From 59dac451a5a0c62e6507579b5eed279283ecc7ca Mon Sep 17 00:00:00 2001 From: nouney Date: Thu, 15 Sep 2016 22:15:56 +0200 Subject: [PATCH 0001/1007] provisioner/file: add "generated" key to allow files created on-the-fly. --- provisioner/file/provisioner.go | 5 ++++- provisioner/file/provisioner_test.go | 25 ++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/provisioner/file/provisioner.go b/provisioner/file/provisioner.go index 2b9a6b5fe..207885bfe 100644 --- a/provisioner/file/provisioner.go +++ b/provisioner/file/provisioner.go @@ -26,6 +26,9 @@ type Config struct { // Direction Direction string + // False if the sources have to exist. + Generated bool + ctx interpolate.Context } @@ -61,7 +64,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { if p.config.Direction == "upload" { for _, src := range p.config.Sources { - if _, err := os.Stat(src); err != nil { + if _, err := os.Stat(src); p.config.Generated == false && err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("Bad source '%s': %s", src, err)) } diff --git a/provisioner/file/provisioner_test.go b/provisioner/file/provisioner_test.go index 53dc315d4..5a2b67037 100644 --- a/provisioner/file/provisioner_test.go +++ b/provisioner/file/provisioner_test.go @@ -45,6 +45,12 @@ func TestProvisionerPrepare_InvalidSource(t *testing.T) { if err == nil { t.Fatalf("should require existing file") } + + config["generated"] = false + err = p.Prepare(config) + if err == nil { + t.Fatalf("should required existing file") + } } func TestProvisionerPrepare_ValidSource(t *testing.T) { @@ -58,11 +64,28 @@ func TestProvisionerPrepare_ValidSource(t *testing.T) { config := testConfig() config["source"] = tf.Name() - err = p.Prepare(config) if err != nil { t.Fatalf("should allow valid file: %s", err) } + + config["generated"] = false + err = p.Prepare(config) + if err != nil { + t.Fatalf("should allow valid file: %s", err) + } +} + +func TestProvisionerPrepare_GeneratedSource(t *testing.T) { + var p Provisioner + + config := testConfig() + config["source"] = "/this/should/not/exist" + config["generated"] = true + err := p.Prepare(config) + if err != nil { + t.Fatalf("should allow non-existing file: %s", err) + } } func TestProvisionerPrepare_EmptyDestination(t *testing.T) { From ed32b6e3c6da1b79eb54d959be22e6cdb06177a2 Mon Sep 17 00:00:00 2001 From: nouney Date: Thu, 15 Sep 2016 22:46:10 +0200 Subject: [PATCH 0002/1007] provisioner/file: document "generated" key. --- website/source/docs/provisioners/file.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/provisioners/file.html.md b/website/source/docs/provisioners/file.html.md index bb66fc220..fb932b512 100644 --- a/website/source/docs/provisioners/file.html.md +++ b/website/source/docs/provisioners/file.html.md @@ -46,6 +46,9 @@ The available configuration options are listed below. All elements are required. "upload." If it is set to "download" then the file "source" in the machine will be downloaded locally to "destination" +- `generated` (boolean) - If true, check the file existence only before uploading. + This allows to upload files created on-the-fly. This defaults to false. + ## Directory Uploads The file provisioner is also able to upload a complete directory to the remote From 5dc6b183655d4eabfe4c9fb6dc22a2e9522e2ac4 Mon Sep 17 00:00:00 2001 From: YAMADA Tsuyoshi Date: Thu, 10 Nov 2016 18:50:31 +0900 Subject: [PATCH 0003/1007] googlecompute-export: use application default credential as same as googlecompute builder --- .../googlecompute-export/post-processor.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/post-processor/googlecompute-export/post-processor.go b/post-processor/googlecompute-export/post-processor.go index f198ab7c8..51a61c9a3 100644 --- a/post-processor/googlecompute-export/post-processor.go +++ b/post-processor/googlecompute-export/post-processor.go @@ -2,7 +2,6 @@ package googlecomputeexport import ( "fmt" - "io/ioutil" "strings" "github.com/mitchellh/multistep" @@ -83,13 +82,12 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac exporterConfig.CalcTimeout() // Set up credentials and GCE driver. - b, err := ioutil.ReadFile(accountKeyFilePath) - if err != nil { - err = fmt.Errorf("Error fetching account credentials: %s", err) - return nil, p.config.KeepOriginalImage, err + if accountKeyFilePath != "" { + err := googlecompute.ProcessAccountFile(&exporterConfig.Account, accountKeyFilePath) + if err != nil { + return nil, p.config.KeepOriginalImage, err + } } - accountKeyContents := string(b) - googlecompute.ProcessAccountFile(&exporterConfig.Account, accountKeyContents) driver, err := googlecompute.NewDriverGCE(ui, projectId, &exporterConfig.Account) if err != nil { return nil, p.config.KeepOriginalImage, err From 86c0c859c58b4e981aaeb816495c6e4406530c46 Mon Sep 17 00:00:00 2001 From: Marc Carmier Date: Wed, 15 Feb 2017 22:04:28 +0100 Subject: [PATCH 0004/1007] Validate the remote_type value for builder/vmware-iso --- builder/vmware/iso/builder.go | 4 +++ builder/vmware/iso/builder_test.go | 40 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) mode change 100755 => 100644 builder/vmware/iso/builder.go diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go old mode 100755 new mode 100644 index 10fce5911..ac4c2c853 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -162,6 +162,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("remote_host must be specified")) } + if b.config.RemoteType != "esx5" { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Only 'esx5' value is accepted for remote_type")) + } } if b.config.Format != "" { diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index 5c1ca5d11..785251e6e 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -139,6 +139,46 @@ func TestBuilderPrepare_InvalidFloppies(t *testing.T) { } } +func TestBuilderPrepare_RemoteType(t *testing.T) { + var b Builder + config := testConfig() + + config["format"] = "ovf" + config["remote_host"] = "foobar.example.com" + // Bad + config["remote_type"] = "foobar" + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + config["remote_host"] = "" + config["remote_type"] = "esx5" + // Bad + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Good + config["remote_type"] = "esx5" + config["remote_host"] = "foobar.example.com" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } +} + func TestBuilderPrepare_Format(t *testing.T) { var b Builder config := testConfig() From 5c11a2e59421a9e12655d3331ccfd8d0895e2f4b Mon Sep 17 00:00:00 2001 From: Marc Carmier Date: Wed, 15 Feb 2017 22:11:27 +0100 Subject: [PATCH 0005/1007] Add test for empty remote_type value --- builder/vmware/iso/builder_test.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index 785251e6e..78ad79adc 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -156,7 +156,7 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { } config["remote_host"] = "" - config["remote_type"] = "esx5" + config["remote_type"] = "" // Bad warns, err = b.Prepare(config) if len(warns) > 0 { @@ -177,6 +177,18 @@ func TestBuilderPrepare_RemoteType(t *testing.T) { if err != nil { t.Fatalf("should not have error: %s", err) } + + // Good + config["remote_type"] = "esx5" + config["remote_host"] = "foobar.example.com" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } } func TestBuilderPrepare_Format(t *testing.T) { From d189676ff079ed5c3815d11461c12a053c32436e Mon Sep 17 00:00:00 2001 From: Anton Kvashenkin Date: Sun, 12 Mar 2017 12:48:08 +0300 Subject: [PATCH 0006/1007] Website/docs: make windows-restart provisioner description more accurate As per https://github.com/mitchellh/packer/blob/master/provisioner/windows-restart/provisioner.go#L16 windows-restart doesn't stop winrm prior to restart host. --- website/source/docs/provisioners/windows-restart.html.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/windows-restart.html.md b/website/source/docs/provisioners/windows-restart.html.md index 3f736c94e..2b3f481a7 100644 --- a/website/source/docs/provisioners/windows-restart.html.md +++ b/website/source/docs/provisioners/windows-restart.html.md @@ -37,9 +37,7 @@ The reference of available configuration options is listed below. Optional parameters: - `restart_command` (string) - The command to execute to initiate the - restart. By default this is `shutdown /r /c "packer restart" /t 5 && net - stop winrm`. A key action of this is to stop WinRM so that Packer can - detect it is rebooting. + restart. By default this is `shutdown /r /f /t 0 /c "packer restart"`. - `restart_check_command` (string) - A command to execute to check if the restart succeeded. This will be done in a loop. From edabd87ea83257d4ef221b88a528c997cb19cb18 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Thu, 29 Jun 2017 10:53:19 +0900 Subject: [PATCH 0007/1007] Copy binary under the bin directory --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f86b30e06..b9b176072 100644 --- a/Makefile +++ b/Makefile @@ -50,8 +50,9 @@ dev: deps ## Build and install a development build exit 1; \ fi @mkdir -p pkg/$(GOOS)_$(GOARCH) + @mkdir -p bin @go install -ldflags '$(GOLDFLAGS)' - @cp $(GOPATH)/bin/packer bin + @cp $(GOPATH)/bin/packer bin/packer @cp $(GOPATH)/bin/packer pkg/$(GOOS)_$(GOARCH) fmt: ## Format Go code From 28a986691db9466f2e89dd8ba46c656b01f36044 Mon Sep 17 00:00:00 2001 From: Bill Wang Date: Tue, 1 Aug 2017 21:24:43 +1000 Subject: [PATCH 0008/1007] Add policies to use spot instance to create the AMI --- website/source/docs/builders/amazon.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index 8873dfcbe..6e3d2cb9f 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -136,6 +136,9 @@ Packer to work: }] } ``` +### Notes to pay for a spot instance to create the AMI + +You need to add two more actions: `ec2:RequestSpotInstances` and `ec2:CancelSpotInstanceRequests` ## Troubleshooting From fdaf4ed8d33bcdfb19fb1269a4c9d1c63e3cc3a5 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Fri, 8 Sep 2017 11:31:19 -0700 Subject: [PATCH 0009/1007] Gracefully clean up on SIGTERM --- command/build.go | 3 ++- command/push.go | 3 ++- main.go | 2 ++ packer/plugin/server.go | 6 ++++-- packer/ui.go | 2 +- stdin.go | 3 ++- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/command/build.go b/command/build.go index de9da51ee..25fc96e71 100644 --- a/command/build.go +++ b/command/build.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "sync" + "syscall" "github.com/hashicorp/packer/helper/enumflag" "github.com/hashicorp/packer/packer" @@ -144,7 +145,7 @@ func (c BuildCommand) Run(args []string) int { // Handle interrupts for this build sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, os.Interrupt) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) defer signal.Stop(sigCh) go func(b packer.Build) { <-sigCh diff --git a/command/push.go b/command/push.go index e1d6c7db2..723e9d92c 100644 --- a/command/push.go +++ b/command/push.go @@ -8,6 +8,7 @@ import ( "path/filepath" "regexp" "strings" + "syscall" "github.com/hashicorp/atlas-go/archive" "github.com/hashicorp/atlas-go/v1" @@ -267,7 +268,7 @@ func (c *PushCommand) Run(args []string) int { // Make a ctrl-C channel sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, os.Interrupt) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) defer signal.Stop(sigCh) err = nil diff --git a/main.go b/main.go index 689780cd4..b5c884eba 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( "path/filepath" "runtime" "sync" + "syscall" "time" "github.com/hashicorp/go-uuid" @@ -86,6 +87,7 @@ func realMain() int { wrapConfig.Writer = io.MultiWriter(logTempFile, logWriter) wrapConfig.Stdout = outW wrapConfig.DetectDuration = 500 * time.Millisecond + wrapConfig.ForwardSignals = []os.Signal{syscall.SIGTERM} exitStatus, err := panicwrap.Wrap(&wrapConfig) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't start Packer: %s", err) diff --git a/packer/plugin/server.go b/packer/plugin/server.go index 667907a5f..470daf950 100644 --- a/packer/plugin/server.go +++ b/packer/plugin/server.go @@ -10,7 +10,6 @@ package plugin import ( "errors" "fmt" - packrpc "github.com/hashicorp/packer/packer/rpc" "io/ioutil" "log" "math/rand" @@ -20,7 +19,10 @@ import ( "runtime" "strconv" "sync/atomic" + "syscall" "time" + + packrpc "github.com/hashicorp/packer/packer/rpc" ) // This is a count of the number of interrupts the process has received. @@ -87,7 +89,7 @@ func Server() (*packrpc.Server, error) { // Eat the interrupts ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) + signal.Notify(ch, os.Interrupt, syscall.SIGTERM) go func() { var count int32 = 0 for { diff --git a/packer/ui.go b/packer/ui.go index c107c23b8..c16a2eae0 100644 --- a/packer/ui.go +++ b/packer/ui.go @@ -180,7 +180,7 @@ func (rw *BasicUi) Ask(query string) (string, error) { rw.scanner = bufio.NewScanner(rw.Reader) } sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, os.Interrupt) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) defer signal.Stop(sigCh) log.Printf("ui: ask: %s", query) diff --git a/stdin.go b/stdin.go index 2df4153f5..758cc6864 100644 --- a/stdin.go +++ b/stdin.go @@ -5,6 +5,7 @@ import ( "log" "os" "os/signal" + "syscall" ) // setupStdin switches out stdin for a pipe. We do this so that we can @@ -26,7 +27,7 @@ func setupStdin() { // Register a signal handler for interrupt in order to close the // writer end of our pipe so that readers get EOF downstream. ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) + signal.Notify(ch, os.Interrupt, syscall.SIGTERM) go func() { defer signal.Stop(ch) From f6bb79784f13d194e85ac0f7ebc24afcbe3fa5b0 Mon Sep 17 00:00:00 2001 From: SLAZ666 Date: Wed, 13 Sep 2017 15:37:26 +0200 Subject: [PATCH 0010/1007] Add option keep_registered to virtualbox-ovf builder --- builder/virtualbox/ovf/config.go | 1 + builder/virtualbox/ovf/step_import.go | 8 ++++++++ builder/virtualbox/ovf/step_import_test.go | 11 +++++++++++ website/source/docs/builders/virtualbox-ovf.html.md | 3 +++ 4 files changed, 23 insertions(+) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 51d394fdb..77b7ffa0e 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -38,6 +38,7 @@ type Config struct { SourcePath string `mapstructure:"source_path"` TargetPath string `mapstructure:"target_path"` VMName string `mapstructure:"vm_name"` + KeepRegistered bool `mapstructure:"keep_registered"` SkipExport bool `mapstructure:"skip_export"` ctx interpolate.Context diff --git a/builder/virtualbox/ovf/step_import.go b/builder/virtualbox/ovf/step_import.go index 6e293d31b..b9a6285fe 100644 --- a/builder/virtualbox/ovf/step_import.go +++ b/builder/virtualbox/ovf/step_import.go @@ -40,6 +40,14 @@ func (s *StepImport) Cleanup(state multistep.StateBag) { driver := state.Get("driver").(vboxcommon.Driver) ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) + + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + if (config.KeepRegistered) && (!cancelled && !halted) { + ui.Say("Keeping virtual machine registered with VirtualBox host (keep_registered = true)") + return + } ui.Say("Unregistering and deleting imported VM...") if err := driver.Delete(s.vmName); err != nil { diff --git a/builder/virtualbox/ovf/step_import_test.go b/builder/virtualbox/ovf/step_import_test.go index 217fee632..fd204c042 100644 --- a/builder/virtualbox/ovf/step_import_test.go +++ b/builder/virtualbox/ovf/step_import_test.go @@ -12,7 +12,10 @@ func TestStepImport_impl(t *testing.T) { func TestStepImport(t *testing.T) { state := testState(t) + c := testConfig(t) + config, _, _ := NewConfig(c) state.Put("vm_path", "foo") + state.Put("config", config) step := new(StepImport) step.Name = "bar" @@ -42,6 +45,14 @@ func TestStepImport(t *testing.T) { } // Test cleanup + config.KeepRegistered = true + step.Cleanup(state) + + if driver.DeleteCalled { + t.Fatal("delete should not be called") + } + + config.KeepRegistered = false step.Cleanup(state) if !driver.DeleteCalled { t.Fatal("delete should be called") diff --git a/website/source/docs/builders/virtualbox-ovf.html.md b/website/source/docs/builders/virtualbox-ovf.html.md index ad7654642..4e0fde30e 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md +++ b/website/source/docs/builders/virtualbox-ovf.html.md @@ -202,6 +202,9 @@ builder. `VBoxManage import`. This can be useful for passing "keepallmacs" or "keepnatmacs" options for existing ovf images. +- `keep_registered` (boolean) - Set this to `true` if you would like to keep + the VM registered with virtualbox. Defaults to `false`. + - `output_directory` (string) - This is the path to the directory where the resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` From 644ac5b367b10d0dd1b82dd84bd3176a804ed739 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Wed, 20 Sep 2017 22:50:37 -0300 Subject: [PATCH 0011/1007] enable vsphere-template to work with local builders --- .../vsphere-template/post-processor.go | 17 ++++++--- .../vsphere-template/step_mark_as_template.go | 34 ++++++++++++++--- post-processor/vsphere/artifact.go | 38 +++++++++++++++++++ post-processor/vsphere/post-processor.go | 9 ++++- 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 post-processor/vsphere/artifact.go diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index 86c9f54b4..e68e2d21c 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -7,16 +7,19 @@ import ( "strings" "time" + "github.com/hashicorp/packer/builder/vmware/iso" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/post-processor/vsphere" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/multistep" "github.com/vmware/govmomi" ) var builtins = map[string]string{ - "mitchellh.vmware-esx": "vmware", + vsphere.BuilderId: "vmware", + iso.BuilderIdESX: "vmware", } type Config struct { @@ -90,11 +93,16 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac source := "" for _, path := range artifact.Files() { - if strings.HasSuffix(path, ".vmx") { + if strings.HasSuffix(path, ".vmx") || strings.HasSuffix(path, ".ovf") || strings.HasSuffix(path, ".ova") { source = path break } } + + if source == "" { + return nil, false, fmt.Errorf("VMX, OVF or OVA file not found") + } + // In some occasions the VM state is powered on and if we immediately try to mark as template // (after the ESXi creates it) it will fail. If vSphere is given a few seconds this behavior doesn't reappear. ui.Message("Waiting 10s for VMware vSphere to start") @@ -117,10 +125,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac &stepCreateFolder{ Folder: p.config.Folder, }, - &stepMarkAsTemplate{ - VMName: artifact.Id(), - Source: source, - }, + NewStepMarkAsTemplate(artifact.Id(), source), } runner := common.NewRunnerWithPauseFn(steps, p.config.PackerConfig, ui, state) runner.Run(state) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index 0e5465054..dda3984a6 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -13,8 +13,30 @@ import ( ) type stepMarkAsTemplate struct { - VMName string - Source string + VMName string + Source string + RemoteFolder string +} + +func NewStepMarkAsTemplate(vmname, source string) *stepMarkAsTemplate { + remoteFolder := "Discovered virtual machine" + + if strings.Contains(vmname, "::") { + local := strings.Split(vmname, "::") + + datastore := local[0] + remoteFolder = local[1] + vmname = local[2] + + source = path.Join("/vmfs/volumes/", datastore, vmname, path.Base(source)) + + } + + return &stepMarkAsTemplate{ + VMName: vmname, + Source: source, + RemoteFolder: remoteFolder, + } } func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction { @@ -25,7 +47,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction ui.Message("Marking as a template...") - vm, err := findRuntimeVM(cli, dcPath, s.VMName) + vm, err := findRuntimeVM(cli, dcPath, s.VMName, s.RemoteFolder) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -75,10 +97,10 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionContinue } -// We will use the virtual machine created by vmware-iso builder -func findRuntimeVM(cli *govmomi.Client, dcPath, name string) (*object.VirtualMachine, error) { +// We will use the virtual machine created/uploaded by vmware builder (remote or local) +func findRuntimeVM(cli *govmomi.Client, dcPath, name, remoteFolder string) (*object.VirtualMachine, error) { si := object.NewSearchIndex(cli.Client) - fullPath := path.Join(dcPath, "vm", "Discovered virtual machine", name) + fullPath := path.Join(dcPath, "vm", remoteFolder, name) ref, err := si.FindByInventoryPath(context.Background(), fullPath) if err != nil { diff --git a/post-processor/vsphere/artifact.go b/post-processor/vsphere/artifact.go new file mode 100644 index 000000000..d8ef75491 --- /dev/null +++ b/post-processor/vsphere/artifact.go @@ -0,0 +1,38 @@ +package vsphere + +import ( + "fmt" +) + +const BuilderId = "packer.post-processor.vsphere" + +type Artifact struct { + files []string + datastore string + vmfolder string + vmname string +} + +func (*Artifact) BuilderId() string { + return BuilderId +} + +func (a *Artifact) Files() []string { + return a.files +} + +func (a *Artifact) Id() string { + return fmt.Sprintf("%s::%s::%s", a.datastore, a.vmfolder, a.vmname) +} + +func (a *Artifact) String() string { + return fmt.Sprintf("VM: %s Folder: %s Datastore: %s", a.vmname, a.vmfolder, a.datastore) +} + +func (*Artifact) State(name string) interface{} { + return nil +} + +func (a *Artifact) Destroy() error { + return nil +} diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index e97147334..ead3b50fd 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -142,7 +142,14 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, fmt.Errorf("Failed: %s\n", err) } - return artifact, false, nil + artifact = &Artifact{ + datastore: p.config.Datastore, + files: artifact.Files(), + vmfolder: p.config.VMFolder, + vmname: p.config.VMName, + } + + return artifact, true, nil } func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) { From 24a8fddf035ef2360bd5dd4bb846fcb5507d8233 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Fri, 22 Sep 2017 13:54:11 -0300 Subject: [PATCH 0012/1007] showing artifact info in packer UI --- post-processor/vsphere-template/post-processor.go | 1 + post-processor/vsphere/post-processor.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index e68e2d21c..5cec3bda6 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -87,6 +87,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { } func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { + ui.Say(fmt.Sprintf("Artifact %s with id %s and builderId %s", artifact, artifact.Id(), artifact.BuilderId())) if _, ok := builtins[artifact.BuilderId()]; !ok { return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId()) } diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index ead3b50fd..0a6e4a6a3 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -149,6 +149,8 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac vmname: p.config.VMName, } + ui.Say(fmt.Sprintf("New artifact created %s with id %s and builderId %s", artifact, artifact.Id(), artifact.BuilderId())) + return artifact, true, nil } From 99dd19ccfdec298992f57355804181bc1b7353c2 Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Fri, 22 Sep 2017 23:37:27 -0300 Subject: [PATCH 0013/1007] Adding correct reference to VM remote path --- post-processor/vsphere-template/post-processor.go | 1 - post-processor/vsphere-template/step_mark_as_template.go | 2 +- post-processor/vsphere/post-processor.go | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index 5cec3bda6..e68e2d21c 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -87,7 +87,6 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { } func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { - ui.Say(fmt.Sprintf("Artifact %s with id %s and builderId %s", artifact, artifact.Id(), artifact.BuilderId())) if _, ok := builtins[artifact.BuilderId()]; !ok { return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId()) } diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index dda3984a6..60780dd0d 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -28,7 +28,7 @@ func NewStepMarkAsTemplate(vmname, source string) *stepMarkAsTemplate { remoteFolder = local[1] vmname = local[2] - source = path.Join("/vmfs/volumes/", datastore, vmname, path.Base(source)) + source = path.Join("/vmfs/volumes/", datastore, vmname, vmname+path.Ext(source)) } diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index 0a6e4a6a3..ead3b50fd 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -149,8 +149,6 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac vmname: p.config.VMName, } - ui.Say(fmt.Sprintf("New artifact created %s with id %s and builderId %s", artifact, artifact.Id(), artifact.BuilderId())) - return artifact, true, nil } From f1773a57f8d624d39bcb84bcdf09f7ebd3179ede Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sat, 23 Sep 2017 03:01:35 -0300 Subject: [PATCH 0014/1007] using vmx extension as default --- post-processor/vsphere-template/step_mark_as_template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index 60780dd0d..82b26a7b5 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -28,7 +28,7 @@ func NewStepMarkAsTemplate(vmname, source string) *stepMarkAsTemplate { remoteFolder = local[1] vmname = local[2] - source = path.Join("/vmfs/volumes/", datastore, vmname, vmname+path.Ext(source)) + source = path.Join("/vmfs/volumes/", datastore, vmname, vmname+".vmx") } From 75a4ca7351899a0018fee74b8ab621b40546628f Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sat, 23 Sep 2017 15:43:57 -0300 Subject: [PATCH 0015/1007] adding artifact testing and using builder id --- .../vsphere-template/post-processor.go | 2 +- .../vsphere-template/step_mark_as_template.go | 17 +++++++-------- post-processor/vsphere/artifact.go | 9 ++++++++ post-processor/vsphere/artifact_test.go | 21 +++++++++++++++++++ post-processor/vsphere/post-processor.go | 7 +------ 5 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 post-processor/vsphere/artifact_test.go diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index e68e2d21c..6014180c7 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -125,7 +125,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac &stepCreateFolder{ Folder: p.config.Folder, }, - NewStepMarkAsTemplate(artifact.Id(), source), + NewStepMarkAsTemplate(artifact, source), } runner := common.NewRunnerWithPauseFn(steps, p.config.PackerConfig, ui, state) runner.Run(state) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index 82b26a7b5..78949d2d9 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/post-processor/vsphere" "github.com/mitchellh/multistep" "github.com/vmware/govmomi" "github.com/vmware/govmomi/object" @@ -18,18 +19,16 @@ type stepMarkAsTemplate struct { RemoteFolder string } -func NewStepMarkAsTemplate(vmname, source string) *stepMarkAsTemplate { +func NewStepMarkAsTemplate(artifact packer.Artifact, source string) *stepMarkAsTemplate { remoteFolder := "Discovered virtual machine" + vmname := artifact.Id() - if strings.Contains(vmname, "::") { - local := strings.Split(vmname, "::") - - datastore := local[0] - remoteFolder = local[1] - vmname = local[2] - + if artifact.BuilderId() == vsphere.BuilderId { + id := strings.Split(artifact.Id(), "::") + datastore := id[0] + remoteFolder = id[1] + vmname = id[2] source = path.Join("/vmfs/volumes/", datastore, vmname, vmname+".vmx") - } return &stepMarkAsTemplate{ diff --git a/post-processor/vsphere/artifact.go b/post-processor/vsphere/artifact.go index d8ef75491..90e475a28 100644 --- a/post-processor/vsphere/artifact.go +++ b/post-processor/vsphere/artifact.go @@ -13,6 +13,15 @@ type Artifact struct { vmname string } +func NewArtifact(datastore, vmfolder, vmname string, files []string) *Artifact { + return &Artifact{ + files: files, + datastore: datastore, + vmfolder: vmfolder, + vmname: vmname, + } +} + func (*Artifact) BuilderId() string { return BuilderId } diff --git a/post-processor/vsphere/artifact_test.go b/post-processor/vsphere/artifact_test.go new file mode 100644 index 000000000..b4f17c759 --- /dev/null +++ b/post-processor/vsphere/artifact_test.go @@ -0,0 +1,21 @@ +package vsphere + +import ( + "github.com/hashicorp/packer/packer" + "testing" +) + +func TestArtifact_ImplementsArtifact(t *testing.T) { + var raw interface{} + raw = &Artifact{} + if _, ok := raw.(packer.Artifact); !ok { + t.Fatalf("Artifact should be a Artifact") + } +} + +func TestArtifact_Id(t *testing.T) { + artifact := NewArtifact("datastore", "vmfolder", "vmname", nil) + if artifact.Id() != "datastore::vmfolder::vmname" { + t.Fatalf("must return datastore, vmfolder and vmname splitted by :: as Id") + } +} diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index ead3b50fd..a022cb23f 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -142,12 +142,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, fmt.Errorf("Failed: %s\n", err) } - artifact = &Artifact{ - datastore: p.config.Datastore, - files: artifact.Files(), - vmfolder: p.config.VMFolder, - vmname: p.config.VMName, - } + artifact = NewArtifact(p.config.Datastore, p.config.VMFolder, p.config.VMName, artifact.Files()) return artifact, true, nil } From b3a0e51fe50b0caedc6ff88bfebfb53c6193745c Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sun, 24 Sep 2017 01:42:28 -0300 Subject: [PATCH 0016/1007] adding documentation --- .../post-processors/vsphere-template.html.md | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/website/source/docs/post-processors/vsphere-template.html.md b/website/source/docs/post-processors/vsphere-template.html.md index e72dc19cc..511224cfd 100644 --- a/website/source/docs/post-processors/vsphere-template.html.md +++ b/website/source/docs/post-processors/vsphere-template.html.md @@ -1,7 +1,7 @@ --- description: | - The Packer vSphere Template post-processor takes an artifact from the VMware-iso builder built on ESXi (i.e. remote) - and allows to mark a VM as a template and leaving it in a path of choice. + The Packer vSphere Template post-processor takes an artifact from the VMware-iso builder, built on ESXi (i.e. remote) + or an artifact from the vSphere post-processor and allows to mark a VM as a template and leaving it in a path of choice. layout: docs page_title: 'vSphere Template - Post-Processors' sidebar_current: 'docs-post-processors-vSphere-template' @@ -11,8 +11,9 @@ sidebar_current: 'docs-post-processors-vSphere-template' Type: `vsphere-template` -The Packer vSphere template post-processor takes an artifact from the VMware-iso builder built on ESXi (i.e. remote) and -allows to mark a VM as a template and leaving it in a path of choice. +The Packer vSphere Template post-processor takes an artifact from the VMware-iso builder, built on ESXi (i.e. remote) +or an artifact from the [vSphere](/docs/post-processors/vsphere.html) post-processor and allows to mark a VM as a +template and leaving it in a path of choice. ## Example @@ -51,3 +52,31 @@ Optional: - `folder` (string) - Target path where the template will be created. - `insecure` (boolean) - If it's true skip verification of server certificate. Default is false + +## Using the vSphere Template with local builders + +Once the [vSphere](/docs/post-processors/vsphere.html) takes an artifact from the VMware builder and uploads it +to a vSphere endpoint, you will likely want to mark that VM as template. Packer can do this for you automatically +using a sequence definition (a collection of post-processors that are treated as as single pipeline, see +[Post-Processors](/docs/templates/post-processors.html) for more information): + +``` json +{ + "post-processors": [ + [ + { + "type": "vsphere", + ... + }, + { + "type": "vsphere-template", + ... + } + ] + ] +} +``` + +In the example above, the result of each builder is passed through the defined sequence of post-processors starting +with the `vsphere` post-processor which will upload the artifact to a vSphere endpoint. The resulting artifact is then +passed on to the `vsphere-template` post-processor which handles marking a VM as a template. From 50904064e19053d18fc61c4f3b26bcd3db339f9a Mon Sep 17 00:00:00 2001 From: bugbuilder Date: Sun, 24 Sep 2017 21:56:35 -0300 Subject: [PATCH 0017/1007] doesn't keep the original artifact --- post-processor/vsphere/post-processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index a022cb23f..d8b40d654 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -144,7 +144,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac artifact = NewArtifact(p.config.Datastore, p.config.VMFolder, p.config.VMName, artifact.Files()) - return artifact, true, nil + return artifact, false, nil } func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) { From f426ba46607ab0f75989f863f331537113ed7796 Mon Sep 17 00:00:00 2001 From: Andrew Pryde Date: Fri, 29 Sep 2017 10:51:31 +0100 Subject: [PATCH 0018/1007] Do not override region in OCI builder Only default the OCI builder region to us-phoenix-1 when no value is present in the packer template and the OCI config file. Fixes: #5401 --- builder/oracle/oci/client/config.go | 2 +- builder/oracle/oci/client/config_test.go | 2 +- builder/oracle/oci/config.go | 5 ++++- builder/oracle/oci/config_test.go | 14 ++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/builder/oracle/oci/client/config.go b/builder/oracle/oci/client/config.go index 580cd9f77..4df6b6a01 100644 --- a/builder/oracle/oci/client/config.go +++ b/builder/oracle/oci/client/config.go @@ -182,7 +182,7 @@ func BaseTestConfig() (*ini.File, *os.File, error) { // Build ini cfg := ini.Empty() section, _ := cfg.NewSection("DEFAULT") - section.NewKey("region", "us-phoenix-1") + section.NewKey("region", "us-ashburn-1") section.NewKey("tenancy", "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") section.NewKey("user", "ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") section.NewKey("fingerprint", "3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55") diff --git a/builder/oracle/oci/client/config_test.go b/builder/oracle/oci/client/config_test.go index 08f0b806d..221e725c3 100644 --- a/builder/oracle/oci/client/config_test.go +++ b/builder/oracle/oci/client/config_test.go @@ -81,7 +81,7 @@ func TestNewConfigDefaultsPopulated(t *testing.T) { t.Fatal("Expected ADMIN config to exist in map") } - if adminConfig.Region != "us-phoenix-1" { + if adminConfig.Region != "us-ashburn-1" { t.Errorf("Expected 'us-phoenix-1', got '%s'", adminConfig.Region) } } diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 883c61cb5..36f8bb8e9 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -101,7 +101,10 @@ func NewConfig(raws ...interface{}) (*Config, error) { if c.Region != "" { accessCfg.Region = c.Region - } else { + } + + // Default if the template nor the API config contains a region. + if accessCfg.Region == "" { accessCfg.Region = "us-phoenix-1" } diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index bc6039a55..9a6bd6486 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -122,6 +122,20 @@ func TestConfig(t *testing.T) { }) + t.Run("RegionNotDefaultedToPHXWhenSetInOCISettings", func(t *testing.T) { + raw := testConfig(cfgFile) + c, errs := NewConfig(raw) + if errs != nil { + t.Fatalf("err: %+v", errs) + } + + expected := "us-ashburn-1" + if c.AccessCfg.Region != expected { + t.Errorf("Expected region: %s, got %s.", expected, c.AccessCfg.Region) + } + + }) + // Test the correct errors are produced when required template keys are // omitted. requiredKeys := []string{"availability_domain", "base_image_ocid", "shape", "subnet_ocid"} From ba72021274e1c555d444c0d866ae6d9548fc7129 Mon Sep 17 00:00:00 2001 From: localghost Date: Mon, 2 Oct 2017 22:03:42 +0200 Subject: [PATCH 0019/1007] Fix owner of files uploaded to docker container run as non-root. --- builder/docker/communicator.go | 88 ++++++++++++++++++++-- builder/docker/communicator_test.go | 113 ++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 6 deletions(-) diff --git a/builder/docker/communicator.go b/builder/docker/communicator.go index 13684b2f8..bbfdb551f 100644 --- a/builder/docker/communicator.go +++ b/builder/docker/communicator.go @@ -18,12 +18,13 @@ import ( ) type Communicator struct { - ContainerID string - HostDir string - ContainerDir string - Version *version.Version - Config *Config - lock sync.Mutex + ContainerID string + HostDir string + ContainerDir string + Version *version.Version + Config *Config + containerUser *string + lock sync.Mutex } func (c *Communicator) Start(remote *packer.RemoteCmd) error { @@ -154,6 +155,10 @@ func (c *Communicator) uploadFile(dst string, src io.Reader, fi *os.FileInfo) er return fmt.Errorf("Failed to upload to '%s' in container: %s. %s.", dst, stderrOut, err) } + if err := c.fixDestinationOwner(dst); err != nil { + return err + } + return nil } @@ -207,6 +212,10 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error return fmt.Errorf("Failed to upload to '%s' in container: %s. %s.", dst, stderrOut, err) } + if err := c.fixDestinationOwner(dst); err != nil { + return err + } + return nil } @@ -310,3 +319,70 @@ func (c *Communicator) run(cmd *exec.Cmd, remote *packer.RemoteCmd, stdin io.Wri // Set the exit status which triggers waiters remote.SetExited(exitStatus) } + +// TODO Workaround for #5307. Remove once #5409 is fixed. +func (c *Communicator) fixDestinationOwner(destination string) error { + if c.containerUser == nil { + containerUser, err := c.discoverContainerUser() + if err != nil { + return err + } + c.containerUser = &containerUser + } + + if *c.containerUser != "" { + chownArgs := []string{ + "docker", "exec", "--user", "root", c.ContainerID, "/bin/sh", "-c", + fmt.Sprintf("chown -R %s %s", *c.containerUser, destination), + } + if _, err := c.runLocalCommand(chownArgs[0], chownArgs[1:]...); err != nil { + return fmt.Errorf("Failed to set owner of the uploaded file: %s", err) + } + } + + return nil +} + +func (c *Communicator) discoverContainerUser() (string, error) { + var err error + var stdout []byte + inspectArgs := []string{"docker", "inspect", "--format", "{{.Config.User}}", c.ContainerID} + if stdout, err = c.runLocalCommand(inspectArgs[0], inspectArgs[1:]...); err != nil { + return "", fmt.Errorf("Failed to inspect the container: %s", err) + } + return strings.TrimSpace(string(stdout)), nil +} + +func (c *Communicator) runLocalCommand(name string, arg ...string) (stdout []byte, err error) { + localCmd := exec.Command(name, arg...) + + stdoutP, err := localCmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("failed to open stdout pipe, %s", err) + } + + stderrP, err := localCmd.StderrPipe() + if err != nil { + return nil, fmt.Errorf("failed to open stderr pipe, %s", err) + } + + if err = localCmd.Start(); err != nil { + return nil, fmt.Errorf("failed to start command, %s", err) + } + + stdout, err = ioutil.ReadAll(stdoutP) + if err != nil { + return nil, fmt.Errorf("failed to read from stdout pipe, %s", err) + } + + stderr, err := ioutil.ReadAll(stderrP) + if err != nil { + return nil, fmt.Errorf("failed to read from stderr pipe, %s", err) + } + + if err := localCmd.Wait(); err != nil { + return nil, fmt.Errorf("%s, %s", stderr, err) + } + + return stdout, nil +} diff --git a/builder/docker/communicator_test.go b/builder/docker/communicator_test.go index 0c98dbbb2..b5b5b1583 100644 --- a/builder/docker/communicator_test.go +++ b/builder/docker/communicator_test.go @@ -209,6 +209,82 @@ func TestLargeDownload(t *testing.T) { } +// TestUploadOwner verifies that owner of uploaded files is the user the container is running as. +func TestUploadOwner(t *testing.T) { + ui := packer.TestUi(t) + cache := &packer.FileCache{CacheDir: os.TempDir()} + + tpl, err := template.Parse(strings.NewReader(testUploadOwnerTemplate)) + if err != nil { + t.Fatalf("Unable to parse config: %s", err) + } + + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1") + } + cmd := exec.Command("docker", "-v") + cmd.Run() + if !cmd.ProcessState.Success() { + t.Error("docker command not found; please make sure docker is installed") + } + + // Setup the builder + builder := &Builder{} + warnings, err := builder.Prepare(tpl.Builders["docker"].Config) + if err != nil { + t.Fatalf("Error preparing configuration %s", err) + } + if len(warnings) > 0 { + t.Fatal("Encountered configuration warnings; aborting") + } + + // Setup the provisioners + fileProvisioner := &file.Provisioner{} + err = fileProvisioner.Prepare(tpl.Provisioners[0].Config) + if err != nil { + t.Fatalf("Error preparing single file upload provisioner: %s", err) + } + + dirProvisioner := &file.Provisioner{} + err = dirProvisioner.Prepare(tpl.Provisioners[1].Config) + if err != nil { + t.Fatalf("Error preparing directory upload provisioner: %s", err) + } + + shellProvisioner := &shell.Provisioner{} + err = shellProvisioner.Prepare(tpl.Provisioners[2].Config) + if err != nil { + t.Fatalf("Error preparing shell provisioner: %s", err) + } + + verifyProvisioner := &shell.Provisioner{} + err = verifyProvisioner.Prepare(tpl.Provisioners[3].Config) + if err != nil { + t.Fatalf("Error preparing verification provisioner: %s", err) + } + + // Add hooks so the provisioners run during the build + hooks := map[string][]packer.Hook{} + hooks[packer.HookProvision] = []packer.Hook{ + &packer.ProvisionHook{ + Provisioners: []packer.Provisioner{ + fileProvisioner, + dirProvisioner, + shellProvisioner, + verifyProvisioner, + }, + ProvisionerTypes: []string{"", "", "", ""}, + }, + } + hook := &packer.DispatchHook{Mapping: hooks} + + artifact, err := builder.Run(ui, hook, cache) + if err != nil { + t.Fatalf("Error running build %s", err) + } + defer artifact.Destroy() +} + const dockerBuilderConfig = ` { "builders": [ @@ -269,3 +345,40 @@ const dockerLargeBuilderConfig = ` ] } ` + +const testUploadOwnerTemplate = ` +{ + "builders": [ + { + "type": "docker", + "image": "ubuntu", + "discard": true, + "run_command": ["-d", "-i", "-t", "-u", "42", "{{.Image}}", "/bin/sh"] + } + ], + "provisioners": [ + { + "type": "file", + "source": "test-fixtures/onecakes/strawberry", + "destination": "/tmp/strawberry-cake" + }, + { + "type": "file", + "source": "test-fixtures/manycakes", + "destination": "/tmp/" + }, + { + "type": "shell", + "inline": "touch /tmp/testUploadOwner" + }, + { + "type": "shell", + "inline": [ + "[ $(stat -c %u /tmp/strawberry-cake) -eq 42 ] || (echo 'Invalid owner of /tmp/strawberry-cake' && exit 1)", + "[ $(stat -c %u /tmp/testUploadOwner) -eq 42 ] || (echo 'Invalid owner of /tmp/testUploadOwner' && exit 1)", + "find /tmp/manycakes | xargs -n1 -IFILE /bin/sh -c '[ $(stat -c %u FILE) -eq 42 ] || (echo \"Invalid owner of FILE\" && exit 1)'" + ] + } + ] +} +` From 35ef7bce5ca489a6a74a92cb3386f34e637dedc3 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 3 Oct 2017 15:35:03 -0700 Subject: [PATCH 0020/1007] implement dir check for winrm communicator --- communicator/winrm/communicator.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go index d1f7d2ab6..a725fe51f 100644 --- a/communicator/winrm/communicator.go +++ b/communicator/winrm/communicator.go @@ -127,6 +127,23 @@ func (c *Communicator) Upload(path string, input io.Reader, _ *os.FileInfo) erro if err != nil { return err } + + // Get information about destination path + endpoint := winrm.NewEndpoint(c.endpoint.Host, c.endpoint.Port, c.config.Https, c.config.Insecure, nil, nil, nil, c.config.Timeout) + client, err := winrm.NewClient(endpoint, c.config.Username, c.config.Password) + if err != nil { + return fmt.Errorf("Was unable to create winrm client: %s", err) + } + stdout, _, _, err := client.RunWithString(fmt.Sprintf("powershell -Command \"(Get-Item %s) -is [System.IO.DirectoryInfo]\"", path), "") + if err != nil { + return fmt.Errorf("Couldn't determine whether destination was a folder or file: %s", err) + } + if strings.Contains(stdout, "True") { + // The path exists and is a directory. + // Upload file into the directory instead of overwriting. + path = filepath.Join(path, filepath.Base((*fi).Name())) + } + log.Printf("Uploading file to '%s'", path) return wcp.Write(path, input) } From a5e61348195383154b9f667c45d36d5270bf00cc Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 3 Oct 2017 15:55:32 -0700 Subject: [PATCH 0021/1007] implement dir check for ssh communicator --- communicator/ssh/communicator.go | 23 +++++++++++++++++++++++ communicator/winrm/communicator.go | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index c10e97dcc..827925f2c 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -533,6 +533,29 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e target_dir := filepath.Dir(path) target_file := filepath.Base(path) + // find out if it's a directory + testDirectoryCommand := fmt.Sprintf("if [ -d \"%s\" ]; then echo directory; fi", path) + cmd := &packer.RemoteCmd{Command: testDirectoryCommand} + var buf, buf2 bytes.Buffer + cmd.Stdout = &buf + cmd.Stdout = io.MultiWriter(cmd.Stdout, &buf2) + + err := c.Start(cmd) + + if err != nil { + log.Printf("Unable to check whether remote path is a dir: %s", err) + return err + } + + stdoutToRead := buf2.String() + if strings.Contains(stdoutToRead, "directory") { + log.Printf("upload locale is a directory") + target_dir = path + target_file = filepath.Base((*fi).Name()) + } + + log.Printf("target_file was %s", target_file) + // On windows, filepath.Dir uses backslash seperators (ie. "\tmp"). // This does not work when the target host is unix. Switch to forward slash // which works for unix and windows diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go index a725fe51f..3970d1af8 100644 --- a/communicator/winrm/communicator.go +++ b/communicator/winrm/communicator.go @@ -122,7 +122,7 @@ func runCommand(shell *winrm.Shell, cmd *winrm.Command, rc *packer.RemoteCmd) { } // Upload implementation of communicator.Communicator interface -func (c *Communicator) Upload(path string, input io.Reader, _ *os.FileInfo) error { +func (c *Communicator) Upload(path string, input io.Reader, fi *os.FileInfo) error { wcp, err := c.newCopyClient() if err != nil { return err From b3cc90125dde7fbec29d6c9616df4167efe5f968 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 3 Oct 2017 16:36:27 -0700 Subject: [PATCH 0022/1007] ssh communicator works --- communicator/ssh/communicator.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 827925f2c..3ec2d1aba 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -534,11 +534,8 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e target_file := filepath.Base(path) // find out if it's a directory - testDirectoryCommand := fmt.Sprintf("if [ -d \"%s\" ]; then echo directory; fi", path) + testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) cmd := &packer.RemoteCmd{Command: testDirectoryCommand} - var buf, buf2 bytes.Buffer - cmd.Stdout = &buf - cmd.Stdout = io.MultiWriter(cmd.Stdout, &buf2) err := c.Start(cmd) @@ -546,10 +543,9 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e log.Printf("Unable to check whether remote path is a dir: %s", err) return err } - - stdoutToRead := buf2.String() - if strings.Contains(stdoutToRead, "directory") { - log.Printf("upload locale is a directory") + cmd.Wait() + if cmd.ExitStatus == 0 { + log.Printf("path is a directory; copying file into directory.") target_dir = path target_file = filepath.Base((*fi).Name()) } From 8452ca898cbf5dcf3b8c6c0a7db975dffc18fee8 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 3 Oct 2017 17:06:33 -0700 Subject: [PATCH 0023/1007] implemented for docker communicator --- builder/docker/communicator.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/builder/docker/communicator.go b/builder/docker/communicator.go index 13684b2f8..0c4a8833d 100644 --- a/builder/docker/communicator.go +++ b/builder/docker/communicator.go @@ -104,6 +104,21 @@ func (c *Communicator) uploadReader(dst string, src io.Reader) error { // uploadFile uses docker cp to copy the file from the host to the container func (c *Communicator) uploadFile(dst string, src io.Reader, fi *os.FileInfo) error { + // find out if it's a directory + testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, dst) + cmd := &packer.RemoteCmd{Command: testDirectoryCommand} + + err := c.Start(cmd) + + if err != nil { + log.Printf("Unable to check whether remote path is a dir: %s", err) + return err + } + cmd.Wait() + if cmd.ExitStatus == 0 { + log.Printf("path is a directory; copying file into directory.") + dst = filepath.Join(dst, filepath.Base((*fi).Name())) + } // command format: docker cp /path/to/infile containerid:/path/to/outfile log.Printf("Copying to %s on container %s.", dst, c.ContainerID) From 93bddb3e65101d553e596d975098949129dfba36 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 4 Oct 2017 13:35:15 -0700 Subject: [PATCH 0024/1007] implement directory fix for lxc file uploads --- builder/lxc/communicator.go | 18 ++++++++++++++++++ communicator/ssh/communicator.go | 2 -- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/builder/lxc/communicator.go b/builder/lxc/communicator.go index 8d9765979..77ea3c052 100644 --- a/builder/lxc/communicator.go +++ b/builder/lxc/communicator.go @@ -71,6 +71,24 @@ func (c *LxcAttachCommunicator) Upload(dst string, r io.Reader, fi *os.FileInfo) return err } + if fi != nil { + tfDir := filepath.Dir(tf.Name()) + // rename tempfile to match original file name. This makes sure that if file is being + // moved into a directory, the filename is preserved instead of a temp name. + adjustedTempName := filepath.Join(tfDir, (*fi).Name()) + mvCmd, err := c.CmdWrapper(fmt.Sprintf("sudo mv %s %s", tf.Name(), adjustedTempName)) + if err != nil { + return err + } + defer os.Remove(adjustedTempName) + exitStatus := ShellCommand(mvCmd).Run() + // change cpCmd to use new file name as source + cpCmd, err = c.CmdWrapper(fmt.Sprintf("sudo cp %s %s", adjustedTempName, dst)) + if err != nil { + return err + } + } + log.Printf("Running copy command: %s", dst) return ShellCommand(cpCmd).Run() diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 3ec2d1aba..8d5a388d5 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -550,8 +550,6 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e target_file = filepath.Base((*fi).Name()) } - log.Printf("target_file was %s", target_file) - // On windows, filepath.Dir uses backslash seperators (ie. "\tmp"). // This does not work when the target host is unix. Switch to forward slash // which works for unix and windows From e8cabc1e83b6aa99a678f5555a7218cffc20003c Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 4 Oct 2017 15:23:36 -0700 Subject: [PATCH 0025/1007] implemented for LXD --- builder/lxc/communicator.go | 2 +- builder/lxd/communicator.go | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/builder/lxc/communicator.go b/builder/lxc/communicator.go index 77ea3c052..bb940851a 100644 --- a/builder/lxc/communicator.go +++ b/builder/lxc/communicator.go @@ -81,7 +81,7 @@ func (c *LxcAttachCommunicator) Upload(dst string, r io.Reader, fi *os.FileInfo) return err } defer os.Remove(adjustedTempName) - exitStatus := ShellCommand(mvCmd).Run() + ShellCommand(mvCmd).Run() // change cpCmd to use new file name as source cpCmd, err = c.CmdWrapper(fmt.Sprintf("sudo cp %s %s", adjustedTempName, dst)) if err != nil { diff --git a/builder/lxd/communicator.go b/builder/lxd/communicator.go index 8eaa47a5f..b59e83f82 100644 --- a/builder/lxd/communicator.go +++ b/builder/lxd/communicator.go @@ -54,7 +54,24 @@ func (c *Communicator) Start(cmd *packer.RemoteCmd) error { } func (c *Communicator) Upload(dst string, r io.Reader, fi *os.FileInfo) error { - cpCmd, err := c.CmdWrapper(fmt.Sprintf("lxc file push - %s", filepath.Join(c.ContainerName, dst))) + fileDestination := filepath.Join(c.ContainerName, dst) + // find out if the place we are pushing to is a directory + testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, dst) + cmd := &packer.RemoteCmd{Command: testDirectoryCommand} + err := c.Start(cmd) + + if err != nil { + log.Printf("Unable to check whether remote path is a dir: %s", err) + return err + } + cmd.Wait() + + if cmd.ExitStatus == 0 { + log.Printf("path is a directory; copying file into directory.") + fileDestination = filepath.Join(c.ContainerName, dst, (*fi).Name()) + } + + cpCmd, err := c.CmdWrapper(fmt.Sprintf("lxc file push - %s", fileDestination)) if err != nil { return err } From a79d5eff4ec3ad22d548a007d44d2bf6ad12cafd Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 5 Oct 2017 10:44:18 -0700 Subject: [PATCH 0026/1007] implement sftp path --- communicator/ssh/communicator.go | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 8d5a388d5..3f668bb8e 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -377,15 +377,31 @@ func (c *comm) connectToAgent() { func (c *comm) sftpUploadSession(path string, input io.Reader, fi *os.FileInfo) error { sftpFunc := func(client *sftp.Client) error { - return sftpUploadFile(path, input, client, fi) + return c.sftpUploadFile(path, input, client, fi) } return c.sftpSession(sftpFunc) } -func sftpUploadFile(path string, input io.Reader, client *sftp.Client, fi *os.FileInfo) error { +func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, fi *os.FileInfo) error { log.Printf("[DEBUG] sftp: uploading %s", path) + // find out if destination is a directory (this is to replicate rsync behavior) + testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) + cmd := &packer.RemoteCmd{Command: testDirectoryCommand} + + err := c.Start(cmd) + + if err != nil { + log.Printf("Unable to check whether remote path is a dir: %s", err) + return err + } + cmd.Wait() + if cmd.ExitStatus == 0 { + log.Printf("path is a directory; copying file into directory.") + path = filepath.Join(path, filepath.Base((*fi).Name())) + } + f, err := client.Create(path) if err != nil { return err @@ -436,7 +452,7 @@ func (c *comm) sftpUploadDirSession(dst string, src string, excl []string) error return nil } - return sftpVisitFile(finalDst, path, info, client) + return c.sftpVisitFile(finalDst, path, info, client) } return filepath.Walk(src, walkFunc) @@ -445,7 +461,7 @@ func (c *comm) sftpUploadDirSession(dst string, src string, excl []string) error return c.sftpSession(sftpFunc) } -func sftpMkdir(path string, client *sftp.Client, fi os.FileInfo) error { +func (c *comm) sftpMkdir(path string, client *sftp.Client, fi os.FileInfo) error { log.Printf("[DEBUG] sftp: creating dir %s", path) if err := client.Mkdir(path); err != nil { @@ -463,16 +479,16 @@ func sftpMkdir(path string, client *sftp.Client, fi os.FileInfo) error { return nil } -func sftpVisitFile(dst string, src string, fi os.FileInfo, client *sftp.Client) error { +func (c *comm) sftpVisitFile(dst string, src string, fi os.FileInfo, client *sftp.Client) error { if !fi.IsDir() { f, err := os.Open(src) if err != nil { return err } defer f.Close() - return sftpUploadFile(dst, f, client, &fi) + return c.sftpUploadFile(dst, f, client, &fi) } else { - err := sftpMkdir(dst, client, fi) + err := c.sftpMkdir(dst, client, fi) return err } } @@ -533,7 +549,7 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e target_dir := filepath.Dir(path) target_file := filepath.Base(path) - // find out if it's a directory + // find out if destination is a directory (this is to replicate rsync behavior) testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) cmd := &packer.RemoteCmd{Command: testDirectoryCommand} From 52c0be2d82cf74f29e4d4d5a246001b5e559bcaf Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 5 Oct 2017 16:57:52 -0700 Subject: [PATCH 0027/1007] fix test --- communicator/winrm/communicator_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/communicator/winrm/communicator_test.go b/communicator/winrm/communicator_test.go index d5eb974ac..3f6b50ae1 100644 --- a/communicator/winrm/communicator_test.go +++ b/communicator/winrm/communicator_test.go @@ -48,6 +48,12 @@ func newMockWinRMServer(t *testing.T) *winrmtest.Remote { func(out, err io.Writer) int { return 0 }) + wrm.CommandFunc( + winrmtest.MatchText(`powershell -Command "(Get-Item C:/Temp/packer.cmd) -is [System.IO.DirectoryInfo]"`), + func(out, err io.Writer) int { + out.Write([]byte("False")) + return 0 + }) return wrm } From d9b404fa00a52c8d02660008ffd73fcc0fe902bc Mon Sep 17 00:00:00 2001 From: Paul Kilar Date: Tue, 10 Oct 2017 15:04:15 +0100 Subject: [PATCH 0028/1007] SOCKS5 proxy support --- communicator/ssh/connect.go | 20 ++++++++++++++++++++ helper/communicator/config.go | 10 ++++++++++ helper/communicator/step_connect_ssh.go | 16 ++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/communicator/ssh/connect.go b/communicator/ssh/connect.go index 43277595c..7622a90e3 100644 --- a/communicator/ssh/connect.go +++ b/communicator/ssh/connect.go @@ -6,6 +6,7 @@ import ( "time" "golang.org/x/crypto/ssh" + "golang.org/x/net/proxy" ) // ConnectFunc is a convenience method for returning a function @@ -27,6 +28,25 @@ func ConnectFunc(network, addr string) func() (net.Conn, error) { } } +// ConnectFunc is a convenience method for returning a function +// that connects to a host using SOCKS5 proxy +func ProxyConnectFunc(socksProxy string, socksAuth *proxy.Auth, network, addr string) func() (net.Conn, error) { + return func() (net.Conn, error) { + // create a socks5 dialer + dialer, err := proxy.SOCKS5("tcp", socksProxy, socksAuth, proxy.Direct) + if err != nil { + return nil, fmt.Errorf("Can't connect to the proxy: %s", err) + } + + c, err := dialer.Dial(network, addr) + if err != nil { + return nil, err + } + + return c, nil + } +} + // BastionConnectFunc is a convenience method for returning a function // that connects to a host over a bastion connection. func BastionConnectFunc( diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 243ca224d..d89a0ac27 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -33,6 +33,10 @@ type Config struct { SSHBastionPassword string `mapstructure:"ssh_bastion_password"` SSHBastionPrivateKey string `mapstructure:"ssh_bastion_private_key_file"` SSHFileTransferMethod string `mapstructure:"ssh_file_transfer_method"` + SSHProxyHost string `mapstructure:"ssh_proxy_host"` + SSHProxyPort int `mapstructure:"ssh_proxy_port"` + SSHProxyUsername string `mapstructure:"ssh_proxy_username"` + SSHProxyPassword string `mapstructure:"ssh_proxy_password"` // WinRM WinRMUser string `mapstructure:"winrm_username"` @@ -141,6 +145,12 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error { } } + if c.SSHProxyHost != "" { + if c.SSHProxyPort == 0 { + c.SSHProxyPort = 1080 + } + } + if c.SSHFileTransferMethod == "" { c.SSHFileTransferMethod = "scp" } diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 669d52410..9179f57e8 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -15,6 +15,7 @@ import ( "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" + "golang.org/x/net/proxy" ) // StepConnectSSH is a step that only connects to SSH. @@ -88,6 +89,8 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru // do this one before entering the retry loop. var bProto, bAddr string var bConf *gossh.ClientConfig + var pAddr string + var pAuth *proxy.Auth if s.Config.SSHBastionHost != "" { // The protocol is hardcoded for now, but may be configurable one day bProto = "tcp" @@ -101,6 +104,16 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru bConf = conf } + if s.Config.SSHProxyHost != "" { + pAddr = fmt.Sprintf("%s:%d", s.Config.SSHProxyHost, s.Config.SSHProxyPort) + if s.Config.SSHProxyUsername != "" { + pAuth = new(proxy.Auth) + pAuth.User = s.Config.SSHBastionUsername + pAuth.Password = s.Config.SSHBastionPassword + } + + } + handshakeAttempts := 0 var comm packer.Communicator @@ -146,6 +159,9 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru // We're using a bastion host, so use the bastion connfunc connFunc = ssh.BastionConnectFunc( bProto, bAddr, bConf, "tcp", address) + } else if pAddr != "" { + // Connect via SOCKS5 proxy + connFunc = ssh.ProxyConnectFunc(pAddr, pAuth, "tcp", address) } else { // No bastion host, connect directly connFunc = ssh.ConnectFunc("tcp", address) From 01ff96b341bac9edbec363b89239fe3f2b6ad969 Mon Sep 17 00:00:00 2001 From: Paul Kilar Date: Tue, 10 Oct 2017 15:39:18 +0100 Subject: [PATCH 0029/1007] Added missing dependency and updated documentation --- vendor/golang.org/x/net/proxy/direct.go | 18 ++ vendor/golang.org/x/net/proxy/per_host.go | 140 ++++++++++++ vendor/golang.org/x/net/proxy/proxy.go | 134 +++++++++++ vendor/golang.org/x/net/proxy/socks5.go | 214 ++++++++++++++++++ vendor/vendor.json | 6 + .../docs/templates/communicator.html.md | 9 + 6 files changed, 521 insertions(+) create mode 100644 vendor/golang.org/x/net/proxy/direct.go create mode 100644 vendor/golang.org/x/net/proxy/per_host.go create mode 100644 vendor/golang.org/x/net/proxy/proxy.go create mode 100644 vendor/golang.org/x/net/proxy/socks5.go diff --git a/vendor/golang.org/x/net/proxy/direct.go b/vendor/golang.org/x/net/proxy/direct.go new file mode 100644 index 000000000..4c5ad88b1 --- /dev/null +++ b/vendor/golang.org/x/net/proxy/direct.go @@ -0,0 +1,18 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proxy + +import ( + "net" +) + +type direct struct{} + +// Direct is a direct proxy: one that makes network connections directly. +var Direct = direct{} + +func (direct) Dial(network, addr string) (net.Conn, error) { + return net.Dial(network, addr) +} diff --git a/vendor/golang.org/x/net/proxy/per_host.go b/vendor/golang.org/x/net/proxy/per_host.go new file mode 100644 index 000000000..242d5623f --- /dev/null +++ b/vendor/golang.org/x/net/proxy/per_host.go @@ -0,0 +1,140 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proxy + +import ( + "net" + "strings" +) + +// A PerHost directs connections to a default Dialer unless the host name +// requested matches one of a number of exceptions. +type PerHost struct { + def, bypass Dialer + + bypassNetworks []*net.IPNet + bypassIPs []net.IP + bypassZones []string + bypassHosts []string +} + +// NewPerHost returns a PerHost Dialer that directs connections to either +// defaultDialer or bypass, depending on whether the connection matches one of +// the configured rules. +func NewPerHost(defaultDialer, bypass Dialer) *PerHost { + return &PerHost{ + def: defaultDialer, + bypass: bypass, + } +} + +// Dial connects to the address addr on the given network through either +// defaultDialer or bypass. +func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + return p.dialerForRequest(host).Dial(network, addr) +} + +func (p *PerHost) dialerForRequest(host string) Dialer { + if ip := net.ParseIP(host); ip != nil { + for _, net := range p.bypassNetworks { + if net.Contains(ip) { + return p.bypass + } + } + for _, bypassIP := range p.bypassIPs { + if bypassIP.Equal(ip) { + return p.bypass + } + } + return p.def + } + + for _, zone := range p.bypassZones { + if strings.HasSuffix(host, zone) { + return p.bypass + } + if host == zone[1:] { + // For a zone "example.com", we match "example.com" + // too. + return p.bypass + } + } + for _, bypassHost := range p.bypassHosts { + if bypassHost == host { + return p.bypass + } + } + return p.def +} + +// AddFromString parses a string that contains comma-separated values +// specifying hosts that should use the bypass proxy. Each value is either an +// IP address, a CIDR range, a zone (*.example.com) or a host name +// (localhost). A best effort is made to parse the string and errors are +// ignored. +func (p *PerHost) AddFromString(s string) { + hosts := strings.Split(s, ",") + for _, host := range hosts { + host = strings.TrimSpace(host) + if len(host) == 0 { + continue + } + if strings.Contains(host, "/") { + // We assume that it's a CIDR address like 127.0.0.0/8 + if _, net, err := net.ParseCIDR(host); err == nil { + p.AddNetwork(net) + } + continue + } + if ip := net.ParseIP(host); ip != nil { + p.AddIP(ip) + continue + } + if strings.HasPrefix(host, "*.") { + p.AddZone(host[1:]) + continue + } + p.AddHost(host) + } +} + +// AddIP specifies an IP address that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match an IP. +func (p *PerHost) AddIP(ip net.IP) { + p.bypassIPs = append(p.bypassIPs, ip) +} + +// AddNetwork specifies an IP range that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match. +func (p *PerHost) AddNetwork(net *net.IPNet) { + p.bypassNetworks = append(p.bypassNetworks, net) +} + +// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of +// "example.com" matches "example.com" and all of its subdomains. +func (p *PerHost) AddZone(zone string) { + if strings.HasSuffix(zone, ".") { + zone = zone[:len(zone)-1] + } + if !strings.HasPrefix(zone, ".") { + zone = "." + zone + } + p.bypassZones = append(p.bypassZones, zone) +} + +// AddHost specifies a host name that will use the bypass proxy. +func (p *PerHost) AddHost(host string) { + if strings.HasSuffix(host, ".") { + host = host[:len(host)-1] + } + p.bypassHosts = append(p.bypassHosts, host) +} diff --git a/vendor/golang.org/x/net/proxy/proxy.go b/vendor/golang.org/x/net/proxy/proxy.go new file mode 100644 index 000000000..553ead7cf --- /dev/null +++ b/vendor/golang.org/x/net/proxy/proxy.go @@ -0,0 +1,134 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package proxy provides support for a variety of protocols to proxy network +// data. +package proxy // import "golang.org/x/net/proxy" + +import ( + "errors" + "net" + "net/url" + "os" + "sync" +) + +// A Dialer is a means to establish a connection. +type Dialer interface { + // Dial connects to the given address via the proxy. + Dial(network, addr string) (c net.Conn, err error) +} + +// Auth contains authentication parameters that specific Dialers may require. +type Auth struct { + User, Password string +} + +// FromEnvironment returns the dialer specified by the proxy related variables in +// the environment. +func FromEnvironment() Dialer { + allProxy := allProxyEnv.Get() + if len(allProxy) == 0 { + return Direct + } + + proxyURL, err := url.Parse(allProxy) + if err != nil { + return Direct + } + proxy, err := FromURL(proxyURL, Direct) + if err != nil { + return Direct + } + + noProxy := noProxyEnv.Get() + if len(noProxy) == 0 { + return proxy + } + + perHost := NewPerHost(proxy, Direct) + perHost.AddFromString(noProxy) + return perHost +} + +// proxySchemes is a map from URL schemes to a function that creates a Dialer +// from a URL with such a scheme. +var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error) + +// RegisterDialerType takes a URL scheme and a function to generate Dialers from +// a URL with that scheme and a forwarding Dialer. Registered schemes are used +// by FromURL. +func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) { + if proxySchemes == nil { + proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) + } + proxySchemes[scheme] = f +} + +// FromURL returns a Dialer given a URL specification and an underlying +// Dialer for it to make network requests. +func FromURL(u *url.URL, forward Dialer) (Dialer, error) { + var auth *Auth + if u.User != nil { + auth = new(Auth) + auth.User = u.User.Username() + if p, ok := u.User.Password(); ok { + auth.Password = p + } + } + + switch u.Scheme { + case "socks5": + return SOCKS5("tcp", u.Host, auth, forward) + } + + // If the scheme doesn't match any of the built-in schemes, see if it + // was registered by another package. + if proxySchemes != nil { + if f, ok := proxySchemes[u.Scheme]; ok { + return f(u, forward) + } + } + + return nil, errors.New("proxy: unknown scheme: " + u.Scheme) +} + +var ( + allProxyEnv = &envOnce{ + names: []string{"ALL_PROXY", "all_proxy"}, + } + noProxyEnv = &envOnce{ + names: []string{"NO_PROXY", "no_proxy"}, + } +) + +// envOnce looks up an environment variable (optionally by multiple +// names) once. It mitigates expensive lookups on some platforms +// (e.g. Windows). +// (Borrowed from net/http/transport.go) +type envOnce struct { + names []string + once sync.Once + val string +} + +func (e *envOnce) Get() string { + e.once.Do(e.init) + return e.val +} + +func (e *envOnce) init() { + for _, n := range e.names { + e.val = os.Getenv(n) + if e.val != "" { + return + } + } +} + +// reset is used by tests +func (e *envOnce) reset() { + e.once = sync.Once{} + e.val = "" +} diff --git a/vendor/golang.org/x/net/proxy/socks5.go b/vendor/golang.org/x/net/proxy/socks5.go new file mode 100644 index 000000000..2d7978fe4 --- /dev/null +++ b/vendor/golang.org/x/net/proxy/socks5.go @@ -0,0 +1,214 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proxy + +import ( + "errors" + "io" + "net" + "strconv" +) + +// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address +// with an optional username and password. See RFC 1928 and 1929. +func SOCKS5(network, addr string, auth *Auth, forward Dialer) (Dialer, error) { + s := &socks5{ + network: network, + addr: addr, + forward: forward, + } + if auth != nil { + s.user = auth.User + s.password = auth.Password + } + + return s, nil +} + +type socks5 struct { + user, password string + network, addr string + forward Dialer +} + +const socks5Version = 5 + +const ( + socks5AuthNone = 0 + socks5AuthPassword = 2 +) + +const socks5Connect = 1 + +const ( + socks5IP4 = 1 + socks5Domain = 3 + socks5IP6 = 4 +) + +var socks5Errors = []string{ + "", + "general failure", + "connection forbidden", + "network unreachable", + "host unreachable", + "connection refused", + "TTL expired", + "command not supported", + "address type not supported", +} + +// Dial connects to the address addr on the network net via the SOCKS5 proxy. +func (s *socks5) Dial(network, addr string) (net.Conn, error) { + switch network { + case "tcp", "tcp6", "tcp4": + default: + return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) + } + + conn, err := s.forward.Dial(s.network, s.addr) + if err != nil { + return nil, err + } + if err := s.connect(conn, addr); err != nil { + conn.Close() + return nil, err + } + return conn, nil +} + +// connect takes an existing connection to a socks5 proxy server, +// and commands the server to extend that connection to target, +// which must be a canonical address with a host and port. +func (s *socks5) connect(conn net.Conn, target string) error { + host, portStr, err := net.SplitHostPort(target) + if err != nil { + return err + } + + port, err := strconv.Atoi(portStr) + if err != nil { + return errors.New("proxy: failed to parse port number: " + portStr) + } + if port < 1 || port > 0xffff { + return errors.New("proxy: port number out of range: " + portStr) + } + + // the size here is just an estimate + buf := make([]byte, 0, 6+len(host)) + + buf = append(buf, socks5Version) + if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { + buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword) + } else { + buf = append(buf, 1 /* num auth methods */, socks5AuthNone) + } + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + if buf[0] != 5 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + } + if buf[1] == 0xff { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + } + + // See RFC 1929 + if buf[1] == socks5AuthPassword { + buf = buf[:0] + buf = append(buf, 1 /* password protocol version */) + buf = append(buf, uint8(len(s.user))) + buf = append(buf, s.user...) + buf = append(buf, uint8(len(s.password))) + buf = append(buf, s.password...) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if buf[1] != 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + } + } + + buf = buf[:0] + buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */) + + if ip := net.ParseIP(host); ip != nil { + if ip4 := ip.To4(); ip4 != nil { + buf = append(buf, socks5IP4) + ip = ip4 + } else { + buf = append(buf, socks5IP6) + } + buf = append(buf, ip...) + } else { + if len(host) > 255 { + return errors.New("proxy: destination host name too long: " + host) + } + buf = append(buf, socks5Domain) + buf = append(buf, byte(len(host))) + buf = append(buf, host...) + } + buf = append(buf, byte(port>>8), byte(port)) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:4]); err != nil { + return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + failure := "unknown error" + if int(buf[1]) < len(socks5Errors) { + failure = socks5Errors[buf[1]] + } + + if len(failure) > 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + } + + bytesToDiscard := 0 + switch buf[3] { + case socks5IP4: + bytesToDiscard = net.IPv4len + case socks5IP6: + bytesToDiscard = net.IPv6len + case socks5Domain: + _, err := io.ReadFull(conn, buf[:1]) + if err != nil { + return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + bytesToDiscard = int(buf[0]) + default: + return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + } + + if cap(buf) < bytesToDiscard { + buf = make([]byte, bytesToDiscard) + } else { + buf = buf[:bytesToDiscard] + } + if _, err := io.ReadFull(conn, buf); err != nil { + return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + // Also need to discard the port number + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + return nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 9f046eeb9..1dac4f58a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1217,6 +1217,12 @@ "revision": "1c05540f6879653db88113bc4a2b70aec4bd491f", "revisionTime": "2017-08-04T00:04:37Z" }, + { + "checksumSHA1": "S4QRxs3K4notNO97Um4sA2IvHaM=", + "path": "golang.org/x/net/proxy", + "revision": "a04bdaca5b32abe1c069418fb7088ae607de5bd0", + "revisionTime": "2017-10-03T05:09:24Z" + }, { "checksumSHA1": "mktBVED98G2vv+OKcSgtnFVZC1Y=", "path": "golang.org/x/oauth2", diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 3d919e272..e6e8c3e90 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -104,6 +104,15 @@ The SSH communicator has the following options: - `ssh_username` (string) - The username to connect to SSH with. Required if using SSH. +- `ssh_proxy_host` (string) - A SOCKS proxy host to use for SSH connection + +- `ssh_proxy_port` (Integer) - A port of the SOCKS proxy, defaults to 1080 + +- `ssh_proxy_username` (string) - The username to authenticate with the proxy + server. Optional. + +- `ssh_proxy_password` (string) - The password to use to authenticate with + the proxy server. Optional. ## WinRM Communicator From 5866d4ea24ba3c38f7ceb9b8d42fef92a7152ddc Mon Sep 17 00:00:00 2001 From: localghost Date: Tue, 10 Oct 2017 22:45:47 +0200 Subject: [PATCH 0030/1007] Move container user inspect to StepConnectDocker. --- builder/docker/communicator.go | 73 +++++---------------------- builder/docker/communicator_test.go | 8 +-- builder/docker/config.go | 31 +++++++----- builder/docker/step_connect_docker.go | 33 ++++++++++-- 4 files changed, 63 insertions(+), 82 deletions(-) diff --git a/builder/docker/communicator.go b/builder/docker/communicator.go index bbfdb551f..d15143172 100644 --- a/builder/docker/communicator.go +++ b/builder/docker/communicator.go @@ -23,7 +23,7 @@ type Communicator struct { ContainerDir string Version *version.Version Config *Config - containerUser *string + ContainerUser string lock sync.Mutex } @@ -322,67 +322,22 @@ func (c *Communicator) run(cmd *exec.Cmd, remote *packer.RemoteCmd, stdin io.Wri // TODO Workaround for #5307. Remove once #5409 is fixed. func (c *Communicator) fixDestinationOwner(destination string) error { - if c.containerUser == nil { - containerUser, err := c.discoverContainerUser() - if err != nil { - return err - } - c.containerUser = &containerUser + if !c.Config.FixUploadOwner { + return nil } - if *c.containerUser != "" { - chownArgs := []string{ - "docker", "exec", "--user", "root", c.ContainerID, "/bin/sh", "-c", - fmt.Sprintf("chown -R %s %s", *c.containerUser, destination), - } - if _, err := c.runLocalCommand(chownArgs[0], chownArgs[1:]...); err != nil { - return fmt.Errorf("Failed to set owner of the uploaded file: %s", err) - } + owner := c.ContainerUser + if owner == "" { + owner = "root" + } + + chownArgs := []string{ + "docker", "exec", "--user", "root", c.ContainerID, "/bin/sh", "-c", + fmt.Sprintf("chown -R %s %s", owner, destination), + } + if output, err := exec.Command(chownArgs[0], chownArgs[1:]...).CombinedOutput(); err != nil { + return fmt.Errorf("Failed to set owner of the uploaded file: %s, %s", err, output) } return nil } - -func (c *Communicator) discoverContainerUser() (string, error) { - var err error - var stdout []byte - inspectArgs := []string{"docker", "inspect", "--format", "{{.Config.User}}", c.ContainerID} - if stdout, err = c.runLocalCommand(inspectArgs[0], inspectArgs[1:]...); err != nil { - return "", fmt.Errorf("Failed to inspect the container: %s", err) - } - return strings.TrimSpace(string(stdout)), nil -} - -func (c *Communicator) runLocalCommand(name string, arg ...string) (stdout []byte, err error) { - localCmd := exec.Command(name, arg...) - - stdoutP, err := localCmd.StdoutPipe() - if err != nil { - return nil, fmt.Errorf("failed to open stdout pipe, %s", err) - } - - stderrP, err := localCmd.StderrPipe() - if err != nil { - return nil, fmt.Errorf("failed to open stderr pipe, %s", err) - } - - if err = localCmd.Start(); err != nil { - return nil, fmt.Errorf("failed to start command, %s", err) - } - - stdout, err = ioutil.ReadAll(stdoutP) - if err != nil { - return nil, fmt.Errorf("failed to read from stdout pipe, %s", err) - } - - stderr, err := ioutil.ReadAll(stderrP) - if err != nil { - return nil, fmt.Errorf("failed to read from stderr pipe, %s", err) - } - - if err := localCmd.Wait(); err != nil { - return nil, fmt.Errorf("%s, %s", stderr, err) - } - - return stdout, nil -} diff --git a/builder/docker/communicator_test.go b/builder/docker/communicator_test.go index b5b5b1583..bdfaef996 100644 --- a/builder/docker/communicator_test.go +++ b/builder/docker/communicator_test.go @@ -209,12 +209,12 @@ func TestLargeDownload(t *testing.T) { } -// TestUploadOwner verifies that owner of uploaded files is the user the container is running as. -func TestUploadOwner(t *testing.T) { +// TestFixUploadOwner verifies that owner of uploaded files is the user the container is running as. +func TestFixUploadOwner(t *testing.T) { ui := packer.TestUi(t) cache := &packer.FileCache{CacheDir: os.TempDir()} - tpl, err := template.Parse(strings.NewReader(testUploadOwnerTemplate)) + tpl, err := template.Parse(strings.NewReader(testFixUploadOwnerTemplate)) if err != nil { t.Fatalf("Unable to parse config: %s", err) } @@ -346,7 +346,7 @@ const dockerLargeBuilderConfig = ` } ` -const testUploadOwnerTemplate = ` +const testFixUploadOwnerTemplate = ` { "builders": [ { diff --git a/builder/docker/config.go b/builder/docker/config.go index 89d28c290..fee08929d 100644 --- a/builder/docker/config.go +++ b/builder/docker/config.go @@ -23,20 +23,21 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` - Author string - Changes []string - Commit bool - ContainerDir string `mapstructure:"container_dir"` - Discard bool - ExecUser string `mapstructure:"exec_user"` - ExportPath string `mapstructure:"export_path"` - Image string - Message string - Privileged bool `mapstructure:"privileged"` - Pty bool - Pull bool - RunCommand []string `mapstructure:"run_command"` - Volumes map[string]string + Author string + Changes []string + Commit bool + ContainerDir string `mapstructure:"container_dir"` + Discard bool + ExecUser string `mapstructure:"exec_user"` + ExportPath string `mapstructure:"export_path"` + Image string + Message string + Privileged bool `mapstructure:"privileged"` + Pty bool + Pull bool + RunCommand []string `mapstructure:"run_command"` + Volumes map[string]string + FixUploadOwner bool `mapstructure:"fix_upload_owner"` // This is used to login to dockerhub to pull a private base container. For // pushing to dockerhub, see the docker post-processors @@ -54,6 +55,8 @@ type Config struct { func NewConfig(raws ...interface{}) (*Config, []string, error) { c := new(Config) + c.FixUploadOwner = true + var md mapstructure.Metadata err := config.Decode(c, &config.DecodeOpts{ Metadata: &md, diff --git a/builder/docker/step_connect_docker.go b/builder/docker/step_connect_docker.go index 7a947d500..45cf2d25d 100644 --- a/builder/docker/step_connect_docker.go +++ b/builder/docker/step_connect_docker.go @@ -1,7 +1,10 @@ package docker import ( + "fmt" "github.com/mitchellh/multistep" + "os/exec" + "strings" ) type StepConnectDocker struct{} @@ -19,14 +22,21 @@ func (s *StepConnectDocker) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } + containerUser, err := getContainerUser(containerId) + if err != nil { + state.Put("error", err) + return multistep.ActionHalt + } + // Create the communicator that talks to Docker via various // os/exec tricks. comm := &Communicator{ - ContainerID: containerId, - HostDir: tempDir, - ContainerDir: config.ContainerDir, - Version: version, - Config: config, + ContainerID: containerId, + HostDir: tempDir, + ContainerDir: config.ContainerDir, + Version: version, + Config: config, + ContainerUser: containerUser, } state.Put("communicator", comm) @@ -34,3 +44,16 @@ func (s *StepConnectDocker) Run(state multistep.StateBag) multistep.StepAction { } func (s *StepConnectDocker) Cleanup(state multistep.StateBag) {} + +func getContainerUser(containerId string) (string, error) { + inspectArgs := []string{"docker", "inspect", "--format", "{{.Config.User}}", containerId} + stdout, err := exec.Command(inspectArgs[0], inspectArgs[1:]...).Output() + if err != nil { + errStr := fmt.Sprintf("Failed to inspect the container: %s", err) + if ee, ok := err.(*exec.ExitError); ok { + errStr = fmt.Sprintf("%s, %s", errStr, ee.Stderr) + } + return "", fmt.Errorf(errStr) + } + return strings.TrimSpace(string(stdout)), nil +} From 6fd7f0877ddc2d94a2eb719f1701125c6191068c Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Sun, 12 Mar 2017 11:31:31 +0000 Subject: [PATCH 0031/1007] Initial check in to add a builder that can clone existing hyper v machines --- builder/hyperv/common/driver.go | 4 + builder/hyperv/common/driver_ps_4.go | 8 + builder/hyperv/common/step_clone_vm.go | 122 ++++++ builder/hyperv/vmcx/builder.go | 536 +++++++++++++++++++++++++ builder/hyperv/vmcx/builder_test.go | 250 ++++++++++++ common/powershell/hyperv/hyperv.go | 106 +++++ common/powershell/powershell.go | 55 +++ 7 files changed, 1081 insertions(+) create mode 100644 builder/hyperv/common/step_clone_vm.go create mode 100644 builder/hyperv/vmcx/builder.go create mode 100644 builder/hyperv/vmcx/builder_test.go diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index fce6da7df..07ab0f9fe 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -66,8 +66,12 @@ type Driver interface { CreateVirtualMachine(string, string, string, int64, int64, string, uint) error + CloneVirtualMachine(string, string, bool, string, string, int64, string) error + DeleteVirtualMachine(string) error + GetVirtualMachineGeneration(string) (uint, error) + SetVirtualMachineCpuCount(string, uint) error SetVirtualMachineMacSpoofing(string, bool) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index bcdb9ca53..4c45f9c5c 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -107,6 +107,10 @@ func (d *HypervPS4Driver) GetHostName(ip string) (string, error) { return powershell.GetHostName(ip) } +func (d *HypervPS4Driver) GetVirtualMachineGeneration(vmName string) (uint, error) { + return hyperv.GetVirtualMachineGeneration(vmName) +} + // Finds the IP address of a host adapter connected to switch func (d *HypervPS4Driver) GetHostAdapterIpAddressForSwitch(switchName string) (string, error) { res, err := hyperv.GetHostAdapterIpAddressForSwitch(switchName) @@ -170,6 +174,10 @@ func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, vhdPa return hyperv.CreateVirtualMachine(vmName, path, vhdPath, ram, diskSize, switchName, generation) } +func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, ram int64, switchName string) error { + return hyperv.CloneVirtualMachine(cloneFromVmName, cloneFromSnapshotName, cloneAllSnapshots, vmName, path, ram, switchName) +} + func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error { return hyperv.DeleteVirtualMachine(vmName) } diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go new file mode 100644 index 000000000..0159d2b9e --- /dev/null +++ b/builder/hyperv/common/step_clone_vm.go @@ -0,0 +1,122 @@ +package common + +import ( + "fmt" + + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" +) + +// This step clones an existing virtual machine. +// +// Produces: +// VMName string - The name of the VM +type StepCloneVM struct { + CloneFromVMName string + CloneFromSnapshotName string + CloneAllSnapshots bool + VMName string + SwitchName string + RamSize uint + Cpu uint + EnableMacSpoofing bool + EnableDynamicMemory bool + EnableSecureBoot bool + EnableVirtualizationExtensions bool +} + +func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { + driver := state.Get("driver").(Driver) + ui := state.Get("ui").(packer.Ui) + ui.Say("Creating virtual machine...") + + path := state.Get("packerTempDir").(string) + + // convert the MB to bytes + ramSize := int64(s.RamSize * 1024 * 1024) + + err := driver.CloneVirtualMachine(s.CloneFromVMName, s.CloneFromSnapshotName, s.CloneAllSnapshots, s.VMName, path, ramSize, s.SwitchName) + if err != nil { + err := fmt.Errorf("Error cloning virtual machine: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + err = driver.SetVirtualMachineCpuCount(s.VMName, s.Cpu) + if err != nil { + err := fmt.Errorf("Error creating setting virtual machine cpu: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if s.EnableDynamicMemory { + err = driver.SetVirtualMachineDynamicMemory(s.VMName, s.EnableDynamicMemory) + if err != nil { + err := fmt.Errorf("Error creating setting virtual machine dynamic memory: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + if s.EnableMacSpoofing { + err = driver.SetVirtualMachineMacSpoofing(s.VMName, s.EnableMacSpoofing) + if err != nil { + err := fmt.Errorf("Error creating setting virtual machine mac spoofing: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + generation, err := driver.GetVirtualMachineGeneration(s.VMName) + if err != nil { + err := fmt.Errorf("Error detecting vm generation: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if generation == 2 { + err = driver.SetVirtualMachineSecureBoot(s.VMName, s.EnableSecureBoot) + if err != nil { + err := fmt.Errorf("Error setting secure boot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + if s.EnableVirtualizationExtensions { + //This is only supported on Windows 10 and Windows Server 2016 onwards + err = driver.SetVirtualMachineVirtualizationExtensions(s.VMName, s.EnableVirtualizationExtensions) + if err != nil { + err := fmt.Errorf("Error creating setting virtual machine virtualization extensions: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + // Set the final name in the state bag so others can use it + state.Put("vmName", s.VMName) + + return multistep.ActionContinue +} + +func (s *StepCloneVM) Cleanup(state multistep.StateBag) { + if s.VMName == "" { + return + } + + driver := state.Get("driver").(Driver) + ui := state.Get("ui").(packer.Ui) + ui.Say("Unregistering and deleting virtual machine...") + + err := driver.DeleteVirtualMachine(s.VMName) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) + } +} diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go new file mode 100644 index 000000000..f46b0a976 --- /dev/null +++ b/builder/hyperv/vmcx/builder.go @@ -0,0 +1,536 @@ +package vmcx + +import ( + "errors" + "fmt" + "log" + "os" + "strings" + + "github.com/mitchellh/multistep" + hypervcommon "github.com/mitchellh/packer/builder/hyperv/common" + "github.com/mitchellh/packer/common" + powershell "github.com/mitchellh/packer/common/powershell" + "github.com/mitchellh/packer/common/powershell/hyperv" + "github.com/mitchellh/packer/helper/communicator" + "github.com/mitchellh/packer/helper/config" + "github.com/mitchellh/packer/packer" + "github.com/mitchellh/packer/template/interpolate" +) + +const ( + DefaultRamSize = 1 * 1024 // 1GB + MinRamSize = 32 // 32MB + MaxRamSize = 32 * 1024 // 32GB + MinNestedVirtualizationRamSize = 4 * 1024 // 4GB + + LowRam = 256 // 256MB + + DefaultUsername = "" + DefaultPassword = "" +) + +// Builder implements packer.Builder and builds the actual Hyperv +// images. +type Builder struct { + config Config + runner multistep.Runner +} + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` + common.ISOConfig `mapstructure:",squash"` + hypervcommon.FloppyConfig `mapstructure:",squash"` + hypervcommon.OutputConfig `mapstructure:",squash"` + hypervcommon.SSHConfig `mapstructure:",squash"` + hypervcommon.RunConfig `mapstructure:",squash"` + hypervcommon.ShutdownConfig `mapstructure:",squash"` + + // The size, in megabytes, of the computer memory in the VM. + // By default, this is 1024 (about 1 GB). + RamSize uint `mapstructure:"ram_size"` + // A list of files to place onto a floppy disk that is attached when the + // VM is booted. This is most useful for unattended Windows installs, + // which look for an Autounattend.xml file on removable media. By default, + // no floppy will be attached. All files listed in this setting get + // placed into the root directory of the floppy and the floppy is attached + // as the first floppy device. Currently, no support exists for creating + // sub-directories on the floppy. Wildcard characters (*, ?, and []) + // are allowed. Directory names are also allowed, which will add all + // the files found in the directory to the floppy. + FloppyFiles []string `mapstructure:"floppy_files"` + // + SecondaryDvdImages []string `mapstructure:"secondary_iso_images"` + + // Should integration services iso be mounted + GuestAdditionsMode string `mapstructure:"guest_additions_mode"` + + // The path to the integration services iso + GuestAdditionsPath string `mapstructure:"guest_additions_path"` + + // This is the name of the virtual machine to clone from. + CloneFromVMName string `mapstructure:"clone_from_vm_name"` + + // This is the name of the snapshot to clone from. A blank snapshot name will use the latest snapshot. + CloneFromSnapshotName string `mapstructure:"clone_from_snapshot_name"` + + // This will clone all snapshots if true. It will clone latest snapshot if false. + CloneAllSnapshots bool `mapstructure:"clone_all_snapshots"` + + // This is the name of the new virtual machine. + // By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. + VMName string `mapstructure:"vm_name"` + + BootCommand []string `mapstructure:"boot_command"` + SwitchName string `mapstructure:"switch_name"` + SwitchVlanId string `mapstructure:"switch_vlan_id"` + VlanId string `mapstructure:"vlan_id"` + Cpu uint `mapstructure:"cpu"` + Generation uint `mapstructure:"generation"` + EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` + EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` + EnableSecureBoot bool `mapstructure:"enable_secure_boot"` + EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` + + Communicator string `mapstructure:"communicator"` + + SkipCompaction bool `mapstructure:"skip_compaction"` + + ctx interpolate.Context +} + +// Prepare processes the build configuration parameters. +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + err := config.Decode(&b.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "boot_command", + }, + }, + }, raws...) + if err != nil { + return nil, err + } + + // Accumulate any errors and warnings + var errs *packer.MultiError + warnings := make([]string, 0) + + isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) + warnings = append(warnings, isoWarnings...) + errs = packer.MultiErrorAppend(errs, isoErrs...) + + errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) + errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) + + err = b.checkRamSize() + if err != nil { + errs = packer.MultiErrorAppend(errs, err) + } + + if b.config.VMName == "" { + b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName) + } + + log.Println(fmt.Sprintf("%s: %v", "VMName", b.config.VMName)) + + if b.config.SwitchName == "" { + b.config.SwitchName = b.detectSwitchName() + } + + if b.config.Cpu < 1 { + b.config.Cpu = 1 + } + + if b.config.Generation != 2 { + b.config.Generation = 1 + } + + if b.config.Generation == 2 { + if len(b.config.FloppyFiles) > 0 { + err = errors.New("Generation 2 vms don't support floppy drives. Use ISO image instead.") + errs = packer.MultiErrorAppend(errs, err) + } + } + + log.Println(fmt.Sprintf("Using switch %s", b.config.SwitchName)) + log.Println(fmt.Sprintf("%s: %v", "SwitchName", b.config.SwitchName)) + + // Errors + if b.config.GuestAdditionsMode == "" { + if b.config.GuestAdditionsPath != "" { + b.config.GuestAdditionsMode = "attach" + } else { + b.config.GuestAdditionsPath = os.Getenv("WINDIR") + "\\system32\\vmguest.iso" + + if _, err := os.Stat(b.config.GuestAdditionsPath); os.IsNotExist(err) { + if err != nil { + b.config.GuestAdditionsPath = "" + b.config.GuestAdditionsMode = "none" + } else { + b.config.GuestAdditionsMode = "attach" + } + } + } + } + + if b.config.GuestAdditionsPath == "" && b.config.GuestAdditionsMode == "attach" { + b.config.GuestAdditionsPath = os.Getenv("WINDIR") + "\\system32\\vmguest.iso" + + if _, err := os.Stat(b.config.GuestAdditionsPath); os.IsNotExist(err) { + if err != nil { + b.config.GuestAdditionsPath = "" + } + } + } + + for _, isoPath := range b.config.SecondaryDvdImages { + if _, err := os.Stat(isoPath); os.IsNotExist(err) { + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Secondary Dvd image does not exist: %s", err)) + } + } + } + + numberOfIsos := len(b.config.SecondaryDvdImages) + + if b.config.GuestAdditionsMode == "attach" { + if _, err := os.Stat(b.config.GuestAdditionsPath); os.IsNotExist(err) { + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Guest additions iso does not exist: %s", err)) + } + } + + numberOfIsos = numberOfIsos + 1 + } + + if b.config.Generation < 2 && numberOfIsos > 2 { + if b.config.GuestAdditionsMode == "attach" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("There are only 2 ide controllers available, so we can't support guest additions and these secondary dvds: %s", strings.Join(b.config.SecondaryDvdImages, ", "))) + } else { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("There are only 2 ide controllers available, so we can't support these secondary dvds: %s", strings.Join(b.config.SecondaryDvdImages, ", "))) + } + } else if b.config.Generation > 1 && len(b.config.SecondaryDvdImages) > 16 { + if b.config.GuestAdditionsMode == "attach" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("There are not enough drive letters available for scsi (limited to 16), so we can't support guest additions and these secondary dvds: %s", strings.Join(b.config.SecondaryDvdImages, ", "))) + } else { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("There are not enough drive letters available for scsi (limited to 16), so we can't support these secondary dvds: %s", strings.Join(b.config.SecondaryDvdImages, ", "))) + } + } + + if b.config.EnableVirtualizationExtensions { + hasVirtualMachineVirtualizationExtensions, err := powershell.HasVirtualMachineVirtualizationExtensions() + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting virtual machine virtualization extensions support: %s", err)) + } else { + if !hasVirtualMachineVirtualizationExtensions { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("This version of Hyper-V does not support virtual machine virtualization extension. Please use Windows 10 or Windows Server 2016 or newer.")) + } + } + } + + virtualMachineExists, err := powershell.DoesVirtualMachineExist(b.config.CloneFromVMName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine to clone from exists: %s", err)) + } else { + if !virtualMachineExists { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Virtual machine '%s' to clone from does not exist.", b.config.CloneFromVMName)) + } else { + if b.config.CloneFromSnapshotName != "" { + virtualMachineSnapshotExists, err := powershell.DoesVirtualMachineSnapshotExist(b.config.CloneFromVMName, b.config.CloneFromSnapshotName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine snapshot to clone from exists: %s", err)) + } else { + if !virtualMachineSnapshotExists { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Virtual machine snapshot '%s' on virtual machine '%s' to clone from does not exist.", b.config.CloneFromSnapshotName, b.config.CloneFromVMName)) + } + } + } + + virtualMachineOn, err := powershell.IsVirtualMachineOn(b.config.CloneFromVMName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine to clone is running: %s", err)) + } else { + if virtualMachineOn { + warning := fmt.Sprintf("Cloning from a virtual machine that is running.") + warnings = appendWarnings(warnings, warning) + } + } + } + } + + // Warnings + + if b.config.ShutdownCommand == "" { + warnings = appendWarnings(warnings, + "A shutdown_command was not specified. Without a shutdown command, Packer\n"+ + "will forcibly halt the virtual machine, which may result in data loss.") + } + + warning := b.checkHostAvailableMemory() + if warning != "" { + warnings = appendWarnings(warnings, warning) + } + + if b.config.EnableVirtualizationExtensions { + if b.config.EnableDynamicMemory { + warning = fmt.Sprintf("For nested virtualization, when virtualization extension is enabled, dynamic memory should not be allowed.") + warnings = appendWarnings(warnings, warning) + } + + if !b.config.EnableMacSpoofing { + warning = fmt.Sprintf("For nested virtualization, when virtualization extension is enabled, mac spoofing should be allowed.") + warnings = appendWarnings(warnings, warning) + } + + if b.config.RamSize < MinNestedVirtualizationRamSize { + warning = fmt.Sprintf("For nested virtualization, when virtualization extension is enabled, there should be 4GB or more memory set for the vm, otherwise Hyper-V may fail to start any nested VMs.") + warnings = appendWarnings(warnings, warning) + } + } + + if b.config.SwitchVlanId != "" { + if b.config.SwitchVlanId != b.config.VlanId { + warning = fmt.Sprintf("Switch network adaptor vlan should match virtual machine network adaptor vlan. The switch will not be able to see traffic from the VM.") + warnings = appendWarnings(warnings, warning) + } + } + + if errs != nil && len(errs.Errors) > 0 { + return warnings, errs + } + + return warnings, nil +} + +// Run executes a Packer build and returns a packer.Artifact representing +// a Hyperv appliance. +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + // Create the driver that we'll use to communicate with Hyperv + driver, err := hypervcommon.NewHypervPS4Driver() + if err != nil { + return nil, fmt.Errorf("Failed creating Hyper-V driver: %s", err) + } + + // Set up the state. + state := new(multistep.BasicStateBag) + state.Put("cache", cache) + 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{ + &hypervcommon.StepCreateTempDir{}, + &hypervcommon.StepOutputDir{ + Force: b.config.PackerForce, + Path: b.config.OutputDir, + }, + &common.StepDownload{ + Checksum: b.config.ISOChecksum, + ChecksumType: b.config.ISOChecksumType, + Description: "ISO", + ResultKey: "iso_path", + Url: b.config.ISOUrls, + Extension: b.config.TargetExtension, + TargetPath: b.config.TargetPath, + }, + &common.StepCreateFloppy{ + Files: b.config.FloppyFiles, + }, + &common.StepHTTPServer{ + HTTPDir: b.config.HTTPDir, + HTTPPortMin: b.config.HTTPPortMin, + HTTPPortMax: b.config.HTTPPortMax, + }, + &hypervcommon.StepCreateSwitch{ + SwitchName: b.config.SwitchName, + }, + &hypervcommon.StepCloneVM{ + CloneFromVMName: b.config.CloneFromVMName, + CloneFromSnapshotName: b.config.CloneFromSnapshotName, + CloneAllSnapshots: b.config.CloneAllSnapshots, + VMName: b.config.VMName, + SwitchName: b.config.SwitchName, + RamSize: b.config.RamSize, + Cpu: b.config.Cpu, + EnableMacSpoofing: b.config.EnableMacSpoofing, + EnableDynamicMemory: b.config.EnableDynamicMemory, + EnableSecureBoot: b.config.EnableSecureBoot, + EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, + }, + + &hypervcommon.StepEnableIntegrationService{}, + + &hypervcommon.StepMountDvdDrive{ + Generation: b.config.Generation, + }, + &hypervcommon.StepMountFloppydrive{ + Generation: b.config.Generation, + }, + + &hypervcommon.StepMountGuestAdditions{ + GuestAdditionsMode: b.config.GuestAdditionsMode, + GuestAdditionsPath: b.config.GuestAdditionsPath, + Generation: b.config.Generation, + }, + + &hypervcommon.StepMountSecondaryDvdImages{ + IsoPaths: b.config.SecondaryDvdImages, + Generation: b.config.Generation, + }, + + &hypervcommon.StepConfigureVlan{ + VlanId: b.config.VlanId, + SwitchVlanId: b.config.SwitchVlanId, + }, + + &hypervcommon.StepRun{ + BootWait: b.config.BootWait, + }, + + &hypervcommon.StepTypeBootCommand{ + BootCommand: b.config.BootCommand, + SwitchName: b.config.SwitchName, + Ctx: b.config.ctx, + }, + + // configure the communicator ssh, winrm + &communicator.StepConnect{ + Config: &b.config.SSHConfig.Comm, + Host: hypervcommon.CommHost, + SSHConfig: hypervcommon.SSHConfigFunc(&b.config.SSHConfig), + }, + + // provision requires communicator to be setup + &common.StepProvision{}, + + &hypervcommon.StepShutdown{ + Command: b.config.ShutdownCommand, + Timeout: b.config.ShutdownTimeout, + }, + + // wait for the vm to be powered off + &hypervcommon.StepWaitForPowerOff{}, + + // remove the secondary dvd images + // after we power down + &hypervcommon.StepUnmountSecondaryDvdImages{}, + &hypervcommon.StepUnmountGuestAdditions{}, + &hypervcommon.StepUnmountDvdDrive{}, + &hypervcommon.StepUnmountFloppyDrive{ + Generation: b.config.Generation, + }, + &hypervcommon.StepExportVm{ + OutputDir: b.config.OutputDir, + SkipCompaction: b.config.SkipCompaction, + }, + + // the clean up actions for each step will be executed reverse order + } + + // Run the steps. + if b.config.PackerDebug { + pauseFn := common.MultistepDebugFn(ui) + state.Put("pauseFn", pauseFn) + b.runner = &multistep.DebugRunner{ + Steps: steps, + PauseFn: pauseFn, + } + } else { + b.runner = &multistep.BasicRunner{Steps: steps} + } + + b.runner.Run(state) + + // Report any errors. + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + // If we were interrupted or cancelled, then just exit. + if _, ok := state.GetOk(multistep.StateCancelled); ok { + return nil, errors.New("Build was cancelled.") + } + + if _, ok := state.GetOk(multistep.StateHalted); ok { + return nil, errors.New("Build was halted.") + } + + return hypervcommon.NewArtifact(b.config.OutputDir) +} + +// Cancel. +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} + +func appendWarnings(slice []string, data ...string) []string { + m := len(slice) + n := m + len(data) + if n > cap(slice) { // if necessary, reallocate + // allocate double what's needed, for future growth. + newSlice := make([]string, (n+1)*2) + copy(newSlice, slice) + slice = newSlice + } + slice = slice[0:n] + copy(slice[m:n], data) + return slice +} + +func (b *Builder) checkRamSize() error { + if b.config.RamSize == 0 { + b.config.RamSize = DefaultRamSize + } + + log.Println(fmt.Sprintf("%s: %v", "RamSize", b.config.RamSize)) + + if b.config.RamSize < MinRamSize { + return fmt.Errorf("ram_size: Virtual machine requires memory size >= %v MB, but defined: %v", MinRamSize, b.config.RamSize) + } else if b.config.RamSize > MaxRamSize { + return fmt.Errorf("ram_size: Virtual machine requires memory size <= %v MB, but defined: %v", MaxRamSize, b.config.RamSize) + } + + return nil +} + +func (b *Builder) checkHostAvailableMemory() string { + powershellAvailable, _, _ := powershell.IsPowershellAvailable() + + if powershellAvailable { + freeMB := powershell.GetHostAvailableMemory() + + if (freeMB - float64(b.config.RamSize)) < LowRam { + return fmt.Sprintf("Hyper-V might fail to create a VM if there is not enough free memory in the system.") + } + } + + return "" +} + +func (b *Builder) detectSwitchName() string { + powershellAvailable, _, _ := powershell.IsPowershellAvailable() + + if powershellAvailable { + // no switch name, try to get one attached to a online network adapter + onlineSwitchName, err := hyperv.GetExternalOnlineVirtualSwitch() + if onlineSwitchName != "" && err == nil { + return onlineSwitchName + } + } + + return fmt.Sprintf("packer-%s", b.config.PackerBuildName) +} diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go new file mode 100644 index 000000000..c2ea23c14 --- /dev/null +++ b/builder/hyperv/vmcx/builder_test.go @@ -0,0 +1,250 @@ +package vmcx + +import ( + "reflect" + "testing" + + "github.com/mitchellh/packer/packer" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "iso_checksum": "foo", + "iso_checksum_type": "md5", + "iso_url": "http://www.packer.io", + "shutdown_command": "yes", + "ssh_username": "foo", + "ram_size": 64, + "disk_size": 256, + "guest_additions_mode": "none", + packer.BuildNameConfigKey: "foo", + } +} + +func TestBuilder_ImplementsBuilder(t *testing.T) { + var raw interface{} + raw = &Builder{} + if _, ok := raw.(packer.Builder); !ok { + t.Error("Builder must implement builder.") + } +} + +func TestBuilderPrepare_Defaults(t *testing.T) { + var b Builder + config := testConfig() + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.VMName != "packer-foo" { + t.Errorf("bad vm name: %s", b.config.VMName) + } +} + +func TestBuilderPrepare_DiskSize(t *testing.T) { + var b Builder + config := testConfig() + + delete(config, "disk_size") + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("bad err: %s", err) + } + + if b.config.DiskSize != 40*1024 { + t.Fatalf("bad size: %d", b.config.DiskSize) + } + + config["disk_size"] = 256 + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.DiskSize != 256 { + t.Fatalf("bad size: %d", b.config.DiskSize) + } +} + +func TestBuilderPrepare_InvalidKey(t *testing.T) { + var b Builder + config := testConfig() + + // Add a random key + config["i_should_not_be_valid"] = true + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_ISOChecksum(t *testing.T) { + var b Builder + config := testConfig() + + // Test bad + config["iso_checksum"] = "" + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Test good + config["iso_checksum"] = "FOo" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.ISOChecksum != "foo" { + t.Fatalf("should've lowercased: %s", b.config.ISOChecksum) + } +} + +func TestBuilderPrepare_ISOChecksumType(t *testing.T) { + var b Builder + config := testConfig() + + // Test bad + config["iso_checksum_type"] = "" + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Test good + config["iso_checksum_type"] = "mD5" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.ISOChecksumType != "md5" { + t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType) + } + + // Test unknown + config["iso_checksum_type"] = "fake" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Test none + config["iso_checksum_type"] = "none" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) == 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.ISOChecksumType != "none" { + t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType) + } +} + +func TestBuilderPrepare_ISOUrl(t *testing.T) { + var b Builder + config := testConfig() + delete(config, "iso_url") + delete(config, "iso_urls") + + // Test both epty + config["iso_url"] = "" + b = Builder{} + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Test iso_url set + config["iso_url"] = "http://www.packer.io" + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Errorf("should not have error: %s", err) + } + + expected := []string{"http://www.packer.io"} + if !reflect.DeepEqual(b.config.ISOUrls, expected) { + t.Fatalf("bad: %#v", b.config.ISOUrls) + } + + // Test both set + config["iso_url"] = "http://www.packer.io" + config["iso_urls"] = []string{"http://www.packer.io"} + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } + + // Test just iso_urls set + delete(config, "iso_url") + config["iso_urls"] = []string{ + "http://www.packer.io", + "http://www.hashicorp.com", + } + + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Errorf("should not have error: %s", err) + } + + expected = []string{ + "http://www.packer.io", + "http://www.hashicorp.com", + } + if !reflect.DeepEqual(b.config.ISOUrls, expected) { + t.Fatalf("bad: %#v", b.config.ISOUrls) + } +} diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 6ea4d1903..461d4120a 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -234,6 +234,112 @@ if ((Get-Command Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { return err } +func DisableAutomaticCheckpoints(vmName string) error { + var script = ` +param([string]$vmName) +if ((Get-Command Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { + Set-Vm -Name $vmName -AutomaticCheckpointsEnabled $false } +` + var ps powershell.PowerShellCmd + err := ps.Run(script, vmName) + return err +} + +func CloneVirtualMachine(cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, ram int64, switchName string) error { + + var script = ` +param([string]$CloneFromVMName, [string]$CloneFromSnapshotName, [string]CloneAllSnapshotsString, [string]$vmName, [string]$path, [long]$memoryStartupBytes, [string]$switchName) + +$CloneAllSnapshots = [System.Boolean]::Parse($CloneAllSnapshotsString) + +$ExportPath = Join-Path $path $VMName + +if ($CloneFromSnapshotName) { + $snapshot = Get-VMSnapshot -VMName $CloneFromVMName -Name $CloneFromSnapshotName + Export-VMSnapshot -VMSnapshot $snapshot -Path $ExportPath -ErrorAction Stop +} else { + if (!$CloneAllSnapshots) { + #Use last snapshot if one was not specified + $snapshot = Get-VMSnapshot -VMName $CloneFromVMName | Select -Last 1 + } else { + $snapshot = $null + } + + if (!$snapshot) { + #No snapshot clone + Export-VM -Name $CloneFromVMName -Path $ExportPath -ErrorAction Stop + } else { + #Snapshot clone + Export-VMSnapshot -VMSnapshot $snapshot -Path $ExportPath -ErrorAction Stop + } +} + +$result = Get-ChildItem -Path (Join-Path $ExportPath $CloneFromVMName) | Move-Item -Destination $ExportPath -Force +$result = Remove-Item -Path (Join-Path $ExportPath $CloneFromVMName) + +$VirtualMachinePath = Get-ChildItem -Path (Join-Path $ExportPath 'Virtual Machines') -Filter *.vmcx -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} +if (!$VirtualMachinePath){ + $VirtualMachinePath = Get-ChildItem -Path (Join-Path $ExportPath 'Virtual Machines') -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} +} +if (!$VirtualMachinePath){ + $VirtualMachinePath = Get-ChildItem -Path $ExportPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} +} + +$compatibilityReport = Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $ExportPath -SmartPagingFilePath $ExportPath -SnapshotFilePath $ExportPath -VhdDestinationPath (Join-Path -Path $ExportPath -ChildPath 'Virtual Hard Disks') -GenerateNewId -Copy:$false +Set-VMMemory -VM $compatibilityReport.VM -StartupBytes $memoryStartupBytes +$networkAdaptor = $compatibilityReport.VM.NetworkAdapters | Select -First 1 +Disconnect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor +Connect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -SwitchName $switchName +$vm = Import-VM -CompatibilityReport $compatibilityReport + +if ($vm) { + $result = Rename-VM -VM $vm -NewName $VMName +} +` + + CloneAllSnapshotsString := "False" + if cloneAllSnapshots { + CloneAllSnapshotsString = "True" + } + + var ps powershell.PowerShellCmd + err := ps.Run(script, cloneFromVmName, cloneFromSnapshotName, CloneAllSnapshotsString, vmName, path, strconv.FormatInt(ram, 10), switchName) + + if err != nil { + return err + } + + return DeleteAllDvdDrives(vmName) + +} + +func GetVirtualMachineGeneration(vmName string) (uint, error) { + var script = ` +param([string]$vmName) +$generation = Get-Vm -Name $vmName | %{$_.Generation} +if (!$generation){ + $generation = 1 +} +return $generation +` + var ps powershell.PowerShellCmd + cmdOut, err := ps.Output(script, vmName) + + if err != nil { + return 0, err + } + + generationUint32, err := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 32) + + if err != nil { + return 0, err + } + + generation := uint(generationUint32) + + return generation, err +} + func SetVirtualMachineCpuCount(vmName string, cpu uint) error { var script = ` diff --git a/common/powershell/powershell.go b/common/powershell/powershell.go index 83190d1a4..9927ffaea 100644 --- a/common/powershell/powershell.go +++ b/common/powershell/powershell.go @@ -246,6 +246,61 @@ func HasVirtualMachineVirtualizationExtensions() (bool, error) { return hasVirtualMachineVirtualizationExtensions, err } +func DoesVirtualMachineExist(vmName string) (bool, error) { + + var script = ` +param([string]$vmName) +return (Get-VM | ?{$_.Name -eq $vmName}) -ne $null +` + + var ps PowerShellCmd + cmdOut, err := ps.Output(script, vmName) + + if err != nil { + return false, err + } + + var exists = strings.TrimSpace(cmdOut) == "True" + return exists, err +} + +func DoesVirtualMachineSnapshotExist(vmName string, snapshotName string) (bool, error) { + + var script = ` +param([string]$vmName, [string]$snapshotName) +return (Get-VMSnapshot -VMName $vmName | ?{$_.Name -eq $snapshotName}) -ne $null +` + + var ps PowerShellCmd + cmdOut, err := ps.Output(script, vmName, snapshotName) + + if err != nil { + return false, err + } + + var exists = strings.TrimSpace(cmdOut) == "True" + return exists, err +} + +func IsVirtualMachineOn(vmName string) (bool, error) { + + var script = ` +param([string]$vmName) +$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running +` + + var ps PowerShellCmd + cmdOut, err := ps.Output(script, vmName) + + if err != nil { + return false, err + } + + var isRunning = strings.TrimSpace(cmdOut) == "True" + return isRunning, err +} + func SetUnattendedProductKey(path string, productKey string) error { var script = ` From 429e1bc3adfefc025510ae6b619e94c6a8884733 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Sun, 12 Mar 2017 17:31:56 +0000 Subject: [PATCH 0032/1007] Adding an ISO is now optional for hyperv vmcx Add documentation for hyperv vmcx --- builder/hyperv/vmcx/builder.go | 89 +- common/powershell/powershell.go | 27 + .../source/docs/builders/hyperv-vmcx.html.md | 985 ++++++++++++++++++ website/source/docs/builders/hyperv.html.md | 7 +- 4 files changed, 1068 insertions(+), 40 deletions(-) create mode 100644 website/source/docs/builders/hyperv-vmcx.html.md diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index f46b0a976..791c9ae46 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -87,11 +87,11 @@ type Config struct { SwitchVlanId string `mapstructure:"switch_vlan_id"` VlanId string `mapstructure:"vlan_id"` Cpu uint `mapstructure:"cpu"` - Generation uint `mapstructure:"generation"` - EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` - EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` - EnableSecureBoot bool `mapstructure:"enable_secure_boot"` - EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` + Generation uint + EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` + EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` + EnableSecureBoot bool `mapstructure:"enable_secure_boot"` + EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` Communicator string `mapstructure:"communicator"` @@ -118,9 +118,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { var errs *packer.MultiError warnings := make([]string, 0) - isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) - warnings = append(warnings, isoWarnings...) - errs = packer.MultiErrorAppend(errs, isoErrs...) + if b.config.RawSingleISOUrl != "" || len(b.config.ISOUrls) > 0 { + isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) + warnings = append(warnings, isoWarnings...) + errs = packer.MultiErrorAppend(errs, isoErrs...) + } errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) @@ -148,6 +150,47 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.Cpu = 1 } + b.config.Generation = 1 + + if b.config.CloneFromVMName == "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("The clone_from_vm_name must be specified.")) + } else { + virtualMachineExists, err := powershell.DoesVirtualMachineExist(b.config.CloneFromVMName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine to clone from exists: %s", err)) + } else { + if !virtualMachineExists { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Virtual machine '%s' to clone from does not exist.", b.config.CloneFromVMName)) + } else { + b.config.Generation, err = powershell.GetVirtualMachineGeneration(b.config.CloneFromVMName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting virtual machine to clone from generation: %s", err)) + } + + if b.config.CloneFromSnapshotName != "" { + virtualMachineSnapshotExists, err := powershell.DoesVirtualMachineSnapshotExist(b.config.CloneFromVMName, b.config.CloneFromSnapshotName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine snapshot to clone from exists: %s", err)) + } else { + if !virtualMachineSnapshotExists { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Virtual machine snapshot '%s' on virtual machine '%s' to clone from does not exist.", b.config.CloneFromSnapshotName, b.config.CloneFromVMName)) + } + } + } + + virtualMachineOn, err := powershell.IsVirtualMachineOn(b.config.CloneFromVMName) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine to clone is running: %s", err)) + } else { + if virtualMachineOn { + warning := fmt.Sprintf("Cloning from a virtual machine that is running.") + warnings = appendWarnings(warnings, warning) + } + } + } + } + } + if b.config.Generation != 2 { b.config.Generation = 1 } @@ -237,36 +280,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } - virtualMachineExists, err := powershell.DoesVirtualMachineExist(b.config.CloneFromVMName) - if err != nil { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine to clone from exists: %s", err)) - } else { - if !virtualMachineExists { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Virtual machine '%s' to clone from does not exist.", b.config.CloneFromVMName)) - } else { - if b.config.CloneFromSnapshotName != "" { - virtualMachineSnapshotExists, err := powershell.DoesVirtualMachineSnapshotExist(b.config.CloneFromVMName, b.config.CloneFromSnapshotName) - if err != nil { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine snapshot to clone from exists: %s", err)) - } else { - if !virtualMachineSnapshotExists { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Virtual machine snapshot '%s' on virtual machine '%s' to clone from does not exist.", b.config.CloneFromSnapshotName, b.config.CloneFromVMName)) - } - } - } - - virtualMachineOn, err := powershell.IsVirtualMachineOn(b.config.CloneFromVMName) - if err != nil { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed detecting if virtual machine to clone is running: %s", err)) - } else { - if virtualMachineOn { - warning := fmt.Sprintf("Cloning from a virtual machine that is running.") - warnings = appendWarnings(warnings, warning) - } - } - } - } - // Warnings if b.config.ShutdownCommand == "" { diff --git a/common/powershell/powershell.go b/common/powershell/powershell.go index 9927ffaea..a41915474 100644 --- a/common/powershell/powershell.go +++ b/common/powershell/powershell.go @@ -301,6 +301,33 @@ $vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running return isRunning, err } +func GetVirtualMachineGeneration(vmName string) (uint, error) { + var script = ` +param([string]$vmName) +$generation = Get-Vm -Name $vmName | %{$_.Generation} +if (!$generation){ + $generation = 1 +} +return $generation +` + var ps PowerShellCmd + cmdOut, err := ps.Output(script, vmName) + + if err != nil { + return 0, err + } + + generationUint32, err := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 32) + + if err != nil { + return 0, err + } + + generation := uint(generationUint32) + + return generation, err +} + func SetUnattendedProductKey(path string, productKey string) error { var script = ` diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md new file mode 100644 index 000000000..c2aa3c539 --- /dev/null +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -0,0 +1,985 @@ +--- +description: |- + The Hyper-V Packer builder is able to clone an existing Hyper-V virtual machine and export them. +layout: "docs" +page_title: "Hyper-V Builder (from an vmcx)" +--- + +# Hyper-V Builder (from a vmcx) + +Type: `hyperv-vmcx` + +The Hyper-V Packer builder is able to clone [Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) +virtual machines and export them. + +The builder clones an existing virtual machine boots it, and provisioning software within +the OS, then shutting it down. The result of the Hyper-V builder is a directory +containing all the files necessary to run the virtual machine portably. + +## Basic Example + +Here is a basic example. This example is not functional. It will start the +OS installer but then fail because we don't provide the preseed file for +Ubuntu to self-install. Still, the example serves to show the basic configuration: + +```javascript +{ + "type": "hyperv-vmcx", + "clone_from_vm_name": "ubuntu-12.04.5-server-amd64", + "ssh_username": "packer", + "ssh_password": "packer", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" +} +``` + +It is important to add a `shutdown_command`. By default Packer halts the +virtual machine and the file system may not be sync'd. Thus, changes made in a +provisioner might not be saved. + +## Configuration Reference + +There are many configuration options available for the Hyper-V builder. +They are organized below into two categories: required and optional. Within +each category, the available options are alphabetized and described. + +In addition to the options listed here, a +[communicator](/docs/templates/communicator.html) +can be configured for this builder. + +### Required: +- `clone_from_vm_name` (string) - The name of the vm to clone from. + Ideally the machine to clone from should be shutdown. + +### Optional: +- `clone_from_snapshot_name` (string) - The name of the snapshot + +- `clone_all_snapshots` (boolean) - Should all snapshots be cloned + when the machine is cloned. + +- `boot_command` (array of strings) - This is an array of commands to type + when the virtual machine is first booted. The goal of these commands should + be to type just enough to initialize the operating system installer. Special + keys can be typed as well, and are covered in the section below on the boot + command. If this is not specified, it is assumed the installer will start + itself. + +- `boot_wait` (string) - The time to wait after booting the initial virtual + machine before typing the `boot_command`. The value of this should be + a duration. Examples are "5s" and "1m30s" which will cause Packer to wait + five seconds and one minute 30 seconds, respectively. If this isn't specified, + the default is 10 seconds. + +- `cpu` (integer) - The number of cpus the virtual machine should use. If this isn't specified, + the default is 1 cpu. + +- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual machine. + This defaults to false. + +- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual machine. + This defaults to false. + +- `enable_secure_boot` (bool) - If true enable secure boot for virtual machine. + This defaults to false. + +- `enable_virtualization_extensions` (bool) - If true enable virtualization extensions for virtual machine. + This defaults to false. For nested virtualization you need to enable mac spoofing, disable dynamic memory + and have at least 4GB of RAM for virtual machine. + +- `floppy_files` (array of strings) - A list of files to place onto a floppy + disk that is attached when the VM is booted. This is most useful + for unattended Windows installs, which look for an `Autounattend.xml` file + on removable media. By default, no floppy will be attached. All files + listed in this setting get placed into the root directory of the floppy + and the floppy is attached as the first floppy device. Currently, no + support exists for creating sub-directories on the floppy. Wildcard + characters (*, ?, and []) are allowed. Directory names are also allowed, + which will add all the files found in the directory to the floppy. + +- `guest_additions_mode` (string) - How should guest additions be installed. + If value `attach` then attach iso image with by specified by `guest_additions_path`. + Otherwise guest additions is not installed. + +- `guest_additions_path` (string) - The path to the iso image for guest additions. + +- `http_directory` (string) - Path to a directory to serve using an HTTP + server. The files in this directory will be available over HTTP that will + be requestable from the virtual machine. This is useful for hosting + kickstart files and so on. By default this is "", which means no HTTP + server will be started. The address and port of the HTTP server will be + available as variables in `boot_command`. This is covered in more detail + below. + +- `http_port_min` and `http_port_max` (integer) - These are the minimum and + maximum port to use for the HTTP server started to serve the `http_directory`. + Because Packer often runs in parallel, Packer will choose a randomly available + port in this range to run the HTTP server. If you want to force the HTTP + server to be on one port, make this minimum and maximum port the same. + By default the values are 8000 and 9000, respectively. + +- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO + files are so large, this is required and Packer will verify it prior + to booting a virtual machine with the ISO attached. The type of the + checksum is specified with `iso_checksum_type`, documented below. + +- `iso_checksum_type` (string) - The type of the checksum specified in + `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or + "sha512" currently. While "none" will skip checksumming, this is not + recommended since ISO files are generally large and corruption does happen + from time to time. + +- `iso_url` (string) - A URL to the ISO containing the installation image. + This URL can be either an HTTP URL or a file URL (or path to a file). + If this is an HTTP URL, Packer will download iso and cache it between + runs. + +- `iso_urls` (array of strings) - Multiple URLs for the ISO to download. + Packer will try these in order. If anything goes wrong attempting to download + or while downloading a single URL, it will move on to the next. All URLs + must point to the same file (same checksum). By default this is empty + and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified. + +- `iso_target_extension` (string) - The extension of the iso file after + download. This defaults to "iso". + +- `iso_target_path` (string) - The path where the iso should be saved after + download. By default will go in the packer cache, with a hash of the + original filename as its name. + +- `output_directory` (string) - This is the path to the directory where the + resulting virtual machine will be created. This may be relative or absolute. + If relative, the path is relative to the working directory when `packer` + is executed. This directory must not exist or be empty prior to running the builder. + By default this is "output-BUILDNAME" where "BUILDNAME" is the name + of the build. + +- `ram_size` (integer) - The size, in megabytes, of the ram to create + for the VM. By default, this is 1 GB. + +* `secondary_iso_images` (array of strings) - A list of iso paths to attached to a + VM when it is booted. This is most useful for unattended Windows installs, which + look for an `Autounattend.xml` file on removable media. By default, no + secondary iso will be attached. + +- `shutdown_command` (string) - The command to use to gracefully shut down the machine once all + the provisioning is done. By default this is an empty string, which tells Packer to just + forcefully shut down the machine unless a shutdown command takes place inside script so this may + safely be omitted. If one or more scripts require a reboot it is suggested to leave this blank + since reboots may fail and specify the final shutdown command in your last script. + +- `shutdown_timeout` (string) - The amount of time to wait after executing + the `shutdown_command` for the virtual machine to actually shut down. + If it doesn't shut down in this time, it is an error. By default, the timeout + is "5m", or five minutes. + +- `skip_compaction` (bool) - If true skip compacting the hard disk for virtual machine when + exporting. This defaults to false. + +- `switch_name` (string) - The name of the switch to connect the virtual machine to. Be defaulting + this to an empty string, Packer will try to determine the switch to use by looking for + external switch that is up and running. + +- `switch_vlan_id` (string) - This is the vlan of the virtual switch's network card. + By default none is set. If none is set then a vlan is not set on the switch's network card. + If this value is set it should match the vlan specified in by `vlan_id`. + +- `vlan_id` (string) - This is the vlan of the virtual machine's network card for the new virtual + machine. By default none is set. If none is set then vlans are not set on the virtual machine's + network card. + +- `vm_name` (string) - This is the name of the virtual machine for the new virtual + machine, without the file extension. By default this is "packer-BUILDNAME", + where "BUILDNAME" is the name of the build. + +## Boot Command + +The `boot_command` configuration is very important: it specifies the keys +to type when the virtual machine is first booted in order to start the +OS installer. This command is typed after `boot_wait`, which gives the +virtual machine some time to actually load the ISO. + +As documented above, the `boot_command` is an array of strings. The +strings are all typed in sequence. It is an array only to improve readability +within the template. + +The boot command is "typed" character for character over the virtual keyboard +to the machine, simulating a human actually typing the keyboard. There are +a set of special keys available. If these are in your boot command, they +will be replaced by the proper key: + +- `` - Backspace + +- `` - Delete + +- `` and `` - Simulates an actual "enter" or "return" keypress. + +- `` - Simulates pressing the escape key. + +- `` - Simulates pressing the tab key. + +- `` - `` - Simulates pressing a function key. + +- `` `` `` `` - Simulates pressing an arrow key. + +- `` - Simulates pressing the spacebar. + +- `` - Simulates pressing the insert key. + +- `` `` - Simulates pressing the home and end keys. + +- `` `` - Simulates pressing the page up and page down keys. + +- `` `` - Simulates pressing the alt key. + +- `` `` - Simulates pressing the ctrl key. + +- `` `` - Simulates pressing the shift key. + +- `` `` - Simulates pressing and holding the alt key. + +- `` `` - Simulates pressing and holding the ctrl key. + +- `` `` - Simulates pressing and holding the shift key. + +- `` `` - Simulates releasing a held alt key. + +- `` `` - Simulates releasing a held ctrl key. + +- `` `` - Simulates releasing a held shift key. + +- `` `` `` - Adds a 1, 5 or 10 second pause before + sending any additional keys. This is useful if you have to generally wait + for the UI to update before typing more. + +When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, otherwise they will be held down until the machine reboots. Use lowercase characters as well inside modifiers. For example: to simulate ctrl+c use `c`. + +In addition to the special keys, each command to type is treated as a +[configuration template](/docs/templates/configuration-templates.html). +The available variables are: + +* `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server + that is started serving the directory specified by the `http_directory` + configuration parameter. If `http_directory` isn't specified, these will + be blank! + +Example boot command. This is actually a working boot command used to start +an Ubuntu 12.04 installer: + +```text +[ + "", + "/install/vmlinuz noapic ", + "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{ .Name }} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false ", + "initrd=/install/initrd.gz -- " +] +``` + +## Integration Services + +Packer will automatically attach the integration services iso as a dvd drive +for the version of Hyper-V that is running. + +## Generation 1 vs Generation 2 + +Floppy drives are no longer supported by generation 2 machines. This requires you to +take another approach when dealing with preseed or answer files. Two possible options +are using virtual dvd drives or using the built in web server. + +When dealing with Windows you need to enable UEFI drives for generation 2 virtual machines. + +## Creating iso from directory + +Programs like mkisofs can be used to create an iso from a directory. +There is a [windows version of mkisofs](http://opensourcepack.blogspot.co.uk/p/cdrtools.html). + +Example powershell script. This is an actually working powershell script used to create a Windows answer iso: + +```text +$isoFolder = "answer-iso" +if (test-path $isoFolder){ + remove-item $isoFolder -Force -Recurse +} + +if (test-path windows\windows-2012R2-serverdatacenter-amd64\answer.iso){ + remove-item windows\windows-2012R2-serverdatacenter-amd64\answer.iso -Force +} + +mkdir $isoFolder + +copy windows\windows-2012R2-serverdatacenter-amd64\Autounattend.xml $isoFolder\ +copy windows\windows-2012R2-serverdatacenter-amd64\sysprep-unattend.xml $isoFolder\ +copy windows\common\set-power-config.ps1 $isoFolder\ +copy windows\common\microsoft-updates.ps1 $isoFolder\ +copy windows\common\win-updates.ps1 $isoFolder\ +copy windows\common\run-sysprep.ps1 $isoFolder\ +copy windows\common\run-sysprep.cmd $isoFolder\ + +$textFile = "$isoFolder\Autounattend.xml" + +$c = Get-Content -Encoding UTF8 $textFile + +# Enable UEFI and disable Non EUFI +$c | % { $_ -replace '','','Finish Non UEFI -->' } | % { $_ -replace '' } | % { $_ -replace 'Finish UEFI compatible -->','' } | sc -Path $textFile + +& .\mkisofs.exe -r -iso-level 4 -UDF -o windows\windows-2012R2-serverdatacenter-amd64\answer.iso $isoFolder + +if (test-path $isoFolder){ + remove-item $isoFolder -Force -Recurse +} +``` + + +## Example For Windows Server 2012 R2 Generation 2 + +Packer config: + +```javascript +{ + "builders": [ + { + "vm_name":"windows2012r2", + "type": "hyperv-iso", + "disk_size": 61440, + "floppy_files": [], + "secondary_iso_images": [ + "./windows/windows-2012R2-serverdatacenter-amd64/answer.iso" + ], + "http_directory": "./windows/common/http/", + "boot_wait": "0s", + "boot_command": [ + "aaa" + ], + "iso_url": "http://download.microsoft.com/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_EVAL_EN-US-IRM_SSS_X64FREE_EN-US_DV5.ISO", + "iso_checksum_type": "md5", + "iso_checksum": "458ff91f8abc21b75cb544744bf92e6a", + "communicator":"winrm", + "winrm_username": "vagrant", + "winrm_password": "vagrant", + "winrm_timeout" : "4h", + "shutdown_command": "f:\\run-sysprep.cmd", + "ram_size": 4096, + "cpu": 4, + "generation": 2, + "switch_name":"LAN", + "enable_secure_boot":true + }], + "provisioners": [{ + "type": "powershell", + "elevated_user":"vagrant", + "elevated_password":"vagrant", + "scripts": [ + "./windows/common/install-7zip.ps1", + "./windows/common/install-chef.ps1", + "./windows/common/compile-dotnet-assemblies.ps1", + "./windows/common/cleanup.ps1", + "./windows/common/ultradefrag.ps1", + "./windows/common/sdelete.ps1" + ] + }], + "post-processors": [ + { + "type": "vagrant", + "keep_input_artifact": false, + "output": "{{.Provider}}_windows-2012r2_chef.box" + } + ] +} +``` + +autounattend.xml: + +```xml + + + + + + en-US + + en-US + en-US + en-US + en-US + en-US + + + + + + + + Primary + 1 + 350 + + + 2 + Primary + true + + + + + true + NTFS + + 1 + 1 + + + NTFS + + C + 2 + 2 + + + 0 + true + + + + + + + /IMAGE/NAME + Windows Server 2012 R2 SERVERSTANDARD + + + + 0 + 2 + + + + + + + + + + + + OnError + + true + Vagrant + Vagrant + + + + + + + false + + vagrant-2012r2 + Coordinated Universal Time + + + + true + + + false + false + + + true + + + true + + + + + + + + vagrant + true</PlainText> + </Password> + <Enabled>true</Enabled> + <Username>vagrant</Username> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> + <Description>Set Execution Policy 64 Bit</Description> + <Order>1</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> + <Description>Set Execution Policy 32 Bit</Description> + <Order>2</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm quickconfig -q</CommandLine> + <Description>winrm quickconfig -q</Description> + <Order>3</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm quickconfig -transport:http</CommandLine> + <Description>winrm quickconfig -transport:http</Description> + <Order>4</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}</CommandLine> + <Description>Win RM MaxTimoutms</Description> + <Order>5</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="300"}</CommandLine> + <Description>Win RM MaxMemoryPerShellMB</Description> + <Order>6</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}</CommandLine> + <Description>Win RM AllowUnencrypted</Description> + <Order>7</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}</CommandLine> + <Description>Win RM auth Basic</Description> + <Order>8</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}</CommandLine> + <Description>Win RM client auth Basic</Description> + <Order>9</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"} </CommandLine> + <Description>Win RM listener Address/Port</Description> + <Order>10</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes </CommandLine> + <Description>Win RM adv firewall enable</Description> + <Order>11</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow</CommandLine> + <Description>Win RM port open</Description> + <Order>12</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow</CommandLine> + <Description>Win RM port open</Description> + <Order>13</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c net stop winrm </CommandLine> + <Description>Stop Win RM Service </Description> + <Order>14</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c sc config winrm start= disabled</CommandLine> + <Description>Win RM Autostart</Description> + <Order>15</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f</CommandLine> + <Order>16</Order> + <Description>Show file extensions in Explorer</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f</CommandLine> + <Order>17</Order> + <Description>Enable QuickEdit mode</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f</CommandLine> + <Order>18</Order> + <Description>Show Run command in Start Menu</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f</CommandLine> + <Order>19</Order> + <Description>Show Administrative Tools in Start Menu</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f</CommandLine> + <Order>20</Order> + <Description>Zero Hibernation File</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f</CommandLine> + <Order>21</Order> + <Description>Disable Hibernation Mode</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c wmic useraccount where "name='vagrant'" set PasswordExpires=FALSE</CommandLine> + <Order>22</Order> + <Description>Disable password expiration for vagrant user</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxShellsPerUser="30"}</CommandLine> + <Description>Win RM MaxShellsPerUser</Description> + <Order>23</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxProcessesPerShell="25"}</CommandLine> + <Description>Win RM MaxProcessesPerShell</Description> + <Order>24</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>%SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters" /v DisablePasswordChange /t REG_DWORD /d 1 /f</CommandLine> + <Description>Turn off computer password</Description> + <Order>25</Order> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow</CommandLine> + <Description>ICMP open for ping</Description> + <Order>26</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <!-- WITH WINDOWS UPDATES --> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\set-power-config.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\set-power-config.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\set-power-config.ps1)</CommandLine> + <Order>97</Order> + <Description>Turn off all power saving and timeouts</Description> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\microsoft-updates.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\microsoft-updates.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\microsoft-updates.ps1)</CommandLine> + <Order>98</Order> + <Description>Enable Microsoft Updates</Description> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <CommandLine>cmd.exe /c IF EXIST a:\win-updates.ps1 (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\win-updates.ps1) ELSE (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File f:\win-updates.ps1)</CommandLine> + <Description>Install Windows Updates</Description> + <Order>100</Order> + <RequiresUserInput>true</RequiresUserInput> + </SynchronousCommand> + <!-- END WITH WINDOWS UPDATES --> + </FirstLogonCommands> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideLocalAccountScreen>true</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Group>administrators</Group> + <DisplayName>Vagrant</DisplayName> + <Name>vagrant</Name> + <Description>Vagrant User</Description> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <RegisteredOwner /> + <TimeZone>Coordinated Universal Time</TimeZone> + </component> + </settings> + <settings pass="offlineServicing"> + <component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <EnableLUA>false</EnableLUA> + </component> + </settings> + <cpi:offlineImage cpi:source="wim:c:/projects/baseboxes/9600.16384.winblue_rtm.130821-1623_x64fre_server_eval_en-us-irm_sss_x64free_en-us_dv5_slipstream/sources/install.wim#Windows Server 2012 R2 SERVERDATACENTER" xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> + +``` + +sysprep-unattend.xml: + +```text +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="generalize"> + <component language="neutral" name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SkipRearm>1</SkipRearm> + </component> + </settings> + <settings pass="oobeSystem"> +<!-- Setup proxy after sysprep + <component name="Microsoft-Windows-IE-ClientNetworkProtocolImplementation" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <POLICYProxySettingsPerUser>1</POLICYProxySettingsPerUser> + <HKLMProxyEnable>false</HKLMProxyEnable> + <HKLMProxyServer>cache-proxy:3142</HKLMProxyServer> + </component> +Finish proxy after sysprep --> + <component language="neutral" name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>0809:00000809</InputLocale> + <SystemLocale>en-GB</SystemLocale> + <UILanguage>en-US</UILanguage> + <UILanguageFallback>en-US</UILanguageFallback> + <UserLocale>en-GB</UserLocale> + </component> + <component language="neutral" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>vagrant</Value> + <PlainText>true</PlainText> + </Password> + <Group>administrators</Group> + <DisplayName>Vagrant</DisplayName> + <Name>vagrant</Name> + <Description>Vagrant User</Description> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <DisableAutoDaylightTimeSet>true</DisableAutoDaylightTimeSet> + <TimeZone>Coordinated Universal Time</TimeZone> + <VisualEffects> + <SystemDefaultBackgroundColor>2</SystemDefaultBackgroundColor> + </VisualEffects> + </component> + </settings> +</unattend> +``` + +## Example For Ubuntu Vivid Generation 2 + +If you are running Windows under virtualization, you may need to create +a virtual switch with an `External` connection type. + +### Packer config: + +```javascript +{ + "variables": { + "vm_name": "ubuntu-xenial", + "cpu": "2", + "ram_size": "1024", + "disk_size": "21440", + "iso_url": "http://releases.ubuntu.com/16.04/ubuntu-16.04.1-server-amd64.iso", + "iso_checksum_type": "sha1", + "iso_checksum": "DE5EE8665048F009577763EFBF4A6F0558833E59" + }, + "builders": [ + { + "vm_name":"{{user `vm_name`}}", + "type": "hyperv-iso", + "disk_size": "{{user `disk_size`}}", + "guest_additions_mode": "disable", + "iso_url": "{{user `iso_url`}}", + "iso_checksum_type": "{{user `iso_checksum_type`}}", + "iso_checksum": "{{user `iso_checksum`}}", + "communicator":"ssh", + "ssh_username": "packer", + "ssh_password": "packer", + "ssh_timeout" : "4h", + "http_directory": "./", + "boot_wait": "5s", + "boot_command": [ + "<esc><wait10><esc><esc><enter><wait>", + "set gfxpayload=1024x768<enter>", + "linux /install/vmlinuz ", + "preseed/url=http://{{.HTTPIP}}:{{.HTTPPort}}/hyperv-taliesins.cfg ", + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", + "hostname={{.Name}} ", + "fb=false debconf/frontend=noninteractive ", + "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", + "keyboard-configuration/variant=USA console-setup/ask_detect=false <enter>", + "initrd /install/initrd.gz<enter>", + "boot<enter>" + ], + "shutdown_command": "echo 'packer' | sudo -S -E shutdown -P now", + "ram_size": "{{user `ram_size`}}", + "cpu": "{{user `cpu`}}", + "generation": 2, + "enable_secure_boot": false + }] +} +``` + +### preseed.cfg: + +```text +## Options to set on the command line +d-i debian-installer/locale string en_US.utf8 +d-i console-setup/ask_detect boolean false +d-i console-setup/layout string us + +d-i netcfg/get_hostname string nl-ams-basebox3 +d-i netcfg/get_domain string unassigned-domain + +d-i time/zone string UTC +d-i clock-setup/utc-auto boolean true +d-i clock-setup/utc boolean true + +d-i kbd-chooser/method select American English + +d-i netcfg/wireless_wep string + +d-i base-installer/kernel/override-image string linux-server + +d-i debconf debconf/frontend select Noninteractive + +d-i pkgsel/install-language-support boolean false +tasksel tasksel/first multiselect standard, ubuntu-server + +## Partitioning +d-i partman-auto/method string lvm + +d-i partman-lvm/confirm boolean true +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true + +d-i partman-auto-lvm/guided_size string max +d-i partman-auto/choose_recipe select atomic + +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +# Write the changes to disks and configure LVM? +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true + +d-i partman-partitioning/no_bootable_gpt_biosgrub boolean false +d-i partman-partitioning/no_bootable_gpt_efi boolean false +d-i partman-efi/non_efi_system boolean true + +# Default user +d-i passwd/user-fullname string packer +d-i passwd/username string packer +d-i passwd/user-password password packer +d-i passwd/user-password-again password packer +d-i user-setup/encrypt-home boolean false +d-i user-setup/allow-password-weak boolean true + +# Minimum packages +d-i pkgsel/include string openssh-server ntp linux-tools-$(uname -r) linux-cloud-tools-$(uname -r) linux-cloud-tools-common + +# Upgrade packages after debootstrap? (none, safe-upgrade, full-upgrade) +# (note: set to none for speed) +d-i pkgsel/upgrade select none + +d-i grub-installer/only_debian boolean true +d-i grub-installer/with_other_os boolean true +d-i finish-install/reboot_in_progress note + +d-i pkgsel/update-policy select none + +choose-mirror-bin mirror/http/proxy string +``` diff --git a/website/source/docs/builders/hyperv.html.md b/website/source/docs/builders/hyperv.html.md index d12e2a212..57f2015a9 100644 --- a/website/source/docs/builders/hyperv.html.md +++ b/website/source/docs/builders/hyperv.html.md @@ -12,9 +12,12 @@ sidebar_current: 'docs-builders-hyperv' The HyperV Packer builder is able to create [Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) virtual machines and export them. -Packer currently only support building HyperV machines with an iso: - - [hyperv-iso](/docs/builders/hyperv-iso.html) - Starts from an ISO file, creates a brand new Hyper-V VM, installs an OS, provisions software within the OS, then exports that machine to create an image. This is best for people who want to start from scratch. + +- [hyperv-vmcx](/docs/builders/hyperv-vmcx.html) - Clones an + an existing virtual machine, provisions software within the OS, + then exports that machine to create an image. This is best for + people who have existing base images and want to customize them. \ No newline at end of file From 452fcbd9a1be9f4c582e4757ea7b833839fc6d98 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Sun, 12 Mar 2017 23:51:59 +0000 Subject: [PATCH 0033/1007] Only attach dvd drive if there is one Fix debug messages for cloning Add hyperv-vmcx as a builder from command line --- builder/hyperv/common/step_clone_vm.go | 2 +- builder/hyperv/common/step_mount_dvddrive.go | 12 +++++++-- builder/hyperv/vmcx/builder.go | 28 +++++++++++++------- command/plugin.go | 4 +++ common/powershell/hyperv/hyperv.go | 2 +- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index 0159d2b9e..025a1bb06 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -28,7 +28,7 @@ type StepCloneVM struct { func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) - ui.Say("Creating virtual machine...") + ui.Say("Cloning virtual machine...") path := state.Get("packerTempDir").(string) diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index 632120053..d91be3a88 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -2,9 +2,9 @@ package common import ( "fmt" + "log" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) type StepMountDvdDrive struct { @@ -17,7 +17,15 @@ func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { errorMsg := "Error mounting dvd drive: %s" vmName := state.Get("vmName").(string) - isoPath := state.Get("iso_path").(string) + + // Determine if we even have a dvd disk to attach + var isoPath string + if isoPathRaw, ok := state.GetOk("iso_path"); ok { + isoPath = isoPathRaw.(string) + } else { + log.Println("No dvd disk, not attaching.") + return multistep.ActionContinue + } // should be able to mount up to 60 additional iso images using SCSI // but Windows would only allow a max of 22 due to available drive letters diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 791c9ae46..0282d1f18 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -348,15 +348,23 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Force: b.config.PackerForce, Path: b.config.OutputDir, }, - &common.StepDownload{ - Checksum: b.config.ISOChecksum, - ChecksumType: b.config.ISOChecksumType, - Description: "ISO", - ResultKey: "iso_path", - Url: b.config.ISOUrls, - Extension: b.config.TargetExtension, - TargetPath: b.config.TargetPath, - }, + } + + if b.config.RawSingleISOUrl != "" || len(b.config.ISOUrls) > 0 { + steps = append(steps, + &common.StepDownload{ + Checksum: b.config.ISOChecksum, + ChecksumType: b.config.ISOChecksumType, + Description: "ISO", + ResultKey: "iso_path", + Url: b.config.ISOUrls, + Extension: b.config.TargetExtension, + TargetPath: b.config.TargetPath, + }, + ) + } + + steps = append(steps, &common.StepCreateFloppy{ Files: b.config.FloppyFiles, }, @@ -449,7 +457,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, // the clean up actions for each step will be executed reverse order - } + ) // Run the steps. if b.config.PackerDebug { diff --git a/command/plugin.go b/command/plugin.go index 11baf4729..373c7320f 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -92,8 +92,12 @@ var Builders = map[string]packer.Builder{ "file": new(filebuilder.Builder), "googlecompute": new(googlecomputebuilder.Builder), "hyperv-iso": new(hypervisobuilder.Builder), +<<<<<<< HEAD "lxc": new(lxcbuilder.Builder), "lxd": new(lxdbuilder.Builder), +======= + "hyperv-vmcx": new(hypervvmcxbuilder.Builder), +>>>>>>> Only attach dvd drive if there is one "null": new(nullbuilder.Builder), "oneandone": new(oneandonebuilder.Builder), "openstack": new(openstackbuilder.Builder), diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 461d4120a..9937ed3b7 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -248,7 +248,7 @@ if ((Get-Command Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { func CloneVirtualMachine(cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, ram int64, switchName string) error { var script = ` -param([string]$CloneFromVMName, [string]$CloneFromSnapshotName, [string]CloneAllSnapshotsString, [string]$vmName, [string]$path, [long]$memoryStartupBytes, [string]$switchName) +param([string]$CloneFromVMName, [string]$CloneFromSnapshotName, [string]$CloneAllSnapshotsString, [string]$vmName, [string]$path, [long]$memoryStartupBytes, [string]$switchName) $CloneAllSnapshots = [System.Boolean]::Parse($CloneAllSnapshotsString) From efa62e1550014d87a445a8baf69e5473d530af58 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Sun, 21 May 2017 17:29:26 +0100 Subject: [PATCH 0034/1007] Can specify an iso, vhd or vhdx for download. If it is a vhd or vhdx it is used as the hard drive for spinning up a new machine, importing an exported virtual machine or cloning a virtual machine. Can import a virtual machine from a folder Can clone an existing virtual machine --- builder/hyperv/common/driver.go | 4 +- builder/hyperv/common/driver_ps_4.go | 8 +- builder/hyperv/common/step_clone_vm.go | 21 ++- builder/hyperv/common/step_create_vm.go | 25 ++- builder/hyperv/iso/builder.go | 20 +- builder/hyperv/iso/builder_test.go | 2 +- builder/hyperv/vmcx/builder.go | 45 ++++- builder/hyperv/vmcx/builder_test.go | 85 +++++---- command/plugin.go | 4 + common/powershell/hyperv/hyperv.go | 172 +++++++++++++----- .../source/docs/builders/hyperv-iso.html.md | 21 ++- .../source/docs/builders/hyperv-vmcx.html.md | 30 ++- 12 files changed, 309 insertions(+), 128 deletions(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 07ab0f9fe..ba9ab5c4c 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -64,9 +64,9 @@ type Driver interface { DeleteVirtualSwitch(string) error - CreateVirtualMachine(string, string, string, int64, int64, string, uint) error + CreateVirtualMachine(string, string, string, string, int64, int64, string, uint) error - CloneVirtualMachine(string, string, bool, string, string, int64, string) error + CloneVirtualMachine(string, string, string, bool, string, string, string, int64, string) error DeleteVirtualMachine(string) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index 4c45f9c5c..c836137d2 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -170,12 +170,12 @@ func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType stri return hyperv.CreateVirtualSwitch(switchName, switchType) } -func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { - return hyperv.CreateVirtualMachine(vmName, path, vhdPath, ram, diskSize, switchName, generation) +func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { + return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, switchName, generation) } -func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, ram int64, switchName string) error { - return hyperv.CloneVirtualMachine(cloneFromVmName, cloneFromSnapshotName, cloneAllSnapshots, vmName, path, ram, switchName) +func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error { + return hyperv.CloneVirtualMachine(cloneFromVmxcPath, cloneFromVmName, cloneFromSnapshotName, cloneAllSnapshots, vmName, path, harddrivePath, ram, switchName) } func (d *HypervPS4Driver) DeleteVirtualMachine(vmName string) error { diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index 025a1bb06..9b005422d 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -2,9 +2,12 @@ package common import ( "fmt" + "log" + "strings" + "path/filepath" "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" + "github.com/hashicorp/packer/packer" ) // This step clones an existing virtual machine. @@ -12,6 +15,7 @@ import ( // Produces: // VMName string - The name of the VM type StepCloneVM struct { + CloneFromVMXCPath string CloneFromVMName string CloneFromSnapshotName string CloneAllSnapshots bool @@ -31,11 +35,24 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Cloning virtual machine...") path := state.Get("packerTempDir").(string) + + // Determine if we even have an existing virtual harddrive to attach + harddrivePath := "" + if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { + extension := strings.ToLower(filepath.Ext(harddrivePathRaw.(string))) + if extension == "vhd" || extension == "vhdx" { + harddrivePath = harddrivePathRaw.(string) + } else { + log.Println("No existing virtual harddrive, not attaching.") + } + } else { + log.Println("No existing virtual harddrive, not attaching.") + } // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) - err := driver.CloneVirtualMachine(s.CloneFromVMName, s.CloneFromSnapshotName, s.CloneAllSnapshots, s.VMName, path, ramSize, s.SwitchName) + err := driver.CloneVirtualMachine(s.CloneFromVMXCPath, s.CloneFromVMName, s.CloneFromSnapshotName, s.CloneAllSnapshots, s.VMName, path, harddrivePath, ramSize, s.SwitchName) if err != nil { err := fmt.Errorf("Error cloning virtual machine: %s", err) state.Put("error", err) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 624746d0b..46c4964cb 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -2,7 +2,10 @@ package common import ( "fmt" - + "log" + "strings" + "path/filepath" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) @@ -14,6 +17,7 @@ import ( type StepCreateVM struct { VMName string SwitchName string + HarddrivePath string RamSize uint DiskSize uint Generation uint @@ -30,13 +34,26 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Creating virtual machine...") path := state.Get("packerTempDir").(string) - vhdPath := state.Get("packerVhdTempDir").(string) - + + // Determine if we even have an existing virtual harddrive to attach + harddrivePath := "" + if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { + extension := strings.ToLower(filepath.Ext(harddrivePathRaw.(string))) + if extension == "vhd" || extension == "vhdx" { + harddrivePath = harddrivePathRaw.(string) + } else { + log.Println("No existing virtual harddrive, not attaching.") + } + } else { + log.Println("No existing virtual harddrive, not attaching.") + } + + vhdPath := state.Get("packerVhdTempDir").(string) // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) diskSize := int64(s.DiskSize * 1024 * 1024) - err := driver.CreateVirtualMachine(s.VMName, path, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation) + err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation) if err != nil { err := fmt.Errorf("Error creating virtual machine: %s", err) state.Put("error", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index f7f206408..382c35394 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -6,6 +6,7 @@ import ( "log" "os" "strings" + "path/filepath" hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/common" @@ -117,16 +118,26 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) + if len(b.config.ISOConfig.ISOUrls) > 0 { + extension := strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) + if extension == "vhd" || extension == "vhdx" { + b.config.ISOConfig.TargetExtension = extension + } + } + errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) - err = b.checkDiskSize() - if err != nil { - errs = packer.MultiErrorAppend(errs, err) + if b.config.ISOConfig.TargetExtension != "vhd" && b.config.ISOConfig.TargetExtension != "vhdx" { + //We only create a new hard drive if an existing one to copy from does not exist + err = b.checkDiskSize() + if err != nil { + errs = packer.MultiErrorAppend(errs, err) + } } err = b.checkRamSize() @@ -163,6 +174,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { log.Println(fmt.Sprintf("%s: %v", "SwitchName", b.config.SwitchName)) // Errors + if b.config.GuestAdditionsMode == "" { if b.config.GuestAdditionsPath != "" { b.config.GuestAdditionsMode = "attach" diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 70df63832..1c655f475 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -235,7 +235,7 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) { delete(config, "iso_url") delete(config, "iso_urls") - // Test both epty + // Test both empty config["iso_url"] = "" b = Builder{} warns, err := b.Prepare(config) diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 0282d1f18..b75667742 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -7,15 +7,16 @@ import ( "os" "strings" + hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" + "github.com/hashicorp/packer/common" + powershell "github.com/hashicorp/packer/common/powershell" + "github.com/hashicorp/packer/common/powershell/hyperv" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/multistep" - hypervcommon "github.com/mitchellh/packer/builder/hyperv/common" - "github.com/mitchellh/packer/common" - powershell "github.com/mitchellh/packer/common/powershell" - "github.com/mitchellh/packer/common/powershell/hyperv" - "github.com/mitchellh/packer/helper/communicator" - "github.com/mitchellh/packer/helper/config" - "github.com/mitchellh/packer/packer" - "github.com/mitchellh/packer/template/interpolate" + "path/filepath" ) const ( @@ -69,6 +70,9 @@ type Config struct { // The path to the integration services iso GuestAdditionsPath string `mapstructure:"guest_additions_path"` + // This is the path to a directory containing an exported virtual machine. + CloneFromVMXCPath string `mapstructure:"clone_from_vmxc_path"` + // This is the name of the virtual machine to clone from. CloneFromVMName string `mapstructure:"clone_from_vm_name"` @@ -122,6 +126,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) + + extension := strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) + if extension == "vhd" || extension == "vhdx" { + b.config.ISOConfig.TargetExtension = extension + } } errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) @@ -153,7 +162,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.Generation = 1 if b.config.CloneFromVMName == "" { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("The clone_from_vm_name must be specified.")) + if b.config.CloneFromVMXCPath == "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("The clone_from_vm_name must be specified if clone_from_vmxc_path is not specified.")) + } } else { virtualMachineExists, err := powershell.DoesVirtualMachineExist(b.config.CloneFromVMName) if err != nil { @@ -190,8 +201,21 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } } + + if b.config.CloneFromVMXCPath == "" { + if b.config.CloneFromVMName == "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("The clone_from_vmxc_path be specified if clone_from_vm_name must is not specified.")) + } + } else { + if _, err := os.Stat(b.config.CloneFromVMXCPath); os.IsNotExist(err) { + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("CloneFromVMXCPath does not exist: %s", err)) + } + } + } - if b.config.Generation != 2 { + if b.config.Generation != 1 || b.config.Generation != 2 { b.config.Generation = 1 } @@ -377,6 +401,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchName: b.config.SwitchName, }, &hypervcommon.StepCloneVM{ + CloneFromVMXCPath: b.config.CloneFromVMXCPath, CloneFromVMName: b.config.CloneFromVMName, CloneFromSnapshotName: b.config.CloneFromSnapshotName, CloneAllSnapshots: b.config.CloneAllSnapshots, diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index c2ea23c14..f0b7736bd 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -4,7 +4,9 @@ import ( "reflect" "testing" - "github.com/mitchellh/packer/packer" + "github.com/hashicorp/packer/packer" + "io/ioutil" + "os" ) func testConfig() map[string]interface{} { @@ -15,8 +17,8 @@ func testConfig() map[string]interface{} { "shutdown_command": "yes", "ssh_username": "foo", "ram_size": 64, - "disk_size": 256, "guest_additions_mode": "none", + "clone_from_vmxc_path": "generated", packer.BuildNameConfigKey: "foo", } } @@ -33,6 +35,14 @@ func TestBuilderPrepare_Defaults(t *testing.T) { var b Builder config := testConfig() + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + warns, err := b.Prepare(config) if len(warns) > 0 { t.Fatalf("bad: %#v", warns) @@ -46,42 +56,18 @@ func TestBuilderPrepare_Defaults(t *testing.T) { } } -func TestBuilderPrepare_DiskSize(t *testing.T) { - var b Builder - config := testConfig() - - delete(config, "disk_size") - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("bad err: %s", err) - } - - if b.config.DiskSize != 40*1024 { - t.Fatalf("bad size: %d", b.config.DiskSize) - } - - config["disk_size"] = 256 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - if b.config.DiskSize != 256 { - t.Fatalf("bad size: %d", b.config.DiskSize) - } -} - func TestBuilderPrepare_InvalidKey(t *testing.T) { var b Builder config := testConfig() + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + // Add a random key config["i_should_not_be_valid"] = true warns, err := b.Prepare(config) @@ -97,6 +83,14 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) { var b Builder config := testConfig() + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + // Test bad config["iso_checksum"] = "" warns, err := b.Prepare(config) @@ -127,6 +121,14 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) { var b Builder config := testConfig() + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + // Test bad config["iso_checksum_type"] = "" warns, err := b.Prepare(config) @@ -182,18 +184,27 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) { func TestBuilderPrepare_ISOUrl(t *testing.T) { var b Builder config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + delete(config, "iso_url") delete(config, "iso_urls") - // Test both epty + // Test both empty (should be allowed, as we cloning a vm so we probably don't need an ISO file) config["iso_url"] = "" b = Builder{} warns, err := b.Prepare(config) if len(warns) > 0 { t.Fatalf("bad: %#v", warns) } - if err == nil { - t.Fatal("should have error") + if err != nil { + t.Fatal("should not have an error") } // Test iso_url set diff --git a/command/plugin.go b/command/plugin.go index 373c7320f..6524f47b4 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -26,8 +26,12 @@ import ( filebuilder "github.com/hashicorp/packer/builder/file" googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" +<<<<<<< HEAD lxcbuilder "github.com/hashicorp/packer/builder/lxc" lxdbuilder "github.com/hashicorp/packer/builder/lxd" +======= + hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" +>>>>>>> Can specify an iso, vhd or vhdx for download. If it is a vhd or vhdx it is used as the hard drive for spinning up a new machine, importing an exported virtual machine or cloning a virtual machine. nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" openstackbuilder "github.com/hashicorp/packer/builder/openstack" diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 9937ed3b7..4d6e78b65 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -187,28 +187,38 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } -func CreateVirtualMachine(vmName string, path string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint) error { +func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint) error { if generation == 2 { var script = ` -param([string]$vmName, [string]$path, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) +param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx -New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation +if ($harddrivePath){ + Copy-Item -Path $harddrivePath -Destination $vhdPath + New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation +} else { + New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation +} ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, path, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) + err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) return err } else { var script = ` -param([string]$vmName, [string]$path, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) +param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx -New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName +if ($harddrivePath){ + Copy-Item -Path $harddrivePath -Destination $vhdPath + New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName +} else { + New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName +} ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, path, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName) - + err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName) + if err != nil { return err } @@ -234,58 +244,111 @@ if ((Get-Command Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { return err } -func DisableAutomaticCheckpoints(vmName string) error { +func ExportVmxcVirtualMachine(exportPath string, vmName string, snapshotName string, allSnapshots bool) error { var script = ` -param([string]$vmName) -if ((Get-Command Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { - Set-Vm -Name $vmName -AutomaticCheckpointsEnabled $false } -` - var ps powershell.PowerShellCmd - err := ps.Run(script, vmName) - return err +param([string]$exportPath, [string]$vmName, [string]$snapshotName, [string]$allSnapshotsString) + +$WorkingPath = Join-Path $exportPath $vmName + +if (Test-Path $WorkingPath) { + throw "Export path working directory: $WorkingPath already exists!" } -func CloneVirtualMachine(cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, ram int64, switchName string) error { +$allSnapshots = [System.Boolean]::Parse($allSnapshotsString) - var script = ` -param([string]$CloneFromVMName, [string]$CloneFromSnapshotName, [string]$CloneAllSnapshotsString, [string]$vmName, [string]$path, [long]$memoryStartupBytes, [string]$switchName) - -$CloneAllSnapshots = [System.Boolean]::Parse($CloneAllSnapshotsString) - -$ExportPath = Join-Path $path $VMName - -if ($CloneFromSnapshotName) { - $snapshot = Get-VMSnapshot -VMName $CloneFromVMName -Name $CloneFromSnapshotName - Export-VMSnapshot -VMSnapshot $snapshot -Path $ExportPath -ErrorAction Stop +if ($snapshotName) { + $snapshot = Get-VMSnapshot -VMName $vmName -Name $snapshotName + Export-VMSnapshot -VMSnapshot $snapshot -Path $exportPath -ErrorAction Stop } else { - if (!$CloneAllSnapshots) { + if (!$allSnapshots) { #Use last snapshot if one was not specified - $snapshot = Get-VMSnapshot -VMName $CloneFromVMName | Select -Last 1 + $snapshot = Get-VMSnapshot -VMName $vmName | Select -Last 1 } else { $snapshot = $null } if (!$snapshot) { #No snapshot clone - Export-VM -Name $CloneFromVMName -Path $ExportPath -ErrorAction Stop + Export-VM -Name $vmName -Path $exportPath -ErrorAction Stop } else { #Snapshot clone - Export-VMSnapshot -VMSnapshot $snapshot -Path $ExportPath -ErrorAction Stop + Export-VMSnapshot -VMSnapshot $snapshot -Path $exportPath -ErrorAction Stop } } -$result = Get-ChildItem -Path (Join-Path $ExportPath $CloneFromVMName) | Move-Item -Destination $ExportPath -Force -$result = Remove-Item -Path (Join-Path $ExportPath $CloneFromVMName) +$result = Get-ChildItem -Path $WorkingPath | Move-Item -Destination $exportPath -Force +$result = Remove-Item -Path $WorkingPath + ` -$VirtualMachinePath = Get-ChildItem -Path (Join-Path $ExportPath 'Virtual Machines') -Filter *.vmcx -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} -if (!$VirtualMachinePath){ - $VirtualMachinePath = Get-ChildItem -Path (Join-Path $ExportPath 'Virtual Machines') -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} -} -if (!$VirtualMachinePath){ - $VirtualMachinePath = Get-ChildItem -Path $ExportPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} + allSnapshotsString := "False" + if allSnapshots { + allSnapshotsString = "True" + } + + var ps powershell.PowerShellCmd + err := ps.Run(script, exportPath, vmName, snapshotName, allSnapshotsString) + + return err } -$compatibilityReport = Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $ExportPath -SmartPagingFilePath $ExportPath -SnapshotFilePath $ExportPath -VhdDestinationPath (Join-Path -Path $ExportPath -ChildPath 'Virtual Hard Disks') -GenerateNewId -Copy:$false +func CopyVmxcVirtualMachine(exportPath string, cloneFromVmxcPath string) error { + var script = ` +param([string]$exportPath, [string]$cloneFromVmxcPath) +if (!(Test-Path $cloneFromVmxcPath)){ + throw "Clone from vmxc directory: $cloneFromVmxcPath does not exist!" +} + +if (!(Test-Path $exportPath)){ + New-Item -ItemType Directory -Force -Path $exportPath +} +$cloneFromVmxcPath = Join-Path $cloneFromVmxcPath '\*' +Copy-Item $cloneFromVmxcPath $exportPath -Recurse -Force + ` + + var ps powershell.PowerShellCmd + err := ps.Run(script, exportPath, cloneFromVmxcPath) + + return err +} + +func ImportVmxcVirtualMachine(importPath string, vmName string, harddrivePath string, ram int64, switchName string) error { + var script = ` +param([string]$importPath, [string]$vmName, [string]$harddrivePath, [long]$memoryStartupBytes, [string]$switchName) + +$VirtualHarddisksPath = Join-Path -Path $importPath -ChildPath 'Virtual Hard Disks' +if (!(Test-Path $VirtualHarddisksPath)) { + New-Item -ItemType Directory -Force -Path $VirtualHarddisksPath +} + +$vhdPath = "" +if ($harddrivePath){ + $vhdx = $vmName + '.vhdx' + $vhdPath = Join-Path -Path $VirtualHarddisksPath -ChildPath $vhdx +} + +$VirtualMachinesPath = Join-Path $importPath 'Virtual Machines' +if (!(Test-Path $VirtualMachinesPath)) { + New-Item -ItemType Directory -Force -Path $VirtualMachinesPath +} + +$VirtualMachinePath = Get-ChildItem -Path $VirtualMachinesPath -Filter *.vmcx -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} +if (!$VirtualMachinePath){ + $VirtualMachinePath = Get-ChildItem -Path $VirtualMachinesPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} +} +if (!$VirtualMachinePath){ + $VirtualMachinePath = Get-ChildItem -Path $importPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} +} + +$compatibilityReport = Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy:$false +if ($vhdPath){ + Copy-Item -Path $harddrivePath -Destination $vhdPath + $existingFirstHarddrive = $compatibilityReport.VM.HardDrives | Select -First 1 + if ($existingFirstHarddrive) { + $existingFirstHarddrive | Set-VMHardDiskDrive -Path $vhdPath + } else { + Add-VMHardDiskDrive -VM $compatibilityReport.VM -Path $vhdPath + } +} Set-VMMemory -VM $compatibilityReport.VM -StartupBytes $memoryStartupBytes $networkAdaptor = $compatibilityReport.VM.NetworkAdapters | Select -First 1 Disconnect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor @@ -295,22 +358,35 @@ $vm = Import-VM -CompatibilityReport $compatibilityReport if ($vm) { $result = Rename-VM -VM $vm -NewName $VMName } -` - - CloneAllSnapshotsString := "False" - if cloneAllSnapshots { - CloneAllSnapshotsString = "True" - } + ` var ps powershell.PowerShellCmd - err := ps.Run(script, cloneFromVmName, cloneFromSnapshotName, CloneAllSnapshotsString, vmName, path, strconv.FormatInt(ram, 10), switchName) + err := ps.Run(script, importPath, vmName, harddrivePath, strconv.FormatInt(ram, 10), switchName) + return err +} + +func CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error { + if cloneFromVmName != "" { + err := ExportVmxcVirtualMachine(path, cloneFromVmName, cloneFromSnapshotName, cloneAllSnapshots) + if err != nil { + return err + } + } + + if cloneFromVmxcPath != "" { + err := CopyVmxcVirtualMachine(path, cloneFromVmxcPath) + if err != nil { + return err + } + } + + err := ImportVmxcVirtualMachine(path, vmName, harddrivePath, ram, switchName) if err != nil { return err } return DeleteAllDvdDrives(vmName) - } func GetVirtualMachineGeneration(vmName string) (uint, error) { diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index f2daf1e41..f762cf3cc 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -53,21 +53,22 @@ can be configured for this builder. ### Required: -- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO - files are so large, this is required and Packer will verify it prior - to booting a virtual machine with the ISO attached. The type of the - checksum is specified with `iso_checksum_type`, documented below. +- `iso_checksum` (string) - The checksum for the OS ISO file or virtual + harddrive file. Because these files are so large, this is required and + Packer will verify it prior to booting a virtual machine with the ISO or + virtual harddrive attached. The type of the checksum is specified with + `iso_checksum_type`, documented below. - `iso_checksum_type` (string) - The type of the checksum specified in `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or "sha512" currently. While "none" will skip checksumming, this is not - recommended since ISO files are generally large and corruption does happen - from time to time. + recommended since ISO files and virtual harddrive files are generally large + and corruption does happen from time to time. -- `iso_url` (string) - A URL to the ISO containing the installation image. - This URL can be either an HTTP URL or a file URL (or path to a file). - If this is an HTTP URL, Packer will download iso and cache it between - runs. +- `iso_url` (string) - A URL to the ISO containing the installation image or + virtual harddrive vhd or vhdx file to clone. This URL can be either an HTTP + URL or a file URL (or path to a file). If this is an HTTP URL, Packer will + download the file and cache it between runs. ### Optional: diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index c2aa3c539..0277e18da 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -9,12 +9,14 @@ page_title: "Hyper-V Builder (from an vmcx)" Type: `hyperv-vmcx` -The Hyper-V Packer builder is able to clone [Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) -virtual machines and export them. +The Hyper-V Packer builder is able to use exported virtual machines or clone existing +[Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) +virtual machines. -The builder clones an existing virtual machine boots it, and provisioning software within -the OS, then shutting it down. The result of the Hyper-V builder is a directory -containing all the files necessary to run the virtual machine portably. +The builder imports a virtual machine or clones an existing virtual machine boots it, +and provisioning software within the OS, then shutting it down. The result of the +Hyper-V builder is a directory containing all the files necessary to run the virtual +machine portably. ## Basic Example @@ -22,6 +24,18 @@ Here is a basic example. This example is not functional. It will start the OS installer but then fail because we don't provide the preseed file for Ubuntu to self-install. Still, the example serves to show the basic configuration: +Import from folder: +```javascript +{ + "type": "hyperv-vmcx", + "clone_from_vmxc_path": "c:\virtual machines\ubuntu-12.04.5-server-amd64", + "ssh_username": "packer", + "ssh_password": "packer", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" +} +``` + +Clone from existing virtual machine: ```javascript { "type": "hyperv-vmcx", @@ -46,7 +60,11 @@ In addition to the options listed here, a [communicator](/docs/templates/communicator.html) can be configured for this builder. -### Required: +### Required for virtual machine import: +- `clone_from_vmxc_path` (string) - The path to the exported + virtual machine folder. + +### Required for virtual machine clone: - `clone_from_vm_name` (string) - The name of the vm to clone from. Ideally the machine to clone from should be shutdown. From 3d0ac529e03edab4e7b3224e38e4125e5bb230b6 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Mon, 29 May 2017 01:51:50 +0100 Subject: [PATCH 0035/1007] use common floppy_config instead of builder specific one Add tests for floppy files and comm --- builder/hyperv/iso/builder_test.go | 108 +++++++++++++++++++++ builder/hyperv/vmcx/builder.go | 2 +- builder/hyperv/vmcx/builder_test.go | 143 ++++++++++++++++++++++++++++ 3 files changed, 252 insertions(+), 1 deletion(-) diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 1c655f475..d32ba4f41 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/hashicorp/packer/packer" + "fmt" ) func testConfig() map[string]interface{} { @@ -298,3 +299,110 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) { t.Fatalf("bad: %#v", b.config.ISOUrls) } } + +func TestBuilderPrepare_FloppyFiles(t *testing.T) { + var b Builder + config := testConfig() + + delete(config, "floppy_files") + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("bad err: %s", err) + } + + if len(b.config.FloppyFiles) != 0 { + t.Fatalf("bad: %#v", b.config.FloppyFiles) + } + + floppies_path := "../../../common/test-fixtures/floppies" + config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)} + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)} + if !reflect.DeepEqual(b.config.FloppyFiles, expected) { + t.Fatalf("bad: %#v", b.config.FloppyFiles) + } +} + +func TestBuilderPrepare_InvalidFloppies(t *testing.T) { + var b Builder + config := testConfig() + config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"} + b = Builder{} + _, errs := b.Prepare(config) + if errs == nil { + t.Fatalf("Nonexistent floppies should trigger multierror") + } + + if len(errs.(*packer.MultiError).Errors) != 2 { + t.Fatalf("Multierror should work and report 2 errors") + } +} + +func TestBuilderPrepare_CommConfig(t *testing.T) { + // Test Winrm + { + config := testConfig() + config["communicator"] = "winrm" + config["winrm_username"] = "username" + config["winrm_password"] = "password" + config["winrm_host"] = "1.2.3.4" + + var b Builder + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.Comm.WinRMUser != "username" { + t.Errorf("bad winrm_username: %s", b.config.Comm.WinRMUser) + } + if b.config.Comm.WinRMPassword != "password" { + t.Errorf("bad winrm_password: %s", b.config.Comm.WinRMPassword) + } + if host := b.config.Comm.Host(); host != "1.2.3.4" { + t.Errorf("bad host: %s", host) + } + } + + // Test SSH + { + config := testConfig() + config["communicator"] = "ssh" + config["ssh_username"] = "username" + config["ssh_password"] = "password" + config["ssh_host"] = "1.2.3.4" + + var b Builder + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.Comm.SSHUsername != "username" { + t.Errorf("bad ssh_username: %s", b.config.Comm.SSHUsername) + } + if b.config.Comm.SSHPassword != "password" { + t.Errorf("bad ssh_password: %s", b.config.Comm.SSHPassword) + } + if host := b.config.Comm.Host(); host != "1.2.3.4" { + t.Errorf("bad host: %s", host) + } + } +} diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index b75667742..3236fa945 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -42,7 +42,7 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` - hypervcommon.FloppyConfig `mapstructure:",squash"` + common.FloppyConfig `mapstructure:",squash"` hypervcommon.OutputConfig `mapstructure:",squash"` hypervcommon.SSHConfig `mapstructure:",squash"` hypervcommon.RunConfig `mapstructure:",squash"` diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index f0b7736bd..3dd5cc4ab 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/packer/packer" "io/ioutil" "os" + "fmt" ) func testConfig() map[string]interface{} { @@ -259,3 +260,145 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) { t.Fatalf("bad: %#v", b.config.ISOUrls) } } + +func TestBuilderPrepare_FloppyFiles(t *testing.T) { + var b Builder + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + + delete(config, "floppy_files") + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("bad err: %s", err) + } + + if len(b.config.FloppyFiles) != 0 { + t.Fatalf("bad: %#v", b.config.FloppyFiles) + } + + floppies_path := "../../../common/test-fixtures/floppies" + config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)} + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)} + if !reflect.DeepEqual(b.config.FloppyFiles, expected) { + t.Fatalf("bad: %#v", b.config.FloppyFiles) + } +} + +func TestBuilderPrepare_InvalidFloppies(t *testing.T) { + var b Builder + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + + config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"} + b = Builder{} + _, errs := b.Prepare(config) + if errs == nil { + t.Fatalf("Nonexistent floppies should trigger multierror") + } + + if len(errs.(*packer.MultiError).Errors) != 2 { + t.Fatalf("Multierror should work and report 2 errors") + } +} + +func TestBuilderPrepare_CommConfig(t *testing.T) { + // Test Winrm + { + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + + config["communicator"] = "winrm" + config["winrm_username"] = "username" + config["winrm_password"] = "password" + config["winrm_host"] = "1.2.3.4" + + var b Builder + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.Comm.WinRMUser != "username" { + t.Errorf("bad winrm_username: %s", b.config.Comm.WinRMUser) + } + if b.config.Comm.WinRMPassword != "password" { + t.Errorf("bad winrm_password: %s", b.config.Comm.WinRMPassword) + } + if host := b.config.Comm.Host(); host != "1.2.3.4" { + t.Errorf("bad host: %s", host) + } + } + + // Test SSH + { + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + + config["communicator"] = "ssh" + config["ssh_username"] = "username" + config["ssh_password"] = "password" + config["ssh_host"] = "1.2.3.4" + + var b Builder + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.Comm.SSHUsername != "username" { + t.Errorf("bad ssh_username: %s", b.config.Comm.SSHUsername) + } + if b.config.Comm.SSHPassword != "password" { + t.Errorf("bad ssh_password: %s", b.config.Comm.SSHPassword) + } + if host := b.config.Comm.Host(); host != "1.2.3.4" { + t.Errorf("bad host: %s", host) + } + } +} From 823275939767d2ec32a50206430ca506334389d6 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Mon, 29 May 2017 02:36:01 +0100 Subject: [PATCH 0036/1007] If vhd or vhdx extension is specified for ISOUrls, we want to use an existing hard drive which means that we don't need to specify hard drive size Filepath.ext includes the dot --- builder/hyperv/common/step_clone_vm.go | 2 +- builder/hyperv/common/step_create_vm.go | 2 +- builder/hyperv/iso/builder.go | 11 +-- builder/hyperv/iso/builder_test.go | 92 +++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index 9b005422d..f867bd331 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -40,7 +40,7 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { harddrivePath := "" if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { extension := strings.ToLower(filepath.Ext(harddrivePathRaw.(string))) - if extension == "vhd" || extension == "vhdx" { + if extension == ".vhd" || extension == ".vhdx" { harddrivePath = harddrivePathRaw.(string) } else { log.Println("No existing virtual harddrive, not attaching.") diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 46c4964cb..4b9601842 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -39,7 +39,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { harddrivePath := "" if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { extension := strings.ToLower(filepath.Ext(harddrivePathRaw.(string))) - if extension == "vhd" || extension == "vhdx" { + if extension == ".vhd" || extension == ".vhdx" { harddrivePath = harddrivePathRaw.(string) } else { log.Println("No existing virtual harddrive, not attaching.") diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 382c35394..4d5583239 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -117,22 +117,15 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) - - if len(b.config.ISOConfig.ISOUrls) > 0 { - extension := strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) - if extension == "vhd" || extension == "vhdx" { - b.config.ISOConfig.TargetExtension = extension - } - } errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) - if b.config.ISOConfig.TargetExtension != "vhd" && b.config.ISOConfig.TargetExtension != "vhdx" { + if len(b.config.ISOConfig.ISOUrls) < 1 || (strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) != ".vhd" && strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) != ".vhdx") { //We only create a new hard drive if an existing one to copy from does not exist err = b.checkDiskSize() if err != nil { diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index d32ba4f41..0fea9b8e0 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -300,6 +300,98 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) { } } +func TestBuilderPrepare_SizeNotRequiredWhenUsingExistingHarddrive(t *testing.T) { + var b Builder + config := testConfig() + delete(config, "iso_url") + delete(config, "iso_urls") + delete(config, "disk_size") + + config["disk_size"] = 1 + + // Test just iso_urls set but with vhdx + delete(config, "iso_url") + config["iso_urls"] = []string{ + "http://www.packer.io/hdd.vhdx", + "http://www.hashicorp.com/dvd.iso", + } + + b = Builder{} + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Errorf("should not have error: %s", err) + } + + expected := []string{ + "http://www.packer.io/hdd.vhdx", + "http://www.hashicorp.com/dvd.iso", + } + if !reflect.DeepEqual(b.config.ISOUrls, expected) { + t.Fatalf("bad: %#v", b.config.ISOUrls) + } + + // Test just iso_urls set but with vhd + delete(config, "iso_url") + config["iso_urls"] = []string{ + "http://www.packer.io/hdd.vhd", + "http://www.hashicorp.com/dvd.iso", + } + + b = Builder{} + warns, err = b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Errorf("should not have error: %s", err) + } + + expected = []string{ + "http://www.packer.io/hdd.vhd", + "http://www.hashicorp.com/dvd.iso", + } + if !reflect.DeepEqual(b.config.ISOUrls, expected) { + t.Fatalf("bad: %#v", b.config.ISOUrls) + } +} + +func TestBuilderPrepare_SizeIsRequiredWhenNotUsingExistingHarddrive(t *testing.T) { + var b Builder + config := testConfig() + delete(config, "iso_url") + delete(config, "iso_urls") + delete(config, "disk_size") + + config["disk_size"] = 1 + + // Test just iso_urls set but with vhdx + delete(config, "iso_url") + config["iso_urls"] = []string{ + "http://www.packer.io/os.iso", + "http://www.hashicorp.com/dvd.iso", + } + + b = Builder{} + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Errorf("should have error") + } + + expected := []string{ + "http://www.packer.io/os.iso", + "http://www.hashicorp.com/dvd.iso", + } + if !reflect.DeepEqual(b.config.ISOUrls, expected) { + t.Fatalf("bad: %#v", b.config.ISOUrls) + } +} + func TestBuilderPrepare_FloppyFiles(t *testing.T) { var b Builder config := testConfig() From 628116f4c4d493a4164ac918f8fd3fa9fa43ca8f Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Mon, 29 May 2017 03:12:35 +0100 Subject: [PATCH 0037/1007] Test settings for clone from vm and import vmxc from path --- builder/hyperv/vmcx/builder.go | 6 --- builder/hyperv/vmcx/builder_test.go | 84 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 3236fa945..c84e9e2a3 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/multistep" - "path/filepath" ) const ( @@ -126,11 +125,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) - - extension := strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) - if extension == "vhd" || extension == "vhdx" { - b.config.ISOConfig.TargetExtension = extension - } } errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 3dd5cc4ab..43b3d339f 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -80,6 +80,90 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) { } } +func TestBuilderPrepare_CloneFromExistingMachineOrImportFromExportedMachineSettingsRequired(t *testing.T) { + var b Builder + config := testConfig() + delete(config, "clone_from_vmxc_path") + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_ExportedMachinePathDoesNotExist(t *testing.T) { + var b Builder + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + + //Delete the folder immediately + os.RemoveAll(td) + + config["clone_from_vmxc_path"] = td + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_ExportedMachinePathExists(t *testing.T) { + var b Builder + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + + //Only delete afterwards + defer os.RemoveAll(td) + + config["clone_from_vmxc_path"] = td + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } +} + +func TestBuilderPrepare_CloneFromVmSettingUsedSoNoCloneFromVmxcPathRequired(t *testing.T) { + var b Builder + config := testConfig() + delete(config, "clone_from_vmxc_path") + + config["clone_from_vm_name"] = "test_machine_name_that_does_not_exist" + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + + if err == nil { + t.Fatal("should have error") + } else { + errorMessage := err.Error() + if errorMessage != "1 error(s) occurred:\n\n* Virtual machine 'test_machine_name_that_does_not_exist' to clone from does not exist." { + t.Fatalf("should not have error: %s", err) + } + } +} + func TestBuilderPrepare_ISOChecksum(t *testing.T) { var b Builder config := testConfig() From 2fbe0b4a7f9d2da24b5ded3b1127a7f1e57a0652 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Tue, 30 May 2017 01:16:03 +0100 Subject: [PATCH 0038/1007] Don't try to mount vhd and vhdx files as dvd drive. Hard drives are mounted in the create vm step --- builder/hyperv/common/step_clone_vm.go | 6 +++--- builder/hyperv/common/step_create_vm.go | 6 +++--- builder/hyperv/common/step_mount_dvddrive.go | 10 +++++++++- builder/hyperv/iso/builder.go | 8 ++++---- builder/hyperv/iso/builder_test.go | 2 +- builder/hyperv/vmcx/builder.go | 8 ++++---- builder/hyperv/vmcx/builder_test.go | 6 +++--- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index f867bd331..4a5b55566 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -3,11 +3,11 @@ package common import ( "fmt" "log" - "strings" "path/filepath" + "strings" - "github.com/mitchellh/multistep" "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // This step clones an existing virtual machine. @@ -35,7 +35,7 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Cloning virtual machine...") path := state.Get("packerTempDir").(string) - + // Determine if we even have an existing virtual harddrive to attach harddrivePath := "" if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 4b9601842..f745514e1 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -3,9 +3,9 @@ package common import ( "fmt" "log" - "strings" "path/filepath" - + "strings" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) @@ -34,7 +34,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Creating virtual machine...") path := state.Get("packerTempDir").(string) - + // Determine if we even have an existing virtual harddrive to attach harddrivePath := "" if harddrivePathRaw, ok := state.GetOk("iso_path"); ok { diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index d91be3a88..1535e86b4 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -2,9 +2,11 @@ package common import ( "fmt" - "log" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" + "log" + "path/filepath" + "strings" ) type StepMountDvdDrive struct { @@ -27,6 +29,12 @@ func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionContinue } + // Determine if its a virtual hdd to mount + if strings.ToLower(filepath.Ext(isoPath)) == ".vhd" || strings.ToLower(filepath.Ext(isoPath)) == ".vhdx" { + log.Println("Its a hard disk, not attaching.") + return multistep.ActionContinue + } + // should be able to mount up to 60 additional iso images using SCSI // but Windows would only allow a max of 22 due to available drive letters // Will Windows assign DVD drives to A: and B: ? diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 4d5583239..2cd786a42 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -5,8 +5,8 @@ import ( "fmt" "log" "os" - "strings" "path/filepath" + "strings" hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/common" @@ -117,7 +117,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) - + errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) @@ -125,7 +125,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) - if len(b.config.ISOConfig.ISOUrls) < 1 || (strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) != ".vhd" && strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) != ".vhdx") { + if len(b.config.ISOConfig.ISOUrls) < 1 || (strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) != ".vhd" && strings.ToLower(filepath.Ext(b.config.ISOConfig.ISOUrls[0])) != ".vhdx") { //We only create a new hard drive if an existing one to copy from does not exist err = b.checkDiskSize() if err != nil { @@ -152,7 +152,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.Cpu = 1 } - if b.config.Generation != 2 { + if b.config.Generation < 1 || b.config.Generation > 2 { b.config.Generation = 1 } diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 0fea9b8e0..56a4e9d7a 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -5,8 +5,8 @@ import ( "reflect" "testing" - "github.com/hashicorp/packer/packer" "fmt" + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index c84e9e2a3..abf93d3c8 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -71,7 +71,7 @@ type Config struct { // This is the path to a directory containing an exported virtual machine. CloneFromVMXCPath string `mapstructure:"clone_from_vmxc_path"` - + // This is the name of the virtual machine to clone from. CloneFromVMName string `mapstructure:"clone_from_vm_name"` @@ -195,7 +195,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } } - + if b.config.CloneFromVMXCPath == "" { if b.config.CloneFromVMName == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("The clone_from_vmxc_path be specified if clone_from_vm_name must is not specified.")) @@ -209,7 +209,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } - if b.config.Generation != 1 || b.config.Generation != 2 { + if b.config.Generation < 1 || b.config.Generation > 2 { b.config.Generation = 1 } @@ -395,7 +395,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchName: b.config.SwitchName, }, &hypervcommon.StepCloneVM{ - CloneFromVMXCPath: b.config.CloneFromVMXCPath, + CloneFromVMXCPath: b.config.CloneFromVMXCPath, CloneFromVMName: b.config.CloneFromVMName, CloneFromSnapshotName: b.config.CloneFromSnapshotName, CloneAllSnapshots: b.config.CloneAllSnapshots, diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 43b3d339f..209094bf3 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -4,10 +4,10 @@ import ( "reflect" "testing" + "fmt" "github.com/hashicorp/packer/packer" "io/ioutil" "os" - "fmt" ) func testConfig() map[string]interface{} { @@ -19,7 +19,7 @@ func testConfig() map[string]interface{} { "ssh_username": "foo", "ram_size": 64, "guest_additions_mode": "none", - "clone_from_vmxc_path": "generated", + "clone_from_vmxc_path": "generated", packer.BuildNameConfigKey: "foo", } } @@ -142,7 +142,7 @@ func TestBuilderPrepare_ExportedMachinePathExists(t *testing.T) { } } -func TestBuilderPrepare_CloneFromVmSettingUsedSoNoCloneFromVmxcPathRequired(t *testing.T) { +func disabled_TestBuilderPrepare_CloneFromVmSettingUsedSoNoCloneFromVmxcPathRequired(t *testing.T) { var b Builder config := testConfig() delete(config, "clone_from_vmxc_path") From 5f2c71f7d7da22a8c548a3d61a7a3b761e74d216 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson <taliesins@yahoo.com> Date: Mon, 19 Jun 2017 21:22:55 +0100 Subject: [PATCH 0039/1007] Floppy directories are provided by default with common.floppydrives --- builder/hyperv/iso/builder.go | 1 + builder/hyperv/vmcx/builder.go | 14 +-- .../source/docs/builders/hyperv-iso.html.md | 4 +- .../source/docs/builders/hyperv-vmcx.html.md | 112 ++++++++++-------- 4 files changed, 66 insertions(+), 65 deletions(-) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 2cd786a42..7151ca38b 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -325,6 +325,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepCreateFloppy{ Files: b.config.FloppyConfig.FloppyFiles, Directories: b.config.FloppyConfig.FloppyDirectories, + Directories: b.config.FloppyConfig.FloppyDirectories, }, &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index abf93d3c8..656a3fa13 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -50,16 +50,7 @@ type Config struct { // The size, in megabytes, of the computer memory in the VM. // By default, this is 1024 (about 1 GB). RamSize uint `mapstructure:"ram_size"` - // A list of files to place onto a floppy disk that is attached when the - // VM is booted. This is most useful for unattended Windows installs, - // which look for an Autounattend.xml file on removable media. By default, - // no floppy will be attached. All files listed in this setting get - // placed into the root directory of the floppy and the floppy is attached - // as the first floppy device. Currently, no support exists for creating - // sub-directories on the floppy. Wildcard characters (*, ?, and []) - // are allowed. Directory names are also allowed, which will add all - // the files found in the directory to the floppy. - FloppyFiles []string `mapstructure:"floppy_files"` + // SecondaryDvdImages []string `mapstructure:"secondary_iso_images"` @@ -214,7 +205,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } if b.config.Generation == 2 { - if len(b.config.FloppyFiles) > 0 { + if len(b.config.FloppyFiles) > 0 || len(b.config.FloppyDirectories) > 0 { err = errors.New("Generation 2 vms don't support floppy drives. Use ISO image instead.") errs = packer.MultiErrorAppend(errs, err) } @@ -385,6 +376,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps = append(steps, &common.StepCreateFloppy{ Files: b.config.FloppyFiles, + Directories: b.config.FloppyConfig.FloppyDirectories, }, &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index f762cf3cc..afbc51cb3 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -63,7 +63,7 @@ can be configured for this builder. `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or "sha512" currently. While "none" will skip checksumming, this is not recommended since ISO files and virtual harddrive files are generally large - and corruption does happen from time to time. + and corruption does happen from time to time. - `iso_url` (string) - A URL to the ISO containing the installation image or virtual harddrive vhd or vhdx file to clone. This URL can be either an HTTP @@ -114,7 +114,7 @@ can be configured for this builder. characters (`*`, `?`, and `[]`) are allowed. Directory names are also allowed, which will add all the files found in the directory to the floppy. -- `floppy_dirs` (array of strings) - A list of directories to place onto +- `floppy_dirs` (array of strings) - A list of directories to place onto the floppy disk recursively. This is similar to the `floppy_files` option except that the directory structure is preserved. This is useful for when your floppy disk includes drivers or if you just want to organize it's diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index 0277e18da..0f24d53b2 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -61,49 +61,49 @@ In addition to the options listed here, a can be configured for this builder. ### Required for virtual machine import: -- `clone_from_vmxc_path` (string) - The path to the exported +- `clone_from_vmxc_path` (string) - The path to the exported virtual machine folder. ### Required for virtual machine clone: -- `clone_from_vm_name` (string) - The name of the vm to clone from. +- `clone_from_vm_name` (string) - The name of the vm to clone from. Ideally the machine to clone from should be shutdown. ### Optional: -- `clone_from_snapshot_name` (string) - The name of the snapshot +- `clone_from_snapshot_name` (string) - The name of the snapshot -- `clone_all_snapshots` (boolean) - Should all snapshots be cloned +- `clone_all_snapshots` (boolean) - Should all snapshots be cloned when the machine is cloned. -- `boot_command` (array of strings) - This is an array of commands to type +- `boot_command` (array of strings) - This is an array of commands to type when the virtual machine is first booted. The goal of these commands should be to type just enough to initialize the operating system installer. Special keys can be typed as well, and are covered in the section below on the boot command. If this is not specified, it is assumed the installer will start itself. -- `boot_wait` (string) - The time to wait after booting the initial virtual +- `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be a duration. Examples are "5s" and "1m30s" which will cause Packer to wait five seconds and one minute 30 seconds, respectively. If this isn't specified, the default is 10 seconds. -- `cpu` (integer) - The number of cpus the virtual machine should use. If this isn't specified, +- `cpu` (integer) - The number of cpus the virtual machine should use. If this isn't specified, the default is 1 cpu. -- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual machine. +- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual machine. This defaults to false. -- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual machine. +- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual machine. This defaults to false. -- `enable_secure_boot` (bool) - If true enable secure boot for virtual machine. +- `enable_secure_boot` (bool) - If true enable secure boot for virtual machine. This defaults to false. -- `enable_virtualization_extensions` (bool) - If true enable virtualization extensions for virtual machine. +- `enable_virtualization_extensions` (bool) - If true enable virtualization extensions for virtual machine. This defaults to false. For nested virtualization you need to enable mac spoofing, disable dynamic memory and have at least 4GB of RAM for virtual machine. -- `floppy_files` (array of strings) - A list of files to place onto a floppy +- `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for unattended Windows installs, which look for an `Autounattend.xml` file on removable media. By default, no floppy will be attached. All files @@ -113,13 +113,21 @@ can be configured for this builder. characters (*, ?, and []) are allowed. Directory names are also allowed, which will add all the files found in the directory to the floppy. -- `guest_additions_mode` (string) - How should guest additions be installed. +- `floppy_dirs` (array of strings) - A list of directories to place onto + the floppy disk recursively. This is similar to the `floppy_files` option + except that the directory structure is preserved. This is useful for when + your floppy disk includes drivers or if you just want to organize it's + contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. + The maximum summary size of all files in the listed directories are the + same as in `floppy_files`. + +- `guest_additions_mode` (string) - How should guest additions be installed. If value `attach` then attach iso image with by specified by `guest_additions_path`. Otherwise guest additions is not installed. -- `guest_additions_path` (string) - The path to the iso image for guest additions. +- `guest_additions_path` (string) - The path to the iso image for guest additions. -- `http_directory` (string) - Path to a directory to serve using an HTTP +- `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting kickstart files and so on. By default this is "", which means no HTTP @@ -127,50 +135,50 @@ can be configured for this builder. available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (integer) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP server to be on one port, make this minimum and maximum port the same. By default the values are 8000 and 9000, respectively. -- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO +- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO files are so large, this is required and Packer will verify it prior to booting a virtual machine with the ISO attached. The type of the checksum is specified with `iso_checksum_type`, documented below. -- `iso_checksum_type` (string) - The type of the checksum specified in +- `iso_checksum_type` (string) - The type of the checksum specified in `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or "sha512" currently. While "none" will skip checksumming, this is not recommended since ISO files are generally large and corruption does happen from time to time. -- `iso_url` (string) - A URL to the ISO containing the installation image. +- `iso_url` (string) - A URL to the ISO containing the installation image. This URL can be either an HTTP URL or a file URL (or path to a file). If this is an HTTP URL, Packer will download iso and cache it between runs. -- `iso_urls` (array of strings) - Multiple URLs for the ISO to download. +- `iso_urls` (array of strings) - Multiple URLs for the ISO to download. Packer will try these in order. If anything goes wrong attempting to download or while downloading a single URL, it will move on to the next. All URLs must point to the same file (same checksum). By default this is empty and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified. -- `iso_target_extension` (string) - The extension of the iso file after +- `iso_target_extension` (string) - The extension of the iso file after download. This defaults to "iso". -- `iso_target_path` (string) - The path where the iso should be saved after +- `iso_target_path` (string) - The path where the iso should be saved after download. By default will go in the packer cache, with a hash of the original filename as its name. -- `output_directory` (string) - This is the path to the directory where the +- `output_directory` (string) - This is the path to the directory where the resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` is executed. This directory must not exist or be empty prior to running the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the name of the build. -- `ram_size` (integer) - The size, in megabytes, of the ram to create +- `ram_size` (integer) - The size, in megabytes, of the ram to create for the VM. By default, this is 1 GB. * `secondary_iso_images` (array of strings) - A list of iso paths to attached to a @@ -178,33 +186,33 @@ can be configured for this builder. look for an `Autounattend.xml` file on removable media. By default, no secondary iso will be attached. -- `shutdown_command` (string) - The command to use to gracefully shut down the machine once all +- `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty string, which tells Packer to just forcefully shut down the machine unless a shutdown command takes place inside script so this may safely be omitted. If one or more scripts require a reboot it is suggested to leave this blank since reboots may fail and specify the final shutdown command in your last script. -- `shutdown_timeout` (string) - The amount of time to wait after executing +- `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it doesn't shut down in this time, it is an error. By default, the timeout is "5m", or five minutes. -- `skip_compaction` (bool) - If true skip compacting the hard disk for virtual machine when +- `skip_compaction` (bool) - If true skip compacting the hard disk for virtual machine when exporting. This defaults to false. -- `switch_name` (string) - The name of the switch to connect the virtual machine to. Be defaulting +- `switch_name` (string) - The name of the switch to connect the virtual machine to. Be defaulting this to an empty string, Packer will try to determine the switch to use by looking for external switch that is up and running. -- `switch_vlan_id` (string) - This is the vlan of the virtual switch's network card. +- switch_vlan_id` (string) - This is the vlan of the virtual switch's network card. By default none is set. If none is set then a vlan is not set on the switch's network card. If this value is set it should match the vlan specified in by `vlan_id`. -- `vlan_id` (string) - This is the vlan of the virtual machine's network card for the new virtual +- `vlan_id` (string) - This is the vlan of the virtual machine's network card for the new virtual machine. By default none is set. If none is set then vlans are not set on the virtual machine's network card. -- `vm_name` (string) - This is the name of the virtual machine for the new virtual +- `vm_name` (string) - This is the name of the virtual machine for the new virtual machine, without the file extension. By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. @@ -224,47 +232,47 @@ to the machine, simulating a human actually typing the keyboard. There are a set of special keys available. If these are in your boot command, they will be replaced by the proper key: -- `<bs>` - Backspace +- `<bs>` - Backspace -- `<del>` - Delete +- `<del>` - Delete -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. +- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. -- `<esc>` - Simulates pressing the escape key. +- `<esc>` - Simulates pressing the escape key. -- `<tab>` - Simulates pressing the tab key. +- `<tab>` - Simulates pressing the tab key. -- `<f1>` - `<f12>` - Simulates pressing a function key. +- `<f1>` - `<f12>` - Simulates pressing a function key. -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. +- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. -- `<spacebar>` - Simulates pressing the spacebar. +- `<spacebar>` - Simulates pressing the spacebar. -- `<insert>` - Simulates pressing the insert key. +- `<insert>` - Simulates pressing the insert key. -- `<home>` `<end>` - Simulates pressing the home and end keys. +- `<home>` `<end>` - Simulates pressing the home and end keys. -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. +- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. +- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. +- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. +- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. +- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. +- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. +- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. +- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. +- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. +- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before +- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before sending any additional keys. This is useful if you have to generally wait for the UI to update before typing more. From 7978fd8ec0ddbb9e9970f841d9ccf429195a45da Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:11:45 -0700 Subject: [PATCH 0040/1007] make fmt --- builder/hyperv/vmcx/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 656a3fa13..9eb88dca7 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -375,7 +375,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps = append(steps, &common.StepCreateFloppy{ - Files: b.config.FloppyFiles, + Files: b.config.FloppyFiles, Directories: b.config.FloppyConfig.FloppyDirectories, }, &common.StepHTTPServer{ From fcfdff0efdc3f0e26ba0cb4367ec96e63a3b3348 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:15:43 -0700 Subject: [PATCH 0041/1007] rerun scripts/generate-plugins.go --- command/plugin.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/command/plugin.go b/command/plugin.go index 6524f47b4..d9e7ea577 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -26,12 +26,9 @@ import ( filebuilder "github.com/hashicorp/packer/builder/file" googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" -<<<<<<< HEAD + hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" lxcbuilder "github.com/hashicorp/packer/builder/lxc" lxdbuilder "github.com/hashicorp/packer/builder/lxd" -======= - hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" ->>>>>>> Can specify an iso, vhd or vhdx for download. If it is a vhd or vhdx it is used as the hard drive for spinning up a new machine, importing an exported virtual machine or cloning a virtual machine. nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" openstackbuilder "github.com/hashicorp/packer/builder/openstack" @@ -96,12 +93,9 @@ var Builders = map[string]packer.Builder{ "file": new(filebuilder.Builder), "googlecompute": new(googlecomputebuilder.Builder), "hyperv-iso": new(hypervisobuilder.Builder), -<<<<<<< HEAD + "hyperv-vmcx": new(hypervvmcxbuilder.Builder), "lxc": new(lxcbuilder.Builder), "lxd": new(lxdbuilder.Builder), -======= - "hyperv-vmcx": new(hypervvmcxbuilder.Builder), ->>>>>>> Only attach dvd drive if there is one "null": new(nullbuilder.Builder), "oneandone": new(oneandonebuilder.Builder), "openstack": new(openstackbuilder.Builder), From d8c6e6d4a4f1e6ead3f67f495a628208e27c309c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:19:14 -0700 Subject: [PATCH 0042/1007] remove duplicate line --- builder/hyperv/iso/builder.go | 1 - 1 file changed, 1 deletion(-) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 7151ca38b..2cd786a42 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -325,7 +325,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepCreateFloppy{ Files: b.config.FloppyConfig.FloppyFiles, Directories: b.config.FloppyConfig.FloppyDirectories, - Directories: b.config.FloppyConfig.FloppyDirectories, }, &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, From 5937f75898f27e4031cb9532fbe364c7032b50d3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:36:05 -0700 Subject: [PATCH 0043/1007] reformat docs --- .../source/docs/builders/hyperv-vmcx.html.md | 268 +++++++++--------- website/source/layouts/docs.erb | 3 + 2 files changed, 143 insertions(+), 128 deletions(-) diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index 0f24d53b2..f5074b358 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -2,6 +2,7 @@ description: |- The Hyper-V Packer builder is able to clone an existing Hyper-V virtual machine and export them. layout: "docs" +sidebar_current: 'docs-builders-hyperv-vmcx' page_title: "Hyper-V Builder (from an vmcx)" --- @@ -25,10 +26,11 @@ OS installer but then fail because we don't provide the preseed file for Ubuntu to self-install. Still, the example serves to show the basic configuration: Import from folder: -```javascript + +```json { "type": "hyperv-vmcx", - "clone_from_vmxc_path": "c:\virtual machines\ubuntu-12.04.5-server-amd64", + "clone_from_vmxc_path": "c:\\virtual machines\\ubuntu-12.04.5-server-amd64", "ssh_username": "packer", "ssh_password": "packer", "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" @@ -36,13 +38,14 @@ Import from folder: ``` Clone from existing virtual machine: -```javascript + +```json { - "type": "hyperv-vmcx", - "clone_from_vm_name": "ubuntu-12.04.5-server-amd64", - "ssh_username": "packer", - "ssh_password": "packer", - "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" + "clone_from_vm_name": "ubuntu-12.04.5-server-amd64", + "shutdown_command": "echo 'packer' | sudo -S shutdown -P now", + "ssh_password": "packer", + "ssh_username": "packer", + "type": "hyperv-vmcx" } ``` @@ -61,73 +64,78 @@ In addition to the options listed here, a can be configured for this builder. ### Required for virtual machine import: -- `clone_from_vmxc_path` (string) - The path to the exported - virtual machine folder. + +- `clone_from_vmxc_path` (string) - The path to the exported virtual machine + folder. ### Required for virtual machine clone: -- `clone_from_vm_name` (string) - The name of the vm to clone from. - Ideally the machine to clone from should be shutdown. + +- `clone_from_vm_name` (string) - The name of the vm to clone from. Ideally + the machine to clone from should be shutdown. ### Optional: -- `clone_from_snapshot_name` (string) - The name of the snapshot -- `clone_all_snapshots` (boolean) - Should all snapshots be cloned - when the machine is cloned. +- `clone_from_snapshot_name` (string) - The name of the snapshot -- `boot_command` (array of strings) - This is an array of commands to type +- `clone_all_snapshots` (boolean) - Should all snapshots be cloned when the + machine is cloned. + +- `boot_command` (array of strings) - This is an array of commands to type when the virtual machine is first booted. The goal of these commands should - be to type just enough to initialize the operating system installer. Special - keys can be typed as well, and are covered in the section below on the boot - command. If this is not specified, it is assumed the installer will start - itself. + be to type just enough to initialize the operating system installer. + Special keys can be typed as well, and are covered in the section below on + the boot command. If this is not specified, it is assumed the installer + will start itself. -- `boot_wait` (string) - The time to wait after booting the initial virtual +- `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be a duration. Examples are "5s" and "1m30s" which will cause Packer to wait - five seconds and one minute 30 seconds, respectively. If this isn't specified, - the default is 10 seconds. + five seconds and one minute 30 seconds, respectively. If this isn't + specified, the default is 10 seconds. -- `cpu` (integer) - The number of cpus the virtual machine should use. If this isn't specified, - the default is 1 cpu. +- `cpu` (integer) - The number of cpus the virtual machine should use. If + this isn't specified, the default is 1 cpu. -- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual machine. - This defaults to false. +- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual + machine. This defaults to false. -- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual machine. - This defaults to false. +- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual + machine. This defaults to false. -- `enable_secure_boot` (bool) - If true enable secure boot for virtual machine. - This defaults to false. +- `enable_secure_boot` (bool) - If true enable secure boot for virtual + machine. This defaults to false. -- `enable_virtualization_extensions` (bool) - If true enable virtualization extensions for virtual machine. - This defaults to false. For nested virtualization you need to enable mac spoofing, disable dynamic memory - and have at least 4GB of RAM for virtual machine. +- `enable_virtualization_extensions` (bool) - If true enable virtualization + extensions for virtual machine. This defaults to false. For nested + virtualization you need to enable mac spoofing, disable dynamic memory and + have at least 4GB of RAM for virtual machine. -- `floppy_files` (array of strings) - A list of files to place onto a floppy - disk that is attached when the VM is booted. This is most useful - for unattended Windows installs, which look for an `Autounattend.xml` file - on removable media. By default, no floppy will be attached. All files - listed in this setting get placed into the root directory of the floppy - and the floppy is attached as the first floppy device. Currently, no - support exists for creating sub-directories on the floppy. Wildcard - characters (*, ?, and []) are allowed. Directory names are also allowed, - which will add all the files found in the directory to the floppy. +- `floppy_files` (array of strings) - A list of files to place onto a floppy + disk that is attached when the VM is booted. This is most useful for + unattended Windows installs, which look for an `Autounattend.xml` file on + removable media. By default, no floppy will be attached. All files listed + in this setting get placed into the root directory of the floppy and the + floppy is attached as the first floppy device. Currently, no support exists + for creating sub-directories on the floppy. Wildcard characters (*, ?, and + []) are allowed. Directory names are also allowed, which will add all the + files found in the directory to the floppy. -- `floppy_dirs` (array of strings) - A list of directories to place onto - the floppy disk recursively. This is similar to the `floppy_files` option +- `floppy_dirs` (array of strings) - A list of directories to place onto the + floppy disk recursively. This is similar to the `floppy_files` option except that the directory structure is preserved. This is useful for when your floppy disk includes drivers or if you just want to organize it's contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. The maximum summary size of all files in the listed directories are the same as in `floppy_files`. -- `guest_additions_mode` (string) - How should guest additions be installed. - If value `attach` then attach iso image with by specified by `guest_additions_path`. - Otherwise guest additions is not installed. +- `guest_additions_mode` (string) - How should guest additions be installed. + If value `attach` then attach iso image with by specified by + `guest_additions_path`. Otherwise guest additions is not installed. -- `guest_additions_path` (string) - The path to the iso image for guest additions. +- `guest_additions_path` (string) - The path to the iso image for guest + additions. -- `http_directory` (string) - Path to a directory to serve using an HTTP +- `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting kickstart files and so on. By default this is "", which means no HTTP @@ -135,86 +143,90 @@ can be configured for this builder. available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and - maximum port to use for the HTTP server started to serve the `http_directory`. - Because Packer often runs in parallel, Packer will choose a randomly available - port in this range to run the HTTP server. If you want to force the HTTP - server to be on one port, make this minimum and maximum port the same. - By default the values are 8000 and 9000, respectively. +- `http_port_min` and `http_port_max` (integer) - These are the minimum and + maximum port to use for the HTTP server started to serve the + `http_directory`. Because Packer often runs in parallel, Packer will choose + a randomly available port in this range to run the HTTP server. If you want + to force the HTTP server to be on one port, make this minimum and maximum + port the same. By default the values are 8000 and 9000, respectively. -- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO - files are so large, this is required and Packer will verify it prior - to booting a virtual machine with the ISO attached. The type of the - checksum is specified with `iso_checksum_type`, documented below. +- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO + files are so large, this is required and Packer will verify it prior to + booting a virtual machine with the ISO attached. The type of the checksum + is specified with `iso_checksum_type`, documented below. -- `iso_checksum_type` (string) - The type of the checksum specified in +- `iso_checksum_type` (string) - The type of the checksum specified in `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or "sha512" currently. While "none" will skip checksumming, this is not recommended since ISO files are generally large and corruption does happen from time to time. -- `iso_url` (string) - A URL to the ISO containing the installation image. - This URL can be either an HTTP URL or a file URL (or path to a file). - If this is an HTTP URL, Packer will download iso and cache it between - runs. +- `iso_url` (string) - A URL to the ISO containing the installation image. + This URL can be either an HTTP URL or a file URL (or path to a file). If + this is an HTTP URL, Packer will download iso and cache it between runs. -- `iso_urls` (array of strings) - Multiple URLs for the ISO to download. - Packer will try these in order. If anything goes wrong attempting to download - or while downloading a single URL, it will move on to the next. All URLs - must point to the same file (same checksum). By default this is empty - and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified. +- `iso_urls` (array of strings) - Multiple URLs for the ISO to download. + Packer will try these in order. If anything goes wrong attempting to + download or while downloading a single URL, it will move on to the next. + All URLs must point to the same file (same checksum). By default this is + empty and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be + specified. -- `iso_target_extension` (string) - The extension of the iso file after +- `iso_target_extension` (string) - The extension of the iso file after download. This defaults to "iso". -- `iso_target_path` (string) - The path where the iso should be saved after +- `iso_target_path` (string) - The path where the iso should be saved after download. By default will go in the packer cache, with a hash of the original filename as its name. -- `output_directory` (string) - This is the path to the directory where the - resulting virtual machine will be created. This may be relative or absolute. - If relative, the path is relative to the working directory when `packer` - is executed. This directory must not exist or be empty prior to running the builder. - By default this is "output-BUILDNAME" where "BUILDNAME" is the name - of the build. +- `output_directory` (string) - This is the path to the directory where the + resulting virtual machine will be created. This may be relative or + absolute. If relative, the path is relative to the working directory when + `packer` is executed. This directory must not exist or be empty prior to + running the builder. By default this is "output-BUILDNAME" where + "BUILDNAME" is the name of the build. -- `ram_size` (integer) - The size, in megabytes, of the ram to create - for the VM. By default, this is 1 GB. +- `ram_size` (integer) - The size, in megabytes, of the ram to create for the + VM. By default, this is 1 GB. -* `secondary_iso_images` (array of strings) - A list of iso paths to attached to a - VM when it is booted. This is most useful for unattended Windows installs, which - look for an `Autounattend.xml` file on removable media. By default, no - secondary iso will be attached. +* `secondary_iso_images` (array of strings) - A list of iso paths to attached + to a VM when it is booted. This is most useful for unattended Windows + installs, which look for an `Autounattend.xml` file on removable media. By + default, no secondary iso will be attached. -- `shutdown_command` (string) - The command to use to gracefully shut down the machine once all - the provisioning is done. By default this is an empty string, which tells Packer to just - forcefully shut down the machine unless a shutdown command takes place inside script so this may - safely be omitted. If one or more scripts require a reboot it is suggested to leave this blank - since reboots may fail and specify the final shutdown command in your last script. +- `shutdown_command` (string) - The command to use to gracefully shut down + the machine once all the provisioning is done. By default this is an empty + string, which tells Packer to just forcefully shut down the machine unless + a shutdown command takes place inside script so this may safely be omitted. + If one or more scripts require a reboot it is suggested to leave this blank + since reboots may fail and specify the final shutdown command in your last + script. -- `shutdown_timeout` (string) - The amount of time to wait after executing - the `shutdown_command` for the virtual machine to actually shut down. - If it doesn't shut down in this time, it is an error. By default, the timeout - is "5m", or five minutes. +- `shutdown_timeout` (string) - The amount of time to wait after executing + the `shutdown_command` for the virtual machine to actually shut down. If it + doesn't shut down in this time, it is an error. By default, the timeout is + "5m", or five minutes. -- `skip_compaction` (bool) - If true skip compacting the hard disk for virtual machine when - exporting. This defaults to false. +- `skip_compaction` (bool) - If true skip compacting the hard disk for + virtual machine when exporting. This defaults to false. -- `switch_name` (string) - The name of the switch to connect the virtual machine to. Be defaulting - this to an empty string, Packer will try to determine the switch to use by looking for - external switch that is up and running. +- `switch_name` (string) - The name of the switch to connect the virtual + machine to. Be defaulting this to an empty string, Packer will try to + determine the switch to use by looking for external switch that is up and + running. -- switch_vlan_id` (string) - This is the vlan of the virtual switch's network card. - By default none is set. If none is set then a vlan is not set on the switch's network card. - If this value is set it should match the vlan specified in by `vlan_id`. +- `switch_vlan_id` (string) - This is the vlan of the virtual switch's + network card. By default none is set. If none is set then a vlan is not set + on the switch's network card. If this value is set it should match the vlan + specified in by `vlan_id`. -- `vlan_id` (string) - This is the vlan of the virtual machine's network card for the new virtual - machine. By default none is set. If none is set then vlans are not set on the virtual machine's - network card. +- `vlan_id` (string) - This is the vlan of the virtual machine's network card + for the new virtual machine. By default none is set. If none is set then + vlans are not set on the virtual machine's network card. -- `vm_name` (string) - This is the name of the virtual machine for the new virtual - machine, without the file extension. By default this is "packer-BUILDNAME", - where "BUILDNAME" is the name of the build. +- `vm_name` (string) - This is the name of the virtual machine for the new + virtual machine, without the file extension. By default this is + "packer-BUILDNAME", where "BUILDNAME" is the name of the build. ## Boot Command @@ -232,47 +244,47 @@ to the machine, simulating a human actually typing the keyboard. There are a set of special keys available. If these are in your boot command, they will be replaced by the proper key: -- `<bs>` - Backspace +- `<bs>` - Backspace -- `<del>` - Delete +- `<del>` - Delete -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. +- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. -- `<esc>` - Simulates pressing the escape key. +- `<esc>` - Simulates pressing the escape key. -- `<tab>` - Simulates pressing the tab key. +- `<tab>` - Simulates pressing the tab key. -- `<f1>` - `<f12>` - Simulates pressing a function key. +- `<f1>` - `<f12>` - Simulates pressing a function key. -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. +- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. -- `<spacebar>` - Simulates pressing the spacebar. +- `<spacebar>` - Simulates pressing the spacebar. -- `<insert>` - Simulates pressing the insert key. +- `<insert>` - Simulates pressing the insert key. -- `<home>` `<end>` - Simulates pressing the home and end keys. +- `<home>` `<end>` - Simulates pressing the home and end keys. -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. +- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. +- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. +- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. +- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. +- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. +- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. +- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. +- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. +- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. +- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before +- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before sending any additional keys. This is useful if you have to generally wait for the UI to update before typing more. diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 1ceb2a276..1d5ddf4bb 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -111,6 +111,9 @@ <li<%= sidebar_current("docs-builders-hyperv-iso") %>> <a href="/docs/builders/hyperv-iso.html">ISO</a> </li> + <li<%= sidebar_current("docs-builders-hyperv-vmcx") %>> + <a href="/docs/builders/hyperv-vmcx.html">VMCX</a> + </li> </ul> </li> <li<%= sidebar_current("docs-builders-lxc") %>> From 91d66fb67c450f2a8fc90be22f2b4d02e04a3b41 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:38:47 -0700 Subject: [PATCH 0044/1007] use new method of building runner --- builder/hyperv/vmcx/builder.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 9eb88dca7..a9583327a 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -471,17 +471,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ) // Run the steps. - if b.config.PackerDebug { - pauseFn := common.MultistepDebugFn(ui) - state.Put("pauseFn", pauseFn) - b.runner = &multistep.DebugRunner{ - Steps: steps, - PauseFn: pauseFn, - } - } else { - b.runner = &multistep.BasicRunner{Steps: steps} - } - + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) b.runner.Run(state) // Report any errors. From 6e9d37485aaa6f15de42a3a6b912fcdada755fb4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:41:35 -0700 Subject: [PATCH 0045/1007] make it clear that VHDs work as well as ISOs --- website/source/docs/builders/hyperv-vmcx.html.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index f5074b358..854710a23 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -161,13 +161,14 @@ can be configured for this builder. recommended since ISO files are generally large and corruption does happen from time to time. -- `iso_url` (string) - A URL to the ISO containing the installation image. - This URL can be either an HTTP URL or a file URL (or path to a file). If - this is an HTTP URL, Packer will download iso and cache it between runs. +- `iso_url` (string) - A URL to the ISO or VHD containing the installation + image. This URL can be either an HTTP URL or a file URL (or path to + a file). If this is an HTTP URL, Packer will download iso and cache it + between runs. -- `iso_urls` (array of strings) - Multiple URLs for the ISO to download. - Packer will try these in order. If anything goes wrong attempting to - download or while downloading a single URL, it will move on to the next. +- `iso_urls` (array of strings) - Multiple URLs for the ISO or VHD to + download. Packer will try these in order. If anything goes wrong attempting + to download or while downloading a single URL, it will move on to the next. All URLs must point to the same file (same checksum). By default this is empty and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified. From 2655cf74934efd2c7d74660500b08c923996de79 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Sep 2017 10:48:49 -0700 Subject: [PATCH 0046/1007] fix tests --- builder/hyperv/iso/builder_test.go | 50 ------------------------------ 1 file changed, 50 deletions(-) diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 56a4e9d7a..3fc17a8b7 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -5,7 +5,6 @@ import ( "reflect" "testing" - "fmt" "github.com/hashicorp/packer/packer" ) @@ -392,55 +391,6 @@ func TestBuilderPrepare_SizeIsRequiredWhenNotUsingExistingHarddrive(t *testing.T } } -func TestBuilderPrepare_FloppyFiles(t *testing.T) { - var b Builder - config := testConfig() - - delete(config, "floppy_files") - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("bad err: %s", err) - } - - if len(b.config.FloppyFiles) != 0 { - t.Fatalf("bad: %#v", b.config.FloppyFiles) - } - - floppies_path := "../../../common/test-fixtures/floppies" - config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)} - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } - - expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)} - if !reflect.DeepEqual(b.config.FloppyFiles, expected) { - t.Fatalf("bad: %#v", b.config.FloppyFiles) - } -} - -func TestBuilderPrepare_InvalidFloppies(t *testing.T) { - var b Builder - config := testConfig() - config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"} - b = Builder{} - _, errs := b.Prepare(config) - if errs == nil { - t.Fatalf("Nonexistent floppies should trigger multierror") - } - - if len(errs.(*packer.MultiError).Errors) != 2 { - t.Fatalf("Multierror should work and report 2 errors") - } -} - func TestBuilderPrepare_CommConfig(t *testing.T) { // Test Winrm { From 4f6a207441be69358b01c108437778dfcb80ae4a Mon Sep 17 00:00:00 2001 From: Vijaya Bhaskar Reddy Kondreddi <vijaya.reddy@ni.com> Date: Wed, 11 Oct 2017 22:10:39 +0530 Subject: [PATCH 0047/1007] go fmt --- builder/hyperv/common/step_create_vm.go | 4 ++-- common/powershell/hyperv/hyperv.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index f745514e1..d88de5558 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -47,8 +47,8 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { } else { log.Println("No existing virtual harddrive, not attaching.") } - - vhdPath := state.Get("packerVhdTempDir").(string) + + vhdPath := state.Get("packerVhdTempDir").(string) // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) diskSize := int64(s.DiskSize * 1024 * 1024) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 4d6e78b65..0c649c450 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -218,7 +218,7 @@ if ($harddrivePath){ ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName) - + if err != nil { return err } From 1c5dabe1c46caaca611cd895f59630237caaf373 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 11 Oct 2017 12:30:20 -0700 Subject: [PATCH 0048/1007] add codeowners file see https://help.github.com/articles/about-codeowners/ --- CODEOWNERS | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..cfac49475 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,18 @@ +* @hashicorp/packer + +# builders + +builder/alicloud dongxiao.zzh@alibaba-inc.com +builder/azure chrboum@microsoft.com +builder/hyperv taliesins@interxion.com +builder/lxc rampantdurandal@gmail.com +builder/lxd rampantdurandal@gmail.com +builder/oneandone jasmin@stackpointcloud.com +builder/oracle andrew.pryde@oracle.com @owainlewis +builder/profitbricks jasmin@stackpointcloud.com +builder/triton james@jen20.com sean@chittenden.org + +# provisioners + +provisioner/ansible billie.cleek@idexpertscorp.com +provisioner/converge brian@brianthicks.com From 26ed801999085d9e9f2c89edec5486a417c293d9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 11 Oct 2017 12:44:10 -0700 Subject: [PATCH 0049/1007] use github usernames and switch converge owner --- CODEOWNERS | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index cfac49475..a9db005a9 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -3,16 +3,16 @@ # builders builder/alicloud dongxiao.zzh@alibaba-inc.com -builder/azure chrboum@microsoft.com -builder/hyperv taliesins@interxion.com -builder/lxc rampantdurandal@gmail.com -builder/lxd rampantdurandal@gmail.com -builder/oneandone jasmin@stackpointcloud.com -builder/oracle andrew.pryde@oracle.com @owainlewis -builder/profitbricks jasmin@stackpointcloud.com -builder/triton james@jen20.com sean@chittenden.org +builder/azure @boumenot +builder/hyperv @taliesins +builder/lxc @ChrisLundquist +builder/lxd @ChrisLundquist +builder/oneandone @jasmingacic +builder/oracle @prydie @owainlewis +builder/profitbricks @jasmingacic +builder/triton @jen20 @sean- # provisioners -provisioner/ansible billie.cleek@idexpertscorp.com -provisioner/converge brian@brianthicks.com +provisioner/ansible @bhcleek +provisioner/converge @stevendborrelli From fef5162b01f3afe427430fa00b7af85573701fd0 Mon Sep 17 00:00:00 2001 From: localghost <zkostrzewa@gmail.com> Date: Thu, 12 Oct 2017 21:26:18 +0200 Subject: [PATCH 0050/1007] Add description of `fix_upload_owner` to documentation. --- website/source/docs/builders/docker.html.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index a36ff9cb7..b64a5b959 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -211,6 +211,10 @@ You must specify (only) one of `commit`, `discard`, or `export_path`. - `container_dir` (string) - The directory inside container to mount temp directory from host server for work [file provisioner](/docs/provisioners/file.html). By default this is set to `/packer-files`. + +- `fix_upload_owner` (boolean) - If true, files uploaded to the container will + be owned by the user the container is running as. If false, the owner will depend + on the version of docker installed in the system. Defaults to true. ## Using the Artifact: Export From 21b3ee11c333825fd02a455ca78356176091b8b3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 11 Oct 2017 14:55:59 -0700 Subject: [PATCH 0051/1007] Correct format and add amazon builders --- CODEOWNERS | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index a9db005a9..56d91a081 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,17 +2,19 @@ # builders -builder/alicloud dongxiao.zzh@alibaba-inc.com -builder/azure @boumenot -builder/hyperv @taliesins -builder/lxc @ChrisLundquist -builder/lxd @ChrisLundquist -builder/oneandone @jasmingacic -builder/oracle @prydie @owainlewis -builder/profitbricks @jasmingacic -builder/triton @jen20 @sean- +/builder/alicloud/ dongxiao.zzh@alibaba-inc.com +/builder/amazon/ebssurrogate/ @jen20 +/builder/amazon/ebsvolume/ @jen20 +/builder/azure/ @boumenot +/builder/hyperv/ @taliesins +/builder/lxc/ @ChrisLundquist +/builder/lxd/ @ChrisLundquist +/builder/oneandone/ @jasmingacic +/builder/oracle/ @prydie @owainlewis +/builder/profitbricks/ @jasmingacic +/builder/triton/ @jen20 @sean- # provisioners -provisioner/ansible @bhcleek -provisioner/converge @stevendborrelli +/provisioner/ansible/ @bhcleek +/provisioner/converge/ @stevendborrelli From 820811675d8ea7b7e94391c90a163f9e2225fd44 Mon Sep 17 00:00:00 2001 From: Olivier Bilodeau <olivier@bottomlesspit.org> Date: Fri, 13 Oct 2017 19:00:48 -0400 Subject: [PATCH 0052/1007] vmware-iso builder: Logging on network errors on connection refused --- builder/vmware/iso/driver_esx5.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 86ddf015b..8da66f0d2 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -302,6 +302,9 @@ func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) { if e.Timeout() { log.Printf("Timeout connecting to %s", record["IPAddress"]) continue + } else if strings.Contains(e.Error(), "connection refused") { + log.Printf("Connection refused when connecting to: %s", record["IPAddress"]) + continue } } } else { From 4d28aa15ff3518f37ad455c04e8435499213e6b7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Oct 2017 18:18:06 -0700 Subject: [PATCH 0053/1007] update changelog --- CHANGELOG.md | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 838f58d43..bf42b00b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,22 +2,53 @@ ### IMPROVEMENTS: -* builder/googlecompute: Support setting labels on the resulting image. [GH-5356] -* builder/amazon: Support template functions in tag keys. [GH-5381] -* core: releases will now be build for ppc64le -* builder/amazon-instance: Add `.Token` as a variable in the `BundleUploadCommand` template. [GH-5288] +* **New builder:** `hyperv-vmcx` for building images from existing VMs. + [GH-4944] [GH-5444] +* builder/amazon-instance: Add `.Token` as a variable in the + `BundleUploadCommand` template. [GH-5288] +* builder/amazon: Add `temporary_security_group_source_cidr` option to control + ingress to source instances. [GH-5384] * builder/amazon: Output AMI Name during prevalidation. [GH-5389] -* builder/docker: Add option to set `--user` flag when running `exec`. [GH-5406] -* post-processor/vagrant: When building from a builder/hyper-v artifact, link instead of copy when available. [GH-5207] -* builder/amazon: Add `temporary_security_group_source_cidr` option to control ingress to source instances. [GH-5384] -* builder/vmware: Add `disable_vnc` option to prevent VNC connections from being made. [GH-5436] +* builder/amazon: Support template functions in tag keys. [GH-5381] +* builder/amazon: Tag volumes on creation instead of as a separate step. + [GH-5417] +* builder/docker: Add option to set `--user` flag when running `exec`. + [GH-5406] +* builder/docker: Set file owner to container user when uploading. Can be + disabled by setting `fix_upload_owner` to `false`. [GH-5422] +* builder/googlecompute: Support setting labels on the resulting image. + [GH-5356] +* builder/hyper-v: Add `vhd_temp_path` option to control where the VHD resides + while it's being provisioned. [GH-5206] +* builder/hyper-v: Allow vhd or vhdx source images instead of just ISO. + [GH-4944] [GH-5444] +* builder/hyper-v: Disable automatic checkpoints. [GH-5374] +* builder/virtualbox-ovf: Add `keep_registered` option. [GH-5336] +* builder/vmware: Add `disable_vnc` option to prevent VNC connections from + being made. [GH-5436] +* core: releases will now be build for ppc64le +* post-processor/vagrant: When building from a builder/hyper-v artifact, link + instead of copy when available. [GH-5207] + ### BUG FIXES: -* builder/puppet-masterless: Make sure directories created with sudo are writable by the packer user. [GH-5351] * builder/cloudstack: Fix panic if build is aborted. [GH-5388] +* builder/hyper-v: Respect `enable_dynamic_memory` flag. [GH-5363] +* builder/puppet-masterless: Make sure directories created with sudo are + writable by the packer user. [GH-5351] +* provisioner/chef-solo: Fix issue installing chef-solo on Windows. [GH-5357] +* provisioner/powershell: Fix issue setting environment variables by writing + them to a file, instead of the command line. [GH-5345] +* provisioner/powershell: Fix issue where powershell scripts could hang. + [GH-5082] +* provisioner/powershell: Fix Powershell progress stream leak to stderr for + normal and elevated commands. [GH-5365] +* provisioner/puppet-masterless: Fix bug where `puppet_bin_dir` wasn't being + respected. [GH-5340] * provisioner/puppet: Fix setting facter vars on Windows. [GH-5341] + ## 1.1.0 (September 12, 2017) ### IMPROVEMENTS: From 5eb1c920666a4bc23afb92a29b94bd2222ea6f83 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Oct 2017 18:23:58 -0700 Subject: [PATCH 0054/1007] prepare for 1.1.1 --- CHANGELOG.md | 2 +- version/version.go | 2 +- website/config.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf42b00b8..2da665966 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## UNRELEASED +## 1.1.0 (October 13, 2017) ### IMPROVEMENTS: diff --git a/version/version.go b/version/version.go index 508df8a25..b597adb15 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ const Version = "1.1.1" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index faa4bf654..93d234cbe 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.1.0" + h.version = "1.1.1" h.github_slug = "hashicorp/packer" h.website_root = "website" end From 9c2603cf44b3f51ada2771f058aae37b4e9e1e83 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Oct 2017 18:48:57 -0700 Subject: [PATCH 0056/1007] next version is 1.1.2 --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index b597adb15..f3d38291a 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.1.1" +const Version = "1.1.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From 04ed6397502198fb3a39224435a80d53f41dfa86 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Oct 2017 18:59:58 -0700 Subject: [PATCH 0057/1007] fix doc link --- website/redirects.txt | 3 ++- website/source/docs/builders/hyperv-iso.html.md | 2 +- website/source/docs/builders/parallels-iso.html.md | 2 +- website/source/docs/builders/parallels-pvm.html.md | 2 +- website/source/docs/builders/qemu.html.md | 2 +- website/source/docs/builders/virtualbox-iso.html.md | 2 +- website/source/docs/builders/virtualbox-ovf.html.md | 2 +- website/source/docs/builders/vmware-iso.html.md | 2 +- website/source/docs/builders/vmware-vmx.html.md | 2 +- 9 files changed, 10 insertions(+), 9 deletions(-) diff --git a/website/redirects.txt b/website/redirects.txt index 62475c71c..0c7f48106 100644 --- a/website/redirects.txt +++ b/website/redirects.txt @@ -46,7 +46,8 @@ /docs/extending/developing-plugins.html /docs/extending/plugins.html /docs/extend/builder.html /docs/extending/custom-builders.html /docs/getting-started/setup.html /docs/getting-started/install.html -/docs/other/community.html /downloads-community.html +/docs/other/community.html /community-tools.html +/downloads-community.html /community-tools.html /community /community.html /community/index.html /community.html /docs/other/environmental-variables.html /docs/other/environment-variables.html diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index 7c83a9a31..c2f7e9264 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -306,7 +306,7 @@ an Ubuntu 12.04 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ## Integration Services diff --git a/website/source/docs/builders/parallels-iso.html.md b/website/source/docs/builders/parallels-iso.html.md index da7f041ad..5913c32c7 100644 --- a/website/source/docs/builders/parallels-iso.html.md +++ b/website/source/docs/builders/parallels-iso.html.md @@ -327,7 +327,7 @@ Ubuntu 12.04 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ## prlctl Commands diff --git a/website/source/docs/builders/parallels-pvm.html.md b/website/source/docs/builders/parallels-pvm.html.md index 941f06d26..ba3d9c1a9 100644 --- a/website/source/docs/builders/parallels-pvm.html.md +++ b/website/source/docs/builders/parallels-pvm.html.md @@ -232,7 +232,7 @@ In addition to the special keys, each command to type is treated as a available variables are: For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ## prlctl Commands diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index f37815b73..f9cbc1fcd 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -443,7 +443,7 @@ CentOS 6.4 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ### Troubleshooting diff --git a/website/source/docs/builders/virtualbox-iso.html.md b/website/source/docs/builders/virtualbox-iso.html.md index 887fb07d4..5fa869ecd 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md +++ b/website/source/docs/builders/virtualbox-iso.html.md @@ -415,7 +415,7 @@ Ubuntu 12.04 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ## Guest Additions diff --git a/website/source/docs/builders/virtualbox-ovf.html.md b/website/source/docs/builders/virtualbox-ovf.html.md index 7904d09dd..b8ff74d48 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md +++ b/website/source/docs/builders/virtualbox-ovf.html.md @@ -371,7 +371,7 @@ Ubuntu 12.04 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ## Guest Additions diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 29a1a7cb3..0d59274d1 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -403,7 +403,7 @@ Ubuntu 12.04 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). ## VMX Template diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index 8aac027b5..389938d8f 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -274,4 +274,4 @@ Ubuntu 12.04 installer: ``` For more examples of various boot commands, see the sample projects from our -[community templates page](/downloads-community.html#templates). +[community templates page](/community-tools.html#templates). From 986bded9d0ccb6c429e31bba23707f598157211c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Oct 2017 19:12:14 -0700 Subject: [PATCH 0058/1007] update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2da665966..61e9a1ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## (UNRELEASED) + ## 1.1.0 (October 13, 2017) ### IMPROVEMENTS: @@ -26,7 +28,7 @@ * builder/virtualbox-ovf: Add `keep_registered` option. [GH-5336] * builder/vmware: Add `disable_vnc` option to prevent VNC connections from being made. [GH-5436] -* core: releases will now be build for ppc64le +* core: Releases will now be built for ppc64le. * post-processor/vagrant: When building from a builder/hyper-v artifact, link instead of copy when available. [GH-5207] From 17beb1d7ad47f65947faa9b30f5c656a2df97b9f Mon Sep 17 00:00:00 2001 From: Pawel Kilar <pkilar@gmail.com> Date: Sat, 14 Oct 2017 21:38:44 +0100 Subject: [PATCH 0059/1007] Check if both SSH proxy and basiton are configured --- helper/communicator/config.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/helper/communicator/config.go b/helper/communicator/config.go index d89a0ac27..5ecbdfc65 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -184,6 +184,10 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error { c.SSHFileTransferMethod)) } + if c.SSHBastionHost != "" && c.SSHProxyHost != "" { + errs = append(errs, errors.New("please specify either ssh_bastion_host or ssh_proxy_host, not both")) + } + return errs } From ca8805efe22e4df75b1baa6e7b8a8f4ac7b5b57d Mon Sep 17 00:00:00 2001 From: Georg <teadur@users.noreply.github.com> Date: Sun, 15 Oct 2017 12:29:34 +0300 Subject: [PATCH 0060/1007] Update documentation to avoid confusion disk_type_id defaults to different values in local build and remote build. Documentation should reflect to what value the remote build defaults. --- website/source/docs/builders/vmware-iso.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 0d59274d1..6761c33d8 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -109,7 +109,7 @@ builder. - `disk_type_id` (string) - The type of VMware virtual disk to create. The default is "1", which corresponds to a growable virtual disk split in - 2GB files. This option is for advanced usage, modify only if you know what + 2GB files. For ESXi defaults to "zeroedthick". This option is for advanced usage, modify only if you know what you're doing. For more information, please consult the [Virtual Disk Manager User's Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. From 51d65021b16447102044158cb85ea2c5939ed0a9 Mon Sep 17 00:00:00 2001 From: Matthew Aynalem <mayn@users.noreply.github.com> Date: Sun, 15 Oct 2017 07:07:55 -0700 Subject: [PATCH 0061/1007] fix changelog version 1.1.0 => 1.1.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61e9a1ed0..5fb01de53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## (UNRELEASED) -## 1.1.0 (October 13, 2017) +## 1.1.1 (October 13, 2017) ### IMPROVEMENTS: From 159785e7b08f5136198bacb42cd6f98bd3d270f6 Mon Sep 17 00:00:00 2001 From: Charlie Egan <charlieegan3@users.noreply.github.com> Date: Sun, 15 Oct 2017 16:49:56 +0100 Subject: [PATCH 0062/1007] Fix build image section fenced example formatting --- website/source/intro/getting-started/build-image.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 23f60252d..0375b7b1b 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -203,11 +203,13 @@ how to validate and build templates into machine images. ### Another Linux Example, with provisioners: Create a file named `welcome.txt` and add the following: + ``` WELCOME TO PACKER! ``` Create a file named `example.sh` and add the following: + ``` #!/bin/bash echo "hello @@ -215,6 +217,7 @@ echo "hello Set your access key and id as environment variables, so we don't need to pass them in through the command line: + ``` export AWS_ACCESS_KEY_ID=MYACCESSKEYID export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY From caa6c9bf2234a0c618d6cb919293e7de5374a5a7 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Mon, 16 Oct 2017 00:53:18 +0900 Subject: [PATCH 0063/1007] Add clean_ami_name for gcp --- builder/googlecompute/templace_funcs.go | 44 ++++++++++++++++++++ builder/googlecompute/templace_funcs_test.go | 34 +++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 builder/googlecompute/templace_funcs.go create mode 100644 builder/googlecompute/templace_funcs_test.go diff --git a/builder/googlecompute/templace_funcs.go b/builder/googlecompute/templace_funcs.go new file mode 100644 index 000000000..cb1b6d4bf --- /dev/null +++ b/builder/googlecompute/templace_funcs.go @@ -0,0 +1,44 @@ +package googlecompute + +import ( + "regexp" + "strings" + "text/template" +) + +func isalphanumeric(b byte) bool { + if '0' <= b && b <= '9' { + return true + } + if 'a' <= b && b <= 'z' { + return true + } + return false +} + +// Clean up image name by replacing invalid characters with "-" +// truncate up to 63 length, convert to a lower case +func templateCleanAMIName(s string) string { + re := regexp.MustCompile(`^[a-z][-a-z0-9]{0,61}[a-z0-9]$`) + if re.MatchString(s) { + return s + } + b := []byte(strings.ToLower(s)) + l := 63 + if len(b) < 63 { + l = len(b) + } + newb := make([]byte, l) + for i := range newb { + if isalphanumeric(b[i]) { + newb[i] = b[i] + } else { + newb[i] = '-' + } + } + return string(newb) +} + +var TemplateFuncs = template.FuncMap{ + "clean_ami_name": templateCleanAMIName, +} diff --git a/builder/googlecompute/templace_funcs_test.go b/builder/googlecompute/templace_funcs_test.go new file mode 100644 index 000000000..36a4b475b --- /dev/null +++ b/builder/googlecompute/templace_funcs_test.go @@ -0,0 +1,34 @@ +package googlecompute + +import "testing" + +func Test_templateCleanAMIName(t *testing.T) { + vals := []struct { + origName string + expected string + }{ + { + origName: "abcde-012345xyz", + expected: "abcde-012345xyz", + }, + { + origName: "ABCDE-012345xyz", + expected: "abcde-012345xyz", + }, + { + origName: "abcde-012345v1.0.0", + expected: "abcde-012345v1-0-0", + }, + { + origName: "0123456789012345678901234567890123456789012345678901234567890123456789", + expected: "012345678901234567890123456789012345678901234567890123456789012", + }, + } + + for _, v := range vals { + name := templateCleanAMIName(v.origName) + if name != v.expected { + t.Fatalf("template names do not match: expected %s got %s\n", v.expected, name) + } + } +} From 9daabf3b12de6b4eb679f60d183c485ac113c003 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 12:27:28 +0100 Subject: [PATCH 0064/1007] Fix some typo's; Fix markdown and formatting --- .../intro/getting-started/build-image.html.md | 98 ++++++++++--------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 23f60252d..b7101dc82 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -12,7 +12,7 @@ description: |- # Build an Image With Packer installed, let's just dive right into it and build our first image. -Our first image will be an [Amazon EC2 AMI](https://aws.amazon.com/ec2/) +Our first image will be an [Amazon EC2 AMI](https://aws.amazon.com/ec2/). This is just an example. Packer can create images for [many platforms][platforms]. If you don't have an AWS account, [create one now](https://aws.amazon.com/free/). @@ -160,7 +160,7 @@ typically represent an ID (such as in the case of an AMI) or a set of files (such as for a VMware virtual machine). In this example, we only have a single artifact: the AMI in us-east-1 that was created. -This AMI is ready to use. If you wanted you could go and launch this AMI right +This AMI is ready to use. If you wanted you could go and launch this AMI right now and it would work great. -> **Note:** Your AMI ID will surely be different than the one above. If you @@ -203,18 +203,21 @@ how to validate and build templates into machine images. ### Another Linux Example, with provisioners: Create a file named `welcome.txt` and add the following: + ``` WELCOME TO PACKER! ``` Create a file named `example.sh` and add the following: -``` + +```bash #!/bin/bash -echo "hello +echo "hello" ``` -Set your access key and id as environment variables, so we don't need to pass +Set your access key and id as environment variables, so we don't need to pass them in through the command line: + ``` export AWS_ACCESS_KEY_ID=MYACCESSKEYID export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY @@ -222,7 +225,7 @@ export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY Now save the following text in a file named `firstrun.json`: -``` +```json { "variables": { "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", @@ -272,10 +275,10 @@ Now save the following text in a file named `firstrun.json`: and to build, run `packer build firstrun.json` -Note that if you wanted to use a `source_ami` instead of a `source_ami_filter` +Note that if you wanted to use a `source_ami` instead of a `source_ami_filter` it might look something like this: `"source_ami": "ami-fce3c696",` -Your output will look like this: +Your output will look like this: ``` amazon-ebs output will be in this color. @@ -314,16 +317,16 @@ amazon-ebs output will be in this color. ==> amazon-ebs: Waiting for AMI to become ready... ``` -### A windows example +### A Windows Example -Note that this uses a larger instance. You will be charged for it. Also keep -in mind that using windows AMIs incurs a fee that you don't get when you use +Note that this uses a larger instance. You will be charged for it. Also keep +in mind that using windows AMIs incurs a fee that you don't get when you use linux AMIs. -You'll need to have a boostrapping file to enable ssh or winrm; here's a basic +You'll need to have a boostrapping file to enable ssh or winrm; here's a basic example of that file. -``` +```powershell # set administrator password net user Administrator SuperS3cr3t! wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE @@ -353,16 +356,16 @@ net start winrm ``` -Save the above code in a file named `bootstrap_win.txt`. +Save the above code in a file named `bootstrap_win.txt`. -The example config below shows the two different ways of using the powershell -provisioner: `inline` and `script`. -The first example, `inline`, allows you to provide short snippets of code, and -will create the script file for you. The second example allows you to run more -complex code by providing the path to a script to run on the guest vm. +The example config below shows the two different ways of using the powershell +provisioner: `inline` and `script`. +The first example, `inline`, allows you to provide short snippets of code, and +will create the script file for you. The second example allows you to run more +complex code by providing the path to a script to run on the guest vm. -Here's an example of a `sample_script.ps1` that will work with the environment -variables we will set in our packer config; copy the contents into your own +Here's an example of a `sample_script.ps1` that will work with the environment +variables we will set in our packer config; copy the contents into your own `sample_script.ps1` and provide the path to it in your packer config: ``` @@ -375,39 +378,40 @@ Write-Output("Likewise, VAR2 is " + $Env:VAR2 ) Write-Output("and VAR3 is " + $Env:VAR3 ) ``` -Next you need to create a packer config that will use this bootstrap file. See -the example below, which contains examples of using source_ami_filter for +Next you need to create a packer config that will use this bootstrap file. See +the example below, which contains examples of using source_ami_filter for windows in addition to the powershell and windows-restart provisioners: -``` +```json { "variables": { - "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", - "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}", - "region": "us-east-1" + "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", + "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}", + "region": "us-east-1" }, "builders": [ - { - "type": "amazon-ebs", - "access_key": "{{ user `aws_access_key` }}", - "secret_key": "{{ user `aws_secret_key` }}", - "region": "us-east-1", - "instance_type": "m3.medium", - "source_ami_filter": { - "filters": { - "virtualization-type": "hvm", - "name": "*WindowsServer2012R2*", - "root-device-type": "ebs" + { + "type": "amazon-ebs", + "access_key": "{{ user `aws_access_key` }}", + "secret_key": "{{ user `aws_secret_key` }}", + "region": "us-east-1", + "instance_type": "m3.medium", + "source_ami_filter": { + "filters": { + "virtualization-type": "hvm", + "name": "*WindowsServer2012R2*", + "root-device-type": "ebs" + }, + "most_recent": true, + "owners": "amazon" }, - "most_recent": true, - "owners": "amazon" - }, - "ami_name": "packer-demo-{{timestamp}}", - "user_data_file": "./bootstrap_win.txt", - "communicator": "winrm", - "winrm_username": "Administrator", - "winrm_password": "SuperS3cr3t!" - }], + "ami_name": "packer-demo-{{timestamp}}", + "user_data_file": "./bootstrap_win.txt", + "communicator": "winrm", + "winrm_username": "Administrator", + "winrm_password": "SuperS3cr3t!" + } + ], "provisioners": [ { "type": "powershell", From 1b8238e35fbaffbadd623b7f5376e1cf931eb052 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 13:29:50 +0100 Subject: [PATCH 0065/1007] Fix missing powershell tags around User Data script --- website/source/intro/getting-started/build-image.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index b7101dc82..f0ce6f200 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -327,6 +327,7 @@ You'll need to have a boostrapping file to enable ssh or winrm; here's a basic example of that file. ```powershell +<powershell> # set administrator password net user Administrator SuperS3cr3t! wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE @@ -353,6 +354,7 @@ set-service winrm -startupType automatic # Finally, allow WinRM connections and start the service netsh advfirewall firewall set rule name="WinRM" new action=allow net start winrm +</powershell> ``` From ed0a60bd61531c1c83ec778de32482522cea91f7 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 14:02:59 +0100 Subject: [PATCH 0066/1007] Fix quotes. Use Write-Host in preference to Write-Output --- .../intro/getting-started/build-image.html.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index f0ce6f200..738dd907d 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -370,14 +370,15 @@ Here's an example of a `sample_script.ps1` that will work with the environment variables we will set in our packer config; copy the contents into your own `sample_script.ps1` and provide the path to it in your packer config: -``` -Write-Output("PACKER_BUILD_NAME is automatically set for you,) -Write-Output("or you can set it in your builder variables; ) -Write-Output("the default for this builder is: " + $Env:PACKER_BUILD_NAME ) -Write-Output("Remember that escaping variables in powershell requires backticks: ) -Write-Output("for example, VAR1 from our config is " + $Env:VAR1 ) -Write-Output("Likewise, VAR2 is " + $Env:VAR2 ) -Write-Output("and VAR3 is " + $Env:VAR3 ) +```powershell +Write-Host "PACKER_BUILD_NAME is automatically set for you, " -NoNewline +Write-Host "or you can set it in your builder variables; " -NoNewline +Write-Host "The default for this builder is:" $Env:PACKER_BUILD_NAME + +Write-Host "Use backticks as the escape character when required in powershell:" +Write-Host "For example, VAR1 from our config is:" $Env:VAR1 +Write-Host "Likewise, VAR2 is:" $Env:VAR2 +Write-Host "Finally, VAR3 is:" $Env:VAR3 ``` Next you need to create a packer config that will use this bootstrap file. See @@ -418,7 +419,7 @@ windows in addition to the powershell and windows-restart provisioners: { "type": "powershell", "environment_vars": ["DEVOPS_LIFE_IMPROVER=PACKER"], - "inline": "Write-Output(\"HELLO NEW USER; WELCOME TO $Env:DEVOPS_LIFE_IMPROVER\")" + "inline": "Write-Host \"HELLO NEW USER; WELCOME TO $Env:DEVOPS_LIFE_IMPROVER\"" }, { "type": "windows-restart" From e4985ae6f6b3c4e801e957332f99382909a5947b Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 20:55:12 +0100 Subject: [PATCH 0067/1007] Set to use a basic Windows source AMI that qualifies for free tier usage --- .../intro/getting-started/build-image.html.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 738dd907d..943f81572 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -319,11 +319,17 @@ amazon-ebs output will be in this color. ### A Windows Example -Note that this uses a larger instance. You will be charged for it. Also keep -in mind that using windows AMIs incurs a fee that you don't get when you use -linux AMIs. +As with the Linux example above, should you decide to follow along and +build an AMI from the example template, provided you qualify for free tier +usage, you should not be charged for actually building the AMI. +However, please note that you will be charged for storage of the snapshot +associated with any AMI that you create. +If you wish to avoid further charges, follow the steps in the [Managing the +Image](/intro/getting-started/build-image.html#managing-the-image) section +above to deregister the created AMI and delete the associated snapshot once +you're done. -You'll need to have a boostrapping file to enable ssh or winrm; here's a basic +You'll need to have a bootstrapping file to enable ssh or winrm; here's a basic example of that file. ```powershell @@ -398,11 +404,11 @@ windows in addition to the powershell and windows-restart provisioners: "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", "region": "us-east-1", - "instance_type": "m3.medium", + "instance_type": "t2.micro", "source_ami_filter": { "filters": { "virtualization-type": "hvm", - "name": "*WindowsServer2012R2*", + "name": "*Windows_Server-2012-R2*English-64Bit-Base*", "root-device-type": "ebs" }, "most_recent": true, From dc45bd381c3b7a8d05f8a9f560d80c7c10d96ead Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 21:07:33 +0100 Subject: [PATCH 0068/1007] Manually set up all required for remote management. Use in-built FW rules Use of 'winrm quickconfig' can sometimes cause the Packer build to fail shortly after the WinRM connection is established. * When executed the 'winrm quickconfig -q' command configures the firewall to allow management messages to be sent over HTTP (port 5985) * This undoes the previous command in the script that configured the firewall to prevent this access. * The upshot is that the system is configured and ready to accept WinRM connections earlier than intended. * If Packer establishes its WinRM connection immediately after execution of the 'winrm quickconfig -q' command, the later commands within the script that restart the WinRM service cause the established connection, and consequently, the overall build to fail. --- .../intro/getting-started/build-image.html.md | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 943f81572..6caf355cd 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -334,19 +334,22 @@ example of that file. ```powershell <powershell> -# set administrator password +# Set administrator password net user Administrator SuperS3cr3t! wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE -# First, make sure WinRM doesn't run and can't be connected to -netsh advfirewall firewall add rule name="WinRM" protocol=TCP dir=in localport=5985 action=block -net stop winrm - -# turn off PowerShell execution policy restrictions +# Turn off PowerShell execution policy restrictions Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine -# configure WinRM -winrm quickconfig -q +# First, make sure WinRM can't be connected to +netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block + +# Delete any existing WinRM listeners +winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null +winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null + +# Create a new WinRM listener and configure +winrm create winrm/config/listener?Address=*+Transport=HTTP winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}' winrm set winrm/config '@{MaxTimeoutms="7200000"}' winrm set winrm/config/service '@{AllowUnencrypted="true"}' @@ -354,12 +357,16 @@ winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}' winrm set winrm/config/service/auth '@{Basic="true"}' winrm set winrm/config/client/auth '@{Basic="true"}' -net stop winrm -set-service winrm -startupType automatic +# Configure UAC to allow privilege elevation in remote shells +$Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' +$Setting = 'LocalAccountTokenFilterPolicy' +Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force -# Finally, allow WinRM connections and start the service -netsh advfirewall firewall set rule name="WinRM" new action=allow -net start winrm +# Configure and restart the WinRM Service; Enable the required firewall exception +Stop-Service -Name WinRM +Set-Service -Name WinRM -StartupType Automatic +netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any +Start-Service -Name WinRM </powershell> ``` From 5eb68e0573b88f186d17ab1533725a970e404be1 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 21:48:48 +0100 Subject: [PATCH 0069/1007] GNU to make a happy RMS --- website/source/intro/getting-started/build-image.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 6caf355cd..25aa7a577 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -201,7 +201,7 @@ how to validate and build templates into machine images. ## Some more examples: -### Another Linux Example, with provisioners: +### Another GNU/Linux Example, with provisioners: Create a file named `welcome.txt` and add the following: ``` @@ -319,7 +319,7 @@ amazon-ebs output will be in this color. ### A Windows Example -As with the Linux example above, should you decide to follow along and +As with the GNU/Linux example above, should you decide to follow along and build an AMI from the example template, provided you qualify for free tier usage, you should not be charged for actually building the AMI. However, please note that you will be charged for storage of the snapshot From 10af3770c756a2a6f6bd6ca0af28e2449f09d27f Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 23:42:52 +0100 Subject: [PATCH 0070/1007] New sample output to match changes --- .../intro/getting-started/build-image.html.md | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 25aa7a577..bf8a70637 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -457,38 +457,39 @@ You should see output like this: ``` amazon-ebs output will be in this color. -==> amazon-ebs: Prevalidating AMI Name: packer-demo-1507234504 - amazon-ebs: Found Image ID: ami-d79776ad -==> amazon-ebs: Creating temporary keypair: packer_59d692c8-81f9-6a15-2502-0ca730980bed -==> amazon-ebs: Creating temporary security group for this instance: packer_59d692f0-dd01-6879-d8f8-7765327f5365 -==> amazon-ebs: Authorizing access to port 5985 on the temporary security group... +==> amazon-ebs: Prevalidating AMI Name: packer-demo-1507933843 + amazon-ebs: Found Image ID: ami-23d93c59 +==> amazon-ebs: Creating temporary keypair: packer_59e13e94-203a-1bca-5327-bebf0d5ad15a +==> amazon-ebs: Creating temporary security group for this instance: packer_59e13ea9-3220-8dab-29c0-ed7f71e221a1 +==> amazon-ebs: Authorizing access to port 5985 from 0.0.0.0/0 in the temporary security group... ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Adding tags to source instance amazon-ebs: Adding tag: "Name": "Packer Builder" - amazon-ebs: Instance ID: i-04467596029d0a2ff -==> amazon-ebs: Waiting for instance (i-04467596029d0a2ff) to become ready... + amazon-ebs: Instance ID: i-0349406ac85f02166 +==> amazon-ebs: Waiting for instance (i-0349406ac85f02166) to become ready... ==> amazon-ebs: Skipping waiting for password since WinRM password set... ==> amazon-ebs: Waiting for WinRM to become available... amazon-ebs: WinRM connected. ==> amazon-ebs: Connected to WinRM! ==> amazon-ebs: Provisioning with Powershell... -==> amazon-ebs: Provisioning with powershell script: /var/folders/8t/0yb5q0_x6mb2jldqq_vjn3lr0000gn/T/packer-powershell-provisioner079851514 +==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner175214995 amazon-ebs: HELLO NEW USER; WELCOME TO PACKER ==> amazon-ebs: Restarting Machine ==> amazon-ebs: Waiting for machine to restart... - amazon-ebs: WIN-164614OO21O restarted. + amazon-ebs: WIN-TEM0TDL751M restarted. ==> amazon-ebs: Machine successfully restarted, moving on ==> amazon-ebs: Provisioning with Powershell... -==> amazon-ebs: Provisioning with powershell script: ./scripts/sample_script.ps1 - amazon-ebs: PACKER_BUILD_NAME is automatically set for you, or you can set it in your builder variables; the default for this builder is: amazon-ebs - amazon-ebs: Remember that escaping variables in powershell requires backticks; for example VAR1 from our config is A$Dollar - amazon-ebs: Likewise, VAR2 is A`Backtick - amazon-ebs: and VAR3 is A'SingleQuote +==> amazon-ebs: Provisioning with powershell script: ./sample_script.ps1 + amazon-ebs: PACKER_BUILD_NAME is automatically set for you, or you can set it in your builder variables; The default for this builder is: amazon-ebs + amazon-ebs: Use backticks as the escape character when required in powershell: + amazon-ebs: For example, VAR1 from our config is: A$Dollar + amazon-ebs: Likewise, VAR2 is: A`Backtick + amazon-ebs: Finally, VAR3 is: A'SingleQuote ==> amazon-ebs: Stopping the source instance... amazon-ebs: Stopping instance, attempt 1 ==> amazon-ebs: Waiting for the instance to stop... -==> amazon-ebs: Creating the AMI: packer-demo-1507234504 - amazon-ebs: AMI: ami-2970b753 +==> amazon-ebs: Creating the AMI: packer-demo-1507933843 + amazon-ebs: AMI: ami-100fc56a ==> amazon-ebs: Waiting for AMI to become ready... ==> amazon-ebs: Terminating the source AWS instance... ==> amazon-ebs: Cleaning up any extra volumes... @@ -499,7 +500,7 @@ Build 'amazon-ebs' finished. ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: -us-east-1: ami-2970b753 +us-east-1: ami-100fc56a ``` And if you navigate to your EC2 dashboard you should see your shiny new AMI. From e1d88ffaabda2fb2df3a4748f4326b41a3348964 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 13 Oct 2017 23:48:39 +0100 Subject: [PATCH 0071/1007] Export of AWS creds for users who skipped over the GNU/Linux example --- website/source/intro/getting-started/build-image.html.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index bf8a70637..550dbefe7 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -450,6 +450,14 @@ windows in addition to the powershell and windows-restart provisioners: } ``` +Set your access key and id as environment variables, so we don't need to pass +them in through the command line: + +``` +export AWS_ACCESS_KEY_ID=MYACCESSKEYID +export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY +``` + Then `packer build firstrun.json` You should see output like this: From 6d4e8ab583acf96cd05610ccf52282601fef0cbd Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sat, 14 Oct 2017 01:29:49 +0100 Subject: [PATCH 0072/1007] Suggest Windows 2008 and 2016 and add name filter --- .../intro/getting-started/build-image.html.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 550dbefe7..7d897d05d 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -513,5 +513,25 @@ us-east-1: ami-100fc56a And if you navigate to your EC2 dashboard you should see your shiny new AMI. +Why stop there though? + +As you'll see, with one simple change to the template above, it's +just as easy to create your own Windows 2008 or Windows 2016 AMIs. Just +set the value for the name field within `source_ami_filter` as required: + +For Windows 2008 SP2: + +``` + "name": "*Windows_Server-2008-SP2*English-64Bit-Base*", +``` + +For Windows 2016: + +``` + "name": "*Windows_Server-2016-English-Full-Base*", +``` + +The bootstrapping and sample provisioning should work the same across all +Windows server versions. [platforms]: /docs/builders/index.html From 69393ef9bba2aa751c8e31ff2946a27fa3bdc3b0 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sat, 14 Oct 2017 01:49:50 +0100 Subject: [PATCH 0073/1007] No need to set execution policy. AWS default is unrestricted --- website/source/intro/getting-started/build-image.html.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 7d897d05d..38c3bf301 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -338,9 +338,6 @@ example of that file. net user Administrator SuperS3cr3t! wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE -# Turn off PowerShell execution policy restrictions -Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine - # First, make sure WinRM can't be connected to netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block From 400f210dc2d94083414845291dd6d2a6a2150fba Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sat, 14 Oct 2017 02:07:58 +0100 Subject: [PATCH 0074/1007] Set region to use user configured variable --- website/source/intro/getting-started/build-image.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 38c3bf301..647946c6b 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -407,7 +407,7 @@ windows in addition to the powershell and windows-restart provisioners: "type": "amazon-ebs", "access_key": "{{ user `aws_access_key` }}", "secret_key": "{{ user `aws_secret_key` }}", - "region": "us-east-1", + "region": "{{ user `region` }}", "instance_type": "t2.micro", "source_ami_filter": { "filters": { From 26319ee74be61361a76d5a7680854c7faacaf247 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sun, 15 Oct 2017 23:50:59 +0100 Subject: [PATCH 0075/1007] Additional explanations possibly needed by a user new to Packer or AWS --- .../intro/getting-started/build-image.html.md | 95 ++++++++++++++++--- 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 647946c6b..2cdddf544 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -329,8 +329,47 @@ Image](/intro/getting-started/build-image.html#managing-the-image) section above to deregister the created AMI and delete the associated snapshot once you're done. -You'll need to have a bootstrapping file to enable ssh or winrm; here's a basic -example of that file. +Again, in this example, we are making use of an existing AMI available from +the Amazon marketplace as the *source* or starting point for building our +own AMI. In brief, Packer will spin up the source AMI, connect to it and then +run whatever commands or scripts we've configured in our build template to +customize the image. Finally, when all is done, Packer will wrap the whole +customized package up into a brand new AMI that will be available from the +[AWS AMI management page]( +https://console.aws.amazon.com/ec2/home?region=us-east-1#s=Images). Any +instances we subsequently create from this AMI will have our all of our +customizations baked in. This is the core benefit we are looking to +achieve from using the [Amazon EBS builder](/docs/builders/amazon-ebs.html) +in this example. + +Now, all this sounds simple enough right? Well, actually it turns out we +need to put in just a *bit* more effort to get things working as we'd like... + +Here's the issue: Out of the box, the instance created from our source AMI +is not configured to allow Packer to connect to it. So how do we fix it so +that Packer can connect in and customize our instance? + +Well, it turns out that Amazon provides a mechanism that allows us to run a +set of *pre-supplied* commands within the instance shortly after the instance +starts. Even better, Packer is aware of this mechanism. This gives us the +ability to supply Packer with the commands required to configure the instance +for a remote connection *in advance*. Once the commands are run, Packer +will be able to connect directly in to the instance and make the +customizations we need. + +Here's a basic example of a file that will configure the instance to allow +Packer to connect in over WinRM. As you will see, we will tell Packer about +our intentions by referencing this file and the commands within it from +within the `"builders"` section of our +[build template](/docs/templates/index.html) that we will create later. + +Note the `<powershell>` and `</powershell>` tags at the top and bottom of +the file. These tags tell Amazon we'd like to run the enclosed code with +PowerShell. You can also use `<script></script>` tags to enclose any commands +that you would normally run in a Command Prompt window. See +[Running Commands on Your Windows Instance at Launch]( +http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html) +for more info about what's going on behind the scenes here. ```powershell <powershell> @@ -367,18 +406,22 @@ Start-Service -Name WinRM </powershell> ``` - Save the above code in a file named `bootstrap_win.txt`. -The example config below shows the two different ways of using the powershell -provisioner: `inline` and `script`. +Now we've got the business of getting Packer connected to our instance +taken care of, let's get on with the *real* reason we're doing all this, +which is actually configuring and customizing the instance. Again, we do this +with [Provisioners](/docs/provisioners/index.html). + +The example config below shows the two different ways of using the [PowerShell +provisioner](/docs/provisioners/powershell.html): `inline` and `script`. The first example, `inline`, allows you to provide short snippets of code, and will create the script file for you. The second example allows you to run more -complex code by providing the path to a script to run on the guest vm. +complex code by providing the path to a script to run on the guest VM. Here's an example of a `sample_script.ps1` that will work with the environment -variables we will set in our packer config; copy the contents into your own -`sample_script.ps1` and provide the path to it in your packer config: +variables we will set in our build template; copy the contents into your own +`sample_script.ps1` and provide the path to it in your build template: ```powershell Write-Host "PACKER_BUILD_NAME is automatically set for you, " -NoNewline @@ -391,9 +434,27 @@ Write-Host "Likewise, VAR2 is:" $Env:VAR2 Write-Host "Finally, VAR3 is:" $Env:VAR3 ``` -Next you need to create a packer config that will use this bootstrap file. See -the example below, which contains examples of using source_ami_filter for -windows in addition to the powershell and windows-restart provisioners: +Finally, we need to create the actual [build template]( +/docs/templates/index.html). +Remember, this template is the core configuration file that Packer uses to +understand what you want to build, and how you want to build it. + +As mentioned earlier, the specific builder we are using in this example +is the [Amazon EBS builder](/docs/builders/amazon-ebs.html). +The template below demonstrates use of the [`source_ami_filter`]( +/docs/builders/amazon-ebs.html#source_ami_filter) configuration option +available within the builder for automatically selecting the *latest* +suitable source Windows AMI provided by Amazon. +We also use the `user_data_file` configuration option provided by the builder +to reference the bootstrap file we created earlier. As you will recall, our +bootstrap file contained all the commands we needed to supply in advance of +actually spinning up the instance, so that later on, our instance is +configured to allow Packer to connect in to it. + +The `"provisioners"` section of the template demonstrates use of the +[powershell](/docs/provisioners/powershell.html) and +[windows-restart](/docs/provisioners/windows-restart.html) provisioners to +customize and control the build process: ```json { @@ -447,15 +508,18 @@ windows in addition to the powershell and windows-restart provisioners: } ``` -Set your access key and id as environment variables, so we don't need to pass -them in through the command line: +Save the build template as `firstrun.json`. + +Next we need to set things up so that Packer is able to access and use our +AWS account. Set your access key and id as environment variables, so we +don't need to pass them in through the command line: ``` export AWS_ACCESS_KEY_ID=MYACCESSKEYID export AWS_SECRET_ACCESS_KEY=MYSECRETACCESSKEY ``` -Then `packer build firstrun.json` +Finally, we can create our new AMI by running `packer build firstrun.json` You should see output like this: @@ -508,7 +572,8 @@ Build 'amazon-ebs' finished. us-east-1: ami-100fc56a ``` -And if you navigate to your EC2 dashboard you should see your shiny new AMI. +And if you navigate to your EC2 dashboard you should see your shiny new AMI +listed in the main window of the Images -> AMIs section. Why stop there though? From c9e6ffa91c459587e47f16e03bb13bfcab6b23a6 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Mon, 16 Oct 2017 02:45:56 +0100 Subject: [PATCH 0076/1007] Add warning note about using the 'winrm quickconfig -q' command A lot of examples out there on the web make use of this command to configure the instance to allow connections over WinRM. Since the danger is not immediately obvious and the failure because of its use intermittent, we should do our best to advise against its use here. --- .../intro/getting-started/build-image.html.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 2cdddf544..c66b04d04 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -408,6 +408,29 @@ Start-Service -Name WinRM Save the above code in a file named `bootstrap_win.txt`. +-> **A quick aside/warning:** +Windows administrators in the know might be wondering why we haven't simply +used a `winrm quickconfig -q` command in the script above, as this would +*automatically* set up all of the required elements necessary for connecting +over WinRM. Why all the extra effort to configure things manually? +Well, long and short, use of the `winrm quickconfig -q` command can sometimes +cause the Packer build to fail shortly after the WinRM connection is +established. How? +1. Among other things, as well as setting up the listener for WinRM, the +quickconfig command also configures the firewall to allow management messages +to be sent over HTTP. +2. This undoes the previous command in the script that configured the +firewall to prevent this access. +3. The upshot is that the system is configured and ready to accept WinRM +connections earlier than intended. +4. If Packer establishes its WinRM connection immediately after execution of +the 'winrm quickconfig -q' command, the later commands within the script that +restart the WinRM service will unceremoniously pull the rug out from under +the connection. +5. While Packer does *a lot* to ensure the stability of its connection in to +your instance, this sort of abuse can prove to be too much and *may* cause +your Packer build to stall irrecoverably or fail! + Now we've got the business of getting Packer connected to our instance taken care of, let's get on with the *real* reason we're doing all this, which is actually configuring and customizing the instance. Again, we do this From 2da4e4c31db74e8d65d4fc5d1cf829f5fc55d6b6 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Mon, 16 Oct 2017 11:45:18 +0900 Subject: [PATCH 0077/1007] Change func name --- builder/googlecompute/templace_funcs.go | 4 ++-- builder/googlecompute/templace_funcs_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/googlecompute/templace_funcs.go b/builder/googlecompute/templace_funcs.go index cb1b6d4bf..0831cf410 100644 --- a/builder/googlecompute/templace_funcs.go +++ b/builder/googlecompute/templace_funcs.go @@ -18,7 +18,7 @@ func isalphanumeric(b byte) bool { // Clean up image name by replacing invalid characters with "-" // truncate up to 63 length, convert to a lower case -func templateCleanAMIName(s string) string { +func templateCleanImageName(s string) string { re := regexp.MustCompile(`^[a-z][-a-z0-9]{0,61}[a-z0-9]$`) if re.MatchString(s) { return s @@ -40,5 +40,5 @@ func templateCleanAMIName(s string) string { } var TemplateFuncs = template.FuncMap{ - "clean_ami_name": templateCleanAMIName, + "clean_image_name": templateCleanImageName, } diff --git a/builder/googlecompute/templace_funcs_test.go b/builder/googlecompute/templace_funcs_test.go index 36a4b475b..b943ab911 100644 --- a/builder/googlecompute/templace_funcs_test.go +++ b/builder/googlecompute/templace_funcs_test.go @@ -2,7 +2,7 @@ package googlecompute import "testing" -func Test_templateCleanAMIName(t *testing.T) { +func Test_templateCleanImageName(t *testing.T) { vals := []struct { origName string expected string @@ -26,7 +26,7 @@ func Test_templateCleanAMIName(t *testing.T) { } for _, v := range vals { - name := templateCleanAMIName(v.origName) + name := templateCleanImageName(v.origName) if name != v.expected { t.Fatalf("template names do not match: expected %s got %s\n", v.expected, name) } From 3716effa757877ac98a06effbb4b9f7563709d3f Mon Sep 17 00:00:00 2001 From: Matthew Aynalem <mayn@users.noreply.github.com> Date: Mon, 16 Oct 2017 09:11:33 -0700 Subject: [PATCH 0078/1007] docs: correct datatype inconsistencies bool => boolean (issue #5468) --- website/source/docs/builders/alicloud-ecs.html.md | 10 +++++----- website/source/docs/builders/amazon-chroot.html.md | 2 +- website/source/docs/builders/amazon-ebs.html.md | 2 +- .../source/docs/builders/amazon-ebssurrogate.html.md | 2 +- website/source/docs/builders/amazon-ebsvolume.html.md | 2 +- website/source/docs/builders/amazon-instance.html.md | 2 +- website/source/docs/builders/hyperv-iso.html.md | 10 +++++----- website/source/docs/builders/hyperv-vmcx.html.md | 10 +++++----- website/source/docs/builders/vmware-iso.html.md | 2 +- website/source/docs/builders/vmware-vmx.html.md | 2 +- .../docs/post-processors/alicloud-import.html.md | 2 +- .../docs/post-processors/googlecompute-export.html.md | 2 +- website/source/docs/post-processors/manifest.html.md | 2 +- website/source/docs/provisioners/ansible.html.md | 2 +- website/source/docs/provisioners/converge.html.md | 4 ++-- website/source/docs/provisioners/shell.html.md | 2 +- 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index 4042e526e..6a0a97bb3 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -50,7 +50,7 @@ builder. ### Optional: -- `skip_region_validation` (bool) - The region validation can be skipped if this +- `skip_region_validation` (boolean) - The region validation can be skipped if this value is true, the default value is false. - `image_description` (string) - The description of the image, with a length @@ -71,12 +71,12 @@ builder. letter or a Chinese character, and may contain numbers, `_` or `-`. It cannot begin with `http://` or `https://`. -- `image_force_delete` (bool) - If this value is true, when the target image name +- `image_force_delete` (boolean) - If this value is true, when the target image name is duplicated with an existing image, it will delete the existing image and then create the target image, otherwise, the creation will fail. The default value is false. -- `image_force_delete_snapshots` (bool) - If this value is true, when delete the +- `image_force_delete_snapshots` (boolean) - If this value is true, when delete the duplicated existing image, the source snapshot of this image will be delete either. @@ -116,11 +116,11 @@ builder. - `zone_id` (string) - ID of the zone to which the disk belongs. -- `io_optimized` (bool) - I/O optimized. +- `io_optimized` (boolean) - I/O optimized. Default value: false for Generation I instances; true for other instances. -- `force_stop_instance` (bool) - Whether to force shutdown upon device restart. +- `force_stop_instance` (boolean) - Whether to force shutdown upon device restart. The default value is `false`. If it is set to `false`, the system is shut down normally; if it is set to diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 90da1a8f7..2d6af0a27 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -289,7 +289,7 @@ each category, the available configuration keys are alphabetized. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. This is helpful to limit the AMIs to a trusted third party, or to your own account. - - `most_recent` (bool) - Selects the newest created image when true. + - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index db438116d..7ceffcc68 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -290,7 +290,7 @@ builder. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. This is helpful to limit the AMIs to a trusted third party, or to your own account. - - `most_recent` (bool) - Selects the newest created image when true. + - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - `spot_price` (string) - The maximum hourly price to pay for a spot instance diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 57fd3408b..bf7ca7acc 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -283,7 +283,7 @@ builder. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. This is helpful to limit the AMIs to a trusted third party, or to your own account. - - `most_recent` (bool) - Selects the newest created image when true. + - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - `spot_price` (string) - The maximum hourly price to pay for a spot instance diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 78a9815e9..418a342e4 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -196,7 +196,7 @@ builder. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. This is helpful to limit the AMIs to a trusted third party, or to your own account. - - `most_recent` (bool) - Selects the newest created image when true. + - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - `spot_price` (string) - The maximum hourly price to pay for a spot instance diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 17be8a297..1b112a57f 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -288,7 +288,7 @@ builder. - `owners` (array of strings) - This scopes the AMIs to certain Amazon account IDs. This is helpful to limit the AMIs to a trusted third party, or to your own account. - - `most_recent` (bool) - Selects the newest created image when true. + - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index c2f7e9264..18853abc2 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -91,16 +91,16 @@ can be configured for this builder. - `disk_size` (integer) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40 GB. -- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual machine. +- `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual machine. This defaults to false. -- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual machine. +- `enable_mac_spoofing` (boolean) - If true enable mac spoofing for virtual machine. This defaults to false. -- `enable_secure_boot` (bool) - If true enable secure boot for virtual machine. +- `enable_secure_boot` (boolean) - If true enable secure boot for virtual machine. This defaults to false. -- `enable_virtualization_extensions` (bool) - If true enable virtualization extensions for virtual machine. +- `enable_virtualization_extensions` (boolean) - If true enable virtualization extensions for virtual machine. This defaults to false. For nested virtualization you need to enable mac spoofing, disable dynamic memory and have at least 4GB of RAM for virtual machine. @@ -187,7 +187,7 @@ can be configured for this builder. If it doesn't shut down in this time, it is an error. By default, the timeout is "5m", or five minutes. -- `skip_compaction` (bool) - If true skip compacting the hard disk for virtual machine when +- `skip_compaction` (boolean) - If true skip compacting the hard disk for virtual machine when exporting. This defaults to false. - `switch_name` (string) - The name of the switch to connect the virtual machine to. Be defaulting diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index 854710a23..59c75199c 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -96,16 +96,16 @@ can be configured for this builder. - `cpu` (integer) - The number of cpus the virtual machine should use. If this isn't specified, the default is 1 cpu. -- `enable_dynamic_memory` (bool) - If true enable dynamic memory for virtual +- `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual machine. This defaults to false. -- `enable_mac_spoofing` (bool) - If true enable mac spoofing for virtual +- `enable_mac_spoofing` (boolean) - If true enable mac spoofing for virtual machine. This defaults to false. -- `enable_secure_boot` (bool) - If true enable secure boot for virtual +- `enable_secure_boot` (boolean) - If true enable secure boot for virtual machine. This defaults to false. -- `enable_virtualization_extensions` (bool) - If true enable virtualization +- `enable_virtualization_extensions` (boolean) - If true enable virtualization extensions for virtual machine. This defaults to false. For nested virtualization you need to enable mac spoofing, disable dynamic memory and have at least 4GB of RAM for virtual machine. @@ -208,7 +208,7 @@ can be configured for this builder. doesn't shut down in this time, it is an error. By default, the timeout is "5m", or five minutes. -- `skip_compaction` (bool) - If true skip compacting the hard disk for +- `skip_compaction` (boolean) - If true skip compacting the hard disk for virtual machine when exporting. This defaults to false. - `switch_name` (string) - The name of the switch to connect the virtual diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 0d59274d1..c5f5c9d34 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -114,7 +114,7 @@ builder. User's Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. -* `disable_vnc` (bool) - Whether to create a VNC connection or not. +* `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. - `floppy_files` (array of strings) - A list of files to place onto a floppy diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index 389938d8f..565ae097e 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -71,7 +71,7 @@ builder. five seconds and one minute 30 seconds, respectively. If this isn't specified, the default is 10 seconds. -* `disable_vnc` (bool) - Whether to create a VNC connection or not. +* `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. - `floppy_files` (array of strings) - A list of files to place onto a floppy diff --git a/website/source/docs/post-processors/alicloud-import.html.md b/website/source/docs/post-processors/alicloud-import.html.md index 356eea84b..d2ab30547 100644 --- a/website/source/docs/post-processors/alicloud-import.html.md +++ b/website/source/docs/post-processors/alicloud-import.html.md @@ -72,7 +72,7 @@ two categories: required and optional parameters. limit of 0 to 256 characters. Leaving it blank means null, which is the default value. It cannot begin with <http://> or <https://>. -- `image_force_delete` (bool) - If this value is true, when the target image +- `image_force_delete` (boolean) - If this value is true, when the target image name is duplicated with an existing image, it will delete the existing image and then create the target image, otherwise, the creation will fail. The default value is false. diff --git a/website/source/docs/post-processors/googlecompute-export.html.md b/website/source/docs/post-processors/googlecompute-export.html.md index 071d188fb..346721fb1 100644 --- a/website/source/docs/post-processors/googlecompute-export.html.md +++ b/website/source/docs/post-processors/googlecompute-export.html.md @@ -34,7 +34,7 @@ permissions to the GCS `paths`. ### Optional -- `keep_input_artifact` (bool) - If true, do not delete the Google Compute Engine +- `keep_input_artifact` (boolean) - If true, do not delete the Google Compute Engine (GCE) image being exported. ## Basic Example diff --git a/website/source/docs/post-processors/manifest.html.md b/website/source/docs/post-processors/manifest.html.md index 774884fea..73b691c1b 100644 --- a/website/source/docs/post-processors/manifest.html.md +++ b/website/source/docs/post-processors/manifest.html.md @@ -24,7 +24,7 @@ You can specify manifest more than once and write each build to its own file, or ### Optional: - `output` (string) The manifest will be written to this file. This defaults to `packer-manifest.json`. -- `strip_path` (bool) Write only filename without the path to the manifest file. This defaults to false. +- `strip_path` (boolean) Write only filename without the path to the manifest file. This defaults to false. ### Example Configuration diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 97e548696..5ea4de0f2 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -103,7 +103,7 @@ Optional Parameters: files. The command should read and write on stdin and stdout, respectively. Defaults to `/usr/lib/sftp-server -e`. -- `skip_version_check` (bool) - Check if ansible is installed prior to running. +- `skip_version_check` (boolean) - Check if ansible is installed prior to running. Set this to `true`, for example, if you're going to install ansible during the packer run. diff --git a/website/source/docs/provisioners/converge.html.md b/website/source/docs/provisioners/converge.html.md index 0673f2f32..b76652abe 100644 --- a/website/source/docs/provisioners/converge.html.md +++ b/website/source/docs/provisioners/converge.html.md @@ -59,14 +59,14 @@ Optional parameters: various [configuration template variables](/docs/templates/engine.html) available. -- `prevent_sudo` (bool) - stop Converge from running with adminstrator +- `prevent_sudo` (boolean) - stop Converge from running with adminstrator privileges via sudo - `bootstrap_command` (string) - the command used to bootstrap Converge. This has various [configuration template variables](/docs/templates/engine.html) available. -- `prevent_bootstrap_sudo` (bool) - stop Converge from bootstrapping with +- `prevent_bootstrap_sudo` (boolean) - stop Converge from bootstrapping with administrator privileges via sudo ### Module Directories diff --git a/website/source/docs/provisioners/shell.html.md b/website/source/docs/provisioners/shell.html.md index 77b9a7659..827c04c62 100644 --- a/website/source/docs/provisioners/shell.html.md +++ b/website/source/docs/provisioners/shell.html.md @@ -72,7 +72,7 @@ Optional parameters: available variables: `Path`, which is the path to the script to run, and `Vars`, which is the list of `environment_vars`, if configured. -- `expect_disconnect` (bool) - Defaults to `false`. Whether to error if the +- `expect_disconnect` (boolean) - Defaults to `false`. Whether to error if the server disconnects us. A disconnect might happen if you restart the ssh server or reboot the host. From 1967c4bc81e51be23ba09b67544f6c33054a801b Mon Sep 17 00:00:00 2001 From: Matthew Aynalem <mayn@users.noreply.github.com> Date: Mon, 16 Oct 2017 11:23:33 -0700 Subject: [PATCH 0079/1007] docs correct datatype inconsistencies int/integer => number (issue #5468) --- website/source/docs/builders/alicloud-ecs.html.md | 2 +- website/source/docs/builders/amazon-chroot.html.md | 8 ++++---- website/source/docs/builders/amazon-ebs.html.md | 4 ++-- .../source/docs/builders/amazon-ebssurrogate.html.md | 4 ++-- website/source/docs/builders/amazon-ebsvolume.html.md | 4 ++-- website/source/docs/builders/amazon-instance.html.md | 4 ++-- website/source/docs/builders/azure.html.md | 2 +- website/source/docs/builders/cloudstack.html.md | 6 +++--- website/source/docs/builders/googlecompute.html.md | 4 ++-- website/source/docs/builders/hyperv-iso.html.md | 10 +++++----- website/source/docs/builders/hyperv-vmcx.html.md | 6 +++--- website/source/docs/builders/lxc.html.md | 2 +- website/source/docs/builders/oneandone.html.md | 2 +- website/source/docs/builders/parallels-iso.html.md | 4 ++-- website/source/docs/builders/profitbricks.html.md | 4 ++-- website/source/docs/builders/qemu.html.md | 8 ++++---- website/source/docs/builders/virtualbox-iso.html.md | 10 +++++----- website/source/docs/builders/virtualbox-ovf.html.md | 6 +++--- website/source/docs/builders/vmware-iso.html.md | 6 +++--- website/source/docs/builders/vmware-vmx.html.md | 4 ++-- website/source/docs/other/core-configuration.html.md | 2 +- .../docs/post-processors/alicloud-import.html.md | 2 +- website/source/docs/post-processors/compress.html.md | 2 +- website/source/docs/post-processors/vagrant.html.md | 2 +- website/source/docs/templates/communicator.html.md | 8 ++++---- 25 files changed, 58 insertions(+), 58 deletions(-) diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index 6a0a97bb3..c19da9152 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -92,7 +92,7 @@ builder. Default value: cloud. -- `disk_size` (int) - Size of the system disk, in GB, values range: +- `disk_size` (number) - Size of the system disk, in GB, values range: - cloud - 5 ~ 2000 - cloud\_efficiency - 20 ~ 2048 - cloud\_ssd - 20 ~ 2048 diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 2d6af0a27..86a723a63 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -171,7 +171,7 @@ each category, the available configuration keys are alphabetized. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not - - `iops` (integer) - The number of I/O operations per second (IOPS) that the + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) for more information @@ -186,7 +186,7 @@ each category, the available configuration keys are alphabetized. Mapping](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html) for more information - - `volume_size` (integer) - The size of the volume, in GiB. Required if not + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` - `volume_type` (string) - The volume type. gp2 for General Purpose (SSD) @@ -213,7 +213,7 @@ each category, the available configuration keys are alphabetized. where the `.Device` variable is replaced with the name of the device where the volume is attached. -- `mount_partition` (integer) - The partition number containing the +- `mount_partition` (number) - The partition number containing the / partition. By default this is the first partition of the volume. - `mount_options` (array of strings) - Options to supply the `mount` command @@ -239,7 +239,7 @@ each category, the available configuration keys are alphabetized. mount and copy steps. The device and mount path are provided by `{{.Device}}` and `{{.MountPath}}`. -- `root_volume_size` (integer) - The size of the root volume in GB for the +- `root_volume_size` (number) - The size of the root volume in GB for the chroot environment and the resulting AMI. Default size is the snapshot size of the `source_ami` unless `from_scratch` is `true`, in which case this field must be defined. diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 7ceffcc68..aebd97e75 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -87,7 +87,7 @@ builder. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not - - `iops` (integer) - The number of I/O operations per second (IOPS) that the + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) for more information @@ -102,7 +102,7 @@ builder. Mapping](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html) for more information - - `volume_size` (integer) - The size of the volume, in GiB. Required if not + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index bf7ca7acc..caa5e3699 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -80,7 +80,7 @@ builder. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not - - `iops` (integer) - The number of I/O operations per second (IOPS) that the + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) for more information @@ -95,7 +95,7 @@ builder. Mapping](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html) for more information - - `volume_size` (integer) - The size of the volume, in GiB. Required if not + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 418a342e4..481cfbae1 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -67,7 +67,7 @@ builder. - `delete_on_termination` (boolean) - Indicates whether the EBS volume is deleted on instance termination - `encrypted` (boolean) - Indicates whether to encrypt the volume or not - - `iops` (integer) - The number of I/O operations per second (IOPS) that the + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) for more information @@ -78,7 +78,7 @@ builder. [Block Device Mapping](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html) for more information - - `volume_size` (integer) - The size of the volume, in GiB. Required if not + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) volumes, `io1` for Provisioned IOPS (SSD) volumes, and `standard` for Magnetic diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 1b112a57f..c92ca8f97 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -109,7 +109,7 @@ builder. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not - - `iops` (integer) - The number of I/O operations per second (IOPS) that the + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) for more information @@ -124,7 +124,7 @@ builder. Mapping](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_BlockDeviceMapping.html) for more information - - `volume_size` (integer) - The size of the volume, in GiB. Required if not + - `volume_size` (number) - The size of the volume, in GiB. Required if not specifying a `snapshot_id` - `volume_type` (string) - The volume type. `gp2` for General Purpose (SSD) diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index c497ec0f5..bcb2b5d77 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -120,7 +120,7 @@ When creating a managed image the following two options are required. Windows; this variable is not used by non-Windows builds. See `Windows` behavior for `os_type`, below. -- `os_disk_size_gb` (int32) Specify the size of the OS disk in GB (gigabytes). Values of zero or less than zero are +- `os_disk_size_gb` (number) Specify the size of the OS disk in GB (gigabytes). Values of zero or less than zero are ignored. - `os_type` (string) If either `Linux` or `Windows` is specified Packer will diff --git a/website/source/docs/builders/cloudstack.html.md b/website/source/docs/builders/cloudstack.html.md index 4a7f92ca9..9268d628b 100644 --- a/website/source/docs/builders/cloudstack.html.md +++ b/website/source/docs/builders/cloudstack.html.md @@ -66,7 +66,7 @@ builder. ### Optional: -- `async_timeout` (int) - The time duration to wait for async calls to +- `async_timeout` (number) - The time duration to wait for async calls to finish. Defaults to 30m. - `cidr_list` (array) - List of CIDR's that will have access to the new @@ -83,7 +83,7 @@ builder. instance. This option is only available (and also required) when using `source_iso`. -- `disk_size` (int) - The size (in GB) of the root disk of the new instance. +- `disk_size` (number) - The size (in GB) of the root disk of the new instance. This option is only available when using `source_template`. - `expunge` (boolean) - Set to `true` to expunge the instance when it is @@ -100,7 +100,7 @@ builder. their CloudStack API. If using such a provider, you need to set this to `true` in order for the provider to only make GET calls and no POST calls. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index 12db018c4..8e89666bd 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -174,7 +174,7 @@ builder. Not required if you run Packer on a GCE instance with a service account. Instructions for creating file or using service accounts are above. -- `accelerator_count` (int) - Number of guest accelerator cards to add to the launched instance. +- `accelerator_count` (number) - Number of guest accelerator cards to add to the launched instance. - `accelerator_type` (string) - Full or partial URL of the guest accelerator type. GPU accelerators can only be used with `"on_host_maintenance": "TERMINATE"` option set. @@ -186,7 +186,7 @@ builder. - `disk_name` (string) - The name of the disk, if unset the instance name will be used. -- `disk_size` (integer) - The size of the disk in GB. This defaults to `10`, +- `disk_size` (number) - The size of the disk in GB. This defaults to `10`, which is 10GB. - `disk_type` (string) - Type of disk used to back your instance, like `pd-ssd` or `pd-standard`. Defaults to `pd-standard`. diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index 18853abc2..be66cd0e2 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -85,10 +85,10 @@ can be configured for this builder. five seconds and one minute 30 seconds, respectively. If this isn't specified, the default is 10 seconds. -- `cpu` (integer) - The number of cpus the virtual machine should use. If this isn't specified, +- `cpu` (number) - The number of cpus the virtual machine should use. If this isn't specified, the default is 1 cpu. -- `disk_size` (integer) - The size, in megabytes, of the hard disk to create +- `disk_size` (number) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40 GB. - `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual machine. @@ -122,7 +122,7 @@ can be configured for this builder. The maximum summary size of all files in the listed directories are the same as in `floppy_files`. -- `generation` (integer) - The Hyper-V generation for the virtual machine. By +- `generation` (number) - The Hyper-V generation for the virtual machine. By default, this is 1. Generation 2 Hyper-V virtual machines do not support floppy drives. In this scenario use `secondary_iso_images` instead. Hard drives and dvd drives will also be scsi and not ide. @@ -141,7 +141,7 @@ can be configured for this builder. available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP @@ -168,7 +168,7 @@ can be configured for this builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the name of the build. -- `ram_size` (integer) - The size, in megabytes, of the ram to create +- `ram_size` (number) - The size, in megabytes, of the ram to create for the VM. By default, this is 1 GB. - `secondary_iso_images` (array of strings) - A list of iso paths to attached to a diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index 59c75199c..d3236a4fe 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -93,7 +93,7 @@ can be configured for this builder. five seconds and one minute 30 seconds, respectively. If this isn't specified, the default is 10 seconds. -- `cpu` (integer) - The number of cpus the virtual machine should use. If +- `cpu` (number) - The number of cpus the virtual machine should use. If this isn't specified, the default is 1 cpu. - `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual @@ -143,7 +143,7 @@ can be configured for this builder. available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want @@ -187,7 +187,7 @@ can be configured for this builder. running the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the name of the build. -- `ram_size` (integer) - The size, in megabytes, of the ram to create for the +- `ram_size` (number) - The size, in megabytes, of the ram to create for the VM. By default, this is 1 GB. * `secondary_iso_images` (array of strings) - A list of iso paths to attached diff --git a/website/source/docs/builders/lxc.html.md b/website/source/docs/builders/lxc.html.md index be4c249e8..bc2b81a57 100644 --- a/website/source/docs/builders/lxc.html.md +++ b/website/source/docs/builders/lxc.html.md @@ -87,7 +87,7 @@ Below is a fully functioning example. ### Optional: -- `target_runlevel` (int) - The minimum run level to wait for the container to +- `target_runlevel` (number) - The minimum run level to wait for the container to reach. Note some distributions (Ubuntu) simulate run levels and may report 5 rather than 3. diff --git a/website/source/docs/builders/oneandone.html.md b/website/source/docs/builders/oneandone.html.md index 16da7b6d3..a84d6f726 100644 --- a/website/source/docs/builders/oneandone.html.md +++ b/website/source/docs/builders/oneandone.html.md @@ -35,7 +35,7 @@ builder. - `image_name` (string) - Resulting image. If "image\_name" is not provided Packer will generate it -- `retries` (int) - Number of retries Packer will make status requests while waiting for the build to complete. Default value "600". +- `retries` (number) - Number of retries Packer will make status requests while waiting for the build to complete. Default value "600". - `url` (string) - Endpoint for the 1&1 REST API. Default URL "<https://cloudpanel-api.1and1.com/v1>" diff --git a/website/source/docs/builders/parallels-iso.html.md b/website/source/docs/builders/parallels-iso.html.md index 5913c32c7..c9c23d919 100644 --- a/website/source/docs/builders/parallels-iso.html.md +++ b/website/source/docs/builders/parallels-iso.html.md @@ -100,7 +100,7 @@ builder. five seconds and one minute 30 seconds, respectively. If this isn't specified, the default is 10 seconds. -- `disk_size` (integer) - The size, in megabytes, of the hard disk to create +- `disk_size` (number) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40000 (about 40 GB). - `disk_type` (string) - The type for image file based virtual disk drives, @@ -151,7 +151,7 @@ builder. will be started. The address and port of the HTTP server will be available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want diff --git a/website/source/docs/builders/profitbricks.html.md b/website/source/docs/builders/profitbricks.html.md index de76f3a09..bbb691bab 100644 --- a/website/source/docs/builders/profitbricks.html.md +++ b/website/source/docs/builders/profitbricks.html.md @@ -31,7 +31,7 @@ builder. ### Optional -- `cores` (integer) - Amount of CPU cores to use for this build. Defaults to "4". +- `cores` (number) - Amount of CPU cores to use for this build. Defaults to "4". - `disk_size` (string) - Amount of disk space for this image in GB. Defaults to "50" @@ -39,7 +39,7 @@ builder. - `location` (string) - Defaults to "us/las". -- `ram` (integer) - Amount of RAM to use for this image. Defaults to "2048". +- `ram` (number) - Amount of RAM to use for this image. Defaults to "2048". - `retries` (string) - Number of retries Packer will make status requests while waiting for the build to complete. Default value 120 seconds. diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index f9cbc1fcd..e1bff6043 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -156,7 +156,7 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). *must* choose one of the other listed interfaces. Using the "scsi" interface under these circumstances will cause the build to fail. -- `disk_size` (integer) - The size, in megabytes, of the hard disk to create +- `disk_size` (number) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40000 (about 40 GB). - `floppy_files` (array of strings) - A list of files to place onto a floppy @@ -196,7 +196,7 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). will be started. The address and port of the HTTP server will be available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want @@ -326,7 +326,7 @@ default port of `5985` or whatever value you have the service set to listen on. - `skip_compaction` (boolean) - Packer compacts the QCOW2 image using `qemu-img convert`. Set this option to `true` to disable compacting. Defaults to `false`. -- `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and +- `ssh_host_port_min` and `ssh_host_port_max` (number) - The minimum and maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to use as the @@ -341,7 +341,7 @@ default port of `5985` or whatever value you have the service set to listen on. to for VNC. By default packer will use 127.0.0.1 for this. If you wish to bind to all interfaces use 0.0.0.0 -- `vnc_port_min` and `vnc_port_max` (integer) - The minimum and maximum port +- `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type the initial `boot_command`. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By diff --git a/website/source/docs/builders/virtualbox-iso.html.md b/website/source/docs/builders/virtualbox-iso.html.md index 5fa869ecd..85d4905ed 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md +++ b/website/source/docs/builders/virtualbox-iso.html.md @@ -92,7 +92,7 @@ builder. five seconds and one minute 30 seconds, respectively. If this isn't specified, the default is 10 seconds. -- `disk_size` (integer) - The size, in megabytes, of the hard disk to create +- `disk_size` (number) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40000 (about 40 GB). - `export_opts` (array of strings) - Additional options to pass to the @@ -193,7 +193,7 @@ builder. is attached to an AHCI SATA controller. When set to "scsi", the drive is attached to an LsiLogic SCSI controller. -- `sata_port_count` (integer) - The number of ports available on any SATA +- `sata_port_count` (number) - The number of ports available on any SATA controller created, defaults to 1. VirtualBox supports up to 30 ports on a maximum of 1 SATA controller. Increasing this value can be useful if you want to attach additional drives. @@ -219,7 +219,7 @@ builder. will be started. The address and port of the HTTP server will be available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want @@ -275,7 +275,7 @@ builder. not export the VM. Useful if the build output is not the resultant image, but created inside the VM. -- `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and +- `ssh_host_port_min` and `ssh_host_port_max` (number) - The minimum and maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to use as the @@ -315,7 +315,7 @@ builder. binded to for VRDP. By default packer will use 127.0.0.1 for this. If you wish to bind to all interfaces use 0.0.0.0 -- `vrdp_port_min` and `vrdp_port_max` (integer) - The minimum and maximum port +- `vrdp_port_min` and `vrdp_port_max` (number) - The minimum and maximum port to use for VRDP access to the virtual machine. Packer uses a randomly chosen port in this range that appears available. By default this is 5900 to 6000. The minimum and maximum ports are inclusive. diff --git a/website/source/docs/builders/virtualbox-ovf.html.md b/website/source/docs/builders/virtualbox-ovf.html.md index b8ff74d48..d58101100 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md +++ b/website/source/docs/builders/virtualbox-ovf.html.md @@ -187,7 +187,7 @@ builder. will be started. The address and port of the HTTP server will be available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want @@ -234,7 +234,7 @@ builder. not export the VM. Useful if the build output is not the resultant image, but created inside the VM. -- `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and +- `ssh_host_port_min` and `ssh_host_port_max` (number) - The minimum and maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to use as the @@ -278,7 +278,7 @@ builder. - `vrdp_bind_address` (string / IP address) - The IP address that should be binded to for VRDP. By default packer will use 127.0.0.1 for this. -- `vrdp_port_min` and `vrdp_port_max` (integer) - The minimum and maximum port +- `vrdp_port_min` and `vrdp_port_max` (number) - The minimum and maximum port to use for VRDP access to the virtual machine. Packer uses a randomly chosen port in this range that appears available. By default this is 5900 to 6000. The minimum and maximum ports are inclusive. diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index c5f5c9d34..4ec9ed676 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -102,7 +102,7 @@ builder. fixed-size virtual hard disks, so the actual file representing the disk will not use the full size unless it is full. -- `disk_size` (integer) - The size of the hard disk for the VM in megabytes. +- `disk_size` (number) - The size of the hard disk for the VM in megabytes. The builder uses expandable, not fixed-size virtual hard disks, so the actual file representing the disk will not use the full size unless it is full. By default this is set to 40,000 (about 40 GB). @@ -156,7 +156,7 @@ builder. will be started. The address and port of the HTTP server will be available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want @@ -298,7 +298,7 @@ builder. - `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that is used to secure the VNC communication with the VM. -- `vnc_port_min` and `vnc_port_max` (integer) - The minimum and maximum port +- `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type the initial `boot_command`. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index 565ae097e..ae5bfd29f 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -107,7 +107,7 @@ builder. will be started. The address and port of the HTTP server will be available as variables in `boot_command`. This is covered in more detail below. -- `http_port_min` and `http_port_max` (integer) - These are the minimum and +- `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want @@ -174,7 +174,7 @@ builder. - `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that is used to secure the VNC communication with the VM. -- `vnc_port_min` and `vnc_port_max` (integer) - The minimum and maximum port +- `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type the initial `boot_command`. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By diff --git a/website/source/docs/other/core-configuration.html.md b/website/source/docs/other/core-configuration.html.md index 234cf4563..0a84ceb60 100644 --- a/website/source/docs/other/core-configuration.html.md +++ b/website/source/docs/other/core-configuration.html.md @@ -32,7 +32,7 @@ The format of the configuration file is basic JSON. Below is the list of all available configuration parameters for the core configuration file. None of these are required, since all have sane defaults. -- `plugin_min_port` and `plugin_max_port` (integer) - These are the minimum and +- `plugin_min_port` and `plugin_max_port` (number) - These are the minimum and maximum ports that Packer uses for communication with plugins, since plugin communication happens over TCP connections on your local host. By default these are 10,000 and 25,000, respectively. Be sure to set a fairly wide range diff --git a/website/source/docs/post-processors/alicloud-import.html.md b/website/source/docs/post-processors/alicloud-import.html.md index d2ab30547..504559c0b 100644 --- a/website/source/docs/post-processors/alicloud-import.html.md +++ b/website/source/docs/post-processors/alicloud-import.html.md @@ -77,7 +77,7 @@ two categories: required and optional parameters. and then create the target image, otherwise, the creation will fail. The default value is false. -- `image_system_size` (int) - Size of the system disk, in GB, values range: +- `image_system_size` (number) - Size of the system disk, in GB, values range: - cloud - 5 ~ 2000 - cloud\_efficiency - 20 ~ 2048 - cloud\_ssd - 20 ~ 2048 diff --git a/website/source/docs/post-processors/compress.html.md b/website/source/docs/post-processors/compress.html.md index 90b9b308f..83b40b7f0 100644 --- a/website/source/docs/post-processors/compress.html.md +++ b/website/source/docs/post-processors/compress.html.md @@ -35,7 +35,7 @@ you will need to specify the `output` option. - `format` (string) - Disable archive format autodetection and use provided string. -- `compression_level` (integer) - Specify the compression level, for +- `compression_level` (number) - Specify the compression level, for algorithms that support it, from 1 through 9 inclusive. Typically higher compression levels take longer but produce smaller files. Defaults to `6` diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index deb86c0c8..5f0a9bc50 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -52,7 +52,7 @@ However, if you want to configure things a bit more, the post-processor does expose some configuration options. The available options are listed below, with more details about certain options in following sections. -- `compression_level` (integer) - An integer representing the compression +- `compression_level` (number) - An integer representing the compression level to use when creating the Vagrant box. Valid values range from 0 to 9, with 0 being no compression and 9 being the best compression. By default, compression is enabled at level 6. diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 3d919e272..83205c543 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -67,7 +67,7 @@ The SSH communicator has the following options: - `ssh_bastion_password` (string) - The password to use to authenticate with the bastion host. -- `ssh_bastion_port` (integer) - The port of the bastion host. Defaults to 1. +- `ssh_bastion_port` (number) - The port of the bastion host. Defaults to 1. - `ssh_bastion_private_key_file` (string) - A private key file to use to authenticate with the bastion host. @@ -81,7 +81,7 @@ The SSH communicator has the following options: - `ssh_file_transfer_method` (`scp` or `sftp`) - How to transfer files, Secure copy (default) or SSH File Transfer Protocol. -- `ssh_handshake_attempts` (integer) - The number of handshakes to attempt +- `ssh_handshake_attempts` (number) - The number of handshakes to attempt with SSH once it can connect. This defaults to 10. - `ssh_host` (string) - The address to SSH to. This usually is automatically @@ -90,7 +90,7 @@ The SSH communicator has the following options: - `ssh_password` (string) - A plaintext password to use to authenticate with SSH. -- `ssh_port` (integer) - The port to connect to SSH. This defaults to 22. +- `ssh_port` (number) - The port to connect to SSH. This defaults to 22. - `ssh_private_key_file` (string) - Path to a PEM encoded private key file to use to authenticate with SSH. @@ -111,7 +111,7 @@ The WinRM communicator has the following options. - `winrm_host` (string) - The address for WinRM to connect to. -- `winrm_port` (integer) - The WinRM port to connect to. This defaults to +- `winrm_port` (number) - The WinRM port to connect to. This defaults to 5985 for plain unencrypted connection and 5986 for SSL when `winrm_use_ssl` is set to true. - `winrm_username` (string) - The username to use to connect to WinRM. From c22c7238ac16f224e8784232ce49ed414c3f12b0 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Tue, 17 Oct 2017 04:05:18 +0900 Subject: [PATCH 0080/1007] Add doc --- website/source/docs/templates/engine.html.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index b699e64c2..7dcc36b4a 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -50,6 +50,13 @@ Here is a full list of the available functions for reference. function will replace illegal characters with a '-" character. Example usage since ":" is not a legal AMI name is: `{{isotime | clean_ami_name}}`. +#### Specific to Google Compute builders: + +- `clean_image_name` - GCE image names can only contain certain characters and + the maximum length is 63. This function will replace illegal characters with a "-" character + and truncate a name which exceeds maximum length. + Example usage since ":" is not a legal image name is: `{{isotime | clean_image_name}}`. + ## Template variables Template variables are special variables automatically set by Packer at build time. Some builders, provisioners and other components have template variables that are available only for that component. Template variables are recognizable because they're prefixed by a period, such as `{{ .Name }}`. For example, when using the [`shell`](/docs/builders/vmware-iso.html) builder template variables are available to customize the [`execute_command`](/docs/provisioners/shell.html#execute_command) parameter used to determine how Packer will run the shell command. From 3600924e597aaff606dcc48cd6c824aff5eafa61 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Tue, 17 Oct 2017 04:55:50 +0900 Subject: [PATCH 0081/1007] Rename files --- builder/googlecompute/{templace_funcs.go => template_funcs.go} | 0 .../{templace_funcs_test.go => template_funcs_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename builder/googlecompute/{templace_funcs.go => template_funcs.go} (100%) rename builder/googlecompute/{templace_funcs_test.go => template_funcs_test.go} (100%) diff --git a/builder/googlecompute/templace_funcs.go b/builder/googlecompute/template_funcs.go similarity index 100% rename from builder/googlecompute/templace_funcs.go rename to builder/googlecompute/template_funcs.go diff --git a/builder/googlecompute/templace_funcs_test.go b/builder/googlecompute/template_funcs_test.go similarity index 100% rename from builder/googlecompute/templace_funcs_test.go rename to builder/googlecompute/template_funcs_test.go From 6837bf8276f1065e6674d8375cd89cfee9efceb6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 16 Oct 2017 13:04:53 -0700 Subject: [PATCH 0082/1007] grammar and style fix --- website/source/docs/builders/vmware-iso.html.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 6761c33d8..36715a134 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -108,11 +108,12 @@ builder. is full. By default this is set to 40,000 (about 40 GB). - `disk_type_id` (string) - The type of VMware virtual disk to create. The - default is "1", which corresponds to a growable virtual disk split in - 2GB files. For ESXi defaults to "zeroedthick". This option is for advanced usage, modify only if you know what - you're doing. For more information, please consult the [Virtual Disk Manager - User's Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) for desktop - VMware clients. For ESXi, refer to the proper ESXi documentation. + default is "1", which corresponds to a growable virtual disk split in 2GB + files. For ESXi, this defaults to "zeroedthick". This option is for + advanced usage. For more information, please consult the [Virtual Disk + Manager User's Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) + for desktop VMware clients. For ESXi, refer to the proper ESXi + documentation. * `disable_vnc` (bool) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. From 8585e0ebf5a9a83afe32064eeb16d29210d6fd1a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 16 Oct 2017 13:27:26 -0700 Subject: [PATCH 0083/1007] doc improvements --- website/source/docs/builders/amazon-chroot.html.md | 9 ++++----- website/source/docs/builders/amazon-ebs.html.md | 6 +++--- website/source/docs/builders/amazon-ebssurrogate.html.md | 6 +++--- website/source/docs/builders/amazon-ebsvolume.html.md | 6 +++--- website/source/docs/builders/amazon-instance.html.md | 6 +++--- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 90da1a8f7..c0dec7eac 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -95,8 +95,7 @@ each category, the available configuration keys are alphabetized. depending on the size of the AMI, but will generally take many minutes. - `ami_users` (array of strings) - A list of account IDs that have access to - launch the resulting AMI(s). By default no additional users other than the - user creating the AMI has permissions to launch it. + launch the resulting AMI(s). By default no additional users other than the user creating the AMI has permissions to launch it. - `ami_virtualization_type` (string) - The type of virtualization for the AMI you are building. This option is required to register HVM images. Can be @@ -120,9 +119,9 @@ each category, the available configuration keys are alphabetized. copying `/etc/resolv.conf`. You may need to do this if you're building an image that uses systemd. -- `custom_endpoint_ec2` (string) - this option is useful if you use - another cloud provider that provide a compatible API with aws EC2, - specify another endpoint like this "<https://ec2.another.endpoint>..com" +- `custom_endpoint_ec2` (string) - This option is useful if you use a cloud + provider whose API is compatible with aws EC2. Specify another endpoint + like this `https://ec2.custom.endpoint.com`. - `device_path` (string) - The path to the device where the root volume of the source AMI will be attached. This defaults to "" (empty string), which diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index db438116d..90f7ee05e 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -143,9 +143,9 @@ builder. - `availability_zone` (string) - Destination availability zone to launch instance in. Leave this empty to allow Amazon to auto-assign. -- `custom_endpoint_ec2` (string) - this option is useful if you use - another cloud provider that provide a compatible API with aws EC2, - specify another endpoint like this "<https://ec2.another.endpoint>..com" +- `custom_endpoint_ec2` (string) - This option is useful if you use a cloud + provider whose API is compatible with aws EC2. Specify another endpoint + like this `https://ec2.custom.endpoint.com`. - `disable_stop_instance` (boolean) - Packer normally stops the build instance after all provisioners have run. For Windows instances, it is sometimes diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 57fd3408b..4965c426e 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -136,9 +136,9 @@ builder. - `availability_zone` (string) - Destination availability zone to launch instance in. Leave this empty to allow Amazon to auto-assign. -- `custom_endpoint_ec2` (string) - this option is useful if you use - another cloud provider that provide a compatible API with aws EC2, - specify another endpoint like this "<https://ec2.another.endpoint>..com" +- `custom_endpoint_ec2` (string) - This option is useful if you use a cloud + provider whose API is compatible with aws EC2. Specify another endpoint + like this `https://ec2.custom.endpoint.com`. - `disable_stop_instance` (boolean) - Packer normally stops the build instance after all provisioners have run. For Windows instances, it is sometimes diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 78a9815e9..85024fcad 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -96,9 +96,9 @@ builder. - `availability_zone` (string) - Destination availability zone to launch instance in. Leave this empty to allow Amazon to auto-assign. -- `custom_endpoint_ec2` (string) - this option is useful if you use - another cloud provider that provide a compatible API with aws EC2, - specify another endpoint like this "<https://ec2.another.endpoint>..com" +- `custom_endpoint_ec2` (string) - This option is useful if you use a cloud + provider whose API is compatible with aws EC2. Specify another endpoint + like this `https://ec2.custom.endpoint.com`. - `ebs_optimized` (boolean) - Mark instance as [EBS Optimized](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSOptimized.html). diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 17be8a297..613d4ed97 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -181,9 +181,9 @@ builder. - `bundle_vol_command` (string) - The command to use to bundle the volume. See the "custom bundle commands" section below for more information. -- `custom_endpoint_ec2` (string) - this option is useful if you use - another cloud provider that provide a compatible API with aws EC2, - specify another endpoint like this "<https://ec2.another.endpoint>..com" +- `custom_endpoint_ec2` (string) - This option is useful if you use a cloud + provider whose API is compatible with aws EC2. Specify another endpoint + like this `https://ec2.custom.endpoint.com`. - `ebs_optimized` (boolean) - Mark instance as [EBS Optimized](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSOptimized.html). From 8df643c3434c24be9c4475f26f785b196b1d875e Mon Sep 17 00:00:00 2001 From: Aaron Browne <aaron0browne@gmail.com> Date: Mon, 16 Oct 2017 13:43:14 -0400 Subject: [PATCH 0084/1007] Add aws_profile option to docker-push ecr_login An aws_profile option is added to the AWS ECR login credentials configuration to allow using shared AWS credentials stored in a non-default profile. Signed-off-by: Aaron Browne <aaron0browne@gmail.com> --- builder/docker/ecr_login.go | 6 +++++- website/source/docs/builders/docker.html.md | 3 +++ website/source/docs/post-processors/docker-push.html.md | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/builder/docker/ecr_login.go b/builder/docker/ecr_login.go index 737107589..d5e4f97ab 100644 --- a/builder/docker/ecr_login.go +++ b/builder/docker/ecr_login.go @@ -19,6 +19,7 @@ type AwsAccessConfig struct { AccessKey string `mapstructure:"aws_access_key"` SecretKey string `mapstructure:"aws_secret_key"` Token string `mapstructure:"aws_token"` + Profile string `mapstructure:"aws_profile"` } // Config returns a valid aws.Config object for access to AWS services, or @@ -38,7 +39,10 @@ func (c *AwsAccessConfig) config(region string) (*aws.Config, error) { SessionToken: c.Token, }}, &credentials.EnvProvider{}, - &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, + &credentials.SharedCredentialsProvider{ + Filename: "", + Profile: c.Profile, + }, &ec2rolecreds.EC2RoleProvider{ Client: ec2metadata.New(session), }, diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index f2f301ecb..951860971 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -162,6 +162,9 @@ You must specify (only) one of `commit`, `discard`, or `export_path`. probably don't need it. This will also be read from the `AWS_SESSION_TOKEN` environmental variable. +- `aws_profile` (string) - The AWS shared credentials profile used to communicate with AWS. + [Learn how to set this.](/docs/builders/amazon.html#specifying-amazon-credentials) + - `changes` (array of strings) - Dockerfile instructions to add to the commit. Example of instructions are `CMD`, `ENTRYPOINT`, `ENV`, and `EXPOSE`. Example: `[ "USER ubuntu", "WORKDIR /app", "EXPOSE 8080" ]` diff --git a/website/source/docs/post-processors/docker-push.html.md b/website/source/docs/post-processors/docker-push.html.md index 6e22bdd79..5400cb56a 100644 --- a/website/source/docs/post-processors/docker-push.html.md +++ b/website/source/docs/post-processors/docker-push.html.md @@ -30,6 +30,9 @@ This post-processor has only optional configuration: probably don't need it. This will also be read from the `AWS_SESSION_TOKEN` environmental variable. +- `aws_profile` (string) - The AWS shared credentials profile used to communicate with AWS. + [Learn how to set this.](/docs/builders/amazon.html#specifying-amazon-credentials) + - `ecr_login` (boolean) - Defaults to false. If true, the post-processor will login in order to push the image to [Amazon EC2 Container Registry (ECR)](https://aws.amazon.com/ecr/). From 5310d5629b05fbde765f5a99913f33cfbcb61698 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Tue, 17 Oct 2017 12:31:50 +0900 Subject: [PATCH 0085/1007] Modify clean_image_name not defined error --- builder/googlecompute/builder.go | 3 +-- builder/googlecompute/config.go | 3 ++- builder/googlecompute/config_test.go | 12 ++++++------ builder/googlecompute/template_funcs.go | 4 +--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/builder/googlecompute/builder.go b/builder/googlecompute/builder.go index 1cb79f2a7..83557eff8 100644 --- a/builder/googlecompute/builder.go +++ b/builder/googlecompute/builder.go @@ -23,12 +23,11 @@ type Builder struct { // Prepare processes the build configuration parameters. func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { - c, warnings, errs := NewConfig(raws...) + c, warnings, errs := NewConfig(TemplateFuncs, raws...) if errs != nil { return warnings, errs } b.config = c - return warnings, nil } diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index 020ec9ab8..d4f37a569 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -63,8 +63,9 @@ type Config struct { ctx interpolate.Context } -func NewConfig(raws ...interface{}) (*Config, []string, error) { +func NewConfig(funcMap map[string]interface{}, raws ...interface{}) (*Config, []string, error) { c := new(Config) + c.ctx.Funcs = funcMap err := config.Decode(c, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &c.ctx, diff --git a/builder/googlecompute/config_test.go b/builder/googlecompute/config_test.go index 551692b29..cd36ba619 100644 --- a/builder/googlecompute/config_test.go +++ b/builder/googlecompute/config_test.go @@ -181,7 +181,7 @@ func TestConfigPrepare(t *testing.T) { raw[tc.Key] = tc.Value } - _, warns, errs := NewConfig(raw) + _, warns, errs := NewConfig(TemplateFuncs, raw) if tc.Err { testConfigErr(t, warns, errs, tc.Key) @@ -240,7 +240,7 @@ func TestConfigPrepareAccelerator(t *testing.T) { } } - _, warns, errs := NewConfig(raw) + _, warns, errs := NewConfig(TemplateFuncs, raw) if tc.Err { testConfigErr(t, warns, errs, strings.TrimRight(errStr, ", ")) @@ -269,7 +269,7 @@ func TestConfigDefaults(t *testing.T) { for _, tc := range cases { raw := testConfig(t) - c, warns, errs := NewConfig(raw) + c, warns, errs := NewConfig(TemplateFuncs, raw) testConfigOk(t, warns, errs) actual := tc.Read(c) @@ -280,7 +280,7 @@ func TestConfigDefaults(t *testing.T) { } func TestImageName(t *testing.T) { - c, _, _ := NewConfig(testConfig(t)) + c, _, _ := NewConfig(TemplateFuncs, testConfig(t)) if !strings.HasPrefix(c.ImageName, "packer-") { t.Fatalf("ImageName should have 'packer-' prefix, found %s", c.ImageName) } @@ -290,7 +290,7 @@ func TestImageName(t *testing.T) { } func TestRegion(t *testing.T) { - c, _, _ := NewConfig(testConfig(t)) + c, _, _ := NewConfig(TemplateFuncs, testConfig(t)) if c.Region != "us-east1" { t.Fatalf("Region should be 'us-east1' given Zone of 'us-east1-a', but is %s", c.Region) } @@ -314,7 +314,7 @@ func testConfig(t *testing.T) map[string]interface{} { } func testConfigStruct(t *testing.T) *Config { - c, warns, errs := NewConfig(testConfig(t)) + c, warns, errs := NewConfig(TemplateFuncs, testConfig(t)) if len(warns) > 0 { t.Fatalf("bad: %#v", len(warns)) } diff --git a/builder/googlecompute/template_funcs.go b/builder/googlecompute/template_funcs.go index 0831cf410..52ae7d121 100644 --- a/builder/googlecompute/template_funcs.go +++ b/builder/googlecompute/template_funcs.go @@ -1,7 +1,6 @@ package googlecompute import ( - "regexp" "strings" "text/template" ) @@ -19,8 +18,7 @@ func isalphanumeric(b byte) bool { // Clean up image name by replacing invalid characters with "-" // truncate up to 63 length, convert to a lower case func templateCleanImageName(s string) string { - re := regexp.MustCompile(`^[a-z][-a-z0-9]{0,61}[a-z0-9]$`) - if re.MatchString(s) { + if reImageFamily.MatchString(s) { return s } b := []byte(strings.ToLower(s)) From 210dd08326b43c39b53f5dfc603f18a6e5ba0655 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Tue, 17 Oct 2017 13:48:15 +0900 Subject: [PATCH 0086/1007] Change args of NewConfig --- builder/googlecompute/builder.go | 2 +- builder/googlecompute/config.go | 4 ++-- builder/googlecompute/config_test.go | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/builder/googlecompute/builder.go b/builder/googlecompute/builder.go index 83557eff8..589108348 100644 --- a/builder/googlecompute/builder.go +++ b/builder/googlecompute/builder.go @@ -23,7 +23,7 @@ type Builder struct { // Prepare processes the build configuration parameters. func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { - c, warnings, errs := NewConfig(TemplateFuncs, raws...) + c, warnings, errs := NewConfig(raws...) if errs != nil { return warnings, errs } diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index d4f37a569..9605f2f4c 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -63,9 +63,9 @@ type Config struct { ctx interpolate.Context } -func NewConfig(funcMap map[string]interface{}, raws ...interface{}) (*Config, []string, error) { +func NewConfig(raws ...interface{}) (*Config, []string, error) { c := new(Config) - c.ctx.Funcs = funcMap + c.ctx.Funcs = TemplateFuncs err := config.Decode(c, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &c.ctx, diff --git a/builder/googlecompute/config_test.go b/builder/googlecompute/config_test.go index cd36ba619..551692b29 100644 --- a/builder/googlecompute/config_test.go +++ b/builder/googlecompute/config_test.go @@ -181,7 +181,7 @@ func TestConfigPrepare(t *testing.T) { raw[tc.Key] = tc.Value } - _, warns, errs := NewConfig(TemplateFuncs, raw) + _, warns, errs := NewConfig(raw) if tc.Err { testConfigErr(t, warns, errs, tc.Key) @@ -240,7 +240,7 @@ func TestConfigPrepareAccelerator(t *testing.T) { } } - _, warns, errs := NewConfig(TemplateFuncs, raw) + _, warns, errs := NewConfig(raw) if tc.Err { testConfigErr(t, warns, errs, strings.TrimRight(errStr, ", ")) @@ -269,7 +269,7 @@ func TestConfigDefaults(t *testing.T) { for _, tc := range cases { raw := testConfig(t) - c, warns, errs := NewConfig(TemplateFuncs, raw) + c, warns, errs := NewConfig(raw) testConfigOk(t, warns, errs) actual := tc.Read(c) @@ -280,7 +280,7 @@ func TestConfigDefaults(t *testing.T) { } func TestImageName(t *testing.T) { - c, _, _ := NewConfig(TemplateFuncs, testConfig(t)) + c, _, _ := NewConfig(testConfig(t)) if !strings.HasPrefix(c.ImageName, "packer-") { t.Fatalf("ImageName should have 'packer-' prefix, found %s", c.ImageName) } @@ -290,7 +290,7 @@ func TestImageName(t *testing.T) { } func TestRegion(t *testing.T) { - c, _, _ := NewConfig(TemplateFuncs, testConfig(t)) + c, _, _ := NewConfig(testConfig(t)) if c.Region != "us-east1" { t.Fatalf("Region should be 'us-east1' given Zone of 'us-east1-a', but is %s", c.Region) } @@ -314,7 +314,7 @@ func testConfig(t *testing.T) map[string]interface{} { } func testConfigStruct(t *testing.T) *Config { - c, warns, errs := NewConfig(TemplateFuncs, testConfig(t)) + c, warns, errs := NewConfig(testConfig(t)) if len(warns) > 0 { t.Fatalf("bad: %#v", len(warns)) } From 8244d8bfb91c5a45f011dc6ff77be71450611c84 Mon Sep 17 00:00:00 2001 From: Marcel Prince <mprince@users.noreply.github.com> Date: Tue, 17 Oct 2017 08:25:40 -0700 Subject: [PATCH 0087/1007] Arguments sorting for Puppet provisioners docs --- .../provisioners/puppet-masterless.html.md | 18 ++++++------- .../docs/provisioners/puppet-server.html.md | 27 +++++++++++-------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/website/source/docs/provisioners/puppet-masterless.html.md b/website/source/docs/provisioners/puppet-masterless.html.md index 63bc76576..1e1689d03 100644 --- a/website/source/docs/provisioners/puppet-masterless.html.md +++ b/website/source/docs/provisioners/puppet-masterless.html.md @@ -59,10 +59,6 @@ Optional parameters: variables](/docs/templates/engine.html) available. See below for more information. -- `guest_os_type` (string) - The target guest OS type, either "unix" or - "windows". Setting this to "windows" will cause the provisioner to use - Windows friendly paths and commands. By default, this is "unix". - - `extra_arguments` (array of strings) - This is an array of additional options to pass to the puppet command when executing puppet. This allows for customization of the `execute_command` without having to completely replace @@ -73,6 +69,10 @@ Optional parameters: [facts](https://puppetlabs.com/facter) to make available when Puppet is running. +- `guest_os_type` (string) - The target guest OS type, either "unix" or + "windows". Setting this to "windows" will cause the provisioner to use + Windows friendly paths and commands. By default, this is "unix". + - `hiera_config_path` (string) - The path to a local file with hiera configuration to be uploaded to the remote machine. Hiera data directories must be uploaded using the file provisioner separately. @@ -90,11 +90,6 @@ Optional parameters: This option was deprecated in puppet 3.6, and removed in puppet 4.0. If you have multiple manifests you should use `manifest_file` instead. -- `puppet_bin_dir` (string) - The path to the directory that contains the puppet - binary for running `puppet apply`. Usually, this would be found via the `$PATH` - or `%PATH%` environment variable, but some builders (notably, the Docker one) do - not run profile-setup scripts, therefore the path is usually empty. - - `module_paths` (array of strings) - This is an array of paths to module directories on your local filesystem. These will be uploaded to the remote machine. By default, this is empty. @@ -103,6 +98,11 @@ multiple manifests you should use `manifest_file` instead. executed to run Puppet are executed with `sudo`. If this is true, then the sudo will be omitted. +- `puppet_bin_dir` (string) - The path to the directory that contains the puppet + binary for running `puppet apply`. Usually, this would be found via the `$PATH` + or `%PATH%` environment variable, but some builders (notably, the Docker one) do + not run profile-setup scripts, therefore the path is usually empty. + - `staging_directory` (string) - This is the directory where all the configuration of Puppet by Packer will be placed. By default this is "/tmp/packer-puppet-masterless" when guest OS type is unix and "C:/Windows/Temp/packer-puppet-masterless" when windows. diff --git a/website/source/docs/provisioners/puppet-server.html.md b/website/source/docs/provisioners/puppet-server.html.md index 6adfd6b0b..180f52b02 100644 --- a/website/source/docs/provisioners/puppet-server.html.md +++ b/website/source/docs/provisioners/puppet-server.html.md @@ -50,9 +50,17 @@ listed below: contains the client private key for the node. This defaults to nothing, in which case a client private key won't be uploaded. +- `execute_command` (string) - The command used to execute Puppet. This has + various [configuration template variables](/docs/templates/engine.html) available. + See below for more information. + - `facter` (object of key/value strings) - Additional Facter facts to make available to the Puppet run. +- `guest_os_type` (string) - The target guest OS type, either "unix" or + "windows". Setting this to "windows" will cause the provisioner to use + Windows friendly paths and commands. By default, this is "unix". + - `ignore_exit_codes` (boolean) - If true, Packer will never consider the provisioner a failure. @@ -63,6 +71,11 @@ listed below: executed to run Puppet are executed with `sudo`. If this is true, then the sudo will be omitted. +- `puppet_bin_dir` (string) - The path to the directory that contains the puppet + binary for running `puppet agent`. Usually, this would be found via the `$PATH` + or `%PATH%` environment variable, but some builders (notably, the Docker one) do + not run profile-setup scripts, therefore the path is usually empty. + - `puppet_node` (string) - The name of the node. If this isn't set, the fully qualified domain name will be used. @@ -76,18 +89,10 @@ listed below: to create directories and write into this folder. If the permissions are not correct, use a shell provisioner prior to this to configure it properly. -- `puppet_bin_dir` (string) - The path to the directory that contains the puppet - binary for running `puppet agent`. Usually, this would be found via the `$PATH` - or `%PATH%` environment variable, but some builders (notably, the Docker one) do - not run profile-setup scripts, therefore the path is usually empty. +## Execute Command -- `guest_os_type` (string) - The target guest OS type, either "unix" or - "windows". Setting this to "windows" will cause the provisioner to use - Windows friendly paths and commands. By default, this is "unix". - -- `execute_command` (string) - This is optional. The command used to execute Puppet. This has - various [configuration template variables](/docs/templates/engine.html) available. By default, - Packer uses the following command (broken across multiple lines for readability) to execute Puppet: +By default, Packer uses the following command (broken across multiple lines for +readability) to execute Puppet: ``` {{.FacterVars}} {{if .Sudo}}sudo -E {{end}} From 265ae7026e3af22a4f50a1b29373a31cd8b20ef2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 17 Oct 2017 11:29:11 -0700 Subject: [PATCH 0088/1007] docs formatting --- website/source/docs/builders/vmware-iso.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index ddc3be7d2..343a685ef 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -523,7 +523,9 @@ file by attaching a floppy disk. An example below, based on RHEL: } ``` -It's also worth noting that `ks=floppy` has been deprecated. Later versions of the Anaconda installer (used in RHEL/CentOS 7 and Fedora) may require a different syntax to source a kickstart file from a mounted floppy image. +It's also worth noting that `ks=floppy` has been deprecated. Later versions of +the Anaconda installer (used in RHEL/CentOS 7 and Fedora) may require +a different syntax to source a kickstart file from a mounted floppy image. ``` json { From ffc63a872421baf04ac20ae8a8dad9e294f8e7f5 Mon Sep 17 00:00:00 2001 From: Aaron Browne <aaron0browne@gmail.com> Date: Tue, 17 Oct 2017 15:00:19 -0400 Subject: [PATCH 0089/1007] Use amazon common AccessConfig for ecr_login Signed-off-by: Aaron Browne <aaron0browne@gmail.com> --- builder/docker/ecr_login.go | 45 ++++++++----------------------------- 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/builder/docker/ecr_login.go b/builder/docker/ecr_login.go index d5e4f97ab..c605bc36e 100644 --- a/builder/docker/ecr_login.go +++ b/builder/docker/ecr_login.go @@ -8,11 +8,8 @@ import ( "strings" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" - "github.com/aws/aws-sdk-go/aws/ec2metadata" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ecr" + "github.com/hashicorp/packer/builder/amazon/common" ) type AwsAccessConfig struct { @@ -20,34 +17,7 @@ type AwsAccessConfig struct { SecretKey string `mapstructure:"aws_secret_key"` Token string `mapstructure:"aws_token"` Profile string `mapstructure:"aws_profile"` -} - -// Config returns a valid aws.Config object for access to AWS services, or -// an error if the authentication and region couldn't be resolved -func (c *AwsAccessConfig) config(region string) (*aws.Config, error) { - var creds *credentials.Credentials - - config := aws.NewConfig().WithRegion(region).WithMaxRetries(11) - session, err := session.NewSession(config) - if err != nil { - return nil, err - } - creds = credentials.NewChainCredentials([]credentials.Provider{ - &credentials.StaticProvider{Value: credentials.Value{ - AccessKeyID: c.AccessKey, - SecretAccessKey: c.SecretKey, - SessionToken: c.Token, - }}, - &credentials.EnvProvider{}, - &credentials.SharedCredentialsProvider{ - Filename: "", - Profile: c.Profile, - }, - &ec2rolecreds.EC2RoleProvider{ - Client: ec2metadata.New(session), - }, - }) - return config.WithCredentials(creds), nil + cfg *common.AccessConfig } // Get a login token for Amazon AWS ECR. Returns username and password @@ -64,12 +34,15 @@ func (c *AwsAccessConfig) EcrGetLogin(ecrUrl string) (string, string, error) { log.Println(fmt.Sprintf("Getting ECR token for account: %s in %s..", accountId, region)) - awsConfig, err := c.config(region) - if err != nil { - return "", "", err + c.cfg = &common.AccessConfig{ + AccessKey: c.AccessKey, + ProfileName: c.Profile, + RawRegion: region, + SecretKey: c.SecretKey, + Token: c.Token, } - session, err := session.NewSession(awsConfig) + session, err := c.cfg.Session() if err != nil { return "", "", fmt.Errorf("failed to create session: %s", err) } From f3c64ce81aca9391fc11571a56e4e1b1f5f1a100 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 17 Oct 2017 16:09:05 -0700 Subject: [PATCH 0090/1007] update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb01de53..96cfb6fb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## (UNRELEASED) +### IMRPOVEMENTS: + +* post-processor/docker-push: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] +* builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] + ## 1.1.1 (October 13, 2017) ### IMPROVEMENTS: From 3e68f1c50507cc6446a879d370967a91b81265b8 Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Wed, 18 Oct 2017 11:10:19 +0900 Subject: [PATCH 0091/1007] Change first and last character when it doesn't match --- builder/googlecompute/template_funcs.go | 6 ++++++ builder/googlecompute/template_funcs_test.go | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/builder/googlecompute/template_funcs.go b/builder/googlecompute/template_funcs.go index 52ae7d121..f33118b5c 100644 --- a/builder/googlecompute/template_funcs.go +++ b/builder/googlecompute/template_funcs.go @@ -34,6 +34,12 @@ func templateCleanImageName(s string) string { newb[i] = '-' } } + if !('a' <= newb[0] && newb[0] <= 'z') { + newb[0] = 'a' + } + if newb[l-1] == '-' { + newb[l-1] = 'a' + } return string(newb) } diff --git a/builder/googlecompute/template_funcs_test.go b/builder/googlecompute/template_funcs_test.go index b943ab911..887af5883 100644 --- a/builder/googlecompute/template_funcs_test.go +++ b/builder/googlecompute/template_funcs_test.go @@ -20,8 +20,16 @@ func Test_templateCleanImageName(t *testing.T) { expected: "abcde-012345v1-0-0", }, { - origName: "0123456789012345678901234567890123456789012345678901234567890123456789", - expected: "012345678901234567890123456789012345678901234567890123456789012", + origName: "a123456789012345678901234567890123456789012345678901234567890123456789", + expected: "a12345678901234567890123456789012345678901234567890123456789012", + }, + { + origName: "01234567890123456789012345678901234567890123456789012345678901.", + expected: "a1234567890123456789012345678901234567890123456789012345678901a", + }, + { + origName: "01234567890123456789012345678901234567890123456789012345678901-", + expected: "a1234567890123456789012345678901234567890123456789012345678901a", }, } From c1a7b3845a33090ef62b24c76e071326736dfb95 Mon Sep 17 00:00:00 2001 From: Chris Lundquist <rampantdurandal@gmail.com> Date: Wed, 18 Oct 2017 04:57:13 +0000 Subject: [PATCH 0092/1007] [lxd] allow passing of publish properties --- builder/lxd/config.go | 9 +++++---- builder/lxd/step_publish.go | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/builder/lxd/config.go b/builder/lxd/config.go index 73de7212e..6a4745510 100644 --- a/builder/lxd/config.go +++ b/builder/lxd/config.go @@ -12,10 +12,11 @@ import ( type Config struct { common.PackerConfig `mapstructure:",squash"` - OutputImage string `mapstructure:"output_image"` - ContainerName string `mapstructure:"container_name"` - CommandWrapper string `mapstructure:"command_wrapper"` - Image string `mapstructure:"image"` + OutputImage string `mapstructure:"output_image"` + ContainerName string `mapstructure:"container_name"` + CommandWrapper string `mapstructure:"command_wrapper"` + Image string `mapstructure:"image"` + PublishProperties map[string]string `mapstructure:"publish_properties"` InitTimeout time.Duration ctx interpolate.Context diff --git a/builder/lxd/step_publish.go b/builder/lxd/step_publish.go index 0c0aabd3f..31e2d638b 100644 --- a/builder/lxd/step_publish.go +++ b/builder/lxd/step_publish.go @@ -32,6 +32,10 @@ func (s *stepPublish) Run(state multistep.StateBag) multistep.StepAction { "publish", name, "--alias", config.OutputImage, } + for k, v := range config.PublishProperties { + publish_args = append(publish_args, fmt.Sprintf("%s=%s", k, v)) + } + ui.Say("Publishing container...") stdoutString, err := LXDCommand(publish_args...) if err != nil { From 76f0176f5e39a85d26e3a1870a921237e09215ed Mon Sep 17 00:00:00 2001 From: Chris Lundquist <rampantdurandal@gmail.com> Date: Wed, 18 Oct 2017 05:05:46 +0000 Subject: [PATCH 0093/1007] [lxd] add docs on publish properties --- website/source/docs/builders/lxd.html.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/lxd.html.md b/website/source/docs/builders/lxd.html.md index 56dca60c2..4915e1e28 100644 --- a/website/source/docs/builders/lxd.html.md +++ b/website/source/docs/builders/lxd.html.md @@ -31,11 +31,15 @@ Below is a fully functioning example. "name": "lxd-xenial", "image": "ubuntu-daily:xenial", "output_image": "ubuntu-xenial" + "publish_properties": { + "description": "Trivial repackage with Packer" + } } ] } ``` + ## Configuration Reference ### Required: @@ -56,5 +60,11 @@ Below is a fully functioning example. - `output_image` (string) - The name of the output artifact. Defaults to `name`. -- `command_wrapper` (string) - lets you prefix all builder commands, such as +- `command_wrapper` (string) - Lets you prefix all builder commands, such as with `ssh` for a remote build host. Defaults to `""`. + +- `publish_properties` (map[string]string) - Pass key values to the publish + step to be set as properties on the output image. This is most helpful to + set the description, but can be used to set anything needed. + See https://stgraber.org/2016/03/30/lxd-2-0-image-management-512/ + for more properties. From bb497c2453fdf1733c0437a75af7778295a86a5e Mon Sep 17 00:00:00 2001 From: Andrew Pryde <andrew.pryde@oracle.com> Date: Wed, 18 Oct 2017 11:11:14 +0100 Subject: [PATCH 0094/1007] Fixed incorrect test failure message in oci client --- builder/oracle/oci/client/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/oracle/oci/client/config_test.go b/builder/oracle/oci/client/config_test.go index 221e725c3..154fe1ec2 100644 --- a/builder/oracle/oci/client/config_test.go +++ b/builder/oracle/oci/client/config_test.go @@ -82,7 +82,7 @@ func TestNewConfigDefaultsPopulated(t *testing.T) { } if adminConfig.Region != "us-ashburn-1" { - t.Errorf("Expected 'us-phoenix-1', got '%s'", adminConfig.Region) + t.Errorf("Expected 'us-ashburn-1', got '%s'", adminConfig.Region) } } From c3a00993d01d4aaafb297030642f836517d6037b Mon Sep 17 00:00:00 2001 From: Atsushi Ishibashi <atsushi.ishibashi@finatext.com> Date: Thu, 19 Oct 2017 10:45:48 +0900 Subject: [PATCH 0095/1007] Don't truncate and replace with 'a', update docs --- builder/googlecompute/template_funcs.go | 14 ++------------ builder/googlecompute/template_funcs_test.go | 12 ------------ website/source/docs/templates/engine.html.md | 9 ++++++--- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/builder/googlecompute/template_funcs.go b/builder/googlecompute/template_funcs.go index f33118b5c..1e0c654c2 100644 --- a/builder/googlecompute/template_funcs.go +++ b/builder/googlecompute/template_funcs.go @@ -16,17 +16,13 @@ func isalphanumeric(b byte) bool { } // Clean up image name by replacing invalid characters with "-" -// truncate up to 63 length, convert to a lower case +// and converting upper cases to lower cases func templateCleanImageName(s string) string { if reImageFamily.MatchString(s) { return s } b := []byte(strings.ToLower(s)) - l := 63 - if len(b) < 63 { - l = len(b) - } - newb := make([]byte, l) + newb := make([]byte, len(b)) for i := range newb { if isalphanumeric(b[i]) { newb[i] = b[i] @@ -34,12 +30,6 @@ func templateCleanImageName(s string) string { newb[i] = '-' } } - if !('a' <= newb[0] && newb[0] <= 'z') { - newb[0] = 'a' - } - if newb[l-1] == '-' { - newb[l-1] = 'a' - } return string(newb) } diff --git a/builder/googlecompute/template_funcs_test.go b/builder/googlecompute/template_funcs_test.go index 887af5883..62c57309e 100644 --- a/builder/googlecompute/template_funcs_test.go +++ b/builder/googlecompute/template_funcs_test.go @@ -19,18 +19,6 @@ func Test_templateCleanImageName(t *testing.T) { origName: "abcde-012345v1.0.0", expected: "abcde-012345v1-0-0", }, - { - origName: "a123456789012345678901234567890123456789012345678901234567890123456789", - expected: "a12345678901234567890123456789012345678901234567890123456789012", - }, - { - origName: "01234567890123456789012345678901234567890123456789012345678901.", - expected: "a1234567890123456789012345678901234567890123456789012345678901a", - }, - { - origName: "01234567890123456789012345678901234567890123456789012345678901-", - expected: "a1234567890123456789012345678901234567890123456789012345678901a", - }, } for _, v := range vals { diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index 7dcc36b4a..c4fa72e29 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -53,9 +53,12 @@ Here is a full list of the available functions for reference. #### Specific to Google Compute builders: - `clean_image_name` - GCE image names can only contain certain characters and - the maximum length is 63. This function will replace illegal characters with a "-" character - and truncate a name which exceeds maximum length. - Example usage since ":" is not a legal image name is: `{{isotime | clean_image_name}}`. + the maximum length is 63. This function will convert upper cases to lower cases + and replace illegal characters with a "-" character. + Example usage since ":" is not a legal image name is: `"a-{{isotime | clean_image_name}}"` -> `a-2017-10-18t02-06-30z`. + + Note that image name must be a match of regex `(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)` + but this function won't truncate and replace with valid character such as 'a' except '-'. ## Template variables From 4721b48c70fe161aa49059f5c18d0dac0ede464d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 20 Oct 2017 14:06:02 -0700 Subject: [PATCH 0096/1007] add a couple of extra tests and reword documentation --- builder/googlecompute/template_funcs_test.go | 17 ++++++++++++++++- website/source/docs/templates/engine.html.md | 18 +++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/builder/googlecompute/template_funcs_test.go b/builder/googlecompute/template_funcs_test.go index 62c57309e..5b37acbd9 100644 --- a/builder/googlecompute/template_funcs_test.go +++ b/builder/googlecompute/template_funcs_test.go @@ -7,18 +7,33 @@ func Test_templateCleanImageName(t *testing.T) { origName string expected string }{ + // test that valid name is unchanged { origName: "abcde-012345xyz", expected: "abcde-012345xyz", }, + + //test that capital letters are converted to lowercase { origName: "ABCDE-012345xyz", expected: "abcde-012345xyz", }, + // test that periods and colons are converted to hyphens { - origName: "abcde-012345v1.0.0", + origName: "abcde-012345v1.0:0", expected: "abcde-012345v1-0-0", }, + // Name starting with number is not valid, but not in scope of this + // function to correct + { + origName: "012345v1.0:0", + expected: "012345v1-0-0", + }, + // Name over 64 chars is not valid, but not corrected by this function. + { + origName: "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong", + expected: "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong", + }, } for _, v := range vals { diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index c4fa72e29..3b7c60b24 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -55,10 +55,22 @@ Here is a full list of the available functions for reference. - `clean_image_name` - GCE image names can only contain certain characters and the maximum length is 63. This function will convert upper cases to lower cases and replace illegal characters with a "-" character. - Example usage since ":" is not a legal image name is: `"a-{{isotime | clean_image_name}}"` -> `a-2017-10-18t02-06-30z`. + Example: - Note that image name must be a match of regex `(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)` - but this function won't truncate and replace with valid character such as 'a' except '-'. + `"mybuild-{{isotime | clean_image_name}}"` + will become + `mybuild-2017-10-18t02-06-30z`. + + Note: Valid GCE image names must match the regex + `(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)` + + This engine does not guarantee that the final image name will match the + regex; it will not truncate your name if it exceeds 63 characters, and it + will not valiate that the beginning and end of the engine's output are + valid. For example, + `"image_name": {{isotime | clean_image_name}}"` will cause your build to + fail because the image name will start with a number, which is why in the + above example we prepend the isotime with "mybuild". ## Template variables From b942c27b21760cb0d7b40e422c19d216e31167b4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sat, 21 Oct 2017 20:13:47 -0700 Subject: [PATCH 0097/1007] remove end of line spaces --- .../intro/getting-started/build-image.html.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 1161e81e0..b242ca67a 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -186,10 +186,10 @@ want to store and namespace images for quick reference, you can use [Atlas by HashiCorp](https://atlas.hashicorp.com). We'll cover remotely building and storing images at the end of this getting started guide. -After running the above example, your AWS account now has an AMI associated with -it. AMIs are stored in S3 by Amazon, so unless you want to be charged about -$0.01 per month, you'll probably want to remove it. Remove the AMI by first -deregistering it on the [AWS AMI management +After running the above example, your AWS account now has an AMI associated +with it. AMIs are stored in S3 by Amazon, so unless you want to be charged +about &#36;0.01 per month, you'll probably want to remove it. Remove the AMI by +first deregistering it on the [AWS AMI management page](https://console.aws.amazon.com/ec2/home?region=us-east-1#s=Images). Next, delete the associated snapshot on the [AWS snapshot management page](https://console.aws.amazon.com/ec2/home?region=us-east-1#s=Snapshots). @@ -409,25 +409,25 @@ Start-Service -Name WinRM Save the above code in a file named `bootstrap_win.txt`. --> **A quick aside/warning:** +-> **A quick aside/warning:** Windows administrators in the know might be wondering why we haven't simply used a `winrm quickconfig -q` command in the script above, as this would *automatically* set up all of the required elements necessary for connecting -over WinRM. Why all the extra effort to configure things manually? +over WinRM. Why all the extra effort to configure things manually? Well, long and short, use of the `winrm quickconfig -q` command can sometimes cause the Packer build to fail shortly after the WinRM connection is -established. How? +established. How? 1. Among other things, as well as setting up the listener for WinRM, the quickconfig command also configures the firewall to allow management messages -to be sent over HTTP. +to be sent over HTTP. 2. This undoes the previous command in the script that configured the -firewall to prevent this access. +firewall to prevent this access. 3. The upshot is that the system is configured and ready to accept WinRM -connections earlier than intended. +connections earlier than intended. 4. If Packer establishes its WinRM connection immediately after execution of the 'winrm quickconfig -q' command, the later commands within the script that restart the WinRM service will unceremoniously pull the rug out from under -the connection. +the connection. 5. While Packer does *a lot* to ensure the stability of its connection in to your instance, this sort of abuse can prove to be too much and *may* cause your Packer build to stall irrecoverably or fail! From 12fc928e1d0d1d82438f91b4ddb36c89bd611996 Mon Sep 17 00:00:00 2001 From: Ben Phegan <ben.phegan@optiver.com.au> Date: Fri, 20 Oct 2017 09:29:17 +1100 Subject: [PATCH 0098/1007] Initial commit of Hyper-V disk_additional_size capability. Support a maximum of 64 disks added to the SCSI controller. Implement #4823. --- builder/hyperv/common/driver.go | 2 ++ builder/hyperv/common/driver_ps_4.go | 4 ++++ builder/hyperv/common/step_create_vm.go | 15 ++++++++++++ builder/hyperv/iso/builder.go | 8 +++++++ builder/hyperv/iso/builder_test.go | 24 +++++++++++++++++++ common/powershell/hyperv/hyperv.go | 13 ++++++++++ .../source/docs/builders/hyperv-iso.html.md | 6 +++++ 7 files changed, 72 insertions(+) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index ba9ab5c4c..3e44b0ece 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -66,6 +66,8 @@ type Driver interface { CreateVirtualMachine(string, string, string, string, int64, int64, string, uint) error + AddVirtualMachineHardDrive(string, string, string, int64, string) error + CloneVirtualMachine(string, string, string, bool, string, string, string, int64, string) error DeleteVirtualMachine(string) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index c836137d2..c06294d49 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -170,6 +170,10 @@ func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType stri return hyperv.CreateVirtualSwitch(switchName, switchType) } +func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, controllerType string) error { + return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, controllerType) +} + func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, switchName, generation) } diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index d88de5558..a244a9f5e 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "path/filepath" + "strconv" "strings" "github.com/hashicorp/packer/packer" @@ -26,6 +27,7 @@ type StepCreateVM struct { EnableDynamicMemory bool EnableSecureBoot bool EnableVirtualizationExtensions bool + AdditionalDiskSize []uint } func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { @@ -108,6 +110,19 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { } } + if len(s.AdditionalDiskSize) > 0 { + for index, size := range s.AdditionalDiskSize { + var diskSize = size * 1024 * 1024 + err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, s.VMName+"-"+strconv.Itoa(int(index))+".vhdx", int64(diskSize), "SCSI") + if err != nil { + err := fmt.Errorf("Error creating and attaching additional disk drive: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + } + // Set the final name in the state bag so others can use it state.Put("vmName", s.VMName) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 2cd786a42..b3c1e1f61 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -90,6 +90,8 @@ type Config struct { Communicator string `mapstructure:"communicator"` + AdditionalDiskSize []uint `mapstructure:"disk_additional_size"` + SkipCompaction bool `mapstructure:"skip_compaction"` ctx interpolate.Context @@ -163,6 +165,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } + if len(b.config.AdditionalDiskSize) > 64 { + err = errors.New("VM's currently support a maximun of 64 additional SCSI attached disks.") + errs = packer.MultiErrorAppend(errs, err) + } + log.Println(fmt.Sprintf("Using switch %s", b.config.SwitchName)) log.Println(fmt.Sprintf("%s: %v", "SwitchName", b.config.SwitchName)) @@ -345,6 +352,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableDynamicMemory: b.config.EnableDynamicMemory, EnableSecureBoot: b.config.EnableSecureBoot, EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, + AdditionalDiskSize: b.config.AdditionalDiskSize, }, &hypervcommon.StepEnableIntegrationService{}, diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 3fc17a8b7..73ae5591b 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -3,6 +3,7 @@ package iso import ( "fmt" "reflect" + "strconv" "testing" "github.com/hashicorp/packer/packer" @@ -18,6 +19,7 @@ func testConfig() map[string]interface{} { "ram_size": 64, "disk_size": 256, "guest_additions_mode": "none", + "disk_additional_size": "50000,40000,30000", packer.BuildNameConfigKey: "foo", } } @@ -391,6 +393,27 @@ func TestBuilderPrepare_SizeIsRequiredWhenNotUsingExistingHarddrive(t *testing.T } } +func TestBuilderPrepare_MaximumOfSixtyFourAdditionalDisks(t *testing.T) { + var b Builder + config := testConfig() + + disks := make([]string, 65) + for i := range disks { + disks[i] = strconv.Itoa(i) + } + config["disk_additional_size"] = disks + + b = Builder{} + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Errorf("should have error") + } + +} + func TestBuilderPrepare_CommConfig(t *testing.T) { // Test Winrm { @@ -447,4 +470,5 @@ func TestBuilderPrepare_CommConfig(t *testing.T) { t.Errorf("bad host: %s", host) } } + } diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 0c649c450..d15ee0748 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -855,6 +855,19 @@ Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -SwitchName $swi return err } +func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName string, vhdSizeBytes int64, controllerType string) error { + + var script = ` +param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes, [string]$controllerType) +$vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdName +New-VHD $vhdPath -SizeBytes $vhdSizeInBytes +Add-VMHardDiskDrive -VMName $vmName -path $vhdPath -controllerType $controllerType +` + var ps powershell.PowerShellCmd + err := ps.Run(script, vmName, vhdRoot, vhdName, strconv.FormatInt(vhdSizeBytes, 10), controllerType) + return err +} + func UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error { var script = ` diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index be66cd0e2..b5b6a3826 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -88,6 +88,12 @@ can be configured for this builder. - `cpu` (number) - The number of cpus the virtual machine should use. If this isn't specified, the default is 1 cpu. +- `disk_additional_size` (array of integers) - The size(s) of any additional + hard disks for the VM in megabytes. If this is not specified then the VM + will only contain a primary hard disk. Additional drives will be attached to the SCSI + interface only. The builder uses expandable, not fixed-size virtual hard disks, + so the actual file representing the disk will not use the full size unless it is full. + - `disk_size` (number) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40 GB. From f07b791a3f3f82a0c3a8ef2f44a8ff18f1801f38 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Oct 2017 09:29:03 -0700 Subject: [PATCH 0099/1007] revert eol whitespace changes --- .../intro/getting-started/build-image.html.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index b242ca67a..5c63a7041 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -409,25 +409,25 @@ Start-Service -Name WinRM Save the above code in a file named `bootstrap_win.txt`. --> **A quick aside/warning:** +-> **A quick aside/warning:** Windows administrators in the know might be wondering why we haven't simply used a `winrm quickconfig -q` command in the script above, as this would *automatically* set up all of the required elements necessary for connecting -over WinRM. Why all the extra effort to configure things manually? +over WinRM. Why all the extra effort to configure things manually? Well, long and short, use of the `winrm quickconfig -q` command can sometimes cause the Packer build to fail shortly after the WinRM connection is -established. How? +established. How? 1. Among other things, as well as setting up the listener for WinRM, the quickconfig command also configures the firewall to allow management messages -to be sent over HTTP. +to be sent over HTTP. 2. This undoes the previous command in the script that configured the -firewall to prevent this access. +firewall to prevent this access. 3. The upshot is that the system is configured and ready to accept WinRM -connections earlier than intended. +connections earlier than intended. 4. If Packer establishes its WinRM connection immediately after execution of the 'winrm quickconfig -q' command, the later commands within the script that restart the WinRM service will unceremoniously pull the rug out from under -the connection. +the connection. 5. While Packer does *a lot* to ensure the stability of its connection in to your instance, this sort of abuse can prove to be too much and *may* cause your Packer build to stall irrecoverably or fail! From bd5d1fc53a7be101df14b33709e4ec98d04f4276 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Oct 2017 09:39:25 -0700 Subject: [PATCH 0100/1007] fix formatting; --- .../intro/getting-started/build-image.html.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 5c63a7041..ba0683797 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -409,25 +409,25 @@ Start-Service -Name WinRM Save the above code in a file named `bootstrap_win.txt`. --> **A quick aside/warning:** +-> **A quick aside/warning:**<br /> Windows administrators in the know might be wondering why we haven't simply used a `winrm quickconfig -q` command in the script above, as this would *automatically* set up all of the required elements necessary for connecting -over WinRM. Why all the extra effort to configure things manually? +over WinRM. Why all the extra effort to configure things manually?<br /> Well, long and short, use of the `winrm quickconfig -q` command can sometimes cause the Packer build to fail shortly after the WinRM connection is -established. How? +established. How?<br /> 1. Among other things, as well as setting up the listener for WinRM, the quickconfig command also configures the firewall to allow management messages -to be sent over HTTP. +to be sent over HTTP.<br /> 2. This undoes the previous command in the script that configured the -firewall to prevent this access. +firewall to prevent this access.<br /> 3. The upshot is that the system is configured and ready to accept WinRM -connections earlier than intended. +connections earlier than intended.<br /> 4. If Packer establishes its WinRM connection immediately after execution of the 'winrm quickconfig -q' command, the later commands within the script that restart the WinRM service will unceremoniously pull the rug out from under -the connection. +the connection.<br /> 5. While Packer does *a lot* to ensure the stability of its connection in to your instance, this sort of abuse can prove to be too much and *may* cause your Packer build to stall irrecoverably or fail! From 449da8389666dd70c621012228d74f04cc0e0794 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Oct 2017 12:10:31 -0700 Subject: [PATCH 0101/1007] use correct oracle builder name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8dac199dc..5249f515e 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ comes out of the box with support for the following platforms: * Hyper-V * 1&1 * OpenStack -* Oracle Bare Metal Cloud Services +* Oracle Cloud Infrastructure * Parallels * ProfitBricks * QEMU. Both KVM and Xen images. From 7e1646826d6bc3f95b3bb38409bac0b139ffe596 Mon Sep 17 00:00:00 2001 From: Mark Meyer <mark@ofosos.org> Date: Mon, 23 Oct 2017 21:10:40 +0200 Subject: [PATCH 0102/1007] Check if VolumeTags is empty before tagging volumes Related to #5486 --- builder/amazon/common/step_run_spot_instance.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 2af83d98f..b34d09bcb 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -278,7 +278,7 @@ func (s *StepRunSpotInstance) Run(state multistep.StateBag) multistep.StepAction } } - if len(volumeIds) > 0 { + if len(volumeIds) > 0 && len(s.VolumeTags) > 0 { ui.Say("Adding tags to source EBS Volumes") tags, err := ConvertToEC2Tags(s.VolumeTags, *ec2conn.Config.Region, s.SourceAMI, s.Ctx) if err != nil { From 1cc9b3f1e3d973326185a840557435758dfbe259 Mon Sep 17 00:00:00 2001 From: Mark Meyer <mark@ofosos.org> Date: Mon, 23 Oct 2017 21:40:35 +0200 Subject: [PATCH 0103/1007] Bring back volume tagging to ebsvolume Related to #5486 --- builder/amazon/ebsvolume/builder.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 7cab85e91..cf2993538 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -164,6 +164,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe TemporarySGSourceCidr: b.config.TemporarySGSourceCidr, }, instanceStep, + &stepTagEBSVolumes{ + VolumeMapping: b.config.VolumeMappings, + Ctx: b.config.ctx, + }, &awscommon.StepGetPassword{ Debug: b.config.PackerDebug, Comm: &b.config.RunConfig.Comm, From 309bf61257abbcec697221ea2b75ad2d0688a109 Mon Sep 17 00:00:00 2001 From: Mark Meyer <mark@ofosos.org> Date: Mon, 23 Oct 2017 22:33:16 +0200 Subject: [PATCH 0104/1007] Add missing blockdevices to ebsvolume builder --- builder/amazon/ebsvolume/builder.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index cf2993538..375511082 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -116,6 +116,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, EbsOptimized: b.config.EbsOptimized, AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.launchBlockDevices, Tags: b.config.RunTags, Ctx: b.config.ctx, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, @@ -135,6 +136,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, EbsOptimized: b.config.EbsOptimized, AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.launchBlockDevices, Tags: b.config.RunTags, Ctx: b.config.ctx, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, From 0cf0a4336dc122677fb04dcbd33aaf69ddeb8ab2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Oct 2017 15:38:37 -0700 Subject: [PATCH 0105/1007] relay ovftool output. --- post-processor/vsphere/post-processor.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index e97147334..2f3dc6c73 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -1,10 +1,10 @@ package vsphere import ( + "bytes" "fmt" "log" "net/url" - "os" "os/exec" "strings" @@ -135,13 +135,16 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac password, "<password>", -1)) + + var out bytes.Buffer cmd := exec.Command("ovftool", args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr + cmd.Stdout = &out if err := cmd.Run(); err != nil { - return nil, false, fmt.Errorf("Failed: %s\n", err) + return nil, false, fmt.Errorf("Failed: %s\n%s\n", err, out.String()) } + ui.Message(out.String()) + return artifact, false, nil } From b3ea9da4f72c3db176bab3d6c34c0de75d2a5ece Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Oct 2017 18:28:31 -0700 Subject: [PATCH 0106/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96cfb6fb8..67e1bda2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * post-processor/docker-push: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] * builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] +* post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] ## 1.1.1 (October 13, 2017) From dbeb48a99323149bff92fdd55aa25c230b1c63e7 Mon Sep 17 00:00:00 2001 From: Manoj <manojlds@gmail.com> Date: Tue, 24 Oct 2017 11:27:22 +0530 Subject: [PATCH 0107/1007] Update wording on manifest behaviour on build rerun --- website/source/docs/post-processors/manifest.html.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/source/docs/post-processors/manifest.html.md b/website/source/docs/post-processors/manifest.html.md index 73b691c1b..8ad53f451 100644 --- a/website/source/docs/post-processors/manifest.html.md +++ b/website/source/docs/post-processors/manifest.html.md @@ -65,10 +65,11 @@ An example manifest file looks like: } ``` -If I run the build again, my new build will be added to the manifest file rather than replacing it, so you can always grab specific builds from the manifest by uuid. +If the build is run again, the new build artifacts will be added to the manifest file rather than replacing it. It is possible to grab specific build artifacts from the manifest by using `packer_run_uuid`. -The mainfest above was generated from this packer.json: -``` +The above mainfest was generated with this packer.json: + +```json { "builders": [ { From abcc02dc6415e115dc8901f72e501052a538ed25 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 24 Oct 2017 11:38:56 -0700 Subject: [PATCH 0108/1007] filter password from logs --- post-processor/vsphere/post-processor.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index 2f3dc6c73..c028cd087 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -129,25 +129,25 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message(fmt.Sprintf("Uploading %s to vSphere", source)) - log.Printf("Starting ovftool with parameters: %s", - strings.Replace( - strings.Join(args, " "), - password, - "<password>", - -1)) + log.Printf("Starting ovftool with parameters: %s", p.filterLog(strings.Join(args, " "))) var out bytes.Buffer cmd := exec.Command("ovftool", args...) cmd.Stdout = &out if err := cmd.Run(); err != nil { - return nil, false, fmt.Errorf("Failed: %s\n%s\n", err, out.String()) + return nil, false, fmt.Errorf("Failed: %s\n%s\n", err, p.filterLog(out.String())) } - ui.Message(out.String()) + ui.Message(p.filterLog(out.String())) return artifact, false, nil } +func (p *PostProcessor) filterLog(s string) string { + password := url.QueryEscape(p.config.Password) + return strings.Replace(s, password, "<password>", -1) +} + func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) { args := []string{ "--acceptAllEulas", From 4c5df7922203a6ed14b7854b28f2a6a3bff00406 Mon Sep 17 00:00:00 2001 From: Mark Meyer <mark@ofosos.org> Date: Tue, 24 Oct 2017 23:22:50 +0200 Subject: [PATCH 0109/1007] Fix regressions introduced in the instance builder Related to #5504 --- builder/amazon/instance/builder.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index ebc93751e..bd534599b 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -198,7 +198,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe if b.config.SpotPrice == "" || b.config.SpotPrice == "0" { instanceStep = &awscommon.StepRunSourceInstance{ Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -211,12 +210,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe BlockDevices: b.config.BlockDevices, Tags: b.config.RunTags, Ctx: b.config.ctx, - InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, } } else { instanceStep = &awscommon.StepRunSpotInstance{ Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, @@ -231,7 +228,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe BlockDevices: b.config.BlockDevices, Tags: b.config.RunTags, Ctx: b.config.ctx, - InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, } } From 0be02ab2177b14cbf3c8bc73ed855f425b6e288f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 28 Aug 2017 13:36:29 -0700 Subject: [PATCH 0110/1007] hyper-v: Don't error while checking for admin permissions. --- builder/hyperv/common/driver_ps_4.go | 34 ++++++++++++++++++++-------- common/powershell/powershell.go | 8 +++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index c836137d2..c5400f921 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -301,23 +301,37 @@ func (d *HypervPS4Driver) verifyPSHypervModule() error { return nil } +func (d *HypervPS4Driver) isCurrentUserAHyperVAdministrator() (bool, error) { + //SID:S-1-5-32-578 = 'BUILTIN\Hyper-V Administrators' + //https://support.microsoft.com/en-us/help/243330/well-known-security-identifiers-in-windows-operating-systems + + var script = ` +$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() +$principal = new-object System.Security.Principal.WindowsPrincipal($identity) +$hypervrole = [System.Security.Principal.SecurityIdentifier]"S-1-5-32-544" +return $principal.IsInRole($hypervrole) +` + + var ps powershell.PowerShellCmd + cmdOut, err := ps.Output(script) + if err != nil { + return false, err + } + + res := strings.TrimSpace(cmdOut) + return powershell.IsTrue(res), nil +} + func (d *HypervPS4Driver) verifyHypervPermissions() error { log.Printf("Enter method: %s", "verifyHypervPermissions") - //SID:S-1-5-32-578 = 'BUILTIN\Hyper-V Administrators' - //https://support.microsoft.com/en-us/help/243330/well-known-security-identifiers-in-windows-operating-systems - hypervAdminCmd := "([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('S-1-5-32-578')" - - var ps powershell.PowerShellCmd - cmdOut, err := ps.Output(hypervAdminCmd) + hyperVAdmin, err := d.isCurrentUserAHyperVAdministrator() if err != nil { - return err + log.Printf("Error discovering if current is is a Hyper-V Admin: %s", err) } + if !hyperVAdmin { - res := strings.TrimSpace(cmdOut) - - if res == "False" { isAdmin, _ := powershell.IsCurrentUserAnAdministrator() if !isAdmin { diff --git a/common/powershell/powershell.go b/common/powershell/powershell.go index a41915474..43e2df492 100644 --- a/common/powershell/powershell.go +++ b/common/powershell/powershell.go @@ -17,6 +17,14 @@ const ( powerShellTrue = "True" ) +func IsTrue(s string) bool { + return s == powerShellTrue +} + +func IsFalse(s string) bool { + return s == powerShellFalse +} + type PowerShellCmd struct { Stdout io.Writer Stderr io.Writer From fb098d045d55868f4c884459b471b1c4e64d28a0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 25 Oct 2017 10:17:08 -0700 Subject: [PATCH 0111/1007] builder/virtualbox-ovf retry removing VM. moves behavior from builder/virtualbox-iso into the driver so it is automatically available to callers. --- builder/virtualbox/common/driver_4_2.go | 12 +++++++++++- builder/virtualbox/iso/step_create_vm.go | 18 ++++-------------- builder/virtualbox/ovf/step_import.go | 3 ++- common/retry.go | 18 +++++++++++------- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/builder/virtualbox/common/driver_4_2.go b/builder/virtualbox/common/driver_4_2.go index 4824fd8c9..3e1151c21 100644 --- a/builder/virtualbox/common/driver_4_2.go +++ b/builder/virtualbox/common/driver_4_2.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" "time" + + packer "github.com/hashicorp/packer/common" ) type VBox42Driver struct { @@ -50,7 +52,15 @@ func (d *VBox42Driver) CreateSCSIController(vmName string, name string) error { } func (d *VBox42Driver) Delete(name string) error { - return d.VBoxManage("unregistervm", name, "--delete") + return packer.Retry(1, 1, 5, func(i uint) (bool, error) { + if err := d.VBoxManage("unregistervm", name, "--delete"); err != nil { + if i+1 == 5 { + return false, err + } + return false, nil + } + return true, nil + }) } func (d *VBox42Driver) Iso() (string, error) { diff --git a/builder/virtualbox/iso/step_create_vm.go b/builder/virtualbox/iso/step_create_vm.go index 149fd6d9a..ad1f72eaf 100644 --- a/builder/virtualbox/iso/step_create_vm.go +++ b/builder/virtualbox/iso/step_create_vm.go @@ -2,10 +2,10 @@ package iso import ( "fmt" + vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) // This step creates the actual virtual machine. @@ -73,18 +73,8 @@ func (s *stepCreateVM) Cleanup(state multistep.StateBag) { return } - ui.Say("Unregistering and deleting virtual machine...") - var err error = nil - for i := 0; i < 5; i++ { - err = driver.Delete(s.vmName) - if err == nil { - break - } - - time.Sleep(1 * time.Second * time.Duration(i)) - } - - if err != nil { - ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) + ui.Say("Deregistering and deleting VM...") + if err := driver.Delete(s.vmName); err != nil { + ui.Error(fmt.Sprintf("Error deleting VM: %s", err)) } } diff --git a/builder/virtualbox/ovf/step_import.go b/builder/virtualbox/ovf/step_import.go index b9a6285fe..33e71fc24 100644 --- a/builder/virtualbox/ovf/step_import.go +++ b/builder/virtualbox/ovf/step_import.go @@ -2,6 +2,7 @@ package ovf import ( "fmt" + vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" @@ -49,7 +50,7 @@ func (s *StepImport) Cleanup(state multistep.StateBag) { return } - ui.Say("Unregistering and deleting imported VM...") + ui.Say("Deregistering and deleting imported VM...") if err := driver.Delete(s.vmName); err != nil { ui.Error(fmt.Sprintf("Error deleting VM: %s", err)) } diff --git a/common/retry.go b/common/retry.go index 4f229e892..b820cf817 100644 --- a/common/retry.go +++ b/common/retry.go @@ -9,17 +9,21 @@ import ( var RetryExhaustedError error = fmt.Errorf("Function never succeeded in Retry") // RetryableFunc performs an action and returns a bool indicating whether the -// function is done, or if it should keep retrying, and an erorr which will +// function is done, or if it should keep retrying, and an error which will // abort the retry and be returned by the Retry function. The 0-indexed attempt // is passed with each call. type RetryableFunc func(uint) (bool, error) -// Retry retries a function up to numTries times with exponential backoff. -// If numTries == 0, retry indefinitely. If interval == 0, Retry will not delay retrying and there will be -// no exponential backoff. If maxInterval == 0, maxInterval is set to +Infinity. -// Intervals are in seconds. -// Returns an error if initial > max intervals, if retries are exhausted, or if the passed function returns -// an error. +/* +Retry retries a function up to numTries times with exponential backoff. +If numTries == 0, retry indefinitely. +If interval == 0, Retry will not delay retrying and there will be no +exponential backoff. +If maxInterval == 0, maxInterval is set to +Infinity. +Intervals are in seconds. +Returns an error if initial > max intervals, if retries are exhausted, or if the passed function returns +an error. +*/ func Retry(initialInterval float64, maxInterval float64, numTries uint, function RetryableFunc) error { if maxInterval == 0 { maxInterval = math.Inf(1) From 1901c0385fc3896315a0c604a5f52a6c4a9dc05e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 25 Oct 2017 09:53:51 -0700 Subject: [PATCH 0112/1007] remove login_email from docker adds fixer removes documentation removes from docker builder and docker-push pp --- builder/docker/config.go | 1 - builder/docker/driver.go | 2 +- builder/docker/driver_docker.go | 5 +-- builder/docker/driver_mock.go | 4 +- builder/docker/step_pull.go | 4 +- fix/fixer.go | 2 + fix/fixer_docker_email.go | 45 +++++++++++++++++++ post-processor/docker-push/post-processor.go | 2 - website/source/docs/builders/docker.html.md | 2 - .../docs/post-processors/docker-push.html.md | 6 +-- 10 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 fix/fixer_docker_email.go diff --git a/builder/docker/config.go b/builder/docker/config.go index fee08929d..6116a995b 100644 --- a/builder/docker/config.go +++ b/builder/docker/config.go @@ -42,7 +42,6 @@ type Config struct { // This is used to login to dockerhub to pull a private base container. For // pushing to dockerhub, see the docker post-processors Login bool - LoginEmail string `mapstructure:"login_email"` LoginPassword string `mapstructure:"login_password"` LoginServer string `mapstructure:"login_server"` LoginUsername string `mapstructure:"login_username"` diff --git a/builder/docker/driver.go b/builder/docker/driver.go index 0eda0a604..09da054f3 100644 --- a/builder/docker/driver.go +++ b/builder/docker/driver.go @@ -28,7 +28,7 @@ type Driver interface { // Login. This will lock the driver from performing another Login // until Logout is called. Therefore, any users MUST call Logout. - Login(repo, email, username, password string) error + Login(repo, username, password string) error // Logout. This can only be called if Login succeeded. Logout(repo string) error diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index 61c5ad93e..c3db3dda6 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -147,13 +147,10 @@ func (d *DockerDriver) IPAddress(id string) (string, error) { return strings.TrimSpace(stdout.String()), nil } -func (d *DockerDriver) Login(repo, email, user, pass string) error { +func (d *DockerDriver) Login(repo, user, pass string) error { d.l.Lock() args := []string{"login"} - if email != "" { - args = append(args, "-e", email) - } if user != "" { args = append(args, "-u", user) } diff --git a/builder/docker/driver_mock.go b/builder/docker/driver_mock.go index 57a02b691..5193f21ee 100644 --- a/builder/docker/driver_mock.go +++ b/builder/docker/driver_mock.go @@ -29,7 +29,6 @@ type MockDriver struct { IPAddressErr error LoginCalled bool - LoginEmail string LoginUsername string LoginPassword string LoginRepo string @@ -115,10 +114,9 @@ func (d *MockDriver) IPAddress(id string) (string, error) { return d.IPAddressResult, d.IPAddressErr } -func (d *MockDriver) Login(r, e, u, p string) error { +func (d *MockDriver) Login(r, u, p string) error { d.LoginCalled = true d.LoginRepo = r - d.LoginEmail = e d.LoginUsername = u d.LoginPassword = p return d.LoginErr diff --git a/builder/docker/step_pull.go b/builder/docker/step_pull.go index 9e38f7b49..6b1ac8935 100644 --- a/builder/docker/step_pull.go +++ b/builder/docker/step_pull.go @@ -2,9 +2,10 @@ package docker import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) type StepPull struct{} @@ -40,7 +41,6 @@ func (s *StepPull) Run(state multistep.StateBag) multistep.StepAction { ui.Message("Logging in...") err := driver.Login( config.LoginServer, - config.LoginEmail, config.LoginUsername, config.LoginPassword) if err != nil { diff --git a/fix/fixer.go b/fix/fixer.go index 938a7160f..5ca0b3a18 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -33,6 +33,7 @@ func init() { "manifest-filename": new(FixerManifestFilename), "amazon-shutdown_behavior": new(FixerAmazonShutdownBehavior), "amazon-enhanced-networking": new(FixerAmazonEnhancedNetworking), + "docker-email": new(FixerDockerEmail), } FixerOrder = []string{ @@ -49,5 +50,6 @@ func init() { "manifest-filename", "amazon-shutdown_behavior", "amazon-enhanced-networking", + "docker-email", } } diff --git a/fix/fixer_docker_email.go b/fix/fixer_docker_email.go new file mode 100644 index 000000000..d1402d3bd --- /dev/null +++ b/fix/fixer_docker_email.go @@ -0,0 +1,45 @@ +package fix + +import "github.com/mitchellh/mapstructure" + +type FixerDockerEmail struct{} + +func (FixerDockerEmail) Fix(input map[string]interface{}) (map[string]interface{}, error) { + // Our template type we'll use for this fixer only + type template struct { + Builders []map[string]interface{} + PostProcessors []map[string]interface{} `mapstructure:"post-processors"` + } + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.Decode(input, &tpl); err != nil { + return nil, err + } + + // Go through each builder and delete `docker_login` if present + for _, builder := range tpl.Builders { + _, ok := builder["login_email"] + if !ok { + continue + } + delete(builder, "login_email") + } + + // Go through each post-processor and delete `docker_login` if present + for _, pp := range tpl.PostProcessors { + _, ok := pp["login_email"] + if !ok { + continue + } + delete(pp, "login_email") + } + + input["builders"] = tpl.Builders + input["post-processors"] = tpl.PostProcessors + return input, nil +} + +func (FixerDockerEmail) Synopsis() string { + return `Removes "login_email" from the Docker builder.` +} diff --git a/post-processor/docker-push/post-processor.go b/post-processor/docker-push/post-processor.go index 5d44cecf0..f0fee00ca 100644 --- a/post-processor/docker-push/post-processor.go +++ b/post-processor/docker-push/post-processor.go @@ -16,7 +16,6 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` Login bool - LoginEmail string `mapstructure:"login_email"` LoginUsername string `mapstructure:"login_username"` LoginPassword string `mapstructure:"login_password"` LoginServer string `mapstructure:"login_server"` @@ -81,7 +80,6 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message("Logging in...") err := driver.Login( p.config.LoginServer, - p.config.LoginEmail, p.config.LoginUsername, p.config.LoginPassword) if err != nil { diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index 951860971..13c43da60 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -185,8 +185,6 @@ You must specify (only) one of `commit`, `discard`, or `export_path`. order to pull the image. The builder only logs in for the duration of the pull. It always logs out afterwards. For log into ECR see `ecr_login`. -- `login_email` (string) - The email to use to authenticate to login. - - `login_username` (string) - The username to use to authenticate to login. - `login_password` (string) - The password to use to authenticate to login. diff --git a/website/source/docs/post-processors/docker-push.html.md b/website/source/docs/post-processors/docker-push.html.md index 5400cb56a..f151c30ff 100644 --- a/website/source/docs/post-processors/docker-push.html.md +++ b/website/source/docs/post-processors/docker-push.html.md @@ -43,16 +43,14 @@ This post-processor has only optional configuration: - `login` (boolean) - Defaults to false. If true, the post-processor will login prior to pushing. For log into ECR see `ecr_login`. -- `login_email` (string) - The email to use to authenticate to login. - - `login_username` (string) - The username to use to authenticate to login. - `login_password` (string) - The password to use to authenticate to login. - `login_server` (string) - The server address to login to. -Note: When using *Docker Hub* or *Quay* registry servers, `login` must to be -set to `true` and `login_email`, `login_username`, **and** `login_password` +-&gt; **Note:** When using *Docker Hub* or *Quay* registry servers, `login` must to be +set to `true` and `login_username`, **and** `login_password` must to be set to your registry credentials. When using Docker Hub, `login_server` can be omitted. From 812fd12a0b58912fc3564c7eb65092035dc43e74 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 25 Oct 2017 09:24:06 -0700 Subject: [PATCH 0113/1007] move trimspace to powershell exit check --- builder/hyperv/common/driver_ps_4.go | 7 ++----- common/powershell/powershell.go | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index c5400f921..5be8a0cd3 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -291,9 +291,7 @@ func (d *HypervPS4Driver) verifyPSHypervModule() error { return err } - res := strings.TrimSpace(cmdOut) - - if res == "False" { + if powershell.IsFalse(cmdOut) { err := fmt.Errorf("%s", "PS Hyper-V module is not loaded. Make sure Hyper-V feature is on.") return err } @@ -318,8 +316,7 @@ return $principal.IsInRole($hypervrole) return false, err } - res := strings.TrimSpace(cmdOut) - return powershell.IsTrue(res), nil + return powershell.IsTrue(cmdOut), nil } func (d *HypervPS4Driver) verifyHypervPermissions() error { diff --git a/common/powershell/powershell.go b/common/powershell/powershell.go index 43e2df492..4d550cb8b 100644 --- a/common/powershell/powershell.go +++ b/common/powershell/powershell.go @@ -18,11 +18,11 @@ const ( ) func IsTrue(s string) bool { - return s == powerShellTrue + return strings.TrimSpace(s) == powerShellTrue } func IsFalse(s string) bool { - return s == powerShellFalse + return strings.TrimSpace(s) == powerShellFalse } type PowerShellCmd struct { From 794e518eb743e88cd1ce7b9972692c84109971c4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 25 Oct 2017 09:25:12 -0700 Subject: [PATCH 0114/1007] use hyper-v admin group, not admin --- builder/hyperv/common/driver_ps_4.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index 5be8a0cd3..d14aea1c6 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -306,7 +306,7 @@ func (d *HypervPS4Driver) isCurrentUserAHyperVAdministrator() (bool, error) { var script = ` $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() $principal = new-object System.Security.Principal.WindowsPrincipal($identity) -$hypervrole = [System.Security.Principal.SecurityIdentifier]"S-1-5-32-544" +$hypervrole = [System.Security.Principal.SecurityIdentifier]"S-1-5-32-578" return $principal.IsInRole($hypervrole) ` From 26c7188cf34f22d07c21f2b071d3002294473362 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 25 Oct 2017 14:53:18 -0700 Subject: [PATCH 0115/1007] add community tools links from @geerlingguy --- website/source/community-tools.html.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/website/source/community-tools.html.md b/website/source/community-tools.html.md index 5a31fa7cc..6dcf6445b 100644 --- a/website/source/community-tools.html.md +++ b/website/source/community-tools.html.md @@ -32,8 +32,11 @@ power of Packer templates. - [packer-baseboxes](https://github.com/taliesins/packer-baseboxes) - Templates for packer to build base boxes -- [packer-ubuntu](https://github.com/cbednarski/packer-ubuntu) - Ubuntu LTS - Virtual Machines for Vagrant +- [cbednarski/packer-ubuntu](https://github.com/cbednarski/packer-ubuntu) - + Ubuntu LTS Virtual Machines for Vagrant + +* [geerlingguy/packer-ubuntu-1604](https://github.com/geerlingguy/packer-ubuntu-1604) + \- Ubuntu 16.04 minimal Vagrant Box using Ansible provisioner ## Wrappers From 95d82b4637c7361b39f1623c518ad29a2d07816b Mon Sep 17 00:00:00 2001 From: Patrick Lang <patrick.lang@hotmail.com> Date: Tue, 24 Oct 2017 22:20:46 -0700 Subject: [PATCH 0116/1007] Fixing auto checkpoints for generation 2 VMs. Resolves #5506 Also cleaning up ifs --- common/powershell/hyperv/hyperv.go | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 0c649c450..fd32d75a6 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -202,8 +202,11 @@ if ($harddrivePath){ } ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) - return err + if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)); err != nil { + return err + } + + return DisableAutomaticCheckpoints(vmName) } else { var script = ` param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) @@ -217,15 +220,11 @@ if ($harddrivePath){ } ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName) - - if err != nil { + if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName); err != nil { return err } - err = DisableAutomaticCheckpoints(vmName) - - if err != nil { + if err := DisableAutomaticCheckpoints(vmName); err != nil { return err } @@ -368,21 +367,18 @@ if ($vm) { func CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error { if cloneFromVmName != "" { - err := ExportVmxcVirtualMachine(path, cloneFromVmName, cloneFromSnapshotName, cloneAllSnapshots) - if err != nil { + if err := ExportVmxcVirtualMachine(path, cloneFromVmName, cloneFromSnapshotName, cloneAllSnapshots); err != nil { return err } } if cloneFromVmxcPath != "" { - err := CopyVmxcVirtualMachine(path, cloneFromVmxcPath) - if err != nil { + if err := CopyVmxcVirtualMachine(path, cloneFromVmxcPath); err != nil { return err } } - err := ImportVmxcVirtualMachine(path, vmName, harddrivePath, ram, switchName) - if err != nil { + if err := ImportVmxcVirtualMachine(path, vmName, harddrivePath, ram, switchName); err != nil { return err } From 6d5f75e1180233ce4bbdfc52c0946e49eee3c8ef Mon Sep 17 00:00:00 2001 From: Patrick Lang <patrick.lang@hotmail.com> Date: Wed, 25 Oct 2017 21:47:14 -0700 Subject: [PATCH 0117/1007] run gofmt --- common/powershell/hyperv/hyperv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index fd32d75a6..f34004f60 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -205,7 +205,7 @@ if ($harddrivePath){ if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)); err != nil { return err } - + return DisableAutomaticCheckpoints(vmName) } else { var script = ` From 5c2f75805318c2028e2723361b5138b0a1a40a15 Mon Sep 17 00:00:00 2001 From: Joe Ferguson <joe@joeferguson.me> Date: Thu, 26 Oct 2017 07:42:49 -0500 Subject: [PATCH 0118/1007] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20typo=20in=20"cop?= =?UTF-8?q?yed"=20->=20"copied"=20usages.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/alicloud/ecs/step_region_copy_image.go | 6 +++--- builder/alicloud/ecs/step_share_image.go | 12 ++++++------ post-processor/vagrant/hyperv.go | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/builder/alicloud/ecs/step_region_copy_image.go b/builder/alicloud/ecs/step_region_copy_image.go index 5f60cafab..f92878712 100644 --- a/builder/alicloud/ecs/step_region_copy_image.go +++ b/builder/alicloud/ecs/step_region_copy_image.go @@ -59,11 +59,11 @@ func (s *setpRegionCopyAlicloudImage) Cleanup(state multistep.StateBag) { client := state.Get("client").(*ecs.Client) alicloudImages := state.Get("alicloudimages").(map[string]string) ui.Say(fmt.Sprintf("Stopping copy image because cancellation or error...")) - for copyedRegionId, copyedImageId := range alicloudImages { - if copyedRegionId == s.RegionId { + for copiedRegionId, copiedImageId := range alicloudImages { + if copiedRegionId == s.RegionId { continue } - if err := client.CancelCopyImage(common.Region(copyedRegionId), copyedImageId); err != nil { + if err := client.CancelCopyImage(common.Region(copiedRegionId), copiedImageId); err != nil { ui.Say(fmt.Sprintf("Error cancelling copy image: %v", err)) } } diff --git a/builder/alicloud/ecs/step_share_image.go b/builder/alicloud/ecs/step_share_image.go index bdd8d1245..50e5a640f 100644 --- a/builder/alicloud/ecs/step_share_image.go +++ b/builder/alicloud/ecs/step_share_image.go @@ -19,11 +19,11 @@ func (s *setpShareAlicloudImage) Run(state multistep.StateBag) multistep.StepAct client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) alicloudImages := state.Get("alicloudimages").(map[string]string) - for copyedRegion, copyedImageId := range alicloudImages { + for copiedRegion, copiedImageId := range alicloudImages { err := client.ModifyImageSharePermission( &ecs.ModifyImageSharePermissionArgs{ - RegionId: common.Region(copyedRegion), - ImageId: copyedImageId, + RegionId: common.Region(copiedRegion), + ImageId: copiedImageId, AddAccount: s.AlicloudImageShareAccounts, RemoveAccount: s.AlicloudImageUNShareAccounts, }) @@ -44,11 +44,11 @@ func (s *setpShareAlicloudImage) Cleanup(state multistep.StateBag) { client := state.Get("client").(*ecs.Client) alicloudImages := state.Get("alicloudimages").(map[string]string) ui.Say("Restoring image share permission because cancellations or error...") - for copyedRegion, copyedImageId := range alicloudImages { + for copiedRegion, copiedImageId := range alicloudImages { err := client.ModifyImageSharePermission( &ecs.ModifyImageSharePermissionArgs{ - RegionId: common.Region(copyedRegion), - ImageId: copyedImageId, + RegionId: common.Region(copiedRegion), + ImageId: copiedImageId, AddAccount: s.AlicloudImageUNShareAccounts, RemoveAccount: s.AlicloudImageShareAccounts, }) diff --git a/post-processor/vagrant/hyperv.go b/post-processor/vagrant/hyperv.go index 14486738b..657304963 100644 --- a/post-processor/vagrant/hyperv.go +++ b/post-processor/vagrant/hyperv.go @@ -68,7 +68,7 @@ func (p *HypervProvider) Process(ui packer.Ui, artifact packer.Artifact, dir str } } - ui.Message(fmt.Sprintf("Copyed %s to %s", path, dstPath)) + ui.Message(fmt.Sprintf("Copied %s to %s", path, dstPath)) } return From 33b85b01305e0bbe973958d72c4df4709b049b49 Mon Sep 17 00:00:00 2001 From: Ohad Basan <ohad.basan@ironsrc.com> Date: Thu, 26 Oct 2017 19:52:34 +0300 Subject: [PATCH 0119/1007] Add suggestion for "expected_disconnect" option if disconnection occurs --- provisioner/shell/provisioner.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 5233e50e7..8d654d7ec 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -283,7 +283,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { // we were expecting it. if cmd.ExitStatus == packer.CmdDisconnect { if !p.config.ExpectDisconnect { - return fmt.Errorf("Script disconnected unexpectedly.") + return fmt.Errorf("Script disconnected unexpectedly. " + + "Try adding \"expect_disconnect\": true in the shell provisioner parameters.") } } else if cmd.ExitStatus != 0 { return fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus) From ecad3348b386709956654d0379770120d1f9ac97 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 26 Oct 2017 10:41:49 -0700 Subject: [PATCH 0120/1007] rephrase log message. --- provisioner/shell/provisioner.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 8d654d7ec..8dd5796ce 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -284,7 +284,9 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { if cmd.ExitStatus == packer.CmdDisconnect { if !p.config.ExpectDisconnect { return fmt.Errorf("Script disconnected unexpectedly. " + - "Try adding \"expect_disconnect\": true in the shell provisioner parameters.") + "If you expected your script to disconnect, i.e. from a " + + "restart, you can try adding `\"expect_disconnect\": true` " + + "to the shell provisioner parameters.") } } else if cmd.ExitStatus != 0 { return fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus) From a63ba2f9c3d45499aa13fd12fd995d6adeb09fd1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 30 Oct 2017 09:46:13 -0700 Subject: [PATCH 0121/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67e1bda2a..d796feaff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * post-processor/docker-push: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] * builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] * post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] +* builder/hyper-v: Also disable automatic checkpoints for gen 2 VMs. [GH-5517] ## 1.1.1 (October 13, 2017) From fe4d4648e697da9447904d6f19d0ad4a2ea8afe9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 30 Oct 2017 12:51:22 -0700 Subject: [PATCH 0122/1007] codeowners for post-processors --- CODEOWNERS | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 56d91a081..c037a38d4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,19 +2,25 @@ # builders -/builder/alicloud/ dongxiao.zzh@alibaba-inc.com -/builder/amazon/ebssurrogate/ @jen20 -/builder/amazon/ebsvolume/ @jen20 -/builder/azure/ @boumenot -/builder/hyperv/ @taliesins -/builder/lxc/ @ChrisLundquist -/builder/lxd/ @ChrisLundquist -/builder/oneandone/ @jasmingacic -/builder/oracle/ @prydie @owainlewis -/builder/profitbricks/ @jasmingacic -/builder/triton/ @jen20 @sean- +/builder/alicloud/ dongxiao.zzh@alibaba-inc.com +/builder/amazon/ebssurrogate/ @jen20 +/builder/amazon/ebsvolume/ @jen20 +/builder/azure/ @boumenot +/builder/hyperv/ @taliesins +/builder/lxc/ @ChrisLundquist +/builder/lxd/ @ChrisLundquist +/builder/oneandone/ @jasmingacic +/builder/oracle/ @prydie @owainlewis +/builder/profitbricks/ @jasmingacic +/builder/triton/ @jen20 @sean- # provisioners -/provisioner/ansible/ @bhcleek -/provisioner/converge/ @stevendborrelli +/provisioner/ansible/ @bhcleek +/provisioner/converge/ @stevendborrelli + +# post-processors +/post-processor/alicloud-import/ dongxiao.zzh@alibaba-inc.com +/post-processor/checksum/ v.tolstov@selfip.ru +/post-processor/googlecompute-export/ crunkleton@google.com +/post-processor/vsphere-template/ nelson@bennu.cl From 6c4fbe8d87a7b890c9b3d3a52d85deb63c18ecc1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 27 Oct 2017 09:58:13 -0700 Subject: [PATCH 0123/1007] use correct default region when deregistering AMIs. --- builder/amazon/common/step_deregister_ami.go | 101 ++++++++++--------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index 3ad8711aa..da0bc0cc4 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -18,68 +18,71 @@ type StepDeregisterAMI struct { } func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - regions := s.Regions - if len(regions) == 0 { - regions = append(regions, s.AccessConfig.RawRegion) + // Check for force deregister + if !s.ForceDeregister { + return multistep.ActionContinue } - // Check for force deregister - if s.ForceDeregister { - for _, region := range regions { - // get new connection for each region in which we need to deregister vms - session, err := s.AccessConfig.Session() - if err != nil { - return multistep.ActionHalt - } + ui := state.Get("ui").(packer.Ui) + ec2conn := state.Get("ec2").(*ec2.EC2) + regions := s.Regions + if len(regions) == 0 { + regions = append(regions, *ec2conn.Config.Region) + } - regionconn := ec2.New(session.Copy(&aws.Config{ - Region: aws.String(region)}, - )) + for _, region := range regions { + // get new connection for each region in which we need to deregister vms + session, err := s.AccessConfig.Session() + if err != nil { + return multistep.ActionHalt + } - resp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ - Filters: []*ec2.Filter{{ - Name: aws.String("name"), - Values: []*string{aws.String(s.AMIName)}, - }}}) + regionconn := ec2.New(session.Copy(&aws.Config{ + Region: aws.String(region)}, + )) + + resp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ + Filters: []*ec2.Filter{{ + Name: aws.String("name"), + Values: []*string{aws.String(s.AMIName)}, + }}}) + + if err != nil { + err := fmt.Errorf("Error describing AMI: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Deregister image(s) by name + for _, i := range resp.Images { + _, err := regionconn.DeregisterImage(&ec2.DeregisterImageInput{ + ImageId: i.ImageId, + }) if err != nil { - err := fmt.Errorf("Error describing AMI: %s", err) + err := fmt.Errorf("Error deregistering existing AMI: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } + ui.Say(fmt.Sprintf("Deregistered AMI %s, id: %s", s.AMIName, *i.ImageId)) - // Deregister image(s) by name - for _, i := range resp.Images { - _, err := regionconn.DeregisterImage(&ec2.DeregisterImageInput{ - ImageId: i.ImageId, - }) + // Delete snapshot(s) by image + if s.ForceDeleteSnapshot { + for _, b := range i.BlockDeviceMappings { + if b.Ebs != nil && aws.StringValue(b.Ebs.SnapshotId) != "" { + _, err := regionconn.DeleteSnapshot(&ec2.DeleteSnapshotInput{ + SnapshotId: b.Ebs.SnapshotId, + }) - if err != nil { - err := fmt.Errorf("Error deregistering existing AMI: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - ui.Say(fmt.Sprintf("Deregistered AMI %s, id: %s", s.AMIName, *i.ImageId)) - - // Delete snapshot(s) by image - if s.ForceDeleteSnapshot { - for _, b := range i.BlockDeviceMappings { - if b.Ebs != nil && aws.StringValue(b.Ebs.SnapshotId) != "" { - _, err := regionconn.DeleteSnapshot(&ec2.DeleteSnapshotInput{ - SnapshotId: b.Ebs.SnapshotId, - }) - - if err != nil { - err := fmt.Errorf("Error deleting existing snapshot: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - ui.Say(fmt.Sprintf("Deleted snapshot: %s", *b.Ebs.SnapshotId)) + if err != nil { + err := fmt.Errorf("Error deleting existing snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } + ui.Say(fmt.Sprintf("Deleted snapshot: %s", *b.Ebs.SnapshotId)) } } } From 5949bc91c444cc9e84a15184ef7ecdef08b84cc9 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 25 Oct 2017 13:50:58 +0100 Subject: [PATCH 0124/1007] Extend upload and subsequent 'dot sourcing' of env vars to std PS command * Wrap funcs to flatten and upload env vars with new func prepareEnvVars. While the wrapped funcs could be combined, keeping them separate simplifies testing. * Configure/refactor std and elevated PS to use new funcs to prepare, upload and dot source env vars. * Dot sourcing the env vars in this way avoids the need to embed them directly in the command string. This avoids the need to escape the env vars to ensure the command string is correctly parsed. * Characters within the env vars that are special to PS (such as $'s and backticks) will still need to be escaped to allow them to be correctly interpreted by PS. * The std and elevated PS commands now inject env vars into the remote env via the same mechanism. This ensures consistent behaviour across the two command types. Fixes #5471 --- provisioner/powershell/provisioner.go | 52 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 4297acf08..3d2f16f85 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -113,7 +113,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.EnvVarFormat == "" { - p.config.EnvVarFormat = `$env:%s=\"%s\"; ` + p.config.EnvVarFormat = `$env:%s="%s"; ` } if p.config.ElevatedEnvVarFormat == "" { @@ -121,7 +121,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.ExecuteCommand == "" { - p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` + p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"` } if p.config.ElevatedExecuteCommand == "" { @@ -331,6 +331,19 @@ func (p *Provisioner) retryable(f func() error) error { } } +// Enviroment variables required within the remote environment are uploaded within a PS script and +// then enabled by 'dot sourcing' the script immediately prior to execution of the main command +func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err error) { + // Collate all required env vars into a plain string with required formatting applied + flattenedEnvVars := p.createFlattenedEnvVars(elevated) + // Create a powershell script on the target build fs containing the flattened env vars + envVarPath, err = p.uploadEnvVars(flattenedEnvVars) + if err != nil { + return "", err + } + return +} + func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { flattened = "" envVars := make(map[string]string) @@ -367,6 +380,19 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { return } +func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (envVarPath string, err error) { + // Upload all env vars to a powershell script on the target build file system + envVarReader := strings.NewReader(flattenedEnvVars) + uuid := uuid.TimeOrderedUUID() + envVarPath = fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) + log.Printf("Uploading env vars to %s", envVarPath) + err = p.communicator.Upload(envVarPath, envVarReader, nil) + if err != nil { + return "", fmt.Errorf("Error uploading ps script containing env vars: %s", err) + } + return +} + func (p *Provisioner) createCommandText() (command string, err error) { // Return the interpolated command if p.config.ElevatedUser == "" { @@ -377,12 +403,15 @@ func (p *Provisioner) createCommandText() (command string, err error) { } func (p *Provisioner) createCommandTextNonPrivileged() (command string, err error) { - // Create environment variables to set before executing the command - flattenedEnvVars := p.createFlattenedEnvVars(false) + // Prepare everything needed to enable the required env vars within the remote environment + envVarPath, err := p.prepareEnvVars(false) + if err != nil { + return "", err + } p.config.ctx.Data = &ExecuteCommandTemplate{ - Vars: flattenedEnvVars, Path: p.config.RemotePath, + Vars: envVarPath, } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -395,17 +424,10 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro } func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { - // Can't double escape the env vars, lets create shiny new ones - flattenedEnvVars := p.createFlattenedEnvVars(true) - // Need to create a mini ps1 script containing all of the environment variables we want; - // we'll be dot-sourcing this later - envVarReader := strings.NewReader(flattenedEnvVars) - uuid := uuid.TimeOrderedUUID() - envVarPath := fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) - log.Printf("Uploading env vars to %s", envVarPath) - err = p.communicator.Upload(envVarPath, envVarReader, nil) + // Prepare everything needed to enable the required env vars within the remote environment + envVarPath, err := p.prepareEnvVars(false) if err != nil { - return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) + return "", err } p.config.ctx.Data = &ExecuteCommandTemplate{ From 4b89fc1c009fb7eb46fc530d805d1dcf3511ff33 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 25 Oct 2017 22:47:08 +0100 Subject: [PATCH 0125/1007] Fix tests post changes. Add test for upload func. --- provisioner/powershell/provisioner_test.go | 85 +++++++++++++++------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index e7e64d52e..749564d4d 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -79,8 +79,8 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { t.Error("expected elevated_password to be empty") } - if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` { - t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) + if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"` { + t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) } if p.config.ElevatedExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` { @@ -403,7 +403,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { ui := testUi() p := new(Provisioner) - // Defaults provided by Packer + // Defaults provided by Packer - env vars should not appear in cmd p.config.PackerBuildName = "vmware" p.config.PackerBuilderType = "iso" comm := new(packer.MockCommunicator) @@ -413,11 +413,14 @@ func TestProvisionerProvision_Inline(t *testing.T) { t.Fatal("should not have error") } - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd := comm.StartCmd.Command + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } + // User supplied env vars should not change things envVars := make([]string, 2) envVars[0] = "FOO=BAR" envVars[1] = "BAR=BAZ" @@ -430,9 +433,11 @@ func TestProvisionerProvision_Inline(t *testing.T) { t.Fatal("should not have error") } - expectedCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd = comm.StartCmd.Command + re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + matched = re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } } @@ -455,11 +460,12 @@ func TestProvisionerProvision_Scripts(t *testing.T) { t.Fatal("should not have error") } - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd := comm.StartCmd.Command + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } - } func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { @@ -488,9 +494,11 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { t.Fatal("should not have error") } - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd := comm.StartCmd.Command + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } } @@ -547,11 +555,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { {"FOO==bar"}, // User env var with value starting with equals } expected := []string{ - `$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:BAZ=\"qux\"; $env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:FOO=\"bar=baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:FOO=\"=bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, + `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, } p := new(Provisioner) @@ -571,7 +579,6 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { } func TestProvision_createCommandText(t *testing.T) { - config := testConfig() config["remote_path"] = "c:/Windows/Temp/script.ps1" p := new(Provisioner) @@ -586,22 +593,46 @@ func TestProvision_createCommandText(t *testing.T) { // Non-elevated cmd, _ := p.createCommandText() - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` - - if cmd != expectedCommand { - t.Fatalf("Expected Non-elevated command: %s, got %s", expectedCommand, cmd) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } // Elevated p.config.ElevatedUser = "vagrant" p.config.ElevatedPassword = "vagrant" cmd, _ = p.createCommandText() - matched, _ := regexp.MatchString("powershell -executionpolicy bypass -file \"%TEMP%(.{1})packer-elevated-shell.*", cmd) + re = regexp.MustCompile(`powershell -executionpolicy bypass -file "%TEMP%\\packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) + matched = re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected elevated command: %s", cmd) } } +func TestProvision_uploadEnvVars(t *testing.T) { + p := new(Provisioner) + comm := new(packer.MockCommunicator) + p.communicator = comm + + flattenedEnvVars := `$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild";` + + envVarPath, err := p.uploadEnvVars(flattenedEnvVars) + if err != nil { + t.Fatalf("Did not expect error: %s", err.Error()) + } + + if comm.UploadCalled != true { + t.Fatalf("Failed to upload env var file") + } + + re := regexp.MustCompile(`\${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1`) + matched := re.MatchString(envVarPath) + if !matched { + t.Fatalf("Got unexpected path for env var file: %s", envVarPath) + } +} + func TestProvision_generateElevatedShellRunner(t *testing.T) { // Non-elevated From 3cdc79de6a9fc5c6bf276b3e9f3627eeb0c0c5f5 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 25 Oct 2017 23:06:01 +0100 Subject: [PATCH 0126/1007] Update docs to reflect new upload and dot source of env var for std ps cmd --- .../docs/provisioners/powershell.html.md | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index f085a6e82..a096bf2f5 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -1,8 +1,8 @@ --- description: | - The shell Packer provisioner provisions machines built by Packer using shell - scripts. Shell provisioning is the easiest way to get software installed and - configured on a machine. + The shell Packer provisioner provisions machines built by Packer using + shell scripts. Shell provisioning is the easiest way to get software + installed and configured on a machine. layout: docs page_title: 'PowerShell - Provisioners' sidebar_current: 'docs-provisioners-powershell' @@ -29,20 +29,21 @@ The example below is fully functional. ## Configuration Reference The reference of available configuration options is listed below. The only -required element is either "inline" or "script". Every other option is optional. +required element is either "inline" or "script". Every other option is +optional. Exactly *one* of the following is required: - `inline` (array of strings) - This is an array of commands to execute. The - commands are concatenated by newlines and turned into a single file, so they - are all executed within the same context. This allows you to change + commands are concatenated by newlines and turned into a single file, so + they are all executed within the same context. This allows you to change directories in one command and use something in the directory in the next and so on. Inline scripts are the easiest way to pull off simple tasks within the machine. - `script` (string) - The path to a script to upload and execute in - the machine. This path can be absolute or relative. If it is relative, it is - relative to the working directory when Packer is executed. + the machine. This path can be absolute or relative. If it is relative, it + is relative to the working directory when Packer is executed. - `scripts` (array of strings) - An array of scripts to execute. The scripts will be uploaded and executed in the order specified. Each script is @@ -51,12 +52,12 @@ Exactly *one* of the following is required: Optional parameters: -- `binary` (boolean) - If true, specifies that the script(s) are binary files, - and Packer should therefore not convert Windows line endings to Unix line - endings (if there are any). By default this is false. +- `binary` (boolean) - If true, specifies that the script(s) are binary + files, and Packer should therefore not convert Windows line endings to Unix + line endings (if there are any). By default this is false. -- `elevated_execute_command` (string) - The command to use to execute the elevated - script. By default this is as follows: +- `elevated_execute_command` (string) - The command to use to execute the + elevated script. By default this is as follows: ``` powershell powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }" @@ -65,32 +66,34 @@ Optional parameters: The value of this is treated as [configuration template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and - `Vars`, which is the location of a temp file containing the list of `environment_vars`, if configured. + `Vars`, which is the location of a temp file containing the list of + `environment_vars`, if configured. - `environment_vars` (array of strings) - An array of key/value pairs to inject prior to the execute\_command. The format should be `key=value`. - Packer injects some environmental variables by default into the environment, - as well, which are covered in the section below. + Packer injects some environmental variables by default into the + environment, as well, which are covered in the section below. - `execute_command` (string) - The command to use to execute the script. By default this is as follows: ``` powershell - powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }" + powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }" ``` The value of this is treated as [configuration template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and - `Vars`, which is the list of `environment_vars`, if configured. + `Vars`, which is the location of a temp file containing the list of + `environment_vars`, if configured. - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given Windows user. - `remote_path` (string) - The path where the script will be uploaded to in - the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must be a - writable location and any parent directories must already exist. + the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must + be a writable location and any parent directories must already exist. - `start_retry_timeout` (string) - The amount of time to attempt to *start* the remote process. By default this is "5m" or 5 minutes. This setting @@ -111,9 +114,10 @@ commonly useful environmental variables: This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. -- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the - machine that the script is running on. This is useful if you want to run - only certain parts of the script on systems built with certain builders. +- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create + the machine that the script is running on. This is useful if you want to + run only certain parts of the script on systems built with certain + builders. - `PACKER_HTTP_ADDR` If using a builder that provides an http server for file transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this From c65fa8490dc668f5fda22fa273142baa489fd4c4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 30 Oct 2017 14:17:19 -0700 Subject: [PATCH 0127/1007] fix various bugs deregistering AMIs always deregister ami in session region validate that session region does not appear in ami_regions --- builder/amazon/chroot/builder.go | 3 ++- builder/amazon/common/access_config.go | 4 ++-- builder/amazon/common/ami_config.go | 14 ++++++++++++-- builder/amazon/common/step_deregister_ami.go | 6 ++---- builder/amazon/ebs/builder.go | 3 ++- builder/amazon/ebssurrogate/builder.go | 3 ++- builder/amazon/instance/builder.go | 3 ++- builder/amazon/instance/step_upload_bundle.go | 9 +-------- 8 files changed, 25 insertions(+), 20 deletions(-) diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index a259960d1..b6b5088a2 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -121,7 +121,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { var warns []string errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.AMIConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) for _, mounts := range b.config.ChrootMounts { if len(mounts) != 3 { diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index aa974f29c..59ef90c2b 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -32,7 +32,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } - region, err := c.Region() + region, err := c.region() if err != nil { return nil, err } @@ -82,7 +82,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { // Region returns the aws.Region object for access to AWS services, requesting // the region from the instance metadata if possible. -func (c *AccessConfig) Region() (string, error) { +func (c *AccessConfig) region() (string, error) { if c.RawRegion != "" { if !c.SkipValidation { if valid := ValidateRegion(c.RawRegion); !valid { diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index f59cb1d61..09b25479a 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -38,12 +38,23 @@ func stringInSlice(s []string, searchstr string) bool { return false } -func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error { +func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context) []error { var errs []error + + session, err := accessConfig.Session() + if err != nil { + errs = append(errs, err) + } + region := *session.Config.Region + if c.AMIName == "" { errs = append(errs, fmt.Errorf("ami_name must be specified")) } + if stringInSlice(c.AMIRegions, region) { + errs = append(errs, fmt.Errorf("Cannot copy AMI to AWS session region '%s', please remove it from `ami_regions`.", region)) + } + if len(c.AMIRegions) > 0 { regionSet := make(map[string]struct{}) regions := make([]string, 0, len(c.AMIRegions)) @@ -61,7 +72,6 @@ func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error { // Verify the region is real if valid := ValidateRegion(region); !valid { errs = append(errs, fmt.Errorf("Unknown region: %s", region)) - continue } } diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index da0bc0cc4..188a40808 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -25,10 +25,8 @@ func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ec2conn := state.Get("ec2").(*ec2.EC2) - regions := s.Regions - if len(regions) == 0 { - regions = append(regions, *ec2conn.Config.Region) - } + // Add the session region to list of regions will will deregister AMIs in + regions := append(s.Regions, *ec2conn.Config.Region) for _, region := range regions { // get new connection for each region in which we need to deregister vms diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index beaa4a276..e28343c66 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -64,8 +64,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { // Accumulate any errors var errs *packer.MultiError errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.AMIConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) if errs != nil && len(errs.Errors) > 0 { diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index f61b2d43e..71fdb2c9d 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -64,7 +64,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { var errs *packer.MultiError errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.AMIConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RootDevice.Prepare(&b.config.ctx)...) diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index ebc93751e..9500867ef 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -127,7 +127,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { var errs *packer.MultiError errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.AMIConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, + b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) if b.config.AccountId == "" { diff --git a/builder/amazon/instance/step_upload_bundle.go b/builder/amazon/instance/step_upload_bundle.go index 91abfc9b6..a38a77c93 100644 --- a/builder/amazon/instance/step_upload_bundle.go +++ b/builder/amazon/instance/step_upload_bundle.go @@ -29,17 +29,10 @@ func (s *StepUploadBundle) Run(state multistep.StateBag) multistep.StepAction { manifestPath := state.Get("manifest_path").(string) ui := state.Get("ui").(packer.Ui) - region, err := config.Region() - if err != nil { - err := fmt.Errorf("Error retrieving region: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - accessKey := config.AccessKey secretKey := config.SecretKey session, err := config.AccessConfig.Session() + region := *session.Config.Region accessConfig := session.Config var token string if err == nil && accessKey == "" && secretKey == "" { From 0e4ea7420b2ca7cdbbd2feb0c1cdc3486110c273 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 30 Oct 2017 14:34:16 -0700 Subject: [PATCH 0128/1007] fix tests --- builder/amazon/common/access_config.go | 3 +- builder/amazon/common/ami_config.go | 17 +++++----- builder/amazon/common/ami_config_test.go | 40 ++++++++++++------------ 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 59ef90c2b..bf295e535 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -80,8 +80,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } -// Region returns the aws.Region object for access to AWS services, requesting -// the region from the instance metadata if possible. +// region returns either the region from config or region from metadata service func (c *AccessConfig) region() (string, error) { if c.RawRegion != "" { if !c.SkipValidation { diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index 09b25479a..7dfe1af88 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -41,20 +41,21 @@ func stringInSlice(s []string, searchstr string) bool { func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context) []error { var errs []error - session, err := accessConfig.Session() - if err != nil { - errs = append(errs, err) + if accessConfig != nil { + session, err := accessConfig.Session() + if err != nil { + errs = append(errs, err) + } + region := *session.Config.Region + if stringInSlice(c.AMIRegions, region) { + errs = append(errs, fmt.Errorf("Cannot copy AMI to AWS session region '%s', please remove it from `ami_regions`.", region)) + } } - region := *session.Config.Region if c.AMIName == "" { errs = append(errs, fmt.Errorf("ami_name must be specified")) } - if stringInSlice(c.AMIRegions, region) { - errs = append(errs, fmt.Errorf("Cannot copy AMI to AWS session region '%s', please remove it from `ami_regions`.", region)) - } - if len(c.AMIRegions) > 0 { regionSet := make(map[string]struct{}) regions := make([]string, 0, len(c.AMIRegions)) diff --git a/builder/amazon/common/ami_config_test.go b/builder/amazon/common/ami_config_test.go index faa67c56d..5f130130c 100644 --- a/builder/amazon/common/ami_config_test.go +++ b/builder/amazon/common/ami_config_test.go @@ -13,12 +13,12 @@ func testAMIConfig() *AMIConfig { func TestAMIConfigPrepare_name(t *testing.T) { c := testAMIConfig() - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatalf("shouldn't have err: %s", err) } c.AMIName = "" - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have error") } } @@ -26,22 +26,22 @@ func TestAMIConfigPrepare_name(t *testing.T) { func TestAMIConfigPrepare_regions(t *testing.T) { c := testAMIConfig() c.AMIRegions = nil - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatalf("shouldn't have err: %s", err) } c.AMIRegions = listEC2Regions() - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatalf("shouldn't have err: %s", err) } c.AMIRegions = []string{"foo"} - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have error") } c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-1"} - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatalf("bad: %s", err) } @@ -52,7 +52,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { c.AMIRegions = []string{"custom"} c.AMISkipRegionValidation = true - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatal("shouldn't have error") } c.AMISkipRegionValidation = false @@ -63,7 +63,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "456-789-0123", } - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatal("shouldn't have error") } @@ -73,7 +73,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "", } - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatal("should have passed; we are able to use default KMS key if not sharing") } @@ -84,7 +84,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "", } - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have an error b/c can't use default KMS key if sharing") } @@ -94,7 +94,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-west-1": "789-012-3456", "us-east-2": "456-789-0123", } - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have error b/c theres a region in the key map that isn't in ami_regions") } @@ -103,7 +103,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-east-1": "123-456-7890", "us-west-1": "789-012-3456", } - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") } @@ -115,7 +115,7 @@ func TestAMIConfigPrepare_regions(t *testing.T) { "us-east-1": "123-456-7890", "us-west-1": "", } - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") } } @@ -126,12 +126,12 @@ func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { c.AMIEncryptBootVolume = true c.AMIKmsKeyId = "" - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("shouldn't be able to share ami with encrypted boot volume") } c.AMIKmsKeyId = "89c3fb9a-de87-4f2a-aedc-fddc5138193c" - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("shouldn't be able to share ami with encrypted boot volume") } } @@ -140,7 +140,7 @@ func TestAMINameValidation(t *testing.T) { c := testAMIConfig() c.AMIName = "aa" - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("shouldn't be able to have an ami name with less than 3 characters") } @@ -149,22 +149,22 @@ func TestAMINameValidation(t *testing.T) { longAmiName += "a" } c.AMIName = longAmiName - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("shouldn't be able to have an ami name with great than 128 characters") } c.AMIName = "+aaa" - if err := c.Prepare(nil); err == nil { + if err := c.Prepare(nil, nil); err == nil { t.Fatal("shouldn't be able to have an ami name with invalid characters") } c.AMIName = "fooBAR1()[] ./-'@_" - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatal("should be able to use all of the allowed AMI characters") } c.AMIName = `xyz-base-2017-04-05-1934` - if err := c.Prepare(nil); err != nil { + if err := c.Prepare(nil, nil); err != nil { t.Fatalf("expected `xyz-base-2017-04-05-1934` to pass validation.") } From 314fc94bd837d8f7a810e84a9854fe94c50ed18a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 30 Oct 2017 15:02:39 -0700 Subject: [PATCH 0129/1007] clean up --- builder/amazon/common/access_config.go | 27 +++++++++++--------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index bf295e535..c692937a0 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -32,18 +32,17 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } - region, err := c.region() - if err != nil { - return nil, err - } - if c.ProfileName != "" { if err := os.Setenv("AWS_PROFILE", c.ProfileName); err != nil { log.Printf("Set env error: %s", err) } } - config := aws.NewConfig().WithRegion(region).WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) + config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) + + if region := c.region(); region != "" { + config = config.WithRegion(region) + } if c.CustomEndpointEc2 != "" { config = config.WithEndpoint(c.CustomEndpointEc2) @@ -72,6 +71,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.MFACode, nil } } + var err error c.session, err = session.NewSessionWithOptions(opts) if err != nil { return nil, err @@ -81,25 +81,20 @@ func (c *AccessConfig) Session() (*session.Session, error) { } // region returns either the region from config or region from metadata service -func (c *AccessConfig) region() (string, error) { +func (c *AccessConfig) region() string { if c.RawRegion != "" { - if !c.SkipValidation { - if valid := ValidateRegion(c.RawRegion); !valid { - return "", fmt.Errorf("Not a valid region: %s", c.RawRegion) - } - } - return c.RawRegion, nil + return c.RawRegion } sess := session.New() ec2meta := ec2metadata.New(sess) - identity, err := ec2meta.GetInstanceIdentityDocument() + region, err := ec2meta.Region() if err != nil { log.Println("Error getting region from metadata service, "+ "probably because we're not running on AWS.", err) - return "", nil + return "" } - return identity.Region, nil + return region } func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { From d322fc6c192a73de4eb37c79a2b208bd798adc20 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 30 Oct 2017 15:14:42 -0700 Subject: [PATCH 0130/1007] Shorten metadata timeout When running in travis, metadata requests will timeout after 5 seconds. After 24 such timeouts, we'll hit travis' build timeout of two minutes, and the build will fail. Lowering it to 100 gets us in a safe time limit. We _may_ need to expose a timeout env var with this logic, however. --- builder/amazon/common/access_config.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index c692937a0..03deca8bf 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -4,11 +4,13 @@ import ( "fmt" "log" "os" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" + "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/packer/template/interpolate" ) @@ -86,8 +88,13 @@ func (c *AccessConfig) region() string { return c.RawRegion } - sess := session.New() - ec2meta := ec2metadata.New(sess) + client := cleanhttp.DefaultClient() + + // Keep the default timeout (100ms) low as we don't want to wait in non-EC2 environments + client.Timeout = 100 * time.Millisecond + ec2meta := ec2metadata.New(session.New(), &aws.Config{ + HTTPClient: client, + }) region, err := ec2meta.Region() if err != nil { log.Println("Error getting region from metadata service, "+ From 1f2135f65edca7413fc02615c677a27f1ff887af Mon Sep 17 00:00:00 2001 From: Matt Schreiber <EMAIL> Date: Mon, 30 Oct 2017 21:48:43 -0400 Subject: [PATCH 0131/1007] Add options to LXC builder for influencing for how containers are built and started via - create_options: a list of options passed to lxc-create - start_options: a list of options passed to lxc-start - attach_options: a list of options passed to lxc-attach Also extended existing LXC builder BATS tests to exercise the new builder options, and added website docs. --- builder/lxc/communicator.go | 8 +- builder/lxc/config.go | 3 + builder/lxc/step_lxc_create.go | 7 +- builder/lxc/step_provision.go | 1 + builder/lxc/step_wait_init.go | 1 + test/builder_lxc.bats | 98 ++++++++++++++++++++---- test/fixtures/builder-lxc/minimal.json | 18 ++++- website/source/docs/builders/lxc.html.md | 15 ++++ 8 files changed, 131 insertions(+), 20 deletions(-) diff --git a/builder/lxc/communicator.go b/builder/lxc/communicator.go index 8d9765979..6e41ace60 100644 --- a/builder/lxc/communicator.go +++ b/builder/lxc/communicator.go @@ -16,6 +16,7 @@ import ( type LxcAttachCommunicator struct { RootFs string ContainerName string + AttachOptions []string CmdWrapper CommandWrapper } @@ -110,8 +111,13 @@ func (c *LxcAttachCommunicator) DownloadDir(src string, dst string, exclude []st func (c *LxcAttachCommunicator) Execute(commandString string) (*exec.Cmd, error) { log.Printf("Executing with lxc-attach in container: %s %s %s", c.ContainerName, c.RootFs, commandString) + + attachCommand := []string{"sudo", "lxc-attach"} + attachCommand = append(attachCommand, c.AttachOptions...) + attachCommand = append(attachCommand, []string{"--name", "%s", "--", "/bin/sh -c \"%s\""}...) + command, err := c.CmdWrapper( - fmt.Sprintf("sudo lxc-attach --name %s -- /bin/sh -c \"%s\"", c.ContainerName, commandString)) + fmt.Sprintf(strings.Join(attachCommand, " "), c.ContainerName, commandString)) if err != nil { return nil, err } diff --git a/builder/lxc/config.go b/builder/lxc/config.go index c3c28d4fb..5d49dbfd6 100644 --- a/builder/lxc/config.go +++ b/builder/lxc/config.go @@ -18,6 +18,9 @@ type Config struct { ContainerName string `mapstructure:"container_name"` CommandWrapper string `mapstructure:"command_wrapper"` RawInitTimeout string `mapstructure:"init_timeout"` + CreateOptions []string `mapstructure:"create_options"` + StartOptions []string `mapstructure:"start_options"` + AttachOptions []string `mapstructure:"attach_options"` Name string `mapstructure:"template_name"` Parameters []string `mapstructure:"template_parameters"` EnvVars []string `mapstructure:"template_environment_vars"` diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index a98926ffa..d1dbdf2d3 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -28,12 +28,15 @@ func (s *stepLxcCreate) Run(state multistep.StateBag) multistep.StepAction { } commands := make([][]string, 3) - commands[0] = append(config.EnvVars, []string{"lxc-create", "-n", name, "-t", config.Name, "--"}...) + commands[0] = append(config.EnvVars, "lxc-create") + commands[0] = append(commands[0], config.CreateOptions...) + commands[0] = append(commands[0], []string{"-n", name, "-t", config.Name, "--"}...) commands[0] = append(commands[0], config.Parameters...) // prevent tmp from being cleaned on boot, we put provisioning scripts there // todo: wait for init to finish before moving on to provisioning instead of this commands[1] = []string{"touch", filepath.Join(rootfs, "tmp", ".tmpfs")} - commands[2] = []string{"lxc-start", "-d", "--name", name} + commands[2] = append([]string{"lxc-start"}, config.StartOptions...) + commands[2] = append(commands[2], []string{"-d", "--name", name}...) ui.Say("Creating container...") for _, command := range commands { diff --git a/builder/lxc/step_provision.go b/builder/lxc/step_provision.go index f91eb56ce..0cf2a8bdb 100644 --- a/builder/lxc/step_provision.go +++ b/builder/lxc/step_provision.go @@ -19,6 +19,7 @@ func (s *StepProvision) Run(state multistep.StateBag) multistep.StepAction { // Create our communicator comm := &LxcAttachCommunicator{ ContainerName: config.ContainerName, + AttachOptions: config.AttachOptions, RootFs: mountPath, CmdWrapper: wrappedCommand, } diff --git a/builder/lxc/step_wait_init.go b/builder/lxc/step_wait_init.go index e5d375312..1ddda52b6 100644 --- a/builder/lxc/step_wait_init.go +++ b/builder/lxc/step_wait_init.go @@ -76,6 +76,7 @@ func (s *StepWaitInit) waitForInit(state multistep.StateBag, cancel <-chan struc comm := &LxcAttachCommunicator{ ContainerName: config.ContainerName, + AttachOptions: config.AttachOptions, RootFs: mountPath, CmdWrapper: wrappedCommand, } diff --git a/test/builder_lxc.bats b/test/builder_lxc.bats index c29030424..7173d0f7d 100644 --- a/test/builder_lxc.bats +++ b/test/builder_lxc.bats @@ -1,40 +1,106 @@ #!/usr/bin/env bats # -# This tests the lxc builder. The teardown function will -# delete any images in the output-lxc-* folders. +# This tests the lxc builder by creating minimal containers and checking that +# custom lxc container configuration files are successfully applied. The +# teardown function will delete any images in the output-lxc-* folders along +# with the auto-generated lxc container configuration files and hook scripts. #load test_helper #fixtures builder-lxc FIXTURE_ROOT="$BATS_TEST_DIRNAME/fixtures/builder-lxc" +have_command() { + command -v "$1" >/dev/null 2>&1 +} + # Required parameters -command -v lxc-create >/dev/null 2>&1 || { +have_command lxc-create || { echo "'lxc-create' must be installed via the lxc (or lxc1 for ubuntu >=16.04) package" >&2 exit 1 } +DESTROY_HOOK_SCRIPT=$FIXTURE_ROOT/destroy-hook.sh +DESTROY_HOOK_LOG=$FIXTURE_ROOT/destroy-hook.log +printf > "$DESTROY_HOOK_SCRIPT" ' +echo "$LXC_NAME" > "%s" +' "$DESTROY_HOOK_LOG" +chmod +x "$DESTROY_HOOK_SCRIPT" + +INIT_CONFIG=$FIXTURE_ROOT/lxc.custom.conf +printf > "$INIT_CONFIG" ' +lxc.hook.destroy = %s +' "$DESTROY_HOOK_SCRIPT" + teardown() { + for f in "$INIT_CONFIG" "$DESTROY_HOOK_SCRIPT" "$DESTROY_HOOK_LOG"; do + [ -e "$f" ] && rm -f "$f" + done + rm -rf output-lxc-* } -@test "lxc: build centos minimal.json" { - run packer build -var template_name=centos $FIXTURE_ROOT/minimal.json - [ "$status" -eq 0 ] - [ -f output-lxc-centos/rootfs.tar.gz ] - [ -f output-lxc-centos/lxc-config ] +assert_build() { + local template_name="$1" + shift + + local build_status=0 + + run packer build -var template_name="$template_name" "$@" + + [ "$status" -eq 0 ] || { + echo "${template_name} build exited badly: $status" >&2 + echo "$output" >&2 + build_status="$status" + } + + for expected in "output-lxc-${template_name}"/{rootfs.tar.gz,lxc-config}; do + [ -f "$expected" ] || { + echo "missing expected artifact '${expected}'" >&2 + build_status=1 + } + done + + return $build_status } +assert_container_name() { + local container_name="$1" + + [ -f "$DESTROY_HOOK_LOG" ] || { + echo "missing expected lxc.hook.destroy logfile '$DESTROY_HOOK_LOG'" + return 1 + } + + read -r lxc_name < "$DESTROY_HOOK_LOG" + + [ "$lxc_name" = "$container_name" ] +} + +@test "lxc: build centos minimal.json" { + have_command yum || skip "'yum' must be installed to build centos containers" + local container_name=packer-lxc-centos + assert_build centos -var init_config="$INIT_CONFIG" \ + -var container_name="$container_name" \ + $FIXTURE_ROOT/minimal.json + assert_container_name "$container_name" +} @test "lxc: build trusty minimal.json" { - run packer build -var template_name=ubuntu -var template_parameters="SUITE=trusty" $FIXTURE_ROOT/minimal.json - [ "$status" -eq 0 ] - [ -f output-lxc-ubuntu/rootfs.tar.gz ] - [ -f output-lxc-ubuntu/lxc-config ] + have_command debootstrap || skip "'debootstrap' must be installed to build ubuntu containers" + local container_name=packer-lxc-ubuntu + assert_build ubuntu -var init_config="$INIT_CONFIG" \ + -var container_name="$container_name" \ + -var template_parameters="SUITE=trusty" \ + $FIXTURE_ROOT/minimal.json + assert_container_name "$container_name" } @test "lxc: build debian minimal.json" { - run packer build -var template_name=debian -var template_parameters="SUITE=jessie" $FIXTURE_ROOT/minimal.json - [ "$status" -eq 0 ] - [ -f output-lxc-debian/rootfs.tar.gz ] - [ -f output-lxc-debian/lxc-config ] + have_command debootstrap || skip "'debootstrap' must be installed to build debian containers" + local container_name=packer-lxc-debian + assert_build debian -var init_config="$INIT_CONFIG" \ + -var container_name="$container_name" \ + -var template_parameters="SUITE=jessie" \ + $FIXTURE_ROOT/minimal.json + assert_container_name "$container_name" } diff --git a/test/fixtures/builder-lxc/minimal.json b/test/fixtures/builder-lxc/minimal.json index 5bf7998fd..997e48cfd 100644 --- a/test/fixtures/builder-lxc/minimal.json +++ b/test/fixtures/builder-lxc/minimal.json @@ -1,13 +1,29 @@ { "variables": { "template_name": "debian", - "template_parameters": "SUITE=jessie" + "template_parameters": "SUITE=jessie", + "container_name": "packer-lxc", + "set_var": "hello" }, + "provisioners": [ + { + "type": "shell", + "inline": [ + "if [ \"$SET_VAR\" != \"{{user `set_var`}}\" ]; then", + " echo \"Got unexpected value '$SET_VAR' for SET_VAR\" 1>&2", + " exit 1", + "fi" + ] + } + ], "builders": [ { "type": "lxc", "name": "lxc-{{user `template_name`}}", "template_name": "{{user `template_name`}}", + "container_name": "{{user `container_name`}}", + "create_options": [ "-f", "{{user `init_config`}}" ], + "attach_options": [ "--clear-env", "--set-var", "SET_VAR={{user `set_var`}}" ], "config_file": "/usr/share/lxc/config/{{user `template_name`}}.common.conf", "template_environment_vars": [ "{{user `template_parameters`}}" ] } diff --git a/website/source/docs/builders/lxc.html.md b/website/source/docs/builders/lxc.html.md index bc2b81a57..1d73ede38 100644 --- a/website/source/docs/builders/lxc.html.md +++ b/website/source/docs/builders/lxc.html.md @@ -110,3 +110,18 @@ Below is a fully functioning example. `/usr/share/lxc/templates/lxc-<template_name>`. Note: This gets passed as ARGV to the template command. Ensure you have an array of strings, as a single string with spaces probably won't work. Defaults to `[]`. + +- `create_options` (array of strings) - Options to pass to `lxc-create`. For + instance, you can specify a custom LXC container configuration file with + `["-f", "/path/to/lxc.conf"]`. Defaults to `[]`. See `man 1 lxc-create` for + available options. + +- `start_options` (array of strings) - Options to pass to `lxc-start`. For + instance, you can override parameters from the LXC container configuration + file via `["--define", "KEY=VALUE"]`. Defaults to `[]`. See `man 1 + lxc-start` for available options. + +- `attach_options` (array of strings) - Options to pass to `lxc-attach`. For + instance, you can prevent the container from inheriting the host machine's + environment by specifying `["--clear-env"]`. Defaults to `[]`. See `man 1 + lxc-attach` for available options. From 1012316442cc65ac4c47f597d6ddca035abb1078 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 31 Oct 2017 08:44:13 -0700 Subject: [PATCH 0132/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d796feaff..a79ce2cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] * post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] * builder/hyper-v: Also disable automatic checkpoints for gen 2 VMs. [GH-5517] +* builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 additional disks. [GH-5491] ## 1.1.1 (October 13, 2017) From 19e6049f17c94871a90834b054048b0a07eea214 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 31 Oct 2017 08:48:17 -0700 Subject: [PATCH 0133/1007] style fixes --- builder/hyperv/common/step_create_vm.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index a244a9f5e..a1d7f0d05 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -4,7 +4,6 @@ import ( "fmt" "log" "path/filepath" - "strconv" "strings" "github.com/hashicorp/packer/packer" @@ -112,8 +111,9 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { if len(s.AdditionalDiskSize) > 0 { for index, size := range s.AdditionalDiskSize { - var diskSize = size * 1024 * 1024 - err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, s.VMName+"-"+strconv.Itoa(int(index))+".vhdx", int64(diskSize), "SCSI") + diskSize := int64(size * 1024 * 1024) + diskFile := fmt.Sprintf("%s-%d.vhdx", s.VMName, index) + err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, diskFile, diskSize, "SCSI") if err != nil { err := fmt.Errorf("Error creating and attaching additional disk drive: %s", err) state.Put("error", err) From b04796c2cccf39cf4d47b9507bd35653e568f25a Mon Sep 17 00:00:00 2001 From: stack72 <public@paulstack.co.uk> Date: Tue, 31 Oct 2017 17:02:15 +0200 Subject: [PATCH 0134/1007] Bump Joyent/triton-go to modern version of the SDK This brings packer into the same version of triton-go as that in Terraform, where we rewrote the package from a library with everything in 1 place to individual packages I was able to successfully provision a machine on triton using this new change, you can find the output in the attached gist https://gist.github.com/stack72/a64d745459107c5a16bcb156965597ce --- builder/triton/access_config.go | 40 +- builder/triton/driver_triton.go | 38 +- vendor/github.com/joyent/triton-go/README.md | 323 +++--- .../github.com/joyent/triton-go/accounts.go | 95 -- .../authentication/private_key_signer.go | 34 +- .../joyent/triton-go/authentication/signer.go | 3 + .../authentication/ssh_agent_signer.go | 69 +- vendor/github.com/joyent/triton-go/client.go | 195 ---- .../joyent/triton-go/client/client.go | 397 +++++++ .../joyent/triton-go/client/errors.go | 190 +++ .../joyent/triton-go/compute/client.go | 57 + .../joyent/triton-go/compute/datacenters.go | 97 ++ .../joyent/triton-go/{ => compute}/errors.go | 59 +- .../joyent/triton-go/{ => compute}/images.go | 134 ++- .../joyent/triton-go/compute/instances.go | 1020 +++++++++++++++++ .../triton-go/{ => compute}/packages.go | 40 +- .../triton-go/{ => compute}/services.go | 25 +- vendor/github.com/joyent/triton-go/config.go | 73 -- .../joyent/triton-go/datacenters.go | 93 -- vendor/github.com/joyent/triton-go/fabrics.go | 234 ---- .../github.com/joyent/triton-go/firewall.go | 219 ---- vendor/github.com/joyent/triton-go/keys.go | 125 -- .../github.com/joyent/triton-go/machines.go | 667 ----------- .../joyent/triton-go/network/client.go | 39 + .../joyent/triton-go/network/fabrics.go | 269 +++++ .../joyent/triton-go/network/firewall.go | 250 ++++ .../{networks.go => network/network.go} | 39 +- vendor/github.com/joyent/triton-go/roles.go | 164 --- vendor/github.com/joyent/triton-go/triton.go | 18 + vendor/vendor.json | 30 +- 30 files changed, 2852 insertions(+), 2184 deletions(-) delete mode 100644 vendor/github.com/joyent/triton-go/accounts.go delete mode 100644 vendor/github.com/joyent/triton-go/client.go create mode 100644 vendor/github.com/joyent/triton-go/client/client.go create mode 100644 vendor/github.com/joyent/triton-go/client/errors.go create mode 100644 vendor/github.com/joyent/triton-go/compute/client.go create mode 100644 vendor/github.com/joyent/triton-go/compute/datacenters.go rename vendor/github.com/joyent/triton-go/{ => compute}/errors.go (54%) rename vendor/github.com/joyent/triton-go/{ => compute}/images.go (51%) create mode 100644 vendor/github.com/joyent/triton-go/compute/instances.go rename vendor/github.com/joyent/triton-go/{ => compute}/packages.go (55%) rename vendor/github.com/joyent/triton-go/{ => compute}/services.go (55%) delete mode 100644 vendor/github.com/joyent/triton-go/config.go delete mode 100644 vendor/github.com/joyent/triton-go/datacenters.go delete mode 100644 vendor/github.com/joyent/triton-go/fabrics.go delete mode 100644 vendor/github.com/joyent/triton-go/firewall.go delete mode 100644 vendor/github.com/joyent/triton-go/keys.go delete mode 100644 vendor/github.com/joyent/triton-go/machines.go create mode 100644 vendor/github.com/joyent/triton-go/network/client.go create mode 100644 vendor/github.com/joyent/triton-go/network/fabrics.go create mode 100644 vendor/github.com/joyent/triton-go/network/firewall.go rename vendor/github.com/joyent/triton-go/{networks.go => network/network.go} (66%) delete mode 100644 vendor/github.com/joyent/triton-go/roles.go create mode 100644 vendor/github.com/joyent/triton-go/triton.go diff --git a/builder/triton/access_config.go b/builder/triton/access_config.go index 0f4d29e12..2df0ed150 100644 --- a/builder/triton/access_config.go +++ b/builder/triton/access_config.go @@ -6,10 +6,13 @@ import ( "io/ioutil" "os" + "github.com/hashicorp/errwrap" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/template/interpolate" - "github.com/joyent/triton-go" + 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 @@ -106,8 +109,39 @@ func (c *AccessConfig) createPrivateKeySigner() (authentication.Signer, error) { return signer, nil } -func (c *AccessConfig) CreateTritonClient() (*triton.Client, error) { - return triton.NewClient(c.Endpoint, c.Account, c.signer) +func (c *AccessConfig) CreateTritonClient() (*Client, error) { + + config := &tgo.ClientConfig{ + AccountName: c.Account, + TritonURL: c.Endpoint, + Signers: []authentication.Signer{c.signer}, + } + + return &Client{ + config: config, + }, nil +} + +type Client struct { + config *tgo.ClientConfig +} + +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) + } + + 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) + } + + return networkClient, nil } func (c *AccessConfig) Comm() communicator.Config { diff --git a/builder/triton/driver_triton.go b/builder/triton/driver_triton.go index cfb3b0e72..a6bc5c153 100644 --- a/builder/triton/driver_triton.go +++ b/builder/triton/driver_triton.go @@ -7,11 +7,12 @@ import ( "time" "github.com/hashicorp/packer/packer" - "github.com/joyent/triton-go" + "github.com/joyent/triton-go/client" + "github.com/joyent/triton-go/compute" ) type driverTriton struct { - client *triton.Client + client *Client ui packer.Ui } @@ -28,7 +29,8 @@ func NewDriverTriton(ui packer.Ui, config Config) (Driver, error) { } func (d *driverTriton) CreateImageFromMachine(machineId string, config Config) (string, error) { - image, err := d.client.Images().CreateImageFromMachine(context.Background(), &triton.CreateImageFromMachineInput{ + computeClient, _ := d.client.Compute() + image, err := computeClient.Images().CreateFromMachine(context.Background(), &compute.CreateImageFromMachineInput{ MachineID: machineId, Name: config.ImageName, Version: config.ImageVersion, @@ -46,7 +48,8 @@ func (d *driverTriton) CreateImageFromMachine(machineId string, config Config) ( } func (d *driverTriton) CreateMachine(config Config) (string, error) { - input := &triton.CreateMachineInput{ + computeClient, _ := d.client.Compute() + input := &compute.CreateInstanceInput{ Package: config.MachinePackage, Image: config.MachineImage, Metadata: config.MachineMetadata, @@ -66,7 +69,7 @@ func (d *driverTriton) CreateMachine(config Config) (string, error) { input.Networks = config.MachineNetworks } - machine, err := d.client.Machines().CreateMachine(context.Background(), input) + machine, err := computeClient.Instances().Create(context.Background(), input) if err != nil { return "", err } @@ -75,19 +78,22 @@ func (d *driverTriton) CreateMachine(config Config) (string, error) { } func (d *driverTriton) DeleteImage(imageId string) error { - return d.client.Images().DeleteImage(context.Background(), &triton.DeleteImageInput{ + computeClient, _ := d.client.Compute() + return computeClient.Images().Delete(context.Background(), &compute.DeleteImageInput{ ImageID: imageId, }) } func (d *driverTriton) DeleteMachine(machineId string) error { - return d.client.Machines().DeleteMachine(context.Background(), &triton.DeleteMachineInput{ + computeClient, _ := d.client.Compute() + return computeClient.Instances().Delete(context.Background(), &compute.DeleteInstanceInput{ ID: machineId, }) } func (d *driverTriton) GetMachineIP(machineId string) (string, error) { - machine, err := d.client.Machines().GetMachine(context.Background(), &triton.GetMachineInput{ + computeClient, _ := d.client.Compute() + machine, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{ ID: machineId, }) if err != nil { @@ -98,8 +104,9 @@ func (d *driverTriton) GetMachineIP(machineId string) (string, error) { } func (d *driverTriton) StopMachine(machineId string) error { - return d.client.Machines().StopMachine(context.Background(), &triton.StopMachineInput{ - MachineID: machineId, + computeClient, _ := d.client.Compute() + return computeClient.Instances().Stop(context.Background(), &compute.StopInstanceInput{ + InstanceID: machineId, }) } @@ -111,7 +118,8 @@ func (d *driverTriton) StopMachine(machineId string) error { func (d *driverTriton) WaitForMachineState(machineId string, state string, timeout time.Duration) error { return waitFor( func() (bool, error) { - machine, err := d.client.Machines().GetMachine(context.Background(), &triton.GetMachineInput{ + computeClient, _ := d.client.Compute() + machine, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{ ID: machineId, }) if machine == nil { @@ -130,14 +138,15 @@ func (d *driverTriton) WaitForMachineState(machineId string, state string, timeo func (d *driverTriton) WaitForMachineDeletion(machineId string, timeout time.Duration) error { return waitFor( func() (bool, error) { - _, err := d.client.Machines().GetMachine(context.Background(), &triton.GetMachineInput{ + 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 triErr, ok := err.(*triton.TritonError); ok && triErr.StatusCode == http.StatusGone { + if triErr, ok := err.(*client.TritonError); ok && triErr.StatusCode == http.StatusGone { return true, nil } } @@ -152,7 +161,8 @@ func (d *driverTriton) WaitForMachineDeletion(machineId string, timeout time.Dur func (d *driverTriton) WaitForImageCreation(imageId string, timeout time.Duration) error { return waitFor( func() (bool, error) { - image, err := d.client.Images().GetImage(context.Background(), &triton.GetImageInput{ + computeClient, _ := d.client.Compute() + image, err := computeClient.Images().Get(context.Background(), &compute.GetImageInput{ ImageID: imageId, }) if image == nil { diff --git a/vendor/github.com/joyent/triton-go/README.md b/vendor/github.com/joyent/triton-go/README.md index 6546ba373..1089c72da 100644 --- a/vendor/github.com/joyent/triton-go/README.md +++ b/vendor/github.com/joyent/triton-go/README.md @@ -1,193 +1,91 @@ # triton-go -`go-triton` is an idiomatic library exposing a client SDK for Go applications using the Joyent Triton API. +`triton-go` is an idiomatic library exposing a client SDK for Go applications +using Joyent's Triton Compute and Storage (Manta) APIs. ## Usage -Triton uses [HTTP Signature][4] to sign the Date header in each HTTP request made to the Triton API. Currently, requests can be signed using either a private key file loaded from disk (using an [`authentication.PrivateKeySigner`][5]), or using a key stored with the local SSH Agent (using an [`SSHAgentSigner`][6]. +Triton uses [HTTP Signature][4] to sign the Date header in each HTTP request +made to the Triton API. Currently, requests can be signed using either a private +key file loaded from disk (using an [`authentication.PrivateKeySigner`][5]), or +using a key stored with the local SSH Agent (using an [`SSHAgentSigner`][6]. -To construct a Signer, use the `New*` range of methods in the `authentication` package. In the case of `authentication.NewSSHAgentSigner`, the parameters are the fingerprint of the key with which to sign, and the account name (normally stored in the `SDC_ACCOUNT` environment variable). For example: +To construct a Signer, use the `New*` range of methods in the `authentication` +package. In the case of `authentication.NewSSHAgentSigner`, the parameters are +the fingerprint of the key with which to sign, and the account name (normally +stored in the `SDC_ACCOUNT` environment variable). For example: ``` const fingerprint := "a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11" sshKeySigner, err := authentication.NewSSHAgentSigner(fingerprint, "AccountName") if err != nil { - log.Fatalf("NewSSHAgentSigner: %s", err) + log.Fatalf("NewSSHAgentSigner: %s", err) } ``` -An appropriate key fingerprint can be generated using `ssh-keygen`: +An appropriate key fingerprint can be generated using `ssh-keygen`. ``` ssh-keygen -Emd5 -lf ~/.ssh/id_rsa.pub | cut -d " " -f 2 | sed 's/MD5://' ``` -To construct a Client, use the `NewClient` function, passing in the endpoint, account name and constructed signer: +Each top level package, `account`, `compute`, `identity`, `network`, all have +their own seperate client. In order to initialize a package client, simply pass +the global `triton.ClientConfig` struct into the client's constructor function. ```go -client, err := triton.NewClient("https://us-sw-1.api.joyent.com/", "AccountName", sshKeySigner) -if err != nil { - log.Fatalf("NewClient: %s", err) -} + config := &triton.ClientConfig{ + TritonURL: os.Getenv("SDC_URL"), + MantaURL: os.Getenv("MANTA_URL"), + AccountName: accountName, + Signers: []authentication.Signer{sshKeySigner}, + } + + c, err := compute.NewClient(config) + if err != nil { + log.Fatalf("compute.NewClient: %s", err) + } ``` -Having constructed a `triton.Client`, use the methods available to access functionality by functional grouping. For example, for access to operations on SSH keys, use the `Keys()` method to obtain a client which has access to the `CreateKey`, `ListKeys` and `DeleteKey` operations. For access to operations on Machines, use the `Machines()` method to obtain a client which has access to the `RenameMachine`, `GetMachineMetadata`, `GetMachineTag`, and other operations. +Constructing `compute.Client` returns an interface which exposes `compute` API +resources. The same goes for all other packages. Reference their unique +documentation for more information. -Operation methods take their formal parameters via a struct named `OperationInput` - for example when creating an SSH key, the `CreateKeyInput` struct is used with the `func CreateKey(*CreateKeyInput) (*Key, error)` method. This allows specification of named parameters: +The same `triton.ClientConfig` will initialize the Manta `storage` client as +well... -``` -client := state.Client().Keys() - -key, err := client.CreateKey(&CreateKeyInput{ - Name: "tempKey", - Key: "ssh-rsa .....", -}) -if err != nil { - panic(err) -} - -// Key contains the return value. +```go + c, err := storage.NewClient(config) + if err != nil { + log.Fatalf("storage.NewClient: %s", err) + } ``` ## Error Handling -If an error is returned by the HTTP API, the `error` returned from the function will contain an instance of `triton.TritonError` in the chain. Error wrapping is performed using the [errwrap][7] library from HashiCorp. +If an error is returned by the HTTP API, the `error` returned from the function +will contain an instance of `compute.TritonError` in the chain. Error wrapping +is performed using the [errwrap][7] library from HashiCorp. -## Completeness +## Acceptance Tests -The following list is updated as new functionality is added. The complete list of operations is taken from the [CloudAPI documentation](https://apidocs.joyent.com/cloudapi). +Acceptance Tests run directly against the Triton API, so you will need either a +local installation of Triton or an account with Joyent's Public Cloud offering +in order to run them. The tests create real resources (and thus cost real +money)! -- Accounts - - [x] GetAccount - - [x] UpdateAccount -- Keys - - [x] ListKeys - - [x] GetKey - - [x] CreateKey - - [x] DeleteKey -- Users - - [ ] ListUsers - - [ ] GetUser - - [ ] CreateUser - - [ ] UpdateUser - - [ ] ChangeUserPassword - - [ ] DeleteUser -- Roles - - [x] ListRoles - - [x] GetRole - - [x] CreateRole - - [x] UpdateRole - - [x] DeleteRole -- Role Tags - - [ ] SetRoleTags -- Policies - - [ ] ListPolicies - - [ ] GetPolicy - - [ ] CreatePolicy - - [ ] UpdatePolicy - - [ ] DeletePolicy -- User SSH Keys - - [x] ListUserKeys - - [x] GetUserKey - - [x] CreateUserKey - - [x] DeleteUserKey -- Config - - [x] GetConfig - - [x] UpdateConfig -- Datacenters - - [x] ListDatacenters - - [x] GetDatacenter -- Services - - [x] ListServices -- Images - - [x] ListImages - - [x] GetImage - - [x] DeleteImage - - [x] ExportImage - - [x] CreateImageFromMachine - - [x] UpdateImage -- Packages - - [x] ListPackages - - [x] GetPackage -- Instances - - [ ] ListMachines - - [x] GetMachine - - [x] CreateMachine - - [ ] StopMachine - - [ ] StartMachine - - [ ] RebootMachine - - [x] ResizeMachine - - [x] RenameMachine - - [x] EnableMachineFirewall - - [x] DisableMachineFirewall - - [ ] CreateMachineSnapshot - - [ ] StartMachineFromSnapshot - - [ ] ListMachineSnapshots - - [ ] GetMachineSnapshot - - [ ] DeleteMachineSnapshot - - [x] UpdateMachineMetadata - - [ ] ListMachineMetadata - - [ ] GetMachineMetadata - - [ ] DeleteMachineMetadata - - [ ] DeleteAllMachineMetadata - - [x] AddMachineTags - - [x] ReplaceMachineTags - - [x] ListMachineTags - - [x] GetMachineTag - - [x] DeleteMachineTag - - [x] DeleteMachineTags - - [x] DeleteMachine - - [ ] MachineAudit -- Analytics - - [ ] DescribeAnalytics - - [ ] ListInstrumentations - - [ ] GetInstrumentation - - [ ] GetInstrumentationValue - - [ ] GetInstrumentationHeatmap - - [ ] GetInstrumentationHeatmapDetails - - [ ] CreateInstrumentation - - [ ] DeleteInstrumentation -- Firewall Rules - - [x] ListFirewallRules - - [x] GetFirewallRule - - [x] CreateFirewallRule - - [x] UpdateFirewallRule - - [x] EnableFirewallRule - - [x] DisableFirewallRule - - [x] DeleteFirewallRule - - [ ] ListMachineFirewallRules - - [x] ListFirewallRuleMachines -- Fabrics - - [x] ListFabricVLANs - - [x] CreateFabricVLAN - - [x] GetFabricVLAN - - [x] UpdateFabricVLAN - - [x] DeleteFabricVLAN - - [x] ListFabricNetworks - - [x] CreateFabricNetwork - - [x] GetFabricNetwork - - [x] DeleteFabricNetwork -- Networks - - [x] ListNetworks - - [x] GetNetwork -- Nics - - [ ] ListNics - - [ ] GetNic - - [x] AddNic - - [x] RemoveNic +In order to run acceptance tests, the following environment variables must be +set: -## Running Acceptance Tests - -Acceptance Tests run directly against the Triton API, so you will need either a local installation or Triton or an account with Joyent in order to run them. The tests create real resources (and thus cost real money!) - -In order to run acceptance tests, the following environment variables must be set: - -- `TRITON_TEST` - must be set to any value in order to indicate desire to create resources +- `TRITON_TEST` - must be set to any value in order to indicate desire to create + resources - `SDC_URL` - the base endpoint for the Triton API - `SDC_ACCOUNT` - the account name for the Triton API - `SDC_KEY_ID` - the fingerprint of the SSH key identifying the key -Additionally, you may set `SDC_KEY_MATERIAL` to the contents of an unencrypted private key. If this is set, the PrivateKeySigner (see above) will be used - if not the SSHAgentSigner will be used. +Additionally, you may set `SDC_KEY_MATERIAL` to the contents of an unencrypted +private key. If this is set, the PrivateKeySigner (see above) will be used - if +not the SSHAgentSigner will be used. ### Example Run @@ -195,11 +93,11 @@ The verbose output has been removed for brevity here. ``` $ HTTP_PROXY=http://localhost:8888 \ - TRITON_TEST=1 \ - SDC_URL=https://us-sw-1.api.joyent.com \ - SDC_ACCOUNT=AccountName \ - SDC_KEY_ID=a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11 \ - go test -v -run "TestAccKey" + TRITON_TEST=1 \ + SDC_URL=https://us-sw-1.api.joyent.com \ + SDC_ACCOUNT=AccountName \ + SDC_KEY_ID=a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11 \ + go test -v -run "TestAccKey" === RUN TestAccKey_Create --- PASS: TestAccKey_Create (12.46s) === RUN TestAccKey_Get @@ -207,10 +105,111 @@ $ HTTP_PROXY=http://localhost:8888 \ === RUN TestAccKey_Delete --- PASS: TestAccKey_Delete (15.08s) PASS -ok github.com/jen20/triton-go 31.861s +ok github.com/joyent/triton-go 31.861s ``` -[4]: https://github.com/joyent/node-http-signature/blob/master/http_signing.md -[5]: https://godoc.org/github.com/joyent/go-triton/authentication -[6]: https://godoc.org/github.com/joyent/go-triton/authentication +## Example API + +There's an `examples/` directory available with sample code setup for many of +the APIs within this library. Most of these can be run using `go run` and +referencing your SSH key file use by your active `triton` CLI profile. + +```sh +$ eval "$(triton env us-sw-1)" +$ SDC_KEY_FILE=~/.ssh/triton-id_rsa go run examples/compute/instances.go +``` + +The following is a complete example of how to initialize the `compute` package +client and list all instances under an account. More detailed usage of this +library follows. + +```go + + +package main + +import ( + "context" + "fmt" + "io/ioutil" + "log" + "os" + "time" + + triton "github.com/joyent/triton-go" + "github.com/joyent/triton-go/authentication" + "github.com/joyent/triton-go/compute" +) + +func main() { + keyID := os.Getenv("SDC_KEY_ID") + accountName := os.Getenv("SDC_ACCOUNT") + keyMaterial := os.Getenv("SDC_KEY_MATERIAL") + + var signer authentication.Signer + var err error + + if keyMaterial == "" { + signer, err = authentication.NewSSHAgentSigner(keyID, accountName) + if err != nil { + log.Fatalf("Error Creating SSH Agent Signer: {{err}}", err) + } + } else { + var keyBytes []byte + if _, err = os.Stat(keyMaterial); err == nil { + keyBytes, err = ioutil.ReadFile(keyMaterial) + if err != nil { + log.Fatalf("Error reading key material from %s: %s", + keyMaterial, err) + } + block, _ := pem.Decode(keyBytes) + if block == nil { + log.Fatalf( + "Failed to read key material '%s': no key found", keyMaterial) + } + + if block.Headers["Proc-Type"] == "4,ENCRYPTED" { + log.Fatalf( + "Failed to read key '%s': password protected keys are\n"+ + "not currently supported. Please decrypt the key prior to use.", keyMaterial) + } + + } else { + keyBytes = []byte(keyMaterial) + } + + signer, err = authentication.NewPrivateKeySigner(keyID, []byte(keyMaterial), accountName) + if err != nil { + log.Fatalf("Error Creating SSH Private Key Signer: {{err}}", err) + } + } + + config := &triton.ClientConfig{ + TritonURL: os.Getenv("SDC_URL"), + AccountName: accountName, + Signers: []authentication.Signer{signer}, + } + + c, err := compute.NewClient(config) + if err != nil { + log.Fatalf("compute.NewClient: %s", err) + } + + listInput := &compute.ListInstancesInput{} + instances, err := c.Instances().List(context.Background(), listInput) + if err != nil { + log.Fatalf("compute.Instances.List: %v", err) + } + numInstances := 0 + for _, instance := range instances { + numInstances++ + fmt.Println(fmt.Sprintf("-- Instance: %v", instance.Name)) + } +} + +``` + +[4]: https://github.com/joyent/node-http-signature/blob/master/http_signing.md +[5]: https://godoc.org/github.com/joyent/triton-go/authentication +[6]: https://godoc.org/github.com/joyent/triton-go/authentication [7]: https://github.com/hashicorp/go-errwrap diff --git a/vendor/github.com/joyent/triton-go/accounts.go b/vendor/github.com/joyent/triton-go/accounts.go deleted file mode 100644 index 88e7bbf12..000000000 --- a/vendor/github.com/joyent/triton-go/accounts.go +++ /dev/null @@ -1,95 +0,0 @@ -package triton - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "time" - - "github.com/hashicorp/errwrap" -) - -type AccountsClient struct { - *Client -} - -// Accounts returns a c used for accessing functions pertaining -// to Account functionality in the Triton API. -func (c *Client) Accounts() *AccountsClient { - return &AccountsClient{c} -} - -type Account struct { - ID string `json:"id"` - Login string `json:"login"` - Email string `json:"email"` - CompanyName string `json:"companyName"` - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - Address string `json:"address"` - PostalCode string `json:"postalCode"` - City string `json:"city"` - State string `json:"state"` - Country string `json:"country"` - Phone string `json:"phone"` - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` - TritonCNSEnabled bool `json:"triton_cns_enabled"` -} - -type GetAccountInput struct{} - -func (client *AccountsClient) GetAccount(ctx context.Context, input *GetAccountInput) (*Account, error) { - path := fmt.Sprintf("/%s", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetAccount request: {{err}}", err) - } - - var result *Account - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetAccount response: {{err}}", err) - } - - return result, nil -} - -type UpdateAccountInput struct { - Email string `json:"email,omitempty"` - CompanyName string `json:"companyName,omitempty"` - FirstName string `json:"firstName,omitempty"` - LastName string `json:"lastName,omitempty"` - Address string `json:"address,omitempty"` - PostalCode string `json:"postalCode,omitempty"` - City string `json:"city,omitempty"` - State string `json:"state,omitempty"` - Country string `json:"country,omitempty"` - Phone string `json:"phone,omitempty"` - TritonCNSEnabled bool `json:"triton_cns_enabled,omitempty"` -} - -// UpdateAccount updates your account details with the given parameters. -// TODO(jen20) Work out a safe way to test this -func (client *AccountsClient) UpdateAccount(ctx context.Context, input *UpdateAccountInput) (*Account, error) { - path := fmt.Sprintf("/%s", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateAccount request: {{err}}", err) - } - - var result *Account - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateAccount response: {{err}}", err) - } - - return result, nil -} diff --git a/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go b/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go index 20dc6bfed..43bc286f0 100644 --- a/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go @@ -18,6 +18,7 @@ import ( type PrivateKeySigner struct { formattedKeyFingerprint string keyFingerprint string + algorithm string accountName string hashFunc crypto.Hash @@ -48,14 +49,22 @@ func NewPrivateKeySigner(keyFingerprint string, privateKeyMaterial []byte, accou return nil, errors.New("Private key file does not match public key fingerprint") } - return &PrivateKeySigner{ + signer := &PrivateKeySigner{ formattedKeyFingerprint: displayKeyFingerprint, keyFingerprint: keyFingerprint, accountName: accountName, hashFunc: crypto.SHA1, privateKey: rsakey, - }, nil + } + + _, algorithm, err := signer.SignRaw("HelloWorld") + if err != nil { + return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err) + } + signer.algorithm = algorithm + + return signer, nil } func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) { @@ -74,3 +83,24 @@ func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) { keyID := fmt.Sprintf("/%s/keys/%s", s.accountName, s.formattedKeyFingerprint) return fmt.Sprintf(authorizationHeaderFormat, keyID, "rsa-sha1", headerName, signedBase64), nil } + +func (s *PrivateKeySigner) SignRaw(toSign string) (string, string, error) { + hash := s.hashFunc.New() + hash.Write([]byte(toSign)) + digest := hash.Sum(nil) + + signed, err := rsa.SignPKCS1v15(rand.Reader, s.privateKey, s.hashFunc, digest) + if err != nil { + return "", "", errwrap.Wrapf("Error signing date header: {{err}}", err) + } + signedBase64 := base64.StdEncoding.EncodeToString(signed) + return signedBase64, "rsa-sha1", nil +} + +func (s *PrivateKeySigner) KeyFingerprint() string { + return s.formattedKeyFingerprint +} + +func (s *PrivateKeySigner) DefaultAlgorithm() string { + return s.algorithm +} diff --git a/vendor/github.com/joyent/triton-go/authentication/signer.go b/vendor/github.com/joyent/triton-go/authentication/signer.go index dfc89ad44..6e3d31dd7 100644 --- a/vendor/github.com/joyent/triton-go/authentication/signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/signer.go @@ -3,5 +3,8 @@ package authentication const authorizationHeaderFormat = `Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"` type Signer interface { + DefaultAlgorithm() string + KeyFingerprint() string Sign(dateHeader string) (string, error) + SignRaw(toSign string) (string, string, error) } diff --git a/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go b/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go index 028743159..ea84c5070 100644 --- a/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go @@ -2,6 +2,8 @@ package authentication import ( "crypto/md5" + "crypto/sha256" + "encoding/base64" "errors" "fmt" "net" @@ -16,6 +18,7 @@ import ( type SSHAgentSigner struct { formattedKeyFingerprint string keyFingerprint string + algorithm string accountName string keyIdentifier string @@ -41,15 +44,21 @@ func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, err return nil, errwrap.Wrapf("Error listing keys in SSH Agent: %s", err) } - keyFingerprintMD5 := strings.Replace(keyFingerprint, ":", "", -1) + keyFingerprintStripped := strings.TrimPrefix(keyFingerprint, "MD5:") + keyFingerprintStripped = strings.TrimPrefix(keyFingerprintStripped, "SHA256:") + keyFingerprintStripped = strings.Replace(keyFingerprintStripped, ":", "", -1) var matchingKey ssh.PublicKey for _, key := range keys { - h := md5.New() - h.Write(key.Marshal()) - fp := fmt.Sprintf("%x", h.Sum(nil)) + keyMD5 := md5.New() + keyMD5.Write(key.Marshal()) + finalizedMD5 := fmt.Sprintf("%x", keyMD5.Sum(nil)) - if fp == keyFingerprintMD5 { + keySHA256 := sha256.New() + keySHA256.Write(key.Marshal()) + finalizedSHA256 := base64.RawStdEncoding.EncodeToString(keySHA256.Sum(nil)) + + if keyFingerprintStripped == finalizedMD5 || keyFingerprintStripped == finalizedSHA256 { matchingKey = key } } @@ -60,14 +69,22 @@ func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, err formattedKeyFingerprint := formatPublicKeyFingerprint(matchingKey, true) - return &SSHAgentSigner{ + signer := &SSHAgentSigner{ formattedKeyFingerprint: formattedKeyFingerprint, keyFingerprint: keyFingerprint, accountName: accountName, agent: ag, key: matchingKey, keyIdentifier: fmt.Sprintf("/%s/keys/%s", accountName, formattedKeyFingerprint), - }, nil + } + + _, algorithm, err := signer.SignRaw("HelloWorld") + if err != nil { + return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err) + } + signer.algorithm = algorithm + + return signer, nil } func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) { @@ -102,3 +119,41 @@ func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) { return fmt.Sprintf(authorizationHeaderFormat, s.keyIdentifier, authSignature.SignatureType(), headerName, authSignature.String()), nil } + +func (s *SSHAgentSigner) SignRaw(toSign string) (string, string, error) { + signature, err := s.agent.Sign(s.key, []byte(toSign)) + if err != nil { + return "", "", errwrap.Wrapf("Error signing string: {{err}}", err) + } + + keyFormat, err := keyFormatToKeyType(signature.Format) + if err != nil { + return "", "", errwrap.Wrapf("Error reading signature: {{err}}", err) + } + + var authSignature httpAuthSignature + switch keyFormat { + case "rsa": + authSignature, err = newRSASignature(signature.Blob) + if err != nil { + return "", "", errwrap.Wrapf("Error reading signature: {{err}}", err) + } + case "ecdsa": + authSignature, err = newECDSASignature(signature.Blob) + if err != nil { + return "", "", errwrap.Wrapf("Error reading signature: {{err}}", err) + } + default: + return "", "", fmt.Errorf("Unsupported algorithm from SSH agent: %s", signature.Format) + } + + return authSignature.String(), authSignature.SignatureType(), nil +} + +func (s *SSHAgentSigner) KeyFingerprint() string { + return s.formattedKeyFingerprint +} + +func (s *SSHAgentSigner) DefaultAlgorithm() string { + return s.algorithm +} diff --git a/vendor/github.com/joyent/triton-go/client.go b/vendor/github.com/joyent/triton-go/client.go deleted file mode 100644 index c0ecc5fd0..000000000 --- a/vendor/github.com/joyent/triton-go/client.go +++ /dev/null @@ -1,195 +0,0 @@ -package triton - -import ( - "bytes" - "context" - "crypto/tls" - "encoding/json" - "errors" - "io" - "net" - "net/http" - "net/url" - "time" - - "github.com/hashicorp/errwrap" - "github.com/joyent/triton-go/authentication" -) - -const nilContext = "nil context" - -// Client represents a connection to the Triton API. -type Client struct { - client *http.Client - authorizer []authentication.Signer - apiURL url.URL - accountName string -} - -// NewClient is used to construct a Client in order to make API -// requests to the Triton API. -// -// At least one signer must be provided - example signers include -// authentication.PrivateKeySigner and authentication.SSHAgentSigner. -func NewClient(endpoint string, accountName string, signers ...authentication.Signer) (*Client, error) { - apiURL, err := url.Parse(endpoint) - if err != nil { - return nil, errwrap.Wrapf("invalid endpoint: {{err}}", err) - } - - if accountName == "" { - return nil, errors.New("account name can not be empty") - } - - httpClient := &http.Client{ - Transport: httpTransport(false), - CheckRedirect: doNotFollowRedirects, - } - - return &Client{ - client: httpClient, - authorizer: signers, - apiURL: *apiURL, - accountName: accountName, - }, nil -} - -// InsecureSkipTLSVerify turns off TLS verification for the client connection. This -// allows connection to an endpoint with a certificate which was signed by a non- -// trusted CA, such as self-signed certificates. This can be useful when connecting -// to temporary Triton installations such as Triton Cloud-On-A-Laptop. -func (c *Client) InsecureSkipTLSVerify() { - if c.client == nil { - return - } - - c.client.Transport = httpTransport(true) -} - -func httpTransport(insecureSkipTLSVerify bool) *http.Transport { - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - DisableKeepAlives: true, - MaxIdleConnsPerHost: -1, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: insecureSkipTLSVerify, - }, - } -} - -func doNotFollowRedirects(*http.Request, []*http.Request) error { - return http.ErrUseLastResponse -} - -func (c *Client) executeRequestURIParams(ctx context.Context, method, path string, body interface{}, query *url.Values) (io.ReadCloser, error) { - var requestBody io.ReadSeeker - if body != nil { - marshaled, err := json.MarshalIndent(body, "", " ") - if err != nil { - return nil, err - } - requestBody = bytes.NewReader(marshaled) - } - - endpoint := c.apiURL - endpoint.Path = path - if query != nil { - endpoint.RawQuery = query.Encode() - } - - req, err := http.NewRequest(method, endpoint.String(), requestBody) - if err != nil { - return nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) - } - - dateHeader := time.Now().UTC().Format(time.RFC1123) - req.Header.Set("date", dateHeader) - - authHeader, err := c.authorizer[0].Sign(dateHeader) - if err != nil { - return nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) - } - req.Header.Set("Authorization", authHeader) - req.Header.Set("Accept", "application/json") - req.Header.Set("Accept-Version", "8") - req.Header.Set("User-Agent", "triton-go Client API") - - if body != nil { - req.Header.Set("Content-Type", "application/json") - } - - resp, err := c.client.Do(req.WithContext(ctx)) - if err != nil { - return nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) - } - - if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { - return resp.Body, nil - } - - return nil, c.decodeError(resp.StatusCode, resp.Body) -} - -func (c *Client) decodeError(statusCode int, body io.Reader) error { - err := &TritonError{ - StatusCode: statusCode, - } - - errorDecoder := json.NewDecoder(body) - if err := errorDecoder.Decode(err); err != nil { - return errwrap.Wrapf("Error decoding error response: {{err}}", err) - } - - return err -} - -func (c *Client) executeRequest(ctx context.Context, method, path string, body interface{}) (io.ReadCloser, error) { - return c.executeRequestURIParams(ctx, method, path, body, nil) -} - -func (c *Client) executeRequestRaw(ctx context.Context, method, path string, body interface{}) (*http.Response, error) { - var requestBody io.ReadSeeker - if body != nil { - marshaled, err := json.MarshalIndent(body, "", " ") - if err != nil { - return nil, err - } - requestBody = bytes.NewReader(marshaled) - } - - endpoint := c.apiURL - endpoint.Path = path - - req, err := http.NewRequest(method, endpoint.String(), requestBody) - if err != nil { - return nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) - } - - dateHeader := time.Now().UTC().Format(time.RFC1123) - req.Header.Set("date", dateHeader) - - authHeader, err := c.authorizer[0].Sign(dateHeader) - if err != nil { - return nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) - } - req.Header.Set("Authorization", authHeader) - req.Header.Set("Accept", "application/json") - req.Header.Set("Accept-Version", "8") - req.Header.Set("User-Agent", "triton-go c API") - - if body != nil { - req.Header.Set("Content-Type", "application/json") - } - - resp, err := c.client.Do(req.WithContext(ctx)) - if err != nil { - return nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) - } - - return resp, nil -} diff --git a/vendor/github.com/joyent/triton-go/client/client.go b/vendor/github.com/joyent/triton-go/client/client.go new file mode 100644 index 000000000..b01f86baf --- /dev/null +++ b/vendor/github.com/joyent/triton-go/client/client.go @@ -0,0 +1,397 @@ +package client + +import ( + "bytes" + "context" + "crypto/tls" + "encoding/json" + "errors" + "io" + "net" + "net/http" + "net/url" + "os" + "time" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/authentication" +) + +const nilContext = "nil context" + +var MissingKeyIdError = errors.New("Default SSH agent authentication requires SDC_KEY_ID") + +// Client represents a connection to the Triton Compute or Object Storage APIs. +type Client struct { + HTTPClient *http.Client + Authorizers []authentication.Signer + TritonURL url.URL + MantaURL url.URL + AccountName string + Endpoint string +} + +// New is used to construct a Client in order to make API +// requests to the Triton API. +// +// At least one signer must be provided - example signers include +// authentication.PrivateKeySigner and authentication.SSHAgentSigner. +func New(tritonURL string, mantaURL string, accountName string, signers ...authentication.Signer) (*Client, error) { + cloudURL, err := url.Parse(tritonURL) + if err != nil { + return nil, errwrap.Wrapf("invalid endpoint URL: {{err}}", err) + } + + storageURL, err := url.Parse(mantaURL) + if err != nil { + return nil, errwrap.Wrapf("invalid manta URL: {{err}}", err) + } + + if accountName == "" { + return nil, errors.New("account name can not be empty") + } + + httpClient := &http.Client{ + Transport: httpTransport(false), + CheckRedirect: doNotFollowRedirects, + } + + newClient := &Client{ + HTTPClient: httpClient, + Authorizers: signers, + TritonURL: *cloudURL, + MantaURL: *storageURL, + AccountName: accountName, + // TODO(justinwr): Deprecated? + // Endpoint: tritonURL, + } + + var authorizers []authentication.Signer + for _, key := range signers { + if key != nil { + authorizers = append(authorizers, key) + } + } + + // Default to constructing an SSHAgentSigner if there are no other signers + // passed into NewClient and there's an SDC_KEY_ID value available in the + // user environ. + if len(authorizers) == 0 { + keyID := os.Getenv("SDC_KEY_ID") + if len(keyID) != 0 { + keySigner, err := authentication.NewSSHAgentSigner(keyID, accountName) + if err != nil { + return nil, errwrap.Wrapf("Problem initializing NewSSHAgentSigner: {{err}}", err) + } + newClient.Authorizers = append(authorizers, keySigner) + } else { + return nil, MissingKeyIdError + } + } + + return newClient, nil +} + +// InsecureSkipTLSVerify turns off TLS verification for the client connection. This +// allows connection to an endpoint with a certificate which was signed by a non- +// trusted CA, such as self-signed certificates. This can be useful when connecting +// to temporary Triton installations such as Triton Cloud-On-A-Laptop. +func (c *Client) InsecureSkipTLSVerify() { + if c.HTTPClient == nil { + return + } + + c.HTTPClient.Transport = httpTransport(true) +} + +func httpTransport(insecureSkipTLSVerify bool) *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + DisableKeepAlives: true, + MaxIdleConnsPerHost: -1, + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: insecureSkipTLSVerify, + }, + } +} + +func doNotFollowRedirects(*http.Request, []*http.Request) error { + return http.ErrUseLastResponse +} + +// TODO(justinwr): Deprecated? +// func (c *Client) FormatURL(path string) string { +// return fmt.Sprintf("%s%s", c.Endpoint, path) +// } + +func (c *Client) DecodeError(statusCode int, body io.Reader) error { + err := &TritonError{ + StatusCode: statusCode, + } + + errorDecoder := json.NewDecoder(body) + if err := errorDecoder.Decode(err); err != nil { + return errwrap.Wrapf("Error decoding error response: {{err}}", err) + } + + return err +} + +// ----------------------------------------------------------------------------- + +type RequestInput struct { + Method string + Path string + Query *url.Values + Headers *http.Header + Body interface{} +} + +func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) { + method := inputs.Method + path := inputs.Path + body := inputs.Body + query := inputs.Query + + var requestBody io.ReadSeeker + if body != nil { + marshaled, err := json.MarshalIndent(body, "", " ") + if err != nil { + return nil, err + } + requestBody = bytes.NewReader(marshaled) + } + + endpoint := c.TritonURL + endpoint.Path = path + if query != nil { + endpoint.RawQuery = query.Encode() + } + + req, err := http.NewRequest(method, endpoint.String(), requestBody) + if err != nil { + return nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + } + + dateHeader := time.Now().UTC().Format(time.RFC1123) + req.Header.Set("date", dateHeader) + + // NewClient ensures there's always an authorizer (unless this is called + // outside that constructor). + authHeader, err := c.Authorizers[0].Sign(dateHeader) + if err != nil { + return nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + } + req.Header.Set("Authorization", authHeader) + req.Header.Set("Accept", "application/json") + req.Header.Set("Accept-Version", "8") + req.Header.Set("User-Agent", "triton-go Client API") + + if body != nil { + req.Header.Set("Content-Type", "application/json") + } + + resp, err := c.HTTPClient.Do(req.WithContext(ctx)) + if err != nil { + return nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + } + + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + return resp.Body, nil + } + + return nil, c.DecodeError(resp.StatusCode, resp.Body) +} + +func (c *Client) ExecuteRequest(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) { + return c.ExecuteRequestURIParams(ctx, inputs) +} + +func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*http.Response, error) { + method := inputs.Method + path := inputs.Path + body := inputs.Body + + var requestBody io.ReadSeeker + if body != nil { + marshaled, err := json.MarshalIndent(body, "", " ") + if err != nil { + return nil, err + } + requestBody = bytes.NewReader(marshaled) + } + + endpoint := c.TritonURL + endpoint.Path = path + + req, err := http.NewRequest(method, endpoint.String(), requestBody) + if err != nil { + return nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + } + + dateHeader := time.Now().UTC().Format(time.RFC1123) + req.Header.Set("date", dateHeader) + + // NewClient ensures there's always an authorizer (unless this is called + // outside that constructor). + authHeader, err := c.Authorizers[0].Sign(dateHeader) + if err != nil { + return nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + } + req.Header.Set("Authorization", authHeader) + req.Header.Set("Accept", "application/json") + req.Header.Set("Accept-Version", "8") + req.Header.Set("User-Agent", "triton-go c API") + + if body != nil { + req.Header.Set("Content-Type", "application/json") + } + + resp, err := c.HTTPClient.Do(req.WithContext(ctx)) + if err != nil { + return nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + } + + return resp, nil +} + +func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) (io.ReadCloser, http.Header, error) { + method := inputs.Method + path := inputs.Path + query := inputs.Query + headers := inputs.Headers + body := inputs.Body + + endpoint := c.MantaURL + endpoint.Path = path + + var requestBody io.ReadSeeker + if body != nil { + marshaled, err := json.MarshalIndent(body, "", " ") + if err != nil { + return nil, nil, err + } + requestBody = bytes.NewReader(marshaled) + } + + req, err := http.NewRequest(method, endpoint.String(), requestBody) + if err != nil { + return nil, nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + } + + if body != nil && (headers == nil || headers.Get("Content-Type") == "") { + req.Header.Set("Content-Type", "application/json") + } + if headers != nil { + for key, values := range *headers { + for _, value := range values { + req.Header.Set(key, value) + } + } + } + + dateHeader := time.Now().UTC().Format(time.RFC1123) + req.Header.Set("date", dateHeader) + + authHeader, err := c.Authorizers[0].Sign(dateHeader) + if err != nil { + return nil, nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + } + req.Header.Set("Authorization", authHeader) + req.Header.Set("Accept", "*/*") + req.Header.Set("User-Agent", "manta-go client API") + + if query != nil { + req.URL.RawQuery = query.Encode() + } + + resp, err := c.HTTPClient.Do(req.WithContext(ctx)) + if err != nil { + return nil, nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + } + + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + return resp.Body, resp.Header, nil + } + + mantaError := &MantaError{ + StatusCode: resp.StatusCode, + } + + errorDecoder := json.NewDecoder(resp.Body) + if err := errorDecoder.Decode(mantaError); err != nil { + return nil, nil, errwrap.Wrapf("Error decoding error response: {{err}}", err) + } + return nil, nil, mantaError +} + +type RequestNoEncodeInput struct { + Method string + Path string + Query *url.Values + Headers *http.Header + Body io.ReadSeeker +} + +func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEncodeInput) (io.ReadCloser, http.Header, error) { + method := inputs.Method + path := inputs.Path + query := inputs.Query + headers := inputs.Headers + body := inputs.Body + + endpoint := c.MantaURL + endpoint.Path = path + + req, err := http.NewRequest(method, endpoint.String(), body) + if err != nil { + return nil, nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + } + + if headers != nil { + for key, values := range *headers { + for _, value := range values { + req.Header.Set(key, value) + } + } + } + + dateHeader := time.Now().UTC().Format(time.RFC1123) + req.Header.Set("date", dateHeader) + + authHeader, err := c.Authorizers[0].Sign(dateHeader) + if err != nil { + return nil, nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + } + req.Header.Set("Authorization", authHeader) + req.Header.Set("Accept", "*/*") + req.Header.Set("User-Agent", "manta-go client API") + + if query != nil { + req.URL.RawQuery = query.Encode() + } + + resp, err := c.HTTPClient.Do(req.WithContext(ctx)) + if err != nil { + return nil, nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + } + + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + return resp.Body, resp.Header, nil + } + + mantaError := &MantaError{ + StatusCode: resp.StatusCode, + } + + errorDecoder := json.NewDecoder(resp.Body) + if err := errorDecoder.Decode(mantaError); err != nil { + return nil, nil, errwrap.Wrapf("Error decoding error response: {{err}}", err) + } + return nil, nil, mantaError +} diff --git a/vendor/github.com/joyent/triton-go/client/errors.go b/vendor/github.com/joyent/triton-go/client/errors.go new file mode 100644 index 000000000..1fc64a095 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/client/errors.go @@ -0,0 +1,190 @@ +package client + +import ( + "fmt" + + "github.com/hashicorp/errwrap" +) + +// ClientError represents an error code and message along with the status code +// of the HTTP request which resulted in the error message. +type ClientError struct { + StatusCode int + Code string + Message string +} + +// Error implements interface Error on the TritonError type. +func (e ClientError) Error() string { + return fmt.Sprintf("%s: %s", e.Code, e.Message) +} + +// MantaError represents an error code and message along with +// the status code of the HTTP request which resulted in the error +// message. Error codes used by the Manta API are listed at +// https://apidocs.joyent.com/manta/api.html#errors +type MantaError struct { + StatusCode int + Code string `json:"code"` + Message string `json:"message"` +} + +// Error implements interface Error on the MantaError type. +func (e MantaError) Error() string { + return fmt.Sprintf("%s: %s", e.Code, e.Message) +} + +// TritonError represents an error code and message along with +// the status code of the HTTP request which resulted in the error +// message. Error codes used by the Triton API are listed at +// https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses +type TritonError struct { + StatusCode int + Code string `json:"code"` + Message string `json:"message"` +} + +// Error implements interface Error on the TritonError type. +func (e TritonError) Error() string { + return fmt.Sprintf("%s: %s", e.Code, e.Message) +} + +func IsAuthSchemeError(err error) bool { + return isSpecificError(err, "AuthScheme") +} +func IsAuthorizationError(err error) bool { + return isSpecificError(err, "Authorization") +} +func IsBadRequestError(err error) bool { + return isSpecificError(err, "BadRequest") +} +func IsChecksumError(err error) bool { + return isSpecificError(err, "Checksum") +} +func IsConcurrentRequestError(err error) bool { + return isSpecificError(err, "ConcurrentRequest") +} +func IsContentLengthError(err error) bool { + return isSpecificError(err, "ContentLength") +} +func IsContentMD5MismatchError(err error) bool { + return isSpecificError(err, "ContentMD5Mismatch") +} +func IsEntityExistsError(err error) bool { + return isSpecificError(err, "EntityExists") +} +func IsInvalidArgumentError(err error) bool { + return isSpecificError(err, "InvalidArgument") +} +func IsInvalidAuthTokenError(err error) bool { + return isSpecificError(err, "InvalidAuthToken") +} +func IsInvalidCredentialsError(err error) bool { + return isSpecificError(err, "InvalidCredentials") +} +func IsInvalidDurabilityLevelError(err error) bool { + return isSpecificError(err, "InvalidDurabilityLevel") +} +func IsInvalidKeyIdError(err error) bool { + return isSpecificError(err, "InvalidKeyId") +} +func IsInvalidJobError(err error) bool { + return isSpecificError(err, "InvalidJob") +} +func IsInvalidLinkError(err error) bool { + return isSpecificError(err, "InvalidLink") +} +func IsInvalidLimitError(err error) bool { + return isSpecificError(err, "InvalidLimit") +} +func IsInvalidSignatureError(err error) bool { + return isSpecificError(err, "InvalidSignature") +} +func IsInvalidUpdateError(err error) bool { + return isSpecificError(err, "InvalidUpdate") +} +func IsDirectoryDoesNotExistError(err error) bool { + return isSpecificError(err, "DirectoryDoesNotExist") +} +func IsDirectoryExistsError(err error) bool { + return isSpecificError(err, "DirectoryExists") +} +func IsDirectoryNotEmptyError(err error) bool { + return isSpecificError(err, "DirectoryNotEmpty") +} +func IsDirectoryOperationError(err error) bool { + return isSpecificError(err, "DirectoryOperation") +} +func IsInternalError(err error) bool { + return isSpecificError(err, "Internal") +} +func IsJobNotFoundError(err error) bool { + return isSpecificError(err, "JobNotFound") +} +func IsJobStateError(err error) bool { + return isSpecificError(err, "JobState") +} +func IsKeyDoesNotExistError(err error) bool { + return isSpecificError(err, "KeyDoesNotExist") +} +func IsNotAcceptableError(err error) bool { + return isSpecificError(err, "NotAcceptable") +} +func IsNotEnoughSpaceError(err error) bool { + return isSpecificError(err, "NotEnoughSpace") +} +func IsLinkNotFoundError(err error) bool { + return isSpecificError(err, "LinkNotFound") +} +func IsLinkNotObjectError(err error) bool { + return isSpecificError(err, "LinkNotObject") +} +func IsLinkRequiredError(err error) bool { + return isSpecificError(err, "LinkRequired") +} +func IsParentNotDirectoryError(err error) bool { + return isSpecificError(err, "ParentNotDirectory") +} +func IsPreconditionFailedError(err error) bool { + return isSpecificError(err, "PreconditionFailed") +} +func IsPreSignedRequestError(err error) bool { + return isSpecificError(err, "PreSignedRequest") +} +func IsRequestEntityTooLargeError(err error) bool { + return isSpecificError(err, "RequestEntityTooLarge") +} +func IsResourceNotFoundError(err error) bool { + return isSpecificError(err, "ResourceNotFound") +} +func IsRootDirectoryError(err error) bool { + return isSpecificError(err, "RootDirectory") +} +func IsServiceUnavailableError(err error) bool { + return isSpecificError(err, "ServiceUnavailable") +} +func IsSSLRequiredError(err error) bool { + return isSpecificError(err, "SSLRequired") +} +func IsUploadTimeoutError(err error) bool { + return isSpecificError(err, "UploadTimeout") +} +func IsUserDoesNotExistError(err error) bool { + return isSpecificError(err, "UserDoesNotExist") +} + +// isSpecificError checks whether the error represented by err wraps +// an underlying MantaError with code errorCode. +func isSpecificError(err error, errorCode string) bool { + tritonErrorInterface := errwrap.GetType(err.(error), &MantaError{}) + if tritonErrorInterface == nil { + return false + } + + tritonErr := tritonErrorInterface.(*MantaError) + if tritonErr.Code == errorCode { + return true + } + + return false +} diff --git a/vendor/github.com/joyent/triton-go/compute/client.go b/vendor/github.com/joyent/triton-go/compute/client.go new file mode 100644 index 000000000..8ce726cb1 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/compute/client.go @@ -0,0 +1,57 @@ +package compute + +import ( + triton "github.com/joyent/triton-go" + "github.com/joyent/triton-go/client" +) + +type ComputeClient struct { + Client *client.Client +} + +func newComputeClient(client *client.Client) *ComputeClient { + return &ComputeClient{ + Client: client, + } +} + +// NewClient returns a new client for working with Compute endpoints and +// resources within CloudAPI +func NewClient(config *triton.ClientConfig) (*ComputeClient, error) { + // TODO: Utilize config interface within the function itself + client, err := client.New(config.TritonURL, config.MantaURL, config.AccountName, config.Signers...) + if err != nil { + return nil, err + } + return newComputeClient(client), nil +} + +// Datacenters returns a Compute client used for accessing functions pertaining +// to DataCenter functionality in the Triton API. +func (c *ComputeClient) Datacenters() *DataCentersClient { + return &DataCentersClient{c.Client} +} + +// Images returns a Compute client used for accessing functions pertaining to +// Images functionality in the Triton API. +func (c *ComputeClient) Images() *ImagesClient { + return &ImagesClient{c.Client} +} + +// Machines returns a Compute client used for accessing functions pertaining to +// machine functionality in the Triton API. +func (c *ComputeClient) Instances() *InstancesClient { + return &InstancesClient{c.Client} +} + +// Packages returns a Compute client used for accessing functions pertaining to +// Packages functionality in the Triton API. +func (c *ComputeClient) Packages() *PackagesClient { + return &PackagesClient{c.Client} +} + +// Services returns a Compute client used for accessing functions pertaining to +// Services functionality in the Triton API. +func (c *ComputeClient) Services() *ServicesClient { + return &ServicesClient{c.Client} +} diff --git a/vendor/github.com/joyent/triton-go/compute/datacenters.go b/vendor/github.com/joyent/triton-go/compute/datacenters.go new file mode 100644 index 000000000..7acaf20a1 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/compute/datacenters.go @@ -0,0 +1,97 @@ +package compute + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "sort" + + "context" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" +) + +type DataCentersClient struct { + client *client.Client +} + +type DataCenter struct { + Name string `json:"name"` + URL string `json:"url"` +} + +type ListDataCentersInput struct{} + +func (c *DataCentersClient) List(ctx context.Context, _ *ListDataCentersInput) ([]*DataCenter, error) { + path := fmt.Sprintf("/%s/datacenters", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + } + + var intermediate map[string]string + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&intermediate); err != nil { + return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + } + + keys := make([]string, len(intermediate)) + i := 0 + for k := range intermediate { + keys[i] = k + i++ + } + sort.Strings(keys) + + result := make([]*DataCenter, len(intermediate)) + i = 0 + for _, key := range keys { + result[i] = &DataCenter{ + Name: key, + URL: intermediate[key], + } + i++ + } + + return result, nil +} + +type GetDataCenterInput struct { + Name string +} + +func (c *DataCentersClient) Get(ctx context.Context, input *GetDataCenterInput) (*DataCenter, error) { + path := fmt.Sprintf("/%s/datacenters/%s", c.client.AccountName, input.Name) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + resp, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + } + + if resp.StatusCode != http.StatusFound { + return nil, fmt.Errorf("Error executing Get request: expected status code 302, got %s", + resp.StatusCode) + } + + location := resp.Header.Get("Location") + if location == "" { + return nil, errors.New("Error decoding Get response: no Location header") + } + + return &DataCenter{ + Name: input.Name, + URL: location, + }, nil +} diff --git a/vendor/github.com/joyent/triton-go/errors.go b/vendor/github.com/joyent/triton-go/compute/errors.go similarity index 54% rename from vendor/github.com/joyent/triton-go/errors.go rename to vendor/github.com/joyent/triton-go/compute/errors.go index 76d4a6254..ae2a4bf5c 100644 --- a/vendor/github.com/joyent/triton-go/errors.go +++ b/vendor/github.com/joyent/triton-go/compute/errors.go @@ -1,123 +1,112 @@ -package triton +package compute import ( - "fmt" - "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" ) -// TritonError represents an error code and message along with -// the status code of the HTTP request which resulted in the error -// message. Error codes used by the Triton API are listed at -// https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses -type TritonError struct { - StatusCode int - Code string `json:"code"` - Message string `json:"message"` -} - -// Error implements interface Error on the TritonError type. -func (e TritonError) Error() string { - return fmt.Sprintf("%s: %s", e.Code, e.Message) -} - -// IsBadRequest tests whether err wraps a TritonError with +// IsBadRequest tests whether err wraps a client.TritonError with // code BadRequest func IsBadRequest(err error) bool { return isSpecificError(err, "BadRequest") } -// IsInternalError tests whether err wraps a TritonError with +// IsInternalError tests whether err wraps a client.TritonError with // code InternalError func IsInternalError(err error) bool { return isSpecificError(err, "InternalError") } -// IsInUseError tests whether err wraps a TritonError with +// IsInUseError tests whether err wraps a client.TritonError with // code InUseError func IsInUseError(err error) bool { return isSpecificError(err, "InUseError") } -// IsInvalidArgument tests whether err wraps a TritonError with +// IsInvalidArgument tests whether err wraps a client.TritonError with // code InvalidArgument func IsInvalidArgument(err error) bool { return isSpecificError(err, "InvalidArgument") } -// IsInvalidCredentials tests whether err wraps a TritonError with +// IsInvalidCredentials tests whether err wraps a client.TritonError with // code InvalidCredentials func IsInvalidCredentials(err error) bool { return isSpecificError(err, "InvalidCredentials") } -// IsInvalidHeader tests whether err wraps a TritonError with +// IsInvalidHeader tests whether err wraps a client.TritonError with // code InvalidHeader func IsInvalidHeader(err error) bool { return isSpecificError(err, "InvalidHeader") } -// IsInvalidVersion tests whether err wraps a TritonError with +// IsInvalidVersion tests whether err wraps a client.TritonError with // code InvalidVersion func IsInvalidVersion(err error) bool { return isSpecificError(err, "InvalidVersion") } -// IsMissingParameter tests whether err wraps a TritonError with +// IsMissingParameter tests whether err wraps a client.TritonError with // code MissingParameter func IsMissingParameter(err error) bool { return isSpecificError(err, "MissingParameter") } -// IsNotAuthorized tests whether err wraps a TritonError with +// IsNotAuthorized tests whether err wraps a client.TritonError with // code NotAuthorized func IsNotAuthorized(err error) bool { return isSpecificError(err, "NotAuthorized") } -// IsRequestThrottled tests whether err wraps a TritonError with +// IsRequestThrottled tests whether err wraps a client.TritonError with // code RequestThrottled func IsRequestThrottled(err error) bool { return isSpecificError(err, "RequestThrottled") } -// IsRequestTooLarge tests whether err wraps a TritonError with +// IsRequestTooLarge tests whether err wraps a client.TritonError with // code RequestTooLarge func IsRequestTooLarge(err error) bool { return isSpecificError(err, "RequestTooLarge") } -// IsRequestMoved tests whether err wraps a TritonError with +// IsRequestMoved tests whether err wraps a client.TritonError with // code RequestMoved func IsRequestMoved(err error) bool { return isSpecificError(err, "RequestMoved") } -// IsResourceNotFound tests whether err wraps a TritonError with +// IsResourceFound tests whether err wraps a client.TritonError with code ResourceFound +func IsResourceFound(err error) bool { + return isSpecificError(err, "ResourceFound") +} + +// IsResourceNotFound tests whether err wraps a client.TritonError with // code ResourceNotFound func IsResourceNotFound(err error) bool { return isSpecificError(err, "ResourceNotFound") } -// IsUnknownError tests whether err wraps a TritonError with +// IsUnknownError tests whether err wraps a client.TritonError with // code UnknownError func IsUnknownError(err error) bool { return isSpecificError(err, "UnknownError") } // isSpecificError checks whether the error represented by err wraps -// an underlying TritonError with code errorCode. +// an underlying client.TritonError with code errorCode. func isSpecificError(err error, errorCode string) bool { if err == nil { return false } - tritonErrorInterface := errwrap.GetType(err.(error), &TritonError{}) + tritonErrorInterface := errwrap.GetType(err.(error), &client.TritonError{}) if tritonErrorInterface == nil { return false } - tritonErr := tritonErrorInterface.(*TritonError) + tritonErr := tritonErrorInterface.(*client.TritonError) if tritonErr.Code == errorCode { return true } diff --git a/vendor/github.com/joyent/triton-go/images.go b/vendor/github.com/joyent/triton-go/compute/images.go similarity index 51% rename from vendor/github.com/joyent/triton-go/images.go rename to vendor/github.com/joyent/triton-go/compute/images.go index f6ab1fce9..b60f05e53 100644 --- a/vendor/github.com/joyent/triton-go/images.go +++ b/vendor/github.com/joyent/triton-go/compute/images.go @@ -1,4 +1,4 @@ -package triton +package compute import ( "context" @@ -9,16 +9,11 @@ import ( "time" "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" ) type ImagesClient struct { - *Client -} - -// Images returns a c used for accessing functions pertaining to -// Images functionality in the Triton API. -func (c *Client) Images() *ImagesClient { - return &ImagesClient{c} + client *client.Client } type ImageFile struct { @@ -44,25 +39,62 @@ type Image struct { Tags map[string]string `json:"tags"` EULA string `json:"eula"` ACL []string `json:"acl"` - Error TritonError `json:"error"` + Error client.TritonError `json:"error"` } -type ListImagesInput struct{} +type ListImagesInput struct { + Name string + OS string + Version string + Public bool + State string + Owner string + Type string +} -func (client *ImagesClient) ListImages(ctx context.Context, _ *ListImagesInput) ([]*Image, error) { - path := fmt.Sprintf("/%s/images", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) +func (c *ImagesClient) List(ctx context.Context, input *ListImagesInput) ([]*Image, error) { + path := fmt.Sprintf("/%s/images", c.client.AccountName) + + query := &url.Values{} + if input.Name != "" { + query.Set("name", input.Name) + } + if input.OS != "" { + query.Set("os", input.OS) + } + if input.Version != "" { + query.Set("version", input.Version) + } + if input.Public { + query.Set("public", "true") + } + if input.State != "" { + query.Set("state", input.State) + } + if input.Owner != "" { + query.Set("owner", input.Owner) + } + if input.Type != "" { + query.Set("type", input.Type) + } + + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + Query: query, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListImages request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) } var result []*Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListImages response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) } return result, nil @@ -72,20 +104,24 @@ type GetImageInput struct { ImageID string } -func (client *ImagesClient) GetImage(ctx context.Context, input *GetImageInput) (*Image, error) { - path := fmt.Sprintf("/%s/images/%s", client.accountName, input.ImageID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) +func (c *ImagesClient) Get(ctx context.Context, input *GetImageInput) (*Image, error) { + path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetImage request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) } var result *Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetImage response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) } return result, nil @@ -95,14 +131,18 @@ type DeleteImageInput struct { ImageID string } -func (client *ImagesClient) DeleteImage(ctx context.Context, input *DeleteImageInput) error { - path := fmt.Sprintf("/%s/images/%s", client.accountName, input.ImageID) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) +func (c *ImagesClient) Delete(ctx context.Context, input *DeleteImageInput) error { + path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing DeleteKey request: {{err}}", err) + return errwrap.Wrapf("Error executing Delete request: {{err}}", err) } return nil @@ -119,24 +159,29 @@ type MantaLocation struct { ManifestPath string `json:"manifest_path"` } -func (client *ImagesClient) ExportImage(ctx context.Context, input *ExportImageInput) (*MantaLocation, error) { - path := fmt.Sprintf("/%s/images/%s", client.accountName, input.ImageID) +func (c *ImagesClient) Export(ctx context.Context, input *ExportImageInput) (*MantaLocation, error) { + path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) query := &url.Values{} query.Set("action", "export") query.Set("manta_path", input.MantaPath) - respReader, err := client.executeRequestURIParams(ctx, http.MethodGet, path, nil, query) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + Query: query, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetImage request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) } var result *MantaLocation decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetImage response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) } return result, nil @@ -153,20 +198,25 @@ type CreateImageFromMachineInput struct { Tags map[string]string `json:"tags,omitempty"` } -func (client *ImagesClient) CreateImageFromMachine(ctx context.Context, input *CreateImageFromMachineInput) (*Image, error) { - path := fmt.Sprintf("/%s/images", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) +func (c *ImagesClient) CreateFromMachine(ctx context.Context, input *CreateImageFromMachineInput) (*Image, error) { + path := fmt.Sprintf("/%s/images", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing CreateImageFromMachine request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing CreateFromMachine request: {{err}}", err) } var result *Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateImageFromMachine response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding CreateFromMachine response: {{err}}", err) } return result, nil @@ -183,23 +233,29 @@ type UpdateImageInput struct { Tags map[string]string `json:"tags,omitempty"` } -func (client *ImagesClient) UpdateImage(ctx context.Context, input *UpdateImageInput) (*Image, error) { - path := fmt.Sprintf("/%s/images/%s", client.accountName, input.ImageID) +func (c *ImagesClient) Update(ctx context.Context, input *UpdateImageInput) (*Image, error) { + path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) query := &url.Values{} query.Set("action", "update") - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, input, query) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: query, + Body: input, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateImage request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing Update request: {{err}}", err) } var result *Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateImage response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding Update response: {{err}}", err) } return result, nil diff --git a/vendor/github.com/joyent/triton-go/compute/instances.go b/vendor/github.com/joyent/triton-go/compute/instances.go new file mode 100644 index 000000000..337e6a482 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/compute/instances.go @@ -0,0 +1,1020 @@ +package compute + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" +) + +type InstancesClient struct { + client *client.Client +} + +const ( + CNSTagDisable = "triton.cns.disable" + CNSTagReversePTR = "triton.cns.reverse_ptr" + CNSTagServices = "triton.cns.services" +) + +// InstanceCNS is a container for the CNS-specific attributes. In the API these +// values are embedded within a Instance's Tags attribute, however they are +// exposed to the caller as their native types. +type InstanceCNS struct { + Disable bool + ReversePTR string + Services []string +} + +type Instance struct { + ID string `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Brand string `json:"brand"` + State string `json:"state"` + Image string `json:"image"` + Memory int `json:"memory"` + Disk int `json:"disk"` + Metadata map[string]string `json:"metadata"` + Tags map[string]interface{} `json:"tags"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` + Docker bool `json:"docker"` + IPs []string `json:"ips"` + Networks []string `json:"networks"` + PrimaryIP string `json:"primaryIp"` + FirewallEnabled bool `json:"firewall_enabled"` + ComputeNode string `json:"compute_node"` + Package string `json:"package"` + DomainNames []string `json:"dns_names"` + CNS InstanceCNS +} + +// _Instance is a private facade over Instance that handles the necessary API +// overrides from VMAPI's machine endpoint(s). +type _Instance struct { + Instance + Tags map[string]interface{} `json:"tags"` +} + +type NIC struct { + IP string `json:"ip"` + MAC string `json:"mac"` + Primary bool `json:"primary"` + Netmask string `json:"netmask"` + Gateway string `json:"gateway"` + State string `json:"state"` + Network string `json:"network"` +} + +type GetInstanceInput struct { + ID string +} + +func (gmi *GetInstanceInput) Validate() error { + if gmi.ID == "" { + return fmt.Errorf("machine ID can not be empty") + } + + return nil +} + +func (c *InstancesClient) Get(ctx context.Context, input *GetInstanceInput) (*Instance, error) { + if err := input.Validate(); err != nil { + return nil, errwrap.Wrapf("unable to get machine: {{err}}", err) + } + + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response != nil { + defer response.Body.Close() + } + if response == nil || response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { + return nil, &client.TritonError{ + StatusCode: response.StatusCode, + Code: "ResourceNotFound", + } + } + if err != nil { + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", + c.client.DecodeError(response.StatusCode, response.Body)) + } + + var result *_Instance + decoder := json.NewDecoder(response.Body) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + } + + native, err := result.toNative() + if err != nil { + return nil, errwrap.Wrapf("unable to convert API response for instances to native type: {{err}}", err) + } + + return native, nil +} + +type ListInstancesInput struct { + Brand string + Alias string + Name string + Image string + State string + Memory uint16 + Limit uint16 + Offset uint16 + Tags []string // query by arbitrary tags prefixed with "tag." + Tombstone bool + Docker bool + Credentials bool +} + +func (c *InstancesClient) List(ctx context.Context, input *ListInstancesInput) ([]*Instance, error) { + path := fmt.Sprintf("/%s/machines", c.client.AccountName) + + query := &url.Values{} + if input.Brand != "" { + query.Set("brand", input.Brand) + } + if input.Name != "" { + query.Set("name", input.Name) + } + if input.Image != "" { + query.Set("image", input.Image) + } + if input.State != "" { + query.Set("state", input.State) + } + if input.Memory >= 1 && input.Memory <= 1000 { + query.Set("memory", fmt.Sprintf("%d", input.Memory)) + } + if input.Limit >= 1 { + query.Set("limit", fmt.Sprintf("%d", input.Limit)) + } + if input.Offset >= 0 { + query.Set("offset", fmt.Sprintf("%d", input.Offset)) + } + if input.Tombstone { + query.Set("tombstone", "true") + } + if input.Docker { + query.Set("docker", "true") + } + if input.Credentials { + query.Set("credentials", "true") + } + + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + Query: query, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if err != nil { + return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + } + + var results []*_Instance + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&results); err != nil { + return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + } + + machines := make([]*Instance, 0, len(results)) + for _, machineAPI := range results { + native, err := machineAPI.toNative() + if err != nil { + return nil, errwrap.Wrapf("unable to convert API response for instances to native type: {{err}}", err) + } + machines = append(machines, native) + } + + return machines, nil +} + +type CreateInstanceInput struct { + Name string + Package string + Image string + Networks []string + Affinity []string + LocalityStrict bool + LocalityNear []string + LocalityFar []string + Metadata map[string]string + Tags map[string]string + FirewallEnabled bool + CNS InstanceCNS +} + +func (input *CreateInstanceInput) toAPI() (map[string]interface{}, error) { + const numExtraParams = 8 + result := make(map[string]interface{}, numExtraParams+len(input.Metadata)+len(input.Tags)) + + result["firewall_enabled"] = input.FirewallEnabled + + if input.Name != "" { + result["name"] = input.Name + } + + if input.Package != "" { + result["package"] = input.Package + } + + if input.Image != "" { + result["image"] = input.Image + } + + if len(input.Networks) > 0 { + result["networks"] = input.Networks + } + + // validate that affinity and locality are not included together + hasAffinity := len(input.Affinity) > 0 + hasLocality := len(input.LocalityNear) > 0 || len(input.LocalityFar) > 0 + if hasAffinity && hasLocality { + return nil, fmt.Errorf("Cannot include both Affinity and Locality") + } + + // affinity takes precendence over locality regardless + if len(input.Affinity) > 0 { + result["affinity"] = input.Affinity + } else { + locality := struct { + Strict bool `json:"strict"` + Near []string `json:"near,omitempty"` + Far []string `json:"far,omitempty"` + }{ + Strict: input.LocalityStrict, + Near: input.LocalityNear, + Far: input.LocalityFar, + } + result["locality"] = locality + } + + for key, value := range input.Tags { + result[fmt.Sprintf("tag.%s", key)] = value + } + + // NOTE(justinwr): CNSTagServices needs to be a tag if available. No other + // CNS tags will be handled at this time. + input.CNS.toTags(result) + if val, found := result[CNSTagServices]; found { + result["tag."+CNSTagServices] = val + delete(result, CNSTagServices) + } + + for key, value := range input.Metadata { + result[fmt.Sprintf("metadata.%s", key)] = value + } + + return result, nil +} + +func (c *InstancesClient) Create(ctx context.Context, input *CreateInstanceInput) (*Instance, error) { + path := fmt.Sprintf("/%s/machines", c.client.AccountName) + body, err := input.toAPI() + if err != nil { + return nil, errwrap.Wrapf("Error preparing Create request: {{err}}", err) + } + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: body, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing Create request: {{err}}", err) + } + + var result *Instance + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding Create response: {{err}}", err) + } + + return result, nil +} + +type DeleteInstanceInput struct { + ID string +} + +func (c *InstancesClient) Delete(ctx context.Context, input *DeleteInstanceInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response == nil { + return fmt.Errorf("Delete request has empty response") + } + if response.Body != nil { + defer response.Body.Close() + } + if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { + return nil + } + if err != nil { + return errwrap.Wrapf("Error executing Delete request: {{err}}", + c.client.DecodeError(response.StatusCode, response.Body)) + } + + return nil +} + +type DeleteTagsInput struct { + ID string +} + +func (c *InstancesClient) DeleteTags(ctx context.Context, input *DeleteTagsInput) error { + path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response == nil { + return fmt.Errorf("DeleteTags request has empty response") + } + if response.Body != nil { + defer response.Body.Close() + } + if response.StatusCode == http.StatusNotFound { + return nil + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteTags request: {{err}}", + c.client.DecodeError(response.StatusCode, response.Body)) + } + + return nil +} + +type DeleteTagInput struct { + ID string + Key string +} + +func (c *InstancesClient) DeleteTag(ctx context.Context, input *DeleteTagInput) error { + path := fmt.Sprintf("/%s/machines/%s/tags/%s", c.client.AccountName, input.ID, input.Key) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response == nil { + return fmt.Errorf("DeleteTag request has empty response") + } + if response.Body != nil { + defer response.Body.Close() + } + if response.StatusCode == http.StatusNotFound { + return nil + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteTag request: {{err}}", + c.client.DecodeError(response.StatusCode, response.Body)) + } + + return nil +} + +type RenameInstanceInput struct { + ID string + Name string +} + +func (c *InstancesClient) Rename(ctx context.Context, input *RenameInstanceInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + + params := &url.Values{} + params.Set("action", "rename") + params.Set("name", input.Name) + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing Rename request: {{err}}", err) + } + + return nil +} + +type ReplaceTagsInput struct { + ID string + Tags map[string]string + CNS InstanceCNS +} + +// toAPI is used to join Tags and CNS tags into the same JSON object before +// sending an API request to the API gateway. +func (input ReplaceTagsInput) toAPI() map[string]interface{} { + result := map[string]interface{}{} + for key, value := range input.Tags { + result[key] = value + } + input.CNS.toTags(result) + return result +} + +func (c *InstancesClient) ReplaceTags(ctx context.Context, input *ReplaceTagsInput) error { + path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPut, + Path: path, + Body: input.toAPI(), + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing ReplaceTags request: {{err}}", err) + } + + return nil +} + +type AddTagsInput struct { + ID string + Tags map[string]string +} + +func (c *InstancesClient) AddTags(ctx context.Context, input *AddTagsInput) error { + path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input.Tags, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing AddTags request: {{err}}", err) + } + + return nil +} + +type GetTagInput struct { + ID string + Key string +} + +func (c *InstancesClient) GetTag(ctx context.Context, input *GetTagInput) (string, error) { + path := fmt.Sprintf("/%s/machines/%s/tags/%s", c.client.AccountName, input.ID, input.Key) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return "", errwrap.Wrapf("Error executing GetTag request: {{err}}", err) + } + + var result string + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return "", errwrap.Wrapf("Error decoding GetTag response: {{err}}", err) + } + + return result, nil +} + +type ListTagsInput struct { + ID string +} + +func (c *InstancesClient) ListTags(ctx context.Context, input *ListTagsInput) (map[string]interface{}, error) { + path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListTags request: {{err}}", err) + } + + var result map[string]interface{} + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListTags response: {{err}}", err) + } + + _, tags := tagsExtractMeta(result) + return tags, nil +} + +type GetMetadataInput struct { + ID string + Key string +} + +// GetMetadata returns a single metadata entry associated with an instance. +func (c *InstancesClient) GetMetadata(ctx context.Context, input *GetMetadataInput) (string, error) { + if input.Key == "" { + return "", fmt.Errorf("Missing metadata Key from input: %s", input.Key) + } + + path := fmt.Sprintf("/%s/machines/%s/metadata/%s", c.client.AccountName, input.ID, input.Key) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response != nil { + defer response.Body.Close() + } + if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { + return "", &client.TritonError{ + StatusCode: response.StatusCode, + Code: "ResourceNotFound", + } + } + if err != nil { + return "", errwrap.Wrapf("Error executing Get request: {{err}}", + c.client.DecodeError(response.StatusCode, response.Body)) + } + + body, err := ioutil.ReadAll(response.Body) + if err != nil { + return "", errwrap.Wrapf("Error unwrapping request body: {{err}}", + c.client.DecodeError(response.StatusCode, response.Body)) + } + + return fmt.Sprintf("%s", body), nil +} + +type ListMetadataInput struct { + ID string + Credentials bool +} + +func (c *InstancesClient) ListMetadata(ctx context.Context, input *ListMetadataInput) (map[string]string, error) { + path := fmt.Sprintf("/%s/machines/%s/metadata", c.client.AccountName, input.ID) + + query := &url.Values{} + if input.Credentials { + query.Set("credentials", "true") + } + + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + Query: query, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListMetadata request: {{err}}", err) + } + + var result map[string]string + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListMetadata response: {{err}}", err) + } + + return result, nil +} + +type UpdateMetadataInput struct { + ID string + Metadata map[string]string +} + +func (c *InstancesClient) UpdateMetadata(ctx context.Context, input *UpdateMetadataInput) (map[string]string, error) { + path := fmt.Sprintf("/%s/machines/%s/metadata", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input.Metadata, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing UpdateMetadata request: {{err}}", err) + } + + var result map[string]string + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding UpdateMetadata response: {{err}}", err) + } + + return result, nil +} + +type DeleteMetadataInput struct { + ID string + Key string +} + +// DeleteMetadata deletes a single metadata key from an instance +func (c *InstancesClient) DeleteMetadata(ctx context.Context, input *DeleteMetadataInput) error { + if input.Key == "" { + return fmt.Errorf("Missing metadata Key from input: %s", input.Key) + } + + path := fmt.Sprintf("/%s/machines/%s/metadata/%s", c.client.AccountName, input.ID, input.Key) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteMetadata request: {{err}}", err) + } + + return nil +} + +type DeleteAllMetadataInput struct { + ID string +} + +// DeleteAllMetadata deletes all metadata keys from this instance +func (c *InstancesClient) DeleteAllMetadata(ctx context.Context, input *DeleteAllMetadataInput) error { + path := fmt.Sprintf("/%s/machines/%s/metadata", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteAllMetadata request: {{err}}", err) + } + + return nil +} + +type ResizeInstanceInput struct { + ID string + Package string +} + +func (c *InstancesClient) Resize(ctx context.Context, input *ResizeInstanceInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + + params := &url.Values{} + params.Set("action", "resize") + params.Set("package", input.Package) + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing Resize request: {{err}}", err) + } + + return nil +} + +type EnableFirewallInput struct { + ID string +} + +func (c *InstancesClient) EnableFirewall(ctx context.Context, input *EnableFirewallInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + + params := &url.Values{} + params.Set("action", "enable_firewall") + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing EnableFirewall request: {{err}}", err) + } + + return nil +} + +type DisableFirewallInput struct { + ID string +} + +func (c *InstancesClient) DisableFirewall(ctx context.Context, input *DisableFirewallInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + + params := &url.Values{} + params.Set("action", "disable_firewall") + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing DisableFirewall request: {{err}}", err) + } + + return nil +} + +type ListNICsInput struct { + InstanceID string +} + +func (c *InstancesClient) ListNICs(ctx context.Context, input *ListNICsInput) ([]*NIC, error) { + path := fmt.Sprintf("/%s/machines/%s/nics", c.client.AccountName, input.InstanceID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListNICs request: {{err}}", err) + } + + var result []*NIC + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListNICs response: {{err}}", err) + } + + return result, nil +} + +type GetNICInput struct { + InstanceID string + MAC string +} + +func (c *InstancesClient) GetNIC(ctx context.Context, input *GetNICInput) (*NIC, error) { + mac := strings.Replace(input.MAC, ":", "", -1) + path := fmt.Sprintf("/%s/machines/%s/nics/%s", c.client.AccountName, input.InstanceID, mac) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response != nil { + defer response.Body.Close() + } + switch response.StatusCode { + case http.StatusNotFound: + return nil, &client.TritonError{ + StatusCode: response.StatusCode, + Code: "ResourceNotFound", + } + } + if err != nil { + return nil, errwrap.Wrapf("Error executing GetNIC request: {{err}}", err) + } + + var result *NIC + decoder := json.NewDecoder(response.Body) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListNICs response: {{err}}", err) + } + + return result, nil +} + +type AddNICInput struct { + InstanceID string `json:"-"` + Network string `json:"network"` +} + +// AddNIC asynchronously adds a NIC to a given instance. If a NIC for a given +// network already exists, a ResourceFound error will be returned. The status +// of the addition of a NIC can be polled by calling GetNIC()'s and testing NIC +// until its state is set to "running". Only one NIC per network may exist. +// Warning: this operation causes the instance to restart. +func (c *InstancesClient) AddNIC(ctx context.Context, input *AddNICInput) (*NIC, error) { + path := fmt.Sprintf("/%s/machines/%s/nics", c.client.AccountName, input.InstanceID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response != nil { + defer response.Body.Close() + } + switch response.StatusCode { + case http.StatusFound: + return nil, &client.TritonError{ + StatusCode: response.StatusCode, + Code: "ResourceFound", + Message: response.Header.Get("Location"), + } + } + if err != nil { + return nil, errwrap.Wrapf("Error executing AddNIC request: {{err}}", err) + } + + var result *NIC + decoder := json.NewDecoder(response.Body) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding AddNIC response: {{err}}", err) + } + + return result, nil +} + +type RemoveNICInput struct { + InstanceID string + MAC string +} + +// RemoveNIC removes a given NIC from a machine asynchronously. The status of +// the removal can be polled via GetNIC(). When GetNIC() returns a 404, the NIC +// has been removed from the instance. Warning: this operation causes the +// machine to restart. +func (c *InstancesClient) RemoveNIC(ctx context.Context, input *RemoveNICInput) error { + mac := strings.Replace(input.MAC, ":", "", -1) + path := fmt.Sprintf("/%s/machines/%s/nics/%s", c.client.AccountName, input.InstanceID, mac) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if response != nil { + defer response.Body.Close() + } + switch response.StatusCode { + case http.StatusNotFound: + return &client.TritonError{ + StatusCode: response.StatusCode, + Code: "ResourceNotFound", + } + } + if err != nil { + return errwrap.Wrapf("Error executing RemoveNIC request: {{err}}", err) + } + + return nil +} + +type StopInstanceInput struct { + InstanceID string +} + +func (c *InstancesClient) Stop(ctx context.Context, input *StopInstanceInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.InstanceID) + + params := &url.Values{} + params.Set("action", "stop") + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing Stop request: {{err}}", err) + } + + return nil +} + +type StartInstanceInput struct { + InstanceID string +} + +func (c *InstancesClient) Start(ctx context.Context, input *StartInstanceInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.InstanceID) + + params := &url.Values{} + params.Set("action", "start") + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing Start request: {{err}}", err) + } + + return nil +} + +var reservedInstanceCNSTags = map[string]struct{}{ + CNSTagDisable: {}, + CNSTagReversePTR: {}, + CNSTagServices: {}, +} + +// tagsExtractMeta() extracts all of the misc parameters from Tags and returns a +// clean CNS and Tags struct. +func tagsExtractMeta(tags map[string]interface{}) (InstanceCNS, map[string]interface{}) { + nativeCNS := InstanceCNS{} + nativeTags := make(map[string]interface{}, len(tags)) + for k, raw := range tags { + if _, found := reservedInstanceCNSTags[k]; found { + switch k { + case CNSTagDisable: + b := raw.(bool) + nativeCNS.Disable = b + case CNSTagReversePTR: + s := raw.(string) + nativeCNS.ReversePTR = s + case CNSTagServices: + nativeCNS.Services = strings.Split(raw.(string), ",") + default: + // TODO(seanc@): should assert, logic fail + } + } else { + nativeTags[k] = raw + } + } + + return nativeCNS, nativeTags +} + +// toNative() exports a given _Instance (API representation) to its native object +// format. +func (api *_Instance) toNative() (*Instance, error) { + m := Instance(api.Instance) + m.CNS, m.Tags = tagsExtractMeta(api.Tags) + return &m, nil +} + +// toTags() injects its state information into a Tags map suitable for use to +// submit an API call to the vmapi machine endpoint +func (cns *InstanceCNS) toTags(m map[string]interface{}) { + if cns.Disable { + // NOTE(justinwr): The JSON encoder and API require the CNSTagDisable + // attribute to be an actual boolean, not a bool string. + m[CNSTagDisable] = cns.Disable + } + if cns.ReversePTR != "" { + m[CNSTagReversePTR] = cns.ReversePTR + } + if len(cns.Services) > 0 { + m[CNSTagServices] = strings.Join(cns.Services, ",") + } +} diff --git a/vendor/github.com/joyent/triton-go/packages.go b/vendor/github.com/joyent/triton-go/compute/packages.go similarity index 55% rename from vendor/github.com/joyent/triton-go/packages.go rename to vendor/github.com/joyent/triton-go/compute/packages.go index e8a4adbbe..f18407e45 100644 --- a/vendor/github.com/joyent/triton-go/packages.go +++ b/vendor/github.com/joyent/triton-go/compute/packages.go @@ -1,4 +1,4 @@ -package triton +package compute import ( "context" @@ -7,16 +7,11 @@ import ( "net/http" "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" ) type PackagesClient struct { - *Client -} - -// Packages returns a c used for accessing functions pertaining -// to Packages functionality in the Triton API. -func (c *Client) Packages() *PackagesClient { - return &PackagesClient{c} + client *client.Client } type Package struct { @@ -44,20 +39,25 @@ type ListPackagesInput struct { Group string `json:"group"` } -func (client *PackagesClient) ListPackages(ctx context.Context, input *ListPackagesInput) ([]*Package, error) { - path := fmt.Sprintf("/%s/packages", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, input) +func (c *PackagesClient) List(ctx context.Context, input *ListPackagesInput) ([]*Package, error) { + path := fmt.Sprintf("/%s/packages", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListPackages request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) } var result []*Package decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListPackages response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) } return result, nil @@ -67,20 +67,24 @@ type GetPackageInput struct { ID string } -func (client *PackagesClient) GetPackage(ctx context.Context, input *GetPackageInput) (*Package, error) { - path := fmt.Sprintf("/%s/packages/%s", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) +func (c *PackagesClient) Get(ctx context.Context, input *GetPackageInput) (*Package, error) { + path := fmt.Sprintf("/%s/packages/%s", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetPackage request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) } var result *Package decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetPackage response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) } return result, nil diff --git a/vendor/github.com/joyent/triton-go/services.go b/vendor/github.com/joyent/triton-go/compute/services.go similarity index 55% rename from vendor/github.com/joyent/triton-go/services.go rename to vendor/github.com/joyent/triton-go/compute/services.go index e220b2699..af1b017e0 100644 --- a/vendor/github.com/joyent/triton-go/services.go +++ b/vendor/github.com/joyent/triton-go/compute/services.go @@ -1,4 +1,4 @@ -package triton +package compute import ( "context" @@ -8,16 +8,11 @@ import ( "sort" "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" ) type ServicesClient struct { - *Client -} - -// Services returns a c used for accessing functions pertaining -// to Services functionality in the Triton API. -func (c *Client) Services() *ServicesClient { - return &ServicesClient{c} + client *client.Client } type Service struct { @@ -27,20 +22,24 @@ type Service struct { type ListServicesInput struct{} -func (client *ServicesClient) ListServices(ctx context.Context, _ *ListServicesInput) ([]*Service, error) { - path := fmt.Sprintf("/%s/services", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) +func (c *ServicesClient) List(ctx context.Context, _ *ListServicesInput) ([]*Service, error) { + path := fmt.Sprintf("/%s/services", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListServices request: {{err}}", err) + return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) } var intermediate map[string]string decoder := json.NewDecoder(respReader) if err = decoder.Decode(&intermediate); err != nil { - return nil, errwrap.Wrapf("Error decoding ListServices response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) } keys := make([]string, len(intermediate)) diff --git a/vendor/github.com/joyent/triton-go/config.go b/vendor/github.com/joyent/triton-go/config.go deleted file mode 100644 index b4f20e0a8..000000000 --- a/vendor/github.com/joyent/triton-go/config.go +++ /dev/null @@ -1,73 +0,0 @@ -package triton - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/hashicorp/errwrap" -) - -type ConfigClient struct { - *Client -} - -// Config returns a c used for accessing functions pertaining -// to Config functionality in the Triton API. -func (c *Client) Config() *ConfigClient { - return &ConfigClient{c} -} - -// Config represents configuration for your account. -type Config struct { - // DefaultNetwork is the network that docker containers are provisioned on. - DefaultNetwork string `json:"default_network"` -} - -type GetConfigInput struct{} - -// GetConfig outputs configuration for your account. -func (client *ConfigClient) GetConfig(ctx context.Context, input *GetConfigInput) (*Config, error) { - path := fmt.Sprintf("/%s/config", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetConfig request: {{err}}", err) - } - - var result *Config - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetConfig response: {{err}}", err) - } - - return result, nil -} - -type UpdateConfigInput struct { - // DefaultNetwork is the network that docker containers are provisioned on. - DefaultNetwork string `json:"default_network"` -} - -// UpdateConfig updates configuration values for your account. -func (client *ConfigClient) UpdateConfig(ctx context.Context, input *UpdateConfigInput) (*Config, error) { - path := fmt.Sprintf("/%s/config", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPut, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateConfig request: {{err}}", err) - } - - var result *Config - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateConfig response: {{err}}", err) - } - - return result, nil -} diff --git a/vendor/github.com/joyent/triton-go/datacenters.go b/vendor/github.com/joyent/triton-go/datacenters.go deleted file mode 100644 index 2834f77c2..000000000 --- a/vendor/github.com/joyent/triton-go/datacenters.go +++ /dev/null @@ -1,93 +0,0 @@ -package triton - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "sort" - - "context" - "github.com/hashicorp/errwrap" -) - -type DataCentersClient struct { - *Client -} - -// DataCenters returns a c used for accessing functions pertaining -// to Datacenter functionality in the Triton API. -func (c *Client) Datacenters() *DataCentersClient { - return &DataCentersClient{c} -} - -type DataCenter struct { - Name string `json:"name"` - URL string `json:"url"` -} - -type ListDataCentersInput struct{} - -func (client *DataCentersClient) ListDataCenters(ctx context.Context, _ *ListDataCentersInput) ([]*DataCenter, error) { - path := fmt.Sprintf("/%s/datacenters", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListDatacenters request: {{err}}", err) - } - - var intermediate map[string]string - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&intermediate); err != nil { - return nil, errwrap.Wrapf("Error decoding ListDatacenters response: {{err}}", err) - } - - keys := make([]string, len(intermediate)) - i := 0 - for k := range intermediate { - keys[i] = k - i++ - } - sort.Strings(keys) - - result := make([]*DataCenter, len(intermediate)) - i = 0 - for _, key := range keys { - result[i] = &DataCenter{ - Name: key, - URL: intermediate[key], - } - i++ - } - - return result, nil -} - -type GetDataCenterInput struct { - Name string -} - -func (client *DataCentersClient) GetDataCenter(ctx context.Context, input *GetDataCenterInput) (*DataCenter, error) { - path := fmt.Sprintf("/%s/datacenters/%s", client.accountName, input.Name) - resp, err := client.executeRequestRaw(ctx, http.MethodGet, path, nil) - if err != nil { - return nil, errwrap.Wrapf("Error executing GetDatacenter request: {{err}}", err) - } - - if resp.StatusCode != http.StatusFound { - return nil, fmt.Errorf("Error executing GetDatacenter request: expected status code 302, got %s", - resp.StatusCode) - } - - location := resp.Header.Get("Location") - if location == "" { - return nil, errors.New("Error decoding GetDatacenter response: no Location header") - } - - return &DataCenter{ - Name: input.Name, - URL: location, - }, nil -} diff --git a/vendor/github.com/joyent/triton-go/fabrics.go b/vendor/github.com/joyent/triton-go/fabrics.go deleted file mode 100644 index 1d32b83ba..000000000 --- a/vendor/github.com/joyent/triton-go/fabrics.go +++ /dev/null @@ -1,234 +0,0 @@ -package triton - -import ( - "encoding/json" - "fmt" - "net/http" - - "context" - "github.com/hashicorp/errwrap" -) - -type FabricsClient struct { - *Client -} - -// Fabrics returns a client used for accessing functions pertaining to -// Fabric functionality in the Triton API. -func (c *Client) Fabrics() *FabricsClient { - return &FabricsClient{c} -} - -type FabricVLAN struct { - Name string `json:"name"` - ID int `json:"vlan_id"` - Description string `json:"description"` -} - -type ListFabricVLANsInput struct{} - -func (client *FabricsClient) ListFabricVLANs(ctx context.Context, _ *ListFabricVLANsInput) ([]*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListFabricVLANs request: {{err}}", err) - } - - var result []*FabricVLAN - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListFabricVLANs response: {{err}}", err) - } - - return result, nil -} - -type CreateFabricVLANInput struct { - Name string `json:"name"` - ID int `json:"vlan_id"` - Description string `json:"description"` -} - -func (client *FabricsClient) CreateFabricVLAN(ctx context.Context, input *CreateFabricVLANInput) (*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing CreateFabricVLAN request: {{err}}", err) - } - - var result *FabricVLAN - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateFabricVLAN response: {{err}}", err) - } - - return result, nil -} - -type UpdateFabricVLANInput struct { - ID int `json:"-"` - Name string `json:"name"` - Description string `json:"description"` -} - -func (client *FabricsClient) UpdateFabricVLAN(ctx context.Context, input *UpdateFabricVLANInput) (*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPut, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateFabricVLAN request: {{err}}", err) - } - - var result *FabricVLAN - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateFabricVLAN response: {{err}}", err) - } - - return result, nil -} - -type GetFabricVLANInput struct { - ID int `json:"-"` -} - -func (client *FabricsClient) GetFabricVLAN(ctx context.Context, input *GetFabricVLANInput) (*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetFabricVLAN request: {{err}}", err) - } - - var result *FabricVLAN - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetFabricVLAN response: {{err}}", err) - } - - return result, nil -} - -type DeleteFabricVLANInput struct { - ID int `json:"-"` -} - -func (client *FabricsClient) DeleteFabricVLAN(ctx context.Context, input *DeleteFabricVLANInput) error { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteFabricVLAN request: {{err}}", err) - } - - return nil -} - -type ListFabricNetworksInput struct { - FabricVLANID int `json:"-"` -} - -func (client *FabricsClient) ListFabricNetworks(ctx context.Context, input *ListFabricNetworksInput) ([]*Network, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks", client.accountName, input.FabricVLANID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListFabricNetworks request: {{err}}", err) - } - - var result []*Network - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListFabricNetworks response: {{err}}", err) - } - - return result, nil -} - -type CreateFabricNetworkInput struct { - FabricVLANID int `json:"-"` - Name string `json:"name"` - Description string `json:"description"` - Subnet string `json:"subnet"` - ProvisionStartIP string `json:"provision_start_ip"` - ProvisionEndIP string `json:"provision_end_ip"` - Gateway string `json:"gateway"` - Resolvers []string `json:"resolvers"` - Routes map[string]string `json:"routes"` - InternetNAT bool `json:"internet_nat"` -} - -func (client *FabricsClient) CreateFabricNetwork(ctx context.Context, input *CreateFabricNetworkInput) (*Network, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks", client.accountName, input.FabricVLANID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing CreateFabricNetwork request: {{err}}", err) - } - - var result *Network - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateFabricNetwork response: {{err}}", err) - } - - return result, nil -} - -type GetFabricNetworkInput struct { - FabricVLANID int `json:"-"` - NetworkID string `json:"-"` -} - -func (client *FabricsClient) GetFabricNetwork(ctx context.Context, input *GetFabricNetworkInput) (*Network, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks/%s", client.accountName, input.FabricVLANID, input.NetworkID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetFabricNetwork request: {{err}}", err) - } - - var result *Network - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetFabricNetwork response: {{err}}", err) - } - - return result, nil -} - -type DeleteFabricNetworkInput struct { - FabricVLANID int `json:"-"` - NetworkID string `json:"-"` -} - -func (client *FabricsClient) DeleteFabricNetwork(ctx context.Context, input *DeleteFabricNetworkInput) error { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks/%s", client.accountName, input.FabricVLANID, input.NetworkID) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteFabricNetwork request: {{err}}", err) - } - - return nil -} diff --git a/vendor/github.com/joyent/triton-go/firewall.go b/vendor/github.com/joyent/triton-go/firewall.go deleted file mode 100644 index a3de9ccf6..000000000 --- a/vendor/github.com/joyent/triton-go/firewall.go +++ /dev/null @@ -1,219 +0,0 @@ -package triton - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/hashicorp/errwrap" -) - -type FirewallClient struct { - *Client -} - -// Firewall returns a client used for accessing functions pertaining to -// firewall functionality in the Triton API. -func (c *Client) Firewall() *FirewallClient { - return &FirewallClient{c} -} - -// FirewallRule represents a firewall rule -type FirewallRule struct { - // ID is a unique identifier for this rule - ID string `json:"id"` - - // Enabled indicates if the rule is enabled - Enabled bool `json:"enabled"` - - // Rule is the firewall rule text - Rule string `json:"rule"` - - // Global indicates if the rule is global. Optional. - Global bool `json:"global"` - - // Description is a human-readable description for the rule. Optional - Description string `json:"description"` -} - -type ListFirewallRulesInput struct{} - -func (client *FirewallClient) ListFirewallRules(ctx context.Context, _ *ListFirewallRulesInput) ([]*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListFirewallRules request: {{err}}", err) - } - - var result []*FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListFirewallRules response: {{err}}", err) - } - - return result, nil -} - -type GetFirewallRuleInput struct { - ID string -} - -func (client *FirewallClient) GetFirewallRule(ctx context.Context, input *GetFirewallRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetFirewallRule request: {{err}}", err) - } - - var result *FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetFirewallRule response: {{err}}", err) - } - - return result, nil -} - -type CreateFirewallRuleInput struct { - Enabled bool `json:"enabled"` - Rule string `json:"rule"` - Description string `json:"description"` -} - -func (client *FirewallClient) CreateFirewallRule(ctx context.Context, input *CreateFirewallRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing CreateFirewallRule request: {{err}}", err) - } - - var result *FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateFirewallRule response: {{err}}", err) - } - - return result, nil -} - -type UpdateFirewallRuleInput struct { - ID string `json:"-"` - Enabled bool `json:"enabled"` - Rule string `json:"rule"` - Description string `json:"description"` -} - -func (client *FirewallClient) UpdateFirewallRule(ctx context.Context, input *UpdateFirewallRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateFirewallRule request: {{err}}", err) - } - - var result *FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateFirewallRule response: {{err}}", err) - } - - return result, nil -} - -type EnableFirewallRuleInput struct { - ID string `json:"-"` -} - -func (client *FirewallClient) EnableFirewallRule(ctx context.Context, input *EnableFirewallRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s/enable", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing EnableFirewallRule request: {{err}}", err) - } - - var result *FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding EnableFirewallRule response: {{err}}", err) - } - - return result, nil -} - -type DisableFirewallRuleInput struct { - ID string `json:"-"` -} - -func (client *FirewallClient) DisableFirewallRule(ctx context.Context, input *DisableFirewallRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s/disable", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing DisableFirewallRule request: {{err}}", err) - } - - var result *FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding DisableFirewallRule response: {{err}}", err) - } - - return result, nil -} - -type DeleteFirewallRuleInput struct { - ID string -} - -func (client *FirewallClient) DeleteFirewallRule(ctx context.Context, input *DeleteFirewallRuleInput) error { - path := fmt.Sprintf("/%s/fwrules/%s", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteFirewallRule request: {{err}}", err) - } - - return nil -} - -type ListMachineFirewallRulesInput struct { - MachineID string -} - -func (client *FirewallClient) ListMachineFirewallRules(ctx context.Context, input *ListMachineFirewallRulesInput) ([]*FirewallRule, error) { - path := fmt.Sprintf("/%s/machines/%s/firewallrules", client.accountName, input.MachineID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListMachineFirewallRules request: {{err}}", err) - } - - var result []*FirewallRule - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListFirewallRules response: {{err}}", err) - } - - return result, nil -} diff --git a/vendor/github.com/joyent/triton-go/keys.go b/vendor/github.com/joyent/triton-go/keys.go deleted file mode 100644 index 001f020ee..000000000 --- a/vendor/github.com/joyent/triton-go/keys.go +++ /dev/null @@ -1,125 +0,0 @@ -package triton - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/hashicorp/errwrap" -) - -type KeysClient struct { - *Client -} - -// Keys returns a c used for accessing functions pertaining to -// SSH key functionality in the Triton API. -func (c *Client) Keys() *KeysClient { - return &KeysClient{c} -} - -// Key represents a public key -type Key struct { - // Name of the key - Name string `json:"name"` - - // Key fingerprint - Fingerprint string `json:"fingerprint"` - - // OpenSSH-formatted public key - Key string `json:"key"` -} - -type ListKeysInput struct{} - -// ListKeys lists all public keys we have on record for the specified -// account. -func (client *KeysClient) ListKeys(ctx context.Context, _ *ListKeysInput) ([]*Key, error) { - path := fmt.Sprintf("/%s/keys", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListKeys request: {{err}}", err) - } - - var result []*Key - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListKeys response: {{err}}", err) - } - - return result, nil -} - -type GetKeyInput struct { - KeyName string -} - -func (client *KeysClient) GetKey(ctx context.Context, input *GetKeyInput) (*Key, error) { - path := fmt.Sprintf("/%s/keys/%s", client.accountName, input.KeyName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetKey request: {{err}}", err) - } - - var result *Key - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetKey response: {{err}}", err) - } - - return result, nil -} - -type DeleteKeyInput struct { - KeyName string -} - -func (client *KeysClient) DeleteKey(ctx context.Context, input *DeleteKeyInput) error { - path := fmt.Sprintf("/%s/keys/%s", client.accountName, input.KeyName) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteKey request: {{err}}", err) - } - - return nil -} - -// CreateKeyInput represents the option that can be specified -// when creating a new key. -type CreateKeyInput struct { - // Name of the key. Optional. - Name string `json:"name,omitempty"` - - // OpenSSH-formatted public key. - Key string `json:"key"` -} - -// CreateKey uploads a new OpenSSH key to Triton for use in HTTP signing and SSH. -func (client *KeysClient) CreateKey(ctx context.Context, input *CreateKeyInput) (*Key, error) { - path := fmt.Sprintf("/%s/keys", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing CreateKey request: {{err}}", err) - } - - var result *Key - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateKey response: {{err}}", err) - } - - return result, nil -} diff --git a/vendor/github.com/joyent/triton-go/machines.go b/vendor/github.com/joyent/triton-go/machines.go deleted file mode 100644 index aba5a984a..000000000 --- a/vendor/github.com/joyent/triton-go/machines.go +++ /dev/null @@ -1,667 +0,0 @@ -package triton - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "github.com/hashicorp/errwrap" -) - -type MachinesClient struct { - *Client -} - -// Machines returns a client used for accessing functions pertaining to -// machine functionality in the Triton API. -func (c *Client) Machines() *MachinesClient { - return &MachinesClient{c} -} - -const ( - machineCNSTagDisable = "triton.cns.disable" - machineCNSTagReversePTR = "triton.cns.reverse_ptr" - machineCNSTagServices = "triton.cns.services" -) - -// MachineCNS is a container for the CNS-specific attributes. In the API these -// values are embedded within a Machine's Tags attribute, however they are -// exposed to the caller as their native types. -type MachineCNS struct { - Disable *bool - ReversePTR *string - Services []string -} - -type Machine struct { - ID string `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - Brand string `json:"brand"` - State string `json:"state"` - Image string `json:"image"` - Memory int `json:"memory"` - Disk int `json:"disk"` - Metadata map[string]string `json:"metadata"` - Tags map[string]string `json:"tags"` - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` - Docker bool `json:"docker"` - IPs []string `json:"ips"` - Networks []string `json:"networks"` - PrimaryIP string `json:"primaryIp"` - FirewallEnabled bool `json:"firewall_enabled"` - ComputeNode string `json:"compute_node"` - Package string `json:"package"` - DomainNames []string `json:"dns_names"` - CNS MachineCNS -} - -// _Machine is a private facade over Machine that handles the necessary API -// overrides from VMAPI's machine endpoint(s). -type _Machine struct { - Machine - Tags map[string]interface{} `json:"tags"` -} - -type NIC struct { - IP string `json:"ip"` - MAC string `json:"mac"` - Primary bool `json:"primary"` - Netmask string `json:"netmask"` - Gateway string `json:"gateway"` - State string `json:"state"` - Network string `json:"network"` -} - -type GetMachineInput struct { - ID string -} - -func (gmi *GetMachineInput) Validate() error { - if gmi.ID == "" { - return fmt.Errorf("machine ID can not be empty") - } - - return nil -} - -func (client *MachinesClient) GetMachine(ctx context.Context, input *GetMachineInput) (*Machine, error) { - if err := input.Validate(); err != nil { - return nil, errwrap.Wrapf("unable to get machine: {{err}}", err) - } - - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID) - response, err := client.executeRequestRaw(ctx, http.MethodGet, path, nil) - if response != nil { - defer response.Body.Close() - } - if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { - return nil, &TritonError{ - StatusCode: response.StatusCode, - Code: "ResourceNotFound", - } - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetMachine request: {{err}}", - client.decodeError(response.StatusCode, response.Body)) - } - - var result *_Machine - decoder := json.NewDecoder(response.Body) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetMachine response: {{err}}", err) - } - - native, err := result.toNative() - if err != nil { - return nil, errwrap.Wrapf("unable to convert API response for machines to native type: {{err}}", err) - } - - return native, nil -} - -type ListMachinesInput struct{} - -func (client *MachinesClient) ListMachines(ctx context.Context, _ *ListMachinesInput) ([]*Machine, error) { - path := fmt.Sprintf("/%s/machines", client.accountName) - response, err := client.executeRequestRaw(ctx, http.MethodGet, path, nil) - if response != nil { - defer response.Body.Close() - } - if response.StatusCode == http.StatusNotFound { - return nil, &TritonError{ - StatusCode: response.StatusCode, - Code: "ResourceNotFound", - } - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListMachines request: {{err}}", - client.decodeError(response.StatusCode, response.Body)) - } - - var results []*_Machine - decoder := json.NewDecoder(response.Body) - if err = decoder.Decode(&results); err != nil { - return nil, errwrap.Wrapf("Error decoding ListMachines response: {{err}}", err) - } - - machines := make([]*Machine, 0, len(results)) - for _, machineAPI := range results { - native, err := machineAPI.toNative() - if err != nil { - return nil, errwrap.Wrapf("unable to convert API response for machines to native type: {{err}}", err) - } - machines = append(machines, native) - } - return machines, nil -} - -type CreateMachineInput struct { - Name string - Package string - Image string - Networks []string - LocalityStrict bool - LocalityNear []string - LocalityFar []string - Metadata map[string]string - Tags map[string]string - FirewallEnabled bool - CNS MachineCNS -} - -func (input *CreateMachineInput) toAPI() map[string]interface{} { - const numExtraParams = 8 - result := make(map[string]interface{}, numExtraParams+len(input.Metadata)+len(input.Tags)) - - result["firewall_enabled"] = input.FirewallEnabled - - if input.Name != "" { - result["name"] = input.Name - } - - if input.Package != "" { - result["package"] = input.Package - } - - if input.Image != "" { - result["image"] = input.Image - } - - if len(input.Networks) > 0 { - result["networks"] = input.Networks - } - - locality := struct { - Strict bool `json:"strict"` - Near []string `json:"near,omitempty"` - Far []string `json:"far,omitempty"` - }{ - Strict: input.LocalityStrict, - Near: input.LocalityNear, - Far: input.LocalityFar, - } - result["locality"] = locality - for key, value := range input.Tags { - result[fmt.Sprintf("tag.%s", key)] = value - } - - // Deliberately clobber any user-specified Tags with the attributes from the - // CNS struct. - input.CNS.toTags(result) - - for key, value := range input.Metadata { - result[fmt.Sprintf("metadata.%s", key)] = value - } - - return result -} - -func (client *MachinesClient) CreateMachine(ctx context.Context, input *CreateMachineInput) (*Machine, error) { - path := fmt.Sprintf("/%s/machines", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input.toAPI()) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing CreateMachine request: {{err}}", err) - } - - var result *Machine - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateMachine response: {{err}}", err) - } - - return result, nil -} - -type DeleteMachineInput struct { - ID string -} - -func (client *MachinesClient) DeleteMachine(ctx context.Context, input *DeleteMachineInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID) - response, err := client.executeRequestRaw(ctx, http.MethodDelete, path, nil) - if response.Body != nil { - defer response.Body.Close() - } - if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { - return nil - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteMachine request: {{err}}", - client.decodeError(response.StatusCode, response.Body)) - } - - return nil -} - -type DeleteMachineTagsInput struct { - ID string -} - -func (client *MachinesClient) DeleteMachineTags(ctx context.Context, input *DeleteMachineTagsInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID) - response, err := client.executeRequestRaw(ctx, http.MethodDelete, path, nil) - if response.Body != nil { - defer response.Body.Close() - } - if response.StatusCode == http.StatusNotFound { - return nil - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteMachineTags request: {{err}}", - client.decodeError(response.StatusCode, response.Body)) - } - - return nil -} - -type DeleteMachineTagInput struct { - ID string - Key string -} - -func (client *MachinesClient) DeleteMachineTag(ctx context.Context, input *DeleteMachineTagInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags/%s", client.accountName, input.ID, input.Key) - response, err := client.executeRequestRaw(ctx, http.MethodDelete, path, nil) - if response.Body != nil { - defer response.Body.Close() - } - if response.StatusCode == http.StatusNotFound { - return nil - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteMachineTag request: {{err}}", - client.decodeError(response.StatusCode, response.Body)) - } - - return nil -} - -type RenameMachineInput struct { - ID string - Name string -} - -func (client *MachinesClient) RenameMachine(ctx context.Context, input *RenameMachineInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID) - - params := &url.Values{} - params.Set("action", "rename") - params.Set("name", input.Name) - - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, nil, params) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing RenameMachine request: {{err}}", err) - } - - return nil -} - -type ReplaceMachineTagsInput struct { - ID string - Tags map[string]string -} - -func (client *MachinesClient) ReplaceMachineTags(ctx context.Context, input *ReplaceMachineTagsInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPut, path, input.Tags) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing ReplaceMachineTags request: {{err}}", err) - } - - return nil -} - -type AddMachineTagsInput struct { - ID string - Tags map[string]string -} - -func (client *MachinesClient) AddMachineTags(ctx context.Context, input *AddMachineTagsInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input.Tags) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing AddMachineTags request: {{err}}", err) - } - - return nil -} - -type GetMachineTagInput struct { - ID string - Key string -} - -func (client *MachinesClient) GetMachineTag(ctx context.Context, input *GetMachineTagInput) (string, error) { - path := fmt.Sprintf("/%s/machines/%s/tags/%s", client.accountName, input.ID, input.Key) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return "", errwrap.Wrapf("Error executing GetMachineTag request: {{err}}", err) - } - - var result string - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return "", errwrap.Wrapf("Error decoding GetMachineTag response: {{err}}", err) - } - - return result, nil -} - -type ListMachineTagsInput struct { - ID string -} - -func (client *MachinesClient) ListMachineTags(ctx context.Context, input *ListMachineTagsInput) (map[string]string, error) { - path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListMachineTags request: {{err}}", err) - } - - var result map[string]interface{} - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListMachineTags response: {{err}}", err) - } - - _, tags := machineTagsExtractMeta(result) - return tags, nil -} - -type UpdateMachineMetadataInput struct { - ID string - Metadata map[string]string -} - -func (client *MachinesClient) UpdateMachineMetadata(ctx context.Context, input *UpdateMachineMetadataInput) (map[string]string, error) { - path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input.Metadata) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateMachineMetadata request: {{err}}", err) - } - - var result map[string]string - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateMachineMetadata response: {{err}}", err) - } - - return result, nil -} - -type ResizeMachineInput struct { - ID string - Package string -} - -func (client *MachinesClient) ResizeMachine(ctx context.Context, input *ResizeMachineInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID) - - params := &url.Values{} - params.Set("action", "resize") - params.Set("package", input.Package) - - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, nil, params) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing ResizeMachine request: {{err}}", err) - } - - return nil -} - -type EnableMachineFirewallInput struct { - ID string -} - -func (client *MachinesClient) EnableMachineFirewall(ctx context.Context, input *EnableMachineFirewallInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID) - - params := &url.Values{} - params.Set("action", "enable_firewall") - - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, nil, params) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing EnableMachineFirewall request: {{err}}", err) - } - - return nil -} - -type DisableMachineFirewallInput struct { - ID string -} - -func (client *MachinesClient) DisableMachineFirewall(ctx context.Context, input *DisableMachineFirewallInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID) - - params := &url.Values{} - params.Set("action", "disable_firewall") - - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, nil, params) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing DisableMachineFirewall request: {{err}}", err) - } - - return nil -} - -type ListNICsInput struct { - MachineID string -} - -func (client *MachinesClient) ListNICs(ctx context.Context, input *ListNICsInput) ([]*NIC, error) { - path := fmt.Sprintf("/%s/machines/%s/nics", client.accountName, input.MachineID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListNICs request: {{err}}", err) - } - - var result []*NIC - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListNICs response: {{err}}", err) - } - - return result, nil -} - -type AddNICInput struct { - MachineID string `json:"-"` - Network string `json:"network"` -} - -func (client *MachinesClient) AddNIC(ctx context.Context, input *AddNICInput) (*NIC, error) { - path := fmt.Sprintf("/%s/machines/%s/nics", client.accountName, input.MachineID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing AddNIC request: {{err}}", err) - } - - var result *NIC - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding AddNIC response: {{err}}", err) - } - - return result, nil -} - -type RemoveNICInput struct { - MachineID string - MAC string -} - -func (client *MachinesClient) RemoveNIC(ctx context.Context, input *RemoveNICInput) error { - path := fmt.Sprintf("/%s/machines/%s/nics/%s", client.accountName, input.MachineID, input.MAC) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing RemoveNIC request: {{err}}", err) - } - - return nil -} - -type StopMachineInput struct { - MachineID string -} - -func (client *MachinesClient) StopMachine(ctx context.Context, input *StopMachineInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.MachineID) - - params := &url.Values{} - params.Set("action", "stop") - - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, nil, params) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing StopMachine request: {{err}}", err) - } - - return nil -} - -type StartMachineInput struct { - MachineID string -} - -func (client *MachinesClient) StartMachine(ctx context.Context, input *StartMachineInput) error { - path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.MachineID) - - params := &url.Values{} - params.Set("action", "start") - - respReader, err := client.executeRequestURIParams(ctx, http.MethodPost, path, nil, params) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing StartMachine request: {{err}}", err) - } - - return nil -} - -var reservedMachineCNSTags = map[string]struct{}{ - machineCNSTagDisable: {}, - machineCNSTagReversePTR: {}, - machineCNSTagServices: {}, -} - -// machineTagsExtractMeta() extracts all of the misc parameters from Tags and -// returns a clean CNS and Tags struct. -func machineTagsExtractMeta(tags map[string]interface{}) (MachineCNS, map[string]string) { - nativeCNS := MachineCNS{} - nativeTags := make(map[string]string, len(tags)) - for k, raw := range tags { - if _, found := reservedMachineCNSTags[k]; found { - switch k { - case machineCNSTagDisable: - b := raw.(bool) - nativeCNS.Disable = &b - case machineCNSTagReversePTR: - s := raw.(string) - nativeCNS.ReversePTR = &s - case machineCNSTagServices: - nativeCNS.Services = strings.Split(raw.(string), ",") - default: - // TODO(seanc@): should assert, logic fail - } - } else { - nativeTags[k] = raw.(string) - } - } - - return nativeCNS, nativeTags -} - -// toNative() exports a given _Machine (API representation) to its native object -// format. -func (api *_Machine) toNative() (*Machine, error) { - m := Machine(api.Machine) - m.CNS, m.Tags = machineTagsExtractMeta(api.Tags) - return &m, nil -} - -// toTags() injects its state information into a Tags map suitable for use to -// submit an API call to the vmapi machine endpoint -func (mcns *MachineCNS) toTags(m map[string]interface{}) { - if mcns.Disable != nil { - s := fmt.Sprintf("%t", mcns.Disable) - m[machineCNSTagDisable] = &s - } - - if mcns.ReversePTR != nil { - m[machineCNSTagReversePTR] = &mcns.ReversePTR - } - - if len(mcns.Services) > 0 { - m[machineCNSTagServices] = strings.Join(mcns.Services, ",") - } -} diff --git a/vendor/github.com/joyent/triton-go/network/client.go b/vendor/github.com/joyent/triton-go/network/client.go new file mode 100644 index 000000000..dbc25a84c --- /dev/null +++ b/vendor/github.com/joyent/triton-go/network/client.go @@ -0,0 +1,39 @@ +package network + +import ( + triton "github.com/joyent/triton-go" + "github.com/joyent/triton-go/client" +) + +type NetworkClient struct { + Client *client.Client +} + +func newNetworkClient(client *client.Client) *NetworkClient { + return &NetworkClient{ + Client: client, + } +} + +// NewClient returns a new client for working with Network endpoints and +// resources within CloudAPI +func NewClient(config *triton.ClientConfig) (*NetworkClient, error) { + // TODO: Utilize config interface within the function itself + client, err := client.New(config.TritonURL, config.MantaURL, config.AccountName, config.Signers...) + if err != nil { + return nil, err + } + return newNetworkClient(client), nil +} + +// Fabrics returns a FabricsClient used for accessing functions pertaining to +// Fabric functionality in the Triton API. +func (c *NetworkClient) Fabrics() *FabricsClient { + return &FabricsClient{c.Client} +} + +// Firewall returns a FirewallClient client used for accessing functions +// pertaining to firewall functionality in the Triton API. +func (c *NetworkClient) Firewall() *FirewallClient { + return &FirewallClient{c.Client} +} diff --git a/vendor/github.com/joyent/triton-go/network/fabrics.go b/vendor/github.com/joyent/triton-go/network/fabrics.go new file mode 100644 index 000000000..20f1d2fe6 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/network/fabrics.go @@ -0,0 +1,269 @@ +package network + +import ( + "encoding/json" + "fmt" + "net/http" + + "context" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" +) + +type FabricsClient struct { + client *client.Client +} + +type FabricVLAN struct { + Name string `json:"name"` + ID int `json:"vlan_id"` + Description string `json:"description"` +} + +type ListVLANsInput struct{} + +func (c *FabricsClient) ListVLANs(ctx context.Context, _ *ListVLANsInput) ([]*FabricVLAN, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListVLANs request: {{err}}", err) + } + + var result []*FabricVLAN + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListVLANs response: {{err}}", err) + } + + return result, nil +} + +type CreateVLANInput struct { + Name string `json:"name"` + ID int `json:"vlan_id"` + Description string `json:"description,omitempty"` +} + +func (c *FabricsClient) CreateVLAN(ctx context.Context, input *CreateVLANInput) (*FabricVLAN, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing CreateVLAN request: {{err}}", err) + } + + var result *FabricVLAN + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding CreateVLAN response: {{err}}", err) + } + + return result, nil +} + +type UpdateVLANInput struct { + ID int `json:"-"` + Name string `json:"name"` + Description string `json:"description"` +} + +func (c *FabricsClient) UpdateVLAN(ctx context.Context, input *UpdateVLANInput) (*FabricVLAN, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPut, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing UpdateVLAN request: {{err}}", err) + } + + var result *FabricVLAN + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding UpdateVLAN response: {{err}}", err) + } + + return result, nil +} + +type GetVLANInput struct { + ID int `json:"-"` +} + +func (c *FabricsClient) GetVLAN(ctx context.Context, input *GetVLANInput) (*FabricVLAN, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing GetVLAN request: {{err}}", err) + } + + var result *FabricVLAN + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding GetVLAN response: {{err}}", err) + } + + return result, nil +} + +type DeleteVLANInput struct { + ID int `json:"-"` +} + +func (c *FabricsClient) DeleteVLAN(ctx context.Context, input *DeleteVLANInput) error { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteVLAN request: {{err}}", err) + } + + return nil +} + +type ListFabricsInput struct { + FabricVLANID int `json:"-"` +} + +func (c *FabricsClient) List(ctx context.Context, input *ListFabricsInput) ([]*Network, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks", c.client.AccountName, input.FabricVLANID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListFabrics request: {{err}}", err) + } + + var result []*Network + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListFabrics response: {{err}}", err) + } + + return result, nil +} + +type CreateFabricInput struct { + FabricVLANID int `json:"-"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + Subnet string `json:"subnet"` + ProvisionStartIP string `json:"provision_start_ip"` + ProvisionEndIP string `json:"provision_end_ip"` + Gateway string `json:"gateway,omitempty"` + Resolvers []string `json:"resolvers,omitempty"` + Routes map[string]string `json:"routes,omitempty"` + InternetNAT bool `json:"internet_nat"` +} + +func (c *FabricsClient) Create(ctx context.Context, input *CreateFabricInput) (*Network, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks", c.client.AccountName, input.FabricVLANID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing CreateFabric request: {{err}}", err) + } + + var result *Network + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding CreateFabric response: {{err}}", err) + } + + return result, nil +} + +type GetFabricInput struct { + FabricVLANID int `json:"-"` + NetworkID string `json:"-"` +} + +func (c *FabricsClient) Get(ctx context.Context, input *GetFabricInput) (*Network, error) { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks/%s", c.client.AccountName, input.FabricVLANID, input.NetworkID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing GetFabric request: {{err}}", err) + } + + var result *Network + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding GetFabric response: {{err}}", err) + } + + return result, nil +} + +type DeleteFabricInput struct { + FabricVLANID int `json:"-"` + NetworkID string `json:"-"` +} + +func (c *FabricsClient) Delete(ctx context.Context, input *DeleteFabricInput) error { + path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks/%s", c.client.AccountName, input.FabricVLANID, input.NetworkID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteFabric request: {{err}}", err) + } + + return nil +} diff --git a/vendor/github.com/joyent/triton-go/network/firewall.go b/vendor/github.com/joyent/triton-go/network/firewall.go new file mode 100644 index 000000000..60054702a --- /dev/null +++ b/vendor/github.com/joyent/triton-go/network/firewall.go @@ -0,0 +1,250 @@ +package network + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" +) + +type FirewallClient struct { + client *client.Client +} + +// FirewallRule represents a firewall rule +type FirewallRule struct { + // ID is a unique identifier for this rule + ID string `json:"id"` + + // Enabled indicates if the rule is enabled + Enabled bool `json:"enabled"` + + // Rule is the firewall rule text + Rule string `json:"rule"` + + // Global indicates if the rule is global. Optional. + Global bool `json:"global"` + + // Description is a human-readable description for the rule. Optional + Description string `json:"description"` +} + +type ListRulesInput struct{} + +func (c *FirewallClient) ListRules(ctx context.Context, _ *ListRulesInput) ([]*FirewallRule, error) { + path := fmt.Sprintf("/%s/fwrules", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListRules request: {{err}}", err) + } + + var result []*FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListRules response: {{err}}", err) + } + + return result, nil +} + +type GetRuleInput struct { + ID string +} + +func (c *FirewallClient) GetRule(ctx context.Context, input *GetRuleInput) (*FirewallRule, error) { + path := fmt.Sprintf("/%s/fwrules/%s", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing GetRule request: {{err}}", err) + } + + var result *FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding GetRule response: {{err}}", err) + } + + return result, nil +} + +type CreateRuleInput struct { + Enabled bool `json:"enabled"` + Rule string `json:"rule"` + Description string `json:"description,omitempty"` +} + +func (c *FirewallClient) CreateRule(ctx context.Context, input *CreateRuleInput) (*FirewallRule, error) { + path := fmt.Sprintf("/%s/fwrules", c.client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing CreateRule request: {{err}}", err) + } + + var result *FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding CreateRule response: {{err}}", err) + } + + return result, nil +} + +type UpdateRuleInput struct { + ID string `json:"-"` + Enabled bool `json:"enabled"` + Rule string `json:"rule"` + Description string `json:"description,omitempty"` +} + +func (c *FirewallClient) UpdateRule(ctx context.Context, input *UpdateRuleInput) (*FirewallRule, error) { + path := fmt.Sprintf("/%s/fwrules/%s", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing UpdateRule request: {{err}}", err) + } + + var result *FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding UpdateRule response: {{err}}", err) + } + + return result, nil +} + +type EnableRuleInput struct { + ID string `json:"-"` +} + +func (c *FirewallClient) EnableRule(ctx context.Context, input *EnableRuleInput) (*FirewallRule, error) { + path := fmt.Sprintf("/%s/fwrules/%s/enable", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing EnableRule request: {{err}}", err) + } + + var result *FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding EnableRule response: {{err}}", err) + } + + return result, nil +} + +type DisableRuleInput struct { + ID string `json:"-"` +} + +func (c *FirewallClient) DisableRule(ctx context.Context, input *DisableRuleInput) (*FirewallRule, error) { + path := fmt.Sprintf("/%s/fwrules/%s/disable", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: input, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing DisableRule request: {{err}}", err) + } + + var result *FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding DisableRule response: {{err}}", err) + } + + return result, nil +} + +type DeleteRuleInput struct { + ID string +} + +func (c *FirewallClient) DeleteRule(ctx context.Context, input *DeleteRuleInput) error { + path := fmt.Sprintf("/%s/fwrules/%s", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing DeleteRule request: {{err}}", err) + } + + return nil +} + +type ListMachineRulesInput struct { + MachineID string +} + +func (c *FirewallClient) ListMachineRules(ctx context.Context, input *ListMachineRulesInput) ([]*FirewallRule, error) { + path := fmt.Sprintf("/%s/machines/%s/firewallrules", c.client.AccountName, input.MachineID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListMachineRules request: {{err}}", err) + } + + var result []*FirewallRule + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListRules response: {{err}}", err) + } + + return result, nil +} diff --git a/vendor/github.com/joyent/triton-go/networks.go b/vendor/github.com/joyent/triton-go/network/network.go similarity index 66% rename from vendor/github.com/joyent/triton-go/networks.go rename to vendor/github.com/joyent/triton-go/network/network.go index 585a65e7c..d853e0402 100644 --- a/vendor/github.com/joyent/triton-go/networks.go +++ b/vendor/github.com/joyent/triton-go/network/network.go @@ -1,24 +1,15 @@ -package triton +package network import ( + "context" "encoding/json" "fmt" "net/http" - "context" "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" ) -type NetworksClient struct { - *Client -} - -// Networks returns a c used for accessing functions pertaining to -// Network functionality in the Triton API. -func (c *Client) Networks() *NetworksClient { - return &NetworksClient{c} -} - type Network struct { Id string `json:"id"` Name string `json:"name"` @@ -34,11 +25,15 @@ type Network struct { InternetNAT bool `json:"internet_nat"` } -type ListNetworksInput struct{} +type ListInput struct{} -func (client *NetworksClient) ListNetworks(ctx context.Context, _ *ListNetworksInput) ([]*Network, error) { - path := fmt.Sprintf("/%s/networks", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) +func (c *NetworkClient) List(ctx context.Context, _ *ListInput) ([]*Network, error) { + path := fmt.Sprintf("/%s/networks", c.Client.AccountName) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.Client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } @@ -55,13 +50,17 @@ func (client *NetworksClient) ListNetworks(ctx context.Context, _ *ListNetworksI return result, nil } -type GetNetworkInput struct { +type GetInput struct { ID string } -func (client *NetworksClient) GetNetwork(ctx context.Context, input *GetNetworkInput) (*Network, error) { - path := fmt.Sprintf("/%s/networks/%s", client.accountName, input.ID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) +func (c *NetworkClient) Get(ctx context.Context, input *GetInput) (*Network, error) { + path := fmt.Sprintf("/%s/networks/%s", c.Client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.Client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } diff --git a/vendor/github.com/joyent/triton-go/roles.go b/vendor/github.com/joyent/triton-go/roles.go deleted file mode 100644 index a01fba6a9..000000000 --- a/vendor/github.com/joyent/triton-go/roles.go +++ /dev/null @@ -1,164 +0,0 @@ -package triton - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/hashicorp/errwrap" -) - -type RolesClient struct { - *Client -} - -// Roles returns a c used for accessing functions pertaining -// to Role functionality in the Triton API. -func (c *Client) Roles() *RolesClient { - return &RolesClient{c} -} - -type Role struct { - ID string `json:"id"` - Name string `json:"name"` - Policies []string `json:"policies"` - Members []string `json:"policies"` - DefaultMembers []string `json:"default_members"` -} - -type ListRolesInput struct{} - -func (client *RolesClient) ListRoles(ctx context.Context, _ *ListRolesInput) ([]*Role, error) { - path := fmt.Sprintf("/%s/roles", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing ListRoles request: {{err}}", err) - } - - var result []*Role - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListRoles response: {{err}}", err) - } - - return result, nil -} - -type GetRoleInput struct { - RoleID string -} - -func (client *RolesClient) GetRole(ctx context.Context, input *GetRoleInput) (*Role, error) { - path := fmt.Sprintf("/%s/roles/%s", client.accountName, input.RoleID) - respReader, err := client.executeRequest(ctx, http.MethodGet, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetRole request: {{err}}", err) - } - - var result *Role - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetRole response: {{err}}", err) - } - - return result, nil -} - -// CreateRoleInput represents the options that can be specified -// when creating a new role. -type CreateRoleInput struct { - // Name of the role. Required. - Name string `json:"name"` - - // This account's policies to be given to this role. Optional. - Policies []string `json:"policies,omitempty"` - - // This account's user logins to be added to this role. Optional. - Members []string `json:"members,omitempty"` - - // This account's user logins to be added to this role and have - // it enabled by default. Optional. - DefaultMembers []string `json:"default_members,omitempty"` -} - -func (client *RolesClient) CreateRole(ctx context.Context, input *CreateRoleInput) (*Role, error) { - path := fmt.Sprintf("/%s/roles", client.accountName) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing CreateRole request: {{err}}", err) - } - - var result *Role - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateRole response: {{err}}", err) - } - - return result, nil -} - -// UpdateRoleInput represents the options that can be specified -// when updating a role. Anything but ID can be modified. -type UpdateRoleInput struct { - // ID of the role to modify. Required. - RoleID string `json:"id"` - - // Name of the role. Required. - Name string `json:"name"` - - // This account's policies to be given to this role. Optional. - Policies []string `json:"policies,omitempty"` - - // This account's user logins to be added to this role. Optional. - Members []string `json:"members,omitempty"` - - // This account's user logins to be added to this role and have - // it enabled by default. Optional. - DefaultMembers []string `json:"default_members,omitempty"` -} - -func (client *RolesClient) UpdateRole(ctx context.Context, input *UpdateRoleInput) (*Role, error) { - path := fmt.Sprintf("/%s/roles/%s", client.accountName, input.RoleID) - respReader, err := client.executeRequest(ctx, http.MethodPost, path, input) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateRole request: {{err}}", err) - } - - var result *Role - decoder := json.NewDecoder(respReader) - if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateRole response: {{err}}", err) - } - - return result, nil -} - -type DeleteRoleInput struct { - RoleID string -} - -func (client *RolesClient) DeleteRoles(ctx context.Context, input *DeleteRoleInput) error { - path := fmt.Sprintf("/%s/roles/%s", client.accountName, input.RoleID) - respReader, err := client.executeRequest(ctx, http.MethodDelete, path, nil) - if respReader != nil { - defer respReader.Close() - } - if err != nil { - return errwrap.Wrapf("Error executing DeleteRole request: {{err}}", err) - } - - return nil -} diff --git a/vendor/github.com/joyent/triton-go/triton.go b/vendor/github.com/joyent/triton-go/triton.go new file mode 100644 index 000000000..b5bacd255 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/triton.go @@ -0,0 +1,18 @@ +package triton + +import ( + "github.com/joyent/triton-go/authentication" +) + +// Universal package used for defining configuration used across all client +// constructors. + +// ClientConfig is a placeholder/input struct around the behavior of configuring +// a client constructor through the implementation's runtime environment +// (SDC/MANTA env vars). +type ClientConfig struct { + TritonURL string + MantaURL string + AccountName string + Signers []authentication.Signer +} diff --git a/vendor/vendor.json b/vendor/vendor.json index f9b17b648..0a06ac4b1 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -817,16 +817,34 @@ "revision": "c01cf91b011868172fdcd9f41838e80c9d716264" }, { - "checksumSHA1": "o8jaSD36Zq42PMnmUaiB+vq+QNA=", + "checksumSHA1": "EqvUu0Ku0Ec5Tk6yhGNOuOr8yeA=", "path": "github.com/joyent/triton-go", - "revision": "97ccd9f6c0c0652cf87997bcb01955e0329cd37e", - "revisionTime": "2017-05-09T20:29:43Z" + "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", + "revisionTime": "2017-10-17T16:55:58Z" }, { - "checksumSHA1": "QzUqkCSn/ZHyIK346xb9V6EBw9U=", + "checksumSHA1": "JKf97EAAAZFQ6Wf8qN9X7TWqNBY=", "path": "github.com/joyent/triton-go/authentication", - "revision": "16cef4c2d78ba1d3bf89af75e93ae2dec6e56634", - "revisionTime": "2017-05-04T20:45:05Z" + "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", + "revisionTime": "2017-10-17T16:55:58Z" + }, + { + "checksumSHA1": "dlO1or0cyVMAmZzyLcBuoy+M0xU=", + "path": "github.com/joyent/triton-go/client", + "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", + "revisionTime": "2017-10-17T16:55:58Z" + }, + { + "checksumSHA1": "O/y7BfKJFUf3A8TCRMXgo9HSb1w=", + "path": "github.com/joyent/triton-go/compute", + "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", + "revisionTime": "2017-10-17T16:55:58Z" + }, + { + "checksumSHA1": "gyLtPyKlcumRSkrAH+SsDQo1GnY=", + "path": "github.com/joyent/triton-go/network", + "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", + "revisionTime": "2017-10-17T16:55:58Z" }, { "checksumSHA1": "gEjGS03N1eysvpQ+FCHTxPcbxXc=", From 5509d0734b103cab006af3472fc627d60a5c27c4 Mon Sep 17 00:00:00 2001 From: Lawrence <lawrence@lisimia.com> Date: Wed, 1 Nov 2017 14:43:08 -0400 Subject: [PATCH 0135/1007] Added ipv6 option for digitalocean builder the ipv6 option is already part of the godo package Updated documentation to reflect new feature Closes: https://github.com/hashicorp/packer/issues/5533 --- builder/digitalocean/config.go | 1 + builder/digitalocean/step_create_droplet.go | 1 + website/source/docs/builders/digitalocean.html.md | 3 +++ 3 files changed, 5 insertions(+) diff --git a/builder/digitalocean/config.go b/builder/digitalocean/config.go index 9d89910dc..6e58bc759 100644 --- a/builder/digitalocean/config.go +++ b/builder/digitalocean/config.go @@ -28,6 +28,7 @@ type Config struct { PrivateNetworking bool `mapstructure:"private_networking"` Monitoring bool `mapstructure:"monitoring"` + IPv6 bool `mapstructure:"ipv6"` SnapshotName string `mapstructure:"snapshot_name"` SnapshotRegions []string `mapstructure:"snapshot_regions"` StateTimeout time.Duration `mapstructure:"state_timeout"` diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index 9789e7b99..ed2c7390d 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -47,6 +47,7 @@ func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction { }, PrivateNetworking: c.PrivateNetworking, Monitoring: c.Monitoring, + IPv6: c.IPv6, UserData: userData, }) if err != nil { diff --git a/website/source/docs/builders/digitalocean.html.md b/website/source/docs/builders/digitalocean.html.md index 7af506319..595c1a62f 100644 --- a/website/source/docs/builders/digitalocean.html.md +++ b/website/source/docs/builders/digitalocean.html.md @@ -69,6 +69,9 @@ builder. - `monitoring` (boolean) - Set to `true` to enable monitoring for the droplet being created. This defaults to `false`, or not enabled. +- `ipv6` (boolean) - Set to `true` to enable ipv6 + for the droplet being created. This defaults to `false`, or not enabled. + - `snapshot_name` (string) - The name of the resulting snapshot that will appear in your account. This must be unique. To help make this unique, use a function like `timestamp` (see [configuration From 7810dd18cd12f0dd01c3d4c101dbb3579459d283 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 1 Nov 2017 16:18:58 -0700 Subject: [PATCH 0136/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a79ce2cac..6060dac45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] * builder/hyper-v: Also disable automatic checkpoints for gen 2 VMs. [GH-5517] * builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 additional disks. [GH-5491] +* builder/amazon: correctly deregister AMIs when `force_deregister` is set. [GH-5525] ## 1.1.1 (October 13, 2017) From 52558e4f759b0825cfa35d84ec9088040fc0a89d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 00:13:31 -0700 Subject: [PATCH 0137/1007] check for nil body from upload response --- post-processor/vagrant-cloud/step_prepare_upload.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/post-processor/vagrant-cloud/step_prepare_upload.go b/post-processor/vagrant-cloud/step_prepare_upload.go index 26d82471e..0723520b9 100644 --- a/post-processor/vagrant-cloud/step_prepare_upload.go +++ b/post-processor/vagrant-cloud/step_prepare_upload.go @@ -30,9 +30,13 @@ func (s *stepPrepareUpload) Run(state multistep.StateBag) multistep.StepAction { resp, err := client.Get(path) if err != nil || (resp.StatusCode != 200) { - cloudErrors := &VagrantCloudErrors{} - err = decodeBody(resp, cloudErrors) - state.Put("error", fmt.Errorf("Error preparing upload: %s", cloudErrors.FormatErrors())) + if resp == nil || resp.Body == nil { + state.Put("error", "No response from server.") + } else { + cloudErrors := &VagrantCloudErrors{} + err = decodeBody(resp, cloudErrors) + state.Put("error", fmt.Errorf("Error preparing upload: %s", cloudErrors.FormatErrors())) + } return multistep.ActionHalt } From f2413ff1385ada49c5ab3644f50a5624de5baea6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 00:25:54 -0700 Subject: [PATCH 0138/1007] add delay option to security group waiter --- builder/amazon/common/step_security_group.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/amazon/common/step_security_group.go b/builder/amazon/common/step_security_group.go index 5e47f44c2..8027903f5 100644 --- a/builder/amazon/common/step_security_group.go +++ b/builder/amazon/common/step_security_group.go @@ -158,6 +158,7 @@ func waitUntilSecurityGroupExists(c *ec2.EC2, input *ec2.DescribeSecurityGroupsI w := request.Waiter{ Name: "DescribeSecurityGroups", MaxAttempts: 40, + Delay: request.ConstantWaiterDelay(5 * time.Second), Acceptors: []request.WaiterAcceptor{ { State: request.SuccessWaiterState, From 7776bf596b2cf1c207c1ea45b85a103d34d8b88b Mon Sep 17 00:00:00 2001 From: stack72 <public@paulstack.co.uk> Date: Mon, 30 Oct 2017 19:26:42 +0200 Subject: [PATCH 0139/1007] builder/triton: Add a data source for source_machine_image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes: #5476 Based on this new template addition: ``` { "variables": { "image_version": "", "triton_account": "", "triton_key_id": "", "triton_key_material": "" }, "builders": [{ "type": "triton", "triton_account": "{{user `triton_account`}}", "triton_key_id": "{{user `triton_key_id`}}", "triton_key_material": "{{user `triton_key_material`}}", "source_machine_package": "g4-highcpu-128M", "source_machine_image_filter": { "name": "ubuntu-16.04", "most_recent": "true" }, "ssh_username": "root", "image_version": "{{user `image_version`}}", "image_name": "teamcity-server" }], "provisioners": [ { "type": "shell", "start_retry_timeout": "10m", "inline": [ "sudo apt-get update -y", "sudo apt-get install -y nginx" ] } ] } ``` I got the following output from packer: ``` packer-testing % make image packer build \ -var "triton_account=stack72_joyent" \ -var "triton_key_id=40:9d:d3:f9:0b:86:62:48:f4:2e:a5:8e:43:00:2a:9b" \ -var "triton_key_material=""" \ -var "image_version=1.0.0" \ new-template.json triton output will be in this color. ==> triton: Selecting an image based on search criteria ==> triton: Based, on given search criteria, Machine ID is: "7b5981c4-1889-11e7-b4c5-3f3bdfc9b88b" ==> triton: Waiting for source machine to become available... ==> triton: Waiting for SSH to become available... ==> triton: Connected to SSH! ==> triton: Provisioning with shell script: /var/folders/_p/2_zj9lqn4n11fx20qy787p7c0000gn/T/packer-shell797317310 triton: Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB] triton: Hit:2 http://archive.ubuntu.com/ubuntu xenial InRelease ``` I can verify from the triton cli tools that the id `7b5981c4` (from the packer output) is indeed the correct ID ``` terraform [master●] % triton images name=~ubuntu-16.04 SHORTID NAME VERSION FLAGS OS TYPE PUBDATE 49b22aec ubuntu-16.04 20160427 P linux lx-dataset 2016-04-27 675834a0 ubuntu-16.04 20160505 P linux lx-dataset 2016-05-05 4edaa46a ubuntu-16.04 20160516 P linux lx-dataset 2016-05-16 05140a7e ubuntu-16.04 20160601 P linux lx-dataset 2016-06-01 e331b22a ubuntu-16.04 20161004 P linux lx-dataset 2016-10-04 8879c758 ubuntu-16.04 20161213 P linux lx-dataset 2016-12-13 7b5981c4 ubuntu-16.04 20170403 P linux lx-dataset 2017-04-03 <------- THIS IS THE LATEST UBUNTU IMAGE ``` --- builder/triton/driver.go | 1 + builder/triton/driver_mock.go | 11 ++++ builder/triton/driver_triton.go | 58 ++++++++++++++++++++ builder/triton/source_machine_config.go | 34 +++++++++--- builder/triton/source_machine_config_test.go | 7 --- builder/triton/step_create_source_machine.go | 12 +++- website/source/docs/builders/triton.html.md | 22 +++++++- 7 files changed, 125 insertions(+), 20 deletions(-) diff --git a/builder/triton/driver.go b/builder/triton/driver.go index 2afa11d3c..5da1f687b 100644 --- a/builder/triton/driver.go +++ b/builder/triton/driver.go @@ -5,6 +5,7 @@ import ( ) type Driver interface { + GetImage(config Config) (string, error) CreateImageFromMachine(machineId string, config Config) (string, error) CreateMachine(config Config) (string, error) DeleteImage(imageId string) error diff --git a/builder/triton/driver_mock.go b/builder/triton/driver_mock.go index 831af8ada..f348c1d32 100644 --- a/builder/triton/driver_mock.go +++ b/builder/triton/driver_mock.go @@ -17,6 +17,9 @@ type DriverMock struct { DeleteMachineId string DeleteMachineErr error + GetImageId string + GetImageErr error + GetMachineErr error StopMachineId string @@ -29,6 +32,14 @@ type DriverMock struct { 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 diff --git a/builder/triton/driver_triton.go b/builder/triton/driver_triton.go index a6bc5c153..19e1e1902 100644 --- a/builder/triton/driver_triton.go +++ b/builder/triton/driver_triton.go @@ -6,6 +6,8 @@ import ( "net/http" "time" + "sort" + "github.com/hashicorp/packer/packer" "github.com/joyent/triton-go/client" "github.com/joyent/triton-go/compute" @@ -28,6 +30,36 @@ func NewDriverTriton(ui packer.Ui, config Config) (Driver, error) { }, 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{ @@ -193,3 +225,29 @@ func waitFor(f func() (bool, error), every, timeout time.Duration) error { 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() +} diff --git a/builder/triton/source_machine_config.go b/builder/triton/source_machine_config.go index 549a2a114..50c61da2d 100644 --- a/builder/triton/source_machine_config.go +++ b/builder/triton/source_machine_config.go @@ -9,13 +9,29 @@ import ( // SourceMachineConfig represents the configuration to run a machine using // the SDC API in order for provisioning to take place. type SourceMachineConfig struct { - MachineName string `mapstructure:"source_machine_name"` - MachinePackage string `mapstructure:"source_machine_package"` - MachineImage string `mapstructure:"source_machine_image"` - MachineNetworks []string `mapstructure:"source_machine_networks"` - MachineMetadata map[string]string `mapstructure:"source_machine_metadata"` - MachineTags map[string]string `mapstructure:"source_machine_tags"` - MachineFirewallEnabled bool `mapstructure:"source_machine_firewall_enabled"` + MachineName string `mapstructure:"source_machine_name"` + MachinePackage string `mapstructure:"source_machine_package"` + MachineImage string `mapstructure:"source_machine_image"` + MachineNetworks []string `mapstructure:"source_machine_networks"` + MachineMetadata map[string]string `mapstructure:"source_machine_metadata"` + MachineTags map[string]string `mapstructure:"source_machine_tags"` + MachineFirewallEnabled bool `mapstructure:"source_machine_firewall_enabled"` + MachineImageFilters MachineImageFilter `mapstructure:"source_machine_image_filter"` +} + +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. @@ -26,8 +42,8 @@ func (c *SourceMachineConfig) Prepare(ctx *interpolate.Context) []error { errs = append(errs, fmt.Errorf("A source_machine_package must be specified")) } - if c.MachineImage == "" { - errs = append(errs, fmt.Errorf("A source_machine_image 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 { diff --git a/builder/triton/source_machine_config_test.go b/builder/triton/source_machine_config_test.go index aeb1977a5..6a960d4fe 100644 --- a/builder/triton/source_machine_config_test.go +++ b/builder/triton/source_machine_config_test.go @@ -24,13 +24,6 @@ func TestSourceMachineConfig_Prepare(t *testing.T) { if errs == nil { t.Fatalf("should error: %#v", sc) } - - sc = testSourceMachineConfig(t) - sc.MachineImage = "" - errs = sc.Prepare(nil) - if errs == nil { - t.Fatalf("should error: %#v", sc) - } } func testSourceMachineConfig(t *testing.T) SourceMachineConfig { diff --git a/builder/triton/step_create_source_machine.go b/builder/triton/step_create_source_machine.go index 46b7d789c..ae51fc60e 100644 --- a/builder/triton/step_create_source_machine.go +++ b/builder/triton/step_create_source_machine.go @@ -17,7 +17,16 @@ func (s *StepCreateSourceMachine) Run(state multistep.StateBag) multistep.StepAc driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) - ui.Say("Creating source machine...") + 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 { @@ -33,7 +42,6 @@ func (s *StepCreateSourceMachine) Run(state multistep.StateBag) multistep.StepAc } state.Put("machine", machineId) - return multistep.ActionContinue } diff --git a/website/source/docs/builders/triton.html.md b/website/source/docs/builders/triton.html.md index f1f670eb8..80c54a5b4 100644 --- a/website/source/docs/builders/triton.html.md +++ b/website/source/docs/builders/triton.html.md @@ -64,7 +64,8 @@ builder. 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). + 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 @@ -133,6 +134,19 @@ builder. 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 joyent-brand image on the Joyent public @@ -149,7 +163,11 @@ cloud: "source_machine_name": "image-builder", "source_machine_package": "g4-highcpu-128M", - "source_machine_image": "f6acf198-2037-11e7-8863-8fdd4ce58b6a", + "source_machine_image_filter": { + "name": "ubuntu-16.04", + "type": "lx-dataset", + "most_recent": "true" + }, "ssh_username": "root", From 95e4ae251e196a6e6590f8c6a91a7739a1bbd1cd Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Oct 2017 12:16:12 -0700 Subject: [PATCH 0140/1007] WIP --- builder/amazon/common/step_stop_ebs_instance.go | 4 ++-- builder/amazon/ebs/builder.go | 13 +++++++------ builder/amazon/ebssurrogate/builder.go | 13 +++++++------ builder/amazon/ebsvolume/builder.go | 14 ++++++++------ 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index b3fb72ee6..852626811 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -11,7 +11,7 @@ import ( ) type StepStopEBSBackedInstance struct { - SpotPrice string + Skip bool DisableStopInstance bool } @@ -21,7 +21,7 @@ func (s *StepStopEBSBackedInstance) Run(state multistep.StateBag) multistep.Step ui := state.Get("ui").(packer.Ui) // Skip when it is a spot instance - if s.SpotPrice != "" && s.SpotPrice != "0" { + if s.Skip { return multistep.ActionContinue } diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index e28343c66..1cc346472 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -110,11 +110,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("ui", ui) var instanceStep multistep.Step + isSpotInstance := b.config.SpotPrice != "" && b.config.SpotPrice != "0" - if b.config.SpotPrice == "" || b.config.SpotPrice == "0" { - instanceStep = &awscommon.StepRunSourceInstance{ + if isSpotInstance { + instanceStep = &awscommon.StepRunSpotInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", + SpotPrice: b.config.SpotPrice, + SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -131,11 +134,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, } } else { - instanceStep = &awscommon.StepRunSpotInstance{ + instanceStep = &awscommon.StepRunSourceInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", - SpotPrice: b.config.SpotPrice, - SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -200,7 +201,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - SpotPrice: b.config.SpotPrice, + Skip: isSpotInstance, DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 71fdb2c9d..16e8367da 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -124,11 +124,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("ui", ui) var instanceStep multistep.Step + isSpotInstance := b.config.SpotPrice != "" && b.config.SpotPrice != "0" - if b.config.SpotPrice == "" || b.config.SpotPrice == "0" { - instanceStep = &awscommon.StepRunSourceInstance{ + if isSpotInstance { + instanceStep = &awscommon.StepRunSpotInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", + SpotPrice: b.config.SpotPrice, + SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -145,11 +148,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, } } else { - instanceStep = &awscommon.StepRunSpotInstance{ + instanceStep = &awscommon.StepRunSourceInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", - SpotPrice: b.config.SpotPrice, - SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -211,7 +212,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - SpotPrice: b.config.SpotPrice, + Skip: isSpotInstance, DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 375511082..ea3f74b61 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -103,10 +103,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe var instanceStep multistep.Step - if b.config.SpotPrice == "" || b.config.SpotPrice == "0" { - instanceStep = &awscommon.StepRunSourceInstance{ + isSpotInstance := b.config.SpotPrice != "" && b.config.SpotPrice != "0" + + if isSpotInstance { + instanceStep = &awscommon.StepRunSpotInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", + SpotPrice: b.config.SpotPrice, + SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -122,11 +126,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, } } else { - instanceStep = &awscommon.StepRunSpotInstance{ + instanceStep = &awscommon.StepRunSourceInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", - SpotPrice: b.config.SpotPrice, - SpotPriceProduct: b.config.SpotPriceAutoProduct, InstanceType: b.config.InstanceType, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, @@ -187,7 +189,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - SpotPrice: b.config.SpotPrice, + Skip: isSpotInstance, DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ From 872b8ceac3a37ba45ce1cb92ae5c69c1c01f73d8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 09:59:31 -0700 Subject: [PATCH 0141/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6060dac45..4d3643fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * builder/hyper-v: Also disable automatic checkpoints for gen 2 VMs. [GH-5517] * builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 additional disks. [GH-5491] * builder/amazon: correctly deregister AMIs when `force_deregister` is set. [GH-5525] +* builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] ## 1.1.1 (October 13, 2017) From 4d117bf117446845e403f0043fb30b72835cd605 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 10:45:54 -0700 Subject: [PATCH 0142/1007] Make vm log output less confusing --- builder/vmware/common/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index c06c8fd92..4e4f38e02 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -121,7 +121,7 @@ func NewDriver(dconfig *DriverConfig, config *SSHConfig) (Driver, error) { func runAndLog(cmd *exec.Cmd) (string, string, error) { var stdout, stderr bytes.Buffer - log.Printf("Executing: %s %v", cmd.Path, cmd.Args[1:]) + log.Printf("Executing: %s %s", cmd.Path, strings.Join(cmd.Args[1:], " ")) cmd.Stdout = &stdout cmd.Stderr = &stderr err := cmd.Run() From 4fc0a1ea0a0ec1aef32866e776c493a7388ac69e Mon Sep 17 00:00:00 2001 From: James Nugent <james@jen20.com> Date: Thu, 2 Nov 2017 10:45:31 -0700 Subject: [PATCH 0143/1007] build: Allow multi-platform dev with Vagrantfile This commit rewrites the Vagrantfile for Packer in a similar manner to the work done for Nomad (hashicorp/nomad#3175) in order to make cross-platform development easier. It also adds support for a FreeBSD base box. Provisioning scripts are separated out in order that they can be correctly linted. Each script is prefixed `vagrant`, then the operating system, then whether or not it expects to be run in a privileged shell. Finally, dependencies have been bumped - Go 1.6 is switched out for the latest (1.9.2). --- Vagrantfile | 121 +++++++++++++------- scripts/vagrant-freebsd-priv-config.sh | 35 ++++++ scripts/vagrant-freebsd-unpriv-bootstrap.sh | 8 ++ scripts/vagrant-linux-priv-config.sh | 19 +++ scripts/vagrant-linux-priv-go.sh | 42 +++++++ scripts/vagrant-linux-unpriv-bootstrap.sh | 3 + 6 files changed, 187 insertions(+), 41 deletions(-) create mode 100755 scripts/vagrant-freebsd-priv-config.sh create mode 100755 scripts/vagrant-freebsd-unpriv-bootstrap.sh create mode 100755 scripts/vagrant-linux-priv-config.sh create mode 100755 scripts/vagrant-linux-priv-go.sh create mode 100755 scripts/vagrant-linux-unpriv-bootstrap.sh diff --git a/Vagrantfile b/Vagrantfile index b61b3d209..30b0437ba 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,50 +1,89 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -$script = <<SCRIPT -# Fetch from https://golang.org/dl -TARBALL="https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz" - -UNTARPATH="/opt" -GOROOT="${UNTARPATH}/go" -GOPATH="${UNTARPATH}/gopath" - -# Install Go -if [ ! -d ${GOROOT} ]; then - sudo wget --progress=bar:force --output-document - ${TARBALL} |\ - tar xfz - -C ${UNTARPATH} -fi - -# Setup the GOPATH -sudo mkdir -p ${GOPATH} -cat <<EOF >/tmp/gopath.sh -export GOROOT="${GOROOT}" -export GOPATH="${GOPATH}" -export PATH="${GOROOT}/bin:${GOPATH}/bin:\$PATH" -EOF -sudo mv /tmp/gopath.sh /etc/profile.d/gopath.sh - -# Make sure the GOPATH is usable by vagrant -sudo chown -R vagrant:vagrant ${GOROOT} -sudo chown -R vagrant:vagrant ${GOPATH} - -# Install some other stuff we need -sudo apt-get update -sudo apt-get install -y curl make git mercurial bzr zip -SCRIPT +LINUX_BASE_BOX = "bento/ubuntu-16.04" +FREEBSD_BASE_BOX = "jen20/FreeBSD-12.0-CURRENT" Vagrant.configure(2) do |config| - config.vm.box = "bento/ubuntu-14.04" + # Compilation and development boxes + config.vm.define "linux", autostart: true, primary: true do |vmCfg| + vmCfg.vm.box = LINUX_BASE_BOX + vmCfg.vm.hostname = "linux" + vmCfg = configureProviders vmCfg, + cpus: suggestedCPUCores() - config.vm.provision "shell", inline: $script + vmCfg.vm.synced_folder ".", "/vagrant", disabled: true + vmCfg.vm.synced_folder '.', + '/opt/gopath/src/github.com/hashicorp/packer' - config.vm.synced_folder ".", "/vagrant", disabled: true + vmCfg.vm.provision "shell", + privileged: true, + inline: 'rm -f /home/vagrant/linux.iso' - ["vmware_fusion", "vmware_workstation"].each do |p| - config.vm.provider "p" do |v| - v.vmx["memsize"] = "2048" - v.vmx["numvcpus"] = "2" - v.vmx["cpuid.coresPerSocket"] = "1" - end - end + vmCfg.vm.provision "shell", + privileged: true, + path: './scripts/vagrant-linux-priv-go.sh' + + vmCfg.vm.provision "shell", + privileged: true, + path: './scripts/vagrant-linux-priv-config.sh' + + vmCfg.vm.provision "shell", + privileged: false, + path: './scripts/vagrant-linux-unpriv-bootstrap.sh' + end + + config.vm.define "freebsd", autostart: false, primary: false do |vmCfg| + vmCfg.vm.box = FREEBSD_BASE_BOX + vmCfg.vm.hostname = "freebsd" + vmCfg = configureProviders vmCfg, + cpus: suggestedCPUCores() + + vmCfg.vm.synced_folder ".", "/vagrant", disabled: true + vmCfg.vm.synced_folder '.', + '/opt/gopath/src/github.com/hashicorp/packer', + type: "nfs", + bsd__nfs_options: ['noatime'] + + vmCfg.vm.provision "shell", + privileged: true, + path: './scripts/vagrant-freebsd-priv-config.sh' + + vmCfg.vm.provision "shell", + privileged: false, + path: './scripts/vagrant-freebsd-unpriv-bootstrap.sh' + end +end + +def configureProviders(vmCfg, cpus: "2", memory: "2048") + vmCfg.vm.provider "virtualbox" do |v| + v.memory = memory + v.cpus = cpus + end + + ["vmware_fusion", "vmware_workstation"].each do |p| + vmCfg.vm.provider p do |v| + v.enable_vmrun_ip_lookup = false + v.vmx["memsize"] = memory + v.vmx["numvcpus"] = cpus + end + end + + vmCfg.vm.provider "virtualbox" do |v| + v.memory = memory + v.cpus = cpus + end + + return vmCfg +end + +def suggestedCPUCores() + case RbConfig::CONFIG['host_os'] + when /darwin/ + Integer(`sysctl -n hw.ncpu`) / 2 + when /linux/ + Integer(`cat /proc/cpuinfo | grep processor | wc -l`) / 2 + else + 2 + end end diff --git a/scripts/vagrant-freebsd-priv-config.sh b/scripts/vagrant-freebsd-priv-config.sh new file mode 100755 index 000000000..30a2e8185 --- /dev/null +++ b/scripts/vagrant-freebsd-priv-config.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +chown vagrant:wheel \ + /opt/gopath \ + /opt/gopath/src \ + /opt/gopath/src/github.com \ + /opt/gopath/src/github.com/hashicorp + +mkdir -p /usr/local/etc/pkg/repos + +cat <<EOT > /usr/local/etc/pkg/repos/FreeBSD.conf +FreeBSD: { + url: "pkg+http://pkg.FreeBSD.org/\${ABI}/latest" +} +EOT + +pkg update + +pkg install -y \ + editors/vim-lite \ + devel/git \ + devel/gmake \ + lang/go \ + security/ca_root_nss \ + shells/bash + +chsh -s /usr/local/bin/bash vagrant +chsh -s /usr/local/bin/bash root + +cat <<EOT >> /home/vagrant/.profile +export GOPATH=/opt/gopath +export PATH=\$GOPATH/bin:\$PATH + +cd /opt/gopath/src/github.com/hashicorp/packer +EOT diff --git a/scripts/vagrant-freebsd-unpriv-bootstrap.sh b/scripts/vagrant-freebsd-unpriv-bootstrap.sh new file mode 100755 index 000000000..26d40b91e --- /dev/null +++ b/scripts/vagrant-freebsd-unpriv-bootstrap.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +export GOPATH=/opt/gopath + +PATH=$GOPATH/bin:$PATH +export PATH + +cd /opt/gopath/src/github.com/hashicorp/packer && gmake deps diff --git a/scripts/vagrant-linux-priv-config.sh b/scripts/vagrant-linux-priv-config.sh new file mode 100755 index 000000000..d31d330c8 --- /dev/null +++ b/scripts/vagrant-linux-priv-config.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +export DEBIAN_FRONTEND=noninteractive + +# Update and ensure we have apt-add-repository +apt-get update +apt-get install -y software-properties-common + +apt-get install -y bzr \ + curl \ + git \ + make \ + mercurial \ + zip + +# Ensure we cd into the working directory on login +if ! grep "cd /opt/gopath/src/github.com/hashicorp/packer" /home/vagrant/.profile ; then + echo 'cd /opt/gopath/src/github.com/hashicorp/packer' >> /home/vagrant/.profile +fi diff --git a/scripts/vagrant-linux-priv-go.sh b/scripts/vagrant-linux-priv-go.sh new file mode 100755 index 000000000..263eba370 --- /dev/null +++ b/scripts/vagrant-linux-priv-go.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +function install_go() { + local go_version=1.9.2 + local download= + + download="https://storage.googleapis.com/golang/go${go_version}.linux-amd64.tar.gz" + + if [ -d /usr/local/go ] ; then + return + fi + + wget -q -O /tmp/go.tar.gz ${download} + + tar -C /tmp -xf /tmp/go.tar.gz + sudo mv /tmp/go /usr/local + sudo chown -R root:root /usr/local/go +} + +install_go + +# Ensure that the GOPATH tree is owned by vagrant:vagrant +mkdir -p /opt/gopath +chown -R vagrant:vagrant /opt/gopath + +# Ensure Go is on PATH +if [ ! -e /usr/bin/go ] ; then + ln -s /usr/local/go/bin/go /usr/bin/go +fi +if [ ! -e /usr/bin/gofmt ] ; then + ln -s /usr/local/go/bin/gofmt /usr/bin/gofmt +fi + + +# Ensure new sessions know about GOPATH +if [ ! -f /etc/profile.d/gopath.sh ] ; then + cat <<EOT > /etc/profile.d/gopath.sh +export GOPATH="/opt/gopath" +export PATH="/opt/gopath/bin:\$PATH" +EOT + chmod 755 /etc/profile.d/gopath.sh +fi diff --git a/scripts/vagrant-linux-unpriv-bootstrap.sh b/scripts/vagrant-linux-unpriv-bootstrap.sh new file mode 100755 index 000000000..ff8783e97 --- /dev/null +++ b/scripts/vagrant-linux-unpriv-bootstrap.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +cd /opt/gopath/src/github.com/hashicorp/packer && make deps From 0956ba53c9164dd066d35741764722995c2fa57d Mon Sep 17 00:00:00 2001 From: James Nugent <james@jen20.com> Date: Thu, 2 Nov 2017 13:35:09 -0700 Subject: [PATCH 0144/1007] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d3643fb7..a7af71024 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 additional disks. [GH-5491] * builder/amazon: correctly deregister AMIs when `force_deregister` is set. [GH-5525] * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] +* builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] ## 1.1.1 (October 13, 2017) From d8900519400dba65ac50a164c3ba4fbaec45c633 Mon Sep 17 00:00:00 2001 From: Erlend Graff <erlend.graff@gmail.com> Date: Sun, 5 Nov 2017 14:51:18 +0100 Subject: [PATCH 0145/1007] hyper-v: implement driver mock --- builder/hyperv/common/driver_mock.go | 534 +++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) create mode 100644 builder/hyperv/common/driver_mock.go diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go new file mode 100644 index 000000000..433dfb814 --- /dev/null +++ b/builder/hyperv/common/driver_mock.go @@ -0,0 +1,534 @@ +package common + +type DriverMock struct { + IsRunning_Called bool + IsRunning_VmName string + IsRunning_Return bool + IsRunning_Err error + + IsOff_Called bool + IsOff_VmName string + IsOff_Return bool + IsOff_Err error + + Uptime_Called bool + Uptime_VmName string + Uptime_Return uint64 + Uptime_Err error + + Start_Called bool + Start_VmName string + Start_Err error + + Stop_Called bool + Stop_VmName string + Stop_Err error + + Verify_Called bool + Verify_Err error + + Mac_Called bool + Mac_VmName string + Mac_Return string + Mac_Err error + + IpAddress_Called bool + IpAddress_Mac string + IpAddress_Return string + IpAddress_Err error + + GetHostName_Called bool + GetHostName_Ip string + GetHostName_Return string + GetHostName_Err error + + GetVirtualMachineGeneration_Called bool + GetVirtualMachineGeneration_VmName string + GetVirtualMachineGeneration_Return uint + GetVirtualMachineGeneration_Err error + + GetHostAdapterIpAddressForSwitch_Called bool + GetHostAdapterIpAddressForSwitch_SwitchName string + GetHostAdapterIpAddressForSwitch_Return string + GetHostAdapterIpAddressForSwitch_Err error + + TypeScanCodes_Called bool + TypeScanCodes_VmName string + TypeScanCodes_ScanCodes string + TypeScanCodes_Err error + + GetVirtualMachineNetworkAdapterAddress_Called bool + GetVirtualMachineNetworkAdapterAddress_VmName string + GetVirtualMachineNetworkAdapterAddress_Return string + GetVirtualMachineNetworkAdapterAddress_Err error + + SetNetworkAdapterVlanId_Called bool + SetNetworkAdapterVlanId_SwitchName string + SetNetworkAdapterVlanId_VlanId string + SetNetworkAdapterVlanId_Err error + + SetVirtualMachineVlanId_Called bool + SetVirtualMachineVlanId_VmName string + SetVirtualMachineVlanId_VlanId string + SetVirtualMachineVlanId_Err error + + UntagVirtualMachineNetworkAdapterVlan_Called bool + UntagVirtualMachineNetworkAdapterVlan_VmName string + UntagVirtualMachineNetworkAdapterVlan_SwitchName string + UntagVirtualMachineNetworkAdapterVlan_Err error + + CreateExternalVirtualSwitch_Called bool + CreateExternalVirtualSwitch_VmName string + CreateExternalVirtualSwitch_SwitchName string + CreateExternalVirtualSwitch_Err error + + GetVirtualMachineSwitchName_Called bool + GetVirtualMachineSwitchName_VmName string + GetVirtualMachineSwitchName_Return string + GetVirtualMachineSwitchName_Err error + + ConnectVirtualMachineNetworkAdapterToSwitch_Called bool + ConnectVirtualMachineNetworkAdapterToSwitch_VmName string + ConnectVirtualMachineNetworkAdapterToSwitch_SwitchName string + ConnectVirtualMachineNetworkAdapterToSwitch_Err error + + DeleteVirtualSwitch_Called bool + DeleteVirtualSwitch_SwitchName string + DeleteVirtualSwitch_Err error + + CreateVirtualSwitch_Called bool + CreateVirtualSwitch_SwitchName string + CreateVirtualSwitch_SwitchType string + CreateVirtualSwitch_Return bool + CreateVirtualSwitch_Err error + + AddVirtualMachineHardDrive_Called bool + AddVirtualMachineHardDrive_VmName string + AddVirtualMachineHardDrive_VhdFile string + AddVirtualMachineHardDrive_VhdName string + AddVirtualMachineHardDrive_VhdSizeBytes int64 + AddVirtualMachineHardDrive_ControllerType string + AddVirtualMachineHardDrive_Err error + + CreateVirtualMachine_Called bool + CreateVirtualMachine_VmName string + CreateVirtualMachine_Path string + CreateVirtualMachine_HarddrivePath string + CreateVirtualMachine_VhdPath string + CreateVirtualMachine_Ram int64 + CreateVirtualMachine_DiskSize int64 + CreateVirtualMachine_SwitchName string + CreateVirtualMachine_Generation uint + CreateVirtualMachine_Err error + + CloneVirtualMachine_Called bool + CloneVirtualMachine_CloneFromVmxcPath string + CloneVirtualMachine_CloneFromVmName string + CloneVirtualMachine_CloneFromSnapshotName string + CloneVirtualMachine_CloneAllSnapshots bool + CloneVirtualMachine_VmName string + CloneVirtualMachine_Path string + CloneVirtualMachine_HarddrivePath string + CloneVirtualMachine_Ram int64 + CloneVirtualMachine_SwitchName string + CloneVirtualMachine_Err error + + DeleteVirtualMachine_Called bool + DeleteVirtualMachine_VmName string + DeleteVirtualMachine_Err error + + SetVirtualMachineCpuCount_Called bool + SetVirtualMachineCpuCount_VmName string + SetVirtualMachineCpuCount_Cpu uint + SetVirtualMachineCpuCount_Err error + + SetVirtualMachineMacSpoofing_Called bool + SetVirtualMachineMacSpoofing_VmName string + SetVirtualMachineMacSpoofing_Enable bool + SetVirtualMachineMacSpoofing_Err error + + SetVirtualMachineDynamicMemory_Called bool + SetVirtualMachineDynamicMemory_VmName string + SetVirtualMachineDynamicMemory_Enable bool + SetVirtualMachineDynamicMemory_Err error + + SetVirtualMachineSecureBoot_Called bool + SetVirtualMachineSecureBoot_VmName string + SetVirtualMachineSecureBoot_Enable bool + SetVirtualMachineSecureBoot_Err error + + SetVirtualMachineVirtualizationExtensions_Called bool + SetVirtualMachineVirtualizationExtensions_VmName string + SetVirtualMachineVirtualizationExtensions_Enable bool + SetVirtualMachineVirtualizationExtensions_Err error + + EnableVirtualMachineIntegrationService_Called bool + EnableVirtualMachineIntegrationService_VmName string + EnableVirtualMachineIntegrationService_IntegrationServiceName string + EnableVirtualMachineIntegrationService_Err error + + ExportVirtualMachine_Called bool + ExportVirtualMachine_VmName string + ExportVirtualMachine_Path string + ExportVirtualMachine_Err error + + CompactDisks_Called bool + CompactDisks_ExpPath string + CompactDisks_VhdDir string + CompactDisks_Err error + + CopyExportedVirtualMachine_Called bool + CopyExportedVirtualMachine_ExpPath string + CopyExportedVirtualMachine_OutputPath string + CopyExportedVirtualMachine_VhdDir string + CopyExportedVirtualMachine_VmDir string + CopyExportedVirtualMachine_Err error + + RestartVirtualMachine_Called bool + RestartVirtualMachine_VmName string + RestartVirtualMachine_Err error + + CreateDvdDrive_Called bool + CreateDvdDrive_VmName string + CreateDvdDrive_IsoPath string + CreateDvdDrive_Generation uint + CreateDvdDrive_ControllerNumber uint + CreateDvdDrive_ControllerLocation uint + CreateDvdDrive_Err error + + MountDvdDrive_Called bool + MountDvdDrive_VmName string + MountDvdDrive_Path string + MountDvdDrive_ControllerNumber uint + MountDvdDrive_ControllerLocation uint + MountDvdDrive_Err error + + SetBootDvdDrive_Called bool + SetBootDvdDrive_VmName string + SetBootDvdDrive_ControllerNumber uint + SetBootDvdDrive_ControllerLocation uint + SetBootDvdDrive_Generation uint + SetBootDvdDrive_Err error + + UnmountDvdDrive_Called bool + UnmountDvdDrive_VmName string + UnmountDvdDrive_ControllerNumber uint + UnmountDvdDrive_ControllerLocation uint + UnmountDvdDrive_Err error + + DeleteDvdDrive_Called bool + DeleteDvdDrive_VmName string + DeleteDvdDrive_ControllerNumber uint + DeleteDvdDrive_ControllerLocation uint + DeleteDvdDrive_Err error + + MountFloppyDrive_Called bool + MountFloppyDrive_VmName string + MountFloppyDrive_Path string + MountFloppyDrive_Err error + + UnmountFloppyDrive_Called bool + UnmountFloppyDrive_VmName string + UnmountFloppyDrive_Err error +} + +func (d *DriverMock) IsRunning(vmName string) (bool, error) { + d.IsRunning_Called = true + d.IsRunning_VmName = vmName + return d.IsRunning_Return, d.IsRunning_Err +} + +func (d *DriverMock) IsOff(vmName string) (bool, error) { + d.IsOff_Called = true + d.IsOff_VmName = vmName + return d.IsOff_Return, d.IsOff_Err +} + +func (d *DriverMock) Uptime(vmName string) (uint64, error) { + d.Uptime_Called = true + d.Uptime_VmName = vmName + return d.Uptime_Return, d.Uptime_Err +} + +func (d *DriverMock) Start(vmName string) error { + d.Start_Called = true + d.Start_VmName = vmName + return d.Start_Err +} + +func (d *DriverMock) Stop(vmName string) error { + d.Stop_Called = true + d.Stop_VmName = vmName + return d.Stop_Err +} + +func (d *DriverMock) Verify() error { + d.Verify_Called = true + return d.Verify_Err +} + +func (d *DriverMock) Mac(vmName string) (string, error) { + d.Mac_Called = true + d.Mac_VmName = vmName + return d.Mac_Return, d.Mac_Err +} + +func (d *DriverMock) IpAddress(mac string) (string, error) { + d.IpAddress_Called = true + d.IpAddress_Mac = mac + return d.IpAddress_Return, d.IpAddress_Err +} + +func (d *DriverMock) GetHostName(ip string) (string, error) { + d.GetHostName_Called = true + d.GetHostName_Ip = ip + return d.GetHostName_Return, d.GetHostName_Err +} + +func (d *DriverMock) GetVirtualMachineGeneration(vmName string) (uint, error) { + d.GetVirtualMachineGeneration_Called = true + d.GetVirtualMachineGeneration_VmName = vmName + return d.GetVirtualMachineGeneration_Return, d.GetVirtualMachineGeneration_Err +} + +func (d *DriverMock) GetHostAdapterIpAddressForSwitch(switchName string) (string, error) { + d.GetHostAdapterIpAddressForSwitch_Called = true + d.GetHostAdapterIpAddressForSwitch_SwitchName = switchName + return d.GetHostAdapterIpAddressForSwitch_Return, d.GetHostAdapterIpAddressForSwitch_Err +} + +func (d *DriverMock) TypeScanCodes(vmName string, scanCodes string) error { + d.TypeScanCodes_Called = true + d.TypeScanCodes_VmName = vmName + d.TypeScanCodes_ScanCodes = scanCodes + return d.TypeScanCodes_Err +} + +func (d *DriverMock) GetVirtualMachineNetworkAdapterAddress(vmName string) (string, error) { + d.GetVirtualMachineNetworkAdapterAddress_Called = true + d.GetVirtualMachineNetworkAdapterAddress_VmName = vmName + return d.GetVirtualMachineNetworkAdapterAddress_Return, d.GetVirtualMachineNetworkAdapterAddress_Err +} + +func (d *DriverMock) SetNetworkAdapterVlanId(switchName string, vlanId string) error { + d.SetNetworkAdapterVlanId_Called = true + d.SetNetworkAdapterVlanId_SwitchName = switchName + d.SetNetworkAdapterVlanId_VlanId = vlanId + return d.SetNetworkAdapterVlanId_Err +} + +func (d *DriverMock) SetVirtualMachineVlanId(vmName string, vlanId string) error { + d.SetVirtualMachineVlanId_Called = true + d.SetVirtualMachineVlanId_VmName = vmName + d.SetVirtualMachineVlanId_VlanId = vlanId + return d.SetVirtualMachineVlanId_Err +} + +func (d *DriverMock) UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error { + d.UntagVirtualMachineNetworkAdapterVlan_Called = true + d.UntagVirtualMachineNetworkAdapterVlan_VmName = vmName + d.UntagVirtualMachineNetworkAdapterVlan_SwitchName = switchName + return d.UntagVirtualMachineNetworkAdapterVlan_Err +} + +func (d *DriverMock) CreateExternalVirtualSwitch(vmName string, switchName string) error { + d.CreateExternalVirtualSwitch_Called = true + d.CreateExternalVirtualSwitch_VmName = vmName + d.CreateExternalVirtualSwitch_SwitchName = switchName + return d.CreateExternalVirtualSwitch_Err +} + +func (d *DriverMock) GetVirtualMachineSwitchName(vmName string) (string, error) { + d.GetVirtualMachineSwitchName_Called = true + d.GetVirtualMachineSwitchName_VmName = vmName + return d.GetVirtualMachineSwitchName_Return, d.GetVirtualMachineSwitchName_Err +} + +func (d *DriverMock) ConnectVirtualMachineNetworkAdapterToSwitch(vmName string, switchName string) error { + d.ConnectVirtualMachineNetworkAdapterToSwitch_Called = true + d.ConnectVirtualMachineNetworkAdapterToSwitch_VmName = vmName + d.ConnectVirtualMachineNetworkAdapterToSwitch_SwitchName = switchName + return d.ConnectVirtualMachineNetworkAdapterToSwitch_Err +} + +func (d *DriverMock) DeleteVirtualSwitch(switchName string) error { + d.DeleteVirtualSwitch_Called = true + d.DeleteVirtualSwitch_SwitchName = switchName + return d.DeleteVirtualSwitch_Err +} + +func (d *DriverMock) CreateVirtualSwitch(switchName string, switchType string) (bool, error) { + d.CreateVirtualSwitch_Called = true + d.CreateVirtualSwitch_SwitchName = switchName + d.CreateVirtualSwitch_SwitchType = switchType + return d.CreateVirtualSwitch_Return, d.CreateVirtualSwitch_Err +} + +func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, controllerType string) error { + d.AddVirtualMachineHardDrive_Called = true + d.AddVirtualMachineHardDrive_VmName = vmName + d.AddVirtualMachineHardDrive_VhdFile = vhdFile + d.AddVirtualMachineHardDrive_VhdName = vhdName + d.AddVirtualMachineHardDrive_VhdSizeBytes = vhdSizeBytes + d.AddVirtualMachineHardDrive_ControllerType = controllerType + return d.AddVirtualMachineHardDrive_Err +} + +func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { + d.CreateVirtualMachine_Called = true + d.CreateVirtualMachine_VmName = vmName + d.CreateVirtualMachine_Path = path + d.CreateVirtualMachine_HarddrivePath = harddrivePath + d.CreateVirtualMachine_VhdPath = vhdPath + d.CreateVirtualMachine_Ram = ram + d.CreateVirtualMachine_DiskSize = diskSize + d.CreateVirtualMachine_SwitchName = switchName + d.CreateVirtualMachine_Generation = generation + return d.CreateVirtualMachine_Err +} + +func (d *DriverMock) CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error { + d.CloneVirtualMachine_Called = true + d.CloneVirtualMachine_CloneFromVmxcPath = cloneFromVmxcPath + d.CloneVirtualMachine_CloneFromVmName = cloneFromVmName + d.CloneVirtualMachine_CloneFromSnapshotName = cloneFromSnapshotName + d.CloneVirtualMachine_CloneAllSnapshots = cloneAllSnapshots + d.CloneVirtualMachine_VmName = vmName + d.CloneVirtualMachine_Path = path + d.CloneVirtualMachine_HarddrivePath = harddrivePath + d.CloneVirtualMachine_Ram = ram + d.CloneVirtualMachine_SwitchName = switchName + return d.CloneVirtualMachine_Err +} + +func (d *DriverMock) DeleteVirtualMachine(vmName string) error { + d.DeleteVirtualMachine_Called = true + d.DeleteVirtualMachine_VmName = vmName + return d.DeleteVirtualMachine_Err +} + +func (d *DriverMock) SetVirtualMachineCpuCount(vmName string, cpu uint) error { + d.SetVirtualMachineCpuCount_Called = true + d.SetVirtualMachineCpuCount_VmName = vmName + d.SetVirtualMachineCpuCount_Cpu = cpu + return d.SetVirtualMachineCpuCount_Err +} + +func (d *DriverMock) SetVirtualMachineMacSpoofing(vmName string, enable bool) error { + d.SetVirtualMachineMacSpoofing_Called = true + d.SetVirtualMachineMacSpoofing_VmName = vmName + d.SetVirtualMachineMacSpoofing_Enable = enable + return d.SetVirtualMachineMacSpoofing_Err +} + +func (d *DriverMock) SetVirtualMachineDynamicMemory(vmName string, enable bool) error { + d.SetVirtualMachineDynamicMemory_Called = true + d.SetVirtualMachineDynamicMemory_VmName = vmName + d.SetVirtualMachineDynamicMemory_Enable = enable + return d.SetVirtualMachineDynamicMemory_Err +} + +func (d *DriverMock) SetVirtualMachineSecureBoot(vmName string, enable bool) error { + d.SetVirtualMachineSecureBoot_Called = true + d.SetVirtualMachineSecureBoot_VmName = vmName + d.SetVirtualMachineSecureBoot_Enable = enable + return d.SetVirtualMachineSecureBoot_Err +} + +func (d *DriverMock) SetVirtualMachineVirtualizationExtensions(vmName string, enable bool) error { + d.SetVirtualMachineVirtualizationExtensions_Called = true + d.SetVirtualMachineVirtualizationExtensions_VmName = vmName + d.SetVirtualMachineVirtualizationExtensions_Enable = enable + return d.SetVirtualMachineVirtualizationExtensions_Err +} + +func (d *DriverMock) EnableVirtualMachineIntegrationService(vmName string, integrationServiceName string) error { + d.EnableVirtualMachineIntegrationService_Called = true + d.EnableVirtualMachineIntegrationService_VmName = vmName + d.EnableVirtualMachineIntegrationService_IntegrationServiceName = integrationServiceName + return d.EnableVirtualMachineIntegrationService_Err +} + +func (d *DriverMock) ExportVirtualMachine(vmName string, path string) error { + d.ExportVirtualMachine_Called = true + d.ExportVirtualMachine_VmName = vmName + d.ExportVirtualMachine_Path = path + return d.ExportVirtualMachine_Err +} + +func (d *DriverMock) CompactDisks(expPath string, vhdDir string) error { + d.CompactDisks_Called = true + d.CompactDisks_ExpPath = expPath + d.CompactDisks_VhdDir = vhdDir + return d.CompactDisks_Err +} + +func (d *DriverMock) CopyExportedVirtualMachine(expPath string, outputPath string, vhdDir string, vmDir string) error { + d.CopyExportedVirtualMachine_Called = true + d.CopyExportedVirtualMachine_ExpPath = expPath + d.CopyExportedVirtualMachine_OutputPath = outputPath + d.CopyExportedVirtualMachine_VhdDir = vhdDir + d.CopyExportedVirtualMachine_VmDir = vmDir + return d.CopyExportedVirtualMachine_Err +} + +func (d *DriverMock) RestartVirtualMachine(vmName string) error { + d.RestartVirtualMachine_Called = true + d.RestartVirtualMachine_VmName = vmName + return d.RestartVirtualMachine_Err +} + +func (d *DriverMock) CreateDvdDrive(vmName string, isoPath string, generation uint) (uint, uint, error) { + d.CreateDvdDrive_Called = true + d.CreateDvdDrive_VmName = vmName + d.CreateDvdDrive_IsoPath = isoPath + d.CreateDvdDrive_Generation = generation + return d.CreateDvdDrive_ControllerNumber, d.CreateDvdDrive_ControllerLocation, d.CreateDvdDrive_Err +} + +func (d *DriverMock) MountDvdDrive(vmName string, path string, controllerNumber uint, controllerLocation uint) error { + d.MountDvdDrive_Called = true + d.MountDvdDrive_VmName = vmName + d.MountDvdDrive_Path = path + d.MountDvdDrive_ControllerNumber = controllerNumber + d.MountDvdDrive_ControllerLocation = controllerLocation + return d.MountDvdDrive_Err +} + +func (d *DriverMock) SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation uint, generation uint) error { + d.SetBootDvdDrive_Called = true + d.SetBootDvdDrive_VmName = vmName + d.SetBootDvdDrive_ControllerNumber = controllerNumber + d.SetBootDvdDrive_ControllerLocation = controllerLocation + d.SetBootDvdDrive_Generation = generation + return d.SetBootDvdDrive_Err +} + +func (d *DriverMock) UnmountDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error { + d.UnmountDvdDrive_Called = true + d.UnmountDvdDrive_VmName = vmName + d.UnmountDvdDrive_ControllerNumber = controllerNumber + d.UnmountDvdDrive_ControllerLocation = controllerLocation + return d.UnmountDvdDrive_Err +} + +func (d *DriverMock) DeleteDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error { + d.DeleteDvdDrive_Called = true + d.DeleteDvdDrive_VmName = vmName + d.DeleteDvdDrive_ControllerNumber = controllerNumber + d.DeleteDvdDrive_ControllerLocation = controllerLocation + return d.DeleteDvdDrive_Err +} + +func (d *DriverMock) MountFloppyDrive(vmName string, path string) error { + d.MountFloppyDrive_Called = true + d.MountFloppyDrive_VmName = vmName + d.MountFloppyDrive_Path = path + return d.MountFloppyDrive_Err +} + +func (d *DriverMock) UnmountFloppyDrive(vmName string) error { + d.UnmountFloppyDrive_Called = true + d.UnmountFloppyDrive_VmName = vmName + return d.UnmountFloppyDrive_Err +} From eeeee3ec351a20b6a48cce10e8d1e950ae274af9 Mon Sep 17 00:00:00 2001 From: Erlend Graff <erlend.graff@gmail.com> Date: Sun, 5 Nov 2017 14:55:56 +0100 Subject: [PATCH 0146/1007] hyper-v/vmcx: add missing InterpolateContext --- builder/hyperv/vmcx/builder.go | 1 + builder/hyperv/vmcx/builder_test.go | 54 ++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index a9583327a..6ba93caac 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -98,6 +98,7 @@ type Config struct { func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { err := config.Decode(&b.config, &config.DecodeOpts{ Interpolate: true, + InterpolateContext: &b.config.ctx, InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "boot_command", diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 209094bf3..8c0be09a4 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -1,11 +1,13 @@ package vmcx import ( + "fmt" "reflect" "testing" - "fmt" + hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" "io/ioutil" "os" ) @@ -486,3 +488,53 @@ func TestBuilderPrepare_CommConfig(t *testing.T) { } } } + +func TestUserVariablesInBootCommand(t *testing.T) { + var b Builder + config := testConfig() + + //Create vmxc folder + td, err := ioutil.TempDir("", "packer") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.RemoveAll(td) + config["clone_from_vmxc_path"] = td + + config[packer.UserVariablesConfigKey] = map[string]string{"test-variable": "test"} + config["boot_command"] = []string{"blah {{user `test-variable`}} blah"} + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + ui := packer.TestUi(t) + cache := &packer.FileCache{CacheDir: os.TempDir()} + hook := &packer.MockHook{} + driver := &hypervcommon.DriverMock{} + + // Set up the state. + state := new(multistep.BasicStateBag) + state.Put("cache", cache) + state.Put("config", &b.config) + state.Put("driver", driver) + state.Put("hook", hook) + state.Put("http_port", uint(0)) + state.Put("ui", ui) + state.Put("vmName", "packer-foo") + + step := &hypervcommon.StepTypeBootCommand{ + BootCommand: b.config.BootCommand, + SwitchName: b.config.SwitchName, + Ctx: b.config.ctx, + } + + ret := step.Run(state) + if ret != multistep.ActionContinue { + t.Fatalf("should not have error: %s", ret) + } +} From ae6987c74b7282436da63f596788b368cef12cd4 Mon Sep 17 00:00:00 2001 From: Erlend Graff <erlend.graff@gmail.com> Date: Sun, 5 Nov 2017 14:58:08 +0100 Subject: [PATCH 0147/1007] hyper-v: add test for hashicorp/packer#5184 --- builder/hyperv/iso/builder_test.go | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 73ae5591b..546ffae6d 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -6,7 +6,10 @@ import ( "strconv" "testing" + hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "os" ) func testConfig() map[string]interface{} { @@ -472,3 +475,45 @@ func TestBuilderPrepare_CommConfig(t *testing.T) { } } + +func TestUserVariablesInBootCommand(t *testing.T) { + var b Builder + config := testConfig() + + config[packer.UserVariablesConfigKey] = map[string]string{"test-variable": "test"} + config["boot_command"] = []string{"blah {{user `test-variable`}} blah"} + + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + ui := packer.TestUi(t) + cache := &packer.FileCache{CacheDir: os.TempDir()} + hook := &packer.MockHook{} + driver := &hypervcommon.DriverMock{} + + // Set up the state. + state := new(multistep.BasicStateBag) + state.Put("cache", cache) + state.Put("config", &b.config) + state.Put("driver", driver) + state.Put("hook", hook) + state.Put("http_port", uint(0)) + state.Put("ui", ui) + state.Put("vmName", "packer-foo") + + step := &hypervcommon.StepTypeBootCommand{ + BootCommand: b.config.BootCommand, + SwitchName: b.config.SwitchName, + Ctx: b.config.ctx, + } + + ret := step.Run(state) + if ret != multistep.ActionContinue { + t.Fatalf("should not have error: %s", ret) + } +} From 27fc72c137d0728bba8cab4eca54142824bc06c8 Mon Sep 17 00:00:00 2001 From: Erlend Graff <erlend.graff@gmail.com> Date: Sun, 5 Nov 2017 15:16:47 +0100 Subject: [PATCH 0148/1007] fix formatting errors --- builder/hyperv/common/driver_mock.go | 22 +++++++++++----------- builder/hyperv/iso/builder_test.go | 2 +- builder/hyperv/vmcx/builder.go | 2 +- builder/hyperv/vmcx/builder_test.go | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 433dfb814..dcdd857a5 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -121,17 +121,17 @@ type DriverMock struct { CreateVirtualMachine_Generation uint CreateVirtualMachine_Err error - CloneVirtualMachine_Called bool - CloneVirtualMachine_CloneFromVmxcPath string - CloneVirtualMachine_CloneFromVmName string - CloneVirtualMachine_CloneFromSnapshotName string - CloneVirtualMachine_CloneAllSnapshots bool - CloneVirtualMachine_VmName string - CloneVirtualMachine_Path string - CloneVirtualMachine_HarddrivePath string - CloneVirtualMachine_Ram int64 - CloneVirtualMachine_SwitchName string - CloneVirtualMachine_Err error + CloneVirtualMachine_Called bool + CloneVirtualMachine_CloneFromVmxcPath string + CloneVirtualMachine_CloneFromVmName string + CloneVirtualMachine_CloneFromSnapshotName string + CloneVirtualMachine_CloneAllSnapshots bool + CloneVirtualMachine_VmName string + CloneVirtualMachine_Path string + CloneVirtualMachine_HarddrivePath string + CloneVirtualMachine_Ram int64 + CloneVirtualMachine_SwitchName string + CloneVirtualMachine_Err error DeleteVirtualMachine_Called bool DeleteVirtualMachine_VmName string diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 546ffae6d..ba167413b 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -514,6 +514,6 @@ func TestUserVariablesInBootCommand(t *testing.T) { ret := step.Run(state) if ret != multistep.ActionContinue { - t.Fatalf("should not have error: %s", ret) + t.Fatalf("should not have error: %s", ret) } } diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 6ba93caac..2a9459ace 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -97,7 +97,7 @@ type Config struct { // Prepare processes the build configuration parameters. func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { err := config.Decode(&b.config, &config.DecodeOpts{ - Interpolate: true, + Interpolate: true, InterpolateContext: &b.config.ctx, InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 8c0be09a4..89cac5878 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -535,6 +535,6 @@ func TestUserVariablesInBootCommand(t *testing.T) { ret := step.Run(state) if ret != multistep.ActionContinue { - t.Fatalf("should not have error: %s", ret) + t.Fatalf("should not have error: %s", ret) } } From f4600a208ffc75ddbe76274257991fc8d09ab5d1 Mon Sep 17 00:00:00 2001 From: Arjen Schwarz <arjen.schwarz@bulletproof.net> Date: Mon, 6 Nov 2017 16:16:58 +1100 Subject: [PATCH 0149/1007] Azure: Keep temporary resource group. Fixes #5045 This changeset will detect if the defined temporary resource group already exists. If it does, it will not destroy it, but clean up every resource required for building that is created by Packer individually, both on success and failure. Unit tests have been fixed, but more tests should be added for the new functionalities. --- builder/azure/arm/azure_client.go | 15 + .../azure/arm/step_create_resource_group.go | 51 +- .../arm/step_create_resource_group_test.go | 46 +- builder/azure/arm/step_delete_os_disk.go | 33 +- builder/azure/arm/step_delete_os_disk_test.go | 9 +- .../azure/arm/step_delete_resource_group.go | 73 +- .../arm/step_delete_resource_group_test.go | 6 +- builder/azure/arm/step_deploy_template.go | 149 +++- builder/azure/common/constants/stateBag.go | 1 + .../Azure/azure-sdk-for-go/arm/disk/client.go | 53 ++ .../Azure/azure-sdk-for-go/arm/disk/disks.go | 728 +++++++++++++++++ .../Azure/azure-sdk-for-go/arm/disk/models.go | 278 +++++++ .../azure-sdk-for-go/arm/disk/snapshots.go | 733 ++++++++++++++++++ .../azure-sdk-for-go/arm/disk/version.go | 29 + vendor/vendor.json | 6 + 15 files changed, 2168 insertions(+), 42 deletions(-) create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go create mode 100755 vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go diff --git a/builder/azure/arm/azure_client.go b/builder/azure/arm/azure_client.go index 3fd58bc34..08dd95eae 100644 --- a/builder/azure/arm/azure_client.go +++ b/builder/azure/arm/azure_client.go @@ -10,6 +10,7 @@ import ( "strconv" "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/disk" "github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/resources/resources" armStorage "github.com/Azure/azure-sdk-for-go/arm/storage" @@ -32,6 +33,7 @@ var ( type AzureClient struct { storage.BlobStorageClient resources.DeploymentsClient + resources.DeploymentOperationsClient resources.GroupsClient network.PublicIPAddressesClient network.InterfacesClient @@ -41,6 +43,7 @@ type AzureClient struct { compute.VirtualMachinesClient common.VaultClient armStorage.AccountsClient + disk.DisksClient InspectorMaxLength int Template *CaptureTemplate @@ -135,6 +138,18 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.DeploymentsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) azureClient.DeploymentsClient.UserAgent += packerUserAgent + azureClient.DeploymentOperationsClient = resources.NewDeploymentOperationsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) + azureClient.DeploymentOperationsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) + azureClient.DeploymentOperationsClient.RequestInspector = withInspection(maxlen) + azureClient.DeploymentOperationsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) + azureClient.DeploymentOperationsClient.UserAgent += packerUserAgent + + azureClient.DisksClient = disk.NewDisksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) + azureClient.DisksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) + azureClient.DisksClient.RequestInspector = withInspection(maxlen) + azureClient.DisksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) + azureClient.DisksClient.UserAgent += packerUserAgent + azureClient.GroupsClient = resources.NewGroupsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.GroupsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.GroupsClient.RequestInspector = withInspection(maxlen) diff --git a/builder/azure/arm/step_create_resource_group.go b/builder/azure/arm/step_create_resource_group.go index 079ad5279..745748669 100644 --- a/builder/azure/arm/step_create_resource_group.go +++ b/builder/azure/arm/step_create_resource_group.go @@ -14,6 +14,7 @@ type StepCreateResourceGroup struct { create func(resourceGroupName string, location string, tags *map[string]*string) error say func(message string) error func(e error) + exists func(resourceGroupName string) (bool, error) } func NewStepCreateResourceGroup(client *AzureClient, ui packer.Ui) *StepCreateResourceGroup { @@ -24,6 +25,7 @@ func NewStepCreateResourceGroup(client *AzureClient, ui packer.Ui) *StepCreateRe } step.create = step.createResourceGroup + step.exists = step.doesResourceGroupExist return step } @@ -39,6 +41,15 @@ func (s *StepCreateResourceGroup) createResourceGroup(resourceGroupName string, return err } +func (s *StepCreateResourceGroup) doesResourceGroupExist(resourceGroupName string) (bool, error) { + exists, err := s.client.GroupsClient.CheckExistence(resourceGroupName) + if err != nil { + s.say(s.client.LastError.Error()) + } + + return exists.Response.StatusCode != 404, err +} + func (s *StepCreateResourceGroup) Run(state multistep.StateBag) multistep.StepAction { s.say("Creating resource group ...") @@ -53,8 +64,19 @@ func (s *StepCreateResourceGroup) Run(state multistep.StateBag) multistep.StepAc s.say(fmt.Sprintf(" ->> %s : %s", k, *v)) } - err := s.create(resourceGroupName, location, tags) - if err == nil { + exists, err := s.exists(resourceGroupName) + if err != nil { + s.say(s.client.LastError.Error()) + } + state.Put(constants.ArmIsExistingResourceGroup, exists) + // If the resource group exists, we may not have permissions to update it so we don't. + if !exists { + err = s.create(resourceGroupName, location, tags) + if err == nil { + state.Put(constants.ArmIsResourceGroupCreated, true) + } + } else { + // Mark the resource group as created to deal with later checks state.Put(constants.ArmIsResourceGroupCreated, true) } @@ -68,17 +90,22 @@ func (s *StepCreateResourceGroup) Cleanup(state multistep.StateBag) { } ui := state.Get("ui").(packer.Ui) - ui.Say("\nCleanup requested, deleting resource group ...") + if state.Get(constants.ArmIsExistingResourceGroup).(bool) { + ui.Say("\nThe resource group was not created by Packer, not deleting ...") + return + } else { + ui.Say("\nCleanup requested, deleting resource group ...") - var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) - _, errChan := s.client.GroupsClient.Delete(resourceGroupName, nil) - err := <-errChan + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) + _, errChan := s.client.GroupsClient.Delete(resourceGroupName, nil) + err := <-errChan - if err != nil { - ui.Error(fmt.Sprintf("Error deleting resource group. Please delete it manually.\n\n"+ - "Name: %s\n"+ - "Error: %s", resourceGroupName, err)) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resource group. Please delete it manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceGroupName, err)) + } + + ui.Say("Resource group has been deleted.") } - - ui.Say("Resource group has been deleted.") } diff --git a/builder/azure/arm/step_create_resource_group_test.go b/builder/azure/arm/step_create_resource_group_test.go index 4e6b7592f..47a4a01e6 100644 --- a/builder/azure/arm/step_create_resource_group_test.go +++ b/builder/azure/arm/step_create_resource_group_test.go @@ -13,6 +13,7 @@ func TestStepCreateResourceGroupShouldFailIfCreateFails(t *testing.T) { create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, say: func(message string) {}, error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, } stateBag := createTestStateBagStepCreateResourceGroup() @@ -32,6 +33,7 @@ func TestStepCreateResourceGroupShouldPassIfCreatePasses(t *testing.T) { create: func(string, string, *map[string]*string) error { return nil }, say: func(message string) {}, error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, } stateBag := createTestStateBagStepCreateResourceGroup() @@ -58,8 +60,9 @@ func TestStepCreateResourceGroupShouldTakeStepArgumentsFromStateBag(t *testing.T actualTags = tags return nil }, - say: func(message string) {}, - error: func(e error) {}, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, } stateBag := createTestStateBagStepCreateResourceGroup() @@ -91,6 +94,44 @@ func TestStepCreateResourceGroupShouldTakeStepArgumentsFromStateBag(t *testing.T } } +func TestStepCreateResourceGroupMarkAsNonExistingIfDoesntExist(t *testing.T) { + var testSubject = &StepCreateResourceGroup{ + create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, + } + + stateBag := createTestStateBagStepCreateResourceGroup() + + if _, ok := stateBag.GetOk(constants.ArmIsExistingResourceGroup); ok == true { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' not to be set, but it was") + } + testSubject.Run(stateBag) + if stateBag.Get(constants.ArmIsExistingResourceGroup).(bool) == true { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' to be set to false, but it wasn't.") + } +} + +func TestStepCreateResourceGroupMarkAsExistingIfExists(t *testing.T) { + var testSubject = &StepCreateResourceGroup{ + create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return true, nil }, + } + + stateBag := createTestStateBagStepCreateResourceGroup() + + if _, ok := stateBag.GetOk(constants.ArmIsExistingResourceGroup); ok == true { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' not to be set, but it was") + } + testSubject.Run(stateBag) + if stateBag.Get(constants.ArmIsExistingResourceGroup).(bool) == false { + t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' to be set to true, but it wasn't.") + } +} + func createTestStateBagStepCreateResourceGroup() multistep.StateBag { stateBag := new(multistep.BasicStateBag) @@ -103,6 +144,5 @@ func createTestStateBagStepCreateResourceGroup() multistep.StateBag { } stateBag.Put(constants.ArmTags, &tags) - return stateBag } diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index 1dd28ec85..6c56ac96d 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -12,10 +12,11 @@ import ( ) type StepDeleteOSDisk struct { - client *AzureClient - delete func(string, string) error - say func(message string) - error func(e error) + client *AzureClient + delete func(string, string) error + deleteManaged func(string, string) error + say func(message string) + error func(e error) } func NewStepDeleteOSDisk(client *AzureClient, ui packer.Ui) *StepDeleteOSDisk { @@ -26,6 +27,7 @@ func NewStepDeleteOSDisk(client *AzureClient, ui packer.Ui) *StepDeleteOSDisk { } step.delete = step.deleteBlob + step.deleteManaged = step.deleteManagedDisk return step } @@ -39,19 +41,40 @@ func (s *StepDeleteOSDisk) deleteBlob(storageContainerName string, blobName stri return err } +func (s *StepDeleteOSDisk) deleteManagedDisk(resourceGroupName string, imageName string) error { + s.say("In the deleting part") + xs := strings.Split(imageName, "/") + diskName := xs[len(xs)-1] + _, errChan := s.client.DisksClient.Delete(resourceGroupName, diskName, nil) + err := <-errChan + return err +} + func (s *StepDeleteOSDisk) Run(state multistep.StateBag) multistep.StepAction { s.say("Deleting the temporary OS disk ...") var osDisk = state.Get(constants.ArmOSDiskVhd).(string) var isManagedDisk = state.Get(constants.ArmIsManagedImage).(bool) + var isExistingResourceGroup = state.Get(constants.ArmIsExistingResourceGroup).(bool) + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) - if isManagedDisk { + if isManagedDisk && !isExistingResourceGroup { s.say(fmt.Sprintf(" -> OS Disk : skipping, managed disk was used...")) return multistep.ActionContinue } s.say(fmt.Sprintf(" -> OS Disk : '%s'", osDisk)) + var err error + if isManagedDisk { + err = s.deleteManaged(resourceGroupName, osDisk) + if err != nil { + s.say("Failed to delete the managed OS Disk!") + return multistep.ActionHalt + } + s.say("After deleting") + return multistep.ActionContinue + } u, err := url.Parse(osDisk) if err != nil { s.say("Failed to parse the OS Disk's VHD URI!") diff --git a/builder/azure/arm/step_delete_os_disk_test.go b/builder/azure/arm/step_delete_os_disk_test.go index 2724ee611..e19f0e0ba 100644 --- a/builder/azure/arm/step_delete_os_disk_test.go +++ b/builder/azure/arm/step_delete_os_disk_test.go @@ -10,9 +10,10 @@ import ( func TestStepDeleteOSDiskShouldFailIfGetFails(t *testing.T) { var testSubject = &StepDeleteOSDisk{ - delete: func(string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, - say: func(message string) {}, - error: func(e error) {}, + delete: func(string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + deleteManaged: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, } stateBag := DeleteTestStateBagStepDeleteOSDisk("http://storage.blob.core.windows.net/images/pkrvm_os.vhd") @@ -106,6 +107,8 @@ func DeleteTestStateBagStepDeleteOSDisk(osDiskVhd string) multistep.StateBag { stateBag := new(multistep.BasicStateBag) stateBag.Put(constants.ArmOSDiskVhd, osDiskVhd) stateBag.Put(constants.ArmIsManagedImage, false) + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") return stateBag } diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index 2606b9fc8..28b7c4142 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -3,6 +3,7 @@ package arm import ( "fmt" + "github.com/Azure/go-autorest/autorest" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/packer" @@ -11,7 +12,7 @@ import ( type StepDeleteResourceGroup struct { client *AzureClient - delete func(resourceGroupName string, cancelCh <-chan struct{}) error + delete func(state multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error say func(message string) error func(e error) } @@ -27,14 +28,69 @@ func NewStepDeleteResourceGroup(client *AzureClient, ui packer.Ui) *StepDeleteRe return step } -func (s *StepDeleteResourceGroup) deleteResourceGroup(resourceGroupName string, cancelCh <-chan struct{}) error { - _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) +func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error { + var err error + if state.Get(constants.ArmIsExistingResourceGroup).(bool) { + s.say("\nThe resource group was not created by Packer, only deleting individual resources ...") + var deploymentName = state.Get(constants.ArmDeploymentName).(string) + if deploymentName != "" { + maxResources := int32(50) + deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) + if err != nil { + s.say(fmt.Sprintf("Error deleting resources. Please delete them manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceGroupName, err)) + s.error(err) + } + for _, deploymentOperation := range *deploymentOperations.Value { + // Sometimes an empty operation is added to the list by Azure + if deploymentOperation.Properties.TargetResource == nil { + continue + } + s.say(fmt.Sprintf(" -> %s : '%s'", + *deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName)) + var networkDeleteFunction func(string, string, <-chan struct{}) (<-chan autorest.Response, <-chan error) + switch *deploymentOperation.Properties.TargetResource.ResourceType { + case "Microsoft.Compute/virtualMachines": + _, errChan := s.client.VirtualMachinesClient.Delete(resourceGroupName, *deploymentOperation.Properties.TargetResource.ResourceName, nil) + err := <-errChan + if err != nil { + s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err.Error())) + s.error(err) + } + case "Microsoft.Network/networkInterfaces": + networkDeleteFunction = s.client.InterfacesClient.Delete + case "Microsoft.Network/virtualNetworks": + networkDeleteFunction = s.client.VirtualNetworksClient.Delete + case "Microsoft.Network/publicIPAddresses": + networkDeleteFunction = s.client.PublicIPAddressesClient.Delete + } + if networkDeleteFunction != nil { + _, errChan := networkDeleteFunction(resourceGroupName, *deploymentOperation.Properties.TargetResource.ResourceName, nil) + err := <-errChan + if err != nil { + s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err.Error())) + s.error(err) + } + } + } + } + return err + } else { + _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) + s.say(state.Get(constants.ArmIsExistingResourceGroup).(string)) + err = <-errChan - err := <-errChan - if err != nil { - s.say(s.client.LastError.Error()) + if err != nil { + s.say(s.client.LastError.Error()) + } + return err } - return err } func (s *StepDeleteResourceGroup) Run(state multistep.StateBag) multistep.StepAction { @@ -45,8 +101,7 @@ func (s *StepDeleteResourceGroup) Run(state multistep.StateBag) multistep.StepAc result := common.StartInterruptibleTask( func() bool { return common.IsStateCancelled(state) }, - func(cancelCh <-chan struct{}) error { return s.delete(resourceGroupName, cancelCh) }) - + func(cancelCh <-chan struct{}) error { return s.delete(state, resourceGroupName, cancelCh) }) stepAction := processInterruptibleResult(result, s.error, state) state.Put(constants.ArmIsResourceGroupCreated, false) diff --git a/builder/azure/arm/step_delete_resource_group_test.go b/builder/azure/arm/step_delete_resource_group_test.go index 25ab14e4d..c9d6e22da 100644 --- a/builder/azure/arm/step_delete_resource_group_test.go +++ b/builder/azure/arm/step_delete_resource_group_test.go @@ -10,7 +10,7 @@ import ( func TestStepDeleteResourceGroupShouldFailIfDeleteFails(t *testing.T) { var testSubject = &StepDeleteResourceGroup{ - delete: func(string, <-chan struct{}) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + delete: func(multistep.StateBag, string, <-chan struct{}) error { return fmt.Errorf("!! Unit Test FAIL !!") }, say: func(message string) {}, error: func(e error) {}, } @@ -29,7 +29,7 @@ func TestStepDeleteResourceGroupShouldFailIfDeleteFails(t *testing.T) { func TestStepDeleteResourceGroupShouldPassIfDeletePasses(t *testing.T) { var testSubject = &StepDeleteResourceGroup{ - delete: func(string, <-chan struct{}) error { return nil }, + delete: func(multistep.StateBag, string, <-chan struct{}) error { return nil }, say: func(message string) {}, error: func(e error) {}, } @@ -48,7 +48,7 @@ func TestStepDeleteResourceGroupShouldPassIfDeletePasses(t *testing.T) { func TestStepDeleteResourceGroupShouldDeleteStateBagArmResourceGroupCreated(t *testing.T) { var testSubject = &StepDeleteResourceGroup{ - delete: func(resourceGroupName string, cancelCh <-chan struct{}) error { + delete: func(s multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error { return nil }, say: func(message string) {}, diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index 8d73402b7..53b639d51 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -2,7 +2,10 @@ package arm import ( "fmt" + "net/url" + "strings" + "github.com/Azure/go-autorest/autorest" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/packer" @@ -10,12 +13,15 @@ import ( ) type StepDeployTemplate struct { - client *AzureClient - deploy func(resourceGroupName string, deploymentName string, cancelCh <-chan struct{}) error - say func(message string) - error func(e error) - config *Config - factory templateFactoryFunc + client *AzureClient + deploy func(resourceGroupName string, deploymentName string, cancelCh <-chan struct{}) error + delete func(resourceType string, resourceName string, resourceGroupName string) error + disk func(resourceGroupName string, computeName string) (string, string, error) + deleteDisk func(imageType string, imageName string, resourceGroupName string) error + say func(message string) + error func(e error) + config *Config + factory templateFactoryFunc } func NewStepDeployTemplate(client *AzureClient, ui packer.Ui, config *Config, factory templateFactoryFunc) *StepDeployTemplate { @@ -28,6 +34,9 @@ func NewStepDeployTemplate(client *AzureClient, ui packer.Ui, config *Config, fa } step.deploy = step.deployTemplate + step.delete = step.deleteOperationResource + step.disk = step.getImageDetails + step.deleteDisk = step.deleteImage return step } @@ -65,5 +74,131 @@ func (s *StepDeployTemplate) Run(state multistep.StateBag) multistep.StepAction return processInterruptibleResult(result, s.error, state) } -func (*StepDeployTemplate) Cleanup(multistep.StateBag) { +func (s *StepDeployTemplate) getImageDetails(resourceGroupName string, computeName string) (string, string, error) { + //We can't depend on constants.ArmOSDiskVhd being set + var imageName string + var imageType string + vm, err := s.client.VirtualMachinesClient.Get(resourceGroupName, computeName, "") + if err != nil { + return imageName, imageType, err + } else { + if vm.StorageProfile.OsDisk.Vhd != nil { + imageType = "image" + imageName = *vm.StorageProfile.OsDisk.Vhd.URI + } else { + imageType = "Microsoft.Compute/disks" + imageName = *vm.StorageProfile.OsDisk.ManagedDisk.ID + } + } + return imageType, imageName, nil +} + +func (s *StepDeployTemplate) deleteOperationResource(resourceType string, resourceName string, resourceGroupName string) error { + var networkDeleteFunction func(string, string, <-chan struct{}) (<-chan autorest.Response, <-chan error) + switch resourceType { + case "Microsoft.Compute/virtualMachines": + _, errChan := s.client.VirtualMachinesClient.Delete(resourceGroupName, + resourceName, nil) + err := <-errChan + if err != nil { + return err + + } + case "Microsoft.Network/networkInterfaces": + networkDeleteFunction = s.client.InterfacesClient.Delete + case "Microsoft.Network/virtualNetworks": + networkDeleteFunction = s.client.VirtualNetworksClient.Delete + case "Microsoft.Network/publicIPAddresses": + networkDeleteFunction = s.client.PublicIPAddressesClient.Delete + } + if networkDeleteFunction != nil { + _, errChan := networkDeleteFunction(resourceGroupName, resourceName, nil) + err := <-errChan + if err != nil { + return err + } + } + return nil +} + +func (s *StepDeployTemplate) deleteImage(imageType string, imageName string, resourceGroupName string) error { + // Managed disk + if imageType == "Microsoft.Compute/disks" { + xs := strings.Split(imageName, "/") + diskName := xs[len(xs)-1] + _, errChan := s.client.DisksClient.Delete(resourceGroupName, diskName, nil) + err := <-errChan + return err + } + // VHD image + u, err := url.Parse(imageName) + if err != nil { + return err + } + xs := strings.Split(u.Path, "/") + var storageAccountName = xs[1] + var blobName = strings.Join(xs[2:], "/") + + blob := s.client.BlobStorageClient.GetContainerReference(storageAccountName).GetBlobReference(blobName) + err = blob.Delete(nil) + return err + +} + +func (s *StepDeployTemplate) Cleanup(state multistep.StateBag) { + //Only clean up if this was an existing resource group and the resource group + //is marked as created + var existingResourceGroup = state.Get(constants.ArmIsExistingResourceGroup).(bool) + var resourceGroupCreated = state.Get(constants.ArmIsResourceGroupCreated).(bool) + if !existingResourceGroup || !resourceGroupCreated { + return + } + ui := state.Get("ui").(packer.Ui) + ui.Say("\nThe resource group was not created by Packer, deleting individual resources ...") + + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) + var computeName = state.Get(constants.ArmComputeName).(string) + var deploymentName = state.Get(constants.ArmDeploymentName).(string) + imageType, imageName, err := s.disk(resourceGroupName, computeName) + if err != nil { + ui.Error("Could not retrieve OS Image details") + } + + ui.Say(" -> Deployment: " + deploymentName) + if deploymentName != "" { + maxResources := int32(50) + deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resources. Please delete them manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceGroupName, err)) + } + for _, deploymentOperation := range *deploymentOperations.Value { + // Sometimes an empty operation is added to the list by Azure + if deploymentOperation.Properties.TargetResource == nil { + continue + } + ui.Say(fmt.Sprintf(" -> %s : '%s'", + *deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName)) + err = s.delete(*deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName, + resourceGroupName) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err)) + } + } + + // The disk is not defined as an operation in the template so has to be + // deleted separately + ui.Say(fmt.Sprintf(" -> %s : '%s'", imageType, imageName)) + err = s.deleteDisk(imageType, imageName, resourceGroupName) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", imageName, err)) + } + } } diff --git a/builder/azure/common/constants/stateBag.go b/builder/azure/common/constants/stateBag.go index a6eef5bd4..1df94a8f0 100644 --- a/builder/azure/common/constants/stateBag.go +++ b/builder/azure/common/constants/stateBag.go @@ -26,6 +26,7 @@ const ( ArmStorageAccountName string = "arm.StorageAccountName" ArmTags string = "arm.Tags" ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters" + ArmIsExistingResourceGroup string = "arm.IsExistingResourceGroup" ArmIsManagedImage string = "arm.IsManagedImage" ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName" diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go new file mode 100755 index 000000000..8bab7acc1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/client.go @@ -0,0 +1,53 @@ +// Package disk implements the Azure ARM Disk service API version +// 2016-04-30-preview. +// +// The Disk Resource Provider Client. +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Disk + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Disk. +type ManagementClient struct { + autorest.Client + BaseURI string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go new file mode 100755 index 000000000..4f7fce74f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/disks.go @@ -0,0 +1,728 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// DisksClient is the the Disk Resource Provider Client. +type DisksClient struct { + ManagementClient +} + +// NewDisksClient creates an instance of the DisksClient client. +func NewDisksClient(subscriptionID string) DisksClient { + return NewDisksClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewDisksClientWithBaseURI creates an instance of the DisksClient client. +func NewDisksClientWithBaseURI(baseURI string, subscriptionID string) DisksClient { + return DisksClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a disk. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. diskParameter is +// disk object supplied in the body of the Put disk operation. +func (client DisksClient) CreateOrUpdate(resourceGroupName string, diskName string, diskParameter Model, cancel <-chan struct{}) (<-chan Model, <-chan error) { + resultChan := make(chan Model, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: diskParameter, + Constraints: []validation.Constraint{{Target: "diskParameter.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "diskParameter.Properties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "diskParameter.Properties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "diskParameter.Properties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.DisksClient", "CreateOrUpdate") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result Model + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.CreateOrUpdatePreparer(resourceGroupName, diskName, diskParameter, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "CreateOrUpdate", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client DisksClient) CreateOrUpdatePreparer(resourceGroupName string, diskName string, diskParameter Model, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithJSON(diskParameter), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client DisksClient) CreateOrUpdateResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a disk. This method may poll for completion. Polling can be +// canceled by passing the cancel channel argument. The channel will be used to +// cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) Delete(resourceGroupName string, diskName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.DeletePreparer(resourceGroupName, diskName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Delete", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// DeletePreparer prepares the Delete request. +func (client DisksClient) DeletePreparer(resourceGroupName string, diskName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client DisksClient) DeleteResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get gets information about a disk. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) Get(resourceGroupName string, diskName string) (result Model, err error) { + req, err := client.GetPreparer(resourceGroupName, diskName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client DisksClient) GetPreparer(resourceGroupName string, diskName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client DisksClient) GetResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GrantAccess grants access to a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. grantAccessData +// is access data object supplied in the body of the get disk access operation. +func (client DisksClient) GrantAccess(resourceGroupName string, diskName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (<-chan AccessURI, <-chan error) { + resultChan := make(chan AccessURI, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: grantAccessData, + Constraints: []validation.Constraint{{Target: "grantAccessData.DurationInSeconds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.DisksClient", "GrantAccess") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result AccessURI + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.GrantAccessPreparer(resourceGroupName, diskName, grantAccessData, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", nil, "Failure preparing request") + return + } + + resp, err := client.GrantAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", resp, "Failure sending request") + return + } + + result, err = client.GrantAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "GrantAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// GrantAccessPreparer prepares the GrantAccess request. +func (client DisksClient) GrantAccessPreparer(resourceGroupName string, diskName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}/beginGetAccess", pathParameters), + autorest.WithJSON(grantAccessData), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GrantAccessSender sends the GrantAccess request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) GrantAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GrantAccessResponder handles the response to the GrantAccess request. The method always +// closes the http.Response Body. +func (client DisksClient) GrantAccessResponder(resp *http.Response) (result AccessURI, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists all the disks under a subscription. +func (client DisksClient) List() (result ListType, err error) { + req, err := client.ListPreparer() + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client DisksClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/disks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client DisksClient) ListResponder(resp *http.Response) (result ListType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client DisksClient) ListNextResults(lastResults ListType) (result ListType, err error) { + req, err := lastResults.ListTypePreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup lists all the disks under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client DisksClient) ListByResourceGroup(resourceGroupName string) (result ListType, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client DisksClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client DisksClient) ListByResourceGroupResponder(resp *http.Response) (result ListType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client DisksClient) ListByResourceGroupNextResults(lastResults ListType) (result ListType, err error) { + req, err := lastResults.ListTypePreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// RevokeAccess revokes access to a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. +func (client DisksClient) RevokeAccess(resourceGroupName string, diskName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.RevokeAccessPreparer(resourceGroupName, diskName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", nil, "Failure preparing request") + return + } + + resp, err := client.RevokeAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", resp, "Failure sending request") + return + } + + result, err = client.RevokeAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "RevokeAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// RevokeAccessPreparer prepares the RevokeAccess request. +func (client DisksClient) RevokeAccessPreparer(resourceGroupName string, diskName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}/endGetAccess", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RevokeAccessSender sends the RevokeAccess request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) RevokeAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RevokeAccessResponder handles the response to the RevokeAccess request. The method always +// closes the http.Response Body. +func (client DisksClient) RevokeAccessResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Update updates (patches) a disk. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. diskName is the name of +// the disk within the given subscription and resource group. diskParameter is +// disk object supplied in the body of the Patch disk operation. +func (client DisksClient) Update(resourceGroupName string, diskName string, diskParameter UpdateType, cancel <-chan struct{}) (<-chan Model, <-chan error) { + resultChan := make(chan Model, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result Model + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.UpdatePreparer(resourceGroupName, diskName, diskParameter, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.DisksClient", "Update", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// UpdatePreparer prepares the Update request. +func (client DisksClient) UpdatePreparer(resourceGroupName string, diskName string, diskParameter UpdateType, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diskName": autorest.Encode("path", diskName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/disks/{diskName}", pathParameters), + autorest.WithJSON(diskParameter), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client DisksClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client DisksClient) UpdateResponder(resp *http.Response) (result Model, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go new file mode 100755 index 000000000..e8118696a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/models.go @@ -0,0 +1,278 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// AccessLevel enumerates the values for access level. +type AccessLevel string + +const ( + // None specifies the none state for access level. + None AccessLevel = "None" + // Read specifies the read state for access level. + Read AccessLevel = "Read" +) + +// CreateOption enumerates the values for create option. +type CreateOption string + +const ( + // Attach specifies the attach state for create option. + Attach CreateOption = "Attach" + // Copy specifies the copy state for create option. + Copy CreateOption = "Copy" + // Empty specifies the empty state for create option. + Empty CreateOption = "Empty" + // FromImage specifies the from image state for create option. + FromImage CreateOption = "FromImage" + // Import specifies the import state for create option. + Import CreateOption = "Import" + // Restore specifies the restore state for create option. + Restore CreateOption = "Restore" +) + +// OperatingSystemTypes enumerates the values for operating system types. +type OperatingSystemTypes string + +const ( + // Linux specifies the linux state for operating system types. + Linux OperatingSystemTypes = "Linux" + // Windows specifies the windows state for operating system types. + Windows OperatingSystemTypes = "Windows" +) + +// StorageAccountTypes enumerates the values for storage account types. +type StorageAccountTypes string + +const ( + // PremiumLRS specifies the premium lrs state for storage account types. + PremiumLRS StorageAccountTypes = "Premium_LRS" + // StandardLRS specifies the standard lrs state for storage account types. + StandardLRS StorageAccountTypes = "Standard_LRS" +) + +// AccessURI is a disk access SAS uri. +type AccessURI struct { + autorest.Response `json:"-"` + *AccessURIOutput `json:"properties,omitempty"` +} + +// AccessURIOutput is azure properties, including output. +type AccessURIOutput struct { + *AccessURIRaw `json:"output,omitempty"` +} + +// AccessURIRaw is this object gets 'bubbled up' through flattening. +type AccessURIRaw struct { + AccessSAS *string `json:"accessSAS,omitempty"` +} + +// APIError is api error. +type APIError struct { + Details *[]APIErrorBase `json:"details,omitempty"` + Innererror *InnerError `json:"innererror,omitempty"` + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// APIErrorBase is api error base. +type APIErrorBase struct { + Code *string `json:"code,omitempty"` + Target *string `json:"target,omitempty"` + Message *string `json:"message,omitempty"` +} + +// CreationData is data used when creating a disk. +type CreationData struct { + CreateOption CreateOption `json:"createOption,omitempty"` + StorageAccountID *string `json:"storageAccountId,omitempty"` + ImageReference *ImageDiskReference `json:"imageReference,omitempty"` + SourceURI *string `json:"sourceUri,omitempty"` + SourceResourceID *string `json:"sourceResourceId,omitempty"` +} + +// EncryptionSettings is encryption settings for disk or snapshot +type EncryptionSettings struct { + Enabled *bool `json:"enabled,omitempty"` + DiskEncryptionKey *KeyVaultAndSecretReference `json:"diskEncryptionKey,omitempty"` + KeyEncryptionKey *KeyVaultAndKeyReference `json:"keyEncryptionKey,omitempty"` +} + +// GrantAccessData is data used for requesting a SAS. +type GrantAccessData struct { + Access AccessLevel `json:"access,omitempty"` + DurationInSeconds *int32 `json:"durationInSeconds,omitempty"` +} + +// ImageDiskReference is the source image used for creating the disk. +type ImageDiskReference struct { + ID *string `json:"id,omitempty"` + Lun *int32 `json:"lun,omitempty"` +} + +// InnerError is inner error details. +type InnerError struct { + Exceptiontype *string `json:"exceptiontype,omitempty"` + Errordetail *string `json:"errordetail,omitempty"` +} + +// KeyVaultAndKeyReference is key Vault Key Url and vault id of KeK, KeK is +// optional and when provided is used to unwrap the encryptionKey +type KeyVaultAndKeyReference struct { + SourceVault *SourceVault `json:"sourceVault,omitempty"` + KeyURL *string `json:"keyUrl,omitempty"` +} + +// KeyVaultAndSecretReference is key Vault Secret Url and vault id of the +// encryption key +type KeyVaultAndSecretReference struct { + SourceVault *SourceVault `json:"sourceVault,omitempty"` + SecretURL *string `json:"secretUrl,omitempty"` +} + +// ListType is the List Disks operation response. +type ListType struct { + autorest.Response `json:"-"` + Value *[]Model `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ListTypePreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ListType) ListTypePreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// Model is disk resource. +type Model struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *Properties `json:"properties,omitempty"` +} + +// OperationStatusResponse is operation status response +type OperationStatusResponse struct { + autorest.Response `json:"-"` + Name *string `json:"name,omitempty"` + Status *string `json:"status,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Error *APIError `json:"error,omitempty"` +} + +// Properties is disk resource properties. +type Properties struct { + AccountType StorageAccountTypes `json:"accountType,omitempty"` + TimeCreated *date.Time `json:"timeCreated,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + CreationData *CreationData `json:"creationData,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` + OwnerID *string `json:"ownerId,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// Resource is the Resource model definition. +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceUpdate is the Resource model definition. +type ResourceUpdate struct { + Tags *map[string]*string `json:"tags,omitempty"` +} + +// Snapshot is snapshot resource. +type Snapshot struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *Properties `json:"properties,omitempty"` +} + +// SnapshotList is the List Snapshots operation response. +type SnapshotList struct { + autorest.Response `json:"-"` + Value *[]Snapshot `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SnapshotListPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SnapshotList) SnapshotListPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// SnapshotUpdate is snapshot update resource. +type SnapshotUpdate struct { + Tags *map[string]*string `json:"tags,omitempty"` + *UpdateProperties `json:"properties,omitempty"` +} + +// SourceVault is the vault id is an Azure Resource Manager Resoure id in the +// form +// /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName} +type SourceVault struct { + ID *string `json:"id,omitempty"` +} + +// UpdateProperties is disk resource update properties. +type UpdateProperties struct { + AccountType StorageAccountTypes `json:"accountType,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + CreationData *CreationData `json:"creationData,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + EncryptionSettings *EncryptionSettings `json:"encryptionSettings,omitempty"` +} + +// UpdateType is disk update resource. +type UpdateType struct { + Tags *map[string]*string `json:"tags,omitempty"` + *UpdateProperties `json:"properties,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go new file mode 100755 index 000000000..f4e5579d0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/snapshots.go @@ -0,0 +1,733 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// SnapshotsClient is the the Disk Resource Provider Client. +type SnapshotsClient struct { + ManagementClient +} + +// NewSnapshotsClient creates an instance of the SnapshotsClient client. +func NewSnapshotsClient(subscriptionID string) SnapshotsClient { + return NewSnapshotsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSnapshotsClientWithBaseURI creates an instance of the SnapshotsClient +// client. +func NewSnapshotsClientWithBaseURI(baseURI string, subscriptionID string) SnapshotsClient { + return SnapshotsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// snapshot is snapshot object supplied in the body of the Put disk operation. +func (client SnapshotsClient) CreateOrUpdate(resourceGroupName string, snapshotName string, snapshot Snapshot, cancel <-chan struct{}) (<-chan Snapshot, <-chan error) { + resultChan := make(chan Snapshot, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: snapshot, + Constraints: []validation.Constraint{{Target: "snapshot.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData.ImageReference", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.CreationData.ImageReference.ID", Name: validation.Null, Rule: true, Chain: nil}}}, + }}, + {Target: "snapshot.Properties.EncryptionSettings", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.Properties.EncryptionSettings.DiskEncryptionKey.SecretURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey.SourceVault", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "snapshot.Properties.EncryptionSettings.KeyEncryptionKey.KeyURL", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.SnapshotsClient", "CreateOrUpdate") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result Snapshot + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.CreateOrUpdatePreparer(resourceGroupName, snapshotName, snapshot, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client SnapshotsClient) CreateOrUpdatePreparer(resourceGroupName string, snapshotName string, snapshot Snapshot, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithJSON(snapshot), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) CreateOrUpdateResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a snapshot. This method may poll for completion. Polling can +// be canceled by passing the cancel channel argument. The channel will be used +// to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) Delete(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.DeletePreparer(resourceGroupName, snapshotName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Delete", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// DeletePreparer prepares the Delete request. +func (client SnapshotsClient) DeletePreparer(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) DeleteResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get gets information about a snapshot. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) Get(resourceGroupName string, snapshotName string) (result Snapshot, err error) { + req, err := client.GetPreparer(resourceGroupName, snapshotName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client SnapshotsClient) GetPreparer(resourceGroupName string, snapshotName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) GetResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GrantAccess grants access to a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// grantAccessData is access data object supplied in the body of the get +// snapshot access operation. +func (client SnapshotsClient) GrantAccess(resourceGroupName string, snapshotName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (<-chan AccessURI, <-chan error) { + resultChan := make(chan AccessURI, 1) + errChan := make(chan error, 1) + if err := validation.Validate([]validation.Validation{ + {TargetValue: grantAccessData, + Constraints: []validation.Constraint{{Target: "grantAccessData.DurationInSeconds", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil { + errChan <- validation.NewErrorWithValidationError(err, "disk.SnapshotsClient", "GrantAccess") + close(errChan) + close(resultChan) + return resultChan, errChan + } + + go func() { + var err error + var result AccessURI + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.GrantAccessPreparer(resourceGroupName, snapshotName, grantAccessData, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", nil, "Failure preparing request") + return + } + + resp, err := client.GrantAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", resp, "Failure sending request") + return + } + + result, err = client.GrantAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "GrantAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// GrantAccessPreparer prepares the GrantAccess request. +func (client SnapshotsClient) GrantAccessPreparer(resourceGroupName string, snapshotName string, grantAccessData GrantAccessData, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}/beginGetAccess", pathParameters), + autorest.WithJSON(grantAccessData), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// GrantAccessSender sends the GrantAccess request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) GrantAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// GrantAccessResponder handles the response to the GrantAccess request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) GrantAccessResponder(resp *http.Response) (result AccessURI, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists snapshots under a subscription. +func (client SnapshotsClient) List() (result SnapshotList, err error) { + req, err := client.ListPreparer() + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client SnapshotsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/snapshots", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) ListResponder(resp *http.Response) (result SnapshotList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client SnapshotsClient) ListNextResults(lastResults SnapshotList) (result SnapshotList, err error) { + req, err := lastResults.SnapshotListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup lists snapshots under a resource group. +// +// resourceGroupName is the name of the resource group. +func (client SnapshotsClient) ListByResourceGroup(resourceGroupName string) (result SnapshotList, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client SnapshotsClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) ListByResourceGroupResponder(resp *http.Response) (result SnapshotList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client SnapshotsClient) ListByResourceGroupNextResults(lastResults SnapshotList) (result SnapshotList, err error) { + req, err := lastResults.SnapshotListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// RevokeAccess revokes access to a snapshot. This method may poll for +// completion. Polling can be canceled by passing the cancel channel argument. +// The channel will be used to cancel polling and any outstanding HTTP +// requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +func (client SnapshotsClient) RevokeAccess(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (<-chan OperationStatusResponse, <-chan error) { + resultChan := make(chan OperationStatusResponse, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result OperationStatusResponse + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.RevokeAccessPreparer(resourceGroupName, snapshotName, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", nil, "Failure preparing request") + return + } + + resp, err := client.RevokeAccessSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", resp, "Failure sending request") + return + } + + result, err = client.RevokeAccessResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "RevokeAccess", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// RevokeAccessPreparer prepares the RevokeAccess request. +func (client SnapshotsClient) RevokeAccessPreparer(resourceGroupName string, snapshotName string, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}/endGetAccess", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// RevokeAccessSender sends the RevokeAccess request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) RevokeAccessSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// RevokeAccessResponder handles the response to the RevokeAccess request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) RevokeAccessResponder(resp *http.Response) (result OperationStatusResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Update updates (patches) a snapshot. This method may poll for completion. +// Polling can be canceled by passing the cancel channel argument. The channel +// will be used to cancel polling and any outstanding HTTP requests. +// +// resourceGroupName is the name of the resource group. snapshotName is the +// name of the snapshot within the given subscription and resource group. +// snapshot is snapshot object supplied in the body of the Patch snapshot +// operation. +func (client SnapshotsClient) Update(resourceGroupName string, snapshotName string, snapshot SnapshotUpdate, cancel <-chan struct{}) (<-chan Snapshot, <-chan error) { + resultChan := make(chan Snapshot, 1) + errChan := make(chan error, 1) + go func() { + var err error + var result Snapshot + defer func() { + resultChan <- result + errChan <- err + close(resultChan) + close(errChan) + }() + req, err := client.UpdatePreparer(resourceGroupName, snapshotName, snapshot, cancel) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "disk.SnapshotsClient", "Update", resp, "Failure responding to request") + } + }() + return resultChan, errChan +} + +// UpdatePreparer prepares the Update request. +func (client SnapshotsClient) UpdatePreparer(resourceGroupName string, snapshotName string, snapshot SnapshotUpdate, cancel <-chan struct{}) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "snapshotName": autorest.Encode("path", snapshotName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2016-04-30-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/snapshots/{snapshotName}", pathParameters), + autorest.WithJSON(snapshot), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{Cancel: cancel}) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client SnapshotsClient) UpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client SnapshotsClient) UpdateResponder(resp *http.Response) (result Snapshot, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go new file mode 100755 index 000000000..a78b351a0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/disk/version.go @@ -0,0 +1,29 @@ +package disk + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/v10.0.2-beta arm-disk/2016-04-30-preview" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return "v10.0.2-beta" +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 0a06ac4b1..503290446 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -17,6 +17,12 @@ "version": "v10.0.3-beta", "versionExact": "v10.0.3-beta" }, + { + "checksumSHA1": "Kr6/gY3LrNiOxMfDBCfBvBvenYw=", + "path": "github.com/Azure/azure-sdk-for-go/arm/disk", + "revision": "26132835cbefa2669a306b777f34b929b56aa0a2", + "revisionTime": "2017-05-18T20:34:07Z" + }, { "checksumSHA1": "HMu0WrEHVs+wqyjsTzXxRsEJimI=", "comment": "v3.1.0-beta", From 5ccba2caaa1a5008db8d72a651d5d44f47df5ffc Mon Sep 17 00:00:00 2001 From: bugbuilder <nelson@bennu.cl> Date: Mon, 6 Nov 2017 02:57:41 -0300 Subject: [PATCH 0150/1007] using virtual disk device to create datastorePath --- .../vsphere-template/post-processor.go | 9 --- .../vsphere-template/step_mark_as_template.go | 60 ++++++++++++++----- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index 86c9f54b4..8b0918b05 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -88,13 +88,6 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId()) } - source := "" - for _, path := range artifact.Files() { - if strings.HasSuffix(path, ".vmx") { - source = path - break - } - } // In some occasions the VM state is powered on and if we immediately try to mark as template // (after the ESXi creates it) it will fail. If vSphere is given a few seconds this behavior doesn't reappear. ui.Message("Waiting 10s for VMware vSphere to start") @@ -119,12 +112,10 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac }, &stepMarkAsTemplate{ VMName: artifact.Id(), - Source: source, }, } runner := common.NewRunnerWithPauseFn(steps, p.config.PackerConfig, ui, state) runner.Run(state) - if rawErr, ok := state.GetOk("error"); ok { return nil, false, rawErr.(error) } diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index 0e5465054..f5d362e6f 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -4,17 +4,18 @@ import ( "context" "fmt" "path" + "regexp" "strings" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" "github.com/vmware/govmomi" "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/vim25/types" ) type stepMarkAsTemplate struct { VMName string - Source string } func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction { @@ -32,6 +33,19 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } + if err := unregisterPreviousVM(cli, folder, s.VMName); err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + path, err := datastorePath(vm, s.VMName) + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + host, err := vm.HostSystem(context.Background()) if err != nil { state.Put("error", err) @@ -45,21 +59,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } - source := strings.Split(s.Source, "/vmfs/volumes/")[1] - i := strings.Index(source, "/") - - path := (&object.DatastorePath{ - Datastore: source[:i], - Path: source[i:], - }).String() - - if err := unregisterPreviousVM(cli, folder, s.VMName); err != nil { - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - task, err := folder.RegisterVM(context.Background(), path, s.VMName, true, nil, host) + task, err := folder.RegisterVM(context.Background(), path.String(), s.VMName, true, nil, host) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -75,6 +75,34 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionContinue } +func datastorePath(vm *object.VirtualMachine, name string) (*object.DatastorePath, error) { + devices, err := vm.Device(context.Background()) + if err != nil { + return nil, err + } + + disk := "" + for _, device := range devices { + if d, ok := device.(*types.VirtualDisk); ok { + if b, ok := d.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok { + disk = b.GetVirtualDeviceFileBackingInfo().FileName + } + break + } + } + + if disk == "" { + return nil, fmt.Errorf("disk not found in '%v'", name) + } + + re := regexp.MustCompile("\\[(.*?)\\]") + + datastore := re.FindStringSubmatch(disk)[1] + vmx := path.Join("/", path.Dir(strings.Split(disk, " ")[1]), name+".vmx") + + return &object.DatastorePath{datastore, vmx}, nil +} + // We will use the virtual machine created by vmware-iso builder func findRuntimeVM(cli *govmomi.Client, dcPath, name string) (*object.VirtualMachine, error) { si := object.NewSearchIndex(cli.Client) From 7bc112bbd94dcdd9edb198807f3b70b22ec385a7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 6 Nov 2017 15:35:31 -0800 Subject: [PATCH 0151/1007] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7af71024..efa4f2b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] * builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] +### BUG FIXES: + +* builder/docker: Remove `login_email`, which no longer exists in the docker client. [GH-5511] + ## 1.1.1 (October 13, 2017) ### IMPROVEMENTS: From d0c1d118ea928246ac4bc9d590e6e5feaf6f50cb Mon Sep 17 00:00:00 2001 From: Brian Cain <bcain@hashicorp.com> Date: Mon, 6 Nov 2017 15:39:57 -0800 Subject: [PATCH 0152/1007] Update vagrantcloud token page URL --- website/source/docs/post-processors/vagrant-cloud.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/post-processors/vagrant-cloud.html.md b/website/source/docs/post-processors/vagrant-cloud.html.md index 0fa535710..bc230c3a7 100644 --- a/website/source/docs/post-processors/vagrant-cloud.html.md +++ b/website/source/docs/post-processors/vagrant-cloud.html.md @@ -53,7 +53,7 @@ on Vagrant Cloud, as well as authentication and version information. - `access_token` (string) - Your access token for the Vagrant Cloud API. This can be generated on your [tokens - page](https://vagrantcloud.com/account/tokens). If not specified, the + page](https://app.vagrantup.com/settings/security). If not specified, the environment will be searched. First, `VAGRANT_CLOUD_TOKEN` is checked, and if nothing is found, finally `ATLAS_TOKEN` will be used. From 497e88759e5e8ebe8540425b6edcf98b12470857 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 6 Nov 2017 15:44:02 -0800 Subject: [PATCH 0153/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efa4f2b5f..e0ad95159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * builder/amazon: correctly deregister AMIs when `force_deregister` is set. [GH-5525] * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] * builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] +* communicator/ssh: Add socks 5 proxy support. [GH-5439] ### BUG FIXES: From 733d5b65e50339672165af96b51e357956f77642 Mon Sep 17 00:00:00 2001 From: Matt Mercer <mamercer@cisco.com> Date: Mon, 6 Nov 2017 12:37:41 -0800 Subject: [PATCH 0154/1007] Website: add ssh_agent_auth to ssh communicator docs --- website/source/docs/templates/communicator.html.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 83205c543..cb19863ca 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -52,12 +52,16 @@ configuration parameters for that communicator. These are documented below. ## SSH Communicator -The SSH communicator connects to the host via SSH. If you have an SSH -agent enabled on the machine running Packer, it will automatically forward -the SSH agent to the remote host. +The SSH communicator connects to the host via SSH. If you have an SSH agent +configured on the host running Packer, and SSH agent authentication is enabled +in the communicator config, Packer will automatically forward the SSH agent +to the remote host. The SSH communicator has the following options: +- `ssh_agent_auth` (boolean) - If true, the local SSH agent will be used to + authenticate connections to the remote host. Defaults to false. + - `ssh_bastion_agent_auth` (boolean) - If true, the local SSH agent will be used to authenticate with the bastion host. Defaults to false. From 8ecb406f5eced5f7f0fa3dc6268f579349bb4c4c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 6 Nov 2017 15:55:45 -0800 Subject: [PATCH 0155/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0ad95159..132082417 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] * builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] * communicator/ssh: Add socks 5 proxy support. [GH-5439] +* builder/lxc: Add new `publish_properties` field to set image properties. [GH-5475] ### BUG FIXES: From b49ead622552dc66ddcc368482d0ee89479a1f0a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 6 Nov 2017 15:56:59 -0800 Subject: [PATCH 0156/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 132082417..16227d26f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] * communicator/ssh: Add socks 5 proxy support. [GH-5439] * builder/lxc: Add new `publish_properties` field to set image properties. [GH-5475] +* builder/virtualbox-ovf: Retry while removing VM to solve for transient errors. [GH-5512] ### BUG FIXES: From 1b3eb1c34dca0c6b2b4f82914e6b2171de1fc5ee Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Wed, 13 Sep 2017 14:12:03 -0700 Subject: [PATCH 0157/1007] builder/googlecompute: Set default network_project_id If network_project_id is not specified in the GCE builder config, it should default to the project_id. --- builder/googlecompute/config.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index 9605f2f4c..b09f1814e 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -86,6 +86,10 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { c.Network = "default" } + if c.NetworkProjectId == "" { + c.NetworkProjectId = c.ProjectId + } + if c.DiskSizeGb == 0 { c.DiskSizeGb = 10 } From bada7b73c1c235df53a833a68cd63747c52ac26e Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Wed, 13 Sep 2017 14:13:47 -0700 Subject: [PATCH 0158/1007] builder/googlecompute: Selectively set default network If a network is not specified, it should only be set to "default" if a subnetwork is also not specified. --- builder/googlecompute/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index b09f1814e..8ed3897d6 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -82,7 +82,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { var errs *packer.MultiError // Set defaults. - if c.Network == "" { + if c.Network == "" && c.Subnetwork == "" { c.Network = "default" } From f2fed94a715433b25ee0dfd4efc6e253ff9ee0bd Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Wed, 13 Sep 2017 14:15:39 -0700 Subject: [PATCH 0159/1007] builder/googlecompute: Derive network and subnetwork IDs locally This change constructs partial URLs for networks and subnetworks if they are not already partial or full URLs (i.e., they do not contain a '/' in their name). Network and subnetwork self-links are no longer retrieved from the API. Previously, if a user did not provide the network or subnetwork as a fully-qualified URL (i.e., self-link), the builder would make compute.(sub)networks.get API calls with the provided identifier to discover the self-link. This requires the user or service account Packer is using to have permission to describe those network resources, which is becoming less common as IAM is used more. Specifically, a user may have permission to launch a VM into a network/subnetwork, but will not have permission to call APIs to describe network resources. --- builder/googlecompute/driver_gce.go | 92 ++++++++++++++--------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 02a230cfe..e767ff6ce 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -10,7 +10,6 @@ import ( "fmt" "log" "net/http" - "net/url" "runtime" "strings" "time" @@ -299,55 +298,54 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { } // TODO(mitchellh): deprecation warnings - networkSelfLink := "" - subnetworkSelfLink := "" + networkId := "" + subnetworkId := "" - if u, err := url.Parse(c.Network); err == nil && (u.Scheme == "https" || u.Scheme == "http") { - // Network is a full server URL - // Parse out Network and NetworkProjectId from URL - // https://www.googleapis.com/compute/v1/projects/<ProjectId>/global/networks/<Network> - networkSelfLink = c.Network - parts := strings.Split(u.String(), "/") - if len(parts) >= 10 { - c.NetworkProjectId = parts[6] - c.Network = parts[9] + // Apply network naming requirements per + // https://cloud.google.com/compute/docs/reference/latest/instances#resource + switch c.Network { + // It is possible to omit the network property as long as a subnet is + // specified. That will be validated later. + case "": + d.ui.Message(fmt.Sprintf("Network: will be inferred from subnetwork")) + break + // This special short name should be expanded. + case "default": + networkId = "global/networks/default" + // A value other than "default" was provided for the network name. + default: + // If the value doesn't contain a slash, we assume it's not a full or + // partial URL. We will expand it into a partial URL here and avoid + // making an API call to discover the network as it's common for the + // caller to not have permission against network discovery APIs. + if !strings.Contains(c.Network, "/") { + networkId = "projects/" + c.NetworkProjectId + "/global/networks/" + c.Network + d.ui.Message(fmt.Sprintf("Network name: %q was expanded to the partial URL %q", c.Network, networkId)) } } - if u, err := url.Parse(c.Subnetwork); err == nil && (u.Scheme == "https" || u.Scheme == "http") { - // Subnetwork is a full server URL - subnetworkSelfLink = c.Subnetwork - } - // If subnetwork is ID's and not full service URL's look them up. - if subnetworkSelfLink == "" { - - // Get the network - if c.NetworkProjectId == "" { - c.NetworkProjectId = d.projectId + // Apply subnetwork naming requirements per + // https://cloud.google.com/compute/docs/reference/latest/instances#resource + switch c.Subnetwork { + case "": + // You can't omit both subnetwork and network + if networkId == "" { + return nil, fmt.Errorf("both network and subnetwork were empty.") } - d.ui.Message(fmt.Sprintf("Loading network: %s", c.Network)) - network, err := d.service.Networks.Get(c.NetworkProjectId, c.Network).Do() - if err != nil { - return nil, err - } - networkSelfLink = network.SelfLink - - // Subnetwork - // Validate Subnetwork config now that we have some info about the network - if !network.AutoCreateSubnetworks && len(network.Subnetworks) > 0 { - // Network appears to be in "custom" mode, so a subnetwork is required - if c.Subnetwork == "" { - return nil, fmt.Errorf("a subnetwork must be specified") - } - } - // Get the subnetwork - if c.Subnetwork != "" { - d.ui.Message(fmt.Sprintf("Loading subnetwork: %s for region: %s", c.Subnetwork, c.Region)) - subnetwork, err := d.service.Subnetworks.Get(c.NetworkProjectId, c.Region, c.Subnetwork).Do() - if err != nil { - return nil, err - } - subnetworkSelfLink = subnetwork.SelfLink + // An empty subnetwork is only valid for networks in legacy mode or + // auto-subnet mode. We could make an API call to get that information + // about the network, but it's common for the caller to not have + // permission to that API. We'll proceed assuming they're correct in + // omitting the subnetwork and let the compute.insert API surface an + // error about an invalid network configuration if it exists. + break + default: + // If the value doesn't contain a slash, we assume it's not a full or + // partial URL. We will expand it into a partial URL here and avoid + // making a call to discover the subnetwork. + if !strings.Contains(c.Subnetwork, "/") { + subnetworkId = "projects/" + c.NetworkProjectId + "/regions/" + c.Region + "/subnetworks/" + c.Subnetwork + d.ui.Message(fmt.Sprintf("Subnetwork: %q was expanded to the partial URL %q", c.Subnetwork, subnetworkId)) } } @@ -417,8 +415,8 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { NetworkInterfaces: []*compute.NetworkInterface{ { AccessConfigs: []*compute.AccessConfig{accessconfig}, - Network: networkSelfLink, - Subnetwork: subnetworkSelfLink, + Network: networkId, + Subnetwork: subnetworkId, }, }, Scheduling: &compute.Scheduling{ From 74403ef91428c60e0f595a59bb2ea331e9ceb86b Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Thu, 14 Sep 2017 10:14:28 -0700 Subject: [PATCH 0160/1007] website: Update googlecompute engine docs This change updates the documentation to describe how `network` and `subnetwork` properties are processed. --- website/source/docs/builders/googlecompute.html.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index 8e89666bd..4ccfe4cb1 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -216,7 +216,10 @@ builder. instance. - `network` (string) - The Google Compute network id or URL to use for the - launched instance. Defaults to `"default"`. + launched instance. Defaults to `"default"`. If the value is not a URL, it + will be interpolated to `projects/((network_project_id))/global/networks/((network))`. + This value is not required if a `subnet` is specified. + - `network_project_id` (string) - The project ID for the network and subnetwork to use for launched instance. Defaults to `project_id`. @@ -259,7 +262,9 @@ builder. - `subnetwork` (string) - The Google Compute subnetwork id or URL to use for the launched instance. Only required if the `network` has been created with custom subnetting. Note, the region of the subnetwork must match the `region` - or `zone` in which the VM is launched. + or `zone` in which the VM is launched. If the value is not a URL, it + will be interpolated to `projects/((network_project_id))/regions/((region))/subnetworks/((subnetwork))` + - `tags` (array of strings) From 13e0c232d40283b76a120dfa78894f37ec591728 Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Mon, 6 Nov 2017 21:07:56 -0800 Subject: [PATCH 0161/1007] builder/googlecompute: Test networking interpolation This change pulls the logic that interpolates network and subnetwork into its own func and adds tests. --- builder/googlecompute/driver_gce.go | 53 +---------------- builder/googlecompute/networking.go | 59 +++++++++++++++++++ builder/googlecompute/networking_test.go | 72 ++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 50 deletions(-) create mode 100644 builder/googlecompute/networking.go create mode 100644 builder/googlecompute/networking_test.go diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index e767ff6ce..69af625e9 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -298,55 +298,9 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { } // TODO(mitchellh): deprecation warnings - networkId := "" - subnetworkId := "" - - // Apply network naming requirements per - // https://cloud.google.com/compute/docs/reference/latest/instances#resource - switch c.Network { - // It is possible to omit the network property as long as a subnet is - // specified. That will be validated later. - case "": - d.ui.Message(fmt.Sprintf("Network: will be inferred from subnetwork")) - break - // This special short name should be expanded. - case "default": - networkId = "global/networks/default" - // A value other than "default" was provided for the network name. - default: - // If the value doesn't contain a slash, we assume it's not a full or - // partial URL. We will expand it into a partial URL here and avoid - // making an API call to discover the network as it's common for the - // caller to not have permission against network discovery APIs. - if !strings.Contains(c.Network, "/") { - networkId = "projects/" + c.NetworkProjectId + "/global/networks/" + c.Network - d.ui.Message(fmt.Sprintf("Network name: %q was expanded to the partial URL %q", c.Network, networkId)) - } - } - - // Apply subnetwork naming requirements per - // https://cloud.google.com/compute/docs/reference/latest/instances#resource - switch c.Subnetwork { - case "": - // You can't omit both subnetwork and network - if networkId == "" { - return nil, fmt.Errorf("both network and subnetwork were empty.") - } - // An empty subnetwork is only valid for networks in legacy mode or - // auto-subnet mode. We could make an API call to get that information - // about the network, but it's common for the caller to not have - // permission to that API. We'll proceed assuming they're correct in - // omitting the subnetwork and let the compute.insert API surface an - // error about an invalid network configuration if it exists. - break - default: - // If the value doesn't contain a slash, we assume it's not a full or - // partial URL. We will expand it into a partial URL here and avoid - // making a call to discover the subnetwork. - if !strings.Contains(c.Subnetwork, "/") { - subnetworkId = "projects/" + c.NetworkProjectId + "/regions/" + c.Region + "/subnetworks/" + c.Subnetwork - d.ui.Message(fmt.Sprintf("Subnetwork: %q was expanded to the partial URL %q", c.Subnetwork, subnetworkId)) - } + networkId, subnetworkId, err := getNetworking(c) + if err != nil { + return nil, err } var accessconfig *compute.AccessConfig @@ -609,7 +563,6 @@ func (d *driverGCE) refreshZoneOp(zone string, op *compute.Operation) stateRefre } } -// stateRefreshFunc is used to refresh the state of a thing and is // used in conjunction with waitForState. type stateRefreshFunc func() (string, error) diff --git a/builder/googlecompute/networking.go b/builder/googlecompute/networking.go new file mode 100644 index 000000000..aa59e77e0 --- /dev/null +++ b/builder/googlecompute/networking.go @@ -0,0 +1,59 @@ +package googlecompute + +import ( + "fmt" + "strings" +) + +// This method will build a network and subnetwork ID from the provided +// instance config, and return them in that order. +func getNetworking(c *InstanceConfig) (string, string, error) { + networkId := c.Network + subnetworkId := c.Subnetwork + + // Apply network naming requirements per + // https://cloud.google.com/compute/docs/reference/latest/instances#resource + switch c.Network { + // It is possible to omit the network property as long as a subnet is + // specified. That will be validated later. + case "": + break + // This special short name should be expanded. + case "default": + networkId = "global/networks/default" + // A value other than "default" was provided for the network name. + default: + // If the value doesn't contain a slash, we assume it's not a full or + // partial URL. We will expand it into a partial URL here and avoid + // making an API call to discover the network as it's common for the + // caller to not have permission against network discovery APIs. + if !strings.Contains(c.Network, "/") { + networkId = "projects/" + c.NetworkProjectId + "/global/networks/" + c.Network + } + } + + // Apply subnetwork naming requirements per + // https://cloud.google.com/compute/docs/reference/latest/instances#resource + switch c.Subnetwork { + case "": + // You can't omit both subnetwork and network + if networkId == "" { + return networkId, subnetworkId, fmt.Errorf("both network and subnetwork were empty.") + } + // An empty subnetwork is only valid for networks in legacy mode or + // auto-subnet mode. We could make an API call to get that information + // about the network, but it's common for the caller to not have + // permission to that API. We'll proceed assuming they're correct in + // omitting the subnetwork and let the compute.insert API surface an + // error about an invalid network configuration if it exists. + break + default: + // If the value doesn't contain a slash, we assume it's not a full or + // partial URL. We will expand it into a partial URL here and avoid + // making a call to discover the subnetwork. + if !strings.Contains(c.Subnetwork, "/") { + subnetworkId = "projects/" + c.NetworkProjectId + "/regions/" + c.Region + "/subnetworks/" + c.Subnetwork + } + } + return networkId, subnetworkId, nil +} diff --git a/builder/googlecompute/networking_test.go b/builder/googlecompute/networking_test.go new file mode 100644 index 000000000..85b481df3 --- /dev/null +++ b/builder/googlecompute/networking_test.go @@ -0,0 +1,72 @@ +package googlecompute + +import ( + "testing" +) + +func TestGetNetworking(t *testing.T) { + cases := []struct { + c *InstanceConfig + expectedNetwork string + expectedSubnetwork string + error bool + }{ + { + c: &InstanceConfig{ + Network: "default", + Subnetwork: "", + NetworkProjectId: "project-id", + Region: "region-id", + }, + expectedNetwork: "global/networks/default", + expectedSubnetwork: "", + error: false, + }, + { + c: &InstanceConfig{ + Network: "", + Subnetwork: "", + NetworkProjectId: "project-id", + Region: "region-id", + }, + expectedNetwork: "", + expectedSubnetwork: "", + error: true, + }, + { + c: &InstanceConfig{ + Network: "some/network/path", + Subnetwork: "some/subnetwork/path", + NetworkProjectId: "project-id", + Region: "region-id", + }, + expectedNetwork: "some/network/path", + expectedSubnetwork: "some/subnetwork/path", + error: false, + }, + { + c: &InstanceConfig{ + Network: "network-value", + Subnetwork: "subnetwork-value", + NetworkProjectId: "project-id", + Region: "region-id", + }, + expectedNetwork: "projects/project-id/global/networks/network-value", + expectedSubnetwork: "projects/project-id/regions/region-id/subnetworks/subnetwork-value", + error: false, + }, + } + + for _, tc := range cases { + n, sn, err := getNetworking(tc.c) + if n != tc.expectedNetwork { + t.Errorf("Expected network %q but got network %q", tc.expectedNetwork, n) + } + if sn != tc.expectedSubnetwork { + t.Errorf("Expected subnetwork %q but got subnetwork %q", tc.expectedSubnetwork, sn) + } + if !tc.error && err != nil { + t.Errorf("Did not expect an error but got: %v", err) + } + } +} From 52fc0100ebe0b7f856fba65e1f178840d3e9aea5 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 7 Nov 2017 12:52:03 -0800 Subject: [PATCH 0162/1007] this is a critical error --- builder/amazon/common/access_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 03deca8bf..ecbb100b7 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -36,7 +36,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { if c.ProfileName != "" { if err := os.Setenv("AWS_PROFILE", c.ProfileName); err != nil { - log.Printf("Set env error: %s", err) + return nil, fmt.Errorf("Set env error: %s", err) } } From c106e7c26c7a954718aeec19901edc5234064d57 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 7 Nov 2017 14:03:52 -0800 Subject: [PATCH 0163/1007] Don't set region from metadata if profile is set. --- builder/amazon/common/access_config.go | 33 ++++++++++++-------------- builder/amazon/common/ami_config.go | 9 +++---- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index ecbb100b7..462e32617 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -34,15 +34,15 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } + config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) + if c.ProfileName != "" { if err := os.Setenv("AWS_PROFILE", c.ProfileName); err != nil { return nil, fmt.Errorf("Set env error: %s", err) } - } - - config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) - - if region := c.region(); region != "" { + } else if c.RawRegion != "" { + config = config.WithRegion(c.RawRegion) + } else if region := c.metadataRegion(); region != "" { config = config.WithRegion(region) } @@ -68,25 +68,26 @@ func (c *AccessConfig) Session() (*session.Session, error) { SharedConfigState: session.SharedConfigEnable, Config: *config, } + if c.MFACode != "" { opts.AssumeRoleTokenProvider = func() (string, error) { return c.MFACode, nil } } - var err error - c.session, err = session.NewSessionWithOptions(opts) - if err != nil { + + if session, err := session.NewSessionWithOptions(opts); err != nil { return nil, err + } else if *session.Config.Region == "" { + return nil, fmt.Errorf("Could not find AWS region, make sure it's set.") + } else { + c.session = session } return c.session, nil } -// region returns either the region from config or region from metadata service -func (c *AccessConfig) region() string { - if c.RawRegion != "" { - return c.RawRegion - } +// metadataRegion returns the region from the metadata service +func (c *AccessConfig) metadataRegion() string { client := cleanhttp.DefaultClient() @@ -112,9 +113,5 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { } } - if len(errs) > 0 { - return errs - } - - return nil + return errs } diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index 7dfe1af88..aa0792e3a 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -45,10 +45,11 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context session, err := accessConfig.Session() if err != nil { errs = append(errs, err) - } - region := *session.Config.Region - if stringInSlice(c.AMIRegions, region) { - errs = append(errs, fmt.Errorf("Cannot copy AMI to AWS session region '%s', please remove it from `ami_regions`.", region)) + } else { + region := *session.Config.Region + if stringInSlice(c.AMIRegions, region) { + errs = append(errs, fmt.Errorf("Cannot copy AMI to AWS session region '%s', please remove it from `ami_regions`.", region)) + } } } From 545ee45567eccbf0555350c68f9b5b1cff425541 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 7 Nov 2017 14:51:20 -0800 Subject: [PATCH 0164/1007] debug region we found --- builder/amazon/common/access_config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 462e32617..ca589c7bf 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -80,6 +80,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { } else if *session.Config.Region == "" { return nil, fmt.Errorf("Could not find AWS region, make sure it's set.") } else { + log.Printf("Found region %s", *session.Config.Region) c.session = session } From f681faa296f6dc87efe0e768d6b41b134ef9bbfd Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 7 Nov 2017 14:57:10 -0800 Subject: [PATCH 0165/1007] fix tests --- builder/amazon/chroot/builder_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/amazon/chroot/builder_test.go b/builder/amazon/chroot/builder_test.go index a52714030..c13658286 100644 --- a/builder/amazon/chroot/builder_test.go +++ b/builder/amazon/chroot/builder_test.go @@ -10,6 +10,7 @@ func testConfig() map[string]interface{} { return map[string]interface{}{ "ami_name": "foo", "source_ami": "foo", + "region": "us-east-1", } } From d81871171c2b5f0bac5bb2b07c270f36adf34709 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 7 Nov 2017 15:01:02 -0800 Subject: [PATCH 0166/1007] make restart command work correctly even if user has their own check command --- provisioner/windows-restart/provisioner.go | 38 ++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 9b77c097e..e3cb1d119 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -17,7 +17,7 @@ import ( ) var DefaultRestartCommand = "shutdown /r /f /t 0 /c \"packer restart\"" -var DefaultRestartCheckCommand = winrm.Powershell(`if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; echo "${env:COMPUTERNAME} restarted."`) +var DefaultRestartCheckCommand = winrm.Powershell(`echo "${env:COMPUTERNAME} restarted."`) var retryableSleep = 5 * time.Second var TryCheckReboot = "shutdown.exe -f -r -t 60" var AbortReboot = "shutdown.exe -a" @@ -174,28 +174,40 @@ WaitLoop: } var waitForCommunicator = func(p *Provisioner) error { + runCustomRestartCheck := true for { - cmd := &packer.RemoteCmd{Command: p.config.RestartCheckCommand} - var buf, buf2 bytes.Buffer - cmd.Stdout = &buf - cmd.Stdout = io.MultiWriter(cmd.Stdout, &buf2) select { case <-p.cancel: log.Println("Communicator wait canceled, exiting loop") return fmt.Errorf("Communicator wait canceled") case <-time.After(retryableSleep): } + if runCustomRestartCheck == true { + if p.config.RestartCheckCommand == DefaultRestartCheckCommand { + runCustomRestartCheck = false + } + // this is the user configurable command + cmdRestartCheck := &packer.RemoteCmd{Command: p.config.RestartCheckCommand} + log.Printf("Checking that communicator is connected with: '%s'", + cmdRestartCheck.Command) + // run user-configured restart check + err := cmdRestartCheck.StartWithUi(p.comm, p.ui) - log.Printf("Checking that communicator is connected with: '%s'", cmd.Command) - - err := cmd.StartWithUi(p.comm, p.ui) - - if err != nil { - log.Printf("Communication connection err: %s", err) - continue + if err != nil { + log.Printf("Communication connection err: %s", err) + continue + } + log.Printf("Connected to machine") + runCustomRestartCheck = false } + // this is the non-user-configurable check that powershell + // modules have loaded + cmdModuleLoad := &packer.RemoteCmd{Command: DefaultRestartCheckCommand} + var buf, buf2 bytes.Buffer + cmdModuleLoad.Stdout = &buf + cmdModuleLoad.Stdout = io.MultiWriter(cmdModuleLoad.Stdout, &buf2) - log.Printf("Connected to machine") + cmdModuleLoad.StartWithUi(p.comm, p.ui) stdoutToRead := buf2.String() if !strings.Contains(stdoutToRead, "restarted.") { log.Printf("echo didn't succeed; retrying...") From b52ba4557ecf67450ed75f3480dd3645d714ecda Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 7 Nov 2017 16:00:40 -0800 Subject: [PATCH 0167/1007] add some example json to windows restart_check_command --- website/source/docs/provisioners/windows-restart.html.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/windows-restart.html.md b/website/source/docs/provisioners/windows-restart.html.md index 450977b55..e9e348755 100644 --- a/website/source/docs/provisioners/windows-restart.html.md +++ b/website/source/docs/provisioners/windows-restart.html.md @@ -42,7 +42,14 @@ Optional parameters: detect it is rebooting. - `restart_check_command` (string) - A command to execute to check if the - restart succeeded. This will be done in a loop. + restart succeeded. This will be done in a loop. Example usage: + +``` json + { + "type": "windows-restart", + "restart_check_command": "powershell -command \"& {Write-Output 'restarted.'}\"" + }, +``` - `restart_timeout` (string) - The timeout to wait for the restart. By default this is 5 minutes. Example value: `5m`. If you are installing From 0a24f4eb2efb6afac6b6558144bca2fb52431e8b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 7 Nov 2017 16:05:43 -0800 Subject: [PATCH 0168/1007] don't shadow package name --- builder/amazon/common/access_config.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index ca589c7bf..73e50b862 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -75,13 +75,13 @@ func (c *AccessConfig) Session() (*session.Session, error) { } } - if session, err := session.NewSessionWithOptions(opts); err != nil { + if sess, err := session.NewSessionWithOptions(opts); err != nil { return nil, err - } else if *session.Config.Region == "" { + } else if *sess.Config.Region == "" { return nil, fmt.Errorf("Could not find AWS region, make sure it's set.") } else { - log.Printf("Found region %s", *session.Config.Region) - c.session = session + log.Printf("Found region %s", *sess.Config.Region) + c.session = sess } return c.session, nil From 450a2333038a2cf531492b8e758f57034fd06194 Mon Sep 17 00:00:00 2001 From: stack72 <public@paulstack.co.uk> Date: Wed, 8 Nov 2017 16:33:15 +0200 Subject: [PATCH 0169/1007] builder/triton: Wait for ImageCreation State A bug was reported to Joyent, that sometimes packer UI reports that an image was created but it wasn't actually available in Triton for use. We believe that there was a bug uploading that image to Manta but that the metadata of the image was already populated and thus packer was reporting success as it was just checking for the metadata presence This PR changes Packer to wait for the state of the image to be `active` to make sure that it has fully uploaded and is ready for use ``` ==> triton: Stopping source machine (61647c3c-f2bf-4e30-b4bc-f076d3b01522)... ==> triton: Waiting for source machine to stop (61647c3c-f2bf-4e30-b4bc-f076d3b01522)... ==> triton: Creating image from source machine... ==> triton: Waiting for image to become available... ==> triton: Deleting source machine... ==> triton: Waiting for source machine to be deleted... Build 'triton' finished. ==> Builds finished. The artifacts of successful builds are: --> triton: Image was created: c2537582-34c7-42ea-bd11-b6ed499d5831 ``` --- builder/triton/driver_triton.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/builder/triton/driver_triton.go b/builder/triton/driver_triton.go index 19e1e1902..5e6acffef 100644 --- a/builder/triton/driver_triton.go +++ b/builder/triton/driver_triton.go @@ -4,9 +4,8 @@ import ( "context" "errors" "net/http" - "time" - "sort" + "time" "github.com/hashicorp/packer/packer" "github.com/joyent/triton-go/client" @@ -200,7 +199,7 @@ func (d *driverTriton) WaitForImageCreation(imageId string, timeout time.Duratio if image == nil { return false, err } - return image.OS != "", err + return image.State == "active", err }, 3*time.Second, timeout, From 74e2cc53f261e2b5988ba381f2c1db7cf83364f4 Mon Sep 17 00:00:00 2001 From: James Nugent <james@jen20.com> Date: Wed, 8 Nov 2017 08:46:51 -0600 Subject: [PATCH 0170/1007] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16227d26f..cb89b9044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ ### BUG FIXES: * builder/docker: Remove `login_email`, which no longer exists in the docker client. [GH-5511] +* builder/triton: Fix a bug where partially created images can be reported as complete. [GH-5566] ## 1.1.1 (October 13, 2017) From 23f4d187e2114b34d841d47e4aa14d814fa30561 Mon Sep 17 00:00:00 2001 From: bugbuilder <nelson@bennu.cl> Date: Wed, 8 Nov 2017 15:57:34 -0300 Subject: [PATCH 0171/1007] validating keep_registered and fixing skip_export issues --- builder/vmware/iso/artifact.go | 9 ++++++++- builder/vmware/iso/builder.go | 9 ++++++++- builder/vmware/iso/step_register.go | 2 +- .../vsphere-template/post-processor.go | 10 ++++++++++ .../vsphere-template/step_mark_as_template.go | 19 ++++++++++++------- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/builder/vmware/iso/artifact.go b/builder/vmware/iso/artifact.go index a0c3ceace..026b4580f 100644 --- a/builder/vmware/iso/artifact.go +++ b/builder/vmware/iso/artifact.go @@ -4,6 +4,12 @@ import ( "fmt" ) +const ( + ArtifactConfFormat = "artifact.conf.format" + ArtifactConfKeepRegistered = "artifact.conf.keep_registered" + ArtifactConfSkipExport = "artifact.conf.skip_export" +) + // Artifact is the result of running the VMware builder, namely a set // of files associated with the resulting machine. type Artifact struct { @@ -11,6 +17,7 @@ type Artifact struct { id string dir OutputDir f []string + config map[string]string } func (a *Artifact) BuilderId() string { @@ -30,7 +37,7 @@ func (a *Artifact) String() string { } func (a *Artifact) State(name string) interface{} { - return nil + return a.config[name] } func (a *Artifact) Destroy() error { diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 44db307a7..5fa15317f 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "log" "os" + "strconv" "time" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" @@ -343,7 +344,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Compile the artifact list var files []string - if b.config.RemoteType != "" && b.config.Format != "" { + if b.config.RemoteType != "" && b.config.Format != "" && !b.config.SkipExport { dir = new(vmwcommon.LocalOutputDir) dir.SetOutputDir(exportOutputPath) files, err = dir.ListFiles() @@ -360,11 +361,17 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe builderId = BuilderIdESX } + config := make(map[string]string) + config[ArtifactConfKeepRegistered] = strconv.FormatBool(b.config.KeepRegistered) + config[ArtifactConfFormat] = b.config.Format + config[ArtifactConfSkipExport] = strconv.FormatBool(b.config.SkipExport) + return &Artifact{ builderId: builderId, id: b.config.VMName, dir: dir, f: files, + config: config, }, nil } diff --git a/builder/vmware/iso/step_register.go b/builder/vmware/iso/step_register.go index a90de5fa2..509b6e017 100644 --- a/builder/vmware/iso/step_register.go +++ b/builder/vmware/iso/step_register.go @@ -51,7 +51,7 @@ func (s *StepRegister) Cleanup(state multistep.StateBag) { } if remoteDriver, ok := driver.(RemoteDriver); ok { - if s.Format == "" { + if s.Format == "" || config.SkipExport { ui.Say("Unregistering virtual machine...") if err := remoteDriver.Unregister(s.registeredPath); err != nil { ui.Error(fmt.Sprintf("Error unregistering VM: %s", err)) diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index 8b0918b05..f5fba9c4e 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -2,11 +2,13 @@ package vsphere_template import ( "context" + "errors" "fmt" "net/url" "strings" "time" + "github.com/hashicorp/packer/builder/vmware/iso" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" @@ -88,6 +90,14 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId()) } + f := artifact.State(iso.ArtifactConfFormat) + k := artifact.State(iso.ArtifactConfKeepRegistered) + s := artifact.State(iso.ArtifactConfSkipExport) + + if f != "" && k != "true" && s == "false" { + return nil, false, errors.New("To use this post-processor with exporting behavior you need set keep_registered as true") + } + // In some occasions the VM state is powered on and if we immediately try to mark as template // (after the ESXi creates it) it will fail. If vSphere is given a few seconds this behavior doesn't reappear. ui.Message("Waiting 10s for VMware vSphere to start") diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index f5d362e6f..7dc9211fa 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -39,7 +39,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } - path, err := datastorePath(vm, s.VMName) + dsPath, err := datastorePath(vm) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -59,7 +59,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } - task, err := folder.RegisterVM(context.Background(), path.String(), s.VMName, true, nil, host) + task, err := folder.RegisterVM(context.Background(), dsPath.String(), s.VMName, true, nil, host) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -75,7 +75,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionContinue } -func datastorePath(vm *object.VirtualMachine, name string) (*object.DatastorePath, error) { +func datastorePath(vm *object.VirtualMachine) (*object.DatastorePath, error) { devices, err := vm.Device(context.Background()) if err != nil { return nil, err @@ -92,15 +92,15 @@ func datastorePath(vm *object.VirtualMachine, name string) (*object.DatastorePat } if disk == "" { - return nil, fmt.Errorf("disk not found in '%v'", name) + return nil, fmt.Errorf("disk not found in '%v'", vm.Name()) } re := regexp.MustCompile("\\[(.*?)\\]") datastore := re.FindStringSubmatch(disk)[1] - vmx := path.Join("/", path.Dir(strings.Split(disk, " ")[1]), name+".vmx") + vmxPath := path.Join("/", path.Dir(strings.Split(disk, " ")[1]), vm.Name()+".vmx") - return &object.DatastorePath{datastore, vmx}, nil + return &object.DatastorePath{datastore, vmxPath}, nil } // We will use the virtual machine created by vmware-iso builder @@ -117,7 +117,12 @@ func findRuntimeVM(cli *govmomi.Client, dcPath, name string) (*object.VirtualMac return nil, fmt.Errorf("VM at path %s not found", fullPath) } - return ref.(*object.VirtualMachine), nil + vm := ref.(*object.VirtualMachine) + if vm.InventoryPath == "" { + vm.SetInventoryPath(fullPath) + } + + return vm, nil } // If in the target folder a virtual machine or template already exists From 0377140c399fa081354d86ade59dc005723a650c Mon Sep 17 00:00:00 2001 From: Arjen Schwarz <arjen.schwarz@bulletproof.net> Date: Thu, 9 Nov 2017 22:07:43 +1100 Subject: [PATCH 0172/1007] Azure docs: Add documentation concerning build_resource_group_name Part of #5045 --- website/source/docs/builders/azure.html.md | 39 ++++++++++++---------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index bcb2b5d77..8f9d23442 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -47,7 +47,7 @@ builder. - `location` (string) Azure datacenter in which your VM will build. CLI example `azure location list` - + #### VHD or Managed Image The Azure builder can create either a VHD, or a managed image. If you @@ -55,10 +55,10 @@ are creating a VHD, you **must** start with a VHD. Likewise, if you want to create a managed image you **must** start with a managed image. When creating a VHD the following two options are required. -- `capture_container_name` (string) Destination container name. Essentially the "directory" where your VHD will be +- `capture_container_name` (string) Destination container name. Essentially the "directory" where your VHD will be organized in Azure. The captured VHD's URL will be `https://<storage_account>.blob.core.windows.net/system/Microsoft.Compute/Images/<capture_container_name>/<capture_name_prefix>.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.vhd`. - -- `capture_name_prefix` (string) VHD prefix. The final artifacts will be named `PREFIX-osDisk.UUID` and + +- `capture_name_prefix` (string) VHD prefix. The final artifacts will be named `PREFIX-osDisk.UUID` and `PREFIX-vmTemplate.UUID`. - `resource_group_name` (string) Resource group under which the final artifact will be stored. @@ -68,13 +68,13 @@ image. When creating a VHD the following two options are required. When creating a managed image the following two options are required. - `managed_image_name` (string) Specify the managed image name where the result of the Packer build will be saved. The - image name must not exist ahead of time, and will not be overwritten. If this value is set, the value - `managed_image_resource_group_name` must also be set. See [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) + image name must not exist ahead of time, and will not be overwritten. If this value is set, the value + `managed_image_resource_group_name` must also be set. See [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) to learn more about managed images. - -- `managed_image_resource_group_name` (string) Specify the managed image resource group name where the result of the Packer build will be - saved. The resource group must already exist. If this value is set, the value `managed_image_name` must also be - set. See [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) to + +- `managed_image_resource_group_name` (string) Specify the managed image resource group name where the result of the Packer build will be + saved. The resource group must already exist. If this value is set, the value `managed_image_name` must also be + set. See [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) to learn more about managed images. ### Optional: @@ -83,12 +83,14 @@ When creating a managed image the following two options are required. characters, and tag values cannot exceed 256 characters. Tags are applied to every resource deployed by a Packer build, i.e. Resource Group, VM, NIC, VNET, Public IP, KeyVault, etc. +- `build_resource_group_name` (string) - Specify an existing resource group to run the build in. Cannot be used together with `temp_resource_group_name` and requires less permissions due to not creating or destroying a resource group. + - `cloud_environment_name` (string) One of `Public`, `China`, `Germany`, or `USGovernment`. Defaults to `Public`. Long forms such as `USGovernmentCloud` and `AzureUSGovernmentCloud` are also supported. - + - `custom_data_file` (string) Specify a file containing custom data to inject into the cloud-init process. The contents - of the file are read, base64 encoded, and injected into the ARM template. The custom data will be passed to + of the file are read, base64 encoded, and injected into the ARM template. The custom data will be passed to cloud-init for processing at the time of provisioning. See [documentation](http://cloudinit.readthedocs.io/en/latest/topics/examples.html) to learn more about custom data, and how it can be used to influence the provisioning process. @@ -110,11 +112,11 @@ When creating a managed image the following two options are required. - `image_url` (string) Specify a custom VHD to use. If this value is set, do not set image\_publisher, image\_offer, image\_sku, or image\_version. - + - `managed_image_storage_account_type` (string) Specify the storage account type for a managed image. Valid values are Standard_LRS and Premium\_LRS. The default is Standard\_LRS. - + - `object_id` (string) Specify an OAuth Object ID to protect WinRM certificates created at runtime. This variable is required when creating images based on Windows; this variable is not used by non-Windows builds. See `Windows` @@ -128,12 +130,12 @@ When creating a managed image the following two options are required. `Linux` this configures an SSH authorized key. For `Windows` this configures a WinRM certificate. -- `temp_compute_name` (string) temporary name assigned to the VM. If this value is not set, a random value will be - assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer +- `temp_compute_name` (string) temporary name assigned to the VM. If this value is not set, a random value will be + assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer build, e.g. attach a resource disk to the VM. -- `temp_resource_group_name` (string) temporary name assigned to the resource group. If this value is not set, a random - value will be assigned. +- `temp_resource_group_name` (string) name assigned to the temporary resource group created during the build. If this value is not set, a random + value will be assigned. Cannot be used together with `build_resource_group_name`. - `tenant_id` (string) The account identifier with which your `client_id` and `subscription_id` are associated. If not specified, `tenant_id` will be looked up using `subscription_id`. @@ -270,6 +272,7 @@ The Azure builder attempts to pick default values that provide for a just works - The default user name is packer not root as in other builders. Most distros on Azure do not allow root to SSH to a VM hence the need for a non-root default user. Set the ssh\_username option to override the default value. - The default VM size is Standard\_A1. Set the vm\_size option to override the default value. - The default image version is latest. Set the image\_version option to override the default value. +- By default a temporary resource group will be created and destroyed as part of the build. If you do not have permissions to do so, use `build_resource_group_name` to specify an existing resource group to run the build in. ## Implementation From 0e706320ad3ba30cd6d04598bbfe948eb8395588 Mon Sep 17 00:00:00 2001 From: Arjen Schwarz <arjen.schwarz@bulletproof.net> Date: Thu, 9 Nov 2017 22:20:09 +1100 Subject: [PATCH 0173/1007] Issue #5045 - Add build_resource_group_name * Created a new parameter for using existing resource groups * Implemented logic to ensure temp_ and build_ can't both be used * Implemented logic to ensure they can only be used in correct context * Implemented tests for this logic * Updated where required to ensure the process works --- builder/azure/arm/builder.go | 11 ++- builder/azure/arm/config.go | 14 ++- .../azure/arm/step_create_resource_group.go | 39 +++++--- .../arm/step_create_resource_group_test.go | 93 ++++++++++++++++--- builder/azure/arm/step_delete_os_disk.go | 6 +- builder/azure/arm/step_delete_os_disk_test.go | 72 ++++++++++++++ builder/azure/common/constants/stateBag.go | 1 + 7 files changed, 204 insertions(+), 32 deletions(-) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index e6993cfb5..3874cdb05 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -287,7 +287,16 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) { stateBag.Put(constants.ArmLocation, b.config.Location) stateBag.Put(constants.ArmNicName, DefaultNicName) stateBag.Put(constants.ArmPublicIPAddressName, DefaultPublicIPAddressName) - stateBag.Put(constants.ArmResourceGroupName, b.config.tmpResourceGroupName) + if b.config.TempResourceGroupName != "" && b.config.BuildResourceGroupName != "" { + stateBag.Put(constants.ArmDoubleResourceGroupNameSet, true) + } + if b.config.tmpResourceGroupName != "" { + stateBag.Put(constants.ArmResourceGroupName, b.config.tmpResourceGroupName) + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + } else { + stateBag.Put(constants.ArmResourceGroupName, b.config.BuildResourceGroupName) + stateBag.Put(constants.ArmIsExistingResourceGroup, true) + } stateBag.Put(constants.ArmStorageAccountName, b.config.StorageAccount) stateBag.Put(constants.ArmIsManagedImage, b.config.isManagedImage()) diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 3fc4f13b9..fd6bd9edb 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -83,6 +83,7 @@ type Config struct { StorageAccount string `mapstructure:"storage_account"` TempComputeName string `mapstructure:"temp_compute_name"` TempResourceGroupName string `mapstructure:"temp_resource_group_name"` + BuildResourceGroupName string `mapstructure:"build_resource_group_name"` storageAccountBlobEndpoint string CloudEnvironmentName string `mapstructure:"cloud_environment_name"` cloudEnvironment *azure.Environment @@ -129,7 +130,13 @@ type keyVaultCertificate struct { } func (c *Config) toVMID() string { - return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", c.SubscriptionID, c.tmpResourceGroupName, c.tmpComputeName) + var resourceGroupName string + if c.tmpResourceGroupName != "" { + resourceGroupName = c.tmpResourceGroupName + } else { + resourceGroupName = c.BuildResourceGroupName + } + return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", c.SubscriptionID, resourceGroupName, c.tmpComputeName) } func (c *Config) isManagedImage() bool { @@ -328,9 +335,10 @@ func setRuntimeValues(c *Config) { c.tmpComputeName = c.TempComputeName } c.tmpDeploymentName = tempName.DeploymentName - if c.TempResourceGroupName == "" { + // Only set tmpResourceGroupName if no name has been specified + if c.TempResourceGroupName == "" && c.BuildResourceGroupName == "" { c.tmpResourceGroupName = tempName.ResourceGroupName - } else { + } else if c.TempResourceGroupName != "" && c.BuildResourceGroupName == "" { c.tmpResourceGroupName = c.TempResourceGroupName } c.tmpOSDiskName = tempName.OSDiskName diff --git a/builder/azure/arm/step_create_resource_group.go b/builder/azure/arm/step_create_resource_group.go index 745748669..934cb3225 100644 --- a/builder/azure/arm/step_create_resource_group.go +++ b/builder/azure/arm/step_create_resource_group.go @@ -1,6 +1,7 @@ package arm import ( + "errors" "fmt" "github.com/Azure/azure-sdk-for-go/arm/resources/resources" @@ -51,32 +52,48 @@ func (s *StepCreateResourceGroup) doesResourceGroupExist(resourceGroupName strin } func (s *StepCreateResourceGroup) Run(state multistep.StateBag) multistep.StepAction { - s.say("Creating resource group ...") + var doubleResource, ok = state.GetOk(constants.ArmDoubleResourceGroupNameSet) + if ok && doubleResource.(bool) { + err := errors.New("You have filled in both temp_resource_group_name and build_resource_group_name. Please choose one.") + return processStepResult(err, s.error, state) + } var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) var location = state.Get(constants.ArmLocation).(string) var tags = state.Get(constants.ArmTags).(*map[string]*string) - s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName)) - s.say(fmt.Sprintf(" -> Location : '%s'", location)) - s.say(fmt.Sprintf(" -> Tags :")) - for k, v := range *tags { - s.say(fmt.Sprintf(" ->> %s : %s", k, *v)) - } - exists, err := s.exists(resourceGroupName) if err != nil { - s.say(s.client.LastError.Error()) + return processStepResult(err, s.error, state) } - state.Put(constants.ArmIsExistingResourceGroup, exists) + configThinksExists := state.Get(constants.ArmIsExistingResourceGroup).(bool) + if exists != configThinksExists { + if configThinksExists { + err = errors.New("The resource group you want to use does not exist yet. Please use temp_resource_group_name to create a temporary resource group.") + } else { + err = errors.New("A resource group with that name already exists. Please use build_resource_group_name to use an existing resource group.") + } + return processStepResult(err, s.error, state) + } + // If the resource group exists, we may not have permissions to update it so we don't. if !exists { + s.say("Creating resource group ...") + + s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName)) + s.say(fmt.Sprintf(" -> Location : '%s'", location)) + s.say(fmt.Sprintf(" -> Tags :")) + for k, v := range *tags { + s.say(fmt.Sprintf(" ->> %s : %s", k, *v)) + } err = s.create(resourceGroupName, location, tags) if err == nil { state.Put(constants.ArmIsResourceGroupCreated, true) } } else { - // Mark the resource group as created to deal with later checks + s.say("Using existing resource group ...") + s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName)) + s.say(fmt.Sprintf(" -> Location : '%s'", location)) state.Put(constants.ArmIsResourceGroupCreated, true) } diff --git a/builder/azure/arm/step_create_resource_group_test.go b/builder/azure/arm/step_create_resource_group_test.go index 47a4a01e6..afd47cfef 100644 --- a/builder/azure/arm/step_create_resource_group_test.go +++ b/builder/azure/arm/step_create_resource_group_test.go @@ -1,6 +1,7 @@ package arm import ( + "errors" "fmt" "testing" @@ -8,6 +9,33 @@ import ( "github.com/mitchellh/multistep" ) +func TestStepCreateResourceGroupShouldFailIfBothGroupNames(t *testing.T) { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put(constants.ArmDoubleResourceGroupNameSet, true) + + value := "Unit Test: Tags" + tags := map[string]*string{ + "tag01": &value, + } + + stateBag.Put(constants.ArmTags, &tags) + var testSubject = &StepCreateResourceGroup{ + create: func(string, string, *map[string]*string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return false, nil }, + } + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error) + } +} + func TestStepCreateResourceGroupShouldFailIfCreateFails(t *testing.T) { var testSubject = &StepCreateResourceGroup{ create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, @@ -28,6 +56,26 @@ func TestStepCreateResourceGroupShouldFailIfCreateFails(t *testing.T) { } } +func TestStepCreateResourceGroupShouldFailIfExistsFails(t *testing.T) { + var testSubject = &StepCreateResourceGroup{ + create: func(string, string, *map[string]*string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + exists: func(string) (bool, error) { return false, errors.New("FAIL") }, + } + + stateBag := createTestStateBagStepCreateResourceGroup() + + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error) + } +} + func TestStepCreateResourceGroupShouldPassIfCreatePasses(t *testing.T) { var testSubject = &StepCreateResourceGroup{ create: func(string, string, *map[string]*string) error { return nil }, @@ -94,7 +142,7 @@ func TestStepCreateResourceGroupShouldTakeStepArgumentsFromStateBag(t *testing.T } } -func TestStepCreateResourceGroupMarkAsNonExistingIfDoesntExist(t *testing.T) { +func TestStepCreateResourceGroupMarkShouldFailIfTryingExistingButDoesntExist(t *testing.T) { var testSubject = &StepCreateResourceGroup{ create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, say: func(message string) {}, @@ -102,18 +150,19 @@ func TestStepCreateResourceGroupMarkAsNonExistingIfDoesntExist(t *testing.T) { exists: func(string) (bool, error) { return false, nil }, } - stateBag := createTestStateBagStepCreateResourceGroup() + stateBag := createTestExistingStateBagStepCreateResourceGroup() - if _, ok := stateBag.GetOk(constants.ArmIsExistingResourceGroup); ok == true { - t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' not to be set, but it was") + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } - testSubject.Run(stateBag) - if stateBag.Get(constants.ArmIsExistingResourceGroup).(bool) == true { - t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' to be set to false, but it wasn't.") + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error) } } -func TestStepCreateResourceGroupMarkAsExistingIfExists(t *testing.T) { +func TestStepCreateResourceGroupMarkShouldFailIfTryingTempButExist(t *testing.T) { var testSubject = &StepCreateResourceGroup{ create: func(string, string, *map[string]*string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, say: func(message string) {}, @@ -123,12 +172,13 @@ func TestStepCreateResourceGroupMarkAsExistingIfExists(t *testing.T) { stateBag := createTestStateBagStepCreateResourceGroup() - if _, ok := stateBag.GetOk(constants.ArmIsExistingResourceGroup); ok == true { - t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' not to be set, but it was") + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } - testSubject.Run(stateBag) - if stateBag.Get(constants.ArmIsExistingResourceGroup).(bool) == false { - t.Fatalf("Expected 'constants.ArmIsExistingResourceGroup' to be set to true, but it wasn't.") + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error) } } @@ -137,6 +187,23 @@ func createTestStateBagStepCreateResourceGroup() multistep.StateBag { stateBag.Put(constants.ArmLocation, "Unit Test: Location") stateBag.Put(constants.ArmResourceGroupName, "Unit Test: ResourceGroupName") + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + + value := "Unit Test: Tags" + tags := map[string]*string{ + "tag01": &value, + } + + stateBag.Put(constants.ArmTags, &tags) + return stateBag +} + +func createTestExistingStateBagStepCreateResourceGroup() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put(constants.ArmLocation, "Unit Test: Location") + stateBag.Put(constants.ArmResourceGroupName, "Unit Test: ResourceGroupName") + stateBag.Put(constants.ArmIsExistingResourceGroup, true) value := "Unit Test: Tags" tags := map[string]*string{ diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index 6c56ac96d..af5e2fa9b 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -42,7 +42,6 @@ func (s *StepDeleteOSDisk) deleteBlob(storageContainerName string, blobName stri } func (s *StepDeleteOSDisk) deleteManagedDisk(resourceGroupName string, imageName string) error { - s.say("In the deleting part") xs := strings.Split(imageName, "/") diskName := xs[len(xs)-1] _, errChan := s.client.DisksClient.Delete(resourceGroupName, diskName, nil) @@ -70,15 +69,14 @@ func (s *StepDeleteOSDisk) Run(state multistep.StateBag) multistep.StepAction { err = s.deleteManaged(resourceGroupName, osDisk) if err != nil { s.say("Failed to delete the managed OS Disk!") - return multistep.ActionHalt + return processStepResult(err, s.error, state) } - s.say("After deleting") return multistep.ActionContinue } u, err := url.Parse(osDisk) if err != nil { s.say("Failed to parse the OS Disk's VHD URI!") - return multistep.ActionHalt + return processStepResult(err, s.error, state) } xs := strings.Split(u.Path, "/") diff --git a/builder/azure/arm/step_delete_os_disk_test.go b/builder/azure/arm/step_delete_os_disk_test.go index e19f0e0ba..7fdd7468e 100644 --- a/builder/azure/arm/step_delete_os_disk_test.go +++ b/builder/azure/arm/step_delete_os_disk_test.go @@ -1,6 +1,7 @@ package arm import ( + "errors" "fmt" "testing" @@ -103,6 +104,77 @@ func TestStepDeleteOSDiskShouldHandleComplexStorageContainerNames(t *testing.T) } } +func TestStepDeleteOSDiskShouldPassIfManagedDiskInTempResourceGroup(t *testing.T) { + var testSubject = &StepDeleteOSDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmOSDiskVhd, "subscriptions/123-456-789/resourceGroups/existingresourcegroup/providers/Microsoft.Compute/disks/osdisk") + stateBag.Put(constants.ArmIsManagedImage, true) + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + var result = testSubject.Run(stateBag) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == true { + t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepDeleteOSDiskShouldFailIfManagedDiskInExistingResourceGroupFailsToDelete(t *testing.T) { + var testSubject = &StepDeleteOSDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return errors.New("UNIT TEST FAIL!") }, + } + + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmOSDiskVhd, "subscriptions/123-456-789/resourceGroups/existingresourcegroup/providers/Microsoft.Compute/disks/osdisk") + stateBag.Put(constants.ArmIsManagedImage, true) + stateBag.Put(constants.ArmIsExistingResourceGroup, true) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to not stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepDeleteOSDiskShouldFailIfManagedDiskInExistingResourceGroupIsDeleted(t *testing.T) { + var testSubject = &StepDeleteOSDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return nil }, + } + + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmOSDiskVhd, "subscriptions/123-456-789/resourceGroups/existingresourcegroup/providers/Microsoft.Compute/disks/osdisk") + stateBag.Put(constants.ArmIsManagedImage, true) + stateBag.Put(constants.ArmIsExistingResourceGroup, true) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + var result = testSubject.Run(stateBag) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == true { + t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error) + } +} + func DeleteTestStateBagStepDeleteOSDisk(osDiskVhd string) multistep.StateBag { stateBag := new(multistep.BasicStateBag) stateBag.Put(constants.ArmOSDiskVhd, osDiskVhd) diff --git a/builder/azure/common/constants/stateBag.go b/builder/azure/common/constants/stateBag.go index 1df94a8f0..6d5a93068 100644 --- a/builder/azure/common/constants/stateBag.go +++ b/builder/azure/common/constants/stateBag.go @@ -23,6 +23,7 @@ const ( ArmPublicIPAddressName string = "arm.PublicIPAddressName" ArmResourceGroupName string = "arm.ResourceGroupName" ArmIsResourceGroupCreated string = "arm.IsResourceGroupCreated" + ArmDoubleResourceGroupNameSet string = "arm.DoubleResourceGroupNameSet" ArmStorageAccountName string = "arm.StorageAccountName" ArmTags string = "arm.Tags" ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters" From 7e0b37dc9ad8fe8687c527d8931d1d91582db878 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 10:28:32 -0800 Subject: [PATCH 0174/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb89b9044..ff531e890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * builder/docker: Remove `login_email`, which no longer exists in the docker client. [GH-5511] * builder/triton: Fix a bug where partially created images can be reported as complete. [GH-5566] +* builder/amazon: region is set from profile, if profile is set, rather than being overridden by metadata [GH-5562] ## 1.1.1 (October 13, 2017) From d71bc34dfc1be82c9bc89dc75329c3fb7def369e Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 11:49:12 -0800 Subject: [PATCH 0175/1007] don't need this in a loop --- provisioner/windows-restart/provisioner.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index e3cb1d119..48a3cb50a 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -175,6 +175,13 @@ WaitLoop: var waitForCommunicator = func(p *Provisioner) error { runCustomRestartCheck := true + if p.config.RestartCheckCommand == DefaultRestartCheckCommand { + runCustomRestartCheck = false + } + // this is the user configurable command + cmdRestartCheck := &packer.RemoteCmd{Command: p.config.RestartCheckCommand} + log.Printf("Checking that communicator is connected with: '%s'", + cmdRestartCheck.Command) for { select { case <-p.cancel: @@ -183,16 +190,8 @@ var waitForCommunicator = func(p *Provisioner) error { case <-time.After(retryableSleep): } if runCustomRestartCheck == true { - if p.config.RestartCheckCommand == DefaultRestartCheckCommand { - runCustomRestartCheck = false - } - // this is the user configurable command - cmdRestartCheck := &packer.RemoteCmd{Command: p.config.RestartCheckCommand} - log.Printf("Checking that communicator is connected with: '%s'", - cmdRestartCheck.Command) // run user-configured restart check err := cmdRestartCheck.StartWithUi(p.comm, p.ui) - if err != nil { log.Printf("Communication connection err: %s", err) continue From a739623d9b3232acd1a6e46642a3caefe8652d6b Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 14:44:26 -0800 Subject: [PATCH 0176/1007] don't pipe restarted stuff through the ui --- provisioner/windows-restart/provisioner.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 48a3cb50a..cd261da56 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -3,7 +3,7 @@ package restart import ( "bytes" "fmt" - "io" + "log" "strings" "sync" @@ -201,13 +201,18 @@ var waitForCommunicator = func(p *Provisioner) error { } // this is the non-user-configurable check that powershell // modules have loaded - cmdModuleLoad := &packer.RemoteCmd{Command: DefaultRestartCheckCommand} - var buf, buf2 bytes.Buffer - cmdModuleLoad.Stdout = &buf - cmdModuleLoad.Stdout = io.MultiWriter(cmdModuleLoad.Stdout, &buf2) + var buf bytes.Buffer + cmdModuleLoad := &packer.RemoteCmd{ + Command: DefaultRestartCheckCommand, + Stdin: nil, + Stdout: &buf, + Stderr: &buf} - cmdModuleLoad.StartWithUi(p.comm, p.ui) - stdoutToRead := buf2.String() + // cmdModuleLoad.StartWithUi(p.comm, p.ui) + p.comm.Start(cmdModuleLoad) + cmdModuleLoad.Wait() + + stdoutToRead := buf.String() if !strings.Contains(stdoutToRead, "restarted.") { log.Printf("echo didn't succeed; retrying...") continue From e56a6dc9a0d0e050d82bd6651175aa9670904e4f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 14:55:12 -0800 Subject: [PATCH 0177/1007] add some comments --- provisioner/windows-restart/provisioner.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index cd261da56..c87c3a4bb 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -178,7 +178,10 @@ var waitForCommunicator = func(p *Provisioner) error { if p.config.RestartCheckCommand == DefaultRestartCheckCommand { runCustomRestartCheck = false } - // this is the user configurable command + // This command is configurable by the user to make sure that the + // vm has met their necessary criteria for having restarted. If the + // user doesn't set a special restart command, we just run the + // default as cmdModuleLoad below. cmdRestartCheck := &packer.RemoteCmd{Command: p.config.RestartCheckCommand} log.Printf("Checking that communicator is connected with: '%s'", cmdRestartCheck.Command) @@ -199,8 +202,16 @@ var waitForCommunicator = func(p *Provisioner) error { log.Printf("Connected to machine") runCustomRestartCheck = false } - // this is the non-user-configurable check that powershell - // modules have loaded + + // This is the non-user-configurable check that powershell + // modules have loaded. + + // If we catch the restart in just the right place, we will be able + // to run the restart check but the output will be an error message + // about how it needs powershell modules to load, and we will start + // provisioning before powershell is actually ready. + // In this next check, we parse stdout to make sure that the command is + // actually running as expected. var buf bytes.Buffer cmdModuleLoad := &packer.RemoteCmd{ Command: DefaultRestartCheckCommand, From 73b6247fd2450384b55afe9910e7c5796a555f03 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 15:04:25 -0800 Subject: [PATCH 0178/1007] remove unnecessary boolean operator --- provisioner/windows-restart/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index c87c3a4bb..cfa4df5e0 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -192,7 +192,7 @@ var waitForCommunicator = func(p *Provisioner) error { return fmt.Errorf("Communicator wait canceled") case <-time.After(retryableSleep): } - if runCustomRestartCheck == true { + if runCustomRestartCheck { // run user-configured restart check err := cmdRestartCheck.StartWithUi(p.comm, p.ui) if err != nil { From 6019e415441e2e4d8d812c15e3e9137df71bb053 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 15:18:43 -0800 Subject: [PATCH 0179/1007] dont read stderr --- provisioner/windows-restart/provisioner.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index cfa4df5e0..4107fea1b 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -216,10 +216,8 @@ var waitForCommunicator = func(p *Provisioner) error { cmdModuleLoad := &packer.RemoteCmd{ Command: DefaultRestartCheckCommand, Stdin: nil, - Stdout: &buf, - Stderr: &buf} + Stdout: &buf} - // cmdModuleLoad.StartWithUi(p.comm, p.ui) p.comm.Start(cmdModuleLoad) cmdModuleLoad.Wait() From e073d63f3016ef326c0bca7315af37bd8b1b464e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 9 Nov 2017 15:20:37 -0800 Subject: [PATCH 0180/1007] remove racy reuse of single buffer for remotecmd stderr/out. --- provisioner/converge/provisioner.go | 12 +++++++----- provisioner/salt-masterless/provisioner.go | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/provisioner/converge/provisioner.go b/provisioner/converge/provisioner.go index 924cfa493..0b8b93e5d 100644 --- a/provisioner/converge/provisioner.go +++ b/provisioner/converge/provisioner.go @@ -144,12 +144,12 @@ func (p *Provisioner) maybeBootstrap(ui packer.Ui, comm packer.Communicator) err return fmt.Errorf("Could not interpolate bootstrap command: %s", err) } - var out bytes.Buffer + var out, outErr bytes.Buffer cmd := &packer.RemoteCmd{ Command: command, Stdin: nil, Stdout: &out, - Stderr: &out, + Stderr: &outErr, } if err = comm.Start(cmd); err != nil { @@ -159,6 +159,7 @@ func (p *Provisioner) maybeBootstrap(ui packer.Ui, comm packer.Communicator) err cmd.Wait() if cmd.ExitStatus != 0 { ui.Error(out.String()) + ui.Error(outErr.String()) return errors.New("Error bootstrapping converge") } @@ -199,12 +200,12 @@ func (p *Provisioner) applyModules(ui packer.Ui, comm packer.Communicator) error } // run Converge in the specified directory - var runOut bytes.Buffer + var runOut, runErr bytes.Buffer cmd := &packer.RemoteCmd{ Command: command, Stdin: nil, Stdout: &runOut, - Stderr: &runOut, + Stderr: &runErr, } if err := comm.Start(cmd); err != nil { return fmt.Errorf("Error applying %q: %s", p.config.Module, err) @@ -221,7 +222,8 @@ func (p *Provisioner) applyModules(ui packer.Ui, comm packer.Communicator) error } else if cmd.ExitStatus != 0 { ui.Error(strings.TrimSpace(runOut.String())) - ui.Error(fmt.Sprintf("exited with error code %d", cmd.ExitStatus)) + ui.Error(strings.TrimSpace(runErr.String())) + ui.Error(fmt.Sprintf("Exited with error code %d.", cmd.ExitStatus)) return fmt.Errorf("Error applying %q", p.config.Module) } diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 5c67feb07..dad5f7109 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -312,7 +312,7 @@ func (p *Provisioner) sudo(cmd string) string { } func validateDirConfig(path string, name string, required bool) error { - if required == true && path == "" { + if required && path == "" { return fmt.Errorf("%s cannot be empty", name) } else if required == false && path == "" { return nil From 9b1ae530c34c4461402a43f9c7e89b302a6d5440 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 15:35:28 -0800 Subject: [PATCH 0181/1007] have separate stdout and stderr buffers --- provisioner/windows-restart/provisioner.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 4107fea1b..6d227524a 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -212,16 +212,17 @@ var waitForCommunicator = func(p *Provisioner) error { // provisioning before powershell is actually ready. // In this next check, we parse stdout to make sure that the command is // actually running as expected. - var buf bytes.Buffer + var stdout, stderr bytes.Buffer cmdModuleLoad := &packer.RemoteCmd{ Command: DefaultRestartCheckCommand, Stdin: nil, - Stdout: &buf} + Stdout: &stdout, + Stderr: &stderr} p.comm.Start(cmdModuleLoad) cmdModuleLoad.Wait() - stdoutToRead := buf.String() + stdoutToRead := stdout.String() if !strings.Contains(stdoutToRead, "restarted.") { log.Printf("echo didn't succeed; retrying...") continue From c3cb7fe9f9729ced8725d989e0c7be0ef278aca4 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 9 Nov 2017 15:52:49 -0800 Subject: [PATCH 0182/1007] read from stderr so it doesnt lock up --- provisioner/windows-restart/provisioner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 6d227524a..3b03cf116 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -223,7 +223,9 @@ var waitForCommunicator = func(p *Provisioner) error { cmdModuleLoad.Wait() stdoutToRead := stdout.String() + stderrToRead := stderr.String() if !strings.Contains(stdoutToRead, "restarted.") { + log.Printf("Stderr is %s", stderrToRead) log.Printf("echo didn't succeed; retrying...") continue } From f43f3155d4a0d11089977460def7e9f65d063879 Mon Sep 17 00:00:00 2001 From: Arjen Schwarz <arjen.schwarz@bulletproof.net> Date: Fri, 10 Nov 2017 11:04:31 +1100 Subject: [PATCH 0183/1007] Remove breaking debug statement --- builder/azure/arm/step_delete_resource_group.go | 1 - 1 file changed, 1 deletion(-) diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index 28b7c4142..1c299ad7c 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -83,7 +83,6 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, return err } else { _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) - s.say(state.Get(constants.ArmIsExistingResourceGroup).(string)) err = <-errChan if err != nil { From 79fcd40bfcafad3c3fb45273b0746c983d69d2c6 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 10 Nov 2017 11:11:27 -0800 Subject: [PATCH 0184/1007] update changelog --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff531e890..dfdab519f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,12 +13,23 @@ * communicator/ssh: Add socks 5 proxy support. [GH-5439] * builder/lxc: Add new `publish_properties` field to set image properties. [GH-5475] * builder/virtualbox-ovf: Retry while removing VM to solve for transient errors. [GH-5512] +* builder/google: Interpolate network and subnetwork values, rather than relying on an API call that packer may not have permission for. [GH-5343] +* builder/lxc: Add three new configuration option categories to LXC builder: create_options, start_options, and attach_options. [GH-5530] +* core: Rewrite vagrantfile code to make cross-platform development easier. [5539] +* builder/triton: Update triton-go sdk. [GH-5531] +* builder/google: Add clean_image_name template engine. [GH-5463] ### BUG FIXES: * builder/docker: Remove `login_email`, which no longer exists in the docker client. [GH-5511] * builder/triton: Fix a bug where partially created images can be reported as complete. [GH-5566] -* builder/amazon: region is set from profile, if profile is set, rather than being overridden by metadata [GH-5562] +* builder/amazon: region is set from profile, if profile is set, rather than being overridden by metadata. [GH-5562] +* provisioner/windows-restart: Wait for restart no longer endlessly loops if user specifies a custom restart check command. [GH-5563] +* post-processor/vsphere: Use the vm disk path information to re-create the vmx datastore path. [GH-5567] +* builder/amazon: Add a delay option to security group waiter. [GH-5536] +* builder/amazon: Fix regressions relating to spot instances and EBS volumes. [GH-5495] +* builder/hyperv: Fix admin check that was causing powershell failures. [GH-5510] +* builder/oracle: Defaulting of OCI builder region will first check the packer template and the OCI config file. [GH-5407] ## 1.1.1 (October 13, 2017) From b754b715191920cc40e2a2e69e20b2f491cf903e Mon Sep 17 00:00:00 2001 From: bugbuilder <nelson@bennu.cl> Date: Fri, 10 Nov 2017 22:57:39 -0300 Subject: [PATCH 0185/1007] return vsphere artifact to can build template --- .../vsphere-template/step_mark_as_template.go | 13 +++++++------ post-processor/vsphere/post-processor.go | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index 8f95ba4d6..2ffe46956 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -27,6 +27,7 @@ func NewStepMarkAsTemplate(artifact packer.Artifact) *stepMarkAsTemplate { if artifact.BuilderId() == vsphere.BuilderId { id := strings.Split(artifact.Id(), "::") remoteFolder = id[1] + vmname = id[2] } return &stepMarkAsTemplate{ @@ -50,12 +51,6 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } - if err := unregisterPreviousVM(cli, folder, s.VMName); err != nil { - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - dsPath, err := datastorePath(vm) if err != nil { state.Put("error", err) @@ -76,6 +71,12 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } + if err := unregisterPreviousVM(cli, folder, s.VMName); err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + task, err := folder.RegisterVM(context.Background(), dsPath.String(), s.VMName, true, nil, host) if err != nil { state.Put("error", err) diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index c028cd087..b9702fe82 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -140,6 +140,8 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message(p.filterLog(out.String())) + artifact = NewArtifact(p.config.Datastore, p.config.VMFolder, p.config.VMName, artifact.Files()) + return artifact, false, nil } From f0299ba713bd62a1517397f496815ddd8fdfa8b3 Mon Sep 17 00:00:00 2001 From: Daniel Hess <dan9186@gmail.com> Date: Sun, 12 Nov 2017 00:45:22 -0800 Subject: [PATCH 0186/1007] Adding GCE container optimized os image project --- builder/googlecompute/driver_gce.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 69af625e9..44dcb85c6 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -170,7 +170,7 @@ func (d *driverGCE) DeleteDisk(zone, name string) (<-chan error, error) { } func (d *driverGCE) GetImage(name string, fromFamily bool) (*Image, error) { - projects := []string{d.projectId, "centos-cloud", "coreos-cloud", "debian-cloud", "google-containers", "opensuse-cloud", "rhel-cloud", "suse-cloud", "ubuntu-os-cloud", "windows-cloud", "gce-nvme"} + projects := []string{d.projectId, "centos-cloud", "coreos-cloud", "cos-cloud", "debian-cloud", "google-containers", "opensuse-cloud", "rhel-cloud", "suse-cloud", "ubuntu-os-cloud", "windows-cloud", "gce-nvme"} var errs error for _, project := range projects { image, err := d.GetImageFromProject(project, name, fromFamily) From ec6d6098de256f1db5b7db6977d1f350e49cc3fb Mon Sep 17 00:00:00 2001 From: Rickard von Essen <rickard.von.essen@gmail.com> Date: Sun, 12 Nov 2017 10:48:04 +0100 Subject: [PATCH 0187/1007] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfdab519f..3787a54aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * core: Rewrite vagrantfile code to make cross-platform development easier. [5539] * builder/triton: Update triton-go sdk. [GH-5531] * builder/google: Add clean_image_name template engine. [GH-5463] +* builder/google: Allow Selecting Container Optimized Images. [GH-5576] ### BUG FIXES: From 853b04420c83fed3daa1de54404c94a80a63c3f6 Mon Sep 17 00:00:00 2001 From: Pavel Boldin <pboldin@cloudlinux.com> Date: Mon, 6 Nov 2017 00:32:39 +0100 Subject: [PATCH 0188/1007] iso_config: allow for subdirs in hash sum files Allow hash sum files and ISOs to be in different directories as Ubuntu does. Signed-off-by: Pavel Boldin <boldin.pavel@gmail.com> --- common/iso_config.go | 18 +++++++++++--- common/iso_config_test.go | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/common/iso_config.go b/common/iso_config.go index 1ddb78d17..5216dc458 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -140,9 +140,20 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { if err != nil { return err } + + checksumurl, err := url.Parse(c.ISOChecksumURL) + if err != nil { + return err + } + + relpath, err := filepath.Rel(filepath.Dir(checksumurl.Path), u.Path) + if err != nil { + return err + } + filename := filepath.Base(u.Path) - errNotFound := fmt.Errorf("No checksum for %q found at: %s", filename, c.ISOChecksumURL) + errNotFound := fmt.Errorf("No checksum for %q or %q found at: %s", filename, relpath, c.ISOChecksumURL) for { line, err := rd.ReadString('\n') if err != nil && line == "" { @@ -154,7 +165,8 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { } if strings.ToLower(parts[0]) == c.ISOChecksumType { // BSD-style checksum - if parts[1] == fmt.Sprintf("(%s)", filename) { + if parts[1] == fmt.Sprintf("(%s)", filename) || parts[1] == fmt.Sprintf("(%s)", relpath) || + parts[1] == fmt.Sprintf("(./%s)", relpath) { c.ISOChecksum = parts[3] return nil } @@ -164,7 +176,7 @@ func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error { // Binary mode parts[1] = parts[1][1:] } - if parts[1] == filename { + if parts[1] == filename || parts[1] == relpath || parts[1] == "./"+relpath { c.ISOChecksum = parts[0] return nil } diff --git a/common/iso_config_test.go b/common/iso_config_test.go index 7a5a0b026..f31c687b2 100644 --- a/common/iso_config_test.go +++ b/common/iso_config_test.go @@ -24,11 +24,21 @@ MD5 (other.iso) = bAr MD5 (the-OS.iso) = baZ ` +var cs_bsd_style_subdir = ` +MD5 (other.iso) = bAr +MD5 (./subdir/the-OS.iso) = baZ +` + var cs_gnu_style = ` bAr0 *the-OS.iso baZ0 other.iso ` +var cs_gnu_style_subdir = ` +bAr0 *./subdir/the-OS.iso +baZ0 other.iso +` + var cs_bsd_style_no_newline = ` MD5 (other.iso) = bAr MD5 (the-OS.iso) = baZ` @@ -134,6 +144,27 @@ func TestISOConfigPrepare_ISOChecksumURL(t *testing.T) { t.Fatalf("should've found \"baz\" got: %s", i.ISOChecksum) } + // Test good - ISOChecksumURL BSD style with relative path + i = testISOConfig() + i.ISOChecksum = "" + + cs_dir, _ := ioutil.TempDir("", "packer-testdir-") + cs_file, _ = ioutil.TempFile(cs_dir, "packer-test-") + ioutil.WriteFile(cs_file.Name(), []byte(cs_bsd_style_subdir), 0666) + i.ISOChecksumURL = fmt.Sprintf("%s%s", filePrefix, cs_file.Name()) + i.RawSingleISOUrl = fmt.Sprintf("%s%s", cs_dir, "/subdir/the-OS.iso") + warns, err = i.Prepare(nil) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if i.ISOChecksum != "baz" { + t.Fatalf("should've found \"baz\" got: %s", i.ISOChecksum) + } + // Test good - ISOChecksumURL GNU style no newline i = testISOConfig() i.ISOChecksum = "" @@ -171,6 +202,26 @@ func TestISOConfigPrepare_ISOChecksumURL(t *testing.T) { if i.ISOChecksum != "bar0" { t.Fatalf("should've found \"bar0\" got: %s", i.ISOChecksum) } + + // Test good - ISOChecksumURL GNU style with relative path + i = testISOConfig() + i.ISOChecksum = "" + + cs_file, _ = ioutil.TempFile(cs_dir, "packer-test-") + ioutil.WriteFile(cs_file.Name(), []byte(cs_gnu_style_subdir), 0666) + i.ISOChecksumURL = fmt.Sprintf("%s%s", filePrefix, cs_file.Name()) + i.RawSingleISOUrl = fmt.Sprintf("%s%s", cs_dir, "/subdir/the-OS.iso") + warns, err = i.Prepare(nil) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if i.ISOChecksum != "bar0" { + t.Fatalf("should've found \"bar0\" got: %s", i.ISOChecksum) + } } func TestISOConfigPrepare_ISOChecksumType(t *testing.T) { From 487ceac7845c53caa72e7403a2e5fec759f68e7c Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 13 Nov 2017 11:45:31 -0800 Subject: [PATCH 0189/1007] fix Vet error. --- post-processor/vsphere-template/step_mark_as_template.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index 7dc9211fa..dffc871ca 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -100,7 +100,10 @@ func datastorePath(vm *object.VirtualMachine) (*object.DatastorePath, error) { datastore := re.FindStringSubmatch(disk)[1] vmxPath := path.Join("/", path.Dir(strings.Split(disk, " ")[1]), vm.Name()+".vmx") - return &object.DatastorePath{datastore, vmxPath}, nil + return &object.DatastorePath{ + Datastore: datastore, + Path: vmxPath, + }, nil } // We will use the virtual machine created by vmware-iso builder From e45a006d619eeb99e3997be2117077b0c82f2ae8 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 10 Nov 2017 16:30:08 -0800 Subject: [PATCH 0190/1007] clearly state that url is wrong at validation stage of build --- common/config.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/config.go b/common/config.go index cc7eced6a..02b214902 100644 --- a/common/config.go +++ b/common/config.go @@ -131,5 +131,12 @@ func DownloadableURL(original string) (string, error) { return "", fmt.Errorf("Unsupported URL scheme: %s", url.Scheme) } + // if cleaned filepath does not exist, error out now. + if url.Scheme == "file" { + if _, err := os.Stat(url.Path); err != nil { + return "", fmt.Errorf("The filepath doesn't exist either as a "+ + "relative or an absolute path: %s", err) + } + } return url.String(), nil } From 3a9dfb5b1897bc3fd795ca1e837bd7dd419221eb Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 10 Nov 2017 16:45:06 -0800 Subject: [PATCH 0191/1007] better --- common/config.go | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/common/config.go b/common/config.go index 02b214902..572f2afa4 100644 --- a/common/config.go +++ b/common/config.go @@ -96,6 +96,8 @@ func DownloadableURL(original string) (string, error) { } url.Path = filepath.Clean(url.Path) + } else { + return "", err } if runtime.GOOS == "windows" { @@ -109,14 +111,6 @@ func DownloadableURL(original string) (string, error) { // Make sure it is lowercased url.Scheme = strings.ToLower(url.Scheme) - // This is to work around issue #5927. This can safely be removed once - // we distribute with a version of Go that fixes that bug. - // - // See: https://code.google.com/p/go/issues/detail?id=5927 - if url.Path != "" && url.Path[0] != '/' { - url.Path = "/" + url.Path - } - // Verify that the scheme is something we support in our common downloader. supported := []string{"file", "http", "https"} found := false @@ -131,12 +125,5 @@ func DownloadableURL(original string) (string, error) { return "", fmt.Errorf("Unsupported URL scheme: %s", url.Scheme) } - // if cleaned filepath does not exist, error out now. - if url.Scheme == "file" { - if _, err := os.Stat(url.Path); err != nil { - return "", fmt.Errorf("The filepath doesn't exist either as a "+ - "relative or an absolute path: %s", err) - } - } return url.String(), nil } From 0efcb1bba21ec8fe09a081f72076e33d186c5da0 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 13 Nov 2017 10:53:17 -0800 Subject: [PATCH 0192/1007] dont error in the downloadableURL function; save validation for preflight steps --- common/config.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/config.go b/common/config.go index 572f2afa4..490553388 100644 --- a/common/config.go +++ b/common/config.go @@ -96,8 +96,6 @@ func DownloadableURL(original string) (string, error) { } url.Path = filepath.Clean(url.Path) - } else { - return "", err } if runtime.GOOS == "windows" { From 0d18de29428094689e3909ce21fd62b4e51ec06d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 13 Nov 2017 11:44:59 -0800 Subject: [PATCH 0193/1007] do validation in vmx config stage --- builder/virtualbox/ovf/config.go | 8 ++++++++ builder/virtualbox/ovf/config_test.go | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 77b7ffa0e..ff8080dd7 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -2,6 +2,7 @@ package ovf import ( "fmt" + "os" "strings" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" @@ -101,6 +102,13 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { if err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) } + // file must exist now. + if (len(c.SourcePath) > 7) && (c.SourcePath[:7] == "file://") { + if _, err := os.Stat(c.SourcePath[7:]); err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("source file needs to exist at time of config validation: %s", err)) + } + } } validMode := false diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index 980c4d4ef..bdab9b763 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -65,14 +65,14 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("should error with empty `source_path`") } - // Okay, because it gets caught during download + // Want this to fail on validation c = testConfig(t) c["source_path"] = "/i/dont/exist" _, warns, err = NewConfig(c) if len(warns) > 0 { t.Fatalf("bad: %#v", warns) } - if err != nil { + if err == nil { t.Fatalf("bad: %s", err) } @@ -84,7 +84,7 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("bad: %#v", warns) } if err == nil { - t.Fatal("should error") + t.Fatal("Nonexistent source file should be caught in validation") } // Good From 764be03876808d20f4b45a3bcf6c9063160b2d02 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 13 Nov 2017 12:42:20 -0800 Subject: [PATCH 0194/1007] didn't mean for this error message to get changed --- builder/virtualbox/ovf/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index bdab9b763..0724968d3 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -84,7 +84,7 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("bad: %#v", warns) } if err == nil { - t.Fatal("Nonexistent source file should be caught in validation") + t.Fatal("should error") } // Good From 771349e58c9a350463678e76a63a46bb2979bc70 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 13 Nov 2017 12:52:47 -0800 Subject: [PATCH 0195/1007] fix error message --- builder/virtualbox/ovf/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index 0724968d3..5e67b242d 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -73,7 +73,7 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("bad: %#v", warns) } if err == nil { - t.Fatalf("bad: %s", err) + t.Fatalf("Nonexistant file should throw a validation error!") } // Bad From 6756df9510fcd49793ef576e5fd61760b6069981 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 13 Nov 2017 12:57:53 -0800 Subject: [PATCH 0196/1007] use url library instead of parsing string naiively --- builder/virtualbox/ovf/config.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index ff8080dd7..3e4b9b879 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -2,6 +2,7 @@ package ovf import ( "fmt" + "net/url" "os" "strings" @@ -103,8 +104,9 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) } // file must exist now. - if (len(c.SourcePath) > 7) && (c.SourcePath[:7] == "file://") { - if _, err := os.Stat(c.SourcePath[7:]); err != nil { + fileURL, _ := url.Parse(c.SourcePath) + if fileURL.Scheme == "file" { + if _, err := os.Stat(fileURL.Path); err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source file needs to exist at time of config validation: %s", err)) } From 9eacd3d61860e68f466ddb3dd6a36040fe50ca95 Mon Sep 17 00:00:00 2001 From: Brett Richardson <brett.richardson.nz@gmail.com> Date: Tue, 14 Nov 2017 13:54:13 +0000 Subject: [PATCH 0197/1007] Update chef provisioner documentation The URL has changed, see chef documentation https://docs.chef.io/install_omnibus.html --- website/source/docs/provisioners/chef-client.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/chef-client.html.md b/website/source/docs/provisioners/chef-client.html.md index 54cd5e778..dabf37ca5 100644 --- a/website/source/docs/provisioners/chef-client.html.md +++ b/website/source/docs/provisioners/chef-client.html.md @@ -212,7 +212,7 @@ readability) to install Chef. This command can be customized if you want to install Chef in another way. ``` text -curl -L https://www.chef.io/chef/install.sh | \ +curl -L https:///omnitruck.chef.io/chef/install.sh | \ {{if .Sudo}}sudo{{end}} bash ``` From 4a5bb756a72727b836932cf57216185a9ab71e80 Mon Sep 17 00:00:00 2001 From: Ladar Levison <ladar@users.noreply.github.com> Date: Tue, 14 Nov 2017 16:40:06 -0600 Subject: [PATCH 0198/1007] Docker Example Typo I think the intention was to show you can tag, and push the same image to multiple repos, but the example given is to the same repo, twice. This change updates the example so it uses hashicorp/packer1, and hashicorp/packer2. --- website/source/docs/builders/docker.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index 13c43da60..8b8e684cd 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -303,7 +303,7 @@ nearly-identical sequence definitions, as demonstrated by the example below: [ { "type": "docker-tag", - "repository": "hashicorp/packer", + "repository": "hashicorp/packer1", "tag": "0.7" }, "docker-push" @@ -311,7 +311,7 @@ nearly-identical sequence definitions, as demonstrated by the example below: [ { "type": "docker-tag", - "repository": "hashicorp/packer", + "repository": "hashicorp/packer2", "tag": "0.7" }, "docker-push" From 46f41d1f1210ad40b88a43325b02caa6130f5e8e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 19:46:03 -0700 Subject: [PATCH 0199/1007] WIP: add options to telemetry --- packer/build.go | 4 ++-- packer/provisioner.go | 2 +- packer/telemetry.go | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packer/build.go b/packer/build.go index 996c9a331..9e406ac63 100644 --- a/packer/build.go +++ b/packer/build.go @@ -221,7 +221,7 @@ func (b *coreBuild) Run(originalUi Ui, cache Cache) ([]Artifact, error) { } log.Printf("Running builder: %s", b.builderType) - ts := CheckpointReporter.AddSpan(b.builderType, "builder") + ts := CheckpointReporter.AddSpan(b.builderType, "builder", b.builderConfig) builderArtifact, err := b.builder.Run(builderUi, hook, cache) ts.End(err) if err != nil { @@ -248,7 +248,7 @@ PostProcessorRunSeqLoop: } builderUi.Say(fmt.Sprintf("Running post-processor: %s", corePP.processorType)) - ts := CheckpointReporter.AddSpan(corePP.processorType, "post-processor") + ts := CheckpointReporter.AddSpan(corePP.processorType, "post-processor", corePP.config) artifact, keep, err := corePP.processor.PostProcess(ppUi, priorArtifact) ts.End(err) if err != nil { diff --git a/packer/provisioner.go b/packer/provisioner.go index 639e8b1a8..a9782bb92 100644 --- a/packer/provisioner.go +++ b/packer/provisioner.go @@ -63,7 +63,7 @@ func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interfac h.runningProvisioner = p h.lock.Unlock() - ts := CheckpointReporter.AddSpan(h.ProvisionerTypes[i], "provisioner") + ts := CheckpointReporter.AddSpan(h.ProvisionerTypes[i], "provisioner", p) err := p.Provision(ui, comm) ts.End(err) if err != nil { diff --git a/packer/telemetry.go b/packer/telemetry.go index 7224de582..60005e606 100644 --- a/packer/telemetry.go +++ b/packer/telemetry.go @@ -11,7 +11,7 @@ import ( packerVersion "github.com/hashicorp/packer/version" ) -const TelemetryVersion string = "beta/packer/4" +const TelemetryVersion string = "beta/packer/5" const TelemetryPanicVersion string = "beta/packer_panic/4" var CheckpointReporter *CheckpointTelemetry @@ -85,11 +85,18 @@ func (c *CheckpointTelemetry) ReportPanic(m string) error { return checkpoint.Report(ctx, panicParams) } -func (c *CheckpointTelemetry) AddSpan(name, pluginType string) *TelemetrySpan { +func (c *CheckpointTelemetry) AddSpan(name, pluginType string, options interface{}) *TelemetrySpan { if c == nil { return nil } log.Printf("[INFO] (telemetry) Starting %s %s", pluginType, name) + + //strOpts := []string{} + if m, ok := options.(map[string]interface{}); ok { + for k, _ := range m { + log.Println("AddSpan options:", k) + } + } ts := &TelemetrySpan{ Name: name, Type: pluginType, @@ -130,6 +137,7 @@ type TelemetrySpan struct { StartTime time.Time `json:"start_time"` EndTime time.Time `json:"end_time"` Error string `json:"error"` + Options []string `json:"options"` } func (s *TelemetrySpan) End(err error) { From 3e3768ec3e84928500d68614d2347f6a8bec7df9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 23:31:32 -0700 Subject: [PATCH 0200/1007] fix tests --- packer/build.go | 10 +--------- packer/provisioner.go | 17 +++++++++++------ packer/provisioner_test.go | 17 +++++++++++------ 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/packer/build.go b/packer/build.go index 9e406ac63..c99164ce8 100644 --- a/packer/build.go +++ b/packer/build.go @@ -194,20 +194,12 @@ func (b *coreBuild) Run(originalUi Ui, cache Cache) ([]Artifact, error) { // Add a hook for the provisioners if we have provisioners if len(b.provisioners) > 0 { - provisioners := make([]Provisioner, len(b.provisioners)) - provisionerTypes := make([]string, len(b.provisioners)) - for i, p := range b.provisioners { - provisioners[i] = p.provisioner - provisionerTypes[i] = p.pType - } - if _, ok := hooks[HookProvision]; !ok { hooks[HookProvision] = make([]Hook, 0, 1) } hooks[HookProvision] = append(hooks[HookProvision], &ProvisionHook{ - Provisioners: provisioners, - ProvisionerTypes: provisionerTypes, + Provisioners: b.provisioners, }) } diff --git a/packer/provisioner.go b/packer/provisioner.go index a9782bb92..dc850daa3 100644 --- a/packer/provisioner.go +++ b/packer/provisioner.go @@ -30,8 +30,7 @@ type Provisioner interface { type ProvisionHook struct { // The provisioners to run as part of the hook. These should already // be prepared (by calling Prepare) at some earlier stage. - Provisioners []Provisioner - ProvisionerTypes []string + Provisioners []coreBuildProvisioner lock sync.Mutex runningProvisioner Provisioner @@ -58,13 +57,19 @@ func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interfac h.runningProvisioner = nil }() - for i, p := range h.Provisioners { + for _, p := range h.Provisioners { h.lock.Lock() - h.runningProvisioner = p + h.runningProvisioner = p.provisioner h.lock.Unlock() - ts := CheckpointReporter.AddSpan(h.ProvisionerTypes[i], "provisioner", p) - err := p.Provision(ui, comm) + var pConfig interface{} + if len(p.config) > 0 { + pConfig = p.config[0] + } + ts := CheckpointReporter.AddSpan(p.pType, "provisioner", pConfig) + + err := p.provisioner.Provision(ui, comm) + ts.End(err) if err != nil { return err diff --git a/packer/provisioner_test.go b/packer/provisioner_test.go index f303bc7d2..8e79d2f81 100644 --- a/packer/provisioner_test.go +++ b/packer/provisioner_test.go @@ -23,8 +23,10 @@ func TestProvisionHook(t *testing.T) { var data interface{} = nil hook := &ProvisionHook{ - Provisioners: []Provisioner{pA, pB}, - ProvisionerTypes: []string{"", ""}, + Provisioners: []coreBuildProvisioner{ + {"", pA, nil}, + {"", pB, nil}, + }, } hook.Run("foo", ui, comm, data) @@ -47,8 +49,10 @@ func TestProvisionHook_nilComm(t *testing.T) { var data interface{} = nil hook := &ProvisionHook{ - Provisioners: []Provisioner{pA, pB}, - ProvisionerTypes: []string{"", ""}, + Provisioners: []coreBuildProvisioner{ + {"", pA, nil}, + {"", pB, nil}, + }, } err := hook.Run("foo", ui, comm, data) @@ -74,8 +78,9 @@ func TestProvisionHook_cancel(t *testing.T) { } hook := &ProvisionHook{ - Provisioners: []Provisioner{p}, - ProvisionerTypes: []string{""}, + Provisioners: []coreBuildProvisioner{ + {"", p, nil}, + }, } finished := make(chan struct{}) From a5197840dfa4fd3925b508614bc4b46bf01e9bef Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 23:45:01 -0700 Subject: [PATCH 0201/1007] add config key reporting --- packer/telemetry.go | 39 +++++++++++++++++++++++++++++---------- packer/telemetry_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 packer/telemetry_test.go diff --git a/packer/telemetry.go b/packer/telemetry.go index 60005e606..f413dd34a 100644 --- a/packer/telemetry.go +++ b/packer/telemetry.go @@ -91,16 +91,11 @@ func (c *CheckpointTelemetry) AddSpan(name, pluginType string, options interface } log.Printf("[INFO] (telemetry) Starting %s %s", pluginType, name) - //strOpts := []string{} - if m, ok := options.(map[string]interface{}); ok { - for k, _ := range m { - log.Println("AddSpan options:", k) - } - } ts := &TelemetrySpan{ Name: name, - Type: pluginType, + Options: flattenConfigKeys(options), StartTime: time.Now().UTC(), + Type: pluginType, } c.spans = append(c.spans, ts) return ts @@ -123,6 +118,8 @@ func (c *CheckpointTelemetry) Finalize(command string, errCode int, err error) e extra.Error = err.Error() } params.Payload = extra + // b, _ := json.MarshalIndent(params, "", " ") + // log.Println(string(b)) ctx, cancel := context.WithTimeout(context.Background(), 1500*time.Millisecond) defer cancel() @@ -132,12 +129,12 @@ func (c *CheckpointTelemetry) Finalize(command string, errCode int, err error) e } type TelemetrySpan struct { - Name string `json:"name"` - Type string `json:"type"` - StartTime time.Time `json:"start_time"` EndTime time.Time `json:"end_time"` Error string `json:"error"` + Name string `json:"name"` Options []string `json:"options"` + StartTime time.Time `json:"start_time"` + Type string `json:"type"` } func (s *TelemetrySpan) End(err error) { @@ -151,3 +148,25 @@ func (s *TelemetrySpan) End(err error) { log.Printf("[INFO] (telemetry) found error: %s", err.Error()) } } + +func flattenConfigKeys(options interface{}) []string { + var flatten func(string, interface{}) []string + + flatten = func(prefix string, options interface{}) (strOpts []string) { + if m, ok := options.(map[string]interface{}); ok { + for k, v := range m { + if prefix != "" { + k = prefix + "/" + k + } + if n, ok := v.(map[string]interface{}); ok { + strOpts = append(strOpts, flatten(k, n)...) + } else { + strOpts = append(strOpts, k) + } + } + } + return + } + + return flatten("", options) +} diff --git a/packer/telemetry_test.go b/packer/telemetry_test.go new file mode 100644 index 000000000..c4192f61f --- /dev/null +++ b/packer/telemetry_test.go @@ -0,0 +1,32 @@ +package packer + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFlattenConfigKeys_nil(t *testing.T) { + f := flattenConfigKeys(nil) + assert.Zero(t, f, "Expected empty list.") +} + +func TestFlattenConfigKeys_nested(t *testing.T) { + inp := make(map[string]interface{}) + inp["A"] = "" + inp["B"] = []string{} + + c := make(map[string]interface{}) + c["X"] = "" + d := make(map[string]interface{}) + d["a"] = "" + + c["Y"] = d + inp["C"] = c + + assert.Equal(t, + []string{"A", "B", "C/X", "C/Y/a"}, + flattenConfigKeys(inp), + "Input didn't flatten correctly.", + ) +} From 49c20e3b1cbd4fb0a8f09965926c5da72f465b97 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 2 Nov 2017 23:54:03 -0700 Subject: [PATCH 0202/1007] bump telemetry timeout to 2s --- packer/telemetry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/telemetry.go b/packer/telemetry.go index f413dd34a..13931d419 100644 --- a/packer/telemetry.go +++ b/packer/telemetry.go @@ -121,7 +121,7 @@ func (c *CheckpointTelemetry) Finalize(command string, errCode int, err error) e // b, _ := json.MarshalIndent(params, "", " ") // log.Println(string(b)) - ctx, cancel := context.WithTimeout(context.Background(), 1500*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() log.Printf("[INFO] (telemetry) Finalizing.") From b07a0cd6f06692046684c7a1b9166d074b15dd8b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sat, 4 Nov 2017 13:06:36 -0700 Subject: [PATCH 0203/1007] fix tests always sort telemetry options --- builder/docker/communicator_test.go | 31 ++-- packer/build.go | 15 +- packer/provisioner.go | 19 +- packer/provisioner_test.go | 16 +- packer/telemetry.go | 5 +- .../testify/assert/assertion_forward.go | 167 +++++++++++------- .../stretchr/testify/assert/assertions.go | 101 +++-------- .../testify/assert/http_assertions.go | 2 +- vendor/vendor.json | 5 +- 9 files changed, 183 insertions(+), 178 deletions(-) diff --git a/builder/docker/communicator_test.go b/builder/docker/communicator_test.go index bdfaef996..14bcdf496 100644 --- a/builder/docker/communicator_test.go +++ b/builder/docker/communicator_test.go @@ -67,11 +67,10 @@ func TestUploadDownload(t *testing.T) { hooks := map[string][]packer.Hook{} hooks[packer.HookProvision] = []packer.Hook{ &packer.ProvisionHook{ - Provisioners: []packer.Provisioner{ - upload, - download, + Provisioners: []*packer.HookedProvisioner{ + {upload, nil, ""}, + {download, nil, ""}, }, - ProvisionerTypes: []string{"", ""}, }, } hook := &packer.DispatchHook{Mapping: hooks} @@ -157,12 +156,11 @@ func TestLargeDownload(t *testing.T) { hooks := map[string][]packer.Hook{} hooks[packer.HookProvision] = []packer.Hook{ &packer.ProvisionHook{ - Provisioners: []packer.Provisioner{ - shell, - downloadCupcake, - downloadBigcake, + Provisioners: []*packer.HookedProvisioner{ + {shell, nil, ""}, + {downloadCupcake, nil, ""}, + {downloadBigcake, nil, ""}, }, - ProvisionerTypes: []string{"", "", ""}, }, } hook := &packer.DispatchHook{Mapping: hooks} @@ -203,8 +201,8 @@ func TestLargeDownload(t *testing.T) { // or ui output to do this because we use /dev/urandom to create the file. // if sha256.Sum256(inputFile) != sha256.Sum256(outputFile) { - // t.Fatalf("Input and output files do not match\n"+ - // "Input:\n%s\nOutput:\n%s\n", inputFile, outputFile) + // t.Fatalf("Input and output files do not match\n"+ + // "Input:\n%s\nOutput:\n%s\n", inputFile, outputFile) // } } @@ -267,13 +265,12 @@ func TestFixUploadOwner(t *testing.T) { hooks := map[string][]packer.Hook{} hooks[packer.HookProvision] = []packer.Hook{ &packer.ProvisionHook{ - Provisioners: []packer.Provisioner{ - fileProvisioner, - dirProvisioner, - shellProvisioner, - verifyProvisioner, + Provisioners: []*packer.HookedProvisioner{ + {fileProvisioner, nil, ""}, + {dirProvisioner, nil, ""}, + {shellProvisioner, nil, ""}, + {verifyProvisioner, nil, ""}, }, - ProvisionerTypes: []string{"", "", "", ""}, }, } hook := &packer.DispatchHook{Mapping: hooks} diff --git a/packer/build.go b/packer/build.go index c99164ce8..1187e49d7 100644 --- a/packer/build.go +++ b/packer/build.go @@ -194,12 +194,25 @@ func (b *coreBuild) Run(originalUi Ui, cache Cache) ([]Artifact, error) { // Add a hook for the provisioners if we have provisioners if len(b.provisioners) > 0 { + hookedProvisioners := make([]*HookedProvisioner, len(b.provisioners)) + for i, p := range b.provisioners { + var pConfig interface{} + if len(p.config) > 0 { + pConfig = p.config[0] + } + hookedProvisioners[i] = &HookedProvisioner{ + p.provisioner, + pConfig, + p.pType, + } + } + if _, ok := hooks[HookProvision]; !ok { hooks[HookProvision] = make([]Hook, 0, 1) } hooks[HookProvision] = append(hooks[HookProvision], &ProvisionHook{ - Provisioners: b.provisioners, + Provisioners: hookedProvisioners, }) } diff --git a/packer/provisioner.go b/packer/provisioner.go index dc850daa3..a754f7544 100644 --- a/packer/provisioner.go +++ b/packer/provisioner.go @@ -26,11 +26,18 @@ type Provisioner interface { Cancel() } +// A HookedProvisioner represents a provisioner and information describing it +type HookedProvisioner struct { + Provisioner Provisioner + Config interface{} + TypeName string +} + // A Hook implementation that runs the given provisioners. type ProvisionHook struct { // The provisioners to run as part of the hook. These should already // be prepared (by calling Prepare) at some earlier stage. - Provisioners []coreBuildProvisioner + Provisioners []*HookedProvisioner lock sync.Mutex runningProvisioner Provisioner @@ -59,16 +66,12 @@ func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interfac for _, p := range h.Provisioners { h.lock.Lock() - h.runningProvisioner = p.provisioner + h.runningProvisioner = p.Provisioner h.lock.Unlock() - var pConfig interface{} - if len(p.config) > 0 { - pConfig = p.config[0] - } - ts := CheckpointReporter.AddSpan(p.pType, "provisioner", pConfig) + ts := CheckpointReporter.AddSpan(p.TypeName, "provisioner", p.Config) - err := p.provisioner.Provision(ui, comm) + err := p.Provisioner.Provision(ui, comm) ts.End(err) if err != nil { diff --git a/packer/provisioner_test.go b/packer/provisioner_test.go index 8e79d2f81..97304d2a5 100644 --- a/packer/provisioner_test.go +++ b/packer/provisioner_test.go @@ -23,9 +23,9 @@ func TestProvisionHook(t *testing.T) { var data interface{} = nil hook := &ProvisionHook{ - Provisioners: []coreBuildProvisioner{ - {"", pA, nil}, - {"", pB, nil}, + Provisioners: []*HookedProvisioner{ + {pA, nil, ""}, + {pB, nil, ""}, }, } @@ -49,9 +49,9 @@ func TestProvisionHook_nilComm(t *testing.T) { var data interface{} = nil hook := &ProvisionHook{ - Provisioners: []coreBuildProvisioner{ - {"", pA, nil}, - {"", pB, nil}, + Provisioners: []*HookedProvisioner{ + {pA, nil, ""}, + {pB, nil, ""}, }, } @@ -78,8 +78,8 @@ func TestProvisionHook_cancel(t *testing.T) { } hook := &ProvisionHook{ - Provisioners: []coreBuildProvisioner{ - {"", p, nil}, + Provisioners: []*HookedProvisioner{ + {p, nil, ""}, }, } diff --git a/packer/telemetry.go b/packer/telemetry.go index 13931d419..a58b1c701 100644 --- a/packer/telemetry.go +++ b/packer/telemetry.go @@ -5,6 +5,7 @@ import ( "log" "os" "path/filepath" + "sort" "time" checkpoint "github.com/hashicorp/go-checkpoint" @@ -168,5 +169,7 @@ func flattenConfigKeys(options interface{}) []string { return } - return flatten("", options) + flattened := flatten("", options) + sort.Strings(flattened) + return flattened } diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index 29b71d176..e6a796046 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -1,345 +1,386 @@ /* * CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen * THIS FILE MUST NOT BE EDITED BY HAND - */ +*/ package assert import ( + http "net/http" url "net/url" time "time" ) + // Condition uses a Comparison to assert a complex condition. func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { return Condition(a.t, comp, msgAndArgs...) } + // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. -// +// // a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") // a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") // a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { return Contains(a.t, s, contains, msgAndArgs...) } + // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. -// +// // a.Empty(obj) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { return Empty(a.t, object, msgAndArgs...) } + // Equal asserts that two objects are equal. -// +// // a.Equal(123, 123, "123 and 123 should be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Equal(a.t, expected, actual, msgAndArgs...) } + // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. -// +// // actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString, "An error was expected") -// +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { return EqualError(a.t, theError, errString, msgAndArgs...) } + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. -// +// // a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return EqualValues(a.t, expected, actual, msgAndArgs...) } + // Error asserts that a function returned an error (i.e. not `nil`). -// +// // actualObj, err := SomeFunction() // if a.Error(err, "An error was expected") { // assert.Equal(t, err, expectedError) // } -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { return Error(a.t, err, msgAndArgs...) } + // Exactly asserts that two objects are equal is value and type. -// +// // a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Exactly(a.t, expected, actual, msgAndArgs...) } + // Fail reports a failure through func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { return Fail(a.t, failureMessage, msgAndArgs...) } + // FailNow fails test func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { return FailNow(a.t, failureMessage, msgAndArgs...) } + // False asserts that the specified value is false. -// +// // a.False(myBool, "myBool should be false") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { return False(a.t, value, msgAndArgs...) } + // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. -// +// // a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { return HTTPBodyContains(a.t, handler, method, url, values, str) } + // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. -// +// // a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { return HTTPBodyNotContains(a.t, handler, method, url, values, str) } + // HTTPError asserts that a specified handler returns an error status code. -// +// // a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool { return HTTPError(a.t, handler, method, url, values) } + // HTTPRedirect asserts that a specified handler returns a redirect status code. -// +// // a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool { return HTTPRedirect(a.t, handler, method, url, values) } + // HTTPSuccess asserts that a specified handler returns a success status code. -// +// // a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool { return HTTPSuccess(a.t, handler, method, url, values) } + // Implements asserts that an object is implemented by the specified interface. -// +// // a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { return Implements(a.t, interfaceObject, object, msgAndArgs...) } + // InDelta asserts that the two numerals are within delta of each other. -// +// // a.InDelta(math.Pi, (22 / 7.0), 0.01) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { return InDelta(a.t, expected, actual, delta, msgAndArgs...) } + // InDeltaSlice is the same as InDelta, except it compares two slices. func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) } + // InEpsilon asserts that expected and actual have a relative error less than epsilon -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) } -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) + +// InEpsilonSlice is the same as InEpsilon, except it compares two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InEpsilonSlice(a.t, expected, actual, delta, msgAndArgs...) } + // IsType asserts that the specified objects are of the same type. func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { return IsType(a.t, expectedType, object, msgAndArgs...) } + // JSONEq asserts that two JSON strings are equivalent. -// +// // a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { return JSONEq(a.t, expected, actual, msgAndArgs...) } + // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. -// +// // a.Len(mySlice, 3, "The size of slice is not 3") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { return Len(a.t, object, length, msgAndArgs...) } + // Nil asserts that the specified object is nil. -// +// // a.Nil(err, "err should be nothing") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { return Nil(a.t, object, msgAndArgs...) } + // NoError asserts that a function returned no error (i.e. `nil`). -// +// // actualObj, err := SomeFunction() // if a.NoError(err) { // assert.Equal(t, actualObj, expectedObj) // } -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } + // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. -// +// // a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") // a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") // a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { return NotContains(a.t, s, contains, msgAndArgs...) } + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. -// +// // if a.NotEmpty(obj) { // assert.Equal(t, "two", obj[1]) // } -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { return NotEmpty(a.t, object, msgAndArgs...) } + // NotEqual asserts that the specified values are NOT equal. -// +// // a.NotEqual(obj1, obj2, "two objects shouldn't be equal") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return NotEqual(a.t, expected, actual, msgAndArgs...) } + // NotNil asserts that the specified object is not nil. -// +// // a.NotNil(err, "err should be something") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { return NotNil(a.t, object, msgAndArgs...) } + // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// +// // a.NotPanics(func(){ // RemainCalm() // }, "Calling RemainCalm() should NOT panic") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { return NotPanics(a.t, f, msgAndArgs...) } + // NotRegexp asserts that a specified regexp does not match a string. -// +// // a.NotRegexp(regexp.MustCompile("starts"), "it's starting") // a.NotRegexp("^start", "it's not starting") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { return NotRegexp(a.t, rx, str, msgAndArgs...) } + // NotZero asserts that i is not the zero value for its type and returns the truth. func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { return NotZero(a.t, i, msgAndArgs...) } + // Panics asserts that the code inside the specified PanicTestFunc panics. -// +// // a.Panics(func(){ // GoCrazy() // }, "Calling GoCrazy() should panic") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { return Panics(a.t, f, msgAndArgs...) } + // Regexp asserts that a specified regexp matches a string. -// +// // a.Regexp(regexp.MustCompile("start"), "it's starting") // a.Regexp("start...$", "it's not starting") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { return Regexp(a.t, rx, str, msgAndArgs...) } + // True asserts that the specified value is true. -// +// // a.True(myBool, "myBool should be true") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { return True(a.t, value, msgAndArgs...) } + // WithinDuration asserts that the two times are within duration delta of each other. -// +// // a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// +// // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) } + // Zero asserts that i is the zero value for its type and returns the truth. func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { return Zero(a.t, i, msgAndArgs...) diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index 835084ffc..348d5f1bc 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -18,10 +18,6 @@ import ( "github.com/pmezard/go-difflib/difflib" ) -func init() { - spew.Config.SortKeys = true -} - // TestingT is an interface wrapper around *testing.T type TestingT interface { Errorf(format string, args ...interface{}) @@ -69,7 +65,7 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool { /* CallerInfo is necessary because the assert functions use the testing object internally, causing it to print the file:line of the assert method, rather than where -the problem actually occurred in calling code.*/ +the problem actually occured in calling code.*/ // CallerInfo returns an array of strings containing the file and line number // of each stack frame leading from the current test to the assert call that @@ -86,9 +82,7 @@ func CallerInfo() []string { for i := 0; ; i++ { pc, file, line, ok = runtime.Caller(i) if !ok { - // The breaks below failed to terminate the loop, and we ran off the - // end of the call stack. - break + return nil } // This is a huge edge case, but it will panic if this is the case, see #180 @@ -96,21 +90,6 @@ func CallerInfo() []string { break } - f := runtime.FuncForPC(pc) - if f == nil { - break - } - name = f.Name() - - // testing.tRunner is the standard library function that calls - // tests. Subtests are called directly by tRunner, without going through - // the Test/Benchmark/Example function that contains the t.Run calls, so - // with subtests we should break when we hit tRunner, without adding it - // to the list of callers. - if name == "testing.tRunner" { - break - } - parts := strings.Split(file, "/") dir := parts[len(parts)-2] file = parts[len(parts)-1] @@ -118,6 +97,11 @@ func CallerInfo() []string { callers = append(callers, fmt.Sprintf("%s:%d", file, line)) } + f := runtime.FuncForPC(pc) + if f == nil { + break + } + name = f.Name() // Drop the package segments := strings.Split(name, ".") name = segments[len(segments)-1] @@ -278,48 +262,14 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) if !ObjectsAreEqual(expected, actual) { diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: \n"+ - "expected: %s\n"+ - "received: %s%s", expected, actual, diff), msgAndArgs...) + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)%s", expected, actual, diff), msgAndArgs...) } return true } -// formatUnequalValues takes two values of arbitrary types and returns string -// representations appropriate to be presented to the user. -// -// If the values are not of like type, the returned strings will be prefixed -// with the type name, and the value will be enclosed in parenthesis similar -// to a type conversion in the Go grammar. -func formatUnequalValues(expected, actual interface{}) (e string, a string) { - aType := reflect.TypeOf(expected) - bType := reflect.TypeOf(actual) - - if aType != bType && isNumericType(aType) && isNumericType(bType) { - return fmt.Sprintf("%v(%#v)", aType, expected), - fmt.Sprintf("%v(%#v)", bType, actual) - } - - return fmt.Sprintf("%#v", expected), - fmt.Sprintf("%#v", actual) -} - -func isNumericType(t reflect.Type) bool { - switch t.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return true - case reflect.Float32, reflect.Float64: - return true - } - - return false -} - // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // @@ -329,11 +279,8 @@ func isNumericType(t reflect.Type) bool { func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if !ObjectsAreEqualValues(expected, actual) { - diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: \n"+ - "expected: %s\n"+ - "received: %s%s", expected, actual, diff), msgAndArgs...) + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)", expected, actual), msgAndArgs...) } return true @@ -886,7 +833,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m // Returns whether the assertion was successful (true) or not (false). func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if err != nil { - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...) } return true @@ -902,8 +849,9 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { // Returns whether the assertion was successful (true) or not (false). func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { + message := messageFromMsgAndArgs(msgAndArgs...) if err == nil { - return Fail(t, "An error is expected but got nil.", msgAndArgs...) + return Fail(t, "An error is expected but got nil. %s", message) } return true @@ -913,22 +861,20 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString, "An error was expected") +// if assert.Error(t, err, "An error was expected") { +// assert.Equal(t, err, expectedError) +// } // // Returns whether the assertion was successful (true) or not (false). func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { - if !Error(t, theError, msgAndArgs...) { + + message := messageFromMsgAndArgs(msgAndArgs...) + if !NotNil(t, theError, "An error is expected but got nil. %s", message) { return false } - expected := errString - actual := theError.Error() - // don't need to use deep equals here, we know they are both strings - if expected != actual { - return Fail(t, fmt.Sprintf("Error message not equal:\n"+ - "expected: %q\n"+ - "received: %q", expected, actual), msgAndArgs...) - } - return true + s := "An error with value \"%s\" is expected but got \"%s\". %s" + return Equal(t, errString, theError.Error(), + s, errString, theError.Error(), message) } // matchRegexp return true if a specified regexp matches a string. @@ -1043,6 +989,7 @@ func diff(expected interface{}, actual interface{}) string { return "" } + spew.Config.SortKeys = true e := spew.Sdump(expected) a := spew.Sdump(actual) diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go index fa7ab89b1..e1b9442b5 100644 --- a/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -99,7 +99,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url strin contains := strings.Contains(body, fmt.Sprint(str)) if contains { - Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) } return !contains diff --git a/vendor/vendor.json b/vendor/vendor.json index a8db37219..3778555c7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1057,10 +1057,11 @@ "revisionTime": "2017-03-21T23:07:31Z" }, { - "checksumSHA1": "Q2V7Zs3diLmLfmfbiuLpSxETSuY=", + "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", "comment": "v1.1.4-4-g976c720", "path": "github.com/stretchr/testify/assert", - "revision": "976c720a22c8eb4eb6a0b4348ad85ad12491a506" + "revision": "d77da356e56a7428ad25149ca77381849a6a5232", + "revisionTime": "2016-06-15T09:26:46Z" }, { "checksumSHA1": "GQ9bu6PuydK3Yor1JgtVKUfEJm8=", From 97ef340423c2e006004d6a06a3e4aa3f549c191c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 14 Nov 2017 16:43:57 -0800 Subject: [PATCH 0204/1007] fix type --- website/source/docs/provisioners/chef-client.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/chef-client.html.md b/website/source/docs/provisioners/chef-client.html.md index dabf37ca5..05898263e 100644 --- a/website/source/docs/provisioners/chef-client.html.md +++ b/website/source/docs/provisioners/chef-client.html.md @@ -212,7 +212,7 @@ readability) to install Chef. This command can be customized if you want to install Chef in another way. ``` text -curl -L https:///omnitruck.chef.io/chef/install.sh | \ +curl -L https://omnitruck.chef.io/chef/install.sh | \ {{if .Sudo}}sudo{{end}} bash ``` From 18b9487a386ca2e8e5183cb68a1dc72d03031cf3 Mon Sep 17 00:00:00 2001 From: Malet <michael@nervd.com> Date: Wed, 15 Nov 2017 12:02:08 +0000 Subject: [PATCH 0205/1007] Fix typo --- website/source/docs/builders/googlecompute.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index 4ccfe4cb1..1c4717768 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -70,7 +70,7 @@ straightforwarded, it is documented here. 4. Create new service account that at least has `Compute Engine Instance Admin (v1)` and `Service Account User` roles. -5. Chose `JSON` as Key type and click "Create". +5. Choose `JSON` as Key type and click "Create". A JSON file will be downloaded automatically. This is your *account file*. ### Precedence of Authentication Methods From b8bd66d10da64b6e885f8576ef279520891e2e99 Mon Sep 17 00:00:00 2001 From: Ammar Ansari <mansari@redhat.com> Date: Wed, 15 Nov 2017 14:47:46 -0500 Subject: [PATCH 0206/1007] Align virtual disk size for qemu builder When booting from a disk image, the Qemu builder resizes the disk to 40000 which is not a multiple of 1kB. This causes problems while booting from the image. Updating the default disk size to 40960 fixes this issue --- builder/qemu/builder.go | 2 +- builder/qemu/builder_test.go | 2 +- website/source/docs/builders/qemu.html.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 2b6b206d9..43ec6b4c3 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -144,7 +144,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { warnings := make([]string, 0) if b.config.DiskSize == 0 { - b.config.DiskSize = 40000 + b.config.DiskSize = 40960 } if b.config.DiskCache == "" { diff --git a/builder/qemu/builder_test.go b/builder/qemu/builder_test.go index 24c5dc47e..7ef29034e 100644 --- a/builder/qemu/builder_test.go +++ b/builder/qemu/builder_test.go @@ -208,7 +208,7 @@ func TestBuilderPrepare_DiskSize(t *testing.T) { t.Fatalf("bad err: %s", err) } - if b.config.DiskSize != 40000 { + if b.config.DiskSize != 40960 { t.Fatalf("bad size: %d", b.config.DiskSize) } diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index e1bff6043..f3de7cf9c 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -157,7 +157,7 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). interface under these circumstances will cause the build to fail. - `disk_size` (number) - The size, in megabytes, of the hard disk to create - for the VM. By default, this is 40000 (about 40 GB). + for the VM. By default, this is 40960 (40 GB). - `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for From 581bb9a329b3c189546ec68d4654794dbd061938 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 15 Nov 2017 12:41:14 -0800 Subject: [PATCH 0207/1007] update changelog --- CHANGELOG.md | 64 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3787a54aa..618431a34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,35 +2,55 @@ ### IMRPOVEMENTS: -* post-processor/docker-push: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] -* builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] -* post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] -* builder/hyper-v: Also disable automatic checkpoints for gen 2 VMs. [GH-5517] -* builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 additional disks. [GH-5491] -* builder/amazon: correctly deregister AMIs when `force_deregister` is set. [GH-5525] +* builder/amazon: correctly deregister AMIs when `force_deregister` is set. + [GH-5525] * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] -* builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] -* communicator/ssh: Add socks 5 proxy support. [GH-5439] -* builder/lxc: Add new `publish_properties` field to set image properties. [GH-5475] -* builder/virtualbox-ovf: Retry while removing VM to solve for transient errors. [GH-5512] -* builder/google: Interpolate network and subnetwork values, rather than relying on an API call that packer may not have permission for. [GH-5343] -* builder/lxc: Add three new configuration option categories to LXC builder: create_options, start_options, and attach_options. [GH-5530] -* core: Rewrite vagrantfile code to make cross-platform development easier. [5539] -* builder/triton: Update triton-go sdk. [GH-5531] +* builder/docker: Add `aws_profile` option to control the aws profile for ECR. + [GH-5470] * builder/google: Add clean_image_name template engine. [GH-5463] * builder/google: Allow Selecting Container Optimized Images. [GH-5576] +* builder/google: Interpolate network and subnetwork values, rather than + relying on an API call that packer may not have permission for. [GH-5343] +* builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 + additional disks. [GH-5491] +* builder/hyper-v: Also disable automatic checkpoints for gen 2 VMs. [GH-5517] +* builder/lxc: Add new `publish_properties` field to set image properties. + [GH-5475] +* builder/lxc: Add three new configuration option categories to LXC builder: + create_options, start_options, and attach_options. [GH-5530] +* builder/triton: Add `source_machine_image_filter` option to select an image + ID based on a variety of parameters. [GH-5538] +* builder/triton: Update triton-go sdk. [GH-5531] +* builder/virtualbox-ovf: Error during prepare if source path doesn't exist. + [GH-5573] +* builder/virtualbox-ovf: Retry while removing VM to solve for transient + errors. [GH-5512] +* communicator/ssh: Add socks 5 proxy support. [GH-5439] +* core: Rewrite vagrantfile code to make cross-platform development easier. + [GH-5539] +* post-processor/docker-push: Add `aws_profile` option to control the aws + profile for ECR. [GH-5470] +* post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] ### BUG FIXES: -* builder/docker: Remove `login_email`, which no longer exists in the docker client. [GH-5511] -* builder/triton: Fix a bug where partially created images can be reported as complete. [GH-5566] -* builder/amazon: region is set from profile, if profile is set, rather than being overridden by metadata. [GH-5562] -* provisioner/windows-restart: Wait for restart no longer endlessly loops if user specifies a custom restart check command. [GH-5563] -* post-processor/vsphere: Use the vm disk path information to re-create the vmx datastore path. [GH-5567] * builder/amazon: Add a delay option to security group waiter. [GH-5536] -* builder/amazon: Fix regressions relating to spot instances and EBS volumes. [GH-5495] -* builder/hyperv: Fix admin check that was causing powershell failures. [GH-5510] -* builder/oracle: Defaulting of OCI builder region will first check the packer template and the OCI config file. [GH-5407] +* builder/amazon: Fix regressions relating to spot instances and EBS volumes. + [GH-5495] +* builder/amazon: region is set from profile, if profile is set, rather than + being overridden by metadata. [GH-5562] +* builder/docker: Remove `login_email`, which no longer exists in the docker + client. [GH-5511] +* builder/hyperv: Fix admin check that was causing powershell failures. + [GH-5510] +* builder/oracle: Defaulting of OCI builder region will first check the packer + template and the OCI config file. [GH-5407] +* builder/triton: Fix a bug where partially created images can be reported as + complete. [GH-5566] +* post-processor/vsphere: Use the vm disk path information to re-create the vmx + datastore path. [GH-5567] +* provisioner/windows-restart: Wait for restart no longer endlessly loops if + user specifies a custom restart check command. [GH-5563] ## 1.1.1 (October 13, 2017) From bc64c6cb658d227aa97e87be02b295f7c4e40a42 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 15 Nov 2017 12:45:01 -0800 Subject: [PATCH 0208/1007] update changelog --- CHANGELOG.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 618431a34..940d5fcf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,13 @@ ### IMRPOVEMENTS: -* builder/amazon: correctly deregister AMIs when `force_deregister` is set. +* builder/amazon: Correctly deregister AMIs when `force_deregister` is set. [GH-5525] * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] * builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] -* builder/google: Add clean_image_name template engine. [GH-5463] -* builder/google: Allow Selecting Container Optimized Images. [GH-5576] +* builder/google: Add `clean_image_name` template engine. [GH-5463] +* builder/google: Allow selecting container optimized images. [GH-5576] * builder/google: Interpolate network and subnetwork values, rather than relying on an API call that packer may not have permission for. [GH-5343] * builder/hyper-v: Add `disk_additional_size` option to allow for up to 64 @@ -17,15 +17,15 @@ * builder/lxc: Add new `publish_properties` field to set image properties. [GH-5475] * builder/lxc: Add three new configuration option categories to LXC builder: - create_options, start_options, and attach_options. [GH-5530] + `create_options`, `start_options`, and `attach_options`. [GH-5530] * builder/triton: Add `source_machine_image_filter` option to select an image ID based on a variety of parameters. [GH-5538] -* builder/triton: Update triton-go sdk. [GH-5531] * builder/virtualbox-ovf: Error during prepare if source path doesn't exist. [GH-5573] * builder/virtualbox-ovf: Retry while removing VM to solve for transient errors. [GH-5512] * communicator/ssh: Add socks 5 proxy support. [GH-5439] +* core/iso_config: Support relative paths in checksum file. [GH-5578] * core: Rewrite vagrantfile code to make cross-platform development easier. [GH-5539] * post-processor/docker-push: Add `aws_profile` option to control the aws @@ -37,8 +37,8 @@ * builder/amazon: Add a delay option to security group waiter. [GH-5536] * builder/amazon: Fix regressions relating to spot instances and EBS volumes. [GH-5495] -* builder/amazon: region is set from profile, if profile is set, rather than - being overridden by metadata. [GH-5562] +* builder/amazon: Set region from profile, if profile is set, rather than being + overridden by metadata. [GH-5562] * builder/docker: Remove `login_email`, which no longer exists in the docker client. [GH-5511] * builder/hyperv: Fix admin check that was causing powershell failures. From 40f18a3e1aebc7384a026270a9828156b6deaca5 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 15 Nov 2017 13:48:00 -0800 Subject: [PATCH 0209/1007] prepare for 1.1.2 --- CHANGELOG.md | 2 +- version/version.go | 2 +- website/config.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 940d5fcf6..085510744 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## (UNRELEASED) +## 1.1.2 (November 15, 2017) ### IMRPOVEMENTS: diff --git a/version/version.go b/version/version.go index f3d38291a..c4dfaf8f0 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ const Version = "1.1.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index 93d234cbe..b3a77be6a 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.1.1" + h.version = "1.1.2" h.github_slug = "hashicorp/packer" h.website_root = "website" end From 097296792a9cc67451e5065868d11a0efe6af8ec Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 15 Nov 2017 14:08:58 -0800 Subject: [PATCH 0211/1007] prepare for next version --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index c4dfaf8f0..7ab8bb073 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.1.2" +const Version = "1.1.3" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From 9ee13852836998eff1f3ba9cdf69783041f1628f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 15 Nov 2017 14:17:00 -0800 Subject: [PATCH 0212/1007] update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 085510744..fa0ea5c15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## (UNRELEASED) + +### IMPROVEMENTS: + +### BUG FIXES: + +* builder/qemu: Set default disk size to 40960 MB to prevent boot failures. [GH-5588] + ## 1.1.2 (November 15, 2017) ### IMRPOVEMENTS: From 284ffa25623a1577b7a2c541f8562f5e63c00269 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 15 Nov 2017 14:19:28 -0800 Subject: [PATCH 0213/1007] spell fix --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa0ea5c15..889ed4d44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ## 1.1.2 (November 15, 2017) -### IMRPOVEMENTS: +### IMPROVEMENTS: * builder/amazon: Correctly deregister AMIs when `force_deregister` is set. [GH-5525] @@ -267,7 +267,7 @@ * core: Remove logging that shouldn't be there when running commands. [GH-5042] * provisioner/shell: Fix bug where scripts were being run under `sh`. [GH-5043] -### IMRPOVEMENTS: +### IMPROVEMENTS: * provisioner/windows-restart: make it clear that timeouts come from the provisioner, not winrm. [GH-5040] From 20390ff1ecd222cb7ff9ddd8ecafb0447c416987 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 15 Nov 2017 17:01:53 -0800 Subject: [PATCH 0214/1007] fix vetting for test fail print statements --- builder/hyperv/iso/builder_test.go | 2 +- builder/hyperv/vmcx/builder_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index ba167413b..383ab5b30 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -514,6 +514,6 @@ func TestUserVariablesInBootCommand(t *testing.T) { ret := step.Run(state) if ret != multistep.ActionContinue { - t.Fatalf("should not have error: %s", ret) + t.Fatalf("should not have error: %#v", ret) } } diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 89cac5878..fb7f35c52 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -535,6 +535,6 @@ func TestUserVariablesInBootCommand(t *testing.T) { ret := step.Run(state) if ret != multistep.ActionContinue { - t.Fatalf("should not have error: %s", ret) + t.Fatalf("should not have error: %#v", ret) } } From 74a4cc04fed4bccd8f52c6e56f9e3b298b099f8a Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 16 Nov 2017 10:22:12 -0800 Subject: [PATCH 0215/1007] fix regression :( --- common/config.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/config.go b/common/config.go index 490553388..cc7eced6a 100644 --- a/common/config.go +++ b/common/config.go @@ -109,6 +109,14 @@ func DownloadableURL(original string) (string, error) { // Make sure it is lowercased url.Scheme = strings.ToLower(url.Scheme) + // This is to work around issue #5927. This can safely be removed once + // we distribute with a version of Go that fixes that bug. + // + // See: https://code.google.com/p/go/issues/detail?id=5927 + if url.Path != "" && url.Path[0] != '/' { + url.Path = "/" + url.Path + } + // Verify that the scheme is something we support in our common downloader. supported := []string{"file", "http", "https"} found := false From 4fb8a27879421803d82e2a5d7d437560a3208d74 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 16 Nov 2017 11:03:10 -0800 Subject: [PATCH 0216/1007] remove the actual offending code --- common/config.go | 8 -------- common/download.go | 4 ---- 2 files changed, 12 deletions(-) diff --git a/common/config.go b/common/config.go index cc7eced6a..490553388 100644 --- a/common/config.go +++ b/common/config.go @@ -109,14 +109,6 @@ func DownloadableURL(original string) (string, error) { // Make sure it is lowercased url.Scheme = strings.ToLower(url.Scheme) - // This is to work around issue #5927. This can safely be removed once - // we distribute with a version of Go that fixes that bug. - // - // See: https://code.google.com/p/go/issues/detail?id=5927 - if url.Path != "" && url.Path[0] != '/' { - url.Path = "/" + url.Path - } - // Verify that the scheme is something we support in our common downloader. supported := []string{"file", "http", "https"} found := false diff --git a/common/download.go b/common/download.go index 86dea34d1..8061f3223 100644 --- a/common/download.go +++ b/common/download.go @@ -130,10 +130,6 @@ func (d *DownloadClient) Get() (string, error) { // locally and we don't make a copy. Normally we would copy or download. log.Printf("[DEBUG] Using local file: %s", finalPath) - // Remove forward slash on absolute Windows file URLs before processing - if runtime.GOOS == "windows" && len(finalPath) > 0 && finalPath[0] == '/' { - finalPath = finalPath[1:] - } // Keep track of the source so we can make sure not to delete this later sourcePath = finalPath if _, err = os.Stat(finalPath); err != nil { From 3c20176dbb066f55a76ceda6d62e505bbc718117 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 16 Nov 2017 11:10:21 -0800 Subject: [PATCH 0217/1007] runtime imported but not used --- common/download.go | 1 - 1 file changed, 1 deletion(-) diff --git a/common/download.go b/common/download.go index 8061f3223..8eaf236fc 100644 --- a/common/download.go +++ b/common/download.go @@ -15,7 +15,6 @@ import ( "net/http" "net/url" "os" - "runtime" ) // DownloadConfig is the configuration given to instantiate a new From 787f08f39bba1b04d9c71801ac2ebe7584ae60c8 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Thu, 16 Nov 2017 16:31:05 -0800 Subject: [PATCH 0218/1007] azure: add user message to indicate what is being deleted --- builder/azure/arm/step_delete_resource_group.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index 1c299ad7c..ca6631f7a 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -82,6 +82,7 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, } return err } else { + s.say("\nThe resource group was created by Packer, deleting ...") _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) err = <-errChan From 2684153cb2852bcc9c208d2a23c98ff443ea8079 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Thu, 16 Nov 2017 16:34:13 -0800 Subject: [PATCH 0219/1007] azure: reject bad configuration faster --- builder/azure/arm/config.go | 4 ++++ builder/azure/arm/config_test.go | 25 ++++++++++++++++++++++ website/source/docs/builders/azure.html.md | 5 +++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index fd6bd9edb..7f69d5d10 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -519,6 +519,10 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { } } + if c.TempResourceGroupName != "" && c.BuildResourceGroupName != "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("The settings temp_resource_group_name and build_resource_group_name cannot both be defined. Please define one or neither.")) + } + ///////////////////////////////////////////// // Compute toInt := func(b bool) int { diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index b7523f655..20954632e 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -899,6 +899,31 @@ func TestConfigShouldAcceptManagedImageStorageAccountTypes(t *testing.T) { } } +func TestConfigShouldRejectTempAndBuildResourceGroupName(t *testing.T) { + config := map[string]interface{}{ + "capture_name_prefix": "ignore", + "capture_container_name": "ignore", + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "storage_account": "ignore", + "resource_group_name": "ignore", + "subscription_id": "ignore", + "communicator": "none", + + // custom may define one or the other, but not both + "temp_resource_group_name": "rgn00", + "build_resource_group_name": "rgn00", + } + + _, _, err := newConfig(config, getPackerConfiguration()) + if err == nil { + t.Fatal("expected config to reject the use of both temp_resource_group_name and build_resource_group_name") + } +} + + func getArmBuilderConfiguration() map[string]string { m := make(map[string]string) for _, v := range requiredConfigValues { diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 8f9d23442..a4068702a 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -134,8 +134,9 @@ When creating a managed image the following two options are required. assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer build, e.g. attach a resource disk to the VM. -- `temp_resource_group_name` (string) name assigned to the temporary resource group created during the build. If this value is not set, a random - value will be assigned. Cannot be used together with `build_resource_group_name`. +- `temp_resource_group_name` (string) name assigned to the temporary resource group created during the build. If this + value is not set, a random value will be assigned. This resource group is deleted at the end of the build. Cannot be + used together with `build_resource_group_name`. - `tenant_id` (string) The account identifier with which your `client_id` and `subscription_id` are associated. If not specified, `tenant_id` will be looked up using `subscription_id`. From ee767e55d1ef2751fe5d0ef1ec55776ffcfccd43 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Thu, 16 Nov 2017 16:36:42 -0800 Subject: [PATCH 0220/1007] azure: change literal to constant --- builder/azure/arm/step_delete_resource_group.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index ca6631f7a..d47ed7f4c 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -10,6 +10,10 @@ import ( "github.com/mitchellh/multistep" ) +const ( + maxResourcesToDelete = 50 +) + type StepDeleteResourceGroup struct { client *AzureClient delete func(state multistep.StateBag, resourceGroupName string, cancelCh <-chan struct{}) error @@ -34,7 +38,7 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, s.say("\nThe resource group was not created by Packer, only deleting individual resources ...") var deploymentName = state.Get(constants.ArmDeploymentName).(string) if deploymentName != "" { - maxResources := int32(50) + maxResources := int32(maxResourcesToDelete) deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) if err != nil { s.say(fmt.Sprintf("Error deleting resources. Please delete them manually.\n\n"+ From 8985bd45ba93d995fe353c0ffcc10dc7e4dd8051 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Thu, 16 Nov 2017 17:32:35 -0800 Subject: [PATCH 0221/1007] azure: go fmt --- builder/azure/arm/config_test.go | 3 +-- builder/azure/arm/step_delete_resource_group.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index 20954632e..8cbfe8f6e 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -913,7 +913,7 @@ func TestConfigShouldRejectTempAndBuildResourceGroupName(t *testing.T) { "communicator": "none", // custom may define one or the other, but not both - "temp_resource_group_name": "rgn00", + "temp_resource_group_name": "rgn00", "build_resource_group_name": "rgn00", } @@ -923,7 +923,6 @@ func TestConfigShouldRejectTempAndBuildResourceGroupName(t *testing.T) { } } - func getArmBuilderConfiguration() map[string]string { m := make(map[string]string) for _, v := range requiredConfigValues { diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index d47ed7f4c..147a33349 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -86,7 +86,7 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, } return err } else { - s.say("\nThe resource group was created by Packer, deleting ...") + s.say("\nThe resource group was created by Packer, deleting ...") _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) err = <-errChan From e9a63d865357d313c7535ccb3a00bbbec9dc1440 Mon Sep 17 00:00:00 2001 From: Carlos Nunez <dev@carlosnunez.me> Date: Sat, 18 Nov 2017 15:27:54 -0600 Subject: [PATCH 0222/1007] Add instructions for the Python client. Azure uses the Python client in their Docker image. I've added additional documentation on how to "install" it as well as translations the node.js commands for it. --- .../source/docs/builders/azure-setup.html.md | 105 +++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/azure-setup.html.md b/website/source/docs/builders/azure-setup.html.md index 90c1a6e73..86522642d 100644 --- a/website/source/docs/builders/azure-setup.html.md +++ b/website/source/docs/builders/azure-setup.html.md @@ -63,6 +63,14 @@ If you already have node.js installed you can use `npm` to install `azure-cli`: $ npm install -g azure-cli --no-progress ``` +You can also use the Python-based Azure CLI in Docker. It also comes with `jq` pre-installed: + +```shell +$ docker run -it azuresdk/azure-cli-python +``` + +As there are differences between the node.js client and the Python client, we've included commands for the Python client underneath each node.js command. + ## Guided Setup The Packer project includes a [setup script](https://github.com/hashicorp/packer/blob/master/contrib/azure-setup.sh) that can help you setup your account. It uses an interactive bash script to log you into Azure, name your resources, and export your Packer configuration. @@ -80,6 +88,32 @@ $ azure config mode arm $ azure login -u USERNAME ``` +If you're using the Python client: + +```shell +$ az login +# To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code CODE_PROVIDED to authenticate +``` + +Once you've completed logging in, you should get a JSON array like the one below: + +```shell +[ + { + "cloudName": "AzureCloud", + "id": "$uuid", + "isDefault": false, + "name": "Pay-As-You-Go", + "state": "Enabled", + "tenantId": "$tenant_uuid", + "user": { + "name": "my_email@anywhere.com", + "type": "user" + } + } +] + +``` Get your account information ``` shell @@ -88,6 +122,11 @@ $ azure account set ACCOUNTNAME $ azure account show --json | jq -r ".[] | .id" ``` +Python: +```shell +$ az account set "$(az account list | jq -r '.[].name')" +``` + -&gt; Throughout this document when you see a command pipe to `jq` you may instead omit `--json` and everything after it, but the output will be more verbose. For example you can simply run `azure account list` instead. This will print out one line that look like this: @@ -107,6 +146,12 @@ $ azure location list $ azure group create -n GROUPNAME -l LOCATION ``` +Python: + +```shell +$ az group create -n GROUPNAME -l LOCATION +``` + Your storage account (below) will need to use the same `GROUPNAME` and `LOCATION`. ### Create a Storage Account @@ -121,9 +166,15 @@ $ azure storage account create \ --kind storage STORAGENAME ``` --&gt; `LRS` is meant as a literal "LRS" and not as a variable. +Python: -Make sure that `GROUPNAME` and `LOCATION` are the same as above. +```shell +$ az storage account create -n STORAGENAME -g GROUPNAME -l LOCATION --sku Standard_LRS +``` + +-&gt; `LRS` and `Standard_LRS` are meant as literal "LRS" or "Standard_LRS" and not as variables. + +Make sure that `GROUPNAME` and `LOCATION` are the same as above. Also, ensure that `GROUPNAME` is less than 24 characters long and contains only lowercase letters and numbers. ### Create an Application @@ -137,6 +188,12 @@ $ azure ad app create \ -p PASSWORD ``` +Python: + +```shell +az ad app create --display-name APPNAME --identifier-uris APPURL --homepage APPURL --password PASSWORD +``` + Password is your `client_secret` and can be anything you like. I recommend using `openssl rand -base64 24`. ### Create a Service Principal @@ -153,6 +210,13 @@ $ azure ad app list --json \ $ azure ad sp create --applicationId APPID ``` +Python: + +```shell +$ id=$(az ad app list | jq -r '.[] | select(.displayName == "Packer") | .appId') +$ az ad sp create --appid "$id" +``` + ### Grant Permissions to Your Application Finally, we will associate the proper permissions with our application's service principal. We're going to assign the `Owner` role to our Packer application and change the scope to manage our whole subscription. (The `Owner` role can be scoped to a specific resource group to further reduce the scope of the account.) This allows Packer to create temporary resource groups for each build. @@ -164,6 +228,13 @@ $ azure role assignment create \ -c /subscriptions/SUBSCRIPTIONID ``` +Python: + +```shell +# NOTE: Trying to assign the role to the service principal by name directly yields a HTTP 400 error. See: https://github.com/Azure/azure-cli/issues/4911 +$ az role assignment create --assignee "$(az ad sp list | jq -r '.[] | select(.displayName == "APPNAME") | .objectId')" --role Owner +``` + There are a lot of pre-defined roles and you can define your own with more granular permissions, though this is out of scope. You can see a list of pre-configured roles via: ``` shell @@ -182,6 +253,12 @@ $ azure account show --json \ | jq ".[] | .id" ``` +Python: + +```shell +$ az account show | jq -r '.id' +``` + Get `client_id` ``` shell @@ -189,6 +266,12 @@ $ azure ad app list --json \ | jq '.[] | select(.displayName | contains("APPNAME")) | .appId' ``` +Python + +```shell +$ az ad app list | jq '.[] | select(.displayName | contains("APPNAME")) | .appId' +``` + Get `client_secret` This cannot be retrieved. If you forgot this, you will have to delete and re-create your service principal and the associated permissions. @@ -199,14 +282,32 @@ Get `object_id` (OSTYpe=Windows only) azure ad sp show -n CLIENT_ID ``` +Python: + +```shell +$ az ad sp show -n CLIENT_ID +``` + Get `resource_group_name` ``` shell $ azure group list ``` +Python: + +```shell +$ az group list | jq '.[] | select(.name=="GROUPNAME") | .id' +``` + Get `storage_account` ``` shell $ azure storage account list ``` + +Python: + +```shell +$ az storage account list | jq '.[] | select(.name=="GROUPNAME") | .id' +``` From a8ff095059c1188e013be9af6a4e64c496e073bd Mon Sep 17 00:00:00 2001 From: Carlos Nunez <dev@carlosnunez.me> Date: Sat, 18 Nov 2017 15:44:10 -0600 Subject: [PATCH 0223/1007] Generate a JSON object for Packer This changes adds code that will generate a JSON object containing the things you'll need to make Packer work with Azure. --- .../source/docs/builders/azure-setup.html.md | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/website/source/docs/builders/azure-setup.html.md b/website/source/docs/builders/azure-setup.html.md index 86522642d..618e38543 100644 --- a/website/source/docs/builders/azure-setup.html.md +++ b/website/source/docs/builders/azure-setup.html.md @@ -246,6 +246,23 @@ $ azure role list --json \ Now (finally) everything has been setup in Azure. Let's get our configuration keys together: +Python: + +```shell +$ cat <<EOF +> { +> "subscription_id": $(az account show | jq '.id'), +> "client_id": $(az ad app list | jq '.[] | select(.displayName == "Packer") | .appId'), +> "client_secret": "$password", +> "location": "$location", +> "tenant_id": $(az account show | jq '.tenantId') +> "object_id": $(az ad app list | jq '.[] | select(.displayName == "Packer") | .objectId') +> } +> EOF +``` + +node.js: + Get `subscription_id`: ``` shell @@ -253,12 +270,6 @@ $ azure account show --json \ | jq ".[] | .id" ``` -Python: - -```shell -$ az account show | jq -r '.id' -``` - Get `client_id` ``` shell @@ -266,11 +277,6 @@ $ azure ad app list --json \ | jq '.[] | select(.displayName | contains("APPNAME")) | .appId' ``` -Python - -```shell -$ az ad app list | jq '.[] | select(.displayName | contains("APPNAME")) | .appId' -``` Get `client_secret` @@ -282,32 +288,14 @@ Get `object_id` (OSTYpe=Windows only) azure ad sp show -n CLIENT_ID ``` -Python: - -```shell -$ az ad sp show -n CLIENT_ID -``` - Get `resource_group_name` ``` shell $ azure group list ``` -Python: - -```shell -$ az group list | jq '.[] | select(.name=="GROUPNAME") | .id' -``` - Get `storage_account` ``` shell $ azure storage account list ``` - -Python: - -```shell -$ az storage account list | jq '.[] | select(.name=="GROUPNAME") | .id' -``` From a3c94850624b57c75fd99718426416bc9e7a14fd Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Fri, 17 Nov 2017 09:49:23 -0800 Subject: [PATCH 0224/1007] azure: sanity check resource group names --- builder/azure/arm/config.go | 58 ++++++++++++++ builder/azure/arm/config_test.go | 133 +++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 7f69d5d10..b2301db6c 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -38,9 +38,23 @@ const ( DefaultVMSize = "Standard_A1" ) +const ( + // https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions#naming-rules-and-restrictions + // Regular expressions in Go are not expressive enough, such that the regular expression returned by Azure + // can be used (no backtracking). + // + // -> ^[^_\W][\w-._]{0,79}(?<![-.])$ + // + // This is not an exhaustive match, but it should be extremely close. + validResourceGroupNameRe = "^[^_\\W][\\w-._\\(\\)]{0,63}$" + validManagedDiskName = "^[^_\\W][\\w-._)]{0,79}$" +) + var ( reCaptureContainerName = regexp.MustCompile("^[a-z0-9][a-z0-9\\-]{2,62}$") reCaptureNamePrefix = regexp.MustCompile("^[A-Za-z0-9][A-Za-z0-9_\\-\\.]{0,23}$") + reManagedDiskName = regexp.MustCompile(validManagedDiskName) + reResourceGroupName = regexp.MustCompile(validResourceGroupNameRe) ) type Config struct { @@ -599,6 +613,30 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { } } + if c.TempResourceGroupName != "" { + if ok, err := assertResourceGroupName(c.TempResourceGroupName, "temp_resource_group_name"); !ok { + errs = packer.MultiErrorAppend(errs, err) + } + } + + if c.BuildResourceGroupName != "" { + if ok, err := assertResourceGroupName(c.BuildResourceGroupName, "build_resource_group_name"); !ok { + errs = packer.MultiErrorAppend(errs, err) + } + } + + if c.ManagedImageResourceGroupName != "" { + if ok, err := assertResourceGroupName(c.ManagedImageResourceGroupName, "managed_image_resource_group_name"); !ok { + errs = packer.MultiErrorAppend(errs, err) + } + } + + if c.ManagedImageName != "" { + if ok, err := assertManagedImageName(c.ManagedImageName, "managed_image_name"); !ok { + errs = packer.MultiErrorAppend(errs, err) + } + } + if c.VirtualNetworkName == "" && c.VirtualNetworkResourceGroupName != "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("If virtual_network_resource_group_name is specified, so must virtual_network_name")) } @@ -627,3 +665,23 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("The managed_image_storage_account_type %q is invalid", c.ManagedImageStorageAccountType)) } } + +func assertManagedImageName(name, setting string) (bool, error) { + if !isValidAzureName(reManagedDiskName, name) { + return false, fmt.Errorf("The setting %s must match the regular expression %q, and not end with a '-' or '.'.", setting, validManagedDiskName) + } + return true, nil +} + +func assertResourceGroupName(rgn, setting string) (bool, error) { + if !isValidAzureName(reResourceGroupName, rgn) { + return false, fmt.Errorf("The setting %s must match the regular expression %q, and not end with a '-' or '.'.", setting, validResourceGroupNameRe) + } + return true, nil +} + +func isValidAzureName(re *regexp.Regexp, rgn string) bool { + return re.Match([]byte(rgn)) && + !strings.HasSuffix(rgn, ".") && + !strings.HasSuffix(rgn, "-") +} diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index 8cbfe8f6e..75d397831 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -923,6 +923,139 @@ func TestConfigShouldRejectTempAndBuildResourceGroupName(t *testing.T) { } } +func TestConfigShouldRejectInvalidResourceGroupNames(t *testing.T) { + config := map[string]interface{}{ + "capture_name_prefix": "ignore", + "capture_container_name": "ignore", + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "storage_account": "ignore", + "resource_group_name": "ignore", + "subscription_id": "ignore", + "communicator": "none", + "os_type": "linux", + } + + tests := []struct { + name string + ok bool + }{ + // The Good + {"packer-Resource-Group-jt2j3fc", true}, + {"My", true}, + {"My-(with-parens)-Resource-Group", true}, + + // The Bad + {"My Resource Group", false}, + {"My-Resource-Group-", false}, + {"My.Resource.Group.", false}, + + // The Ugly + {"My!@#!@#%$%yM", false}, + {" ", false}, + {"My10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false}, + } + + settings := []string{"temp_resource_group_name", "build_resource_group_name"} + + for _, x := range settings { + for _, y := range tests { + config[x] = y.name + + _, _, err := newConfig(config, getPackerConfiguration()) + if !y.ok && err == nil { + t.Errorf("expected config to reject %q for setting %q", y.name, x) + } else if y.ok && err != nil { + t.Errorf("expected config to accept %q for setting %q", y.name, x) + } + } + + delete(config, x) + } +} + +func TestConfigShouldRejectManagedDiskNames(t *testing.T) { + config := map[string]interface{}{ + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "subscription_id": "ignore", + "communicator": "none", + "os_type": "linux", + "managed_image_name": "ignore", + "managed_image_resource_group_name": "ignore", + } + + testsResourceGroupNames := []struct { + name string + ok bool + }{ + // The Good + {"packer-Resource-Group-jt2j3fc", true}, + {"My", true}, + {"My-(with-parens)-Resource-Group", true}, + + // The Bad + {"My Resource Group", false}, + {"My-Resource-Group-", false}, + {"My.Resource.Group.", false}, + + // The Ugly + {"My!@#!@#%$%yM", false}, + {" ", false}, + {"My10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false}, + } + + settingUnderTest := "managed_image_resource_group_name" + for _, y := range testsResourceGroupNames { + config[settingUnderTest] = y.name + + _, _, err := newConfig(config, getPackerConfiguration()) + if !y.ok && err == nil { + t.Errorf("expected config to reject %q for setting %q", y.name, settingUnderTest) + } else if y.ok && err != nil { + t.Errorf("expected config to accept %q for setting %q", y.name, settingUnderTest) + } + } + + config["managed_image_resource_group_name"] = "ignored" + + testNames := []struct { + name string + ok bool + }{ + // The Good + {"ManagedDiskName", true}, + {"Managed-Disk-Name", true}, + {"My33", true}, + + // The Bad + {"Managed Disk Name", false}, + {"Managed-Disk-Name-", false}, + {"Managed.Disk.Name.", false}, + + // The Ugly + {"My!@#!@#%$%yM", false}, + {" ", false}, + {"My10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", false}, + } + + settingUnderTest = "managed_image_name" + for _, y := range testNames { + config[settingUnderTest] = y.name + + _, _, err := newConfig(config, getPackerConfiguration()) + if !y.ok && err == nil { + t.Logf("expected config to reject %q for setting %q", y.name, settingUnderTest) + } else if y.ok && err != nil { + t.Logf("expected config to accept %q for setting %q", y.name, settingUnderTest) + } + } +} + func getArmBuilderConfiguration() map[string]string { m := make(map[string]string) for _, v := range requiredConfigValues { From 10370adbabbbccbd87fd5eca45f757629f33b397 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski <kw@linux.com> Date: Tue, 21 Nov 2017 21:09:01 +0100 Subject: [PATCH 0225/1007] ansible-local: Add ability to clean staging directory. Signed-off-by: Krzysztof Wilczynski <kw@linux.com> --- provisioner/ansible-local/provisioner.go | 32 +++++++++++++++++-- provisioner/ansible-local/provisioner_test.go | 23 +++++++++++++ .../docs/provisioners/ansible-local.html.md | 4 +++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/provisioner/ansible-local/provisioner.go b/provisioner/ansible-local/provisioner.go index 2f6a873f9..ec1eec041 100644 --- a/provisioner/ansible-local/provisioner.go +++ b/provisioner/ansible-local/provisioner.go @@ -48,6 +48,9 @@ type Config struct { // permissions in this directory. StagingDir string `mapstructure:"staging_directory"` + // If true, staging directory is removed after executing ansible. + CleanStagingDir bool `mapstructure:"clean_staging_directory"` + // The optional inventory file InventoryFile string `mapstructure:"inventory_file"` @@ -260,6 +263,13 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { if err := p.executeAnsible(ui, comm); err != nil { return fmt.Errorf("Error executing Ansible: %s", err) } + + if p.config.CleanStagingDir { + ui.Message("Removing staging directory...") + if err := p.removeDir(ui, comm, p.config.StagingDir); err != nil { + return fmt.Errorf("Error removing staging directory: %s", err) + } + } return nil } @@ -367,15 +377,33 @@ func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst, sr } func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir string) error { - ui.Message(fmt.Sprintf("Creating directory: %s", dir)) cmd := &packer.RemoteCmd{ Command: fmt.Sprintf("mkdir -p '%s'", dir), } + + ui.Message(fmt.Sprintf("Creating directory: %s", dir)) if err := cmd.StartWithUi(comm, ui); err != nil { return err } + if cmd.ExitStatus != 0 { - return fmt.Errorf("Non-zero exit status.") + return fmt.Errorf("Non-zero exit status. See output above for more information.") + } + return nil +} + +func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error { + cmd := &packer.RemoteCmd{ + Command: fmt.Sprintf("rm -rf '%s'", dir), + } + + ui.Message(fmt.Sprintf("Removing directory: %s", dir)) + if err := cmd.StartWithUi(comm, ui); err != nil { + return err + } + + if cmd.ExitStatus != 0 { + return fmt.Errorf("Non-zero exit status. See output above for more information.") } return nil } diff --git a/provisioner/ansible-local/provisioner_test.go b/provisioner/ansible-local/provisioner_test.go index 2195b7107..d96ed113f 100644 --- a/provisioner/ansible-local/provisioner_test.go +++ b/provisioner/ansible-local/provisioner_test.go @@ -188,3 +188,26 @@ func TestProvisionerPrepare_Dirs(t *testing.T) { t.Fatalf("err: %s", err) } } + +func TestProvisionerPrepare_CleanStagingDir(t *testing.T) { + var p Provisioner + config := testConfig() + + playbook_file, err := ioutil.TempFile("", "playbook") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.Remove(playbook_file.Name()) + + config["playbook_file"] = playbook_file.Name() + config["clean_staging_directory"] = true + + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !p.config.CleanStagingDir { + t.Fatalf("expected clean_staging_directory to be set") + } +} diff --git a/website/source/docs/provisioners/ansible-local.html.md b/website/source/docs/provisioners/ansible-local.html.md index 92d46fb3d..5277c8a89 100644 --- a/website/source/docs/provisioners/ansible-local.html.md +++ b/website/source/docs/provisioners/ansible-local.html.md @@ -140,6 +140,10 @@ chi-appservers are not correct, use a shell provisioner prior to this to configure it properly. +- `clean_staging_directory` (boolean) - If set to `true`, the content of + the `staging_directory` will be removed after executing ansible. By + default, this is set to `false`. + ## Default Extra Variables In addition to being able to specify extra arguments using the From 7d80e37c144b83312dc5021c4cb742d5ef39074d Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski <kw@linux.com> Date: Tue, 21 Nov 2017 21:59:27 +0100 Subject: [PATCH 0226/1007] Add new `packer_version` function. Signed-off-by: Krzysztof Wilczynski <kw@linux.com> --- template/interpolate/funcs.go | 26 +++++++++++++------- template/interpolate/funcs_test.go | 21 ++++++++++++++++ website/source/docs/templates/engine.html.md | 1 + 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/template/interpolate/funcs.go b/template/interpolate/funcs.go index ee5e21ccc..924c13d73 100644 --- a/template/interpolate/funcs.go +++ b/template/interpolate/funcs.go @@ -11,6 +11,7 @@ import ( "time" "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/version" ) // InitTime is the UTC time when this package was initialized. It is @@ -24,15 +25,16 @@ func init() { // Funcs are the interpolation funcs that are available within interpolations. var FuncGens = map[string]FuncGenerator{ - "build_name": funcGenBuildName, - "build_type": funcGenBuildType, - "env": funcGenEnv, - "isotime": funcGenIsotime, - "pwd": funcGenPwd, - "template_dir": funcGenTemplateDir, - "timestamp": funcGenTimestamp, - "uuid": funcGenUuid, - "user": funcGenUser, + "build_name": funcGenBuildName, + "build_type": funcGenBuildType, + "env": funcGenEnv, + "isotime": funcGenIsotime, + "pwd": funcGenPwd, + "template_dir": funcGenTemplateDir, + "timestamp": funcGenTimestamp, + "uuid": funcGenUuid, + "user": funcGenUser, + "packer_version": funcGenPackerVersion, "upper": funcGenPrimitive(strings.ToUpper), "lower": funcGenPrimitive(strings.ToLower), @@ -152,3 +154,9 @@ func funcGenUuid(ctx *Context) interface{} { return uuid.TimeOrderedUUID() } } + +func funcGenPackerVersion(ctx *Context) interface{} { + return func() string { + return version.FormattedVersion() + } +} diff --git a/template/interpolate/funcs_test.go b/template/interpolate/funcs_test.go index ab8ee36a4..eca121025 100644 --- a/template/interpolate/funcs_test.go +++ b/template/interpolate/funcs_test.go @@ -4,8 +4,11 @@ import ( "os" "path/filepath" "strconv" + "strings" "testing" "time" + + "github.com/hashicorp/packer/version" ) func TestFuncBuildName(t *testing.T) { @@ -257,3 +260,21 @@ func TestFuncUser(t *testing.T) { } } } + +func TestFuncPackerVersion(t *testing.T) { + template := `{{packer_version}}` + + ctx := &Context{} + i := &I{Value: template} + + result, err := i.Render(ctx) + if err != nil { + t.Fatalf("Input: %s\n\nerr: %s", template, err) + } + + // Only match the X.Y.Z portion of the whole version string. + if !strings.HasPrefix(result, version.Version) { + t.Fatalf("Expected input to include: %s\n\nGot: %s", + version.Version, result) + } +} diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index 3b7c60b24..065e6001b 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -43,6 +43,7 @@ Here is a full list of the available functions for reference. - `uuid` - Returns a random UUID. - `upper` - Uppercases the string. - `user` - Specifies a user variable. +- `packer_version` - Returns Packer version. #### Specific to Amazon builders: From 707ec675b2d64cf16cade5e16c89b5d32fcf61f1 Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Wed, 22 Nov 2017 15:49:38 +1300 Subject: [PATCH 0227/1007] =?UTF-8?q?ssh=20interface=20for=20amazon=20buil?= =?UTF-8?q?ders=20=F0=9F=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/amazon/common/run_config.go | 6 +++ builder/amazon/common/ssh.go | 31 ++++++++++--- builder/amazon/common/ssh_test.go | 60 +++++++++++++++----------- builder/amazon/ebs/builder.go | 2 +- builder/amazon/ebssurrogate/builder.go | 2 +- builder/amazon/ebsvolume/builder.go | 2 +- builder/amazon/instance/builder.go | 2 +- 7 files changed, 71 insertions(+), 34 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 73970e59e..8b605392b 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -54,6 +54,7 @@ type RunConfig struct { Comm communicator.Config `mapstructure:",squash"` SSHKeyPairName string `mapstructure:"ssh_keypair_name"` SSHPrivateIp bool `mapstructure:"ssh_private_ip"` + SSHInterface string `mapstructure:"ssh_interface` } func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { @@ -75,6 +76,11 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RunTags = make(map[string]string) } + // Legacy configurable + if c.SSHPrivateIp { + c.SSHInterface = "private_ip" + } + // Validation errs := c.Comm.Prepare(ctx) if c.SSHKeyPairName != "" { diff --git a/builder/amazon/common/ssh.go b/builder/amazon/common/ssh.go index c451bbf96..34fb64ce1 100644 --- a/builder/amazon/common/ssh.go +++ b/builder/amazon/common/ssh.go @@ -25,21 +25,40 @@ var ( // SSHHost returns a function that can be given to the SSH communicator // for determining the SSH address based on the instance DNS name. -func SSHHost(e ec2Describer, private bool) func(multistep.StateBag) (string, error) { +func SSHHost(e ec2Describer, sshInterface string) func(multistep.StateBag) (string, error) { return func(state multistep.StateBag) (string, error) { const tries = 2 // <= with current structure to check result of describing `tries` times for j := 0; j <= tries; j++ { var host string i := state.Get("instance").(*ec2.Instance) - if i.VpcId != nil && *i.VpcId != "" { - if i.PublicIpAddress != nil && *i.PublicIpAddress != "" && !private { + if sshInterface != "" { + switch sshInterface { + case "public_ip": + if i.PublicIpAddress != nil { + host = *i.PublicIpAddress + } + case "private_ip": + if i.PrivateIpAddress != nil { + host = *i.PrivateIpAddress + } + case "public_dns": + if i.PublicDnsName != nil { + host = *i.PublicDnsName + } + case "private_dns": + if i.PrivateDnsName != nil { + host = *i.PrivateDnsName + } + default: + return "", fmt.Errorf("unknown interface type: %s", sshInterface) + } + } else if i.VpcId != nil && *i.VpcId != "" { + if i.PublicIpAddress != nil && *i.PublicIpAddress != "" { host = *i.PublicIpAddress } else if i.PrivateIpAddress != nil && *i.PrivateIpAddress != "" { host = *i.PrivateIpAddress } - } else if private && i.PrivateIpAddress != nil && *i.PrivateIpAddress != "" { - host = *i.PrivateIpAddress } else if i.PublicDnsName != nil && *i.PublicDnsName != "" { host = *i.PublicDnsName } @@ -63,7 +82,7 @@ func SSHHost(e ec2Describer, private bool) func(multistep.StateBag) (string, err time.Sleep(sshHostSleepDuration) } - return "", errors.New("couldn't determine IP address for instance") + return "", errors.New("couldn't determine address for instance") } } diff --git a/builder/amazon/common/ssh_test.go b/builder/amazon/common/ssh_test.go index 9f1d4a53e..e39088e67 100644 --- a/builder/amazon/common/ssh_test.go +++ b/builder/amazon/common/ssh_test.go @@ -9,9 +9,10 @@ import ( ) const ( - privateIP = "10.0.0.1" - publicIP = "192.168.1.1" - publicDNS = "public.dns.test" + privateIP = "10.0.0.1" + publicIP = "192.168.1.1" + privateDNS = "private.dns.test" + publicDNS = "public.dns.test" ) func TestSSHHost(t *testing.T) { @@ -20,44 +21,54 @@ func TestSSHHost(t *testing.T) { sshHostSleepDuration = 0 var cases = []struct { - allowTries int - vpcId string - private bool + allowTries int + vpcId string + sshInterface string ok bool wantHost string }{ - {1, "", false, true, publicDNS}, - {1, "", true, true, privateIP}, - {1, "vpc-id", false, true, publicIP}, - {1, "vpc-id", true, true, privateIP}, - {2, "", false, true, publicDNS}, - {2, "", true, true, privateIP}, - {2, "vpc-id", false, true, publicIP}, - {2, "vpc-id", true, true, privateIP}, - {3, "", false, false, ""}, - {3, "", true, false, ""}, - {3, "vpc-id", false, false, ""}, - {3, "vpc-id", true, false, ""}, + {1, "", "", true, publicDNS}, + {1, "", "private_ip", true, privateIP}, + {1, "vpc-id", "", true, publicIP}, + {1, "vpc-id", "private_ip", true, privateIP}, + {1, "vpc-id", "private_dns", true, privateDNS}, + {1, "vpc-id", "public_dns", true, publicDNS}, + {1, "vpc-id", "public_ip", true, publicIP}, + {2, "", "", true, publicDNS}, + {2, "", "private_ip", true, privateIP}, + {2, "vpc-id", "", true, publicIP}, + {2, "vpc-id", "private_ip", true, privateIP}, + {2, "vpc-id", "private_dns", true, privateDNS}, + {2, "vpc-id", "public_dns", true, publicDNS}, + {2, "vpc-id", "public_ip", true, publicIP}, + {3, "", "", false, ""}, + {3, "", "private_ip", false, ""}, + {3, "vpc-id", "", false, ""}, + {3, "vpc-id", "private_ip", false, ""}, + {3, "vpc-id", "private_dns", false, ""}, + {3, "vpc-id", "public_dns", false, ""}, + {3, "vpc-id", "public_ip", false, ""}, } for _, c := range cases { - testSSHHost(t, c.allowTries, c.vpcId, c.private, c.ok, c.wantHost) + testSSHHost(t, c.allowTries, c.vpcId, c.sshInterface, c.ok, c.wantHost) } } -func testSSHHost(t *testing.T, allowTries int, vpcId string, private, ok bool, wantHost string) { - t.Logf("allowTries=%d vpcId=%s private=%t ok=%t wantHost=%q", allowTries, vpcId, private, ok, wantHost) +func testSSHHost(t *testing.T, allowTries int, vpcId string, sshInterface string, ok bool, wantHost string) { + t.Logf("allowTries=%d vpcId=%s sshInterface=%s ok=%t wantHost=%q", allowTries, vpcId, sshInterface, ok, wantHost) e := &fakeEC2Describer{ allowTries: allowTries, vpcId: vpcId, privateIP: privateIP, publicIP: publicIP, + privateDNS: privateDNS, publicDNS: publicDNS, } - f := SSHHost(e, private) + f := SSHHost(e, sshInterface) st := &multistep.BasicStateBag{} st.Put("instance", &ec2.Instance{ InstanceId: aws.String("instance-id"), @@ -85,8 +96,8 @@ type fakeEC2Describer struct { allowTries int tries int - vpcId string - privateIP, publicIP, publicDNS string + vpcId string + privateIP, publicIP, privateDNS, publicDNS string } func (d *fakeEC2Describer) DescribeInstances(in *ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) { @@ -104,6 +115,7 @@ func (d *fakeEC2Describer) DescribeInstances(in *ec2.DescribeInstancesInput) (*e instance.PublicIpAddress = aws.String(d.publicIP) instance.PrivateIpAddress = aws.String(d.privateIP) instance.PublicDnsName = aws.String(d.publicDNS) + instance.PrivateDnsName = aws.String(d.privateDNS) } out := &ec2.DescribeInstancesOutput{ diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 1cc346472..56757b826 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -193,7 +193,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Config: &b.config.RunConfig.Comm, Host: awscommon.SSHHost( ec2conn, - b.config.SSHPrivateIp), + b.config.SSHInterface), SSHConfig: awscommon.SSHConfig( b.config.RunConfig.Comm.SSHAgentAuth, b.config.RunConfig.Comm.SSHUsername, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 16e8367da..fec997816 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -204,7 +204,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Config: &b.config.RunConfig.Comm, Host: awscommon.SSHHost( ec2conn, - b.config.SSHPrivateIp), + b.config.SSHInterface), SSHConfig: awscommon.SSHConfig( b.config.RunConfig.Comm.SSHAgentAuth, b.config.RunConfig.Comm.SSHUsername, diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index ea3f74b61..6bd8927ee 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -181,7 +181,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Config: &b.config.RunConfig.Comm, Host: awscommon.SSHHost( ec2conn, - b.config.SSHPrivateIp), + b.config.SSHInterface), SSHConfig: awscommon.SSHConfig( b.config.RunConfig.Comm.SSHAgentAuth, b.config.RunConfig.Comm.SSHUsername, diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 7cee44c09..220ee7b10 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -268,7 +268,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Config: &b.config.RunConfig.Comm, Host: awscommon.SSHHost( ec2conn, - b.config.SSHPrivateIp), + b.config.SSHInterface), SSHConfig: awscommon.SSHConfig( b.config.RunConfig.Comm.SSHAgentAuth, b.config.RunConfig.Comm.SSHUsername, From 7b03613649b4753a0aa281bcb169a1e296bc856b Mon Sep 17 00:00:00 2001 From: Henry Muru Paenga <meringu@gmail.com> Date: Wed, 22 Nov 2017 15:52:22 +1300 Subject: [PATCH 0228/1007] Update docs with ssh_interface --- website/source/docs/builders/amazon-ebs.html.md | 13 ++++++++++--- .../docs/builders/amazon-ebssurrogate.html.md | 11 +++++++++-- .../source/docs/builders/amazon-ebsvolume.html.md | 9 ++++++++- .../source/docs/builders/amazon-instance.html.md | 11 +++++++++-- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index c11525dd0..4385a754a 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -237,7 +237,7 @@ builder. - `temporary_security_group_source_cidr` (string) - An IPv4 CIDR block to be authorized access to the instance, when packer is creating a temporary security group. - The default is `0.0.0.0/0` (ie, allow any IPv4 source). This is only used + The default is `0.0.0.0/0` (ie, allow any IPv4 source). This is only used when `security_group_id` or `security_group_ids` is not specified. - `shutdown_behavior` (string) - Automatically terminate instances on shutdown @@ -328,8 +328,15 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - If true, then SSH will always use the private - IP if available. Also works for WinRM. +- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private + IP if available. Also works for WinRM. Overrides `ssh_interface`. + +- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, + `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, + private IP address, public DNS name or private DNS name will used as the host for SSH. + The default behaviour if inside a VPC is to use the public IP address if available, + otherwise the private IP address will be used. If not in a VPC the public DNS name + will be used. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index c044fc350..30b19ad6b 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -321,8 +321,15 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - If true, then SSH will always use the private - IP if available. +- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private + IP if available. Also works for WinRM. Overrides `ssh_interface`. + +- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, + `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, + private IP address, public DNS name or private DNS name will used as the host for SSH. + The default behaviour if inside a VPC is to use the public IP address if available, + otherwise the private IP address will be used. If not in a VPC the public DNS name + will be used. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 125064626..cc6cf39de 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -226,7 +226,14 @@ builder. must be specified with this. - `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private - IP if available. Also works for WinRM. + IP if available. Also works for WinRM. Overrides `ssh_interface`. + +- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, + `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, + private IP address, public DNS name or private DNS name will used as the host for SSH. + The default behaviour if inside a VPC is to use the public IP address if available, + otherwise the private IP address will be used. If not in a VPC the public DNS name + will be used. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 95a1bc007..93975fb88 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -329,8 +329,15 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - If true, then SSH will always use the private - IP if available. Also works for WinRM. +- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private + IP if available. Also works for WinRM. Overrides `ssh_interface`. + +- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, + `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, + private IP address, public DNS name or private DNS name will used as the host for SSH. + The default behaviour if inside a VPC is to use the public IP address if available, + otherwise the private IP address will be used. If not in a VPC the public DNS name + will be used. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is From 75320440ec2e904faa885c1769bdd3343d04d436 Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Wed, 22 Nov 2017 15:59:15 +1300 Subject: [PATCH 0229/1007] =?UTF-8?q?adding=20missing=20quote=20?= =?UTF-8?q?=F0=9F=99=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/amazon/common/run_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 8b605392b..48f8337f8 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -54,7 +54,7 @@ type RunConfig struct { Comm communicator.Config `mapstructure:",squash"` SSHKeyPairName string `mapstructure:"ssh_keypair_name"` SSHPrivateIp bool `mapstructure:"ssh_private_ip"` - SSHInterface string `mapstructure:"ssh_interface` + SSHInterface string `mapstructure:"ssh_interface"` } func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { From d4f37ab5f69166eea0494c31fa731475a738b2b3 Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Wed, 22 Nov 2017 17:15:46 +1300 Subject: [PATCH 0230/1007] =?UTF-8?q?changing=20config=20varibles=20name?= =?UTF-8?q?=20in=20docs=20to=20match=20names=20in=20code=20=E2=9A=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/source/docs/builders/amazon-ebs.html.md | 4 ++-- website/source/docs/builders/amazon-ebssurrogate.html.md | 4 ++-- website/source/docs/builders/amazon-ebsvolume.html.md | 4 ++-- website/source/docs/builders/amazon-instance.html.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 4385a754a..4d8c56a1e 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -331,8 +331,8 @@ builder. - `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private IP if available. Also works for WinRM. Overrides `ssh_interface`. -- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, - `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, +- `ssh_interface` (string) - One of `public_ip`, `private_ip`, + `public_dns` or `private_dns`. If set, either the public IP address, private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 30b19ad6b..acd976538 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -324,8 +324,8 @@ builder. - `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private IP if available. Also works for WinRM. Overrides `ssh_interface`. -- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, - `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, +- `ssh_interface` (string) - One of `public_ip`, `private_ip`, + `public_dns` or `private_dns`. If set, either the public IP address, private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index cc6cf39de..b022c9e81 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -228,8 +228,8 @@ builder. - `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private IP if available. Also works for WinRM. Overrides `ssh_interface`. -- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, - `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, +- `ssh_interface` (string) - One of `public_ip`, `private_ip`, + `public_dns` or `private_dns`. If set, either the public IP address, private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 93975fb88..8636b6a49 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -332,8 +332,8 @@ builder. - `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private IP if available. Also works for WinRM. Overrides `ssh_interface`. -- `ssh_interface` (string) - One of `PublicIpAddress`, `PrivateIpAddress`, - `PublicDnsName` or `PrivateDnsName`. If set, either the public IP address, +- `ssh_interface` (string) - One of `public_ip`, `private_ip`, + `public_dns` or `private_dns`. If set, either the public IP address, private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name From 0dae5bc8bdaf5d510276e341889445d1e8e0d697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilon=20Sj=C3=B6gren?= <ilon.sjogren@netinsight.net> Date: Wed, 22 Nov 2017 09:13:47 +0100 Subject: [PATCH 0231/1007] Should state that file provisioner requires source at execution time --- website/source/docs/provisioners/file.html.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/file.html.md b/website/source/docs/provisioners/file.html.md index da78d4b61..26e2fc239 100644 --- a/website/source/docs/provisioners/file.html.md +++ b/website/source/docs/provisioners/file.html.md @@ -47,6 +47,9 @@ The available configuration options are listed below. All elements are required. - `direction` (string) - The direction of the file transfer. This defaults to "upload". If it is set to "download" then the file "source" in the machine will be downloaded locally to "destination" + +The source file must exist before running Packer, this means that creating the +file with a provisioner does not work. ## Directory Uploads @@ -90,6 +93,9 @@ drwxr-xr-x 3 mwhooker staff 102 Jan 27 17:10 a lrwxr-xr-x 1 mwhooker staff 1 Jan 27 17:10 b -> a -rw-r--r-- 1 mwhooker staff 0 Jan 27 17:10 file1 lrwxr-xr-x 1 mwhooker staff 5 Jan 27 17:10 file1link -> file1 +$ ls -l toupload +total 0 +-rw-r--r-- 1 mwhooker staff 0 Jan 27 17:10 files.tar ``` ``` json @@ -97,7 +103,7 @@ lrwxr-xr-x 1 mwhooker staff 5 Jan 27 17:10 file1link -> file1 "provisioners": [ { "type": "shell-local", - "command": "mkdir -p toupload; tar cf toupload/files.tar files" + "command": "tar cf toupload/files.tar files" }, { "destination": "/tmp/", From b7e3f37b44bf4738c4b749c5c48316f9e16915fd Mon Sep 17 00:00:00 2001 From: Vijaya Bhaskar Reddy Kondreddi <vijaya.reddy@ni.com> Date: Thu, 12 Oct 2017 16:05:31 +0530 Subject: [PATCH 0232/1007] Add support for differential disk --- builder/hyperv/common/driver.go | 2 +- builder/hyperv/common/driver_ps_4.go | 4 ++-- builder/hyperv/common/step_create_vm.go | 3 ++- builder/hyperv/iso/builder.go | 4 ++++ builder/hyperv/vmcx/builder.go | 3 +++ common/powershell/hyperv/hyperv.go | 23 ++++++++++++++++------- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 3e44b0ece..2a2f0b810 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -64,7 +64,7 @@ type Driver interface { DeleteVirtualSwitch(string) error - CreateVirtualMachine(string, string, string, string, int64, int64, string, uint) error + CreateVirtualMachine(string, string, string, string, int64, int64, string, uint, bool) error AddVirtualMachineHardDrive(string, string, string, int64, string) error diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index 82b4c3f42..853aa7021 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -174,8 +174,8 @@ func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile stri return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, controllerType) } -func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { - return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, switchName, generation) +func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error { + return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, switchName, generation, diffDisks) } func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error { diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index a1d7f0d05..02171d9c6 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -27,6 +27,7 @@ type StepCreateVM struct { EnableSecureBoot bool EnableVirtualizationExtensions bool AdditionalDiskSize []uint + DifferencingDisk bool } func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { @@ -54,7 +55,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { ramSize := int64(s.RamSize * 1024 * 1024) diskSize := int64(s.DiskSize * 1024 * 1024) - err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation) + err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation, s.DifferencingDisk) if err != nil { err := fmt.Errorf("Error creating virtual machine: %s", err) state.Put("error", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index b3c1e1f61..849cbcacf 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -94,6 +94,9 @@ type Config struct { SkipCompaction bool `mapstructure:"skip_compaction"` + // Use differencing disk + DifferencingDisk bool `mapstructure:"differencing_disk"` + ctx interpolate.Context } @@ -353,6 +356,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableSecureBoot: b.config.EnableSecureBoot, EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, AdditionalDiskSize: b.config.AdditionalDiskSize, + DifferencingDisk: b.config.DifferencingDisk, }, &hypervcommon.StepEnableIntegrationService{}, diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 2a9459ace..6a976b3df 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -76,6 +76,9 @@ type Config struct { // By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. VMName string `mapstructure:"vm_name"` + // Use differencing disk + DifferencingDisk bool `mapstructure:"differencing_disk"` + BootCommand []string `mapstructure:"boot_command"` SwitchName string `mapstructure:"switch_name"` SwitchVlanId string `mapstructure:"switch_vlan_id"` diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index b793e171a..25073d238 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -187,40 +187,49 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } -func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint) error { +func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error { if generation == 2 { var script = ` -param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) +param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation, [string]$diffDisks) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx if ($harddrivePath){ - Copy-Item -Path $harddrivePath -Destination $vhdPath + if($diffDisks -eq "true"){ + New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing + } else { + Copy-Item -Path $harddrivePath -Destination $vhdPath + } New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation } else { New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation } ` var ps powershell.PowerShellCmd - if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)); err != nil { + if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10), strconv.FormatBool(diffDisks)); err != nil { return err } return DisableAutomaticCheckpoints(vmName) } else { var script = ` -param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName) +param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [string]$diffDisks) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx if ($harddrivePath){ - Copy-Item -Path $harddrivePath -Destination $vhdPath + if($diffDisks -eq "true"){ + New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing + } + else{ + Copy-Item -Path $harddrivePath -Destination $vhdPath + } New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName } else { New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName } ` var ps powershell.PowerShellCmd - if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName); err != nil { + if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatBool(diffDisks)); err != nil { return err } From 3d5303c60d389d95c5b54b1332dfb10a2cf9e2a8 Mon Sep 17 00:00:00 2001 From: Vijaya Bhaskar Reddy Kondreddi <vijaya.reddy@ni.com> Date: Fri, 24 Nov 2017 13:24:44 +0530 Subject: [PATCH 0233/1007] Fix tests --- builder/hyperv/common/driver_mock.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index dcdd857a5..3823cbd12 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -110,16 +110,17 @@ type DriverMock struct { AddVirtualMachineHardDrive_ControllerType string AddVirtualMachineHardDrive_Err error - CreateVirtualMachine_Called bool - CreateVirtualMachine_VmName string - CreateVirtualMachine_Path string - CreateVirtualMachine_HarddrivePath string - CreateVirtualMachine_VhdPath string - CreateVirtualMachine_Ram int64 - CreateVirtualMachine_DiskSize int64 - CreateVirtualMachine_SwitchName string - CreateVirtualMachine_Generation uint - CreateVirtualMachine_Err error + CreateVirtualMachine_Called bool + CreateVirtualMachine_VmName string + CreateVirtualMachine_Path string + CreateVirtualMachine_HarddrivePath string + CreateVirtualMachine_VhdPath string + CreateVirtualMachine_Ram int64 + CreateVirtualMachine_DiskSize int64 + CreateVirtualMachine_SwitchName string + CreateVirtualMachine_Generation uint + CreateVirtualMachine_DifferentialDisk bool + CreateVirtualMachine_Err error CloneVirtualMachine_Called bool CloneVirtualMachine_CloneFromVmxcPath string @@ -374,7 +375,7 @@ func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, v return d.AddVirtualMachineHardDrive_Err } -func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint) error { +func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error { d.CreateVirtualMachine_Called = true d.CreateVirtualMachine_VmName = vmName d.CreateVirtualMachine_Path = path @@ -384,6 +385,7 @@ func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddriveP d.CreateVirtualMachine_DiskSize = diskSize d.CreateVirtualMachine_SwitchName = switchName d.CreateVirtualMachine_Generation = generation + d.CreateVirtualMachine_DifferentialDisk = diffDisks return d.CreateVirtualMachine_Err } From af8a0c46c540ac5bd28ed6e7ff3ae09df1e86a0b Mon Sep 17 00:00:00 2001 From: Vladislav Rassokhin <vladislav.rassokhin@jetbrains.com> Date: Sun, 26 Nov 2017 00:02:54 +0300 Subject: [PATCH 0234/1007] Do not re-download iso multiple times from different urls In case of two or more iso_urls checks for downloaded files prior to downloading them. Speedups case when some iso already downloaded and another url prepended to iso_urls list. --- common/step_download.go | 45 ++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/common/step_download.go b/common/step_download.go index f63070a04..765a07d23 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -61,10 +61,12 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) - var finalPath string - for _, url := range s.Url { - ui.Message(fmt.Sprintf("Downloading or copying: %s", url)) + // First try to use any already downloaded file + // If it fails, proceed to regualar download logic + var downloadConfigs = make([]*DownloadConfig, len(s.Url)) + var finalPath string + for i, url := range s.Url { targetPath := s.TargetPath if targetPath == "" { // Determine a cache key. This is normally just the URL but @@ -90,22 +92,37 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { Checksum: checksum, UserAgent: "Packer", } + downloadConfigs[i] = config - path, err, retry := s.download(config, state) - if err != nil { - ui.Message(fmt.Sprintf("Error downloading: %s", err)) - } - - if !retry { - return multistep.ActionHalt - } - - if err == nil { - finalPath = path + if match, _ := NewDownloadClient(config).VerifyChecksum(config.TargetPath); match { + ui.Message(fmt.Sprintf("Found already downloaded, initial checksum matched, no download needed: %s", url)) + finalPath = config.TargetPath break } } + if finalPath == "" { + for i, url := range s.Url { + ui.Message(fmt.Sprintf("Downloading or copying: %s", url)) + + config := downloadConfigs[i] + + path, err, retry := s.download(config, state) + if err != nil { + ui.Message(fmt.Sprintf("Error downloading: %s", err)) + } + + if !retry { + return multistep.ActionHalt + } + + if err == nil { + finalPath = path + break + } + } + } + if finalPath == "" { err := fmt.Errorf("%s download failed.", s.Description) state.Put("error", err) From 0c787ec9df19a69f3968835c4f138c62b654a582 Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Tue, 28 Nov 2017 11:46:01 +1300 Subject: [PATCH 0235/1007] =?UTF-8?q?Valadating=20early=20=E2=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/amazon/common/run_config.go | 13 +++++++++++++ builder/amazon/common/ssh.go | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 48f8337f8..7e523740a 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -76,11 +76,24 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RunTags = make(map[string]string) } + if c.SSHPrivateIp && c.SSHInterface { + errs = append(errs, errors.New("ssh_interface and ssh_private_ip should not both be specified")) + } + // Legacy configurable if c.SSHPrivateIp { c.SSHInterface = "private_ip" } + // Valadating ssh_interface + if c.SSHInterface != "public_ip" || + c.SSHInterface != "private_ip" || + c.SSHInterface != "public_dns" || + c.SSHInterface != "private_dns" || + c.SSHInterface != "" { + errs = append(errs, errors.New("Unknown interface type: %s", SSHInterface)) + } + // Validation errs := c.Comm.Prepare(ctx) if c.SSHKeyPairName != "" { diff --git a/builder/amazon/common/ssh.go b/builder/amazon/common/ssh.go index 34fb64ce1..be414a8a0 100644 --- a/builder/amazon/common/ssh.go +++ b/builder/amazon/common/ssh.go @@ -51,7 +51,7 @@ func SSHHost(e ec2Describer, sshInterface string) func(multistep.StateBag) (stri host = *i.PrivateDnsName } default: - return "", fmt.Errorf("unknown interface type: %s", sshInterface) + panic(fmt.Sprintf("Unknown interface type: %s", sshInterface)) } } else if i.VpcId != nil && *i.VpcId != "" { if i.PublicIpAddress != nil && *i.PublicIpAddress != "" { From 52f5f2b895257265916c8a67963231dd0e47d19d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 27 Nov 2017 15:10:29 -0800 Subject: [PATCH 0236/1007] clarify where ansible-local runs --- .../docs/provisioners/ansible-local.html.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/website/source/docs/provisioners/ansible-local.html.md b/website/source/docs/provisioners/ansible-local.html.md index 92d46fb3d..439abb63a 100644 --- a/website/source/docs/provisioners/ansible-local.html.md +++ b/website/source/docs/provisioners/ansible-local.html.md @@ -1,8 +1,10 @@ --- description: | - The ansible-local Packer provisioner configures Ansible to run on the - machine by Packer from local Playbook and Role files. Playbooks and Roles can - be uploaded from your local machine to the remote machine. + The ansible-local Packer provisioner will run ansible "locally" on the + remote/guest VM using Playbook and Role files that exist on the guest VM. + This means ansible must be installed on the remote/guest VM. Playbooks and + Roles can be uploaded from your local machine (the one running Packer) to + the vm. layout: docs page_title: 'Ansible Local - Provisioners' sidebar_current: 'docs-provisioners-ansible-local' @@ -12,15 +14,17 @@ sidebar_current: 'docs-provisioners-ansible-local' Type: `ansible-local` -The `ansible-local` Packer provisioner configures Ansible to run on the machine -by Packer from local Playbook and Role files. Playbooks and Roles can be -uploaded from your local machine to the remote machine. Ansible is run in [local +The `ansible-local` Packer provisioner will run ansible "locally" on the + remote/guest VM using Playbook and Role files that exist on the guest VM. + This means ansible must be installed on the remote/guest VM. Playbooks and + Roles can be uploaded from your local machine (the one running Packer) to + the vm. Ansible is run on the guest machine in [local mode](https://docs.ansible.com/ansible/playbooks_delegation.html#local-playbooks) via the `ansible-playbook` command. -&gt; **Note:** Ansible will *not* be installed automatically by this provisioner. This provisioner expects that Ansible is already installed on the -machine. It is common practice to use the [shell +guest/remote machine. It is common practice to use the [shell provisioner](/docs/provisioners/shell.html) before the Ansible provisioner to do this. From 150bf1f6dab86fdfc4d0bcbd8fac9b2fe3a7404c Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 27 Nov 2017 15:15:52 -0800 Subject: [PATCH 0237/1007] clarify shell-local location --- .../source/docs/provisioners/shell-local.html.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/website/source/docs/provisioners/shell-local.html.md b/website/source/docs/provisioners/shell-local.html.md index bb9022453..e812f3228 100644 --- a/website/source/docs/provisioners/shell-local.html.md +++ b/website/source/docs/provisioners/shell-local.html.md @@ -1,8 +1,9 @@ --- description: | - The shell Packer provisioner provisions machines built by Packer using shell - scripts. Shell provisioning is the easiest way to get software installed and - configured on a machine. + shell-local will run a shell script of your choosing on the machine where Packer + is being run - in other words, it shell-local will run the shell script on your + build server, or your desktop, etc., rather than the remote/guest machine being + provisioned by Packer. layout: docs page_title: 'Shell (Local) - Provisioners' sidebar_current: 'docs-provisioners-shell-local' @@ -12,8 +13,12 @@ sidebar_current: 'docs-provisioners-shell-local' Type: `shell-local` -The local shell provisioner executes a local shell script on the machine running -Packer. The [remote shell](/docs/provisioners/shell.html) provisioner executes +shell-local will run a shell script of your choosing on the machine where Packer +is being run - in other words, it shell-local will run the shell script on your +build server, or your desktop, etc., rather than the remote/guest machine being +provisioned by Packer. + +The [remote shell](/docs/provisioners/shell.html) provisioner executes shell scripts on a remote machine. ## Basic Example From df492d35bfb608ed5f5087c9d3bb4e5a57630742 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 27 Nov 2017 15:17:54 -0800 Subject: [PATCH 0238/1007] remove confusing use of local. dang. --- .../source/docs/provisioners/ansible-local.html.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/source/docs/provisioners/ansible-local.html.md b/website/source/docs/provisioners/ansible-local.html.md index 439abb63a..cec5eee17 100644 --- a/website/source/docs/provisioners/ansible-local.html.md +++ b/website/source/docs/provisioners/ansible-local.html.md @@ -14,12 +14,12 @@ sidebar_current: 'docs-provisioners-ansible-local' Type: `ansible-local` -The `ansible-local` Packer provisioner will run ansible "locally" on the - remote/guest VM using Playbook and Role files that exist on the guest VM. - This means ansible must be installed on the remote/guest VM. Playbooks and - Roles can be uploaded from your local machine (the one running Packer) to - the vm. Ansible is run on the guest machine in [local -mode](https://docs.ansible.com/ansible/playbooks_delegation.html#local-playbooks) via the +The `ansible-local` Packer provisioner will run ansible in ansible's "local" + mode on the remote/guest VM using Playbook and Role files that exist on the + guest VM. This means ansible must be installed on the remote/guest VM. + Playbooks and Roles can be uploaded from your build machine + (the one running Packer) to the vm. Ansible is then run on the guest machine + in [local mode](https://docs.ansible.com/ansible/playbooks_delegation.html#local-playbooks) via the `ansible-playbook` command. -&gt; **Note:** Ansible will *not* be installed automatically by this From a325780aa59da7122d98858d7cb953ee026611a9 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 27 Nov 2017 15:18:58 -0800 Subject: [PATCH 0239/1007] make description match --- website/source/docs/provisioners/ansible-local.html.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/source/docs/provisioners/ansible-local.html.md b/website/source/docs/provisioners/ansible-local.html.md index cec5eee17..b6e7028d9 100644 --- a/website/source/docs/provisioners/ansible-local.html.md +++ b/website/source/docs/provisioners/ansible-local.html.md @@ -1,10 +1,10 @@ --- description: | - The ansible-local Packer provisioner will run ansible "locally" on the - remote/guest VM using Playbook and Role files that exist on the guest VM. - This means ansible must be installed on the remote/guest VM. Playbooks and - Roles can be uploaded from your local machine (the one running Packer) to - the vm. + The ansible-local Packer provisioner will run ansible in ansible's "local" + mode on the remote/guest VM using Playbook and Role files that exist on the + guest VM. This means ansible must be installed on the remote/guest VM. + Playbooks and Roles can be uploaded from your build machine + (the one running Packer) to the vm. layout: docs page_title: 'Ansible Local - Provisioners' sidebar_current: 'docs-provisioners-ansible-local' From be3fe340c8f60db399f11878c457695d2e5d05b7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 27 Nov 2017 17:23:31 -0800 Subject: [PATCH 0240/1007] add a section about uploading files that don't exist. --- website/source/docs/provisioners/file.html.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/file.html.md b/website/source/docs/provisioners/file.html.md index 26e2fc239..0405e8db5 100644 --- a/website/source/docs/provisioners/file.html.md +++ b/website/source/docs/provisioners/file.html.md @@ -47,9 +47,6 @@ The available configuration options are listed below. All elements are required. - `direction` (string) - The direction of the file transfer. This defaults to "upload". If it is set to "download" then the file "source" in the machine will be downloaded locally to "destination" - -The source file must exist before running Packer, this means that creating the -file with a provisioner does not work. ## Directory Uploads @@ -78,6 +75,17 @@ directly. This behavior was adopted from the standard behavior of rsync. Note that under the covers, rsync may or may not be used. +## Uploading files that don't exist before Packer starts + +In general, local files used as the source **must** exist before Packer is run. +This is great for catching typos and ensuring that once a build is started, +that it will succeed. However, this also means that you can't generate a file +during your build and then upload it using the file provisioner later. +A convenient workaround is to upload a directory instead of a file. The +directory still must exist, but its contents don't. You can write your +generated file to the directory during the Packer run, and have it be uploaded +later. + ## Symbolic link uploads The behavior when uploading symbolic links depends on the communicator. The From ff3efb4641411d1cf693d647b652ef08716a4dcc Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 27 Nov 2017 17:26:03 -0800 Subject: [PATCH 0241/1007] remove trailing spaces --- .../source/docs/builders/amazon-ebs.html.md | 2 +- website/source/docs/builders/azure.html.md | 2 +- website/source/docs/builders/docker.html.md | 2 +- .../source/docs/builders/hyperv-iso.html.md | 10 +++--- .../source/docs/builders/hyperv-vmcx.html.md | 36 +++++++++---------- website/source/docs/builders/hyperv.html.md | 4 +-- .../post-processors/vsphere-template.html.md | 14 ++++---- .../docs/provisioners/ansible-local.html.md | 22 ++++++------ .../source/docs/provisioners/ansible.html.md | 2 +- .../docs/provisioners/shell-local.html.md | 12 +++---- 10 files changed, 53 insertions(+), 53 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index c11525dd0..df165ea4b 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -237,7 +237,7 @@ builder. - `temporary_security_group_source_cidr` (string) - An IPv4 CIDR block to be authorized access to the instance, when packer is creating a temporary security group. - The default is `0.0.0.0/0` (ie, allow any IPv4 source). This is only used + The default is `0.0.0.0/0` (ie, allow any IPv4 source). This is only used when `security_group_id` or `security_group_ids` is not specified. - `shutdown_behavior` (string) - Automatically terminate instances on shutdown diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index a4068702a..f673d34fd 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -134,7 +134,7 @@ When creating a managed image the following two options are required. assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer build, e.g. attach a resource disk to the VM. -- `temp_resource_group_name` (string) name assigned to the temporary resource group created during the build. If this +- `temp_resource_group_name` (string) name assigned to the temporary resource group created during the build. If this value is not set, a random value will be assigned. This resource group is deleted at the end of the build. Cannot be used together with `build_resource_group_name`. diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index 8b8e684cd..e1390ff12 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -212,7 +212,7 @@ You must specify (only) one of `commit`, `discard`, or `export_path`. - `container_dir` (string) - The directory inside container to mount temp directory from host server for work [file provisioner](/docs/provisioners/file.html). By default this is set to `/packer-files`. - + - `fix_upload_owner` (boolean) - If true, files uploaded to the container will be owned by the user the container is running as. If false, the owner will depend on the version of docker installed in the system. Defaults to true. diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index b5b6a3826..ff267392c 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -54,20 +54,20 @@ can be configured for this builder. ### Required: - `iso_checksum` (string) - The checksum for the OS ISO file or virtual - harddrive file. Because these files are so large, this is required and - Packer will verify it prior to booting a virtual machine with the ISO or - virtual harddrive attached. The type of the checksum is specified with + harddrive file. Because these files are so large, this is required and + Packer will verify it prior to booting a virtual machine with the ISO or + virtual harddrive attached. The type of the checksum is specified with `iso_checksum_type`, documented below. - `iso_checksum_type` (string) - The type of the checksum specified in `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or "sha512" currently. While "none" will skip checksumming, this is not - recommended since ISO files and virtual harddrive files are generally large + recommended since ISO files and virtual harddrive files are generally large and corruption does happen from time to time. - `iso_url` (string) - A URL to the ISO containing the installation image or virtual harddrive vhd or vhdx file to clone. This URL can be either an HTTP - URL or a file URL (or path to a file). If this is an HTTP URL, Packer will + URL or a file URL (or path to a file). If this is an HTTP URL, Packer will download the file and cache it between runs. ### Optional: diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index d3236a4fe..1aac29fc1 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -10,13 +10,13 @@ page_title: "Hyper-V Builder (from an vmcx)" Type: `hyperv-vmcx` -The Hyper-V Packer builder is able to use exported virtual machines or clone existing +The Hyper-V Packer builder is able to use exported virtual machines or clone existing [Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx) virtual machines. -The builder imports a virtual machine or clones an existing virtual machine boots it, -and provisioning software within the OS, then shutting it down. The result of the -Hyper-V builder is a directory containing all the files necessary to run the virtual +The builder imports a virtual machine or clones an existing virtual machine boots it, +and provisioning software within the OS, then shutting it down. The result of the +Hyper-V builder is a directory containing all the files necessary to run the virtual machine portably. ## Basic Example @@ -193,7 +193,7 @@ can be configured for this builder. * `secondary_iso_images` (array of strings) - A list of iso paths to attached to a VM when it is booted. This is most useful for unattended Windows installs, which look for an `Autounattend.xml` file on removable media. By - default, no secondary iso will be attached. + default, no secondary iso will be attached. - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty @@ -275,7 +275,7 @@ will be replaced by the proper key: - `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. +- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. @@ -289,7 +289,7 @@ will be replaced by the proper key: sending any additional keys. This is useful if you have to generally wait for the UI to update before typing more. -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, otherwise they will be held down until the machine reboots. Use lowercase characters as well inside modifiers. For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. +When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, otherwise they will be held down until the machine reboots. Use lowercase characters as well inside modifiers. For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. In addition to the special keys, each command to type is treated as a [configuration template](/docs/templates/configuration-templates.html). @@ -324,15 +324,15 @@ for the version of Hyper-V that is running. ## Generation 1 vs Generation 2 -Floppy drives are no longer supported by generation 2 machines. This requires you to +Floppy drives are no longer supported by generation 2 machines. This requires you to take another approach when dealing with preseed or answer files. Two possible options are using virtual dvd drives or using the built in web server. -When dealing with Windows you need to enable UEFI drives for generation 2 virtual machines. +When dealing with Windows you need to enable UEFI drives for generation 2 virtual machines. ## Creating iso from directory -Programs like mkisofs can be used to create an iso from a directory. +Programs like mkisofs can be used to create an iso from a directory. There is a [windows version of mkisofs](http://opensourcepack.blogspot.co.uk/p/cdrtools.html). Example powershell script. This is an actually working powershell script used to create a Windows answer iso: @@ -357,7 +357,7 @@ copy windows\common\win-updates.ps1 $isoFolder\ copy windows\common\run-sysprep.ps1 $isoFolder\ copy windows\common\run-sysprep.cmd $isoFolder\ -$textFile = "$isoFolder\Autounattend.xml" +$textFile = "$isoFolder\Autounattend.xml" $c = Get-Content -Encoding UTF8 $textFile @@ -399,7 +399,7 @@ Packer config: "winrm_username": "vagrant", "winrm_password": "vagrant", "winrm_timeout" : "4h", - "shutdown_command": "f:\\run-sysprep.cmd", + "shutdown_command": "f:\\run-sysprep.cmd", "ram_size": 4096, "cpu": 4, "generation": 2, @@ -514,10 +514,10 @@ autounattend.xml: <Order>3</Order> <Size>128</Size> <Type>MSR</Type> - </CreatePartition> + </CreatePartition> <CreatePartition wcm:action="add"> <Order>4</Order> - <Extend>true</Extend> + <Extend>true</Extend> <Type>Primary</Type> </CreatePartition> </CreatePartitions> @@ -609,8 +609,8 @@ autounattend.xml: <POLICYProxySettingsPerUser>0</POLICYProxySettingsPerUser> <HKLMProxyEnable>true</HKLMProxyEnable> <HKLMProxyServer>cache-proxy:3142</HKLMProxyServer> - </component> -Finish Setup cache proxy during installation --> + </component> +Finish Setup cache proxy during installation --> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <AutoLogon> <Password> @@ -842,13 +842,13 @@ sysprep-unattend.xml: </component> </settings> <settings pass="oobeSystem"> -<!-- Setup proxy after sysprep +<!-- Setup proxy after sysprep <component name="Microsoft-Windows-IE-ClientNetworkProtocolImplementation" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <POLICYProxySettingsPerUser>1</POLICYProxySettingsPerUser> <HKLMProxyEnable>false</HKLMProxyEnable> <HKLMProxyServer>cache-proxy:3142</HKLMProxyServer> </component> -Finish proxy after sysprep --> +Finish proxy after sysprep --> <component language="neutral" name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <InputLocale>0809:00000809</InputLocale> <SystemLocale>en-GB</SystemLocale> diff --git a/website/source/docs/builders/hyperv.html.md b/website/source/docs/builders/hyperv.html.md index 57f2015a9..58358f1e9 100644 --- a/website/source/docs/builders/hyperv.html.md +++ b/website/source/docs/builders/hyperv.html.md @@ -18,6 +18,6 @@ virtual machines and export them. an image. This is best for people who want to start from scratch. - [hyperv-vmcx](/docs/builders/hyperv-vmcx.html) - Clones an - an existing virtual machine, provisions software within the OS, - then exports that machine to create an image. This is best for + an existing virtual machine, provisions software within the OS, + then exports that machine to create an image. This is best for people who have existing base images and want to customize them. \ No newline at end of file diff --git a/website/source/docs/post-processors/vsphere-template.html.md b/website/source/docs/post-processors/vsphere-template.html.md index e72dc19cc..a78fade3e 100644 --- a/website/source/docs/post-processors/vsphere-template.html.md +++ b/website/source/docs/post-processors/vsphere-template.html.md @@ -1,7 +1,7 @@ --- description: | The Packer vSphere Template post-processor takes an artifact from the VMware-iso builder built on ESXi (i.e. remote) - and allows to mark a VM as a template and leaving it in a path of choice. + and allows to mark a VM as a template and leaving it in a path of choice. layout: docs page_title: 'vSphere Template - Post-Processors' sidebar_current: 'docs-post-processors-vSphere-template' @@ -19,14 +19,14 @@ allows to mark a VM as a template and leaving it in a path of choice. An example is shown below, showing only the post-processor configuration: ``` json -{ +{ "type": "vsphere-template", "host": "vcenter.local", "insecure": true, "username": "root", - "password": "secret", + "password": "secret", "datacenter": "mydatacenter", - "folder": "/packer-templates/os/distro-7" + "folder": "/packer-templates/os/distro-7" } ``` @@ -38,7 +38,7 @@ each category, the available configuration keys are alphabetized. Required: -- `host` (string) - The vSphere host that contains the VM built by the vmware-iso. +- `host` (string) - The vSphere host that contains the VM built by the vmware-iso. - `password` (string) - Password to use to authenticate to the vSphere endpoint. @@ -48,6 +48,6 @@ Optional: - `datacenter` (string) - If you have more than one, you will need to specify which one the ESXi used. -- `folder` (string) - Target path where the template will be created. +- `folder` (string) - Target path where the template will be created. -- `insecure` (boolean) - If it's true skip verification of server certificate. Default is false +- `insecure` (boolean) - If it's true skip verification of server certificate. Default is false diff --git a/website/source/docs/provisioners/ansible-local.html.md b/website/source/docs/provisioners/ansible-local.html.md index b6e7028d9..5e7467084 100644 --- a/website/source/docs/provisioners/ansible-local.html.md +++ b/website/source/docs/provisioners/ansible-local.html.md @@ -1,10 +1,10 @@ --- description: | - The ansible-local Packer provisioner will run ansible in ansible's "local" - mode on the remote/guest VM using Playbook and Role files that exist on the - guest VM. This means ansible must be installed on the remote/guest VM. - Playbooks and Roles can be uploaded from your build machine - (the one running Packer) to the vm. + The ansible-local Packer provisioner will run ansible in ansible's "local" + mode on the remote/guest VM using Playbook and Role files that exist on the + guest VM. This means ansible must be installed on the remote/guest VM. + Playbooks and Roles can be uploaded from your build machine + (the one running Packer) to the vm. layout: docs page_title: 'Ansible Local - Provisioners' sidebar_current: 'docs-provisioners-ansible-local' @@ -14,11 +14,11 @@ sidebar_current: 'docs-provisioners-ansible-local' Type: `ansible-local` -The `ansible-local` Packer provisioner will run ansible in ansible's "local" - mode on the remote/guest VM using Playbook and Role files that exist on the - guest VM. This means ansible must be installed on the remote/guest VM. - Playbooks and Roles can be uploaded from your build machine - (the one running Packer) to the vm. Ansible is then run on the guest machine +The `ansible-local` Packer provisioner will run ansible in ansible's "local" + mode on the remote/guest VM using Playbook and Role files that exist on the + guest VM. This means ansible must be installed on the remote/guest VM. + Playbooks and Roles can be uploaded from your build machine + (the one running Packer) to the vm. Ansible is then run on the guest machine in [local mode](https://docs.ansible.com/ansible/playbooks_delegation.html#local-playbooks) via the `ansible-playbook` command. @@ -118,7 +118,7 @@ chi-appservers cli](http://docs.ansible.com/ansible/galaxy.html#the-ansible-galaxy-command-line-tool) on the remote machine. By default, this is empty. -- `galaxycommand` (string) - The command to invoke ansible-galaxy. +- `galaxycommand` (string) - The command to invoke ansible-galaxy. By default, this is ansible-galaxy. - `group_vars` (string) - a path to the directory containing ansible group diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 5ea4de0f2..5c9f1c31c 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -250,7 +250,7 @@ SSH servers only allow you to attempt to authenticate a certain number of times. googlecompute: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '[127.0.0.1]:62684' (RSA) to the list of known hosts.\r\nReceived disconnect from 127.0.0.1 port 62684:2: too many authentication failures\r\nAuthentication failed.\r\n", "unreachable": true} ``` -To unload all keys from your `ssh-agent`, run: +To unload all keys from your `ssh-agent`, run: ```console $ ssh-add -D diff --git a/website/source/docs/provisioners/shell-local.html.md b/website/source/docs/provisioners/shell-local.html.md index e812f3228..c52bcd893 100644 --- a/website/source/docs/provisioners/shell-local.html.md +++ b/website/source/docs/provisioners/shell-local.html.md @@ -1,8 +1,8 @@ --- description: | - shell-local will run a shell script of your choosing on the machine where Packer - is being run - in other words, it shell-local will run the shell script on your - build server, or your desktop, etc., rather than the remote/guest machine being + shell-local will run a shell script of your choosing on the machine where Packer + is being run - in other words, it shell-local will run the shell script on your + build server, or your desktop, etc., rather than the remote/guest machine being provisioned by Packer. layout: docs page_title: 'Shell (Local) - Provisioners' @@ -13,9 +13,9 @@ sidebar_current: 'docs-provisioners-shell-local' Type: `shell-local` -shell-local will run a shell script of your choosing on the machine where Packer -is being run - in other words, it shell-local will run the shell script on your -build server, or your desktop, etc., rather than the remote/guest machine being +shell-local will run a shell script of your choosing on the machine where Packer +is being run - in other words, it shell-local will run the shell script on your +build server, or your desktop, etc., rather than the remote/guest machine being provisioned by Packer. The [remote shell](/docs/provisioners/shell.html) provisioner executes From 10aaa49bebf7edbb4c50005aa5b19d5d4f3d434d Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Tue, 28 Nov 2017 14:26:55 +1300 Subject: [PATCH 0242/1007] =?UTF-8?q?fixing=20tests=20and=20funky=20logic?= =?UTF-8?q?=20=F0=9F=92=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- builder/amazon/common/run_config.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 7e523740a..4f20ed3b4 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -76,7 +76,9 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RunTags = make(map[string]string) } - if c.SSHPrivateIp && c.SSHInterface { + // Validation + errs := c.Comm.Prepare(ctx) + if c.SSHPrivateIp && c.SSHInterface != "" { errs = append(errs, errors.New("ssh_interface and ssh_private_ip should not both be specified")) } @@ -86,16 +88,14 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } // Valadating ssh_interface - if c.SSHInterface != "public_ip" || - c.SSHInterface != "private_ip" || - c.SSHInterface != "public_dns" || - c.SSHInterface != "private_dns" || + if c.SSHInterface != "public_ip" && + c.SSHInterface != "private_ip" && + c.SSHInterface != "public_dns" && + c.SSHInterface != "private_dns" && c.SSHInterface != "" { - errs = append(errs, errors.New("Unknown interface type: %s", SSHInterface)) + errs = append(errs, errors.New(fmt.Sprintf("Unknown interface type: %s", c.SSHInterface))) } - // Validation - errs := c.Comm.Prepare(ctx) if c.SSHKeyPairName != "" { if c.Comm.Type == "winrm" && c.Comm.WinRMPassword == "" && c.Comm.SSHPrivateKey == "" { errs = append(errs, errors.New("A private_key_file must be provided to retrieve the winrm password when using ssh_keypair_name.")) From de0017c37a5cee90a73fc35ff872ef13eeebec0f Mon Sep 17 00:00:00 2001 From: zhuzhih2017 <dongxiao.zzh@alibaba-inc.com> Date: Tue, 28 Nov 2017 10:22:16 +0800 Subject: [PATCH 0243/1007] Add security token supported and TLS handshake timeout support --- builder/alicloud/ecs/access_config.go | 8 +- examples/alicloud/basic/alicloud.json | 2 +- .../basic/alicloud_with_data_disk.json | 2 +- .../denverdino/aliyungo/common/client.go | 159 +++++++++++- .../denverdino/aliyungo/common/regions.go | 3 +- .../denverdino/aliyungo/common/request.go | 6 +- .../denverdino/aliyungo/ecs/client.go | 75 ++++-- .../denverdino/aliyungo/ecs/disks.go | 25 ++ .../denverdino/aliyungo/ecs/instances.go | 66 ++++- .../denverdino/aliyungo/ecs/networks.go | 4 +- .../denverdino/aliyungo/ecs/route_tables.go | 1 + .../aliyungo/ecs/router_interface.go | 227 ++++++++++++++++++ .../denverdino/aliyungo/ram/client.go | 21 +- .../denverdino/aliyungo/ram/group.go | 2 + .../denverdino/aliyungo/ram/policy.go | 14 +- .../denverdino/aliyungo/util/encoding.go | 12 +- vendor/vendor.json | 28 +-- .../source/docs/builders/alicloud-ecs.html.md | 6 + 18 files changed, 597 insertions(+), 64 deletions(-) create mode 100644 vendor/github.com/denverdino/aliyungo/ecs/router_interface.go diff --git a/builder/alicloud/ecs/access_config.go b/builder/alicloud/ecs/access_config.go index bcc7ba76f..b49bd0bbf 100644 --- a/builder/alicloud/ecs/access_config.go +++ b/builder/alicloud/ecs/access_config.go @@ -15,6 +15,7 @@ type AlicloudAccessConfig struct { AlicloudSecretKey string `mapstructure:"secret_key"` AlicloudRegion string `mapstructure:"region"` AlicloudSkipValidation bool `mapstructure:"skip_region_validation"` + SecurityToken string `mapstructure:"security_token"` } // Client for AlicloudClient @@ -22,7 +23,12 @@ func (c *AlicloudAccessConfig) Client() (*ecs.Client, error) { if err := c.loadAndValidate(); err != nil { return nil, err } - client := ecs.NewECSClient(c.AlicloudAccessKey, c.AlicloudSecretKey, common.Region(c.AlicloudRegion)) + if c.SecurityToken == "" { + c.SecurityToken = os.Getenv("SECURITY_TOKEN") + } + client := ecs.NewECSClientWithSecurityToken(c.AlicloudAccessKey, c.AlicloudSecretKey, + c.SecurityToken, common.Region(c.AlicloudRegion)) + client.SetBusinessInfo("Packer") if _, err := client.DescribeRegions(); err != nil { return nil, err diff --git a/examples/alicloud/basic/alicloud.json b/examples/alicloud/basic/alicloud.json index 8f83262fe..d0c643f48 100644 --- a/examples/alicloud/basic/alicloud.json +++ b/examples/alicloud/basic/alicloud.json @@ -9,7 +9,7 @@ "secret_key":"{{user `secret_key`}}", "region":"cn-beijing", "image_name":"packer_basic", - "source_image":"centos_7_2_64_40G_base_20170222.vhd", + "source_image":"centos_7_03_64_20G_alibase_20170818.vhd", "ssh_username":"root", "instance_type":"ecs.n1.tiny", "internet_charge_type":"PayByTraffic", diff --git a/examples/alicloud/basic/alicloud_with_data_disk.json b/examples/alicloud/basic/alicloud_with_data_disk.json index 31f10ab70..dcc8c70ef 100644 --- a/examples/alicloud/basic/alicloud_with_data_disk.json +++ b/examples/alicloud/basic/alicloud_with_data_disk.json @@ -9,7 +9,7 @@ "secret_key":"{{user `secret_key`}}", "region":"cn-beijing", "image_name":"packer_with_data_disk", - "source_image":"centos_7_2_64_40G_base_20170222.vhd", + "source_image":"centos_7_03_64_20G_alibase_20170818.vhd", "ssh_username":"root", "instance_type":"ecs.n1.tiny", "internet_charge_type":"PayByTraffic", diff --git a/vendor/github.com/denverdino/aliyungo/common/client.go b/vendor/github.com/denverdino/aliyungo/common/client.go index a59789fee..10dcd9000 100755 --- a/vendor/github.com/denverdino/aliyungo/common/client.go +++ b/vendor/github.com/denverdino/aliyungo/common/client.go @@ -3,12 +3,16 @@ package common import ( "bytes" "encoding/json" + "errors" + "fmt" "io/ioutil" "log" "net/http" "net/url" "strings" "time" + "os" + "strconv" "github.com/denverdino/aliyungo/util" ) @@ -25,6 +29,7 @@ type UnderlineString string type Client struct { AccessKeyId string //Access Key Id AccessKeySecret string //Access Key Secret + securityToken string debug bool httpClient *http.Client endpoint string @@ -32,19 +37,30 @@ type Client struct { serviceCode string regionID Region businessInfo string - userAgent string + userAgent string } -// NewClient creates a new instance of ECS client +// Initialize properties of a client instance func (client *Client) Init(endpoint, version, accessKeyId, accessKeySecret string) { client.AccessKeyId = accessKeyId client.AccessKeySecret = accessKeySecret + "&" client.debug = false - client.httpClient = &http.Client{} + handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout")) + if err != nil { + handshakeTimeout = 0 + } + if handshakeTimeout == 0 { + client.httpClient = &http.Client{} + } else { + t := &http.Transport{ + TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second,} + client.httpClient = &http.Client{Transport: t,} + } client.endpoint = endpoint client.version = version } +// Initialize properties of a client instance including regionID func (client *Client) NewInit(endpoint, version, accessKeyId, accessKeySecret, serviceCode string, regionID Region) { client.Init(endpoint, version, accessKeyId, accessKeySecret) client.serviceCode = serviceCode @@ -52,6 +68,24 @@ func (client *Client) NewInit(endpoint, version, accessKeyId, accessKeySecret, s client.setEndpointByLocation(regionID, serviceCode, accessKeyId, accessKeySecret) } +// Intialize client object when all properties are ready +func (client *Client) InitClient() *Client { + client.debug = false + handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout")) + if err != nil { + handshakeTimeout = 0 + } + if handshakeTimeout == 0 { + client.httpClient = &http.Client{} + } else { + t := &http.Transport{ + TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second,} + client.httpClient = &http.Client{Transport: t,} + } + client.setEndpointByLocation(client.regionID, client.serviceCode, client.AccessKeyId, client.AccessKeySecret) + return client +} + //NewClient using location service func (client *Client) setEndpointByLocation(region Region, serviceCode, accessKeyId, accessKeySecret string) { locationClient := NewLocationClient(accessKeyId, accessKeySecret) @@ -65,6 +99,95 @@ func (client *Client) setEndpointByLocation(region Region, serviceCode, accessKe } } +// Ensure all necessary properties are valid +func (client *Client) ensureProperties() error { + var msg string + + if client.endpoint == "" { + msg = fmt.Sprintf("endpoint cannot be empty!") + } else if client.version == "" { + msg = fmt.Sprintf("version cannot be empty!") + } else if client.AccessKeyId == "" { + msg = fmt.Sprintf("AccessKeyId cannot be empty!") + } else if client.AccessKeySecret == "" { + msg = fmt.Sprintf("AccessKeySecret cannot be empty!") + } + + if msg != "" { + return errors.New(msg) + } + + return nil +} + +// ---------------------------------------------------- +// WithXXX methods +// ---------------------------------------------------- + +// WithEndpoint sets custom endpoint +func (client *Client) WithEndpoint(endpoint string) *Client { + client.SetEndpoint(endpoint) + return client +} + +// WithVersion sets custom version +func (client *Client) WithVersion(version string) *Client { + client.SetVersion(version) + return client +} + +// WithRegionID sets Region ID +func (client *Client) WithRegionID(regionID Region) *Client { + client.SetRegionID(regionID) + return client +} + +//WithServiceCode sets serviceCode +func (client *Client) WithServiceCode(serviceCode string) *Client { + client.SetServiceCode(serviceCode) + return client +} + +// WithAccessKeyId sets new AccessKeyId +func (client *Client) WithAccessKeyId(id string) *Client { + client.SetAccessKeyId(id) + return client +} + +// WithAccessKeySecret sets new AccessKeySecret +func (client *Client) WithAccessKeySecret(secret string) *Client { + client.SetAccessKeySecret(secret) + return client +} + +// WithSecurityToken sets securityToken +func (client *Client) WithSecurityToken(securityToken string) *Client { + client.SetSecurityToken(securityToken) + return client +} + +// WithDebug sets debug mode to log the request/response message +func (client *Client) WithDebug(debug bool) *Client { + client.SetDebug(debug) + return client +} + +// WithBusinessInfo sets business info to log the request/response message +func (client *Client) WithBusinessInfo(businessInfo string) *Client { + client.SetBusinessInfo(businessInfo) + return client +} + +// WithUserAgent sets user agent to the request/response message +func (client *Client) WithUserAgent(userAgent string) *Client { + client.SetUserAgent(userAgent) + return client +} + +// ---------------------------------------------------- +// SetXXX methods +// ---------------------------------------------------- + // SetEndpoint sets custom endpoint func (client *Client) SetEndpoint(endpoint string) { client.endpoint = endpoint @@ -75,6 +198,7 @@ func (client *Client) SetVersion(version string) { client.version = version } +// SetEndpoint sets Region ID func (client *Client) SetRegionID(regionID Region) { client.regionID = regionID } @@ -94,6 +218,11 @@ func (client *Client) SetAccessKeySecret(secret string) { client.AccessKeySecret = secret + "&" } +// SetAccessKeySecret sets securityToken +func (client *Client) SetSecurityToken(securityToken string) { + client.securityToken = securityToken +} + // SetDebug sets debug mode to log the request/response message func (client *Client) SetDebug(debug bool) { client.debug = debug @@ -115,9 +244,12 @@ func (client *Client) SetUserAgent(userAgent string) { // Invoke sends the raw HTTP request for ECS services func (client *Client) Invoke(action string, args interface{}, response interface{}) error { + if err := client.ensureProperties(); err != nil { + return err + } request := Request{} - request.init(client.version, action, client.AccessKeyId) + request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID) query := util.ConvertToQueryValues(request) util.SetQueryValues(args, &query) @@ -136,8 +268,7 @@ func (client *Client) Invoke(action string, args interface{}, response interface // TODO move to util and add build val flag httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo) - - httpReq.Header.Set("User-Agent", httpReq.UserAgent()+ " " +client.userAgent) + httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent) t0 := time.Now() httpResp, err := client.httpClient.Do(httpReq) @@ -185,9 +316,12 @@ func (client *Client) Invoke(action string, args interface{}, response interface // Invoke sends the raw HTTP request for ECS services func (client *Client) InvokeByFlattenMethod(action string, args interface{}, response interface{}) error { + if err := client.ensureProperties(); err != nil { + return err + } request := Request{} - request.init(client.version, action, client.AccessKeyId) + request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID) query := util.ConvertToQueryValues(request) @@ -207,8 +341,7 @@ func (client *Client) InvokeByFlattenMethod(action string, args interface{}, res // TODO move to util and add build val flag httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo) - - httpReq.Header.Set("User-Agent", httpReq.UserAgent()+ " " +client.userAgent) + httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent) t0 := time.Now() httpResp, err := client.httpClient.Do(httpReq) @@ -258,9 +391,12 @@ func (client *Client) InvokeByFlattenMethod(action string, args interface{}, res //改进了一下上面那个方法,可以使用各种Http方法 //2017.1.30 增加了一个path参数,用来拓展访问的地址 func (client *Client) InvokeByAnyMethod(method, action, path string, args interface{}, response interface{}) error { + if err := client.ensureProperties(); err != nil { + return err + } request := Request{} - request.init(client.version, action, client.AccessKeyId) + request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID) data := util.ConvertToQueryValues(request) util.SetQueryValues(args, &data) @@ -290,8 +426,7 @@ func (client *Client) InvokeByAnyMethod(method, action, path string, args interf // TODO move to util and add build val flag httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo) - - httpReq.Header.Set("User-Agent", httpReq.Header.Get("User-Agent")+ " " +client.userAgent) + httpReq.Header.Set("User-Agent", httpReq.Header.Get("User-Agent")+" "+client.userAgent) t0 := time.Now() httpResp, err := client.httpClient.Do(httpReq) diff --git a/vendor/github.com/denverdino/aliyungo/common/regions.go b/vendor/github.com/denverdino/aliyungo/common/regions.go index 62e6e9d81..c87fe0691 100644 --- a/vendor/github.com/denverdino/aliyungo/common/regions.go +++ b/vendor/github.com/denverdino/aliyungo/common/regions.go @@ -16,6 +16,7 @@ const ( APSouthEast1 = Region("ap-southeast-1") APNorthEast1 = Region("ap-northeast-1") APSouthEast2 = Region("ap-southeast-2") + APSouthEast3 = Region("ap-southeast-3") USWest1 = Region("us-west-1") USEast1 = Region("us-east-1") @@ -28,7 +29,7 @@ const ( var ValidRegions = []Region{ Hangzhou, Qingdao, Beijing, Shenzhen, Hongkong, Shanghai, Zhangjiakou, USWest1, USEast1, - APNorthEast1, APSouthEast1, APSouthEast2, + APNorthEast1, APSouthEast1, APSouthEast2, APSouthEast3, MEEast1, EUCentral1, } diff --git a/vendor/github.com/denverdino/aliyungo/common/request.go b/vendor/github.com/denverdino/aliyungo/common/request.go index 2a883f19b..f35c2990d 100644 --- a/vendor/github.com/denverdino/aliyungo/common/request.go +++ b/vendor/github.com/denverdino/aliyungo/common/request.go @@ -20,7 +20,9 @@ const ( type Request struct { Format string Version string + RegionId Region AccessKeyId string + SecurityToken string Signature string SignatureMethod string Timestamp util.ISO6801Time @@ -30,7 +32,7 @@ type Request struct { Action string } -func (request *Request) init(version string, action string, AccessKeyId string) { +func (request *Request) init(version string, action string, AccessKeyId string, securityToken string, regionId Region) { request.Format = JSONResponseFormat request.Timestamp = util.NewISO6801Time(time.Now().UTC()) request.Version = version @@ -39,6 +41,8 @@ func (request *Request) init(version string, action string, AccessKeyId string) request.SignatureNonce = util.CreateRandomString() request.Action = action request.AccessKeyId = AccessKeyId + request.SecurityToken = securityToken + request.RegionId = regionId } type Response struct { diff --git a/vendor/github.com/denverdino/aliyungo/ecs/client.go b/vendor/github.com/denverdino/aliyungo/ecs/client.go index d70a1554e..117483c35 100644 --- a/vendor/github.com/denverdino/aliyungo/ecs/client.go +++ b/vendor/github.com/denverdino/aliyungo/ecs/client.go @@ -20,8 +20,7 @@ const ( // ECSDefaultEndpoint is the default API endpoint of ECS services ECSDefaultEndpoint = "https://ecs-cn-hangzhou.aliyuncs.com" ECSAPIVersion = "2014-05-26" - - ECSServiceCode = "ecs" + ECSServiceCode = "ecs" VPCDefaultEndpoint = "https://vpc.aliyuncs.com" VPCAPIVersion = "2016-04-28" @@ -37,38 +36,80 @@ func NewClient(accessKeyId, accessKeySecret string) *Client { return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) } -func NewECSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client { - endpoint := os.Getenv("ECS_ENDPOINT") - if endpoint == "" { - endpoint = ECSDefaultEndpoint - } - - return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID) -} - -func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client { +func NewClientWithRegion(endpoint string, accessKeyId string, accessKeySecret string, regionID common.Region) *Client { client := &Client{} client.NewInit(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret, ECSServiceCode, regionID) return client } -func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client { +func NewClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) *Client { client := &Client{} client.Init(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret) return client } -func NewVPCClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client { +// --------------------------------------- +// NewECSClient creates a new instance of ECS client +// --------------------------------------- +func NewECSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client { + return NewECSClientWithSecurityToken(accessKeyId, accessKeySecret, "", regionID) +} + +func NewECSClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client { + endpoint := os.Getenv("ECS_ENDPOINT") + if endpoint == "" { + endpoint = ECSDefaultEndpoint + } + + return NewECSClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID) +} + +func NewECSClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string, regionID common.Region) *Client { + return NewECSClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "", regionID) +} + +func NewECSClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client { + client := &Client{} + client.WithEndpoint(endpoint). + WithVersion(ECSAPIVersion). + WithAccessKeyId(accessKeyId). + WithAccessKeySecret(accessKeySecret). + WithSecurityToken(securityToken). + WithServiceCode(ECSServiceCode). + WithRegionID(regionID). + InitClient() + return client +} + +// --------------------------------------- +// NewVPCClient creates a new instance of VPC client +// --------------------------------------- +func NewVPCClient(accessKeyId string, accessKeySecret string, regionID common.Region) *Client { + return NewVPCClientWithSecurityToken(accessKeyId, accessKeySecret, "", regionID) +} + +func NewVPCClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client { endpoint := os.Getenv("VPC_ENDPOINT") if endpoint == "" { endpoint = VPCDefaultEndpoint } - return NewVPCClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID) + return NewVPCClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID) } -func NewVPCClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client { +func NewVPCClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string, regionID common.Region) *Client { + return NewVPCClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "", regionID) +} + +func NewVPCClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client { client := &Client{} - client.NewInit(endpoint, VPCAPIVersion, accessKeyId, accessKeySecret, VPCServiceCode, regionID) + client.WithEndpoint(endpoint). + WithVersion(VPCAPIVersion). + WithAccessKeyId(accessKeyId). + WithAccessKeySecret(accessKeySecret). + WithSecurityToken(securityToken). + WithServiceCode(VPCServiceCode). + WithRegionID(regionID). + InitClient() return client } diff --git a/vendor/github.com/denverdino/aliyungo/ecs/disks.go b/vendor/github.com/denverdino/aliyungo/ecs/disks.go index 7a67c380d..6b898c60d 100644 --- a/vendor/github.com/denverdino/aliyungo/ecs/disks.go +++ b/vendor/github.com/denverdino/aliyungo/ecs/disks.go @@ -135,6 +135,7 @@ type CreateDiskArgs struct { ZoneId string DiskName string Description string + Encrypted bool DiskCategory DiskCategory Size int SnapshotId string @@ -240,6 +241,29 @@ func (client *Client) DetachDisk(instanceId string, diskId string) error { return err } +type ResizeDiskArgs struct { + DiskId string + NewSize int +} + +type ResizeDiskResponse struct { + common.Response +} + +// +// ResizeDisk can only support to enlarge disk size +// You can read doc at https://help.aliyun.com/document_detail/25522.html +func (client *Client) ResizeDisk(diskId string, sizeGB int) error { + args := ResizeDiskArgs{ + DiskId:diskId, + NewSize:sizeGB, + } + response := ResizeDiskResponse{} + err := client.Invoke("ResizeDisk", &args, &response) + return err +} + + type ResetDiskArgs struct { DiskId string SnapshotId string @@ -249,6 +273,7 @@ type ResetDiskResponse struct { common.Response } + // ResetDisk resets disk to original status // // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&resetdisk diff --git a/vendor/github.com/denverdino/aliyungo/ecs/instances.go b/vendor/github.com/denverdino/aliyungo/ecs/instances.go index 4eb999537..a08ac1244 100644 --- a/vendor/github.com/denverdino/aliyungo/ecs/instances.go +++ b/vendor/github.com/denverdino/aliyungo/ecs/instances.go @@ -224,6 +224,7 @@ type SpotStrategyType string const ( NoSpot = SpotStrategyType("NoSpot") SpotWithPriceLimit = SpotStrategyType("SpotWithPriceLimit") + SpotAsPriceGo = SpotStrategyType("SpotAsPriceGo") ) // @@ -244,7 +245,7 @@ type InstanceAttributesType struct { SerialNumber string Status InstanceStatus OperationLocks OperationLocksType - SecurityGroupIds struct { + SecurityGroupIds struct { SecurityGroupId []string } PublicIpAddress IpAddressSetType @@ -259,11 +260,12 @@ type InstanceAttributesType struct { IoOptimized StringOrBool InstanceChargeType common.InstanceChargeType ExpiredTime util.ISO6801Time - Tags struct { + Tags struct { Tag []TagItemType } - SpotStrategy SpotStrategyType - KeyPairName string + SpotStrategy SpotStrategyType + SpotPriceLimit float64 + KeyPairName string } type DescribeInstanceAttributeResponse struct { @@ -535,7 +537,9 @@ type CreateInstanceArgs struct { AutoRenew bool AutoRenewPeriod int SpotStrategy SpotStrategyType + SpotPriceLimit float64 KeyPairName string + RamRoleName string } type CreateInstanceResponse struct { @@ -624,3 +628,57 @@ func (client *Client) LeaveSecurityGroup(instanceId string, securityGroupId stri err := client.Invoke("LeaveSecurityGroup", &args, &response) return err } + +type AttachInstancesArgs struct { + RegionId common.Region + RamRoleName string + InstanceIds string +} + +// AttachInstanceRamRole attach instances to ram role +// +// You can read doc at https://help.aliyun.com/document_detail/54244.html?spm=5176.doc54245.6.811.zEJcS5 +func (client *Client) AttachInstanceRamRole(args *AttachInstancesArgs) (err error) { + response := common.Response{} + err = client.Invoke("AttachInstanceRamRole", args, &response) + if err != nil { + return err + } + return nil +} + +// DetachInstanceRamRole detach instances from ram role +// +// You can read doc at https://help.aliyun.com/document_detail/54245.html?spm=5176.doc54243.6.813.bt8RB3 +func (client *Client) DetachInstanceRamRole(args *AttachInstancesArgs) (err error) { + response := common.Response{} + err = client.Invoke("DetachInstanceRamRole", args, &response) + if err != nil { + return err + } + return nil +} + +type DescribeInstanceRamRoleResponse struct { + common.Response + InstanceRamRoleSets struct { + InstanceRamRoleSet []InstanceRamRoleSetType + } +} + +type InstanceRamRoleSetType struct { + InstanceId string + RamRoleName string +} + +// DescribeInstanceRamRole +// +// You can read doc at https://help.aliyun.com/document_detail/54243.html?spm=5176.doc54245.6.812.RgNCoi +func (client *Client) DescribeInstanceRamRole(args *AttachInstancesArgs) (resp *DescribeInstanceRamRoleResponse, err error) { + response := &DescribeInstanceRamRoleResponse{} + err = client.Invoke("DescribeInstanceRamRole", args, response) + if err != nil { + return response, err + } + return response, nil +} diff --git a/vendor/github.com/denverdino/aliyungo/ecs/networks.go b/vendor/github.com/denverdino/aliyungo/ecs/networks.go index 100835c37..4c4cd7150 100644 --- a/vendor/github.com/denverdino/aliyungo/ecs/networks.go +++ b/vendor/github.com/denverdino/aliyungo/ecs/networks.go @@ -36,8 +36,8 @@ func (client *Client) AllocatePublicIpAddress(instanceId string) (ipAddress stri type ModifyInstanceNetworkSpec struct { InstanceId string - InternetMaxBandwidthOut *int - InternetMaxBandwidthIn *int + InternetMaxBandwidthOut int + InternetMaxBandwidthIn int } type ModifyInstanceNetworkSpecResponse struct { diff --git a/vendor/github.com/denverdino/aliyungo/ecs/route_tables.go b/vendor/github.com/denverdino/aliyungo/ecs/route_tables.go index cc85cb129..f8531a20b 100644 --- a/vendor/github.com/denverdino/aliyungo/ecs/route_tables.go +++ b/vendor/github.com/denverdino/aliyungo/ecs/route_tables.go @@ -102,6 +102,7 @@ type NextHopType string const ( NextHopIntance = NextHopType("Instance") //Default NextHopTunnel = NextHopType("Tunnel") + NextHopTunnelRouterInterface = NextHopType("RouterInterface") ) type CreateRouteEntryArgs struct { diff --git a/vendor/github.com/denverdino/aliyungo/ecs/router_interface.go b/vendor/github.com/denverdino/aliyungo/ecs/router_interface.go new file mode 100644 index 000000000..62af67860 --- /dev/null +++ b/vendor/github.com/denverdino/aliyungo/ecs/router_interface.go @@ -0,0 +1,227 @@ +package ecs + +import ( + "github.com/denverdino/aliyungo/common" +) + +type EcsCommonResponse struct { + common.Response +} +type RouterType string +type InterfaceStatus string +type Role string +type Spec string + +const ( + VRouter = RouterType("VRouter") + VBR = RouterType("VBR") + + Idl = InterfaceStatus("Idl") + Active = InterfaceStatus("Active") + Inactive = InterfaceStatus("Inactive") + + InitiatingSide = Role("InitiatingSide") + AcceptingSide = Role("AcceptingSide") + + Small1 = Spec("Small.1") + Small2 = Spec("Small.2") + Small5 = Spec("Small.5") + Middle1 = Spec("Middle.1") + Middle2 = Spec("Middle.2") + Middle5 = Spec("Middle.5") + Large1 = Spec("Large.1") + Large2 = Spec("Large.2") +) + +type CreateRouterInterfaceArgs struct { + RegionId common.Region + OppositeRegionId common.Region + RouterType RouterType + OppositeRouterType RouterType + RouterId string + OppositeRouterId string + Role Role + Spec Spec + AccessPointId string + OppositeAccessPointId string + OppositeInterfaceId string + OppositeInterfaceOwnerId string + Name string + Description string + HealthCheckSourceIp string + HealthCheckTargetIp string +} + +type CreateRouterInterfaceResponse struct { + common.Response + RouterInterfaceId string +} + +// CreateRouterInterface create Router interface +// +// You can read doc at https://help.aliyun.com/document_detail/36032.html?spm=5176.product27706.6.664.EbBsxC +func (client *Client) CreateRouterInterface(args *CreateRouterInterfaceArgs) (response *CreateRouterInterfaceResponse, err error) { + response = &CreateRouterInterfaceResponse{} + err = client.Invoke("CreateRouterInterface", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +type Filter struct { + Key string + Value []string +} + +type DescribeRouterInterfacesArgs struct { + RegionId common.Region + common.Pagination + Filter []Filter +} + +type RouterInterfaceItemType struct { + ChargeType string + RouterInterfaceId string + AccessPointId string + OppositeRegionId string + OppositeAccessPointId string + Role Role + Spec Spec + Name string + Description string + RouterId string + RouterType RouterType + CreationTime string + Status string + BusinessStatus string + ConnectedTime string + OppositeInterfaceId string + OppositeInterfaceSpec string + OppositeInterfaceStatus string + OppositeInterfaceBusinessStatus string + OppositeRouterId string + OppositeRouterType RouterType + OppositeInterfaceOwnerId string + HealthCheckSourceIp string + HealthCheckTargetIp string +} + +type DescribeRouterInterfacesResponse struct { + RouterInterfaceSet struct { + RouterInterfaceType []RouterInterfaceItemType + } + common.PaginationResult +} + +// DescribeRouterInterfaces describe Router interfaces +// +// You can read doc at https://help.aliyun.com/document_detail/36032.html?spm=5176.product27706.6.664.EbBsxC +func (client *Client) DescribeRouterInterfaces(args *DescribeRouterInterfacesArgs) (response *DescribeRouterInterfacesResponse, err error) { + response = &DescribeRouterInterfacesResponse{} + err = client.Invoke("DescribeRouterInterfaces", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +type OperateRouterInterfaceArgs struct { + RegionId common.Region + RouterInterfaceId string +} + +// ConnectRouterInterface +// +// You can read doc at https://help.aliyun.com/document_detail/36031.html?spm=5176.doc36035.6.666.wkyljN +func (client *Client) ConnectRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) { + response = &EcsCommonResponse{} + err = client.Invoke("ConnectRouterInterface", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +// ActivateRouterInterface active Router Interface +// +// You can read doc at https://help.aliyun.com/document_detail/36030.html?spm=5176.doc36031.6.667.DAuZLD +func (client *Client) ActivateRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) { + response = &EcsCommonResponse{} + err = client.Invoke("ActivateRouterInterface", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +// DeactivateRouterInterface deactivate Router Interface +// +// You can read doc at https://help.aliyun.com/document_detail/36033.html?spm=5176.doc36030.6.668.JqCWUz +func (client *Client) DeactivateRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) { + response = &EcsCommonResponse{} + err = client.Invoke("DeactivateRouterInterface", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +type ModifyRouterInterfaceSpecArgs struct { + RegionId common.Region + RouterInterfaceId string + Spec Spec +} + +type ModifyRouterInterfaceSpecResponse struct { + common.Response + Spec Spec +} + +// ModifyRouterInterfaceSpec +// +// You can read doc at https://help.aliyun.com/document_detail/36037.html?spm=5176.doc36036.6.669.McKiye +func (client *Client) ModifyRouterInterfaceSpec(args *ModifyRouterInterfaceSpecArgs) (response *ModifyRouterInterfaceSpecResponse, err error) { + response = &ModifyRouterInterfaceSpecResponse{} + err = client.Invoke("ModifyRouterInterfaceSpec", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +type ModifyRouterInterfaceAttributeArgs struct { + RegionId common.Region + RouterInterfaceId string + Name string + Description string + OppositeInterfaceId string + OppositeRouterId string + OppositeInterfaceOwnerId string + HealthCheckSourceIp string + HealthCheckTargetIp string +} + +// ModifyRouterInterfaceAttribute +// +// You can read doc at https://help.aliyun.com/document_detail/36036.html?spm=5176.doc36037.6.670.Dcz3xS +func (client *Client) ModifyRouterInterfaceAttribute(args *ModifyRouterInterfaceAttributeArgs) (response *EcsCommonResponse, err error) { + response = &EcsCommonResponse{} + err = client.Invoke("ModifyRouterInterfaceAttribute", args, &response) + if err != nil { + return response, err + } + return response, nil +} + +// DeleteRouterInterface delete Router Interface +// +// You can read doc at https://help.aliyun.com/document_detail/36034.html?spm=5176.doc36036.6.671.y2xpNt +func (client *Client) DeleteRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) { + response = &EcsCommonResponse{} + err = client.Invoke("DeleteRouterInterface", args, &response) + if err != nil { + return response, err + } + return response, nil +} diff --git a/vendor/github.com/denverdino/aliyungo/ram/client.go b/vendor/github.com/denverdino/aliyungo/ram/client.go index 974bc023f..2a29bd804 100644 --- a/vendor/github.com/denverdino/aliyungo/ram/client.go +++ b/vendor/github.com/denverdino/aliyungo/ram/client.go @@ -1,8 +1,9 @@ package ram import ( - "github.com/denverdino/aliyungo/common" "os" + + "github.com/denverdino/aliyungo/common" ) const ( @@ -16,15 +17,29 @@ type RamClient struct { } func NewClient(accessKeyId string, accessKeySecret string) RamClientInterface { + return NewClientWithSecurityToken(accessKeyId, accessKeySecret, "") +} + +func NewClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string) RamClientInterface { endpoint := os.Getenv("RAM_ENDPOINT") if endpoint == "" { endpoint = RAMDefaultEndpoint } - return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) + + return NewClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken) } func NewClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) RamClientInterface { + return NewClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "") +} + +func NewClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string) RamClientInterface { client := &RamClient{} - client.Init(endpoint, RAMAPIVersion, accessKeyId, accessKeySecret) + client.WithEndpoint(endpoint). + WithVersion(RAMAPIVersion). + WithAccessKeyId(accessKeyId). + WithAccessKeySecret(accessKeySecret). + WithSecurityToken(securityToken). + InitClient() return client } diff --git a/vendor/github.com/denverdino/aliyungo/ram/group.go b/vendor/github.com/denverdino/aliyungo/ram/group.go index 6f1224f5f..491e6931d 100644 --- a/vendor/github.com/denverdino/aliyungo/ram/group.go +++ b/vendor/github.com/denverdino/aliyungo/ram/group.go @@ -31,6 +31,8 @@ type GroupResponse struct { type GroupListResponse struct { RamCommonResponse + IsTruncated bool + Marker string Groups struct { Group []Group } diff --git a/vendor/github.com/denverdino/aliyungo/ram/policy.go b/vendor/github.com/denverdino/aliyungo/ram/policy.go index b0a84b86d..0acfd71a7 100644 --- a/vendor/github.com/denverdino/aliyungo/ram/policy.go +++ b/vendor/github.com/denverdino/aliyungo/ram/policy.go @@ -1,8 +1,15 @@ package ram +type Type string + +const ( + Custom Type = "Custom" + System Type = "System" +) + type PolicyRequest struct { PolicyName string - PolicyType string + PolicyType Type Description string PolicyDocument string SetAsDefault string @@ -21,15 +28,16 @@ type PolicyResponse struct { } type PolicyQueryRequest struct { - PolicyType string + PolicyType Type Marker string MaxItems int8 } type PolicyQueryResponse struct { + RamCommonResponse IsTruncated bool Marker string - Policies struct { + Policies struct { Policy []Policy } } diff --git a/vendor/github.com/denverdino/aliyungo/util/encoding.go b/vendor/github.com/denverdino/aliyungo/util/encoding.go index 8cb588288..99a508f5b 100644 --- a/vendor/github.com/denverdino/aliyungo/util/encoding.go +++ b/vendor/github.com/denverdino/aliyungo/util/encoding.go @@ -66,24 +66,26 @@ func setQueryValues(i interface{}, values *url.Values, prefix string) { // TODO Use Tag for validation // tag := typ.Field(i).Tag.Get("tagname") kind := field.Kind() + isPtr := false if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() { continue } if kind == reflect.Ptr { field = field.Elem() kind = field.Kind() + isPtr = true } var value string //switch field.Interface().(type) { switch kind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: i := field.Int() - if i != 0 { + if i != 0 || isPtr { value = strconv.FormatInt(i, 10) } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: i := field.Uint() - if i != 0 { + if i != 0 || isPtr { value = strconv.FormatUint(i, 10) } case reflect.Float32: @@ -197,12 +199,14 @@ func setQueryValuesByFlattenMethod(i interface{}, values *url.Values, prefix str // tag := typ.Field(i).Tag.Get("tagname") kind := field.Kind() + isPtr := false if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() { continue } if kind == reflect.Ptr { field = field.Elem() kind = field.Kind() + isPtr = true } var value string @@ -210,12 +214,12 @@ func setQueryValuesByFlattenMethod(i interface{}, values *url.Values, prefix str switch kind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: i := field.Int() - if i != 0 { + if i != 0 || isPtr { value = strconv.FormatInt(i, 10) } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: i := field.Uint() - if i != 0 { + if i != 0 || isPtr { value = strconv.FormatUint(i, 10) } case reflect.Float32: diff --git a/vendor/vendor.json b/vendor/vendor.json index 3a5b35714..ddc99ef45 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -396,34 +396,34 @@ "revision": "6d212800a42e8ab5c146b8ace3490ee17e5225f9" }, { - "checksumSHA1": "b2m7aICkBOz9JqmnX2kdDN4wgjI=", + "checksumSHA1": "2+1TPdvFj4W1QS5drkFr+ibM3G0=", "path": "github.com/denverdino/aliyungo/common", - "revision": "b8a81c0f54003ea306ef566807919955d639cd48", - "revisionTime": "2017-08-02T08:24:47Z" + "revision": "ec0e57291175fc9b06c62977f384756642285aab", + "revisionTime": "2017-11-27T16:20:29Z" }, { - "checksumSHA1": "5UYxIc/DZ5g0SM7qwXskoyNOc78=", + "checksumSHA1": "y4Ay4E5HqT25sweC/Bl9/odNWaI=", "path": "github.com/denverdino/aliyungo/ecs", - "revision": "b8a81c0f54003ea306ef566807919955d639cd48", - "revisionTime": "2017-08-02T08:24:47Z" + "revision": "ec0e57291175fc9b06c62977f384756642285aab", + "revisionTime": "2017-11-27T16:20:29Z" }, { - "checksumSHA1": "VfIjW9Tf2eLmHrgrvk1wRnBaxTE=", + "checksumSHA1": "sievsBvgtVF2iZ2FjmDZppH3+Ro=", "path": "github.com/denverdino/aliyungo/ram", - "revision": "b8a81c0f54003ea306ef566807919955d639cd48", - "revisionTime": "2017-08-02T08:24:47Z" + "revision": "ec0e57291175fc9b06c62977f384756642285aab", + "revisionTime": "2017-11-27T16:20:29Z" }, { "checksumSHA1": "pQHH9wpyS0e4wpW0erxe3D7OILM=", "path": "github.com/denverdino/aliyungo/slb", - "revision": "b8a81c0f54003ea306ef566807919955d639cd48", - "revisionTime": "2017-08-02T08:24:47Z" + "revision": "ec0e57291175fc9b06c62977f384756642285aab", + "revisionTime": "2017-11-27T16:20:29Z" }, { - "checksumSHA1": "piZlmhWPLGxYkXLysTrjcXllO4c=", + "checksumSHA1": "cKVBRn7GKT+0IqfGUc/NnKDWzCw=", "path": "github.com/denverdino/aliyungo/util", - "revision": "b8a81c0f54003ea306ef566807919955d639cd48", - "revisionTime": "2017-08-02T08:24:47Z" + "revision": "ec0e57291175fc9b06c62977f384756642285aab", + "revisionTime": "2017-11-27T16:20:29Z" }, { "checksumSHA1": "D37uI+U+FYvTJIdG2TTozXe7i7U=", diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index e634e8840..500d4debb 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -182,6 +182,12 @@ builder. generate. By default, Packer generates a name that looks like `packer_<UUID>`, where `<UUID>` is a 36 character unique identifier. +- `security_token` (string) - STS access token, can be set through template or by exporting + as environment vairalbe such "export SecurityToken=value". + +- `TLSHandshakeTimeout` (int) - When happen "net/http: TLS handshake timeout" problem, set this environment variable + to a bigger such as "export TLSHandshakeTimeout=30", it will set the TLS handshake timeout value to 30s. + ## Basic Example Here is a basic example for Alicloud. From 2f7b9640d9badc085cdaf73502360ea109a6b645 Mon Sep 17 00:00:00 2001 From: zhuzhih2017 <dongxiao.zzh@alibaba-inc.com> Date: Tue, 28 Nov 2017 11:16:14 +0800 Subject: [PATCH 0244/1007] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 889ed4d44..8cb17b49e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## (UNRELEASED) ### IMPROVEMENTS: +* builder/alicloud-ecs: Add security token support and set tls handshake timeout + through environment variable. [GH-5641] ### BUG FIXES: From 8f02150178236e7a1215a3b3e9d52312436cea56 Mon Sep 17 00:00:00 2001 From: Casey Robertson <casey.robertson@caseymbp.slo.mbo.ad> Date: Tue, 28 Nov 2017 14:23:12 -0800 Subject: [PATCH 0245/1007] Changes Linux install URL to omnitruck. Changes powershell install to use omnitruck rather than hard-coded 32-bit url --- provisioner/chef-client/provisioner.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 3853613fc..c7bd865dd 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -30,13 +30,13 @@ type guestOSTypeConfig struct { var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { executeCommand: "{{if .Sudo}}sudo {{end}}chef-client --no-color -c {{.ConfigPath}} -j {{.JsonPath}}", - installCommand: "curl -L https://www.chef.io/chef/install.sh | {{if .Sudo}}sudo {{end}}bash", + installCommand: "curl -L https://omnitruck.chef.io/install.sh | {{if .Sudo}}sudo {{end}}bash", knifeCommand: "{{if .Sudo}}sudo {{end}}knife {{.Args}} {{.Flags}}", stagingDir: "/tmp/packer-chef-client", }, provisioner.WindowsOSType: { executeCommand: "c:/opscode/chef/bin/chef-client.bat --no-color -c {{.ConfigPath}} -j {{.JsonPath}}", - installCommand: "powershell.exe -Command \"(New-Object System.Net.WebClient).DownloadFile('http://chef.io/chef/install.msi', 'C:\\Windows\\Temp\\chef.msi');Start-Process 'msiexec' -ArgumentList '/qb /i C:\\Windows\\Temp\\chef.msi' -NoNewWindow -Wait\"", + installCommand: "powershell.exe -Command \". { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; install\"", knifeCommand: "c:/opscode/chef/bin/knife.bat {{.Args}} {{.Flags}}", stagingDir: "C:/Windows/Temp/packer-chef-client", }, From b66426e668cda04beffe4464c6782cd71e6deb94 Mon Sep 17 00:00:00 2001 From: Hariharan Jayaraman <harijayms@microsoft.com> Date: Tue, 28 Nov 2017 16:23:49 -0800 Subject: [PATCH 0246/1007] Updates to Docs to ensure permission issues are clearer --- website/source/docs/builders/azure.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index f673d34fd..779a374b8 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -29,7 +29,7 @@ builder. - `client_secret` (string) The password or secret for your service principal. -- `subscription_id` (string) Subscription under which the build will be performed. **The service principal specified in `client_id` must have full access to this subscription.** +- `subscription_id` (string) Subscription under which the build will be performed. **The service principal specified in `client_id` must have full access to this subscription, unless build_resource_group_name option is specified in which case it needs to have owner access to the existing resource group specified in build_resource_group_name parameter.** - `capture_container_name` (string) Destination container name. Essentially the "directory" where your VHD will be organized in Azure. The captured VHD's URL will be `https://<storage_account>.blob.core.windows.net/system/Microsoft.Compute/Images/<capture_container_name>/<capture_name_prefix>.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.vhd`. - `image_publisher` (string) PublisherName for your base image. See [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/) for details. From da0c13f622234be9c70183d32fcbcf4fa9ec0e4a Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Thu, 30 Nov 2017 00:11:17 -0800 Subject: [PATCH 0247/1007] azure: delete keyvault deployment --- builder/azure/arm/azure_client.go | 15 +++ builder/azure/arm/builder.go | 12 +- .../azure/arm/step_delete_resource_group.go | 110 +++++++++++------- builder/azure/arm/step_deploy_template.go | 15 ++- .../azure/arm/step_deploy_template_test.go | 4 +- builder/azure/common/constants/stateBag.go | 1 + builder/azure/common/vault.go | 78 ++++++++++++- 7 files changed, 178 insertions(+), 57 deletions(-) diff --git a/builder/azure/arm/azure_client.go b/builder/azure/arm/azure_client.go index 08dd95eae..c4d8b544d 100644 --- a/builder/azure/arm/azure_client.go +++ b/builder/azure/arm/azure_client.go @@ -48,6 +48,7 @@ type AzureClient struct { InspectorMaxLength int Template *CaptureTemplate LastError azureErrorResponse + VaultClientDelete common.VaultClient } func getCaptureResponse(body string) *CaptureTemplate { @@ -209,6 +210,20 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) azureClient.VaultClient.UserAgent += packerUserAgent + // TODO(boumenot) - SDK still does not have a full KeyVault client. + // There are two ways that KeyVault has to be accessed, and each one has their own SPN. An authenticated SPN + // is tied to the URL, and the URL associated with getting the secret is different than the URL + // associated with deleting the KeyVault. As a result, I need to have *two* different clients to + // access KeyVault. I did not want to split it into two separate files, so I am starting with this. + // + // I do not like this implementation. It is getting long in the tooth, and should be re-examined now + // that we have a "working" solution. + azureClient.VaultClientDelete = common.NewVaultClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) + azureClient.VaultClientDelete.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) + azureClient.VaultClientDelete.RequestInspector = withInspection(maxlen) + azureClient.VaultClientDelete.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) + azureClient.VaultClientDelete.UserAgent += packerUserAgent + // If this is a managed disk build, this should be ignored. if resourceGroupName != "" && storageAccountName != "" { accountKeys, err := azureClient.AccountsClient.ListKeys(resourceGroupName, storageAccountName) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index 3874cdb05..c6b8bcbe1 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -127,11 +127,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe b.setImageParameters(b.stateBag) var steps []multistep.Step + deploymentName := b.stateBag.Get(constants.ArmDeploymentName).(string) + if b.config.OSType == constants.Target_Linux { steps = []multistep.Step{ NewStepCreateResourceGroup(azureClient, ui), NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), - NewStepDeployTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), + NewStepDeployTemplate(azureClient, ui, b.config, deploymentName, GetVirtualMachineDeployment), NewStepGetIPAddress(azureClient, ui, endpointConnectType), &communicator.StepConnectSSH{ Config: &b.config.Comm, @@ -146,14 +148,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepDeleteOSDisk(azureClient, ui), } } else if b.config.OSType == constants.Target_Windows { + keyVaultDeploymentName := b.stateBag.Get(constants.ArmKeyVaultDeploymentName).(string) steps = []multistep.Step{ NewStepCreateResourceGroup(azureClient, ui), NewStepValidateTemplate(azureClient, ui, b.config, GetKeyVaultDeployment), - NewStepDeployTemplate(azureClient, ui, b.config, GetKeyVaultDeployment), + NewStepDeployTemplate(azureClient, ui, b.config, keyVaultDeploymentName, GetKeyVaultDeployment), NewStepGetCertificate(azureClient, ui), NewStepSetCertificate(b.config, ui), NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), - NewStepDeployTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), + NewStepDeployTemplate(azureClient, ui, b.config, deploymentName, GetVirtualMachineDeployment), NewStepGetIPAddress(azureClient, ui, endpointConnectType), &communicator.StepConnectWinRM{ Config: &b.config.Comm, @@ -283,6 +286,9 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) { stateBag.Put(constants.ArmTags, &b.config.AzureTags) stateBag.Put(constants.ArmComputeName, b.config.tmpComputeName) stateBag.Put(constants.ArmDeploymentName, b.config.tmpDeploymentName) + if b.config.OSType == constants.Target_Windows { + stateBag.Put(constants.ArmKeyVaultDeploymentName, fmt.Sprintf("kv%s", b.config.tmpDeploymentName)) + } stateBag.Put(constants.ArmKeyVaultName, b.config.tmpKeyVaultName) stateBag.Put(constants.ArmLocation, b.config.Location) stateBag.Put(constants.ArmNicName, DefaultNicName) diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index 147a33349..c3db6de0a 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -37,54 +37,19 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, if state.Get(constants.ArmIsExistingResourceGroup).(bool) { s.say("\nThe resource group was not created by Packer, only deleting individual resources ...") var deploymentName = state.Get(constants.ArmDeploymentName).(string) - if deploymentName != "" { - maxResources := int32(maxResourcesToDelete) - deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) + err = s.deleteDeploymentResources(deploymentName, resourceGroupName) + if err != nil { + return err + } + + if keyVaultDeploymentName, ok := state.GetOk(constants.ArmKeyVaultDeploymentName); ok { + err = s.deleteDeploymentResources(keyVaultDeploymentName.(string), resourceGroupName) if err != nil { - s.say(fmt.Sprintf("Error deleting resources. Please delete them manually.\n\n"+ - "Name: %s\n"+ - "Error: %s", resourceGroupName, err)) - s.error(err) - } - for _, deploymentOperation := range *deploymentOperations.Value { - // Sometimes an empty operation is added to the list by Azure - if deploymentOperation.Properties.TargetResource == nil { - continue - } - s.say(fmt.Sprintf(" -> %s : '%s'", - *deploymentOperation.Properties.TargetResource.ResourceType, - *deploymentOperation.Properties.TargetResource.ResourceName)) - var networkDeleteFunction func(string, string, <-chan struct{}) (<-chan autorest.Response, <-chan error) - switch *deploymentOperation.Properties.TargetResource.ResourceType { - case "Microsoft.Compute/virtualMachines": - _, errChan := s.client.VirtualMachinesClient.Delete(resourceGroupName, *deploymentOperation.Properties.TargetResource.ResourceName, nil) - err := <-errChan - if err != nil { - s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ - "Name: %s\n"+ - "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err.Error())) - s.error(err) - } - case "Microsoft.Network/networkInterfaces": - networkDeleteFunction = s.client.InterfacesClient.Delete - case "Microsoft.Network/virtualNetworks": - networkDeleteFunction = s.client.VirtualNetworksClient.Delete - case "Microsoft.Network/publicIPAddresses": - networkDeleteFunction = s.client.PublicIPAddressesClient.Delete - } - if networkDeleteFunction != nil { - _, errChan := networkDeleteFunction(resourceGroupName, *deploymentOperation.Properties.TargetResource.ResourceName, nil) - err := <-errChan - if err != nil { - s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ - "Name: %s\n"+ - "Error: %s", *deploymentOperation.Properties.TargetResource.ResourceName, err.Error())) - s.error(err) - } - } + return err } } - return err + + return nil } else { s.say("\nThe resource group was created by Packer, deleting ...") _, errChan := s.client.GroupsClient.Delete(resourceGroupName, cancelCh) @@ -97,6 +62,61 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(state multistep.StateBag, } } +func (s *StepDeleteResourceGroup) deleteDeploymentResources(deploymentName, resourceGroupName string) error { + maxResources := int32(maxResourcesToDelete) + + deploymentOperations, err := s.client.DeploymentOperationsClient.List(resourceGroupName, deploymentName, &maxResources) + if err != nil { + s.reportIfError(err, resourceGroupName) + return err + } + + for _, deploymentOperation := range *deploymentOperations.Value { + // Sometimes an empty operation is added to the list by Azure + if deploymentOperation.Properties.TargetResource == nil { + continue + } + s.say(fmt.Sprintf(" -> %s : '%s'", + *deploymentOperation.Properties.TargetResource.ResourceType, + *deploymentOperation.Properties.TargetResource.ResourceName)) + + var networkDeleteFunction func(string, string, <-chan struct{}) (<-chan autorest.Response, <-chan error) + resourceName := *deploymentOperation.Properties.TargetResource.ResourceName + + switch *deploymentOperation.Properties.TargetResource.ResourceType { + case "Microsoft.Compute/virtualMachines": + _, errChan := s.client.VirtualMachinesClient.Delete(resourceGroupName, resourceName, nil) + err := <-errChan + s.reportIfError(err, resourceName) + case "Microsoft.KeyVault/vaults": + _, err := s.client.VaultClientDelete.Delete(resourceGroupName, resourceName) + s.reportIfError(err, resourceName) + case "Microsoft.Network/networkInterfaces": + networkDeleteFunction = s.client.InterfacesClient.Delete + case "Microsoft.Network/virtualNetworks": + networkDeleteFunction = s.client.VirtualNetworksClient.Delete + case "Microsoft.Network/publicIPAddresses": + networkDeleteFunction = s.client.PublicIPAddressesClient.Delete + } + if networkDeleteFunction != nil { + _, errChan := networkDeleteFunction(resourceGroupName, resourceName, nil) + err := <-errChan + s.reportIfError(err, resourceName) + } + } + + return nil +} + +func (s *StepDeleteResourceGroup) reportIfError(err error, resourceName string) { + if err != nil { + s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+ + "Name: %s\n"+ + "Error: %s", resourceName, err.Error())) + s.error(err) + } +} + func (s *StepDeleteResourceGroup) Run(state multistep.StateBag) multistep.StepAction { s.say("Deleting resource group ...") diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index 53b639d51..b67dd5c1d 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -22,15 +22,17 @@ type StepDeployTemplate struct { error func(e error) config *Config factory templateFactoryFunc + name string } -func NewStepDeployTemplate(client *AzureClient, ui packer.Ui, config *Config, factory templateFactoryFunc) *StepDeployTemplate { +func NewStepDeployTemplate(client *AzureClient, ui packer.Ui, config *Config, deploymentName string, factory templateFactoryFunc) *StepDeployTemplate { var step = &StepDeployTemplate{ client: client, say: func(message string) { ui.Say(message) }, error: func(e error) { ui.Error(e.Error()) }, config: config, factory: factory, + name: deploymentName, } step.deploy = step.deployTemplate @@ -59,15 +61,14 @@ func (s *StepDeployTemplate) Run(state multistep.StateBag) multistep.StepAction s.say("Deploying deployment template ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) - var deploymentName = state.Get(constants.ArmDeploymentName).(string) s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName)) - s.say(fmt.Sprintf(" -> DeploymentName : '%s'", deploymentName)) + s.say(fmt.Sprintf(" -> DeploymentName : '%s'", s.name)) result := common.StartInterruptibleTask( func() bool { return common.IsStateCancelled(state) }, func(cancelCh <-chan struct{}) error { - return s.deploy(resourceGroupName, deploymentName, cancelCh) + return s.deploy(resourceGroupName, s.name, cancelCh) }, ) @@ -104,6 +105,9 @@ func (s *StepDeployTemplate) deleteOperationResource(resourceType string, resour return err } + case "Microsoft.KeyVault/vaults": + _, err := s.client.VaultClientDelete.Delete(resourceGroupName, resourceName) + return err case "Microsoft.Network/networkInterfaces": networkDeleteFunction = s.client.InterfacesClient.Delete case "Microsoft.Network/virtualNetworks": @@ -142,7 +146,6 @@ func (s *StepDeployTemplate) deleteImage(imageType string, imageName string, res blob := s.client.BlobStorageClient.GetContainerReference(storageAccountName).GetBlobReference(blobName) err = blob.Delete(nil) return err - } func (s *StepDeployTemplate) Cleanup(state multistep.StateBag) { @@ -158,7 +161,7 @@ func (s *StepDeployTemplate) Cleanup(state multistep.StateBag) { var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) var computeName = state.Get(constants.ArmComputeName).(string) - var deploymentName = state.Get(constants.ArmDeploymentName).(string) + var deploymentName = s.name imageType, imageName, err := s.disk(resourceGroupName, computeName) if err != nil { ui.Error("Could not retrieve OS Image details") diff --git a/builder/azure/arm/step_deploy_template_test.go b/builder/azure/arm/step_deploy_template_test.go index 3a1d0c0bc..d812e0ffa 100644 --- a/builder/azure/arm/step_deploy_template_test.go +++ b/builder/azure/arm/step_deploy_template_test.go @@ -61,6 +61,7 @@ func TestStepDeployTemplateShouldTakeStepArgumentsFromStateBag(t *testing.T) { }, say: func(message string) {}, error: func(e error) {}, + name: "--deployment-name--", } stateBag := createTestStateBagStepValidateTemplate() @@ -70,10 +71,9 @@ func TestStepDeployTemplateShouldTakeStepArgumentsFromStateBag(t *testing.T) { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } - var expectedDeploymentName = stateBag.Get(constants.ArmDeploymentName).(string) var expectedResourceGroupName = stateBag.Get(constants.ArmResourceGroupName).(string) - if actualDeploymentName != expectedDeploymentName { + if actualDeploymentName != "--deployment-name--" { t.Fatal("Expected StepValidateTemplate to source 'constants.ArmDeploymentName' from the state bag, but it did not.") } diff --git a/builder/azure/common/constants/stateBag.go b/builder/azure/common/constants/stateBag.go index 6d5a93068..720979b9c 100644 --- a/builder/azure/common/constants/stateBag.go +++ b/builder/azure/common/constants/stateBag.go @@ -15,6 +15,7 @@ const ( ArmComputeName string = "arm.ComputeName" ArmImageParameters string = "arm.ImageParameters" ArmCertificateUrl string = "arm.CertificateUrl" + ArmKeyVaultDeploymentName string = "arm.KeyVaultDeploymentName" ArmDeploymentName string = "arm.DeploymentName" ArmNicName string = "arm.NicName" ArmKeyVaultName string = "arm.KeyVaultName" diff --git a/builder/azure/common/vault.go b/builder/azure/common/vault.go index db5c6db0c..ab54ee493 100644 --- a/builder/azure/common/vault.go +++ b/builder/azure/common/vault.go @@ -9,15 +9,18 @@ import ( "net/url" "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" ) const ( - AzureVaultApiVersion = "2015-06-01" + AzureVaultApiVersion = "2016-10-01" ) type VaultClient struct { autorest.Client keyVaultEndpoint url.URL + SubscriptionID string + baseURI string } func NewVaultClient(keyVaultEndpoint url.URL) VaultClient { @@ -26,6 +29,13 @@ func NewVaultClient(keyVaultEndpoint url.URL) VaultClient { } } +func NewVaultClientWithBaseURI(baseURI, subscriptionID string) VaultClient { + return VaultClient{ + baseURI: baseURI, + SubscriptionID: subscriptionID, + } +} + type Secret struct { ID *string `json:"id,omitempty"` Value string `json:"value"` @@ -76,6 +86,72 @@ func (client *VaultClient) GetSecret(vaultName, secretName string) (*Secret, err return &secret, nil } +// Delete deletes the specified Azure key vault. +// +// resourceGroupName is the name of the Resource Group to which the vault belongs. vaultName is the name of the vault +// to delete +func (client *VaultClient) Delete(resourceGroupName string, vaultName string) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, vaultName) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client *VaultClient) DeletePreparer(resourceGroupName string, vaultName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "SubscriptionID": autorest.Encode("path", client.SubscriptionID), + "vaultName": autorest.Encode("path", vaultName), + } + + queryParameters := map[string]interface{}{ + "api-version": AzureVaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.baseURI), + autorest.WithPathParameters("/subscriptions/{SubscriptionID}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client *VaultClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, + req, + azure.DoPollForAsynchronous(client.PollingDelay)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client *VaultClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + func (client *VaultClient) getVaultUrl(vaultName string) string { return fmt.Sprintf("%s://%s.%s/", client.keyVaultEndpoint.Scheme, vaultName, client.keyVaultEndpoint.Host) } From 556da47d35139b653dddac1bded87cc8228f5a2d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 30 Nov 2017 13:51:33 -0800 Subject: [PATCH 0248/1007] modify validation to allow user to have the original region in the ami_regions list --- builder/amazon/common/ami_config.go | 38 ++++++++++++----------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index aa0792e3a..50c01975a 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -41,22 +41,20 @@ func stringInSlice(s []string, searchstr string) bool { func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context) []error { var errs []error - if accessConfig != nil { - session, err := accessConfig.Session() - if err != nil { - errs = append(errs, err) - } else { - region := *session.Config.Region - if stringInSlice(c.AMIRegions, region) { - errs = append(errs, fmt.Errorf("Cannot copy AMI to AWS session region '%s', please remove it from `ami_regions`.", region)) - } - } - } - if c.AMIName == "" { errs = append(errs, fmt.Errorf("ami_name must be specified")) } + // Make sure that if we have region_kms_key_ids defined, + // the regions in region_kms_key_ids are also in ami_regions + if len(c.AMIRegionKMSKeyIDs) > 0 { + for kmsKeyRegion := range c.AMIRegionKMSKeyIDs { + if !stringInSlice(c.AMIRegions, kmsKeyRegion) { + errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in ami_regions", kmsKeyRegion)) + } + } + } + if len(c.AMIRegions) > 0 { regionSet := make(map[string]struct{}) regions := make([]string, 0, len(c.AMIRegions)) @@ -84,21 +82,17 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context errs = append(errs, fmt.Errorf("Region %s is in ami_regions but not in region_kms_key_ids", region)) } } - + if (accessConfig != nil) && (region == accessConfig.RawRegion) { + // make sure we don't try to copy to the region we originally + // create the AMI in. + fmt.Printf("Cannot copy AMI to AWS session region '%s', deleting it from `ami_regions`.", region) + continue + } regions = append(regions, region) } c.AMIRegions = regions } - // Make sure that if we have region_kms_key_ids defined, - // the regions in region_kms_key_ids are also in ami_regions - if len(c.AMIRegionKMSKeyIDs) > 0 { - for kmsKeyRegion := range c.AMIRegionKMSKeyIDs { - if !stringInSlice(c.AMIRegions, kmsKeyRegion) { - errs = append(errs, fmt.Errorf("Region %s is in region_kms_key_ids but not in ami_regions", kmsKeyRegion)) - } - } - } if len(c.AMIUsers) > 0 && c.AMIEncryptBootVolume { errs = append(errs, fmt.Errorf("Cannot share AMI with encrypted boot volume")) From 1c681fc0961230775bc7e2fb409ac868ab405424 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 30 Nov 2017 14:08:48 -0800 Subject: [PATCH 0249/1007] tests --- builder/amazon/common/ami_config.go | 3 ++- builder/amazon/common/ami_config_test.go | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index 50c01975a..9af2244ee 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "log" "github.com/hashicorp/packer/template/interpolate" ) @@ -85,7 +86,7 @@ func (c *AMIConfig) Prepare(accessConfig *AccessConfig, ctx *interpolate.Context if (accessConfig != nil) && (region == accessConfig.RawRegion) { // make sure we don't try to copy to the region we originally // create the AMI in. - fmt.Printf("Cannot copy AMI to AWS session region '%s', deleting it from `ami_regions`.", region) + log.Printf("Cannot copy AMI to AWS session region '%s', deleting it from `ami_regions`.", region) continue } regions = append(regions, region) diff --git a/builder/amazon/common/ami_config_test.go b/builder/amazon/common/ami_config_test.go index 5f130130c..120c88bfc 100644 --- a/builder/amazon/common/ami_config_test.go +++ b/builder/amazon/common/ami_config_test.go @@ -11,6 +11,12 @@ func testAMIConfig() *AMIConfig { } } +func getFakeAccessConfig(region string) *AccessConfig { + return &AccessConfig{ + RawRegion: region, + } +} + func TestAMIConfigPrepare_name(t *testing.T) { c := testAMIConfig() if err := c.Prepare(nil, nil); err != nil { @@ -118,6 +124,15 @@ func TestAMIConfigPrepare_regions(t *testing.T) { if err := c.Prepare(nil, nil); err == nil { t.Fatal("should have error b/c theres a region in in ami_regions that isn't in the key map") } + + // allow rawregion to exist in ami_regions list. + accessConf := getFakeAccessConfig("us-east-1") + c.AMIRegions = []string{"us-east-1", "us-west-1", "us-east-2"} + c.AMIRegionKMSKeyIDs = nil + if err := c.Prepare(accessConf, nil); err != nil { + t.Fatal("should allow user to have the raw region in ami_regions") + } + } func TestAMIConfigPrepare_Share_EncryptedBoot(t *testing.T) { From c28a50af168ef289ae8fa956f6cea9a538a42608 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 30 Nov 2017 16:30:28 -0800 Subject: [PATCH 0250/1007] try to fix transient test failure --- packer/provisioner_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/provisioner_test.go b/packer/provisioner_test.go index 97304d2a5..22d34806f 100644 --- a/packer/provisioner_test.go +++ b/packer/provisioner_test.go @@ -67,7 +67,7 @@ func TestProvisionHook_cancel(t *testing.T) { p := &MockProvisioner{ ProvFunc: func() error { - time.Sleep(50 * time.Millisecond) + time.Sleep(100 * time.Millisecond) lock.Lock() defer lock.Unlock() From 0e08640fff9dd62aab47bb4dceb3f8b6c696a968 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski <kw@linux.com> Date: Sun, 3 Dec 2017 23:04:25 +0100 Subject: [PATCH 0251/1007] Re-factor version command to use version.FormattedVersion() function. This commit removes surplus code which is almost a duplicate of the code available in the version package by favouring the package implementation instead. Signed-off-by: Krzysztof Wilczynski <kw@linux.com> --- command/version.go | 28 ++++++++-------------------- commands.go | 8 ++------ 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/command/version.go b/command/version.go index 1142e1747..3d45205bd 100644 --- a/command/version.go +++ b/command/version.go @@ -1,18 +1,16 @@ package command import ( - "bytes" "fmt" + + "github.com/hashicorp/packer/version" ) // VersionCommand is a Command implementation prints the version. type VersionCommand struct { Meta - Revision string - Version string - VersionPrerelease string - CheckFunc VersionCheckFunc + CheckFunc VersionCheckFunc } // VersionCheckFunc is the callback called by the Version command to @@ -29,25 +27,15 @@ type VersionCheckInfo struct { } func (c *VersionCommand) Help() string { - return "" + return "Prints the Packer version, and checks for new release." } func (c *VersionCommand) Run(args []string) int { - c.Ui.Machine("version", c.Version) - c.Ui.Machine("version-prelease", c.VersionPrerelease) - c.Ui.Machine("version-commit", c.Revision) + c.Ui.Machine("version", version.Version) + c.Ui.Machine("version-prelease", version.VersionPrerelease) + c.Ui.Machine("version-commit", version.GitCommit) - var versionString bytes.Buffer - fmt.Fprintf(&versionString, "Packer v%s", c.Version) - if c.VersionPrerelease != "" { - fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease) - - if c.Revision != "" { - fmt.Fprintf(&versionString, " (%s)", c.Revision) - } - } - - c.Ui.Say(versionString.String()) + c.Ui.Say(fmt.Sprintf("Packer v%s", version.FormattedVersion())) // If we have a version check function, then let's check for // the latest version as well. diff --git a/commands.go b/commands.go index 17b6a7f36..47ee467a5 100644 --- a/commands.go +++ b/commands.go @@ -2,7 +2,6 @@ package main import ( "github.com/hashicorp/packer/command" - "github.com/hashicorp/packer/version" "github.com/mitchellh/cli" ) @@ -50,11 +49,8 @@ func init() { "version": func() (cli.Command, error) { return &command.VersionCommand{ - Meta: *CommandMeta, - Revision: version.GitCommit, - Version: version.Version, - VersionPrerelease: version.VersionPrerelease, - CheckFunc: commandVersionCheck, + Meta: *CommandMeta, + CheckFunc: commandVersionCheck, }, nil }, From d043c37ad41dd1df465e434a94d4c23c617d811d Mon Sep 17 00:00:00 2001 From: Jamie Lennox <jamie@vibrato.com.au> Date: Fri, 1 Dec 2017 11:43:35 +1100 Subject: [PATCH 0252/1007] Azure: Don't provide location for build_resource_group_name Location is required by default because you must specify where to create the resource group containing the packer resources. When using build_resource_group_name you are specifying that packer should use an existing resource group and so the location that resources are in can be determined by fetching the information from the existing group. It is forbidden to pass both variables as it is easier and more intuitive that the location comes from the group rather than ignore a parameter. Closes: #5655 --- builder/azure/arm/builder.go | 11 +++++- builder/azure/arm/builder_test.go | 1 - builder/azure/arm/config.go | 8 ++--- builder/azure/arm/config_test.go | 1 + website/source/docs/builders/azure.html.md | 40 ++++++++++++++++------ 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index c6b8bcbe1..d1f98bbd2 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -103,6 +103,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } } + if b.config.BuildResourceGroupName != "" { + group, err := azureClient.GroupsClient.Get(b.config.BuildResourceGroupName) + if err != nil { + return nil, fmt.Errorf("Cannot locate the existing build resource resource group %s.", b.config.BuildResourceGroupName) + } + + b.config.Location = *group.Location + } + if b.config.StorageAccount != "" { account, err := b.getBlobAccount(azureClient, b.config.ResourceGroupName, b.config.StorageAccount) if err != nil { @@ -290,7 +299,6 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) { stateBag.Put(constants.ArmKeyVaultDeploymentName, fmt.Sprintf("kv%s", b.config.tmpDeploymentName)) } stateBag.Put(constants.ArmKeyVaultName, b.config.tmpKeyVaultName) - stateBag.Put(constants.ArmLocation, b.config.Location) stateBag.Put(constants.ArmNicName, DefaultNicName) stateBag.Put(constants.ArmPublicIPAddressName, DefaultPublicIPAddressName) if b.config.TempResourceGroupName != "" && b.config.BuildResourceGroupName != "" { @@ -312,6 +320,7 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) { // Parameters that are only known at runtime after querying Azure. func (b *Builder) setRuntimeParameters(stateBag multistep.StateBag) { + stateBag.Put(constants.ArmLocation, b.config.Location) stateBag.Put(constants.ArmManagedImageLocation, b.config.manageImageLocation) } diff --git a/builder/azure/arm/builder_test.go b/builder/azure/arm/builder_test.go index a44d363d0..2db475a02 100644 --- a/builder/azure/arm/builder_test.go +++ b/builder/azure/arm/builder_test.go @@ -20,7 +20,6 @@ func TestStateBagShouldBePopulatedExpectedValues(t *testing.T) { constants.ArmTags, constants.ArmComputeName, constants.ArmDeploymentName, - constants.ArmLocation, constants.ArmNicName, constants.ArmResourceGroupName, constants.ArmStorageAccountName, diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index b2301db6c..f384c88bc 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -590,10 +590,6 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { } } - if c.Location == "" { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("A location must be specified")) - } - ///////////////////////////////////////////// // Deployment xor := func(a, b bool) bool { @@ -604,6 +600,10 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("Specify either a VHD (storage_account and resource_group_name) or Managed Image (managed_image_resource_group_name and managed_image_name) output")) } + if !xor(c.Location != "", c.BuildResourceGroupName != "") { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Must specify either a location to create the resource group in or an existing build_resource_group_name.")) + } + if c.ManagedImageName == "" && c.ManagedImageResourceGroupName == "" { if c.StorageAccount == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("A storage_account must be specified")) diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index 75d397831..4cefd6730 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -972,6 +972,7 @@ func TestConfigShouldRejectInvalidResourceGroupNames(t *testing.T) { } } + delete(config, "location") // not valid for build_resource_group_name delete(config, x) } } diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 779a374b8..8fa59f4e8 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -44,10 +44,6 @@ builder. CLI example `azure vm image list-skus -l westus -p Canonical -o UbuntuServer` -- `location` (string) Azure datacenter in which your VM will build. - - CLI example `azure location list` - #### VHD or Managed Image The Azure builder can create either a VHD, or a managed image. If you @@ -77,14 +73,42 @@ When creating a managed image the following two options are required. set. See [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images) to learn more about managed images. +#### Resource Group Usage + +The Azure builder can either provision resources into a new resource group that +it controls (default) or an existing one. The advantage of using a packer +defined resource group is that failed resource cleanup is easier because you +can simply remove the entire resource group, however this means that the +provided credentials must have permission to create and remove resource groups. +By using an existing resource group you can scope the provided credentials to +just this group, however failed builds are more likely to leave unused +artifacts. + +To have packer create a resource group you **must** provide: + +- `location` (string) Azure datacenter in which your VM will build. + + CLI example `azure location list` + +and optionally: + +- `temp_resource_group_name` (string) name assigned to the temporary resource + group created during the build. If this value is not set, a random value will + be assigned. This resource group is deleted at the end of the build. + +To use an existing resource group you **must** provide: + +- `build_resource_group_name` (string) - Specify an existing resource group + to run the build in. + +Providing `temp_resource_group_name` or `location` in combination with `build_resource_group_name` is not allowed. + ### Optional: - `azure_tags` (object of name/value strings) - the user can define up to 15 tags. Tag names cannot exceed 512 characters, and tag values cannot exceed 256 characters. Tags are applied to every resource deployed by a Packer build, i.e. Resource Group, VM, NIC, VNET, Public IP, KeyVault, etc. -- `build_resource_group_name` (string) - Specify an existing resource group to run the build in. Cannot be used together with `temp_resource_group_name` and requires less permissions due to not creating or destroying a resource group. - - `cloud_environment_name` (string) One of `Public`, `China`, `Germany`, or `USGovernment`. Defaults to `Public`. Long forms such as `USGovernmentCloud` and `AzureUSGovernmentCloud` are also supported. @@ -134,10 +158,6 @@ When creating a managed image the following two options are required. assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer build, e.g. attach a resource disk to the VM. -- `temp_resource_group_name` (string) name assigned to the temporary resource group created during the build. If this - value is not set, a random value will be assigned. This resource group is deleted at the end of the build. Cannot be - used together with `build_resource_group_name`. - - `tenant_id` (string) The account identifier with which your `client_id` and `subscription_id` are associated. If not specified, `tenant_id` will be looked up using `subscription_id`. From 89707228453e8d2f20685756e6161f8027131dcf Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 4 Dec 2017 10:43:38 -0800 Subject: [PATCH 0253/1007] use latest go for travis tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5e753eb01..146d5858c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ language: go go: - 1.7.4 - 1.8.3 - - 1.9 + - 1.x install: - make deps From 05327b75248f9510cc0caacaa0f6410781f49d0b Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski <kw@linux.com> Date: Sun, 3 Dec 2017 23:43:30 +0100 Subject: [PATCH 0254/1007] amazon: Remove Session Token (STS) from being shown in the log. This commit adds a change which ensures that the Session Token config struct item is removed from log output. Signed-off-by: Krzysztof Wilczynski <kw@linux.com> --- builder/amazon/chroot/builder.go | 2 +- builder/amazon/ebs/builder.go | 2 +- builder/amazon/ebssurrogate/builder.go | 2 +- builder/amazon/ebsvolume/builder.go | 2 +- builder/amazon/instance/builder.go | 2 +- post-processor/amazon-import/post-processor.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index b6b5088a2..388061bee 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -173,7 +173,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return warns, errs } - log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey)) + log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token)) return warns, nil } diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 1cc346472..d30a0c0be 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -73,7 +73,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, errs } - log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey)) + log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token)) return nil, nil } diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 16e8367da..97e8e4b8d 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -88,7 +88,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, errs } - log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey)) + log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token)) return nil, nil } diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index ea3f74b61..6da6cd938 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -66,7 +66,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, errs } - log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey)) + log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token)) return nil, nil } diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 7cee44c09..066494086 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -159,7 +159,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, errs } - log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey)) + log.Println(common.ScrubConfig(b.config, b.config.AccessKey, b.config.SecretKey, b.config.Token)) return nil, nil } diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index f66c2435e..c9cbd2077 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -91,7 +91,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { return errs } - log.Println(common.ScrubConfig(p.config, p.config.AccessKey, p.config.SecretKey)) + log.Println(common.ScrubConfig(p.config, p.config.AccessKey, p.config.SecretKey, p.config.Token)) return nil } From 92d1bdbdabb62cb4e029fc60c7292a64d404d8cf Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Wed, 6 Dec 2017 16:50:54 +1300 Subject: [PATCH 0255/1007] =?UTF-8?q?docs=20change=20for=20deprecation=20a?= =?UTF-8?q?nd=20proxy=20usage=20=E2=9C=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/source/docs/builders/amazon-ebs.html.md | 7 +++++-- website/source/docs/builders/amazon-ebssurrogate.html.md | 7 +++++-- website/source/docs/builders/amazon-ebsvolume.html.md | 7 +++++-- website/source/docs/builders/amazon-instance.html.md | 7 +++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 4d8c56a1e..54782d9d4 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -328,8 +328,8 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private - IP if available. Also works for WinRM. Overrides `ssh_interface`. +- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, + then SSH will always use the private IP if available. Also works for WinRM. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, @@ -338,6 +338,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. + If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy + `ssh_interface` can be set to `private_dns`. + - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is required if you are using an non-default VPC. diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index acd976538..998733e4a 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -321,8 +321,8 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private - IP if available. Also works for WinRM. Overrides `ssh_interface`. +- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, + then SSH will always use the private IP if available. Also works for WinRM. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, @@ -331,6 +331,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. + If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy + `ssh_interface` can be set to `private_dns`. + - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is required if you are using an non-default VPC. diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index b022c9e81..a28398746 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -225,8 +225,8 @@ builder. [`ssh_private_key_file`](/docs/templates/communicator.html#ssh_private_key_file) must be specified with this. -- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private - IP if available. Also works for WinRM. Overrides `ssh_interface`. +- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, + then SSH will always use the private IP if available. Also works for WinRM. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, @@ -235,6 +235,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. + If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy + `ssh_interface` can be set to `private_dns`. + - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is required if you are using an non-default VPC. diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 8636b6a49..9afd894c2 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -329,8 +329,8 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - If `true`, then SSH will always use the private - IP if available. Also works for WinRM. Overrides `ssh_interface`. +- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, + then SSH will always use the private IP if available. Also works for WinRM. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, @@ -339,6 +339,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. + If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy + `ssh_interface` can be set to `private_dns`. + - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is required if you are using an non-default VPC. From 76ac755ed98ed28154e38de0b13247e91bdef451 Mon Sep 17 00:00:00 2001 From: John Davies-Colley <john.davies-colley@xero.com> Date: Wed, 6 Dec 2017 17:13:02 +1300 Subject: [PATCH 0256/1007] =?UTF-8?q?fixing=20wording=20for=20proxy=20usag?= =?UTF-8?q?e=20=F0=9F=91=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/source/docs/builders/amazon-ebs.html.md | 5 +++-- website/source/docs/builders/amazon-ebssurrogate.html.md | 5 +++-- website/source/docs/builders/amazon-ebsvolume.html.md | 5 +++-- website/source/docs/builders/amazon-instance.html.md | 7 ++++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 54782d9d4..c050cd070 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -338,8 +338,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. - If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy - `ssh_interface` can be set to `private_dns`. + Where Packer is configured for an outbound proxy but WinRM traffic should be direct + `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included + in the `NO_PROXY` environment variable. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 998733e4a..640710230 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -331,8 +331,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. - If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy - `ssh_interface` can be set to `private_dns`. + Where Packer is configured for an outbound proxy but WinRM traffic should be direct + `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included + in the `NO_PROXY` environment variable. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index a28398746..2b92c6b44 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -235,8 +235,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. - If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy - `ssh_interface` can be set to `private_dns`. + Where Packer is configured for an outbound proxy but WinRM traffic should be direct + `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included + in the `NO_PROXY` environment variable. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 9afd894c2..198345ba7 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -329,7 +329,7 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, +- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, then SSH will always use the private IP if available. Also works for WinRM. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, @@ -339,8 +339,9 @@ builder. otherwise the private IP address will be used. If not in a VPC the public DNS name will be used. - If packer is configured for an outbound proxy. To configure WinRM traffic to bypass the proxy - `ssh_interface` can be set to `private_dns`. + Where Packer is configured for an outbound proxy but WinRM traffic should be direct + `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included + in the `NO_PROXY` environment variable. - `subnet_id` (string) - If using VPC, the ID of the subnet, such as `subnet-12345def`, where Packer will launch the EC2 instance. This field is From 19c997cb0e3eb7059c1fd8a68185d54826422e57 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 6 Dec 2017 10:37:11 -0800 Subject: [PATCH 0257/1007] revert to using UI becuase the remote command syntax breaks things on linux with vmware fusion. --- provisioner/windows-restart/provisioner.go | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 3b03cf116..0568516aa 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -3,6 +3,7 @@ package restart import ( "bytes" "fmt" + "io" "log" "strings" @@ -212,20 +213,15 @@ var waitForCommunicator = func(p *Provisioner) error { // provisioning before powershell is actually ready. // In this next check, we parse stdout to make sure that the command is // actually running as expected. - var stdout, stderr bytes.Buffer - cmdModuleLoad := &packer.RemoteCmd{ - Command: DefaultRestartCheckCommand, - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr} + cmdModuleLoad := &packer.RemoteCmd{Command: DefaultRestartCheckCommand} + var buf, buf2 bytes.Buffer + cmdModuleLoad.Stdout = &buf + cmdModuleLoad.Stdout = io.MultiWriter(cmdModuleLoad.Stdout, &buf2) - p.comm.Start(cmdModuleLoad) - cmdModuleLoad.Wait() + cmdModuleLoad.StartWithUi(p.comm, p.ui) + stdoutToRead := buf2.String() - stdoutToRead := stdout.String() - stderrToRead := stderr.String() if !strings.Contains(stdoutToRead, "restarted.") { - log.Printf("Stderr is %s", stderrToRead) log.Printf("echo didn't succeed; retrying...") continue } From 7b5c0900ef53018783d295cfca1177a52432b120 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 7 Dec 2017 11:12:57 -0800 Subject: [PATCH 0258/1007] Correctly set aws region if given in template along with a profile. --- builder/amazon/common/access_config.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 73e50b862..1ecd9dcdb 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -40,7 +40,9 @@ func (c *AccessConfig) Session() (*session.Session, error) { if err := os.Setenv("AWS_PROFILE", c.ProfileName); err != nil { return nil, fmt.Errorf("Set env error: %s", err) } - } else if c.RawRegion != "" { + } + + if c.RawRegion != "" { config = config.WithRegion(c.RawRegion) } else if region := c.metadataRegion(); region != "" { config = config.WithRegion(region) From a90c45d9bb3f2abd56ea77c8a456df19baaa60a7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 7 Dec 2017 12:31:50 -0800 Subject: [PATCH 0259/1007] Wait until source instance OK before continuing --- .../amazon/common/step_run_source_instance.go | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index a3dca8057..43a63493f 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -174,21 +174,27 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi ui.Message(fmt.Sprintf("Instance ID: %s", instanceId)) ui.Say(fmt.Sprintf("Waiting for instance (%v) to become ready...", instanceId)) - stateChange := StateChangeConf{ - Pending: []string{"pending"}, - Target: "running", - Refresh: InstanceStateRefreshFunc(ec2conn, instanceId), - StepState: state, + + describeInstanceStatus := &ec2.DescribeInstanceStatusInput{ + InstanceIds: []*string{aws.String(instanceId)}, } - latestInstance, err := WaitForState(&stateChange) - if err != nil { + if err := ec2conn.WaitUntilInstanceStatusOk(describeInstanceStatus); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - instance := latestInstance.(*ec2.Instance) + r, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIds: []*string{aws.String(instanceId)}, + }) + if err != nil || len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { + err := fmt.Errorf("Error finding source instance.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + instance := r.Reservations[0].Instances[0] if s.Debug { if instance.PublicDnsName != nil && *instance.PublicDnsName != "" { From 4acc98a729e2545cb7285fbf262f6268ac162b25 Mon Sep 17 00:00:00 2001 From: Andrew Pennebaker <andrew.pennebaker@gmail.com> Date: Thu, 7 Dec 2017 23:15:56 -0600 Subject: [PATCH 0260/1007] add super key (vmware builder) --- .../vmware/common/step_type_boot_command.go | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 28db3c72e..b100b609e 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -183,6 +183,8 @@ func vncSendString(c *vnc.ClientConn, original string) { special["<rightAlt>"] = 0xFFEA special["<rightCtrl>"] = 0xFFE4 special["<rightShift>"] = 0xFFE2 + special["<leftSuper>"] = 0xFFEB + special["<rightSuper>"] = 0xFFEC shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" @@ -231,6 +233,17 @@ func vncSendString(c *vnc.ClientConn, original string) { continue } + if strings.HasPrefix(original, "<leftSuperOn>") { + keyCode = special["<leftSuper>"] + original = original[len("<leftSuperOn>"):] + log.Printf("Special code '<leftSuperOn>' found, replacing with: %d", keyCode) + + c.KeyEvent(keyCode, true) + time.Sleep(keyInterval) + + continue + } + if strings.HasPrefix(original, "<leftAltOff>") { keyCode = special["<leftAlt>"] original = original[len("<leftAltOff>"):] @@ -264,6 +277,17 @@ func vncSendString(c *vnc.ClientConn, original string) { continue } + if strings.HasPrefix(original, "<leftSuperOff>") { + keyCode = special["<leftSuper>"] + original = original[len("<leftSuperOff>"):] + log.Printf("Special code '<leftSuperOff>' found, replacing with: %d", keyCode) + + c.KeyEvent(keyCode, false) + time.Sleep(keyInterval) + + continue + } + if strings.HasPrefix(original, "<rightAltOn>") { keyCode = special["<rightAlt>"] original = original[len("<rightAltOn>"):] @@ -297,6 +321,17 @@ func vncSendString(c *vnc.ClientConn, original string) { continue } + if strings.HasPrefix(original, "<rightSuperOn>") { + keyCode = special["<rightSuper>"] + original = original[len("<rightSuperOn>"):] + log.Printf("Special code '<rightSuperOn>' found, replacing with: %d", keyCode) + + c.KeyEvent(keyCode, true) + time.Sleep(keyInterval) + + continue + } + if strings.HasPrefix(original, "<rightAltOff>") { keyCode = special["<rightAlt>"] original = original[len("<rightAltOff>"):] @@ -330,6 +365,17 @@ func vncSendString(c *vnc.ClientConn, original string) { continue } + if strings.HasPrefix(original, "<rightSuperOff>") { + keyCode = special["<rightSuper>"] + original = original[len("<rightSuperOff>"):] + log.Printf("Special code '<rightSuperOff>' found, replacing with: %d", keyCode) + + c.KeyEvent(keyCode, false) + time.Sleep(keyInterval) + + continue + } + if strings.HasPrefix(original, "<wait>") { log.Printf("Special code '<wait>' found, sleeping one second") time.Sleep(1 * time.Second) From 42d0e6f920217e239d8e4c49d46e1189f8fbec2e Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 08:28:27 -0800 Subject: [PATCH 0261/1007] Navigation and placeholders for guide --- .../building-image-in-cicd.html.md | 9 +++++++++ .../building-virtualbox-image.html.md | 9 +++++++++ .../source/guides/packer-on-cicd/index.html.md | 10 ++++++++++ .../packer-on-cicd/triggering-tfe.html.md | 9 +++++++++ .../uploading-images-to-artifact.html.md | 9 +++++++++ website/source/layouts/guides.erb | 17 +++++++++++++++++ 6 files changed, 63 insertions(+) create mode 100644 website/source/guides/packer-on-cicd/building-image-in-cicd.html.md create mode 100644 website/source/guides/packer-on-cicd/building-virtualbox-image.html.md create mode 100644 website/source/guides/packer-on-cicd/index.html.md create mode 100644 website/source/guides/packer-on-cicd/triggering-tfe.html.md create mode 100644 website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md new file mode 100644 index 000000000..4c234fd44 --- /dev/null +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -0,0 +1,9 @@ +--- +layout: guides +sidebar_current: guides-packer-on-cicd-build-image +page_title: Building Images in CI/CD +description: |- + ... +--- + +# Building Images in CI/CD diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md new file mode 100644 index 000000000..dc086223c --- /dev/null +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -0,0 +1,9 @@ +--- +layout: guides +sidebar_current: guides-packer-on-cicd-build-virtualbox +page_title: Building a VirtualBox Image with Packer in TeamCity +description: |- + ... +--- + +# Building a VirtualBox Image with Packer in TeamCity diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md new file mode 100644 index 000000000..32b4f33cc --- /dev/null +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -0,0 +1,10 @@ +--- +layout: guides +sidebar_current: guides-packer-on-cicd-index +page_title: Building Immutable Infrastructure with Packer in CI/CD +description: |- + ... +--- + +# Building Immutable Infrastructure with Packer in CI/CD + diff --git a/website/source/guides/packer-on-cicd/triggering-tfe.html.md b/website/source/guides/packer-on-cicd/triggering-tfe.html.md new file mode 100644 index 000000000..60aa59d4d --- /dev/null +++ b/website/source/guides/packer-on-cicd/triggering-tfe.html.md @@ -0,0 +1,9 @@ +--- +layout: guides +sidebar_current: guides-packer-on-cicd-triggering-tfe-run +page_title: Triggering Terraform Enterprise runs +description: |- + ... +--- + +# Triggering Terraform Enterprise runs diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md new file mode 100644 index 000000000..752a74dee --- /dev/null +++ b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md @@ -0,0 +1,9 @@ +--- +layout: guides +sidebar_current: guides-packer-on-cicd-upload-image-to-artifact-store +page_title: Uploading Images to Artifact Stores +description: |- + ... +--- + +# Uploading Images to Artifact Stores diff --git a/website/source/layouts/guides.erb b/website/source/layouts/guides.erb index f842f51a6..be059a632 100644 --- a/website/source/layouts/guides.erb +++ b/website/source/layouts/guides.erb @@ -4,6 +4,23 @@ <li<%= sidebar_current("guides-veewee-to-packer") %>> <a href="/guides/veewee-to-packer.html">Veewee to Packer</a> </li> + <li<%= sidebar_current("guides-packer-on-cicd") %>> + <a href="/guides/packer-on-cicd/index.html">Building Immutable Infrastructure with Packer in CI/CD</a> + <ul class="nav"> + <li<%= sidebar_current("guides-packer-on-cicd-build-image") %>> + <a href="/guides/packer-on-cicd/building-image-in-cicd.html">Building Images in CI/CD</a> + </li> + <li<%= sidebar_current("guides-packer-on-cicd-build-virtualbox") %>> + <a href="/guides/packer-on-cicd/building-virtualbox-image.html">Building a VirtualBox Image with Packer in TeamCity</a> + </li> + <li<%= sidebar_current("guides-packer-on-cicd-upload-image-to-artifact-store") %>> + <a href="/guides/packer-on-cicd/uploading-images-to-artifact.html">Uploading Images to Artifact Store</a> + </li> + <li<%= sidebar_current("guides-packer-on-cicd-triggering-tfe-run") %>> + <a href="/guides/packer-on-cicd/triggering-tfe.html">Triggering Terraform Enterprise runs</a> + </li> + </li> + </li> </ul> <% end %> From 5df2e040d03505ea150be68d8d8f95d61088a177 Mon Sep 17 00:00:00 2001 From: Ben Gnoinski <ben.gnoinski@beanstream.com> Date: Fri, 8 Dec 2017 08:49:49 -0800 Subject: [PATCH 0262/1007] Update amazon run_config.go absent ssh_private_key_file error --- builder/amazon/common/run_config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 4f20ed3b4..eef56cf4c 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -98,9 +98,9 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { if c.SSHKeyPairName != "" { if c.Comm.Type == "winrm" && c.Comm.WinRMPassword == "" && c.Comm.SSHPrivateKey == "" { - errs = append(errs, errors.New("A private_key_file must be provided to retrieve the winrm password when using ssh_keypair_name.")) + errs = append(errs, errors.New("ssh_private_key_file must be provided to retrieve the winrm password when using ssh_keypair_name.")) } else if c.Comm.SSHPrivateKey == "" && !c.Comm.SSHAgentAuth { - errs = append(errs, errors.New("A private_key_file must be provided or ssh_agent_auth enabled when ssh_keypair_name is specified.")) + errs = append(errs, errors.New("ssh_private_key_file must be provided or ssh_agent_auth enabled when ssh_keypair_name is specified.")) } } From 59172c5a2d735422df3525bff7e4e7dec3b829b2 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 10:31:00 -0800 Subject: [PATCH 0263/1007] Adding the CI/CD guide content --- .../building-image-in-cicd.html.md | 9 ++ .../building-virtualbox-image.html.md | 93 ++++++++++++++++++ .../images/teamcity_build_log.png | Bin 0 -> 333088 bytes .../images/teamcity_build_log_complete.png | Bin 0 -> 230524 bytes .../images/teamcity_new_build.png | Bin 0 -> 249258 bytes .../guides/packer-on-cicd/index.html.md | 5 + .../packer-on-cicd/triggering-tfe.html.md | 27 ++++- .../uploading-images-to-artifact.html.md | 16 +++ 8 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 website/source/guides/packer-on-cicd/images/teamcity_build_log.png create mode 100644 website/source/guides/packer-on-cicd/images/teamcity_build_log_complete.png create mode 100644 website/source/guides/packer-on-cicd/images/teamcity_new_build.png diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index 4c234fd44..3504f4cae 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -7,3 +7,12 @@ description: |- --- # Building Images in CI/CD + +The following guides from our amazing partners show how to use their service to build images with Packer. + +- [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](https://docs.google.com/document/d/1hetlS94SpUQ979K-1At9hwn1oDNWHegBqHGNcIFLBoY/edit) +- [Using Packer and Ansible to Build Immutable Infrastructure](https://blog.codeship.com/packer-ansible/) + +For the majority of the [Packer Builders](https://www.packer.io/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](https://www.packer.io/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](https://www.packer.io/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](https://www.packer.io/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. + +[Building a VirtualBox Image with Packer in TeamCity](https://docs.google.com/document/d/1AQjn4PpApnZ6pf097HYZzZa4ZMspRATxo9wNj78hLLc/edit#) diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index dc086223c..df060b68f 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -7,3 +7,96 @@ description: |- --- # Building a VirtualBox Image with Packer in TeamCity + +This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. + +The Packer VirtualBox builder requires access to VirtualBox which should run on a bare-metal machine as virtual machines should not run inside other virtual machines. This is also true for the [VMWare](https://www.packer.io/docs/builders/vmware.html) and the [QEMU](https://www.packer.io/docs/builders/qemu.html) Packer builders. + +## 1. Provision a bare-metal machine + +The Packer VirtualBox builder requires running on bare-metal (hardware). If you do not have access to a bare-metal machine, we recommend using [Packet.net](https://www.packet.net/) to obtain a new machine. If you are a first time user of Packet.net, the Packet.net team has provided HashiCorp the coupon code `hash25` which you can use for $25 off to test out this guide. You can use a `baremetal_0` for testing, but for regular use the `baremetal_1` instance may be a better option. + +There is also a [Packet Provider](https://www.terraform.io/docs/providers/packet/index.html) in Terraform you can use to provision the project and instance. + +```hcl +provider "packet" { } + +resource "packet_project" "teamcity_agents" { + name = "TeamCity" +} + +resource "packet_device" "agent" { + hostname = "teamcity-agent" + plan = "baremetal_0" + facility = "ams1" + operating_system = "ubuntu_16_04" + billing_cycle = "hourly" + project_id = "${packet_project.teamcity_project.id}" +} +``` + +## 2. Install VirtualBox and TeamCity Dependencies + +VirtualBox must be installed on the new instance along and TeamCity requires the JDK prior to installation. This guide uses Ubuntu as the Linux distribution, so you may need to adjust these commands for your distribution of choice. + +**Install Teamcity Dependencies** + +```shell +apt-get upgrade +apt-get install -y zip linux-headers-generic linux-headers-4.13.0-16-generic build-essential openjdk-8-jdk +``` + +**Install VirtualBox** + +``` +curl -OL "http://download.virtualbox.org/virtualbox/5.2.2/virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb" +dpkg -i virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb +``` + +You can also use the [`remote-exec` provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) in your terraform configuration to automatically run these commands when provisioning the new instance. + +## 3. Install Packer + +The TeamCity Agent machine will also need Packer Installed. You can find the latest download link from the [Packer Download](https://www.packer.io/downloads.html) page. + +```shell +curl -OL "https://releases.hashicorp.com/packer/1.1.2/packer_1.1.2_linux_amd64.zip" +unzip ./packer_1.1.2_linux_amd64.zip +``` + +Packer is installed at the `/root/packer` path which is used in subsequent steps. If it is installed elsewhere, take note of the path. + +## 4. Install TeamCity Agent + +This guide assume you already have a running instance of TeamCity Server. The new TeamCity Agent can be installed by [downloading a zip file and installing manually](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingAdditionalBuildAgents), or using [Agent Push](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingviaAgentPush). Once it is installed it should appear in TeamCity as a new Agent. + +Create a new Agent Pool for the agents which will be responsible for the VirtualBox Packer builds and the assign the new Agent to the new Agent Pool. + +## 5. Create a new Build in TeamCity + +In TeamCity Server create a new build and configure the Version Control Settings to download the Packer build configuration from the VCS repository. + +Add one **Build Step: Command Line** to the build. + +![TeamCity screenshot: New Build](./images/teamcity_new_build.png) + +In the **Script content** field add the following: + +```shell +#!/usr/bin/env bash +/root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json +``` + +This assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. + +## 6. Run a build in TeamCity + +The entire configuration is ready for a new build. Start a new run in TeamCity by pressing “Run”. + +The new run should be triggered and the virtual box image will be built. + +![TeamCity screenshot: Build log](./images/teamcity_build_log.png) + +Once complete, the build status should be updated to complete and successful. + +![TeamCity screenshot: Build log complete](./images/teamcity_build_log_complete.png) \ No newline at end of file diff --git a/website/source/guides/packer-on-cicd/images/teamcity_build_log.png b/website/source/guides/packer-on-cicd/images/teamcity_build_log.png new file mode 100644 index 0000000000000000000000000000000000000000..13d23e19cda1ab2cd7697f44e2bde9e7729fd6e4 GIT binary patch literal 333088 zcmbrl1#le8k|-(*EV962#t}0!TFlJM%#0RUOcpcCVrI6O*<xlMF^uTx+`E78M*Q<4 z_Qacrp02K{tjx-+%C3YCSCA7&fWv_U0|P^lln_w@1A_s8fq~n>eEz60$`N`41N%a5 z`R$v6<hO4`3QqQBmNuqfU=ra;DbOm)l9)q>NdN$#K@hSqcmwiS)eC`$NVVqcPeEZ= zVq}%G;e2pwp@BejUG&;YsJMY2Q1FokKzM4((Kd~mfNNP4!Nu3nr-MvSp!>yI>rMB~ zMg|AOcPBJ$z^I5S*f7dLctOx>Y65CPYN1>%%pkaFF4C9fOr3ap6&23!rh9J>*KZht zg%76-vl{O<@71D7V`KYZ-$jJvwhx@@hzOy;+z-O~J;9K@^42ZPvSFCNmO-8vQ6ksX zCeH1hQSYO1g^u|c6}%EtK;#OV)(=>MQA)Zp-Edhl#wcN%XcMaw1+T#@NA{UJ6C()| zq$DLFXfET`d5*d}&c0!=n6i>*WU-H4>zIfV3&zomnoPY3{Mz+TsgM~N#uBShdfJJz zu$-Lr92-VVU`D?dHIxzon6M3VK<cD*C$>NRjB7D`kImHa=QRKR2~29g4x*RnRFFN< zr2h%A9#fn46#jLl5Zuouke8nt&0HL5NE|*m?dx`*<LD#r0*v~V6NIstj}nv+?eHab z{#_ui+L^<6<Wt}y%&=4(;htH4Fv5ecV$VY?7QQqJ-JdTxT%YTl#GQUeDGvzEIQfsK zF&Kz`S?#-dtR=qgT5>_uE*3&{;%0DndJH3=XCP9jf~MJn-TmQew4cx0ePsBal|No$ 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 literal 0 HcmV?d00001 diff --git a/website/source/guides/packer-on-cicd/images/teamcity_build_log_complete.png b/website/source/guides/packer-on-cicd/images/teamcity_build_log_complete.png new file mode 100644 index 0000000000000000000000000000000000000000..a05b2a685b397d8bb27bfae43ba822282f54a15e GIT binary patch literal 230524 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 literal 0 HcmV?d00001 diff --git a/website/source/guides/packer-on-cicd/images/teamcity_new_build.png b/website/source/guides/packer-on-cicd/images/teamcity_new_build.png new file mode 100644 index 0000000000000000000000000000000000000000..798d00cedb2f133d2baac4ed905b717d234c553b GIT binary patch literal 249258 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 P&7XvrtZ4CjU7!B}WTjCQ literal 0 HcmV?d00001 diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md index 32b4f33cc..c65a49a2b 100644 --- a/website/source/guides/packer-on-cicd/index.html.md +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -8,3 +8,8 @@ description: |- # Building Immutable Infrastructure with Packer in CI/CD +This guide focuses on the following workflow for building immutable infrastructure. This workflow can be manual or automated and it can be implemented with a variety of technologies. The goal of this guide is to show how this workflow can be fully automated using Packer for building images from a CI/CD pipeline. + +1. [Building Images using Packer in CI/CD](./building-image-in-cicd.html) +2. [Uploading the new image to S3](./uploading-images-to-artifact.html) for future deployment or use during development +3. Provision new instances with the images using Terraform Enterprise by [creating a new Terraform Enterprise runs](./triggering-tfe.html). \ No newline at end of file diff --git a/website/source/guides/packer-on-cicd/triggering-tfe.html.md b/website/source/guides/packer-on-cicd/triggering-tfe.html.md index 60aa59d4d..4d2ef6fcc 100644 --- a/website/source/guides/packer-on-cicd/triggering-tfe.html.md +++ b/website/source/guides/packer-on-cicd/triggering-tfe.html.md @@ -6,4 +6,29 @@ description: |- ... --- -# Triggering Terraform Enterprise runs +# Creating a Terraform Enterprise runs + +Once an image is built and uploaded to an artifact store, the next step is to use this new image. In some cases the image will be downloaded by the dev team and used locally in development, like is often done with VirtualBox images with Vagrant. In most other cases, the new image will be used to provision new infrastructure. [Terraform](https://www.terraform.io/) is an open source tool that is ideal for provisioning the new infrastructure with the new image generated by Packer. + +The following is a sample terraform configuration which provisions a new AWS EC2 instance. The `aws_ami_id` is a variable which will be provided when running `terraform plan` and `terraform apply`. This variable references the latest AMI generated with the Packer build in CI/CD. + +```hcl +variable "aws_ami_id" { } + +provider "aws" { + region = "us-west-2" +} + +resource "aws_instance" "web" { + ami = "${var.aws_ami_id}" + instance_type = "t2.micro" +} +``` + +Terraform Enterprise should have a workspace with this terraform configuration and a placeholder variable `aws_ami_id`. + +**Steps to create a new run from CI/CD after a Packer build is complete and uploaded**: + +1. Add a new step to the CI/CD pipeline. +2. In the new step add a `curl` call to update the variables in the workspace using the [update variables API](https://www.terraform.io/docs/enterprise-beta/api/variables.html#update-variables) with the reference to the latest image. In the sample terraform configuration above, the “aws_ami_id” variable would be updated to the AMI ID of the latest image. +3. In that same step, add another `curl` call to [create a new run via the API](https://www.terraform.io/docs/enterprise-beta/api/run.html#create-a-run). A run performs a plan and apply on the last configuration version created and using the variables set in the workspace. In the previous step we update the variables, so the new run can be created using the previous configuration version. diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md index 752a74dee..3510a1dd5 100644 --- a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md @@ -7,3 +7,19 @@ description: |- --- # Uploading Images to Artifact Stores + +Once the image is generated it will be used by other parts of your operations workflow. For example, it is common to build VirtualBoxes with Packer to be used as base boxes in Vagrant. + +On the agent machine install the [AWS Command Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, this can be incorporated into the initial provisioning step when installing other dependencies. + +```shell +pip install awscli +``` + +Add an additional **Build Step: Command Line** to the build and set the **Script content** field to the following: + +```shell +awscli s3 cp . s3://bucket/ --exclude “*” --include “*.iso” +``` + +TeamCity provides a [Build Artifacts](https://confluence.jetbrains.com/display/TCD9/Build+Artifact) feature which can be used to store the newly generated image. Other CI/CD services also have similar build artifacts features built in, like [Circle CI Build Artifacts](https://circleci.com/docs/2.0/artifacts/). In addition to the built in artifact stores in CI/CD tools, there are also dedicated universal artifact storage services like [Artifactory](https://confluence.jetbrains.com/display/TCD9/Build+Artifact). All of these are great options for image artifact storage. From c4abcd9c7c83e103bf1fccda01ec8370bba107f2 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 10:59:43 -0800 Subject: [PATCH 0264/1007] Adding more context for references to other guides --- .../guides/packer-on-cicd/building-image-in-cicd.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index 3504f4cae..452b425fc 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -11,8 +11,8 @@ description: |- The following guides from our amazing partners show how to use their service to build images with Packer. - [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](https://docs.google.com/document/d/1hetlS94SpUQ979K-1At9hwn1oDNWHegBqHGNcIFLBoY/edit) -- [Using Packer and Ansible to Build Immutable Infrastructure](https://blog.codeship.com/packer-ansible/) +- [Using Packer and Ansible to Build Immutable Infrastructure [in CodeShip]](https://blog.codeship.com/packer-ansible/) For the majority of the [Packer Builders](https://www.packer.io/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](https://www.packer.io/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](https://www.packer.io/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](https://www.packer.io/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. -[Building a VirtualBox Image with Packer in TeamCity](https://docs.google.com/document/d/1AQjn4PpApnZ6pf097HYZzZa4ZMspRATxo9wNj78hLLc/edit#) +The [Building a VirtualBox Image with Packer in TeamCity](./building-virtualbox-image.html) guide walks through creating a VirtualBox image, which requires a bare-metal machine, running in TeamCity which also supports running the scripts directly on the machine. From 79c10a251ce00cf9179cf43e829502b4b423189d Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 11:05:17 -0800 Subject: [PATCH 0265/1007] Using placeholder for now --- .../source/guides/packer-on-cicd/building-image-in-cicd.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index 452b425fc..213fe0aa7 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -10,7 +10,7 @@ description: |- The following guides from our amazing partners show how to use their service to build images with Packer. -- [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](https://docs.google.com/document/d/1hetlS94SpUQ979K-1At9hwn1oDNWHegBqHGNcIFLBoY/edit) +- [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](#) - [Using Packer and Ansible to Build Immutable Infrastructure [in CodeShip]](https://blog.codeship.com/packer-ansible/) For the majority of the [Packer Builders](https://www.packer.io/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](https://www.packer.io/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](https://www.packer.io/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](https://www.packer.io/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. From 98420fc9f5928ee20b667a1e931d88cceccaee5b Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 8 Dec 2017 13:23:42 -0800 Subject: [PATCH 0266/1007] update changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cb17b49e..799e41f93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ * builder/amazon: Correctly deregister AMIs when `force_deregister` is set. [GH-5525] +* builder/amazon: Add a new parameter `ssh_interface`. Valid values include +`public_ip`, `private_ip`, `public_dns` or `private_dns`. [GH-5630] * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] * builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] @@ -41,9 +43,30 @@ * post-processor/docker-push: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] * post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] +* builder/vmware-iso: Improve logging of network errors. [GH-5456] +* provisioner/ansible-local: Add ability to clean staging directory. [GH-5618] +* core: Add new `packer_version` template engine. [GH-5619] +* core: Improve logic checking for downloaded isos in case where user has +provided 2+ `iso_urls` [GH-5632] +* builder/hyper-v: Add support for differencing disk. [GH-5458] +* builder/azure: Add sanity checks for resource group names [GH-5599] ### BUG FIXES: +* builder/hyper-v: Fix interpolation context for user variables in +`boot_command` [GH-5547] +* core: Fix windows pathing regression when downloading isos. [GH-5591] +* builder/azure: Only destroy temporary resource groups if they were created by +Packer. [GH-5593] +* provisioner/chef: Fix chef installs on Windows. [GH-5649] +* builder/azure: Clean up KeyVaults when deploying Windows images that used an +existing resource group. [GH-5656] +* builder/azure: 'build_resource_group_name' is mutually exclusive with +'location' [GH-5661] +* builder/amazon: Correctly set AWS region if given in template along with a +profile. [GH-5676] +* builder/vmware: Correctly detect Windows boot on vmware workstation. [GH-5672] +* builder/amazon: Builds on new C5 instances are now possible. [GH-5678] * builder/amazon: Add a delay option to security group waiter. [GH-5536] * builder/amazon: Fix regressions relating to spot instances and EBS volumes. [GH-5495] From d7fe37b8628bd1b382908cd69799b90706aa8ee0 Mon Sep 17 00:00:00 2001 From: Nick Fagerlund <nick.fagerlund@gmail.com> Date: Fri, 8 Dec 2017 13:25:32 -0800 Subject: [PATCH 0267/1007] Delete empty descriptions --- .../source/guides/packer-on-cicd/building-image-in-cicd.html.md | 2 -- .../guides/packer-on-cicd/building-virtualbox-image.html.md | 2 -- website/source/guides/packer-on-cicd/index.html.md | 2 -- website/source/guides/packer-on-cicd/triggering-tfe.html.md | 2 -- .../guides/packer-on-cicd/uploading-images-to-artifact.html.md | 2 -- 5 files changed, 10 deletions(-) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index 213fe0aa7..99607b2f8 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -2,8 +2,6 @@ layout: guides sidebar_current: guides-packer-on-cicd-build-image page_title: Building Images in CI/CD -description: |- - ... --- # Building Images in CI/CD diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index df060b68f..e06866650 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -2,8 +2,6 @@ layout: guides sidebar_current: guides-packer-on-cicd-build-virtualbox page_title: Building a VirtualBox Image with Packer in TeamCity -description: |- - ... --- # Building a VirtualBox Image with Packer in TeamCity diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md index c65a49a2b..5c79dfd88 100644 --- a/website/source/guides/packer-on-cicd/index.html.md +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -2,8 +2,6 @@ layout: guides sidebar_current: guides-packer-on-cicd-index page_title: Building Immutable Infrastructure with Packer in CI/CD -description: |- - ... --- # Building Immutable Infrastructure with Packer in CI/CD diff --git a/website/source/guides/packer-on-cicd/triggering-tfe.html.md b/website/source/guides/packer-on-cicd/triggering-tfe.html.md index 4d2ef6fcc..a241b0f15 100644 --- a/website/source/guides/packer-on-cicd/triggering-tfe.html.md +++ b/website/source/guides/packer-on-cicd/triggering-tfe.html.md @@ -2,8 +2,6 @@ layout: guides sidebar_current: guides-packer-on-cicd-triggering-tfe-run page_title: Triggering Terraform Enterprise runs -description: |- - ... --- # Creating a Terraform Enterprise runs diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md index 3510a1dd5..7ca746df7 100644 --- a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md @@ -2,8 +2,6 @@ layout: guides sidebar_current: guides-packer-on-cicd-upload-image-to-artifact-store page_title: Uploading Images to Artifact Stores -description: |- - ... --- # Uploading Images to Artifact Stores From dada63801b2139374ae06320474fae9bfb2a69d0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 7 Dec 2017 14:05:51 -0800 Subject: [PATCH 0268/1007] also use waiter code for spot instances --- .../amazon/common/step_run_spot_instance.go | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index b34d09bcb..323032de0 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -231,21 +231,26 @@ func (s *StepRunSpotInstance) Run(state multistep.StateBag) multistep.StepAction ui.Message(fmt.Sprintf("Instance ID: %s", instanceId)) ui.Say(fmt.Sprintf("Waiting for instance (%v) to become ready...", instanceId)) - stateChangeSpot := StateChangeConf{ - Pending: []string{"pending"}, - Target: "running", - Refresh: InstanceStateRefreshFunc(ec2conn, instanceId), - StepState: state, + describeInstanceStatus := &ec2.DescribeInstanceStatusInput{ + InstanceIds: []*string{aws.String(instanceId)}, } - latestInstance, err := WaitForState(&stateChangeSpot) - if err != nil { + if err := ec2conn.WaitUntilInstanceStatusOk(describeInstanceStatus); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - instance := latestInstance.(*ec2.Instance) + r, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIds: []*string{aws.String(instanceId)}, + }) + if err != nil || len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { + err := fmt.Errorf("Error finding source instance.") + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + instance := r.Reservations[0].Instances[0] // Retry creating tags for about 2.5 minutes err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { From 73b98b2a0405dfa6b3068503c2559ba45877bfd4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 7 Dec 2017 14:05:59 -0800 Subject: [PATCH 0269/1007] use waiter to wait for ebs instances to stop --- builder/amazon/common/step_stop_ebs_instance.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index 852626811..7d6b2e943 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -75,15 +75,12 @@ func (s *StepStopEBSBackedInstance) Run(state multistep.StateBag) multistep.Step ui.Say("Automatic instance stop disabled. Please stop instance manually.") } - // Wait for the instance to actual stop + // Wait for the instance to actually stop ui.Say("Waiting for the instance to stop...") - stateChange := StateChangeConf{ - Pending: []string{"running", "pending", "stopping"}, - Target: "stopped", - Refresh: InstanceStateRefreshFunc(ec2conn, *instance.InstanceId), - StepState: state, - } - _, err = WaitForState(&stateChange) + err = ec2conn.WaitUntilInstanceStopped(&ec2.DescribeInstancesInput{ + InstanceIds: []*string{instance.InstanceId}, + }) + if err != nil { err := fmt.Errorf("Error waiting for instance to stop: %s", err) state.Put("error", err) From 4b1d8e3fe8b4f0b490902748fd09520423a4b4a8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 7 Dec 2017 15:27:40 -0800 Subject: [PATCH 0270/1007] don't allow enhanced networking flags for spot instances. --- builder/amazon/ebs/builder.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 56757b826..42c87c365 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -34,8 +34,9 @@ type Config struct { } type Builder struct { - config Config - runner multistep.Runner + config Config + runner multistep.Runner + isSpotInstance bool } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { @@ -60,6 +61,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { if b.config.PackerConfig.PackerForce { b.config.AMIForceDeregister = true } + b.isSpotInstance = b.config.SpotPrice != "" && b.config.SpotPrice != "0" // Accumulate any errors var errs *packer.MultiError @@ -69,6 +71,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + if b.isSpotInstance && (b.config.AMIENASupport || b.config.AMISriovNetSupport) { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Spot instances do not support modification. Please ensure you use an AMI that supports either SR-IOV or ENA.")) + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } @@ -110,9 +116,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("ui", ui) var instanceStep multistep.Step - isSpotInstance := b.config.SpotPrice != "" && b.config.SpotPrice != "0" - if isSpotInstance { + if b.isSpotInstance { instanceStep = &awscommon.StepRunSpotInstance{ Debug: b.config.PackerDebug, ExpectedRootDevice: "ebs", @@ -201,7 +206,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - Skip: isSpotInstance, + Skip: b.isSpotInstance, DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ From 6601f18c7861b2c30f7a32865a13319a6ea3f473 Mon Sep 17 00:00:00 2001 From: Nick Fagerlund <nick.fagerlund@gmail.com> Date: Fri, 8 Dec 2017 13:46:51 -0800 Subject: [PATCH 0271/1007] Minor edits --- .../building-image-in-cicd.html.md | 8 +++---- .../building-virtualbox-image.html.md | 22 +++++++++---------- .../guides/packer-on-cicd/index.html.md | 4 ++-- .../packer-on-cicd/triggering-tfe.html.md | 18 ++++++++++----- .../uploading-images-to-artifact.html.md | 14 +++++++----- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index 99607b2f8..a5bc86725 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -6,11 +6,11 @@ page_title: Building Images in CI/CD # Building Images in CI/CD -The following guides from our amazing partners show how to use their service to build images with Packer. +The following guides from our partners show how to use their services to build images with Packer. - [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](#) -- [Using Packer and Ansible to Build Immutable Infrastructure [in CodeShip]](https://blog.codeship.com/packer-ansible/) +- [Using Packer and Ansible to Build Immutable Infrastructure in CodeShip](https://blog.codeship.com/packer-ansible/) -For the majority of the [Packer Builders](https://www.packer.io/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](https://www.packer.io/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](https://www.packer.io/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](https://www.packer.io/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. +The majority of the [Packer Builders](https://www.packer.io/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](https://www.packer.io/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](https://www.packer.io/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](https://www.packer.io/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. -The [Building a VirtualBox Image with Packer in TeamCity](./building-virtualbox-image.html) guide walks through creating a VirtualBox image, which requires a bare-metal machine, running in TeamCity which also supports running the scripts directly on the machine. +The [Building a VirtualBox Image with Packer in TeamCity](./building-virtualbox-image.html) guide shows how to create a VirtualBox image using TeamCity's support for running scripts on bare-metal machines. diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index e06866650..484308f8e 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -8,9 +8,9 @@ page_title: Building a VirtualBox Image with Packer in TeamCity This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. -The Packer VirtualBox builder requires access to VirtualBox which should run on a bare-metal machine as virtual machines should not run inside other virtual machines. This is also true for the [VMWare](https://www.packer.io/docs/builders/vmware.html) and the [QEMU](https://www.packer.io/docs/builders/qemu.html) Packer builders. +The Packer VirtualBox builder requires access to VirtualBox. VirtualBox should run on a bare-metal machine, as virtual machines should not run inside other virtual machines. This is also true for the [VMWare](https://www.packer.io/docs/builders/vmware.html) and the [QEMU](https://www.packer.io/docs/builders/qemu.html) Packer builders. -## 1. Provision a bare-metal machine +## 1. Provision a Bare-metal Machine The Packer VirtualBox builder requires running on bare-metal (hardware). If you do not have access to a bare-metal machine, we recommend using [Packet.net](https://www.packet.net/) to obtain a new machine. If you are a first time user of Packet.net, the Packet.net team has provided HashiCorp the coupon code `hash25` which you can use for $25 off to test out this guide. You can use a `baremetal_0` for testing, but for regular use the `baremetal_1` instance may be a better option. @@ -35,7 +35,7 @@ resource "packet_device" "agent" { ## 2. Install VirtualBox and TeamCity Dependencies -VirtualBox must be installed on the new instance along and TeamCity requires the JDK prior to installation. This guide uses Ubuntu as the Linux distribution, so you may need to adjust these commands for your distribution of choice. +VirtualBox must be installed on the new instance, and TeamCity requires the JDK prior to installation. This guide uses Ubuntu as the Linux distribution, so you may need to adjust these commands for your distribution of choice. **Install Teamcity Dependencies** @@ -51,7 +51,7 @@ curl -OL "http://download.virtualbox.org/virtualbox/5.2.2/virtualbox-5.2_5.2.2-1 dpkg -i virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb ``` -You can also use the [`remote-exec` provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) in your terraform configuration to automatically run these commands when provisioning the new instance. +You can also use the [`remote-exec` provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) in your Terraform configuration to automatically run these commands when provisioning the new instance. ## 3. Install Packer @@ -66,13 +66,13 @@ Packer is installed at the `/root/packer` path which is used in subsequent steps ## 4. Install TeamCity Agent -This guide assume you already have a running instance of TeamCity Server. The new TeamCity Agent can be installed by [downloading a zip file and installing manually](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingAdditionalBuildAgents), or using [Agent Push](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingviaAgentPush). Once it is installed it should appear in TeamCity as a new Agent. +This guide assume you already have a running instance of TeamCity Server. The new TeamCity Agent can be installed by [downloading a zip file and installing manually](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingAdditionalBuildAgents), or using [Agent Push](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingviaAgentPush). Once it is installed it should appear in TeamCity as a new Agent. -Create a new Agent Pool for the agents which will be responsible for the VirtualBox Packer builds and the assign the new Agent to the new Agent Pool. +Create a new Agent Pool for agents responsible for VirtualBox Packer builds and assign the new Agent to it. -## 5. Create a new Build in TeamCity +## 5. Create a New Build in TeamCity -In TeamCity Server create a new build and configure the Version Control Settings to download the Packer build configuration from the VCS repository. +In TeamCity Server create a new build and configure the Version Control Settings to download the Packer build configuration from the VCS repository. Add one **Build Step: Command Line** to the build. @@ -82,14 +82,14 @@ In the **Script content** field add the following: ```shell #!/usr/bin/env bash -/root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json +/root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json ``` This assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. ## 6. Run a build in TeamCity -The entire configuration is ready for a new build. Start a new run in TeamCity by pressing “Run”. +The entire configuration is ready for a new build. Start a new run in TeamCity by pressing “Run”. The new run should be triggered and the virtual box image will be built. @@ -97,4 +97,4 @@ The new run should be triggered and the virtual box image will be built. Once complete, the build status should be updated to complete and successful. -![TeamCity screenshot: Build log complete](./images/teamcity_build_log_complete.png) \ No newline at end of file +![TeamCity screenshot: Build log complete](./images/teamcity_build_log_complete.png) diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md index 5c79dfd88..dce80ada2 100644 --- a/website/source/guides/packer-on-cicd/index.html.md +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -6,8 +6,8 @@ page_title: Building Immutable Infrastructure with Packer in CI/CD # Building Immutable Infrastructure with Packer in CI/CD -This guide focuses on the following workflow for building immutable infrastructure. This workflow can be manual or automated and it can be implemented with a variety of technologies. The goal of this guide is to show how this workflow can be fully automated using Packer for building images from a CI/CD pipeline. +This guide focuses on the following workflow for building immutable infrastructure. This workflow can be manual or automated and it can be implemented with a variety of technologies. The goal of this guide is to show how this workflow can be fully automated using Packer for building images from a continuous integration/continuous deployment (CI/CD) pipeline. 1. [Building Images using Packer in CI/CD](./building-image-in-cicd.html) 2. [Uploading the new image to S3](./uploading-images-to-artifact.html) for future deployment or use during development -3. Provision new instances with the images using Terraform Enterprise by [creating a new Terraform Enterprise runs](./triggering-tfe.html). \ No newline at end of file +3. [Creating new Terraform Enterprise runs](./triggering-tfe.html) to provision new instances with the images diff --git a/website/source/guides/packer-on-cicd/triggering-tfe.html.md b/website/source/guides/packer-on-cicd/triggering-tfe.html.md index a241b0f15..a79af6f7a 100644 --- a/website/source/guides/packer-on-cicd/triggering-tfe.html.md +++ b/website/source/guides/packer-on-cicd/triggering-tfe.html.md @@ -4,11 +4,15 @@ sidebar_current: guides-packer-on-cicd-triggering-tfe-run page_title: Triggering Terraform Enterprise runs --- -# Creating a Terraform Enterprise runs +# Creating Terraform Enterprise Runs -Once an image is built and uploaded to an artifact store, the next step is to use this new image. In some cases the image will be downloaded by the dev team and used locally in development, like is often done with VirtualBox images with Vagrant. In most other cases, the new image will be used to provision new infrastructure. [Terraform](https://www.terraform.io/) is an open source tool that is ideal for provisioning the new infrastructure with the new image generated by Packer. +Once an image is built and uploaded to an artifact store, the next step is to use this new image. In some cases the image will be downloaded by the dev team and used locally in development, like is often done with VirtualBox images with Vagrant. In most other cases, the new image will be used to provision new infrastructure. -The following is a sample terraform configuration which provisions a new AWS EC2 instance. The `aws_ami_id` is a variable which will be provided when running `terraform plan` and `terraform apply`. This variable references the latest AMI generated with the Packer build in CI/CD. +[Terraform](https://www.terraform.io/) is an open source tool that is ideal for provisioning new infrastructure with images generated by Packer, and [Terraform Enterprise](https://www.hashicorp.com/products/terraform/) is the best way to perform automated Terraform runs. + +## Create a Terraform Configuration and Workspace + +The following is a sample Terraform configuration which provisions a new AWS EC2 instance. The `aws_ami_id` is a variable which will be provided when running `terraform plan` and `terraform apply`. This variable references the latest AMI generated with the Packer build in CI/CD. ```hcl variable "aws_ami_id" { } @@ -25,8 +29,10 @@ resource "aws_instance" "web" { Terraform Enterprise should have a workspace with this terraform configuration and a placeholder variable `aws_ami_id`. -**Steps to create a new run from CI/CD after a Packer build is complete and uploaded**: +## Include Terraform Enterprise in Your CI Builds + +Follow these steps to create a new run from CI/CD after a Packer build is complete and uploaded. 1. Add a new step to the CI/CD pipeline. -2. In the new step add a `curl` call to update the variables in the workspace using the [update variables API](https://www.terraform.io/docs/enterprise-beta/api/variables.html#update-variables) with the reference to the latest image. In the sample terraform configuration above, the “aws_ami_id” variable would be updated to the AMI ID of the latest image. -3. In that same step, add another `curl` call to [create a new run via the API](https://www.terraform.io/docs/enterprise-beta/api/run.html#create-a-run). A run performs a plan and apply on the last configuration version created and using the variables set in the workspace. In the previous step we update the variables, so the new run can be created using the previous configuration version. +2. In the new step add a `curl` call to update the variables in the workspace using the [update variables API](https://www.terraform.io/docs/enterprise-beta/api/variables.html#update-variables), so that Terraform has a reference to the latest image. For the sample configuration above, the `aws_ami_id` variable should be updated to the AMI ID of the latest image. +3. In that same step, add another `curl` call to [create a new run via the API](https://www.terraform.io/docs/enterprise-beta/api/run.html#create-a-run). A run performs a plan and apply on the last configuration version created, using the variables set in the workspace. In the previous step we update the variables, so the new run can be created using the previous configuration version. diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md index 7ca746df7..3ea0ece15 100644 --- a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md @@ -6,18 +6,22 @@ page_title: Uploading Images to Artifact Stores # Uploading Images to Artifact Stores -Once the image is generated it will be used by other parts of your operations workflow. For example, it is common to build VirtualBoxes with Packer to be used as base boxes in Vagrant. +Once the image is generated it will be used by other parts of your operations workflow. For example, it is common to build VirtualBox images with Packer to be used as base boxes in Vagrant. -On the agent machine install the [AWS Command Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, this can be incorporated into the initial provisioning step when installing other dependencies. +The exact process for uploading images depends on the artifact store and CI system you use. TeamCity provides a [Build Artifacts](https://confluence.jetbrains.com/display/TCD9/Build+Artifact) feature which can be used to store the newly generated image. Other CI/CD services also have similar build artifacts features built in, like [Circle CI Build Artifacts](https://circleci.com/docs/2.0/artifacts/). In addition to the built in artifact stores in CI/CD tools, there are also dedicated universal artifact storage services like [Artifactory](https://confluence.jetbrains.com/display/TCD9/Build+Artifact). All of these are great options for image artifact storage. + +The following example uses TeamCity and Amazon S3. + +## Example: Uploading to S3 in a TeamCity Build + +On the agent machine responsible for building images, install the [AWS Command Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, this can be incorporated into the initial agent provisioning step when installing other dependencies. ```shell pip install awscli ``` -Add an additional **Build Step: Command Line** to the build and set the **Script content** field to the following: +In your build configuration in TeamCity Server, add an additional **Build Step: Command Line** and set the **Script content** field to the following: ```shell awscli s3 cp . s3://bucket/ --exclude “*” --include “*.iso” ``` - -TeamCity provides a [Build Artifacts](https://confluence.jetbrains.com/display/TCD9/Build+Artifact) feature which can be used to store the newly generated image. Other CI/CD services also have similar build artifacts features built in, like [Circle CI Build Artifacts](https://circleci.com/docs/2.0/artifacts/). In addition to the built in artifact stores in CI/CD tools, there are also dedicated universal artifact storage services like [Artifactory](https://confluence.jetbrains.com/display/TCD9/Build+Artifact). All of these are great options for image artifact storage. From f216330ba30d72ddaa44e57f3cb32c3b4b7bb651 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 8 Dec 2017 14:56:19 -0800 Subject: [PATCH 0272/1007] spot instance ena/sriov checking for all other builders --- builder/amazon/common/run_config.go | 4 ++ builder/amazon/ebs/builder.go | 81 +++++++++++++------------- builder/amazon/ebssurrogate/builder.go | 76 +++++++++++++----------- builder/amazon/ebsvolume/builder.go | 73 ++++++++++++----------- builder/amazon/instance/builder.go | 47 ++++++++------- 5 files changed, 152 insertions(+), 129 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index eef56cf4c..1b50b4842 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -152,3 +152,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { return errs } + +func (c *RunConfig) IsSpotInstance() bool { + return c.SpotPrice != "" && c.SpotPrice != "0" +} diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 42c87c365..255506ccc 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -34,9 +34,8 @@ type Config struct { } type Builder struct { - config Config - runner multistep.Runner - isSpotInstance bool + config Config + runner multistep.Runner } func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { @@ -61,7 +60,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { if b.config.PackerConfig.PackerForce { b.config.AMIForceDeregister = true } - b.isSpotInstance = b.config.SpotPrice != "" && b.config.SpotPrice != "0" // Accumulate any errors var errs *packer.MultiError @@ -71,8 +69,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) - if b.isSpotInstance && (b.config.AMIENASupport || b.config.AMISriovNetSupport) { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Spot instances do not support modification. Please ensure you use an AMI that supports either SR-IOV or ENA.")) + if b.config.IsSpotInstance() && (b.config.AMIENASupport || b.config.AMISriovNetSupport) { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Spot instances do not support modification, which is required "+ + "when either `ena_support` or `sriov_support` are set. Please ensure "+ + "you use an AMI that already has either SR-IOV or ENA enabled.")) } if errs != nil && len(errs.Errors) > 0 { @@ -117,45 +118,45 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe var instanceStep multistep.Step - if b.isSpotInstance { + if b.config.IsSpotInstance() { instanceStep = &awscommon.StepRunSpotInstance{ - Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", - SpotPrice: b.config.SpotPrice, - SpotPriceProduct: b.config.SpotPriceAutoProduct, - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, - AvailabilityZone: b.config.AvailabilityZone, - BlockDevices: b.config.BlockDevices, - Tags: b.config.RunTags, - VolumeTags: b.config.VolumeRunTags, - Ctx: b.config.ctx, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.BlockDevices, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + ExpectedRootDevice: "ebs", + IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SpotPrice: b.config.SpotPrice, + SpotPriceProduct: b.config.SpotPriceAutoProduct, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + VolumeTags: b.config.VolumeRunTags, } } else { instanceStep = &awscommon.StepRunSourceInstance{ - Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, - AvailabilityZone: b.config.AvailabilityZone, - BlockDevices: b.config.BlockDevices, - Tags: b.config.RunTags, - VolumeTags: b.config.VolumeRunTags, - Ctx: b.config.ctx, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.BlockDevices, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + ExpectedRootDevice: "ebs", + IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + VolumeTags: b.config.VolumeRunTags, } } @@ -206,7 +207,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - Skip: b.isSpotInstance, + Skip: b.config.IsSpotInstance(), DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index fec997816..8cf1fff12 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -84,6 +84,13 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("no volume with name '%s' is found", b.config.RootDevice.SourceDeviceName)) } + if b.config.IsSpotInstance() && (b.config.AMIENASupport || b.config.AMISriovNetSupport) { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Spot instances do not support modification, which is required "+ + "when either `ena_support` or `sriov_support` are set. Please ensure "+ + "you use an AMI that already has either SR-IOV or ENA enabled.")) + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } @@ -124,47 +131,46 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state.Put("ui", ui) var instanceStep multistep.Step - isSpotInstance := b.config.SpotPrice != "" && b.config.SpotPrice != "0" - if isSpotInstance { + if b.config.IsSpotInstance() { instanceStep = &awscommon.StepRunSpotInstance{ - Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", - SpotPrice: b.config.SpotPrice, - SpotPriceProduct: b.config.SpotPriceAutoProduct, - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, - AvailabilityZone: b.config.AvailabilityZone, - BlockDevices: b.config.BlockDevices, - Tags: b.config.RunTags, - VolumeTags: b.config.VolumeRunTags, - Ctx: b.config.ctx, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.BlockDevices, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + ExpectedRootDevice: "ebs", + IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SpotPrice: b.config.SpotPrice, + SpotPriceProduct: b.config.SpotPriceAutoProduct, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + VolumeTags: b.config.VolumeRunTags, } } else { instanceStep = &awscommon.StepRunSourceInstance{ - Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, - AvailabilityZone: b.config.AvailabilityZone, - BlockDevices: b.config.BlockDevices, - Tags: b.config.RunTags, - VolumeTags: b.config.VolumeRunTags, - Ctx: b.config.ctx, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.BlockDevices, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + ExpectedRootDevice: "ebs", + IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, + VolumeTags: b.config.VolumeRunTags, } } @@ -212,7 +218,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - Skip: isSpotInstance, + Skip: b.config.IsSpotInstance(), DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 6bd8927ee..e7384784b 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -62,6 +62,13 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, err) } + if b.config.IsSpotInstance() && (b.config.AMIENASupport || b.config.AMISriovNetSupport) { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Spot instances do not support modification, which is required "+ + "when either `ena_support` or `sriov_support` are set. Please ensure "+ + "you use an AMI that already has either SR-IOV or ENA enabled.")) + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } @@ -103,45 +110,43 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe var instanceStep multistep.Step - isSpotInstance := b.config.SpotPrice != "" && b.config.SpotPrice != "0" - - if isSpotInstance { + if b.config.IsSpotInstance() { instanceStep = &awscommon.StepRunSpotInstance{ - Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", - SpotPrice: b.config.SpotPrice, - SpotPriceProduct: b.config.SpotPriceAutoProduct, - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, - AvailabilityZone: b.config.AvailabilityZone, - BlockDevices: b.config.launchBlockDevices, - Tags: b.config.RunTags, - Ctx: b.config.ctx, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.launchBlockDevices, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + ExpectedRootDevice: "ebs", + IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SpotPrice: b.config.SpotPrice, + SpotPriceProduct: b.config.SpotPriceAutoProduct, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, } } else { instanceStep = &awscommon.StepRunSourceInstance{ - Debug: b.config.PackerDebug, - ExpectedRootDevice: "ebs", - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, - AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, - AvailabilityZone: b.config.AvailabilityZone, - BlockDevices: b.config.launchBlockDevices, - Tags: b.config.RunTags, - Ctx: b.config.ctx, + AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, + AvailabilityZone: b.config.AvailabilityZone, + BlockDevices: b.config.launchBlockDevices, + Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + ExpectedRootDevice: "ebs", + IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, } } @@ -189,7 +194,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &awscommon.StepStopEBSBackedInstance{ - Skip: isSpotInstance, + Skip: b.config.IsSpotInstance(), DisableStopInstance: b.config.DisableStopInstance, }, &awscommon.StepModifyEBSBackedInstance{ diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 220ee7b10..ccef52d1a 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -155,6 +155,13 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs, fmt.Errorf("x509_key_path points to bad file: %s", err)) } + if b.config.IsSpotInstance() && (b.config.AMIENASupport || b.config.AMISriovNetSupport) { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Spot instances do not support modification, which is required "+ + "when either `ena_support` or `sriov_support` are set. Please ensure "+ + "you use an AMI that already has either SR-IOV or ENA enabled.")) + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } @@ -196,39 +203,39 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe var instanceStep multistep.Step - if b.config.SpotPrice == "" || b.config.SpotPrice == "0" { - instanceStep = &awscommon.StepRunSourceInstance{ - Debug: b.config.PackerDebug, - InstanceType: b.config.InstanceType, - UserData: b.config.UserData, - UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, + if b.config.IsSpotInstance() { + instanceStep = &awscommon.StepRunSpotInstance{ AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, AvailabilityZone: b.config.AvailabilityZone, BlockDevices: b.config.BlockDevices, - Tags: b.config.RunTags, Ctx: b.config.ctx, - } - } else { - instanceStep = &awscommon.StepRunSpotInstance{ Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + IamInstanceProfile: b.config.IamInstanceProfile, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, - InstanceType: b.config.InstanceType, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, - SourceAMI: b.config.SourceAmi, - IamInstanceProfile: b.config.IamInstanceProfile, - SubnetId: b.config.SubnetId, + } + } else { + instanceStep = &awscommon.StepRunSourceInstance{ AssociatePublicIpAddress: b.config.AssociatePublicIpAddress, - EbsOptimized: b.config.EbsOptimized, AvailabilityZone: b.config.AvailabilityZone, BlockDevices: b.config.BlockDevices, - Tags: b.config.RunTags, Ctx: b.config.ctx, + Debug: b.config.PackerDebug, + EbsOptimized: b.config.EbsOptimized, + IamInstanceProfile: b.config.IamInstanceProfile, + InstanceType: b.config.InstanceType, + SourceAMI: b.config.SourceAmi, + SubnetId: b.config.SubnetId, + Tags: b.config.RunTags, + UserData: b.config.UserData, + UserDataFile: b.config.UserDataFile, } } From 3710c34eb5771ed0bd9713d85f4559b34729d2f2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 8 Dec 2017 15:17:32 -0800 Subject: [PATCH 0273/1007] Revert "update changelog" This reverts commit 98420fc9f5928ee20b667a1e931d88cceccaee5b. --- CHANGELOG.md | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 799e41f93..8cb17b49e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,6 @@ * builder/amazon: Correctly deregister AMIs when `force_deregister` is set. [GH-5525] -* builder/amazon: Add a new parameter `ssh_interface`. Valid values include -`public_ip`, `private_ip`, `public_dns` or `private_dns`. [GH-5630] * builder/digitalocean: Add `ipv6` option to enable on droplet. [GH-5534] * builder/docker: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] @@ -43,30 +41,9 @@ * post-processor/docker-push: Add `aws_profile` option to control the aws profile for ECR. [GH-5470] * post-processor/vsphere: Properly capture `ovftool` output. [GH-5499] -* builder/vmware-iso: Improve logging of network errors. [GH-5456] -* provisioner/ansible-local: Add ability to clean staging directory. [GH-5618] -* core: Add new `packer_version` template engine. [GH-5619] -* core: Improve logic checking for downloaded isos in case where user has -provided 2+ `iso_urls` [GH-5632] -* builder/hyper-v: Add support for differencing disk. [GH-5458] -* builder/azure: Add sanity checks for resource group names [GH-5599] ### BUG FIXES: -* builder/hyper-v: Fix interpolation context for user variables in -`boot_command` [GH-5547] -* core: Fix windows pathing regression when downloading isos. [GH-5591] -* builder/azure: Only destroy temporary resource groups if they were created by -Packer. [GH-5593] -* provisioner/chef: Fix chef installs on Windows. [GH-5649] -* builder/azure: Clean up KeyVaults when deploying Windows images that used an -existing resource group. [GH-5656] -* builder/azure: 'build_resource_group_name' is mutually exclusive with -'location' [GH-5661] -* builder/amazon: Correctly set AWS region if given in template along with a -profile. [GH-5676] -* builder/vmware: Correctly detect Windows boot on vmware workstation. [GH-5672] -* builder/amazon: Builds on new C5 instances are now possible. [GH-5678] * builder/amazon: Add a delay option to security group waiter. [GH-5536] * builder/amazon: Fix regressions relating to spot instances and EBS volumes. [GH-5495] From cad5ccfa64e85c14fcf3ae8f3611796a687ed39f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 8 Dec 2017 15:24:37 -0800 Subject: [PATCH 0274/1007] update changelog --- CHANGELOG.md | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cb17b49e..8a5864a7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,41 @@ ## (UNRELEASED) ### IMPROVEMENTS: -* builder/alicloud-ecs: Add security token support and set tls handshake timeout - through environment variable. [GH-5641] + +* builder/alicloud-ecs: Add security token support and set TLS handshake + timeout through environment variable. [GH-5641] +* builder/amazon: Add a new parameter `ssh_interface`. Valid values include + `public_ip`, `private_ip`, `public_dns` or `private_dns`. [GH-5630] +* builder/azure: Add sanity checks for resource group names [GH-5599] +* builder/hyper-v: Add support for differencing disk. [GH-5458] +* builder/vmware-iso: Improve logging of network errors. [GH-5456] +* core: Add new `packer_version` template engine. [GH-5619] +* core: Improve logic checking for downloaded ISOs in case where user has + provided more than one URL in `iso_urls` [GH-5632] +* provisioner/ansible-local: Add ability to clean staging directory. [GH-5618] ### BUG FIXES: -* builder/qemu: Set default disk size to 40960 MB to prevent boot failures. [GH-5588] +* builder/amazon: Allow `region` to appear in `ami_regions`. [GH-5660] +* builder/amazon: `C5` instance types now build more reliably. [GH-5678] +* builder/amazon: Correctly set AWS region if given in template along with a + profile. [GH-5676] +* builder/amazon: Prevent `sriov_support` and `ena_support` from being used + with spot instances, which would cause a build failure. [GH-5679] +* builder/azure: `build_resource_group_name` is mutually exclusive with + `location` [GH-5661] +* builder/azure: Clean up KeyVaults when deploying Windows images that used an + existing resource group. [GH-5656] +* builder/azure: Only destroy temporary resource groups if they were created by + Packer. [GH-5593] +* builder/hyper-v: Fix interpolation context for user variables in + `boot_command` [GH-5547] +* builder/qemu: Set default disk size to 40960 MB to prevent boot failures. + [GH-5588] +* builder/vmware: Correctly detect Windows boot on vmware workstation. + [GH-5672] +* core: Fix windows path regression when downloading ISOs. [GH-5591] +* provisioner/chef: Fix chef installs on Windows. [GH-5649] ## 1.1.2 (November 15, 2017) From 4a864d59d72806b739031a9c539a97f32e0958a9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 8 Dec 2017 15:26:17 -0800 Subject: [PATCH 0275/1007] Prepare for 1.1.3 --- CHANGELOG.md | 2 +- version/version.go | 2 +- website/config.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a5864a7c..e1a6958e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## (UNRELEASED) +## 1.1.3 (December 8, 2017) ### IMPROVEMENTS: diff --git a/version/version.go b/version/version.go index 7ab8bb073..1cbe0158f 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ const Version = "1.1.3" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index b3a77be6a..fc5caf4e5 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.1.2" + h.version = "1.1.3" h.github_slug = "hashicorp/packer" h.website_root = "website" end From 3818ca8347182d770b8e5d6702c5fa43ce3a34ea Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 8 Dec 2017 15:45:12 -0800 Subject: [PATCH 0277/1007] prepare for next version --- CHANGELOG.md | 3 +++ version/version.go | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1a6958e8..62b92ca3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## (UNRELEASED) + + ## 1.1.3 (December 8, 2017) ### IMPROVEMENTS: diff --git a/version/version.go b/version/version.go index 1cbe0158f..03ee6f644 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.1.3" +const Version = "1.1.4" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From 203f29a95e3c69c9d363fb87a0c708c7025b73a4 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 15:49:26 -0800 Subject: [PATCH 0278/1007] Moving images to assets folder --- .../images/guides}/teamcity_build_log.png | Bin .../images/guides}/teamcity_build_log_complete.png | Bin .../images/guides}/teamcity_new_build.png | Bin .../building-virtualbox-image.html.md | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename website/source/{guides/packer-on-cicd/images => assets/images/guides}/teamcity_build_log.png (100%) rename website/source/{guides/packer-on-cicd/images => assets/images/guides}/teamcity_build_log_complete.png (100%) rename website/source/{guides/packer-on-cicd/images => assets/images/guides}/teamcity_new_build.png (100%) diff --git a/website/source/guides/packer-on-cicd/images/teamcity_build_log.png b/website/source/assets/images/guides/teamcity_build_log.png similarity index 100% rename from website/source/guides/packer-on-cicd/images/teamcity_build_log.png rename to website/source/assets/images/guides/teamcity_build_log.png diff --git a/website/source/guides/packer-on-cicd/images/teamcity_build_log_complete.png b/website/source/assets/images/guides/teamcity_build_log_complete.png similarity index 100% rename from website/source/guides/packer-on-cicd/images/teamcity_build_log_complete.png rename to website/source/assets/images/guides/teamcity_build_log_complete.png diff --git a/website/source/guides/packer-on-cicd/images/teamcity_new_build.png b/website/source/assets/images/guides/teamcity_new_build.png similarity index 100% rename from website/source/guides/packer-on-cicd/images/teamcity_new_build.png rename to website/source/assets/images/guides/teamcity_new_build.png diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index 484308f8e..d6b23dc42 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -76,7 +76,7 @@ In TeamCity Server create a new build and configure the Version Control Settings Add one **Build Step: Command Line** to the build. -![TeamCity screenshot: New Build](./images/teamcity_new_build.png) +![TeamCity screenshot: New Build](/assets/images/guides/teamcity_new_build.png) In the **Script content** field add the following: @@ -93,8 +93,8 @@ The entire configuration is ready for a new build. Start a new run in TeamCity b The new run should be triggered and the virtual box image will be built. -![TeamCity screenshot: Build log](./images/teamcity_build_log.png) +![TeamCity screenshot: Build log](/assets/images/guides/teamcity_build_log.png) Once complete, the build status should be updated to complete and successful. -![TeamCity screenshot: Build log complete](./images/teamcity_build_log_complete.png) +![TeamCity screenshot: Build log complete](/assets/images/guides/teamcity_build_log_complete.png) From 9c90744d3e29f2b60b9d841be893982e761d3ee5 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 15:55:22 -0800 Subject: [PATCH 0279/1007] Clarifying virtualization phrasing for VirtualBox --- .../guides/packer-on-cicd/building-virtualbox-image.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index d6b23dc42..7d1bb5067 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -8,7 +8,7 @@ page_title: Building a VirtualBox Image with Packer in TeamCity This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. -The Packer VirtualBox builder requires access to VirtualBox. VirtualBox should run on a bare-metal machine, as virtual machines should not run inside other virtual machines. This is also true for the [VMWare](https://www.packer.io/docs/builders/vmware.html) and the [QEMU](https://www.packer.io/docs/builders/qemu.html) Packer builders. +The Packer VirtualBox builder requires access to VirtualBox, which needs to run on a bare-metal machine as virtualization is generally not supported on cloud instances. This is also true for the [VMWare](https://www.packer.io/docs/builders/vmware.html) and the [QEMU](https://www.packer.io/docs/builders/qemu.html) Packer builders. ## 1. Provision a Bare-metal Machine @@ -33,7 +33,7 @@ resource "packet_device" "agent" { } ``` -## 2. Install VirtualBox and TeamCity Dependencies +## 2. Install VirtualBox and TeamCity dependencies VirtualBox must be installed on the new instance, and TeamCity requires the JDK prior to installation. This guide uses Ubuntu as the Linux distribution, so you may need to adjust these commands for your distribution of choice. From e0d5e184507f091955cf770617240268d5e2d56f Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 15:57:39 -0800 Subject: [PATCH 0280/1007] Calling out AWS CLI dependencies --- .../guides/packer-on-cicd/uploading-images-to-artifact.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md index 3ea0ece15..d981a8b81 100644 --- a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md @@ -14,7 +14,7 @@ The following example uses TeamCity and Amazon S3. ## Example: Uploading to S3 in a TeamCity Build -On the agent machine responsible for building images, install the [AWS Command Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, this can be incorporated into the initial agent provisioning step when installing other dependencies. +On the agent machine responsible for building images, install the [AWS Command Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, this can be incorporated into the initial agent provisioning step when installing other dependencies. The AWS Command Line tool may require installing additional [dependencies](http://docs.aws.amazon.com/cli/latest/userguide/installing.html) prior. ```shell pip install awscli From 3be55d20bec96a146d368b1f52395ff03ef5c914 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Fri, 8 Dec 2017 16:01:18 -0800 Subject: [PATCH 0281/1007] Updating section title to be specific to VirtualBox and S3 --- .../packer-on-cicd/uploading-images-to-artifact.html.md | 4 ++-- website/source/layouts/guides.erb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md index d981a8b81..e14d94ac4 100644 --- a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md @@ -1,10 +1,10 @@ --- layout: guides sidebar_current: guides-packer-on-cicd-upload-image-to-artifact-store -page_title: Uploading Images to Artifact Stores +page_title: Uploading VirtualBox Image to S3 --- -# Uploading Images to Artifact Stores +# Uploading VirtualBox Image to S3 Once the image is generated it will be used by other parts of your operations workflow. For example, it is common to build VirtualBox images with Packer to be used as base boxes in Vagrant. diff --git a/website/source/layouts/guides.erb b/website/source/layouts/guides.erb index be059a632..b9ea693ec 100644 --- a/website/source/layouts/guides.erb +++ b/website/source/layouts/guides.erb @@ -14,7 +14,7 @@ <a href="/guides/packer-on-cicd/building-virtualbox-image.html">Building a VirtualBox Image with Packer in TeamCity</a> </li> <li<%= sidebar_current("guides-packer-on-cicd-upload-image-to-artifact-store") %>> - <a href="/guides/packer-on-cicd/uploading-images-to-artifact.html">Uploading Images to Artifact Store</a> + <a href="/guides/packer-on-cicd/uploading-images-to-artifact.html">Uploading VirtualBox Image to S3</a> </li> <li<%= sidebar_current("guides-packer-on-cicd-triggering-tfe-run") %>> <a href="/guides/packer-on-cicd/triggering-tfe.html">Triggering Terraform Enterprise runs</a> From fadda1fe6d7711b05cd21bebc818e9894deffec2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 8 Dec 2017 16:08:36 -0800 Subject: [PATCH 0282/1007] shameful ex post facto changelog fix. --- CHANGELOG.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62b92ca3b..a0b095d29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ * builder/amazon: Add a new parameter `ssh_interface`. Valid values include `public_ip`, `private_ip`, `public_dns` or `private_dns`. [GH-5630] * builder/azure: Add sanity checks for resource group names [GH-5599] +* builder/azure: Allow users to specify an existing resource group to use, + instead of creating a new one for every run. [GH-5548] * builder/hyper-v: Add support for differencing disk. [GH-5458] * builder/vmware-iso: Improve logging of network errors. [GH-5456] * core: Add new `packer_version` template engine. [GH-5619] @@ -25,12 +27,6 @@ profile. [GH-5676] * builder/amazon: Prevent `sriov_support` and `ena_support` from being used with spot instances, which would cause a build failure. [GH-5679] -* builder/azure: `build_resource_group_name` is mutually exclusive with - `location` [GH-5661] -* builder/azure: Clean up KeyVaults when deploying Windows images that used an - existing resource group. [GH-5656] -* builder/azure: Only destroy temporary resource groups if they were created by - Packer. [GH-5593] * builder/hyper-v: Fix interpolation context for user variables in `boot_command` [GH-5547] * builder/qemu: Set default disk size to 40960 MB to prevent boot failures. From d069dc5b7c18e39ac332ab12566cdf801b14bd32 Mon Sep 17 00:00:00 2001 From: Andrew Pennebaker <andrew.pennebaker@gmail.com> Date: Sat, 9 Dec 2017 12:02:20 -0600 Subject: [PATCH 0283/1007] handle holding a-z keys, such as for boot options (vmware builder) --- .../vmware/common/step_type_boot_command.go | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index b100b609e..520ed4320 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -5,6 +5,7 @@ import ( "log" "net" "os" + "regexp" "runtime" "strings" "time" @@ -195,6 +196,9 @@ func vncSendString(c *vnc.ClientConn, original string) { keyInterval = delay } + azOnRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])On>") + azOffRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])Off>") + // TODO(mitchellh): Ripe for optimizations of some point, perhaps. for len(original) > 0 { var keyCode uint32 @@ -244,6 +248,25 @@ func vncSendString(c *vnc.ClientConn, original string) { continue } + if azOnRegex.MatchString(original) { + m := azOnRegex.FindStringSubmatch(original) + r, _ := utf8.DecodeRuneInString(m[1]) + original = original[len("<aOn>"):] + keyCode = uint32(r) + keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) + + log.Printf("Special code '%s' found, replacing with %d, shift %v", m[0], keyCode, keyShift) + + if keyShift { + c.KeyEvent(KeyLeftShift, true) + } + + c.KeyEvent(keyCode, true) + time.Sleep(keyInterval) + + continue + } + if strings.HasPrefix(original, "<leftAltOff>") { keyCode = special["<leftAlt>"] original = original[len("<leftAltOff>"):] @@ -288,6 +311,25 @@ func vncSendString(c *vnc.ClientConn, original string) { continue } + if azOffRegex.MatchString(original) { + m := azOffRegex.FindStringSubmatch(original) + r, _ := utf8.DecodeRuneInString(m[1]) + original = original[len("<aOff>"):] + keyCode = uint32(r) + keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) + + log.Printf("Special code '%s' found, replacing with %d, shift %v", m[0], keyCode, keyShift) + + if keyShift { + c.KeyEvent(KeyLeftShift, false) + } + + c.KeyEvent(keyCode, false) + time.Sleep(keyInterval) + + continue + } + if strings.HasPrefix(original, "<rightAltOn>") { keyCode = special["<rightAlt>"] original = original[len("<rightAltOn>"):] From 567b566c23bf46261a360a4d046ef7bfccede62b Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczynski <kw@linux.com> Date: Mon, 4 Dec 2017 14:27:56 +0100 Subject: [PATCH 0284/1007] docker: Remove AWS credentials and Session Token from being shown in the log. Signed-off-by: Krzysztof Wilczynski <kw@linux.com> --- builder/docker/driver_docker.go | 62 +++++++++++++++++++++++++-------- builder/docker/exec.go | 13 ++++++- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/builder/docker/driver_docker.go b/builder/docker/driver_docker.go index c3db3dda6..50a2b9920 100644 --- a/builder/docker/driver_docker.go +++ b/builder/docker/driver_docker.go @@ -150,24 +150,56 @@ func (d *DockerDriver) IPAddress(id string) (string, error) { func (d *DockerDriver) Login(repo, user, pass string) error { d.l.Lock() - args := []string{"login"} - if user != "" { - args = append(args, "-u", user) - } - if pass != "" { - args = append(args, "-p", pass) - } - if repo != "" { - args = append(args, repo) - } - - cmd := exec.Command("docker", args...) - err := runAndStream(cmd, d.Ui) + version_running, err := d.Version() if err != nil { d.l.Unlock() + return err } - return err + // Version 17.07.0 of Docker adds support for the new + // `--password-stdin` option which can be used to offer + // password via the standard input, rather than passing + // the password and/or token using a command line switch. + constraint, err := version.NewConstraint(">= 17.07.0") + if err != nil { + d.l.Unlock() + return err + } + + cmd := exec.Command("docker") + cmd.Args = append(cmd.Args, "login") + + if user != "" { + cmd.Args = append(cmd.Args, "-u", user) + } + + if pass != "" { + if constraint.Check(version_running) { + cmd.Args = append(cmd.Args, "--password-stdin") + + stdin, err := cmd.StdinPipe() + if err != nil { + d.l.Unlock() + return err + } + io.WriteString(stdin, pass) + stdin.Close() + } else { + cmd.Args = append(cmd.Args, "-p", pass) + } + } + + if repo != "" { + cmd.Args = append(cmd.Args, repo) + } + + err = runAndStream(cmd, d.Ui) + if err != nil { + d.l.Unlock() + return err + } + + return nil } func (d *DockerDriver) Logout(repo string) error { @@ -292,7 +324,7 @@ func (d *DockerDriver) TagImage(id string, repo string, force bool) error { return err } - version_deprecated, err := version.NewVersion(string("1.12.0")) + version_deprecated, err := version.NewVersion("1.12.0") if err != nil { // should never reach this line return err diff --git a/builder/docker/exec.go b/builder/docker/exec.go index 201055b74..95752382f 100644 --- a/builder/docker/exec.go +++ b/builder/docker/exec.go @@ -19,7 +19,18 @@ func runAndStream(cmd *exec.Cmd, ui packer.Ui) error { defer stdout_w.Close() defer stderr_w.Close() - log.Printf("Executing: %s %v", cmd.Path, cmd.Args[1:]) + args := make([]string, len(cmd.Args)-1) + copy(args, cmd.Args[1:]) + + // Scrub password from the log output. + for i, v := range args { + if v == "-p" || v == "--password" { + args[i+1] = "<Filtered>" + break + } + } + + log.Printf("Executing: %s %v", cmd.Path, args) cmd.Stdout = stdout_w cmd.Stderr = stderr_w if err := cmd.Start(); err != nil { From 54f059d3d4006cc1481709d8485ff14c67c03f43 Mon Sep 17 00:00:00 2001 From: Vijaya Bhaskar Reddy Kondreddi <vijaya.reddy@ni.com> Date: Fri, 13 Oct 2017 00:46:24 +0530 Subject: [PATCH 0285/1007] Add support for skip export --- builder/hyperv/common/step_create_vm.go | 8 +++++ builder/hyperv/common/step_export_vm.go | 46 +++++++++++++------------ builder/hyperv/iso/builder.go | 5 +++ builder/hyperv/vmcx/builder.go | 3 ++ 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 02171d9c6..852880911 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -28,6 +28,8 @@ type StepCreateVM struct { EnableVirtualizationExtensions bool AdditionalDiskSize []uint DifferencingDisk bool + SkipExport bool + OutputDir string } func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { @@ -51,6 +53,12 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { } vhdPath := state.Get("packerVhdTempDir").(string) + + // inline vhd path if export is skipped + if s.SkipExport { + vhdPath = filepath.Join(s.OutputDir, "Virtual Hard Disks") + } + // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) diskSize := int64(s.DiskSize * 1024 * 1024) diff --git a/builder/hyperv/common/step_export_vm.go b/builder/hyperv/common/step_export_vm.go index 8c32052a3..a9c2097a5 100644 --- a/builder/hyperv/common/step_export_vm.go +++ b/builder/hyperv/common/step_export_vm.go @@ -17,18 +17,19 @@ const ( type StepExportVm struct { OutputDir string SkipCompaction bool + SkipExport bool } func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) - var err error var errorMsg string vmName := state.Get("vmName").(string) tmpPath := state.Get("packerTempDir").(string) outputPath := s.OutputDir + expPath := s.OutputDir // create temp path to export vm errorMsg = "Error creating temp export path: %s" @@ -39,21 +40,21 @@ func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction { ui.Error(err.Error()) return multistep.ActionHalt } + if !s.SkipExport { + ui.Say("Exporting vm...") - ui.Say("Exporting vm...") - - err = driver.ExportVirtualMachine(vmName, vmExportPath) - if err != nil { - errorMsg = "Error exporting vm: %s" - err := fmt.Errorf(errorMsg, err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + err = driver.ExportVirtualMachine(vmName, vmExportPath) + if err != nil { + errorMsg = "Error exporting vm: %s" + err := fmt.Errorf(errorMsg, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + // copy to output dir + expPath = filepath.Join(vmExportPath, vmName) } - // copy to output dir - expPath := filepath.Join(vmExportPath, vmName) - if s.SkipCompaction { ui.Say("Skipping disk compaction...") } else { @@ -68,16 +69,17 @@ func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction { } } - ui.Say("Copying to output dir...") - err = driver.CopyExportedVirtualMachine(expPath, outputPath, vhdDir, vmDir) - if err != nil { - errorMsg = "Error exporting vm: %s" - err := fmt.Errorf(errorMsg, err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + if !s.SkipExport { + ui.Say("Copying to output dir...") + err = driver.CopyExportedVirtualMachine(expPath, outputPath, vhdDir, vmDir) + if err != nil { + errorMsg = "Error exporting vm: %s" + err := fmt.Errorf(errorMsg, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } - return multistep.ActionContinue } diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 849cbcacf..35ed2c698 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -94,6 +94,8 @@ type Config struct { SkipCompaction bool `mapstructure:"skip_compaction"` + SkipExport bool `mapstructure:"skip_export"` + // Use differencing disk DifferencingDisk bool `mapstructure:"differencing_disk"` @@ -357,6 +359,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, AdditionalDiskSize: b.config.AdditionalDiskSize, DifferencingDisk: b.config.DifferencingDisk, + SkipExport: b.config.SkipExport, + OutputDir: b.config.OutputDir, }, &hypervcommon.StepEnableIntegrationService{}, @@ -422,6 +426,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &hypervcommon.StepExportVm{ OutputDir: b.config.OutputDir, SkipCompaction: b.config.SkipCompaction, + SkipExport: b.config.SkipExport, }, // the clean up actions for each step will be executed reverse order diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 6a976b3df..51997a384 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -94,6 +94,8 @@ type Config struct { SkipCompaction bool `mapstructure:"skip_compaction"` + SkipExport bool `mapstructure:"skip_export"` + ctx interpolate.Context } @@ -469,6 +471,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &hypervcommon.StepExportVm{ OutputDir: b.config.OutputDir, SkipCompaction: b.config.SkipCompaction, + SkipExport: b.config.SkipExport, }, // the clean up actions for each step will be executed reverse order From 5346583df96f06b888b6a2a69a652c61605751df Mon Sep 17 00:00:00 2001 From: Vijaya Bhaskar Reddy Kondreddi <vijaya.reddy@ni.com> Date: Tue, 28 Nov 2017 14:56:58 +0530 Subject: [PATCH 0286/1007] Update docs --- website/source/docs/builders/hyperv-iso.html.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index ff267392c..24fee6f05 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -97,6 +97,12 @@ can be configured for this builder. - `disk_size` (number) - The size, in megabytes, of the hard disk to create for the VM. By default, this is 40 GB. +- `differencing_disk` (boolean) - If true enables differencing disks. Only the changes will be written to the new disk. This is especially useful if your + source is a vhd/vhdx. This defaults to false. + +- `skip_export` (boolean) - If true skips VM export. If you are interested only in the vhd/vhdx files, you can enable this option. This will create + inline disks which improves the build performance. There will not be any copying of source vhds to temp directory. This defauls to false. + - `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual machine. This defaults to false. From dc96e7315181ebd2c8f18e3ba3bcac8bb80e2afb Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 11 Dec 2017 09:08:12 -0800 Subject: [PATCH 0287/1007] Adding more info about the options for Packer --- .../guides/packer-on-cicd/building-virtualbox-image.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index 7d1bb5067..28848f584 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -85,7 +85,7 @@ In the **Script content** field add the following: /root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json ``` -This assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. +This will use the `build` command in Packer to build the image defined in `./packer.json`. It assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console, since this will run in CI/CD, the the [`headless` variable](https://www.packer.io/docs/builders/virtualbox-iso.html#headless) instructs Packer to start the machine without the console. Packer can build multiple image types, so the [`-only=virtualbox-iso` option] instructs Packer to only build the builds with the name `virtualbox-iso`. ## 6. Run a build in TeamCity From dd5e5b8993050ca65831857d506f7f1a7e3891a7 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 11 Dec 2017 09:14:46 -0800 Subject: [PATCH 0288/1007] Using relative links for the docs/guides --- .../guides/packer-on-cicd/building-image-in-cicd.html.md | 2 +- .../guides/packer-on-cicd/building-virtualbox-image.html.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index a5bc86725..bbfc7ec5e 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -11,6 +11,6 @@ The following guides from our partners show how to use their services to build i - [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](#) - [Using Packer and Ansible to Build Immutable Infrastructure in CodeShip](https://blog.codeship.com/packer-ansible/) -The majority of the [Packer Builders](https://www.packer.io/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](https://www.packer.io/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](https://www.packer.io/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](https://www.packer.io/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. +The majority of the [Packer Builders](../../docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](../../docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](../../docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](../../docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. The [Building a VirtualBox Image with Packer in TeamCity](./building-virtualbox-image.html) guide shows how to create a VirtualBox image using TeamCity's support for running scripts on bare-metal machines. diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md index 28848f584..f2859f095 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md @@ -8,7 +8,7 @@ page_title: Building a VirtualBox Image with Packer in TeamCity This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. -The Packer VirtualBox builder requires access to VirtualBox, which needs to run on a bare-metal machine as virtualization is generally not supported on cloud instances. This is also true for the [VMWare](https://www.packer.io/docs/builders/vmware.html) and the [QEMU](https://www.packer.io/docs/builders/qemu.html) Packer builders. +The Packer VirtualBox builder requires access to VirtualBox, which needs to run on a bare-metal machine as virtualization is generally not supported on cloud instances. This is also true for the [VMWare](../../docs/builders/vmware.html) and the [QEMU](../../docs/builders/qemu.html) Packer builders. ## 1. Provision a Bare-metal Machine @@ -85,7 +85,7 @@ In the **Script content** field add the following: /root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json ``` -This will use the `build` command in Packer to build the image defined in `./packer.json`. It assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console, since this will run in CI/CD, the the [`headless` variable](https://www.packer.io/docs/builders/virtualbox-iso.html#headless) instructs Packer to start the machine without the console. Packer can build multiple image types, so the [`-only=virtualbox-iso` option] instructs Packer to only build the builds with the name `virtualbox-iso`. +This will use the `build` command in Packer to build the image defined in `./packer.json`. It assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console, since this will run in CI/CD, the the [`headless` variable](../../docs/builders/virtualbox-iso.html#headless) instructs Packer to start the machine without the console. Packer can build multiple image types, so the [`-only=virtualbox-iso` option](../../docs/commands/build.html#only-foo-bar-baz) instructs Packer to only build the builds with the name `virtualbox-iso`. ## 6. Run a build in TeamCity From 004a43492857f337936c9c64dbaadf37e6de85f4 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 11 Dec 2017 11:48:34 -0800 Subject: [PATCH 0289/1007] Add "coming soon" --- .../source/guides/packer-on-cicd/building-image-in-cicd.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md index bbfc7ec5e..16cb5aa7d 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md @@ -8,7 +8,7 @@ page_title: Building Images in CI/CD The following guides from our partners show how to use their services to build images with Packer. -- [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](#) +- How to Build Immutable Infrastructure with Packer and CircleCI Workflows (coming soon) - [Using Packer and Ansible to Build Immutable Infrastructure in CodeShip](https://blog.codeship.com/packer-ansible/) The majority of the [Packer Builders](../../docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](../../docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](../../docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](../../docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. From be3f0a121a1b97ecb115cd463fc8811ffe64db2e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 14:31:44 -0800 Subject: [PATCH 0290/1007] guides should use infinitive verbs --- ...e-in-cicd.html.md => build-image-in-cicd.html.md} | 4 ++-- ...-image.html.md => build-virtualbox-image.html.md} | 4 ++-- website/source/guides/packer-on-cicd/index.html.md | 10 +++++----- .../{triggering-tfe.html.md => trigger-tfe.html.md} | 6 +++--- ...act.html.md => upload-images-to-artifact.html.md} | 4 ++-- website/source/layouts/guides.erb | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) rename website/source/guides/packer-on-cicd/{building-image-in-cicd.html.md => build-image-in-cicd.html.md} (94%) rename website/source/guides/packer-on-cicd/{building-virtualbox-image.html.md => build-virtualbox-image.html.md} (97%) rename website/source/guides/packer-on-cicd/{triggering-tfe.html.md => trigger-tfe.html.md} (93%) rename website/source/guides/packer-on-cicd/{uploading-images-to-artifact.html.md => upload-images-to-artifact.html.md} (95%) diff --git a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md similarity index 94% rename from website/source/guides/packer-on-cicd/building-image-in-cicd.html.md rename to website/source/guides/packer-on-cicd/build-image-in-cicd.html.md index 16cb5aa7d..f35f7168a 100644 --- a/website/source/guides/packer-on-cicd/building-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md @@ -1,10 +1,10 @@ --- layout: guides sidebar_current: guides-packer-on-cicd-build-image -page_title: Building Images in CI/CD +page_title: Build Images in CI/CD --- -# Building Images in CI/CD +# Build Images in CI/CD The following guides from our partners show how to use their services to build images with Packer. diff --git a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md similarity index 97% rename from website/source/guides/packer-on-cicd/building-virtualbox-image.html.md rename to website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index f2859f095..d4c80bdd1 100644 --- a/website/source/guides/packer-on-cicd/building-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -1,10 +1,10 @@ --- layout: guides sidebar_current: guides-packer-on-cicd-build-virtualbox -page_title: Building a VirtualBox Image with Packer in TeamCity +page_title: Build a VirtualBox Image with Packer in TeamCity --- -# Building a VirtualBox Image with Packer in TeamCity +# Build a VirtualBox Image with Packer in TeamCity This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md index dce80ada2..97e4a1391 100644 --- a/website/source/guides/packer-on-cicd/index.html.md +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -1,13 +1,13 @@ --- layout: guides sidebar_current: guides-packer-on-cicd-index -page_title: Building Immutable Infrastructure with Packer in CI/CD +page_title: Build Immutable Infrastructure with Packer in CI/CD --- -# Building Immutable Infrastructure with Packer in CI/CD +# Build Immutable Infrastructure with Packer in CI/CD This guide focuses on the following workflow for building immutable infrastructure. This workflow can be manual or automated and it can be implemented with a variety of technologies. The goal of this guide is to show how this workflow can be fully automated using Packer for building images from a continuous integration/continuous deployment (CI/CD) pipeline. -1. [Building Images using Packer in CI/CD](./building-image-in-cicd.html) -2. [Uploading the new image to S3](./uploading-images-to-artifact.html) for future deployment or use during development -3. [Creating new Terraform Enterprise runs](./triggering-tfe.html) to provision new instances with the images +1. [Build Images using Packer in CI/CD](./build-image-in-cicd.html) +2. [Upload the new image to S3](./upload-images-to-artifact.html) for future deployment or use during development +3. [Create new Terraform Enterprise runs](./triggering-tfe.html) to provision new instances with the images diff --git a/website/source/guides/packer-on-cicd/triggering-tfe.html.md b/website/source/guides/packer-on-cicd/trigger-tfe.html.md similarity index 93% rename from website/source/guides/packer-on-cicd/triggering-tfe.html.md rename to website/source/guides/packer-on-cicd/trigger-tfe.html.md index a79af6f7a..0200bd571 100644 --- a/website/source/guides/packer-on-cicd/triggering-tfe.html.md +++ b/website/source/guides/packer-on-cicd/trigger-tfe.html.md @@ -1,10 +1,10 @@ --- layout: guides -sidebar_current: guides-packer-on-cicd-triggering-tfe-run -page_title: Triggering Terraform Enterprise runs +sidebar_current: guides-packer-on-cicd-trigger-tfe-run +page_title: Trigger Terraform Enterprise runs --- -# Creating Terraform Enterprise Runs +# Create Terraform Enterprise Runs Once an image is built and uploaded to an artifact store, the next step is to use this new image. In some cases the image will be downloaded by the dev team and used locally in development, like is often done with VirtualBox images with Vagrant. In most other cases, the new image will be used to provision new infrastructure. diff --git a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md similarity index 95% rename from website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md rename to website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md index e14d94ac4..b7f034e95 100644 --- a/website/source/guides/packer-on-cicd/uploading-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md @@ -1,10 +1,10 @@ --- layout: guides sidebar_current: guides-packer-on-cicd-upload-image-to-artifact-store -page_title: Uploading VirtualBox Image to S3 +page_title: Upload VirtualBox Image to S3 --- -# Uploading VirtualBox Image to S3 +# Upload VirtualBox Image to S3 Once the image is generated it will be used by other parts of your operations workflow. For example, it is common to build VirtualBox images with Packer to be used as base boxes in Vagrant. diff --git a/website/source/layouts/guides.erb b/website/source/layouts/guides.erb index b9ea693ec..1d5653c04 100644 --- a/website/source/layouts/guides.erb +++ b/website/source/layouts/guides.erb @@ -5,19 +5,19 @@ <a href="/guides/veewee-to-packer.html">Veewee to Packer</a> </li> <li<%= sidebar_current("guides-packer-on-cicd") %>> - <a href="/guides/packer-on-cicd/index.html">Building Immutable Infrastructure with Packer in CI/CD</a> + <a href="/guides/packer-on-cicd/index.html">Build Immutable Infrastructure with Packer in CI/CD</a> <ul class="nav"> <li<%= sidebar_current("guides-packer-on-cicd-build-image") %>> - <a href="/guides/packer-on-cicd/building-image-in-cicd.html">Building Images in CI/CD</a> + <a href="/guides/packer-on-cicd/build-image-in-cicd.html">Build Images in CI/CD</a> </li> <li<%= sidebar_current("guides-packer-on-cicd-build-virtualbox") %>> - <a href="/guides/packer-on-cicd/building-virtualbox-image.html">Building a VirtualBox Image with Packer in TeamCity</a> + <a href="/guides/packer-on-cicd/build-virtualbox-image.html">Build a VirtualBox Image with Packer in TeamCity</a> </li> <li<%= sidebar_current("guides-packer-on-cicd-upload-image-to-artifact-store") %>> - <a href="/guides/packer-on-cicd/uploading-images-to-artifact.html">Uploading VirtualBox Image to S3</a> + <a href="/guides/packer-on-cicd/upload-images-to-artifact.html">Upload a VirtualBox Image to S3</a> </li> - <li<%= sidebar_current("guides-packer-on-cicd-triggering-tfe-run") %>> - <a href="/guides/packer-on-cicd/triggering-tfe.html">Triggering Terraform Enterprise runs</a> + <li<%= sidebar_current("guides-packer-on-cicd-trigger-tfe-run") %>> + <a href="/guides/packer-on-cicd/trigger-tfe.html">Trigger Terraform Enterprise runs</a> </li> </li> </li> From 97bacf679066874b41134aa7d0f92b5954f40bd3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 14:37:28 -0800 Subject: [PATCH 0291/1007] use absolute links --- .../guides/packer-on-cicd/build-image-in-cicd.html.md | 4 ++-- .../guides/packer-on-cicd/build-virtualbox-image.html.md | 4 ++-- website/source/guides/packer-on-cicd/index.html.md | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md index f35f7168a..29631703e 100644 --- a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md @@ -11,6 +11,6 @@ The following guides from our partners show how to use their services to build i - How to Build Immutable Infrastructure with Packer and CircleCI Workflows (coming soon) - [Using Packer and Ansible to Build Immutable Infrastructure in CodeShip](https://blog.codeship.com/packer-ansible/) -The majority of the [Packer Builders](../../docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](../../docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](../../docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](../../docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. +The majority of the [Packer Builders](/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. -The [Building a VirtualBox Image with Packer in TeamCity](./building-virtualbox-image.html) guide shows how to create a VirtualBox image using TeamCity's support for running scripts on bare-metal machines. +The [Building a VirtualBox Image with Packer in TeamCity](/guides/packer-on-cicd/building-virtualbox-image.html) guide shows how to create a VirtualBox image using TeamCity's support for running scripts on bare-metal machines. diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index d4c80bdd1..097843687 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -8,7 +8,7 @@ page_title: Build a VirtualBox Image with Packer in TeamCity This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. -The Packer VirtualBox builder requires access to VirtualBox, which needs to run on a bare-metal machine as virtualization is generally not supported on cloud instances. This is also true for the [VMWare](../../docs/builders/vmware.html) and the [QEMU](../../docs/builders/qemu.html) Packer builders. +The Packer VirtualBox builder requires access to VirtualBox, which needs to run on a bare-metal machine as virtualization is generally not supported on cloud instances. This is also true for the [VMWare](/docs/builders/vmware.html) and the [QEMU](/docs/builders/qemu.html) Packer builders. ## 1. Provision a Bare-metal Machine @@ -85,7 +85,7 @@ In the **Script content** field add the following: /root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json ``` -This will use the `build` command in Packer to build the image defined in `./packer.json`. It assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console, since this will run in CI/CD, the the [`headless` variable](../../docs/builders/virtualbox-iso.html#headless) instructs Packer to start the machine without the console. Packer can build multiple image types, so the [`-only=virtualbox-iso` option](../../docs/commands/build.html#only-foo-bar-baz) instructs Packer to only build the builds with the name `virtualbox-iso`. +This will use the `build` command in Packer to build the image defined in `./packer.json`. It assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console, since this will run in CI/CD, the the [`headless` variable](/docs/builders/virtualbox-iso.html#headless) instructs Packer to start the machine without the console. Packer can build multiple image types, so the [`-only=virtualbox-iso` option](/docs/commands/build.html#only-foo-bar-baz) instructs Packer to only build the builds with the name `virtualbox-iso`. ## 6. Run a build in TeamCity diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md index 97e4a1391..bd10914e0 100644 --- a/website/source/guides/packer-on-cicd/index.html.md +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -8,6 +8,6 @@ page_title: Build Immutable Infrastructure with Packer in CI/CD This guide focuses on the following workflow for building immutable infrastructure. This workflow can be manual or automated and it can be implemented with a variety of technologies. The goal of this guide is to show how this workflow can be fully automated using Packer for building images from a continuous integration/continuous deployment (CI/CD) pipeline. -1. [Build Images using Packer in CI/CD](./build-image-in-cicd.html) -2. [Upload the new image to S3](./upload-images-to-artifact.html) for future deployment or use during development -3. [Create new Terraform Enterprise runs](./triggering-tfe.html) to provision new instances with the images +1. [Build Images using Packer in CI/CD](/guides/packer-on-cicd/build-image-in-cicd.html) +2. [Upload the new image to S3](/guides/packer-on-cicd/upload-images-to-artifact.html) for future deployment or use during development +3. [Create new Terraform Enterprise runs](/guides/packer-on-cicd/trigger-tfe.html) to provision new instances with the images From 532c4a49733d3fc06453cb5d86751f3b57a67cdc Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 15:04:03 -0800 Subject: [PATCH 0292/1007] use a vcs project that will work --- .../build-virtualbox-image.html.md | 70 +++++++++++++++---- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 097843687..44292058d 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -6,15 +6,32 @@ page_title: Build a VirtualBox Image with Packer in TeamCity # Build a VirtualBox Image with Packer in TeamCity -This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. +This guide walks through the process of building a VirtualBox image using +Packer on a new TeamCity Agent. Before getting started you should have access +to a TeamCity Server. -The Packer VirtualBox builder requires access to VirtualBox, which needs to run on a bare-metal machine as virtualization is generally not supported on cloud instances. This is also true for the [VMWare](/docs/builders/vmware.html) and the [QEMU](/docs/builders/qemu.html) Packer builders. +The Packer VirtualBox builder requires access to VirtualBox, which needs to run +on a bare-metal machine, as virtualization is generally not supported on cloud +instances. This is also true for the [VMWare](/docs/builders/vmware.html) and +the [QEMU](/docs/builders/qemu.html) Packer builders. + +We will use Chef's [Bento boxes](https://github.com/chef/bento) to provision an +Ubuntu image on VirtualBox. We will use a fork of this repository as the +project we will build. ## 1. Provision a Bare-metal Machine -The Packer VirtualBox builder requires running on bare-metal (hardware). If you do not have access to a bare-metal machine, we recommend using [Packet.net](https://www.packet.net/) to obtain a new machine. If you are a first time user of Packet.net, the Packet.net team has provided HashiCorp the coupon code `hash25` which you can use for $25 off to test out this guide. You can use a `baremetal_0` for testing, but for regular use the `baremetal_1` instance may be a better option. +The Packer VirtualBox builder requires running on bare-metal (hardware). If you +do not have access to a bare-metal machine, we recommend using +[Packet.net](https://www.packet.net/) to obtain a new machine. If you are +a first time user of Packet.net, the Packet.net team has provided HashiCorp the +coupon code `hash25` which you can use for &#x24;25 off to test out this guide. You +can use a `baremetal_0` server type for testing, but for regular use, the +`baremetal_1` instance may be a better option. -There is also a [Packet Provider](https://www.terraform.io/docs/providers/packet/index.html) in Terraform you can use to provision the project and instance. +There is also a [Packet +Provider](https://www.terraform.io/docs/providers/packet/index.html) in +Terraform you can use to provision the project and instance. ```hcl provider "packet" { } @@ -35,7 +52,9 @@ resource "packet_device" "agent" { ## 2. Install VirtualBox and TeamCity dependencies -VirtualBox must be installed on the new instance, and TeamCity requires the JDK prior to installation. This guide uses Ubuntu as the Linux distribution, so you may need to adjust these commands for your distribution of choice. +VirtualBox must be installed on the new instance, and TeamCity requires the JDK +prior to installation. This guide uses Ubuntu as the Linux distribution, so you +may need to adjust these commands for your distribution of choice. **Install Teamcity Dependencies** @@ -51,28 +70,41 @@ curl -OL "http://download.virtualbox.org/virtualbox/5.2.2/virtualbox-5.2_5.2.2-1 dpkg -i virtualbox-5.2_5.2.2-119230~Ubuntu~xenial_amd64.deb ``` -You can also use the [`remote-exec` provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) in your Terraform configuration to automatically run these commands when provisioning the new instance. +You can also use the [`remote-exec` +provisioner](https://www.terraform.io/docs/provisioners/remote-exec.html) in +your Terraform configuration to automatically run these commands when +provisioning the new instance. ## 3. Install Packer -The TeamCity Agent machine will also need Packer Installed. You can find the latest download link from the [Packer Download](https://www.packer.io/downloads.html) page. +The TeamCity Agent machine will also need Packer Installed. You can find the +latest download link from the [Packer +Download](https://www.packer.io/downloads.html) page. ```shell curl -OL "https://releases.hashicorp.com/packer/1.1.2/packer_1.1.2_linux_amd64.zip" unzip ./packer_1.1.2_linux_amd64.zip ``` -Packer is installed at the `/root/packer` path which is used in subsequent steps. If it is installed elsewhere, take note of the path. +Packer is installed at the `/root/packer` path which is used in subsequent +steps. If it is installed elsewhere, take note of the path. ## 4. Install TeamCity Agent -This guide assume you already have a running instance of TeamCity Server. The new TeamCity Agent can be installed by [downloading a zip file and installing manually](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingAdditionalBuildAgents), or using [Agent Push](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingviaAgentPush). Once it is installed it should appear in TeamCity as a new Agent. +This guide assume you already have a running instance of TeamCity Server. The +new TeamCity Agent can be installed by [downloading a zip file and installing +manually](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingAdditionalBuildAgents), +or using [Agent +Push](https://confluence.jetbrains.com/display/TCD10//Setting+up+and+Running+Additional+Build+Agents#SettingupandRunningAdditionalBuildAgents-InstallingviaAgentPush). +Once it is installed it should appear in TeamCity as a new Agent. -Create a new Agent Pool for agents responsible for VirtualBox Packer builds and assign the new Agent to it. +Create a new Agent Pool for agents responsible for VirtualBox Packer builds and +assign the new Agent to it. ## 5. Create a New Build in TeamCity -In TeamCity Server create a new build and configure the Version Control Settings to download the Packer build configuration from the VCS repository. +In TeamCity Server, create a new build, and configure the Version Control +Settings to download the Packer build configuration from the VCS repository. Add one **Build Step: Command Line** to the build. @@ -82,14 +114,24 @@ In the **Script content** field add the following: ```shell #!/usr/bin/env bash -/root/packer build -only=virtualbox-iso -var "headless=true" ./packer.json +/root/packer build -only=virtualbox-iso -var "headless=true" ubuntu/ubuntu-16.04-amd64.json ``` -This will use the `build` command in Packer to build the image defined in `./packer.json`. It assumes that `packer.json` is the Packer build configuration file in the root path of the VCS repository. Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console, since this will run in CI/CD, the the [`headless` variable](/docs/builders/virtualbox-iso.html#headless) instructs Packer to start the machine without the console. Packer can build multiple image types, so the [`-only=virtualbox-iso` option](/docs/commands/build.html#only-foo-bar-baz) instructs Packer to only build the builds with the name `virtualbox-iso`. +This will use the `build` command in Packer to build the image defined in +`ubuntu/ubuntu-16.04-amd64.json`. It assumes that the VCS repository you're +using is a fork of [Chef/Bento](https://github.com/chef/bento). Packer defaults +to building VirtualBox machines by launching a GUI that shows the console. +Since this will run in CI/CD, use the [`headless` +variable](/docs/builders/virtualbox-iso.html#headless) to instruct Packer to +start the machine without the console. Packer can build multiple image types, +so the [`-only=virtualbox-iso` +option](/docs/commands/build.html#only-foo-bar-baz) instructs Packer to only +build the builds with the name `virtualbox-iso`. ## 6. Run a build in TeamCity -The entire configuration is ready for a new build. Start a new run in TeamCity by pressing “Run”. +The entire configuration is ready for a new build. Start a new run in TeamCity +by pressing “Run”. The new run should be triggered and the virtual box image will be built. From a2c9898db71686b36b6bcceaa6460961ff7968db Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 15:10:37 -0800 Subject: [PATCH 0293/1007] justify 80 cols --- .../build-image-in-cicd.html.md | 17 +++++++-- .../guides/packer-on-cicd/index.html.md | 6 +++- .../guides/packer-on-cicd/trigger-tfe.html.md | 36 +++++++++++++++---- .../upload-images-to-artifact.html.md | 26 +++++++++++--- 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md index 29631703e..1604d91df 100644 --- a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md @@ -6,11 +6,22 @@ page_title: Build Images in CI/CD # Build Images in CI/CD -The following guides from our partners show how to use their services to build images with Packer. +The following guides from our partners show how to use their services to build +images with Packer. - How to Build Immutable Infrastructure with Packer and CircleCI Workflows (coming soon) - [Using Packer and Ansible to Build Immutable Infrastructure in CodeShip](https://blog.codeship.com/packer-ansible/) -The majority of the [Packer Builders](/docs/builders/index.html) can run in a container or VM, a common model used by most CI/CD services. However, the [QEMU builder](/docs/builders/qemu.html) for [KVM](https://www.linux-kvm.org/page/Main_Page) and [Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox builder](/docs/builders/virtualbox.html) for OVA or OVF virtual machines and [VMWare builder](/docs/builders/vmware.html) for use with VMware products require running on a bare-metal machine. +The majority of the [Packer Builders](/docs/builders/index.html) can run in +a container or VM, a common model used by most CI/CD services. However, the +[QEMU builder](/docs/builders/qemu.html) for +[KVM](https://www.linux-kvm.org/page/Main_Page) and +[Xen](https://www.xenproject.org/) virtual machine images, [VirtualBox +builder](/docs/builders/virtualbox.html) for OVA or OVF virtual machines and +[VMWare builder](/docs/builders/vmware.html) for use with VMware products +require running on a bare-metal machine. -The [Building a VirtualBox Image with Packer in TeamCity](/guides/packer-on-cicd/building-virtualbox-image.html) guide shows how to create a VirtualBox image using TeamCity's support for running scripts on bare-metal machines. +The [Building a VirtualBox Image with Packer in +TeamCity](/guides/packer-on-cicd/building-virtualbox-image.html) guide shows +how to create a VirtualBox image using TeamCity's support for running scripts +on bare-metal machines. diff --git a/website/source/guides/packer-on-cicd/index.html.md b/website/source/guides/packer-on-cicd/index.html.md index bd10914e0..328e699c7 100644 --- a/website/source/guides/packer-on-cicd/index.html.md +++ b/website/source/guides/packer-on-cicd/index.html.md @@ -6,7 +6,11 @@ page_title: Build Immutable Infrastructure with Packer in CI/CD # Build Immutable Infrastructure with Packer in CI/CD -This guide focuses on the following workflow for building immutable infrastructure. This workflow can be manual or automated and it can be implemented with a variety of technologies. The goal of this guide is to show how this workflow can be fully automated using Packer for building images from a continuous integration/continuous deployment (CI/CD) pipeline. +This guide focuses on the following workflow for building immutable +infrastructure. This workflow can be manual or automated and it can be +implemented with a variety of technologies. The goal of this guide is to show +how this workflow can be fully automated using Packer for building images from +a continuous integration/continuous deployment (CI/CD) pipeline. 1. [Build Images using Packer in CI/CD](/guides/packer-on-cicd/build-image-in-cicd.html) 2. [Upload the new image to S3](/guides/packer-on-cicd/upload-images-to-artifact.html) for future deployment or use during development diff --git a/website/source/guides/packer-on-cicd/trigger-tfe.html.md b/website/source/guides/packer-on-cicd/trigger-tfe.html.md index 0200bd571..55d40c65b 100644 --- a/website/source/guides/packer-on-cicd/trigger-tfe.html.md +++ b/website/source/guides/packer-on-cicd/trigger-tfe.html.md @@ -6,13 +6,23 @@ page_title: Trigger Terraform Enterprise runs # Create Terraform Enterprise Runs -Once an image is built and uploaded to an artifact store, the next step is to use this new image. In some cases the image will be downloaded by the dev team and used locally in development, like is often done with VirtualBox images with Vagrant. In most other cases, the new image will be used to provision new infrastructure. +Once an image is built and uploaded to an artifact store, the next step is to +use this new image. In some cases the image will be downloaded by the dev team +and used locally in development, like is often done with VirtualBox images with +Vagrant. In most other cases, the new image will be used to provision new +infrastructure. -[Terraform](https://www.terraform.io/) is an open source tool that is ideal for provisioning new infrastructure with images generated by Packer, and [Terraform Enterprise](https://www.hashicorp.com/products/terraform/) is the best way to perform automated Terraform runs. +[Terraform](https://www.terraform.io/) is an open source tool that is ideal for +provisioning new infrastructure with images generated by Packer, and [Terraform +Enterprise](https://www.hashicorp.com/products/terraform/) is the best way to +perform automated Terraform runs. ## Create a Terraform Configuration and Workspace -The following is a sample Terraform configuration which provisions a new AWS EC2 instance. The `aws_ami_id` is a variable which will be provided when running `terraform plan` and `terraform apply`. This variable references the latest AMI generated with the Packer build in CI/CD. +The following is a sample Terraform configuration which provisions a new AWS +EC2 instance. The `aws_ami_id` is a variable which will be provided when +running `terraform plan` and `terraform apply`. This variable references the +latest AMI generated with the Packer build in CI/CD. ```hcl variable "aws_ami_id" { } @@ -27,12 +37,24 @@ resource "aws_instance" "web" { } ``` -Terraform Enterprise should have a workspace with this terraform configuration and a placeholder variable `aws_ami_id`. +Terraform Enterprise should have a workspace with this terraform configuration +and a placeholder variable `aws_ami_id`. ## Include Terraform Enterprise in Your CI Builds -Follow these steps to create a new run from CI/CD after a Packer build is complete and uploaded. +Follow these steps to create a new run from CI/CD after a Packer build is +complete and uploaded. 1. Add a new step to the CI/CD pipeline. -2. In the new step add a `curl` call to update the variables in the workspace using the [update variables API](https://www.terraform.io/docs/enterprise-beta/api/variables.html#update-variables), so that Terraform has a reference to the latest image. For the sample configuration above, the `aws_ami_id` variable should be updated to the AMI ID of the latest image. -3. In that same step, add another `curl` call to [create a new run via the API](https://www.terraform.io/docs/enterprise-beta/api/run.html#create-a-run). A run performs a plan and apply on the last configuration version created, using the variables set in the workspace. In the previous step we update the variables, so the new run can be created using the previous configuration version. +2. In the new step add a `curl` call to update the variables in the workspace + using the [update variables + API](https://www.terraform.io/docs/enterprise-beta/api/variables.html#update-variables), + so that Terraform has a reference to the latest image. For the sample + configuration above, the `aws_ami_id` variable should be updated to the AMI + ID of the latest image. +3. In that same step, add another `curl` call to [create a new run via the + API](https://www.terraform.io/docs/enterprise-beta/api/run.html#create-a-run). + A run performs a plan and apply on the last configuration version created, + using the variables set in the workspace. In the previous step we update the + variables, so the new run can be created using the previous configuration + version. diff --git a/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md index b7f034e95..9916fd871 100644 --- a/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md @@ -6,21 +6,39 @@ page_title: Upload VirtualBox Image to S3 # Upload VirtualBox Image to S3 -Once the image is generated it will be used by other parts of your operations workflow. For example, it is common to build VirtualBox images with Packer to be used as base boxes in Vagrant. +Once the image is generated it will be used by other parts of your operations +workflow. For example, it is common to build VirtualBox images with Packer to +be used as base boxes in Vagrant. -The exact process for uploading images depends on the artifact store and CI system you use. TeamCity provides a [Build Artifacts](https://confluence.jetbrains.com/display/TCD9/Build+Artifact) feature which can be used to store the newly generated image. Other CI/CD services also have similar build artifacts features built in, like [Circle CI Build Artifacts](https://circleci.com/docs/2.0/artifacts/). In addition to the built in artifact stores in CI/CD tools, there are also dedicated universal artifact storage services like [Artifactory](https://confluence.jetbrains.com/display/TCD9/Build+Artifact). All of these are great options for image artifact storage. +The exact process for uploading images depends on the artifact store and CI +system you use. TeamCity provides a [Build +Artifacts](https://confluence.jetbrains.com/display/TCD9/Build+Artifact) +feature which can be used to store the newly generated image. Other CI/CD +services also have similar build artifacts features built in, like [Circle CI +Build Artifacts](https://circleci.com/docs/2.0/artifacts/). In addition to the +built in artifact stores in CI/CD tools, there are also dedicated universal +artifact storage services like +[Artifactory](https://confluence.jetbrains.com/display/TCD9/Build+Artifact). +All of these are great options for image artifact storage. The following example uses TeamCity and Amazon S3. ## Example: Uploading to S3 in a TeamCity Build -On the agent machine responsible for building images, install the [AWS Command Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, this can be incorporated into the initial agent provisioning step when installing other dependencies. The AWS Command Line tool may require installing additional [dependencies](http://docs.aws.amazon.com/cli/latest/userguide/installing.html) prior. +On the agent machine responsible for building images, install the [AWS Command +Line Tool](https://aws.amazon.com/cli/). Since this is a one-time operation, +this can be incorporated into the initial agent provisioning step when +installing other dependencies. The AWS Command Line tool may require installing +additional +[dependencies](http://docs.aws.amazon.com/cli/latest/userguide/installing.html) +prior. ```shell pip install awscli ``` -In your build configuration in TeamCity Server, add an additional **Build Step: Command Line** and set the **Script content** field to the following: +In your build configuration in TeamCity Server, add an additional **Build Step: +Command Line** and set the **Script content** field to the following: ```shell awscli s3 cp . s3://bucket/ --exclude “*” --include “*.iso” From 6b30cf365315dbc2f26bc58d42df667bf223e9d1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 15:50:10 -0800 Subject: [PATCH 0294/1007] use more screenshots for bento in the examples --- .../guides/teamcity_build_configuration.png | Bin 0 -> 156540 bytes .../teamcity_create_project_from_url-1.png | Bin 0 -> 231743 bytes .../teamcity_create_project_from_url-2.png | Bin 0 -> 110107 bytes .../images/guides/teamcity_new_build.png | Bin 249258 -> 0 bytes .../build-virtualbox-image.html.md | 27 +++++++++++------- 5 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 website/source/assets/images/guides/teamcity_build_configuration.png create mode 100644 website/source/assets/images/guides/teamcity_create_project_from_url-1.png create mode 100644 website/source/assets/images/guides/teamcity_create_project_from_url-2.png delete mode 100644 website/source/assets/images/guides/teamcity_new_build.png diff --git a/website/source/assets/images/guides/teamcity_build_configuration.png b/website/source/assets/images/guides/teamcity_build_configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..bcdcbb54a9d5c9884ef033ae364875344e2ba9fd GIT binary patch literal 156540 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%0DsV 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 literal 0 HcmV?d00001 diff --git a/website/source/assets/images/guides/teamcity_create_project_from_url-1.png b/website/source/assets/images/guides/teamcity_create_project_from_url-1.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1ab30813c771d1574be3192777b6a524c56f16 GIT binary patch literal 231743 zcmdqHWmH_twgyT<AV81=g1d#_!GkmecL^3~EYP^SLkE&T2yVd}x5k~u6M{<zZJgi^ zK^tfq9($kj?!9BYALs19ug6$xRae!lxoXz@O1?ECv@{e6@Tl-GFfa&|mE^QBFz}!l z7>`PDu<vuMO>yZkFz{d4$;xUe%gQonxw}}~Ia*<0C`BZvJl54wChyxyW?^BefAgr| z)6%0IJ%0iQ2EFQM32$U@8K3Iz_vbxyknRa3H6g93z>4b$!+H|={^$wE%fS|d>W~w4 z;x`EN;MHcP-;vMZ0_?Q&bSXmw^Mm_yBbGrqJ&b<h&4~Pu=+s1##MA<f9Gu>VRyjoY zvzf;6F1os}KUl5bB2R9~-V`ABrpFEL9Pg^+lZS>jFh0mhYpiU#*D}y!Vfbu*`RRx8 z)IWF8)*6Dt{|x$Q*W%^V+M1+^^?i<w=c3_5ffo5_MmEfxH&%5$b{H>}z4%T=?Ow%b zQ(77^zGL{bfHND}ZR5d6Btw^yoJ?RiOH=DN=;JniOD13?_#z`qc<{v7Ql9Zm9Os}V z{8p-X4V+T0HqcL@P_2En8fR-aI_@{rPngJ0dLnPGBFADW)GzYLIIT0O^(rB*+59dx z(-{2P=EDOFm5o}=9}IhMgp(|PUJ=%j8*%MDL5~$Y40a5akmPu7qe#@J_~cXCvz2bQ z!Aps0oOj3Wm>`8fZ7gZ7{y&s?=b;k%`>w;0SD}|U{VH+v>()O%5g>!!b|GUaXjO^1 zr|`2yv1{EG-M>fa^hl4ngNM_2-^=6Acb{I?FrIYGcoG^FNt3vX@%p%5exc*xWzed8 z%(;%c7UpHKktfl)ZGM-PH(X*4E{{*4<Z7UnaUL0orQDfMd2A-^$MagrCR|~luV+f$ z?`@5{(`%AXnBb=vsc#-S;Pqqgy!ka}gm|I=48@@SB2D%C!Jhe$QtTtc$fu^DHxDjJ zh>6x?E>060PTok?gDD#ZtEL(Brqg-%;vcjy+N{hqlOKkJcb5^BUo>+b3XjK@O7L^= z#ZkP$XT*NSZH<H1BlXkjA>l9si9R3BM<2Rj6{z&<JhTywj7V<QpH$bxU((G_R=?|P zvt25NE$87XIFU#{j-nFGG#NzBt`uoCkQ{~w$e^{vN4pwAgbr~8j(gh8oi%=4J5Aqa zc@KQCujQs>jb%i|jeyT|YIWVI4wy#{0<zpq*z?maV;gT?r{DR&+*Sblikgn>-j5u5 zN8hJZE0hzys?jk3OowL0oou%r>s~lVMUin&BtBTfQ3!N&a13yK45r8cNOTxn+(^^8 z=tIuBkKtq^WKYH~{nX5wfv2fljD6NL6HC*hSQtBVyk@{9eoF_jAI&!--#n-=nuu-H zP}ZPsp>1Cgj5Fl2qk_wCwrb)JBu+FDug#ph3&|hmbb-H${d(x{dcYq}Ig4rY`$6Cv z1{|z-1~Qh=9aqQ|!xJb3cQaHzhaxF7`91dxPGczTd!iX4!jEFVa7I5o`Hg3bDe^t& zveGjoC5Nc(F(yuE+*2wU#rmf~KOfb|>_2<=^9iopk9b>_XUYoWPZ^n{H<=>iwF_uw zzc?yF<IUpN`YG3m$72@c#p3DK2~H?`v^bzKyLm<1zLTWq^4-4-JgL&dHgm9SpS94K z#OmjwegV(${ju63ymNTRg7M#frN9*ED(8DQOdt6(p;}ihYNSu48m}Br{DV*zTM+GD zmw%1s>u1GlY70~yRgAtgqu)LLT=`OVJX`*VSl#-w=gYPf4rcv@Bld_hR6ImJRZWR` znB_SM2Tm(aAI{c_$dtUVCJQm8oIu`_8-0?9ou8sV`B$x1rC04N#E)@nvgMfU;>(pF z1xmyjNs1gVoEQ$6vzSbnz2YS~UUF=6&Tu|rXJN-7#Utf-e!-Ec+g$WV&HO{Tj4)$s zBJ+UpiQ@_0iH1Ao6$dO*;?3K_)VC7sHA$X>OoRS|4+i}PF$az0<>h7NMS7IKKJ5AY zb&r&Y-Bfp9_eM@HAE=Ek)hQ+3b>DT~wc9n>HKK~PRyoaO9XqidvYV=}t5>X#Rq<q{ zX8lI|&Mri|P`hGWsPNsOr4@;l*~ZQw)*$JiVp0_c5*nwcrgx(^!*Qy|p%+uOpuh93 zuxzeW0cu_Pt@Kc@z2Mq7y1*JrR?@4-sXd?Tt$%<^n@>H4-l4g+xYoG#^G^|byQr2` z2&puMc9^y6wQI_%cfVye1$|Q}?8S{H#O{4%RZWo=MH<x|WfTPmdG=k#tVA0MZ+4|R zfFx~Wrq0IJ?Y`O4O}3R@8Ag_pmL%sksFZ2!<qB6il>(FliY~|wPUqS|Q+@tX8&TYp z0lxbHTHQWvHlR(+C}9>^R<H?R@x4j>A@*WjOS?ZlfWF<cUC5v9-2ZIn+VuJ%TIjm? z%<Pp=YR9nJrvIj>b#_RM^p}vI?^~tIzJJI~GtV^7U6Jk%S9s3+E?+laNI_j8sQ0>; zBzlVqL9r~rn9-d6M}0a?FeC7lkbwFt6APft^@7?&l$HK_eb7Z$ruCr{1Y~Lz+#PDW zVjpi_Gn+R;+~8TeZln)1ZIG$RtazlKQ8Cx|tQQtd5>rOyGoNmM;E?5F0$Q}|uEuR* zuP?3h6I${O9KY0C%jg3)c-4;7FWLnxYmD$rR{pB|ei+?e2<Yn=zYW72VeB^#k!|mG zP~=pEtdaGJYj_q%XsBkUXLh`9eI1!a^cvYr(aO^5=ngx89#U-pH~q(=e{XIzc2$fW zB(~NCKv3q$PKj~=zr=;VMD}~(5E1jOPi&Adh$H*}LTjp4Wm)B9O1p%;<aoq!)F-JR zX`F2$2@m8BoCrc*b)3|llb~o%QNNE4rQmm-7-Uarw1|IEm5@=8H}m~@8)vQs)Kb?n ztJe9G`Fn!#Q(SeN9%GYX3m0Ko`V{#tu^8`}F@+G<3rEn*n(L6On{T(Ar^WWqDH3|Q zR5={xT_$N3PIs^M?w55XnI+3Fp0UZRLo+97oyY+qEuvv`0?gJf!zhE!8PXc$+VC2S zoBHwKvCdlAniR_;mLxV$H99H3rFG7Txror8*DTuFf#a10x9lN0(;7SJyMhhAyA^iU z6V~djf+hj}n`a~fNjB9sG|Den*jSF#=`0m%%VyB*<w@%7K{Vh|u~F4ZA|HaL@T~#P zEr9B|8n<Q;WHYT%tRnnqr0O>k?*@w+t7<}ayr~G>|7Cb4i!UiH&hM2fBd6$IvzB@) zqeMzY3V^fK#FCYR%xk@Qt9)dKBs{`rg9$d_zIQsg@}gDVg6B$kJnbmiEbY$C`evB9 zPS*z4reU}-v)%EcE;J|9Z1cCrYmf9zs$mnsCJ)F_+rer475ixh83p%C;ID>PzAF&< zBzelnVBUIeF5bYV*XC}r@y=sE^4O%X?sRp^b-8#t+JAxurVB5%zmHE_5e^A+p@2WQ zVaE1Gz_(%sz3i<wb&K#lFdY!m(&qK~^eZ=K1m|Z?mx>e9hGOG}ww#-R-H0*=#4AKn zxnGla@0==W45<;~?X>c=S2>ZHS?71(?m>c&)K}Cl`qz4N3k7v{vqeN1u#76F<5~Cj zWrx$_71>R=jf=B%ZS9SN^-zn)Zi=@thgrws8DKYbp?}In<+zEN_Y)tV{fH%x%DKW8 z|Ekd?QX$*uf+Cyc$si{b<^_VjTCy6=u=ak3(N)QPyQgZPb4iTGyLso!UOc9vdW^G} zf|R~?<m71OLD?F@Ym#lciJl0sH2HhXbzdZ7*;|B4P#^N^b<HZvhUM5mt`1i5wPvIS z5~3`AT41Lzfv!u0FTEDoG2XkXJ|*XUWb%4`e?D+GZ>y(Q^)MyI%)8y#r{_w=DN<*s zW;rWZYI=787%;VAACzHaB#ZiVk%(xk%7W3kqJI!fM{|lWJ2x(WZS~r^n4G8eY4(9E zkF=q#O>f&nP*3Qe(j`gg`WYN6ZM~hMCj-;$yB@wCqx>~{@_O?a&6df=o4qMXyU(#( z<n>Ns0<4c-xb*{RYH7|#vh%i>el;aLBfBfT-YR;xSrv1;ar#bmdA*|&v5Js&8C<e& zUqp`{o9KXb@A8p`M~@|w0w=GVw-Wb?H{rP1*#yHhECiKz7RQAv4l{_yvWBv<OpU4B z^LX#8^GZuG+GYtbxSt);&SB)J#b=LLV#Q~(Sv|TX8G^giuHtt&(_^fXJ$y=td};Jv zC`9eE&yKgm^y3^t!hEmh^&+vEA<)|u-0(kcw%Zjv7zNlE9bdx3u!V^Tf@X1hmau+% z#@wjA<Q^B;7N%xz@M?c3^$q+0KgRVUyJY+R2!Vm?s$}SafkDRl*Y!YIo8=D%#)E7- zT?0=8bu}@NixZEzrHh3XkFS&KeQgX3316}Mq?47WIfJj0qqB#YFM#Rq8e;e9zp{Cm z82+x}=>T9dP}gFRb#b?15aJQ!dBr4&$H2fK;cjUyrY)!NZ}Izo047^cPggNsULPMH z9v=Z77k3+8K2cFo-dFs*{QTVaHMl+eoITBbxt%?j|JBI<+m4)-2gu#d)zi+!nc=T? z%`IHKJONBhe<}K(-@o3|%Gd6HH933yyIc1i<o&CJmyhQa@Bg%YFDmg@u9%jcua%>L zoSl=Ev&X#-Nq!N5R}y~<{C|r6SLOc^HT+*uK0Z<Y|10``ivBGs!TVPi{!f?wWv{<; z?+qr2C&Bwa#+Sr9qG}et9}gNkIZfUB=fl4S=l=0m`sKf#_vr_PcRJQTLNGAiU?|H; z>-s*}UnC0DJ<mG2(>&nPaQd3B&c`_xL-d$xUYXp!x!1%t_Yu~2{jU<0EAZQ&yA>~W z>r}AH0$>hC+j-IYoM*dVW1oZ~!=D?ywZ*kiZTZQ{ZK&*kcf6&Wmr+zo;5bKk(2Ncm zO%wI#u-P28d;xxyTO~o4kS4Gd2uDi5kvGTj$iUHn+si(wTf<9fj0caNzWGPD_i<QD zvRYno@^*y(ShkCdp=9vQKhyWu%TW+N2!+c2P|3$(_<-^7AKf15QDXihfxj!uGQH9A zQZlf6{*Sx(A%_F>kL>w(<@ZXDaG->^oY74Gw0}5lTbkhOiEQ(KZq+yMtFi92HoiPy z{Kr~n9^M-k=l|D+eX47P|Bu}b2R{NsdWzA!@a;dv6~?`bNBv`W!w6w~#!w>0QZD%Q z9|8l1;f+=@-#;FBhF2{2Lm&PrS>f3~_PC`)C6-%!%zp;pzkTc@_dOn~<?V?6v4OhC zC|Yvt^WM$HdMo`fRev+sE6?(rqS^nb3N$`OiwJwDUFq}<UnavZz$?#aZfU>KhMkf+ z{$vc(B)6q4-4i#8C#8QTp{<O5fF5!ZBxGsOK3;vSY=?$_`qVp;v}dFDyuAo~l>#1U z9o~|<^Mh~oj2;>KepzZp3Ebfk`~ONwN>;v<&Akyg*<rxF*~rwnCK9d&HP5Wo%v?QL z;#u=ga!LDSN<Y*aR_NJ<C<}C8KNIi?{I)CP>3cR%b%eVU(^G&Vnl@3@`jPVKe7OVM z0&;3mbMGJ)BH9J0AnDK1CE5|j#?SzZM|TB%Mp}bY%zjOI8dVK!O~<;6;RLw3FxsA~ z-=3Y|A<hIka{mhYB-Cn~!<y`W_Ro+Bx%d5{P}%_c6gDEyqBNNlo&>A9A3I2N&{(Zk z#eN_+B{=J<C!oOI6Kurc2wRfX9Qp`vnimMKGJX;Hg5Xu4PoCj)u!j$S7d3<($pz&o zXBOT3>hL}XB~|ge5*u66fG1ZbK}d9t!{5E_omlV$h?nf<O(}L<8>iG13c7tu-qMvp zaFQIYez8!PV!|c@|MI-W(!ayvqeIVVw&~c@j#o$<=`u>v1l)<u{!HbSP;2_@wAJy7 zTo07(SVuB=TM##b=tR_t0kvWRpx@ZL#E4z7i0!l3f+M_61y21fHQ?uBm)}c_>;6zh z;2(SOBd!m2dN1*fB^33iHTuO-trsgU8S9+O_DWS9{sStdl=F(if@2&+l|lOcI;wiZ zt;)pWbcq*t<G40*ma~fpWj-JL_RhmNI?i?Iv)S>QLM$vRoie%vvrXT~;SQ6^4BIS$ zfQ_9hK<a`*kPpXUcbMfGe`Ef(7yb{l(byi%izlgTOs5^b&Cx67G72L9#nP<%{!1vd z{bXN+E@^t1x;J02{<v^ehProrC#7PZF3ARL-XjyrzZK~-_=%D5_ZeNV0^N;sM*D65 zz7^Hv%NO1Whm9zvB_`x@=LF#pmQcON7KW_2weKr|SHCMgZB5h6v5s+_GIxW71dZ6o zYtMrT6pfC1iD8?g^Q^lgYh?96w&rhT?z?Y_$tNQojIJNTSE=xV_NfeoMSu%3vV2X? zQuj2!IKFHVeCb5^*GL5Ui@+7Ht^vP5zRfh9o98c=FZ`vRsEm*wChZdW6+>!$#3bn_ z9Uwtdbe|lSex1(;ENh?CIBZ<NNd4X+JpS1Et)m8bYx^n9VONI^>#XfaySl@mQE1%! z-O8LU>3G{nfuta2&I5uEl{6>3t7lW39&IqBRMA8!jA*Yc8;x2xJ5+okiIhOwTFLRO zO7WDd^QnjTQP9PAc~bqy+2yr5Rv1f3`WK=8xsd_9q@wvxbK+K`J!qvX%IIcum<~zY z7y4lR!#n4)#gBLdP*d^WIZ*xgtx|>|+?US?priB#UZM!up9BdM?`1E?@i{L)I~(~( zFu`xj6$7;La#!cWC3GcNGSY2R2pqD%IhP&R=xjh(6HyK6E5x3A@3wTFq=C3ymmZ}F zh;j{#cP;4$h#PGbrpyEANp-V+%@6<X6nN;-6W)*ADgJTVBG47ij=7T}s-SUx_0p#E z@d^bUPhXYaX!2VtZ2^Z`hzSWqJr?PyG?Z(-BVn#as5g)`WZfZ7Di*yqdL(9kc47ji zoUfA>?sUvPkiWihSC^rpGvZY5RPk<=!@O#O6AaZYPx9^<T%d8FEoOg2g^(gaAsK5U z0ElKv4pa&0P%)m1;&}gjl;Dwn;V}$*r=D~EYZ6*LS}kV#tu>wX^$S-GIgTItpJzMU zvKNp&#qgQSq4_dLzW=yFygGX*ORVcvhOk@I38D$SkvkbX3#k#Rbyq(B&^SmSLlDc* z_d(eDDVaB*JO_GeyCiMf{Ncs$(;-(P2GVNLjyg~J87}IJ-hDVWaXlT6w8(NamusHr zbSOPcL3Y{?S^%+)SL}f4l&997>-f(y!Tc0vg3*;|(4)<-MDgto?R0NBh5PzTCFwUp zsiOYn%AyFWZXf%eQDZZ-?R<kY<Vu;t)9))s9O@8rt(p1)fm_iMcqigBPYSPa8lbL5 ze7I!3E+pBaN%1i?OC65r=3TdmX`0|GNryd7I9j`w`+%Czd{lC|f8g%4VP?%Rwam6W zxgrvFdj1XmU(5>{6<xm{>y7MsX}^f<cx~t%e43`4%3KhuVK$A-pCD-;zqN1m^tS7_ z){S^1TS!bv9v}C@eSslKq=ZUpjQQB7o_`vpQouqHcUd)GxRGpd;?_N<u!BVkM02d~ z_O=$DS68mdRXsXCO&I5oFeV-iR&!zE0o>VPIbjlu_2F>-3@F?p0$S{~OXJ#6yxW&- zvdeCur^3U_GU8ZK<tPy3luwFVTE3VQ`V+eKDNshiZO50}+9d#f)KFMg@6v)^iA<P3 za{SQH9`W{p-C~V2)qdZ2<R_^HrAl;0TxF*m$}$;8VEX)lNs5V(niElzvKq>e-#S$H z-8V7yuRj9{(C4Y1K1h`+eG<;G0}kA<g8goD_J(=Y(ez(VM`+L+|KN*q$EA5^P5e*A zgS8H9N~=T(-nCl-(F;O_W~>^Xs;$m0K2<H~w+In2mW}u?N!f{5HoS?jY!WuHf&+3| z2-+YQH3r@}vwsr!3{ex%S#L0Pd|h6d(m8Ms)uH8~o9vc82==chzMq;X4T!dHI33t5 zD{^MgM|N*wVKZ+5VF$<dw47r4yirP)<!+fqPiFe6^}A3(k&ZK$+Weo2P#$9=2&Ely zf5+lcN=T!?aseE3TJ%Lh-)G5n132HoLDskvZLvQgZk8DjDS66X8WW1mV*%)4Fm*F$ zkwq+3W?W=yx?)&~MDW=m;Qr?~&*=-d65}A*+FM=w(^+d0Ycv~ae7SoLi5E@&XEW-C z@*FHDjBA;jY0G~3Tg(7*AJ5jI<XbNTrWI{X@Dp)*Q76dY@<$JRqLeiRKH=cYp!%DX z69BNoNcip)J7Nd6a9wIzuWkQhX^isDDg38rrWdmJV2$bd<ernV(vP(>;C7bKtkU)J zkKWIKfCtigTbI?9b<*vl)>)ld0ih7*b`1l>3jm#D9^&0v%ev=?-4Kktx@b#$I&&kT zbFCH?k17;RmgK&gX#lb|{18{&HGzLG-iSY9s{&7V7!;v?h@Cd?X+qc%>RS73Bb>9< z%McyYX4?Q+_z|n;7#oY2f^2ZC%eRYVBh^P%yLlN_KW6=7a}mw~W)xdF@2~wKjsUdF zgVVFNS)Q7vmIIH-Ah2E@l47gGrkBsD!7irBSbEAqe~JBV`$X;0>^^$UxR3Kp4C3>2 zc9G}Cc#Gmi)AZf#fY{<5I>Ku?cMuZLxNd=U;}FJ;s?>Ec>7EN7;{i;=fJh@-wKQF0 z;vLlG7>aI>PQ)*}7-hiAky~5+2|YTHhRpE4n{zLbuL87)`Ukz_o^pV*ZU$)@TZA_N z%a^uhg9iPi?A@QcsTKF7fif3FLXa2hG~FS~4rXU`i`N4UN9FKw6dcyn_~PW_e?Ahp z0&(#DwHmg5TNAkabj*C?TU2hW%NiXUByXw$pljMc+1u#d*%19hJYMTiw|}D?ezdib zGMc31lHYa~X^LLJf%?-0nJ^2nR?I2bcvI&Ksh#vVur{u_&0Yy)!y87R@THdmoQpX| zN4dot-?tLYleXLDH_}zh-={pY`~~&);34WCZLgT!n_%BaG2ukOUxo4j?c6K$)9Wps zO9$!x$@0kG*$^W<Oe*eNPQV{8EN<adk>b~@%$70?nB|1uoPHethQ|Q&cwHsqelTdI zo%>zF#^hNAp0J{6f?~(~s^m)`5)Nnqmmk<IG#Z+;W?|O`rvw)$IA@wUJ$3{(Rwidv z85;e*ThpcU+TtAhaB{Hp!Cm47+}U3N2)6qCp$`0zzC6x>%#@QfKN>!a4m{RPqj5|Q z%f31neK~dN{EaHWjB<z^b%MCxsJe*EsuI*Qm5_K2O?`%gZ%-kyU$d6${xG!d_*EEs z-{nYKJP5M9R2RAk<`piPYxAqvk74ao*4Ju~LP@ooxY;e$7<!}Vy2U0+v={Fp3pOqG z45r4MXu2;xMS(L<b$c!0Mw--&1SIY6FoQdf#j!*A%`eXRZStOBh{PbedJz4Cv$%eN z-J@sug&R>{xLQ#ymi-4KFJ^DR=QR`F1|t(#sAw-jgMzIO>)#3`MMl|kRjU%M>X;x{ z6{mv&0l<R$FC&QuA|YCGm1xu+iv^uc>FnHvBsZMS)(1`w>G2Y;YSY+M<3N;t&Wa6{ z3e=`Aqf6PP6yo>NW}%!utrvadg1tk*bK%S7eJj(nfKPZqt1DEg(-Qh8dB}3CV6x#r zu2tf6Qeb>jJgj2rQGrEE@bQYf!<|1EkDk1A;~EFrcod`!k^F6X+72=}!i7u(go1sf zL;^_0_qxs-HjjVD^mN1s)zO}MA#d5Nx`}l5hOV$ae-e~v)KAw&3OQ#lo(~zmt?&(q zHmy3x5xt3$xLgztB8?OEsZ8pE^li+7kJPFz0N1<l9Un?wg+0;BNC8&!%svU!c<Q2r zrq$>K3YhP>berJ0)#CCxU)TONo4U~7kzp}!-bJ9=E~YF8J8X#MA~N;JkI8rG5zKjj zhTSJat%;WR!Z^h?`7uJW%qC+JK2z!rPZ$_&T|Zj3mtSy!k-BxiTPg=FNstHFAi*}y z*|0@Q4>mE&;-&8TwzR`|KG`=+DQ27q^;n9D1m1b16f^v$dIT|)&iwT2oLQdhNYw2% zdb43dWqo!lBj_7%d|J~IPyCF=?4LHbY@4&3n{kKrYs0r7l@qI)zIxHoebj2r!A`(P zd2a=7KAVcwY8;J*2|@;F9yA+OeN?`A$J>lt=&0j=_8)h=Z{B~x#dp`zD~q?o8niBZ zSa|z7q-RN%YTS1T&u%;RHW%$3WL(2$YXy#r>m4B)ROP$-od<~AqGv9FN>`wSZVa~* zAl9`@N&Pfv(A_7G1p0M6dx=v5g0Gu6iB`fpex8mozcga00IL*M!tdLNf-Pet-2r*A zMM1C7w!pQuv!Qg}CFZGo;QDuz&)oNzlUTU|ow8uRJTGr8uTVDEMCY!p&m_HWm?e?| zJ1lGrYuMBu`A;K#RFX-;#K$<OJFdz-QM}G--0|tW3p`WwD(W2eQhULZuKSNTStsH2 zO?PwC<PF@#cWB$Hncu*gQ)IrXWF!lV_cp8D%yI##eO7FD?LI`_`^)(Gueb(%rS^$p z8E9S7d8^wR&~ImC{mbd2AXMw!L2rQ77Bi8GDs(j$)-jBDM!;@T%*ZOBn<yHKmZY7z zKu<z!A&=eR8^Of4ljpUzDt`8%)Pfw8MvULhn*6#gN^|Ug|Ir|*YiN#M_b=S~m2pm! z9%Hugy4WDH$${Z;CuQ+XCOFZ`eQ}VQ)#B3t&|9L!Jh&6%ThnLv#nHXuPk3VVSe?ZW zkOuA&{gkZQe0I=DwG0MEQ2WyK<J(c%I!y7fNB~`AR_8D7^Qdk~PUuDd#NEx8`r^=t zov+Y{REZAnx-%h;a!Ebz79H!b#Y9`TH723k(<peON$ik7Z;FZxeH#1F=DWhztNu>@ zTHQINe2GtXK2EuBjZ=v~wf|g{<pAmcji5QcYUcNnGnH$WrP#6pncM7mb5AAQ@9Iib zjvti5yb5*ak@$z#BOGOi!4qy^H?29-Q&aQ_wjQe=Az?vxC9FH~(7)}J#e$&L+anR) zYpuaC<?(%F$0GzB&?{`sbBGMqH6RPJi+BEvnwW=sWEFp{5GEh{bMB>a2}Je^Ec^a! z=Y3+=<uf}x+3bo~L~<Toz>+PaS=SCuE=3^UG_wD6@}(r1dS@+2bQ6^IUP$s}5IuKY z{|vR-s9h(Q+vk1w+^y5Da{0)sXWz>GKn{ts4d=@e;^Aowg|@aMQy|IV8%I_6{dZTv z0q*vdcSK6{1I!MKY_E*VG~buFYDz)K{QirT_tnWGY>|@dJq1J5K}rI+T#}hfWV!t% zY0>!m;dcw~)x=(be66sbhJx7oGdW+VUVa2hovBx3!W^3F1Af>kXiee#c&+{|*bzFM z24pQfI{4Om1YlO@bJ-q*o_UQ3>9F2B7*j0hV1e7R>aY=#qy@Dai||nvj$D6iLq867 ziTiF^tp6fY)S*_c@0)U4oje3R>b&C`T5i4FwOvMiaoT93N0KF=it={WTD_ZPRF|4@ z(mhboXRElBZLRP1FWB%i(X`K3mD1;)T8aC)1|)Dv!0sY;)|zsw34ScQL44(!mK0W2 zuv`8D1}>wHd13~gA}q_-zLtzu^lThb757oeScBjN|1@)mZzOrJ;}k4x@|Ne%_mWB7 z@bj7qT=t4ohG#+RRn)`+7s<U5KK7|FR@zUK@5|~&k-dcn??3KOa>VS=*X3oIZw1n| zGy|=JYgGo}PgJ&Yu>+*ULN>H3c>FvRyp(NV9bkv28=O>fHP#ZEoK1^@up@beeVX?1 zmL_Q`Q|EL2MVfm8Nypm0=eOmr-o<ROFv+~B4_k^Jj&8<f43edKPqSWqqg<!zx<xcJ z0FYlKPLD=EOe%iZqkxE30O2GLg5-h{A#CXd;<R)s*ad8D6Fl5b{x?YbWCON(KZP{4 zEIromzQzwh9F{+Na%tuhG94k0*YUH8_Nu1=TZ8uOcW>T^#WrrYn7Nk~*l)-!|4D~^ ztCJyyy)2J)is_#mk{2$(6q{CK)%My@E3L#=?Gk$|xc{vPv2Z|WTs{SL&<T-TYra3~ zU*l{<xu$!S50{pHt0giBSy!ld=%nj1UA?SAfHF)QyDWnbqUVh&G-jkiPV@L}dMzW8 zQk2^A)xGybzXQn0gC+4i1qTGg%@Shhw$w5lJB{H+I>mce&h-r!-)}_GG3M~sf*ju0 zrGB!5hoa3UvAM+)eQ_~$J7S}fWYcf5C9mh91?7EOn!6Nu=#hrn{aw7)tJ|o^5>oyl zK1rkO`5Zm@ERRo0vxSJk=(>cxT78Opc7gLxOSU3UHnUKo;5J&Lsa|;ZYOths7ki~0 zq20PREwx!AT=;`-YX@FyYTGb*4&*);86Z-_w9$v72e)y7$DSJcTGQped$TSY%-7<A z!b~fC^l`|{D@IDx_a>`i{Xw<cM=aN+RJe~x5^$0RKSex?p!bH>`pcFmcqnY>dqAQ* z4!5f(hf_JmB30yXe{mj2ott`O@lqHbq@%qtGlF}kuk2&gD!CBC;)NT9*nR^gz6Yhi z16*dH1N*9Rv4@CLhZ)tlnJu1O!-bW1!$l*lztd%!M-0~#^h88ezEgvJ>A<6Dez)v= zjg~$y*|yAPhtE?vjU|{Qv6p^-5+$_7BlmGMQgEAQI>yq`=VVT=5Wxee+7<1X^@tHc z9Ua6@VeSPxjM@~b$W;X#NCoS2n)Q_r9KsDZv`=S6`B%DG$LGg5;J2Nv6NndeEq>tG zopQIg?BniQNAsbJe!Z@5AcA*N@0GnV79=Vku22Or$u_jAx5@nH&r}r04?j}rI!$l{ z!V92(lD9zzE+TXe%WdbuvuNN+ED{oztiFwwZM&l{X=s_dMop|dLq|62!`cK4H^y;( z7>p#_k(N<MbLi(ah>L)oKK|5R$@n12?`_q~44U_GiYo>u;P<3H=qs1%M`7v7lB{1? zd9>+SG+b|e1a9c9xm~|J!85!lbU1(}-R9B;8N0Sv=xbHNwlpGuLxo^LisLWXHrkX? zrDn~FFN&d2=_^rR;Y;iYec(XOq-IzoDNb6;wn7>WkK5*-PazA{n%5wLcNDSnLQS$Z z%C<R9P8`2B$&EcfMjv*3?QGGJb>-e6RZI109ftiph&>M>t!_0d>lAfs^weSj1>8K8 zvpzQ!s82C958)l|lJi{3avxz0a|m(5N6oI%jyG?y+T9=x=H?Dhx7|x2!g@ve_DbV3 zI6mNAIf9yR*;S|m%|m=Z=RtheO9GMevlsIo53_n<@86@$$|@F*bd5;Zr=Bj3ls+|S zAqR4w47fOci_s+=u*6!$9f<YflFEyXX(VE<*!C{gXXW;+O5b`=Ruktu!M}F%%~(2I zzdDfL<omcu6Y|D-g!*>U3+N`4V61j`j_s-{6zEk)+o1x_;k5|Jp0p37Emc0`+W>2f z?M}zqdhJb$GNUp}MpCz4E>7rlR%^pKmo{!jlk-BY3pI*EYo}`3w(@o12fTDQInqD@ zx-{BxUN*IM8B9-5`_{)v3;8=S+F0|W*ORALZE4!+zg~e<*q-7jwH3<(!Q)(f0#7pu zb^K+$cb;bDQcIOfZyde&ct3l1Vyyjm?eds+`a^(|Zh8}dsTCYgmDzImr<iQ#_^Ee5 zZmuL}^I}%Iwq9AXNds}|)mo_x<kmuMxi5WIp%Sq<b8OssfHnDtubu9W1Lj!^b@hX? zgV6r%Z6;NyY1@lKkt|nzxysfJu?Sz`0sN%h<DlZDWs2+!r-G`8(gv~4z%AwavW*G$ zA$~(ocr;|UXu5V2w&*zD1jx5{a&M<1L+6Fb3vk5v{EH||s4EH8Ne+CoCDz(NI9t9o zYp_ehyQQ}WT9>Ee<LFH{pVxi-_0noz)@1Oknku5R(WrA_BGd5*zd`}c>LO&n_wkz( zF#ekSVllgah6-k*+^~e$pN2M;Zk$CvKyH&`wn@2FU<ZPs+8u_Um*(jm0^TjH>l&#y z{wkOnqSl@ol8^nocdlwN`lWtTsjX3GTFgvo+>4F#De^A$f}VUj{Up}hBh%_uD)eHU z<S9~ovqI?4f3pd3$67ia6+gQ1b8T5>q&}KYg&tDI*_j!zCiYQq_jwNlWoUy75MpHw zW#5YEc{z_|Yn>N0&?HUgI!qq#Capf#@5gEg4z+}P7j8~4^f_@_=8?wy+Sv2*6DM<3 zfN`Nuh><lj7opdEr{U8BjICdbFAnq%=3y6)cfhMv`*B_xui5w&^(QszrS^iXGA6-I zBf+$3?Z);}&&Cn$wQC{Qx;bw+t+`EE1<Jn~Lg+zs1m%;9Ld%5ZsX+uqhzaKTj@#;b z(Uq3k2!0>aXu0}4=qU-fP93<sn~dz}RO65WLI|HWI+vx;>NhB%-B2mOLC-N|((H=F zEBYo2fkRElJHlBXLD)^RCLHm!tW_hRvhsx?@&KUh;URt|JJGvH*5uUWa@b+N*r<WZ zz~c(H8G!ca9X{+WYotA|tq_{6>YAaf-3_xp3jW4#7<i;^7(zX!$d9O+H;={Yl%y={ zKjr6Xr87;zzp~o~?WB;~L={U!#(aofHF2svLIo5Ua-O71eXqr<s27oaVXtS}N$&%` z4oU|BdyHX-k~Xn8v`dW0m`dx=5mY^_Q$XK|Zb;vjt^ICzjS<9UBN%@^UFRH)!430? zV8dDGinCp2cW9(j=}@nle@(v4CM{%Wo@%g_=;SYHhYE79aUF3t41_I9{_>_9Kh=Oz zxiwptj=tL!<r%*}oEAg%vVeZEH|s6_gpLW})D{;R<3nUa<C?eA9z2lzt<?z1;ztgf zhnVx0Yn|Ro3|dSn2%h*|zJb$hQH9!3#S7p9n3&Dt;<cmwo+sOG*_)SK6GiZZ-Pqm6 zbJW(EL|FS;wH8hL=3=$Xi}~29Sk<*gC-+G)th-XVA~f1~pv}{3FV!HMilk$00FRbT zfG28==Xn-u%Fu(^sa;4wUR}!If~GIB0haZkU87RPBvzoQc_%`smW}k6s%iKd#KGgD z=G&}H43a7-$akdCvc$xuv}46IjZavp$`nL5?V#rVgr7SKwD`I&bsn_1c8Q`K0-F7F zJ9N=56PoY$a=aSNk1buUvFbd#O%{IMCbtQ%8pYcdaRRahSPbmd&NjLPP$H$QQh4Jt z?1v33q22z7-%CDr6tj|MSdYCcJ<<>DlZ2L+QV4Cu6DyW;Rkwyt$~cCV<vWCtvKK+g zegu)jl@kFnodOO`j@Q@Mx~al`RoY|@Nlv^Sl|jl%1I>2)2z={#z<ykX*>dW2-bdJ7 zJ38&+b3i+Cy2WumCj2~@U6g5P$}hsp<P|sy#l-2`ZhWLDyD7x9m3k(HK*c_B_-t)9 z;-uuIfSeC%S>De+JLfx3D~^R#9hJhaKL2Mz@YO>sZ0?ddln#NX<nlKroWZC$81XfT zNu4+jRO=O>a~&jRS*WurwamWPSp37JaH`gRC(84wK>G)@%pDGd(4G?fNF?-C2+fM3 z$Q!GB2X($(0nm<)!AEwSKXl)K0+l{C3<ZTY^hzka?~y9ua96_26xVq$>e)2PF$PUu zvovO58XLsJy?WHUa4<-yo4R-M=wh6+KQKP-Pz2<@U!k$Hf75VFo)|M~>hr=w+!JaC zN*8_79ON-9B++P!nX@<`3blXN&*h>lYV$U}DZ_H4>4N3sONDACS|vKbTm6Mi3Fldp z;RWk^aC&S8+kJX3lQM0;&6*If^z2O8C!lVBwoY@dH8F&xc&{*?Bh76CpFqJTtRhP^ zp>q+vlLfgmc>{IWvkYs`e%yH1YG%M|q@x#mdXz#(a3hgPcr!fS^-j+^2LR&QTE;#y zfP2L#H?A}}uNmjqG?qW@)R!>sw03~5nk#&f$_D`+3mLSCTWhL6zKlA}7T6@I0n}RS z>;{&_0*GRdpLE!tk2K9KD#{przZz;?+&F<m3W$C4cZhk04BU}&@wd-YOgCF#MVUHl z2H`TE50q$^Ua#Y)dHb<&8l;#CBO)ixD1_lKnDAmI9gh6^?&nk1^t~C4GZn>hS+Tpd zR8Mc8A#mHX#8Hw%uX!H{QgNQBW4nuy;GnRulFm%pycqOvzS%SPVu0!^T^=jOY>z~Z zU0a_rX|_J2E*$7Jje{X=Kj1t5_ple+UcYzOy>hmG>jSXo6Q5WcQuMXB#T@U8pjUg^ zr^$J1gQKh-3zVeSKz>FzM|f@DPVe1Rffw0pM8paZr5e!F^uCH&7oV1<>^kSEQ-@x1 zaHd|m{>7F3?PKhFU{Osk(-Kfyt%VSRzIJd`B#^4wkb*n@)LS@bBf9a@4h=gM?&-f* zxi#jvh7W#6WxvUJH#e^%VCOQ9U;uS2RTA!OZzqAWvc?y$=!paBCUBO-kZRKp6~Jez zk5$iAA5-$_M(mM8rwco^Hb@{svEL_~@zW7s%H142C$|dkn)|oQ;1tuXL7KjPc}tk1 z%8Quk5ByN7B=0^2O%JpD7oimKT(6X*^^WL|o;>6W4cnw|KMn6HSDX|hm5Y{Irv`uW z2^C5U`eQPhI<Wt7HcWI;q$D@?X;mw;9`}?joSJ95EDzf7zG~mkqFu0khu~SdI`&!o z{)D8s8MNCOi`S=>ACt7DV1*dRL2tY#c!eU1dzx$B`ykOk;lr456M7D3$>2zxdScjc z^dO_IDvBeVY9=E$*{RIqk@0XxB*@WGvsy;h>oif%CF^{)bHs0))B)gec2%TT20N@S zgIzyXyLRld3G1T=FW5lEcY3K^JeRl2EVhtb`$z?oY1=7tkx+dm(iHW0yX^7=?QD#C zGm^vG$sd8DP9)<b4)GP52MLFFDh<Trf3Dm)1Mj1mmya{`qaBp>qBCH|-_%Z?m;v_$ zLjl$Xy%f~?dN9vqP-pZ=s&&ly_>jHT4(Y%zV6WqKqY<ZSRf=WcASF@(tYG&U(aO(p z*4yB})}ni^P{H41%z3%Fz@Pua!=IjFenagv*o~nzC0M82>Ynfipg(`S)y)^|`x4M` zW|Xm9-&{|>z>B(TP!`kH169C&00;bQOa|s$DDUh(2H}$jNRWwl-sxLv3iahiaU>eP z(~M7$`|-Lm%jzL92azi5ZSwrp&ud!oW>s%=iF^zA2=Z(go`ncrE8TW8kJ2nQIrXs( z)$eL+`H{JP*FylOnRQ868@UG!t;1~OM&@eia5*Ap!#|72P`am2uq1W(mx>%*wgGY) z=U3jkMd8tzW;T9YxnM9Y;ZkVL|JUNQ0V#f$ZuV<;Cmcj9B2&6_&bFN9gle+6s8cIj zTVB`igWFbbb%B62qNJ}ID=9seMXK+~F?6$Ii%ZteC_B<q{ehcU>?n4$pPjSWW>9j| zwU>DXHS*bU>i%4#D$rt4vaftL-Q%FTh!X8~_<7i{LNsbG6m~aWm)7@wcaE($W#}uQ z$fFAW7Zw_?*Km1@I}NOFr9Q1BFJYMe7m;$AgbzQG=mN&L_UPs|D#8%OF-8Z&Bv2}G z)v{>44db~A3Huwy<xA!^lJWt^E&?seAxeQXu&>DctK!xN7;CY|qL?nCn>+bc?biku zn7s4}7k5>%Et;3%`Xed@hu&7$9G+{}1}P0!?e{y&>!U_0;%j%^H!AgbAUnG><LB)0 z-K`l3Q*;82Q}ui!nY{}gqMPkN^)ge!S;qPg`jke=<(@lS?{9^#52<xWNRtG=o$e*V z@a_<Ne)}Ej7K#pE%lS8#P2KHlzBk-Q5H&fY1ON(%ZNBuF!mPJ1CMu`<%D`>Lm<6BF z_px7QT0&F$jwuUGrK0D(rD78I4xjsA)yeyVL3bq8Q=@&{FKP4dX#)QCcT8O9HP+rj zgG1cT-ubw7`1b|3&b1JKJ9PW#2Du<Vy<a)$ixh{?10j#~n(Tkq17<4(<Q|4}T-1iq z!qZ>gt?7W{?y{i6?;L#xfN7!%3#V4K)SqwWQPySqek-DO2WqjCk{1nTWgo%+cI##R zOLYM_tOGRQk{e}Lah>{ywzTh)I6amER-vV5Y0|gkA^Ac;?N*^Mig}C1zOw1wrRjY1 z%c!cOO({~QFD$o>6^nJ3t7WXCy!y6tD}d&0057ySbIuxK$1Y}>YMT3M+t^T2WM5zR zTzuM{>riTzLUB&9mG}fk#bK6+m+W9NG^eL3Ad}t;>uWYm4~Ef`yKp%`nzXY{8*?8R zX8&otlK|A7u7q#Ib!XZ0=8(?IZY8N0&dQ(UCWc#@*{h}YRe%GmrDXZdI0xT7LSu~t zhzD?upgBv;nq>1+?!#d{vTD+o-g)n~t3ru81ptaYZ@1Qd1ZT{r_?b=RZz02VwtSq_ zkCLxx(*3!=1bf4V3Fwo<>F3xXi#Z^118t_lt=(W8GnV6TfP@8t(T48bnlXBiTH5?- zXLgk6FzD4(7{$u8MeNSPp1}34Kv*JR9B&m#N&53>3e>;9%&_D``LIpyzaUt!AATg( zbrPW);La@>&XOGUm$9GLWO$nLvDI677|(G>Q@O{uG=o0*XU28vE?as6iR`r!azirK zvq?&*%#ae?FLK*|@W>${8g|$6fCD6o1Zm21)DhfC^;3hR;Lm9KDS2MzRP8vku8uE0 zOOyp#RhM!bCJ*0o6~s1~Kmyw;T20bI@UrUQUTL{v(NB^UtZu>Cg|Qz*blAfDdK=S) zi_#{*O)fDoy=dnw{d`rznC&*PG}PNBvGTf1^t`WU6DfyraEgB2o<{)QtTh~1yL5It zNpLAIRfb0S#@t$Qr-4IBjED3@y>cc_s}`>Xd7K_oS;Aupm17Ox-XD+4#q6NNmuGUv z0WFQQm90`waG>_;W9nv$FZo)byTAAEAlN}Pmm%wJTEtnrULKsohm=+Adm2*SvlLSI zz`;HnTPzEtUv%=4?shVp%JHyoP24-&3w)Ls-J%xW9!0V%B;4ma+YZhz2bXq35+paH z4pcM)T9u~*9b$v1G&BX~2G04HI&`L;)IWEgJPIQ=3AaSXE>9-*rV(GY+G)r8*SCo( z40jn-p0gISv0O|9)!Kj)CB2t21sGOvCoHGS?b#1F39Pw<pZEP~1>d|7`6aPMCLVS` zra?2#o4l_EE-ergleM1`v4os>NmNYi4(Y2+Qi@|zk@sFEz1`3bm?w^S6b<^Zo9YqM zBwp$jLFAZlPQZsUk%M<PU}c9#dka*)D=mt=w!*en<uzhb9V9HEuQ>$M{W0r=ExXf` z_tr`>O4UW<38fu@EMkIe0GooG&uOwm&8*eGZc{DLALXwtJ}rl76a(Px(Tyop{QlvP zI+3E$*?}6*(XLT1jT926T2svK#nFH@pI7{<`jeZtwTXNVF)5qD{T)^IOZ6JwJ^T5x zo8<<KB<lS%+`z<<8kTGMc*-XgyO)e`;=`*6m^F}|8a=>QghnQg)o)R#>0cAz|2EDJ z2vRT$>aCt&_7Ruo*sO>%>^tu$WArmAORWH*NIrTjZ<NO_{})l@-LmhWhC&x>clP#J zzu|Rm;Ay?iaKNsR8?-!b7g3%mf4Qy8L%qgjeseg-j0|dJ7y5oF+i|Su%Vq%Lvg-7_ zd*#e!Gi-Ugvgp{Ic}P9k|2HuH?3Fp+UEdpn(<#|Z%!~{n7X@K8^AD9#DCt|Q+<zmV zEv<JDNurb>FlaT9lA`3dnLeVDNjYynmujs+;=F9^;gde9r_YUC66{V}JZ&}P+&xgy zn|xyX$1<5z;<)aVtI!26jm;zNEP!BKvOLzSQ3bNYJd?7`JX0qzeoBV4XnwR<ZtBxE z{t^}3Y-Ryi67=({2U@FTzu3q}>x67}oX#(s#y9K3O;Rc$;%iUJ3V^Y8b<q~cPRgP| zQPT#J&HT^uocr9JoO-#F6x2OoH^VhNz$4FFjtZvj?&o(`goaH3z1-I(i*TGHOBz{a zfi;gTE$=I0SZS}z`gy;8#U=tGhA5&JcXoW|-|0JA3cMPF0=E{WFIqk2Hv~fYk9RXH zM=ueJ9--LL<BZEuR`XH2jk))nzzOG%3!2SaFL(;&lj7wImAzX46~sB&RJ<VL`n|4F z9#~x6S}j85*sU;EG%S4Rc#kr?1H>M^hx$<$7<1}!Bux-~;M|nr)0gO0@zUEkbxo%; zvsR`v)8a1GOyL)<b)f~^Es5=w)4Omq3{s70#qYDDPE6}Wql*5c>^+PY8S7A;c68Fv zz>&9HMTxKf${0|odP^`fg0{6*83Ut>0uI-H7)-OR+cduQzOn!)ep-wvGClCymqaru zokZ8sou&?ZIlFbIETM2bvNQr90n{dXwlWo5opVR~#3{7?1h(p*;oU;2R>vFCO{*0= z8D&!bWJoE*Y(`PvrGLAI4_nhjOAJ@mx484s;PC;>C*tX-?|bGIV-m>ZU6_mA?n270 z`ff^NuAZZjCJT%2p&ZO^M|U<~uVG%>Y#e&eN>niHoBU`UIRqs3iT9;mENd#Ddihd2 zE_UkA&}Q*{o`>gY-kZV{K{cjS$deG)WZmA3jW~d_&Yfl)pSa6^5qz&f6!PG)-kKBw zFK|AquZrxCqV*}!rhO{DRFZ9>Issk5Lo)srnQu$NX7uF_x1K|d;nS){Evt}YMc4ch z&+1-dU9(nm0+1+(?v&`rntIc7IY%Mp_nT4I5HmA?-l59*+ZNS2`a*{=f6pxM&u<Uz za-FWftT$S^zBrjB1^SKRj9yj@%~<mx_NaBE_kv3`-@Qq$%d1_Dfl=8h-TKn+l|3k! z)5Tyvhh@Wx{VPYwAuV!bn#W-${=qG>bitCO7ZZLj>=|rhNO5)@0?N<H_+y2#mt)_4 z9>-U|8UgOt-^bYrpq!+v(WvW^6_J3E0b(lgw?!tRdU+sKiHZBOx<2r1IPSPNb6M0I zyZ)}iz7T2GFh1!Yx<aYl)I5jU-e@8k=)RvqtM+GOH+>Nx+t2ztUcK%Lh`ObFdVR0E zYsTKttsDQSg#<`>zNcZOE2I*B67@$T=2U*Tgse<;u%3F?viA6;r$biwS^R<cM69C- z9V`npEF$Tay+4sxJgxakLcQWe0LnpcH=sn4mPJ)E!B}FV{OJrHL1IAWDsaR#%V?zf zI!te;uW<`N&)S;TXB#efILn4IvRL{tpFdRSKPQ-WaqOxfm4)@>5+K+2$5k{Ku=c9Y zV6fN{Qdj7h9{l!wt&jI&Q!JpGTkqLx5I!}iu*5AM6bR&W1|OQw&aFz~FVd>g0{uKd z(820EFBu7Q$E}tnWX<N{?~bJ%a<>ks*-yTYlhaHc2-Q8zyYmdxh$uPGBLEz=yW#)S zN`FsqK5h)?cPs3&apk!!F;!AWSC?P|3;Ug7`RVuCK|n#UgU+=<`7hL$tI~hN$*CSe z8n@fy#m~Gis;X3Op0D3^sB~T=x4EFtMxy92vJ;ZISKmPB<dd)2x|w2B&Py_EQe&LA z#8Y@Zj^G8+@0K5W7k`@ws6lnK^PczK86V7&U$}{>dKZ3#?pkFFw4-hBzJqGdH%2Fa z5~sC7HS#V}7^802UvK`k0Cl+G7kz|MZrxeL+;7l^q{0^I(#$N~ip4YyU5o$V{pXmM z-=4%2u38Pp5kgd9Dl;#>e-#CCJ6X_60ttrj3yYwI%8s$+vy<yQ;!s_vq^LX(>=jG9 zOB)9YJjt@S$vjkX&xBvk=n+UhC)V(k_2_j!ocnpxjbbN)+MicD0oiLtW+j7Y0?umL z`45c`-dD@{ixUprrp%AWIuL$p__4jp(TW6Imt2QuYwCBB2$fxKV^N)m>AV<8XWWR8 z)vk(lZM68ZDGbXvAh;bc+~9ZWeO^(*elibIEZi~65EwqM`7U(2u{*>(z>ubIWP<!v zsoNP!T=}J6G^8`3_D-K!5A;#=$9GDUnYa!y<fRU8^q^?I|HjluQ~_*}fXDBlsKU$- za6o;H%%<A|iK;n4!G;k+b*yu@Ue1EK6Z(Sed*q$YXa0;x-JfsOOb2FZy>+kri|n;F z;hu_*1AGUBxkt0P>}}pSZ?rww2RkhVCe^n$j?MM4Cl(mf1D3B&Kh_?x9qe=^n_TI3 ztB~$gCm>&Q61?ljVgvvOUkpSkFICt3s0yZ^4+@vwIcNCPl9p$>!;IZcwfxU$8jgCb zca$H`4ciw4J&qRa*uY%@a@NuXNR`$aKV%cz_)UaVZhiXzLDDtCw<#d|-QpbS!Zy%+ zDoYIJ^wT&{)BAted(Wt*)~;Q6tB4|k1rg~sKtXzw4kDoRk^~7&rH3jZ^rE7oARy91 zRiq_AXd(2dNbe;eB_JY%7K(v{7Wkt3-R}2!&l$tbcg~+P#{R(=l*PSP=9>2`*SzMu zHzb9QI=CY3b})&zW~mo8`_04NO+E||`OcLwLI@;em9h{^37blNTu|)`{Bk;Ng0}N7 z%_PJZnKT7dgqJ4X$p7?c!?JQWoHsv7G~ayjtj{6PSZIj;Yu_qKy>tS)<EWFhc50eL z`|@XADHsLcelvBkc|(`nZ!Xt=tXIzZV~gUTPLrmcHZVIb$S``{^h9g@p~5-mw=Z!$ zL?+N|#VZ@(s+k*m(n5~%?ceH$R;{s4iL8NM9JmSlJgGYz3AZ-ozMDEk#lwa8wR>1P zaK(X60Q(*Mb-d5T=3sAC_(&=Zu2pkTN{*WLw@Q9XVBMs;PtRgy=hg=U6v4!<y=7CK zo89@lRGEt2*&1NX_V*Wwx5Rocp?G>0d^_r*a*=OGNhiKoI0WC*8r23l3G1!jz+PDa zQX&qXM!aTickojuYlc9vYi=1+vt1cMOl1{8#?#js<{qrgzoGgI!zdb6!R!vLaT3cx zsKM~`J6YEBn+wp(yA`0hAU|xmkH8pk7TGs@Jio3QJSw#nJC#JCxj<->_$)mzsL1&+ zPygm%qR(+o%XzuV+dSjkk~z=meW`+-{`QkhzikhA`2OhGb9W4ZLT3h5;*Q?{)8iu0 zrB<Is4#X#ZGQsIxite)cV6!dTnv;0nFA=69buhPycM^K|9KI*DBy}`N;MKi~$-N_f z?jG+M2G4cQwR4dit<#zd;R`RE4Smws2i9fmYlY&gFv2)3E&%~Qo|x2hq0Hz-D?Z@c zg+8hc&RlvZK3&hceEw3cPr1Jk1fH>7mkt}PGqx*K>E&N{t{7Ik1Fc`_m@f4-zM^G_ zgO{mSC>I-zq`gY5D&F)5R1J(*+`OpYQ~Z!RwwH-8`XJh!mD9PzN*ZCPrVX^9!EbAU zfW@8kr`y|_hcv^i#x99+yFhsxgEem^gj9hR`t6?NUF6V4b@FQaM9W!zwi)TBy1Sd+ zfLADA3mDnvC<CL5K**i!Bhl#M5LVgVFO<6cFPOSx86h2{huzI)v4Zv@@td)!f6zKb zM6`NZAm>-@V-<Hkr58+HEqj23JEwu5Fy@FroBAFoWc@2^dieA4`NCu+kMS_uuEKV^ zx2I;ie3bo{NzS$oHJnX?$h-vh{@mMl4m}7ZNqRMVlr-Cvkl3oJbz6;3w$|8K1mEc+ z53;c>;}%|<u}e>cclVqieu3SbUn)co^`jodOu-2S@{)=R&x%?4D)X(#jjvf7(l*P2 zonieWHEZ(sPGo(ILKnz<*Ykx&k5O*MIz)|8<aZZjyLpE{Xkq3m2=nXhr`ZWIQ(R-U zPLYe@Rn4zzY{|$qe~E)d!_X~VhVEYI*PGozM%7A6>aIGbN7l_`psx*{?(C*5RNE~K z4e8X7p7L}{^Hufv)_^u9{IB3c{{$vu*0w)doujx_Kdiww^?{WF`VXaCo>^<$Xd(6G z-6H0f&L>}`q^!8qC2rkR_0ID_!mze<Rh`*eT-Hr>vFrf!$PaRvdr(m1J<J4gYx-s3 z>!`IY0E0JSn)M&3`P_N2%uIwp+`H(fsQ%`UY-i!U;b8D4LJ}Ax_Vz;)m`Mh#qJ&zE zDGVt0M;JUW+37Qrm`n>TEo(&lF{7+KcpMUclc0?s%flyZMsva?6C~}$_Ey|LIuY1X z^}!$vF1_rA`XQ3az4iX15-$gd^_}iD&<>j?njPzRgq~xEuZ`B18QfRe{gC<!#8c<L z%eAU}PxeBmf=pX_hL83|%T950WEOaO5~fgYg`@{UK{b&&{ZV?Q&3S*=uQ%?>Apr;# zbD^pGqid(?^;6HYKGr*Ir@*}Q%2l*N8+GclM=E&TXj)-WD}FnfqTLT2wYAm>Gdj?3 z_CU2wFsEf_GnV-9oh14d)uKmnjvmkUpfIUQ1SnqiwG6g3JM~esbo9oqX(Rnmc$&)I zNCZ{t0uemyodFVGdRe1}b7OjqGC14{jTZ2+Oecl<)sB>{+3eNm=`6n2_gm5md)Iu< zr>hzCw95>9xb)*uL-`E8wR58zYdmv1b)00un!u7V0E@T%D%CZeS6eWrbpRUGx^&2X zeQ@A@R=e%UA~=~#yx9P?IN<T+4U2rY8HY&iC4)+_iwABd{xu7LCpOJIJyzWvtW~)C zuHo_E!s+}<mxK;fezA)7p3Re2I|t{KRNUiSYshmlxrw*1M-#vxD4#sP!nKhH9*K*^ zh)-MR!kR#>I7WNB)QAFmXh!rWW(56Z&ta+L^*O=9Gf7KLnYHKI{^~cS7ZcJZODA|r zBWzrnn_T-w(t^?$5;SRrA=CDfJ#$gLuB#JAwZVF4l|;T<kWxje<2?$mUP#7j3th-< z(i+`$EnU#k^c^?56_N<~?6*6{ZVczq(cp5{RM@nJ@XZ`4|5^pzdD#d3YT3FHO!m|~ z`T4WT%w|KCvb`wM<TQ6{P=EG4Ai>|Q+y);Y<%Ykq-GP|Of2J+<zJ3FaO(>kuwjyQu zbEl+KM>X2$l{(eH#@nr&o!)^V1gp!VgH>-nJPbZ{FFyFxhrQiq#Fc9O=CE{it*3TN zwRv14X!B+BF(|}S*q=LEzrO-WU1p3>9D?!oEEuR?Lm#-1jKq~@eOM&Ql^0rhSIFI) zFy_|L>9@HW;D){0RF@K*8W6I6Yf7drtToTp8RM(jqiot;_<|qVoeN@7$fW2nY4Y85 zSeFm^R$4_H&;!ettuKx{-pZkd<D#SlMTt&vO!_bhl7Emf@+0S<#}zn*`zm*phaG6- zT!YPlY_MO2)aJ90f0DQ9JUVa~7-oEV*Bj$ikGBascW7BCzO>{5=J6N9BHwf6Y0oLz z-R{-WuTK}NGk>5wz3k=oLSRK~7O(p$d)qXvk9347h3;T=y~I^+VveeR&HX;Vix&<s zeSO-TbfNYU`SJxNOYT0-EAg*Yyqxo7E>BmZ`m3@Y$ym>R2kVssg<g<bl26wKzLh<1 z?#P)t8Cd5|(S8wC_hy^@^Dd^FC8S4nVB0@iJv7s9dYYV7e53|zf3k%s6dW{UGjr3T z+r+=)<tmTlq4`jlqPLfJW&yxoLAq748qfwMhOu;l<@`*?+gd@^rv?1iQb&XzC>Wf5 zWsE*{cw4!z16ravZqm+*g$-`8WQDCLc8OaI=->VXQ}iOw`u6m4_E5n&&H7t$8LyV^ z=oT#AbJVROfWH*j7B@ZZx3b0tz!tp~D0Gir@hoH;zh5CDhhsLY#xHrz`dzqQebe7y zO*`*eL9^#X%Kc@@h3n-aB!6oo84y!i<LSE75p!%-YZf37k4)2JN%h@{R+0`x(XJxR zz4v|>Y;(kKNLk0~NcFn>UFsbQa&!4!?NDSU%uRMF|Fl3g-(a>iphw(_M~2*e^>e*R zfNlz_XWitQNpXI`!GDl#Se`srp@#GM@EG`G{6qc0T{Yl@nZf3#Pu-YSIMJ2tk3UJg zx=b(hC!m~p{y^DR|GSIF&0y*<wRUlqf8ZxtSbe)gs6!!Czi-|d>6d7CQ5U^?7>He6 zM3TcF#~`P582Op0+S?ZDsPf&>dwyuYjM@>`#M|+&X9?eUmDz~U+xCC9`+tc$=7?L! zDzVx$Tp9YF*4cf#nK#xsV~yg|Uf?l-t21!2He>$>Pn5}c62R?c%yILNNBw%4lw1w~ zUas~r!rpgqm49XG)(Ynjx!t|aP##Rkm{ur!;GTFRu^n%ndf^kG?pm$-Z=rR4E!sSV z+$k%&6xuR|hfkL%eMj#>&kx)CChSa27;p@bxBKrb8(<*5WJmwr2wGfvcIc%JmT>sb zXK&E>(vyH{g%VrmC%iMduEcKo?4GE)eBHwTmdZcqzI<l<Fmv8;zE9@h(Nvj(FIbfN zob6l=@}1^T;+n_uy`$VjT`o8H(0hS_IZPx?CLo3B=OC7Ix{p4Ma(h-%lRlyIAm;)6 z@x0huEqTm2Vy?fR(9vK{yXDHb%G$oivYacSO?1#&EXtbt2T1IHT=IT}Hqb@BmU5!* z_b=psNKLbVHYej$&BE;U-z&?1vR1@ue@rb|rm8Rhk0pQm<D*kTv@sH&mgME5{&UIS zPr*3uPE)6bfW01t-xvG;bI0HPbd09yB{fk|KepX}i0^klHkf}=3K`6p#B2D6{qEZT zWnr<?G%-bes?*H)2R`RNMEB?vZ8QjsZt-&U^ZnlS<xQHHE<Hf?I_z6abVq4oI-u}E zWZxrjE*a4@|JIoE8vB1r{<k*b<hcVsH2=N++lc=~e7|{D?{A%<Y5r*nN08?4Z}Xpn zQZyg_(EQ@q*^B$rhNI{IeWkyb^}nz5H=0Y^(l2j5GC2!S+8sP4=f9S>^L17<d%?7s zFTL;Bv#waiy{#LYD;tb<V;WP_i<Ib_np-dTYX;80x++$#hMThNTdB+a_CjIsmii1F zT8rAzO)CJC{qmE=_?x+Om0jt^A+P3G&bCY*a50=-dn&Pv7&ev+2!E+U={QinCL#*I zei246NXUKZR<PGAo@^@q7}NUstku3O#E#vu<3@(-@1)$fpIN}1gZ6;AsMmETaJTvV zaH-D(LVWs2!^sYiJn=8dQUw#KE~6rBfu3`j>kr75oYM=K&IIvGE$8c2mDO<mOb8K0 z?ofn)L0juh|8@<pv2?l9l;jeIe^TlH+Xk$#o!g;JB+^N*loJ%f60jfd=N92{g0dFc zVCi<^w^L>wA8ZY>N6?}?v7B!&<sKxoW^n+hH6Iue{E_zU<OC*(>7AIVyOeEF{ycx< ziXp4>I+W^5)icfkcI}bzOLSJhj}`u#wWEb6p_~A{+6(KZfL8b*m-1E;8J&TQiH@!@ z)WlkcK3PtUv!>2J=Nhju0lE7sH{ZCpF3J=Cw6_czyvw%v!Re$67d#Uo&2d(H%6wfS z_%d*A;LGZ1CY}_n4|8Tlz)*xNgx0H8+8vx}BqPGJ$L4pgtoOg&|98Bh_j4j*&uOak z{U-6cnG-<UYekR^6@O&;&XxF0gvD-=4o8KuAmdW-fLX_ek~z7)-bir5U3W_-#1Bpn z9NPVo2YR}Gf-fUbE93N@m2-1O+>|9Yu8FOp{dLVkkk*aPL*Q)a>QO{re*E*HR9;r7 z^B^`*cg9lcqhQ0<5)<^I8qg$kXrIsPsD^7uNoZM9=<t7aySiF{(+&rGYO15S=^uKn z%H<IuhU~2qA*(%fsLX&uHQFGj<*4D_BA=%(z9#w%we{(RNiLp+R8|GsK20%5kBepS zk?bl*FlTtH&;bo<EZgY!^Md{8=mqlp1F^civIY`ak6|frJ6t^5j9J~D)^79@R2<PY zz^<)ow|%Ekk1r3h_+2EQmnB}h>CA#%@0+2Q(|!tPevJFN5ihfkDB{tipx70f3?{(m z`}a&k9XN&d2#lqaLBa0w`{P`}7DDCY#KIo`_SnwSEyUMQRAYh9r;Y^{faRV|5MZY= z#^h<g=&P{_kGa(hMZqciLh@ogZbD8FqpLhB87aG5|DMd*+|svPMNOg>Y7Sq=t{~c% zUjLJRroT7gxut`LP9V1E_%;62TV=6_ofKqWwQrV}lGtef>?&sbm37(~hWUZYU4`AZ z;^W=cD%Y4Ix2HYY)#ToiKq6M6$f7px@CAr-0`<tA9zjJAt2iDD5xP7j0BZe)O}V@$ zEN|7d*zBFAIL@cVjJ=2|=Z=vbzm5ocFuJ?4Y4dH7BoepU8{Pg6q0LST?&hy_5B9N0 zR1o>_(2dw?YCA2!_MH8M71{}Ptw7QI>-+@<+{TwMyN;@$Bc@@H6nxY+mZKvRQHwio z!+&k1AaCZ8=5Xm}{E)!J(rfEoO-rx6MwW{NORqPnu1oDx?k&4@+u0@AW>H*08v2@h zYBIro72i%Pj>B$RIVoT33}bHRMC}>(1+49?8q4WZrr+I`sK2k<HLa8uAKRDhddKGT zZtred&>OPoP+J{i`zj`?<wH)WXU}|qzsrljjkmXr<@~}20H$ZhK$`vX30`C9`io&H zDbp)R)a-*8_>_y1NEb>sYV<|C=j6G)F8I<1Nm^5}k8UC^0FNFRLu(8U23s_HSqRLB zIHU`(r5n8e%=+~oAfUfIlbGjWdM<#{_#M$HWlYm0vF%57r4JrtJAhZ+*G^6PSn%n{ za(lC-)mufmra92<>9?6=)T_>e@n(HMjS1yz(ZRP5J<y!ibS@g^uo`oG!j{Gty|Z%F zObOe?vg4&p+AWGhrwq0;nN}aTwM<}N9#_6-pjZh8xrtrMW+&O!rUeaY`mIz9kDtt@ zXUF`o$&nAOo9++0m(|vm9UqnnFpVYQGijxbgZ;_dTP-<<B{rFTR652pZ6=}BywcA% zchoWMuTcR)8`{j+sX`{>J>22%j%wR)jX^4#nPZ+n-sXnZhSD#O=h9a(<VG7$^#PTg zxlA6FYU}yE2Uco9RnyMq@0PaUFCR>oe<PV&lHG#<GkBwA(wpvg-371NcIVFK%TJ6F zbbT`TB>8c-rb>h*#z%FV6l*npA5{IfeZz3@5Hn(FZ{91J^6C^nu5i3>gim_>V-6M5 z)Al-@x9ngJ>v*kELyG1(7&W@acKisXeJ$MYD-l>4-?8$x<pI;DsD9M~2jL)Wm0uRu zcJ3HXrjR}gqsTW^l($eLjFrnl#b=qjpTrc|k}I}^XOa^xIm*S2E}Dh#y3<SNZF!TG zyT^vKDsZje%rmqpf}4J~c&J_g5a&I@+HtdB0lU2^+4kBR$%BP+hrib*)q~*~wHhKF zto3UQBZGUhN!JQm&<|TCY1O~2!sr>Z{0S{s-^P|8dj=AMDr;G7DD@xnx>^BqUZt6B zC18XkJ`MP7m*!Y_Mz6$I$tqFa20s3!bH9(Y&Wjb$(Vqj*8W}e24qprN3@B?zSqLdM z9p4C>D{T_>&9hupWLECwGq@Jj*7jJ?#@=0P+I7@!IWgBZ<gVUa-xu2fm1_%FRr0{_ zL|=FYDXp!LnwQ5>m}ny^A|==}FaOLlrA+q1a@>dGh;)~r8zLKP+TC0873emELDh@7 zj`!b$Ijvr`q9*tl>zCM^26J+d6QJhhcT$1tf@ZHywUG;oyJa~}E9G1;!v0|&qlTMl zPHX{E89GLSEcgoDajoYJW=CgtmYH?%8vTutYaAJ@8=mVvQEkGpvEmE60017z3S>Z> zectJ^A0H|9vpRRkl~Jl^Mp@VLa#{Fvk6VDZq4dxeM7hjRP?Y1+l*+navaB4t)z}_R zoL0wxzTn88DA%?JL??<bV@^L6nBFM4)VGr6-qP2h)v%BYOOZP6m(BT1x5C>ZJ&!w) z`(fnx#f3emblrTfk-@=<Uh>5CYuzrDIw1G9<GPT{Vx2=z^F??zCrO@bK3g+&S<**q ztP;*emtgG8HdKb%7h8tCQ^*&Wc?HT;rs*t+S0%hgQ(dr0AxA{>{4LUrm#bgCe_*fC z*O3Y7s@KmD#@uXfA7<-%Row_AyJ%Gi_d*Jk;{n8=YE=k-@SQGYljew}?xLX+?Onn? zt!+%n+a@V(h(7qd#wj&i5pPk<?9Nuf(vVWI#*C%h?WT;B<ImF-SD)>SjuR!82c^wO z;m-<c0@VlQnu;p!MxwHz&fgkrx)LM{UoEu8dVa&vo9&&@`IcXBw-ThGga8^97I6(t zIV>B=u`8NrVku0?n9rP7iY#iuAWLy&CATRFFr+Byq66VrpS?Si$$zB(ze}Q@<-dRU z7$GoP(SA6?Vt!c4pwYNnKz%g_l{xQXhINkb*i2b%y_?p17+c@&FsQxojMEbYS1cOc zmcv`Q@AMGFY4p`Ms9M*E+LdVzcbG|*3g~>rBvPmRey#vHg>Y)ty=7h;n66cZ+Ix`L z!AWo$Alcu-4437696zrABal}KE;E4ja`?S*jR2%Akh5twh7=b26XSs#hTe%K*4*w1 zho_3Z)0Gy^mF*F{hdmbJQn$;Is|+uKyExm*6U@;Ic>|X4<FVjnV#W<xJRjZinvp+3 zRzktN0^<^Qm7ox5x1$_<XRsqpWS#w9U&nbAdf>l8kuJwfeq6ov)jQ6Ev88*D_#~DW zW<GavgF|+s#7k{sYmT{3-}RA4?MtAV_3z(5MrhHDo6mUW{0J{sJSV^Hla*&3R}Bo; zCD%FREt4*J&0|tA{!T?A+fS9;{YuS1*06j2F^hg@=PykxP<c1gt+cJZq+60^58AZ3 zSh{8Hc|N7*>@Q>@%H*1we2SnI6byJ0FBO72p^e5Fko1f3K6U2<mT!U7VbyU8dDVti zj)jSWxn6~3s`HddJssOE?r}%Q$Y%hI<1I8QV@k#EMra26J=`o<ZtE-4S2^utV;RGv zhF3?;DQ$6FK?W3qLq#wSk03!MHS25R7cEZ=oHNmf*o`oj3ii7NZYFiqUopKUjrP3} z+D`}w?cc@Olr>N07k+ec5fR--V0nP<nZ@0nP((10Bg{>xRNcK5<}|xjSj}|-n3m;? zrN2S&s|N0U6*oIay!0{=e1GpyKidDDk*V|)t;es{Pyjf@8S~z;jw|57y{@*DxhUJG ztVhK2<Uft3jz7C-wQ(3IeP1xXx1K}pT9_mv)IYHYg3v<45dsW?ueraMCm`a4g#)tr zO{I<T0?6)+#e54P&j=|j8Z2^crFV^K@4Dt$mld)HH9D%b_Lxnr9Wfwg(I#JK@Z}5b zy551sBjmQG#`vbVG0|w*!S>4TLUH?+Jo=q2lEh3YUlZY?wDqWvx!bh@>LrfZv_*!s zK}U@*!p2T6Ilv&;b|l-6h!=SwZyx+l7)-x>`gJ@Vy;5HFZZpSwPQvXRrZ;BZvz_4N z<t$vJl~-Lc`0bF&y#6ZEV=fp@6-0i|r~hs>q?%4@+4ywZZ))9Id(2G2BmE`z$|dQ! zK>MApqIx-B+I-^)dmDvgL36wSVXwI{QXxJY7$n+BCNm<ofL7Ax<b|n^Op(TWRjV^D zo7UThRe2rbgd-wljxiwWv(@?->|X&6Rmm?QQXeE@*|wa#dvFC018r02_1xD%QTQJL zMG(*#HW;w;+-2{>J%)OfE2oEgRdS5&4QOnYbkXf3zP$NAzW=Nc{Q8`KhbaHM@2*pS zNCAw=2ZAik97|m@Gl$>E#ysuY0M)(hHX(ZMnW8Vwt7~cubQdJraF&0ZR}f&F?Me2W zS%%xGH3DfPS<)=2eH&sEI!tJu<*jU~`eKcQG1n&!L_2!XJo$nOx#>x^gPmG9f<ym; z?Xo)Zoka5ri4jp0Ql&Fv8CNq++d+V)POxjoE2F0a8<#0M+_`A5h8IfVFMnUja_lI= zJ18XbCR@rn09Jst66Iw+BjKje6}bGs?`wEoffS+_exdizq$*Jyk%gR|jlkUU{x(GP zUPYBgo0Xkt#5AAYha3LmV1wD+yK1<K+;5K!2K_3Q2cC7&_EZqCWi4Q>(&5n7W={7* zw;SI!M%`ODwW3;tT*Ibkk*Jm!b@yB9$Wuw3U<$2<RF+l>!bLL#xj}hdnQ4>E>{kV= z?ycU)Pkwdj4SZgU_M3<2?a5P%?!D*N=4;g)v7K%k&ElnZLswh9n6%u}1m;E>4$}dt zg6SN><mKs3^LGmw5U=4yu|mhBiuU9EWOpWZ9lPj8lYp+4S>}I2eEr+_J_FoURRj73 zV0BSR0`>!?Gmq-FZjstP%$3tCoWMR9a~1MP2WWPRy)~F6nn#vC2%ed0!t*~9%!3QL z_<R%SZYP<i$4IBtMgwF6;<ndUm=QB0Gh?Gu)K8*$)!wGav6D*X`jBGTJp+rcFEUf9 z!IAzm`RUFTF{}Wz;GDAC6OGPf6V!IuO9M&IZwfGp&6(V>=q*+NPR31o#KU}H59y_{ z1--WJfL31cQ;i;O+>9FDEeNyw`xE?w@1BMJa33#ZZPzz}U;XX|9RLb4;#V%EoNf80 z@KP&g;qj<>jjgsk63*?9?Clv%sC|Q3v^z#LsNXCd9K~HjqH45xq<PBH-Th)X%r=tg z{pJH^EE*K@;OI{KAx2*!8=#N|zM0*LDUt-M3O((9%_^T}g#zlaRRi^c;QmujamKJZ zxsRr;y+!hJqYmSNv86-!jBrHmb=q9=1AU8A?wOAWflGnU_7gX+EFC+3Ef1n3veU$9 zn=fE-wX`H#XE%hrbVNC-`u+BX>7*S}>8PjAiv(x672^XeJc|CF=~q22pLIHkev^8c z9CaqWS*B6wjlZkmg)eGg^pmZ}?+9uQ3)&yKrPoh6%8AV}Fex{iS%FN-FLT{O;6!+2 zR7)0Emo__>x|TY+7VTf_J!_?%Y@$=DKuVd&ptx7)^H1#LczaJC8b!YW!xqvO&@xHQ zMHmI1nk84P-Doi!`MvRIU2|TwT4zx_xOtf3Yhj0LFJF9I)p|(F2U#B&Gj__nrb`<q zQrMf3CTEbFkO*-b&WCT0OT@?Bnbc+35r)x+<cj6V58G6P$wn=^!wk`$dZ;Z^(U#Gv zH-(Y*tR~Hn$^)Q#>&PA!KxYwQ_7&X0w6)3#;_W!p&&J~B1_ma}IxY+)c2rb;6#ydb zrVpBgQJ_W&GxML4;g7N3ogB0emV5}fd3!&_nMe67SH$ulZ{ufTW=Lt#QnEpXRfX0{ zLx8iN7mQ#QfFckf{9QV$Slt_pe%VC_{5c^{GX4%?OD}l|H;y*9)G@x$-!a2b|DAl* z$Ou;E?_LFF)V(fEFdcisO1Rz-9?J@d&++b%(~9$HHs=N~o&L1;Or6wmyQ_CAm1UUV z`7jgV05fIrj>KCgmf=>3D|1udc^cjF*{!8*637(|;Ru_zM*q+a{B#XT6$cL=0j_@+ z0cIEp5UO*H$!)n)lo!jy!PE%2<&nWL+k?eIX$S7O&k6^yYMUO;mrY-pw59*PqbTA$ zw1Q`{Q4twu0d=s1uf@fGj||doUJT>9J8I4YU@Cs?5SSr%qT44uEPft8ggPv6<lNor z=dxZz2I!F_1C(i*H?L#w*i=6g>)OYf#}6XNP4IXDFww1>uFzaGzptp2BR*N_$o2`u zTq`$12m@lQpbbVgdyJ@Hn%GB_^yn+g6~(-HQj14K{!9)xKR`a@@%;xdYdNh>>QciH zk!!Ft{B*M>?ekgR=~wpf%Cwx07+u871Qc#jeDeE}bD@jtwNh_BlBHcal3@sK=4i;; zH$ij(?W8q^<4u%x_}!^vLl-Oq?jzEOBj5IB-h0QV_s@Qo^;5&;bCqQ^O!?0-S<Rdn zjY4{6d{j420isJ4>I4i`Ju6MKc^`B;OvAb7t+{u`c!H|crxVL_M$uNjASlyGz&hj8 zBXSdxOwBmVy}}CKD@Lu?pyNCuzy|o)P6Iw8rF-_!y95()Tv|f@g$W_|%CTkWG_`{s z9u~+{wy%=`&X*pHJqeJW)Xl&d6rPfus4*9gn28ElN!Lm>mj;wWd>u>%5%0!(%rn1? zPpV0$g9?dJ>C$7;nPff^m$@f)jWLKhDRV)Q#cTbUXedfV!Pm47;l2cwQuI>;>P;qb zbMp-8pn!Ct2oBs#L>t;01$CS<1LA7nh!+o>n?0gu6eNe#9wYeAEHQXk59U*ShOQbm zjX0pK34}&>WvM9Kvu(F)Kq`NjNuxX|*-~c4At4jd@G@~9-d#0@L08)l_eqjAv{uzJ z27M4=hYMVO$bh70d<dQn<8d{`851D6gP{ENl6%r=Q@Ug`bAfXJX)S+Vs2eCc@IH3F z>zvSc0*j)>NcQJvV5GXT8t`gMI3g>c8d%@6`P>gF!{UjbNI&`>yli1TBfby`MOfS$ z?Gn)2vy3+L;TE^E@y49qNwXH~V^2M9Wm5c_1#E-^a0k@tvFeQABa^<YjW@$jBWJ69 zDkq2%lT-4h8=n^`j3M;L5ZdFf$_L7wR0|`TcV8064GT3Ej&O6k^er7Kggb){>IX-{ z&%0DP@J%HY2H*nKAj7~K$3Y)#v47{Y;Pq>T9U}ST&K+3R6ZSFzpv2C_eIbbt-%GJ2 zy`!;i#gNj2KTL#wW`*8#AFSF27AojKV0aW2l}G79gG+jI=~?LT?vFFavjlhmzygD8 z)^%^T{t0sobKcxzt~c0*oahBk^!-@LMFMm0)>BcS>y1cr&nFzwP0|}*hzP56)+f4a zSGwEMv}_<5mTxM&y7dayi-OApUA)D5jP8avEjr$_5TzEpJqL&{ag!VzXNUAfDG9@u zeXN>o=IhqAyQ}UW*rZQ9L}OO2XOnZR@T<dz1#gGxbDKQy0@PsfMH)g1T%4WNMY74~ z=d>xC5?fwjZK6)F__FbGH}Q;!2&xL(r9*f)_PT;Cu?*sZ7_`KIkZxI1lI7(l4GRl9 z+e>o{oc|yO`TLTb*!SNK13UAk8b+lFmm;g0t?`+#2xl+vO^dYa?Vt1~o-cffP#>Y* zL5);w&;eMarIUdg=2TNw;kz0@<ot)41z=F9K@BS!;#zCLi?}9Bm74OO&J5nEbA?z< z5V=zrhKUnjeAlYGwR2lTAp`!23=8SXrgrv=s|`n_*Om{>S5{d@wWR0n!lf-C`N~Fc z>IGl|N7-7U?7NgPU_N|ag7iI;Il&smjj23TZz3_{mC;1GKSBrWEZzYfM{Ajv)oL)| z7y-)LpT1RnU#3Fphq;fT+Xvx5%^F4IOL(1HC?aQeHoen+9gp^ok6Mn0R68Xj_I6z2 z(;U0vH-tELCq?k})tv;cb~M<%h}0%!(wj-{79AYUP0asxy{vDM6zab*&N{zhcDrh_ z=l~0xe4@f0<>GuIv$R_Cg(T%}wmh#>>uNGahs6CmFy?Q;(`ZieM|EknHV%)Sr^?dl zrpq;@^BZdL0hKXC+iMFge|6ZDd5mOHy*XR{cvZDcQBELcJIpbxLIweu_MW)JUtRLO zB6!_;%8FXL++>V%Z!@t$GxUxxAMNE2*Y8Xstz9G(&7A?D=}&QfE(mW7KG2)0?nTTK zN2ZetEWV5+1WQI`B48aYSwuLtTsUaM*V;?D${IG^^`$K9S=J?p^>u640PfKyl7vES z8q8&}R|a@(y~rTtDhRntwM2CE*6GUauXcIU@@`)!;>7`8p1v7QQ%7P#p!3t2+!D}f zq6JW)Y3e;A6M}zRtP%~xnMG@KPbid8N?{zID|Ja7;mC2(eiRN`em}y;pi7vwlf!q` zzpm6N=4>IQ8s~OSOz44qp&|Qdc3*gPDzHs94}MK~)20g_X%X=81fu%Tr}~^K`IHgm zYLtOc7jMYPn(6Ta(xPo}6$kUF;|OqA6M1dE?Ws^8NCyT=rB<sc85Ei56}>`O?l|h! zVJz}lQ)&rsEk7*>G`QA*eL4?LcP7EBM;%PB_;geZ7Q7v63`YdNci9iADku5<03Fce zXjVfFZd(;I=(fn*VO#@AD?+&&PCNN!xy@~P<H3dU&Ea`z21)T3yN`OiRG%hY<dKXP zpC~mG8YC<`Puq1us+J%)K%D#uN|2IN56!}V#-}^jwYAOjOADihve`Oxo^4x=7dA<r zy&9l22qs-w7r|=frv&@B&jBZvF1Ri)Ln%`dWpC&4!$JuAaNWivNpv)|O*C(0eIOV| zpSoRQ?vdDH)hd~rzb&?0la<90xOmTX*T1Zq)KLh?pBXJO#lHr3wpR&yAhsCjfGk=~ zHY4kIG4iGr)7FiZZ$U)oqM>Ov)0q=7_K`9bK8e*e^0*4Vg|Rk4)3U%ca6(Eqaq(e> z5(@|q3&B(<?H;0Te5fxdb`51fRM4Vki5cO2ux`Y-59dhb!Rh5VOc$SCP}<&krAdy4 zNCjW6bDnu&Czuj|Xd`st@}b(&QyXhVn3+Z+Cn=e?F?V#sthQZCPq^O_pav(;q{|ra z)eGg#EJFgNa@Z)m143cUSB<6=Ch}wTui?gqq0|LQwU#%$)H_G4CD(Z<`tfO2MSf+? z+VV5Y>f?1LVl%Zw*50m-**vSA>E~9PFo;{{XZ<ZDsD8JIiPPNm8JD+ez%aWVJ7_xh z^}Ns-MV-K85;=`;rdB!w)fan+{ucLol@&N+k}5j?rTqx3MgD~zesJivT`s))sa!N; zfwCFr-oC0pS7aV}JVrF;H2I!Pa(Q(7C_>*mF>hZH*dLE>(CBGr1zT2+>OOlYkO$5m zucLwu<=Nv+j_l(F(JC<Rku*9LrYQ|{%7c-M2S9bg%|l&WL+)cax{@Y8f7IDeu5*Ac zCy}<=oV4{?#dEr^S>loP;_8xKh9@SfZ*-c|b7vued%GgQ*Cw!}mDBq&&D9Ji0cmcM znjsOIcO7-=5FmviLl|?RM!*Rv<eD!*#%h1$K(RX7d2#xv&9@kh%VOndGoVmSkk&w{ z>zz&@U;Xyy{qgqRd;K^<%+fwQ_-vYL5i8Ifb3AYEtDlCf75$U_<m?`cv=6C7o=H8W zb@Q&*gou)&SV3jf?5)6@w%u<o!j&HN+7370g?b&@kL3P%bnu6w9BrB0N9_AwPrXZ{ zE>JB$@Bd^p!%UhM96TV$wXY}raq)X=TE2>9G~Y+M_FwlnMk5r0&z}$5pCbGyL2l5f z)ayR?g!Z>@XyR0TL=zAr-8YZ@?U5fbM+lAQxhvwbFRSr0`@UlMFcb3VA=kbcxaYr! zsv6=Zo)+$34-V59xWXr2HSGVT?9g;?tEQNB-+GX#N)yoGgP!|lH$Qxc{X-2H!d9^_ zlG{%f)tM`*hG<n)X0838AwOTr3fuX-`Q?wGee1!$oAY;@?%&P%8wvfpIsbbO_rKY? z|8CCTn5BO`=Wj@~|9Z~f#0>whdCnLng!0}FX;;bq@1XC!_yv!xx!f=b{UQbRdpW26 z+B7t*+rmfF8!~(DFGFkyp#A17&P(FluWP;^yk{9g|MYww2O!+@Z(+ST_5?PmYbZV7 zlr8@2TF)QrxoOXy{Iy=(kM*X@C9eFsru64}ho1);N<;3d-MjjC`;wUW0fp-vgRo5e z_zQtF#S&)dnZMR~_`dv%?{rW5i{P*zJUb|$-_v+j>aRZ<J~>FHHWwEiYH&jx&3$>{ z7YDi@d>%0rN(ancchVsI72(lJAV;@94!cEXLRQmsULO4`erpj>HI&X^-u~O<^6R{> z-@9c9E4`V2<gcq#&u6H99?IC<`Z`7%&XE7X`LECQ$0Llz`9(&D8l}ew_sxO+zyAS1 z3-{i5_WzQxN5`?x6kY}dPg(9ChkgZQH&~BuZ%NL6If|f<f6MjPM|-Gx<={Q*>!ZX| z046(sC%V5@eg2Y`g|z4%=Kgg`dpP*#!=m$YlRx|tK+LJ1i@v7~!~1v9|F>kyB*XUd zuUP;;bJl+~;opt$uO0Z;4F2l{{&j*sk(qyEfPX`ve<Q$u1K>Y1kbmR<AGsPW{i$-K zr=(2mXm%@a7o-O)$x#U*ySY|=)2wym5odX?*;ijzE5}!(d@k>rg29O4G6(1JT0cZy zp5YyWPp>L(#34C2$J*-Q<G~X1S28!R%9WpMj$?xP0@Ov1JKKKKh~&{<N~H}avxBw+ zf=3kNJKB`r6Y7YzM8R)d-}ASG@qmIUe;p&IvC}_NuRM7*T&8i{-_`n~8h<5;Z*)Z? ze}OYGv@#n<a(?EezY=U!BSu=1*l_IoQ@oXt!MM0Yr9--(CLWLX-<S-us|zM|$~G%~ zr_@vGs#iWT0!>YGqeFJ4UWhGJ3SFIjSm}>S&0?jpAm7<HJoHcKO8NYu(F+iGi$=pL zS6WFD1VV?05j%I|MW_SWh*YHpN{b~Y0*DC~D?w3TP$AbFu&K)*UPRglo2G2yUtjA* z3*?LpSLqleDvi2d15V}Gx(m#lCdNc9jb?Z5ea^2C4)Rj~SCwlN4vF+X?$_RF=l)#O z2jz&}Mkt{7cI6`}$G@XC3diSneURt6A7Q{7cidEdX6Dh;Wv@$qm9<Wt`71N0GoY{j zRbbS8LrZqAe#(aYookmr4BCsygutJ$ojO(A)!7}i1RW`{(W=&R57{1F-=$zxO0?&< z$0^Ebo^4m<C!esa75UT&8O_Z0W^r(H<3vL?b*PIDDmn$V)ehY}b-P;&bMgi8pwZD$ zSR<?HJB%Kck!7R0iH@B&^^OjWJK?4kHlSFejc2g|km?RW%;LB=VBL|{=iG<zt{m5| zn}qWk;l3}R-?R8~*F-URZwf13leY<18ZV4`bc$v7C9(i<yItgpa1UQmJySantL*!2 z7*b5GuyU=oe<bjPgLes+8eMRUJSV{dsH=JY7!ehM*-_>^tWOul+du;VLg=&k|0n)( z^hwa93r5ROI&LoeZ$w9eR<^q&$?EkBDYybTu)TYU)<m8@<0M--u`?r!C@2^Z4PK4# zn&9N*gpIml=9HHG4E)Vsv0=CI%WLlsotPbQM(I7dL$q0{-*&SMTE~$`ukJ1}QzJ1Y zu;}B?!&P!1D3`lke^uZkHK6nC0*_<@;kqy$I>j`VOpU^M)NL1nn-L9ylKA?!k~uVf zG6I}@JpL@t2#+*!A|cll+u5NV33o^0hNq#huQ8@l-^WgrZ_Y6D4Gnk3AuRflyEsM( z&JH0{L-c15fY#9gcOKVG|AD)x1?U?}=bf4U8>G2GgE;;~bFTF3{Jni_X+>~Nd%@YG ze`WoK12m9G>oGz@sk7hBV`8(*XRXyBxDU6Cb{=ZmvcCO7(sowxHK~(=-3!7E4J|aX zS?eas(U7$Djj8C|2?HXd&n)VDPVhRaATEmDWqsq}ba>qzS_=d2iGE5!Pkyw`PGn^i z*SWq1%b|R~*h_AAO7t5P60btfHlm#yz^)2+S2T47Jj{_ZHD?#Sy1CVGD+Z-+3Oo7p z;1*gK?}mrf3HGRP&RT;S8359)ZYt0)Ql8f=w;D?D7n0)``eMV4s7G|7Q8>Eh6s`{s z9wS6}#?PO;b$)T7TQyDM>Hj%w<Tt{!G?$w(xU)%8q6QOa6cp@61lCYP<Eg&VIv_qi zKEJ#iAZg#xv)asyQV(O!-eZesTpNRS&mB?Oc$6MQHZ!o)Nw{{qpnQH<oR4$tUh|Cx zZ<D^pIYTFqAx=dKu5{7{>mOxvxD(8@xZGFEK0NJN=hK}QlA_l34WWV<&63Qy&4{S) zLH3bA*WYu}$Z17wx{%=#QIbSG#uO^z$usnJ@(xsfk%l_jGz!r@KK3Mt%3f|w2MpCV z`g^j~`7@7-MN^67qljk`byB}Na&KzVip#b+kE4FsTn*v76Cs!Lzytk?M0!e_5K7l^ zdSLbVTD$dbsaw@_!YY@ss+rHMyY^$mYNh6hXzk|sa|(NB?8g>WP8%@UH0j27d>3W2 z&FreSPrvh)Js4RJkJo3J9v7455$H^f&$4($Uns$H3;|bOTo_CxrSuoBExyRN_ue8V ziTb0i;=+%_Hp*wb%r8>hK1tcB{#alS?CLd*x_sigh~1Jyyyf(nTA!}urqn$}8^L$( z`X@{bUdZ`KJ!^h$W(2FRdpmDwuYu!ZF*id0Ny+o7U&v2_7_`@RQy?o#n!t%-CCg8K z%#jLt^E(zv94r|TFG9}r2f<euNy{G{=O+&PSm(@gC3$Gc6(`YstlvEjq1lrE<E`cC zQRdJ+NVBi)R~NRalnInU$X34z2wQXC=Zo`4H5^+7a(CXX^NK>ApN>4P)HnU>5qenn zGa0nooQ{lHZxL02Gp?(y(Plm%(>%o#a~1fp7p*OgA9%ObJ>Zl+fp{Hu1m~}pVwGz5 zF+Eq<q?^rIYRwTdGAQf3ZKWkWW7qi|gti!c*Jezb$#Wu&Go$f67YOQug_j@+D3f+r zJHW4W-7VFc<v5}Z{o1~8%X-#0n?06_-d?gVoKtyM8u|c7RX4r(e8gwL(=}L)p*iLV zCb!wh%o16Z&`io%l$8gX-uqBRz>xB(2)VIbvVxmwbLj9v;|92XVP(@qpsiL72WIDv zT~60X_r#lLP+`M8l<hEYQmGx-yImd^m+PPeecx+D-15fAE12UFr5%j3IY7ewrF%hD z$(ThOyp88mcS*EPRwzW0FladclGAS&fL|qox&^aK>Vm3soy$guBq_@<7_${B2MGbr zC$WrPaH>=4r-XCh(%rWFeQ)N9)T<Zj2=+@)2Z>jkuTMwxWjtz=uA8^6JHLFPC{1+P zc#a)5rzbr63}+F)(?iFE0B7Lb*+XX{@pJxtqJj{dKT%uSLdKde_yc~;!CD@@<xi?w zE4rRm)GiWGEhp(9o41fK(t$lPcjE!m((EA7+InI0nkh&&&uQ}*&Qi=^)HD%J68AIg zf}Xb&5IuQR<Rp3Bp(mY&Vhd`>{q4pLX^Q7jF?uPFqiwD4m#IF<PD9LNl8?#%+Pr7b zfBJhP15!EH*i$yEJlb(%fo)s6S-jL+4jDn@INWm4XYQ>OM?)O@b0ogpJVh`hQ;zq6 z^6Rm3f3sZjgk|E<oJhD<f~ZXNHHs!5zOHP%Fu)d-VE6Q*rBDn=HXnWeRv~BIgCSj4 zz4-}~+;J!Z7c)FdLKxQtY@^Tn(DxJ0l{r0D!+nmD0b1bF5oKzJj*Li)a??veq0?N2 zvj$80&sM*U%uKMeRO5S4>DeH|J|%2bn}fT1h|3)&LM02W-+>c|mZ<V{=zMm-BxDJv zZfWN(8C1nDR8C`)HigUE4Ib!RQkx0-8DV^LX;<Q(c=fft2It#!(Uhu}LO%dGIFO90 z+>(((1P9fVnglKL({sJ^X3A~vdOJouxTB=mjnt!^7ov4Vp+Ap+>#48@3U|}pROo~t zU<XW1&_WU1&xb{U@(R%J@+yf4nGEc9YzEfr9_hY^c?u$Nl#mHEATQ99h8-z^GGnga zcri5v1|eV7A=r1?uIXP&YeeG{rSlg*M0r&XQMf#KKPu22Wc+D^ZT>IVVBsT_;qGA2 zj|e6A-EuRxPbxF7asj(!scB5=>lxkbr5<Y{9k2D$@l4z`_uiL!u0^lzzNO@|0@0`; z#U*8-Pmp6$*W5vK$IHIvo8iP2-j8gx6vMkZ=>*b<cI{G0WJ1?Dqm+sHS92ewAz+j2 z*OwZ`J#}i%j2fnhu+M7HJUQt$i_Ep|5Zj%H49@8$iOi!;K-7I}ucCKz>6{8L6RCMV zSdfI8u@5(Bxa}B=zAoK?$PWk=lNXw6#nFC**zL}95`@WDejP#a)T96w+GGdXSz#uF z1zsa}tcY?dkj|YwvsPW|-5NQc(#PRM1w9X$k{bom2PsJ|Y|aK>+n?NB&^tQFuHuTX zFx3Ml|B(ySnuvq~u&v5hHu3Wf!;)XOJ~Zhbl|XAz8|=~M&|^``b!O9v1u)(us)*JV zshXtqan``XJGql-?H#GQU5N|Oul)jqRC};)I-8``Zi$(ljKVAPtnnZv@RvI<-vSwl zb&mCWq+!gV#bK&Ak{i=qWSBzwgH&ywFDGi>J<zfghQnu2Mb%4-30y6RP|VSnT0i2A z%plr^{m)|H|Bql)u98glwhW=J+mNYWBSZ(M6RnHP%IxP_1u_7prioUxztlE&rpOx5 z5;>P~iP)Nc?k%JlE`Lx+kTsg%H0@hPnmyjBV3ThD4z%ZWxF<EtYOtUPDT2%BOhK}j zX#?&*&U58|Ib(q>xu=dAw5&RBnaFyPYs@=fP%zpa-Ako?0o?lV>1Z$^Q&4YW+1e!6 zI6$MXK^?N~8$VKZBU+EsJI`)zr{hv{bW~nLt-D^K1>|CxnNW)Sk+>-sO=0}{nQ>{b zw_mmJ)553?lvepdNhbs!_tKa@V8XU(2+m{u{R(BQ@}utye=W4%y{f^Sro^Mr^vUPf z`MJhmmq%ZNf6yuKH_yM-irmC>w!vvF8Qg9-kAkb*aIa?^&0s%S>*0D%9m@l~BPsr{ zW(T%P9wFY*exwkayy+N>+^EE#*v=S)P)3cjdXde!z1QZLS!7)GqS5wx(ekFa$}O=q z$1p^KecN?Yx`b)>z$42=rt3_teg)FV&)#Op&-^p|RVsMZF1DqTZ{T$)!lccjN05GL z=$jJdc+fx%#Brj+oCye(9Q`Wpy0-;`col&b@30RGCSf9V^<J26w#l1L>YcF~DZ*o< z9G41o`Bo2wR#PQ$>D}cETrFn^tOr?srooN^|K}A*KQQxB%>=dRtcXPtX4z-#K^UkI zJS}K**w7gQStDiajiK?IGbR~ZaTTtkGh<SXsIteNkIa!qd%HZqEqblkc&Vf>RsmmE zNy*wa(HP|Y+xDHG=*u2EZ=cq>D`5giFHP}A20f6tNjO$()_hGm`qadipn}a=9+q1c zpW#JlTD#o5nVbrBJowbakSoZ~RllxK+C~!Tkke$J*t)GGln2KYI5=cGp(b*bC}X}2 zzBWV*hi76*MY#(eIm4KWi~yU*T6aCnN891Ms9;dc6OW}755x6oON4Tk2>0c}pNUTw z(AI=oeByp|MgGSptg+Vd_I%yD1KR0J;=>}VlSJ@ZOp_Pho_GhQRHcrN0^W;-MIxr& zdZKd<*3&K>4Ia|2$mj2rrN}vM6%Va_P?P0})h+BYT`CzE8$_i$7hGTc7FeY$V5Wxq z+0SER|Fo}5pyODz!$!thdZ|HjX)a&;jPs>{Gji?lV&8?uP3`7)LSVFyLoC-oGJ@s| z(oEv7I+H&WRC7+EP9|0UnU!h(UkM$tTR7C(IHg|JVM4TS%~)xzN8NuNXSyDb3e>=E zG>Uo=(L?hMyt~D;1CrNzql2XgC9>nbS#I^4GpXAGAz=zv*lL4)lKNRy%LL7Sbf%3I z%$JTrddKgSg`5+9U~7Rl?J_E>>&u@inH?s=h%fTJy+P1Hb5h=_@wU+vqBm-ir_<+} zJY4zXlL-#J4dKm961c3|$#if&XYTc`=rLL_FNidkD$X|}Sp-1?{C>XU>Uoi@d2b>X zd!Y<o;2>q+IBMJ+j*0T)GPojXIvnHL3CGqd;1Jtf-@O_;Zf^sH2E2O~hZSazUaD>$ z*aYapw9-f}IDqqwY|A1;r|RG#xqDkHj~VzBKt$a{omvkJuDF#B$>#7FSJgCEbZJ7t zhl=K}#K&K%OhYADY+GcoI2htmQITat68@$?iS8K-toaB~B^TU^w&8QglyTrxPHQt8 zlosIkg&gc-%70jHAkD$;XuA2eVohY(;Zj`$+tHWiKMgzg<^KzYU7@nC&$w=_Pp6)` zytD)g3aSGYS>#7WedBn9r37GeV`5I#(SU}*tGTIf4;^9N;Mwlp+v(myVz-1Qf=tSK zx#LV=v0!B2khqr=@6c?Fv1J`XE&D}tyMxm1Xxy4*+G-wyT36ST^C=aJz=g)m(eUNr z0y)N^oRKa%PRmEK(oU2|piaH@#$F@RIr0VR6jdt;j%0y{9ObD<&t}e{RsI%Ctp?C8 z7-_;$6Pm@rF`iANCgZNfN=qm8*w$Q<qPctbbM6IHP~nn9XH%`+anc)M8ibMda#5bw zM<w0RzNoY)UM`Vx#ak!xkoc?)B?)3GEmU8k#QnA$;^c3O1$VELx~=$dsV3V?hQl$H zAybmsyc0%mw)FDxUB$V>an7l`@tdx&XuFR0dDg6c6|@c6Ro}b?ur$iB3aV(Pt8?CY zJRVj3r@7A0Lu3`Dx?Yb$Th9n8lx6`*DD7SItI{dm(1<<4aM6_o(hSw*^Wn{?_Zx?Q zByuC_k7)wC@;9;OWVq^Qwl41gI-q*86~`~c{Ng1V<3++mP3tc-<<Z--#mg$E0mAc6 z=@p^KqN2gBG=-q;J@-Ab`wy5g-g0KxAp=+IM_PMyB2ZOjv(+FlI%p=@!E4aWVRI=3 z9=Vh`cGJ|0=8Zcb3H3s+;XroIPQ=UnqwnN1q@qty6cg}DZ5Hd*6@NCiZlX@lA1j}p zO~l#ucrGp3jaNm<s^JAX1v93T@%1R?=7E4_7_FJoDz^_j>>0LY+HJt<(;X@MQg$#H z$>Ec{nj-7;{>ei^^2rt78_BzN_@Lz3sstr|>(O}_M}0`L1>-=@F=kh3wXt}z*=&H< zQluFHzIPqUyM(vV?Ld4GS_Fo2A24(uRy2>YCz2RnDa=PL|IF1*jz}lTxfygk00|di zL}bH47s_TG8(<#udPSxBS`ODoP*LAxC{^F6F5i@2D;<5wN6T*rcc>*4766)W<8K1{ zNru0`2+jLjb98@!Q77RvM6)N)=@<Fvdd}g+?Pxk+^j!b>(okzOB))z%(tU&6J+fQX z9i*?Mqy(<^${!CT=?Pm@8b&LAe{L1D4y1uHS9vH!U#{CU9sh}L@A_i1)q+ysPa>Dz zn-b|sv#Z(3S}8|d-*c<BulsHq!K_V+W{$+7Wn8#H+lPaVZfGIH^eWe-6vp5Tv?eo2 zHQaU<D}ae7RdN@pXZRpO$=<=SM@e>EzIntQHz(5nofc7dce*QYmHQQJ@sVwClE}~U z4Nq*+1bzsg9m#C|X&Y}D?Gxgu(_ncBV*OPqF)gSa=F&yPEkQ@khHf@X`ub#<<x8=q z7CPd_)AZV~T^`=crHWiaxS5?)u33{gx%Ihle{wP_&_Ex%9&~EL`C}nl_Q%2~RY;f2 z4upLPIHv`=Ou0VqArD{okmhn;XJU6ictsCy54Xg9V?8+alSbvZw@*CmMdd?QWnUV! zzCN234WTUI{g<i;r$5jkM+H(n9`AlL*u6<2bPv%$!2%u8Isi!Qk?4PAu`Ne`lDX`4 zeOb95xd)R{wrIHW!sr{7-6@s9bfo}*vGLnCZ!U0O_fREdgw&7kk}=MmaOtgiQ|x@e zm>eNBi+6V=tbRMkElXiVy0<t@sNnyj>aC-qP`~eC1CbCB5J6Hv=?-a7x^sr^?jDd9 zB&0>8yP2W88Kt|2p}V_=X84Wwe(ra@?^=WZ!D7jI&a=<n`|M{^%YF=YboE19wbtfT z697V6)H~32)MHAw2rMID-Qs7j{R4~U&RCw`{)!pGdVwxpEncuFu;9A2;D{K~r$y~y zyM$m4?Ka%sHUq5v0L~$pJp#(^_C*>CH-FHS3QC&U;+k?Gn3jjo6Fbmg*$)=$sY2k$ zq94pGUnI0Hi4dqc#{`*zAnKl_B&T$@EUikr<(-S$=$Mp$5fq8j12t<f@&w;)alpqc zZpZLyhcn8f0eFSQd#*cIX`QGH079U8fNHYSxnFe-BzeupaQNDz%qyiB2ijz^saIYx z0+ROE0}0mM!eZw)MH0L16Pisf-epyki+=k_@IQhe>2-h>b3tK-m)y5+-)8F_GnGWH z&03Fqk0$6uPB4ek1wGVev+)1^2?BOlUR?xNFHoR%vwRmvz5gQ@j9O4kcn_1*wW;Fr zXtsFMTC^ZOlimF$FBFse&I84C-^@Ypb@e?KKmt2?aZkv_ss8=WaQ%OMbkmkzUeQN? z+nu&$db}13%n^<9W;E1o$@dc6B6NLsxpaT%aWe~VEBH%x-DEyoQ$oe@;onGk9nKec zL8J=-<qAbkJ}l^1#mVfJd;1W#tTOXd?S*Q_huw@r>0g#&aRIZ{A<I}lq_~Q9Ng^;q zUM3k?adL0}@A7%`wOQfSS+@NUL}$^SoS9$j+c0}J*NbH4?Yr{kp+WwQMFUrLsF#L@ z0PcAU1<Cfrv2pb^4)|`wmYc0|*HS~+)(cka6;P6vFZk8^BcNpBc-XuQ#xMO`K!Lph zw$E)y3m|W9X1(@$@&HO!aN;pBFLi(bTf=>wKQAvfj8IxH3>&i)%lMV)-IBS2QMBE8 zOE-Y@-|Pz0lA>L#D*=rJP;D$zUWQHI&W2FElzWX05(qA`{{b|wZf{&1kunm&qF(;% zK%AHeAS1<qY<@N7dV-<Q_Ph0Rv3P1q<FD+J(O(K}x!r>z_tN}5xA?Pu;7C`$%-B|^ zqb<%TIedMuTc}&-+vY2Y+wlnR)9*L`<N6`OPknHKzvq)uj^WM(B0rzvVHo}vf%7|Z zUDSoOnzwu$UaO7)9aisA?s>bD`)#Bn&>4<2pU=Je{sYx`F%;4D!_t1&w;@<c^%~Wt zDASeKi&5k@sumJip?9ZYWWyYIZ@$NLbDz&wlX!9z&`i|^G}0!aR6kc`hKYIp!W2Sy zw^n;E#hlsv^E4~+;k6Q^*-~!Jt=6_jb2=CT9Ys0|J;4Z~{fA&CA>qe~Qa73?P_%Jy zn2M#5_K6WXY*;%l^uH+#6P2jakh@2e`yc2I&o&tSdGZ(Zh5@x)-=zE`M^PTM0KT?v zJ!2lrcf-J_W)}W-hcc6BUKG6sahA9FhFO7=+LNP;*J5;#95{hm)bToRHhng+{{ze$ zxpi@VSU*2+-u=>|8|J$~#&fCLlfu@c*CZD5FYCb^cW+2QZO6srQ&(6gIKrSgJtnm3 z`xiS6frf}E0rzP(i2PmcdRHi>5$$TxZmUJKhEUS{*tMAgs88sNNylOHZtb?kEqxyW zWXOQy;#sxHehGj^WJ!u*q2z)N7c!|ed@m74GR&fw=#s+Mlg#>RJ2;ufw5|OkZ;zWu zr6I@??fUwitsgKKN#r%Y)_2X1${mm*AgPDPmo^Rsg_QRZkPKsmXq3%lBVm2<=KA)L z9EHBT8pVF<F8TUfjT;7C9{WJ^HScDgt(?u8vWLdZ#UX68?!T9@<>>H#WMfjrZ<H#i zdq1>v7lqPGk2Xp=bc|OLbREVDMeldg%xO)f_noU>-2VKi3H-zMgEKVhki$Q_rh=#X zPs?iipRSeL?rTj6p3U+~l#(i+I8e`~|D6cqos+_Uqz592uQi9K_sZV}_Ru7;lx|es zb~>8X=uEgyJAy{K%#KDYy9|z2hMbU!%1(BBrhfKC3c`2Cd15~Bra?c8-fi{}FwvUH zt@|PNjy!hn%)xW(8Ky&P$q&l;$iuMtp4$Wdv%3!vXw_%z5m9-%t00xN5z#zcR-JSK zw`?zex5DA|%y*)4b&517-gLsMYTL%@iDTP!fyl%4NO9`|5@ctrs2dPk?ti}**3<Du zLwz*26-tKVl?P<K^@DwhX1S=U6rO`swyBaw8w%Y<H#W)Y+ok}#l{Sf%W;W7d`qPRU zZ;ASnfqhkTr`|_?%sW@nh~g2CIqX&oP~oJh%n*&9Y5nBY8&jGm7-XdX>TEsTKFV-a zk;{44n|{r<9RKS?e^nt0%1icP)NtG>2g$r1v=nQ(aCM&`cT2UJ9tK6NVDJj)Rv8HT zms__w&eXw6AiMteapY3PC_1$)zmHvi^n#ia5OtvDE2%FKxnuBn5`|2bz|EH)BG&Cu z8MljvoC%)I+RoKfwW|e)#cQ4>%j#==<m`Dt0gE@x%h|<GuQ*;ntYfDgOf=)VFH|U% z`4M5bTJ*5EV57hOa6YXXr%bQBMUeJb;W9~xRXba*SXUU8WRsk}yF8YJIj)iSt%is9 zfSswCRy+}mAMIFRXI)_TZO5@W7h0CJtN(OY=jSzfTkcN|LyP9r%!<k8dTH!CQIegT zkh(gEjk)xVZ@#vE-BJmwt^Woxt+Un_k*0v*6M2DN&t2>VvWeGM_iV<*;e9XGv8gy8 zWUw`ztywLwSD~F=+j$tU)@)0tS-o(5Byo`jOpSLs@+c2V1v3;xM=(w{@m6=azBF?` z!3uExmyku7-v1TFXqiXH$8)?78+$Il?6Dmuu<A1wM<T2$z(|*+AcfkG!{%G1xqAMH z1V{*W=xd1#$Fhj|k{<N+xx_*_cdD<S@K7S#KQePIhH^m>?oQOhWTL23m>1pjNV(4( z8c;S&Q6;9Moq#>NZ%@JM)G&_a<{2=vsa*d7Ij-Q!b^IN92cb>B%rK?7zq<2ivkHXh z#<5ePfTm#JbD%zz=18T(*~tjv+3eLQx^K;$1U!4@Gb~h51#xa_3ekJn!oZ5E=`Nnk z$O5Owdt;?jzD<XRgKURb<v<%NtI-4&-SfKoR(nneY3|EQHt!z#{Tbo0(Y(SOlUXCb z$BW(r@jAxk#IK#~;s*q454r{7uS%FVTBP^xf}#4L{Syb!i^wF=)v$l{`D3KT9Adx* zo@;)f<KpkJ7|Ly{&QBqqdYg1|=!_V-9@sn4knlu%MUVAANj+&ehb)Ltp;kjyc;lD) zx#0uCaJJ32+5K=H{O8YS92}gTTDZYk<Sj~Hj}bWzz%7D6<P!DWwN1KUxzaHx1b7pV z+>Sx^s{8HoHk3cTFXIS2r#gNJZPwsZoSJU})u*sJg%X;2djTui5j{*{COoqo^SRgH zNAsPt1FrY0yP6p;jqG|osXgVQ37&UNOH?OUMIq>3poQ^Txl*=d`l%LBxz0G;>9Fwx zskG1v?c)1r$?v5BP^?h{5BD5u>Q7P1L>=zIR?jr~ZYGS%E>VgGh;qQ(Vb{8;*sxT7 zzSt>RXfgX*UWcG``oTF<J$IL$C9zs!?<3a(Q2PuDpVq6PCRhfQF7Hy*!@D8{Y`YXa z9%+%xPL)75k~5b`9QI&Mwr?69h>_bx?)M!aNb`(=$0TXHn*pU}%6?}wn+436Ch~eg zxWMd0u5@k|91=4)5xJj<gCZQEu2CfLIp6ANrx4FLo`y~4+u7OLsuEzEMys;@c;G}D zFY6k~{A_`ZH1Wr|adLEC81up8G5Xn=LKSw{L$~2{{>Bz8U(-p^Zg4kdg0pgIvf9Hp zT`t|U-mhCnJ)6)Xexo1Dnw?MsA^4nZ=nOx=8S@`8!}b5p&ie{mcv&Y+TM6mHjNudt zs3VUa3{XBCi;FS_@1sU`nHuh4XbR;*>CLHRGIl?}vC)axdo~Su7~$zk)e6&-DOWI% zu{<Jewva<@RCAzy{J%#DRX5h034wtSY}nbu;UvHMgNMijTAYKF=5O+pb9CTBvA@@) zw1-*n#ULR7Q4*d4y}0XX8ajjjvOUt?z43q0+~P+@Q5B^Ogda?3f6dx;%MiX1A$)@R zZDBWvy}}%uQtfJ~y{XdFpG^z#H}@u!`qWF!pqM1X&dj|#pjq2^&u@`4?8)fhL!cji zZdnn~b}c`J7mg-_+rxc2L4_!FyqssNrRZyVI25>K>sNd>oCPuD`+}lGDD|Kv6qeJI zo|HecY)quCaZ!M-@*i<-_qDkCeb6)aqs3BewifovDkKD0EEIuFF5;tA-f|iqO~y~X z$B=yFvn9ymT5z4aHkpX<He#ChT8rY{EvX(J_q|-OJi<C@z7=rFf!ez1o0>fvt$Mzu z_d%q!Jm-%d9T04{S%h9!3iOz=Iaj=VnH0~<RSZOT7$JN&MDPhmhjn44gs5z-`r?`I zUL(5ONYtgru7&>;&6=XmNR5UC1^H6Ems?BoOHIweaOB<_O~`r!4auxAh2ujO7pHAt zk?x>PA(7ydJZ+{}+Fgi)#@5g3q1uB8l5HDcJ?2Y`CqWv9=<&Wvo?>|#k}#YCHVdSp zq2K;a1m^cco?^Fx2XvHRS1zApIr~otAeSiwRQAQDd)z?-XfOXp@xES7(Ut_@X^|Y= za%^hf*0_K-%fm4`cLQ^c5=;`T$yWsyryGx%0f$gRUlpHgTT@COqPv7~w#}(+mW(Nw zHbMhp3`~a%3&C21^J0a4ZRXbPs}ZrSHUhj+zxdorMr7+^K`I;L7A&`}6PIIn_R#F1 zvuZiG`Ymt|t6HuZ6&kisAQ1<CNXqm+Y?@39+nm4gaCNZfI8!m+zo6Zsakemf5L^+Y z+Z58P9v+kplkyiRs@)Szi%Jq0(p`(+BXc6!B!BYfAFsd^Q&^Ub3PV5D*WW>CA}Ahc z_jc)_ZEL!?yiLd6{!pG)Ih$d6xeYVf`uDx2e)54|c~#<d{eaVok^DOH@O-2#X{4Ub zBWnNiqX3itGktMnDB@A7Yp5Wwmu5@5v8n@CNFU!EoM|0Cl2%0vsQ>h?tWdyVtOLra z2z3eEZL87Px(lc#JyiMd8Ca-z2w%g5WLyV76fYK!^xrxTlxIG8fbJIzi}wnnKbGG} z-<usg+rdEtPP}fRr$${WlHAEJ@{IzdDLf@2-mtj9TyGERZI{}7y_N%>yKRqB!Q1p4 zOP1RSHTAMlo}hc3R<GLPBtnB;hYp~T+G2zMjIO6T^hPtqkdgvNtI;(+^=s&BM-EeK zid^f`)3|F0aD-qF=o)fM)N_Hvt4`5aGuhe&(xUI)NqRw+dvnQ~`bvgD<J(k2hLr|5 z+R*PWT{1^ew@)DC;`K2q+liX--{D~lGe`F?2@X_Kqh@jvu$?ODq?U*vVw-wKr1xX` zQ2HG8;_tS!=uNEq{&cLC@RE)v?4}7Zr3>o7;k_c~?3$a02h2c2U(7b_RUXeg=FXIp z8Z=$lDx};yRR3KGwvN+ooIqntH!QPF@i}OGlIQux*hRQaNI45OgSll3KN%+fV{lsz zIm#e~E`f0u^~-ljZ-k=E#NrPHgr2$DS+N)A*IAY(*bt(K81LO8;Mr-zEboWg4G*QR z!Tw@GZKiTBh^)Pq<&&fVJ$UOO$93cTm!Kivs;UfO4%na)(C3SceIXDmjQDuOn+X&v zJ<aw0SnRW+bCeA`nDzJnwuL*=@~pZpsluXOo1<n1Q7xhIc4UqObhr=D55B~G-h)C? zidpqzXkM*bKMLOx1Rl;e4%L%)xr3W>h6(o(6l^@H@0@OLCgtk<q%4$lhSJQsRPP}! z_5+?T8{|&V1C0Lh*X<FajG9U)qh<gmhL-5yuf#+;WIOAvlWlOwUO806`|KA~d1+nY z9w^uJ#|QOdg4h&xb>xGj#asU^!$&7XtgP8Sj^oGzm5VN)Hs9-AGs-6zuTh(V|FW(T zM|$CR->U*4J!+rWPF=;Hi=zTPQhsN&69PrO254r#blrAmsGm8G!$q9Jn#MmQ?yOi& z?VbbJGqP+*LWm^aqrw}$)5c}Let$f-gw(K1a}JS`k{U;7eO716v+>pb^K1_+gF@Od zB3FNKX~l}@GJRZ3mIm0MB`9x%hUnc2uKB(3O=8>mhjgcQ%rIY#^eK^BThxD4m_R9E zL&4#|{lMb>t+G1Y;RGfmFj{unH5`ndGDM@UJ07Dj#J`&80Y*lm;-Mrx17GtqV*XdC z{O@N_&p)Z+{lghY^+%54iay@E^H~Wd(raG4sH@+pnNXV8pQ$$2e;7*Q5T8OUp}4cW ztqgCaawxK?xCPOTRc7GQ_aWoJ*lrqBtnKMy>XP4qe%8ZzAm81Hp9kxEiqbX<Mcx9= zN?z=WhJUeBS@2jas}(60*O8uNwud3$2Bp{9#k@MVdT{RRS=SIkCY_qgN{h?f&eHx8 zw(1n~x&3SKXwGfyW#1FiJGc(ccuCQbJ`UH2Ga-)+q*N7jkgv0R`&{wR)(slZY)+xP z<lz|l@$wwZR;!Z_Gue#Em<PF~z}RhHUV`sYiMV5#X|9&IOl-Cq16!$slv<wRG474i z83v`=4ej^Dmy^RO8wWP`Cg1w~el*e!pLdl}T?_jesa)DM>6h|vLfwJQI%W2wLdu%+ zrl%lT9-gMcIW*Z+E*!Qa;C{lh<V)I)3fnykP}zAISqi<G#?8T<PWA3EsDycsZ`O<d zeA}XSVXpK*X~bvCZ0f|%(bNJq>3wK-R^qb9stex4DYa>G36OKSTglpUt!f#FY@O1V z+|{=mai3T`;GeT?0ILsa!mJOOmpbA|hqf9ILiX<V*o!YO7ROCAy6$m-iF8j(<59d3 zbe5k8+%&}Bx`%vOTjpMFWm~V;j7rc_SVk<9M~pu>fJ7=qYXd9v!;df&P+PAkOMtMs z<iAE|)C6*eVn8QCMb4>~))r5*AcdMU@(12n?|EDPvG!dZzBngh{p+Zsl%)_gEwD(T z+_qS6SU$DytmF_8fY5*m;TFS;9HL|b?jZ=5w6#8uIR2%!iV$%@jCZea{*O;LMaF;) zf?fflpvZ8)OD{byIOT4T$MtrKZP=BuIxR>M<?&9}8s(9k7ka|1nuuAK&OT7`G8L<# zQOA#_Ow*9Vx2i2VHJd;w?Jgpzvq4?4rK4%FiuKps&Ch*F;|CtNcsYqBxrfPcWuAUX zLgWc10eO}67HqPiBurpMpP;CB$Fb=wnqVj`W}<s1HK{{8_*%qgLFj$~N?W*6EEwXp zv(pDRMe-US@g-vINcVR^4saLkhZkP8otC2z-P7wBP^kaY=Rn1{5mBd7*4C3sz#2A+ ze-{K<>~hl-rT8mN3kst$W|T%ebK!Ap6~-MQou&rqJi5h}zDM3mt_~!ZwtFX)F`~$Z zy@tQDeMY>7{xdAUHKh5`FH}0(Wrx%d!Z1wRc<{lC*>8HjUf!^N2oMHJ=lsKFsn4a% zefjAA@IwlrDZxg`o|mhAVuR+kCaV)=)q@sPO7H?<<;R&RWWkcF>``?0bIPr8N;+g{ zO;8w`tb8=$$5B<QeWppPN#Fk#gZQs`dHT}2r(P%NOe8N%H0hB8eERYHzEbqbB4XgY zL=wNfseI3-XFei>Bj9Y*6WKS(aX-AlK^wk+5%m7wYYv}pNI}M^@8^e`srojaY}54T z_p3xu88qGWx#(oL^w3d&>2nY}qIo&FT1jo@DDjOO6p>WPWR|r#D`?^8=-1mYB7}S& z|0^NIHes2t+c0`3tFeWR1KyO&mU>h@bVAVRqdfFbBnSBD3SdLR72=1|jr9LCA2B2o zkNA_T_8pB(em=X;8|REyvig((p=<jyIM$2A>+<uJf!6w2aELN@Sq`hr>|fe0T5ocx zjgGL2EQF`Ju72gGi`Hq3Ocv-XA=Y<siO$UTd8uqyHC(I(iC!Dh%g{?W+k)x=r{|<i zr}z_m<oX7+%^8`<Ee-d>ucCkR{R5_EdH&Pu*4}(UscGklD7K`nX9F8TA@oJ%;Nak< zlTIWX*Z-=ctw-4{caL^`9AqQfs60gK$_CF|82*Qc+cdjQNo@jn9J`lJ|GHx;P5TV{ zqR>pStznsXjZM2HSF+P@JLv+)V!8cwSso;Hd12GFbYUYk^La?u3##*GXtaz4>F;TJ zZ?3gRR1Oc^hjw%M8^h~rfa05hLI!HZf>XR#55eiMOt+c0B>Y0k>6bSpKUIEzNkh&+ z>5u1#yleC|7jM@(4SBjUMS(0!4nXrZ?^(7ZjkAsVy&ssooxpt517qACRcv+>XWiIn zuaX%5JIYG1NHs^L09h;u@~$~urxx+{ens9{ziCB@;50Sc@W@wz6zW{+l_^u_x0yJY z3l%k`xKF<cf7qq-x<WemUQ^c1rgAQg=oPW)xz@5iOg{$&Dt|qJWs2mn%^zo3+^xt9 z`1Xm~z@#m=!=4|Gb(0Ei_}DZ6jn{|{0c${P#PfoTt8)LG#b&|t%gb4+28FmN!z*d^ z!$66~!Ksths$KtSJy(Q}X>lQCSjw<rPPsv=LSn{c+X>Jvp2AaMK+|3^`kH{W26EwB z^}<_V7E$|LZ6$)s5rzwGeSb!rcO~z&DtHO*X~-*}S~yJJVw*UHw(3xpUUi(;ok#E* zsKIwh&wtgfbPk-?roP$T5`^X}lJo90&-`xsR6J!^dL#cZ?@=}mN+E(Gch+`WA4KeH zZuh1=H+wXSDo;4|Z=k2sNhdxYd%m;hmy4ct5P^qq3$9Qcfg?A^Ue^&{!%58yVo+M{ zIKe?N>?{Z0K=c9LGw$lXd5w*bM#%vFV`(Gx_M`ch7H}fC^25Pr#Qa0o`Sk&DxQG`_ z(WYf}O`xZck~6b0ifL-cvlw~FJl0){&C@{w_r0`&!9Ny4z>}G64`%mmjRkc#$7AJo z>@flThu^BZ5+_|3a4e#S7WUxsfQNii5OUtgqv|YFG2Q-);g+cT>Sx&1vG~n$&p{72 z+hhlAkquH-)&~!O7=Ef-fC{^U?TCg(W;q4$F8QdV#2|<t@+`BNu^M@G2QI|dd|!63 z=IOfVxwZ3GY|{%(L+yHm#p^DiB(~-{<;7G~LA6!rBQ!nej`~=300XO@awWfNvK32p z)nejG*kk_8?|gYt&}cbjStiX}exch{q^8Kr14eRzM3@+o$0#WPdp!1DV@>`Zvz!Q@ z%I*@Y$<jK+&};@sw9>+}SUVOh8=t?)SG^ivdkUDtA<yVhpVDGF*Q-~Ef83E@#?MYQ zI_`!6u$eZ~c+Z6%03DPw7_#_KKH0&ZpL#>6o9sDwusxAlyNc}#_Ri?`7!!)xx6)jD zb1SlZG3X1Z7Sk*ReRlcl=EWwgZ}=|@0OjljOV>9AX05$Q6*v<23WV(3=31~~H6-rt zE{(Gu7(Q6;-iCU+-42N`F#=Nw%QVVV^kICFu8Q3Q;+suSX>wlg5zOk0RP9om<g&IL zsr+kJ?T8({;f+prG_im6f1I}&o82FrPy-Rs-E+yQT7wJFMuWg-<Ns-EC~@wuSm&Pd z-w4?740#KE5Io`g{#O*sFdgCFBGVQ<1^@tgm*m1;fWMwj^U{)I)LO|-CUPh9yfVg@ zxz(T3pus^bg*3>UG^S{k`j+iz$Q0jXlLNDn#6?8y&#xUXn{tbJ?d%(tzNbFlAkPPL z%Z8mrb{RD{EWEn}aE|mWkll=DJpWA2^>iO6%dFuu&8e`d%$cK0i0@Vf2_so;k{|DI znVfK)QKYne6tHgeBnkEkvJZRp@kNoX_2y==tHU^z##vE?%~=uZSvVY=%R`OZ9HE%^ zPLpgrwnqU8^Vxc$LUkw}^!@)imBV&K>jXGtKf|`5rW&90;$HasAu2zo^L&Y5)jxQd zC7=no+qrOul^(t@YL(D`TEE*O>O=%8YxsghJzTPRws(#@Bdf4QrMUp^5y6AEE6=R( zZYgc;SqPsDhGPZ;A4I(^pBPGl>P`yZgaLzc@bxezKhXd9{)Q3oP7A+?S;r=v`j=dh z9bP^IrLH7Spt&uHGgVf?@)K5Wn|MjQV^ekO&y|=F5-V}^@mVITYOIpCt*%Fd^RAo2 zt;rQHcoVmfejm6j7hM-G??yT)3^Hyrl$Yqmx_^j)DvIE5O*6aZmkiz_8t0w@v*4{p zJQj6c&owVx2DfIPw75QiKChS?!AT+ydAP;0cFCGy<S{0y4savNTkYkikq&bN<uf=2 ztT)-~L${-l%2a!v1ce8jZkFlI3l+!a3y~6*ZK6i>%#zO+JmU5o;6+*J0E1R^CG|Rv zzXUfwGx^$}hgttXey>vS)SEh3Ip?7-o~z>v>=M;hoNC9N2v58~{nkupxbJv%(!Fhu zz`)VG75}VA@5OBB@o;1W2T&`~YN6TW)zt6#)u+57LH3syqs)_}hz0i9E##4sSz57< z1T>oEW7Oiv7yRa<SZtuEju)NR^uxW8By76)cVXD4uVOF>Ey>{(E6f&@I=MYns@usf zdNUS79qkvz4$1z*M|<&rVgad3G|COg5d#N!-L(#UAH{$`vuW=`+CjyKP_@>H7jpdQ z6IWH&I6qBmT(m0NGum2Sh|li4?fo4cEYsJE4T@WPe>UMxy>#c&daKo_Rr`VTgQl5D zbaTMW?#XM09^&1~#*hZ*83%9yBlYa8597ec6=5*r?Kl6YeLDwZda{}}{K{O?MRk&h zIEK~bLh)52P!x4%f$DP%VU@EVc)qs%F%Z+93fP*uU{?bLAm}vEjzyHLLts@kALHwU zm(q8u7&{s1lMwUmbP}+JVvPsC%b^`r0D<`Leo?g|FO#c@V%{f$?)#tS>g-o8j+z#w z9?>eLeHTTZ#25@&OFw!4>7S2N8pc)Y!?^$s7O?ea4mswJ-*|YvgM$**VDIp$qBJKI zvxojLZt}jgCyF%ma?zV@yXT9BhDM0%urobPG<~=e9SbHy-+F&flaY=K3A6UM;_1o# zGD_|EnA3i}k`|t~G=^AjCC=j|%-b*|5N6H-=+V7_s%F+Bhw)lhKZgtI0d({l5CW@{ zkV3qcU14fm(O9&jo43L2dwfZ6Uj8ZVjHPo<3N`N%>1Rwh;K+z!k>bhK*n)`Y3eajp z7?PxZMzSWF)%=8iq$C!FutRkjX_J7oIpo*{Zp$Aqe|$>AKlWa;yUtbNQ8N54@p6C) zPzsCP!Xg4zB)ImxdM#=M40%DSO$Y?e9Z!_?zD1f&idGPwWw>ex9)z#*Qc6CTe6%AH z!jTf`8X9@lH^&*RZO*;_-UkMul)7vrelF_6g<=@~z>>yWwWp^B;sJv83#Pvu7=XsE zoU>VN`?&6<>6EHrZktu(MjP6#>gR&M$RrLvTv==^n&7`2q_FM#jO-gDwGVDrg!WEW zTXXb&l9q8)Fo!Khm_rmK(<3aY3N7Rl*Lzm`51OCt3jo37e!<7ro%W?6GKc|8cf^3o zqb8%VmyCSF{8w&;0Bzq7>m7bmyA&n9#_#s^8#=k<R~hPXA|s}HKQb<_s@oY>@QM8p z)J2<EIDq7My`ajr!LJkL!J1J|KT6$1dwa=Blnr6<y0;)bym2-REt)J^7eLd@NDZ=A z)1KCL{wVg#u9{F(4d#BebH;H*xKMaPL8J&JrlHe<O6#khUgTPR0BS9W%sp_vo~a(> z0e1E~)D3?;@L&)R8jcAH8deglzn%64Z9-HQ>`R<<dEVgI#()!!g~TCfqWER_B}j@# zUbV1e;uh+FCP~ymZmKniytsPBt|XkoVJg+RjM`57e6-j~Giy6h;kKi8zB56WGca9g z%Hg^>`2E6kV)+$Bgt@WKZ-q_H8<8FUqFPEpVtn3uGx2vk-e5Rnno4@qQp+$1SCo>z zv3dPH_=|wIanM&De@}jwxnM3m2=o{uyEtGK>N!rK5a*oZU-d(<jf;ewIi@C#ZBO&f zqy-Bogt!tT{?bCy!xv3?{`9L<JZv&WA|Y9l8Zh+ImtO(WRxk}T^ftX;G^siNQZ-I- zUFGe4HgN7B1~ZM7uZ2$*O}rY^Bq1~xZ(J_<+<4V@9aUj@`}6x9yF`f&l?hA+)7own zsQZSxHk82~^)f*#@jU_e&s@s~4%29wQ08Yi?nE^Dc<-L$AL`eAJ`O}v;(N^WAd|g| zX^4fc^7OGOE}z@BiqB~u9go&-42twTGCf}Ylf-5Dau;4+F1n67;gA0Ld_6+DTlDuz ze-{ifkR6LglgZLRYeV(RtnG8khpXp@O?zcYzERK$K4`kfgd*?CpXZd3Ge<HM5Lp!& zlWH~m)chEnPn(nq;H_<Zz~W4o`SzoPXxYkVaS0ez??Y5-Phr+Fq-L^48@fTtWzvfy zh|VurE(ElBh^m-Ba!|{+8Vgg47v){Hv^>w>Fn64%&e8NKwV+oVuHf}%kU?5(+*oH- zsNx}mZWhcZ;Df%F@5bIGTe;z?I7hpBFiW8Bd)WmVJxn82?GIHy(*p+X7vp8xOuk-! zf=KRb1+z-K)Fcm#+EG8oKTiC*L~1!e84N*|akXMT26EHYcVK69fmleXo%r66Gsym$ zL@Q;*qI_G9IrXb-A#^G9F&s%ulsSiHnX&jv)-e2QRW)l?+Ub>znTJYHb~neiEAs2u z*=vq`ai79#F2Y|O*an^3i!1$!0s2hrS#WykXTwuTr~A3R4y4h-$9=lQzC(`fV$z{( z<^rm0yh@H?Y0swC%93tf9&@T8a%V+-JvcZWnkG2gr!9G@3QHYKMco=lpLvD<sion# z-OOC;k4UAGCC>Ep;tBVkp{U*u&tyFzyL!~M=53Pj0sYqs_e#lyftCr3BB^;lrdK7V zI<ZzqjSo=#Yj!u9PUYv^*vsPyUM$HNZL_7P)Mf^;5if^2TycGxaIixzy6glkz)}LH z{1y+??_a@U0-sBXHjs5Rr>?5Hn$a058e!>kTVn#h=|g#tubtP+CCIFAGEduS%?6GF z?yvo}ZA`OE&V-tQjOmM^gakL)$<*)e-EIex-p6|r)^JQSnucw=^nZhP$L|p3hE+x* zM1Eu7b?L0FzqbE9of*8O+q_kO%h9Yzr)3=F=R*+Up<+^xv%prfl)uIR08UK^<6D;^ zAARuO4QtN8)_su)eVkkVazyt*I7@{`AzTxb{3sX#@<b5dR#N|njST?pO<8x;IxLXr z);qvvqt6QzQ$J4EDL$AeYz?Q=_)zRz#ooKcnon(0uP-G<f3?fa_1o?1=#aJY)Rq@q zvWR$*o?bR0ezGibB|ESwBan+n67~u-d%eQ;hjjBPw%mIUco&8I%OBD^XZ})~-<>j4 zO4bL~gRQI!j@<mIKASdmBG0e(kF7r&9(C623FMC6{j4L@DO<;)d-+o@8|L%{ce58| zgkp@lnq_L+*UK>{-Y7gD5rwwiZ+P=46Xi>nrsi%uHonuBSp}Tcwqk4affd?2Z@ho< z<ECrB2~XI1E}6)4@5{)*fVsi8L1Wo1$K`<6sPVlQ_Jo*5l!Rl9xK78%8s9(pJAmt~ z($9faCxoXTV}BvYTJyZhlT?IO#4x&LI9xTzRQj9gP-NkC1e~V6I3*(52X~@Jp4BTd zIYK1u>rvHH0!P_p3H*xFnAebuUSO7EIa=G*Dz*^vYVB&z@F5(v(X+Pnfb^IwLn+~J zQETXiM$;9>$9wnDBrhoc*IpiBPXFyMv(dH<St_;YpL`UayjSsl5+YOU|A3sXw#1z( z(f+3E(D>}H%VjGd(k$C}sU(>?<#=AOE;|K{CkXP#arsD}@ktNr%^{ySJ^Z*G4U=(_ zG8+O;b?@XQ&w7a;UaNDc7w8p>3S!t|^D<K(y(!X5h^hJGDwgqUtvC{$#h`KIW{r`# z2_~Z<C>l@ytG{Am(1Im_7*l<V{-18Lrr=WS3d`XCnK#R2{$%#VsDI2h9FtA<E7~r` zV<_)%f+!YnuNV8LjIm8%rw+<(Ja6qj*6Cm|_X`?6&8A2+XwSUQBnGXJF)ASYv)FTE z64BusR0`<bH`VBMyBT<cH~(6Fvgl<lFy+_tvCiz~4ANi`kJNY`TZSp@a570^n=mp{ z%xCb$1$-I>ybRVnK(0G<>X{c+svUoVU$_@@E4Tmkp^saGbrZjgEk8Q4i@xXgQBRAZ zJ642vsAzz_XTfjo)mE#hRRmj32fssQ7{>XbTV!=tunj`_#5wt@qPY>M$3q#u?6O$? z>x;x_lUXsqk}$SN!~>7c!Iys80oT@G-^-z>B$vTyYH^HM3}&>Hk`Xah=t$Lk=Gfl8 zMVf!J-Kq+S@vB0gfxiISQMT84dk5u28ZixVPIY^ibtD(O`)GzyLiqUn`!m!-h?i<a zCl>@LQ*~8kw;OWOFEQuJ>7w$`^b(d#0yFJ#m#J%-6~zrRDQvo-@u{(8GSDSOI*O0} zmgJ^5VQpbL3OqYfyx4Ae7tr+i@7-Ui6nT1u&xcY)Djk<ZhWd(BbE9X7dL5zn?m{Sw z-Ru?Wc$b3WS?#|j@p`qf7Jx6<<y`_J_S3RxIk^we!;Pv&UnwwV_VWbG>{*(xOZYJo z>S5;soT4hyn=ylVxpAZ4pl||k2*TpJj=ga0j;4K@e<|6YxLEo;fE+u&zZj^`CD%5= z>5hD{FQFu7*&JxM7-ybzb=KP|Q85RPr(d8tiZNx|AmiM*OR!2NTjY}%dYVFR>*bIn z$?htE@HzUX0{i|!QR$Bk70`VFt)pE?Icbi^m7ISyr9iE=?G>0eXsIJCV&DfH<~uaC zfZ9%I-286sVl%xvzq|v)JF=v18Q=+6bHzW7{TlCoF5kOVFG{I89zTMHB2gZUP#)($ z52)ObwdFtG`0mdqjQ6Rc*m!vyO2|6aUG3cd597Z||I~8$oB<HkX5l0D<h>Ib8guM! zcNFQj*5@zDzPGdp-Q8`8_WaeE*1n6P<fr3K0_7}}5rJoxA}k<fy(Spa9ect%5PM<~ zA0Q;VuITpu^g@WO=W`UhdT<?vnzE1WstRVA%e|OFT)4__BAHgd5T9=g!u$==L68HM zY>2SCmAg)hnzeB}K<E3bv6Ocxpb%YjMdI^X+{eZp=i%SO_&N>Z8ujJE?4>}AwoNyK z?1G%^Zb)uIG2`G)Lby+LPSDvE_s}n1)ZF5%{QD@XdLu>**5J>B&-RITEG<!6AbM>I z&30UL>ko{0Zs8=D@`Ohx+R=ZAY)RXbtKHs+RH_C?^A{kd5Pl!k8D8pXwRws=(VVat zCSv*~G$dhdowwil)KZF%6B%%AuIIUsG#aN9j)>d^=w_sT`&p%oGsJkK(11%m405Jc zEDuuw)i7+I`@QzEV%E>1v*%@8m7YsyeF;dOq3sX;=txg3-Qyig6*%4a@^cBNf=cI% zjzroNU9%BS!Fd8=3Bjpz$=TT7p+#+w>u7XqqIW&u1e=kicBgn}VkxWyz7t%NjJ%TE zbLwIpIN_x<mf!JP=C;1_BhZVrX#FNYRGMQ`;ix!b&gdWKVcl}g`Z=iCG2Dr_8~V-8 z-{y5yValo{{i^<R-Q4zlEWGumR%n3BigS8b$HG<uzc0sffc+os8j@RPIX~}w$&LwS zdxKh^%fF}83rmWlzu{8bbBlT_=YgUk2ND>W2uk{U%YHc_zTu!bMj5!-OiKFV=++LK zkD{$af1;a~+}+)MFGC?sf1257#cvtqXCeixn~|?Rzhsm$|LoY~q-5y8&r~b_2-{KV za|UpS+rH^LS}2-ippt)=F5}p(Pi?s;OV0w`T+f1~vGz4}jR#W;I82dTOd-*@mX<|y zo3Bxp>z8mI?RSt6z;OagwbCoAH8e8*Id>E6e7?e&lWR75e{DH;Xz65d=UqrCS6e%b zkT~hhn>~S0h#pO$D*{_{fn}DS&O)DfL1cdEgktKQ3(melc-l+;X*!^R`~WNO*-$jc zk9S8d#Q5bh%RvPHUVX>;MvwkCCZmRBC$(3{-VZy3jQ<CirJg9oLSQS%+au{13gKhX zhci*FI=f^T*~!Eec9Zd3rRi0}I7V)+ol0DqaW<qH0@k*MUF1i+>yT#K!4xV~fgK*Y zQ^6t_MQ>j{=m7&Co3>-h@X+R_z9|>)+$GaM<&tD@;1>*Ym;eD$6+qHxBN3fQPL0Vc z9MQ~j@lEp?3rXEXw8r;ZaUcGW+^qLITU;;3aB+E`JV#Bwcc|a?-^tf+F(8f>Kh%oV z)QLiX8@xhEz473Ro9_A{WQll@%{q`r{P?O20CIbI1_mVWla+DuU;2AUfzRI-K<~lX z)E8V#W{lJVLz%@!T-+hFHm=}dE6?%$*P>HrG|21HyERZ2iJ{*e-V}54x8_alc1iwO zqyg%yJ3<(@w2Qt~uXv0ED7!&?HM3dtmU=raeysC8X~wJS6U>n+7fvsTuKOF@N>mA{ z($P0p7GNg#NZy+C;EnNoI7f(?MKW_n<zR=Gss_TWLuElawqy}wkHHo<>iH?w72=wa z>0`L$`7Tn`n?p_oXTI3DjG9eW;~9na>JzS?ijM`aRP9n#Iud8w@Ujsx9b&d~h20v9 zPvhdr!`-tr^P-B#?hd4rU<IV%Ln2(7`@bL^vyXTdt)TM%I}TIC-zVOgzL&FD&yE*= zQSv~cQncIIecL4a_jYP@h`gD`cOrm9lk&bqg{tt;Mt8?h#w2rDN=0s@s_<|TU8f^Z zF94&_+{Qz`^<5oo2e{YD7xq?Im3~KObG7p#D}1yew=s5S6)&w=7{GECJ8l~2N%W>? z7wJ+d>!Lff!06~Tbmmzb5%gGC6hpyKHJVDZ0c?zuZ4(A?Am8~IzPQ<I+dcSHZX_jx z^xNLxc&wlZX<v6@fz8ePXFnc7t;6HRBXvmKIZ#PArz&+GIrn}H!ySnMYGAWeYt1S| znr*^m#qr&-tZpOrM=Gc$3vWT#4QuGmY54zdsQi~F`sZJ|XOE$mnFiTvMZ58@4`jZg znc#n?RjU<vO9-?aN(ugp3lVTbX=`f+l#?ZZRx#xr4-etrt<U3P!+R{mZlk$TscJN` zFlBvGBHJ+0<acng)?2q&R$!w>c0_!~B1=4$fEFe^fI5(wTk;1*FeHF+pP5a1N6=q- zCk3H(IWDK`^p+!6LH~Vmm!JtA<Izy~wh2#BT?z)bRQu$v?Zdf=cjRVn7yV<2C{bd) zNAf*+(}boI8(P)C{z{Adn2mR5xY^;w+Lt9iX-3XXr}wW<0#Spn(tk&#R;h&|j4)4} zo7XiNV}TWN|JoFLN^EThMisxC&M|**Ge-|Lu?`m`%m(kWC5$Q))ONjELH&X7Y>rj4 zyhPm(7DMb)7rSSp=GN(5)y?+CPqu>~s%T!1!8&sv^=hZO><4K*IP&4OYK+n0U#`gc zcadvbX7`8DdeH69+pALXV`cdh`2vS`+xlEyMs`z(?ddie9sS8s<H8u*k%_v~W4)k; zHHF9aK}M4l(v3fsSWpW7!NiH6Wj&KVY#=6&(FwPi@fZz^CDd7lRRYY4QsvMhAMq?j zvQl*)eXq`Rrfe=B<~IHESnAT6B`5CFy2>fM{I?&TD;sgJC+%96DwA)URO&@@I6d@v zEXB0g6K6$KsW%u<pl=a8rXjjKs6WM_+~Ber%~}qVmYcvcBrz36OseZVs4MY*XfL#I z0-%6cSv{Gd!F;)Ssq~~|$V;kRo)mE{t(woBCE%AF#pbri$d6@Hhp#|3;$Qj}-jcV> zT7OIB)#1_jo!l|e1aN3iql3!=eYaYa#f_E(6jE(7e!QmH+WF|WFJw&rBq}*gf^c}o z2Cr!m(2uEUJ%y?1RN`nq-Bkfwji@bf54vd<bUO5Uy|}!x04hmLyc~76)_=d-Y&R4m zD*NswhSs$-7I4jogZRmRJjf%=G_-%15J|agh^AT%&13xUa#^&f#(uJ2J<=V5L+XUu zjMP?adjQ0xrKkX@wLLvJ(FbvY^Jryw3C(igk>ktX&QCsQ@f1Y7t<Mm0yG`)kIScM3 z%k~pr+9x@XF3GdU2?K!~Z0>616nbRJNT?_$u3z_xzJ7s4r<>dDSOxhRP5^fA!mO<d z0^rEJ)Wo4*q?gXsC&po)`#Xv}`M*)5eJ<9BV@i#i$o>Li#IoyrhGOCOY(r+n2YuBU zAp(#Ov$#Xpir)*rZv*@xNgO#)GGYIG(0R-FgUmtN{k}KYtZ6-<kGK$^P@5^)_?@s` zmq;-y(V245GcVKE4s3s<rQE!*7R-_|*=-#q=?MMKq!c6Eo6w#>%sx`Xq3sU_0>}fS z1Zk(K2dr}KiJWcg7#u*HH!im%gDhm>Ccwe%k1E}0%#HpStW~B{l5rP82W>pU9soe= z38q~$ub%2Og;eto-zGKlsS9xBLBP*?N--uuCHt?ViU>hsXP9C|fsihwz@0Zj9Sk&Z zrO=D2Tu5zv@v2$&UO$i;J!XOF9I!{KI-_MtBCkSmLHOHt!m)k(+1x&@WxUqG<ySFa zDgoQ>$H%Ct?c#>x##B7Z6BQv;R5XgtH7jy=EM9sb<ET?(6(H<=VYQ%+GULs1f6Hwe zI|J!Nm%LfCq3$S>25TCxl!AM`8Mu#scWuz`?;3bcy0aK2jKs1Hgs!I=2jm?pKTtO> zz#EFFJS^wDYO4i{h&anr%?*mh?042Su-8myi_sU$F8dQ7%GsfJluTPYy?7+w;J@g& z?YJ$dKk5TjBi#xOrr6!Ci`F7u6Yb?Y$`}7zz-t52p60A3P;%hUHHF}K*^9eF8;(Z~ z{5C{r(FGE|iR2UOESPDZo@gLr#b5*t7;cLHk@%mU(Bb{lnaBRGGwWe~Aq11a-coq3 z<Dpp69uOInr1pIt&1Vw&xZL_CZD~hE32k$VpX6a8_oO?hQ92oo*;ftX6U|YKo<yJk z6(O1-pBSU&c{`L^_v!4{CZFQZI)?OUX6s@X^{s*roVEOX_~pBgx)ED@KRmVTv`>Kb z!i#5NBv8WKH4Mhv=}H$_uerN|+`Anrp7*|`kFVp<WZoHIUbQ;c-KiFllsig1>B$e< ze59+OIlxdH$Wz!bO2VkZnlrZ7om8)uf3|Sz6pO&EOo&}86ewfNQJ>4b<_Z~?u<ubU z(uw*2wT*Eu-~Qu4DTGh1qaPSCVjn`g#nbVOi2F~Ed^=Fuw5v4cb<@NqzM{%@QPHgL zF`Ao|##6Hi?JR+>Q@k%ehq~r}_GS~(0L1ra`j+%(((c9N0y;sdnf&s`4Ds@c31h_1 zUdn9DrmHp9DKNrW8QN{<7NiC{!b@q!_HVnn^ts<&XTT2|>BjQARjwDtXIp`2`hu+= zq?j>=#@+<luDKEZ*~_hbR-S!`=MRC(zj}Nwh4(4*t?|ZU1qxI3X4q)pL|@&HCrjxL ze2>L#3Es~{qEG#N$u|3SOw`sS)f)QzHDp%ri)uZlN|8=IJZ6lN^a<R+n+3Hp4Ez3P z@yi;{-FcyClvTN6N2+667|OFNkQ3p2I?hzi_t6PYLwYuAYp;e(n<ZpYB4i9=O!4`H zyuF^}J8-R_OM=d{!I_W2LCv31()4Vq^^z!zNs@e<GqSvkLEHs_O@KN@MZs2g7716d zd9U%lDC{Igu84#t5z<9;KtA67`p_k3vX@RgDq~6CzBC}GR&C~z)6pNda)EBY*>2<q z(R-9X@t-!Ue5J<z2>;#V|9$uv{!yB+;>CdFc~+?5^wsCAvM@jtrj@LWbl~gI%XbfV z7fGhWH8PB@7vPj{zbLLPBF<8eyv8*MAabCf$7<xp`7;E`1eM4Yp&B;^+Tsr^<Q(9W zsb6W4HpL&9Z28dT34I}$29%owJbn?`ck>LZOT!6Q9uk<0M+br9q0isBx_oy#j5F_j z@T?mDmWYD(pxFP&VbF;^c#Xr>gjW((kk(+6`l7%ZVW!ch9(vdHDSE#%Nw=cxoLyGL z_LuzdB0B$7S%O+gjGgwla~q;Vyf!R5!|zP~{4)-{4Qo_`B#Tci(VzWvcRg;mo%bpq zO|K`u%)LrPnb!c<{KcwGQG2rmtwaV>auQ)45x>tHN3Es=kH>5$#?~&bv!xPE=V^Qg z_|$^k(zHdm*A_RDyw|#7Ert^uA(g&s14-O2RV+^23f)K$fy+2ae>`hSNvjIsmxIFu zV*BB882L!f`%5{?*EhbXk+=RJ0zNp!!1jx}IsVSHwR;MMOI6ymBo;kVXrel2$vye1 z6&9NflaCgbr7P{lG#8*ff(IT7L75+p<bpMoQ=a&izB;+h=c-=}OX(P2GPV@`+h$=Y z&f_^suTZ?65;MU!p<%QFrS$OT!zQM7`P++wZ*(-UazoM8<irqE#9+31q0)4XwR+I? zF9vmX>+!t5Dh;YQZTbr(&)zZ_T3*Jc=_0Sw5A;?$w+3S2{O&`8|4OV}p%~bogs-{0 ztUX2U<u~2+YAYuMf*rYI!Q9>=A&V4Z<^8)tGmruyBgGLMUJ@>z80(%__hRItbt(u9 z)R1yD{=U4WDI^>+J3E!b2{|8#y&Pps`~httYdkP%2@Nf-aOm<vYs(D!T`#*mpBv$` zBkH`gvF-Rc^T$^xTFD&^N-=OL<o*8?ur{iFJ)HL^|5w0SctsJ^K+`8W_~TSqJQ;~1 zv^hPZK@u_AYY{(K#9*<m@=?;;_Z4KoB{m<_9T;=?p}xO<erT-~kZofW3XmOQFV3UJ z9_S~^_WgBdRFX7l$@5_<cUItMd>8fa17Bk&IXr(rn*fgWH>{xxr>eP_Yl$esD79j> zcVVjw1eNFQ+-EY(vWG_rG;PBwg2yQ+D9iev-dW4q#sU(uP~`SV3x=%Px}|2+IgOOP zc#E@APid@?>OlW7vv~DWd7!f5<Qu9yY{83v>UccJuk`RwHxarNSjIE2z4Zs1BZq*G zf)`%3|AGKn$(bB6TMFX!1>J|0SFE3h$>A$x;zoO4*s3g<dwv;qzKZm##-Z_>hl^w^ z;uG0$3{=EPl<>bxz)~aNdYVhQ6tqH4vN}<fSb1C<<3#duHOJOJ;;{6^33xzywLyNB zo`X``nG8F7m$g=)glgMI7cIT8xzp&QHMKsyiD6VJZ#H8E<r(W<(9GsEm!_Rq^#|ym zug~kA>DsK52rKw71j1h?ECcsLMiQ|KG((w^qz-nAd`PZu_rDNHx(UriY)`);EY7j? zytH6C%0Mc4ZV-Xq_@LONzg%O37CO3fAm$y4R+B&p=K8tpkW!J8P6Dg(&W;CB2AcgP zC?)iI$T3Gl5w+vu;e5T3$Rr%Sk)Kgs%#itJsG2s=t&b|?W~c3k_V@6@=hRb|N+^;` zYB;VyQ?g}yDD!-xGje5Kzf-7XR?@A8gpq@VA4enM)z2m7nMw?Oy|y4ngo?k0eFhs0 zKo^us_QJOR>D2i=v6iWOWH1DBd?w=pjy;jhpTJSu;pVxS%g($2VrN5QbKA6CCW{s3 zzlE!6kIuD(-DOAQSLf**Qs>cqIBh2D`^xg(iTYpAtBmG*^ZvhH{4O9a=Ihd}a(NH~ z03jFdj%tM;1DY7scxba|`O}xyah05o)ZQD$(j@MjLVtYXnP$C2W!domtn_-KjB3W_ z<FEJlygIKoTLI4Lv_QRsJV%zey6kB&e~9Zu+_6_0!G<ov(_smch*qcbOstePi_R}* z#3!exd{}KWhb$l-<oiaW&1|Zahp7ZI)k6CizbF-j!TEHN^nlXTBl+}b9fBcp%WTNq z+J-Ilr)r4W6MfYdq^cWVPx|u3)}h43Lc~F+yQG|T7*qD{(t7XhiA5UxjnUjae1^l8 z=p~+omIPQ^vK6&az#&ne*{1qEl1g%uPrq_|NZMKQSAT8O!K;#KfyYC7L6D-)Nsael zRTs27EWwM$hh~DeTm7XihSd^jc41LeKp?!09qmxw;9tyff!VUMn?Z_wOKoW&^9ziX zU?1Aw^>eAVrU!!y1$cRYfb_<a*S@SScTd|)?{yYVf&jpSqAwb(lI(&yXw@1#z|z^G z3&AaYt43RJi>0a9k#=z;#qU`{3xpQ9qKSv?J-de3vCnlMNllwYk;$U6M8jp*>lKpr zC3wM7&=|Iut%(~2%M<uY%5R`0g#mUK@RvN|l9cz&a=LeUb=Sw)qsL4TDXQMhCaJ#^ zMV(3H<rh45NTI`G3qRl8dS9F|hHR!k@_P9mm530G+GAf0A$7pO(m@60ns(q{^ZQ(} z*V)Yk{``qAblOXEb$2#G6P1^*-|Sun)X<NLDN-Hzw!_bP^wg%2UAj$)+<c_Ur-o9f z$06m)Cm8@#tUH25eD#t2ke>=v1adk)D^?Ne?fonuk;rj(O$T_!2q&UG2(j*ejcx+; zq#7q>P-IOESYR3}?s&vfy*t=3_3Qa$hV*M(41U<uwiXr;XQfarZ5dViQbArm<4(R* z{gkBiF!==$V3NNpBdwN+`g*qAk;Hqrx*aYPygUC?LD;$f|FQQKKv{0v--;k5ARtO3 zE!~~c((%4@Nq2Xn5)vXPB1ktc-CZKx-QC??--C*tx#!;dKmTved^6w7nNjC)zt6K{ z?G?Yh*4leJJ(5tb+^Uh(>t@}bBFdqCVqJ`?Kvdg)AKgQ2M(C$!ZzVk5^AC!h<2y1D z|BXyYWFv$jP0#}*X-v<tRdo#I=?4PV17&xWOD;o-5)^riGvL9+x>a6PFzXEY5vsvp zk&~)NKBf9PQ88X0S$7pEJhDQtEv4Qbu9Ub$^XHI+?;j@b4ZG4`4;_g!4){M+4}X50 zdbt}Zb8td~oe&3BTY6e7S~K;`k@DK#&kTS}=?cH(K_T~r4s_<*rFW&W;P;y@SlO<@ zawCWQy8%#kMmYgc_eQQt1@uDLLW0<`@WRExglg1xqsdGH3AYYR(x5H0OfbO0Zd|UT zf-74OIXqNqpmcL_^p$W~I2|290Y$JuHnSWe%~4R7vKO_ENe$(cx-;z>rt}%ZvTBkU z@chJ0^slgAg&jH@*}voM%1QAdiZ6PTuS2FY=_r(Cs*(ZKJ~NP04NG;!{;+evB-#5? z*+z>z$d%Rz^&)9-<cZwgxGc*^h*0uq!y{vC6wxO%%{y_zicXhy^8$JkjHCD@>c*fa zQbQylJRZ+tf7&mj^KWPm7=lW+bmQte>hVI8jr5`7YF@)~PCt6Q956XjYat*Vr2?a< zyRMNQu;xfV2l-Ou_zbh5T9YaqduWRQ42N5=5)j!v^_tf_=D~vTA?&kL1(}JItniJF ze1~Q+zdI_+80*IaSm9^q*>Bw%WzTu&p$9C*_0`a`ZE=^~`QKp3bAKj4^XGzk1ZkQK zqmM@ynkiq7ZIEJ{d~|TtA9wW#IMxj9YA>Qz`zv$`Q7SjE72Z}(RW-o2tGD({2PA9W zpNbR|$Krl-n(~Cxd@xHSUZX7!ilPE9O%$<|-iiu4Ha3mtF4=;Ec@C0Bc?z^KPgZ|K zkmwn_r05b|bY*`u78{UCGl(gqOsR#*rW#Zh7~3uCU?>{f??fWn7LoHgq@%t+i0g7* zTUh~L);*TD0=j)`LucDM+ndEe9KYWMe?5(}Ch8v2VefPTacc_p{K~G6h%|xRo3!mN z2RPZxJi8{Omi%u?I@s0)5s!q$N&<;mC?91tCq8e(24xExn3ND9Zv}@1+x9LB*x!51 z|2^6bSE&bepLXQUSIwnLNHtS}6Z*0Sa;KkXSlwF^?L`6#5Km|(|MVZc<$K?~<>Az~ z-ts$uuRJt5Cnu)~$OKO6%}~nK%(D@Q<8?1Oaw_W$d;bnP14C;u^HdDyQO+CfA{jSL z$a@C|k7*4VRTF{M+(n~7M5g>cY>-E)R-B)=hFW5;F>L;RcFHq1d3O`6RAR>qemxZI zS9TON@l9$9Iy|4u7c=|yq-RNzXK9XOi7pnnXBsxwL-|}2P!lfb4$RLEn9C^@!X|k; z$Q3U{s*Xe<JxdZ8s?7)qS&S&Jf(X!_dP6^*Ic^%=6HPFIs^YdcM~E`&f=z(zjIxVD zbb)hd)yh;S+0pKeX%MZohU|<De1&6}+Q3Lz$?;dYl|n9Qfx)_?#<IN#M^y#*s|{W^ zC`MY7S0t#~7U~>$q^8Bq311X>=sC|_^rj~o6j&s4Z5i%g9|RL+Kp@+dsv2C-qkN{X z$qtcq#!V3!w!_WEWq~ZKW6_3Je9f*2m_&d_|13GsYj^$9X>)be$-MIH(Px@LP$kYF zD7(A#T<#)M`txF5`(qJ2Ro3T+ewHuS?#;H9Cs+vP2|+3~_2Bta1XkfPWFaq^PYzEr z{6Rt~&$c_q!UROAiF7V1Np%K<Kja7uzFfsj<DeHRkfPsT^y_Kn#6RpW6?(XfQy7-P zQa^;r>+qEJ6NhJ&HH-mYX_L#tGmaC&Dy9Tc<$?J8Y#&*$h}!p+v8<mZ4fw5AkZQPc zagg(7)9}jEpysIyTV~U~hcEmxck7pw7)+m++2pV+B|l+($^S+bWQY%lDt7Z(MqurE zYo%4(C9P2{tRieT-y)Bv(v&TjYPOsX>BY<mYP{^>N&aGsePEsE^|_Ya+5kL|R$xGH zMVw~n4+eIsxlpSVe2eWk*_~%_KeId6tj6SWpuPfD&>2#w!@h714ZcVxz@ddtb~i>? zR!%FT_KbTk0DsUk4xvm-y+t|aFxH2s95KBIMU+{d9#D@VTA+yL^1YNJw?&D~*h^y_ z0a8ap7~RVQ6T?x_OBElV(o~{t(zNH#{31PGDr78N!yJ9g`Bqde5hF6|3fmC1=fxG* z@qC#fbbhfjT;~qk8|WzPLS0HwxJiNN7m4u5^<5u1Or`SqG~#M7G44b)`aby+N+^YS zV|>;ZEQ3qpji6;^i*5T1`gS||c5G(U(U>>Gr35-J<aj@Q!kSl$dy9HH@XaG4+j*ZH zJ{t3<!>A!n6L2R2PWzibGkU}`$5;JSTDNJRckVyH^a`gEoD&yJHo=8I0)kpeKnR#M z#_4ee_H!WV>o@?S^N6r5$YG#5_GIV{#5Z>t*a!56@J{e$E1KMjIL!;p9Arq-`X?`t z=sRQAGBjJ4WWwoL(M?PBWBeGux(xvZ?Qxt;%79RdE8V@_SecF!Ja5hqgQ(#9xJOl_ zfXP$)W%AUvUkC`{oZLwoKPt*J5kWYq>a-c27D?zndGD2N@LZMu8zf06Ywh7dd4)-E zBptUmFEXk+H#|6)QbuCyacGj_%RY0)>|TU%Tq4o!ujTxw?PYtMh1li~db1auhfU>I z4~~e|S(mya=`7J0QsqC%qboFRKzO1lUI{O&!XQBrB%B;sd`^LXUYyew46?X9f0Ji4 z<hGXr_lk=hx?ViZzdf>Dytg^WEHjX7a%z8521)p6pv93<w=eMXxv5|g_8Ih1R{aXT zpnY%FVb7_p)m>KUGGs%@=GeCS<{OB&4XUtKntvkRpedNGxaO01UZJlzsj^=@`w@FK z!{VrD=w!*;z{swurEA(ZesE@5&*rvU9bQwu8T3FgL(F|br0Jpbt^E<i1xAD`4i1P( zp&M0XphMrpTpTvXMzzG)gfegPd>IV8aLq;wV1P6UVGAG|sK{uRlORdn<ofDTBMvJ# zEzZM*KEi2KKSH>egB9h#O+)Im$cXnIm-zdzmx}!M{?wCa8!8I^N0+JPJOM`SF_j3X zY?xY@D4xuOI@F%XcOg-gh#_Q3-Z3pNR)gLTF!{!V*B@<?d4;2d)Oodre(g2ldC!Xa z<r7LhpM^xDnBc<NX9X$eItb1Fq7Z3yqGeA6E?A3DbPz`k!8}+f9Xs4d;=PMSuTM8a zONxo<8ro~uetr)4Oj$no_RpChkdz!Hq@s5CZk8)M?C6Kd0Alv)!=?hfMkCKpg?M5c zKmv4)8R6a9AIqIfB5A%qSR)(so7inQ>rZPWZ387zz)4KpkZRS0WjGVAqzO+30rE<Y zv|XzLLBUT4NuK4<2{h`C&LT)0ZFt!q>l2N0TTraW>MPr+xh`hdW7WxXTv0B!_PF=@ zBIv1M#7TaLF<m0AorcaXfDDeO=W*^jmbZwTk~ABU>Lzo%+nqqGhU^ZJG-dTFqGgdX zHR&#xl_uLfPNnN=exD=7kfvrL))Vz9qyVFQOb*m+!&`1s1gfzw`q-foJbl`sV{koD ziPoz0fZnoSu0R)~qKrh*+*K3EwHly+^017i@q7ds$`~eLcol9Ev7bD)Xr>UI8hBnM zv)ez67|Os%5^&&>e3_<CmA8}6@vbfQW!$JPBK^hE`T_A=XLFRSy)Ul&RbXHPUN}|p znNH@cOgu?$(jKV%LJz4R7YiFL6#wnX_PB|en+vi{YM0V|BrOL54-}CH_|N9rQLL1{ z#6HU>aDD=rgVTAi;f#oge=eaHF4OOMg!k1c4^dYtopMlWI-CwITf=|UHdQw}@O}RI z&bgk)C9uJOhan>HPD$;NQb!EasNCrQ<7PlUO!>)RvC^DmW*FqK<;<D?U5u8jf8~;} z;$e|w5Xa)h8K-*kip6W4x#_o`Pr~1a7YbPBfrqR%`#tLu!&n%bt%_BKk5woaYf4Ti zI$~589^!wI(>rMB7#B&DQOn>4HaMT78kDa3I@dd7JU+_-As$jjf1Dm3HRp_U_wEg` ztlL4hAd*W{*gmdgtqGc2)s>wq=vsTm@c~~znlIx%F7Z*Yk35gFroVp4MXdDOJy#$G zT;-scQ@u-Q2Amkw(s4?iXq)95s+`Y)(wSJTm0z)k1&=EVKuUbkGTaJjG}*>fUn6_q z3_*GuFHK&$niC?A({?Qp7I)x^UtI*1BnR$SuqK+8GY#u<BQhLBlj}}lu5BMD6m~We zFgb+m%lP#v9`ha;O8U#IFq_Kqdho548s*|O<6}QZCu-VDLjVguP%ROV#+0YD9NTSq zE7ZRrlqehHd5Y#COsLv4!ZmWKqYm1fdJ{J1m()c!!jjFFdfmOvkf-EAzihG$oEBFw zo}y61J=3MMtULC~N4bL14hm%DW*;rivBlfTxmDv}n>EG_o58dHS`bR^3}2rXtk(a$ zG5vEd7S%GwT=$1%cFJ_@m&wH2A?Tr8?1;hYLkc(&SxF2`B9MuKN45qRShgUGrq?r~ z7mpT*kC$k3Jg75;JOPWfM-G4T;`<hcHFEniAb<C#|JeHjkjD!+ERugZEUd!Ntq{O5 z>}#*Y2C)j`j=j67@^jY^ak(EvJ2av6u59Qr+mQHCEvBc@1uX|hB|6(A%|Dr%y+cWL zJR6vc5)jhA(@=;*c$zhK%GJBy`)*nueV{o6TNLm`0LfNAGlqF-88sSFy!lypCzXOt zMhW<@D9V97yzGVfxGb7a8ug~{?<{(ofWS)g?>kaoHjstdqJ9bCy?AzT5pBSpmY^%> zz^y3a=279vhnz?#%~eD&c!)FiicBhz2{5287;Ro1o9%Q0>)`7HUn4Zr=x4SJO(WNh z9=KudhE|<8Z1o($ruFqR)Vd%%xEbbI#~qwex!6(qZ+*+hOYQg0N#FIj4Cf9%4DJd& zK0Z+GAVnY^UXoFaKV(Vj5GAsiq$C=iXP)-zFddFX$-Caa6Bee&>wO1muducJ$$a8t zhAF(^x=}H}4<88R_vEkajJAr$r>8$t<{12Z4V;o0B$p(T0M1lAIa|+tjiKmykVH_P z_?8sJ0x5WhYph6azZs()Tu_=5HZfkKy+!j8(TuX3fBt$1eU8}mLmLl)PIrxa9m*G? z)j)T+mhPqH()YN!iIVav8M^N!z#{kb2sFVOZz0+_$~J|;9TQoB{NQz^@h`cVuQ;@s zO}vvKDEV}&enz3x+b_*8NX{zN)l!Sdy_25)SZpBpZ;1bnev!;XerFDEx!c49dZV7F zRcC9Ns3gzigZaPu&Wp!Wsvm+cB;9IoonuVNi+FNot*rozpG5W(<FCol;lTpT#{L)@ zS74CTM!jMg64(5dui1(;Z;?)rL3=1_rclw5J1}g5N@H^bpqp$dV0%?dhXQ-gM74M4 z8e3Xh;R6)FxpY-KP-jP*nXIG376RZTY*TA%2H;2^!||JBgYWQ5TI2^N`(S;@VR*~o z0OQ4d9|cpg>>w4zSm+)286dV(53D@j1mm!cF+Y<pmfQJC4h47%h>M${`_*WNwmU`J z$3Rd!6w(!hK-X<<Z2|siR6aSdmxqCbKVgmGjdPGM!~>Q%rvl!zbJied<SlP!Nbd-) zFMtEzpaIzV&0N|(JNXWP`E*ZqW|e_sQt*t;-#{iS>>GfCf~{IfBStQrpZ}ycIn|F1 z2d!uKt)_mP*crO-5lBPP+bB95+R0jGF5vPf;Rdc?qQ4SwUygB1bUofm7KCaJ<-bFP zcopPs9MgNTF24}cBAT(9?O5;f2*t!1*WK0#m>Klvw^@GZ`C|t!ZsJ9NPYaHOJaIN@ zcv*M#%AhP!<&K1J(DSz#LLzskoEJDrW)ez<9sr?6X-YuX#)8^ATk#3Kl{B4Ue0+SI zE)R$E9X3_%Hb#2wlS`*u5V5eZ%9f%`cYt$m@PXi3b|xOqPlP<9_j6H;r4(lisD#@f z*7f%Y0H@$BYW5PD0TQ9vJa%3a7@1cQdd~|!^$Jr{px+~1Ub&YNWkQ&l!I{4k3ytP= zt5V>1_N)*{-orsZ0|f_yCk{*HR+v15g{YY#!V|lNKW2z{y}SoMAP01RsMkk#<Trg~ zn|}bC^^va(>c2XKmYxKlW>1$!p<A-wu<&zeDCH3v7-xORIW_f|a!?i`1)6LI5FkMF zx$Vc>z5CYqB(lx$&?PU0#%q=s_JM`vR+3R8O~`g&#d>+ditRCW=k`kCAm&w}fhvwA zz`4Id>n?w2pXx`b#9qG<6X3WXdrJUVVh-i8%~#!*c+1MbFVXZ+;7W<zZXT_tRu9EY z#vVna6$>S~kW=Gw0wiYdx`qEdU5M?oz(jDP!-16MWqUZ`4Ox@L2bs!rjg>D^OU$m} zye*;XR;8@0Gl$sIX7lap@`29Hc>`K(HxD7m`*w}v1&tO5q|GMFvg{5=G5x{!?F6jr zulm=cfBC+DQMu+e6KF7EF$MkiDE)D6+(Di4^bdcRi5dM6;y0QG(!lna+ojc<?{^_a z2eSKq2=OnPoCy46Xt36&2<cxRh&{Cc^awVaL_Pl>$`XFWP|;l?Im$nT*UjE>_;iVv zl9Dn~o`!IjBbuCIm6_Rm6fGj{8hVpXf>)*0YRcY=f2Pnq{o)``$OR!xp<A$z!v3j| zFQBPr-rn>{=J{LHTW`#5Z^i1K-0F<8f+{;8JNP!;%UbXzETV#N{|{yGQr|6eR8M<H zYs?#Hhn&ce&`Yv-=A{YPM7;((yBAUc#^5i0-VjRM3)X?8UX@^z{_qlV9Pc`|bl#oq zo-CZ`x4uYgrqEM#nt>LU?oZ6rG_8=vn0xT|0bLZ2{2ioYVEm1p)Pr`Q?Gjube=O3$ z$wPyeq958fm>7)FQnRD%55D(9NPO3+vmnZE4s;pJzDbS%q6xKK6+BQrSf5d3JPg(D zr;#qTewj9uG|rinXu^|4yAmYv3<PX?_k~_#{I2s<ewm$L6X-_x)2u+~+9k+;5tZa2 z+l}CVNzs1#yX<|>4-tZ|?uedf71DNu5910dGMsRAV=$PA@>vi`)j6=b!!@n?>H<eZ zC&fHGq@YcmWc*mv1(m-wn*#GRthbhJNa;}$sSiXHfob*}rfo`i?KSMH{f*IGfsS_L zgwE4T!zupKVU!m*J`ilosrUR)-@S7fSbrm_g>Fb4Y66jX%_L2r@e1tdU>$e4yiPw; zV5XL(TJ#(ONyX2Gd=vmXj+ogK%YKj@%tjdp2!{6hyTA-QyNyKsqRjuTG;Wa)$)4@p z(UV3V6wiL)rg~<TI`ZlM>O$@_(JhQ%^%vmH$+tY$kftX$s=H^#&&cCtyOob(q3F!| zov=0V%UN^d7A7hPE!CI61Ez0JDPF{uBWJVShk}Eaad~oX6s5w3vx@%yXr}o9BOUV1 zuku)XS_y3*#lzosnMJgHA2^u{7Il5=A!K^oFF*!4agA@9aP{C!O!|~iULL!7?a=|r zgzN2D0B(;@B+o9VmC`w_FufIIo+lOJ%!Cc>Pb{BK5<)|Q#1miTgho4h26SwH@SMHW z=)1<*b%mT%KMR<yV}tWY`bL)V+<m6fGS73IcjHv3>7zGxj60{is+N~;@5%k@HUcfY zy7O&!{D9#V$DD8Ds&nDWIv&VwWY!)D9SRqhE8NUx@pjBQ7cxAc>%s?{__@f)!`YKC zpB>v_>ev{Uo6`K$*_Y>*Mm}qudVtz4vRI5g<j|QzoizBm7(zaVtk0MMdUZ#<Zu>HA zxa@D8!FU9)?GrNrkK83WLxPb?cuxusB(S$Q^V&zhiMaI=u)aj7rzrB{Pr}HdEQt?~ zr#T+B`pz)qq2H6|93NC6&Vr>8(0{HdR5<l?P}x$tz6IPDrRX0pcn>ur#jX^7L)rgh zP}PjpDsif=cAvQ9XFRm^HC~q_r_IY1ca=?;Obn{&CXK+%d{u&;s!TuU2Gs<^%0l8e zkG;G2Rkcus0^}2-+_ly1FlF<@8Dr}AzH1D^yUQJFs`0%Q2oI)7=M<LHtnZn99>Aw4 zA=}5PVxQeEYuFhqV^GvWnYcQ+Yi57+;rxZW0z+0BoM24cHgCgT;wI*mj3C3tMf9u4 zOZi^Db?)VRs3jgjhFjNn<|)<Z9<9el#0IO>N{9;fX4Ys`J)WGhDP_7J%XVdQP?cVz zqlA)404S%TCvy)=c=uVamJeU&><hl`-{~-qm|qK&>@}sI)2$<CN4~xR398>Mbd$s% zfWr@%v-1li)KJsK{4!tf`6qys4;G70ue|?ICh#MoMs~nxYeSCe9TRBVb6S#e6huy| z>@$JCIz<^ZR_*nD2M(K*v2|s%e?hgg*i{MW4J5MH2lDw{KpSBcCX)>_YQhxd4Om`3 z6i#=d9&enQB$L&A^--EQlvYFV@FlURl3FSqUGsZ~sYb{)Um^aarX#uqBq`v;mY>tt z9w`ufPd`P>eTQkXWm8%xMZbSMG2xV2_9*8dFcF}1M9pF!Tk<UE&1Y$@h;vwrS_Jq0 zM}&qmT259SuAdJHp6I5m9@RwXn8^rdxy%R#eaXY=e#V*;k;ckDD!3`9@><ruE$^r- zMdM!8^+zi$L#tfBMVOdg5!40RxHHEGxmJgXEM2%mk1xknFf2pDLRcAZ@Y1^<P$2(T zQr_QT9^y^V?<XGxJPba<XFzr5EEaWXm*^!T<tVW#w!sVQFEBSLhaqjLzM>?FySqW5 z_SV&9q3+YyceKwJPcrig&B(3Bc<s6{wU62bdiUOnJ%Q1W*HlQ>`eYWe?2+Iv%OsqB zW``sIZfrt>V9%$fy;TNN)*)Za6G?6ilVaK~Zpl+uRX$0@8dQB9N1ZiR4Y$e|ht0QL z9k}F)94Jz$F^2i!jHQ|MNwjxe^YvH6knK;Di9^rC7rVE4n+8G`oxZt{=(NK$&<dp$ zk;%IsFqwH6vz^u2w|I<Y>mpLOl+!zHlYwGJOJQ8>tL`AlM2IKmS_pQhOpmxfk*vU; zlwWIiPkvY^B`$bj%#T=99?t+3PB6FY$M+3n%1I%WZzxY?8@;{L6jZ!Y+g`;3rVP6} z5-2jIA?m(&o?oF?s;GY$`2wqqQ@AY&n|C{mGAG=CFLL?bT&`MWs*%$gVO6aQxrJx` zSdPoswPD6*o57b=TJ{JK&Fedt(};)b4syCdo4bND)6<0IU_@qPw*WGb29W6^A(>zz z+={bOMAVVvSxHuQdG=T=l=r;U-5<tt)DPA?Kbz8q2b*{3;snTooKgO6dsz%_7ZJCZ z`Mnq2Ed)N)cV2z-M@$J|TkFC{5B^Yw7WD($CPYMj;A(|~Zc`#k>-U1ohXfFs%HkKe z9y}jnSv5+=%RtVm;=;PO<eNoKODm|U<k!NShwe-flTU9H=A*wD*fT{fTVW^3XcNnf zf6#PR-Dspj$1L6HiI0;2nI(7Ja#@(}>6<M;05<Ok$5JS6UhcR&I<_5Sub6qLDC2(b zwG^RAX**rrt8sZe5v|!shA;G6nX-joB+wIuSTfOJM>|{%lnt#@$09W|cxmAUlK_So zfkEfmS_B?CFlAgord6?=_LBe6if2l~oE;p4LYK%XNk(d>$VE7a4^LN-&m7R-h#e+b zl_iO%L6?LQs2LWYoW5Xkf)<m`%xs+zK219?<Yj`+RKU9Hvp%gcy<6%jAJp%&)&>uV zLIi`6umidY{B-1n>Ub*EgPd!ndpUhCeMbE`F%`Dq5WOt7Lj&?hpBP>4O!9IwI&h^% znf4X7`!G5n=5rwMR=`dHt8iS>?<lV!<!?mvp#Y*6XQQqUix8JRS!nwVy%(n*G7<MB zv9p0I)YfBJwsD|CAj6DP_6cVcF-%E^sCWo`eI++)q4a|Q6^#50;2evG36RvVAPnC= zrHoIIW2;g*DhSl+v)m4!j4y+g+Zq82R5k+U#{F_NF8-A<gH$_&zSH?Q?XQo;i$Uw< zr-f(1jtoaBbiFGBE@g|3N(r5#u)A~68H^^1v@te;xcZ*O?iSU3YPlkui=Rq#$irpY zZ$M>2mpQFTz~X#1Bu!jNcmYc)9XrPba-h%{6(Gw(jll9ISLy8z_(_wm2)kEvb5&sF zD=1mi!mf3H$PIw5XsB<t(CL@0?cSLi*mNSk!(4s<6?AE@w>T1uCoCDI>;Ix5&Po#4 zE7f)%vcfV!V@LYn%a;e%Cigz_4B#UTmIs2(PuTsIc>vc&FY1j)pGEa=l%i31f1~1p zIl-#Z>PKIuR6|H@pCk^{e|!8zF-Ooq)nVoIu>A8>etAP*nUugFgj<p+^Me7#P2AkK z2aFmP`!vC1h(PIOZ}uuJ1CG?)3`mrYB6u?xOq47YLYkaC@-9~4*ymmL6Cg0eR-gVQ zZTrecg?PH*b-f|c3Uxr1w23{U*%Zm3h+qm|<y&Q2Z+{jrgTZxNijIM&XrrtyS-|H( zjdWElNSP*{Tq8J>(gYD)+knF~lz5#Z3u>UX^!lif4cEZ;L7FGX+7gc$XYHkP{b0Ha z`-EkE@&h{w>yIyy97D?FmuJA~71t@HJr>5#d|y`6H72ij2V$}f#4A>?=xheDA`JvU zif7RqVZH!s@OPiTgLCh{&xGN^uRsfxRV+`EmZdGX$Sw}dC}en5lw#6M(LEP$5}T~? zt(+nP(Y!-XfY6lL2bUw*hAE^hL3T6B=S*kt0Fht=jWW9w_snRY5v=VV$afa1L!3qW z8!Fzi43_+`>_nMgAgn;#x+z$Ww>mpeOE}9I5gg9yPR6kHV0Sr0j&~4(i&H&kR`h&; z!wCbT__4}cnhF`lFPb@v$G6xv6J*M*xU2`(1CN<Bl8-$Ykp?#ZC4YCb1b?{A{k&Z! zlguFA?$2;n(c}cYa6f%T-erXR2__TNF!%mY23#j{lPe*$qQA5t{TRx1n6OqGBdqIA zl);jY*zm##Q!b^jrU}{O``LYR@+AmL?lrP+AkGOM#;YwRW6VdGBYy4~wavhRB7x8L zzA1q^HS*w3t0y3J*!}NMk`vcjv`Ljw1i&dK#z2%21Jkh?)~U(L*+dW(ay24MZ^Au5 zm87a81+K$-oZ!2W%{OWOh%l8#px8y3Z_=#hYoIRc>^s?)N*UZP2qx<G`FI|#I5QdY z6Q~1wXCxqZ10K$54|euQ3L;STqL>e)cuqHeUIuW~=?edV|9_u5WlN7R&yh4N7xQ7% zX1osQ@j;ID5@{)!?t%ni;c6xo{leE6Oskh<isA}o@+QFzpYJz|rMtMJQsTEepgK|t z^h@SDbLyc#i=fPl5ddo!ZmIYPm!^oqm!bJg_R(i|I8A(yL*r);WV|fMeAH>^W}tre z2}@(_ZnnU17ay=2vt29mv78A{vVG+vis0k<P`Po2Lq6Y^MZ`;juR*z|Tz!w-(W^MD zfy&p3*L!UX3GZYF&m8<Ph*Sc$D)bchCgr8!CyhKk{En3@gjFzlcB%?{HrEhe$$;~- zSsaVU&t<YjOYIFLVPdS`K9ZTN-J>Z|bE7vJy1^Zze9WK5=<F`B@Cm>Hm9I>-L7tn` zQ0i=<IfZFYa105iJ^&uJPv0eT_wV#Q2+ZtAFGNpcNxa_Q4A$og=)KBP{(z#L0K)7< zRK!FAgEno3q!(H-6DTvCpJhhFl~!c=vKJ|(aqz3!UU*EYA4s!2iUZ~%;O!h6UElWi zts$)9!4$%%5UBEzA~u4~_3{qa8~?@|=<F71q0|0*y)BI$76@+svyK~0d)lu_9g5<{ zo?wWFcfWL3dnw<|v^)2v_Di^kcm8Fcwd>GmiTlYM6*qCXWOHP=q@lP^&y_qO2*c`3 zK@LN9*{ZVRrI}1=6ohClx&nTm_Y}EPp{wcMe81ewz!!Jf@{O%>?xuXDmTp*b#_JWr zPv5s&Unc|kfXdCUwDaC%!o8Le9Tikcc!`<rjxln<Do=pAo40HH6l{(d1S!!JO4l?K zXxO{qcw+J!2cl^*5P~Na=DL;m8`0MSG6}!$a9L~L>x2L85B-J&>`Iz9pumLtT}HzE z-H~o0K*vPx*!NJD^4<OAXg}~GdMLhdaJlU$vmL&=QQvCtp=)5TJap_A{4Sx~*5@40 zT&}IL0xZq9pFZ<wO4eTZkg)W%7z5KOGEjC9x4W044FH=k0jwY*E-(v{_Ua@>OQdOu zFa`ul<@lo*c#zh_aK?&s=|D`-BQFXvpy2Mr6L4NUU{16pROA!^Cru@YGNwNEsNHir z9fEy=S-ADA`L)5cA(`RKnypMPr6)F6T<fzN%h-#`Gw16_ww}#HK?4PMGp8AoWH=FU z-D-p^MqGH(G68SXkT&zyF2p+Fxh|?_i4P&JRPmdnKF9i#%-+q!vo&V9-9ELIB4!W_ z#*-NGaAP_oUX&_g_hnz9G#)O^AZHE=RX(Kz%A?u(*>Q&UqK#2nn0;T3tiuLx6bAdR z7Th`|$m^j2FGfWc!E{6*I@SuV8>}`E`&}wf|2}&Kc;w>0FRY5OmZucn@J6m0IkDe~ z4t-O%?3!oO%Pi^2NFu@#<oYB_U^o6imao_*qbM1rP1HmBF)dFm1@hJ<x%gIhb5TS` z%?~i95ox#lfn$ZcDQlI}h4V~(^if(&Xuy<)DVh(IYizgRIckDx4iTGh?><q1IVGi9 zhFQhImDw&90^Nz>g9OMfH|Bm1ZyEO~^TznT4E5RNoel<J2%}mS<e5lCLU#6S(p#p+ z5-FQ|lAErq*evW)ZSNIzhUV@WG=iN!yRjZgGGK8+hx>k^;GyL&&BUH7g5>6{HHI+c z%yA`goWKWC$h?=un4S&h%N4#p&hqzq!N(;tcS#r~!xL11gt2m6LBWdg;l;f^hOG5b zn-n;%&YUK0E)6?u?3gP&R_g3JyluP^*qGz<%-(%@g_g5Hiw6Yz2^#qh;t@=t>f4W) zYnSAUI7)dZd?5UXZKdx^*l{JSq%7D`I=eYw!nZFF3qL997H=|8-x<<j@hJ(-^<s=m zXFZy!x^Y<ue0N#+zW5tm7Fga88pO~s;_m&d!X^orJ_Z+<zP8T&&>>p^B;DksWHXEk z62HzPYV`b7Z3#1zk~EA&okM;Omulbc;gs)2Xh{39+XfMcg(UIis`<h50L2JmE-C0d zd_I@OexsN*-NS=S>leC<r{o0M6FeABBE~kA8xE(=%2sOWZRxw}+01Kd!r+Eo$Mc<& zk<GGos(G?A^2CCyq*um8v6q$V{*kp7s2&$F{`R7uM0X+?vv@3who3@Z!BCAub8J2P z*?D(Zxzk<j5n{2XQI*CqG^_n(t4Gp#oq*keRwO@AOX%N-T123<wx74Y5(tXkco<Ac z-Iv?l@NN3?v5Ij(AIKShq#E9K3x^;l7Q(&GQvruAs-Kjiu<cxiKw7xZV7MyqQ58cn z_j_gy3nEzmqHfCmGb<U6ts+HNP<xTL@<D`K(S+tRff0_nr&xtgnGNErpebTR?sGkG zbHWmdJ;vX&Yzcf=m5LJOkELtVdv$?LT8O+X-)Ot9$em}zhi{E)ja*p;?>jwqUuwb^ zX`^AUnYV7o6CWYi8FFzF!f}ytxWhk<*vr<={z>z6V=N$+=}0$|naAoJyz<4NVvpV~ zL(v6k{25XELesOjz9AoHDORnQ`wIG>i?+0TYM0nCEfL?c37aBMwQwu(UEMV>=Y2Gq z``o<)$BMzF#1y+X*JZ!*bH&P?Sh+G@`b3^HO$vd*@2+<wi^IH%cqUroc*p5$5sIa7 zH-p?4IL>DDOuUzL=0W4OV?@Fj$eDv$A)jT8+^&Fdr<L80$@}y-PM!gjyj{WCzWBzu z8v#_4@#>*hGE-FI>S?Rd0$G-wE(TmY1cGq4&`UpQL64-By?Gz~p(l76D)?zl?KE5~ z!z-{4q#AK3$w{_d+o+zQ1{pf{Lsw3to37MG-Q5j7Z9Fb50wg+ioEMtx9*%H>1O)u@ zdy#M;4|ryFbR-;61X<nkqvKIWI5&qogW%M<qXVYi1$9690h*_}vEi@}PnIfs`bGM- z%}_2Un)b#FvR=%9P!VABw4ihASvVR^4R2!N(Qx0DK-b^M(_&8(;Dyj3WCzI{95=>1 zz2Q6Mg@yk<JwpNnd7c5de{pf)Cgkz{yOo0b`w;UxXtXGPZBcl6Mv?o=BbC}b0kFlA zE2lO#H^CIy;U62<0{=cv5__5t54u?uvx@6~TJ==-0hgwdAGvXS2Se%e-|5%*x6<zf z8tN`Iay#=nDIo>LZdyB57~nVK*8tKtfHYRBzt0N*?EnA0g8LpP{`PlH(=QkB-ybLb z&bvSQ4#cZ(!tc`2f8&h*3K;|O>hDL!TK_}z$R7&hAEJL3n*V1R5&v-dt&X~j_7Bm4 z+#lcn9v}Hfr~fu;e{@0qGDbH!NdM^co3nv#60ZJHFaM~Q|4sPy|FwDvaZP{>zwP-$ z(jfrH;Z9=8q^Mn@k$yWE-+L)RO*sCGi_$xZu+DwCw?|j&_ar~{9z)wP1)^!Re};6q z&=+IuYSYj5?QQHtey0cCWU`fQ2mL9Nt!!KJ=OX8)a(TK1cTx;oFtA&O0da}Bb8~9k z|Mj1_4>viU<+MQo|I0dNu171cSJKy9r>`wNeIZ)A&4kf&;wL&^24W2cG>zB$;@e3i zo+K}xu?$yw;Y!0-n4v+?${)*TN@kO4`wS3}fT;3y64M?YxIECL+69TZjs*;c9Z<HS z(zb@N&dX!bjYtYFpN}#X8uG^RxRQM!coW&mMB93`I~qq2(mjQ9?Q}W{_tfhS6z~s! z6XHWq=Lv=0o!gS{#ed-+eiwv?AgONW1f~D=m;bc+gZTfE%Ky;zCwu;93jM=F|M1Xv z?)d*sR+7zS?SW0NSRw6q9`fJ0`{NEQ5jrd2n$vezIypkOMZbUi^OJYcL*T;K$Nl`| zzkiE{f(FMBZ4mztd~rjx_s&qp1R&D*_s(n>JR-LZHW6v(W_5eQz7q~LMg7&Y-wpih zlNbtc>+vcB$^qaD`}x~bB7WI$wY$Ime_Qpxe#(Exdjl010gr8~*zIrLSvO<C=x=#? zTk_wkfrEbtS`_)+OED^-GsY}<cK83=S3lqPW&pm%LnnChn^-}m!0m9mk5hPWhw`7h zeivFg8h9DqP^SI2>7xaxuOZ9+=09qz-#_sC0+zG0=WWvX?dSX@Hzh-n`s%kOzu*4T z(+4@=f_A-V`zGM7+#jze=L6kgj>WC;y)F4K>az|GxC8Xv!=Sm}O*Jb4HSQj!IQ*5d zlgR@w3z_sk{@M6buev;7?0%$)f1&X^P*}wLvMjo(0q=-z`SgPzP~pO7Ly@=ta|QGq z(7*+z@0<-j-u9lq2@W9L=ZwUp+mioQ%L6KYS$kz7gx~a$Oa^H8b|97JuZ;a&F7WdF zy2R%1wuph7mpKLK1AcST@4El>>3tJGsD3A#73^Eu(PQ0Q$l9c0*zvo@|M)aY36M_B z@RK#+E$OgsN(9N@S^SmOX8_q8gz*vlT|c=rK>4?YY5IR<>`iLG%T9svz(v$Q$5r<k zn2dLCLjwPjviP%ndc{*7|F_BdMZVD+o^f3Y3;k81LI{*lrG`HLRdU;@e^Vi_O)9-D z_?BjX_EWr>1{2Pe2fv2$Z@#*HUl;hAlZ==4mzsQtX?gb*WS&Oc{lBz%`!!rNJMc1j zSL~<XL{bOHRuOLn_g56v0}MbXCZLO!-hS?Fc2kng)L!-%v?N&)z^|?B>p@tzZHegu z-7)6outT~n`K?0#^yG~Ss3kl?%*NZs??V3@3HZ-cko=QudA|hs9a%!?FEoA^no-0n z-lRzq15fx?7nAwjjEA8+2<?BaK-&gT3^BO-9nWri?;Uhwau^hZMQ=;~TP>K10Kex6 zJ^D?R&td@W&@-ge{_}``vm>q+@N)BT#Mtk)M4kc4=Z*Fw(c9ttml=E-3=k@HccF*n zRyMU6fysyoD(w3FyT<=mK>-*bT}c=9yufW+j3A)IR~mQnHy{5V*}p#3346su5E1-- z*Z*%U-hZaTpKa;CF}S};^{-F=PClQ5xBlB?{Te`lC@{>U4pQRhw*xN_07?`kiC_PE z=l7`o^aN~#lMToDjbEN-1G1VrXxD>vI}Nwh{^?WThbG`_dr3F-UxxW9{S=^Tn$<p@ z{kzxywT#^wcv&Wzhvv67F9UcOxFYl6Ur|&)jlq^E-&yDdaM$&F;6fwePt+<z<>lpA zoM;unw@U6a(2Nwy(Z4qT@95K_2XHYKyKAOmb{KG<m9VSFm~mPwaI8Mv;NYN5C(Cfl z3-XvpJk7v%v>&th-WaHy$-HTW?zZHYCj8fF27Y)8FgaPti*}~2_mIL5z_#cFu%c3y z@+^0wM+H1?Kc^j}BxWsj{O~BhcOb%~lDuNV=^evN#MQk^n;q@i6JBhDV6(PJ1$`Hf znuX=gj}sXj<Ss?Jrqd+_Ce~BvtzE&{gR{9q<M=gpduUzOq;x#1U1#o>ebcV8XYRaM zXCS2Oj}(k7jui`9@9CKKZAi(-FE(7M#+z7Hx71NzK|WaZVKM&C<KQ2<L2vOHc(lMd z0i>7@)+(D{ay{Kd+)qxmwF5_FZ-<pM`Xp7dBj&74$&;o~aS{<ze86)zXLL1LyEpDE zlS4hG7m@ohM=+T2L^}hNwT_HuHo@{V{E5C(OCNshQKevTB_-oleh|aV`llgLY`wwM z7}d?)FR`bGbJdxOOC4?8?fhDm3mPiu_#orL2izKjN6*|eg5~W51y?5CIz4tRReZ6_ zczzY)D0Awst4^U6aR_s-?@~UKnOc*yVPaOkwwJ1yt?TU+4wi&%2YK-D;}?P<EU#=< zag9(z+#3ux;>jGF;UUsnr-ldrS?Yhy?<naFDp|56Aq1O>p`(GSRbaqz1b8!V;hKYU z(wdhkuh*sI>4$N$s~jXkoO0WPx5y{q>?FXN8A7@qrKN$}Ik^&*tOUC7)@0`AZ(>2S zE7q90*Al^uuGZ|yk!x0Ku`6L`&Rg{+)0x?Q1B1D*Jnlwns#8hiN?YSAn7e&k42oZK z!vI}6Q>Q~<h1<bKRr;?4=d0D$L9)g6ABp>EsmwulC)zqtR7?c1_m}cLFh-*B;LTE1 z)ne?B1|(jR!E)WJUaMBdb*B52xm%=n<Rl+cK}{<v%MwT)k?;$A{bx!@a^4sU?#1g} zf@{JEb(^=*)=gLxrQCh*Az<qYSl|@T5poGSoO-lG3R8WtdfjSywj||5IUdpX^rO$B z35T1M2G%l!8EFZ-^fqHpY;{o}_ooyygETQz^at=|<;n->qKHqIr6MMngwI?wKY-Vx zHVS*EUoM}J#NnSwrrjw)1=(kDyCj}-Yd#+=7~JeDF_X4?H$oqWI-XQjp}F*Eq5VJ| zBawHEJl9-<RH|z*5AWFD-Mr~SaeILBP#OvLL`9B8cZueOC_IF$e)iG-ECK+oCj)ff zE3%F0tIg?!X1=TZi>u?>Cn3$m<E54nbilQ24JEu$!1z~%V8J|@Tq(AZq6;H=f(TF8 zSsHCr)Xk1VBvR(;w_4!Z^+dJ4bVw6cR_@2Ds}!~RW_;lBTO++5@Y>L<6)z!>Z@yGW zu?bc(NNfHY>mb@ZTZ;7+=M<9fF{&>AG*ck%K8mB^<`GXp5j$UvW%EVBIeae2jSrht zQGYFESvF>Yb4!EA&Y4J&Jb2sfM64j*<XS?i;7rNg=G}E(M~(`4ctniX7t-F!uc{1A zie`=4xod`-DQopsRNJ2eg&u!cbc#1DTnNt!KytiN9o?UiZ&kW$wj5GxS?ZLV<?piy z_O8h0k&h#zg5o;o+Ne=|QDVGkvdXoOE9Y38Rhh=PrGi(2jF21-0GXmFWX{*OO8J-c z{F$wO;%vIZKpD<elB6Au<!E9V-qU2ab+u{6ck5h9NExd3l6JBzF;FfQFF7q?r!2sk zu0z6=%B8|S-*Rxs=#AW_RFfrP-i&8??IfRI>B=6;`YmXxVuVB7bwZq$%in;KNQI8F zv`F@cHiPhuuR6Uzk3MHY40L2!IOFXmtg=|S_xNo%kxg{Y^n6E5Q`X-rA$;(0<{P02 zq=md+!Q*`u9z$**RKys0vz%EPHQe~~DE>6i(eE5%Fn|Rr{!)FuRjGftHV9m}o;Knq zQ0s@7adWu*9&ly{_V5aq3MvQ*`kUtfolP4kl5_9@?3gZ6`o5rdi)PoONS9Psj!L(J zX%`KJu2@PAi@S8i5Z&~NGzb}szCxFzEUk**5l1nUc0<r;pV4;OL$v+cDH0gl>LZN4 z3s;QjXqK-G>$-U+*hy+dOi3g39bi5in*rsC2|@c1nsjWZN)4FTrbN{TV&~&AjLTIo zIo*rY9%l^lY(9-U7A~$>)?X?py;NJ*J1W>|%Ur~%OkQmI`jQf_x!;6Vu-o6BPjx^2 zlvGX5{u>W_YHVYOZ(;<g8*d_MQyznFyh&Z|6znIT!=%_w=-l8P=Tg3GYkcth1D<IG zy|$0I_A(V1xL3+WbZa~e;KRnlnjsAtxqY@d<n>GXIF#--yuNas63sgM%Jb#G<b(52 zt}3JKgX#iM2iJskq(^s#f^PW}f$nR$LnuBbB`l7yNUzBiT$TB}DL&%MbKR`R3AOV? z-QiK!6cG2}T1T=vBD^mEKz>&!5cgNG0cH%q!@cFfClI0M;LODJoJ#4jv9X1!{jVA2 zvjPx%dwZMf%j0(Aw3ttM1X$=Go*u$L3zP8Z)z|V)x`hMNvd_E)C-+Xy?(bUUHz))% z?ue%d?d#l)+qlrrG}G*Ti1e`ODYtxOh2rB&Tc1Z2DcPW%9#`AfxS)jex~!Bw2c^h^ zngL3r^|fTdbCN2smP)bGTCExtzG-N`E~Jw@DtY!?st?bUx(KXTt+*CJhtX}7Alhs{ zWN|Elfp-2<FIt`~26pV*2a-JfoX;!ayjteWppxZf`+|b~JV}BFVvXIZbBb3*>S}7N zEf82Pb(gu&w(w$kg_MctdH=4^mX1EIk6K|nUo?&c7P*q-RkvtDI@OW~y>it`%txue z3>P=4_y&Ab6yGnv&Uof<pSSbrl$g>O^Q$kAgcAI?k4S}H*#X{dOJPtd80BmmV9Rqy zX7RyK)d?~X*dxal>GLTH$`5;pgE1~eS_V@)3cFKA*$z1GWB77Db;1rT^+wt>i{y4V zVEf&-xJ(G2+~y5QkcVGpWDFTJ!N1%zff*H}FD+8JADiRf<#T=5DQ~;nwPRbV%;UHp zJv57a>f!)#H7H~r>DD>1T9N6#;LOO*cyFt!1bcfHKtTIM?qI+>Gu!0ngFWXn)`z@C zL9PT&;--tp_F55IQD%t%gy>@(z4&HeylKZfIh&)DWA-WP%ltIORjflsc{b17Ns&!Q zXpGu`tH5ESio)jF<BUsb=M~$7A*P-)f0xH>jeLQ{nd6}H0y(#mDL3Ba3Jtg8F03Km zo<fy9aYf;_!57^LF2f~)-J7~!Qnu=?o~h-sA0TJtJn9ZwQR8$O^H4lE4%_ZTKJ3bt zpPJRtf@FQ{zjk3i;65av`M5;BmO@_xF^Z`k$4NFY&0WY`PT3JTj8*isRNh|cq>5;l z_I&q%EOY*~rm<&*RFntiHLa4Rdxlyq$l`3fjqk;IQZXC~|D+|Cs(!=0%(<(s{4Upl z^V|~E>gyc*<z-4p1P2a)bq#Y?DE^9pY`AebN*hIYjXxg@q^nWRDVswWEi(Qfx8D)T zlu})-QDQMkxjvN5)HTXw7;Wu)bHQnWcKxd!!b<7$sw*yqR}dGcJhy)Q(FJFzy__PY z>YyMoHRAyU-$_|{^e0gL%@&rq?)jphG!5<#Kv|YTz%1)ug+czEY6DbLu$%Ge?kQK5 zik#C~?~f!TQeN=kmS!uiY{*gBMRhiY2XI;O`@q+t;#f`&;b+uxJ}33o%xI%}%r$0^ zGnFA=0$^D(v<n+wc6T}!@!mP#vZYC6c0SA8?$D2ro}GSGqY*i8m7xcss>1HM5RZw^ zs(fvV+wV*CU7ig+nB!<(SrMPe>1DGYvULqKtIg!bJ_xR?<BeC8dXVn9&_A*kRjmd| zcJkptcX-~sojxdb#^W}si4jJl$rzo0V5TG!kt!AHI*tk&JlCqx%!aBQ!3x-yIOky# z>m)Or=wlEub@WI&FoW13u~mG;zv_W|1@W$lk+)w=Ec1dCqIS2jj^-y)V-Ez!DrI7` zX>zGyZ^T<4ycrjX+;FPwgu_~Yr<ga{zZ~Aw!nC6J8dTa6d(BHyILJkPDpQRRG!)!3 zQ017_qu-umKvCO5lW$pqFH7aB%EytGZkO5~&{Vy4DHr|qJjtUSKckX%I=#v<(?#)< zPaK9Rj8QjEW^&osgUV0C*UFsOTLGHOm*J}ACw)SfM=x|OLPuoy4|t5K2-;I@<Au3R z*v~>_V2T2l#uC&ogKWo%X=+Ca7h&EZfb#Q|Tg0~5FrE@96Cg%#xw2y&0eIY3#USV} z7}^iOYJLs6vj~r}dLc|=A((CIJ)o$|^42KQqKV=>&N56xYIc0+T5P*{$c2T0tsV|B zz4ykN-oS!IPg`wyxRn((=s3P$CqD03u?qM~1qs+)Jz7!8$Wrvq!7ZN4P+jfD%Cz-> zXjsxI3OZ%V7sti*(;?AP-EV69^kTD3Cz5mEiI#<R;K@)#b3kg5zHbi63-;D)mk*CR z4n<5^l%QDzO+@?^vTdTygCQ&S3Bidr88qNoq2dbd{>O$h1&S5O&MEY0%1j-&-lB!_ z7%Lm5Auz!)`shdVIv7t6BrFXTCJ<g57_qiu#^70xqu8}4R>?CBD1)eI_*6(5g?)(6 zB&&*vjO(quOIJ=r`?eSKCtuf?V6=p5eW1AVaDJ(9!SpcE|A_QKe`T?>4{XEB`jdFb zsNb^`)zy3phn$ls`OGZdZKu8g@_AR_FS<}x5;(ai)I|2MPTF3Jjxm#(M#;TO8OpMn zOsf0K-Gc&_m_CQX;;-44=<naT?j^Tfc-~KTv(8q}QoMgiVB^dRGMYNxN2rAA#Y=(} z#2Ip(GYzv{VKKH-31(F-Nta)vLeMkvR8lW*BR>+G=Vm&<s-~^?#g8ry1mzfqMmaai zvlGkh^wX|hRbHpukE|~1WmjRXRjfH$#2u|nljFp#pD3o(s{kQJu89<z*pH{$?}mDI z17<$l{F<f0CLdIqF{s@h#G1s_<SOLjcMftI!H%+?{wNWF09nf{IGZ*Le`QL1{Xw9J zkwvD|Qz}(@x7`$?wS<@SH3t?n0#=)KF?+n`p_Z^!O4Hi}4B*lrTW4}SY04A1UDY1N zNz@7DbFtwO{`0|(SU#7KKLNi#v#b|kJXEmp>3$d2HgvXU;i6~)Y_=y@mW4UFoA;br zSwjPl(;!ab;QY(<g~3h(3SUr?7-)*q<HFPT)wo5}<7ifzi|w!HB{0W_TZmhm(tF!# zu7b;cyl)RJ(jC=`kSlX~w!aKPYmHR1v9mj|JDvDbUbkvnNhQ-%PVA98!W>q-s!y1i zI%0Wu_6hbFiPR*Q1XLn)=q|giu+vgA6J@HSTR5(ExnK%`*<Akcx;_~3zy?B7jh}5) z(CIEi+j~|;Up9=L+uq&oXlhR5)V2{g*1tTTQL4i;c`Q+Q^<;|EZ0M?0cBhy;!qolq z<AGeZC8K&)(MkhwYui@eIiLB<9eqPS5csugEaO?eb;#84H(h4eP^WF}W|JfjSBvav zQZ^bC3nw!*t6`k;SFinaJ>X3PI}WFsAB(K3?=4JOS+A=fXkxyo{qPZQ?1}oE(|!DD z_nwW|sP^hwJKlS1HP#*DHCjzeuB{)=gE;SdZdQ5NTMc`-;}3jbEn_RI-wmQZO;HJv zTNQKQ9etvn6Rc4CM0XGu*@Ah@u{>^SdfACL4W{(aWS{fI#%?O>RO_U!y}qHBBd{oW zic7|LyWDu#?7<pZ#e9*N=TMR8mbVy&U^N}IMA7b>?eef01=st!4RUIN+gk{<1MQO^ zFI1RlOB@Gy3RH6&Mrh$_Yb|xH#;?aPCQ3bfcDIVCtS)#jqDGHla9*EJv9;rRtm_v} z_jeq}zf3+fY;~7`am=WtyFbl`i!0x+!~12)Rn4;3No!4{$-VHK(>Cm2<=AS$?r_&R z%hh&B7_4R>3y&gV^ZvR+EmHM)l=Zeuplf$?1rt_D!Dj6}@`h*zk-y^GLxYzTN@S25 ze-UD+#$S&dKK2}Jy3^nT9t_BMo;!>~x$LVyym~aAeQ|=%bkE*phVHZkLB~Xefp`QH zo`I&c!9&##*0Z`EE}TXNEg+C;93OGNvDnei6?0<;2PgRGF>fNwry>ue>J(V22u$7n z0Mco<;RhYrr^Q&>h#DJk9NAm`!4&G{90V?9-EaXJb&2QQvO5$sCrW$D)Zg?!b3lc3 zRiH)i;JT@2dNx?_Y#9#i?cwF~ZwU|!MLGo;AhjMJHTp#AZeks8y&|m-mZ^C-u?}a< zX*%p4lhAE78hXHGJ^Ea<#bMqe;+&+f+<o&Me~#`H+Oacz*>gm6=`ST?4=z?;D-lXF zWkK3FU&p$ff=Ywy60o95GTEy{J$WTw(bby9SzkFE?AB=XLJ3X+cSN4tC-%ao(KD|) zf2G*v)?_cbKK0^2bL?D<y2C7->E1~GP|(9v-7cLJ-%-vgwz4L;9`dqUFyE(%YK8+o z=x;D~#8OoT2d=NNR)#AX%G%+I*0$->LRqfTrmUQ=zz;zvYZW+=clGCabSBsgWDj>N z_P0ZjEVf5loPzkPA4}pF`t<T)L`~)1YbxoiRp_Xt(@i03RxG)6oLTtHBJvl)jb2`r zbuWfqV%SMm#+jWjWFo})27zV4Q*Qg6>BkUorXFx8Wv{#Y{D6W?_~H6+yLstkD#1I8 zaeEOIBb;VWRdhFe_4U{1sb|pzXC#H><ZeSJpelQ#@3xSO*1iNx$5T^55{HE%w*Hkn zqmVBti&tVQjaS0L9dB$@v;7M%Mck}W*BCf1ue-W{%tqk6s;JN?UJ0@nkV0(7eP!F< zHMezs<M?=ZzEK?LeSJuFnBi=>U{iYaStPjfe)3)-eZeWm4x{napiIhK-$_UjEV5lY z!4y)<GVd{4E629ZZU=%V<pjO0o4^!D>^J>;1%~bSjlolMPs(SfL?Y*xaws>HLvb#- zOHNhJzUkT>>5g0`@s5^PgH_eAlamZb`iS<c`-(N)6S*XH)Z;zJCN^?4%t$V!K||cM zDZrY}E=35RxRP+QR4ZzLXR)|>>2v8Dch)V}(6dc<d8G};6)_3#SjE==!`^=fMYU`X zps)c&MFEv8Ne~ba5RfcML~>?^3@SNi5QZS2q97nSNs>G;AYsTsL~=%koHIih$zgzb z8_$8`x%YbXSM}9b?^T^YsM_r5-MxC{UcFW~^BZ^hk=+4jm{_JYS%M957iz|aE=_zO zM&7i1AoSzmr=jH#=kS9&YSMj4j~MTRDsga^Bd#nK`zzr3YnP~!MYh@I*6#FF?7m$L zq;brjQ>>iMDvJ}Y99m2%DdTcehfwjgkh(jzMi(sEpsRSCr57W>rv2AE1nAgMS5Xm0 znUy(r!Ln^)h|A~^`ur`mv-um{U!31R$t%$~->ddwMPaH0DmXB=v}vpd9s1&It&uI< z+na>jR9VPmcZWMN>1@4wa!063_2um)tR6Qt_hjkw{`b2_?DO`}P^J6nZ+%{_I=__E za4gv0h`-e2ILg+r-+ho?`C;_ST5<JEV_hV~09qjXkb20|aL5ze2<^uHTX_f}z?woX zjWcj=NimaBRj0rxVA!!wr?yC0LxV9$XfNX^?)XTfTz=}Yf$?V_XexY?B@j<I#vSLi z=WR8svPurJc6RRos7=8ob@0P85nbj%yD3i|1>bvw+hetG73J78bg80LV=YIAu#|=< zkZULlRKt;L{!#YYtN0I<m#kAX+ij!mi}lV87!8SXD;)?Xey%XCmtL-5P$RPRTk24| z`7yy)>~Y>TBN7?B?cH*+)bUrZ)RoL-+SJx3l~=X*=%S-znfau=6<-b9ohS_s3vil` zx^(6I{v_3WWaJQ!<cLq+<2cfN+57b-I?4SPcHFzs2@pdRN;foaIY7!g%dq><DYlib z!{Q;{Wb^^NB_L(&Vl(9;F$xIv5M**_^mkZ+P?5Z|a>D7`1KY|z1S~}fg<oo9%C9gx zR=6Zx(vWyC;i{9zK|9P5&ls5qb)~uo-S%>qh_qY^o9$k>Mq+0=r%IT;;Vjh^?o`s1 zDiql=9p$R#4s1d2=tf-eU!)Or$V#MqPS8a$BDOWr95DBJbJvk^E~>!hjnaN*{p5}L z@Jj2Y@IH?M6|zt)wU+OTqJr9h9VZ!6rI!v8F&3i;T0`V0Ud9~Pim`Mc`JqlS0b3rb zvtOX^?lnSIP))~YEEhG-ch;I(mRnY^kV(UdZJ)U<r-cd`9O4_>0Zy<f52=}fH#f#g z)HBfBJWgYSmOVLE5#7v!YpEKXbk1gHNXoz6Ldz*ShRE^Op6sOlJiyavb`-q6SLu|| zgA2{kDF-7L7gekdCjHqWj1%0!tQFrr&vX5;LI6U!Ej&(AEdhgOZkl=_mSm?{B`(}? z)k)NXX=;*P@#n%kdZ~dEg6(<@VNR}ajU;wH5$cxs;0bZvgD3UU5rN@5$l~n`5Nn+1 z2-fKa{15!j3h_PtqJ6h5ERroeU}0m5OnT+OiM-F^P0gdOT#uJY&Axhh85t4S9+wx$ zThuzPpU=+EO5TzK+(@^*93EF~5dn&Q@4gO2xS0na+%~D>2lUFX(=IrB=LbTl!;L?w z6ZW%PzuB|Mu8LjS{pg$4>uyo4F{0Jsi&qjPtjP<%LTfXB?T({*3fMF|jB*l}3MASt zL^!<!7L|uzT4>L~g@+hrSCponqefh;Wp5I=8$S2hi~(V1l<=q|-8=0NZ_m)WPu?^~ zm#$r4*rS>xt32@IMZwOj8+>QK+9LR8N6}9cdUTC)=go8OQ}6`U!w2v4twe^!Q%E$_ zw>;f(ZBB7=EWMQDAy=iV8nxj`ZR5bs?0gYwG*ifN``1p2mlTi=0>t1)al<u55l|?T zMwMG>*V<9I_~_c}X+6xQUMdXM#%qjHH_WyN0zy|P@)rv`7ONTVXO!ul0}%(YXT*H7 zpY<@UEEPf0JSl00xpzN<Q|NX}z$~di6TKQvC0s<B(tH;pZf~S;T^*E#zh5saap(M& zp4&dJZTQh%1Xg5bBn7gZ-L$>Q3i<$PFfvuYMkQ<Sl<H;}yYC<#-T#>}R)cUMA<+2+ ztvJl0zsf4L$AmeJf5>Siwx(gCVZOp68|`(rJaz8|Vb{AtPy*+C8un`I;UFyNNVdtg zqa~R-MDkr^dW`MG5t<9@F3H<of@E{36&8?k8BIlVDtaeQ?Q#K%#C*7NiC0+G(l&i_ zZ{NB|rVY+z`=qVJ{{!|@)U`!Lng)~A#z*<3oh@ma^3_HbL#GES^E8<}NVMwIX-*q1 zYP6T<8-*bvrRGGm<^@x4gu@oXied$&7KaOLgIm#0ZV73P&{siPKF_!d&=s2~O%J*f zlH_upnYxIXJJWFRp~JH~(1antr7JMKh_v8BI3`hx8&g<AhlR?9X=^$is5Z0Zk9}!h zAE;JP<U-FyT|LQ%`tRk@@d`?o^1EpEIb}FB0~?q33_OzefV<40g~i1!*%}4YUloMI zJ$EBLrAWYV<f?0>9dJ2dOA|xF`;XhCq^fd--cz^1UpRfl^K7DRhe=a<xB_fcmRu_( zO#~2jw#4;Rcg4JsUk9*NsW)YV<F==pX&_uZNGHPKZXst17`^Bxc2}XI31I^m<p9eF zq%3u@hJO3q=&~h;jasz2OMh6Ks)n9gGQmhEzE$hD&8%=9oDa;_gO!ZAIiY;<4;Xj$ zWurYrt6E!I!hJe=Gdm!~ul%BF8hRQ``lt>pTUFfp?`gJMis6kx*8_4dOByQOVa)zc z`fxz4BiG02fWKfu!Q>?V22OlIE1rohEmSc(@td;|d+CVfPfsmUtOBC+?WwAV9Hj#J zW|^$AasAiKa$B1cLQ+2WXWqoTdq&jT{GJq9wW1{2dQAeqAVV9;G%GogeI`0uSZB>R zqa!cDMG?8?M`tGiRp={zD6AvAKkPdszey?$*S2_=$5P3b*`~8JxJ6j1TtJskwM%t= z+H%G|e0d7EsvIosu@-w%x#r!@*{`W<0)!zDvq=a`Z<+q0Ncpr!t(96OHf@cYyPM%6 zXxuT6_M6!-&!E5%Z%+Jyj+yw1zcQI*q5iCNMso3Mu!&_xcr0XWka?uHd<Vg5>N;9l z1OqkFT2_zUG%R@3tGC!}v2!yc=1M^$$<Gz}U;Fv5FJy@5YaUhr>ub@)F^gTLVbNkw z>#~Kk@v*}#9{s3>Knfh-LY78&g-%0p)g~-uF5ps7OS_`Ykla`AuW2taI&0HaN^p*z zau&^o!gE93Vpedse6|w)?m)!os}bK3Y0`#QqpnO~R3TkWWw4)$SqD@KUV49UHe_6= zFEAkSeOEb_fW+2$;zvWOQ^U#inR|H;1-70!f5?knU+vL)!%sf8)rrRTVG}OWT+g3% zcw&PJw$Z3vO2e`z$aETGi)=u4&Dv+6SNm<b;$Pxb;NRbua?{JEb)}ef=h|aG?<?Ez z4hC6Yl?Z@{ZXV=SK8pTw0QZkR810QUup(clh-*;54cs9mS?Zisjm61Qd$Z@JSUnpP zQ1j3^Rxm%&^=UE7>q=~*z%@bqECoxxisbWM4}fKU-<QGRB4O93ST}rqg3KM&x6wG( zbR@7Ys&$=rja>s*r%3HuU+Qur?Dn{}wyGE+zr^Q-&9+x@klgRj5iH(9uN~;rgv^&4 zyVy8b?|j+T%yyjXeWLGCi$dSjuhRACa|sw!xTg?kY?i#KE4Q`YG%=nNNbJpq$&K`3 zb6C1monGHWqft<!@X8x|?Agtd!4kIgb260dV?0uejrpMiTVq}t+=7>}e<Lx*>*~di zAIxrjgj9GAFhd8I)tR%nxwxc2pm6ub9ZOiYriuz}kl<F7?R^A=BXNqRL)c8cF<o5` z82{c-NTZ);Q*YFwA~P0vfEkO(B^4Du*vZhUVy+NOlJ(6rYn>0S%raNOT2s}98X8KS ztKO1PlF~_WfGzP&hr7Y0pX>*j5@@~TpdJ~biX_Ixdict2I(7_3sNl^eg+^QoJvVqM z)QRF%^sPl7_?~&D<^fz_SkRKNLwD0<XR>i_BGm*I6O?*Uh|xN*Ry*nIedBGm(a+1T z6=Hg%Q%4)6Q}h3D(!p;XnJvi$23h=#!XK%{!^TD#9P8L0x~EDMR6DU40jtw~+EJI? zEvfbGBhUTbmi+60u57V;S_NkyY}7Cy#GS*LkGh?Z(J`y-pAE`tU`2p~;O0SxLWz6m z0Cmqe?k+ppfxGdHaBrCA>4I+c(_ag3t0jb5OKtJ(>L29qj<#_`h0>m83>yqLOYKmA zq)Nj=%sjvSVf2Y&Rg%m1nhT#+;auY*>&v33MX(dQ4yd*)^z{!N=Fl^i)R?2B*R6Y+ zlg>4bhID=CK3HdBJn(o}>!HU#SCbcFvxNKx9{(h7`Yc7pu3ZJaI~KNAS0Kiq%+<ZP zIFbVf<>2N%VKyUN@FJvHzr=KF!$@l5kY_KeBeYDfr$A9(7{_1hOL3L9b$dT<#RwD} z0v{_iG!yURUVY!q?8vzUa-32FaWg3j<PcQ}c5n2zTvPPN%(|66Fq<RfXY*gmLZqu@ zAkvqst3!s_E;2R7)MjVIaH%wj{Eh}vY;j9lP$+_>Y%UdaoChu~?CxaBAl7~M<Qou; zCIKH7bO_;q)zlbt_&_7IIdi@+x7Ks5Aey#tHkI7_2turYa7qM|=M5)3dJBULEj>9$ zO`E3BJi-NKOSTE5TRZqVY;x{S<mBOm;0^sO8mMhO_+BBn7s4XNGVAsQoJ4-v>UEAE zZ>w2hy?WZYWJi*$;0P>dI?Z=B7@S9An}l|o;SA}SAdTyXyvVz#tcUut>an&@QTjLm zhb$OFGxLWl?#g<WcA7Rr9`@p@?iMoFdP-4|c?eb+O3C{{Y{OTz7<)7YdHJ!;Zq;AP zL=I0$fnPa{O6+N?-+q*^2~tD|e$*`2OUn%ByDn_%8vqJVA7Hj6Lnil2IZ&B_t{l1s za7W_!<W}a!IatIPs$t`4GVk&a_V+H9NDjI0u3Uq``jM^R;1_{|o4rO*RGexH9~2M8 z4>pMBwsf@715O9*TiX(K)Unt!am1K*%;lg9^YqrAbrU){kED;3J6AmJi_cfuIAdO$ z=e<xb@w8(c8HnYa!k#|cTnwRNPdFeB$^LBq)}=<Ji~UA}#1r<N#VdpEVQ%nApS|Xu z+U%#6C58j?K;YzYgdAS&Now6cQ2y~lAP-F93s=!+@HYp*zSQ6e?NHD7J-PvwEA>($ zz9;5mlz4YjS_RjL^k#|;wb@iIUOm^noqBGT%Ld^pH@R8V`O3ChJ43rNx^i#Ly!8)R zB1uwY*-8EEBPC2~?e2Y$rtTs*Zt{wX_`Kc<Lga%E>7^CdJ49)P!&`$cvifhK0Rlzh zwOU&<Vrb`ck@Ke|%(c*8N>?@P7C9Fyoo1Y_)QnFQ>t0}W=y`Hp_<9gKSSAEk3z<R! zk<Fs<#~<z{Y+kgHkVIUv;@{l(__WEryhrv6W{Fb>mNT0_q~X8j`EVPrBULB}T+(e? zu^h0|sk=nl`QX){wtD4P^pcxXoO_(p*QpvG`Q)UUac+qWr(q$bm6EZ`XJdPnj0Ov5 zYIIQbEmSM+19$yjy`bpOXmV$3=!lKM5L4bg8we(GP9Ss$*uQ08*rHyo;*Ltul+V=~ zb9$8rJ1iTa-Qx0vI7i<EZSGt4ob9X(++L7Vs2jt9=DSyqnp8ORm^h}G8EiA|54rWi zI=2eVvyDHyCEVyE*?uvl<Mu4_>Rz$76W^IRvj}g<(B`R)!tpiSWmHt2<`NGJvCucW zZy%l52J}f?``jW~-R^7&YxWz`w^#$&aE58548Pv#{A7U7+eBu-pL3^$K~KNnshpCf zCCp;5kkQE|3N|GS3+%AYMTJDvy%92eUs6E3+XK(dQu4Dhxy#H9C9nqN$tFxj<}7EW zAPy_+Q&g9)>mWH7^E^_Abw77V#<s~oXUHSzhDHvilrx{*-3T^^saJ07AaAJ&Jhh5h zPx53H>`WFi)OqUJ%<mR%>;Y5N)}>ZK^tGQoaPKb5VcgfSELYxiS*}WFt~(^zTY=c6 zel9s^t}9=S<<NPRvh5t3YU_`*4wgt^7`BGfjSMnmjqE9Ul&dvgN^c2E5?vUa2#76L zRP$?2_2}{pZKj(!a`V^+M<`c{Q6NXWk@*te9`X3y@MirY*#v&^{VGvXayL0Lo&l;? zL5RVvG=*lPFIzC!D6m?opsBJLNn_2dzG;Wrb&|H~qM7=fZ<cGOa*=XAJdldJS>BO* z+9;e!8MF1pb88fiNrmTcoezp(u6D>WPHbAetd4lYP26kM-H}JNF7*{IJ_%Z06b?75 z@~ghDvyWY7fGBG;9!NfC_B~xkA%K$P;MJ;Z-Hm?2at-xu#~DY;XpiQ1OCw1uEpwZ5 zlJ51D3hwoS4l39wAa~p<`C{em7-ywuSz&9x%T=kPH}LoyNUTbM^s&RCE8)r>rdD<m z<;h6r@7f5sXCu~Zh0K`XO$!BUc(GdJQs???q^M(1b#K>gia@@IAs}d`7Oj*%gl^>6 znN3BG3b`uknykib@{UqSp}3Oi>>F}Nx6ie2A50Rh!q|9l1|jwCDy%wZS(Kyn6I4;O zo9`p|<G<$DZ7SQQk~O58k+%ifO706dTM&6Tb`VBwzjvK9R|89m<~XXHPeCETra+>V zBc{5WAzXYbmX|xe>0_NI_WxzW)a+I3hGZ=i$XjtQ*ICPfUhMFum7U|}I$$#49ilUt z2NyZ1q(1{aSHMW|U6{Qf=m_l$mB0}cU%b2_4bshfq3^dkkzrDL)dI_vJL~ZR)0E%Z z6Q55_V(&+^kgAd`g3pZa5ezCN)t)Bg?`c>ZVo4PzG>YOne2}T7!5HB5TIpQxdDVU{ z?EvJM-~G&iNxNX%#^euLBY{q;pKL_VUA7Mi>dK&RlE-AlA_NWg=ou;bK=dr-nkoA< z6m)LQm{}vnlHODy{e7D9zN}Mg{DQm--AEwGLvWDfN-WY#zuW=kL`VX&%6C>lFFz}K zbp`MIUaD!6#VS&?{RImGdMbnG+9^5p+nd+x3nF<l%s~C+$)bLd_tI3I*K>q2OKubG zaE_jnGW!+=70CbkzL;b4eo^M*!;gW%t^q~l_DMW(W_$-RC6-*yv5{>NppJ$(Dc4WH z?*CFr*8Q~#r1;tH)hQQcLgM(omi{56E^p$>OU`9?W&)V^a0`uf<C8J{yv0_`MQXR< z?;#VSSTR^()JzLPpmw(%w{ax^q`WG|d`)Orp%mD{7dJ|nyTikcv+69PBbu4APY-_L zoJ-;4>|}Ut>AGqhR%k2!Z{*C=2LSm@mt&BspP@h|vRw;Haibq0b0E5L12Mw{gt?{y z^1@|QtoA$Q87m!>c%yi$HO_nJPFxG)Fvr;`OWh2<lHY7tCzE9`@HBULbtKkcD|<&V z=_-~?Z#-oLvoiDIfi%nrS)@6g=V2PfuJu`|RGRRc#l5rfMtv$noXA4fRY@&{^e{SI zc~CgJ*n5_0s&{q`I|tUNurzEk@+?`T4pZn}09XD7CYDxZq#inaqpEuNz!eTPMptff zFl^%~YvSV;x`K;j=KT2b&Ij%qZeI^jUUlDoXSlm;J`)&|I>}eAhBP8Df5N(*2puBP z54cj`*uy}fAk2EBYHa>O9e*yf3UfoRq#;eH<mzZ7w@mGISa%XOna)b?3M@dmEW2hv z(xlo+uDoaLzC>9cTZqeI_FbLm!tFxFuRD{6RU_Sn?TbRhW`>>cEYI8FdP29?mu&Kq z*<3&6Z@m#TLrm=NJn9idR3?MC?|*F8X6MvY9<V4AW18!5s@D53^Qa_A7}8sbNh{l? z$m&OOoyWcHFA<aa#2<1h&(5%*2c#xhMHF9{TTFffmHGO-&+=5#Sj1GbfI+5a5?t@4 zkFoj0<31pWi(Pc<88#9{(XosyEs=q+Zak7$73yK@D|WYbYMep}n&vQNMP9JhLbb#o zrK45eQJ*3!O{vb(Awv|5Ys2}K{d=+?PcmC7$03=benh@w?`EXlPD1GO8TRg|8~bX& z`%0|M41+W$c*bS~jY{vqh7xCoFH`vrZA*^0=Jv44e#3q1U{^?#)B@Wc|0*}B6TCB` z58KdGsdVV)d*i@h?s-+UZ7|dD@y`Q2C&{3pibqu&a%EcTn;TyhBK`dQ6h$_Hq{xU+ zd49&)M_kP-lsGShzj`>_R;>x+><C_%o0FDz6LJi@Vz6L%dS-UpACu7-_WmYm2qT9h zQZ?Gu$j?UNU~+wT<{SHr2a;ejb7KLyN01Abgt?$a;3(njK_Wh5XxU*!W=OIxkZgH) z7Q1%N-dK7?5=k{txGVgvX*@}k)D2^^)2t%IF!$abFmp+Rg4S45((n=e5A`UVU1q0M zyqQLa%>`@y{mfp%7=KYNVx)IhtGM4XR?h*)PEF!vjpYpV%=`6pDymol^pvLT2&d4d z6#8Z~lggRqTXW>m(OIL|d+sx?Nq#QO5}q6JVANGdVSd!Y^ISdLJs3n65gVylc`+uo zzxMQI#a0#?O>1a(t9wJEmn1#NiaZ!1-(xSZahNEpRBbPokdx5=B%l;N&ub(dh)KL0 zIPUSLhyteXK-6n*Scx;!%1F~Yrf&>Ix9_sP<>uby1~OQy_>8~&26YC2YC^8FbG^7( zRcp=6NjAvh>I2JNU(X%i%j6ezP6}-%fuz{_SR1V0S*Ob$Rd;1_N>m>!EU!C9Z&I(f zeEbJ*`?x5DJ{3@5Qhdvo$&Sa8JSsz45a8LkeEjCGu+V=!c?BQUdu5W$91jlEdu0JV zPBqKS{02HM$YubIFV3W~pTw%YCV=`GT!t?$CvW}%434APo!M4G!INDI`j<!ZVQ;(q zJM~^6NA+H}uD9JihTco|sNRc_Q(XA?%|8r|PofKCNqu`1_7_&7M2^C(ujN#JXYS<2 zK;s6|DCA#bJvvHoHqZ?_VT6C6Aa&ePz1R9uC(kja9$!1E_j(c9{_d|Hf7(GlP^@Ow zE6;LP?3fieRDd@|?KdiaXY@~UK)qM&rG~%ymyZH4fBlg{?eEO}Z8^}`mLc`QG3=+j z@&IB`_*3@%MpT>noi4Ce{Aw;Vf8}^}ad+V;k9<$-)Txsme@Z&9J3xVEjCg31;xY7I z7Dt8TzZ)FA033iaBmWoG|1Bi{w~+jwYS#V`h<^*o|1Bi{|7amO3EOEsz2YTz`&@_Z zEq`JBckkbmNAp)I-q+g%5>W`6dsG^-=#Zk1-=7O~yL}erK@N35o=b=<=-_vGe<P6} z3!hgB(ANrK_m_W1x!*km8aIrEkzH-PaN2XsYSknCfhHux*?GB_Rm0Ws$=U;2z8l~C zF(y0SjK&J#<lY}?yJ8ItF|1Svo0wM(Zi92vOY0qX>#3ei1u1`ANbby|8sX5Yav#vB zcX7fOp|%Gsh0)4zm;J9T#c8bLBU0{O!~!zpWkx|<wzQiBE)QMHQip8Qw%)L=w%<tj zXoiXqSFU(!obeK#d%3au1G$9x5)J-UUOSP9Y~I_s>gDNiEbc-3K$22~NJm1-_ynHV zOH^(=3r>}^A{R{q8x{xPN|@Cv+&uf2Rr&c7_0bs)(lzJLggzWs&+Tcu9RY@v07+FY z)~V0z()}KSdEj6z%d+$bWCF_%C`~=fRc7BCqk;~dQN8?(x<po$wtdf4byFnpB=p$S zjFLpg6WvfnXV>0x720=%SHUAmL_tcTh<!=L&6|X(mGOyYM59=jP4kbOi)_x0lHYMI zfCER&xZ9cZA5gy$NmPKPxu#aem{o3&LqmrpMGzIOY;ttxCYLW#v5fW8vG4@CgFxQU zG!BRq)+-z+eQ6lrKfN0OxPTLKI4^i?;{Qp-mYos>>G)V;(R)3|w6!VQEJHgbeQ^@b zyK>9uN|j_AJEl9Zu9sXow=cx^EK%=#(7xQX{aoWl$DGW>W%z@v!|N9$#|eT*)3Z_? z#3kli2Z<pDrd_HRGaNbWl{M56(5a}hjh<UGBh4A+XOPe4CAh+py-QsagwyxjinJ1H z)!xo`eA2_vU`jEscZ3gR?c@bOX@^r9A!>JZ?BwNj<;D+0Nq2;iWq3hS<AtGy$X(+m zVjLmV%G$sf2!o-dY**bZg@B3&Ru)1a6MP|&&Q@;8UO{w;d-UmXtbE3CIqjbGRLh=f z=g$ifVHltzoIP;8y$V@@G5*Nuxklf$1hmkFZ8gVFWOKwAsZHl7Tj}xF6@A<B8yHYP zP1(vYV+a}(pF1c(+pBKk)|*nvTnzJ2(=BX&?^slESWCl)zRtD6*{;Y6P0FZk3bD^| za?hp*%}yyogb?wV>s$<GZo9<tp{CI49O0>%DNR1?t0L4Oz<te>R>J+MpY_)dUK_-K ze|2d85br99+UY-wd2<TN#ND<d7;-RC3WHQ`+OEE;A{+0OGxfL|_BZyhN4hsEXC~dN z1gZkNHBI&O*zAqeFZMhyWNQtLY2SG|K?~2Hd#ARhqviz9?Lyu*3-eNAYO8wTR~mV- zVuZ;>4e?U?8MIH@uw7nbb6mds>9TWa;nH4anBMe-0W-R5mgl#YLlf@r5xZ=>hP)BT zjbkhZxB3b1_Bl^aB;YnG2)z|Hq$qW4KW8^2OiZGGrD9crv42Bp-Wy#lsFJoq`3|+D zHlZ@tQEJ>|?QvIYtx$H>vuG(KWK6>_z0u!UHk1Mnudz0PmyIAAvg+VsG7uTyB$g@! z(bKi?kf|!@lfEqADIbBhzVq&!VS;nKB3fd)m<3{3gZg}0%h)S7BXQwu3tM>Z{?x*U zpbm}pLAFwhwEMO#can$2oZWPCFd>xSgYx~|XyIne&i2jS0xddYxnSc6ojYpU8G5uF zMpVT`yujf;v_!yJBu_b5f38iA-G4wcS{|(^mU}wcu>ylc5_5qdX7(GfZc)Ctho%l| zsqrJc)FNAx;xJv!o2*ws%dSC%l>>~1oT|?^j0jcTbp;G9TvO~5Rqjivfe^^3u{&pl zb6?{rX?m%bQ^4K|8kr0BPaj-yHe2?0&)>-JsfBv+9Hw|DUkphb<dtEq5{Xv_;|pG! zUx@Jb9Sd4v80Ov9UeJKNc~8NJKd-bbc;5|@G>IG(a)imD6BHb!nyiZ7nYu07&$)?u zY<0NgUH7VPtYucE?xX7`V@~-D@AH&ed7tGA3Tm`>Mg<SKxiS_nht3Re)hYL2jPAW& z1S6T5GWI?Ysv^i&zN=z020P&hVielP&G^%@*?Rv$u{I43t3T|%06kTK8F2W)<I6{e z>3Kuy@2qfAqJb68y;%G*pHHjA-&&4}_7M6-szB96a}IMvuFEAlVK%)q`YSnmDL0EH z$!I~(ps}gD<%Y`7MhRB&Hl!DWWDrbQP6wOaQ(2+I$wCVhBw=xCnfAddj<JKOlL_s? zpA-WLhzO<IZGi3hn?1?^30$KRq2PL4sAik1pQ<`2pwdn*wr7l&fuM7fVm_i5GAkwK zP}j$?aKDp2KIMF{DAxIDNO2`?$3rJ^SkJBn;tnHI6#d#NWNptLMUwUUk=o(@l1^!E zngS&}H&jI|>xHgHN{+x<RmI`{>8Y}i76j7=sP3W!p2=Y3nCF3PwDaycyDd^Px~|B> z;@0Jzejz%A{qakTO#*_2RK#EIFFUwALO?XSc0<-zeb=P567IaoiQpI4wXV`mi?h(# zi{5t{Vb%C3th{V$Cf*&}<A_Ol5KmRbkXuM~7p&nvi>=l~=#qqEI3CSfx;Cai(Jzo& zDng{~>?Nz>A6>Owjn~{kNfjos{LOr2x7)KpxG`Z&nK^e4Lt~$C;}TECAY?18qb01G zBJ{oIdse-QZ+B`%@u0Yc7;w%$$YQ4VT%=s6)?7zeg}nkUeEWqNTan*V=Gx@m(_QIX zQ~a(8uW_mY9ymIRClH4={3PJ^56tk62w<46Ps!%7&RoBPKObICSEqTGv&vn;G*xv} zk+m+>UiB10H;7Za{d=Y<ZiA{|ak0#tjy*YHM!1|>2BB*43p|J?f&m^We`R^Ydb@cE znbzsFZtbRgRqJt&lCQm*77GX`DJFHeWge)gbz4qjT^&_4(Pi>5)lsK*4E|`gThD4* z+NDu%`)1Hx;Ux`QfmpC{9G&2zv4olsTn4k-#Tt!v<;^hlEE>J6A|I?qS*BfO!qEZ| zz)(k8!q29sH#0LS?urv;IGhK0rU^lW`*xNp_g+*M*+D5MdxHE+;OM;j#Yj9mEt48B z%a>A2M@aQb<+pdLCL4~3F`MTI%G7~bHP-e};z)PV8Lc*v6+9xB>4>b3ARPls3O;HX zFnO5T0|^CiO;^_Eny!xXs!`i<Hc@J@%R{-~R|roB-+7X=(8{5wr^mH&S>6dSvv#tn zxGUH63yg)J17F~E#Bs{N$OSkHInAgF&K(Kq+an>p(D+;7r<C9$A&t3Q=Kbj*&W@{7 zOA)42XOPMweC1X^WUf`DT+8f3A*$S$qN&>ac<|Q^mUKPI5QDC4mwXjOmahh+xL0a5 zzgN-xd*(ci1V85!;X<bd0^la_gk13FJPiqbU;bO$-Oz6}AK=~F&C1($T`e1m>5XE= z9y&Q}$}KPWJx4tyJk~<1UlXoZJUxt@*<%(;e<>>Nv9Ua`w#>ZL(Yr{TwTA*HDe3L> z2UWShVRFv7s(R4;^6N}pxLz;YC2JHqblUntsvI5Jq^j`-^(?H<Q)A`5fZ)nt|D}vP zn{1Df1B71WIXy?xbhq2p>Z=T;0tBZ(PkIwF@0tf88)_#!USEpc%KT`$|JIY<(`wh} zejz4GR&Ws$OqE@6i+t+}xoQ@I@<J{c5>e(<=>pSI1PRj{$H8)T*;tn|Z!RA2%bj~m zbrJjRrfuLC2HfDY7pU*j1D=8Y<kZvOaj?6k0asB|4m(bC{L951;HVW0xVWNdj%#3` z>y`k7++B$|eJ?v)1xPcu1=7r4$Vd7+w~@nH(_4b7L138w7d@F9hT{v(ijTh?<reok zNDsA9M&fGuo-qR<DjI>5))xYa4@y=uoBQDj2jY}D0}R3!DU@njXLmr4^k2eR97hy- z9P!d^bjCLYmA{!hTj&UBF>bmJ;tWVcdYfOGK0FslC<dx@eaxu@_`~pPi<^Pr>M+*2 z&oNGlo1DALWjgtfJu_<UTI!6YMolLy4?5m|4Q$%>;3426&<)^n-bPL5&wXyNV!?zA z^I_Ka=$eWpuBy7DToAevC6!vL5Mjyw(W@>-b(FihuepotEG(9op1sdkSbJhabQ<ds zD-aNzHq!PwPU!pxwIfmnc<6F{(Mft2-akH#@e<76MX#qMarOq!j$M`%KNJPZb0Y%# zCnkyu2^AF_6ya9pK|OkLv56fXrp+w)*7Fvn4w;E&Px2Fy!9HtogxJ&KS#F;Z55&Tw zJ?9hB)v{c+G7<N$b0uTT&p{KB9ps{jhgl`azEW(^GCp*G%bbm<x3DFOxuITf!s!<I zVXI4yjI<LK4xwa^T5*<G!=tOJ6ebv$_HI_SFDs^orC=taWf%;F%P;EZH!N^(DT3;$ zR)y+Kfi>D=@*^#KmIm|>(>=k+JNhFnYd|x9{>*h6n`}Mqv2u+)kp8Y3Ye;GzA@0{~ zy+Lc%cQJFdbx2TS!OB{#rXr9*pSlWU6odJB=Ywa77sZk~u2ZPOz8`HdBT!B<fG1h5 zsRXAdXcvqZMVtn98k|2T6bj3^#~%h`0jQ|#KAUbO3KDz)#gnd<XA6~X<fv-B>LL#l za@BhFL~XZOgQ3NyKq#ZxW3G2Vd1ID}fjeVQHd1>RHSu^UNL6uj2n)11<Zbys4lFwk zN&e+LpFBNQ2jr^un$jsCfXO=>`ifM%n}kd`b&0R%_HH^ol^$k`KU!ymj7ha9O=Zxk zJ+k-ZIc4LQeDHAP(7tN|0<5Bl-8PPI>z5)ylJLaL-s0mEfNIUSUKz%#`@UsKxEDbH z9OUEpQJWv(2aSIy6Q?OI1X1%){>p%-HN^3!sU{y}$LuV*?=Bbke#s4-C2kAJbz8`| zzo)%C&wT0>osZN*QPq*+=_-Znr|B)scse)rWINj>at}rQ28D1D&Xe9y8c&Zxnb|6< zb0P?2G9Dqrl66M%AQcLZk!M9C6z3ZOB?dTeXqRORi}hrlttMtPhLtZp?k3&XzW20x zV6wW>W@Q|-5;n0#q^&}|%~nF)`#Nv4YJakP#Ln3S_j6XYhd4_W8C5rMBKUHOGW{V_ zAaLlU<PlRn^w0kXi+!@jOgTE-b0eP0)%O!GP6qW{n^|3F<E6||Vsy$@ex}sW{D?AL z9W(y}LnLtB?55hBbc3IE=HOF`weLH!Gi9n*=Lu26WCJjH_jS*EG9wk=kg%z1s^P8+ zs|YFW0;;8mZhxkfA*8%_B2*G~Y2J0@Y#H_--S&+Mk*qLo>9McjA=(lcw~EF;w6`EF zrT$pLEzerti7A(_sTgd|nNpDFyCE9im5MIf;)pmZ&p7g6;~wd>G5>4>*J{n14qlo! z?{%4Fx}JN}oN_JSftfQArs}%5sR#B_Ddqx&H@HKljRB`^ZM{9x7Yr4#`5u>O6zSks z+w0Yvymt4nd~L_FXX*`=HXWS{QzpM(A{3!pH4=ZRa_jz@BcGP<8w+e*Oftd!J*8); zJ8<ao-ZyBGmA<oXyfo<?7jUTTr^X|ExB7Sg7QPDrd^^Nb?7jMAi{I&!4(=>;>2t~~ zX%q}3onL(Cq6U8HlK^FFt0sNt=Z#6IMB}ZNSD{WF(pcI(&C>X&8{=f0uJcr8<<3;f zjhrG`u}8D`tN35=GgAEn=w9ANlG|3o@>`{3-&lUA3nqeIpaVDG%O=4_oM(K+5&GED zER|0?7Kgj?UZ96Q(N<|WYQ!D2f^IuF^cX{-wrw%P+vwd2&x+BYzJuLqcT08~8?|ih zJ^}5K0D;MG`isf#pWCv9*{q%($nMhj-YBXjhj72e0{M?GM*8~X3U~}tEvm_Hznc;( zD)%oHoSKc8EcIM^Jw(NvtHzl@mN%OP@z(<7QdHa84lU)t<GKVKV$Ez5kUah|)}%Qu z`=3_FJe06_bD1$&yXxA*&@%f;7!-4ZO=u%@XP?b?F5ty|X6r-piqs7>#zD@(^Vz;* zcJ;G8k-V+wwO2Be4Rvi<6u=++K}L8uf{Zinogso9MIPXY`Q}7UI+)^G84jtJyuIn5 zHw@X1U3Dlef%s{GcoZr?n*p?WE5X-i;5fAnIJGsa>7Inn!w2A{8~fVX&e<1A!H23V z+tzwa4=Oyt+Hc4jrn&@lgM3@g_BlF#nYtmY%f~V~ojX}m?a5pP@+h-iZtfrCbXzw= z6a*y*!nD*FWLLvad68ba0By%_wK;=z0iRmr`Ki-Cd3g5`a1=hbDUo@dyL$Uf^pH?D zsQ?p^-g@e2zr%Wrx`!yEG|Jq+s5_H)BSE1)%{QL>hU3%<@7_a&-B(?Q{avG^LytzC za)L%M`!7qJ5QbM#l>U+NE-6t0<d0aMCavywrB5R5h>A7}7?P(7v|btOR?|6Imq2&i zY_l~WmUrUtohURsrnmEG_FWzM_W4UzR*YAIa%Sp2*R{oVxK}b1g<Jbkka@-@BFE7= zS1P;E&Ym~a;ClECL6t-bBaT{2OunlAQD#f1q3b&0w;h@jnze+nvDtL51&!s?fOYe4 z4UP&>ba-s{t=jB9>Uo{_ap8-|%y>^O?7&2Od%=Io+v{r{W}tX#w94Km$k&6ZHVkn# zhL+aXvyY4uO+8!6`>io(vX`fRYhX`}+0PYodyqIGpjQ0#ZZBr9cD@Bx>{wUdab@h9 z0Bft(TflD*=~vgT9rAd>j(YiYR7QWDsYBxyXlh{c(Liq40k<=ofBVy>RL`{rTe-YP zFwS__iSYUT(f*jMAz>1{(Fz(?bmxb8jA>WUoP3>sayWSFRvO`hxWI||H6eWJyUeFW z5gK{X4}VV2KS&)y0QfBVEPgZ}Kb@%-B+wGFbyxkO*irq&*t%k`R$wZ>nc5VSWeb@b z`yxpW?>)2aiL$ZS)kgO(7H>U5Cs>oAg*Hs(u3mOGLq47__nj<i$qgc=Z_U|*ODn>6 zBsP+ZYr%0U9wq3y<gTw8^1boak9Tzz((9^=J(s4#Xq}0QJx1?2EE>DaTaUhlR1fmF z4w=Bt<&>L=yP;du0;_U{t(WM#y86VZ%wF;`i$$P|Jn6xBx)1m#(r2UW8>R%dD=6{a zp0{R@z2m9lKC{;E+{eJIOXT$x+y9fPUR|;o)lg(zSFSr#{aTIj)3LMIlYxh;K5EXM zceX4mDvT7lCbh{2?5TSz?VR?%NR1KIece6~*S4<<>Ehw)5aNI876p%ZQfEVT5kKnX z^F-vGPT8CPAS2&@dIJa){UC|qRdpM$g0rhgy!f{genYC}=Y<8VUwc-fa?~+>I)oE7 ze$CPiPf<KhZ>wG4`(=yuEM1VXI6z37ygI}>mR?(q?F2oW_?EObzqx8R7O2h@p_tuo zu;0*)sUR3yS$U&_ZV(Qd1ox#MR`P%=t7vl$_j6ufDNnYBbSRFbCPR{^*nDgA7OQvN zEHqaiZH!hJc9)iO4^!cdxEpI91e+3YJVEcYX|2XF>`i+4X(>v)(pDRucj>6ldg|Dq zPHi`>6BgJ|#W4C-Kv#fs-^6xxv2tyw4iyx~qeIC9BRwqMNVfNIxz#J^KodxS=VW#0 zFx=xZF`pHT7cPouW@qsDChZ{1^K587<eBXp*J?T_ke{eGn|s!Qe1B!4Uvt=-zXVf~ zkmM>1?ipfVS^XBtX={KoU;T!spf+s8&taitp)+*#285N$<?dFwjr+!;`|5rZjhm*2 zYX?ih+cxtE3Gzc!$x_z@a6lTq4g1y?FR|5~QRhjmna9h>$$>_)V%^d^++&BC^XlA1 zi1GAN^jp0So-<fR3_wIqfT!S}wVlXw5x+CuP(~+lIV|KIMY8#zsp><W%lk?93hjrm zBkI?-X7U_N!wK}^gY6Md$BWM@G3h-XC@K_;@JJl|v<m@~k-YZ8FdtrVBY;#}n-(Ud z_ckXYuMFu03f=%;A>=5mFQ4JmQ|`InHWj~3kowgYiW#|G>6}ASbbBy@#os>?bTLC- zdwMvUcXO-B#Ju{p^g(sd&bWA8Mbqh?H($xN546KZ`AE~xH=iEDVe^v_)}C?gl{zOM zRlMU};_y_{q5D0b5U&e|d>Bzfs%0v#(hD%#;XGYekx8I=jQsOY-T;%b-p;MN_>Vdt zz=F;>EYM=JCFdC|vYU#`8H2Aim!yuAiV6;}-*0Jv^)qvEEG3QNz-CFLd}in=FAd<6 z_Lz1c&-}u@ha!sbn@iku$IX6bd2nc`Gs>v5iReVA>Abo-wjMPY^IQpcsNIUx?|21b z3{M9_JQwhzr~#Uu{-X91({(b)yS$@qo;DT!(`UXC%zHBCpqAc<)qTtH9H2s1_j9$q zd36;4M1&R#3v?sNO5s=CeY^{>2+oul=nR(f_1obe9Exru4=lTSBQ$N1M{2@L8qmVh zR}y}S<WZm>mu-d3KTWV#+I4(Y%d!Z5{9j<V@W>|P@QigGkH83!HLahJ>u4H3wd6;T z4O|3h(cX6Fc#2-<uHmcdP^-6G`_-4{FI<3fpBjlcaTnkKhnNpN6Z^*jfr;1wlWK$M zBadl*uM_}2l&6377m}Em3Xnq!I)W?n=LnK|081TEX1@EU86IIyRt;FamnqkuV50|M zMmTFL_b+w0<5hfB7*2uQ3214|0Eg)?PMy5?$%DuqK+1(}$(P5Zi~#Uzndu~O=NF{> zFKm<o6q@a2-~1&(27wXbmK7&+GI<W*^=zl*cQHMo(*JlMk_6D>^_b-tuhe%10Dc`P zjTZkEDV2}BhCF67nm@VhzxeQfjCO>u#07wqu{o)@$9_qp7C=hWVP^cVNT~`iHrQ-O z_878G8vxW-#UiJFGSYE7k;kLJkaGdu4^A4c-vmfW<=6WQMn8SV6yWr<E^N?=iVOod z{ebc0-=92q%>vA08L!KK@lTQ`G9JzPLjbPm2~<CMcm*^(xOvj=EjnP=PE~;5m!dU$ z3z!mvQ0TE5z?uc{>R2TXllaL%C)`U0Si?bHh`{w@Y^WY_zW3zSU$85FqbfkTul0<v ze^Rb98(_n>L5;a%o;aDs-ygid0Pk4V<p^;8IRf<)fRZm_lkXj?qMwa?R}5%K>P;$t zJg1Kzfgy1g%^iRBrJ@4xrK{PH|1p<6K2pq#Z!RBC`tKnA0Kfpi0!Ck%ULFgfrWl|= zxb~L9PPplRKXj4-puxI~({KGLAqKPnDdn;Vq>q9BnSM?K&=VKZc<OjgUakP=_o@u( z{_lbQ>gMqifIEqM`;aFMIgh%!83iPC{&ardfBH`fh%f^~7Cr5Yi$2EJPk@dA0oc$G zSOoTDzK`G~3xL3B`9A-I4}UVU2qA!frrVS!ius;A(39<!6a8QF`QKx%vjChv_Mw;d zxM5T%;FiDNk^SYDQh+|CN8r|-;Nk*w@5V0~pbeng;QdO6Yk$&1MCHi*iQk~`{snF> zTn5J56FV6|QW}t#OsCtge)V0e6d=0tZuBP-*;)+D(9K^n=vQC<7ZNi7=SlNi9qlnM z{lM6N<B4~ffW=4)P~rZwL81mg$5?nl`>zZE>^6WMKOJYIW9)ne*#07qgz4Y9KPJ@) zE~rHwzdF-|4KjX437oO{=j)h<<9^IJCLy7`=YIz0aYrUP0Q>YVSB4(rD1->GM`eP3 zCtUHvP=Dj2uh%5GGx%Z1E5FcEe}_O44A5?%_x9UgQQ&wk0NcL<sAe{Lpd$G9u6_pC zAA+a>%*#M4`R=a>c8mz1H<ADF9e-yyF9U$Sp_T!ke<Gg$bDA!I_dYu!j5x;m?|d6V z2+*a7>(Vdj@&mt20}>wNj8Rqi8{vLv@B@;M@$fH!0FwPnAZiine<cX(!oLy(EO7r- zasS$&?-t}=8}zS}@ZBl;*Gc%-N%+^zK3;(Q|IbPIl<fn>#-nUSPeU1w9rj}={_e|r z-N7m=FE7YY3I4&|mj%{#aTb%u!L*;P3T^=*uoy+oum>j%fHh_TF0|c->aR8C@2pug zWr0vc9ob6B4>0^4%>Q0udAS0M{a%?tq5sP_L`OmXyjKFO|J~nD-z4e+3+&C1BD|lr zIGO&*Lt-5eRn*F!2t0}N{xcQ6cbyRlEMF^AmVX&~`~jsV?7;Gs$h>6gI9m3@Z~vR% zz)(ma#;M6>ivAUff1L3D+ew7MJ9P?!Ngk!^Kfan}Y2=E7>So*yMu90zQOP@;p}2EW zPxX%Jb>Mt-9LIBmln?ssJ(?yNr$2gf&0n4OVRs_TV_uXZ966=qvGb9;_wdt~b>dfo zS?9Ix^+R!nyrqb{u^!+NC||s2LVwAK#ukNvpjzY5m3X1D59otXd<^Yzkm{gZlruf) z?38i$WykAQzmo+-eUg9m{b?g#gv<+Cc}Lp*|Ne2rDKDr6*6(DX{w?FqE9?S(M$9!Z z*-1tD-+n&H#rvyj;^c{1F<kKP@c+kj{^!5%uAM#uQu!?XTbB|4y$394KK5@zCvps@ zGL1;0nY6ko!9UIAr1g*eKNkUQon&49_Dn^ju`Z~}U1SdUo!Y;@_llp<O!+?{IiAap z(4D-Kd;^f4@ky%E|C#szB?f@}<-Y^*>wg)qQY&)NW#9ArKO;vZkqL4F_ixXXn(ho1 zH0?$Bqu;2+`wt9VP&LH+^@RQt1t|}oiy*>2cHjP;QoO%^>;+x=Kl9nCe}(Ypyzs9O z{%<M!|BVnT(|=s&saDV!y7$+OyhrNb7VW$BksBe5kA8ZquNT2Zz;Mv0#~d4utAH{& z_oFa$jsar3wSB2m_<xJhWoJPD_@Z$iAO7)GisC0+)ft}&0-CS)e)!_7>?aSZaf;rO zx9n>?YHuSu^qex?R_v2+v9JJ_$!P^$seKnDY!$gJyrVcO;G(Jd+4$_@y2q_|FGGI> z<_8@o0_2Be3>x=1y!ejUPv5S86i%G=0qO*{T1ifX_wml9e$-h9ujoFx&`cHj`E=KV zorhutJw24`@D}t{s*4Q&p=yr*^%5eaR)i~*F8pzxjMoI+V^5Jb?AluMk!Y5ad42ju z^l=Qk|B_z$p(d&4t~&aOG)f`CG~69UX}4K}zDkUZciiC#NPlQfFCk)}|Bj{w{O><_ zP0;??zj0gikJqeip--uNVB^Sit*eX%xd=}ZPO_hj{&$w@EIuL>jHmLCi(BtzV=duj z>^^>`&LR+cOkFH|lG!s`=;yYi`qT9{s)pIfAf6Zo(~Al4z1aiF>N}_7erE1$0V+=s zkpHQLMXYi9sT9|1Y^+<lDSv?HtQtV&PO1S_OG3dcCX|E);mS|6z1QK@`7sg17MRaA zAKnt39wZ%^mykf6{K!!w?2HfSQ!#P3;UockmiGMO3lg5AA)Yh-fuSYrA1vgnpyvld z<7s?);r?v$sK_@70>r^%mFr{Ru?nh%NV-IoAKLy%32N5PTrcRdZ?i#j@uexB1tj%) z1R~$5O*&e@GD<w#sZeIo_iC_zSZ6xTLS!I?-Rbv-mG2nCuY`y2;YVnm>ne&@*<#1! zMFuRJW!X_2k&v4H5AZB5{xIZs@E%V%SFxI!njUc2*4~|l>v(?rC9=H^uc!)M3t=47 zzDgyVkDXPFkeraa9>O9t-vT0#dpA_f|5d%XTy!Oh51)oNj$LP7soa|FPKYyEd}J0H z5<|gYuuNDmlevRMoN;P!O&2dw(D`w$+g@Iyag|&0+tOR3q}TvPKP3|XAv2=YVX{9M zbgz_i=bO>by*L6>CT_p}JC~hE;AJH*QPK>v9Px}ajagiOb%fJJmINART_>mU`eL$M zn8CxqafkY^%n}U`I3~^unz%eSP_@jB97=Bu_S?Coa#aMKROrSdBV?&8rB%GIRPR31 z{mlA1fBEP<$9sj1zQp12118JZ?kbLAUk<Z%(0fPr6P56(^BT!xFDQ<|R1st*hW%10 zOm0xfGII7hHl6B5RK<jC$G)v3Q(x=mdkQ~1U#Uc>X4$Mh!>wz2pB<uk4ZYuzT@~&U z#-`X*epW}$=)XM*@q$uO?Z6z|tRl2s5w|a5p1pF|mp=zRgv7m#?F9~Qu*yww-z?{# zryXVg1D^zvNS_JZU`gNg8`L%*puok2ksBMIvfMqDZ`kiWCsjS=V;2zR)P1G=HT1f9 zb4)CsnxmD-F19RJrplZ9OMJ1A>}t%Gq!~@k%WTI>RXw`{qC%*4hQ2yPQeky@6jS6M z!Za`Al`@LGQS<zKGw<GGsKd|7tS*~)ohHhFdY@8&=0dj5U&zRg2x56pd&B%*%dUb< zt-s4;8}s0x+XMOc77;e)v4vTaq)gq`J$1<j$gnKKr8-Ubbw&5PBcoOkej|_GhA4r3 zmhC1xMfp7L-{Dv_i;m?&us#_nF6Ndw$g90(Wv1qy!GE2hSuG8_&^ls8(Xf!U6}NS~ zWeZPU(tX+1ls{dwgjbB?&<JWEZ=e3!k|#I7Bs?F)nX1^5QMLjnE7hOvHyP7C)hF3@ z=rh-U=oKTjJYj-aNH&=4F`qV5z<^aQBD25(Tp{+b=J^-*Dybs2Bpm{;=e}oE(_`-y z_&l#)Kt&j3G4@ED__N1+m9?5BRo77bZM}*WvuIZhH4-Q(oU+X`C$d&<u!LSdoDEu9 z?)`MxrI;$LJh#o(P<2FO{jEU^gs~`MrG^fjAu7~ZCUw|w$D=J$92di=xf-K^ENSMK zFZYae^JoHft?v^9a!-<SrpfItd8Ui}BV$$tt5+JO%6kv<2;3l#>}FI{&9;3^IWX)6 ztK^wxS?`v-u8CxIY+JzZlo>=U6}D&EdZg5w9(IVtjnF{bO<?jv_W9`gCc7~zP-?ca zX%?&E&D@ca%(3*|HgvHLPs}|014a6DQgG;uv60W7_F<V=ciObZ$g~AC+>dGtHHutt z3#u&9&e7h}4uay%x@?<#UX@NaaCh=Putez;EQ$12ud>_!A;F)<@g-;7Mf6$?65l4X z%}P`KOr}JLNS=8?uP`ZcQICH668Iq6y*RW_`Ig=}xYb*1c>FVlTX@qs-wbsTtHi?x zh5P#nYX%RNYG=2^3^``BUdjh+#Ye<Q&^PL9xX7Pxi@uTi#M$E>brD=Q-qqk`_K0g| zW-<j!8OCLIH;A}NeYtjN4<=(M-*sbE8E3^)bM4kGW=iMwI<{u%0T&ZkYn5!AQcbB0 zLaiM;+^*R<ZsaSE#7xnOM=&;JAImb)dg{J#Uz7Jj`<Wf2vtiHZoum-7VO=%2KfrYb z)H_VEc*`@8VW+R0C|}b|o~XXB*(@a)G`dp^&)-P!sn3xf&evp0xE&_@wZqvw@?eNt zvK<;w#k}<f(V^PhJS=Mtb6+pQS=i2dywF%)9X9;ZOqMg57_YZA+?lNR{EB}0-tMc& z)J@b%9@Y6Vz4Z>eCQNZF@mmV*sDdMH`-wmj@J||(>_`P^t0C9bwdq;dSi%pb?o$M> zX-UW&a@#kSDi0BbkdF9`E{&=}bouWn%)Sk!svxp_(w6gx@o+0eJ{G5Xmy?tSm1II{ zI9x=hwI-p*AkfN*bk-SaPaV0S3X<n*Zd&r3Fftt|g(mbe^HaR(k%|{2wzo3FM75-$ zs)vou=^W<9FRQ}Pbu^_bIVS3M7WGnNhSty!D3uX|jz=Rw&-M#r&pykx(8a@=;oZ{w zIR{Cr3b)4Am^Xh||4xQ8O%-_a{$7AK-l)@FIQt*2&GEk^jc0u572&}BiLDx`*tc_3 zy`W4aisxSTqSTq~S3H>b=AzA0jkcxP?IVk*E;fZ(=ge2=-XT#6RF!P!v5p+a2f;2D z9Oys~)IUOnR%AihEqhMS(|TH#k<4?~UqT*1v~PtoedPK2h8c1GnxI2l*X5L+g6=(O z35ELyV4rE78<ssFVNsX7f+3HOdREScRC21K1~s)e8TGh$bU%#+8Cw~FbqGshd0Ts| z%)DNhH5=xXep=PadJ&-zNvH`P+@V9&aD-<%S2ja?11fFZ7MGbwH1rrd`YYYPP&&Kq zCq2a7_kFnH(XTTZLqiI(%SuroWuqNYdv@fJUgq~Q5F+V4dyXzk@`1wi&KWX=1H;^~ zkxj)r0w!Tej~kR255~Uk)fjxlg8Gr8x6#wh!<$OU0%A|^#|~xowU>7rbg_L9&;Ha~ z%EDBObX3~Dg)G0}EC9-UKI+kSe@Ka;MM9SW+^)oOTWQSGhfk5q%_Mh;ubXCJL9?fD z53<qEylA*vZ*t1qX~KwcSAg*K&_uTCt!u#>rep71IMEDCL!`jnxS1k|hv;&vMLWU_ zvNlC6%@O)@8ZqX=m%~~AFf}9=f6$um$}ees_KqSVj*bi0c_lGBj$2PVDPwiKvDol4 zoatkyqZYM!LTl)o?pwJznu|DFZim}#`I2?;9UoeqfQMAAYNQ~~O|DX{b5h9vhqbqW zYP#+JfCWSp0|iAwLP1eFM5N)CMw-#3FgheQ8pK9Qx(9;PM#Jb*x^o+h6ePz$V$@)~ zL+|@}eD3G*egF44?>QU}V>`cH*Y)lAe6Nr1kgfaYtz_pJ3HdqFmz1}XY%gas=h`Eb zZy9(@uCckb!_`Xl$e|6A(mI#)4w{Xx=We;^f>W!9McNZNO)Bo7&9WI9b2sqD=J)V` z%indcP0YYpWZ1I@L#Crky@%&X%vl|?xfA&8^9g2@m57d&<cup>gn(_w5-jI{hl)&k z-ey|SAy@rN?J<L7zysvy^2;n$AmJrpqWt{G;k4$~?$l-=+#IPkokJR(78Pt?KlRRA zbbchonmHzWH3yhOX)n2UJ_FglHbN=({ty-IwzFn%D$>+qR*=4aD{X!@WR+%uji`lR z>a!+Ny}`-IY9;bsj9nJoqm4|ZTIkGZ&ye+u0^H(3$Ty@TXKL!bkxb7;p9w*sqHjIB z^If;H&`AM>y8fSD$hWf>zte?<W|n1)=>TYzYxC(lY$p{ysrsx2wkQw0SlmA4&M+GU zWj@?%w&dfD=ZaS#<8`mh4K3+DW79Ue_sVCVb&voihcXjIQ|O#77U+}oW3D3I><_A+ ze?fEs8xpwuf0uh9GqiY44z=#8DR2P#th&$axU;AXcam*(Q-~bAxF@tur3@T2u{)a6 z5j+xi5Vnl%-Aw2b^l@F)#mnAH5j5X6$!7$#4fw?hjIi9W6N$d}I-)S9$mHX!c%Q#k z1FiQ^w1AK~nBbb)({L*ZR35NsDY*DR5@nP9>Jp&K1b1z_K?Z=3UzpVB4sqDDdI2>% zPR_CFD}{sGkw-6Z>q`5jFw4b5*`%F4(^zVWvk=RMS0j6iNptJA@s)v~%5RcOmzquM z=iXiIqfag$+$}tO`PjS)Dg6ErCk~t}9YgA)Dg&QsJ}?oVj=lodv{x^zDD6LJUq0<y z!NM7RZ<^BsUcUin=xmf?c#rnU{ll$sz7OmWVXpgOOPhF?7Nuf6FmpsA(Ph88nr5?` zr9X~h+YzQW<J2JRyqp{V$2I=dRhGbtkpm~r%oWbbe)Bfrz0sH9(T$PM!czx#X{&9s zI&w5x&$tcu16LcT{!l=$KJ2?mblRzjX5@)}Iy7!s@L9%`MOQj^DrfQLNMdn$s?!yE z0d<84<@nIh3$b>B#qy}m?}<7?ZrSp>;mY*!0_uXi`Z&MOiOOdz(1u+8I7?G-t}7u+ z%V?xtw6D`Vft^0M&9-9Rj^hwzIpn2hg$4|hw%KZ^vcQx!))Wlgx7hI+7^%aBeyfSP zw;79+TrHy?=1i!Trn|ZlZ6BL!TdJV&eOf_9*9JqO5HWQQN%8k77gZll+~To8K*O{! z1+-`*7Z>Ty(@=C!%A_G<e=(aql`wQeE+$bF(iwdRR4N7Oy62TkVFFGR&<h*$yOc1e zpBe8OeW&}=tK=bi#~}v`J%QaQ?=sZl>b*RC$i9hi{hjV|J}<#qg)eR^MGIS>7$NpY zUvd}_Tg`sXiTyy~h;ACm>Jft;fw8$@CZbu>p$B*-u*LS`jjRxk{Z;u~hksoxLw$~Y zONv!%a!Nv4vu!ZhJ%i_$0OZ%`(L$4w?#L@-#6_enf@S(;ns=M=x*`R$w@cc_m$>Vp zSU#r+!r?)&ufkWdHc5z-S#F2{kQCqO{nGWJk0`otzqzd$axflIQ_Ig%?^EQ<Or?LL zl9DN4nYsUv`9XM^Cu-VkrqFks*8kF#X5UHX#@g5!MOpU==Hx~lwx@O9{deiwt~-i6 zev^JMSFZs5<QY1*?vJn|&YE8bMYMV~LqZzU#%D1z@OqA`aCoxtdc<3az7m4}V*9l9 zjR6!Y-*2RrD*hpG<e+vpqA_52oR2Po)`kB;j9efyPr&EOHfxavV@22%Lgjeauz9Mr z-}mW)6}J}K{lWXVJzs_Hv?Tvl(UYL#f<n-H^W*p@1P`zSj7w;QMQbqaHBiCW<~0IQ z+FDW?<uJ1H+Sop<_qC|HF*vydKY;)$WG;FZPXe&r$rrE1(Hm6S>bxGDg`zs?dd~EV zFeJ}e>N;6FJuq4g@4;6nWIBSJEzFU0IMKxUh*2r>HZ9@sw#h8CL0K55i+5Q#*kJ<R zwv6ff0B-d+aLo}qj;h~zXB--pKkDu8B*rv+!P1OW)jjom#fT9T24m*K??tVicq4PO z+_#R0f-5xRbzj1q?_K0>(k7?p>n*rKkR-1YuR6=qZ&F&;F_Ky{USsnJfAz1{nMiBb zN=Hetn%bTYctN=jGKEFUw_jM^pDIsug1&s+xV)aXEy*;Dq#o=K1&0W+T+2;L|0B7? zMztgoOJ51B@d_)+`7FHW#W-n7)^1c_V;NGiXlUcucK~F}!arW3&Aj#5=&EEb#~x_5 z4qBFX_t}x0TWBwz@8bI8Gz7Ha!_6zS(v>Q(DDid7(v==3F$uWA(!Q{_rOefI^Jo6$ zkqK+!E(v}IE7aB9?K|J@$h8#L^YF!r>u)EWrF)W}F;D>Du7Id3;o|mI^EdDzlW<B- zaa;FhS5d#&clTLDd2t}T)tsK>Ft9v7HF6}aRp;CCvEzrj<-x~!dUoatYLW8Yo0H~3 z`K6U{l5^iC?qh&cjXFTTRBV54&8oMZS>s)?52JzghWgj@LZSUR+?gx(d3L;4i_Esx zA9VG!Mu^VU%-h-B?WGYtNq3Z&1t{?0LtD~tAZ#I9sh~stFa$Kh3slWkdXnYtgLQyT z;A9hxv7t~x#r26OJ{nv$A2SyP#JejM<hfuZTI!p1--%0iOg$A|BD5jK_Kpc&sp7Dj z9M*f`sbzcH&U2R|tn0qf(nfGcA{DS@K3;*w8y<K!QiCscyB}92%6XFhB2!^ayr4iF znum6MyvFFAm0xL{*8rL7%Vj8xlb^Hh>?^bmv`H+Ntkta_8n1k}>i3<obg9H1FZbPF zFZli%SCq0IQeINWwr~V0&{NE~`tUZ!C6Rl#-daS59l&!t%8A2LqD+6YE$~r>Hv?91 z3V#b>tz4(po+H!Mm7`1;dRtD(sbgo%t&;~vg1q#`OrDP0TKnA8&qkBxNt$yC^;9dY zu)A!71~+*1z<lypF_z&<tMIzp>q}UN_OWE>r<J#3v*kB4NC9MxMv_{I-w7PR2~<Ej zoWajP(~K)i^{F{%T3!Kg?bAKeRZ_q$MNUR8D+tFu>{_59`_^#@Y%*t6<1IUWbJRcs z8)q23*pBD+sn${<^w}Bozk<4bRhiotE;+g`fs(VqfnNwg-^^DVw|8zj1slDC@WC9S zvruS8Q=l34Gs6;Q%-hA(96-{qUBg{bVeN`Te;2}`)1}2<7<C4G(uM{=|H$i2b_rbU z3Qrk~VhJQDgtQ(f12~;r%s8g$cEd(%u5}J>-4^WaYh&QcZB(#=N$Sjx3vFclnTh0= zBaiZCNhbvB5br8hv$MCaVSOD;OhWXEOmh=cZVlil`nN^Yzf1Cxoc1wK_nb4UMI}jx zWOKlBIHH%M(xmKec=ab=8s`53Dq^Ja6?);bvXW>_W3y4${&2M`A$wu2yCTsxbZcVl zkH+H{v5_OmTDXe%ZO1$<KJ!FfYuzxQ3a%iAuNHeIQ`vA2b+>8BFM1=l-M5)gTy$Q@ za>-q!_9(7pVP%~oPD_|Iv!Ed^IHI>F=ZbmuIP3BAAh8@$L1>NOn%Hg8KTeWzXD=(= zc^MfE)B?uo(w~3nE~3CFUGu2>5~oA{h0KN6_kZw|EqoDH0D=kzhlZY(-$ydU_OF24 zOz4#uJ*&$2Xq_nO;he*k$xvfBY$W!HpiOkDq*i}TE)e7-ZhsX+FI@J1lHNQ_Ayck@ zpsK26R0m}nRt9!SjK&UgX9A@_`?fgu^C4lq{d(*@)G)rcYdUq~X|&})7i9^2CgnGG z=$**dx<?>}B8RZ$#Q0EsLj9Lq-GDy0qvck(O6DdIM6f6i^fxoL(Y?lIws5GGse}<y z1a=jOQG*;Mw1F`zhM?<lV)#5p_f7!4rUT;$K?|Rb?1_Qma$YDPRKzOV;&De=f<@># z(MenEP0#EpYJIS&Bqm!4Ea8yvYzZkE5cjB2U&)1qLVcM#k;uHJv)C{xPX^2m-EALh zi+h6h*v4qzsxxceiFgHUNIWc5VSd6uf7wXicl~O-J{04Gbgy=V#|ex@=NU}T4T5*+ z!g3G{5Gkk`*+l<VFQQ~orU{ZeS+KLTrh?iU^fS$!06fuM4Y#(sXgBs&M4zJWDSXw{ zOuWWRP1XL&y*~>Qti*8N|G8*^hSYwG*L<wLPYM8$?@$rB6u0`28nGzxOWOQDaxXIL zXO-6P50~j3eh!`s!-CWls`5H*eKhdi(vEVgRBe)`<nXVj`TB&MYdwR-pX-wA-npQA z6tIn1Gc~Q-g%&joH;69{fd~tygP?`1Beoi3LYlZI7!1b0K~{kz2&%!nO>s3j2+HS0 z`o8v(E-_Yl0TT5kwMunR&6h!7$=8H$X(HgY-Y0pYPeh|a^~UtG!+8V>mi!sWX;3ad zDT3Ywah`Go71C;QC{!H5#}^sHgg0cq2nPiv1Cm#3j4bkC5W3b{vJ8@lSLITG=NY)& zcO04s36vfzOqP5m&s(lrti?z3Dfr228X3FmTAu^^BwBK9-<dtzPuMascsdebrLVGP zMkN<3&gB=o&DvP{(rCt1hBeJlbWA{$#GhRKgJr&FeVEr}sEt(+kbyHrSSy@hoUB#D zPb&eVICn?%dTieC^fyI#A!`>k9yTHAo0}_<?yMTiwIpCBf>dp_=h5`|NI9}oUTv-4 z)UX}F|20va48X{h`dsDO9ut*ZSS8YWX->z`JX7DN>db+U5lNNeER#G{c#Nn6Y{w^$ zNt1yOX?wLj4O6W?;GJ2)!QP&GfmIwzkyR8<Zpkr9W9{j4+1Jq2?-Wwj7*6}jsWR)@ zAm$AD8wYt&xgVK!iw;Vnv)KeWe9IDG>o{IfF#Z{8%~a-WQ@KWr=fG9OA(;Qc75{qq z><K9`(iUblw#nHFp_`Iv*_d0T=R4dfz9NM=t<vCAByLb*90Y9$O;Qc@Ux&%&Ii_C0 zw)4N#t&?8SU6joo>;##$Nw;G`eG?fx?1Un|0guB>y=+~Vu<U8)XB6Ms1d9$<D9EAE zQ@ZP7j$Yz-Gwny?wQ$udwxZ_JbC&b~GIW4jU^K7*ZyeO4yw}ea&@B!^AYJD=eb)t; z3CqpMe#u>_Wh*4Epiz=HP$=ccEo$G-vu}Ma7Wd+zwV<O?P~EO-%6(7aP>~lJ+^V4U zBvPxcwa;gTSru_doF<bt*C>a)b(tir5bC6$1YGJdOR)TQHLkVv$x0BEXty54ay8u- zH&b^}D#~ngCiGF(*jaXkkw32S*KNw7Rb&{En-P^{)hItDUG~g4HcnuKW(kH8dU@9} zj6>v(e_xWX4C5rFu9L(4F1_o97}JXWG$y1btbFW}E~3qmT_~R0vu$`(vp`(GxTxN| z97nD3MnivcvQ_<5wke8t=A34QP_WT1iR=e3+-hC?yl%ndQ;KH}^bYkGG0r=qL_KrR z5KNJTIa>B#9(y(ie6g$R<Sk3Izf&!+Q3}q4y1QKC9fk=`SI3HI3JEDkPI`lrhxlP8 zeoTNmQ~-_FI3z*uJgZXt$tAhObCZ%0c?epG*&yCbeTOOEK28|p0m7_3tg(;4{BIT^ zO0Fc0k`OG9>I;4z8Nkl2(@^~f#y7HV_<Nm+q>4CV`AID?$rX8xPy96!YyUyKwET?N z%KQ%3g3@apxd#mh)_qhswfXT@THKrKTXHa-A=f{UW&*~Lp_QU3S2@bXP(<Ima@4DD zL5oyfqapG}{b5lPEE8PrIbl%;POk-R0ETs|8MyV1t?t5b=?7F|d~<1YXjFJd7iRLP zmSKc>Zy~pEA5*C^7PYKxkO!!fH;h>b_Cnq5P#U2N84+_ttn^RcRW$3l?jM7FJK__l zYVM+3M?1Uv`hCVZw^}54;pk=_cM=SgeW{-*ChT}y)vn$E=T!*Ep3=VSIdLDb;(7PD zmMKsRtH<nXCWsIltK3NvOcX2{2*_R2?-J)gbs^YBKBA>x+aEvV;r@`S*afV3P=b8q zqPmnyBiJ?dFzxvLw?!*^tm{ej>w<YuYU6&r@P5kr)Q8JA-EvJ7`a3kdCVg+_6ze{a z)@B`U^C}`{1m)QM?r?_%O5SM?AL)Vw25JXX6o`QZ^zFz05M(p`HiD6k?wt1S5GyLx zQ`xBGxNSS&D|TzXGCc0kX=-b*{iDJow|X^DN>o}{3isgDNPK(zTdO37oP<V)SrOq} zA@SSCiv9Ba+}zO>sjBk#(^5E~pJqA6HW(&FM~`N>6ORo>K6<%?<nNo)>*2l!7R0-X zOxZ9kI%;E&H60o=)#D=S)bp>jwq+{ZJ4m|C9KH6fYTObzt{L=Pn}67G%wIJ-RPL7B zN{;}1Dooq6*ys<9Ne*!Wor5A{8N1N+^+Vj(+yn2fr*FNTON^4^<5c!y-&$?*NSCQx zgGrX(8DxH+Ta!5nGA%pWx}=<3NLU+kF>D>GatV9vhP_fR<JJx`j_(E?U!K&d?nkOD z_0ey<KY(-uWISd*cwscY2LKJ+jFQUG+Kf}!eXCTco42S@;qV=566G*3?_=)}Q(vPE zWlqhBXcH^M%R@{&<EttAAZ`nhJh5Q_!G8SV7MxoABaY+1Oe-E#nSPXKu5YLV?Cl*~ zj7}NjDQoM$zLgkv)WV#1&>0r&^Ox~`WONcUnLTGy4DTQu;p=nASo$H7#@QNa%wB5J zW6`clIMLr;E3$Mu2+~@)qh8Qrct6@{I<0dH!b4Hsb!D!gx3XI3HMHpcx}E|6f&R)f z^*|SitfXQb<c3_C`#wG%<_#%IpEhIZ^+9`Aj4Wx2pUB7Fx(ol5m{-$7%^blHu<I6M z@)&TDeteguvW-P_+^Wu~uEoa6Mh=Id>dA#t_b~f?MzuxF>W5{Q4U#-S)H_cs2rvY0 zxxY#EM4&VzGNJah&b39@x0Q9kSC+xRW}FLs#MCNL`DrXYE1xT)2)#WO5IY^Tn;F|I zJ9n^*35W7!u6S80cY=X|O%D&v9K$NTj^gMjo>~%9h-Xg<T@cbvEB>J}Zm6_N==&9; zOlVElaaj@4*0IFh=RnfIGoD^P1lyArELb9zD2a270)m3aal4;vKo^!2fiJe__jSi^ zxYzbjW9+!%w6u3OY{1(Qyo2;8RP1%VmJq;Iv7<K(vpJa*=LFU7h}@a%bglGN$_{%4 z?5m`UHC72ViDep|5IPrFlc)tMTZb)R2a|R=bsXX*^&_=lrL!yM9Ol}SW6VQ5FUlN| zQWz@{;l(oRN|)=)FO?4r`Y%990dSv#gjH`4s0cVm3{BWgG<<c@0je?dh{TBcoNe#Z z<LF-e8l0e;ZZBb3Y}mKVAzLvPr}F5vhvF_I)lLr~Ze(_KI^rW+1M`pM2eG14eC4Eu zcDb#=A79f0wU1NYK@PjJk4w$}nk@RIuugJ1iiXaO9)O_0-`d*BdbV>quW0n{HDM$@ zDiESa57>(8&9z5v0}&p=i-E;I!siaLX(Er<BKo>>9kWz*D~418MQ)w{RQl0G5c?QH zBL6}Vdgkg@3TI4GGz|EnYi1tClAwjiU+X_yu^ZWa_9J25V{5N%E^VZMSgWkp-hqYY z>R8futW-`GmZDcgLH>_iQ|}&ImT_0z0z*xK-%@A$IvDvR+%xa5_QlUZ@~f?p$Ti@Z z@X8JnqD#X6?Q~S9#U~rX`$7N)P95N`^Odpv84)WjZsS~25#J|;J>5yS%ba`SERV~T zm`h6?#SH0iq3?j4nTtcuLm^<}HD6+Ayxo<gmYlVwDE-cQTsMcZ%OT4nIJ#PUJ2c5U zHvdLvT$}BD`Z1xzDBB6m_K{_3smqKZW=tU0XQn#b(rvnf3s?^lSV-TLS_p$&WAa2= z+vS<vE~)!4c!%05Wdy~&k>J76KFMq>=p<*aTQS*VTQTV+ZO=?a^gOo`&;>x%zFEVl z)I^@L(l+G{o_#$9RsFag_JvY!^N{=`EOoKC=I#}5UYm06z+MReJA6@<{V4XNK$DwG zsT-TY?E=-Rt#Q^$Uy19wAgKdo829Hib|}AH+s7d4(_oOjJin?sS%uoI7SDt-L?>x9 z2(y&Q0uyehuBybcdHCe5^73i=ezGAdwj>9KZ_F^ECpJ<$kRd0myZXL*L^;94S03PY za3y$MQo~YwO(nX{Jb}aAN<;PaM8Xw4Un>)jh|`j35;*Ulof%D<v?okBaEOq$=}LBK zxTmJ3CL0f&Z3%YU>J?EnGBTP0t#?Ago5wFj{H7O&<TS4)Yqb}0B!;ppV{GzqjO^Hh zc3&Y|ALj9~2mVJK9klj+Qf}LzKx=i4+QEQzflDo=?~-tr8o%|m`HaUIWNU0aT}1*C z=dMxV1>Y;+YkD6}$S<g)Zb%v`zD!-9FJb{PfDj^!<H3=xgsPI8c~WhR#0zDa{Elqt z0X*5x<wsv+#Wi3&Hw4W1HmoH<HWqLm<|CYIt@a@S=lildoNv@QL3=8+YOdZgqO#=& z8y^12hTGP{j}`K<7IqRZKT^^Ob?q<-qjf7(kHF=1ta@#IUzYm(3`#{@ce>(U`i8!b z=L%IpIB#d$JiD4{rJo6^0lEY~2zSi9<s+t-(|Wh0%+*Iwq>YljZkXsxntXBVG|Bb( z()rNA`jpf7VyGcG>L6L^gR5Y*z_NOH?WD4x(?}btx6^*POCky0Haa|GUOSLl@;JT* zMD5-=Mr>N`4=l224Fe81`gyDQ^@dpDo6NOR&*j46hs)4VY3!U+*NRHLK}0yNCw(mx z`lf`Vfo0^t3nG*XLJkWrx%I+@H^ULk5kf4!8gTjzoL>L2BmrxoFKoZ7XVgCrWh?o^ zC~ykJoWo+X-pcr%sT|-EUIZBIUO87(nvcflmp9``X9~J3f2OhD)X500lTqLF+wA0M z<0`6~?asG{2o-@A!8hlY)TLwo-6Zz6KF%c*8L`HcSr~4r$fL3S;Y1i!Cw5R6;G#h% zcd(@DLSN(prU>cd^5!za)uY0^eTtXsi;RNaf@>S_W$j_u+q>*%8B%Q|YUV+ioxvOB zP?4hpEq!lsB|Vo~jNp|y8QVuqH(W5ATnqjr>ATJ%mstD|RcdLTt6pZG&&<h0O9_G| zOxbQ%@oif*8DxHjY^_aN)B)BnvIBye8tN}!eFZ}Y*uC`aE%%<#JAA>=XhTxId}F$C zvWi2NwLrAc-{^UvUN3*22zik&w=Ie#7rNs*`=lyq;Rhd$kVoxX7*LsQoe8-;r&HUy z-?c4Al0yt*PpK`!KARp*(W?x^9@Ol5%~*tM0b7GtND|b2t;q_XH|O`RbkAaw%{ba~ zJ$OgSGj@3Z3WHy6;9_?~H%=M&r(9>qwI7LXC0ll5z9-bBH_khzFmJc3nXh<`bU%tQ zTFM5?HD@_lh1QfUlNFg167#I@m6Hv&@1;FxjG9z>%6qF-A>;d(3V(IYjIKk*qa?3h z9TN-|qSn1OTjg8loUb&;%Q1>@%-ryZjbxm5e|mLY{r)XamSE;(lK80^4UXr=<R%;! zkj?^KYdyklw2O4)8VNyVlICQnBnom<qUK?ONlM#DfzzQ+mWoKo=fN`7rflG2t=LGX zTH?j>C=E<M9zC}m{ZJF3SqluCTu22f0KK&wQxOiWiV(tI>W81^ME%&XvjpsYEO8pI z@G6FSJ3=sP*gx6_Ckb~W{uQ{M<P&}=BwpqoXbggWwp`g5`;J#@+c;=$`+6{^pc75` zW>t2;K|3`qg6?bf9Yn+!>Itk!33{-3NeM?2ESH~VwXk^p6hbgV%>AMBtLAzZLwW(! zobAZcp0ApMjp-{`nmhS+lA*GAcOfPp_oUg;IFj8z<W=*AYohP%d|(r{G_tCZb4=f1 zYCiq$$)YZp{3zAGMAdzM+S&7%N}FqJG2)aH?7S$6eFmu@wn{p7zO?C*pw6yrkdG5Z zYLmK+qfa`7hTA3#K;FD8`-a>&g*&UzLjKyw0!!W#T_?8}&Zrhaj}@uwH*%q*nD=ne z@iCUvYVQ`B)0?+N?nFc{?q+va45W#cXBqX!I8dBlaXLc*MXn8yO5>V_*%zMre3N4Q z001DuDA=Kb8#9AjM(G)1=2v54ku+W_Xqy}^c>O(vu}Iq{=S=2Nw0xXq|NDLB6_WUd z84dko`Jm6SJU-70W52=|i8iKT5ZNJu9PLTjf7maHGK-pMN_WVCRJWBZW+BsdMbjG# zV-WiWa~#{?x&EBzM>mR^PUM1kF3oZ$&atUhiWsQNYoqmg0n1huN97cqqQ*hirT-x1 zFO+?5Y@tLBt;uO)(@8IrK?JdS)O|^H1=pqC#Nqqt33V{CCoQ2QCmkZ`;wOz$`4mOo zFI%IQyJI7@$upd%09mEl6?9>W_F)5M;5UyJF(ateTtW0x+33O|ei5>ZX$AMgA5_rs zgeit~+2EclN`3%Pjkv#<UoEM5d7&(fQk)-2Gji8ZUZHggJ!$~c1?zAq0a`jopm-Cn zbZD2<e*TokNb3RG&6o7R|AkD0Rl9Drm^ehad?r$xtvvHfE}YF{d_uOqTH{s5&PBMC zuh6LhNbOWM(7<1p{sDs`)tZ3HdF+Lf9UmJ;Ai|!c2dDm&7o7ft*koa;VVXIZfi9S2 zbR)kXk}tpjPdDBr(6HqckK_ts9z0<11v`StGgS0~Y18w80e~%cijEa?o1%r%VqI7c zpC+o^hZQIxqXW~cMpp=~yA#Vl>jDhe#U|Qa_w;;T2Bq;6lQ3=TaP_{P`)Hrv_9Dbb z9c}0ln<W}Cw1<(2)ne$saihMXed^_jQGm3Ws?$!aiid=iGTnr8tiETk2oWD0MZ?Ys zo_2sg{3{D}l3!q@e|2!+(|owRTu|9II84ZU`=6rvZ~9)orX;jJLIIt4lPiOd{P1{x zfzk&2GfiL><DP9ELG&tl-Sq%_?Zx>fNhrSWX^R(5ScO=$9^Fr#HlFL<U%Pm&o#|)0 zT!fjq!5t^@com;7LnPO4flB?hL7OH`S#mk0A^>Fs72<l3szKK}1IK=&lCGeS6h2ZV z?_jyk;N!cPX)&YC%0w#nEGQ5ASRn}v<C%v6CmSYbW%<NfCA1#b7}KgH@`?A(sXJ#O zc(jSLgFpOiyqe}Lcp;o+kqs+TH&TAKTqJ(msp}T@X}GSx?#(gFa-E$gZ%diz%Mi#r zV**URuGJ>hBlUve^-8!#?kL0K(O3l!{+$V21NI3R)M!{;P_tu@<1XO&2&8{exkC58 zu5#b?3G!V+n#6uv1h`7$fccsdKsC=wF&+R7jN~X=dynYkjBH!EmG}uIYRuyu-$Pvs zxYoh>QM^|RyslRXsy5lB8WisEuF&ILOZn=YJ{OaJjJB#?k60U?QuH~NG=2Hvin!Qx z_eyn24y1b_1&|I+DzeF6sS`>w$piG))9(!5G~wxP?_JphrF-dT=I?_ai+v_kED#pm zl#`kLr&@VRRk8|dnsyJ$=L+w4mZhz0b6Z19QATZyGe090Vk`QG9{lr$0lK?$OCi-m z6u*&m{&ezpqfBVh$eQb+UUAw&#>=~vjFBYw=bMe4-6Q(Da%)<=F!dz&mEOEKVW$Dh zpihEysZ*BU3=A)~YLa}E#K2r5O4?$z2K%TJovy~iE<jljHKk9X&m{}e9%Mr6*rm?k z-Wp4s&!vplNu<Y>S_|`J+Uu2Y)mqmL(t1`5^y14OhuRZ0?`ocU;FxC|9pK_%ek|Bn zomM3_75-Vu_vY@}V~DmvWR(EVoK*!5zCM_t9H9)1<S{n2u(A<#@0rZ-t)P!hJ~VXc z6~2qk5cEa9o^{Xy54hS*7}M678ImiENyYY-7jm2RJ9c-qq32CnM)L(H^y*D!`(7}N zQ;BkR+e<JyK2H$Me$gbEyO2@Zx?*S$Mr+d_(nWehjCvql3{hGum#i4Bh0}Ug-Pb2Z zuY}8QnquJ5qcy&E28O#X9-ipqux)#hfpfM3sF;Eatt{A4b#*MdTD7BG_e#sy>@s6! zm)NS)9|$VRC+537z^@FML&;Z!KSPRrVQ6i~Z&sp)K|t3;pB=o56aGQ_BsK5_4mJBj z=uVM7GG@)&CGnTxC$=+C=wzM$T|0x!`43tknYUMVzs#UDlnguh=3m7=f}5g+7P?me z?i7y|5DT7<HYWl{LPXQILxTlD3n;74B0|8`cV-FVYCnwncCAdB4Zj#;oQ@6KEvA)S z6`wa&CeAs=x>uR5h=Mq|1#g+A_J7!ZJ}n&i%;1Z)|5hA?H(IwkW^%;qi_I5mElXjS z<#>&#3r<yoWzF9jYvegFbBK3E@kZU-0`~Row$B&L&cfijc#Eh8s=6?CuhnwmLA^oq z84aI<8sxA+%^j!`G4^XW0s5pnMmA2{i*RD&3w22vX|~<<<RRCUBjKfzm!(v1YegcM zce6Ox0Et13Pk?9o;<|<bg6o^-?ZRq)dM6hy21y07e0c7Z9?JIl`@^u`sKN`3C$N`Z zZJ|H$dIx62rgi*O3iB12bSiQ&VuAJ>sI+<2%{8&SzFapd)NZX=cIetqQS$$*mwo$) za)9l3;#EupATk+XKHL6GCeUe<`teJAii_@KeJ=BOX5^z~l$2fhs^2ZeO%_;1U)-uw zWX5sq7w(>=lio67p#JXkpH2L-<sKKV{neEDH`o5}s6&48J&Oc?;sYM3&uCVE>h18< z;BqJ{*Da#{qC3eg@uMI~*FZ`(@82Xt-~N5_T+fZ)Joz0Z5eKRM=hp?rocsRyS(mLH z5t(zK%&NVW653}{h%;mLRgdoqi+9NR%N`}1C&G1T0~Rq+adAjKhBr?-9BK&`xKtvH z=>T}a<F{DF%S5zJZ0cWz>fWDNpqMMe{G?~M;WCPH>PPbl<#M|1Y;B$8usg~J?;4m- zAN`4xDJEatB@yY}hno1g`ZQkHnW%nuxR!cc@&5_a_`hRf__u281VLS|0_c~5-&p76 zNm}E2@sR<Bq+-8|x@L)Jp0;}r|2n`a+MiI3skki3U&Q!KArb##VbVrdz43-`w_9eH zK+qVXmU8(2@##%Bo&;I}5M_BumNQ51@|rIGhTu!m#N)vCLm+>4j&73fP>c{+_FH_? zxnEF4m#?27rZ^hFM{q&HX30)-%v74xFeiRW^4rSGT{hlJ%)bN)e-ZSDX!`RKA;4+T z!#96QOtWGWo&@(jQB>&HBMb^60)<y(49~Uw1{Ki^AfiIQ)@=4L{@6zlaqPP$oa)0e z>95-oI{|;`F!TPh?*CZIJtBBZc)rEsKmPesfBbIse`*(v6Sc8eBjoT45r3O4{Phji zc_Kq(rzBkZ^`HNdTl~!%L0|6?PvpCar}gi2*>9Kp$>an<OEdguMDTyv;Lm6AOOO+l z7X;In|J#()?^YXgo(M>Edn$Iq_{O=ZOMlG*_|4~krP{wg@+OA}rfznhOcef&cKt2k zKDZGHq@(`$1kdvu)&IZWX!?GYRTJb@C|>s4ioxG>@4sGZpD=b;@bdqKn*Xt1Vov@v z^in^_2Ki4{E7L_Jkea9f)BoPg|I5ysbx!1`daZ}yKbG>Z&HS4PfB#FV`UK(5kxlkb zS>M8oXiLN-P^pGLP1`>p%)RSNuIVea>kSx&2^`AYMY5uQi;l|uQ87zKKMjORg2hYf zyAQvCIaPuA8amKRat;@Y5;E&QgTc@jnb!qu9JFGt6aSDFHmBJ0Z(1h{VEK-JK232b zHM2|7NVV_#ypdwh*W&xJq($M)f8A(*LPt826a7u<y#Mwb;mH@jl}#$d;Ujo8m6zlU z?m3EV5jRji;36UI6_9`rnvOqgxW7wML{Z25-KPn2vytl0@7mlw6-f2{fBf2RpC+?T zoA~vFEuNj*ey9n0rWQT;JFWG5CfSA)N#oC>9{Br@{BK5S;wMfK03~qWAO0Co{sR_1 zFd{Ni18t7<KW2vn;;;*`$Fxay|9GSRJVZ$|4;g0pr)q)!@rgHf=X~$|f2`0NXo<F@ zsCAj@pUMjz@rE$yrRdkzN&l28GUh}jibl<D|2B~Sod{i^Ik8Wje+a4lQ>vsF5j6_d z!S&z=g5dw44*vC#Hz$)Xnyo%2-ub6g89)(FXb1lAPe<-|oBAKD+k7$`;z{YiW14?T zl_iH0H^(T2@T>6sU)VnA$%$veZ)lqx{6oFU1fC`K{iuaAOQKm!hdKUh?-xjeh)H^F zT0S$0vkG08{}<o+a1z;BV?OsUGMiG?;n!;Q(m6jvO|`ZDzNnxl92RHtlB7}Qfk(y3 z;xzxmPQ4-CHvw(7gC}zRT#i4t#TjUlh}5$cORt*06V~GL+3)LTURp%b-TJS^vksg; zAr0xRpV1*PWGOzy@{qjt<aWTn9h}^rCmHyEco_T=CnCp;>EZsl^`+}1#C2Q;|Ch&X zq4{GSPZR0b|9c(JJ`>kr#((qTpG+Wgi}(~3_Ga(DFXQse^u^KtF-E27JJCS|dF2b0 z{nT*j=BM|X^2|q<|2~N(NcQHy^<(FOsVUx~h6Cu~f=FZJ5q`Hj?fB4Ue<?G9J580h zTCT8Wg)>pox596?b~<+5f8AHmek51+iAVy4-9aTB-nl5XD~eeZO55+TfLyZt*#-0q zA%ob7hoVLreCtn@Fd!7vKwORuTPE#)?R~pahVyum^~R;{{y>8JSh-zvd3iazFv4}N zturEEo2_~g;>*s)#+D~`bp_Hy>_fY2(+>&LS5Z}s-rn}$vWR8<`tbaJ`9T*%Pr&I; zF0nKm#?f+W@k9)KY>DN5V<M>d1Wf%jjZRoE+e`o%aKC(=Y^QIOD_g~8JQMfroSl=W z!S*J$pm%6n)@113Rge2B*w%gxrP27Jg0JPgvSuldP6a*T`Orm`@<y0D`tMt}ID7Wf z%JjtwmuX&@UP08t!UFR>wFG`yh~K92KECl7&x}}i&N|*tJB|zwzqG$StWn_G%-<qm zGnFiD&7b34yOa^q(nGwPsO2oZsM{x8RjohH#@pos)RTLmu7?|D*%rEC_CJOzTyP5t zAnsRM_l`~jU{vx;B3IU7-XDg~u>9vbR^=93`rv~2ikuW`ArY14HNW7un?Gg;aPDp1 z0({en+*WPx%Dtk#@!9WcxhE3q{6XBh&1OBx?9b#WO0?eZ2$?0Avvd)KD`e(2s8B}| zhMC;pHe3hj%|ccEi|!}G1?c`D%{yqaJ9|ao+TYpsO@WNdacvO&g!i=nZf9E<qi<_@ zaj~X~ic0>>fSH}9L(7H7M|*P-S@rd%eQDA~rpknY3noXaHqu;~iV?IzjCo80Nq*=3 z^-E!_0DpFU6W7;-4}TU6e-TtVQqm*FT!zaM3Hi$_Ov2g^ZT={2eQQ<yv)wCEsPZSE zd_x9t(xQdeTP$TxSWaO|QIrkJVVt)AaOe<CrHkmsb4ObnvVKf*ON2Sen;Tc=g6@Hk zx0kbh4fuyNZ>QCvc<pE!x#J(#mcK2~JP9<Hn1ZGVO?jRQ@?8IA1o<zY_Su@g*wd5Q z9mf-0Du|u#@qH4tzrSA!!XVAglM0t*S5#D}u+I|S@JXsd>7U!5NnHubvA$fmZ)syH z{L;8rbX=sYFDu^6p1c6Pc&5wW^M!7&08Or#re3(~-;KtAFX_t%ngFXv-IJa&zBS3v z&&Vh~_Z%)wxal9=IUVogQw^7c68pwJd*6RX3W%Ndi|yQz=ZG%gBX-mB=Is)ejtQyd zE{D+_U0An$(=zSpo02Erk$QG}fkHjiqxtsVNqd>@6>0tc`WY&T@6RO&dvo`+s*VYG z;A9Qx`a}i2t<S->9oOiHbI&2vSEy;5s4_zRIrDslln@ud!Y|Ew!B}Gjg*ORK*|R&H z9BCaLk!+?U<)*mdNmf9aBq^X)dtU7CD&wWb37(JlL)iFQtV7$oaya~6@8HTY!6|wU z5nDPdi{)Cg?A!0JV`FqLV)k39zdyS}m6Vl-*l#Qx=1b<JnKgf;kq+&f09e5IsywVe z#vFH7-hPCA<jw&NyPJvF2r|{^ChM>JDB{E<eUx@FN<=cL7lG1aISqwK8{TGV^dydi zanM)Bhl{gscDUTe5==MuZ|iqfqw6=9ZHRnfCJzQoe{m&->e{>?mdJ9vkRPrrM@ik9 zZ>BS0@<@qF<y(s@KDd@v@0Hinah8sdXMZm+OWmr6z0*)aLy)(nm@PwURNMcPrzMY= z+$|`?TUFoT?)9NYgi6%078%?JIL&^JmMg9YqLR@X;6DYqs5)uRP*DGX*Ru3+($(!2 z&FJq^B0Wb=ePNQ(EtI>(@AiEx8r~(et;|1X{N*esuPAM=pP964=EkEPij>vW!(r$* z7a6||e0;Pyq{^rK@CMjab-U@pW*rV`Ol$%vjLgWmrC;*?J*7EIA*r$i|1p>_^ODNs zc6%s2+k%EC8K768r)e-Qj#hsLV<U|>tUlcAHuX1IB6FW0s%-dy5E-C7jFH3o%xIyr z<T-8Oadu5Omto=Gqb2^m(`O9QS8jPPe%o>bH8r}FqhdN^ykGNvmB&m+F2<8nKr0@g zx`Pky*omPEZ{1bsYza1xffXfjW|E@gcEEP}EXC+bt?RJo&Ea4>f_wc9XZxs~j=S{2 zt{EmmNA`&y<j&{|JufGWJ~@}Bg?$h8^?qX_q=u;H-g8*S1{6poN2u<-1l##Y=O0{y zt+jOO%&&0GUdi2<MFxrP?9n6QS29d{y+_{Z-7^-}p@fG*F=ntxaqIA~@O!p*7mW~A z8Z8HUP9`Zgi9;VCRW86!HJ;8;_wLF^@U3ZzZ?BS$TloA<3kfffiKcCN*CZ*8$Xw{L zuKGbaMp~F+*k;4b5OEs8!jOcE5OVIN@p)iCBp#Ew?FetEI3W7yxJa(~!%M<-!RB%0 z+0x3}=hH?u<UkXj`fQ4#RUwT4tis7OK$&UE(*ZMA^P=T5i=tEQ?}{edXU)D9su8)1 z_XH2Ddz9VA*LbJohI%_apZelLc-+?O+reNepLtU>`jBk$$RepHut%a%fua9;_a{i- zR*$pc{eXb)Mx)^*PKx%B=)uJ9f*>cU(K|5f9a#^wxu+63W@&wa8Ota=S1cOc16iS- z`y;K=6#OAqMh<-3O=U%pmdd%-5ecoJ?7TDzE?jIYF%<MhvyKbxZ1tr$HMwg%qGNqa zoC2|PQbw|WXqYvmXUe((r1x;AXZ>{HU*LT@YtkU1_o7B7wA>0unQ?Kbr@TYmCsXTX z1#ImMDzYfMx|T@nPPj*<raF;-Gy{(Tk-|c@+uy%7Ynz(#kdu>d4m_gjyd7`y)KqBv ze$iNEo=%RDQ@Eb;MIRsWKtf%t7Q$GXhexgFl#bBeRz?VKX+TdCV5`nss4OSRPzRev zwAupWg6s7n?ta#+b}m!u5Q$~`z8lH(Bgs>p#|6k?qTXU71(;4q{3~+!(?D4$oxM;e zgE&LPuwPX}Y4N?*@3|r=!GD)X(gDU&@Vxdt*g3N_L?bljOUh$xMwdj5)%*Nh5A}KJ zI=ydcsG5V)q6O(2Q6SjDnKOs*v<W`O_ik31$T-vfnl$sf9~IYQtA`J1@{fCUN}rAy zi7r9Yr486M)_qJiOYgL3JUF&4=rPF#CZ*;zydc1fI<Yzn9mM$+vJ{-G2A<9?ahjb+ zrL*Q-FDPN|oWs~~P?WR{6yx*5>~}2N4MxXq?#1G*7QRr-&S&R7oPBe!_vp&CQ|NS3 z8B<achuQ-;o3@w#iy0Gy$q6S%AfM>Z*IqO6;by0CHu$=dfg%M+kMg}nEp!AW4odoH zV&`&>-EAa{VK5#1=bXT}-J)Z4?uQ7e<@&VSnLCd0s@hv&8dH5<C!@kz$VsK2t>i|} zvlY<@t#a><8J(LPOO-*qi&+efJ4ETuzfR5qE^=-x0P@F^I8a9~>Fd+DeAVB6YnxKL zMV)4Bf2n+blAd~Q%p_1G(!P^XQniPkHU_1#9JRJrog6X}1A9K~hxz2oQ|@~Dq2i@H zAE6AK3LxEHmZ<Vq{A=1*AT$wmq-di%Xq_oe*$BQRZ^jV|x5Y2`v=~=&d{EA_pb-dP zEd7*>dcV7+I~e4bb}3F$XvwTm_mn&2fQ70D#b)@Ugxp33pqMm~s11GlZ#Ti8?eZQ` z4X^qf9pK!E-chyvq{pz@=J+%L2`a3mBJ8*v>je<q@M>smOw68OK@FwHM$?6dPQ<&+ zGe%yUJ|J_#T8y7}=*+`j)P)zZufT{NlF(gL&za;Ug>?H{^nL%OU%klBn55fhQKt8J z$P2VR8>fPv>e<hDtL;Muz<5gCad#dcowv7wS`4dPb7ZI|&R&@3)C6=(pn+uFy2bN8 zp2a{6OSjd5=LEeu4ZIAj7?z(hcRB^RZUSp7AWyji&Fw1!7;5R8u@o3LV!?@JDl`Hw zWzsrhY5_7u;0Nh&d1_C+pvX#CQ%7I7VzNQ{MAw}2t%jMt=MdV7jpHuH#=}N*EV;IK zzKI~br<~weecoy@(k(Idp*q~03@}cWx7sl6Rs?b(hk_9mXO^W7%T1-ED)i9=!X=HS z6>fUN26craY5m0D*VQMb6Mx>zdqKnG<aK%JwZ?$-l?U#e)ts=W9r1vY9}^|)-+X=_ zqX%Q{%J&M8#!NgX^yj5UJ@AecZi({e(Y`;<_y*Q6cKEZ6TnFg(qs4KFFKYWLt|ymV zJX~e@7(xphuP$T0uaa&*G;yTEA1oO=(!{&uovce0^m--WBWeG7=@-^4FU8pW8t)`I z-MimDT{zxC<0m?#=1=QVL1YlJI|o@n^fe9E?eqYiOA}!!|ISk>y_T72Wc0{n6KY<% z-nb{fk1;=9f#PsQfu;e+`03g{(C+7pA``5Ed(A8+2*QF3p{;Ae-ufzbxj@-JWIQJ= z06n~7iWDl#GgCsM(l1eyLz94tc`jN)_;R%xN^K?~>rfM)<*XsY<kQeI1*D6=_|rdB z7~KRZ8LuWTHJURMDk2_r@P5DY80*}LxAA;9Kiuf@q0Rt2lpdP6FvOkEC^MDoQ5t~m z22>R&=uKOl@jD=T1txKWJ=uxShTH>!L=M-<P>O{X!O)7e`2At`!!b=8Ud?Ky=?@}) zW2Qp4b#?B!_pXtZ26y$ympZrZS~+6Qos-;4;1IX}IC8&;whYRrIdb@ZzaVilfl}As zHz51Q1-e~Q5FxCqnmC}qD7Lx+5FqMOBXOC(L2e5?L3*HXxj98EK~SX!9Wxcm7}Q@Z zBerX*-d=Qd3X7BE>&0ZsicRgTw##A)C_>QltN6k$JU3v#rL604r8X57pA**~36DL9 z^&`3?ZF>zkIIyrgWUa}%z9L`(@eo(qF!$Ze``BemG6-rO7g^*OU!wC)8|QuE{T;}$ zekaR0PwC}Op^1dbAm|}p!urp2S%COeo}QKCG9~LH+Z=o6up5%*+{1N&G|C2$9(oRG zexWW}y>}%y7r)f3T@Ln;%YQIojzU!n1wpU3O~u1&r*xFV7hXUrm3OXa_IOKibYw6T z%>_Cy;XO3ZKrcn1ij>$77;do*-8S{@bwjEjX^_3N;@!ahXh{8;dm;`cJWZ&T74Zoq z_TB=g>bx5m%nyd*zm1kyHf&9b3OJ$f?{}LMW?`kiyUx}73(5YA(UPtUJ&EdN!FR^h zGu-CdBjO|36z|kbWNv{q^TrAjFXASu-3!6IHA}auS4+D;6%?rTK_oFX*3wGEKs_`x z)a!D=WVXL)BZnpcHS_Puhd+}BK_74OH<1DW7Rx*#Cg$hUK9<@uj~acYA_e)s_N$HI zNxb#i=le`)nD&-!!(;xrEit34*^O&%_(uEBA4>JY?-#|C5FvvLL%cp7ITB@l6~b{l zmM-0sBHyZC@W|`Io)7-PW#Msru+KR##MD!x1(fQI07^L(p6iVA=9+Ndb5%-0^#EK; zahy8&5E1~820*W9GfuBagzfAPFVwEQxg^{@(M?J!Z%PtLIA!9(YJ;iO=-hto(7W8` zvXAlXssWaG|D3^LJ|SukNMBXHb{8h~YKPnkUC`5`A5?MPDuXgR*ks=+@jHvq?R9#5 zMhyy8m}y9k?DN2tfKgWr6A{W{0EC<;nOH67dYWoBcg;K(H0PP)jCD=TojfnY=|_XA zf5tT7vFD$;7O2)4%*f(De&|Bhd;#^=Iv0j)P+Z&$K&q9nA~xK#z7}jQw{ckNyF_k# z2J%|+zQ4Y3a@I>iK}}RC)TirSYotcSJqwXj2#xNH7G$>!<sb!+1G>&iJ{MGkN<rUQ z>k7Zj%*Wj7L#c&0>KQ8QdzVEe&955go9*@7v(xnt=^A<HJoK%}F${bSV+MbM3=Y>v z&<hbqcl19ax2x{r*pjK95ZM$nEb3a2Fur}w(;Dw^RBbYpy=c5hV;uqr%E=)N-Q`)4 znk+vYVz)8bndtTAs4)yreF*dMIb|Vns&{o)*TAT+LJoiQVg*(9D!AtHLfw?jTAa~2 zp5%|ni9}d}JHY=8JNj|9w?4gtQ-5x~?b_SWZ>R^<<BC^+357c?-;|T;VH7x43m)~O zYW0HTnru?S9gU=H2-%v-f_n=(XXT)(J9;cfdG#KUP6}~1%mz^Wam@LR{qE-T*O=uk zq~z<R%(5qN{T@klaP)k-bXr*!G)twF26*|Bm-F@xqy&jVU#A9X7wH65K8M52EOkvW z!fhtvMI|l`=gb<nFBL4NxRs-L6D2>QG(7Spi=qN928T`CmvXo(->3b>GGFixY6=ut zYRhNwnj!H%+-Ua~HuJ{;49j!3tj;#5KxnRAyS7=s?%(gO_l-k(KUiX;g{EPv6LR)# z^X5i73x{#t`1~CW2)DJSt;^JEy0(xe;=(H@Cnp>^42+z9cZDrqMsI7XVay2~f%7E= zfG&prJyA={jw(n`-NKDu#6>Vn9`6&tY#9;w+{)CqVa<y;(v`i#Cv(gi=0(iH-EyH= za)`iHFSLj%liz2NJ}l1uDs*yO0y{+`=J;T>Mwr+*t#LFSO18j$i*PX4c$~Z8gL}f} z_W&)oS5NGp^}*?Qjy`<${rTWk@xZ+--wCH0lfx~akLvnc<}88hutEW2swv;e$+t<c z$?&2;kdxU4W(_Wovs7mM^v1j1&y5ts@gu&dK55Qo^L~1LnGN1<ir(9a_0`{Q9~<G( zZUw3XOXcqC^+3nH<;=D>Q5TW@nbO2&Y#gM)*~qZ}t77A%V+vvA{#;LEy@TogU5{Ga z-jTk2sD=daN4xNLY!eY?b#bd5ByR3-_1!gNm#dC>g7%*A44mx4nt?{u0j28`jyIe_ z5V{~YNfd6A+!z{G+PZdd05UYOHc(r}a`OsscBzu$<6aY6JU`Q-iZiLup_0bPs<yn{ zXuMM5;L^S%QcpiSwqF>!D(Y?IGG<K874M|`z=yYudCi+$TrYd{`!&&N+gF6ZovAZo zA)6Ds4X<+89}L*CJ#CFrnb3L^MqOEAF@LtU>Y^ezgmH>&@wF-UsG7g1>EK9>zoaPy zTxMc?z6<j{uApS+?7IRBqbpxOkUCFXyk?*K@l5a?r(%KA@04F9$T6qv*4QjSsuwW( z9Tb=Mq#Zu@2)PFm)*`CYdIAYs(ek(W;uXiX#;YcPJEB@|*brxYOOx8iT%%CJoe$mV z2pwVtljF9IzD7CNg}f?mpQp*Klf2UH9^-i}&NPcDQ?AWDUgbtC+uyv~GabU<5pPhS zHpzJfQ-fjAd-Cfe_1bISKVYFd-H=hMay(iuXQax%z_lGTRfE|J(M>yBUR@cE<w5i% z3~Y>mXHBoYfvW5_sI_GjZx?Y1Rrp_4GP&NZG@7Gc&X^22>mm}T!Z=@K;DlvI#=BzV zD!?_;xewxc2mMF8F`pM<^5(AlO3XgTp9_MfTwaA;9MixL+Zci6;p<FoXj4LI6)<gM z=|Lv&xZ+)fv6Z8*MrA6aB5JS<u@%4Ioj+)RZ({mrnObOkRr?N;KxYM?``O)r`5Kob zOR?S>_IuRoFHfC){?|{+(dj>qoj)kRT^jZmn$T70>8xQ_sVM+<-pIv6V=U2$^O;pr z?qe1Q_t-i+s~<$9>R$x&3LA{r7gr%Hp4bdMEGQ^Yc3U5}Go5OFOC^3TS8#bQxPmCt zZJp5^sa`%DS~r-^7+*d`@?SqeWp7WV_Ca3-U(~rm5zcICzj`&$<y^K<|K0k^k*)QQ zzWz^jX#r9@3KaU%cSrqJL6KEtxd^Ww4kgo~S7{_4mnAGCRFKEZdAM^%*k?CMji_Gc zoez7PX6UjyHqCJP`5juhGng#$Y`wu3i)j;#M$asJP55d#jxAoF|JIMCzI+zeqh8KH zg&&o46e{$$hA5sDFQ`Lm@NWAS_u^S~Cl@JYUV=7|W5ah!c|(wN1yX}5tOXvgpdaCC zM>9Ft)Qq%kI#aAOla2=YP1#eYWh`dSzM6VQ{X*op7t*wg=~DX$88p3qk5$+8j?{*) zrBkr}-hwiwhEg%t{=F5v`2C#Em;DC5X<m8T$+m1?>bD}pL%<3Fm698SObV&UY;XSa zuJPtE+0EyiSMNe2jEony(u-CHac<oM^+jLu8t>_<byc_Z^c&~2Jhqm2(pqwUg%Xgt zvV5fsjctnrL7rqRSeV+#z4tG0+dE#Y@MkrVSysl^%#+;QtWdOhctP@sB=+;{44a_F z;1uLpu;H7W#=A#Spo~F-xIY?b0!w>&%9jGa&R+)ZhLOZ7;h8Io<l7o;Uh?Q+A8=BK z4hBP{T7yGMJ4^l_#=bhPt)^SILR+LQ6n6>~cPlQ%-Gc{rcMp^nEmn%VTd?9TMT@&@ zNwGk12+mEv^S<xbbH3htZhrfZ`317~%$jG`ewNG{HVja~<__|^qBYI)D&pv!8rbvP zUTlC%n))WolPWXa&PL_xR)`hvzIykYOra5SYkPN63f4YXLN^)JH)&6Q!vzmFa^T(a z>qu}k0SEPAs_o81zE$35o+4Sfit00sjrmL^#78w?>j+Xe`SJU9cNkW0wpa*eFCb^^ z+l8e{F*X?N`y~t@jPUM$U*G2Js*8zne1s%|n414_8Ggs)fdqml69laUu7|4k+mAyc ztyJ-g;6WD^R$XGGl_q&bj$ln+o&&FqU;=F06vg5I>KDNrJqhGdxjrBK#nx@DAD@kN zjz@v~q_iA(m#^eGX3*HIjNh4lZQ&EHwkBU6@3Vafu7?WtR%b6gr~K?6idCjqa-JNt z@|JyBm;b}M!Q_TU-=~#e6hPPFuq-9MUq+?c%`mev-o6ETzu)(3CFT>}xdqTTRLWla zu~k?bG`N%W*Q!k;LK1c0K~YI=>(5P--d(X_TZpbD;;OK;P?5W+I~O$X*^i#Cuw}2a zi#M(hle`>UjIe|9G-uA(ZNc2#S>hg5(Y$p`Q|K*#)qQ4s<B(Dv0dZM@!6YGVcD?M; zh7rpOwH=3oI}v>2T6fO1h#DyNHT7R}i$;^(E=gx6)IPn7S2HWhr4JwF4Bu#8YN$%A zv7J^d=ZLUY`fP8~1r&Yr-K%t2-(;q6qm?jsowWUd8Zsbgv1FqtC9Rr17WV;^y#!W; zS4R-}sV_#-WHMKEsZUgPEBht+y4*LFc=4pK0>geM54Za5Gz;|<Bo?uP8b)NZjN3QN zDyl6B;HiA&a@>WwT_D9zCi#bT8#v3<xc3C;rCiqP!a@_qy_5E}xP==D+Y3XQj$a2$ zi35ilU`#(=)>17g!Rzst1tg(!Khz3<%vY&uWk{d_hK5b2Q&ji{rN-jrveO`ZA)U!| z?+r<P6RT967yil-?Fj(Zn+7&GkAh3E=!Spm6<mx^(5-j6pB6Pd@SK$?v74IPcF43^ zZ5tv;1iu(&tKb1CTi70+I<e1CJ4<nGB}uyY*~~Y8n^eMUHJs+Iy)5aWk+zVUE#s0z zgR9w;+GuF_>(woDs7RZ(-L{RAtG+4ivypW>ihp46OQZaKjQ}5I`*TY_4!Hq>;r=%e zvceeA^{o3{|67*PgGcF7>sn!>^d94^P6a{*Jq4Md^W^dQc`M)3aVbd$hl*rN_81!q zBg=JFDxs3WO*}C8c*n(Pk@Z{I2pwaKP(ha=+N0MG{^N2y$KdG-1gk`)k@Q}@r-X9$ z0czbQyYye>;Z{@6kN6b$i%y5U<sy(2DT21mtV}9s74eN~l14k8dX}i1mC!^^G){h* zk!bEm=-~nub&x7gM3dP83J=)Ys6hBWsNirma%UdR(O7e-wZglnSuK;ZQvfKqv&|A& z@s!6ZQG-O>KK1Q|M8T3G1&2RSvU>aN>7<5D+|`29>2{w$IXIx^wfYN*u#bqYZ#@kd zBT^LlwwQyLN0i+of%@Qf3#d|nEz%^AzwHR~gEus84W{m+`rHbHBL^M2<lJ6)MQ_6b zvUH8EGn}_J<NJ<|@WYSX0YqFr;7Dle4<*xv@<>E+HA-llnMH^UQ&y|ZM}cqjtqO{5 z1C`UxmZwkWH=WQFUaRAbV>+FGHGH_b0D6}?ry%;e*}Ywe1t~=|kiKeT`H=Na0PhlL z2B7GJMzE7>L}K20A46u-<+vBjNb!LDKYfUhOmI8EZ;yKz(02MHeIliJU<p!FF@yX^ z0SXxu#VpMJxFl6-`3BB&ZPPd^DHJ9Ks4<{{NrTRG3!;2S_`^lOG`IT=MAeLp%iiqX zXAC#T`_uIbHMuEh41%Zw&`FUBy71JzrLwj?Eg5yZZYr<FihL1;G0o(ai%q|pyEwL3 zm+dn2%y{T(GfVs=@u!@+`4oxEU=G|mW2U8H_3PuW?W^048D)h^dE6m^C;+#GFlf&I z1kAs%8IBt@07FN3cQ{q0iPiI|CTFh0OsIqxCnhlI4sU+ODh(m!>F)fh&q5nea`na; zFzqz_{_#a7?q}I-Xr)OX#coztNg3t>{dn0uW!DA#*64`j-z(ssr66Lsjr9wbXpsw{ z-0|=|^rk32(NXW!#^O<(&Ub!6QQn<e_Z;#n54ls8f_cC~HThh5X1X8uGtczqu%7vL zO5l#67An$YLwtNi0p&JHC*V&VX7<YlHl_ZXYzD-GRsb|nEHsLbqSI&BR7-1@eJdCP z3WaMV52dCp>@+p~@0#=!)khVT521WLI%o9D9i6M{!VmXzBdrGAC3{yIhgcq*pK~Gb zN`sL|dJ#WL;_mvT29sx45*MH5*C5sy$uYdU`YAn4RCKg}L637a18F1-%hyz?Rp2cQ zQ{Y21T0yUBUF*0{C9OI<8aj`7qdA~%=!DY;my{kvT+MZrv~EQFCRd~Vm{;eQTzfit zbjy5#*+Py%Up9Pdw<l45pk98b_2G@9M&q#&2kF_XeouU9K@h$Fsv-n0D8W9?o<H<_ zH(Hr1;6Vi_(Q%v8K!O<+r;b6-EdKSBoTijvpN#u?nihLkl2bGjVf>M(zFUQf>`VKr z50ClRyh)tPlH8(1VxRk`mS9x9XtC>~!8)Z&-X}3KHsEl=z0v0$Pf}qYr}bIEHS_6J zB!nbDcopkod|!wq4C1^!ak3C-zSY1PzkGvF^hJeY+}twr6^v+Y*VG<ar5Sf(ppME! zZTqt=TY`Z_V}>=JYI>fo0sE3u?uhr~3%7ADETe!jMcuIPBry#m<PES<;xE!ggup~Y z0!O6Zkg~Q!g>mKak<;-xnUKKiH^8rk?+EGMyyWx0yAiqS3VtC+Oczuw6-^q6?FGIj zfI`q+)&tK>Z4e(*Jre35iaZ=~G?`juE<g-80x!Bx&<pBfq^l(2`|vlW@(-KkVL(oE z5}kgmDo6JUPRxpXmBv_WIDy<?6C5sK!!2MQcehOrA-~hS%H@)bP1aQY%FEY1UyaCF zc>l5R5`2mA?PrUHwORl0?R$(bJ(1vYzlZk9d-K);{Ii(O)<%Udv7{#{%b(Be_6tjs z(`Uk)r$&HSj+|$SO7ZW|0&g#OouAM<kXbH&`F`o1Q7MJXLjMXR5ZFw=SnYr$(Oc$^ zT$kP+dFv+gMjdv9mMcZ$WHGImFT!VQFkJ?DfEG84Z<A4fCwP5RLRzl@1lj(J#TH>8 zxBhs8<bdUm$?P1rPE#Q*|Eab!$OffHg~EZpI2415zNyW3ss;ASXMv)6cb_#uuytmx zt}x1Ace!4}Y88UY&?R9Pta4K1mtQ|?r@FD-)+?xYXc<4CNv0b~7v#I+m~bRYA`K`I z-QGgo7w5eqSC7O#1^cRDOM<hYlN4z(WJ`o#`kF^qcZvH6gP1+LFR`qtx7N-fVLy!f z_6emPK<)Uuq^An?Jk)Tl3-y7qyA+FMZ_Atp?bESH5*G=27ZPU)Z43_Y7Y*ak@J#5k z+;{_{;o>G@=aa72@`E$amQ%+WBUUgp?1c)FX*H?ju;~{P=0LNv4y6?o5e~!+XJ;q? zZQnh<d&zv8e0}&SiQ;_MQq-*kbd;E43pyoHe}}oo|8E=WeMh7GYebCN>cQo4V*6gH zf9>K<gA-&zn%qe_K0#5_0g!QfD_yVNu6%OgH26cbF&FA0TLTsv000_Gpb+PhDD)Yr zt=vEaeZ6X4p%0nc-?yI>1dyFL0PvYQ0UM{8iL1{_NTu<9L;2s-KxFOo6+WLR0GC?m zCl(m0Iaa+isn!0SVUt+!jNHVcwaj;Kht>TKN}f4ZGsR;l^qv?q@g(^?_e@gl8H0?{ z*XEtJGxCvweH*AvCY;|k>MiM_y3J{laW`qM`(SKa3-9f*pm_;=4<1g7N61eUqyxWr z2r)8fC0j7%ji$!c44$&tH|ZS#)k?zr<c8*}M>FA;CM)c?k_(CzW!EK-*4M`OG)m6$ z?rvgH0FjVda$=Z!vxi{4v3KTz#paU+`bubx1UkX!optLGG?=TmEBr<gtl@{23I7!K zFW|mF%>^EngWtVoGPt(-R_S5WSoQS!BRA|6nVj=qgxK#<Hg{T}mOAQ$Kz_VYMmbht zU`M!tivgaoKLOpTYH_G57V0dI<uH~G@xUX_>)KV=^$hBGI+KQ*xaUo)X-uWNW&@{! zy6B!Ws78ckz)m%e_d5eGIz#oLqw4o99RA>t*(ZsJ5{X1+NddUvgad`2T8s8^{83+S zyj@*d3*|_cW&~NpL39mDP;5d2W*2)6W_aTglyyd<>bcW$gr!G4*)GqDx|zYt8lY(= zDnmHSa#01!bvB7iaAltzcQgTrgL}HHG<uNSv}N!{bjiq!Oul~fyI+iTW0@Z_zEn+_ z6mn*jay-!fOt0%@8@XEMr1QkB*EpK<o$H5C5|x!u-f2|gSBf<c1Hq3N+<)hds?@(U zVVnt3@9O>SYRDa;P*k}hW&B|ledO2G$MmCjeoakH6hSE=FG<*+6w{+`e5UV7M|@(A zY8I{h2XS!?!lk>!tLP1O60Q(IYl#Gv{1b#5FID@Oab;xI!S)|EJwitYWGfhMBLl>` zi_rYtI<m=J8&6R*LB{Wx&Y$BnUUhmu3DRgncX&0DzIU#ZB1+6n;=WeXlO?HSr~G`t zYFJl&V5H*R!%|rjP%Z%W{`JH`5!A)_?56`*RIIyH270t7#H98Dl|2>}&^QMWMs-N+ z6R@vPtfpQu`cblKHd|)mDKv8#5<#75NyR2-z$Ut+S36jWN+8XEqE;eb*Ja;Ph9e3f z1NlCAh=FhXFI&ne7CX-ij7vZ*%1A}g-1#<>G8>h0LV;TStN~N@AtcN_*Z%sc$>rm4 z3W*Yr?b-Zr=b(Mk`OUmaTc3uD36Prrzai;SA%&MXGT|^Sdm6(<tf-KKZeYl4<Dh3b zG9a_I?uU_hlTbhg5x+o$Jj+$>7Ja;ZZjN|(sM;$qv$MTG!MafKAg`h5H1bP(VfRJ3 zEjxP&gYz0-rx4W~H8z#Eb5)!82F=Idz?dAFoUq>R-7hyLY?~D1d<xy<M{{c#uk}Ea zFb?ON5~4{CS<FP;AOy*ltbrvns4MutjB%kyR2gM8B>PQyyaxQsp5S5+xt{gE)!gDv z$Bw^)t=^T5FD|A^%C2P5m&=M36vKb%E!v0HNg`@w{LVi^=~SmLeb47D3Odv>(HH3x zXTDtpZWKn<*4Gn(ZSR!WE3I{Pbvv)FC%ZiU3=E~U2rTf7<bri@C_SDRkSA5&pK;2F z<F)=z&;3kWQH0DH^)zrC@As@qKe?lw<#7*t)~@LGN437Qm=sBdapqxJieT)#0uxG3 zQn!bf;yUQ$NLOEHShAC*f}?3xgj)I$+dvzh`EB4#6i}$c=Ha%|L{=V)r_a=tK;R{} zW!cDdQIk>^`Cio!j(T!Y0A0$<ybUXV;LH0Ncl99U>5qg42#yvk^vjwcH?9*=pzL~s zx6s&G*DVU5FP2`Dr9Ck^(s*>;xqptEYtG;PXvyhFouVJvDZ3)4+{Pp>OEnHs{-SMe zMiXAUJaEayiA;tdGyEGagVaI3q?MGh+Wb=Cg3E_|ZUhyhqSLhXGUMl}7t|;6wCwxk z9Q$J<u_|8MpAPGep8SYtV$fqO{ZM~U^7d_ORsURFpSN+*1`d4saIlWrar^~S^coSl zx$Cvl=XP!1Z!&ejb)jiH+cEnR&aR@U@^Y1Wn^f)96!@OVtIK4w@%x}4qaS<En*~jI z-Qr9aEnj{x>Ym$1oUOH5yVOWdGTqlT$UJ~EUI)Sgza>P6`Y8;0ic9(DeSeE{<mSJL zfegr9d}#4+4*md1mGYNnnaWAYUh%uOvw)Qc<$3!o+SL<)oCp9;>U!x>{w2r6p`%BT zzDU*(RXS9F8L#(g5yGGFMR~3`u#842gE-VUsDOMh?;Ow=&tRJqjahjG$-fd*Y2tbI zAGRpMI%VZVNz=#%zrxs{!exB=<UR39$t9;Zp$B2~GSOWVd^{JA&<0WdUA*93HuS3X zS%hYyk3>>}qif31+|vUFh~ThaOTSio3#WLfRT!pRVg>h0OB#TZ__>>1Iafvt_YL6O ze8ojB^34B`p7B<ofN6C{X}W0nP%HHP45ma=fKP-VQO0u=i+G=f)@TC$U7%G()NIp+ zkrGgj+cT(?FU^98;`n*OA{OOkA{I&Sh=HKFyc{huqEJg?|LVE@#Iv^-;;nFRi7|WW zTD(1u+#pN7&l;W1R^Omq1%oz89EVr8ZHoI$&)WhJp4koph1aLSYDr1M2I1dXMUi@q z$5JpJ7Bkq&QK*}F^ks<^13#N^MKvgfD=xxIx%O!ryOP)}5bk=H%{t>+G#Vu;!WVRD zrCVXRQl4)i<Ah$l%MSBDm+*DlX!HPD@DIDlgj7gz9|VD9@nHh{k*P`55qMPVXy}v^ zk(j9dU%wT*#3{#PBA+$E<C>4uFu()Os)1`UW?;!iO3XB)GyWelGB@<+hciEt788Tw zq@1;g=#$*9od`vzv9ID7OwG0?@N854>ie{PmhNewSNaxcO_Y6kp~Se7#JRf(QZ5V4 z2|zh7-*`s$I?!4HK|gs=<qxYx*Xto4n{@Zo3(HdmF`Eo#2=BXLw82PR7k%lKIuIt< zyBlIE&fi^!KS-?7<nHC>6%0GGcp0F~6+s*IOKN{#d1AlF*v^{{ql)%BZ;RVI2-*Ey z10;$+?ZDt>9WU}3neUkAZdtuRMIqcGn^+OPH*az?*nSh9y?)VCeAPT)^IDkRfNEQw zS}PLMlb+m${oA%kTzzx%BK9rVnV8S@`voE&T1{4?u|+aoaQr9^Q|k2}^&Ppy+9@jF z85Te(WPD-Cl(<N^<31%~rjEAKK-qP>r5Bh#UbIfenv%jFk)f<2D@~<%iceBjhA<T1 z4|8j451dj{bR(l6DrV^Y{7{U<*22QR8;dtZQc6ULi^UvUf)BI@DctsS4_?*NzuNcC z>?(bpIU_V%l6(1H<vK(VLCBc-4-V#aZ8+KdegA9mDx&{VZK4gEI8vY3C4*m4ux{uO zIxEDAw$xrrq*!a_*{qnRsJ)^{LsZyU<`{3J<2nkkGpBG<8g-0fS|r`Kz=vvh<)o8n z))Ooa`EyA&12^|u%d?zgF*f@#X9coPe8+IV^;e&_VeA!amN*=una+<-x*4A~waSub z)-z$cBph8as+*CUeqDie_Qwy>6VsVxfMNTdeBw)kFos>IRUxIDJCURATzL`oyUl9p zaCWa|fo?#pPbPzo>%bfFY_NbC%hVI1E$PVJeW;A?A&y%dia08#+w1W}x5fO4LIJlQ zY}nK@?k5^)Fz=wBh2iVAl%2Ld9VANO8R%Brq(L}T3*Qp2gYfn3wOc+ctM^LYUp+?? zl4#dz<`)07_o`->Ev3Z{3k|SL1iibIYr4R!L_1*%X{lB_sUccr$+BNHfJ6kO+~x?~ zCW#5SfGb#N(!$d*O`iSsdR^0_`IiNneS<IuT>UDPQaJmS_jB$MDN>unlN6JPoeSLp zTT1$2g43(TZVlqP@v|Zzq3b;kDS?tD<@h!AFb#lLPGHG^Hh{O(4-sW0t+W&%B`Y$f zl9yUGk)Ca=Wig%(4C;{iGwNj4_He)jOT;LFV7kJ9_hHC2ZAW>RA#GM_U1|22oUbVr z#L>5Y;la=n3t{SElbfGRalXSxIK*ghdV>?W3EWg&YNy@4rg_e?o4^K%BCMGPFn9R4 zGs+n_-olDG7NTp2m~On`8y<~0d^nQfbot22BrHB3PCykszPI|6eI=eE$laDPlsT{! zO>%qpdHXayZK)~34My*raoXx2=j<H$hw^Pry791Yh1>*O*IG%J&W(=2)1o4?VH&8H z#P4#_?I}js^}R&_U7stcH22Giv^c@`-P5pna{=1!Pv+OiKT?M#1^Uj?Je7Fs?a=Ch zXzgIXk5Z1Zc|jjFg7U_aYUGN5nhwbgc9|>YoOLxsFs8`fx<WE+*cMJzo$Xmhs*_TX zO71`x_sf#xR){QkVH`r8qBn$3HRhTEJT+T(m${B3NIp4t%rH{7Eo0MBzxS^QzOKZT zD!F6tDw;82cq3fM=uJZ(A%$#JzbI6)Oa#ALSl;?TG(g@{Ild|caWHTh@;5xIPbu5` zY8$OIO@_xSy7AL4Rk~>5i{qU$FsY2K!w&vw*<IjSJX%02-vJKLg9xY7%55D>|C^)1 z)@O0i=|Hz}(0>b^1-N90Y_GnU$jd>>l+6PBGaz2RuwcG|x~rsx761F&7`pqlXTpbp z@kgg^17i97%48d|V5DMMS3>H$DNzk7QNUK$@r+_28R&Fe1jj~sLPoQck2Xjo=MV1R z2agKl9|VHQE1W!t0ZKNLX@bdQ7t@{Z!@=I7z*`?nx!rj+m8t)7yu21cysohLwX6dY zap#^;NTRIp80LCTx3+2jd<6{Cbl*LRVpS<*K+;vjC+C~&OR&S4iAsYbPPUulIMP7v zZZYQ7eY2ns3&kfp-N@FiInc3ReUpk0^)Bv8)^&$7!b8!q;trb3qWDV~7oWq@tZ33g zt0NN2m8aL5Mv;xml6~qBWG?!GgFQVgszb}g`APJUWS&jB1<h<TCTsOc@&(o)P_wYO zZdyq?z*(IzJc5wvf|HU4kE6*xuKcUkW(m@V45v8JOy~9bS;TAl$Hw{Ty<gN~LRph= z$d*|x|Lk;ESkUk&OI2UMZcz$!ZtS+E0wj5~aE?W{6iM6Mm(1(6NR0_54BKP@WF^=s zHv9B`a$rPCw~=V%u{GR>L4J9vQfipNLKpwMrGCY7PJYE+$DYw&!w<NH?k`9AjVFQ4 z?gXu^t-TP$`K`X!i>q(_5czV1{)jv$3N=4O-Kg{iBOAN;x&f2d!m^$VOG~zQY99b+ z7=@S_!C@L^ZL(|N?y|BQ4Q`VAxysL)%-^LgI{f&Ir#Z435C=E^{_wxr9S^YHE5`?c zZ8mjsWSBAnmE8<|<^#4U1Htfei>tr7n>PH*P^u)#@e}l!M~nP1J^MkGs>pi<F6)M? zUIsFZVN(fJxHYoQFfbo#P~^$APLzycUap-fT5RsudNbi<FB$)J5Gs^uJi=_HP$XAO zWthsd_0A;K-J!P2rZO$QZsV9vBGiqh6XR=<Jerc*eAfrBC^v*r;c)>qN!Sr|XLLjI zzZr1kSJHkPO{<ch8hY|9l{g!=0B;h^A2Tpruz`DZxwh92)1Jgn{!}~8QW=hlC#vDd zD{7Xn@YPILIT>&+e6HB+<e&VFxn#mfGqJBsnBQ9n13QiW$Phs?D8*|$zU~%PkU;~z z7OQN^Dy8cal~}dTx1UPkGv?r@x{@3$bnreCW?HP}U~N7Leu4qgKD+-38c2Lre-JEH zi#$cs@zebfZj##$NvJ+p8Qm{->2AO-#T9Itu|z2@T(nOSgChP2lEf-m9N8~6x{aqM z95g6GsWGUkJ3|IYkj-97j2Q5VaE}HEhgmnXyVISc?v+{UXG1?$1cu0Xyo?c@{^}H8 z!`!4e_u+4%^9w@N|ALSdp{lL-?b$3*Uo@E#Z~nl*K%nR}V&6`Fng-uPbP~Rwp$fIz z>UPsdh}yjPh}e8Evvum+-?ado<pdGb-09-bXfgm0Jb5iBC<bAH^>>41efhD)>vw9{ zI)8uUKOoXV8c`!^YxGz2e|fj1b9FiMF)rra)U^uB?efI4?ajeUG@-|$YlmdqV+(fA z!tS-q3lhEF3Eje0m*u$)+>YMoMT`FzD;d#y<j{JSpv}|v&ea^7y)6^hzx;g$AfHZK zZn@&tW8mj<283kFDXl`yDQ5_cISWk^oEs*rNc=J(+3TU1bJ~#BI?u>FB*gL{^G=@g z*g555S}v{2xo~UDZ{a@i<-pB=c+=Gvq>Uf!@a}1@gp=8C7e3Koxd`+mGiVkL7E2!4 zP0YvPAKv!^;QFBh*FCuF+!A0%iXD#T`b3o_GWO~0*&}=YkatiSBvC#qFh|-N6&?@+ z8Oyz62Wx00qHm+}A|!}(&4li>c#OEQl!PS2Gu=ELX2Ty?K;rhb@Z(E2El8w#Guvuh z-^;?}<GIl9t5&O=*AZAs`Kglap|q0s=qEf|sVy3dM?9m%UMQnLkhDAUC^@KzDd!() z|C($gq^DO0Pld1NN4NKz58m1&CnieCB{JuiRJ5faJUK;0MWJoS@fCrX7l^c5g=+I* zR6+QZn$kGD4c<EDax3_q8QjebzEueBjUW(1WNRFF@D)-7jEpE&3%crWrF)RxcMrUA zFWd0pY+%W4{9{<qg6JVKV6+Zb0`!+Txb~cab&Nah3RsJrZQVX87>ROvv!l&-pVDKF zVlDubO5JbbQ%;Ez7LdVP`8vhtH~W-5V>7WA^7xmLC;z|&x#{6=dZ}aQ4J*Dsx93iN z;`Rvt!D%QtfMlL4zU{2cAxMK;z9=O=UII}OpLjT#gNAcNgxGXe^9r#a?>asXvxq($ zs(eLTX^jYZ(kTKSO&cMc{rT&;rGI?6fnGnzwkFFWNB#TZBGyPxA;D_ayi$RDXhGnq z>cqR<ONrAI;D#B??AW~;dyKq`s=MsX3DM}pg;m05z?0%RM9yJbN}G!nk_s^*j{zTw z#2WJa3|IW}-#$1)X)OHGcA^%<R<qO5`<u}k(6xJr5})X_)nvgqVw+|AB#x%uk8ZMv zbWZ_AsVL&?yOs<4pWkCngIIixSU-hu{`*${czk~`w+>{HB0fXf7>vKW|30(BaM|&A zEA|+kaeErQg*P@x-<eiBbz5?;Xz|h1<sRCjeyB9+&8Ej4vmNcz+P6P1z8pQw!vNhY z!~bP;B6hcLe!d$M)BBB72Haub@3j-z&Q}GI`rkM$RGK`4Ej7lro!3?b;lknV_ks$^ z>_PU88@Nq~^L=;f7VXhqaN|Go@%Apt&HadAwAD4Sn)Z3~^YgANUR(Jjc!+Gi-+1yr z?KO4G_sVDL6O#IW&6Q)+EBrkoMJq@ISq=`jZ<ybqRFoI+iQ56tbtd#JTvJd^xWTOw zQVKQWh)HO#N*FNLhY3bF{Q9*aRtNEi^54VRj(mt1jXyUJ2?mc6l`3q1|LuJ`j}t|9 zmo+19?$D4tLR;qi=nBa!z@+?Rp3*}M>1YHK+Bp)n{985woXBZ0+-d9Lf=8s~64a}6 zGP&$xZ!G(=#ipE#dP+@3*~&Mz2X~+)%-KV87{w1hp*(u+sDonolDF(4hWGC|L#${Q zq>=CKL}{BEtj|9pw&+;hO){4Zu({2BHOdnQTZg0n`(J-o1kbr1VSr!O;);3w1rI~y zR~;`3$)~hv>HqMHG~-7X&EM#rM(zDy#LxK(A%4yPsk*<#&y0b%olADSiqzjD{w?^m zP4w_)Im=-Q1MN?9iSVBhB2+|(PIz|9U$<ioL|zM?#IR<>#`(i96xk5BTf=@V<^I>d z|2}t!wqptc>)t6H|4a@K-mlv=jtvx1{$a4Ekq_?d$GGi7pZv*-geb)oiI_{VvL0pq zzlMe{isaa3h0KNf3H1-ZC`>}!&hb+KCI25Jfd~WgC?LI77gSh_Vfw2tX=sSs?dVyW zO}+ZVV6P+}Ao6F4xVs<yCeVMPi3s1h<O9*^>=|QPmcMTIocz%hLU#1*f9&0B$4@AF z{<mj^JW{5A^qT#WA3X{}e)Lw9EPsuFr|*|Qqqum$f6Dv#55@Q!+dyCt(H{i#vU^2U z{;Zk)S=0ZIh9NBiZ*H`;xC4KZ_@7bmKR|()$IxH%SX8O3{^yDLw@@Eqj3KSlyto2E zRIY9_7q>gIql?Q*5{0;J@i!uf-$A6Jb7UYc+r5J<Idg|6uGs$ygZ^jt*WwUN`7Dl7 zD)@iz;h6BFb_X8W_9FW{bbcR9YF8_FYLL&dXG)xhN~a?aLL2<Yco5%wlt4`WH;QoA z|6R0(?@@fs@oSo{SZa(8o|z8>B?6@lns35gyEb@FdrDvB>1ixR!6#PG7j}k){l#nj z?YO&cA>AyKANmcljkdl4-QK4n_5bcQ`$xaLAxFF!F-3S@{JE3A_uK+C;QqE*n4e<$ zV2LxMjq9i?P~v)+>|S>C&LWpUG7QiTn%qF?g1q^|I{k$uPK2U(mO?x6_>YU>_b&t9 zy*@-7uQ*1jd!9-sd=))A4lua-(CBb@?|)_UtkwU52gLj~!k#!&ELX~$hsv{l!{q8m zuyD%iK|9R4Y3I}U2=CrMBm8fT4nxGWx_w2V1pV(g+NKG(konlw?9ELgxFQ$sFp}%v z;9i=%ZV_zsNz>!LF|xeD^NpLY^M?iD%eaJ_M22l5O@sBHR|AW~>PM1~f1z!Zu_4B| zYt&`L=y#9NZ)kfOi@^0q89b}svvmJkkN;Va9S<-(Z##^<OQAsemOW9O^D>(>?D#>b z(*0=jDKdYlzE?l3>ONR$-!u9SBElfpZi$(G-}pmu?*4KYq<%f?-sEu=?>ZQ7k_MUk zV|K%XfNyUeWJ3)nBo=<3_CL2-A0Uy=S7pZ0p83?@yomQblT-ZUgYGA;V3#>oPp!X6 zd=2VS@%D5fxxM~ie5LAM;Nm-&sk2=?yPDhYmAhjgTkan9-`r^bPoV^2gsR=@`V=vZ z*pt$P^#Tp#O*lk9NDy25)CWU_Kb_3S#@)t?(l>B2P~^Eaz@-JJTV{I=s%YCAK06z? zt@Wi8n=3I*b8)HkRg$XG^+`tLp*i=e-f;z~`^KLUB6d1$+31?QfcZ6Nr07OZ94Ya- zGfE~?GG|pnj*BfZXYJy!u=&4;w8UDw&#D|8+R`^vzOUM7ByU>n2W9Uov#3bETy_Kr zT{fo_>NMTOeKX1WPVo5X{OLmVJ?jgy{ibEl^`pdC0sE?|KIN4_z5VI7=vZczkyUJ! zyKT;=i7dtH?dPOcS=OXt3S@PN$4}v_ni#$Ta=uMO_4K77$}Qgf=m?@*J1s7iE8bpM z>b_Mq&E6b=uC|NW3DQ`3GKQDmT)EQYr+?K9pPN$%@2Gsb(0agn)UkC$ax#QsmG6@B zXjVf*dD<Y#<;csK5FozV>_R_kTkN-BY0_g2z7H%J9X}~pmf@&?UE^feSAOz4Pt{S3 z*g_o0V)f&Tb{vF3wrj><tYUSCbujfZzqrO!F@~kP@#Ji13#Tx+-g=vrrD6)85*dB7 zp0lP?-mWmCtJHo0kL+&!aPmDbb&Dl?eSAe+&1fSsz(Fis<RIjRXr1MThyr4)Kf9ql zJF0)Td^qzCx}j~ae6{{SlwWf;pIOxBZY}>Ze->M1zv!EG*Y;|P^^V`MDK3sYv-}Sa z1(xYnZLxHLt>;@opuO-X>aKv*3Xpwz$PDRB3do_N=l)uO&$l!&<Fe40@Z^c6FH}i| z7tFkR#XJp~dxvxHO8J7!Jp(K63_{wpd%5g-RP-EtaUMD1^ncYG2+r!px<g_2x84YN zjbI7eF_{PMQ5Has@Pv`?9&I#>RwepkI1Ze;->SlkZTqJJJ4=A0f};G|_qjq|^-THm zv({DyY1Rh1VyW<29h%%bVSmP9J=R22=F{b+2yR4?{BZSE0-SNa3?GPXijSQBy2#f0 zya`v$dNI8kewxQ3raj*EW+|>t)%)7eC#A*V>59VL3yB(Io03#+)C27xy5W?pYaQu% z@mmv!T#>C}HbK!Y>`c8apZtyJ969dZ(hXAzm-Z=3409wy_Vt$bPH@lueWm^a@RArN z&5m5vi!%v4nRr!x)^2Lyj9TFM(~!k%3$HTN<ItyJvCx?FcAuSI_MO1$`KCA6b9oWn zrM)t6Q{Vsm6Ro0K^LHT~&BiZpXR5#S-sN>IU{drbjBm&!nBp!c9VBy;WFH%b84CZj zxw3|*WDL)qQd#LuhHdBrN;Fg>+Y(+9$(<aeDut1~8qfQ%xLl$+7KL8sl~fg8<l66w zj-F$#b27;_b(4(4?XzyH<6M#?_E9EdT57~sA6Ro&xG`l|k0<=%=ZML<H@W?}-Pxh) z>X!QG!k51B(yE@g1Ko2f3ocLKhU<vZN6iurVKWOLH)C|d689oD+4)9_cat?VE)&hs zzEtiuZ~0QJy!JNx>Kf>*VMS#&Y_$HY#ImP}kbBo@(rehyUXU}O*8JY@@eO43E><z^ zCSu0_V3*VQg0-F{to2+;D8CQ<a_l-Jdi)~?^_XU#_v{gUn=H-S8v*Z2AMWs^IYchP z?{wv_cEC4Egz{ahlo<F&;gTak=?AqxPi|xoB*=vyq!Kv_xIDf%Uq7p{mZ0JvD^kK8 zW(3MUQGt7{zfi9<7NipfoG0eZGYWj?2zu69W8=mPn=;0A^VWJA*=YHumUKVQ7T4L0 zv^t0xO1!1!3|FOhMbb~NISK=)&)Q{h-Vfr(i{Sx1ANF`hsbUq93tuvJr{xDF9d|dj zupq@Z4q23MQbzd%^;ifo&esdBFMiE|&!}Dw4ChITK1Bn_)grdz%F_GS3NcFltYqUJ zDGaKgt11t5rKE&I#F?TuhMgHRGbK!zTSD1Q1YNf)%BFUa!yBS5_4>3w(xt$pBov+0 zrN&q(G80xf7`8w0cWmr9U#UMGHOV(74Id~<d@Ef0#X4Gh%OtmoF1J41*#RiZffZJf z`-O<2Psy!Wn$dY*xi5BvjG{`-{yNEj#Z>~J@jd`|_j|~@FZ!_(jT`m{%|uok4$w5Q z#(KtrM(!(+a{A;rf2&)K^@gMmsDoHrPjHc@{CqS1-DJD2tOTAUjh99y0cJ~6(Q%kF z*keX_$y^{h`GZfTKI>xfs0-L(gh)7@jPwYlSJjX!3DiTd1uBOaChYGiEGDNufuB|s z7e+^``7w)5?8<gujh8t<&v<~l6NV^Wcb;im(MsCu%%rGj!Mm%k`sd|$*6CdD(_=BI zb*k;D07qhSSCsx}+a?z98SVq)vSfFc`}#tEspZU!JiK-vERY}4;$^V!zHWP>x00{q z{mFSnN_p|!YYgyJ*ni7b`!|0mMmRyB#aR)E8W4ZkDz=XlPQ#`2-?WEVedA7?7%IU; zlwH4&(JWbV_?oqG<@io+c9HRF(KzhR7*e1*-(t*>A6$l0<5xjt0C;w6pCPfDvIheA z%!bs~INh3CPppTk1gU#_gzXG%zPfu(B*uX^3g;`Y8k~(v)R^4=SohjPoRq1}!X0X? zX8;-<sTi^}!Ko#oA@rD(rzf>2iHxp%e?lkMk$hTkMetN|rASfd92@DO*HXQO%W6~~ zB8ZNg8{3y+d3_}d7A$pejLvQ}L!;9S`${=M;;2p<pd9hZ-avYi=DQPq;nnP{+D58^ z`wUyk)iOK1kmeJkoQG+Cot=qPjOu6JL}BkA*X(|hSH%IN8qM|eFxDmUiBR!Y$MR0Y zD6DwA7N7kBl5<sq{k3k)Q}yRvCmpixy)zuI@?Vd<lE7=$PgElWh{zpeB-e#D!xY^0 z{FmMJ-~wsu=2WxjaUU3(iB9$wi3nS~t@>PqbC;zqr{^kpdN@1<-RfI2Fn6C+yIt`W zlFmyo__a;CdTQ=q57XuEKw6bV@;j|reL^`#u66ppF)nGR)%`3dV|3b@Qb%A3{qt{F zs=&O@{I)xRJaks!khehD8ppN&l)jOTn?n8mrQC>y?2dr6RS*7{jmtgQ<&&{V+5GD2 zgH_$?kQDx=9gBPT3(oV-lgF@`anOgmoq6EteFFB_>@hQHn&vYd;r;C9j8(f&S`2L< z6H9zzq(3XH0BQuDM6e{h|4~>mNO>I`@L&o)#32^0aq^l=6K5lm?&&qlv(BH2ZI9Ib z2y73l!wnvm0@cvkv<Hl}a7jIhwZl;7hFuEWPflrmpy{?`MHJ{0QhJH8-=C}c^)zda z8B$I5GaHuJ;<5gCusKQ@bbtt$a0*aTDoarr3V0oxZZ~e5YHyGGd{I0uapurEO@j6f zg!5ErWfA|dD)PM;a(tQT{dP&nO}))Hcb+9@zKOTMfSI2euN?k{W9{nsl+=0n!&gX- zt7#<D-18icw~&&e0AS8s#gto8I0oT!brLr|)rQaU!m$Y>^kanrx;ssToA%o%ONlH3 zPraw{@kbz(=>>agEp3q`fHI!wAF+Cp)5}oq1T`~~@VQZztcios)7FHgXW8f*>RxOZ zn??_J%%rB{3*;QYIVt+?5&Bkqk`_NljcJyA4YGgEB1#>qsb5pGtVq_{ET!nB@m)dS z8$JWDoCWdt$jgGs4a|6%5fb{e-A@BvB)j<+q4=YKZ#M5ycjI(HKcf9tBC2(FP=9Eo ze1p_-8n@`sY2CxC!tM1M$12sFr#R<tu2?LGQ}=UeVoa9y`{bFNN6wlCdn^Y$1}rBm zwR23bg*@K+MLH+na}BiFcr){tkDT$AQx8%>TcEKt(;u0(3O(#1Wm$eWjg*w|D^|V| zC=};X>_nRCpB$89!nguHL+Hkm)PXd@&iuPtfO_Mod*{}(@PxyU5-ZP;RSj{z*n>k< zwFh}20zrH_v#CEG^GW6FBxd7|5Z9y3d>C2s)gb{~H)L$~Iu49pi+Kb2kY|@g47e)P zte0ap4{*sW(#!h*8e}!~=?-OufOfk>Vg*|DjjA3cXUDh0Q#SlcKLaj|4GME-fGUXd zqtjG=eCSiU*HHt8T+p!9H#VCmY;bOw3w<6rFe4DQ6;5vyU~CgO|DJGr`pe#g+g}pV zUqTaq(z&!>cgrkzt+C=nk7lC@3sX4ilgu3#;(9~R;FiuSmRE^iO2oR>UjP4^x}mQz z3Q0;d#_ZM5K8v{=7)VEsz#09h&L*(+Wy%o9DxK%7c16LtsLeTg3f8L3kYAlLGO@Y? zoyfEjx0a=l%&vSTp3NHsE6%r<mFUS3?Zz|q<DmBwwM(4r7w$lADoYPuF#2gZd?KS5 z*bbjLpOMsoH$NS?ImXrz*p*$VJ)#1a+i(Hf(ujtR-Y(R7akO6AS8q*2=OL(8S1_tL z?g51w_}WYF{b>(cp*@NeU%7`|umzd35W7T899ylY8;VKt92VFie6u~#Q{$UV{KflX zx*bL|>26L!3YXUe>Yl}9-gq!SJ4%?)m^?5O6;By=@~1v;vMdjo)XliAl1;|4EJ>UU zmc4-pq9B^Nwv~7qA3xKIFMoowGkcN61yWNikfe6Y-h0D3Hxg&J=tr!4N|hm-g5|2j zZk@W?E*rA}W2(@7BM&HQ+MKeYA%1g}km5VPhLnwl!<KU|?Lh&rx^tQ93pec&!FiUn z^W&#Z?Gnhc`42d?2}g!UCK=U-8;zKmGH~}*aU7Q98T7$iyD%P_!Mb)kQU#I<T@A=i z4oQjTB!8dx_6G)Y9@s?p%QB+fmnxe<SeCNnDrf#vTCk$r^h~iJZbh@cQUOr+(m7X# zVje7=q~<cRzIc8o(brrnqSrS+wBW8weIUMTP5Q;{dVacVT94uh?r2^VG_vM$n2!|Q zx*=U@%OWbv(}U(L<&nws6BpW#eFO3J%vn28C7jLU8V&_8|Ds$)*!GaNx#`x#Pu+PC zPe-^?-RxwqX1z}zG?a0m*_}{<a8krZ-pC&_8@$Zi7xK!@tx8(u;TkW6k9q{~d8>(I zR#K7Xksm|Ia>?pO^7}=%ZzK?_U8pSBVbbLR2O(F2eH)0mnc1bis5CFd+eT5nM-9e$ z4o<b28CoNr8G>o_z-H(dBXhgeg&T_l3k)jCk=+d-R%}Mi#5P&O75iCD?R6?Q9PyQB zDpoj1S81u#$#y=4mbxU9&G9ZFd}@x1dW4HNPXVyW{Va`(w4)wQixG7fQoFgf;J58Q zX>Pdo{#Bw!Ey?Ncx>#BQy%(dLdzu=^!Y-2@n{6D*3kW3QF7YP23)e@zWZj>$aB5lu zTdBu+z1P16wr*X0iHVh(G#@%0zHC*mwWgZpNqp88m3Zu?7ag)fy>K+}5`2kPpJ-Sx zki=&F9OyIYn&Mq%{dkv>%v43Hie{vMs$R#0cST<cP(hZ}fN4;jMD3zix$Ng|TKl6B z)HB(y$7W#K2Y?-?iB%8cs_6?)^|q4DjP>5DDZG$seB94>j6cvMtw)nyX=a8?v(YUy z==`m&#Bf+mimulQl4&;allO$q<siJ~_7>tBvB=`{X!ug{CBSY@QK3rd1b?{M=;?4< zPpe;gaf>>@2YtUFQQzm|mfARtl&RWL*<_ft#~8n_-dRsLs%(QI_;&dyZ@WjBNTz;- zrC`~nZo+AEy&O*+YOOe2@cbo*87cp=8tQGZW*Ey|&4-k|^Vr)F*_eB!YzJN=wPhJA zrmY#lA2)f&riEu<CjO!s?iKc`zKL4y#4+_~h!;5Md9a+Fz8i$Ar7_vP1t4W-J)AEr z;IO5qA)*Gd(E#b#H?NfCY}Jvnl8F<z+%l%P<?>q`ep=C6<tombxAORwPPI=Mi|*Fe znyhjEEc~IcaDqAW+L8IFf>WEm{kZ`P<xJPe(vm^8b<4bOc*o+B(AAa0%%rJ`G?h!i zq}HfjT(7szqZ1ha#ulW1CQc>lrqB+UGUGO@>9kcM7~F6VRAr6b!mibr?(_D{NS2|3 zyj07-0~+>)A8}b9+qqb(&Up{YEH1~SrROrz8w{XRUTQW#$scYl^zYW}{eTh<1CwUO z@?AWgc745z?XPWWPLv|aXAcEZhGu_KoOo#A0R-z)Dj)(F#*Lc`92au=$@H24RSrbe ztO|$|r*?Gi)NE>NB>y(Soq|kdc#-Kl6p}kTD!||w{=Fh$tZ?$?PztuHMWL!5XcxX( ztZ&2I+BVE|pOZXwzQDJja?l10YG6X89?eVMYtp^<rm|bsbtqqU>#t_naJur3=Q#-# z%2-HC>eVa9QZ%~e3s)v9@lHf#Y5tr5+D*YWM*4WO&3(NML-=-Ab~GoLG^0?ScD(wN z1&N4BBK>mLKT?15kINZDGz-KXF72MQUO1PpR&4u@t+sXNlO$%?vZ!h<!f`OMDJeIE zz4>Y8%$+LUp_n_j>811f=Iczl6wO`=wbAq+h8m2=RzgefP8(x5&0XtuvNYRcmg}Lm zZX=hCoGvSj^!R1dyzD6MT^waPj5HEn)V8a|lb0s6@RPEsH~X2%+(~`hYCUR1Oh<NF zk9=($p&kjUN0z&JrWk~JWW+IYF86(U(Ut|UGFk9NS&!1Q6NeM~45jMy)O0)bOZ6wy zWG5k*tCwyga{C!pC@5M*jm{h9lgY}{Wr5&^)|P!y#UZ0TNB7JP#{~Dri|G!A%&Oyl z0^tNcqSW-+>xodd(@Q1Y9jy2m3=aOw<0#kXL#<|P!>w$d*P0=T+~8*h7_YCZJbNqy zA7~^xW!1IrO*Bk6Sq<f^FKRmyk_T2Uu?5BESR!)PcFDt$=`(4$mqX(}R}Qr~9YjRG ziT{qz9h5MVY8nN=si`;`YKSkfbZO1)M(gJde=;U#iOJ7Y63tL&;&k31Z_T&eD|jG4 z(S<DY0lm>hi^i^8OQP0z@7iQr^8gBw6;QsLu&+1R#R{;)%%*Se1wCo+1%3}(!tTZ| zB@v+pgXD}C(?cFEJ^$##_V%Od%S<COe_`;d&bxRYERmn$rAKKpyZ$<gFH}uw*_C1J zK6;PKuDo#I1KUct;lPBEsq#+ydjQ*)ktf8GBP8REa~5+FEpfnZ^iUf^%e1*If+XJN zpbT^E=L+|QRy8MHHhvMvKY8^ohV#|ek-@2!!%7C6K`iE3dld9Q_GM>e^8o*KoA`L! z5w2>>qvyJYbeqg4rH*nHAgd<^2g?}*M13cn0(9F(7V~O*pXM(|%yrJdRGn~<V^C$% znP>NB`cTNReei)X9>jUFM@x!j(<>j6xHmvLzU9W#ig;7M6=pR=@fj7@2d4ptN(G*n zo2RGo_VH&7`89`L!>Yrs%belE4yDoy4&IkWpW@HEu<2pNt4#UpXj}lB)D{P?E}Gi} zSKsYgJ<W+r8Qw>I!b=JpB_2t;#YHVH)W=$AKKL~BqTi3Ewg9z?pVVF$Fo2<0!)fz3 zpBKJ#qZfy*zI?NZRP8C{K29mTYL&>j-Py9+C}p{2<hFn~P80TVYin}-V3eYD!ew*w z4jG`Gq*+<T{%s*W{5yI*qdAQM!z$<O<lBI+k!pTI$)`GRHVx@g<bg$ej=K{)!l$t- zZrr8k&?J8UhFuxBmO3LyuU$sWKYF1lt-APi=4y)(+G{aLxKKK17<)jlA=cWfm^Qh@ zSrZVarqF37AK`xzpWJ@=lL&E~e4J{(=YfN2qq#@V#ZDQwnQ-X3A!&Qks%s}Yp5$GV zkb=!H)sq*#x0U|0$B)S~Lgd7QFw3}FA#t-Lj~iz8!kc|=^4_fiTT`P*5AvJsM<CqY zmJh1{*<E|z+mGuHChBP-3mI4lsI0AE_P))@8D6;o&XQ4Cg_j5HnMCCsYyV2@_{RYJ zr}0tgS8&TBg7_a_L(=<QW_l#T)|(V~{EW@Y^l;|du14;-Orhj@sxkaTf$cJe8}>>2 zGv73J-lx>qjMPqc^W)o#5Pr)itN33swa)Pe$TA1lYmVYPyqL|r4qgpp#a!=4D!vK? zW;io91ybKEua0NG5cUvfs7&*1@|r+udcE=vQJ5_2DNK<Xiqle@^zM>dKD)ERRBg+^ z+G>l`eRxtEC=f)TSk-nke2?RMVleo@cz$n*qZko1AUPc=w~k)SHs3`(<q0#IS9hH> z9k?});1ep%<v!=+vD#Q|i!)a+^e1-`TWa!Btg*4-B7xcFG)c-WCAwJ&0h6(EGv>6K z&SnsVT&&Sls0nPH`b{w*F@h=YsISDT?_Id)5AMs&eL&TZpSym2Nz5HT+OjnUs&1c( zVkjRDv!{3gF3MKC-PKB$Oq!Wc9|o0Hzzgb2Z$<XxG)?#g-FpUGDWZF$2lE9;(Rg#; z$i);|ULUeI<uG~aA9JahWIG+j858#9<a~5EC|KUx%M(71F9Ai)o>MoowD0rjm`AhZ z^v^~VYHhs(m#-+;MZJ%>mYf$=+a@7)(Fm(@VJ;{gig6w9p)9s?U`iJB)xzCS`kp)2 z&lA~tr!h$|NC_s15$lPinQYkO;o2`LAoS7unvN4*td-VrM!iE^Rz(;ur)E!|6VBny zGh!b_33w?J2p%}Hb9up!-&eeo?hRF6S8(S5oJcH@e(ZY|*N;!A%Nl>I!(F8e2u<c0 zrQ^mq@tu^M*7Z;=>Cy(U_PWfe)3;EhF5K0GyYocl=GcoO<rqgW(H7*OKxk){B@gyC zFL%ER?k0B*(7763yIXJeGlPM~?bpdC%1D(ZFl-m*2sIZHIBy8cmVu6SbJ(%lrW3Bt z;>L&>`Q4HY35yjVuY+bx>M?oCv$zYhn`WEs9zpv|c<`D7+y3jL^A02U12lm4q2}-h z;diToBu$A5)dN}&iVCR6EZ_kcR4s1l-`&{fdH1HyWJ>y|<|Y#xu}LcnJUu%`rAE*+ zu8JFso6rY~cqAA%llQSswyUUDy%*=6JLs24O&sOgk#g%0{>#ZLXLtM%FKVq=%;!a! zZ__|4X|<O94%{IhCUj)I?p*0|bDQ9DliU|BM_N$`V4yE+WO0%xt)~8{&B%6ohK3uP z;Ml&LAzw5ADbI4MwXi>8tsngAvy7_$c&>yb18YFb7S;+a7^_z;j>am8-Fl|^KFyPf zJ2oYDNJ%1*)a=^@p(g9diN#T*#JO8#N=5iS*K2jotvH7MD2EoB3{CB?Bj_k)YaxM* zRcr(4Jjtki8_H?3p3NmTX}g7K+?{e`5~-Q=g$pK7+n1xl;boU0?fu+uimFX6e-vMi zbg3Cf=J->76|tuhj>w*E<-P3Tyo5UG6-a_tv`v5~JS3NOPb?V2+!B1!@n%T???a;t zqj_OixpnO=V$;SX<xhgGDher&0U_zfCwIy^iQY4!bU=^X*9|8j{CCSHd>T*N>5QF^ zkOm0+(#~xwa;U4@kLKkr>&G8m*T=jhu5#n8zVOy(gXviaE`5m~MXwy1K(Ew#MWnUV zu;Tk!vTOraZIRE9C+x&!un(jw@Li@wgR#Mg9mpFsYYcm41wU|CD}mKjNEEgnRIS}{ z&wRvUCjm|o`hCqG@NI~#xb{d?ePx3y7@?-+&~&R`2=-G`EI={n&xRZvWP@85$^>W$ zXW52eRysC{gXK;^VDooXMTeVoasDXLvG;4-nA^44KrJp|`9^nv;(AY8Q0q)GciL*D z)o@t<Y)S%ud5F5Kfgk+tmAC1jAIF}Oh0-aqs_?}&*3~O`_&pm_X8GuC4o&Ohkf?D4 z7ftEg|0^7xadPqK&++|_GQae6UU<zvNeH%&hWDuJdcAAG7@0+}{BuW^^*f$%<&NT? zo&|bJQqlM5l0LL0D)VpoKp6M_`>S_F$UFWitEG8d6|+*35s?GgN1E8GM|sACM4W6W zky|U<HHup+JgJ*06>S@uNo}<m8n-jf#KZW)=?3W9KV?kdP4Q7{><4xEoYy)D9xYwv zRSSZ_Ao)Un4-_0ar_}$$-gkyIwQcRHh$t#Wr3eBl0@9^P2Sqy4dk5*g_Yx5irT5-D zp?5-n&?8-HfKa4{8l(mSfg6u|pL@Qu_u1#$zwV#=EFPXLSZmFU_Kq><dgq)Ml_fAH zcS{}#7nZ@Kj->_}UxRtI;icvT^ghr8(G-4Gsx`9+G`JZXLN=?Y%07|&;}|=PVVX|2 zJ;;>QJruZ|#n2TppNcqAyO7RjOzVTR#7UHuPgSw6hJ5iIxR;(ORkNEW@8zD_1+rz{ zu0GX&m`}t^n`zj~-@o;p!P*kpcYH9}OA`YLb?!~=yLj182?+2Wt2<gu&zN5x9~r7Z zYdjT$6Bk8wL+E7BOGJn_bQtiC0jo<I?QHh$iZ|(pDn<q{eer6Z%ce|?YR%`|RuA=w z159a8V_Xq+F2{WN(@QT_6($=zo&AjipuD7G+gs|^=uQQ-5-mL=P5*&#7po@_l}Wh& z_Hs|fbBGI8dK;xJ-h>)jE;*djy2|`>9j(IP8ZA5A(20SyV^CAEUaEFuWskodXl+!l z<<n%daj2DDp*(|d#8~gpXo;<bRl@5^AF5Es*dZw=(mUlZ=BQep=Cm6xS!H5b1x<Nf ztKEdSLQ6sqqF$@Es>;T8wH#8ACaWhu<<j&WIXVvA9<sefA6K$u>;A}9v_-EWKEZ|V zHuhB-SHH98+Lgtfr_}b}VRge0z!Mn=uwaLTh18BKHjyAXJ-klMBQN-qD*dW{h4_X2 zt&U@%JKI-G%99mb>{;_7a0J)$HEkY6e-zjmV&B$jL|)cB)FLix?fXEAl&&HV&CdHC z6u7=6m4?%$01TG!6`L^T=RSfA<}NvDj}KG~`8&y#9b^Ucy#{BVoi%M~FyLNjB(Lza zv%jP2x8q*0rR~+}c7c!67A<mJfM&Kr7(dQx9IsvO8z;Ncgc0{@fzP7`nf$-@B%cXw zQFvU8?iI}YiIUL7`Xvv4=I`T*IE|wdY3gF0<+&fKyvS=lR%^qa^Jyo()~SLyPc+xd zX*ypJq)lSKu;jp&Rjj#MId;mXgBew*Fq$F0f%eil&}u)OC5-UuhR*D;!8gy<5H3{5 zC`yRuq#Jglg`x|^d<Rf=?Cy~nYoW^B%uLS+#9m8ZE1MDln1a1tKYS-g8aae!_Ts>K zGMcVw@(z>i(&_7db~KQtw)ZtOp>zE-$d`)6sUk2S?exiq9f+g&sdL6$ONvAf%_i<W zsRub?p!)vREtFoXKloisrHwb&rHGaZMuZ3^Yhmw>&UL;qX|ttPUYx!i0`7C(IX<VZ zVw&l<DyxNUcpD_T<fRD?k{fSr5SgQ~FCj#-#$bqR@XvM0x`rgQsWjpg+iu0pq<Q{x zcgLYZ--l?t=kjJ{SKkn8H@6yYYA@W5c9BjET3vP?%1SnqD?TD)wrtR$@GQT}RB%qE zBW<>jDVe&%^F>#LG<tu=yvD(9d4+OD;hi7pSJiQb)H#L3O1KrxWa_*>Hp&<iz5P}D zj+7jCR^tq|(`M=l8qWE-50Kqz-%EpWY1y(b?^2{Y><OLe`snu(z8+W$jvP(De<aIo z%|>Q4I*;kzy?D#Mi)jmMIN9<#B!u;zzD$~B-p<o$R{(ChK(VB$j#M_n8y)|ti!J`M zi~UsZ**^(WM#MJ(t66SrLu@aYZOM{;cC*6_g%dXmBXA8V<G+WB?iVEauC}<Ra^UO@ z3S*kQ?(wD%y7-+|G$gxYp!VJfjHI<7y?w&jXv_!I1;$}blq7?kf>6g-zMY~<2k%dx z^Gn4kPI@lAw|XF$83{KWz1!+_jbCG*0HPz*=u51`Ntm}?Ps|asXKSk8B;p)CSATEl z#ddVx?ZH(jbWu;iiZk{Ch{*in2E}|EXk=YC-uAZ>dttZqu#qX|14i91^<Ci_!-EG! z%PPKUk|2Dkar`HwiFK~UJKjYyUnwW~xl`ww_HC7un>SKI?kC%dDyF+?I5TfDIw<%! z<n`TLJTtM^etX;D!L`26uAL@?T_bG367z=PCY<qE^YHFUwRocgHd5P^r+s;5u5j_{ zXy4qKHv)_{(5}|5R0??SwKa+orkU_TLynCC)7uL&VW8(6&8pN3k5+aZM5-FnQ4#p0 z$Ei)yt3L!IH#2ms1P3JqwLnfP#1lnf9j8!2jl1~wgYgiLh*m3ao8W?90GaT_&4GCi z6&A|CrfIg#Nw~OrMU^0Rc%Dp6fzQW$*V2qhH8qu*6tM4ky7Nhd9EVy@eh~NaOZV>- zWkIlXwMzxA?%*0hq&i51L2`(;J2JL`U^r*_j7)K2;Tl1{iuht=360vfXpBq9BUNYW z$;HsMxT>+DlG1qCO|Cn)OB1WxnxG8t-TGIKY0?Xvr`Z}?KjW9Dyh;q;%qm!8Bi-9K z%W4R&?jch`K0nB5gMs4RFEu#IY(np8@V0=G=PkE$-VzjCujj`dvqIM)n;B@{Wj)t? zi%7{2%JNd!8=WV1Ns6E}DeQVmN{1lRlOcO_#>@jK9Xj0a#NDRnf31&dR!G?_U6mdp z+~$LMxT!_1K9<^eP&Qg_8lc*;Q(CxWRk+F(K_-{p;%17HYjqzagRz0^RUgdmZ6F>) zo0?l)9xdQV_wsp)XKYV0R$Q7tJb|qE$pybPW9Gk(>#2d?UYABeHN=M+P~;SzbMRd? zLUjQ9sK&>=(j+4?C0(YqD-<(b5$cgR{x?YGIRgvy5_g;JvJQ-dc^aUn#u2`KE#J}| z#QN#W>$GvVmH1Wp)tU&~x+S}wUocj*2fZ40D;vm3ZbmYb&%c6vuPfVly_0H~E_6zP z`s_CcBh38h<bhBdAxjtkASmykK0@s-K1?kdU*JRSx!53IDR|)xr!uUd6ec9gtIi-W z-+1KIH!S6f9+J6?NP?}nb(B?zik+YWv=Rws-C*gWvjQM!oSef{W5r_dC2$;0>gyuw z8Qy)OW<%_*3E7`JsvXr!CE_PYd&EEgb*m_`v~HE${fYtK>9q{#bU-@7slitWOjDW- zo3~vFRTmjt!qZqOEOEjs^R{X@z49eYb(oM?V}_8}+QWcEF=VHXToiM(Ce|cf>L3g$ zb6f1<lb?YN@YxG~^}aKyqk3$zTQ{C3{tr@&H~QJzG?v+<^rn14hMBZ9j*aC0omjtF zEEiO*swTi-4waoOwrECH{bo}_t*avKYn9>N=;VYP4<3BOW0xj>2BKqsc6pQ{w^7dM z#l78pfKKAd`BN4sc4rPOOL*pAdDKxi0`#|2n#SDa>HJ&X?M+3G=RT^?(jpd|?t03r z>eanabNY!BQm(FZjlNH+Y3GY34E&A<MmH|o)54grIS3V>?swUnXS2R=!Qr8{%_``j zx850NC#w@%t-<LpjWfL5CVM39@kC+woTZgylcc9dt9CRWm-$%!C2XXRr1C3g>e&V5 zSOYPH!mVaw9^s~X*yBo-$pQn5xrgd5^3gOI*I?On$P?ybqjyhM`Ip#4*!SJ+(Z!a^ z&{LjjKSs@HB4E#yT?xwyNruYj)dY!S61k-Od@K8%W}l%!DUt1h<-5ziCQ_}=?klRJ z3SNO4^U~@&X@l49>@p~%r>hWchJXefKV-gzrS=&4ZROVo%8$2UAkk2<F=MF1w}EfO zh77E^{RWfmi~Sg%J>eQ{1EO<j|E9a>dlesnwpa5sO}`H+hsm`rmd^6eaTFT784xS& zZC7bpU4;3#JesSpo{sl)Y02Q_d>%@LBb=KC7Te`OogadCa|#eF0dI0nS=0tL%0BPv z@&S0$1I(6w5Os(*yjnCHLChT!+`rRZ462IQTyQ9;pVSZ-pYL(Wd%Su77T@X*Dil~h z#fvahc}T*95!H8%sp%7ys`lIIOe~J2e|EnzZsq+^&i9)ed;GPB%(X}?L8Jexz*A^k zn!{j?@wL0u6+<}GOi^>NRA2jemB+f56yO`Xu?KPS4Hu$kOL|S!S)b__k{rIkcJA*l z-ghf{KbK=+-C#*I4LNF2F}UqyTIoqEN^}r&q+?2Foq?WHVQN+SB<&%(PO&9p{F8~q z5?SFBTbxAo<_NmH*@stCkt{D~p6068HRxDR#J3%fx^NbJ$0UdYfN%K<!^b-02I9?) z#d=B_=~G^(Ijs*})esifb7I}=sS=~VfWS!To!VYJ@nwoA`Eu|h^T<isiM258B#pmg zF=v!?V|rNye0=Ic-MCvkR5DomX(8`h>Fh$cREwR_cA`tM(Y4z!C?fAUlI&=_<F(Yy zR0&o4%vTPrO>n&i9YVp+d&N}Gx+zph7)%}*dJQf-X>#1W1~&su96S+*e)@$%Zk)I3 z_e=)WG@;k#2;oI_J4AJL9?E(@MwWSpAa<iViVR=J7)66eHl%KlnJ5`B%%YtKRBPF& z8n?=^!+&nhkrHL;kL)w{NU?AAGi8gc1z>XRrw^Jghh)r6VYu_8N*0Y~PW=q~Up$mM z1$UK9T)67$>qkZ+UT*Tx+^g;IT;en7I0JXMJ@b$NZB+1T`}%zIJ5dgCNFNP3<+C#6 zq78!iRZgZ<(*(yaXam;ydy2_-pOxwYU2@`$n*8KQX{Y_&I*Gko(Zh$v7K$BNiRKog zA7m11lH6SX4tJg9+R~Z=lQc_ka#uyE%UCpl*)(^F?XA`O3y;PlvT{%2b3FPrLqbyL zibLLs&Pp(A?s7Z4N6ZT)t|^!UMjG!0Re!g-9@@)!E+$su`ja|)(to5@QRf|T(#6^W z7zTND^9mFmgbzKHI$xO|IDp>5i2Q@Ur~7&BFnlcPo79P0m*|3B#tR3}p+46~cdQ<O z(Q`XZ=-w%0iPl{0&v$HYkonhTIxm=Mi!jO{Zku+!KFy<hm=2dWT$_!K8gEPV#ELdS z+05A0TLfo>RcC+5*C{sf2FBjLmPhnDq2GtL4m;j=Q`PRk2Elw%cTnF7zb812e2+y4 zO$`sD<K=O)5PFk19;VW;G`Z$jcRM{P!SvTg3rP$xT=wQLdq5&0eUI4v{&cw-{8(MB z3QFPHWOzh3KcGBOJ4#w_wr3NXsBk+q_G4-~t9euePyit6P$(pF^`pxy&67i)FvMrN z@d2?30hea81DlOR&$%}{p7xo}P;1MWp?1fM(RiE3$&E(@%!Z!YuF9QTq=hN4Nu>#q zF+oMVyY{&!XAvcz<sIzv`qJGZKKEuOIp1lGr3$QDp8|+Xdn5*ssDy}25I1B@o_=#O zPRIWoeXl$Ipz@)xt!?*dd}Aa;x=csO?7-^gP4zO^qE7dE-p_aCNW$E1pgEuWt27Me zG|oct$yI`d@7xuNEG@AWE8*@?-FBpBy)^&0)5NF5p@No($<lf0L1mbrU>UigYQnq~ zSmwZO70aM?by?);o4veONM=~(5&=RY>=zmoZa}5pCt_sZF;qpRk9GDNk}cqn0@FmE z7-v3Gf74@s^V(LF<E1KI9!_>dEIu>U%eu16H!)hrI&9HO6J9}HSRQnYuXo|ui;C*y z?>%HMRpu6pydH;!AZBG$p$wV)l=bB~M?MpE=`d(t)qW(q3dniSLQ-xwRhAOa$95?s z6~2fkPO4z<(zReRUFUpZ+Ug%#r_6K|f#uCsdj*wWQ9fk#P`De>TUom-Wo<dw1YEDH zqLL|ph>iGQGiw^kzOB&!5VFZ+sKvesI_uSQdn8#`0_^j~6T-hpmCY30ZvaM5jxo7^ z=G813>WsJ7p51qv+5Xt<btI?eqa~WQGN=eR=vp)crcxzhs+#H3hHb<&Ur<v*vBR+z zEp=V26$*?a8fCowLSpLEn(0aJ!h$k9u5G6OXd;}{8KY`ggp53*H@2hJX%HFsqIdN1 z)RG%B)uTvpn7K=ny}(<q+!<{$?moNuhM$(}Bw$4OkjMYk_bnEs@VmjG)}k+H|7>d6 z`&Xja*+nyo?>`g#KAaSl^q$$Wwj;S>{SZvfxbTYggUsu1j4rN*yTy7JvQ}$9V3yqu zn}d(rHP5Olw?QPeaCeU*h_^;T2`XRd3F6aqt!JMMLNeD~Z`3$Ycd@9Gw>570-P7K1 zp97{uDp~|SRGJaHz0W*f5Zeh$7b_iCET`zICSxRXPRHJ~*lZkjCyIsFj95aI^NdzS z7hZd<PbBw9K#$~@cFl%T2^15ol~fbg-Km|;i{S$mEsJ%<Ol?ePvOQ6AGnA*YW!!M) z-nz(-tE&58Fk2FrRSZ6t#VdNzK%H#E4iR%%EzuB-=S_*7lXe@8`oKUc7GFiw7x(tI zKc_y!{QK>j3{91kO&LO-17%Ab7W2ssxKlau9sOUg9WrR(8U$^IMPC1qHt+G0Q&a9R z-yse~XCPxM7!TjMKbL@%ci-t-#aEy1J`prid-P6YB@PNz5YRJQB^&!#+53(>a*tT( zxTa_9F3dn&HqW#b4Npw4y@raPX|H1H1fAKpn4W!Y<&S#%i28}k7w0?UVl3LE`Wg*y z?dMi_UI+EJ@<r~m(MXxF^=8lZv*#ATGK>*A8DQUmG;EJ&t9e|br5yc=R?y-S^d)7Q zL+hj_=1kW5A#I%>gM(lr5-d=!tGM;qbR@IUxs^wipak3~nPj}Z2irqa=p2~WusywP znmD>`<M*Lv{v~j(F4cO$B605}J3E!~5aOcg!7y`v@$%D;Kg_SaV_Vu~1ijm5Mj%2o zhqjy#-QYfX0oKRkqk`M?b89XtFsr8J?ww(@UeC?eZGHl;QOqpO<j%4{d1m6zwP=yY zu6xc1SAEj{Qx(86D@4buTU8yI<cxlIjbO>!qF|+qctdi#sY8l@Xmd3ETFK|yTtbu` zYvHKN%#5m3JAJ#GGJh}-#6)@<P|4KPj7)AFDlx|wA{>Xn+iW@{t<hP@0{JyO{bv>l zZ1NZMxO+E(n&G6X{ut|-*{Q8CFN8dPqC!3$Z{2>$$b`Tvp+maKDBr93OQ{S*L2S8P z#lg_!MjMB$=G!LOvva3>eDwP7jx&6}%2H88%X?|Aj5NwYm4?>!nrzkX3m+VskLior zo)^?+5SVUK^HEObW58I1==zBe=UZ3g*?gNfYTC>08<d)?FmFTWt3R%pYK-);-o;h| zth214x~&E?%2hG$aKhYTe<5>U>eUEJITNV^U8Wwh(aA!lf#A4VKJ1tm<x_mbtRh_% zleejUxL5U$)O<DPcsF5rKufaRW@#A5`0r~0c!U~|1s|z{GHwdfw2^9f><029>&9rN z!&5iWaH<9zTD6_6wDm)hVLfC8P3xaeQEHo(#||Oafc=zzpEJofcwNBiCylcGf$>K^ zOa6SDWk(WszMLgoGj1&5&7tVFW@*@->bj(Nto#0;jT>##3Nl}<XjZTrN@BOyuH^LL zW~sP}VwK4v$5zrtBTs$1ml>G0DNb4FOf0UAH&2BWc;h<WC@6YP<+KiAOi^FZU{h4b zpg;@Z4#4l(3k~d+@78OT5kU1Au|yhi0_fw19yj<$=NP;1Xk!`VRC|jm6xxvB8Sh}# zW4iMu6L*{F%pnhtk*09L;;{#`c-<ixlqq7KOTq@QVCO34G9rmj_{G~FdI<MRG+^38 z)m{w)d8G|6Rm!YANQGx1ZO)Hl-0<Ov&FQe&VB8gxeUfip9Xv_}i^YJ)R4_W3Ba=eK zoBkJ+QvuJ=zON!eSHuhu1*N3nmARXJg)dXty0g<hW{FR>%S(lTn&TZi8!HMuBJ-&o zdVcKG?(-&m=V69?#8OWW&GTAi7z})Tp=lgstVT|K%V3$g+Vt)bpE%AZ=!q45ysh>0 zgyjd6{Gad{^u*PLM3XUUpJ~r=-6W<)%=UYnaIeGwcEK#ysISu#M1B+am?)75qhfEe z7ea^(E$JVm#LACBYLY@E`)$6Y$sJfRiV9`r$1Cugg1g{F<{rXF1jAXOP(>qNCdQQQ ze6+Q@j$h}!49}iyHlq+-ENV0Zw!ufW*S@;%L62?=UUQld5-n+yl^!6Q4ERp|g;!%F zB#|XM^kGki182~b0hPz~!tLt~CN_6%+8&_D!&~f`NK#-2e05HjbD+AAP58$y54EeJ z&228_M0BaAUoYA!MD4LOl;lhk;^{BceUIFTSD!OjIAJuMRGhlg)O()tPSdG%6&+51 zq7-+rd~^&e=>`EJw(53~<IFRPlF=2{6oTynU>Uf0kT`SSI?srnHQkEC1L`H+kzrE~ zN0mi2MS}Ov?RF1Si_mu-uqO!D`%TFT&r&DPQVVB--{Y!zKLf4C`ha0&SyVF<8tGAl zT8`e}$@sCMzz*SW4})*<ot#wwb{=#GG}|adGK1J$@k?F5jW;-75X0;YuU*uo3GCF? zbxKf?*bEc}TQ4DXZ&X(#OURk8lzg`GAI;SCnJ>#mM|v~TZoNx!w4;tRM~%S^6e}>* zqh8DJ#~kJ!Kk-5CehHJiy&hxYHr{2!jkyv-`;C$#0iS&<Yev$a{B^7PYsZ@;wW<8> z%5$l^M25yzZ(l!Ijo5@JskinBF#`lD=t7#^mg^9--aA$TPc4)&x>n_deh?Sa8_pMm z`VL>(EC!lfUsZsS=Zglsb0&d|YO7MZp28i3`o%V{-Pu;VQ;J{fpH0d5UikIxsQJxS z^R3>uF`|f94BgG3qt;V%np!<4cIQV3GeiiKiY&FqgnhWz<mSm^HwzV={IrJ?g#r=2 zYJz2}!BPtqiUhQ5<oQWE*3y3PPj*l|SnRpsUS?$xc=yjawQ0;hr(SF7P#pb6M-Lc# z)kf>sYYc;S*Ke6fYv+O0zxU`$d!m%cAe%~|b+fq-k_{<aEFn+Tf{vRLG{rT+N83Pc zt0wDxGXIwKr8Dz`K{2n+3`1@qCsNi{p7S068CWo3OA{^d?vWw=l1)yk>0rg>hq<j% zP3_2^<k7SQ=6Cx@;?`-5i=5>{lP4+<Z%41l^HW629Zcs>oLzHieZ5Jx6hSkjAhP}5 zO7N7gLY@TV)~YU3;;-vK#Sz5Qpuz*OukLwp7?BM^u|G51C~9@4Q=eoemfaLnUyTy9 z`H;YSGXSqJMhB#I{_G=*F)#g`wM=`kkD34xNU9T+H>Do*JfqY8{j%Gs#3RzSIMJ3s zpO_=YCC9NH$LhhDcuhfhYu+cS^v^c8ZbHQ;mBIQuc3l(}2eGF?kNWT#>%(-RJD?F; zMUfO$aXB(YkLv)=H1G5SCer+r6mtS&{=!?)M4|CW3tp|$;)TW#rma$PXEw(kJiG{f zfuKIpw=p9Fno@}_2Ba|C6!rS92YE-V8IEtvNBSO+4l6c|r|R38fmR24gX@R}?I2l2 zZ=vpeohF5cXI%PMBOSvILK<D)k}`-^e==O@qtPvO9Vc$s|GETgN|>o|o8b7I?xDF~ z(!+YH>6)DOV@=_+V~3CkAGX3#Nm_sK9LS>a{;>nE(CI1g`G5)T!3%Jc;`mzJn;sLV zF(AoS*+oAr?(CFe4bwHf=N7bKdwf~r!P}-hhibWm;OIVMy1)2Uk`0)DgRYu6?9pxA zurE&%yvT2d>2`l>ziMuqxYqZP@=fv`H^Erv-GP>f%ZF^w-c;GknheuCTBrFu`t>zi zbvqgS#n-FQ4vjs5j(ELO9X@>9R~&G*^h?yX7dqW9M&qV%s|USh9b&`70OI10;6rbt zl3q`24>L5}t8F>%a#>hV^zm*w=t$AQuC?ZMSd!1l!N5RGBCj_oP(SJKS3aAy2u~|1 zL*rgSrB%V~a7{D-xswD22KfCM`gcdoKC;c(;gvfy6`g?|##O<zvJg4M1Uw(KCtWY~ zUZUArvobm<4<AidJ)bRtMZTo%(rT7|DXPO55Ms^<@f?K!lQt$D8bnVGxuoxB0!_Z( zpu(9m=BkSE{q7x4^qw1LkOe!go39fdp*=l6iqN*8LpsIU18(#)TU~}rji;WOv=aKt zd`%`A{h^^9Eg1*y7$xTD=$~|Dk4kQDZ=CPe<j+=0DDzX31psnZRz8kW^9J~+V)qV* zWKUE$xKga1ufzK?IN&aRk5SH(3C*o9p$r(I*~T}+cM-tCfOP=|BD)3!6UW_0QB(>f zQldo^@m~uQcbt?^m!DD(T1;U2Y$s#ufgg9E2sw^&f9FO6f@V8IXe<!1DOOc;cYcg; zcKK!F;L5^)UtJ-EpGAGUHn*q9hHxHAJSa*{7#*i!LqI?269IV)HfY$bnQMa}kW`W8 z-Ov>m&Z>#E6Wsz5R-5#Y1f(ykPlL^SI5oVlmdR}={R!rpYyxWR;Rj&ueyi(ym_CgA zWK7h(#U_rJ;0T)hU8NW;%qR7O*Wu#h8M!FY=J4)3`%Gq@WhQn}khqCWGPw_z;nOa@ znbd_;d)=x*ku94Y7xYKebs7*B<5G(&sML%5I4YXY<Oy8p0sNzuF|G1dyL%7Ihg%A~ z*a|3Innk#W+$vfmGpG7LHCtZ>I#+DiK6ht)N{kTg5d-l`UpzpSci7x=`1k!WUtI~{ zc=Afg?X4@VU;uWv+Q;wPzCQTDd}`&^c|v2vr8bNIkr&?-bVFA*5b#C;9J@wyF_$b` zE4$h^U3@8>KwcRwgR8;=XjO}gm%eyb7BGfseFQlAT$_#x<UrDtl^sdVk7TX&D=4V~ z2ub2(kNnU{-*R-HX<i-zPDdH;U98^XckcnPIR7AAvu6$z<+_L-D4j0~C5anOlt8IV zM{D?QdS5nj(~RQV?}g<1OXwU#I`6T{v&C!%16PNZ#6Zp$X^#ZQpWE4+3Fb0c9NNZe zDA*oRX!4clkPd=X?MDSvchfBs)*5z1qjb0$0o%8)-z<oeKEgRLT_dx<cRFXb;fYA% zPQN3VeUss9%Au5KVa4IW4n<n^ic5j|R~&V^dnrlmW({P$6IW}QQ$^EKBBjH3eZ_Ed zPAnc?-uh%!rhU6E6S$0tqtz7Mibp9@MVk+cStR9LEp+p5>)qypy*#2HeD9u}!5%q{ z2wh}4&F8!<e+t^y4ne>Lm<PciF`)TcU%>88lsn?2*A?k$2XfS@zpR|T^=h*a$<LiD zZGYnDmxFX*mxbZ!xcxZNV2|1ghGIk&bhnt(>ZCPT%A>yJ+w)^2V;|YLsEi5>5|Wa? zrm}hBxB9jsijHt7@gdrC9%-1KKwmbqm4TD}Fw}GmAMBj$VK5zf<OBNg<nDk@e9=<H zqvA%umx0S_$x6VPgY$VjJ^$Q>WH_cWWC3ttF@)bt<L~2~=R1$1l0p{K{LoCNWe4~P zS*PM8^usQkc~zyxv^7qlf9!yVMT&sOEB^UyL}>yP37Y~b3-`~wGH}WtXGvqG%N$G5 zwTP4(>o4@X{CFh@mX*irf0=YKX$$M@IxNy|c#@6pj;`0*kvV?Jl(cb}1GYAu)^v!S z1wdGKEF$_BVeoSkjgl1B3SGv0floT@HB|nPIBEC+TH^EYQcag18K6!!1m899a)-gY z`K6rP6u&_WyVRjMcG5k(z9H5Vd3I){$a|LWc6oe4Te-v71DVOVOHmsB@HLMKuyw-8 z#4n$FNBSmEfNNEL<jNu)iX4@gcG+bPLYZUc9@!kiqHg5#b_b5?IKlZMcIaI4^3GrO zj>&r28DBP8${*kyq3Q0GmCi4IddEZ5U=TPvssAP?vgMLavfG_ii`NFE5z11>i@2a{ ztdQ1snn>X}LaVANyTeLg%T&6QVJ>nEZ`tDZ*-2$f3-vo_@a6{2@R-wL_xpLg{WSn4 zfy7CNk$yfky(Y5nz;ny=dk5{uvO?52h6#@0G5$A(2lINr(0CeW-ytwxZU4B+Of&ab zqVU21qO^z#@|jPYbTq2bZQ(JjXm`8dnKB4BY#BofuU3&{a-6vcD}B+0jb!@p+o<|y z((CcQD>N&?E-V;+s<TxBf~ep#=to!1SMX%GGKr)H%*r(l44JbRHCfKl7Y`7*-%<NC zUVmtzhv{V75*aO*wHIE@+P~;lQ8#!1k-Eq`aLw9u1Z3t!kvDNe9z8~rMEEVhX{m<% z!Xl()uC9D<v6HTV@Nfb&idVYJBFIt2I(yDF`g@};s0gSUjH)D91u~FTxi0KEn8_9k z$9GwE_5fda^enakEFKJMvz6?!-~AYwFNzu~=H2lXpxBjjNX*c@TwtjHZxEgDbqZe& zzF#>a0ET4Pz>o9}E^SmUDdj7&CnkBgFJwnr+c^1EPL0Y2AQ;jw8038`zvZHNTDY;b zjnh_tf*ab5{Qy#)i>B+{K_))i34dlghJN9hjvU4m@FT%63X7v-!sU#|tA}j^lkAMg zbIAzrS)1dD3pGR&Y$ea{K18Q{XgrgH<DjMBXyM8et2v1JE+TDY_Eanac4PkW`+p$r zzy30jexJ2TzWLT27rWmn7MzLcvaSNrJK+j+-Q(&n19$FTj12gtSvY2JLvSyOECyqh z+F85b=|c&>Qlp{=84FTrNUSHup`?`YmagwgH2iFxfg&jf1>TveLWYx~-W3<qLI=#t zG`+4PUGHuC>g2~{V<X{k&dcYC&IY@0%Gl~8OXRv~hHU{;1y5Q|mY=qG#Vo8?kvq2B zzY%At<!<Nj4R6!j-;2aD{JqR~!W1<06>rgIMX~ti%ZhP4xV0ATmis9Q4i0=z6A8Kf zsD?rTBp0X{djEss#cc7yhJeAz>s(hK<1gbi)0t~>gS?x09YrhV$J&NFM-gQD$(r#K zj)S#k4m#(A*$pzCgojQW3gi_PJ5BwP^H$?+^_1dHqVfk^**Oj>&-n)5`B%2x+009x z#%MLv?L*4r?jb&MrO#@sT)fp9!bfmVz~o9&)#X7^pX$iU<5z2LFR5ZK<Ot$Hp?JU% z0UA=PO8+{NQrMLr1b45TjWBsIE*IWl!9aVCUGzS)XJ9vKoH?>X|7bgUu@{)2P`CQZ zh)Gpf1@F_0tF8SuVycuw#;LPv18vqF&RXqvx$#&zWP$0@w1uT<E+q7N2^R|CD=Q>< zKXEUT*{5^Oi+JR*b&Dzo$2XR{8WVP<@#lG4xq^w_m!~++=QJvK>T{rh%=r_l%NHD; z>xKvuowA)Xux|5@G*HBMA6iof4bQRU0l&A0RRv|4bF8{8{xSsl+VERy-2*?m1J$+` zDxbc=?oB+mz%c+c0>2IvH`lLKGc3O)R4{AZ>_puI;E7N_L#=R(2-~ad3>$gVQAcic z7}yK8WO`>-T3A$yRq)zXYaE@kEa5fHF7qz>Ru4@}P*^qu#(#lkHPoLZTJ{a^C=dWA zv25A0nC<zJye8PTVz;`F+;ryFr1SKAzjl8fWoGG?B-F;obfMSi%B)V0FUdM)KnLYd z@0e-iog#OA!9uiLgmLb&DE_tn`uENA1x|HS6vBC)PKfyRuHj27Gc(jgwNJ?-%+xKf zhp#<6nvTXwKid1-xAHPS_CdsW2;Ha<yr{A)Z}-e}G_-mvbNVvR1YQvAQUlIZ0MRdZ zDtj6>87n9z!1PT3I1U(>aY(^QrnZUZxxhoM9&+8Ww~9%^M9&DR@85cD?AO%u$xV{Z z&m@f(o`~+h^F`OqANH~wX468WF|m0@F@toz6nr)airT>xXp_KOCa>$nJy?5-F;fO4 zzeRZj0xst?&s5X540OXe#^zAlQ1P=+t>m74>^vxm*n?X9OV1xV?UX-5_#bin&tFCZ zH;L4!xb%A?eg*%F>gxl25?*E$OvQtb(3Lt1E-Ew@Cn@@6Tya0})(3pZ&fjDiPO~1U zD3@)HJFX{*I8T<knXqtm17GPdt9M^yUWOIl<M&ach)7F7%Gt9ry8v4=<Jd_KZ1T+O zHH^2R{b#h=9kj)R5<bJ}Q5bfbF}svZon4na+o5;b?f?+k=cCSNUMh8t^{y>mZ=2Fy z<bZ3B*5@Q5SrW1AdXrlH!j!x{trGEBd=I49{r$XiW}RY3d$G@|H23E`+kiyzPt7e@ zxd6#5smofHM)?MTWg0gsx7!8$W{WTJ27g5Rjd}v#yc?p?E|YpAnjh)qp_`-*4iinI zw};MA9a!`m+!b)u!6a+V4W*S-pjw=DN+zg<bI+p8CqFz?SJBmF#YHOcA0$VrAxm1! zZ}y)BnkQu6JgdrH?V)uV)1-P^$6R%L1|cfUvZ&@qZTR>ZoldmJbd2nB<oe{tq+043 zT6v4}KBZ%Hoz5)gKw{pWl-Xuo6gYL0;O!)SkIR0ZMC70Wig53^BgRmVky(QUzY&d4 zckiDr39~jt!dkawk^PK8oR{q+&bxO2zAuJBDQ;W$fq??y;|Hb-NXd;KJ>eg-PV(J_ zBU4l|q&6Z_4X8qosV9MbL#I?JSse-C5ytAPUd{pr-Mor#lC5S|xCbv5gYn)10153p zd)ENyDdZ|;dSBao&w2gz4;n+RmjWh8T{Q*n?F1A1d{qa1ji6--72!9`yIvDLV%F8Y z$ih3Ado&(~qfWfW=d~JCD$8C0TOSP~o2A~Oc769FlncwgAX))>(_GhSP$h`bML(Sl zfkkqj4rbw9?tX(7jiVbq&UZJgm5!1gs-^2aRc{EbC0DQ6Vf~cnI+WSxTy|{Hdhd;4 ze58Gh#L#lBNoIYY;^oHYT2x+Z>zb9siWxwImQLXV*B)_iKE=ENQcXhfu!=fe=u$S; z(92df=o7%&b^N8F4#|PfkwN}?vo?BtnXa8Zt<i;{e1TGN?&0Y9wl|`P8$)y1e0zvA zCP(|gv^xg)(S1XYv7=K$ht8``oo?Fa6xxc3_6mb%KC6cd+uswVv90J@t^$y#w@}4K zpmd)3mdia&JevAC82jNN38#a(8cyD^@M~X%ow1{tLN5w^yK-1t?pe^)yN@a^j%A(l zOP6gIF3dOfdsKY{^L4r*=d%X^S-{mFo=&OTKR(Qzs(_0X`tFr?1_0d|BUwEROI<K$ zqt5fKqu{Ib9@Yh!)3g2EuvlZ?>H=NFiN7#Zb*@5PsFKB#1{kRUFos`6+~z@dm*2I? zXYt(6vqZn@nfM&heOG{#!2nS<v305}qG+9{PB%-LH&weA?PZ&4@{vbwCGOL)VHNY& zf+mB;5-ZX9=kgBqbaSF#P5qiWKIjx@SONCBQWoGD9zrRvCw#T*vlaTzDns2fqUP}G zmVAuPC*o~L);2}U5;ESLHM4hh1p+ms4bH#|s4--O**X6VQjYl<c+0*i9R(%4Y<d`b z9}HoKmMYa~-V$zXhV7nu+ZD?-*I!4}`5&w)I?<Tics58>+d>LRYv?IF>hIf$%-tFN zajr=BNam#C^DXblQiO|)N6oybVBpgAyFh>V9iX*O82k1!L)~rpuFJtC|FQFHAwFds zlMjlj4YCbqi@yMz7+y$quwS$icDI-t?x4^w)Z=&JE(ZmoIFxU3hOJUb8ASOxOfQ?Y z`peYYJ8k+TT$lEj_&3PJo=T=)c|D;FGvg-z4M=b3J|+#9h6PikeBPwFZo=^;$T`2V zQ7y!Nd%0p*;mx~5*HcCC5l64)l5xF~LdFBqi|hx7E~f$8k#+LeWYW2-A02w>6!<`X z81*3yi9Ubv<wnd)OFFW-^!0pd(4+o%rR|&>;`nq6UfXrxx4_Ji+rs<3`Tct`yl+7= zsD8q={1n4?${YNbHlTeU5IRY7?k)0e3~xRlff1It)>#UVHy6HuN|NN9Gfk^$rkidK z!!tcLznwaG+ln71jXn#b)&+Uts_b{)8!2pwEYmF2Y!bN;e~K=0oRhz`!5=4DriAaH zAi{<th<wDH-HU#%clRo(0=u*g5<{$w<4IZT9p@%~<Ud1OrRR4CoZ$l+!&hk{a0R^* zJQ|2t=l9>^V&*1_Dds)ioxN2~+rKbgi#V64vSr)6nB#7FzIu^tQ#bU*aO>1h6-gpI z?9f<l5=HWo+WEeV#hG^nRAZ&1V%d*0MM&L#)MSJzh^3IZsW~IsFVdpNz0^j+W7w>B zqH0ipz*#hr!Hb_3VH&X^B2{MMsv_-7zqamW$vr<~D9m5sPdb4i*l^-eb}qNJbO0+W zPY5@p9e_|Cnsf*kT<6e?#PW1dPnVPvBHo7FRa>m`DG=%udEDv16UWCWHJo1T-1%T9 z^cDOA$plZ%yu}q3_v|+_Lsm*suvni1JC&EhprGiXN>{ya85%Jk1ex-ldyxV>M1-Hf z0j?|tBV2hC9lW544h;WjYv|_D3Cz1x+u%MxRM9?#Q+@wX;NetvtsLRt$JZ!MnmUnU zwUT>mk($Da4ZIrCme5dE=L!Djw|B>(X`<f&U!Zqfw71qBw5H%0)bNoKZ(AGk7kN-^ zg&$WA%wx60J9gc=h5@~dF(Gh_QjVZ1pmf%&EVJ<FHrpT?m#m^1#9tMO!hjODOh^KH z*ZiV+kR%(8yhRmP!%L3qmi7Vb!i&3Bm+L%&4t+l|X<EFg8p+3;&PCb!;(K{FgaI_D zdf3f}Gz@I|<4#je!HqJzkh!ZeyCkA5Im<y21HAOJP(GA&poge18Yw4*c0*ARhK7Yg z577@dKt(7Q^n%Z=OAN`#W&O9yq_N9Y)D~ow)8YBq*<jcf<@lH7T>}@TQ>}+T$A12` zCvx-gi)*+yfe~#A*)qTXtIg=<^$$RF(QHT?Z5^J;Z4(=+7M*aLVAXKuDizq&%-9Hs z*Ze#8Nz&NB8P~T}&WiZrn_*Y4<}SJVI)pKmV&H<y#C?<3FgIBW^mc<tr_r6c8X4Rd z`0^DA@-{$~A#Y)kT43((MIou*%^D1oexpVSh#rr;0$MM%Do_`5+}d(ihh)ay5AdO7 z1Vv$bCb!szOqf+?Ma`=-jkvHnuh&g_N>8O5*Xjkr4dD!U3Ob6{zK%K8X*jvn1S2DU z-2Z1C_D75ny7~b~jr-35vVbbOS4wrFn1|81ccoTjht$0;--7SQF~&@!YWhTyB8PR7 z5a`>U0b{-Bq%j9v8kZESEgXHeF@fYyZAnDZcYx+z_S!e1W6$y~c$kYUAWRpgfg=07 z;97$dr55hSNRG(~wX*4F6Jx>U)WxSosBed-`{OA-QffSEF!#LkZ9gf<_+B;Uvs<#- zQ|8MpS;mbT@YB&Bf!?=lR<}hARr~Vo=c>a<bk6jkQ3FKLe#4WYZik7YS`7WjM=P88 zZ>kAxum4AB1G4WwE)sB^w7vEFCFCksMc>|wk=S}ELr0<>i(yYsC=*O=k@cUvL#HF} zKsRw1Q}*dJb`k^6-$)Y?@%<oTj)o`GaM`_d%j!?w`YwFUMCGy5dH?=wwY>LATfP2h zd8A$>gkJOOCx;1XNG`C-y?DX<)!~z#W4V%Id+H8r?3Q0}3J;m(;3vgtT-YVb7~Lp3 zB3-Yw?DEKBvI!VLF6HAa<>NXz7~k%uyuBd5(aGh>A$bEf2k-b&ZB=1>F`x$A<erF^ z4t;{U>_)gBy<4nDg5n<v?tdDZ+~V4Gb*Of54fr>2e&K&TC!Ha0al-u;NkVTmojQh) zAe`oDv?X}^bU`#8S@QHg!<x)S8in@DLQ|nzVJUt)eDlvMAT-e*_PtbMC1~!tf|POI zydfs9e5KYTAi5Wb&MsEr6g~q+RmlmDx-C|Zg;3@dH9js0$!p1U@2wE6=?vwSXO9-* z1mGY?Mk<YV3wQSCebPt$HgdX3?Fm==#;qh&G&I;Gu8T;$AsdzaWB1{AX>L5jj@iDl zW%>9&Blh0{_|HziC1O))>&K*szkTP6$JhwLd1vzEKYy+Np#6Z>>o<YNbX~50|IVwo zu-zph%G*!=OqRd=+u_gnWq(pY`<GY!JLdho_|DHUnD<j!H-8U~fA7ToZiPRHo5hY* zk>4#2s=s}w(JQQX;&t_i{SLMNd-M2VRkS1bdE@WjiE|H&0*_ykiv34{{?k9!<=$sm z8;ZS^`cD`9N0pIBVg2uFRTa@6^UZ%T)GI@*iq7u66ZqSAw!O#tAHnDFpg$PwzkYo* zRz)+3L}S=B>i?!q|9^=7R~P<&6QTiE@zfR51xU28TfEgQL%^8_g4B~&+xLtz8PW)U z9$|R7ZbD&(v*7^p;a`X3mS@jN_wNTFQ)l@K45u7VkFb&2QTV%e+tK^2Cn%g*LPyaT z=v};0k(Ho-l|2_5EWrDXtCvaNFOw=2^e-Z<u|HdUMnXT2AJ8}b9llQfj{aIu9GF~r z;-piX=da@{_PJNF4F&&vavSE#uO|Na;l(2q&g4t4e}%@j^?T%wN^Y(@^ksk2jruR{ zPi~DxuQ#ki$N%NJKZHVn(^G6ZN^|7~fB9Fr|2Keirw$7T*`yXe|C@{d6|CF%h_T?M zAdoUA{&yqulMWW&l|pNT|86=mO8Yr@$3Qh`|Mb6L)gRRGh83%!qV8$xzYAV36tLJ8 z5gTF7`*$HIAe$7cq46bK!oP`JMC1%VOC=epn$*8-6{Xu)4Ou(Y2me6>|K(9(_p#2m zoR>Q-|F^ADgzcsf)bYXJ{9Q-r`GR#mr_qsZ`oC?Jajb@db<%eJHTeElA}@<$osVzB z(*0LoBw&$f3Ic$n33}M`y&Qb`n~jaG;}0ZpywNDt;<%<O8T;4qSpKu3+oJ3D{_W;h z3RrL>1m4qFHTpeLne(hM4#(TmM*kW?fBd>(v_EZ7R5Pvq%Lbox+VFuo?AI9IunzwQ z3glkbX34^uMY1LS%ARdXKLZ8dto}Dj0UycZC{6{zj5*1FnCNlP6%;O`(#c;ISmby= zo$xh7P3W(d?j&9bh+B-Y_^o^o6S|7LEoqSX?df0ni_!C+nLmgV{!0@^Y4}9a4-2V= z?SEB;QDX1UK0J8t`<G>O7|u_vWW`QP{H7JT_pkaKdu#N6ol0h4g`urbv?Ts3CwlSV zr^ARP+x@b@3kBSpd0}G_77f3QCjF$%?=}7dk-x0OdIH)iZ>Z-+AB<vBnQyq1KbRMg zcNXiBT7zq;4FSekFYfsbII#8m{H73c=c`!DDGc5C)dYFfPs>e}XB+>e<=jZfC$p?Q zQLxok`3iDDJ~;!-x_WZFiLYt%-Cckl@@#E5T#<9wVc@Io@9o^cw$u53i2k>BvVXSo zEh1a{uiGIdpU>L72&WM88=30P-|vwcmeZcevUWe9WL{(aO_g^7u{Jk;WfA-9QDI6y zZEgwu#`0U!zx((9IQ=ew#h{j<wo>YU;9kHU%d5v`LMV~5UtOM8N?4m`;X(c~a+f8r zQR=y2b^KeD8WUk1_|CfRy<d+cW@__mzqv!6@;~zYzssv<5y0_KEnIR)4tm-0d}Q7p zbh1?>Z6EQLl_hRTxBr=F1>uOLcn6KEtVbjpfR2gZD@aAffWA9(SjON5{k`x_^ql5% zDd(jciTs1@ha2mS&sDVO4_ftD?uBkPBg4?D76Z37_8}W_j=I6FC>?kTlWJ&)*(6!P zLoRwq`0j$#oC2krI<I^}F@I)k#|9lItC?URe5khuMYnIPr6VZlCR)eJD<2QH&!ii> zllc`YfC;o8&UTcnijyB!w2wOdf<$=f@1D^J`db@n={+$sTsPr&p=$m|(NE5G?Yc_O zTg__PUt;UkV8a0R_ACBhfmMJq<BR$a!05{D^IgThggJ{*_nwZzjM$x2nrJJEdv}}P z5qqry9HJ{O8^~~Id>}&Swaw^D+c@n^lt}dYG}-FpDJ6!G+FxNFvpcqu%r5$LUI#fv zPeY|mM+Jtkq3pc7Q#}^f5G%y|&lN?s0BiDbZqDo5q#*cI0uL*CacduPfhL|l28vpY zf^jKVzfBgdA~!DLG+VjkTMc$EFZ9Nqd=Y98zu2_6ut0*{0H{y4+RD%IAO}2N)gnR5 zow_UGyA`pVwBI(_C@&D{`ztA|G4B}D&5DHpreKzq&O4=&tB3{dr;(5+oXoBF^!LjV zwU|ih5Uon^L;rsi4Pj5Q(UMzKW6AW($6?x7cig%&u=yK$|7i{jAZB{u{sA~rX$v|M znVzOu7i?wTrS|V2EZM9cUay9u_1v=``J$kl!;GF3nD1G$=y(P$_PX!<r<S|4qg8<1 zS(LnBt91~kYB2wxx-jdmfAffq$ziFzjXw>1pEQ#WZ@87|VCgli=#idJiBR&>xXr<g zom5<k);VzB%~;9R_{%Es)(cE4%DP{1KHd!lA~8{|9o&0blww!-LKG{>3(lW_HsGJF z{>vTi1Y_NyGkfUwjP~bZEs~LQy`C7#w2cFAH47AA*Tzuv)1*c(`)>FiWC_(^=kL2N zUwEu;ROkfsJ}~Y*8NF?`_(5|eK5sLh;<0eWRTZ0Fe_Zt)r9y0&Ra_8YP;)2X+Dl*5 zSG;}k=4%^X(=T@jyy%UG+yG#C<S9;c1NU_>S2p&o?MaZWwo0j79vt#9-t2VC#lins zq;GFT?5A*|a!88yre=}<YmXB5&2|qSamry}fhFZ@^~@*_tZZ%MKcV1;K(zjEDJAN9 zBRlysX^p@?=F|V1ZNoSNIPR;--;o<a!!=hY9A*gP8qg~P<rV!OATPyY6{+G509=YW z7KY=p`II<w^<^9S+C1=b^h5qLm(!VZC=Q8I=0z`F^<L}wo!1lE)q8;Q*pQ8<WIl4H z6Cq%_D!<7a78Ak@K9_66$pv1+KSX!q&ak6<wI+*`yem+fKJllJC|pCGdzPK`v^2dy z!P%zV-hko!rtO2tYO4>xk_%*%Z^N;DFKC8Q)O*|hwB%z}$?RTj^GKy~-+o!W-B>-Y zNwsc@NR(R*cH`zSA^)vwr=XF2bzQf)$jzoVXycVIAyx3J`iI%G+Np%SC8@}I_;Hbj z4^M-<(nQqCPdtBt{^=nXBBq4D5Q3Zq3+6ZEVvhc=mj2{ZuAI@p4fQhnsm3Gd{?`va zdA3bAm`sRo0j5};)fu{S?%gHnD}@*K4)e;#LOssX>wy<!)jKvCbSjteYGrPN2hRRm zqvNmDnZHlxT~*|Lvsp^dU(}@Fzqd!qSl^L0wDo<)YJX*Tc0s(k(rUZ;+}EK-uXoUm zULiJ!dF=}_{vhOQd!3<di!CtAI=%i9!tO?vunwk}^m|M`>4#kL@>;o#WKs4~#>uA) ze^pGGvm;b1f%La66wLi>vJA-D6%l$qwkBldyRv(hoVgvBC=wRZVxhSrd*QdAXoHZs zmRZH(@Q=usjK!w9k#XHxl3yuiiy50@j*iTB{ynSwtCHHJNyv|0PiTsI8<<-GIT+uj zJZ^Ozl=QOPdkR8iXseui@!m+*`{KITS(5in@qNh3s+<jG=oODD$RyO)(KLO<-%-gP z6Y{X_ffsTxawVD_w1uLKexN2#y#6)~dK-u?`2q<|+l?D?4E}hzi-$f4Yd*w~1@4T2 z&dp*`P8$nWbrU2Sb?Rp%@-va@`#n&2-oWjV0<B=xDxRvrYNO)P6p;!2x(l^|29Lf_ zNeT7nAm<<3k!JIV@M+J`p8@lN{-;;;+M5;r<`q#`-1u*Uj7H<P!z#0^-@W2oPkj*5 zybRt)Ml+b|_`WP-YLY1lp_ot(lskhA0(}&Y{Sn0aY%ID33k;INN`Qi}-GmU5DAujF zcYp;BfOqiwojH?hF>6j8S$hTI9s9Xux+@i%hP_jq9`AaxfFJ|?$5?Mso3A_`?uQrL z1}0ca%;@5fSk3J)T%_gGq;ZJMx^L5JyMY_7n&AJkV^0j$j#cBS+qZwicY3TH>rSh< zf1UohHDBo9e&Q)gIh^uLro&tCQ(v3z9lNf2SI+u5Cy}`R5B*c4-TNAY3cGF>i52|; znU~@O1x1{jgQhKBn^|cKdQXSnLUikK=?@W!K@@5jCub$Mc9;E;c_|f<dJ&VG6Vs+M zUOC3oo?CwV?@|g_eLaht_iHlo3JBzt>fRch4soA)`x%X4(5qkyHNOv8){xSqpDzZ; z2eBz$(q(tV{a1Z;Llc{-+K)`_{#=M(UE(%NVr&5kT&G18`mOf9pBNK8ef4tQLQ-+A z7qOab<#GK@{=*O1lPV(%X^B6QVLV-4N*UAXT3^P26gun{t;LJ5Oc0!Cdi1co6zq~B zULlDgWLSF^toVkJDcampafS#8iLWJ5?-ZSWj+($V0dCb($GORsn9d+-nTqRI&lT&x zQn~rtO=aT)>5;Gwi10Jf3w94Yj2gQ|PE{^a*N&I{r!)aotk|m17RB!KtEc+vCAMlc z&FyafOWCG~$(>%SN9Q~LNIc?nXgbw8DLQ|LGVG0!Z?9Y{9SmNXkoT~05U-utgw@Uf z&m6t(X8V^$mh*myidGd|mE+M3%g_a?D`zGSK{7}^T`{GDcy8$jVW)?7yAP+2(`jU$ zDdN<&5HtFF<_hgiy!&GP?O21$(x>GE@QkMjEe}{AyBOA7h1ys=v>Ugsu?Y--{}fZb zyJgwR3-wj<7HRjy#VHMZ<*m>eWpvt7MXzCbIvL?*2LEAB^8~E|5g(JPh43>u$RoX( zDdqWJ^$6$BdZe_|lI=HtRsLCzeC`MSbv?rJqWQJ@-K2~40QO$PmQ<G7TBMcs$tq{> z&Q4U~OS|arfjc{=4OFMn8gs_DI=TBxxea|inwTS&b9mtXIq%Mkyd$fVZ(Pm`Ch+rz zrs?NP%d9FV%y(0V2sPa5fbsU{HC{0lB@w<qnzql`Bfq}P4KLYTh_W+ermW8bmU=0O zOrbwFx>*cEs#K9DGo&U9+(_`zT`zz6Wd8)lE^GFf2aOYzKPV}dSP!Z@9!?Sq(?%{d zJ^uE8*n97AxVm?5{7E5+1Zg5jkPxDdUW0@LQA5<xBD&E<H$;Radhfj(#wf#RqeP<j z&L~kw??xHJZ#?q+&i8vxj`N=P@AukQt}C`}@3roJ-)r5UB~~(M5sp4Ku807OO686E z&SkDDwubLoebqo5Y~WR<K#C^;vOM77*1N#3Stu_$TGe{3fY9-q-rv?qG8M1eO2cM6 z6u)gWJzlpRJ{gssD>PTh@6V?|8lO&rm8`(;3@~z_r08v}XxBC$Coz1;Dict`9--=B zWVh*^xMk0M!;EdWkiE7IC@T1Q5y~@1CHxDRKL8BBm?WX1G+;F-uDRFG`ptdcuX>-G z?(!1c1#g7kIQ+bMS=GU9D%teskWlS3NQQ5w0j-!6ovBwSDy_fnqY+5(+uWL;n%mKW z^r^EU->Af!TW^I{qI0>e^oV2Sg{mymQ5R~qhPP{nW@XB9%L>OFo29RGLKaFs<nfyC zxc!74SEahO^aW+8mc%WU|F(>+Mk|REl9i?9hzccz`{n7h@l>Ti2+e92ubAQdvX7&_ zWBc0g5Q7GKu@_Zkahbi<eULmFvw;EUf!<PJX}^tT&VZWd16Y|kARbPW%M4*q5hX65 zV}@CSwW(b&kvxH$V!D;Ps?Z&wwgcK%Z+In!hxD$mpRvmS)SdReh5t_AmI0^kl;8OJ zxvY}Dd;ivp0RcIB)+<gTjEbW1sa)t!4qHd_4#hideZ3lzbM1=9FOqUmj~5?@=kbX# zQVoec{yAZ=I<ER^jvVXMI&UpX*RuQiRg`F{{P7kbsx9BF@e@t$<Lfm?4xS#+t;0|? z7v6arb$0a00Y!yD2jBXh>aKNj8BCK*5vShh(wQ7;k_4nh-DYW6n!cW_jHs%b3+2^1 ziX6uWV{XprzAoVnDT?c!>U<sp{Bk6af-rv3Q3j*Nprh&a8g|*^cvxIH38*2_`ay){ zq>Hky+^zk@-3>_>*M{V_@4`o`Kr&U&nng7icf_PcY8u3={xpeyw{sm|6~Td<sn22y z4h_65yb(pe{Nj&M``@yU-;)zv*L)39X;qYya8f8y>50{9so0g}+T~B|eb^TIT}##w zSQDD?0j;>rP5DiFmj718{i?^eTO)H14#G|<+*_`x=*uH*X8F-idhL}yyl&};XZ9iJ zqt8BxS3vf@IP4#Vtxe*OA&eO)6K6^otOZkMbnJn6%fN`y<&{UfeSGuiz?*d*s~5Qc zPULSy;rU%3W+-yT-vE!(N`WU$@s)G={rs||?i&YMw|cJMk8wOc)sJSYRHd^UH~df2 znD3pE=jw+(Ilj=kqVxRH?--`)G&Q!GEH*iNi6K6edr|hjJ^0)Vff!$9GDxQxxqjws zB{T37x;4VaLv&_q^l$yDd8aWv^7Py|V&$~TguHJ0`%4Du_)^vIsut$P*-I=4$^p%4 z0SD*Krs%XE$YO`i?RW9+>s@@p^SH`K@~mRQ!Fnnk*M+IhU10Fl!52^poh}gn&XQJ6 z3vX56wxqL{gh26h9r5ElO&$N+QaT6UY3V!A!w~SBuA!&#h#{i;=^2T9U*TPqzP?HN zIq&#bS9n^H#;~VcID0BU2k-9;5Z3tpk$=CnnCw>#trq9}xht8CzW5SrQBUv+!P$7} zl<{=^x^j>5to~D1c-2OagLTE??r+^V8}EOrPThCJbGTuGfagrByoy-x5y%RL&CU03 zZaptMjX+o$kItRV@J+m^@g0UDf7A8lDP2Ry#nXS2=pJ6~eSH!G&t0HsV8?TKxauR} zZ+&+>75ecSqpq`;G^^q1YVk9M=AYS&_QgE^2MgdoP3rF-?^B(YY9+;r$$!&W8c$=o zVlC6VXXI*lj5of8g(XU7B>y9Ip1&JDE#te9cmH+vRAT{N0g6zFmESv)Mu=?mLZJ7z z&t1<qkid)G@PZWP;+eqTV#3q-rQ`L$v%=~-jnicPo+F>%d8&A$3eRo*^^26hBidmy zn@davPNe^c%*|%CclcuZ2>bVQdG*)DbPfDyo~}KMJF7g_NuSz@UbnB9-<q^@s;v_V zZ09qJ3C}En-4VX?ROL@P#Nm6oeQT=IXz0%b|L={v*VJA7KobrvsQ!_FKXLs}_wF~G zN`ei#7<8T#|B3i@Hbi(mRREU-{^_^p-3!pi>y<&d{Rr=Q;`OK5z7seVxolC?*|Nl+ z9{F$XH5TGUgmbK7h4O#Rm4s8KzfHD0lVc8&%kRlY=b)Z~fIEx|a!7<ataad<AQ!k% zj;TVBararnzS-=UnHiRzIgDF=Emns))uZgE4*PnPU2aV1WLIX4rS{bykL@Zm<<stL zXSyp?&{IDYG0~dcul*py!@$J}lb#3Es1qH!{R+JP+|dqxwS1<QBt=<GwZ-;X{zLL` z%-ig_YTeGPE=WWe(+y^@;}>DI<p2Ut_uz<e0oQiPr3!v!)Bw7u?#4MBwZUhKs<7A) zvfsx1IfK`P6G?MWG>W@pTD~n-?GejhzjV*l)=%)YNoIL852rw?%2EyT8I#Haujo`@ z#h9xOJ3wEkHpswBHrr^q)3_&HMusLoe9q}mX&?%Rnp+T*4|9QqumTaUnX{c~Hs*z{ z{_vhlRB8d_MQkn70XRG#I=V=!Ee4;|&j?Vfxk=U5+1MAUbg)u}l@*5S3T_}D_8uoc zPNm>2HhV=tAM|{5d-8ssR7NaS#sEM>Wht7vJ(Oj<f}cK7R2jufFWe=0j?&PcZb$yW z<^IneD(}bLSY7WGXQr_e2YL4JO6viP@XgT^GE$39HDVGz&H8#)Z-^zaa0cfXOB%LB zckfHeQr%J0tg_^O?n`e7%Xo@859=<9ihg?KgRV!-OR>I>lcS}|FW&4{QWNPGx`!pf zs08({To=~S=)^-#nGah2+NWmS2v}Z>^tBYGKU%-6dMCCw>7++(qzL(XM}}RHa&4TW z_dBw&G-IcJ_b~Iyi9&-|)2Bz9Kftx@wZZ+4I?;(nnddOHTMw^OxXAaSzg6mf$VUnl zHvE3fs4n&pjdsYBT-Y1w0^Oz1Jq4cE+bA83$)WY4IFw5e1>;(jzwgVh!x%sJ(&VKb zQETSBm))XukvbqpX2bHnt7V2Y*JCNF_)K)M^rm{$Yt^E+SJsvDEG9?j)kFrq3$n}= zVPz!`g92hPv1m{tp{i8l0{5XyIt@a4CO%PUkX+iqvh=P%)vO-59sK<UAu}PVlKK}t zP{g2OdYHO<aDThLyX{C{(g~et4&((8X{_;L^vBZJVyB2xGHh8985P*<s56vkJa^vg z|I;41A^Kle!os}q=idkiRnuZ8mV!L{hv*#BdvfI3TV9g{n*YV;xC>c$$#O~fGc4w1 zy1G$Xkq-BMSgyDM>%GW4bw(M5&Je!gA|(I|nILDsHGsv?T{ZCSp~+1}l!=urT#@Vz z$`<$FeI>Do&_$df-^kMS#L;!W8?KW-M-7_>8=V(&RuuW9S6An~6FQ=dooU3bOjq@+ z<GN?dUqVGYzE6shu(mCGt{4t$87O0#ii-+AQ#naX#H(JY(B^XoY5ux3I`6)@H)N2| zV*rRVesI6pmM>-d11;9*p|Bs9QWwgib8L7-a^z6aveGb#6$RIA<z~0oT~)1sG?^$w z%}5+24A~x3lETce0Bl(kR;wx1Vvl!G0GUO)0s;o<n%vR5Bvf`=o$I@YqT6xybx32A zoXFa4U90ngD>fEq`;N{0VJ!vBf1Y>d5z@F_ZVdptW;QX5ZvK(qHN}%xB1RqHm}`5a zi^sHSEthvnL-A{B$B(@_IBz$}kUHMC{zrW@z|HHJQ1!_x+6=Tx`U<#2$Idzt00LQu z-wDLdIcp&_b~SKI`buVQtA!6hmf_7NgnJp!n2`20tZpgauP6GDu7^t0R_51-X~$w0 z43u5cIX#ao<$#!4TDD}}&@r)`uqN}o46L&^&yjK-QlUnk+S5I>5ptwHyK>FUeKq65 ztNffO9FaVGNGk!avQ2?f-004uH6~_ABm3vf#Z0<hOc6H3Nykw<D55=qr7cQ@plqsu zf74`VOz8j{J<+#2`Pg5bExP!JRKv2t?A}p>enpN3g3Uww-uPNswK|Z5SEdcC(~DhK zFwz3eg@3>zIwC2@J(PJ{G=dXM&BMY?s^|}sJ!H51Sqyt5c$Lj9s$im8d~@*ewQhOk zk}S#2+FshG2FK)45Xo!(5p7K+H|sEoAvdYagI%W#)J9oUQ9DbGGM&FMxl15OtXPV& zOE+SS%A_?8))CTBMMXbmu+tauICigF25LOYB1J_x3m@^l_K2wxoYc=QyXIfNAZ&}3 z3~q=eg@#rX&De%_XT-c51IH&Y9>jgDobvZK+MVXIu2rt>vH#WlND#9oC~_r0bRc${ zNXBR_%t%>KM6j;k7NQxHWD&V0+sNhm;4ZEwQMp7ePmkeAq3hhv6ocTgZWXn#hpc$` zc4q$jn*Oomv}v1rO+lrNm~eT!9hLZ<7|Y({r~3_dxe5Y<FX@n)G;JOwyNMXw+W1z| z{9A+MSM*COZ=cpax7!&jx7?(hsa`x0xHJ5+7a-DG4uZi?*wyD@nk?Lagb*Zv27!I2 zoZD}yO)YkE=$RmhO~GT`i0ZX6!rO`v4PM7BEr8Gp|5AKkn9~goD&CK{%Kn0xAtf^` zg8Cc9jF$s-R9EhxOk(B);d`3o5ONP!nSy2&%_DT4(RBQvi;Je60rI#=h)Ivg?tNIi zP5$1(!9)hSO0dR{`nr#&3ey0oy6iU>X-`+6?y#pEd)`z!D7xk6jL>nCg}<;|b1ZAP zJ>$0{H1Q^1L~NTNo24*ZisU3Oh&)`@2>+Can_I|!mM3l~eaJWKGst_vMVZq?sjf-S z?Ip}Qu%468V@$m@&F9tDV12{Zw=&N)zX4^JlBAgV`&+-#l@t3BYqqIddfL+gkJd~$ zD>B_<S%cLrf?5_EMeJ4@+LX5<d6nIoV40gu^1Y4|kRCIYs*bH^Ya-c^AA;f1Lp~FA zoM8tVJG|{qmnilmIya++hbA1j4Ic)V_U@kS+8%qR>Nr{;Sfb`5L6h?9QS<y-m-Z-K z`rxC7TSi{XDX8OP>MI^qhfX^1c~4Of9Df0YtI69pA#~~to&9c+<}I%U_AcIw7Ror7 zOYc2|xvuhdP9+>YuCUh)ROylvxb$9Ullj;B!qJ)l#bnbyC-4z3%e~j34jQ_ksvQAg z$R6c7{TS$T)?Jx7^?R>(6OVZ(sA>T^q47J;1x%s<;x&z>4<Ad%#;&M0BVVJxpd^mY z*<$9EdKxQ7j9Oej%Q$SGcCV)_o%J?s-ZbwFpd2Yo69?{DM`zhnvL|RieNsEg_E1DL z<)KR8>zPiSUdNV`XN!r1!D=uqYEq@02a|MFx<lQ$HCrZZ(Ung;QkakRRak&l2o|7> zN2W!N7X5maWp`cff%FDu2-EBpj;Wk(%fd1~${EG#hOap1@{W&H!i<VBTBQ`9lrd>p zpqB4Knu5ZQbRqSVtCWRBX|WzT2r0^bmV_3NOhrFbYyOKWptPkRG4OpiBV0rglB@wx z<ww!%4Vdtz(p8>JeRjy$cK}9O^cDujN8X^BctUKQZS7O)8-^WfZ54E^%Yy1x@%ZB2 znftN*5F;}4U^D*A-f<xQ6OS{I9yuZ9J>aDF6txl`_ogHc?uNQn-NR?WH+nPX-bto< zoYQJZABCCts8oElXs^iNa}0@~d7_q?o{w_X6z67xypG+kD{dL%H@q3ywNlXSqpx&1 zw2Ortc{qmN06O$pXrtF60ldpg8Snjg!GAT`^_siQ)$KV-SKaF8GTH26A!an@?2K8K zc7+B1m?#KdDx1A-eE0RNwz_+}e;4|)s)T0XEhN6F;^FPiet-g<%sezA(!Qe!X;Q1l zN&I>6Bu7wpm)~qMfpm+9r_4js<p^;W)<O+XBqF}L6A**STLFCP?;k8fU0Hd20%>an z^^U+vgy7}biABs+eXHyY0d*lEoDt&$UU&hhCfA<ofnwJJ3da()!AF2+Rf^NQ)r=9X zqt*aLv13g7NhQf@SR?nMVsiq8|IXojFw1SrXb~|1S{<_>3Hu?WLGOKu+f7Vv9w+4+ zED_lU7V*?#LWJ{jETL2$<Bvpig~f|cF&QFO3NDCbQyLDj#5V13eOWRbY5xq0sz~p| zdIe)8n+G*up5ySW6Q6{<^_ipE^oHvY%DmSe!l}|~9&V*EChA)En!F|pW>v3<+7|dL ztydGtm3sCVlq&>Jh43qOKgQVluMC5EL<uuBgpQT!bxMl|ai2c>ra4(!H`|b=_%95X zs!3ofCivdwR|Gq@5IofK7-l_=jjs+$pcp9jcok`{_lu^h#hy?s7g+Kdl34Uuz-RKD zaQofU(=;uU5A{2Ve?Sy-A)pu@oE6yeZG1A?fChCTD}jp`GN>l4)j&c_#c+8DzGYf3 zk7#ZuDCOEbF&*yIlw3BKS=6!5oc1TM+tiy3pRxAA(Mo#xQV*FgaNdhLgc3X6eEi7S z+(CY}|3a?kPm&vzQwlI*$zME!Bdl6`Nf=jdMHc_g+B`Ws7)E;e+fXL5>FRrmwwBC3 zN@WmcRP~M86Z?~LjrXDUc1Ocz-vlnCzOgMOq|d9~&2}}Yth6L<H&MxP$j0ikC)$hG zs6CCxgQ1YN{0v6T?jlB!b=o5m%e%L}tL^^$%43li{3Rye;R{i#;RKS~$b2OYnS9Gc zEHT87?AC5|KEYUYj|o{c$&<^f_8BWl6<piFM6+A4iLiNua6+aymtI5U9`J$&-46?S zR%TdOYwXY4hxt+yAVK!2ZG~UG*T}U9?u3t~lBu9QGiCBVW12S`nlglMDiE7dL3W2* zqLZ8yn|rve{t}e(4y9UoH%p62)D#hz;O7Rk^)x{3ehPVvu2`bw0pZGQW^r0M19X8h zMT7Xtb5c0ga0nDM^7$E)dK=1b`-x-fTi}F6s1;*fjAt}q2|22Mg`L=9-S#4Cu=1Ir z&iruEy+vC~p1Y-*4c`Zsf2^789tG46czzJJpO-lZaQ}7$Q4LzEn5W+Ku~%y|*wcDZ z#~S>Q_%Ex0zp{}@ArTsAJ6o?Ls)xOHNARJngkmEhz6e=-^ow%bHc<fvKL}+XH*G=z zpY+6K_!@D`KKa1Q@T!EoiKVA(Wg>1|z`*M9Cel_nF5C|8x6Jm6Oxev-I;qV(U?EbH z7*a;@LUs8Wv<4yGFz@;-7X8Jl`-TOvVQn>S<$yD^Uq}z}_NL!!buE8*f_+1*>x4!3 zwxr@q&xGQxOuL8P!AYjk(k6Lu;cxIXF1LpjeX9mYbcRRjFW$We{T=N&5fvrI(ocJt znu4jCvhTLG$_KyxW~_=^je%5JyhyzZo+70`^4A+}8jK(sDJ*CteY?EUQxaH=OCFuR zes8Qqc~JCSBeC}~cbAU6AIkH(pYWX2=DPyk0ZR4x#bG{G_9d6CL)7v8<u6MHb{~e+ z%xo8T_Ve~z-I=PMsJq^dDjHk}nllz212}5*;i5gY_xrd#@98;yItJ-{fgggV0)Y;P zUGuWbofZWbD5*buf(;&S`IoLU%j}H0DUD8W6$H*Z^u%!vEXOs14OaLDS7{grcNkwy zEX^DNoW+=OmUIykNc8LmOE$8*jN(&}>AMn9|Cu`LXw+~`fj`h|Z^QPWG$_~-y>h3e z(s(RuD1asPv1WC-^80mOfgxaDnk>fMI+(_9aQXc}f(%oQQpR@TOz&++(wCn3rXzVX zdfD9H-L}7EFiwf)z5hv=8*6J+w>p}=x@05K8xH5fjWNfj8vPVLc{0p?@?baEM9~r$ z+YXImBDezp4e`l-!Dc2bZX0dKxs8wPpO<1ZoHkj-{2F0BtMSads=M)SHnJo7r)U17 z%Dm$Vy>B00F9Q_Zyo5l0R9P}NsG{06*;&?|ASs06tS-gUd9G?gsv<L>A@iVJ;I;l1 zahGKt{26s1K2RiEEt^!bry8(RtCqZZOCFS|a_NmORlvKBYl-U`?xKlrFMR|h{*_Xd zrA9o=S8+khprQ|$SUQsXUbE5$%9?Dcegco~^NU2m-y1!nHzkxED<$-dE6{arN%(p7 zM@3%;bNV+dd!p3b2$F4+cQ$g!{MC=*=QjMgL@Avk#ZFa(8Y>~Di{8sd2Z=5<(S1?R zlNU{ltDto=Y1XE-X3~vdhX*51uoJ}%T$w;7#|kySRj^62ni0GqX3b>nh?2W6Wx`Q7 zCwtIpKnpgRPqEEn2-XR->Tm()V=GY;>Uq60M~r;KUK%D_X2kP6P2PeYPb%wIgt-mp zG4k$xoX~};fr5p2(f-x7&$tp*)M!Mvnl;JH{f!25k>Yi?s_N%&=8`SCn^5sx;`|U< z$Z#?7a^{hfN2$T`Sk8FiU=AFj#VwLZ`-_ZjXFS;;o8iOobq?~e5@5q8<AFAkkxVkc zjMPs<VoHxZ$<aW+3Y=h+NH~x6_dwx{RC$Tb@HPir+Y#-|Urn(*@jVTty!YMv{JPp` z^wvc9o?&NL?+>>2g`Bt&AH>7TBzA#Qebm<^`gkwbN=j^88inO3Axqz=S$oJ`L>eYk z&ADo`_06=3O?n#u<r-48W~SbVH1aKS&POQ>>hcA5&DwH3mfzj&UAnP?w_@fTl|P1q zkZ6~ms$2W%1D%4_zAs8EH~8U|g`D&IXtyL^@*!a|H~AMc;KpPBh5Nee0aGmo@$RnT zWhV<UxK{*wl^eN1uf*&c)2;!3?rRy78H^XG#g3(_GK|AO&NDteBqw8hqq(x>7mPh! z=et%iw=>Lt&M2=wV;(=+lJxAHnd2Ts`qiiD-5kl+ySb@nEGA&!FSxVM-8iX(DyMli zF{YX=OpULe_?DCgaUmH7;s)9Rm$URL_^>n2tKa07M$Q^A4&b%_Ej_DnlI2$#nr}k^ zDp<-M0AGKVo`rP&M<{67b(LVmo=aCtV+H$B94Z8Df|Jn>05bZ`22@H&tW;3Q@!XKL zhw*A91(`Zbkk%`Cv7qNVP1GXGNQ1G__gljz+HK14aiA~xIknXrP<#n4b=UZJojE}G zf*5O0tqy+!hw*SXw0H^sY8nF1I+wfEdOv#-%};nFD6F1HmbmI3=L2)Kl#RPARJ3?$ zGFM9LiSJQtw|u^h$JS}R8~ly$(ru$+4+H4z&(S#_=#`ZwSw;fq1V>Qjph=<()aoym za;anMED#6nbi2W2i?KzorTB3FjKfs(inlakRwh30du{nxk?Io4AGBg;L6I+Od-d#| zc1*}r5nd%7z95bc{h^;uWc5B-vn^(oFV9^FN^*H&%uyCD5l3qFQ?ug58dT@*)uxur z!j+K$S{=2zp;bEY@@{;MA`zE4&0243rP@Z%3JAx0yp`u5q@Ug5jdC*9=s`(=+L#X8 zt&|Qu(-X7jx?Aii8`;7~f7X9|zh059Tw9BW6z?U@BY<20nc9|+0p*+>63wI1p*p~+ zT|#j6p<RnhA1Nt$hgM#&0{^AK!S70f;BqBk6}t>8LWLUqAqnoR`WWl7@+^X7a_DBV z4gw&>yr%bfyH=aQMInT(mm;d*I%f+Ddw3XCX<V}A>#{BbLH#RlkCq++8aWL+__}Qw zeln~C2Z)wkG~=bbT*e&SsCS8y&Wh_h(CT9wes^y}ewyi*jaL$xmng(KQan3%h%~oS z)K02L0zXR8AL&N_U@%u5MV0zxSxw?qt-k(4@|7UP^fVZPWsr*7FfX-icM=l$yu0h5 z-7>QDYc28zfc(CJL*=R_i;W(|As{RDCsbirY@9b&0;YvcSdQBD2}sjh3nOHFsr{ig zNz49r7xbNTHx(eju^e57dWp@ZncmJeIc^6Q$kp1s$<q@k)VowcsA5{!L;9V(0}>VI z;v`dl7tL&+D)F6WPez)>KFVwk9RLGS?s+%GS3NutxT>J&bR2I`Z2EIe-obymskBP8 zC$HJdvTAzDaL9$W>BWGLBp_#UeK~F5>Wsif5OKC`3)UQytyDBNNfD|M&BOm7GN{?8 zLcj4+@s=0YV)t^r7O<4pQ?itm$h|_csfo^Qwoc1&ccu<gVy><dG-w@tkI_Bp1JZHS zM9r}@ug0GfbD+o0<%EWN#Ab~ga>@H~)+Yq-om2MY;5l8IXpDvaUKX?>I4XQeb2)q~ z^Swu4e>;YzYQ;y2hjLnka6&Wi<m%Gr!srSLVp)sHiMz0OXkTd_%#7HfnuM7Zfr41V z)AwTE2T2B<Ep0AY9DdzeJ^X5y7i0>d&8l*NftjL8=38RZ^iyKC1;+QqDVO~)GW{+) zP`$(s9fOVRMarvR%S$q^`u%`!&8fk{a)i?x=eDkA8a7%gd#L+FxTbQ0KbMFqKU)!1 zcDG9+1a@G6q-8-eFyZlBjlnqr)o^V4XxfOCu*I}*S^_4+6fvm`{;^-dckKis>snbg z7k*u&5}YnyP|E&mH=c}84iXl_TsUX_(>nc*@$K3!XhlKkdatiP*IE_+^xpON$ll`# zH@kv7*~%)n*&%W_dP-O)sB4w_1i8L2lcGn`BqrxFmZ9O2rv|VjY6^DNgj;#5D7@x; z`zzh+f$*M8`hm2$2{@IBK=}jcTSQlW#1;jCt~6_vfnaxeM6Gj^zwHf8ZdbJJ`<#Al z*;d=egnDP|9b0J{DP)WLgHp~i4cVP_0hZnGz+Ca6wJ0R6uVi?sp}TD~dvmFCBrsX0 zX|FkHX!TuOl~wG`uut)R8M9?}xe2PNsV}YlY-_G~d%Z@-lmrNpWIv#p&f^OLtO7tc zNGZse-hRpL3&1woEh5nC!7ghIm}ER=f$XfA05``EExLIVD@&DI%SS9?d(}LRT~L*o zh>~&H?A^G&2etFg=zQA;73i`a8F0LLK-*F5?oa=L!=Kk{WeTP&pw)UqAH^ce#<k{# zo9YLf@s-x<%$HUyfM`Eq*<Fj)dEO9PG3V+EEm@~A7qry(18WQdYeep(gXuEt^LlUv zUw6=b!#ihdx`S}Kp+PLYSD_#?p`I?5xSbW8Q;5W;VMVe!y@OeL_xH=CD&0gwlddCg z+pnqTYZ6WreC08HGF|9^?8V2ArD+b3nTAOkC#^@;E3)J-<x#Ls(alTetZMqI;mgY1 zt|h<M5*rggQm{X*@GKQ=#W7U44w!t!RS^<1`oQhdwA8wj=Y4J@*hEr<aI-vAD;Qz* z&%(C3tOpSJ7{@S<X~2RH%G#VXRaYU|UuJ)7Qx*uqEMMn@E#X~G;r;rXv1!44x+bEd z!>D4K2)WV(F|ARj)M?6*9n(VbEWwh$b%2{<l_y(DSj%u-F<1sc#o>T<@>F079pz=o zwD6;;vt`7?{JfyKezZC_eMNQkdBTXv;MOIOlbiz0C|!riiq!3F%P$}(w=*uQNg<GM zn>k=Zd+BC$ty*nhXL0y#>Y=r+xGfz$a5SHGL{^uw)eqbomS4Q9696b0N^5o)?RJF4 z&ijH7gP4uV<Vrid9ts}-UleUN1>%c-q}v2T)b6Y<C&6>SfXcY})pWcNZ|k%PgqsT+ zPga4aJ4|+J_cVR^F}CwpRKo{NSlvFLOM2~E4(mj-wiWitR7)O;2`li)G!*dxRIDu+ zj`?8aGSr@MA!@$uV8kz%n6>SN3WkxI+5z1zkvt>ZB@c_<$si?)-bFx38bom7plzX{ znRKyyT?OFK1cr&Pe11%9R=_77Hy_sMmL7Z?i34-ZcWsp67ud+qjv)LQHxqrTVLZVU z){|WDhKUSMlEc;Zqgc&QA=`%(jt$AP+LyL?l~KLr>Op0hG%(qD*67GRJTzREJOA)Z zjSKD?9x|`fvv0zQhbrDeC}iec>@Ahu!{M=jo=LC8MbRN6oMSn53BjvV*f*Ae6~!!? zjg%k+aU$N_Gj%AkNMmS@tB{9m6d;d(DDxR<hfFD^EFi`Fd--aah-Gah_qo_4zAAXB z46!TW{Jk|I`6EqK;V0W=ql!I^sT#JUkQd+b$IF%5zdS~mMM}YLCm!ru*q8S3;g<uI zKy7BvK$3wL8dI0W#6%u-Eg3XI)hF`jiaowbBSpVYw7#D0f<#t6G1@d66!W0kxzz`( z0CeTJ-q*-Re8x5Ai7yg94VcT9@=))HXR>>u{|Lv+&#zu!YE(2WydH|Tt1gx5-K7dT zcP@Tu#BaN}ZQ|3TC_Ia^M`z%)zkG1-eV9|j^p@EWS9xGJoRb6OGpUiobwv<I;W1s) zf(>C2eiR43>UPPR@oOdHOrQ9THM)UP$8cpPoOqGi0!v63;3)OOgF`pyelBtaxcp4F zmRRx)?;EAvQEcZ8F@i&epEX+8_~XoAxe5HgHCuFZ=y!@tWo2#pSNx#Jv1x6=YWrxo z+0zjbHTjc>NNj@Y&wS;O)Hl_ia;;-i53|%zrR3klHbmY8B5Iq0s>pAzhHi{Fitu&4 zZj#cu&6zj9R8b<=wP!~+G_hBt9bPP+j1U3O{4MQ$FtY?s{$DlxhvhG6c58aw`>Sj_ zF`fZmT~!IjMIHH#jx9iAj{+?>LpgMnc=zxiM`DR&QbG+vzVNmRQsInccltNhf-v{k zd_6U*gmo*8PTgTKl0I-jaH^*?jf5Dtk>xAv<ng*h8WrN#yLaL<mW=J!6Zgo0hRdYE zji^|4-MrPdP@S%|zAuP8$0H}tF~uS{PRaN9x=L??GQ)OTb}L!>w4pn}oeu%Y83xtV zp^>U&y+*sT&vN2~hH3N~1=y=Mzne-ec?>Z}ighzbHdZ7HrL2D;m-snwIQNy=U?`9% z;m~XlT|}rR+*t!a@7!NpSP5B^=8)4Xz*Vstos7!gKeE*$sP^lvpJ5+Aunro?O$3WM zRn`)Z2YXOoN!`QO`(-JZb*ONw4=>$&TiNBHyd^k~7!a{mPShEEZZ*I}y0{O(ANVsm zdQ(g)zvG))4FLB(_pTx!;#0irENS+K=E;*nCXZkTw$&{N!Xzh$a$u<mbxHEF>J0e1 z*nc0(;Jd8wK-~Y)WtFZ}M=HBh`zgIDS=ZUH*!N{^<|8GiPscYvb=i-ot9$<nBzy;Y zd-+|uNvY7J*vP<vIHk(?ETJl|S`Xa*3miyB$a}xY-K*IvdUPjxwrRlaG^~-_=LHYb zJ-)J|RJJ;pZZSRwuUsyGUYYg^-U(h<i!2LYZ!xlz(s%KRkZZZA0!Dun{f^Y(4-x7% z5*0_0gv`F)@7L<Rllb%i5z$DKPOUe5z-Wj0ykhx`A=J6Bl}H{M-7IERDiIP62QD?v zh28WC1dMEUnl0Ac4yQVPmlZ*dKJco&3pQr!MsJ4Pt-iKs;N>(NOfYzl)%878Wx}G8 zUR@m?bO$y`NS7nzVuNM3EPrY?`Sx4W$f{?+U-4vLfmH>3H|OsyhLH1oH5uUD5m#wU z@9gv079v>>16yltBHeSx-!K+QSj8x094YcO7o!3rOsk(r(wH{8G*rH_b60n4QkYtw zh~BVH3k&C$H(pAw?_hfg_&nDw#wR_@{wd#UuQtSQ7_0f9jf%dg7)HEsviuORcCaK@ zS!Ua)SG&jF-E^%UcOmeW#~an&q-@FO@=`sNA_#jus=9qmE&6P&@3#|U==zM?BYNX6 zA?c@PfM&Z6ZgO_0+gm}1cO2a`S3V_6b@465SO)&2q-M(t-7RH;$bg&+bQ|n98(v`Z z6l$M`SP3V&9R=DZKvY*R3HEN-E!m2dCv0l@9{W4+wGAS(XSk!s^s*n#-bJrxl9&}S z2l`rt#Fn(pyinZ}idyr35c(Dm;uIOQ?~3F|v0X#w^!dJIw6ENILVO}%)8yShrRwDA zt&6K5jF4XoLx?VfeiNiLtxne_YL}oNq+_JSv=!N7zCEaBs6u`4G?#Y#YsO>wc(wOK zC()15CYQpnvaezy&SROvCmltj{PrkQoE+c7X4_v^pnYSE1VO?x{!ELa2w>EQwb=R@ zcjBWVf{Q1cNUlcOWm#d6A3UzyJ~>pqOuDP7b>Ct_?03ya4{6YM$kyiQvS(m+*a6Jc zyfrd$?}cic&wt6OPsH5zE@>Nq(clwdo55d_l$JcUEphpVfmXD(R6GGs`<s(_%}3>Z zz|Zw1E61=eTUCbTXqML6*^wqmrE-k?aEZ_=*`E}J&Xdpk_+%<2>j<usYV=al<~4nC zn)cO7%gu<1>=T*Tc88tRE+4&CxafOlOO*Qwx@#Bhg!HIgc1jdV-bVgM^&j6qgWqcT zAAL}qPj7yH(tDYMP%sNVbxWtInmAwk?PJ-}Y4d%Co)@nKLFC^CP=_SzA<!?b-`x-r zj-{y~+ICa{8$kt$Dr8EN%fg3g7T}I+_YPjDLX{lf#ry8LLUklFTwC5MzqKG_cR)6D zf#MTTPqJYQrcfAZy3o6+asRn*S7Z|QRy_l03u+w2ABJaGmQ3gl)!>{`S#`0WV?Y{t zuS#Vs?fZ!i1O{+K!D0a6AfeUQ6JOXdUcM?x_TtQ;#X@HJ0Md(T*Sy3)*g=D4yoTCv zet$~Itc%;Nd~@<ut;w=?sa%affLmZ?FP>ee%C7YDCE1p##~_FGTksyOJ+3{SUd~Fd zvJdNS#Ii>q*5tQpF#S@SSIspILL{VuGu@;mu`fWxX$)T?+qWgXA%VooTk*8dOjS`j zNc`5MW*^6q@(TH7#w9wKj2eG?G^rld#PC7en0GN&UEw3!09*HrHLq-+BGS*h?a4Yh z%9l5an*_oTP$ZjZa=Xf+@UQ4jbGjHh`W$wMFiRX#C90FC>+_{-ARL%}=QyHeRE&~7 zDd$271OL0I%_A2qmhz?pv!bj=X}*q9xQ(-|rEIuPJ^ywJM6KDfpQz$kB`4JeYPEXz z+8_-HD=5M(>$6i|PjyRfO1?FzY6Wk#vGeh!m@ID=j`U8_eYEz|7!$y~%MC{2p{&P^ zy%~a-=CWP8?i#{{v0~TKh-7YTstU^&fZWyiy=H$ZN9pL@^ef=Y*p)sS2@4008%inQ zqGw~|JyC3j5+rDMqKi?v^GKC-L2U8yD#g6ZQGcRNFTCx*R{FR-vv~S=LnFdD+rq-U z2<?~p3Bm^KK|u&DaWV9LE|b+5h7LNRJ<A@V<pP<7%3peb+j~YkPQUK&XAnW+#BMf! zco1<s-^&7t5-A3<+`Q8AYj#;<{|X+KY`6SH9(6qF_7!%=H>I-?dW)rUo*8eFH|Tr} zg!x;&tg@A@7OqJ6YB8)Xjl#r&oEt=zv)e-(jrL+Xde?<lix;n0I?k!Fd|pu*AZfJP z5Mil~n}p5ph3<dc0ne&_NzRDW??`^`GlV8Pr%a};i}!=kL*dY~9j70ke|mm1ibI0$ z+VxDAST4g~0IEJn4pkx~XV7ivu8jPud&Tx3)!a<d+g^-v{0GfP<jYfP<JSie*9kBQ zKZ$r}cVCJ(v#3(FLp%rLp6JB@w%21BhRoRd5tF9jgZyJ5kloZ<Asj5#K>dNOky5Vg zG!;8o#nT=-Z04?M|21v%S;xiE%xm>pAcID_{^PGIqUCR>W7O!$-O}xBtn)r#MtbDk z2moV-YF{E+o+xkES;S`PZqd-l4#i&y#8tgeE3r$pVyblyYOjSU`@wrbU8paamg}60 z_STj<P_N=RrqC|h9A==VqP6}iVX0ru8x{w>Y8?jLv4J3Xy0F?Vr|+6HPzo|t=tJzE zse(f9p^UCU%)JECh1N6o64i210@bJ|sE4up!4x+KX7XJNb?3)yOMaZpfES%{A0NP( z`749J`i@ZYv>U&&8+GD)t%VR4WteSCs08L7_KAO69(I{CfdVV~4_M2|%6+G6(o+Qx zFuH>|<-NHphD*e^1hZ#SUNw2W{Wf&fiqw9k{V-7#H%$E2oF#8fk9J`071!&ouX|Of z%vG|7ptbvjjldpTmait`t-3U^0Y)Y*@RPWiOm__a5C*Eyv0NkIz<!@>yvgl7)63=6 z+r8R``!nrVK^0WYketxb5ht0XP8O4(_2?*xiRv`_jc3qCfrhwiQe2)(LX&-hLy7A4 z{&|M=<awD-_1y3$LCa#7E$vvBK6m8Pg3<{!p(qDo1kaxMqyk;Xvbg@w2f6Gmk<GKp zOns1c<GGhCJbErC5?tsmUbT}d&*%nNnT#6(wcc3q&;n3R(>LfcK_^^OBH=n#WPyxc zY9ee|u2{d(<C$8v%xl*9i8A-7@A0=Iso)159UGesnNu`m8U`-M-rGjNB3=2;${|i{ z6G7*(H|L$Tz3+Yp#ilPZU$Q6kd6*8^Pp)3kVY{k9xP0R{$#$pVSultwt@yQfjxK4W zd#a@Iq=>xLkwj>4mqSav`UekNnEU}ZIVgm86McK4hL=O^lZ)5~OSO}OlcC4Ctlch4 z{HwhXvIgXGByT}G4M&E^32bo(y;Ro@O5f#=G%G*M-W@m0vAr2E$uk+=8z>C+OxKlN zNshj&(t2s&$?ez}MkA-YnWB3EH02slM8RU|p8D%l+`|lcU{EDl=q~nk$0ScHd@aSU zN?VJ*)KilYL9WnS^Nj7w9`bP_QbBrPRIR7or+DXBc{x`{$w6b)&n$8_&??eUM<lID zd9V2a(?LRWZSpf#D69-?z`XFKZsI7(Xnhjbw5~qm7DLe(c@4;ROqHAWGafZ1c%CVs zJ~ahRp}(tpAD>ftJ-T$?Y_McPfsE@aTLFT9qPSuJ8glROhjS<kubySdQupd~VzBp; z;~)qo6I}!m<wd<4e?NM?Doz#m9YkNvb@BEfV{Cpjg!%n<wbke;Og8YlOBX4>*?q%2 z-xr^*zFl(Is(k}sxhF6nh@G^EViOC_((QIbJZDK^tCdP;(}$@pMQY?(JVzi}#*-%5 zt%V0C?|LODKuLzD)voZ6%j3qb(YACUwVn$P=r@q@dViF?>3Xf~UciV=%wq9wqOI0i z$O}IMQefngrg$^kz~gzh35|Y~@cM9}@ZCXfa{DB-EN+QRdH&vlzZpTNJkX2#s~98f z(E$)@|I<D2qhRn<U}6m1a=@=vf~1pKGZWkVuwFx<=luy(0m?A;Ui}VcGVC$21AD1> zVzfZlWvzY_ik;1kMoo?=3GD05$7zv7$-Oc@9-F<l9;mO##aoQcjZKLDWIsYcYN}=C zCqqFhZ%C5A)C<nT9&;Jh<m(uZ1FQ9b2#ZjX?48V_=lf=h)nt^F9f-*rW#pnJ4IlxS zxV|z}4>*}KGbZ)A)OT|t1UJOU7LSn0zQxWvh)H&>_rM0eDV6pNjZkbqNR!I@v@V@b zl=L3@F6g=y&Z-8j%1%6S-P+I@UDUj&US{qvo2oD?o~W0!fsWpwPE@Ch-D6<{-E=_` zhQ77r*wJ-<mL+o1RtX2fsV*l1S@OtLeaphwb0E7tUwBC*?R4N&X)`_7KNAwOg!-2H zKY9Q82O6YmyG}X0J4)iRx$sN;Ku;rQ@&eBXN{Bes%A;}aTA8)0qXV$WWQ22Ma^LE& zQ7+BRU01}C4M)=3<NL1>p-b3!vqUT8hblDqoZb56Jg2fc-!%F=!{hk;QFAJPrJgXi zw$I;{q$tf}<;xA8ghH8yYu{3(+^!d~o8gk7_@x)Yfe5WP?4{S2;opsyz&=*rp!#j4 zlx1@6`<C4(30SXIQoQBYnn6~#$*(f)1)U~O5)<z0twqShI)Z~Alt4x^O|gp&Y`us6 z3KSfW!x1c!PY;3~l<nYQbdMa4njHf7R$5klxUbr=Vw6v0MLNcAeSDPia2nd*tpW9I zTxs&jfv=P?r@HX22S62?Bew({l=-=}=d6CU-x|q82}R$nX$>uoy`HglY$tX!@0KZG z1ybBBxiVXYN~|+z-F$bs{*z<Vtn{{{;DRcMCr(>KRL?wXX|)LVQT8Rv9IwprHU1yG zsc-HTxQNS0ynxe=p|98lSQ4tT**j?EW%S+`i_TmRSh9WO-CYD56y1KDEID&KxluuO zyDWKM^$jkVaaQ`^l7q6H0?Sd7O;_MGS88yBNboecw+s}mmMv#Hv9J%t<^h>r4}*`q zNk))TEM!$=>NxOX_~X2^83|Pn=>e>TfI$<{Q))A-K@Sq<dRJ5tWcXfWSJYwU(ys>( z>NQBpqBrCayVIC^i<Q4#+0rQ^SD30~3X!u<+PPCjD8LVvu-)SLq{unwYNMTkZE1V! za_A+-+Y+X?s+P9J^QMizdl+7BGTK{|6{2w_%L}xWWFT)@ky^?GvZMopX`jbsBbKc~ z>^$Xm+q@Em=VCaI{dUwgWpP?Rn=-)b>{yLz>P;tZO*G;Pd5g$f?-7Av#Vx^Q7+QoA zA|vUCmYuoH@*sYSF8!D)gpRFBoGcItMbAdJd;*Bk&+#AJ?35BZjyq}6h4L+_<OFD^ z+h?l27>)}!iI5qhdg%D-HFu7=j<pbGt$SN|)4j+3<XG@=t@$06N$c_N$f-xmU#?IR zPNwPGfC1TZ64ASA3wWL!yD5aXdwy}ECgt*QNFUtg95{Nv*5x94<T4qT2X!%T>Kx42 zj5Sbwz*hSd3eyy;ZthF5khmEk?{=(3=Bx*oz<I@v^wt4vFrr=V4+2&y7giW6PhOb` zPCT*Q!+s{0CWTNiCb?0jgG=zo1zSgZAY@91-h--DmmJa^B{v?@4uW5nt@oJ2zqRS+ zsjlFUcsj(?EPQFjr9iA~=vVy`Eu(eB1ZhQ%pRFL|h)NHa(<<FQ9q2Wkgsx6TdYd@- z+OP;Pc3L0rg;vXGj=urvB~Krw`!nErd~nTuH0nH;#R{%s8h`iG{YNJEFaO(T#dq>~ z+=E#B1Hde)M@t=EGqE>kz%p>RLcxl)nH=f1_w?Cx?@7JjH^oXN2Av~~>EyQP>d!Zn zD<yBZ_cNkrZpH2-qvxhe`DJ>DUu-as3*}A(HyzF;Oeh>wij_a5Y1>u)@Rkr&gcObN z_vCnO4P)mr>vaedcG>W40xWp&Jb%B6KJwIMeD!uK%-cGb(z#-yk8jU&CpF=Oo;?%< zi>9(}-S!UUEUnJLep~LD4equT=&05P^Cy5w$}FDo(c-{pha=F5Tn(pT_lXxn-(%PJ zFSqEe?Y_UB3c3UmVY%T7*6#_K8KSmEcM2C-hzwaJg{|*NRPvEnuLz*~n@(~Kwn^ct z;S7tz{aOv#<K+%(q}Ht2sQ!@k;H_ueI|A1~*$KW~hEE$*P=88dq`8cKotngGwpx9O zy53fByR&IjYVbzd_AuJ+3BO6Rh>KhM28{b&zWoGsGXGtM;HevkS+>FKNNGf6q;y^s zPwUZi+qki{;wYxX)v_ETRN*{Tt?lHUr1cG*jL5+b#kX0v2RAp>_8lc+5`XMsw&mHF zK0%IUF#EyUc?iRy4V%=Y;N+28#M_kbI@)MF?0P8ZLSGB<&$SkQX}*dEyG>$tcMWb4 z^P@@ile@{HH|I8*>W#(@QsRpPCTdee4+{%&Uky6TZhtkK^vszND99R`v`G&#TE~9s ztfkTJ=gc0OqhjycW8bDUC}l|(WR<USIj`faSPBn1i`gMy`}e+N-$(BVRo{-sx!;ec zB=^U(tr2U@!c`w`#c`QwyoHtWmK^D;*b=L&bZj~HJv+zgoc6Qb!22CSLdAdUkM$~| zd;W$uyhaG=iKymGQFZA;vSnl6W0-xoqg(InksB2sM(X&cEJf~`tpE2F$<sB}=u=cN zBYnf)kXgT*rRq$t-;mz+mA^eelo~pH&|98i4yWQ^zzh|E(&0(A7a@+`Fs4W{&^?)B z4O5(tquJ<K7QY&KYTA;<0>|jr^IGF*LuBwIV<wyUcWA_7U0Q}FVB8Z|(Z@!5`Qb~` z3HjEWk*2>Eal*5VO<iVjPHD3f&Q<-#s?dl43W$ebVV<fhJO0R!3D*jfr5LmQ$OUuE zc{``B(uQQ>*OE)%2B!DU2}yqw;NNG!F?iaxxJ#XZJD-^U^|#NX@GXQLz5fI9+`oVA zcZ;XSX=mo3TL|Xd?$ZDI$-gdYGUJ6qR@m40cZU6^*Z=vR!D)-M#`=rVbNj;oL?gpo ze2t9te}bR;(_aQS;04?OdByD9#_K<Ilm0)3{)sC8cJKc&^iLx9ulN3+hW^<U{EJ}; zaPYcyMKzd4j9Lgo!EHPYL+-f*e&MCPPul77{h;pja_3M(OJJw1jvCw>|GxOt(A@KY zf3D+`Twc<DV5v{xqyNUK-U5GIzvNDHA3J%9PkjdM@Ov-@r})%V<#S?k8#E00Z=+A% zba>{JHD1_0y<Tw80PoFvZ+mYyP?Bl`Dg^4*NB_YB&;`zXJUF{T{syYXf9XK9Ztp@3 z>BiaTeqsNbyt0qK<;AiIt{Y_}{a62cU+W?r2_y*GkZ~@6&Yww^ehR1z|2abQzxFS` z0hQ-D{>{suvnS-AK-R106i|6|dgcEbP}x4_UpW1*it*<;;vdEb2l%#lOIytUHK4Mf z+`rQNPfh#(`QAJDsRu3-!2WyG@DCZzp;Y5<K;;MjdqCw;e7qo~m4N$SyU~9Dl}Y}| zE&dP2dG^SCOT05oXX`xvKmLo~l=}bi&cB==1pS+LIOBXk8QyjG+%xg~Ukk!Nc;^l0 zG^72QHIiERK*Q9(MC^Yp2>;-n>z^T1*gU!HxH|g8q%)!7c9n7R?<s`%Tzs3Y5c$gg zo{@f=>Fsm%vCag4D#va~n9)Cnu+TOI(;&PdpH(UT!54VvqXIqYh~d0+<J{qT*`Dss zf8fCP<qXRMuP7S$o{bl@M)0|RjKT<G-QK5_<vYOh@tse>U3%Ua)BNVpTReEl417k= z;_Um%S2vKf1Vq;73g*mnJc$Js3`uVN%>pl$C(mi;WLiq}&fZb1_;H<JWQY-dKH~K$ z1W<ZvyXbH6%szz?GHbFQJ{wrZ&0lVKjOdB~0V5he8Qbob2anJApe}<)s)-CUsXcp# zVe(&-*Ngv0uxiRvWt4~opP8tCz^c)OXBHC=R=tNu&8|Kd{5ar}7Ymh2;I8c6$nm3C z#yPpL>Z6M-EfjW2_sYLtEIQT|+(Y?$urSP#$<(741!z7q;zw8~a0iby)G3tEa0V{) z?&gIW@*AHTq|QeFXNy^<%4+k<8&ZVO4bhs<Z;3%n%PO{2*6J~pSU=g1;T(MmxIcaz zGd8pjsU7n39A(6+sqDjCKAoCe4*bD183C~4dDF9*-Iv4j$$N3*4~Jp>hc4Uf5^0a5 zED5{KM!6+FC|m2RQfQ3>+`Hi>qPD+6kXAL=4Ayh2pX_OnhqaX%86AU?{vLM#;8d>i zY6XF3GC_Ffms|ZiA@?)%pZ~@IXd^EgaOIdgG$n;2x#IK92Lt6kK{SV+@SF-#c^Y0o z3Z9AypJ5l#=3U;`4N)C`VQ`*3^HRFgT%5A>Y@~46dJeO^voCh=QuKg_0XfcSs5rxY zdrWSkDA(CMcm<0cNhkan#Dza8DlYbp?5X(UQL&%5;!&}KeuJu|671`8z;DU^nJ>Sm zq@Mmfia?bnYN*R9yjc3811ob^{{$nI0_A!aSZxAzkTZMVT2m40R+WjhfF-P-ynKIn zc(_~;oiO%*sU}ly%kIuSKHbJcx6EbF<mll#LBW&M0zoFJ0s!j+JCSd@pcqU-0@Z%v z+S{R_dpgP4%Vg2g_2|ICpRe9?=Dn(KFjrr=6}-sRC@d%#7XI!Q6~{g4&5BaT6$J7& zc+V0mkdK)ib4HGNfHccR8m;KZJ!WvX!6g!v1L=hpWh!HoaQ>{$9@A)Q#M+}hSKJXF z6H9aW8VxM8ic)t2actAKTx_WsdlGjly?6qhLc{MbSqI%aGXwQ_j&Q_~B%f<L)M3vt z1gevLDdr(xcINI}3V9q1%5m_fF<<on2fJ^xC^D$xyHHaU=Xsy8P@PQSA+#HkaY`dc zddU$ED8(3m-=r=#nIWzC!la$Hyh%OAU@*&7BVV;*-F6*1w^}TGOf_Yy#|hKSwkJvf zoE=F=ZY@CTwE+D0nzvT#K|PQnr15~pxa12{s;PI@D=UDxT3%6lDhvgRBiY;ybJRE4 zYC&gX4u0^r65a352k&FChPZxyL)TS)Tq(=3S@MdOQtFjnwl3Vb-GMO?%+J@lt+iTW zYxXc2x7(g#ezJ+4Whq_a9Y5Ir(K51i=(enkLDXLOtrli@wJ@l}nm#)-SkbC@6^xDy z4?LG<29odE@t`NxOn_o#ZwRGbf4A9A)ADSMZ%1sZq8=mT9_(&Mkof`^^RiWiA{Ws9 z5HUB)qURt{!0A%48D*2hvpRupNkVwgmxv9qEoY69jSkId=|&Ul+2#c{hKrHA02MF= zwxbY~B3Cybvg9N$EIWDk<dC4kvOW$D<q*@@n+Y%864k2n5H_ot|Gs7~Y*YDi=RVgC z*N{C6L=piQdTw#^J(-IJ#*Cxl@hc9&S9hHMZV-QW;}o#VJ5e(H%;M|^;6-GEqP|%3 zJa0$aMo`R}Ls<~Egd$D|aX@qu`#dvRE7_XplzM_je98C~B!zpG$hd7dzDE-&F31P~ zTPDWzNH1?&0$X<Up@wnVnX2jGieN4318$@b4uEOqMtL)*54wUJ6C<)~b1rl_l@>3y z+c@<50idCgq>-;rs$gyWLyRh#4lL=%#byQ1;1fAxhfhR&p{_Ru8@p;)2|R1YT#cVG z^UPK%8hcK-vM{(sjXhSR98jh?KE^9WD4`D4lgZxNO*(*07!@O`IBym>qOM384^Lil zR9tc#&o^gyG2nu?k>TTtt?85Uqy8%GiHwXGA855m9R3Kpy>v4DK9%m>K{Vi0GU|r! z;ax)+HhA!?L}Md}H$FCkyd&opm^d6S;|T|RG&xbDU==_6S0kYZBf8UZ0Xol5@58|| zxE2ZyEGZ3JFox1scHSIfPFy#S?9|?a4qwx>Z`0;XPp2ZOVGN!O4OdBpPt)vTFnWC` zR8{aDEt>EOPm{|W<8@{$i6VAwNXa*<dGMNaRUouAYmm-yOR!?j%UTGq;+Y)f1m{}H z2nQ@+jR*Qt(oENDpV9S2TXGEACW%4^6#qZ&-ZQGnb_pAORqP@*ic}S)7m?mYl-{J* zARsl;3B9NYD82Utl%5cJ4@E$FFCjqa5F&)$LQ6RD_5JoaYoEPcYoDLz4~zCZN$%&K zxn{0=<{FefQeCj{BsmxqG1ggS3Y>EfRnYuPS8saITaz(k{_$%c^^KS(6cYD^+@jhh zm0jMCPE@M|7&j7@B*;%8Nnrtd9c5U~uoovuwYa5yIA>08StP!v2iNqd=kCYCc~bq2 zHX-#s-Ob3^Y36{xfuZP^;;WuPh>OT?R5kuciV1kmMd|!0ANs(@6>TYlRCyAplvP^Z z6hD13lc*Rs<%Yv@EDbdca%9b9nFd0uEvd9Cbqz-Ln7!OKrZt6LS>(|+hBx}CEol)* zgui~a2FC_lbap1xUt+U>d}q(JFR9Gv`eW8d!zXImi{Rr!ZB!UmVVl8{_H9IWDmy;t zMfvQ^8N?Ul9a(=&adBsy3K+E2dVQ(gA3l$|XmzO5TG~Jx86j_3>o5`?Ak~NgO>9xN zJ{L}*|3v=cTfs*tNmWzffJl(Yn*?_6W4mTN{2zOGtr#OF8g^8g-S`%(tTZa|`_xMz zXOl2L4E<tT*u|a0$&MWT2G74i%^3U(V*C9u`TxXZUr1{u_pM#*j{(UzHBFoh5@cxU zmZM`Su>I9+cm`j$w7%gXz&810D8NTn=$$ZgdjB=RE97q|={1DSlS|dVi;yUL(>Uel z5p*v=iuG`7T2k}r2&v}P*IXKQIJ~%XXez;lpU(M!GLltP6Wyb5#SC$?o(e7#Mx>60 zLR+%m=c%AxsTqceBJ~kX#YmGT%26%Q*vM)zA31c!oJ5jeQ~>cC8ju<~6UhZWVqycK zQ9U?oVTF|24<a^{@`I0atT7GnsACyjSk4%8ok<e##sTRv@RLL8UwHOL;ws5^sW<eM z{!Ry;){qwC5`JFmPp)guj*>=;Wa#9$rIp~O#87rQ8*QK5Gq|2*Yc*qB-^nu^3vWIY z*bQk%FLkZU7V8ad6|S9z$me_~cZ7^r$}RhI`*k8`7xog$9PwfWhxNN^XWM-)M(bi{ z7AXiBHUDb;M3n&T^utw&BlnT%oxXPKDN6wjZ<j1LE(p(TMIfvnJwRNL^x6{wiJU<1 zogP^<AM8!cc=%w7rUs4NH9$p|bOJvYe#S=s(mj8nYP>wZ*~EjU3W8M``kZ3Uj2=+< z36BfQAisb7rRVwG^OqbZqYv2PpIJ7Qq(#s~Z2cpj{Ga!QQ|0xyCK~$_fvlF0U@;5l zK!451B|jc@m+)&DGkK+dgL5v-!SEpkFK2vG_2mQw_<sHS-0FxKQ>NHy-ZT9JUwn{8 z^vKE7*~uv53gKje*fTzHcSmzqxy*Xtk{9wy%<=U@bx2~IHA>_mD!V(EqNgr^D+V+> zxyI9=rq;-BG&Vz}Ep4)^j$8UM3y+&)8~b?xajznkv4B}mW(YCb*;k-axiZK%bRT3j zuT(0^=J&Kb9Q|Q=8d^l;6I1_2a(E|1p7HB4NU{fjUypxLg%s+D;GAy$y*2*&AoDBK zxpI@~kFc#*`YRTUa}<@X@l!b{ta$}FO{vumdN;mbDB+^_WeFpepl9m96^)TYj{YF& zum2sUNjfV42osE6EDz^6c1r4rGeYdwsog5|qR97@QQ{0c$Bj(Cpi0kB5T7#6=yPFY z-;{IBF2oFm33^i9Neg>Xh;M9&-c@g#Y$z+<=E1&_-~i@Mu{JYuz8x?+d0S=Fj5M{M zOWGNSQ{0z9h6oPU_1&ys3D(dGQqDpr_4q~bo}|UC&@D9(qLd%Cec6;|acv@r4ZmOb zl_flF{H2|_NyPsA?LD88Q0a}`7X9Dx-+%c+BYob0N?VnQOm+H6mkiReX$RuFKM--4 zeMvM47(Mb?zm8Iemt+vdopEUOnzS*$4CF27>&nWrL#tZ2JGc}`?qR1Ph_xogJH=j< z8iC!}#E&GM^Qh_V{M*;ac}Gr)>E0fHvp#L>WBrZq`VSPFH7vf8pUlQ}<RLne?`cyi z>Z}X!h1&%?+?7_Q)LuW^cXdI3bfksf@;ad2?8>UXKgLJiH)9@b1>%(hjS;JFc0o{x zCmlvlnlu>$@*h>G0)G2PlVAR^h`40)+dtOaBPDFcp^UgcN?Kaz%|Wk2rDiJBg}8QG zqWDDj2$#I}jI30U*CUiPDo59wyv}OmtNiS%OrHqU;qTXOej%6JEQ&XUn6OfNuxL|* z5o-QNr%LSZ7m`ao0Er<RCOiPLvB~dMq~LZ7zL9%eS+`<u1=4b)HYDHA)|KVH^`)Uw z-XUc-8~<TjxOR2zD%@QRRp<^?mL{A^8PsOJh<d`pdO*-v<}tE<C!4*%RLOxur9%r- z$bM;xja@?!f6jTQc*uYF;ZK*qM3lyN)oFmxP8x!B1U`5-t+o+T0e&eU;4vk@NpSSV zKWjt&Yi)u7OEmwijl_9h-WrL>cNhQ5zWAG6q5+=QGtoe9yswSwNkvp}tn|<=VdA<> zcGhIzWZv>>snDF=rS0HnqG$b9US6gxb*7Un4Mt33w^pvxJ~D~h`WpO<PFJaGBL5vR z<$ikwmGX@w7QK%kp@WL_H52Akt%T8L4ZkL{s68TTqJLqgiJc?Gn<<9~J2&JZ_#hSM zoBCQqhdN?o_&rHH|Lg21nqo$flcc2IajmYgh|;d-3iQ$&iC?_n|K}(IB!l#$HKtb! z>f1|@AHjG3j=R}ME*@ioD66|tKXGIhpnQ#6!E~oi)=-Yz0@TR0qLbN}jy!CT)W$SI zEmyi!bPpnt^Ki5Y|018(%D(;;WQq~+)&wVB<|5~5G<K)d!!!ZI&lLCL^E*#_oKDcY zlQw|YVbueMRGR04q*}xM6U!)X$&{F+^4wbPk5DsJz~9-e%&+YBr)A_n98T}Abo!sn z_dmOJk{i@Z`%Xy??H2dRo&)S29DGTT=U?0)>@ylP%yq>->=T@wW%j^J{mRMm$qY-~ zqt<{o&VOa~Kb7^$H8bhnhf_&39vB#uufAr#Sq64*^$sAEy#q8E3$f|~KxvYW6Jkf` z_NGKc?&CrmKO$OoXPhA__~2+SO1(SvWX&6TKvgH$>#fJu3pJa-3vi{GyB=J-FkNQd zbIHqvaQ&d?M?m4CXBjDHbmc7Y&cG9U_@DVrT-wYblL4G@FDk0sv_Es)v9Tzr$IsUX zTVqyu!+PQ5$D>oaE*d%~Mo}T5P{@M-l4tt>QztDB5|u~)&y+J}N)mgafYJXW6;6Xb zuP2o6ow9x$faW9>Phh^O#Nu{$vgdXUy#!*9)XWKl;WM<qC{t5DP88jFVhmZjQ5m7% zw0E%LeW4D5*p!$KP^)`xyR1q(5xbr2M^7Lm2Iar{x>V2>-NBdMup;H{Ga%YQUkkW) z{n}&RhkuEu_m%#w*6|%l68^=kuIWYoBcB~ZV)5QQwk!PelpeniFphk&14JP6Z>D!{ z_0EH67tlVd{O{|&=a6nQr@5#98}$B*9n+BXzjZnsW`|sU2S#Op_s^BaJZ_W!W^Uh% z{(?%o(X~I4ft?&AGSC3YAaLpLSNQ<@MJ*ta8T91;<jIdnB%Jb)#XnQ%e!H0e7n4tt z-PUG6_{sPDMyF11Qs{3m`%2)}@0-5<#X;r2E@%Ez1V`ePu0XAHJO*ig|5p*uulzwT zz(wG<RTzi<${$`uf&Q33kkqa<Kx+pK-2aeOI1+BY^`jno{`;nKs-(0(ORg{SKYx(l zGQ1xONz-^!|8It?rjA748JiHghJG_pPVB!t>^;e`KT4C6gr!LxCTNd}-yr>=korM% z?7qp%3%}n#jUWla!f6G?|H!kJ{VJ@`1znE#U5oPn!;QjAS`_k}5C3?+r*`N0t$JxH z{YwA1SN{6I$x9;myYc6^|FIw_<%4{0q&xTJ-#q8{&%e%=k|QbqxLNpqX<n<i(?$Hx z!pvo+ziNc=x4Hl4Q<C;<(zf86uos~HFJ}Gk#`Q00=uUr<sZPwwSNyiB|KW0)xL=;) zZS|1NpA7I{FZBO-2M<n2>u43gH1y(sz4DF9FP{)MEtmDDNARCM#D_Ifl}swZ@8$LX z`O1HLpl{Z${E!yoc04sIR!JA(17%4Qw53Rmep<O|aj|JGn!K(TXV;}ic)*(-BnjcA zjr%!wx=Of7)knff%9zpm8z}QqKGs{CNe33-J88+B7=Df?j-SshfGNZ>vkU8#c4T`x z9((VVq_1wosZ&0}=PIQH1Q@hiIP^{o&B62^@Z?2RD;KMQwK$;JZ(VFMP1`!aIU&mf zT3(t`<;FFS$fwl<2avMG0hq+jF;`wAGzjAzD*4|_gPzX(8dOlti1qx(g;;+0AnehT zn~~9PQ!IKhq0Ghre$VoCZh?hfTm|Gym<n4$up?Km$ecw{wGyhQPvLz~d;0gkE4x_4 zUSuydUo!B;&fPAV^Znd;nh>EWI3d0uHPK)OOD8tq4bN`6_TC5X2xy&S{;rpEu5m4_ z+uHlVMAg*$HDW)DC?VkGBQ0Q#^XnY+bJoH!hA@SRa1N4VbQ9}O&Qk(G3`KrO2#Q5? z2RCFhMKv39YaY*W2=)}gY8bNpv;xT7v`V$rIiEcp0sFK+%9tN{XOFV>?0okpqj*MA zz)XF3FYKSx?|UcNB{jjG+@x<Q#lH3_0=^AWi_dMA=@=(s84yBt8ah4aZ}JO_Pt+?K ze!K9<TLQM{S;o2W?Ai4(rH8k0(W-PtuY3$!Rb(%J|G1?kl27Xc(-9(8v`)*s+}Uw` zOUgdU$wA@ZduvJSaE<r8CoMKf>mu@gvKNNy&Ej4PdNSOE0w!)v=kveqxf$UMQOuMw zN+nEGGZQ=onh<ZFRR<i{lW#t(NnBD`??!5_oc(+_T}ur(EB8)-uOAmiCawP=b$Px_ zvRD3UbH#s*j^@L2wlzM-Ag=Tn-t8Kl08OTt&%WMY)zuhm6RJ%2MK)KOa&`r_ge|tZ z<B2U9+i{RAdzWm4smo4J&cTPBaL3k-%R0qFnX9xPp&8D?CbfMO{Q0!vJ}QR(LvRae zQ@d5*<5~M!FNij;5vQP55viLTCTTjDxxL&Q*uL1ke1}5l*f7k^_g3800wTxV>I<Us zobAyJ%gX7?$MT%;q61DiV4+{%@5%>%(ZOLBKc=vIvqr4Qw)is8_u(jcSGE4`Oz0VN zCOy2rVKTp;JN9^r&iu1+Zq$Y9H9M50n1s-u;-#bqBv*fDOaJ%8x^rZ~R99YH57bLv zn>?$pKWrEE37o&?+ja7}&HNc3E32pg^xXJiUPh?DjpZBp?b}KEYg#EbYr>>+4++LN zb!jl0sAy7Nv+kAgM>WQ1x>rAXnqbN_6f5n?)281D81kp&P>0b_sG+NHRw#7k<};#h zm;j+dOS(Uyu3bmd-z!+QZu)4`XVG%uhe9wm9AY6h1}eerqzDZgV6{v-Ja&zuSHD!& zH)hz9C}?ooK8>cmLkWHXTvkxfR`l8Epwq4(L&)>}0DgEEG=8Eq5?Rx4ov}I<BXCi_ zBZswIv^aa><xl(Kh}M(~>7d}I;=xFM@7p7pt8%RQhPtdUT+d|_;L^Iw@)CW6n(tVY zn`;p9k;OQ{IwEKuY?RSFw9-Yb?5avTvu~G--F_2dK7gtF{t}1hPQvw;yC?fg1UDhb zkcn_UTghkkA=1HGe%7Vc@vBVMr)u<XAq`8wU}>ok{-iuR;9-NZL(&br_w6-l&i;%{ z(ZAEN{}MKRAR|H3)d%(epy7ue&RaKqZnyy5vYzGW*%ohlhOM2p*`~Pl&>OrCK+xMx zJP8pWunlj%aj`vnw^DEEjeOo7FhT0fS+yvBMpS;4G5;Pf^q!w($Qq%qgZ63K<MKp_ zhdRQC$|NOImv^XLm$ksKXDd-q%$H+3QI8sf)BrdVP~2dW$eY1bNA7cGB%h6`%o-kX zY+Fi~Uz+qSNHyX-vNp`FEH{1p>J{=({<W>2ZIc@WIndDYiJm=0NO_eJdUL(?L}bO0 zi$mQ1Ff<)yQA?OHxFhPSG8vF1bk<>{>BwYi%(Kf>kf3>%_<hFuk!0RY1@u>8O!|;J zP76jzz>jsG-hb8Ha!l$pnk_p^-t!fBvnG3?)a%JJ;0N8GX{mIE#JwS1QKx#XW1bqM zD_ouR<>Rxco}6}IoX-s=^+5tvzvd=X<FL2^<0X1J^UB0Iws(jK6*$3V-SqOu${guS zr)_sWtL-Shm3-t`k{UljgF}^~9?8$H#w25bOv(wP{XI#ESi`o}E*0oT+W=z>Ho(Q0 zr+dF_t~jathv`~$V)Y)|!UZvZ23UHR*PWrfYF^T)-_0usL;IVO3zF_RKZMUvqF+|* z#|R<QjY<V30;Zv{E+!X-iApefDUji%aL^;vvZ4WozMw(6)@AFt2cn|UMPCh1euyYJ z=HFa?ma_W>9zPpjad%~8H%oB-^wzXIruWFutXyC`lJM?%<hp%~g(Kc3Eu7Ca0zzFq z5NjyO`$900H+{_Y=X*DzkExA>;bOI~m1^jEhzGT}>+`AxH>H7rn!OY3`^bS)`dSg^ zR0vLx=tXmusbv`8|J1i}b=l?m-uT(V!-DjMzNhnkj~k9NO(3&576+-C24&yW`kBT= z7i{vTFUyEX^N^%P%g&PKkGL>i?q6Kr|2SEC4usX)Mgr~K-nx9%o)$N?+qf}sZfyIl z8vuP->cQnI$0RLp;;b=%_4?+QiQNQH5yc*k-kg^?HYtO3d)CxC<GLl|V#y?B(m^7F z%hq&M&eDvfrZhp;_UJXK)6{TrkK*xW9dOObLW0$c=$`uYfjzpa2kpIKa>nZVc11S9 zp(pn2t&rZ0th0KPpZl3lw!P;7O&dpXQiL_tn6B!cZy0ZrAy8rI$-u#Qg8?a#*XX{3 z^>8#EckOhszPUX!a^#ZQpCowTTY#Ra(^5MN=`Zfl?W~B3?Cj5AN^~7dhg(#b^}RSr zr~BI{lv+pc6!&9J@ZHUE)~B^YMqI*8+E$X<tUAP6Y-II0dmpvK)BQ2ghS^l$08UU% zI-pP?b^lm&+>`5AwfvnoyInCr$nk4@y7;5Z>i1E9H5gJR_Qk&1#~-=|RrBJe#J*v5 zf2MwATBg)vF^Ow%SFJNk<?_nbKiG6g$d~k=hOg+eWf*XR%F{(h45WPfqJcY)rCE96 zh;ARaOf>FE;WzNm`{HPv*bK|%NOuv!nxH;*;+u4>mL0C5+oMIBQ5^ly=L}PlepDhY zfC{Z5jbx-RFrD-5s2g?PU-5|5C8(MEXOtE31qEn65j2Iy+;Q|D6gt5^Uy>^@(dBF? z7V4SL-<=*5&6YWC7q=q*0fxWl|0;?Dxw!u>e*b=Wr&A>Vc!<yTxcQv;_oa(E;_mkG zWBjz|8>%#vh+FAy`xo8S*q-wI>ZHR4%@MM#QHkBd3D?(40JHN9W&6>=YWp#Ir5d!1 zN>_T?D(V*G^6I`V>2$3IAMI43E|I4T6&B!IUGhxP4-rvfXr;-#Be@qEpgC<=u&G$@ zla_&E?l?-*V!Y#3CgPx{rS^`%jOw<4ysQFj3BoRO{P?(A*Or*@A;laXd!pC5kkTKq zauO-rGo}art`_=gy}FypHoDGMH(n#qqR%Ls+m4JjPPaR5GJ#xEv{v2SahxM>z2t2p zmoehSN5+*HhS`aSk`7NRY!0p&i1pY;Rn|gU2YMo9)h^EL$m^~&!k_0|Dh}pjEL^`K z+P-n9;qL2LJ$n-fc8em_j$CluNK}=UhNn3>gh{MmRfk>L!`6eUjh_|EPz_vZ<8Qrg zbNCL|ZY8-Y!$>P)^z{S3teSg(V@SG??DQ8H7B_CnH%sA(r=R8)2b52y6JPIRkhGt# z$G!ynR4es-+2ig>5i@l>0bm?T)Ke>GzXgIj;(Bt-EWvlvN4{edv6E{Y`74I;u=!3M z&<YH6i4bjm{jNYZo}4v1scW1U+@MX>uXGc{;vhPn7wj0us;K92OWWfk^vQ4?D9kO} zI&RpD^DU{-MVQy@W^~l(7O6@8yI3iB2A5tSSZ4RSl8%w7-^<?K?0ITawc<Ci{xu69 zjci+27?Z~S!Tf2&Pk0X<*eHntVN#btUdIHMb-AXrR7Zix9=IL{><KFhQ;wS1nDOpC zS~aZ2vS4e^HYYBW`JeEeSZ3GA(I#o1Fg=mF?^0Bw6^sg~yTIvGZHp=u;IX=Xo_RMl z)g|(2dyq71j`!wA-M}%aQh%!$=}Lv;fjzQyr$A_onMrZ52V<Ii(y8%<A4bB8Cl9b6 zBe@EW?6S1cezf7jxQ>U*m6K?9>s>k9FRMd_8O3Y~aM|z<G$Jq)S{)G|a2=ZSI&hsx zdGI370bv>KC8~#R=(ex^JX;h`M=`^dUaJkMX;LUQP(5y7+ZU7##r8}-sSX)vcm+6| zJbp+@4c_?WDV?yzA0yR2Q`1H@AX(@FCL!*&xC@*0_q`B%VuiE!4YQhklj~cJ35+9i z0a1JdAC@d5Jno#dAAZjJuN>&F+0LZ6SbjEL^0(1GEh6iEE^}-I?7(y$Y<4%7s~tYd zE7WzoYEp16Qk9lV@rr~UX6Tg8G11l)XSvX1_p`;M;~G5P-z-s^Xxo^6W}3IOMfY0# zy@dr982vWrlH$VaiQ&<;Pvx4Q4348V6S<4UK1lG+Emk*QNpDA>vu&+!&2%C;Y+V~Q zSmLDC<06?uDps>^KjIsUyS`3)!)_OyV5-YqPAt@4AXqPLHM_5PT+jt<Sqy&o)|{p4 z-Q%UzF*5^hd&C6lDK({!bM>bwRY)u{;c$=dzd~k&=H)0(gxa><Im#wQ_Tq&JQ&YFX z=tlcW&s#g(>NS)i>6TgPB<5qhR(xAUbT>r=Pw$ZpKhiYcS9ES<v`C^CpW^XzXVa0j z+^}!T;!ex19T5%feg(^Mhtj#9&V4Qn*vPC@#`0N47Mi$6ojl^XTqW353cy+Ztu>-A zxEN{gNIT;>2s$NJ3SlHq`E*&SO(!0A)R&BYGKLF@%Xd3K9{V+|M9VgbF_0nLOdNYX z(-ilGMVMR!3K53gyzUC<GZZuRKt|$EgO0EHg_^L*wj8JS^I7I^cE%#tM;F)KJ0_PN z6+jH0v<bh=<~2J_E0V7&M(y^Z6Lkt46XVtU;`}8c7rgsDnNinYbzP=i^69_2V*tdc zu_qbmU}A+!O~nAx4_*fpUM36{n@w@M)1VBQA6a?~B-#eJG^DFP-EA3^d9OvC5uJyW zuvYBCGP@Ap<<WaHKjj&D?$U56mhe5Z(hL4m9Lv}N%iB$+7heP=9v1<)6J*@S3@1Hp z5{%)uPQFI=^z*Ad=kQQUnJU7N@ydn1ZT`s7HN-cbZ86CIWyzLO-p3S+8NDs3cl`0Y z-hQkcTysSp8BQQm4{W5EDTiP%)T>_kloxzb!EYM(mj#bBC4q_eux*&$FRjBHRYNzi zgoxl>he1m@vC9fk_4yCCcz6d3PN1ne+*-Sjh6#=#82wTH(Z3d_!z|k_c)OGD)>o1A zLTI(uM@2i2=4D7i$&wH925|IV-+IJe!0#Bo9YAf5KQ1tSqoYDEg9s;#qenyG<_t-? z8{G9@6`<YbhDcP($S%j~e#ceI1M?Z_p$4PuqfaAevitLMuCE%F82#Km3DnZuMrrPs zKeTs=C2qoFKc<IGVhtannR;}A;G=IYW!;c#=i}M2^cKd485G+Ptl1_zuc-qMH2(O6 zd1viukshhVx6hA7YV)@g4g;&$X5y@*vIFnfD&i`ts-E{Jg&LK<wBwa_BPhr6*a3l9 zUaSK;wg_qNSd1VI?auQP6-(+HuH`b7BKFY@A8=OtiFNc1eJ{NGaRY_JP>GA!!|!(S z#!cW=;&A)kwgJLFJ*@98UMBNLq=SFfn&x90`!T|*vHbF;F$WHK4(YEi6a6hp@7Z0P zxgf8m9N-a>?p_X_5wsY-2bU6CJpSZ5a20y+lLF*kBRyK`jxjw!?#(q@5GxG?rfPKq ztH&s$0jK@C0T8EUA{w+2g_HQ|3fFxKVm#8Et$C3PpfNxkN3K$Q23+^wixbvqvd~sZ zPzb1|mwH#xQ#U5OS_#NA*rj)xj8>ej>BCU`=F|V9cQfWArB8a{5Qg8}&r_*ie$8Qm z-eAj`R_I7T<RFY7IlSHD&aBO@*`Ok8YIsh7@B8a#u3xztXW_N?uNg0Q`@%JJL0Tmy zLr^QD3TR5&;#Re7@O@Yk97!O<(T`WnkW1Tv)X4$yb`M${1F3(EwnhDPxx5~oeW_M} zt-R%CHyL_m@Vz~Zx<qgch*~YQcMvSsuzcx*WQ6lT6L{7iSl?2*R+YNddxg;;BVKa+ z!M;Z-QuuN<sE1``>m!%pLr{UP0)yx7EBMb9vUf_A=GYdEw*KTx#zK?x&zd;EuR-bp zTL|3?P0g|wvWx_u+F>VMavb(K*!fx{k34vh(P;*@Wy)1W0Yg`<OpMrJO#sfj2nw5@ zsH-oQ?V{f$&^_jd%}$=AWtyQKYs`#>-lM!(=O~A+xkM;eJi}h;2%K%&kO^u}zCWCv znXuf*sGV9)jarRLtKi6?W2SwrfxHGWh&nXl9^M;K^UIBlfMxq`^=9#)co9wIuhfjb zN>m?zojBnmFSmDdG+GZqzL2BkF>GilPR}#C%?DNPe!HHLQ0b!7T4L`&BXo9sUu>*Z zrfDwyHaiLm1$h{cIv1{&b(BJq0<y3e@`EvOfWT?(>(&hSA0v{&b@fUibuSl0*~O&B zd=|5eJLJJLWoY=QZBTrYor0)9%YkD8^=!%IY&4`oQK$O#>xqiSiH+7D4;t>1^&_v9 zz)r7~^h3e4F7KRWBgbmZLguI8xyKg$L1Wn3He{KvVuUN&i9uOaEOCv-C=}W)Njrs} zzl5(39r;2krNX}VpB|&)B}+Cporeyn{dFYAOrO%_Wq)z1RR);}wZJX2tPHN!0`#ZL zX%!Jl;RF$MSHkM6o*XNvj@g8_Ti31_c05Lmnf|A*mA0F1h>l^`q*2e2#OY?HYulA$ z-h1?;+vSE>UDt|(risE2oB8O^bE$74nMn%aX?DhRrvo9L0{|0P6t8ikhSIdCZ4C<6 z33F)EoE{&<I(stmr8!D&4tnJwAs*@7BRURgYnX70?SYG~^fV}ASA_prkW`d%-L{RG z(XPva@t9?=;7sM{X{mCJUByT&N#bZV>U#QnpOrw^+j($pv&Ri!Oqbz0$Wo(r8mhr) zY|%=!QhdLlzrpFJK<Rn+pAw}-GTz+0XAS*|wAxk6*`NCZBEIZqoXLLcK@}}+z9Jk; z%E43+vliE^dB&h+-eYvTuXFtt_x?KjQ=X7OVkW(x>`w^)w(-U159rxwj^Fn=g)ngq zA?rC{GgNB0b({yHx)=|W_GYRJ=$nh94h^+^;FQI1WmGBHDo8SG63XO1x_)TC)xzEG z@{O`z*CvP`FE`ab)8`a_DRa!`FC`dOvKYC$_FY?ZZp1`~v$Dv8v(o#+4U4S#JUM+< z(dVl?cDhgYIkMa9vh9m?9TRX%kmIAT(HS<cDj1B?ayqWv_wGp3(1GWFle4p)Wj~4o zE9jhN@gVNlyo50)+O~;b)%n^R(|y7eD;fY`sdYFHYZB*>WNH)4)?;~MNZ{A5T%U9y z4?|9v@kwj=M)2(Vh;uL_4J(V}T06J-4Ts#5w1&oDWun8|bNJ$_$Ijs?NUE@@%wkU5 z*^1Y?*M#$E0T(u;<y1W`gA6NsOQJkc3Gcr{_0gj)vbu}T(3W4_aY$+w!BBs)O==N- zi>Fgd5GyvZDuLQmT}rZk5;>Jz(KP&sK@$5!sz5uDiz5*XXzLKLko2!I@h>Zu?Wg#W zvqyaL?1UofsCm&1YncQ=@YZ3AD3ywR9X&K8w<jMJcxB6Nj2gutm{sa#Lc71`dDG$1 zJuk!jgE_FvDh2T&jH4XY!d|yq{l7qljgr-S6UxLZb{xMa9H%%ldZ`_Jw5n7lSL7Xw zuF$CzJ{{abU4o1J40ZwP72V<WqzCkSQSOyCs$G#w^^3c=<0|a_26ky>{YH^d!<dcF zvg>zx(R#})de=bHl>^IQw{_RT=bTSYke2+S#acm_!V8Lcf0diz*(M`DD1I0k@s4bn zHUyvbhImEl*<#Q~4j6RJ?O1hT-4T0M=OP;aGwzuFKDzbqMLJJ}^E+)fUJGRZ-1mBF zn!Ly+VAY@#;XEH8^}|PZyjZvOi~q%i+s4JKMUu}7cgKMa(5BK2_X(f9a6ooXw*Loe z7xzSZ5fat1CT4Y+jaM>1)j=ZFwM?kBc*?F~><Ur5zg8|^K=kEi;r-Lj7O3%Leu8qA z|D0B~T}<Ra!Mp+IA>-Zfb3mhJkt<CZtMu1(K4fTSA-iA^7n~snKlhiOhv?#odtxc& z@4ga0n>{bSe1Zwr{Q&k3@H-57?#;+F-uNnVf|A6(F*zenm5Q#a@~1a=X^~WGt^6#A z;ml?y|A$xnkEcbiNu2{?|2pRWu+4t!6IHMX5xA4>q6Q!Bzq0T~<~y5c=iMoy_`^3A z8*;6pbi!4WNV>r1%28{BXaIgZfvwUzC0GG|CD03PzN@?9Pgg&e``S!^ukh{0q@!u* zej&z%1(?jSF>`4g@Vb?~^xPMN^<nw9cBE+F`enCt^{Ie}xfqY@`-9knum_(O^%VB0 zLzM?o)V>gN<&XQpad_#~xDV>#2cGL=B7-sOs_p9w)8xi+oI%1#o$DBkrk8aA0}n`w z&zGctvaQme^vy^q+t)B*#!gE5-h;gecu73N!F6a;!i==(l2e+=*K(%=O)qoZ7_xK2 znLF@JFip*~$u~NgD)bc1jd30Nd8R8Pz@%C}{1Hi<@8=97nj$Dizt@LTgy|VM-V>O6 zM%OgR3<lHwC52|i9?v8-MqPTm5y=eXE;eECmVm#8rJB~92TXFOS(tPzt~R%4A!5$K z&)0SppD)-JCKm_^u08NwyIXt-K2p_GugHnF_kgaZ+IRJF#>W;^D<4sF<cv~$3!Nzw z_q`7E0bjk{)l{mW<iMK*4OJr7Of#Zgs{PxThL=l|kX@_CJMnZ^+dBtyWoB{q)ptL( z$js^^x?-k)aKq5{)>K9wkpvn75s@n^v~p@?YbAAA;=xISQ5;>flZE<$RyjPfr=z*v zmMfiDe{&h~W}{M91>fl0vu9Sxd527A+9)fH(tSOb_JdzJcXREgZnQv83T?+vN%BN> z2xstYz}c(1D*M=<tabaJ2Ft3YagI(V*OtSU8Wpe1=g^MG)>EfElc!CZzPmO_b2gTi zVq6TVt9I1KI+v8oK-w-Z?G<Rb<mSougK=>b19-*Wo5A8ZGQ$0E*ql7o{Q5BgYl<!$ z2;Bc@FN#a)pP_j4!bs&=1Pu}b>H@m%tK0;)jjiRO3_Lg;o~$uS=cgVcR0bp8+|V~t z!23fjo?$VA5?CS2eCZ3;>OBQN@2?!qrSJJ|ecd~9jj3GDsQ^|3c-7Ddb=!9V&u-P& z%^J*3JR+$UW4smp;+!JK(HN#boZ9|dTOy71d70#vYg*h$qrO?T41d}OKj3yLhJyUU ztfEhrE-P!2;d-y7>hzFEZuVv&g0-BE2>+)$_7ji#z-o#zux}Q9@t^4@a?N@H_R23X z3QgpInzk#?JD2PX5M}MN;G?&L`@I)OB%<yCH9(41GCG@7EnR7=G2A#0n|*CR&vn$C z%E=7FuzO3v`PBNzlgOs}eKC@HgnRdg{ykiLuQ6NLCND^L3<~F#wu|YXc@X{60ZF*q zDCu#k0@GDkFOe>fvRq|vz-*nfw|%)>?60(Nwu^B24xQ3{DnG{4WMsHEHV^j3IbkdB z7SXPFZk@2V(Oj2OcIE_bz7OAyR{V?Yw|R&w5$Vn{P2AVs#km5u*u8F_Fch0KZ-2sr ztpwK(9$c}7NZTf%C_XOIy(^e2kG)Lyb{p(<2PefM9^mqTP^!Wcb8H!w(@UP|&R`$2 z90>L=5g-4y%T--tn8;hecYgGXa!qlB#a{ZFdWFl*SgsYEwJ=Jif47J*&=W@5SZ#y3 zxvDm%b?$@0V>d&*e|nXcy@rxpAqhQX-CrTyeKb4ca)5L#ItkMzX-GLj)lFQz8uec) zB<Pr|__n%*wj_<4BTb2*89^g_kjm3`6;?SmJ^((FUOBXVH!~_$wyW8?{hDotAp!M3 zl9W<b3{3A4ZiT13@x8ct@!{TJk!Hlo!x?3<rU;BIT5Y!l0U*aqsFjPV+Ts;(2PVTq zxS(<^-uo5eG<waIJoS;Y@?V|r6jHzIF>pNWZ`Z%EDYg&0nlro=5kxY-Kq(=;E0ed0 z64NK_fl#@U5$TLRaJJWsYrT$p!=%~SIBVad<AY8#<p}Uh4nLXUgV!|Jf3DeUT+Kwm zfvoeh*40+^l4w6vJ@PsZoWJ{r-F$e1RH)z|T=TCJ<d){jJu~R2rc6opOWi^PuH}gC zK&9XUSoDNZILNN8nF_J+hV7HN_IM9mpAE)%hum$W>H^q{a({SBBV{%-liadQiPH;1 zo3Q)>y@zsw98w<CYlN3VKxvrO3Gac`u&bOaJ&JKGU9aFYdcN3cO>fyls_$QOWM#s2 z%AU@<qx#EeTP6z4*f>WE)=M~I{PL?!X4hxjrwv((Gqsf*xyM%Xk2GCyB+<#4fH7zq z?bH3q^>>{F;oNGo0HgkNQEroI6PF@s`bQiAZxcpU`5h1pxVWE2d6>Nv{^5N<)Lt5; z5i(QFQP9Kz8yCn?sQYAswOin^jgA2#_a(Ysf5A}375A_qqCtnR^s8p7u(+SyB@H<- z#*ai*!FD0VFw2-nKUT|W2zFH+XA<*@bxyDA@OO170I4!cI1{*n@o`>`rbLd$jw45m zG-T?@+3AJ6$y^lAnf_&%80_l<*m=9h<_TK@AEANTlo9ABTFiBkkWH&s$S%ugd8gjB zHrgJQ6mLF8?gHJ?f#Ogo=aT`N<x+~eC3^<mya6{w)Cu+l@~)*zPNAUz40th$xRK8j zVAxO6#guFyOdik07y(#etD1T*_LJV-47>Gzv;dw(4!M>|^B)UZM_W*+w3=}ToV3Sf zMloydBIODi*$)RZc=zB_Wp*iv(7)zBDX!+m$!%!Yp7h`O@@W#XLSORyAYcHtWWWP! z1W@nn8QvRtgKkgycF+?Ywy!3K1=aoa<`|zQKU(yFo`$_>$SGilyARHSX9{>-RX=Gd znXtnvtTfHU7`-o!o<@l|PMbw?oUCUDoHmYmv2S||oDva3MPxudZB<c}7=ofdk7QMg zY^oYa8ifCBP`gqffY<H){mmyjOM+E=u{fmDz~WPPmB24_m}KysYN@W6mV$pY<!uu% z3yM44%W(Hj;hIaA7diGTm49qzMSGM0O1M$}`A&KBSdkEt9&BGaGwLiOp4uyA&j(Bh zg=M?gL2heO9FOl^ITk<ls>6p|gXR`KU)>ml^ne~!=Pr$>2$9E#VL$IXzvMJdQss{M z*7As*izfzGhwr9Bcpq3#7iC7(ueOrF^XB3oSPKi4_nE6SxTmRMe|KPh*S~wE<(};e z!9e<GrW;Dmz$Kd=7I^5Y_8OOuQ^IK86}$GCVLKCP5C_QcT&LXG80LbZnPZ%r{yDXV zzP*;(M+no^QR=R0w*&NCkWu&+j5<{zQe?l!p`qcx7Dv@K<83$%0**K!URY#%HeP~4 zHR+GuyD>^WVFHR@>*36KTNX2?Y&?0TD|;GJ8V*W_H4@*~m&wT5=^`GhF9(2vw5Q*0 zFxR>m^k07MwFs6<NzRh#T*1UTQZ+{4yJD72T(-isz+*R4bbmZKMkg;VQFT^`D+`+6 zlQ3s`Wx07~lbBy#6QJx3{BmGIm$M#z$+Va|b|<Z0*&6@;umf{B%r(1y!D>aq>|*~; zwm&E^zE+&(7tDBk=1b&xYkz6(R72mXQ*q$q?!yr$^<kDZ;g3cijhfq!%Aita5+Ea) zdW(ZH0OHgF>Cw|vZ`kT(wW%LQODO(2hzu}!Jg^GKtc#TG8_IrD1iDo##?c+ZPIov` z&O$;6s3&+}<!B1~oh0hIrDPqjunSlv?KO*J$82=t_{%Ott#)@_s<Rt8O(W=~dlh}W zzxWz7f$MD3($HUkqx6fY=2K8={LI@bHkP4QlJ0r5E2piqBOLtgVpSL+$~n?gt^Y)( zb6V6x^P*U#W}fc3^^y)(mxR7Ito`L~evW>Vl>snatIAj}QO#XpSkCb!Ylhv~4;yNt z`%NTftw@6-FDMX7tTiusBPkp?kappww`&HaKA={KW16FK89LNJ8Uy&r^_wA&plDu* z7vS=_VW+>IUI9O8+#Kj?wL!IrkF0k{(Bf+Qn~p8WltrGAdUdc>$}o`cRmzIHsAr}p zSoP3a^FxA1R>cwF7UX)bU)AQj*eVB3e+DiK$VtJAkYy|}S*TrR6@TYre`_NkL7D3q z);qA60L$TMt0|9~zR_hj?$_3RJQ$_D_bvvDYGQL|uxKbMt}4b6h6_=~CzFZa0t&aR z%01S1i@FZ_ha)<EFiq6V1Ik@vRa_&wGYq*weJ>i6o=Dftyi0PWUUZpeQjObLn0ieC zT~0&+-%B6zMWR}G2)BE}4x;qafw;B|`*>YkYGG8F7iYG=oTr0OhcEmfPdF+&0~-ss zaIF04A%H_9ff!&&oPH?B&T&>ax8d|8B%)%okZI~=FvBA?<lO^@qs#v(Bl_oea<57D z$!1>8`5QIcv!35Ftof8_$ELr)mRg-##o@?<>`t3cYqxX4_|O_VJBC5@*UJZB!?x~9 zp-&-9YCGsRpN`z7vz6SA0kcEYmN=l=zLa#nUC>|EzYY$7A-4+vJMp9U(jLAx+1%PS z6detnwR!py7B`lLR9yFn2ndf3XDBflW5cWPNulz<w9EF+t@Ua-<Bt%b8GZ;`@}i<K zyHKlMb%9%xds8xbB&P15YshF<sJ42!FQZmlcZx|j@wZ@hYq+k)KJV^LV4E)MoNmKA z_~_#bcA{>%071Y`c$7kAg_FNzf#KDcU<)erd@`fgwzzn9PhoG0DR%^?-CDQf*bXxT zMHd0LF6o?>WBAJ1?8O@;bfpa1@^Sz_-E8yGEwX_^$y^_48`VRDlKMzWa_|`IC$*^c zDYnaX)6p?>OE>T5(coOZng}^KxPC0~(kZJmOI*XZy6M&k*6zFwxfI^;R15PBsVTni zC;gJ;Zs^->;Y20HniZF~Xm3%QjLUW<$BLqO*#-=Pl9qb2YHgnKTOVDHs2xKXr8Ydy z;%vIWpG)l0*ecBx=>@U&v~(jVsY1)};Io+8ZvW>kFMxng0T-B(@r2NkR;iT7pEwd? z5IA<xk7~om=Sw*)*USc4SkCi~gPk|;#Ek}_tvHX*W0W^rHknf|bcbsc_S0)ED=e1z zq?>r2`H%9X`43v@eXD}n8YV=!5<xvr2XJoZG?@z%H422TG+NFS?a*8J_}dJLM{k*) z84J&-6=vG|#_x@q&NflegoS6GN$s_EiIr8-uC4yCD-mOI96cHr4U6F0{e3j<1L3Ln zDV5lM?-hJsx@B<r$hDA9_mba$boM-;m>6b^FFs2@@{-WkK-vJ+3>pfHC_*?+ZsPVy zp2x3m$Z63|cxt@Jb>?h#2K>HD2kEtV1{zirRunr|_V8Sb)pxS<EHq>n4en4qvAcJV z&?+v%8yU{aadQzj_wnS}V({n2-Z`;3q0FCTSMS`q^jP8j1GCqU#2?>^jm|0GkKH({ zt#s4#5Hrfr`l^+&pr|(s6~m|RisEOWAy{-%Dj2bB@5`{_vW_eBf6}2|y;!>I%k8|j zrPvf7UT#yjb->gih+mp*6$Ye@S}BSR1SCrj0JQ?B2WVzVJ!@`}fOKe_hi^Jtiq>{I z8{tCQy$mpf*vV|#S1<B)ctDvw-+TMwP^zDQr_R02#<N1z6(3V~26Y)^OHTO++y}wf zu5;(X>?k(*2xS^myaVy(*6rF@v%sNP=s>{5ZvB)OEfer6e}x-BHo&GU#gWYWzs{W} zyK?Kn^MCth?aetEB*Tq&_`m;{IeD>)hHd=DpjDs@dm}&2ry$jgXD-qGnUh<(=W&I| z!u#8$-t)|SC&3fjDi5<$gI<+$7@OGHfv!3%UFH)D8tTVU$>D5on7rUESQ$sDh1qtf ze12F!wQ7Oyk2Jtjy?{<QD8Jy#p#+p`v>z_2MJ-ZDvt7z7-UT?}nasx|ukSn@x>qZS zUBtRwpIPo0-!6arI4+=&hXt~=EJEzOkX7a7+>7wjo!Yk1m41q#gh?i9gO#Hqz1COw z2&y63#SZ}t>JkF14vo7*FW5LFQ(gpH1DxFHE6^Wn9$kFBTL~<$h0t^~IJ^j_xmW7F z&F|dNS8m>1=DTHaIAq;X>(jTHADtL9#R7IxQn@e9vO3ZW@O20DHhMX5agvGWWjn2Z z@u40O1XEI!-?p~kfpdxCR~>)Yhlw?f`z^kA^6HRP$E9sbpG*kuQIcC&Oxli^xA@!U zP*X;hE^H?OOm1+3s%8(X`**)S_DtL#ef_Wqw@A17@JzuL`J?dK`if%)V@P<BI&kM@ zZ|(lF=U$F)J-5$(a@Ih&tC|QKp^B^MWD>vl<;7gJ`{7|Su_|uiyQH1PwuP(ta)j&k z1ZD9H<2jTTyB%wLBDO9>nl#su-ejZvTsnegG~VLqfupTp|608SG5)T_LbJs;_w|-! z*ORqmM5dE*?(^jitq0{5v<_Cj3yK|WpWGNbCXw5{fgbVc)CPa8OK$(ftkm<SqbE?- z89TY`d{&-fExHXfyF~r6GY7NfdgJPh6^Xh+4Z$jh(H|nVN>J^|0R3=rH<fp61)b@Y zw0@q@A6`?pV~U<`cTSgE99#fnj}8j`{9l?x&Azi&3)tOu9?WkpCFWe*4xtktC?8^f z>JOlz;l<HLdjpjyukmtfv#F$2+Rls&h)A{HjPNARi}K+Ty%?}QrK`3m;LKP$N|oX3 z;eyo8u1W$oueuJnd|$a^ecLfLzUWRRpL<IUO_dqCBLSSnKSC_q@<aLWG=Po_?%e5> z2Ba17QRDR+s+18e?aRfKm_k!U<jknNJ6DF({`i!b#4f7hrZA{T)?IQf-*5uc025+? zxLc(Qn5k@t)G{-$Mo|@YOq7U6_QYCPmPb)8r%v1BPLQdw99Sc%r~x$F_n9G(?Hj2+ zpJ7}6g+p0<=vXCh`>FIy;tXm>W^ir4a)s7KrY`ucPM>ly^8}yYatdo(^4`qx5+UGo ziU-xK(a3e>nYi*rYpo88bqiDnrSQ8`c}jz(S|jz`9HjI}Sa6iIRBnT_dAK5Sh&mUz zw&oULqFY0xnmrSXgbfSwxW!D{uQq($-Cmn?^HsT@)}I|5Xg=jXv?w}c02W@anB5Zb zKVIQmnHw5PE#ehE^Qdbq<RTN%vN>M3m&!w6{#4h%+7`|q8PPC&LJW%<h(bFwGE-5{ zbd=+R*sXJ*J(rh(J&w4Vx_Z;cfv4EydyRm7-`-kF-CkuRa<{tQHIr0mwphCboib4e z#zB$;)`f?ebni*YXLlbkZI+h#twf%x{hM$4m$%x>B{fkv+D%gb_F*M4->EKKq^tbt zo5}or=!yRDk#BbKmBt;P@*UHwMmtU@)5{%S0s>@IR(2@yM|y6$?!8sJ2^SE$_my=N zwFHZebxIw~P{SOiCMUQmr2U%FNKxKu#Pq?Wtb%=(o}0we<(hIW!A@UfgS<5$1zNbw z330D~6W6p9_%Lvj=nu`+ztP~Z+LmR}{tDYxQ<s}eAZR~yRpw=qV&{<vFywioJ!O&f z)UMht*#tV8t1Ibm>2<$DcI6n5+|qlLuj>4ArBNBw72Dx+SlRJir5Xi-P_%715ih2B z*BkBj_ubP)?3AS#i5!TVLUa%fB7U#jN6M?)D5W!uuDtY+n#ELC2vO%$cA-*%N(t|a z6%yWy%eI&RjK-7Wp#^H<CHi0ogWl5_{NhmTEk||xP#HLv$PwXQ`qaY1-O2mTME1pR zD_s-L6P3H(la@&xEIHRoMs7~qyh7BoT=$_0go4$>Bd$yNyYq|_e@3kMb~Qfo=dW(Q ztQK~CAhjYzZz+SrWHEBk%oYY09n*Y&ny#HAq=&A29IjKB2Jz=@xb$|Q*!QiKv6n27 zv)aeoZ=+OO=jfDzy2;(oXaLv$*BjJdwq1H9Np8Lim!%oCXuI#DgvfLdXU?)kc23(O zy!U%q{MQqJuU3w8{B@<0p*u6$`Q3;w{<{<&!Fy%vMVlsR4&%<MN~rdpVINB>(@oF9 zrNb4^LUd8p3c-$UV9~)O;hp=*g%7dT-lvs^j7EmYst#%@#<d+l<I19QOB{Q?p?(^p zpU`}@4p59k=b8U3Uv20d_`_h)=G8X#cz|$jg7&v{-}=LDw<eEkrVt+m`NOK7TGa7N z<6St;+|1T;CpP!UG$aqdy*qN^d99NOvNGOAa~m@&O)|xEcw~6}n2UX5-xZfer{_(b z2Erup1?(nGh_LDCOY`fQNk(vkg)xPFr`lj2-6Ao(E*V-mcvJ5`qBF??GCj!1bbLC7 z0KdWegX)!d-32<2$%}l8pLsy4!b2QqPV!Ilw*>bj<@!@0UkuI!IhT1SMKDi2wV_I$ z%X=bh7c;%<;EHB&&QLS>J^CZhYmshEpzw!&I>$jw5)I1H&duwnjtD%@=Un40X4s8X zie2&<A9Iy)KeOIGj?{yv2dvAz;RYU(w7|N{a_)4DT56EntZFnfel&EBNuS=fGy0j| z@NsZ>#-_{2S?@bnlI%8Yz_<Q+m>}3TjWT8MxCb*#T=UvHv@PH;JXV_hrWiVuPHYad zFyBEhC2O6$YaE#cd53c^-_zP!+Q1d7`?={h;?{D7+QX%JtW+|F+n)I}3V3QIwFFQn z1fLC~OiU9SH^lT<1$4UW+59j*@*ZGu^>Z`!;*4Tr)ghqOar?!OHN+(0-0spNj-1L1 zBTClDrDO8QF9mgLq(SXEJ5|ev8|fCPV$%)ZdVaRip)(eLTknI7nqxf=H|_j&&k2Wu zx-GPNxTP@h8}q5w4X9PIt;sX#q7xmch;e=<YKVvMY<bJpc`S_;RBj(}By5@ldr<e< zxYA5T#plF;&vtVIR?4yg@v=`^4QcaV4UP)anmJgekuJ+teFpI|(Y;!Q=1Uh;>R*h? zU>u3sI1SwuRG(o$%|t_wDPb(s9*_;-NOGjOg`CPnaR;Yd7w2vh&tWUC`7&YPC2-!i zaQfu%u(S5)mcc=25Pl#u#iKVWfq|0jI-;|EKUh2AaJ<lPJ<$;itpAb;stRjojg^Il zP6W1YUC8?pexJ2{%l!62S@F4}QX%eCY7}v~N`Jg&2-^Nr`|3{NN{5@cd^M(Ct$B=7 z>y4yIqH+^N66e)t>KF#I&RK1EHE?f6LOh7{6T*Ix<0>@Km)zGsnC{HjYk+s58@-$0 z)S=e!pdT{Tvnh`*^ADQ0WRxD@P^FH<O!}|T_eHj8n|O9N!};(Zf^4&Z8iKG$37ouM z$7yVLSM9VVWw^T7W5)WGNaN3b=GTB3kf2Is=uda!Jf+Bt$c}3k91ZBD%BDO#%w8f& z`DA6sXXLIkA<BQ`HKu&A)*r-2%wFMhcZM1RZbakhsHy$A&g3ukFs4)L%?dP?KlA)L z|8twQ{V<uj+A<)U@141^Tk{G7sz#L|%0hE%AFYR#B}g8}AA&@vk9$lqhDrGnTcIiS zVx-iQ+>EDE)S7*OMyGy3=RUA)#7RUXzqB`iUR$Cm>|`~+N|Gx`fwwbAVOJd<j`k<+ zCZD{+T4(STOzw!XhL11RQp0=94=Pc)964b7YtwsMQjFWZ>A1zZVY`YTYE;gE?ua@A zU3u}wsq9yC4Z*hJYCmJ!w&iJ0`>BJ$mWZ>@-ySlI<bf$W?r~IE$=Yzc+Cz?7qZX<0 z%hE|VlmiZ(WR6=e3;$Oq;&T2YG@*R#?mqy^e9<t?d_tMGeU-~qNBpr|I4xr!;-Zwh z3LakS(zRd%XS%(Q)04*y&hr&M4ydk`LUEZ=aT)@%8ZBQH&f32WpRmAv1l9T_etLUT zZ1J0j>x<P2TU9QjDgo=K*=8?q%uW$wQQa72i?+J4{AqhU4WEm?yi*=~1ki6aTX0o) zQvP6S7=+96f9~f}6!nliFv}sX-zyEty}z<Q(Sx&a@+PpDHi{P7`#D^ur+}++S~wpY zuHR;7ukqG7HpIR?P^u9WEDFzw;QS`Ypp4k$dlW2qkK((V8ka#v{Rr)5>Gn}{+Q0%S zgMBGxeK6_c*}*rsTfc)#Vc?&zS7-&S9I_oCUBlMc3~SlIObGHX`?le-2Q+c*)hWym zsvVRq{KOiEZ&U5>%MSCEuSo3x%ftdCa#O}A80Z6q{hmA6MH}sVy00~j*NEXKxgn-T zl^uQc`GVjcUbq6*%CFGIn2Gs-v3z^~olo((pbh1yz%|3CVhpG>gRi5|XW0F!C?G#1 zC~u?jn9jN5+u9)mqcy<y|7!2c<Dp#t{!eurrz9<+vgK4{PuUrhB&Q_GOwwRPvW|(# zZf3%_C|jE)Vnntf62>yjI48>~WF0b=sTsS5tiv!f&#mA0oL8r#^YHugd6hr%a^3fJ zf9}tAectcuy6%g6>S?vo<P`;Yq560i!m`}W%?%xy4aenwF!UO}I1Vp}K`v|LmQjIe zcjOZ=7v}KC%?=r#7}W!%A3)DwJQ(m9_Rn#lN%3_HFoTu58%_U;`Z%9L@H)K()|pw7 zC(+4Fd;r#mwW}jI70-_1!%$8Z67$oH=cCk0ExzB1=B!$e9<2LVm4V8Q=YNsYx4Tmo zWqPx4Y2=1Y|9~Swy;BkXINxw|#&o{h)h|Frj-*i~s|>6Jyzg_&J)$ehR4{XPs*RQK zk>h@&v_uL0oVNL|3hwW}1e0X;XH&Z_Hv0W}#pB~HzbZlTAe5LqW#hr)cB0#_3%(;5 zxjzw&M<admsn_BQPSOZfkXcGH)Gu%w{^E@zItRYSvR^#pg#_U6J;7OW|3$raS(|^( zVX6g4?D8}Ex$GzR+M{`=;f5G=-Z|+0c+gR>h~{w8S#1`>lim+&4U#3FH20QOxjFHt zc&i}i0Mp~<C0&P^;r|8J<_5uai#a;)^Q^tA3oTT_i)6`1Nw-NM8!LV>@7tKa0anO$ zqqC7VI|R0DpyU}aG3|6Z>n!yyL6>*PO|nuszijl5dxt7BRJ8ut?PRdbfqy{tFJ8|) z8YqahU8#Tm$%k;f{g~<uc_K2l<Q1dL_lcy#xX=8}S>PiHMts(r2q8o{4<Z|%KrEIs z0xi{#gvLY_Wt!d5N0nQ1ovpF2DlhGNMNjZGjR|EpR+rklRQ~51bOG?dR6J0S<hqud z#(n#me-!fO+5pY)#%lb|dhUS&HiVY+%9#A4yKh@Q`w5_#!MwSX>$yiB5DtIY<Kdxi z_xlfPK+Xa7_v#GzWj*)A0>VL+N?-5%M|Xc(@}CrqyzKt$%i3<B9qYIUe+Cc^AJ=pB zUmW-!Pm0~O9rFB1Ny<MOR`LEnuYn!{go8F9UjEB9UpEE6+59v9;@it+UpK7IP<_@+ zFn%W>9DY#4>RUtHD)v4;2zaW3({tJN+yh+^j^dT1_%G6Y-IV(G;dM<O@jZ+_r-JWc zwBoqm!)PU;d=I0QM3w!0G+GIX@1qeg-XH%y8hs9l??oL@a(pl9R!YI|Mcqo-Z2lb^ zt(1@d7qQVJ2}l)>yF`rinjUyv&ZIL4{#W_`!;r?NXh}U0dduInsmrkI)kmH8oa&`u z)}~4RexXV!Kkz5a$jr^=P5MF$dhb{HrFtGM`Nv!7FBw919Dqipua9H5E=n18=K%k^ z(|CK{*Q@BpSew}ZKUKJuZdac3^xGZ(^~~yMw%$Dnn8z2WZdNJyWhfr)mUwDC5PrY8 z3xLPZM2yFLMhM?V#(#p)&jE30g)Dg4l6iU+Ao#6*vWo!?WYo?XujihffN=6w&g}=+ z1oQr1&ydRi9&e+w|BbTxx;w}nK)6`NVwZK11xf%Ock$$`i!3+^2zN$=s<tk&Km@?! z#bw+tZSeIQd~G@CFMx1|1Q3Z|xX9PneBBg$MgYL$m#wj1H++r3zc692{0>042e&j# z*8}`B_yDp%DIdI^dt!eEgnNA=N#<Xq`MN2!ZH0>$>5}@o;fpu;x+(R{3g>q9sp-RS zx$-LH(DyJ}QRDx`FltdSphz_ZX?avE<y`voaoX7hk-Jl;{iA8{h7u02sw1$*rCxmd zWD@2Qa)L@)dx!=nAADhBKp7U%tOH}0=KTg<JL<YDRP^oUlM&a_BXRHVvZu8Q66v#z zYv*wxQPn<tQ1EpMr_k=aL&vPt_L8~KG&p&~easDdNvUy1$2;XMpWe+*-E*g2PD(3r zu_;D6-|-C8tRa)JUgzI}zK(@&he-=R-<xfCuKin-=U|iBNiw%Y)vjeiE;Vsu&Mj-# zxcW#%oU3kp`(UA9y`heCVrO3Xqsvi3XF-SGVqTHZpNfxOU3={B-*s3wn;pz6153h+ z<!?d4jL6jB?)*0Lga6<Wl8%x>i09+!jtB?wm#ljWEUcEicEvh!GWvY#$JDWoW}2ju z7&VP_<!Z6hUW#Hu;+e3{j*e%3_R=q0lZ>_N4Fh3nn#vJejvKwx#B3yDI97GnDv975 zdHM9pGm?}!hTC3vjQo1<#{ipD7s`WPectel>>QiKytnpTlO1_{(STwG93P%^85e@T z#m<>%Pjswx^miv4qPF0#Mf(PQ7<lt!bAa?WWLYJ<2iVvxh2WXY^I&&Kan{nT1WWE| zcM1<5*rP|7@pJaDPSnkxSfF><f=AXVYPSJ}0roag{`JyUeCM;vY0Ob_qOf^mNG`$O zy?M%fE53g*!zEUG*X)UJ``Xv<F<bFj13m)yApyM4Pf&yt-!*^X(1spAy&FG5$%@(3 zai=PYH4o*%TQ&oAAZTJ&(E$_tPC>C)qS>9sphJ}3ElE8?_jB`LLsKmsWoo|GeT%Uc z@;Bs1Zm-=~BZ%PXP<(u^c#fTOhmgc$q8Z;Yf!!zD(d<5rm>{F>>FBT_sEJp7s}vtJ zaOp|u+DAll)s=b=SvkNe|IyxN3tr@5POV)Uvlt@*_r_sV4*D)0jI$2$Z_qc*jUVXc zE>J8Ke2$L%IfM4KN>?cjMr>9@=S?p?BD=@1Z=Ww;N_^DVNbns&$IUj*y?l(JwrgG3 z_Y%%7eN|tSK1?iP;rz3(y041LJzYFF6YMdUs=%5av9+g^|Gv?}f~m_r=K1&#e0f{E z)#ldXWQ9W&p%Xnx@ilL5HG9~AH?hJE0w*Lk`Su{jZQ;RFlg>EXK5U>{9+v&vC7iWu zSWJwxp~CpPN5F@9gC^Kr?d?_TkfKGDk8mJcM<G5UPfX{iLPhu98AZ$>y6unJi-Dd* zgkO!AtEC5t%%<)sBdKBnn|}}D8Ey-IdVm#)(Y4d70+B5{xYVxtF~V-ox($M@ZF-6m z0fi-9T`1HH!nW$5?+<-*$Phew>UaCbRRVGK@dHSJ;B0mwa7IaKu;2kNR_uc3G_1Zp zD_XqL+ol8&o+YBU7tSe#F`Co2MHqyR5%QBQ2l-Bs<@1-S_3yv@t+jGCLu)Ru83M`F zwmh#+&o9`FzbI_$v}OTP0i~#9C!Vq2CZ4!rmjo9`c^lqpGi5fgVw}l*NLx-^=s0gk zK(Lh>7`dYTyEUWsCTDoHm-+NA1O$?Fy|H0YQ8Y3Nvh^&rNhJd~FCADIW<VaIn4s!g zZQ!DiKEkH{+%?z4)e6Qd`LvK1<NzcV;5@#Ch1u~f1{6ZvLeH`BG*!`X)6`o_w{Q2^ ze+=JHe$(-O`DhNgwgaaa!?g<05Wo{MoY)!I+V_LE1zY3hMb$T@!4bUPN}Uh_6VcjF z-G@+T%8gJ}TwVExd|IcLuZ0va#V)5;DRCMqm|b8_t|{*V54L4GbE-INsyO5JqQ<5+ z^lLv&3aJI&qcPvrpEy?{Z7SDPfW3m@XG&?}diFv<gFH~*Xh{w?BBkn6kZQKhuo&{( zF5h*46n5H5){C$(S3ji8uMyeUH!On_I4tro{Z?4fekbL}<(wW_vf~LS^AbmB&};<u z4u3!|FMMHw*9Vr_`lc;;lyJq{dT!B}o+bB`x;!0PNKlOm9Jr$DY;LNig4O8Ezx+7R ziU-;jb^A(a`y{iqzip3c11@IHt!tQoQaRjMfPIx~UwS1yjew<Mg*c^}1>tiIxbV!9 z9BAn<|JELrv9PFcuAESkP@WIFxHSJXT3>X$>#8789}cG9%NEnqV&>1x)y^}Y=UNb* z95`d%Vsn<@>6UD<qle>jl}P$DPgt=ANq9W2YP+0BPX?JQxKxvRx*!5Z)2v8O8<V32 zx~5P0^ufEPhJ4B->J3qhm%ZDDgBVJSg^TMzqO;nc^V%#CB3BF=yB!TEa^qtwz82wU zjgqt-Jr>P}1@ZaODnTDUlzCflO!baj!#yteIq?Brb&0w}j}StH$7KlBkzR$>Kg<<N z<5gtYb1D-3`ZhnL4{W-9imbkamPC}Nc2@0C5LG!7(Jg6=yY5%%i36owInHx-b-A0B zg4MuyF3pUVC+?ZW-#Kq-+2crJj@yREs#M(z<Tka-)ZR}ItE=8{|3t1Eqo7%D2YIpm zWpP)Z{U4-)J5)@vEmKLQ{*94YR@G2Fs#o980=J_nrw=ztlJyAE;DdxoZYNHb8}GZA zg?#3taDnKqXVIp2m-&(_d6s!C!-si@IX&K<nAjAfF82afMAP@=o?og>xZ>>+>4J$6 zn9==Mldx3Sb<&24nlXuRp!!-!>H48fShSZq+8NvlZs%T?AHU=sRv9_IEQ^lAg@NKN zpwSrlN0YDJtMI!`fn&3;&dB43fD^;q(^!NO4g+6Msl3hfN^_9;T)!}+?^r&2plnZk zTfAwrzPLrcYt*=kw%#`JN3oiwrH&?aQ(Dmei+Vi2My+9l=ZDP>_9yev+|g*<cvoFA zwoE~JdGL2(Esz@DIe}*POZTbzdnbAIzBM${eg#oArnALDh6@v4Hs@Pfd#JRt?#206 z7L{s!)P3nw<>cC&NsNiL9>P5at)b658?^Y490Bu+wc{URUA#sVbW4e>%Q(Qet5PM+ z2jky;>Y`UE2HLxjHR##9*&$sT^h5w}dtV-Z@l$7SnOav;sw-csx6zubngFZR<<v2w zV<_6P?aJ7P^fTMk)5?-H1M4X#A3bQ+(zXY;^fA=aZLAoS0dl*`5=%_;Z;B}NcvrK) z5EW|XQ?l5p=21SMvar1TVG0)?9l<Huk`)nO(*`oGOL(x~b*90DQDcJLJ8W~^qmuXH zDeM_$nj1)O<he&m8}bit%u-U|?vvvF5y<!$TBP$ViQL3tA{l9cr;Ow~_E`~GDXjUj z>t6V{it--nA<x%*zBN+y6B1S$gi4=rhrVMR2AIcK&??5DlD+lg1@M^R*AgUBM!lH{ zP?PpxE8GKyk1wBEvpRmBm0PKA3V>}miitWeu3Vi^_)t`k(rg5EYeUadW_9fX$6zL* z_y)!UGS8~_(g?w@>IM4saC1zN(BYp>Sqyee_KVR1t~4)jownWaJoKT%nn)n{`8%3a ze(L>wVcH^;o`vkmb?|Ma?wpad5#i0aqdsEaOR6$kZtuB}mzrp+&Y~tUa9q8EY>Ha# zm3nazTA<1F;r`Bo7%*trYq@!5+@Ux4fCKf)Aq4DVttNQp`f?`LA`i4o@uU&w<p_6& z2Hoh<Vez$w<8F+EsaK3Shr2VsZs^I9yt^ykdhe#6ifgEMK*fOvOJJpsebf~g>7pqj z$L8fA_f4zvZC@U}mgT8mb?x|Befz88WTX?eJ2g>MB|1kgyCS`-^aigfH-3=4)b5CE zy8V7VYBgBNeo~8*!WM{_3h4tVmbzR*B4YB7r5t4Po_I-{yzB~j44Sj4(Af@MtXXQz zsZP9vn+S^%-;LCBbr*lvvbQF3uz|i%0FFDQsfYR0oo_%9O|cfoE&s-t^3&i7mP|#N zWYs(}xD{(nmf_9`2-OMN43!|QIprLCcf<#E6OlSG(%g+%<hUrDH=wGTA<gqcG2WED z&lMVG!Q6THP4=C)3hw^C)xIBrjgG*OHA-{|>3w6vDR**ce%TR>0bg-3OL2G}fhyb; z#EhAeYVc9W?TZ!UugeqIb{LWv<@aG~m|+7B$TY$7lU+_&`@eay=Td_G3|-V=Y|zSx zB0(f&EFn)DP~4YNkmTn_w)n2O5W0CBzUv(+)fNBba=bjAkhNqlO-Y<>h^D5nI}hlD z;$cdCB1HvcUD9><#S!n5%kNRi29%*%lM6r0Ad?w=yqjf%oIqnziZg84%#}5|6p&!H z#jF2u$dkpM+Y6lLp_=&4$f)i~T0uHf30$G8&nksj5|Zl4K_er64I`M=C-|~{(D;Xi z*@*ND#1lBBoHHMnFe2mzz7wc9Bi)V9a7%6Ay2!%CPfQDx<Q;P0RaS?`SrXZrh|Bb` zlIXFw)1r|Ai4CsvQAnv{YT(&U%G6?WV@x+Fk9LbUJmSYn2->G91wsF!jnKnQ%#1&0 z#;MC?C+buVdjb35f`_74g+5}+_{krB5dQ7-Ndw4gssx5yAeN1>3#H}zuK>q2BXy7J zTL6x>yQ2xn+JZ%r;mEg2Ke-s!2!XNAkz)7M&lz;Uo9~##{&-$C`KUAred4LtC_bJs zNuG9IehzC<ld2Kl(G|qK_YPc&6NYd`ZKfJp8H_Ls;{oFmnG#N0dZC>{NHXJG%024t z+zgL!vVPSsV{9We?<DxEkq@dexYVd2QQJrX$-N0wrj;M1voxvurBfw}9Q3@yF$OG# z<b41P*Vi_6Zm($R+dZ+l_(VRa8F!wcdnj9nrHh=Dxv~y+a71C_AU_m5n`C{xF#pO) z>FNZiV$;T_R(x%F)7K`EX6T+BQ;)keZ@klAes3~$0>7W?Zz5sL+jFT$L`84W%i6Qc zq_6In9%kWI*FY#<DVLFp!|cac9_>HvbT$%6erk@m(VgbU=t>#sBx#We3$sSZa0}KO zOD&rttilB&o~q~QfOPp&HKhRkOw90T3W%DN=7>gh%!+O2jEylme5*8+lOG|wv}2lh zot0Nl2hElDy>Vt;=mj=oz4e1)dLxE7>iuYDTT0jX`%rr444kqTQl%(>7a1lybOO0Z z$!(gE7<emnY$)cZ=C$K)%lzX2Js>A)ixbegcr;sw$;?S}Rn4ZpJgUE(!|z~wx}{ic z<Q>Xf0}A2L-RSr7cDkB41Wi~7)qH#~|1eW(Z#?<w_W#&SU#;Z2H5((yk|CvH`xq8d zAoX)J;<0S@%sW~AV~*E7GLljPb<QnMpzdGS+)_bMR}QZmbVC{Rvs-sDB2jQr+~Y^c zc(-1{t<XbI7y>g@yYMFM_DgD?csf0@s_k4G;zK1r5W6M#`c&7*J{9h#-wN;V_H2^J zr_4SlGasdnRnd~~i{(nK=K8CbN5^TO5gqn|xjM&E^Xk<Jk_=R%iQqfHDc+l5KsnKJ zBZ<wF&c57+X-kR;Z=gZ4vn%L}TH_9^dV#=+ZiFqOwYXRg<3E_=X(!?rMJQVw#zxYZ znsQJFCCDk8=^K^vZREPtr=b-A#lWcrvP`MTq$g}=k2|_fU<tDJ4g2K}#eJw)lOz$4 zNIhopaki8-t;DAIRKtTXdu9dXwc4DPbK`wgJ6C_EKKp|M<0HovWjxjvHWAgHe|d*D zk>brPKtS`7k4STG^m75j3wX9^S^$}~awW4`RVjASs%U6qk37uk@4spmL7T0Bx^ex5 z@m_cSZF}!e^t6+OpPt=)5|wenw`E@Ln5`I2JJWnhEjOHf$KMlmQO7%XNo+58+3PfL zmMRmDcJ7_$o-c24uDM+{h*zMeX$RK6zd|(TQK`;It6fbExadsH=J2rQeoalDwfP)g zmw}o}R7PMqgOhclDOB09eYcIs7-nl{?;cYXkQjXFt+D;sA3^P+l75PBE0LF6OD##w zg1Pi*6h<8Eyk{3t@GW&NVqS1O&3}+F70tql@s=yDXb*=C>j_KQ9tmLh7+xSs=h*N% z^3_XV_o*Di(?p`=UEEe+ds39rkFGG=XcJzSx+>}&=DcRMG@EjjVZD1iPG3}t)5ho7 zA8ZAp<b{k2c+xd_gjZdqz^0ya29%FJldK=1sO@XlY_R@ebBy_%6gD{`tW$8WZRDMa zPfIS73Bov~&3KFkpQ)4V?1{5J3KPb)F=s;XVx=??X{P&t{q+0a&*Z~*#;34~{xJ56 z$kjc>T^e)PLV>h9G{Db6&85z$_Epid;Mxc0n?)6(G9l2pCqf(z?gjU_K3ve{ULM!b z3wj2%p$nIBb9|E_eY*MF#7NO-dA<E~y@xy^76ble&i{llPKf4(4SLTyZ%Yh2RX+)? zFcVJ0w=N7E@NAUz7;U4u^>d@kWcWO1R4L(^!Vu7?m;m8-P56}ec$Y(aL9-<!s%(<C z8Si5yF1F?XOcnY}`Hh9Z2Q#&g@Ie*4bq5>M=|u%97dP2R;Hm~lW&TMzQhUMdH~-PP zdfc_64YlN%CAkBfLNFe-g(cE|<ClyHOu4knp^hn4FQqNNkL|0EW+6RdB6tZj{Xvig zz33sow_bPg&|ul%+j>T`%1LqU!S@L|SDK?gIaO9Fie7KB)tl%zozwhOf@$A`FJo}C z=*>CJ_Zjn1$1*>P33ewG!QA$-$OFSR9z-GZNYqqH;jNPhs$=`zczPTdBw?mFDaD8h z@IH(7etqfXaM4{n9IH59WnXG<L|MuYa;jx_>{vVb)<WFaBMLzvV*r9lhqRLfLUeU> ze0;%lk^7llZoj?Q8xgd~VATlrbkMRFUX!C^JgrWljxl*3&;>CwG9AeC>`{J^nm}wt zc0&-DRj64j7dY1w)C27PT69Fwr*9?OO0nx5=pcS%PBWp5qv=~CJ8@Rsq`mUkq!7}O zXmWwL%)T1yAX_(ZTPd>WNW@UQNd0Ese7rSQ*9&bDgBuc_HkGJD^Dsk0N}zSja97%| z%u}4>R(qG99+bylqs^rd2RA(`pA4sM=m83ZJ(g9Dep?&o`^xmV6UT&VLafczyR6uS z8C(nVIhqVG-nzxrhv{>U_m<w7&pM0SBc<gN^N#4jIN~%@F{e8GR+jM~$+nU26tS7L zX}C(ce<@K~^+l1hi|5TkcE+IRAO#x@S89|T)9D|b)H$jj)FG+*EX=1#r679T<B1r} zf4{&+QQvqZn3JbeLewN3D+t6I(sxOTOJzywX-!)7I{MJ4`&gU|)omcXs6z-1@(Zp0 z*%IS+q)k2XKxtB!V#BGOEPx3YU;YwyubN>03J>)86}lg&gr#fm;$7HQH(#dzKAK+$ z@|f=T{Fu#l-qWIz2)pdi`mn)%$RWxl1(rfPUqF+UnIyrs<jEumbA#Nu?VdAf_O;!n zrQop=V0Yn2aE{HE*VmXSXPF}I>^ZB!R(Cz)DvdeK3gr?LF$pH218#U0%lPyT8}ld{ z;Syn_&{<b7@pfYwYyxSV?>j>c0=$;T$Wz<?<+6#@>CnGGWU9&*fVoee73#{g8_So1 z^ie`e(T@7HsbiJ7{S?t=1qYcm5Z(XP+k+K)jm5LvcK!YP5BoO*lMFM7j^*er_<5b@ z>zGWqyZMn61jLIkH@Id%nXR2!MBZ&C1?w+m`uFIysovW%5r@_*77oSJu)Y&oGok-( zsJ|=*{4x@_QbqE7MIeZn4WY&Z69VS}`t=On=M)q%b9mg(*=oiszpqm2N%BPB|Dw0Q z6nOK8VAAKoVG?_vp3PJRQen|j;w&z3Ta~wXab~Kkj~?jLD;Dq?ZxYtb&i)X5@P&i{ z1vgBhqTk>9P`+gUp(PPwuD<lfx99bK?N5g%{hV!xioW8YPX`R3mhx+!2yC%jiDl9} z8a%!eV!GI&7~j34vAD@0FgncMe6AUcLBc_$kx6S-DWqz}<TEc*T?4m@AN|D_em1-F z+0L|X24N<{(f^UJUU5EJ+gF^kD9eLWaL;~NvsRD8cdw9M12m2r-{u2+(6Hf&8Mr4c zWje>|NMV9SNmF_y<LRaIbHDL~A<SG+QO4Tcbj1ZMx8P;S!Jz;X%&~mPZII6y3V94n zrwvcFRLDRfruFfu_z2-Or~VP*Mn`^V%&!KNyc=UTg&|6D=1Rbv+OWx+=|A}68?+@a zcPceYSPI#q&(T1{$R}%8Z~2OPQ3bD|mEu~?&An*TkVbjCis2TqdV}$mcwYoo5n=8e zMX%KXMjBQml}$l;d-QL*U`~lTjua?<1~_RFwyC_T%57;KY`XkGbKv;*X@783T%4e) z-F1MZI-~}CXLEiQZfc6pp{5k%xFi_^-xz@v=fQStVt3VWz}i_SvO+x8>;*pr_lvAd zTu+#Bl_k-xF0%!0;TR78GtZ2huF8dDDTeyl*7=4#w=>_h6wA~}y>MEdHgTGrS4FO4 z{mt=PKdwx}kK7JpB!R2IuI#Q;%<9|W7ywAUk-f$Tjqry8Q@D$Mzw(=nv+Hgsmehf( zoV+TL>?^x<cHc1kA`$#A{xVBg!D{aNC%H9^3FP<X&Th6+o5W6KRFB;gzQl|d!iyMR z-kMK+EAVM#alsiG(K$qEtz>76Si+=s3H510Es|~ZTzl6sV~#erBZlCctIFi{mt*0z zudsnnh0gWegXe4vt71bv7Y|KFqFMXcXC%@**D=`-lU`YLLFbZrx!~H#i3JnA`3{rT zwu+|<F9J8hl#Zklu;O0T*?tXE1$Sm>i|pqf!?(Un!v8+TRx4PhT87{YdPn!}{a^I? zH(XTx7T9ssXEn`U&!)JKbYN{0abaVU<T@T@=LBrIno#uTtQn;Po%?tK%kXT1f=$=6 zNbp4wu#Cz#t`f8Mabv?qVj1vxG-XnC=6Y5MzOw=pp=)AGUb~@w2)3~XPMH;j+qJJF zXZ-w85l}?(p#u0?GZx@3)ym5IvnwK0UW~58O@H(O){Bn4ebA+{9@~nF0$x-r3VdYp zZ{GFq30v0$P=wR#@%Vqg>~Fe#5dka|oS+N12mI~N|6XeaCj<KzD~bl@)=|B0e^(2v n6!e|q(*UhU<^P}I!~<)3|8^a=!KnHN;NNMZb0_mp*oFKLtfM{d literal 0 HcmV?d00001 diff --git a/website/source/assets/images/guides/teamcity_create_project_from_url-2.png b/website/source/assets/images/guides/teamcity_create_project_from_url-2.png new file mode 100644 index 0000000000000000000000000000000000000000..5b98b16b84ae661c63762eb1c4ab7f50704b0094 GIT binary patch literal 110107 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 literal 0 HcmV?d00001 diff --git a/website/source/assets/images/guides/teamcity_new_build.png b/website/source/assets/images/guides/teamcity_new_build.png deleted file mode 100644 index 798d00cedb2f133d2baac4ed905b717d234c553b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249258 zcmb4qb980T(r6}{*tTs<Y}>Z&Wa4C!2`8S|wrxyo+qO>Zyv)7dyWd^w{qge4>YUSO z@2=gu(A8DdRiW~-Vz5wHP(VOHuoB|Jia<aR4M0F3EfC-zS3)qQ3xR-O$Sj0}<RyfJ z2;?2@Of9TUfPln9;}gFsD@mXa9K@55kks*m<^`;S9;tZ15)i0VA^zqUgd{{zJ{`;f zwi4*`N7X^CE(eS53j%`<)4zbGq8M&bukyQ+LE>L{9e&(TbH8vsUv0kbyk1Xb1Nq^I zqD3++tO7KMv>%%L^ED|JIW{RzHVdL3*dz-cW+_cO#!gw8{fEi!+x^uW8h_sX$^5kX zyY+jeNc_mi9?%bA0okp6#~K2BFd*0ckY0Bn1dr@BbJGk6Cd3lZV?zprn(DZj-BYSP z6pr8#FT>ndLUNESev{fh3m^&!7shK23x-HVOk*uVHG+Uuh^4R|GbciLLA=EHcvy`k zoErCGSBL30G-eYPvefi%!&lnIB82?W)WgOTZ+wM2zKLbhLxUKiRf><>(dHK8)9xdK zaIs9NS0V<I!X(D5gKVJM$(?bnkH4dv4Bn&Cw0+sletZFv+^YfUCOF~$7H8c12v>`) zMRNlEI+X|PW9`q)ONC-420tJM9gvK;)#EVyz&#J425<y167^C96QCKq#LT(%=T<$n z9}Ro-e}EX2jK<$J?G1pv_g3h-kHWx}LZY36$>ad9aTIg>6Ry-JFy-hwnoO@R0<+R{ z{ZLJK)v@Rdr&S<;?8r&)>i7_XM@LT}U-6ZC7jh@a#c(f&yYtZCJw0c%$iTNOCJ~dS z9$V0MY%B`%XeIHh-ZytTc5$;{(V>C9IT3e-YDXJ(<Ny#~1fV2-U@NFW@FV`oWvvBh zQB8j!><|I0%`YbgBjQn@8es^!M*LqMkdfebBk!(b>#z8E>wGcmhb!j^ROVCYPh!5b z5Snc*H=&>V1^1M~m)$i{pMRT<D&}UQVvNS%ham(<q&0<r>f`G*0frkTKvrdh`00u_ zDp?}Hp7W}OBgmGWewkz+J1Nivz5Pe&ko-X`Xd?$w)CO7LYd985n$Gb3(pG_dJ@R?5 zr{JqR*LYXGAL}^;GoY{Cz*cth$!7j7{rgaeWeqJRX%yje^qB9BQjM}B)*12GnP<AA z4rOlgLsY{Hd&;|Ov%?n8shFHK<#$l4{&D@pD$z1HhH52so_YWD=&Qq4fbyMfcsLsE zOzf8(2vIL<D{D{duf7<mJlq}XcP|2XcB&aSJ%9<cF*NAu2X|?`Ce7<48o~inoSF6c zaWJ5xWqLi$btYpg&hDm{u>>b9phhHf>1R`;9@axQHlUmP4Qo-mP4X(FAILU1q3n9L zJ^ARsSzW%rI46NU?9Z5jF_%EhHotiB6F`8)5TKFxAK7O-5<r(^K<@jCWMRbl$LrHB zLNxf}>ccO>!~Nu(gc$z;y$NLw!uH4ep~BfOF$=!!D+q*tGy;~OSRI0QFKD&kDWY00 zG^B8Mj5!ISgy=K^A(6m7QCN&(9?nvTwOC1vUd+xQ<}T87<f;f~4Bjs66=t72RY~M= zPQjtuEb6UD&!oCDR!Y!*7MM9=3yw~dYWDM_<_(MoSbOOAEcz)Q82w)uAk1B5jB2C! zVZFbrl%>PR1|+MX%AmM@uy&Dq<DPVRRLij=7Vb!|Vs%s!y5Wrfak_kT!|XuZ__?rs zaCzcJz8>sLItjrEO6||(Cz2#BPCQD2f=mU`3NZk2u*Ehf;wDFegelCN1O1|k9D3Bt z(aW@Lx-GD6VaNr5tj-iBvWO`Y&&U%;N{thvBC{blBTgsMA$E!3rJ|rZq+X;3r6i$* zK!rl3Lb;<#Q*J7_ls5QLCiso8HI{ft`^x$X>PprT<dLd5jGJE}KS_a`vO3Orm}uBz z_{*^SFvzf$h=_=g2wR`TFW|nwUni*Wl)B2N$}hqyxtfZv#Y)9U$BxIg#}>yr$68ns zrjpm$q*GVsBNlUYwRK{3QIgK2*rW+aY8HNq`HJP!todrg#wN%ndV5F1V8f`xVsVvJ z_a)IP(kd@1i&WPtR4S3BtExw8`K8Onq9vxq3B~6s?Rihy5qYL1Xhr=h)QT(F-&M~b zadWY!UXO5|44-75+&vOG71pHF^D`=ROFH!0Rodl*WO@{cb&V24^ZOwq;K2JCOsX)F z!%@R~!nMLDjGPA^BDW$mzU_A<SsC$~N6y_$?OG(5<IT1eKWc;(qZY+y*Grblo@9Tk zuqoz|@GQ7PJG)+PH<}yp2;U2*#q@ML<-t`RP$bthiyVhbM@#q7;aStyi8%*ft8Hob zfZ@S!cW!6(AiwpvIeOB40)AzED!kESU`^^6mEQN*=P=Fmixdd)>(y@+DE;#zJJ}%3 zAbU%oCs-7PSS?pMmsM0o)Vu$wA35RxYXM_}nJ~2}<x*xonI+YWft6W?LB~+j>}gec zCfr0-U)AWYE6w!WCc{YA#HYvKe9JP%pn55145{9^W>-s9Q@38QJgpp5HMM+s0I|P0 z0y(l2%XKBi^2{pTPRD4?qNfV7k+QD1)}3|T&1?EWWhZsOx89{@tZvQ1b3=BFZnk2w z;?H?Rdp^%V$Mjne$Qa?EfuB%&kChm;SjG<80GF(DVW_NBT1r|6dn<cbIz0P*6GkgZ ztF>eES;;xpp60&CRK(`~K|@#h)LCq6t!Kuw!F?xp84nZpod<WO{x?51gM$F_jGzqb ziL(q`UFk~WN*i6=b?|lT3#y9&UQu4{OdZ|{FIuk|@B7D&tJ+)SXWZ-O&5LusiFaop zGz1)Zq)DtIGz|16#!H2019?q(8F{@brOUL<8Nz_*s%RC$MvWF4xYCq4^kXDW`WtNw zRvI#Eqs1Nj5qk%>9${z0!`?Y$eBmTv2;yTR0TOCQm)#zU+M=|g4KhS>5t)*-SzH@* z9<~;aAUtMbQ@hb;_0C1q>ieD19TEo_z%W2*r*wyp1e7F>+*ulr&wYKDI&?YIzxRnm zQPFF<BJYjTPibEEDCL-?-tD;D!gR(|rj<p<(_{YznK{m^$_z(>jD(!zLI%%RtfqAF zm9i{OhSD3ycbs!vssi2>wlVl%i28s>>Q<Uo&O2j2xq-7h_+qSb^B(F23>&O+MrgXR zz;`fYbTOSVE;-trL5h%?<D^MmCW(+cu{@E7x>d)RlnTvdx9Om4><BqH)OC-jdB*YN zdUlJfRm70)QDQpzB3>`~-NE!_l(<&e4AQKAv>~nC`mWYL%U^GQ(}~?FWglx)ho#Xe z<D%{CI_8n`Iu#9rmO^u~p22M^LnKZFGt7s+j+TbrtC8KnK`6#{sym0A5A0o8sZ5!M zuA{xzXlOqFLGjP@yb0XMH=1Y7ZrWyTOD#<WPW67u)|c9~i4$Ku&5V{dm%!^^wA7*0 zfz)>8SGx6u+VyQ&FGI(nrB(|J3vp%cjo<s1rBEYLwH6fSCFWhq;Pv!6|G4!G!~Vp6 z#I{p?Qo&oztF>4vfKP2st+W9wIqH|5&rg?UHbOS6E#bAbHw@R67=CpSdy70z2XLkO zI=tq4B;Hj_>*#%lc6B`sU3aQj&TsLk9A8IeHIK+EFx!~*ws{7*Tfnd4t$HQc(LW-z z7k51Ds~qZF=fwHmbQE$D10p69Y0D|fr>Yn>J6>^Cy0hRiOFrL-56`ncyE$cl%9gtE zoehgcHDi*!dYfd=cxotH39Rr*E==}5LxSr%&q8$OwKjHQot^DS`{c3e8l4_ghkfOA z#p^idps!!*JTX%5d%L!4-=m~Wn9@k~M!FB*{PC)$=iHv9cdC|_&~w0D>_S^*dNZE= zYd7qC1T`D6ZNtW|R+odj*%e&ZCfAIOv9{+Y-M4nXXJ~u`yf|)UcXfdHfx;X<nlH|& z{W<#-=H${9`##{6JdK<_bDtOYl<K&^MU8vLSM_!E&D}^&UT!6flD<XvmoD55+I#WS zL4n$SW#rr5wVKq%Zb!w!_JWYz@VaID+Uqz#N6A<DJ@;PY;wx{Q*X&c%LF`H4{sd%Z zChRB<32eo?As~OtYH{JKkcN;DQ9}~#3Y30TPH{0%+Y&4gE#f)uGEkOuOy-y|SWG6l z3FsU0$b?<ZHcXc-KF~HAFaq2?g_b_6pLC$>(Rc3ouUT+#xh_q+1)Pf`MhaVy!Iuu^ zhvjrYdEh`DA;Cf5-{4`rmmvGr!8V;EU!*B$r<o7GVN=$-v;*@c_<n(jw7<(NI{a`U zfFSL~HJpHe&`AIOf00lmxda0Gl3}5&?yN2&&1qz3LuX)YXJ|s_W@G;`8VHEnjq{^x zW8!Q;;AUfO>%{5CL-el^oFDzam+6TJ{x!teiib#DMxH>(&e4Q`m5zmufruB1fPjG8 z(b$wzQCReUz(0QR5ScqW+jG*>ySlp4xiZt)IhxTka&U0aGceIJG0}dEpmlP$bvAIL zwRIx?_e1{gbA(Ntj2tcOoh|Ha3I0CUz|hXcnTLqz??nIk`}cdAxLN$~Otwz{gVqOv z^ndTrGtx28|L55spxl42a>`q{nOLg}TiBS`I(^K+%f!UY!2K_P|L4~KPWfM;8vhH* z!OHUAkpFe(e;~Q(|6=f882y`E|GN4?FJ35a`v1_L7fQ~nH|&EQI2OWk${*jre|hu4 zxwVfEihqB9^nnqf1w`?zfq?jdB!mT&-M*Z*Lwc#~HDA29&ha_$TMPYEj4>z7k+`I= zgq|gQ?TJ8BmUX1FtRPtK`ZCl><Uk+~3Obw@Bxr{KHT$K#+TNC%N`A<1g#s_D+`pbs z5~PoSC4N@f5a&Cc$NR*xC+x*@MSY<(=*yYUaLPL18O|#8pfU5H^F{CR2R;(Pmw(m{ z4ME?a18H@vg%@%D86<%p!xtzmc0}<Xp#P|~kbHo(>{eANknjWlqoxo@JHX2&%lVIh z{tmY9hLB%$?4GPO{HG|YgHl+BiUd#mBMd(V%VK;WDU0EuD*ew;BtZxR3Z$(*yu^fz z2Kpzh3zC@MU<6WV;+Mof<cA?*Ruw54E-&#vlpJ=0587}T9BMHBllS~Uik}7;rJ*;c z$Lyc-kv#l^Hsmlo)MWqgRYOF6bSJ1gKZO4?NfqA=Kr~OSBApEg>Zfn(&-4MGp7wBC zkVp%}iprrhHZvFEkWgL%NTf#QY$;Wy;I(@a_O-q&r?Ix{Md-A?|7iCtt$y!Ps9WT@ znCAk~KsO<{_Ea;HHwE|b!re+c)VM4z+amLXZ9Hh<!t34wnOii9c;>2q$Xds|N6EWA z5A#Wc7vASHF`6XB6z6yq7BVk<YF=M~t9gS(K^+&7s<gy8(+RqTzD8PM79tEFF_E0* z$%CvMrS48i#|Lf~&9NRsx#3XR*I6m91^txZA5McVlUZ9V28CPoTjF|szt>|VQE5ee z-+myZIp)K#ijOOOzf{}Jqhyoqo&ni2a+tZX`94w$nC_4?7G-VA2*3@W*#%h{QQ*A$ zqTDZWz>TM)9aM~b9eu}YxO?;3izDQge`tteS7SBd1w5Aujf9LOY-10>s+G}w6Y8XZ z%o_1TfK6H|so-YR;BlSD{oYb}-vGa?P}Xz^MN<z=<qqIM(Z$rGSgJE4tr$+l9%pqQ zTS?+<Q`1+1Q|A7W`fH?T!f{{O@OF*-Jq`Ml!tVEH)=(FvXqHVk+G9kUDF!-wuG(3* zKlU?OAZ1-8&Jr8%=HAc?=K8W1{B|l!JB<!Nnl%rY`0}`e_3+*W!6pFCzy_dC;|Pi@ z0W14WQtypz)$vh+`-x~)^LdboCC!EIa)~hyHr2m-Yp6UlFS?$yy4pu9A-jb}03K7o z1&{An{Z3_9PDxg<!+C@kuw6W=^LUD!rI+Ahvn8W02b9GMBTIT}@Y1~wHpScHa>YHn zQ0k#kgdUPpwdJ}i!yi?VeL62#6EMs_D#I_@%kNNS5PW0(wXM{#=my}4qphD@Vz}a2 z5#4B62G52txUHjBhLLXGZk!yI@SX`#eKz@#X2^&GG`_IVwh@MDH<rg&W+~aK0krg? zReN#wi&qx3XeMh}?i&u^RLq4yjr-bRy6qxs*GG(ARj$|x6>F#5^O4ZsI)kT@$%~uz z+-QG2ZESj!3?UjlADj1oFJDOaHh|D_6kfb?whE*b)sR#ZMVA#aeeXDoPw|)EAv|4W zLdPzN106rwy)E*7&^##FiIj+lnySPI??^alZx=n9v6LPh7Kzu<J!<&bMEV6)e<q`_ zS8GIWO|=)LLA)fW{Hg=XuCo$qA^R@Iz*aZolbY382G|Czp^HHrSmF(79X*I*=tU>i zs!8Q5Rln3Bv{(}(Smzoathek%H>|DIOfPXa6d+_X0LkIkNDP7ysgY<_CIq%uraba@ zTMr~xRO;;_dm=>OGgQLKr4AgO_aF#z(~v5YpKH@@{ddR<*}WpzfaS$1?_`KoG^-)9 z#18+VM%}=;9~>JuZ(44)<Fx9U`6hq-$G(b8qA<wa7~8Z;T6!Uw-PCJc*kFUvx{l54 zFj_{otC3Mea#y*K+G62D3hbhwxt3!Z>1p1otvbfUriy(^3lR8Kh-aO3qaCU2-CSf9 zt)A#+2M|+9FyO?{!zdsTQnX>U9xgfL>U;tBA?}m#*0{b=XO#8Ka4j2;D_aTdKG_c5 zf}HF0TM1eX!iw)2I#&3@kTJm8Q0jd?d;NiBbt-CiP%C|ZI2HZeu1clBaRi`^j#Yx9 zR!X5Ps0^zayxxSk&7X6drWhdMKeb@p-ncS}vBT)TwvyzbLtp+NzoUR-%N{gohQHnA zX}7g^6sB`QXW1=0uQ^7wREW0xtn4@17>LWgF$<m{eULqYP;=lsoNV@GqYC?71zIpu z3@<N@_WqIZGkb_19N8pYcR~RVH7QQO)yN~p7U$?&l0gVrC1UQr{aTU5{+0_m$>#Mc z2nn%$jmPXwWB_XO95l6mEUQ<nL6KbVqK}~{3*?k&8F&!M%`_1G4HAPy8}gXsD3`(x zHU_IWB8$m*cjQ=XG+Jp#1Fw{&7mR4(@5_pEoE6GWG&~3}H<t}$hFk<(3jDCtf|H!) ztYc(Ns|!0((Q!AfRyT-eA<`h{!vJVYi-pen!~<9T*;KtiY|fnlwJd%8`%CvjIp5y7 z&L<MD4BxdrH<ow*iVe($=uhl|n|Xf`N5cr(wr9_A?NwhShQrpw$T2|jG1Zy9WQP4( zQtj(Y`?mf7))AdEA<lum(ZPcKlkNx`<Gi<+=f(nAP*1c%QPG1yB-Gh3zS+!<Hj>pR zg!zpUzfrq5%u-NB%whADZ|CwEmi^A6Ni{8I8D!(!8}I3Uh+k9Q4YzQ6hmge^t)^0O zGB;SUI<}uZ2n#NIzg-g`I~hPP81pnPBPG=NmYBOC0{9_mFug!lSZOAqXG71JElTNX z#|nqfYg)@C^c3y)mS{#?j@$iuXrP{lTYeRw9|Dn=w1kvmDxEgT0(+r#y^ZijhlfjJ zD9!<5p}GNXoF!KVsGc4spC!2__9}={h>dG?%?uA5WlOeU-#JC`YV`%Lp&R0l0=nRe zaa4>(DiH;+HfAwtlSMPXqP|46)*?bJ)feq-&(n^no(t`d`=#(@nZAEzpT7jFxw`lh z|E2%FVGRAJE0RA;t5wX;<~NZS1+9ca(oi2l8w5N0J{4K0C6K!zJOs017S`Ec2XI#D zgGpNIXN(iS7&Bur@sm-uc!>Av=&Q01p}3Fh=nu>m749}-uJU;jj(w2q+Nme%y~U49 zirv3{h4Vo;AHkeXjH~N7B=^+ntYas@vA(M=?m+W2;d7c7+{8ONM||>P`z08ADiUnc z$s=!fAu?Uz<e8T};W{pq=~Dy#+bTt)ZN`wBZCjE1xXCi54X++v??mckMbC?phz$v; zAq&zfe_Z5yItMg$bqfKPWT@W8imyf|bnbUi?pkiD?gTHf#VcFZinqN11BRYT*@0;; z`Wu44$W6fSpAYS)Q5Sd@L5cgm@EbP4_hD*ZK4oZkM1n4hEfVd1ryJ_ip)S!03M^eu zuorF-@AWp%47h6#ImHfZTT$pm_}ai5xDDW&>zQ?H-lf4-N=(eToVR|kDMunR2?&s= zjz~&&q5}L5fl0Zu>A%4qXx#=WZAuHQ4E39V%bZq^IKa~i7aKA1gdD`-fORsJ?T&AM zWyN2=0`g(6UbVHb{^>0=W=i92&;5-ZT$d}+2P0_7%G6-=(wtD&Ii~B>#<wqtx8BWG zHs+=W8@pYa!1c)^PPXmakMv}w<=cN-H7a<Cwp<}v(v8r=*XD(=TKgZd!ua!@-&c(a z>?G!Rf%3I`l+u~(Z2fJ~hK^(gw>Qr*%mlwE#M>gI5$uRnwy=V?=3Y-G3vIFSUWXQw zj1+42Sy4)M2n-V-K^#GPa+}ht<+Q6KV+NXi^+zOENnRECpc`;{55KJAST#N>lH?$f zqsU_i(2BgeMA26M8c6W@vW;IaH~zRqJ5qJICq$IO4(??|B8fLH6gTzTr4^RCAhK^6 z<AkKK3C4-+fKaA<L;q|R*Ey~IktdJat+>?;G~eNz<2lp?*RH)(SB%M|(!Dr~zC?Ab zD<E(jZ!4|@M{K;iREjKH566K&_7p$N@Em^$3C$W7suqq=h<jI<_m8Kd(%3gj>bsZ5 zt6&Z}l=1btx)GUedHQvwpm0~_QJ+Vi@a9#%Cs?i#!0KIYf{(<zmji^BYFw))zhO7p zCVwADQ}N;!FBsRI+{{6k?#RLwRY{cyV9{|272WW)$vH~y5JZ}`xM%({eWu#yO<x<$ z?A#;SUG!6~+8@wmnMI@$O0m0;uWg!05KGl&bLy)NlgN>AZ4Y=*mC6w*GHxbM`Sxc~ zx<`M^z)ak%vMo>++7-ifJD^EH*1J_ovij-97=HzkD2p^;mk>2kUE6BR3GC|TX}P)V z96>-<SNEeE_E4Ek%<MR<q>Y)zOjUwBTaYe1w`6(oz@e`Op-xF%WrP$Jd2EHuhiYLp z5bmT@>uMm$?$bh&=SJq;Gx*hp#QqQ$R7u-3=J7$9kU^x!iX`Z1#@}IYsY8Ok0%>D1 zUl%3YTDtOUD&<Gi>Z7Q&f3%`#o<qZY>;?!=9R5<SYw=S|7D{dn>)kxhgto<_Y{=b* zUM8?kChSgtl}uzNuk3jW4z9Q5rQ9njWJPsiELlY6DV}&ai0yrzp_zDAQrx-58&{`$ zmIb~ZSz<1G+9`LveLM_2VKjcXq0l|CYknUmS>h6=$g`ujtpTB*=##l8?I&gaT2$;< z^K_rrqlFfRVV4|B;J1SU$;C=rU8VFTAJ<I-l<b}ZI2Lic+)PH>jz^QRA4_pSNXksN z?L8-e_-fwWD$vcex^UWs#Q>W34Z(MHCEQlkY=R3u@ir=e0_t8TfVNg-Q4z6&U5C2? zreGj}0s2ko6KtPE13n|O7T{OUzP%{>S)in#bu6Vvu+Eer-^P7N1j}Y6`=tO5ae~H> ze?_Hb`hbwQ){RHEMGn>^J26&?9c*o$Zic&_-6Xi3K3u}jBCj#SERv=x0^|u;52t56 zCBCT4(UD`o;;QtWa=G$NMd;fm8<7@=j6;-?rtBXS7`#d7Z1^{1sfDLNIE1Z9Eu?c1 z^r%B`mtn`qWMcBIc`K#>9ola++D9H7_8FzykO#U%10N=fgG$DM0f|`Kb{SeFJMOhb zx09>X;cqJ6qg--1A=63}oVOld!!t5DhP}Me_-JAi(?P@@hVwj^$Yv(Jpqq=Zg4Y$` zegVeb=lxnG|Mx@3Z^v{r83FZ7g+F;C*%IN>>B~_Y#DBVuKf|3fiC`szQFt38*<#Gz zRk1#4Izqq-835oX$w>p!xzL{%@*v8-hjdZl{Gl8INND*ok|n)5l&D0OB$BsByxmst zsX<lCGK=Y7QIyil6lv0X7f)r1AzQOp>jh;Sp`V2AQE}VRp9Ye-ybs2)Y9Iqv<0vgG z!+9v3`MJ$uuY2)ivzu$sO>TKXvW<|&t!<j^CPd;c1!Uh2#f&<K-GS%i&`HRHnC9hK zWIMiz^UjUP+a6g_j7052jwC)?IS`jrk*Z#Fa{4d9<J<($%7s+zVOKMKG6d60KIzkq zR$MB|T@|j#U4>E+V=vs}3D(dJBNRv3Kb44g2TExwj+F&8VVfF3`07kK;8%{+VA4ij zQbkoO7#cq0JdN3}l*=0EG;F_fUo&;^ay_|YJ>;~=aK10yQ#w-ERfHz<wZY)2syc<g z|7EVzcJL0nMFxDU0F~QsW1NORvo<~m&#rs?;Fm+<)?B`Qyjy0oLhrY8a!Eb0H<(Jg zHnEGJZanTLTNnV0>;MWX?cimxpyqs1563JoZrhaeP&?<h(1hRWEg-0hiCa^>S3U|% zPntLK?X4`55Cvkkm+mf<E01cscdExsFgxS1s~jiQ_Td_)tZ1;qfhDe!`%OC*`?ZY> z$5&d~Tk;hU-orH6QP-;$X7X!@eSR!Ppr-WnU0G#*hu7uI(bGcv1*F^zJh1f#UKT&A zz#{DQ{R5hc9f7b0a1d2sJH8Wuzbbuu%D<1VN9%hHiJ|wh2q>*SAJe_Z>enuWMl53x znX#K)$Rn$9d?4rMRh5xZUwK!gsgW&@3ZY-uRLX)LJ_Up~uHPQSZ0DR=`CPDk*>X%- z?*>gaQ;}7098J>>VpR&i<R{cPkqWQJ8_&Iv*k2x|)cr|L7B#sLzspsnbGKT3oI$;J zif*So-ln>Yd_9YRZ6fOnMlaJwWs0^TWCTk}V~u#BihZ7d;G*(96w(djdTtHOHXzdL z$Hx1CnA`It`h(}7<s_TEKxVD|8vIiTdAwb}?bZP7!_FN%pw&BbOZ<?UK;)_*J@5ja z6aJlr0alFa`&PkOjL7w2R3-l#{|fVn8vf4O8Eg&H4?OhSev_j$z|h;zB91H6@dv&! z_4*@ZYxsp1SZ>ZM?i;RaYA=TuXJcJg#_{Yy(z~Qf%1=b(_zC>Jqc%MF0PuU%%{?;g z+tt;_SYR>|0QdRra&879;S~Xvy_<Z30G6ydY?0F#O8<CRB6S5Y5=Gmd`92KJb?82Y zmb1#H{7i*xZwn|TQ7Q8jFj;dfiCpX&7vdVsZ-Z1!x({f+gNQSWxRVR~6LjCdN{^SL zd^>yvt*fppwM_hJ(AzMa)@F)c0H@Z+V=2>Z^wj4;QQCb=wB9@~g(7d7Wrj{3OjrZK zl80>qUQj*EJk6o9i&EM1-ZTNTvxC3#J(Ip1$G31T8zj|Xr3z4yHPDRjh5}EjWQQF} zDCF~F)TccfNeD%ObX{Nhf)ZM|>Dw}D1!lglW(1~2v!ptS)0%|GPtREZB)X0L!W~+> ztvBw&$y}zEyU~SJ{7mOhB67(ni1bkgo&tov6nJ`xhr&&{E=>mR2Ia94)bYqk+6MK$ z(=f_oXxpC-ja#tcE&JbGJL-n5Bo&Q{7b@@7x_QnL?d2HvvooHB^}NH+OfC$re8kH4 z>?T}}HoCW;YwaW75#O#-*%(W%!hVp)XeH`Q;<~22VVW+4Zi?`JXr-HfTh3e0i8>C1 z^HEX*dKnvj3U;E?LHM9AwLWk4O`~ob;3PY=pK|Ok5zW;MpzTqp=~{rL)+~bvKU{js zq91gV=8K$ay`;M03B`MMMpx1L6ZEnw{|^1gK48}C_Aua%BdmqEyNzhS*ypI-n?vf= zcERZFC{yXmWq2Ah!e#yqa}j=oxdH`6jI*(QVTD{@zZt_|p2U%eF{8v@4f3$I!3=t* zM|4(}_6bQu9%uK`QadVM*SRev8#!6!R~Zymb&i;9ICP^q>1JiY)I(o~<6$OdTcW@Y zs&Jne?=0~t8;Y~@M&z-=>@e)-D5Pi~XGa5zAc`jYS(N!lIB&H;&1ZRRLHM#Kj3<2v z#k+lLy05X!>FOoQ`G<z<NfWD%jO{y-%|3D&7}kdfeaY^B$^Uj1H>nPmAr|u+eM2Z4 z3wdl4&&8`-1lx)VJU8h?XLvdjB&8AGmu>Q9T&d}JK66=4+91sBHzr|*@oKcl{`C*w zzS40DK*^5jQ~)iZ@-K){<mo}qNK%3lUy!i<PKY#Lx|Fx?FwO9^{No}LZd)<?$%2Eb zklVkpq|%4{67joa?m31DZ_~32PdwD{jjnU&lF+6Sn#NkCg*h%#I1`~gw&mb;_Y10J z-xL9!;mhkeYqfO1*DJ+2kXk`{>5=)ax=BB(^09Tjw>_H(Dh3iNFNb2t(wzLZZ1!h- zL&Q>?0B5sJU=L4y*q;dllJog}M{5WH%tJ^qYjh*Zuy!LRXUNvs6LvcvTxlapvS)w@ z-(0=1uyY0!4fdI*5{haa>;xV$!p!_8C=k%-Za0QeYU>n#O6w+PaCs3ozWd&d%~9XW zdmLn~vp8L)!`%~p8~$F<m}pKK+`E{5hSmCIjl%9mrMp0xPiGTdf+8^0hNWGQLLxWA zavMWpjtazOcDns5SK?rs`qn5kfdV}ut6UU1VBEBkpxisiU^Okwmh8UQSeq>T+PPme z`3a*L3=B%kEBp89ZaT9b@KX*8Tk*_C9AS3OZ~}jWe{KYIQGPE%>&8)Zb1B`5K^W1H z^;A138!T*%#>6*TUeST=XRbOGa4V`T9U}DHFZID!5>DPN7|8HOovP*p-8J$pca-wr zH?JhOY)$kz=y(-l>8)T&=il<S^^z29trGoz4#UW-0nm13qk##V=DV!oC)v)u6!rCq z`-_$*OjClfSW@ls-rO{V69NFx*|*nOE1Tyzz4?poqVx=Z6H!~vE4#MIUnHPj%Re?= zSH6V%u6Vvx5`Wz!?>Q53GR6nzUEgHgzG1#x?R|S7=dxBPs>WLxhBsXH0dyF;S5}9G zl3V{7AmV;h&cXEdL8%?as+y}X07QM=Y*B80FqKPl`c9M+XR0jijjdJ54lgxe()4V3 zC}+2GtjB5uXtEA(>PBdHYv20J(Nh<tWY$_BZ9y;?Xuvr`4??`EL{nxMPIm!7CA`!r zgCAcQJ{4iy{l<4^3N>;7P36)cfxL4R{pVHulps;aKxqCeYHrg^*`)&p6!|-lhERoo z={w9#7_svdY+*}P9}IC0^CZ<AJ&aJrxY~sk(K@YRy+S4XQ@pO|wtws)DLBv6Gq~`5 z%g%^RNW5sG<Y3WDxH!|#!t*Z!YQI+*mJt~`W#niep|zNNgBrhW{3Li(HXB9ny%a?f zCMxzM{K&Ga=zDAT?XKXn?fF%oF)2<j)_r{%TV>SH(S<UcZI6bgokWz2@ES{$k!v~% z5H{-Y!8H1-9aJ!OaDT>hz}?*1qUQ5Vqy^%plJ}vU_8~PSZS!ZUrBJxleZ%NR6F1L- zfrLeQ7{Vmftqn4`ya&(m?F|2p*plSbQX5E1)}uOy4^awY7sT6j`kPaEQH7gIFzN*; zJ9s~S@8*0Fu!y=9EquXS3)0wr765Y`l!)dHzj15f-qDRu+Pjj}F57aL9fA`@Ya1mb zmgoKT>@J;d4<3$ULk8FWD%mY}2^S!GJ$C+JGlcrkP$viL%W~cV4bb=T;MZLz`b6B5 zT?MkPv#Jkjj);&6uiPOTGXrvzLD+E9TMDKvgK>j_gsYFleH0ZSsG;7bAD8$89hpVd zs6R{FIz-Fto2VRJ7w!8MJ;wCJiC-*j0-}a*f;a|ItMXQ3-Mjt-cA%;G!t*hsz2+|8 z@!2Kz&MU`@t296$IuXye;?Ok(D^fH7dYd*&Op`uOJp%*@F;19z8p13W5)&py=qTZ5 zlgW>X>C(6|=DSd`vN+LXO>aqwH|KbYFr+(4{KCj&dOvT4m6eQx?Ww)4%m#xVxdEf{ zR<%V`ight*fKX|Q{;wz`+)R6uk7d0^;T`^BCE;n?K$&I47)VPrKdj0v)tA{A1BKP_ ztFQ<Vc{s4qU*M`6cPZ8~Q1YYTOL7mxV}sYK#|gxZR7AZluv4&|CHJmuG6aqj{jUt( zONo!2KM^6UGNa~1`_=m-^<k?ZWbnG?hNZ02mp`uGJKPMfq<^PjAf6Q-uJ7K{H)H^x z{fF5pP6|1CEs9Lm@9-)S)b)>3fer|*oKW#G&Yp!|Ris|tob#)E5F28&;BPPZwvi(w z%2U5Gje|w#&t*P!mXTHi%E`Y-lmV&h1H`tbb}pFOCfkjuvq0@-^Cr1Y-oX%vZA&SU z(bVtI!;t<%fJ1u*Kz6!x*I8w{B&T43wGNW<TSGm_C2E%v7`I30=N9fCmSf)MaXrS~ z$_U6J$d5BUE{b(yzF(x)8Wh_Zz$?rW`V!SE7^Gnr-(v&BS|lN(;z9~B^a#gcg#!Fz zkVFecp@@ybi3_&M?+eY_(uuqV)cfsrG`uQdMY&kszK@9}heB)RM5&pLCaOYfS?@HD z@X!c5R&J*S$T#nzp->VQ0Le8evC^X>&yykbQ>e0j_<WrK%udVkhYtZ^()w*@CAW-M zVWM>h0@wYAf;3xwTeMDqo>1yF9KeAMi3PWT6uZg{p|WaRu5{ZvN!4w3RUH!P<C3iw z63>*II2n}IcC1nlg2r~FSS24e?fbxW*>>FI*=c3fQ8K&^;z;gJ1^=7LdzUic4ha(Z z2DU7d2PLsD<oJ4kl}o#l)<Fo71Jw%8M3dM$#$OOW$54UR)b|vHYLA-{1O3z!UCH+m zv0<gLvXv8;`n+vYqL=s+=6V;Ube2#6t+^LSF8JC$rU>+~d^-dD{KeBPgYc5u9eg~- z?*gQ6Fhj{;>I`q1Y1w3<o^N0s?A`>T8<v<_5m!hI6sdi|Snyk29h#@!2QtcM+Cjrq z%z@rIO>lEjFwpliExFjXE<%lO(lC!mKKYqo6zc;F!zYHI?Uf2(sFJuITsPmSh72>m z4Y}!6gf|jNhon!vvnVS?o+83G!8@X<8oDfog|4&lfX1eBKkUAu$HeToXHPa^aPL5a zhJObgBhQsC=dBM6Er{iQVs{z!nmYKsJgI&Fc^MMV^CI2ttCJV>esu??Ly{O#41EzO zOeA@HEkXgtkt>#__;Grllc;Wg<Bnq19;RO`(JgkirWcX2h9qd&C#ft#*=9dS7q_~| zHaxSrQczg<U`3ymMlv5w--wt~rgHlXb+(B8p-rU(A(JI*9$bQiz$3ULhobPR0}0JG z8|Abk?0ktmbXA0Bin|l+V>`O<23+;85Kp$9%g`t26E!mQ1YMfScR|{y3p*IZRTX_c zlMNy(0gOv*UENFKsu#XZ6`YJ5Imn>@H3*CeW^dadzkz0gvItcyw~c^MuqNMUnIvdk zh64K;h$^DZgo`vy^kQ&KUDSA{NUKFgaFZm*8d1nr;T^lpLquAM+Aw8M?7~V}AaHtL z-A4I$9|zAbR3d5hlDrhnH#{=(V}H@1Ml*LhTk2bGXScm1r{U}4Y-4zCRuP~S#C3-7 z0XEx{@Q<V-(PV`I!YSwJ(hrN-&l{4YWSzyWPIA^b;mhc{7lIL!(u;q_D-n<rcV*F- z_&zt}`4Gg;b~)*pJMeQfhuvKB(Y06n4_7kinDZ~>kyWHWib=0l+VgQ-Wn8;4IYP;{ z8lTOw<&cbK>YPX`sFF@lfa-nE$K1#zBJy?Bd%i=Cu*{!`l^!pIoo<$*A$q>7qj{33 z&6%iahurd+_jfUIrA>S|z57OLO+=$v)3SM0dl&B-5kv2H4(eUNA+E_H+d5?Vm@5l| zukDBi6E4$*s5{d?Q^q|%W9k-S_`xAH0C@~T6VS*Xw#!_nDKs71JjVNy2*(Voux&?m zNqH_1%skb9FN;FuG(X_lE*3!wT|4O(SjdrMk1}A1GLq-jzDDDPAUq{35X-c_kqX<x z%YnrHMb`&IP7|$MjwQw_)PVSFkmY!P6mf#YbpZZg>f>w|!w9{V#IZN4eHoT5@1C_J zt9#7G16X2x@(jf#%aGfaYW-Au*dZmrH+kEANIpZD$Hqg7yK{Bh{mIYme32H<TalRK zjs~APC(*|CZi&7#m@#o6YNO6cg6>>VaIMG)w1=UB$H_`j&bi;u5FvN8XeZj7v$%tK zUrJwZwnB`fGVKi)CEgPr8O@?u1E#=n15yfknH<l{_J;d`gmeGvU7KI7p142_dYb1J z>tLI>#(;$VMM*arOGsj#6$-tCACUmM{Vs`eM9!Dy3<}w`SmXDy#~Cgn32vq7f~*PB zCGoKOgKz(~1?)?sy*)BdXP`{)72;ymyVEH&UK&44V4l`yGg3ag+bhl;Nz~MrlXp)- zDDY7FT5~vUS=ZHS@uD2&i9d}KZ(mIlafC&hvXR!!ru4no`rV3MTr&PTIp<FsI}Pc& zg+Y2#*kNxg8g8cJUtYRfBl`Hp`$PN~4Jlpve^kMJ!Xx&RC7d+qM)P_?BQsvx4yqXZ zhz|YMO|@UZ5qn{PIoZ$%rUr3_l)2yzEVX?th9)Rs=#nwOd_y0pd~es=m{=#m!v|Ma z<?1oVQ(8po4njmX5{=NY-$yQ5*G9NjI}1S^CrYU5L$830RKw0!>QL%5i(5(+S&cd3 zpM6e&XiT!XnZw@+l8Ym<h?taSbR5Y=peocWgCrTX7m`5&KP~~5oBf%Vxm8|x;WzW# zbv0I{ZaBISpcrJ(RtlxXY1C1t`r%i(&;>>66>rKZ&Kie*QU23cI9C(3+wvU3K^`aB zu7r6F0~xsQ#dOdXlz2XFPbUH)ABMSoJBVn~t4scr@~e+xU2{5PU^SRXCW7|Gyn7ij z(J-b~O(H>Y>Dm_Z!d+Kwj=B8p5=3N>EGJQc$iv~+HKP)A%>=v}_YZuu#1%D3jV~4; zc9?|SqKO?rV2{J>V5UsAWUL7u>nVi;Msd%)mLku$+njsH;(c_hbv!xeAt%*&)n9zy zg@tLi0lR6?GtpO%Uz0d%;k3>Y=;)sCL~kz8^4G?Sk{-XA`eM1Sx_2i`RJrflO4pvG z114VO?SD4$KhNMZUaDm-+MEU5&Q$iBwBu~a#?f7V`_w)vl(iE;D<BAls`UqJmJTO- zU19tcI8qVOesvp)JuYucNrF#MaEo14gBC|}JIJDxVuo70I6%0WGzc4bM!k)HI;vsj zWa1@gCS9t7I72wDBShY4AjLDsjRP{<^3hFNo;!g+DF8QB#UOZnVG;aUydAJyR7ZDi zF*ak=Cx7a$T+L)GtNYWXk9d;UG~_p#GToycg<@NYx;t(q?!5c1Q9#Y_RE`<FKgXeJ z9FR9V03mgU6MYk1anAy^?flSRW;i_z>$=@&tlG*I7^frtFn6MBfd10l11XxRAh`J^ zratodoftWNF^eyToZL|8GXZM7CkoXcOh>6q!gCc(RQ&}ch$)oI@v+a$=}59uXOhEh zWlTN<jLa>>%{7>3PyI{Frv}m{sL?3ND--0DlLNPFv9>GG8465X%YY`gkmI6ekD~sP zC-cyVX#+=>Vo1mvKpTA0p7mvzU*17?qFu4@3MN^IPTVl>w4=XO{9gP~vx4#9#Fd87 z61ot7Ap&T*f`4&5)_v)=eVKml4Bk2#sD3mf!g_4=zV^>}nE9Cq=6bPa3G=cya9(R1 zK&vE$0|<8uOs3a0Fm!)&u(Frs73vdeWqf`(Qg?dad+>SE*!oI{*q}|@oiIZ8KsJwN zwu57-iKEZ`|IYyHTJY!p3Z+FuPZbml3ueL2G8KK;@eQkiJ|UVb<0~5V$?o(mhSN^H zW=MDth}~whd!vC!yqa4<2(GSUA6(EE=12jKqV?Y@@fhi`5qOr1LD2!{i&rF~YlRI8 z_ky{YH7fKdvPz_B;z0q(Q+!}<-$z(rFegXa*Oc`lV6UC3#aZ7*W{@EJl!^kkr=GFo zC=65(8Y66}k=Qxt`T<%hJ58}>plD^y_-t^9K_xNQZV+EB8w_lQ+^p?IBx1OqFgW)@ z82R*djnQ6U^84P`ps`8!zKJ(G+2U3P=u{6+4v=e?7+~1Z8-yJrf+ojap6<BjzBiIs zhj=MYdx!+^imo{fl>R)BDh;HaF6`0T-wsArsiakvt5vA+LbGkZ!^+Dq2@}H`dg7?k z>hH)JyiGIQtK#J)l>8aM&}wSEoBe7Rx%cHb193fR<W=5?mTF;C1OO$XjY^`<&?NTZ zYU$Jz^u|V?Bndy&>FZEBKCPTwpX!R&HdecR_+EHs_%$VwXVoG|7~RqKP9~9w6{&&P z;I|^bLWTrof~!20ILJmB2l^$;!xX-cBWI`QGC`uN{-_z7vF{;m?=}$`j*8Q0zA6N8 zaA6wa)HA4t1}HI&F!eK?V>w=7pE89l?BqXJxMY0a+8NlE$X~wA^SARw?o7{!u)`LN zBJOlYW>e9uZYrC=d^npf1=w&r@7~)PnY%kZRNPK9olFDt-vZBF9`XPLrW0I-!8E_P zCAAkFg`r*ReD3tM6O8M!h%3)PD)4?l&$@~fed%0z!|dSW*0H0m{EU&<fd=~F{R2bV zDUfW@Qh8HAe<T)?Pfk?1oD7k$jB!KC<YH<PQ!<GdD=Mi(j7n$qBM1Y<Uaq{>P7d56 z<b?5TV_&3RuC66+Pf@kA#*|v`?xqFjiZz1GQm+gBD-SY*9C9ogm&7_o5Z+EF96wU6 zk5RT=abd87y~Uyy8?V>h5cg+0_Mx{-?_jDp_MFE~Mp(9cUpbq(u3{Z`a!<5pHOxz4 zuso#^#sgv{hF$!g2qYs(hE>9<KV*<=qCH3QlH#3v(P|z9b{v$Xt`~NonumY(CGm%b z`p6z)eu<w3KXGnwyTvqezhyj@HE!c{?C90Q78R?L!bI1oL<XKOjin(s18qsi?KZ%~ z->9iaMy>FGC1rc+nZiNX8kOPQ3OD}EC>AkFyaeqJMO(@lvKlrTA*x3%`<#}`#d{Y4 zg1Y0N1Ta0Q{yrMV`u@9pf9J1>>ItEhN1A=lM$Bc_Heb+7AMV{G(aoz<5#X%|jWo{D zZhTP+h1a@7RD+!xdOABgHQ^!<cPv2Wfp;cBJulDRiI`)3)zZj#`%#)PNp;MLp555z zIm9fhj#sL)(e+bkyzib4F>tP$%-VMc{~>TEUL+%OWUT8aALqpR55n;3bDwJ%n%6&# z_I?z4kuL!Jq^Abrkm}k&LIVS6lDNs-ZPb2;JIALZ3|GIl@IDZ!KXMgaVEc+UC7Yj# zy#YZAlTKEDoH;f~wgEkauf;Cp-fao{;L>j=knWHQ%T&q#*(jB8v$&@*E+~<MA^r{w zZsMgGCZfUCM94Hdos+Ib=sM5G4P3G&%WRCjjyUUx^_@2`8;noIu8$kPU0$#n#SIvX zzIuH@H~^_-sslC1q|)(1n!B;B#vbO^f+%8z8>P2dV18v537@1nA)5;XS0-Jzj+1{M zxGmG3@t+Ypqno`iK~^6^z}t-m2)MoiX*%j~%m-U9))EsJ+=glTgX*(K;{{s^{gMMm zZ?;>OyDzm8KpWFAr%cmdv`vtmumt^nd+O54u;0@0_Vq3uL@Ob*$;4syVE-o=Q3D39 zh;_{5!y;JFy01bnv4|;P%gQC9PwQg&8uTu^2~TVFuHA1tZDrLRWl{d5Ab``e_#qX; zrF14y!c9f^$E!AC7KF*2gr1#qh8V4cCxb?>xDrUOxMq$ydJsAhYn)ac&9b-AYspS_ zJ~N&3gxrUFoi5pHPhh&s3rK7cOE^4hrfDaiU-M1A)9o%4yA0#_3K-d$x=xluLT~U2 z+<5i++P{!Y>IHIg0N-a)f{w-vS^24?d;%yxIP`{qb$6(x#^am_<A_96_2h$LG^4%( zbHPx9q;^Xz(T${X?8{Tx3+>-wt=91P$wVdYlmZGeV+rq}H70x_CNd}<j$BT=DAKeo zUpbO}rUFa{`%z98`Cu)6A!<<97o%0iB^r%&#|uP~cS|@y`vw7w-oey#QD_5V39Tu; zVND*Z1Ce028BL2$82c|bvsf7(!^j|!>$iM)BSfrrpyeIIM&!B4;9pr36i+#c_bPv1 z<w9oGD6qf!gkv%Td*@&(!}hrSJ5EO>ch#6}sap|Jf7(p3Zc@_MDlH$GLMyk`ocPXm zXNf1-8}jy*F{e<XnFvU8>ir|dyEKVPm-xelWz7NEm)f@KnGkM`<zH#L>0xl$5)L0v zL@*LSXb;$`l^0^w^*KIBswR3$qe`m<4+JCLPC$3{ifh5P{I=8Vf?D*H>n5*w2jVii zUG9439`3%Qs?~{!Da36@!+5a&KjAHbyJ*-T^1RVBU=5J_&H1ewK0G%>%pRPrUwFR; z%kO7$i&m?UOprRnk4l~wIfl|-K!5e`6W6)|gB%!N;hIdeXbJMDh~SanA`Pl{Hbb7e z6K(vV7EvrjUZ#zyzN~-l-GDf&>|^e<MYy2Rd&DNrP(*uo;uL+!YJ5+2IVg<+v|hcs zZI97kR?zpcF&G(hR=oT2_R74!X*?Wl`{D*5CZ?nE!nbQhl=@;i3^93$b0(~R&;F3P z+ah(HVDw0wf!0X3{hQj$l>zX;9>SwgcacxzvhV`~Af214NPUohiz8YJ3cUuKKhPMP zNeXB#yI;MV3r3L)N5-&xq;RHS@e0Q(V?Qwk#LXy965n#)JgCCw2_u*EQqb=cGlG75 z-J!t3iV8gO7bo-ZI?+Bds=TYDHWgY1Yyl9kjxDR-EAh8ueOW>^G<XyKT;Jdw&UDg0 z-Hz}_H7xd*UzGzae%ExyIhuG)8~<&S>pMpE?bO~a4_+3Q?7w<$@i&XgR^$X@Tv8oX zv8Fqm@Sf5()cT9#LFkQa%ZI?tc!!emyh`bx26ZRTt!k(vT#0NDzY!YXJ~4q&nhm|j zv&w&DCWoi&K>R5XUu>|DT>R#{l`Xmy_D1L#qmpqdLP<IAb0d>?Yu;HuSLcLTL1oVk z2x+qI3@BDwKDAT9zF=u5B}}vxh}V%G3cHX9sfqLsuB+~=uJv6G?|gq%+QiY2ipT^h zKG<9-UNbsy$ncr-mpgv<E0~~l7-ft8?eTrvJ)Oyo<P!mRf{#RFdq+quP7Lrc@{jR; zv4KDK+D#A6;Y9{X{j+PCqnSw>T*)>m5_FxxRM~N*32=VL)(J%oz#AyM|FJ!6j6_Sp zS!Y7$OKX}wSHzLi#9ekkll_!1kVHd#lqw-*_p<zroJ{sX%$5!J6$Q$=H5j;ATyPqT zLN}Az@LgVMuR3QE9|HZmykbcwM=e;-2Z*n&l6yJ<4i<Jcpq`knkBF;(`f#t(;7>UK zR6qw95nJF>ub`*(Q4r*16P$tjfjfIL<VV_1c(zfZyUt*me_}>6ezL{er7Wu!n$fH< zDQykllq()%T7~EmLsx6~`x|O=dwWIwf<{pR&Jr<RRoF>DmDt&weZptby7+<hjQ&m? z@ikND@6@4?0hZO~U9h$g_=V&gU`qBqdx=?Un(zTwmVo1y=At^DxF(B&u*QT?ogS^Q z88Vq7r6#!gC>STa`WeOmwet>)K9!hl(aPmOFt$6J!Ws>jPk5w%E26|cYOwNi2Wzzd zMlBA_fnn{k4^y<{lZAPbV;A&adx$shPksv%;{L9KoRCP$60<>+{afphulHPEV=*DA z9nZ!#eKo4#W_3;Cj2g^}>mM8V|95;oChnpX{HTmlGA3Ap{SdlJO1~X3h59W@n)D8s zAR{zf@qLImUMA>9n4@l8$@PtJ1&$r!*Fj35+Zp#Wk}d@iW~3mC!T^KgAM#?H_PQ~j zDYgNEto!;QZ_7W4M*fy6`XS3~vQN(1Lj+@E*`F>BKm_IqP*NVwU32H%9);E6ogKX9 z^|VrXL;A|v4Wy(ol@qPhu70;B3j544*2e^w$XQi=69KNDF~<LUObgK8BE>F(D#*{o z6aRaR&xb%gBwxaPj`RN^89zD!zkw7w2Ix1xPo(GncZpw@+>dTFKIHXJ6*T;pE;<DM zsNXvR{@F$L$$FUo410hS{>U7Pz51s(0zo?CeUOziiq-0q?E5Ps|7zm?AEkd1U51LE z2<!b{n19LF_(xf!)IqhW%zyLfGkpn!kFrQeb!o{@sj&Zj;-vduvU1Oth5kc65<q@P z4#}4=iBH*z|0MyOQ6IEPA4p;S<O2K;A4vp07C(tT<7d*v{v)U#9sYyA>grm(mh7K$ zgXE(Q_ctgF8R>uX=o9@z?ho2H<5|rM|3hv>gMJ9y?;m}6|I47y6&<IGeb8pyXe{Nw zwZdomzyGddq^hL2f5`r<>kryYyO(Jo|5MF@1iDOPZSkhX!)s{~L)Dt?y0Ly`_ab+_ zaZDmdvc_R?B+fIFS(sl9*LtsPbg_=bf(K0)fRg6)_IUWdMq{j(9C0%XYH4X9y0&h4 zy55NX49`Y%!x8Oh%9ciNVr(M80fJ;z+38Z=blqH+zm;p>Z|-d?Qj8my4|W@TYyhhu zhnac)W#|8}_m)9%wOiZZ6GDOp0tD9}!9BPIcXxO9AdPqM;BLW!1qkl$?%udd<Bd1k zJvm>^IrDz+d7o4BW2S0;%)h&K)$YC5+G|})uKQj+CyHCQREX@gJ73}Je4}KcNUa&L z6QLiwPykEsC^5G<0iBU#sFxmk>P1Ur-yX_u(>`gBrPcaoe|j3Roo&2sqpc73(85vf z^l9fKv~6q0XNmW3WQ+zVq`x{-y70%VTS~gjYcD(AH^dDn(?7}gRlX5!BK{FK?5huo zyjF#hKzzUK*)9Ty_&T;OHK<hdTk!0G+HpCvHPbEHW?yGy3OyfQz#7D%>Lnth0H{lq z(n-V(S}Q;a>GkpX%RUQ}ZVMWHDLpb*n9F|p6FWy;(#jlPhZXaGGMx7*U;fms6Kx4V zH+G`49k7<h_T#+l0=xb{X91LWNRs*Kh9{ctR*xxh?=Q>k-D*lO4B6E<U4AZK-%chn zFgmXGt#Lm-lZm^6uC<<>u-zs!IIRZB6GpcvPxRm7OVd;Hs+XNNo<4DXr4=Te)NeMU z8uZ*3kpOn$;{<4g=-E0B7B1-cOG}kKuGwZt=qxO)kyKW$W~@toFBmUYvhPPJks&Oe zCr``UsVv8t{w|Z!z^c$4k^+jBJ>}#DqMpCF8qMEk>d;pxYj*7}rgQC%T#!KJM!qaN zYf+U&A-DV>CY~`vL6i9AHal)_sU+3>3w17%rEi|tes_G)$z)Xh%Bl5!Z&`jt*jTUn zDU^oJs6{h8$&;0VXU}x*(16MQf~>_?DXM+Wtpm`Sl0Vk9+wOEx9`)Xa5A@wi-h%GT zmajrUO;RD{rufoh4?K0%3BB#YCth5OjfID$xyxs4Q-Ay!0KnwYz3Yo1=C@XQ1A2Kj z8DG3x6-?Gv6on*(&}Pd1Cs=U&IL&Pu_590sPWkKQQZA(;!SfcUj=P)B_}%BlXCfZu zSY*L?Ejl0t*$EM;9){xpDPRH`jjbeWOE~-<$GyT#BT8_zJ0D-m{Nh2Wceti89}y>2 zV3rV~``ath#^D0ZiVWLzLPpbI*V4ABE;X2y5}ISVeRXcwfYpR~*!wFrRgYam2{|gR zR$@sFG!V*sOb$0Rw{MFvz-K8zi&4)mZ*hHP&%)h-KJMR%zGys+`r7I=$XwWQqYjTp z*$_Ye6IvPY&(Rka3Ww6NtT<OR!N49_&Z-nX!dGh^>2J}S0b`3!KgS?*Mkh05*Ot&@ z6uJQ6FIn6!s0=`MY<OP#NyYDVKp(h)?r{e3RCC3RqelJ5#2k)9_v3jQ<L1knGULGO zHnJ({5h;iO*&8hu)tvgoZ;$Ij1`=K(<0l`coMw(I%jgo}gO{Fb?Qd|?IX-Vxq3WT0 zTmDaY_!AAwrl9&w$tH{dm2COLks3l*?0SO%IwmewU+||8+qD>!hk;0>Q1mqcWdjG} z?ESD_TieQ^^WV30-p`V6@}BivGoSTlJh?W%+9VOkkh$er?@#rQyDo-{(}y?*(0>dJ zfRd++m}jUh>O2gXn})-7R9{|ur13n`OBpSC9bupO&@!wh<#n7%RsT`)NeDAu#3Zbt zhGlSWDF4LEf!#aj^R-?^5?14f#zVJq^U4)LV~e#&iSfe>xfIVZp~kh?MPOp^L*w@a zpC7K9oI2U8Vp^N&xd!<ZMa6<bqKNYVuV$1AEKHIlNPNLOB%W%&ZCm^t(1$b6rRAH5 zb1^XiqrA~~3kqRYTE9_nPn=@l&i(tC@U!6`C>|K%LYG+0g%zyBaG<3jfhkS>5se9d z1xp0cZUxUFJ0a>pAj=6|dU-HoIPze=|9ua7u4-&X3zqa6h?Q_?xywSK!<&VHtbK!C zLxlSr`=eq6qtnr0HO?{l5WT}pcz%WUAC*Y`H4ReIf4~jCia2kw)sbG28PDQIFJ+!p zI05GJ6u?;ZFZZqkl;x<vDZ6<m{38hgUzU;+;sk@~`PATG?6(EJV4t`M?sp0~v_5_X z4RZkFjHCqXKUpt<M|Vu)WLj!4C343QP6$G2`onx30ZY#K56gGqeQgod^_8kDr^-{; zb67?!o$STc1E&4vX8%wmuQX!_^X<<5?=P2MQ(Ud-wUh~xbzY}OBIdupm{629z^3u{ z-H0^;aDrmG2<@T14HJHy*nI-aPubc6|MAG+PdDUx!zD_olZtDJ<XYxglL@q_86;-( zglAW;g6CuQaznmaTs{E5)1l<WRnT|y=nF9^Rh2hP1otYu8bOwcT7C5WIAy1X*>U+` zstxl&mi6zwj0N<z<0~B}2U6^J3k$nRQ~J{t`aCzM3&b6)hcQl#NQAUSk4VS9+M057 z`A#-`pS<H_HsS_!md;3SPLpD9u6LXA9%M*i25>Ary~0V(DNzW-%8Sf43)O!J?=#u& zp(p7MKOtY~Qe}1xDb5movCvf33c1$Mfxm?Ly3?3T(mX-rFa7q`KKwq#Z=qAnka{O9 zs^3*Fl<_Xd?z1xR%%XR>?NCb8UsApLme0)^Vzid>*=Es-5``uyrZk?T$qxoyRYVQa zp%rT<pgLNXmL=}36-PT*=7orZYw`wA{oa`3g?~}{%Sj+Vh?zrq@@Sd(h(j6ME}u&o zrWO~+v>nQ|al|pi6l)C1vsr4cE@4{X)s2y{>a71f*1W<D@w5VL3WE5H4AR3qJQNv5 zroXE6#;g~F6T7XRM~A8dc}h2XS7yJj0ASIr<`Xg#1ks}YDSQ?ab>a;rNte}wHJN)y z*#RiCPrr`y5U3672C9mP)CV||k2CUJY~MI_X&m!&nxNw_Z#vbDPU#U(k~pMtYb`E_ z`h4pVN6Krf5#fz4=X07EIF2l(GdgPEIB$2t+Kw;hNfGxFk#&jXyG0_mgv8fwrukR0 zw@-OU1D3%o$C<GjoDNB~0Etm-Q~9D0!11SDcNNgWwp4~O9)1R#u-0jZ`LAtNfXX0@ zDkBYapOX=JBX8+fa7v~3#QX^<G~(2IyXB*|FErKX=@DwJNqvyKjYC0nJ-5o4MRHez zYmVi(Q9^@MWP9u9irV;SahjJPtxH#-6X`%`Y;9OSykt*q4@9q0W_8cLUK^V9o*uod zzngmO;@T}xwqUX(k55ywz!-g2is1>*YAqn?gIsjYZ&T6p2=YvwMchC>T~yYNoq!DQ zF!-F4xnS11R9GM5PsKM=ynl2*3Ch*2L6FEt)-cn&od8*GAU+wP%?)^gW&JtNSdQ+K z^*oPUu0_0>uO)@=w{hPi(>hI^``t6;yLV^r1Ex^$?I-kKXRk1lrro3gOuIMsJ2TI) zv8}KjVG+=-E91Rwl4T%{FDBRSK<-+!Wu){+4~(}Jq-CY-(0#4R1>_*=JB7>)K=suq zfXmys`PBE<SOBqk<ro1MTG@p($WrI~r$vt|!(Wv~cLw&)h0z!HEmeHrwpc;u1i?~J zJ0^^!^r~*7X4?baGG5b>0Il_?D)#FdtG?4JrmDpRombo){M78aH5~P`<~=$qXaLz) z+}cbSo){*q5T^~dQMzOk`_|4i9!NdJ-Wi4D-cBAa7dLHi7bu;~ULoshGj8hk*-L?{ z{K%)8bsnjVDBM1<#()3lAZs;IqG+SI-oPruOL-<BMyR!!QiM0=_Md7V-hJfy;A+X} z*Ups#6PT4z-4R%^GVjDcKVx0iaxm=_iFV}vFpi9T!oE*&yf$LWgt@ifJxJRKdcMx_ z4nUpVXFdL1ZFwJU-JcW{BKQ5umamrhWV9*ba*L`EqXR#*FTa>8%7(8VP5vO&r0gn6 zmQ|7A%4)o?qeb_e{DI4KY}fLzWfz=ota@VUI{6lFCxga3f$U-kKKP?Thr?IclZ!W^ z!+fyXmmS)(IwL?~ydG;Te^^9o2>EQpa>9hhsXg9zF|Gk=G|TdoMA}fFhv-BF5#D)? z`Fk)i!%2L3gd?P>4KyS;3N7lDp5prRrHf6f@5W~F+IfZX$Cy&F@62|?R;hw$nae~J zU(j&&FrQwbpZP^R2Q`40&8fAzE~b_Q-4Kk>3FdsY9s1AwPijtKTVSo>vH|EjXhWN1 zJDL!^`Q1(~g00D(e^Gj($Z$5TURvCO+1a?Q4t_FVOD7r6IN}!iq3<dX`?HelRN9n1 z`?fUBnztIAKUrq!cbWRZBYa^~d5vA=FLV_8>001e$->j}r%|>#h|>qbW>5vw?T}?j zbqr6#D#&c5-J|DvJbjV*DIjJo0_!qKKi!*>EQevBFUdSz{@1gM>RS<e$CQo>w%<T* z4CU6hi#pq}$$U<YiY=ZYt_k|gONKS*17ke&^fz<cNqE~ZfwxZwzj7Gvf5Rs5*-u2d z95QoQ7~vnsv)E==0m&UyiC=l~DhOgLk}Rv{>%ywuDl-h^3n1J*u@cwZYRj{UboVLq z?sf|%3;D3ts%6ipp~X#6LweNKeCuk@{m!`CW1kfT{nod=?<40^1838;%%@wF)-O-q zk)Un1qoh*>+Kyg;bC;fe&4qj`5H`L++<+BtYF9~(wms&V3Uvsr1f+koXLpc^8Jd*a zT=|19-2=5q=g1o(75SV_0myEUBtC-AxaEkd!k{PM@~N2v>Jp?+w;Zrg?#r%&J3I0; z;jg{Ce;~w*a}QYF4IU-rf3tsmm53TX$F#|ulMKOAUA0_bbYx6{9#WhM*$LV7R9ai- z?P&*0>7?RUgb#Z3naj})%|A<C`P)~g%)ESttVTX?26tKOL|j=Vn@0LIT?$uNCk{W4 zH9I$iw2xl=M&q|nWs~4JG5wxX>PPpS{l2pS$J*HG%%EX4<tC@}W@uEv_)cGWwnQ*l z{ls@;ytIkR(4QHo8#fe&+wJ>$IH%2>4WyV&t}~geNt^(H<+20)*c;#arH!|$caABj zbdK5dy4i+|AI+M^(4_*Z;G867Ku(+vNe92hdCNe^LCwxb=8HDZtOh6lp&#0xNlGKD zN3%o-uY`#LfkU-FAs_-4vyO1~Vd$jI;K|hFP<b~OCy6@hWKZqB-2L1)2=_=8VYtD` zi4$MFW^X0G2y*<@>|nl`c%F>)e;h#)sGjzv4O#zZC{$*E5=Hv+((}o0yf7K`AmRZE z0@!Xlfh5yzmg9Z)LwWOD>IG88i%pI}VSGDb(UtVgAsM!wy7G0WVzc*-xoh3;$_q_X z`L*asBqCbJmpe;3FNufU*6S|<2YG(0A11zQwbdZvkYTcYwSD+j6Q}+2!p?X4gLn~r zddX@d`tE`E8G%y-<`pSb+I|NZ<8lLM9r;Lu7%#FpA4T%?Jr`o2NDO_5%cy5;1Tv>z z5IU_JW2~;(H%4`ImsCKa!KD&5l*)gDu1iVVQS-g1Lc+E#wHDt2Z-ZSY-LBI@5o||D zYaPT%KJ?eFav{1UNw!${q{M#Ec1aao0-IS4*sd_QqvrOqjSXo2?9J^d%7+?$ho{WW zI;z9uW``~;mq}$*_#=r$#NcNSYjdJbp7%`$8*djsOU(VP@)hokLOsdXF5t&e?U;qT zFoM#)xVui3p!}4YAu2Vg{`3sfh+}NCpNpqxlDFQZWKT1^11e?3&`OT#!%z-%VPk*e z&!bP&oBp|8wy!6{ghOJ`q@+NGU)t6m$eZzKG^XlU=^($kqeH9Czwu$GThad}zuU-u zC4|2D^$9D!+t1iXwj3a8;cuycZQ4V6v_uU#8Zrn>rTlf>pqO2treHs$el?Ni{hs>! z)rxIy(a3Ya$IFNHX7J*0Q-|NfD2EfTugsojH_WmSY8Yu!$)G1ALFJmi$xOLC4$))w zdbt!}V+{14sQ|5CQv!||$orb#<Vf@?T4xn*&<CZX#8UjaRq%tnD<C_W^=o=VEjlK= zyh+RO)b>cqU=r{+R=r5FQVad7VukZ;@DvY|<aZhikT_dlu#>hon-Z%~s-JD6)kCf6 zAe~)S!X6;exoGP!S6KfSyF#tU;U;{q0c&f7xmp3sIk`*auybhsAxURy0y5k>G}6sK zkvRy+1XU20O>=`PUI1yDIrR1Q=a>JHlPSgvyu)flPBM%G7xZ(NAbQKq^uAvXJFVtZ zd)jsQCd#V2F|?P~RxodTE`>Twlp4M*-WBJ-_#E1N<?L~TP|>002^UO;-EdpT%OKXz zn=cMFq&LiR4hT_;WhYS1UlN1VT_Nq>_f^_f6q>#6r|U5L5A<E%vLAww{YZk(HjShw zN$U)-K~*p`;Ado^sSny$z5{O2k7H|@_z_slW-fME_{S}gXdWkv<($rKuR7)mh2D8A z)%y_TxJ%LnUn=b953^?BipSe&aKOLi(ss3H=X<sMsn}Vi*sCDHKtc6(N_32H;)la6 z7C|02Jnj}LtcQgg=h1lFJGKIXLG*&aRa<t1<}ghG#W5_Dm+7^46Z(UuT9VX7w<j-8 z&Mk;}Q+m?^RPx7na>)GZ@2IxHAl7YbTuOa0na@#aVKjgVR9}h9tH|)oBFx=Krpt4x z-IvEIEAJe@e4~8&&j;*JGI<|!T=y2?F9Qu7UdSsinGJNR2N8BM*yJ+zxA&QsdjZ8D zne5;?>Z%a@5`Q-wGVeXvv&HFS-n^9SH@OhpIA+P5A-o4m=+Z0Kzg84)Ts7WBDe>$P zSTuXAoHL4#fV1?Z?lRUvZ;?&Z5@xz+?Vy=tew29=Z-Fhil7Px@_kh{vmi;^B0qG9Z z%OGUZpf}t#W0>Je>Yy0)N;tt*OrN3!THnSiHR9(pg|pni!54DVQFT@d$d1zw07DZp z-$=ZB0LImqW#ai8QSgK>X#1cvr<jB`X5lTed2ZqG@*IxYR<ad27pw6^?W8jZ@k4?J z;cS)OQCb4NSxGrId#=APv<^q*nb8eH!kR;;-G{lh-RDic@2I-wuslv+hF8#cf|%@9 zMb)Tt`f*uHQXC>Q<MmgNp6<``s<dKZ4=9uP4Th869mu$7TAiN;?KZ#5VP{<1#>lX~ zpR#`F;Cl5tWmC6F^i+^t@non@Ng`txUDXOS5lZmUwC@hG6par!+&#sS;miIUcSZWq zxRdJMC+m}&f@hZ=lyu)hqmPOK@)7L1R=}_qlcFOSwEv+yDMo4*qf32*n4<^q@{}Zu z>3R&Pu(8LhwNeiTm20+NO<n<|Bj(8+F?`$grwXl8{H(qFc+@O&xPGiz3aSy?u^)<N z0C|S)epyfA0-W>=FDkNSx^93K{@(N(z~)<D<<BrzsDkbHgIg6_o%#0T&NLNxvKS73 ziVz)%n9>CeC8}bH0!;!3gei_chfP|M>O}RRqH}b=h4RC-zqQO4uL9JZ0@QD3E#OtE z@&kIuxWP}bAFo#Qnxdnj*-L{~s9~q8g8!l%{)a_3z4*`d5au5)lCTTnOTR5wwZ3;5 z8={e4&x|wmx&}XJuf!(Ij%Bau);&ME{q`EYco8+A|73nB6HUO4&Vx=GGXL#DNKWmn z-l(7WO{|xAJB3C$;fdQz2XvY8!wZ8Msz)zZI`A*dt3O94$QVB@kueJP{e+cGwtMfV zf6W$^L4Qqi6}A4|`3+b*(?@v0H+u1-;g@Y#k1>0)g`&?}%Paer4%}<i`n4q655h*V zHQJ14(}GujQ4N?p#}mGlGdQTq*7@eq=(=+4lK&iN#7^XORzGQ0i1kW2mU(NWRe2?o zd=>duY8j!_Y`+XF==@TOhnLSG1zV!~DjiveJJdPmLmVGwC{VFH%1<iNW*8&tr^SLe zzxSYnf2D<Na}o#5nrz`WJQPfqq3mnJ-E!;Uxgnv;2eTALvC`n%E9bqrI%ob?Mkn~$ zY9LZfK?<c~bBF=~8QzXg8gni%=n=qeekNr|X(BX+Q^la(Ulv(~ev)@9OB~%Bv|Y>U z7c%YLQS(q-_c<>Rchc(M@VoY}RCDZn2fqZ$pV-&!L>meRjcuC}a`;o9Q=0w1o!yG} z3rSL*tLkUCJdC#1M0sMSiV8!%9`$UBHN#@>P1P0fu&M~<cw+|*ho@LwheQk#aPRi8 zP<*lPvee=fqoOX-84aR7(<EFNq*mKyBbR~fC=+{hZl2d<kZV|J{CcZ?nS!nvX!J`w zf1FCz=AHx?sj*wy5?)m%zvQ=I*h9#{=dTj9yeXTkPzXKhusDv5mhGLIpg*Kgk~jkL zc_0<f-e?RKuwlrp|F+EDcDJu;XFtZwCy%O3VGMiRDk>KVuFjgekZ|bkG!^Aw)aO|k z&uh0_*1lUi<n+ea&?+ZqR+qBaq)+F5u4t&jGf)!7nB}*Y@P;TCD2ef^U>vg}p>mya zDL^j07bSQN;}jQ5J%PbYPNliQ*IPJ}(LJewf9TkrJJ06I{Bh-LU-AQ=&O0KOkNad~ zmZ6P_4XWIlA*qi|m=OPS?oA*zMf1$Ng$YWQR^4l<z1YBcd*M1k-f=%W`Y>aM2%HKw zU3qGY3@8RBPq+W(@#dS}DQZFU2dcXj+k|P8vEqm{rUql|$HGxm|5?vZoe$u~vA7Z7 z5TtZ)m$LNrL9u#RE32_k31KKam#k7L8=oDT(|DR;&24se=vO`$B81H?-MjP-H7c{> zB354IrdilC;k{{XvD8uS+}#0H8{63=_F1;otw<kgF7F8H85P;6#pH1wdk2KSvj(Lv z=}rjP71Dbg+e&)E<`ia(n89P-5VD&LNIh*+9?hu=J;uhA$0erR%(fp;p9o1gZnLOP z7UDE$<Z`xWOfwBSkQ~0&usFxkno|o`6kQHZfSP27Fp?A_4_1IT+B7!Y3igGHU8j22 zit%=Rd?)TtQW4f#mQ%UrK&=%y_d@O7o23=t=l=mx{zX=HmrDNwTc!myyntR9RC5xT z!GCsiM8$7Q#HqmP$Op#6%c`R;Js`30?t@K-!B4ws>sH?81J^QnJKp_%=Y}V5v*?vI z!-QzPrp`FoRfM?RI?}fTA@F-s_QS{{>4ydT-vlEJ2x2%TWLgH|=@+i=F3mzJ4BXlX zrk=@f7kjsj)qq{gV@Sa*i5=ckQR#POo7-7#KD&*!>XZnmmI`4abZ>1R-nCe3$PS2? z<qXL5C55kuEb5fc?`AcUd|>5(3gWeV*d3H&cXHQ$XI?qeJ+e)LdnZNI;56}b-y-Hu z0H!i0-=y14cgLhTPDhLiPWFso=iLeYgE1diaHnXskN2g1P<va;c*T(>Fw$ldkx{3r zSXU8*L^=e=uR=hR`07l!!Mf8_DdyAHhtR8jUVa)T3^WF++k*_RZBeY@r8kE`A6w{i z#C}spC)}xqC?!1gU5+<q$TUgtkFI%MHQOsX)t5fA21}Cq3=<WDmZXzH1v)*suUpbV zl7ck;?q76|BxLTEsu2{^w+V0a7po?{X;Yj`nno+dBamA)UdihaEOu?sI;eKY>FnG3 zerZOKmiU;@q>Fidc55O;#I!+#N4P<x06_<lAcxmpdEdK$%$pN0L|~oEWbU6uW4~Lt z>joQs`|fM>-ZgGlcC2&tpypyiHay%g(Bpg3phGa9adIMp@`BLk#BPh?b2m@a%Nz~Q zaDqyIN4F5>^%d@%S9v2+N<Si2D~Urk@C)<x<vEXIhxHqa-Z1Zs{NAtEuz07^pDHSp z(%1@7fAXFtDcigwKs_i;{1hIZ8|;k9(a|a^bWDabUw$EU`B!7Zj)&jugl@mkrSWx@ zw%Gi`0OL6?(#;sIUkmQ>pWWJyPll*{ZTem!u6GKw!0sP$$nM+MBneD7o6kv}89O$` zgs=iwXG4xXWa8U{tvA&ybieUTC?J62fRTI0lV>geGsCys2J4N01K@q{o)GmWvvj03 z%Wa*9Q775K%mdknX%V-n+bHR1sN}bwbGBX14uz_%YyvV{Sj$P-WcA-o*tKz(R!)xU z`NyX;g;rl-3hC1rVJzf`-zAWob!^>CtwEo!L0v}KT;>tMZjvPB0a*}}<Br7v;v&3_ zGE&g^ZE?rOuU0C97dOyR=1M?L(!adz-xuAb5<g!;n8hrib||ke{r2!X`mB@9t(^LY z3%%XgftnR9AMsxeI!oLnh9IScycI_`z6F+vpZP8<UAJv+H#oNWS;<dT1Vm#GsI)7f z4<x9($^pa@@U2PzcBL4Ox1!OQYYt;WVN7B*{odQfO3q6Xx`^mabrd$ZnClM2BIY&% z&-*@nSUhtIHp@mNkXzfcrL0`u!e1;2>)wtVUc!vBGSP^kcr_?Cq_eAam__#%l`3YG zd0FJtHw^1Cx>i-NApH?1RPv(AG{uw82&1($C}`=rutiF&Qz7<wg^!Y7W(eeMwzg?? zs~_#msv#r85FQwy5p(0zr7vL2^xA`1m~6-bbp$)FTTPp8i?xq+_^RkAH?*f?Qk5a) zRrz|P;Yw9CXLX4g*IRv`H<p6g3g>!B#EuMIZN^I+I)cc|a=pRvbD!!+&+k`I>=^g7 z&&N89TacnE|I&Q6u#8EaEM4UPeM0}$SkN}Y`t4?9s(-_S+fWzg^x611<(Df?m)@Ed zkNd%Htgj{Z^ojiDTP8Oe;o8Ud*NqjAFy@?2hW@!l+OYSOTtF;_^QaI@x0BSQ)TvBn z=8&f&&&vAM#ZS;0-$VvTC91%9rmwoviXdKRD=C>Av+HbsCaaumU@?rHXLXC57@+jH za)8X&`hbWj8&j-YQph7D-(L9+zsf$ia$L&ix4GEj+<j#|<WCVc#Tl9kvOWaNKJeXd zf?=PJ$qE*5ZpA>L&ErdO*L-MK+bMj^sJ(Fp-Z4P>I(Lx*y#8BTrD+EBrN9g35`7bS z!JSC;Iyn4po&$hSxC$a&VP4f&18nlrj`j1vqXF$kW!|{``j@@9Y$7jDwO!E`2X+AR zu70S3jyEmKHUB<pK!-jk<4$O$b=yk_<uI4Nl^cqbPI>i>Ba82Zm^fEuWl9MLPgecK za_K4R6J0$&O@3isaGujcJe+KaW^;KVZZ~vdk(HJ@Cviz(w>%@&|1H3{i!$`SU8$k( zM@tjf{xO|ax2bMb@+5QCKj%Mf#OtP){An1<yux~kG|K7(Ou+v`P!fd=Kj4<gt6m>q zJ4CzA+0pLk0e7R8R+)J8Tg|-?wuRPCuTIWeh2ViSn8LrBt*5Z#kStq=Uh@R|=MxPS z0#jy1z?kD!YS(%%eVw-MF0;RF4GMxFaS)~BL+KMtsC-qqC)~w}h%g^qpNmMqH!nC@ zWx3${yEv-mig8cuHf_{SY(XH33XxBpJz9dxMpC)pt6MalUJ5&lVBa^};Ra56rl2vc zmHiv(7u>HOs8Z&rfva;gg%XvdPQ7=ZuoMq*r@6ao221H5*_(}L=8%LgdEW|gL5j@o zvy)VLrFzlm{jXC@i8d|H)5(O!6SM8-z+rVcW@!2=I<SENXPOyM>)fQxpEx2c1)C<0 zcahhGdYkHHeT7CYRS)A4he7!A09lByq;oF?GCGw0aF6+~`y)F)$0p3dPhP$qyjiQ= zAeL8kM(O>~=Ue@rnWD{OZ1LBY`?=s(@}@qW`(uoysGY(HA>*|{DIry8o(yH(yJKPN z;_u*^{hc_!4T5~`FTPuTnC~%ZIH_-9IezJJ>{F5iScHX;N8s}-wtwCuFd~xU(Rz3j zlM9i8#YJ+x(zG~zG0UdM9%Y(BvBYyq%1r@o(8Xvg|7l#WU(x8aDZYCs_%uD0?f-F@ zYVde7`9Y%hHvxx1;!9@*&l^@Bt_{r}Sq%B2($Oul8@h4yA3GB*cQS#hT}WPvmy<ge zcNL`FO|15t;vI>*xsnHVP{%M6x(Fe4+&9w4#8EMn)StN;e<O1zP8!j^+IjERneh~i zuQYUS`WIC(`sNbvrrR2zDYuK0l{8>xRL1!|W`HMwEUn|kj90-bq$UoX-F!O7`EK1d zvr18Qu>4`dviYIsdzR2zqo)q1<z^ZL45c&sMSbE4YopTJ3?jT@`A-{^vYruFG?x&* zODB;G6-2zCfzQp#ljCs{Hj$CMtESh7!9qrX^xFEs{@Cl8wN`1wzX)Th%w?BPWD-Q0 zb92?d*If3N$qfHYR2}f-jnNp#g%B)CU&dlNDGH$IlLQAYi{E0NDG^PWq@+ehyWJYA zW?Fthpzu!?CY*|WK;&5k@;cX57Xiu0h+rsW`bW>R`j_8KdA_{E#Kw@l;=*rC{_gv7 z;T%2CHz9TDVop?=<*Gg;Xy!5#%3MUO{S;HFWMwJbI!Lsz55&IS50!3r5mCAvAyIrC zg^T_3G;~Dfg`*HR>FWXCp_BJ8GTWC-OJ4sg)c4yFCliBhnZvr<3@AvJp;M8j-AUn& zjGMF$uIM)r^(x9ZnW4rC2|m_@44*8HLWeca&~VsHi_EB%C6>$x(69y$56Z?{w|DJP zsm%(Hv}p5^25s|_5Kb=E>+j$k?eJ<R17*9->xNbB2!Hd!kOm(*Y!HKAG3j8hHUQg< zVzrsXw^QOI3Shh*P6?QBjWTV&YuLP7nuQl|M}v>yxgBk<VopY{B;iQcqs<8;Dy>8Y zg%O`(7&Fo$i7647(OrqlK{N?0ghz=rG5Xv!YW=k~j3Awe%Bs^&N3>lDGJ&u0`#<S= zw1~%0s65<?LW&v12VaT2LwwU(Fl`$uJEl;==FKqJOpx$8tm*Dy4J^;#Pt$nCYNNTp z_jFn}1vzCXtxH=J8|-Xcqvg4PdC=1nB-He`A$V&_Sk<~bU_A)X91Cc1G+N|3r9O*q z^gU*iU^uu2X!|nvX>D^G*+UnylA%5;#v5bnw5+rG9O<xvv?AFvw=Sw%1;Yc;nN6WQ z3RK^O08a%u*6dk%){JbXd#a8uOn=`oaYFsxMS(6^8(4*%iF`=Rvrx+oB<Igx2TjNN zgB!{zqwXis*OSssbT&7G9)&t{U+Z6OfBk}{#J|uDYh(DZw1c>6o89lv69&#o9`ut> z8N3leANj5AXuZG*E$_De1up$!GIlVKz531p#iHSB7v^(XH{iq1zuwS&d4;O-4dK5n zLDAi)NR1_-8uSUSGkSideDtCWBB{x%p5G)52%|^F)OrsceNjq>-@G#RB(Sd0f-f#% z(U0^2Cc2h5fM3E$&h(#4`W8-@XW(MbPDX0Q%3?H0vM@&)1~P`rA~Q_ZM;)p;xOm&@ zFSZB=$Fi30#&o#NnSOVsbB{7C^!{F&Q%#yW@CM{arw!LMHZECXqQ7O8AxsR}lzWNV zOlT^P7PPx*$y{IZpMTV@*ycb4-Rg>56L?jUy&QBsdg7(mcbY@Go=;xz_lzOHj~$43 z9qvs71f`c=QDi-#2KM!>lJ1);OY6XqEOEG78@q{-d5Q(X@%ITtjr(R}7}v!&Z;oPk z#I<fcrfzO{?3j6p&#>-b_0S%=;@H71NfgZ_K5!}u2<BTE3ahPPTC=Xkg#M@(4|bdf z$W6h9G!-Ht3Gol7Li0-ARYA5lEsi`cBKB7Sx-XmWQnw>A)bG5(zNoQO_pCF)PrIY% zhx^;}53^5Gqhjv7by32pE+F!U$|sf1lN%|7fC30tJDh7gw7a(pUuD5lY}9IG$Ik<V zfv15aK@f5tI41>X(xtWMb;FGjVGecG7HC-;>gPX$$-QN{eZl2OfOO<ht=7NZFS4*Y zgd2AZ%gR#S(v25Q-*geFlBtTJSgJi%w0?szt^_rZ>?ZfH3B;4<T@NOIiR{4t7+07) zNmMIm%}1L+F<y>n>Jx|;o3TK_8@A==+8W^t>JqQuhQSt)n9@`FUi`ua$&Djz*rA+u z<)Q7#;EW&r(&Wz=eLO-jhwRcf?}_X~8u%5S$UGh!<rYFoZy=auj_i)*sgKG+yz|RO z9$O*fJ*demJ>MAWMx82>;{z~%?7J0*cZ39oP;sa&cgatD<@I@sf>PP+Q}n9nxUNWK z&+V80)p*r<f2&y~0LGp7fd2&eCQJZs5aHEx^e~*yoEE~IbgWag31GFVWC07fts0K# z?bM}pwG`I>fIn&d+M`u#yr|Y}REZ&&-0a9ZaT5j_eV4j;`gqTyu{3-_<?bxDd9>|& za-Ehpc!z~Ln((FWBRvYesAFda?IzTRt^CpdXTShb6{DBYz=y?8By=B0_kO`+em%OK zre0_C;4e}am{l!j-<rFE8-;_fyoKw~vZ<`{)ao)zP8OAV)Bc;+{TE+6_YK6wbO<Cf zs4YMt&2;*C9oeup>*<Zor5bgUXlv>F;)-8)KCfBt@D66}4`^zSrwBKejStR#6z=Gf z#<Qo<4}3-naCW6Ne?hwPPU`yLq8LQuqgjm@IlM#(FI{KEDS-9C2|OR=-s_m(6g_Ra zB9N1<9z0<_ZHKZwHM54VzrkpVVd`&P7NH<?7Ir{m_9`jR{5e$#wwx(o3JtF6i2RM@ zCXALc)BS*d0a`B4eKgZs7%4kc(RHd1#Wn^7cklc*N*r!-Q3ZYbsGA;<&+6y-t^w%` z{u9D9{=KZphN$5?i}{4|&(6+uhIg)0NR5Y!ujjK9|Ej7;AX<4&dZ4Ds@|62U{E|aW z<6=%nO!}RT{uNt==U>rnKWpY6uBw}me@(@i86)AxWet$~W4Y&b2KhHH7Lt~vwR7;K zjre)961b~&A7(6Gj%3-Xc0XQOPuBu68z{;q9E<g#b)Se+7l0*@k~bRQ@@o+!X0e_R zfxyxV1ex+sK!x$h;T)`<%mQ2IV&TUztG{UQUF@J+;^hH~W2}TlJzLji8sQQ)6BjOF zwR*Z3wDi@QY7f2Jn`Du7>gASE|6F4GB~u*nPT=os2zgxssTUsBl9_)OapzRY?mQ*o zw_}aB6yArq+V;Tv_H>AmO-5SzZr>(ho;RV6fssuo@5`XjQ)kzNR8PwZTuEJVZOYna zLm+A=LglD>2VzYx6?ZPVsAxT-HAq#2Ft>s)XB32Ra`yAfNo&>@*%QM(<xOb8Lhs9y zsDO!HEuQ5qI!Ps9NfZvNZl(Jb<H_-4c|jHyJpBv=mh`RpQY>G!o5&SAXM_iXRcc1W zG82EMTQSoOI_x7ht|g8W`U+&f-q(eZC2sw83^dkPr&=et-;2c^5BvNh_Ee(9NN)Pv zwB}RZ11(TIdU*5w3QsI|<JMSp6PVIb{F;-uNfWsJGj|7U*YW_>zP&c=48(oPen5N9 zRpHB-uIcPbIGy7KB865?Jv@8+^t9kUz6dIl=lSji;AM>&b{ikr0ax{;m!V&3-MtA( zD}+>mthmC&l3-^M(Fnx$4+o&#jMvOdpWw!nUWT1dPMEBXidzuf1woQzQrI}3r_QAH zAo5!Vmh&|wlPDNmdj7sF)<8_!vBhTu>2Crb-IqWv`s%Ad=Gu6{3xkU61aZzx+9gqD zhP8NXs-Y_1Gh&+NqK_QSl9s48gO`kxU7%Fp(Y-JI;?*~Pt+8WMPtD+*&8Cm$=hu&( zMiVlRFaA!CFBiQTb4tKFX0zXtw>>5xJa|`rd4fp-HwxYiyf46OW{6+hAakVCr{1Ur z@17&kHIFvgRTK{|R*o<>Q%eLC#N@Y{cuULXHEgs7V3EOlXf3pe)%^BFe|Q#;F9_{T z3;P59ZgEzk#ABD|;+V=vkp4U`+T3CJ#ENC<o=7iw3LM$E0!GyiG%Y+MMfv8Vqu-PK z#2-+Lmp%FHg6DpEG7WEVKj@~pIc0$TX(>dJsYV&v*%;x){tWf-@jo>p_jyY^^BukR zM{4L`dE0b}rRPkr*B&)9_JtZg-I>O{gAPJStK%#GKpdSFKh=%5znqmQXyHV9M)}Vp za>*h;H<6(3dH6X69gHq<Vn`AW$ah#r%&%}K)F>sU6yn!bLfoW}RdN)%ho?;H!ECKn z0%$v5DTREaJw>uV-V4W#9f{00@sMY^;XaYntGJb%jf*}{#L20^Z208ndF@{?;uB4U zvSWrF7(};E=nYP62EP&3gR?Z@mF|s_LMN|)ld#YH8_Cg3aiaj;0HW7jlV;r*O!az8 zmIsj|dYo}dFkR0{1COoG7{dAyg-mt_U0Gk?V`l_hbsu$^*9L}FQr|6CDHz#{NgYVR zu3brdYvy<W)dk`Rm}P#sZs7Jmv(bXNva_)*4pXTU|D@XMXb)uP$q-Yp{sO<GRJ*cS zrXS{{pZmMzBrPpk=uP0j{u^-AsMhBxarnA97uuxZi|?e<cJd4Iy0WvW{}HtA^9PmW z4L1aE?dqBd5**^p_32Dtp2%!(ihhJ)(ZM>!jcA_qOmz1y`o^$3*^39Mz2mRG>R<uo ztVx8fsrdsJ;-;D>N_WhrMw3I0Y+{NZZOg2>Gtbvw;ITI^jyrb@9~smVF*f%qeyTXO zJ<Pu3+##W5K2e*`L@Z*Ak|ghfsnOPv@TUWea*I+DV@~TWsPsE!y<oB~iwSdH2efLf z=XvOAM$u9isN>K%@kIKIcBsB6U<MejkAwtnZ16a8(|qZuiH3}Oun!sW20C8(N41bR z8JxMl?ys0Zc&FA_r<!t>1-=H?znfr&cCIoX98vi>2L)_DL9Wx(#}~tM_GgF`u@#Fa z^UkgJv7_xw4veK-?`@i#Vf;X<xBm#X3&wt#E^JA5#(;86#nm|(0`Il^Gxi5K(MG%4 zQ+9W1$RnIs?^{QUGgfYf$@^md&U?2qkSVm;#CPEb=KqlH{-1%@Uep8^K|de%rj2Qg z>{wjcpMQgC$GD!hX?}aFlffb&tJi0($M~1XKpVJ?4XdH#=;pb>0=T?y2~^E2yQ|;M zaEvqGT}QyCsdc}Fs0COb1|@S`;B|2#`A}1c)pj!7AhY~63>-f9lEhn(m){c!0bjIL zdZM>QjckZz!pQG-@mkDQ5fMle^@%U8Sj$v8ZK<NG;L)46onhM|D~psgh+!M{Z1{aQ zuz5?GChq**G&RsqYLwm0PZzCBc+Kz;Bi8joLvyb@ifUvkG-@T;{Ptw3-%Vp!e@M@! zcl0Q+!;0%)AR|T<$zj$7E06g5vo->^*ksyex^A3b{fG7+H5i|;43aP3P+3fS9TL)K z*OSrHR}|vagMI&zI1dm#m3T925c|7|Li)%L3t(^jc4sggo@`N38dPpqjc$wpL3KA2 z<R|So*2goIMd?)ui64N_5Rx`gyjJJVs9k*NvsZe`olo`s5Barn7Bqd~oWI}5yV+7* zketQz_!c(A_!6G>0Tfq6VJ-P*-@T6*!G-I}#oia!&3iC$|C8$;K7H4zo>0A)5~&fq zS&C(`AS0j5l10@F`uvqrN7blySI33B-{y&Dw&5bHNejZgCPuU`*Pk~Dv;D7xz8cE; zF9#A|x9~|HPLXOC&MyXEkzx@gi4gQ?vrL_Lqj@5;<{X2+`;fNd^C&q%-*`%q?rt6c zvLUV64?7|oaF+Wvu{UbBvZ+<|h&Z}&7yhmyxz{V9ac(}*0e9!tUOoDx2~zv9U)M4S zhmxOsLFcyeNP`<CS1F?rg3|q)L<whWF+Lgb7q^IABF|ko<x0JdYm@8vGr8c;zwO9H zO%LD$A=d&MLX;PP1;dBzI(we5hOW5!Uo)%?i6W{QKk_ka8wcO~`rWa8lD+BJ3CY}p z38SB7gPo=MjJG-I=iF2{KzwoD!GytXt9*2VQr5~hbv)V&u!qWz$6inYbyDI{8*Gn| z#)%2fVvM^W=WIMt`1BeoEFh;i?qVq@z?28t)<ZVk?k|zG+7df#edfHd<?&{!EH<}l z!VHqZM>gSfl$$XymA2KQX{!Nj%rtwgJ&|)C{NIbmf2FbA{`A!hfy|w??4RV>EdvU- z&*<HSS4r;EPA)4`kS2HfD<h}Hv|vg0B_idERdEpUGg*1=q#P6OByS9QKjFv~{I&yI z)3ezz%|rMrq2|La_d@s(+$3{t==GAngnqLt#+48wSk$3T9<#&{R!-45xRS|m6XQ;C z_FQJ8YvUrvFUkDji=6a={1F{3)3E+lqQl4FGn)?Hyj#*+ju;$mpK3*BI)S(n2eiq~ ztvV(q-k#3~EDxB^X99O0y+CFNoK}0rJ`hfL5kP?u&2ffimXf<#QYtl9!q?y4#-L|R z7Qz>k<M5}CGe)`J9o05NZqWXY%%KZ2)=~CavQ2Bj(FJ2LYh{hZKu`_-dl?XSAh5In zUPrSRzxdJ4LTx|iJ+fkvW_r~aZXAjLq8#nyrTN)jkhb(EF-_;&&!)Re!D4XR;<`PT zzuZ*-d2U@LFz~E~F6uv*Wt^-p0lxBf26jl_3eovz<{p@#<JnOWDzrjR8SMgvk2hk* z)()A>oaRZ|Lby>9*~s(Q-y8sKux9wjpJI(SI&@AEN>K%8#>Q}Yj8BR2E(_rSwVqE; zX_h+ZT`Dn7XHRs@g!+%3vfZLvzT%{i303d9y{C+!2IGYSZA`oRxA>QJ*g{mr39bR* zlJ(O(^i@{$9lMB^M^DdHNrzrwj^Ar)j@z@;o%URqEWcvlOb2b>`3Po4yKL==2bC7Q zx&)}-*TeVy10CchKVsjsh=jtLhO*x!`sd4b76V#0(KyLRtYJ&Nx!y8g#)pYL?py~9 zAPA0>b$Ggc(Qu(H!?$9Vmi67s@%AoG_AgA{m3sb6M*?%g{xw7S3bm4kPD$7*cY$dB zutME=2)L%{xZaxzcrB|^MtsOL#Cxp=Z=2^gpRW4eojO%Ceh_68)=~ng+7XU}O?k5e zIhp3I<VIt;o<?JrD_xZXyBt&RGHUpZK`r7L{X~Ttw&oV4v(56`o_`-npqbsrh>eKq z?nrpb2a<{93`yh$;*gBMB}v+pk)nbMEL_Zqx=79VL~3o{84ntQ^Q~;5mZG;vnE?^M zhp6YeDaoab<os{iV*{8^!saCPI11X`ZHki-FA;dqAL6Fl?%aR$P$&_36n9*gvr<Sj z(69ZF0BRSfWe@PF<Zw1Hd+{-5m{X3j?28Z&h1TJ-!9sB&cSv;_ieJYh;?nNFTQK<U zkTy#o$HFo<8J$eM0#2pAf{*R5(e55Xj*_o+!3h=*PVW^g{n38hjqy@BWnV5J8a;Wm z`DO`>*2=j*7a(ptA9<W)^$Z9uz^x0s&KyKO)!X0TWv}Omv3^}_t9~jR4ajE>IjX3a zEU-cIS1nenCCLKSlE_FW4p={{btPj}<KvvwzCWPfYt_Tx$#b$dI4VT=^w#(ChlMrD zM$2C6+boB&{wMgfL#ky2(P}<8%Co}GuTz2c;M*>6Tt>IZ-$|Fo7T+~)C$90%3)<@g zNllO7b2&I*^O^E^;^5^|G#6RTD}QU7^(T@S{U{6^%704R3THv7zWRF9KVI7Hy|Zy3 zOehJZ2Zk{$fOK8lW5@iN&RFCGm=C*`!{30@S2?ai`NCO70kNs;qmFd`O&zl#KWG~s z^rJ=D9rpmkd+~lwlbGQLo&3OGjVMS!UGP(^#}Eyxm2hgyrQP`25<`~=1|kr+Hw|BN zLbq9F3ECtNRi<X_-~Qr~mqREv*_P#-0Jk8hB00x^Z{UFE;7dWhG$>21@(!V3t(t2| zz*l4WUv)ks?gs%=4yohD&bk?0S=>qfy7Up?(4cwQj1D~dI(!U=2viHh<Co-JsROw0 z&)Uv+ipxaKd7Fe6VpGS?Ax-<vA$f;?CPe|YWgilg+UlSF3IS^4&wcW78C*;{JhvIJ z>9^)%?%E~J9WF3rP5PjVp~{i&CloBAtZaUeDeyHPQ4Lchb|^O<+p0;b#=i<bIWsje z&_8fCEL30Z{3PEZFzRt!{)^^ZO>oI-!etO8^`R||!h8cX2a<B_<EB90@=9aI;tu4Z zOTcqjQ34_ExGtL1EQ^x_TH6(~_|X7&Z$sXdf0CUi^&yP8O>v?~Y!SNf)wc{6VCSWN zHEA@I*Nw-l9=9OZ2{(#|hyXUc{SSd@KODu~l;Fg}$ILg-?-mJTpeEl<$2{RZ-UmU9 zF>sB*)pfeWL}2j!e%)2mZ=7kW@DJBK;_QxAPDbKjRiT2P9;6K44{w}vdhbOa+U7S9 zna!i?Y%g;O!7>kq4gGFNuRUjd_v*4LF8B`^|K82*RZLP4^tGgZ$4{BwWeQrsul2Vo zZypNN3ds~QiX0<_`wU-)I$I^QWe<@qOg-LO(dW$8swK<lrdf(aBV0WQ+-t=slM$20 z2gqyvG%jm9%ys)Zxw^tPrbc&=ES2|7mv7Rid`JqVmhPbWP?V{CK`{4K@+b6hygl8? zv}*aVaX|e?sNJ0t0&&sve6|Piet@(@&-h|bNApxpxJ+vA@Du_~kqll`Rcwb)lz`h; z(;e%{nt}0kn#nZZ1a>=x1HS}s$C9Zn{tO;7gL+4e@Ic41b>No!cGFk*y9bgC%occr z#0@k`HGV3_55EQD$}l;Z!-VmY%>rX$6k4*}<enbisXhYPaie!L7G|w$a{R01Znn^G z(>5ye+Ay~jz;~Ms_7fQc?8{BYG`q3B7%eU8$DgFIvyQY3KVb9REv$FmJRQMFB4hl* zQ%50TW&y?HzKT03X)XTNlRwNO-u;=JYRKi>HMVq=*@R**cnxoj-%8{RXV2QC>*A@9 z{&i>h+2L0DR52%Qi<&ue#&20=e5&2=E(?-FGciy^Fx<|wmy@2m?A-|oG6V}JQY@Go z>EszPFfBDUL*;YJe#0&Otw*7b=TFtF7*-zoBOzmB4M6hTq29$SIA0bdkmfm7f705@ z6^xOLm?AKHbwF@TW|*-FE%Oat7Wn%fLJ`{9Tp+W27ZaK6zuM~o1PDps6B?U=i54pS zY|)`iTGiVUR3~;eAyCvQJuoBB<gWNhk3r*W$y@EJrjMEuY-j%d>m<*Z%3nAf9MjPC zHwu(S-#1jFCm{7||6S*>n+Vs$WQ?ezrk&}ZX8Y&4p;O_iPiBBi{I+!LgaPPdM<aUb zm|Z(tP}ops)VSK_iRJa42wUJ$kCg?hQj4~s$0-B9CsSwP@6}hv|4t74GrwzAMkHAJ zn!84ak@T+=upedI05aH_1S@AsaOC0Hnk9~*W34UJwjhV@46Y`X02^_gHhxSn6L^<l zpgXqUJL3)2QwO%te->FsXDtuSh)CTV4*ur@{yRMp_@wqNkQut~xcig-pR~m{<L-MO zq5}96(FQs3&<zjFKcm8<qzo?L;9E<A0<Yw{b~^A8dFymgV-)1snJu5cJxqkYrOOG3 z!mqUn?EU;WWhfrd=aaFyxf210VcVsr*vv!={u?3k&sS;|dGkkR;090ZkN-<%RD!Tq zYYm>X+~o@@sY_#EjDM>BpLhN5f`H=xdaVzdp4cn;d)@x;cl_x}HBfhVr#86rcr*Xq zr~h{@$K)LfTeao8bp<2TzctnWWu8tW*kArR3*f*0ypB8qx`VDfAZbzTUuOJ2%k*Ea z{(n!r|6inkH?;r%EB!AQ`+wK3{vR;B?%!`32_6U)0<P$P{Sp?3-8J3goz%F_eR6=w zzKs*P<Q+|lkdfN;#AsO!JC&!nH9?K=NSHW}h&k6;Ov!)lN%S>S*o07^?>X(8Y;+`k zP@5FWVKh0&)OE8V9ve+qyLgFBv^I|Z22idj&;q;Z-t&hq^JVZwggj(yrYq!8KQfxJ z2OFEMLJoeU@$!;M{olcXEhL(Mw9uQ1*)NV654$pQ@i|%wP{0@v32zEA3m>+q(*avP z?uZ=Bu=tknV2bvdUo%iq@>%GG&cXzn6Iivm%!o!MktrdU@i{$H?C!`a9pDVa47;-$ z$05iy7Qc<^I5-(Zqq6a0a+%ZiA{aZKWQ%A0FwTNaET>XyI*^je)ed<!Im^)l8!b;2 z{iAg8E&bEVxvx5X%Ay^tP}P8(&A$E6c_1c?X`VeE)Ap8E`7=Xj;lBguzlVY9UIa#> zC9^f6p~{YI<k0%$qJ&hJ@T2Y>E{l_+9$^iqt4ceo64Iwh<>9bs#HgFKxgN?#9bb!b z=-2nLAq`tAZVQK85K+CLut%+c_QB69Wp!+jjX>d>Q@KnY(EV3}g(*O0Rptgs&!jYD zy&F#mnYQ!|*o*T9=}xY#7?e`A1-`nYuAOT95vU@%0CCGXyyiOoVLixS1DS6Yu$aV2 z3u65*Sp4_P^5*W*H;sFi39UxPg-QiSd-5gT98|ij<*vk`B%eh5@XxHn8qiArLE_6S z(}drcBs|eq?;DYqp*j%0XmYi}N)ENzctzWirh_OrI=k^kzFoGby!t=bd#kXx+HGAh zL4Q2KwIFD4_aF%_!QI{6p^yN<-66Q8aHnt!?(XjH?x*svz0Tf!cK2H8o9>%^Gp}aV zGv_z_9q$-3R|HD);A9(;vHvC32KUV3BUfGvw9vjC7*0>gHbF2*4c&UuVFjBxk{tYK zIsFJM=a?m93?%s9(fnVEK(8N)7IV%(@5zjv$ChWa;LE5uJd1q@H`He)WwG*{TpnY< z5j}qS5>z8=QG$1CX3v8c9Jr+B(c%VVdZ?!tCSI<g7X~mhULH5HhG!ry`|@Sr^M@G0 zU#Kpc!;eJMb^P!p&o8H>r;fI##(GkiWOefYUH<<}JO1-Q)!zFiAXwd75H8+2EkH|d zbgjJun{Nl?h#m~iROF)=+D?&tKxq*%RF?+CDF|0po?RoGI8@iOnvzszV-{w{lU;wa z;2Sk8`<BA^8b1HZM6N0UMW9HXM=VL-tY(85{b&K#utaoO-=*7s50Dng80DPltCE02 zgjLT|jdG^2*}=E;zn-j5?;KL)UXtI8?|zENr;Z=Imo#7){fKF#WwG2QT>31=?`J&) zENSvzPjbzj9hq}*IU@ux#$<4a3xpw)F!er_a}SO5b8%P+7ioFMqIWyF!VUA@eBNF= zgAG{1f^Tr0z^8Z!;9i{Vzd@PlE@%aT@@>s^&Z`mQ%?vL`XnD6c6br?=Xc#;Oa;dkv z-9*EupJFy8Up0DYds+_@^+JDXuZ?5|RzBL5yW4rZs#AlmxRlZYY?owaS-c&~o|=ZR z%#GChmXxsHqY3Tgeb^m4)&9J*kZEky^Lnj&cK2%SWp?$PZ9~YqtPr7%qQJ){WhoRR zV7yX1Iyls}yRCsP{&V2GZ^z+0^K;XZqO#6_$DRMDw9<q5X4h99|M})0xel^%)SqG* z#1z_gi?q%7HCl|i9@E^4Ezgz-oWtj~Z6sE!tNT(fW%y-%Y61CZ1;CW}>U-kI+G_Uq z%%htNU9jMIA+JdEJEuJ+4MvX?6YMmq5t2LUKk<j(pu(`#V%if!F0ajq2U4kIXEM9T zvO@#l6(HT?S2v>9PgF?Lbv}_&sv2?(#gjS};uIsT_qTTi#aNxX-<t-HxP2Yxt+QdR zmxc|WAcJo1-I}4dk%<@LAQ`<~6<S`%m)}}w^bF3NYjg>3ZNaM)b!=-}w)oK!9#VTN zYGl}tr#oY>8#c)GhULHV4~ah3L9-+GYfL^K${@dvJ0NA$?2M_`OsU?L+uGpIgQ}Ag zd-k9C_7+nS0B|sipOWmN5I7U*HF=p_B&&>sPmrye`66B-Rhizgo1AkmKESMawN4}Z zjX`UMkCtaYh|sF#9be#D0IEiI;5ZX%^^RI}*LqSq_Xy=xK>+hB&#|Cz8pDLlFR$fM zBAKp^STe6W#!CFStx%gYFgm>Bk@mNMWTHiZ*aBV;^sm!+mkS{H>OLK(k<z+q9ak+p zp#&f*v?5sx7bQh4>FLT2KAxhKo-|ybZh>fBIEB|5`a=f$*mH3SXB{U$xjcJaN!&4) zFIto}651CqCjW`(@%!R<)$JH5E^STJ)w#hROcyIM!a*~_E+HvVa22O&K3yZ^_)$k) zT`4-OYW)`Pm}jS(-IRB_hs9Bh4tVXV8W1JeZ)@-I?7sjNBjTwns|Vt+Oqe{+*`1=? ze96~0w;a7h`DbN$GA&0J%n2B*F;^*hDz*vv6BKj~UWRYYJRFgEiBU$o?<3dw|8<@4 zPv;$sqvqR=txlqX)M`TcE=vdsr|76X;BK<#^xRKmW04EU62y=VYF%=tH79b|Td5}K zTy;y$(V0$b4h4hKMC_(>zK!SB?ls~~Ypf>r%&*>NZ@jgHM4NVlHfFNTIZ%X<B<r(| zB<p-Ho^E9BgF97c#EQ?_bs~0nv-~bBwVAR0Rr~u@`3??r!5FW`dE~(JTE|s3gRM@u zQ^J#*b|i!@^D^6MC_<=5Xxr=aeP5`rwvm0m+OS;KAFQnf6&;{jY~;cYh7heJc5U@$ zGd9QHlAmzL?bWjsz-IIjJ$qu-GP*R-Z|LORriti+e-RU+kIx~6M^|Z5xn^H_IK2z< zHk*WPnCVS>hf#hdvz>t*|02aHdQB4Ysu0!o{2F*hRqfyI>A-uP^yI*AS(a--<!B<k zBVCz|#cG&7=W4OU*ZGU_$xzYJJ!xngmVE%<&bi_}bxP(idKwnqPX$U-PJt#o1dD^u zJ11;Bmen6!oKQezIpfG0mnG?k<Gbm#^sN#6x~1TQ9~2ea#;3rMea<^Ve%T7xRmDFE z5LxX8Fp0!-q@M|or)3J!Uvq8^;5KTm=_iUKjFq|0Q$>}m7({+0cSjVb$3}FkW6!ei zicb=lf;aDimlacthWDNzv^j=^2`X;sr?`QQ4Z>Z<BsSKGNH5c7WJYJPk&V+jfyj7a z_^sBoXgZ2s<`bAfGd!8*N{d-~JnBZHb?+$v+`xg|ew9(Ke2UnV(7?5mq&bdlWh*)n z&JVc;b;(Wfn;-pX4_@kq6Y%7$gJt2)R!nBbstXHcugG9`hJby6p*I2pA0Bfsq~k;v zQ<Bd5qFMtg83KlKJ))ylQZ5_6Su#%L%%XJlWo@PzN%Z$6=d+Dm_2zQ9l+5BRRTQ*i z@3I{<(D?_xzJ#ks7Ap8*dbl3B(8uv=oLSu9d`v3g4k#Dst}wd9tAH;0#-sII0lSlM zx083((12?Cy1Tk*Pc4w=mq{u5V6Qbelv~yJq$PRs)Ijq5BJgPE*@rLJ2u5Lit`j>u z_Q4m=XBC$Smt=aE=imeX!-CdW7pj^?)tlDQcq)aq0-9|INQ{~%XDVS+_-o{qrq?zW zc)zZn(xwtDzFhdB#_FpEw7vJpR|z@sYAj3z%C{1y>Te}F!s!iTEAt`mfq=iD<FmA{ z4U{3(PVB7#5-l(^{Nx86B@SKpkt7V8=d~rH!YfWoQvT@N-dl0TeWk0WARhNoh#dBj zXV~3qw~8|ItKv(0pXbW9cIpjA(0v_z#H~N^%s6g2F=e$PLgfmv#lV?kaTJC6@j`NY zM1a@CO7b|5e@myaf+xJ(DY6gmv8MTlUIYDaud!4HW@RcUK|YmG2`pg6Y8XbsmWQ8O zn@~$t&*|gU8hy73i;Al&fgR81vK9yvr$rP`0^f8L<#==@$6K{q`X({Y=m0lXny5oC zE|68o%#(#sZq1nQTyo3JFroXU5|9@`-On_B1Y2rl{%d;H^`U1SEj+l9AK_=ieAKcS z{E@z;FHA>Pf&rA~5{CyE4cIJF*7k_=z#3covv*iybB^X!d*hVuj*+5*qWYC?<oJ4k zal6b_|5k!l_#^e__x@sj`Jks17yOZktn(1`EpnuO8!Dv!9Z}?#>2K{s-Ba5pY;D%C zqIUy4%lO?lE!sQA0jy9Ga<MS>+@B@b#Tc_oH3o6>A`#=W1_%%0O1{v%p(Yd`ciW-C zU%KF)*cjCB-<q_}AkbVOzm$w%6r}K}Cb$+WWf4~HEz2<sx|U$Q;NG$!n6W32lyB|t zM>n(%edKoM4x6ca-cG`o(fP8eIK#e8aX5?=d)?CjQW043OaoXYUVQbi3yDW-n(z&U zpT4J9GcO^SSDbmSj{LfDHTI5XI5pcRvb1F%+6%pF8^#iAtgQum1SDA7CmyXDg|S6( zdOcb_-)Yisca=C`hY8m4)(i7&Jzisjq^23ll2ZGdVDLHBzlL=FS$dX)w}--jYozqT z@EFi5aogtf55juZV?V3d>I7oh#(0?&;609Lh8;nCwnRf}K|ur*9QmbqTZ((vz?pob zAd@faOMeH$)vG=>L7eRRHW|A~)^|=7YIdi4JmgbrXMaF!Em6H^9*x{aZ(H)}M_*hN z^x*g2eZQW@E$Y}}7j05}>2noWiUx=5HW~s(iB@tJ1O51Fb`;U~#;o9Z=y)n9*j$}x z5%gl)v!%D_(}ls{=^@nE626FRGOV*QjM&eHbUgk&#}ZD?&0*?zucJ3@;f+)!V>o>E z!fkNQDG&TsHnAk3>AsJa`nbB0lHWqH2%$NvLj~qY7nq}7b`O~KOjyp7S`>UqH(987 zY>OO&dxPDCzY<ygh4dOf^jSNWTO5toet=~k{;)%2#szpH9!S8~Cw6Sv^z^|3FcB3P z?%u>_VhK!ufp$*r5PW#9y}55ek&cWoXnaFk-z&a$4zi2}54snU{Unzwokvw-1xB|g zG9y??c=r0zzu0Te{>uEPEdDzR^Uo0f8;hu5ff_`!I!_=gj7KL0Ef2v-;pO1a<zNr= z8fAYX9A2wEhhnoyE36x=Czr1Up>7{`n#z*5ik^y?Qm+o&#6Hy%G)1YaGg*)$iKeE* zl6gA0g>gonwe}zxLJDOjm;Rmc?Zlb$BzeRexjU;jweXL_!#1M9rxX<;P&6`<g5A#S z@#H*kL2|X!TpEWhALeC>(ygdsyK{O+TC?H5@1?LhwFR=qT5n6xD+rY|b`LbNDrA`X z<TC<8c>P{+MPH-S6@_6_n;TG`PwX!Vn!L;yuPWi7v9Czb_zXi`>Yo)Dm$!_tCZIL_ zKGW);d4N-ja$^(n7e;)P&Y;|~Bp)DA$e7PFQ?nS<M?%u_6f-}BV3m@HZsa1E$`?H} zBWX1SPk|>xSq7wNohmbGF_Pp_`cUqKc9@k_S3CV+zBHo0qif1^nc(pP6-OLlK%+Jg z>`Tvsr~5}iS`Fj(;WJ+ip^T7vGjqho=o{fG#>TuAMJRHaCZVt=(Wwyfj1HgeL9jwF z^-*(!nNh<a7U#y|os`=8_40|xeKXjC+&HjI3Xh_NFxF<<<RX}7CX=X3`|LFXN;8mR zQmQUxzniubllvg~e7}Qq+?W2nFW|i|PR#BUXORM%?Wai946u};bqq4Vwg4H>EpS!Y zcyhDufmaxagdTjEj2*nm8vv+TAC~8g3y&AWkGT+!5j%WKr=gO(B&LwKpNtisPw*hq zl+3x%QibZ+gSRK#Q?1Ri;f7YMeb1@$F0PL8AYtHpE*7gpxddlbB$CIb&D%{?9kJa- znR8IVORY7s)i~2#?Egl!|An%)FT7KOxFjQ;GbrM3jgY9|K0$NH!Wa|(#XL#jqY6Jf zquwth>=1RcB$-ZYMBGGlp=Fbh5B-Rh+z}J*vZzCni#@I$XLnRV%jlwmC{~5MQ+~Xv zP0Ti?v1e6^bN-M@>Bi#m#~^uAA8<V1O6jog4H7->2TYhXEn6!BzG#w_nf)H%%xO7H zR`^vmDGRAk<d~oQ)%pHx4!rUA(_B}T7RCf>$`<!*UYgsh8#1oj9mtU8gE9oUFz;<; zoe8&&Z%+)&hXd2Sv)eQ#_A~0cmt)!5yB(p)Hr}-#Z^yn@NTr&IVZQyxs0W7>pZf7p zd*TyU(XA81Mc%|x`t1YzJfEeyw~{DM`IW*QTmLX#yf<@xgw(<i#@qzycK?CrcK@$k z*PWmIy2mjRltlnej08^G+#VtTZQZ{(*#ATovf3wLRY)pelbh2-4i_h9K4PoYxCUBy zQsWV4oK~$gsuSk;sicuLo7(EnBaJ0DE`{&Zf%0Ok2;xNcNGF}PddM+)sA(}ohb5>* zu9Tem1lKPSo-U=|9?nw8H?%-e#D;Vez>ksiatu^<h@4X*e4E>c6Z}V~I@y;|xt?vt z_afOIoBu@YIOgqT&N9h+hy)z>&^-<Y`7n1ARCs#$MwUQ~TR@u;{YyUCw9y=|zQ#5p z1wau^&Zl^ul{-(|X-1b+?fu=EuW4&<r~59$@S{{ldQsGvnlfI4V5FTT+T)$YDE`{= zKvM9SA>7?-a;J`CMMz-!cwd)L;MNy9Gu~UI>(4{ysyLuRR2xdB3~2a1S^NIQ<kcPd zlWLUrB|oovINK|1SuZD?b7p3S$n#{W$x7VN2kLXBOpej25@L;av6He!6(iQvzE@Vo z*n$SD#m*fH!sxiHQ~rq50!Ca!MZ3-j<ZM2h4AD%x%{%&avn|fhpr)-z%I3yboR5rB z8eX34p~t|Z(|6N-&M3Fqu98qE;DfiWunl6hH+)qiYeU0l4bPX8sdY2<v@WtGCwKqZ z3Hz5~X7j~Du=@N02c9K%Z7St;R>qFWg%&Omjn&^)jn(g_vxUyPz0I<<?OEEU$A83$ zTOQdKQA)+5PZjn27E0%qX(jqfY!dS@|GC*C4>5$10(aA$7PnIqcXsrr&Lhr1DINX; z7Y&8@b`3!u%RH4Yzv_`7@!ngy7w=zT$0P2wS*Y_{aJ^=}^!*Q$xI9Yxglqh}6n8l* zsI6nruurq^Y!6-XTE?v7fFlMUHM5Vebz~&pNEZ{m$<5S6!?g2*pOTlq9Y6d!Iu{c^ zL?IO0(6xBj8v7<<q@`R>f#c~D5S4zKS{E*xvVW>_GO4hWXQDnoVPgL883U7(vEOoC zC_EKXhlbD@<F#1U#n!7W3;5<NkL~=yHNaCiz3)-A;4O+bMJtHkVyi?zul!LriZof2 zAs9kJbJ)%k^<@TihaH?Qxuw>)yvm!j%WQm84Ec>EbnGg$z!UO3m=u_I`yzfhJC5ts z@=h-|81drmQu;Q08Qf!j)+T!KJNlVAw>Rp=&+oTWO#*)`TS=MVloe+f_Z@svr_D?v zTiD&6;R2sto2J?CnCvalsM%zM(`OG!&rsk0p?p;Y^^Bo3$<H=>`Yj0CP9h5A{WS4O z{WbHfby*{ue2HWC*KZY8cHSP&-TM>mn3JVY98gpXuUN%aR*Atty?IhM&|tbzAwqXl z0PLBA$YbLbVuxtyeM{&A>HJP(MeK@g%Q2;o)F>>2TldQ0v-i{mlw9yw2SxPKCdtzK zGVH&=)wJW%SHQM@!&}sbb^ny^?2mFK_!et!BOyFC;6cQw_OmzC_4V=1H8g!}z|WE4 zFNWz&XY&;>j&pCnR7nWb0Y0w5pcUjAJeM$Jo0fJYQfhg5nSOi>1vqV{DXs>xH0b(w zl+dHIIhx?`h?Vdb!GF209uWt}YkR095;oSI1}0RCl-a+kUmcZJh#ewpoO~{IMJtNb z`65<(AcVAK2hH>pbZ~0&8@G;Ug+JnhoYfYJ&sxZW;TDMbTtY@6yDt@GyTG$*2`9~f zn8@RTdmcD>P2|R|8DR9QeQ5aY5wD3c$_0eR_~|EnYD`N(6*+el`45?Nq2<x3`|Ud) zyzcef<&$Rl(uEZ~q2W%8tRF#M^^UJonqDJnO|;v<jhaV3eNT4Z9lm1?N<8!J#)HrD zGvf!Qot6A-pOho#8EvyJyJhysR3FnD@c8Rohl|oVZKrv!`?CI%f8LNX+`lmLr|F%R zFBYOzjJ~*>NE3|mUIT>Xdthg$i^U=!qtAD;#yFX|v3#kW%p_H#CWMygbdDYI9M=C3 z&{LbjrOQa+SfU4;uncKl4;Faj5E9Jd-Cg#!2|eObk$=W+7)8!Lm!QoduW#3FXoHU6 zW%;;F((CoHH~lv95(?`I_T)^>OP$x~%w`7b&Yx_Giy+EHZ&6ke-6*azV)Z8HwlVHl z<d^DF`(G6A{(_s+3Ysh(B~gwQ)HgxLiFAI%KD-uu>s$i}jxMzBVs#j~M*pkwxbVu) z_Z^05*9<C*yw@}#mv0;JOHcEM4{zU{Zrq6!-$gBe01pk2A5ysq)`m1iS!7=SrIw(a zb8H7q<4rpMEu4_j$MvnYkc^ujHpw>9o7jwjqOo&Hq5&zX=;%%F+3Co2#xzGWUm=S) zl>rG@IyM0MYL`bI*hYvl<y*#kF?LxSYvJBjYjM74L7M|O57`@w4s4Irg%(F>CM7iH zD8KkOMblDmB*v5r(juLYuJlx(q>s22XTHbWy8NOk!JMqC=FTCEsiu8VPd)s+d*@%m zr^!oB7H%ZLvT6>vvA1^=Jq1^R;qo1QI`*7*TP=aLEM^Ud3I<1cJ~9^cWV$?#ikamq zLdQRhJ8O(W`!k}r+Kwze9br(Su=9zz;cWh>n<V(Q?ROWZz}r?f`*Pld(=hl|Y2Ec7 z)L2Aaxd2ria(@8zYfKC}Wk(R;-MXbCXOJ(BYwjwF#$N#Q76^{qzLssh;Etq_Q-H0l z0a>?AmajAz9B*NtSbA;0moJ%S`0UG}5iR76etccpN<y-W`^??4%jQv)u)vj{7N)Z! zYD;*ofrcs9WZJVpffNkzASVbz`TlWY1~1UthEJ{?0l?HtW^8klVr=u|3oS#ub2%Gl zwlaNyG<SYnw+h30jLA<davY{D|J7?zgZy2#44QDX74NZv0aey_(SC(VJ=4MzLMySu zZapO3x(mv`Ik(53X~TtJDH`w`LlLZE05;-G<My1%eYz)-0;!y6#>H2Bq$$B^+(mU^ z9z;Vm7}Gs%!><iW^Wi@zQe$vJw{4GGiiJn}%#D_O%>gdCSCHn}vE<_E)Am5K_YN>0 zkDg;sw9)x@>Q!1DP~N~J*VBiWFd1~2G5Uvf*eBlv6f1ed2F>;@_}MX_35iRkrm@4m znWb>I&<RZ)5KHGLEd9H#Wy_W`?2FumzWbnuacXsyv?cnJbz{65LT@~0&Fc%65glkn z!`ZWk!k1us(74?d1)Gwo=VwY*1s1bRb(R8jFXA*&9^CJS;u1LrUN%`#jE|v4sCaGU zo6QDEsnl^t%&T)`i9_V{L8%5k2wOHfo#(k8ChrdMA=3eNCwnr|nZ+U?n0=V)^)(wn zE?;@}Yc9f8dI`5iB9a*COT)L24xMJod38T<KRpW9yh_OJYc^i)gzJtRvByCv32X~Y zJV1P7xffT!lth8SqP`qwS!i7^b}JFT88VSG5Y*||-zU4SF?zT+%d*C${gYyHKq|<E zw7MVRll{$``%%&Jg?Vpj&vos5ew%5Q+kUPGAP=(*ynNx3fXv~*12)@n5;Ak^2lH+F zP&US;qc6wuw1?sjqw2`U(8f_mAApfn`awn_+&e}hl>~HWO7-l%v$8c!vm5NPx!Xfh z;+}TWeywT6VRu7VTQAK-UOq~qIX|EwA22j6jz;w4ryMb*=#0fd&oz~2=_SdG8NW>5 z!w>0;tZIOxLjB}xDRve6MIsHC@E7>&4VL&D_1VEvTol+wi9~Yh6eV?BK^5BDt#}DU zSg>$>^?(;k=!xRXk>WuKvQ_2rz3`v3bo2sXRQM}I2-H4gc9y_c4!!Kwp`VfRdMkxa z`BPV0h0Rz^>tNgL+Ji`TRiaP`Vk93(QA&>A3wZUGE(TA0Rrp1jvm9#GXqk03TvGCy z^s8^sQGz;FLBni4h>+?S1y9%DB+^|=LcW)N>C%sWD%o~)V<fFc3*O2z3zI@2)@+&> zJWa%&v{k7yq8XncFUao$zq-(yvZ?)nHdn5_<ew}-sCaaPD)gwr4ih%r8b2N$hN$d= z>}hrmo89Qa!R|h?%510e%N3?B^<g9s+Wk?<w;*P!o(nwYsb|e3!9q_JY}Q$ndq8rF zS1%9$hgE2_0X~*;2UzdEwD>_Vz+n|51nbZp7Ot1!zv3AGy+!&TWTvH8sABv%hu6z9 z#E)l?jV2T^1Nh7rIzr>y0j;3-mo<N8o`SwuI1q|kXk3*LBAqsgD{W9j|8=t4BbL*G zv4=&Zw#Z`S)CBK#%%A?-qtb6q*?z=k#cakmdrQn|U=tLMihuF!Vzfr~g{beyed3?g z#E{a>P8Nx&VmqUik8lZ1qW$g(zex9Jnt?kaa*(gU<72k<rqrJyw^{9IVvuJNNCOVj zw#>qwU^88IBb%IhB0UvgMp-e4AsA|$TsQTc|51B7tDOcBLIT6GpJ)Fw!0_+71yX(D z&Q&?_{ulb<zZY>u=x?@|h?dLOKe3?yXq{9zy@eFw%aLLVf7DC)M}=IH17Xmqyid~p zBW&kC)Q?UZa;Q>un}4bqf4@ZWM+ogsxyyL=57p`KA4&aI(1~L=^8Ys{{y$>+hiv~x zO#g5<|6f|upODP<27mm`8=FrOJjjlJ+Ump%wr7UKktXXmhm!Iydi|u8$U~kt)IVS8 z8GEUspX~9mqJHXa<&S=;AN{4un%qL`y5ozffVKp5?ZM0Bb_K*YRNKT54qEdkCEdSJ zJGfUa%K2S5!A_)}@PPstCesyHuT96&H`{xv9LPE6$eimKk9j-Naiku?>GF(^IT5)% zAA+c*WxuW`dIH+g<7}Hz2+qe=2X2>TX`|gga?6UrIn+5st5+9@?f-O$@4LD<nI%P) z?Yr&%+3l@Mm*c~c{||-xmq5+OiZ4*K#B&ZneCYC4zn4^WI_6Qbf0Ehstf&9s<=LaG z{%-5Hyh1_mG#pW!hB~GIhDd?-8V_G{PyPAx()GRtjKu$*8>6MXaxwmj3oJ*?9aYYK zB$)qjDz>tSaEOgpPq_%3zJXAqfyE~PB%X<$AaW0W+%G@Xke2mA$}fp^g`VGAuJCA+ z-`?t(+4i^tS3dzA5zX99k)6?eI5R(cMRMxke(p598Pc3__2XdlymSw+>0Lq&1nLOg z_Dw+%nT)xVL9@%|{W{+H8ST}Gcc9puEVeU7aW$1B)TY}_oY|3I35fUMtOMWaS5o|m z@ACcD9tsD>t?Q|@w59s;f!^30p((ki1~K%EZ-R?&E@<HEis<H`zLLPIwGD*$APl7m z6~m}ANjz1|m6Ve0a>QHyOOXYAXk5{Wsn<xCPoo^>B%WyQ!pB=VqD(+CNt68BHVW0Z z?)HLeZ75Aq@`~-1M%IP9t{hpqP}B?c8|i`E*9H${n4Q~a{JD)`>b0gP<euU4`s40p z4r`se9Y=ey(b<8!1GpcMm8eRBk~{4XJfi5#)lxdQh362B<+3i=Gl_eQ$}2y6wY)Dd zh5+Z*>-{_|=O2ZlJ5(4Ih6)juZ$=c*!AZ^}5kKP?vv>NDC69*iinMySf=+Xuhbmmm zo$EbXV5ys|hAyxxYi(xd2Dxx-<$=r{gs_lFyRZ{ROa(Ylc{5Fi2m&UeU_W&GUBC8T zGs9=bR>3#)f@^@`xed4#&skr3$4N799wb)N-W^dbuiVc&j&B2+5K<m*btRE)WxOCa z<f2c_7<)Ttk{6VYpjw2bK6ZO`shY0@ww{I(L|7znPm!gl)JXG7AzMjE=}8eoYla4y z{z*o%){3bHnZbeH6e}KgpJe_I+8s3?RM@Y-X?F`W<CV=KR=ZD@r`#jmNMF>X^}@h& zZTVlTs-`gIRm6D%A$>4}pRkl%+xkx^C*`gyX%9Bgnj7&OJKkEr*PH3&I*rVixNHj_ z_=5~dGU{{b2A^ll(~Q$!!X$A~Jb9Y~xJ7^(|BRaZO=s1R#)sf45f|vrdjGEimcpHi zg?-`lDGNNG&<PZc*CHzsP=fH)Li?b1|HahK{|@DA04%kX_Qdj@N-tTESIFN514n7I z+*Iu-GP@K45o>RN5!|^SZKy_9t0jr6C0xV2IxbxFT`?xWy?$vJ8N->swlsS5!>u!_ z>x&RkeEUO0er$Fg=5{J6sa@Wt-+^a(k~7)sH1bRAU_Up8xYb<nl<Yu^2Z_rymksX8 zO?Noe?*seDP|+=Cu0FHeaW>dAUOa&EnPtaw?E6I17X<_DFlN<n`mK!PP&zf;Pwr5f z;fvfuPnM|Fj*0d(*MAKVho3oPy%9PYlwNCv3>|$ij}o)w8I`j3jIG?BxCX=vWl}ke zz7%2lT*@_E@yc@El;xBO?da>vEQQP3t5sp8R5#qf^q?wBGCH&d7wX?UCa}Y!m{(M? zQSeiDX%{u>23{#|utft|FSj#|PYA@HYtXl2^?SYM9!-qBiw!w`Du@fjfB7{MxCPc+ z3*ZEOOLXm#yM=H$Vj5m|(;k{7MlDW~2A86IYkErf4Oo0gk*D^_7LzkrY_ATLt;48g ze`@oROUdl(zM?3gQRY)w>%i=kvW`x>?GO|%lnY#)yDd&~+2_MArs-k1ioM-5y~%MT zm%Fj-Meua9N}Z-5t;pZ5su#fY-@UPJ89PmC5P9TBVcY&Qj>K*H@7}m{TDjO`bgf-# zi9lGk5EhaU=FhQb0i9lf(P2`b$K86T{O%z@79&2V1b1w@3pYBbbHCEN*}>wCud#un z>$GpRo4aZNoyj9{k80fBi!-h0@C5IR*G^LvewtS`3YLWJ>Xjb$d{|M10*VL2Y5U_V zNw1iZPTzl!`W!v@0(9w(KiM;^<hZ=|rB`5~qNQ+bc94ImoK9~HO)Sk<_*t+(qgay* zZP;6MWEqC`jtST=oBcZ5%XHQo%v;@n2=cjPq45uUage?(Pi3}(o4f1HS;@E5wA+v) zQs^MSx1rIjIhW9rii1fC&peH4o{{!~m*G(TfQNNf8GOjZ-xhd)10)lJCb!psYNk1U z!zfgRdHvF;SjPTK%%gzY37h`<rQvY-lI@}AA^NU@;8DiixEY@@JZqgfWTGLp_inK~ z`*J|IOD&Ilt`K9cft~+R?2N=#roSGw=FRIA5%+DJCca%&^?N*By9mzSiAUgAohog^ zW}0|vkO#qX^;alfi=%eb(GN8K;V_X`&OKT{I3gUKU+JqR<6ep~CrDPz&F&0MSN2?; z;ohhwpehaaj5y%AuvV86>hhv%XOrU$v&~E*WSF<$v~};CB&|}U%yFxfrz?W8jMxVB zCsE#x5wS#2FO2Tpt0dHiqqXm->d|F1ER%wm;!mVtUxM9Kd(V#ybe#wE)Of6LQD(lB zx~qcEWt%a+OfQ$SYX{dHc}IHiUiPc23{N)l+op+J84xd@)(ufE$hkWjRRlE_ZDjzE zjVEyv9_RB<K(@YGNQCFGe~F9tt8!LYj(+Kppl)N?OVEvJ|9P`uA{=0F_dRTce?44Q zgh~WH>h58ADY)2{T@dY7?Z|o07q_+bm=guvZQ`RZRZr4pf%i(k8RqoF3RnaRedP=a zy&0$zk_er@*UELkJBMsF?+L#QBsU`^-IKJ{a=f5f$g}#&jAko?HOUiEE###mmyDek z!#x(1p}lWM#cbVtcnx3CWvzPaz82td)eBn!J9?B_H{w}|-yO+57sTv8a^QtKTbIPH zx7Q+yU>xeR^_#HM-~R0Ar_Y84f~Qi9y!39}9ebvEU}e=UUlRM1a&T?s@18Q<6?pJV zIaZdOuw6IQEKyx>`lC2@U=%k}r$qmka~g|`k764(Z!=d2MT?E>?Ex#K-Xu-GW<=BY z<otV;_die<vRnqqH#^kKqWIgfeiRqW?%t@PNxS<>M#GULxu2rGR9{pjoZM}iS1a(b z2T$zIeSb5=@w`VpyhZEMbdqVtE9|yOgSi9>3c{EJU*eU#j`E5>U6YARsbKL{7)!GV zs39oU2)@z%CWxvX8}X}!^*=~#vXb{dev{bJOxuV1NR6ZTt(g5Kn(YU1IcC?cUZ3)p za0YKCecV@F1+I^X^c79RIQUt+1YzrxBzq#Ut>S=i4W^micMKY%Ztkp4>O6^dM2_y# z&(u_SiZ6b%QBEmuh4vRXny*#?9d)nN`F<04c^u*-U8sETzC;uvB&6mGM;p=pc*-I^ z#%W;+xq930P&GK<khAKzOQTGgT*SvKe~&@UdbPzdbY<Op{vKFv1mIb|ms0wqMU(IC zkbFm#(A}Mq+nw;2BH#XP4<d$S&iS0gl=as^t>_CG#n<rJEsyjJ`M=R~4ZJTkBoT9Z zG07Yc*9Uk~8(>)!j@<hkUPLxRK3YRhtpOgq<Yx!;XQE!_GWe&vol;**NTxfxk{M5u zmR&$Xh_>Rf{n%Q~alb2n_U6$`AANp7MORK;V`LsQQs~Ylrg~!A$%<CaDOJk7xMWI= zp~7&>PoK$r{oA{LZY^FwwelylZbf;XlZ&+8X+b_-hx;Q~<u<Jy5n_+I4Lp|g4pKXQ z#jy=p_08|bv17vKTusL)I^L?B36op~Eq`6V)Sqgdvu>faj1Rbhi(g963m}pi3&2sz z&Q#aMoWYsAKBlqT{>`AH>E~4$Rf_vO3eVSPb#^1#s?p;{s=Y<N!WD*KWiOf!>nolZ z&D@W^q5L?00}J&w2TJEk8Z+C9duJaJmro;%K^ajLfD)UZBQFVd+l13#@Cj}VDtR6m zUAmU(x6_C9oJz<0G8lKc-6<z#zRAH`_$wccM-EU=6(9>I2drP^|4Q+|&lOQqqkiC= zOw|8mm2_X|*W@=3gf!OjJ)<$|(b=Q6mN*|P9}6&&x0l79Gg5cwC%zZI)=$z88+lTs z=-tev=#dNVA7sIxzz)!UMXMzPt|0PCoy4%{&m%rAY-U~ob2VyP$c%jfHzvXETgMV? z0*eQ5bv4c0fsJDM5!iW^MUbF1QlLFx!HwsGZyd=6vm3mWbfW#(Y{k)fPj|0lGrSfF z6H*|SQ$kp1U~wyKq*W#9Mt@ccYEUzcZ`d%Z37Oli2?4qc%1QXIJ%{r4ESJHPHW1wV z{R!;W-a=hL>Pvr&K4-wdR4#~s?8Ur_z&2jjppHuViR!V+tR+VhYkr<OmOEU>gZTcs zs&EV8sHA)himL>bl94m_+M4#z-;uvoOqcG4rCqI;OTbigq4G2wZv^sLc0QAD->Vrf z=G7kDoc#CfJ>I^LfutEzeu7Y8&#iCXueKH#LUr&NqAy_t`!LBC8yAbuWb};1NJ>kA zBTC||4XceJ<mc@GQ=~}YpMJJQTYWr~j9$=+j1_DTJari2T)5lvTBb$_oX5vP-W>fg zX_n|OVYXdEE^hvQRzF?CkM3yn8$pR)lmz3Xak^BKXm!NH2SWjx?aZS!Vo<vGsPaup zD>K5caZl60AC;%gtggKkim-{_0kG7wik3--A*d&afSl21qn4#|p@a^~oyRno<0G)Y z3uMz|j%_*2u-RvPZ=}+&zwOxZlSNZ2%BANiCVx}lf`7|Qzt^QY!Ki_bC=8g30<?21 z+GGMsKg6gUHOIIudEC3DEo-p_eoP*&OS1j<$RGp~UQ+x`u!<Q%7>?!c(9pSM(WASj zxrVhgJ?FTUuZ#asCD~`>!j@I_$>6On$8!DLY2t%j<aGpOE@p|7d+Ws-j=O*6Z2ayG zr4l#bF`GD-5xY0x*ZBe+WkDBr>L*5nPx1^!p!|r>NKgp$H@(MUa}0Q9jTB@Mmh@Of z8w)0vk<PIXa;}ef0$gmb3AN_sj0`z>r%Y{}e(wUAaSTgAVcD<IjObW#pVUNT{P(x> z<^&!yJ@5!JcrhfY1-R(kGH5PL(D@m(>KD$*pfM<nB|TVne%-)~`$1(a{y1qC_)=*W znX^Ri(cG%iB`!rq<KXyW8d;?v2ds81H*$2{+}oT4NCV_MW`cTOs^Yf{Jo2$xL7D6Z z@chHk;3xc;DrE|L?1v6!>#M_QfiU^SYiTZfU(+4x>xs|V4P|IWeY3HJl(Z=pN_T0O z1w1ZTM7-Dob2&*?)sarSp*!nW4P({bx>t|2WA;1VCRWs;ArXHd7GI!{-aTa3o!ydp z3z|x0!Upz8sT3y@H%oY-Uo)$uTy1d=T_t*LFduyib(M=rsKI=5fIYP0Z29`HX>V!s z&vf$7ZoPYN$<8}?R{Sm?9N$EajE^|ZC{jd1O6ng5g^}K!!$JvL-NLeqgos)>LXjA$ zp5(qoP;(f75~(c}7IQ=@%1|RQYyYG~Kupfse{H7@*hLPIZOkW(A&Sf$==g+0&oyXX z+g|NLRH-g`H5#Z0p#7=&{KE4V?SX?TEX=h&gT8l>=e2l)KXWB5wo2FEzhD6qLytVg z4Ll3h06A5CgDClk^Y<RiNzpc)=W5(q?NOCnc=zuk`AG#A!@G8aIpDsz<q6B1xBVW} z=T2t6=(6uqbXbCnPNqR#>NaW2Y-!Ek(_>%uBG;|X1#G2%u6232-wxVTH@r>KiMuf9 zseAEHa}9|Qr!dTEP2=$V`A6Ai)L(Q06(ZP?*ABGKrg<<!aq<*;P^zA)EVxH=rU^`6 zG*~3AK2(36achg020#V^BhtIAb?1Lnu}z@CJRr8V@I_pBC5_2zhMvdO?lqTjij%f% zzyEYGi41s@fGcdc9rx%#9JC(+X#m5z&p*?4*Nl(SQ8Ofd%J`UM(7R9U?*W4K{f_;( zc_RXm4LJC4XX307O4Gzvz|S#hQI6qu!Bc$ZN1-ewlfB{#C(Fs;_jN)ZTTxU{jQ7`q zU-^}&!W1|1!zlEc;dq|wNLK2<oV#Ew1V^!}1QU^e3+KZF_$Q}-e&9c-e=Zd&4vzRp z`=fu;{^Tz0q_aY;_lGUBHZLHBeW-aky!&se?1SsCr~GeS`>GpPVh#0UT6K(W%(AU? zpGJIHR?7xGQ$bpZ{5rb@Kat4h?vr7X%`SWAXGw3H7^-UGCx1cMfJqJ04LCX&tvP=r zfz{vnJ`&U4Ozz_iLJ@`{d<c8^jZ_k>X%a}D8|EqOzUu7J3;{7yJSDMH#U$#dtC6pd zZ-D!*4P*p0&VjS#W|3`yA+4PeAay^mEu1b(v__9zuBA8V&{Lge&jVO-6pjvUVztqo zx`8T_uoEdqEK>`~db{5Pnbf-?rnFmEtJ7YQM6r5d;V%jxMBqe<fRRim+7}X$RtS9> zwwWTHW&s~b(x39ww8Kz+?8a9_eI7mTY3Dpxe(K-|h<cO<8nu5K+9x~7(DZ^<OiCSp z0@FZIIy#lW?<e13fV?V4SC*0llN}*bvZSaNa0iD`opdY|w*pF`dt(&+;tBx%<Ft4t zj|Ce2Ev;e;OxG6q#Y@h|ZGgseQO4mvcLC@qi%|rZ@@#x6Qsld{2-w-%y7#Ez$*-N_ z-h$K%{u$bMhhNW3y`knGZUo0v;7om1{SmS9K*Pkla(sOw^Vqi~tBlpdh}x!0_x0(2 z6wY1$4(ENV?JnwTE&yl99FFm!=eA)D9ioGrhY#ArjYiln`LMYjdIZ0DOZbkdjP@Wg zFgNIeZ#3M=U^QQYocNA=q-7lH@4eYnLmbW^^0=WHJ4!r8t~X;iaV^~&2}oAw4=~ug zza5pnPUiXM)rS<@8j|QSQn#hnf@8RzD3#pHp9e|_rFgMb?CaHqYkq(8+FYLh!D|c8 z<PNv=VUcSreNT0x^57RS1R&3qO)|Q|V_(Ho{31q>NvP<2RRqH;Jp9?5%J77x_Xx&@ zJkgEFg((0#ISbz6&fj|Dv|(Ut6Yj76xpZlO{p}KY3^6MiOWUa0B`<$*gw|=l$#24a zA%s6%ELQXm<L8D`@i6r~1Ogxi6g%ARGhSUbW$F);s{3e2UMU>}C6{;liYP>i0qkc9 zYL{=*<z~KR-{Kp?1rmF-k4eJneuh#$ppffE-W!)ucg%yQuf<!{;%NQRb<S7nVnS11 zd6>^(ZX$#9+|&mV*^w9g9Q~Kf{d%&7KNDFCV+D&ZeJuUoT(?=t7dA;dDIp`fu$p5_ z$c9vxK%4~a&D&UQA!CMUu_;mxBZLMBXv=#U07E9;kQ=DiK-O{;HlTO@8SU&5vVNo} z99z&I2FwNrfx60VvfM}QIpe;B8Tl7hS9iEUyxCi_?iyxUo7b_y7&@0v;|!~=dSTy< z%u+-v@)1;ZS3{Jt$io0{^kKd8JdK@l2A8*(&%W?I3@h-4L9!1!>NLR7=WR+K{J1ou zhdFE0hc`6F8EK*#1EloFJSE?d`ItJ0=b*O8d53IxdBX=v99+b!oM1?qeo~OoS|)W) zur_rqJG#m&X9z!6mqM1IJFUJ9iT_6IM{wNMZ}MBtc4})YKl2Ypbc|li#s(NAB?WXn zAKm$}kycF=kbpqdxOJl-V7IpI)y+Rxa;{=0TiJlLGBhJ;YU%72@H`R?0*vRDKxWrg z8%|fJV1E>?{Q23J4+4M*qfDbhhqlh<V~dsP<MLlZ6Vo`vQHEDPFZn=q2t%fsDbta@ z^o=-w#CI1k`b|cA|3$sRCJEM(*5|v(k0pg5|Hq=}dwaw~dw8Fem%kC%E>3{^-?Ng3 z3GYL6x)R5*OFhGR8XaT_@QY}oW4|RYWm4L&n<Z&BQa0?;1y*5Y8{$W1bh8R1&_PxO zD02D)jfAQ2zcXcnRIh1Va{lpjlEAP>TAVrb=D^?RXMVCh&+IOr<@{GjO6|9qaCLqh zws?ZZB&bfYfXbP*K{db~)W51NI2(<nm52SDPC^Np%`gU<b6v0$vE)0rAPC<_;WfYB z*h2<c0ru(`qAQCHf<NC|d!7U=JoDfGh3*RZDA2<jo>iAGG)8O+{69zOiK}Z4nPl@} zDffKwXPBU#2WmM0$L$;`K_QSWrB7g-mf4my_?8lxB|cY1SsiI{^)#0{x=61U*?7ZE z9%!GJJ6AJ-&F|jgc1bYb+2NpnU5y;guB2VK{K%|(rOD)M;PXkr7u)UkW;6^L!l*`$ zng3)*%rU#}bjW&<BALZRmZ_*4LaqD@BrADG$8Q+MqkKY!fX}m|t=kAj`1)E3MSy`` zbYY9(_N-P;P-B8h&y*STd$bjgi-J|IN)%;YJ$DF<^wKA>Hf_UuX3^2p3P+D4DtDWV zEu1?{4Eg}ANr=GzCv9;7Ctrvwl#i_gjon*Sr$*?1SQ>yfwKq@=VD#_u47-nm#FPgx z2KoERrg(}5o;fpPlyhVI5OZ5w6$!SX3DU>Mv-Oo4h^0#5kvW$My1<qaFuoyajhNAb z;xif3X&J?N+FUGeL5QRp5h3;;P{^%{qI(+iL-P!KJ`jiQY>S2U!BW~-#HrI>@Zt;E z(Jr;oi#eb;katy(RN^yEf^VdKOU&CGP9T4rZcTI=o@LQtg+Fqq#l3sBw_A!HZeKJ) zOjjL$DA!`?i{OzJ2;6ugUpVaCHd}hW3A@Ue-0Sx+PT4qVIOVb@bhBT76K3>`fDBmJ zc`Uhq7+<;bkE|hzVWb^rb->4?m&rYwXP*KbMOYCn75ui&B^P#8DvC!%r=9q<lr1kk z{-}XZr&a!-D|=x=yq0|k-wLE7ID4%ppR>0^Q&GG*>{#HT)T!{*_=Qc?)GIS{8xHK| zD{61}f3qU6{dIJurB_0J_5Q_2;0s}Mcq6O$_iGXYeFM8@LU|SMtu9u1Y{TSw7IiWP zBvFQS13mQjesG)6A`~Pv?*yTe|I#NiWU1hB)9+`nj3m^;(29LGBeFr-i)?|5O+;Q3 z7PSg0YHBQQU3NSiy!uvt@4tUgW~-f{ysYT?sGZ3O^%u#vH~;lQNDOt40(N`!EKy&~ z1S$*?YY~(tzPmW1X&B02mVs_L=Sj;v8>6nJEvfRoq&QpAEt|bKr4Lo|3SrFA>I4l> zZM6YPCdTBrn2~7d+HA{|U+vmF!S_`2PwZZ`9%?jt^7>fhDjKjMJ(-MSUvE9Iv{{fr zv2#001$o=<Y0HY>#mU$~9fF=66Cd2vsS2JGo=K2UM`D<j+YgHMb@QWI-eaWK(ixfy z4XIJ8L~o<=nR2Z%k?ZvzeCM+RjQC|Kbzf)nIMdKACw3Z*HB6M1mU1_1OX@w+TDjLn zm3cZ5C}xsxEEhKrR9d=<GOvh1y}QUWVNt`g2XgH3ZqNiYJ1)gX@<b>~6gY{~-fFd^ zNR)0s9qwV8=qd8RkCF^i0JZBM!%^ikOU@yo%zX6UE^Q3TO9#Fl*HKz_MJsKSmYZ{p z#q764Yc#j)9$3$Z&4PGuN@|Qpr8QlOtRHeI3Cap7nYAXjf>eu6EoCicatkFnKZkX& zvnug+&=4B`rO0mMrLfvES(t2qG8hy-)9JcWu#Bc^S%#vGT{bs0!M!qZ+2L|j>pbk^ z*5DFI^ZC9!<?yH>F5k2@zX8SMIAb(hPpV!)ref*l#m3XQ+WTpa#aj9?93fF}cPVfD z!D2YUyE}Dle(Mz3w{B}prawi)JNf}xe2CR3kYib(S^LA!#H0b*|5Gpi4>ckACOG@9 z&!>W-MtAsY1dpEX3h~`q0j$nZfFiKqmb=CJj)Y*8yf;(Lu^N@oL!dR@22?CIs*vy< zivDEd`99U!+m=_R@_x|zMenB}Gy93an(XzSxlk9m?q4Q-ucu{TKKDhTYAf&CZ!5QH z$Dqd)J|&yZv6_d?+RDxQm-nfwCiMF%Ik6KnQKrR%NNsL;>R(+l2#1}PIxicds^`&M z@lt+b3@SIEG))=pYMJwTve1J9c7LF;??0OW+uQ|QGH$__pBM#JT!^bSEqcY58y6oz z%|xddmWGeG)wibo?}4ZDt%+b~hOLUqbuZgl_oU877WRnw1{Xb_T>Pl`J=WcLvs2As znp5LU*Lxng6qNzTe|u)_2n=$N?_VO=^qze9zna~DJKld9C8pdrJ*l_$>TLhjNdF)2 zhKS_`3P!W4E|=m@?|%#X7Z~$hk_g!!K9CWkU<Cz`SA+Bq@Bg0{_%{b7_&*Z(H-_^+ zD)j%q3T4@KBtjf@>vTbK+d0L7y^L*w3+-A4rv7-PP=v)NBj8+V&_jlz#&>!%^8}Mu zlcm<YnmUi9q#Cx|S5F54qu#<KBG8Pf>w-9a*`|1$OKYQc+j4`V?T^WEGKE{#LFW^9 zFX#1cXk~XB_u@q?pYfaRh}8uL7t7t#)u~6Z$f8H;W#yN`m!kT$FDT9RIogYhkyy+~ zf8^zyn0@_VHGhB^6o%6e<C=J{%Ba{L4_5m3rO^z6eoT1|0rQ3PxASjouc%z|)Q82; z<x?guNa67fGz7epv0H2w=Nzl>GaBW!DHj}!K$Kd*Vwc6A2~pZb56lVjeSJ#RGb+lK z&KnKuxBS_7nYPbd{Tq_0Ak@jF)h+^M8K9Pw<wIcNLJ7|7r<_xMF!z;KU=Ux>LB{>+ zR6^zm-Rx6O*bm;zriB}uKyWswXZf*S)Q7+MWh|_By%W3w-@DFG+5c}W<nMrBL?M@@ zCnZfle^){B-t(-kq%A-|r55`oc)y<@(7b`zpkQobSEcA8evkjSEHw)u%EKPTe5nd9 zqLsvvgmj@uPBGi7xj-c~F<cyJ1Jh#Int>CnSsnOwj3c$uVM3CgNPXNQuI0Mg>C(W~ z<`IuYGxdac;h~l7bgFc^&H}WW^#$#@QxfIVWM;+CpbkC0bM*`;Kz=}ZTzBEwL(!mT zs(k!bAlqIjNB_sp>`bx8M$VLUh}bq?>A+yqSBE5)tC3!I;9ST%8}mo6=)hkXfAY?0 zSx^B8;3FS-WwN$ZQ4ZiTB?@0}X(##+HezUj0&S*d5hB$bI;x(u&UhBV=qYJO;tRHw zy7Lp9CMLH|f=7XVAsqM%L1B;MI5N^TvMh}LkD8l6{8H2ajX;@3vCT4~k`+_RNMMON z(C41<htIB`FjEij%XTBEOh)wvacADLBQ5n=FVe?Fi%kP<xKSSGrizCD#ZHBpy`@sS z_%t;?LZ_SX6{K}}aL8WImrDTqwQ=hdyb7=FP(A+<=AGc1xBupXNFo=lH+a&hSz0C8 zoFTRyEqT23qu`kN;6rH|Q$@hC*(1`kS%q;NtfmHHe@#VbGe6P7$|m1jjtL)ktHvP4 zhnV*&pYvx5vto0q^@C4p^n<}YnFymzbsaQqpOOon3>arM?#zV4*2$1M!t35izmrB# z4h?Ck)akTAD5?z~!w@J}wiOtQT?oC)r7Q)L3@->rQ+kP$yS{Ad^Em0$zB}Uq-1u1w z|JxUNCrAP*EzrP(mQ#MkwiBX0hjj60OV=7+$HNOpvS`zrsV2qcabh9toKnjxvkxhp z<_!X#G0G@~KsB7io;<}8r(orKxjOV`@QY?6{rhCR+ck{F$_uA%r6L7TRT#V6q-KPL z=kB)^0d&QFYS7`8K=u6q5JVGHlV^Hp;b~cpPq12-A78LF>H$emQx*cC{_2NVON4FD zEJ5{Gffg~e>t`q31fIvkG9H%#d7#f~0W`RjhFbn~B~yOYQG+@qR!y)doxR%YXn7V~ zy|h5ISgcvzI$s_<k&zwT+|6$Dqd4^>ia1{-h^$IKm~xIu`21})jdfo^{`rSo(q3(R z`|<!oeqth>kJfEuZxcIQY=$mJBX(40iykzKpXV15i`iaBcGA%^>z4c!uj%1HIhMC0 z+>;!2N?6G~oGzBOn{N}Y00q98sQ1Lxn+NF_r*qu;@EkVFoHj(-Ru4+>3*c-1VAWy- zmGz8G3YXUT^V4bG&3kNKgGV6U3OKLprXj+SMGdL#{lC|`cOQQWuK3fhXMOIT%h%xk zsj!GMy9a)t^brtS(zTry{Ic0iIA4k|D<cj=!6Jv8l5gA0D!YnC1I!yX&`-(KRHKw1 z&pl5%yk1_!sjY7gEjHZ)x}vJOYrsaESQi6@s{voX^QK+LFWPb4j^LFJT#&qfhX_V4 zoE~W7)xHD`4cD)X-}0B)XPzF?jZ>z&SX?i=njhP4aKzv}piMV(v$Atdj(rVsvAjOA zHMQAAS#(^?f9R*LyBE5z;hf76T4Y}@x0QlbvEs@ZkOPy=f%}+*RabNAUA6byrs|zz zY#JTC48Y?>t1KgMxE6;X^;F^~aAJ$qdyL{n7UN+B6uvs);Wn+(gT>h%0$o0cr^Ek& zd+@RI!XRSdZZGP(X-=Mq?^1F&&CYo65^h*%cWH~*X5z1w0!>>9q9zAk+r#7k#ol{{ zHMu8Y<BA|CQUn170Y!>{5$PRNq*sN|LX}<uBE1Cxg#!pkm)=`Kl@K}z2#E9^O6a|} zgc2bCc+Pru_rJUEo=@-fe%KFOaB(H@<eB-++;h)8^VFjWUWqfrZ<G*^akt)#KBcHK z(@H+M?Ft85CkOO=JR=9fZB9{^D2o;Sdh%E1kNsXB!-KUz{7)7shfeoe;Scwiu1_bd z0X(n%w-AAkBK{?8pH@tiT|Os`ZwT2G5b@(5GuO{YO)b-9paoM^mdj~$k$z3{w1kZ7 zoq5YiQl8=A0|17*#@wsHfI?EI)L*-jjlSf&fa83P#=Qp@DiuQ0dc{N_kj+AqR%Y;p zY3|juHP!b40I*=im|erAw){YikCl)O+3>q)RJVV~;{FdoZ^Kl_&puF_I)~z#;x-ML zw~gNd-H1Uc=Zd8FPP)RFW}GO5tq*he4!fpLL9Pe$9>cF!QzPv#WjCHNxi9E{jv$w1 z1rB$QN}82w?I4t9;AQpje6u=1J0v0LMXcQ+oS_oDx36%IlgYlYf7x5!cDs*XPM;+# zrM~DHew~Hd<wQ;SNyLfN?ff7>Hk&sOka#EeyY>qXuKeQR!KBb{F$2z(=PNH<5>@_6 z<<&p_lLdJXgB-$n=F{oHSBN~N!}YaXW9HEkKU~!f8%j3gkRxV26XzQZgN5NqPn;a) zJFoY6>?WUf7s}IYjDq4;6zXPd2g9fxfmsp3K{Hb7V>&4%N74@mtR9z?p*Kei7$6)4 zReT<s_NpaJo5A;A%agBG^%au?&F(k=jVxJV^_$?&xyj5^@w!!H+0Iy*Q`?ab>tNB? zc435`YwV6~1@P9MUvwOQmg(i4%6%Be#&o$~ZfM$4sGeXv$4<o-8G&fjlW?*zbEdty zq<Xi?)9Lq3uZ&?=hw5=v`c1P4EpZsf{<nDjHe$5RXv_kvQbMmG?^Oje0{S?v0r*;G zdh=pQ4&^$wub`Xv;C_&TVEiJa-F*@#%y;9Zhc0JDwX-hYZ2`|Vc9aK%>l?NHb8%)N zn=LXyea6om`alB#Eggty85cMA;T;AhsK8`~G9Qu(mGT27zoD#yq?Dlv95Fk3P%C;n zsne1)U7dI{<+wbRnjvPAjy}3`8D-Zh=2{I_6rUzuIqGjOTuu?m=YrY^Vs|cnFdK2Z z<-DAPAPk(xh*q3ztvPt!qZi3q;S%KyOEKC|h&iQK2>p`}ze?!;Q?;x^_1&(F?JngV zAM8SsPAYVwykc7$b!uIoCEv!%kY#P2yFgiT^;Kb9ay+!9Q*IMn_VsJv-fAf5vMg2@ zW^2xJTN5m^IK{-w!ciIhhLY{p3lUnfZyzCLMhlPKuMUK04gCULyZiQl#Gvl-ISb42 zC(4lF48LM}?eN_|sc>oIjO6X`4*efs(1txIyN<s29{&Va_Q#4J4+oUk<Fq9$ZL+*n zta)Z8?Bh(9*;@gO*AU+^2imYSYH6kW+27_{n-lhvg0-Z<Ci655>+J+|VP{`uKP-=w z4x0o&sr<0z<6>S)tJ<Kq5pzH7&~53Q*zQ}xqs>>Yxy;v<(z8EU4F&)L(Hba8dL*~g zt=Dd9H<Ul*1c8W>?l=%7nT6|1?y(oE+8cj)uJjmu-UHt9rF1J9UI4{&p~=H`Ho}gy z*XpE?m_TgVeq~B>5ZC(*==GikFPyGVT67xi^fkKAA<{ife+A6Bi26%h1tr02q3kbT zvPqb$zfK2uyfSN!IsW>%75yHlvW5a|-XsszEn5;LMId*d&!sn@we>8V>RH+rX@t(Y zP6{1Y%&=7(omTY<aw<y+5XDxW$T1PcO2;p@9D*UX9ED5rEi80BWv0<V;`d{YsSsm; z{&i#K{<Wp_vF^!Wko~>-1~r<bMJ1U7-QPi#y-A)1$+wmVw6ldD^YrJ7ldJ5Wqrn%H zqDvzOT7FoQ55d^N6ihXl;6gk7ylU(HEOH`{{iM*0cz4iD2#?kK4?ear_tW3ZwlL~* z!qe&PGjlv`GILlJiJ1j1wq+&pj~SjomI3aJcEW%A@$yJ_B$=C<CV;Q!rdRJZMD_i` z@1g^KUx=a|x~r#<3=D#s@kDz>99*~J>P=f6P|>&DV1eKTD`zC1Yg)U`U=doo-0CG| zUitkbOK};2wj_-0(S>DPEJnMnrY0}!xuwKkL1`Hz1fHabZ$=e7haBvU{Ru#7Jz<cf zy+_Jy{<ok9wXWSo<|3vk!25T=K!sP*#lD%$>99%@Wn0lb`EnUm+o_p?cHCG&L(@!Q z&&DYBe$+9n@axkB9@@3My7@p>vZjq|J=GIr->Q|#^I9hvnBqA+P*}z!4ibcJZltUZ zaVsCt_7K^8Cs5$D6s>Q_9C^8uLg8aS!hAKypaLwCpV|CIZ4T&V=Q~6|XEyI27C{8c zS=P~koq|Fxr?&vDSw;+6S|79>@dL}-$Qnc#642(|K{mF-ew)+9sih7>VNJ*)R7j?4 zbQpYHIC&5{!)mN5NkR-_k+E#Ex~4OH$9Co0CT(BHZokIfb>StD=7@*b1Y(fl?T6kw z-pn<ZOHt@5+m?9`)l`#UJl|Y2m(BoH1}l{G9qz#F<*l#BcR2nRME^VJuMK@V9RQeQ zDjFyXdO?{j=`C!Iz_YIcx7MxCNqrroz*j+ds9|tqCV7Hv*Z7TXs6B_^%3Q`fP|X9) zu3_iQt%mQ=@<)5n@@nZ!&j6D!GIbXinfk48_Uf$^8^7DxbEh5sZ>0C;KBb%lbZWfG z&Tgh1*AT0)zn$h`m=de$aXU+iLCMy}{9&QBAYE0GTA5xVM7Xh5ukT{{ol-=**2xls zX6t2(q;b!ZwVo|~?>=zUT<C=B4H+pKGv>h`yv?7K_GmUy<}yYoX6Aj{Lq3M9>j7^r zao69>Tu3It&x5gG5qsBV*SbDxKMu8-{NZRbS{vV&5qdvc&~svyTrcP-wBs*@1RDP{ zLJ-S{#6+Fl_8VESZ|00#SsTFvXTTGx$Oo*5OsfxE+^4p)R@}o!0oNIQw}k+^!Q+ZV zLM^RWIQOlnsfK>c)y%j>yXL?f2QLBuOVHJs2cK)&W{Ams<tR!EM=*)4@Kxbyd&{x1 zS64tkK<`Hf=1jr>zLT#>IoY6XA0hn#j0p+W2dP3Y21bwBdyT3TW%@$eJz64`1Stw3 z`T~!r9M>)w_RAC6^?oyV!CleEHdId74fzI76%6R;REMY7Fr-;Q$@&)R6dr8*KCeu7 z%wAV}h>Y&EattK%M4L!VEI4Y)2LPn|8o}5Az#b}+aRRo*<2b~Fs4oZy@qaKVg7($c z!WR~2c|-n6N=u;qu3W|@;i7yp!hg8iL#Ncix9MJG*-$;JU99$=@~XPG!GY~5yXB4G zyRVvKc3<hkkYDP0gRDIT_K5uYZhBdFiokSlszP!m^5bW!JA)!>{IZ*p=4eAd4?KUE zby5jFO=##@pDs2Cgk6QgLDt^lRQ4~ekCSL8KOBjnJ@Bm+T9NTBX<qN}56ZpaLCOK5 zt*y^3t~(GOR33_BCSrt&hWC%Vboz$k9gq6)r8>}(?*?k22YI%x&(LD+`Z_AG^6iiW z(0sc7n*@gY6(jr2QPJF&r1k}Q$2ad3b@)lC`_|<qnS0$L&(iv6XiKBZ#orU}RT6HZ zyr9jHw%&WZs}<;2<qQ`Sk=G3SP1<&Fg25I(!A!-;dusqTUIp&cc(F};JS4QJb5IvP z(THDJs8=r~I+f5OqiA9OJ?1ZYCD>nr5R_Eu=2NNN#56O2fTjuH-c~{#jgvL*WO5*e zxr~e-+`6TBV}pt@Ah$9UzzdtWsm0GZR)6Y6_Sk(+#y`4$-^{UStPDikX63+ZO*JiK z<A$Oo+oJI*k=%+tcptn~4yAWRBObYfz!R{i{L7OQ4ivbf_rXB%qSBVj5&JK-X)K;E zLmy58E;)l(F2$&p$#%5NMQ0}YuB;__`+=TC$^oFYihDIV`$?YKl@@P;7?mYy$R4O_ zw`vMQwdTw?!y#qUT<tlG-NVl}UwViZe~5_=pCCcJ=nYBB2I7WAEG7b$XCw>PIYTaK z_)T5_g`uoIQm$oSi69!W(&sCMO<S~t`cEuME?U`3?s`YcQ7D$GP<z`|1cfIt%mBq# z@aX1=Cgd+r9F!tbL~qFv-=^U_gB`4m3OXVMg9Hi>wPt&GJ!JzOBxbPdl6S4kLb;OT z^MGeaLr0(<Z3pa&%EcTz>Ub@KRiPUEfe56XM+BnxGmR72zW$mnQ|X>O#&)z)m|JRB zWjWKn-uJEz7P+|dsw^_|(sMred>`d0$ALuDn?BhX^tT7X&??P1*1NA2gEW&6g?X0R zUs&Xe$x!?)ci8h!+&2LBQ6%fgc-F}v1XPlusucdFyVk??w%<h>W~UDDA!uIthR*h0 zTH#%Bb&AM4MY9jvRzh)gM|3dP1H)%uIq6NV5d$BwWZ&T)wXXJyc%MM&H+9x-8D7IC zBJ>J`=V5@Wce^*K$=0+Yd=->CMDAx<k}?7FgBt0*Ru+=La}PKZ5YwX{`Ycv_Dd}G; z(c?Fq^=KH=9re4Z9&b!8GS_I7<*rq3O<br|Fou0r!gZLCoe4P6;S6S(|9dL(e+>BK zj7Pxl3Q`cSl<l}Crslw5cJ>OX9x5+Jj;y=3bWXu7{y{(1olXba8b;1z8*BFuXdoh4 z<3ZmG$%DSHNgGreHw>rojNshSCg&Z4{d|JD70gWeKc=;D3mVx7$qIumhUfRmK$E+Z z%!7+|4fj73QK_^(LY<jVf}^fRrWQNt=s-I-dCxoI$?)5A>IkI^FUc(TD?Kqjb5}li z(Mqu{s>|OfsDGue;`&`)hF6xYe1L*TVh=n#Ut!j^olV?hbMWrRRNObUQYTAyi7aV? zS1GA+4onwI54bajQ_NG_%P-H$?b>!VnK?SZzYYeh-k=+?9g4nrCy;CJPIBd5uPp#c zZ)=Ga@*LC=Jg#VPJ>?wqZ>U4hYergcjSfp$f4>2)_4BZ;i3;W2vj7@M>Sx1BwPrNI z$kgapaZI8aTgiS|vgpDE_Q}SplZ`?T81U&khn*p!fSvblR29*ZOuG%HM+bV8$Ywir zk`+HwC&9$DC+t}8LB*0ohP?)krXAbIW>g93yXMG-tSdBoI-641xhNHmJB+Q@(Q<k& zvj$syDeLxtS;t!IIP{HG2^z#S8J`9Im2}`l^p+H%OBAAqCu_9CImaZ0ihAP`gGQV% zyqF|196xUXSM+rUd@8>jgOzzkRBG5~@*91ZkNI_w?ylLIGdHk&Cg66J$g>+(4cm(% zFk1eJQo`5%AH4ye_MF|xttJR=lhJ<tjhG`VGp<{v5zg0lu~qB32=1f|sK{Gf{LMRE zV{1i5rdM~>Z0lQcw2U;HmHpf^L^EyG{%=*sZe#}!`rdxj3ku){*eBx-DPg+Kj$Uo_ zg5a^Dq{-+w7k$usToM`f;JDVQ^Nk|xAebv1zFg7Z5bxkUEXq7YYmn(Z3K)r7d7+%Y zIEbh`de(VCC-`>JJqGAKD8zB{9_ZrP%T=rU`8$lDVjyT;e>eF!ta!`$izvlk2~4X5 z1foPBmS-_xMeFU+8YAJ_?!8>`Q*UBMn;6n<zK|6<XA9@_ma~Hm#EfBn<*KS7WA$8j z=eX{RGtjO@b>L*{X2=4l11tAyJfUSgy9~ytf|?oqPfWCHdWD@cNyRr;wj$mWylTDY zIeBxaS5<vI3ab;$<wPj{GIPKkqM02G%!7u$ZzXVOi^|Xg9Uz}5Z0J0W)MiwK1DdR> zEvJR_0{O}B3>AT0y98&T6@=HDxw?4hi@mLGj8+Uej>z%bJJO_P_#Pi^pXv!6YEo_% z3=an7LhUQ=D*0UV_N#em$84C<^UO7BH=v=zC@#rSeRQ|0Va{9sSah^#t533UiK3+E zjS3Zb6B&^#AS<l@A=Mh5^TEPPy#r&rU6x!q&V*PRI$pOdHWCxAVO|<#f5L2_3F|bI zFK{Gf*Q)|A_)^+U6mldy9$HT)uGFhfy$<;y=(2e$oIzBpA?DtIi86Fuqd#coFC|@7 z|C9iLp>smcvW%)%(@8;-Cra77U@9n5@#3zHw%HK&Rn-vwailiwPhM2}+8wYZByI$n z3Dx)35g%TZ9|zQ?+e{kJPb|mB?^KGLZ$%()2;~f}jg|}tv92pg^NQ1ks}j4+Hg!+o z)=HQfu+Y+R_r?72pjff8COu-Q-S{EHe4JjPSL{&)(`3Y>vcQA(BruA%P+n1mIBCnh z?`_;?PjARuo5}TkGq<zkt>a{Q_vG?#3|WPeE2=QkCE5QTi!T$_Mtr??$9_$$-u~KO z>TKcr{fM9a{<v($zxw)TKl}Z$2_OD)zn>f5?+1xa{1w{lXPfet7GALM%u`R~uU^pq zKEQwRe)IoX;QyTH{;!;YwkYgKDP&2amG!?n_ERB(1VcAHp&sj>DVi03;#fK7DM%0^ z_f-D7Y)0=orF|z=geA$nPq*$NqjP?fCJ6vsxq9P`ktx-`X$55P6S-|oER{w;l6tkQ z4FAEG7Ul0%r*R;onbqS1zIN!nGYNA(y!IciL6(X{tmPWw*4m{q{eK8lZz)MiR<0oy z-zjJkQtskEhX@BjGcECZ#eaCs-x6tt0>LwRk>+?7#!K2^f4A3Da)M^GM05OIN}JG2 z1dW%PX;)s{L(ac@@^5O{TZ;EqNjQ+Na;|)}{f8#i_h)~6jw>vxH=ll`!@oO)gb;L> zlKmfE^S73kKg%^j#yLVzsLLf?z(3eYl!S2XfDrWdX$~g=$uT}+rcnEvgk5R*H@4JZ z_0M>aVxk;HehDV~_patWV*gpMG!td=-vsc#HU4=sSt#wDo__u}oLVR=rOSJ2d(Oej zCYAqak9(8`ebn}ym!tAX?#+_o->pU%03av%HznuOD8hh<Hvs@yu}ej?e>b}SUBZA3 z&j5hvy}?_T34JaH0D427mbG2}caHHe`f2}7wX$3V;&&te;B=n?pT3b)FJmKqk;L-u z9bU`TCVKNfIp+VI;+G5k&nf<FqWpEIc%B&uz~X#^rz6<3y;QhxVVBo6wdd_+efD>m zF{|jR<Xi_K)L?yi>qNx?O~d{^`Ic9mVoy&G7eEqZ<+n^gR(tl=@YR5FVnUj(#b$=v z`P*Q(GcjwPIE;kq`Kdt$e&Q}mS!yyLjp>b-$Mksu`1D?tIAc?azYOW4Y89y2{{`aD zF0kQGrn^HKTi$t{yG`(z@jkQnAp%{gYZcZj>HY3;jmxL2h7;<EwfvYJgcNh~2$qvm zTIb4Xd>cn?e^YrN7QP{!Oy#S}w(hrgDRmhwp88a}Z8JHv2#X9^^Cn2;+PwZZmvIUB z{hZ}em+27^a8&<{dza{hkW@pYGu1|65N7=~x|P*&o51JlgcRWEJ3>3XCKC|xgY8NE zd_Cu}RTJxYc(4_4P5cN2?L&(KwsL)W#%$(O1a11{({JY_c3DB8j$YVRpJ^=>v{}g* zR64I|aFG8>Nphh#JFrkv+0o|CiO0n*vzy*;->KvwR%$g@4W`PUs!JjKE&jCSui*4l z3m<rQicGrZ8hC6j7O{s)F8nEleBm|TX>vvb9B3c=^gLtfmvsSFz4WE|qr<lvnjRoi zW{=X+)kcOpFs$rYo4LMt>#v;6FvHa&yg|_$V>EVKmZcw)LEVj<?kGc~a5kg*pJC{P z?vJ!G6VJx7>qL!@=y&&8@Fg>T%cRZbR8YTu>3~_^Ff_s2y?c%^$*Yy|dM$nZ)dglR zCBgJ?`KN9YyoT;Ys%{DI;}cHiVrA6}YguTR$8r1g;i;Mlp388nE&=Be3Lts~4AkkQ zY*z$n2XT~qE+li;aV_9e3CdkO)PkFJ6w!e-RAoWf<RLDbkAKftfBOkcg3lzWH|<4_ zZBylZ^NShYy<(8C9;E82DKS0^K{AmdR8)yTT=~|m0qa>9*BpcZ+InWl-EKbnnZ4D! z_%r*=Q`a_=t|-H#)3~)lNclnc0d{Nek>yNm-S*?nWHC06_rLz<Ev?@Z+$#-B+K8_m z&wu8Y&!mj@FN41Rh+SgPLJ8Ani5&0qg(p#yf7P;S3rbu!tJs?PqF}btG;3cYtd|E_ ziL>k5X?6N+f_OHn$ICITH#aRC`#E>LHfr7VZ3X7+%d^t=upb_!AmSFyQU6b&?Sx%q zI5*rCW=Ju*W3FFq!<lw@#JVGb&c2-T<wFv!&y`=a{w2j*tKz+c$EA!76AY+@oSl74 z9^9#i*nVk@SD|r^5vI~BTXG;p5JufBWzO||_VFX^5i(}rBJ%OwdXd*@#vxt^6wgvQ zO@-qRLw7n10C}f9;8z0oFZd%Vt+(7FAaOCk-vBf1T@&RXoXHWx`MdZj7e#C3*Asj= zub!D`FX(2isJ?J#(4#LJKTz5eLgO#z`v%o34;r(145qjt92%QtMknJws0Jaiv3H8x z@ZDOe&@JC*W9mk+`qfw0{9T>#e{OX}vX5tQxNUB?`x3W$U0L`(eA{nU251>U1gmg@ zx;qRW>UFU&K0j}NJP_TaIJI=EoBm9SR<m2~+CD@{>CyOtc2!7I?B2}hv3`(y6_s7G z6D_XOw{MbBIZV?iu|*D0wM_FbcktnRd`>n(nkaku1y%8ksdztKz^zlIE+5H!gYPVz z9^OyowkziA66CT0AYc1Z^Oicch_Ne84CR|1oSxq?iqX_x>)sXOJEJb@7@a#xe{ZZT z(F-ceW!(5tc8Za9?LKX4yt|IOo-%3h{IpzUS|v_-Mk{#(ZTV&lrBue2Y_?fhF2yHa zTa0n4w9`zy_6u07vi^Z>IQ%Q<3Drz~!ir{qPZ^tLTb!*VX7d*MI-+e`Dbc|__dPK^ zy;&<|I9^7EIUn*-^?9TGBp>I!97+b=SE><_7KaD`-OtR`*T-Ls#KmBQ@J&>`#S?hl zZ&T!il~x8ON7B0h9jS2(8BSFSvRr|$0RYleldcOtKSi|qC~R)2?7cvSZI0aZu?5*W zgVKBsru`zJ$(Tpdu=F&a0lpELN!LrC5#=ZT%J>5Ij7!;tb!(<pt_$bXlr)3NGK}I9 zJa<tA)~MC`)aMzDaKI^<{tP*PhB~XC2=T)W#5asyWqinhEdW?m+TVTS{Bkh3I*Wm& zm4?lMaD7?Jz9vgMQguD|R9;7~Ne=3mSF}&>>pbB>w(hJ?KR4$qe%MWI2e(wNX3kLo z8Z%}mJ5<ZvNka0yo~X=y<|=)j2%I4si52ZS6)ZUqwJm{#!tDUax5qQa{ev7;O8MWa zwsxalh1d9op0Wv#j8?kFq@7?n;B57eVfQv2&3fpDS3YXsVo@oT%l^QL9l*|aQ}pTC z?eH3?v2~M~*P48!^^o|N>&?L<=k@fejU@)IkYr16h={^D6siTuNdOOh?icz%yCU5! zGovLmc`lrwJN3=b-K#9OwL@f}19)_(JaN#`zbANbS;t3B(9b(YN@w6X?z3|1pMwS( zgnxL&&0Re<0*=o=GuS&fxiZ<Et^R^2_ZM98-3AtOvC@&a72Iy=*lLiTYbJm+=zeIS zX**gU!H<45?n<G{mhh%BVc2fkYk8(lE?8N4tJ5;hSWK>R%<wf0D8(eKVWQObV|!%5 z;JZd`G}~%mS)C)f-?8ai|NPYW%}xa=I^Wp~;>IPDF8mWlCqMTVMkHC|leZ4UC3yQn zaUH$tHLn@iE|noV>O^@Faz4kV%Is%sdt-Swth1x=x}Y~i%utir&O&k}yz2gE+lku& zoHZs)|C;`ohyo&ZpI-${NnN+e8I=@o&$^NbA%~h?7@SvpkWwlx%{__bvBn(Q#xXhv z01}ge(nyc4c&hJsLK=a+D5|7ZU){V!ZpiJ1@--x6WF%rF>3g`CgLt9aiDqq{W4(F@ z8G>-clVS(*OnCTlsKEBoh^YQ?<+G6Wuh`0EL^;&X%y40)ShJ_?nkeiwKPt#d2~(S5 z;rqz0#rKhebOK5Xc%)iPf5(=3JnQ(y7Xsy=u|Zg#`G9a-j~mWD1Ssl;ZOdwoCud%G zfQ7H(6$B;uDK-hE<&@gsAWH2#PfzkcPrCgdHnr-ikRnu*_<7QKw_;7gP#*?&!x`X@ zhVMKvi3UEZc?=o*p&TZ^*0`eSZW`-55QLW$v{KqM#fRU41!>SkXGDipFchoT;-0xL zZ@ae%p0>~=Y()Pc9nM$RtH08k$Z?Q^W%l44`Xp5zDDE;-AkNat8J=<!+isAuYVH(7 z^rODyxMHjuqEabCRq4P-J~aGl!|o8tUpd&-CE(^Dqs-sQKwal+CQ?;TV)X3qRoEXt z`ETN@qo4LN@^p#ahKP+&3^^V?XW;XC+98Bw3@r#Bonwe2*Pr=TAX<E=%9<dkpbQa` zKUdpJD>E%xK|UGf;V`yedIn8pu-Dt~evUqo@oG!D?8ZOPve@%tbjEB$f4Ia|k>BsQ z2-=Gg8n}klQY$x2hRU3)I7mkmJzLMS)&n)i<6%c$R&H|Xl!fK*mYCc{o$Fsim^*(Q zx}u|fXC*8>2GfuO5Z7FRp-S?I)AX~H^;v9|x@Xyb<%Nv?KWgLW$`w9@YQL9ryxaIg zan3x<_-eI?*KO>FLTdc|l&Bk}Ib<)*mmJdd3oh%Ob-3cX>;&A@s<}R1iAveb=jCrI zi~`QRD(|FAC0<J<p7tw&*(;>C%2QPc39rSa7E;w;R9J-%o59)(5_CA1cOR=ZnR=}| zFnRxA81niOZe#e`KZ9{&Wh0`)NbylOmPV^0%1sX)w>G!VZDp8EOsg`=W(De!)<w_d z25A4<1(38i@I<w`Xt#tTZ=zqJa7$_W+__sj>Nesb{MEk+yBt5^)CW>THBhFgC76uZ z(5&^D`)UW7j7NAMY_z4$Ve}mzY3AAagCtyxhM(M<2jTcfk<?1*$C;h^a%=h8FvlUE z2!NOx)DP0t(K<Jh5YL?(ksZ*zMw3>RVD6$=n;-QbppDfDuXnayqEa;<i~ylK5Eadm z)m-bcTqS3wQ)SpUKIvB{Zv8nQlAH~>kj}?58?LQj*z>y<P+#lJl9Qt1ja?~036Ynu zmdpfhOWRfy5OJ<n)`k%kyM>sHj4gOGkES@c3C^2-BX3(55Lyey3{`g>3e^SrYK}X& zD>uhGjNe_TNS%F^xLgFve-`pu#9`GUC$+*%%&Rvj;vvPKXy^I0-`R-kY~62f9v_q7 ziGT=KD<Y7~E?YRgtFg667N2i^??vFLTSG}HnLBMx0E3Nt?f32KaTE7-LK$LF?BM8P zGYWM0z2N|@R6wAj3}#uf0wr;RAI;HP-Dr67l)JtzkZLXp-W$yWk?&KhsCyYLz2?pu zezY?jwO)L^7ivy(mwN!)>bfWXo(gP+EgG_VT`<HkoJqBX-1{-?P*&&n<-Mu{_rEqt z?$P1dk@`=~@pSgc71>PFbbequ*qM3i$$K*MTjVUONGVm^{<q<9iI9wT#ojjq1DQ$S zVtF^4b)CF?0;W)%49R*aG5Fi#WkyF3%CsPG40S=_-UQ7940Q9zIXX<B-=h@ZLZTU; zN)l~GoMBWW&gXGkLnzu_#WuH1xkoS)z6?-&bG&9f<C}>*ptn<%#OK~y_ScN;*4*Ka zTwqk@MfNe(lq;bOxdo)LPki8h^Q8Mn4!e$`RnNi-sFwH|y&<2;yC3ROMO8RtQH*_{ z)S0FV$9W`VeW_;e&wd(yVB~kQhfe&7Jvl)~=Fi-h;i_NO2910Xcw0NseEB+1P+vA$ zW9ifIlNX3g8+<NPqp~tS>(uR@XWvVYj_!UI-s-qB)YNbqZFG9Vuf{pFN&wq2vT{FS zbs!6AjQ#u;cO~5^56%GtH|1-g_tIy~fI4|W&=T`n<sX0<vHeC@H=Q34)vAazb7AE- zE1KruUJW&EHmg)%=N{(!7BVE*Ld?Tm+uTs)U(;C$o{96g9|$1Bk2=s^$EO}u{V9yu z=-51vd=F9^SMaS)uY>G0A&uNwV!huKB*Wu4dlT0?h9s_HT^ZCHRo?3ue!_2*E^GTE zxySD49mYqvz9%s_D?~3{W0(5yTFp6g^G5T|1Pz0WYWf>olz5683w-|l!>m@(aZJ%c zP`gtL=N9>I$k80n+7Y7wfScdSwD1U~7KMLkjJ+rTW>&9}i#u{q^?5==7rI?YrtE@B zK-b()AIb<Tu2nyj&HGii`#*m0J7c!S7yO>=*=#k<&qA@b7vIkOJnxC6Sf7u-2&A7W zTYU23B4_g2Ytzr;ZVBC=`VIN!&O6`e^o5dDieXz@PoI3=q0V1}zp?rj)jCmyojL5= zNGRO4$loyEq+&1@^%_$v`+V$pB#oJV^4wWqlSgUEHP0jUVR@dUKEJyj*SmRP6=3do zlWSCaukZaDBy@a3z*#{+WkK6$ucPt8Hj&oXv*;C|bfDJC?z~^=t*H%-#i^cEKNVTo zxx2U<2_k3s@1@?~jP<nqX9jB_0`c7dr)WzG)gP_-^7HF}HAeJ|MxqM~p=>rZa#K<< zc%9ZFb3VSN?3{FI;kKPCA4@3LaMUkj16r_?Xv6zi58;!zoA^ydW%`kl{IU&HajpQ< ztOVMbENq%O`lfIGww~|yM{DJ($gZ6}F-Jdb_VaoO6fd$An-GpeY`ZaaK>#;oV^O@A zQyBS1E_2VA@7(>Otj)c`UCNn6qZQFVQ`K*Oq$(CBLhbOc*I0h?hM!XJ*bhvC4s$`v z;vmX26(XtmzC4Q7Y`FNlS6dWKwQ|Bf`H#`>&*jHp8vBF7n<Z(BpCrHB_f8AHF-|Rj zL=V*oo|kLvvTsT6H>Wf^R>jEu&}|$e5RO{s8kM+x%2E7UIq1GWInFyZe5;;a*QTCu zn<f~XsHy3n_;GUGO{%Ty$SYOQp@Y0Ro|WfcLe;~hpS9L^lQ4!KpZIj1?%kZ8%zXJ^ zhXnX?%}RzGFp%*G7884xjXFHEF4$=cN@Y43sTeuSr#$J*<wA2L=kE8}EV^ESbH1`* zcP?Anoy4LciteN#cY#NPZ{t$6qepQ!^_BNcn+7PXJ5>`{^M<$)kIGHLnWYpFWp6ah zt63PByzm?Z(6W{11J-sBy3u~CIG%bU@^3d^o3{ovxrGTMn#;A1*kdc?dW5G<4%WH7 z)|UK6xceNhktxTCUAn?v+~2Y>Kk`YlZ=d8Bh<n)h2eowE5rE$a?eUWkzuT-vhS0q; zQOhfA-NT$3PQu<Kf)D%*w^UA=%<48=eYc?Bov#$NnwoxTy}vgY<*P5`lttgth1n6I zUv#0@y*W8RT73TQJ72>!;oCzyu+j3p$_%pyU^nlUbBcO8T~8%Jn*7|Jv%#~MwT{Z` z4(TS1fwb*+Xs$0DkLad=!{V#Rp7RD*T6RAiVLK9*;TUe#5wIOb753(9Tr&_xMwbsg z0P}bd{Q3lc4xn7;#Pe}<e8{XD!m|Z$>qh|viZDX#VD^yf%#io<x|C|0WnH({?ZXql z0Z7`%)~8KX##nMi4p(eH*KRzlFFl>T%F(>LK3`yeUIQ2A%nuybp|eGeUCki^$?3Dr zn&yH8+_cxPvN*2TCQN>M;k$5UYV&wN3$+(BEF}*k^>$_+{=yUfD)6Wur%0%!WUsIa zY7aWiyNV}SM3o|3Vwb1!b@Kw5O7m$;lk-mUV7YzOq@lZy-xslVD^PBV--(X+G_A^) zbg2aGLgTEAy}7ER)%0|q7hP%UjMRoNVPx*cG1pt)D|-CNFWq|i2iNm0@GJDD$TLDb z_fGu9IS??ImY;8DOUh<7B!0a<+!YqV>Xz|Ef9B3P5n8N`VcRMpzDF<Kjaa^)bIwh{ zL;1FVS6;iH)2Cjk6V|l{b=2k^(stWZz(UI3dWJA4W;~YxB1cp|i@qFV|2caD{}sri zcf8ox@71MMw@O^geltS!c*83^iH01b`!2V)9gLu=E`7w5TPKt2)CILg2PTev-x)1e z3pv#@tK<@}bUP+zb@zr^mGmFqx5Bn^u)RO|SABizqo39kK)%M)r1?X|w#DMC{r6N8 z4YMyx78`}4xdnW1QVo>QcN;JNz;D)Zd=o`a<}rz^&+qz8WEN&`lc48r^rrwRtozeD zWZ253>vPr?c9a_+X+*ah{lb${GE=}$tO1@-?eluIPiDmEmKI0rf%suE*=Hu~6S$j% zs`iu1$bLB<Z|_@Y$WJf&CO*9os`1<4V-OOf0qu<etv2?9AB5U;sP7Ch&V@Fugb&p2 zM8Y*b)%6X2ALkapZ?x3IjmFDc*+5uXhn32fifoH@rHri7wO;!QHVavvrZ)D@T5`E> z7kn7oiCazn;Z=unU3v47x%TOip){``JdSaO22Wh7KY1}cIqK)848;{~B@awBSkeD- z{nfjFK#LWR3R*%n^Pd&iz}BWo*o8^!&G0^fyD$4|X6-YCPZ0R$Te4|+vbH|j*0dPw z8K_kZS?AFfa<7f+ajmnP5*k>$tbaWGoQwo@M(vAA#>0sj{PmukBvpGTzr8uv-yI<@ zzZQ|NnaVS*Vi6ZOY+Sk#mpZV54L2-c^NT4EI!LSe=wf(kqXDcjn%P%+_-Fwzfay?L zA>YOO0<$|w&T$2%6j(F<WXpMKFPd=f@~>9NuTkVwj-SRBL(UWFjOw~ZX|W+On`T^R zQLbfer)+K#rZg`{gP@K`DAw?0u2hdWylsv6nuGp6G^ePXi!<|b!8sX|mY{;_C^40x zzHPyV_2&n-Se;-~UXvy?kc4BP3xBEIJ8(9}exSr0ZQw^OaB&|tjnyl?(g}^|Zkp!8 zw5RtSI*#ihI65(zTcTe$#6G_KQcmW4D8sP4x*0zRIKi984R4-&O#VWL?!;@;?31Xn zflJ|u7>l^J>ER^#4VH6*IY=cd&7Y~m|M4Fkx-|mgK-H(SBELu0uWA$s55}8O_g$zM zVoh&n?dIX1RzGFxz6s|}c^#*mcAYDMmG-U25ov9v+e?qAVktFOCAd(sxX|0K=6K}v zRYPe{JzG;Cf2FA<P~z$9R7KZHv&!}wQZ7N~`KY)|!>SCiSF|2Dm@7Rt)%s)#?uPm1 z!94(?<{I!u26@yr-<j`pOc08Ao0q$H_y2DLl3UMzQnDUpZIj2J(ehKH5f>zW@-TRr zL*CV6pmIH8oJ@AOuWqiLt7y27o~Dp*qqOCO<LyxNQ4;D{V8p>EG)Ol^PDr#ZD5OM9 ztHm`C5S0u`Yn+5$Z=%wB%BNtqk>s#p3uCtJM-mIHI6hW<oZWU2zjzn(wFR)>3Mjny zo6bP)9D}g6UQlCZJXhH_y2SLx!c7D|My}>T?IX%Rgy&6sngBBzcM@p#>AI$7Bq<}~ z{}g^djUxKJohd6tS;XW|{q!gCO(`yojIPmFm_UB-bvunI5A<4F<A86L2YolB@6_v~ z&)AD;ETnJxX16~+9EjI=FBNhK;5b09`a~nI`Z$F)o>ZEyJIg7%x4dWg2Di8XBsH-C zfoxNrRB4)Oom!l(M;bnjtrL4^3rS5PLyhR6?~@&Ni@*f)q8uu0D|xZLs4*E&KH`C{ zdlR=@Qm2Ap^jvS6BxrOs>cn+`{0b?;{utugjwb9{6#iFZ$o=f1;MtTWQr@lc2@@J# z?X@^_wy534xV5D6nc?G`fiC(Y3bR*1o0chLZv1Lc;kM#s-rvayNEuuCG-F@sk12}z zqaBr(=ueQ$B{oFosT;kvbe2V5zP#G0A+MY!`?!Wurqn0vvNnWiAXw(@gJRpB+xfOV zG;R+DQ6UUb5t~D#k)?xK`Pp-He#*VD!S2$?mm_V{v$6x}zMu^OyX_=+BP?pj61un) zrysM~<fJk^nJq{momHEVJrJ=MCRC8eQZq0Rrx*9x2d(PrQ<v(RZXv^0yccAC9b%8n zi(oS2FTf4(75{kS(~wJkx~`&nG0BCt4SAp|_~&Hl&o=zee)}J7c#cm$>n9W12grH* z=d>}rj8e#)yd!dM+KOc%<gSf{6-=kD<)ILc*AAC9bg}p<E*+Q`{f0x878LItbKKZ4 zbCxMJtSGkDJp^vjXQbe)`GJgTwG}&Vl#;Ln)TQPOb$PA9zxB&>Ch|!>p_m!Kvo6W# z8@EvRhUE7D<;ZX};$h*mXLEe4&1OTO7uKW#ee*aKAhz}KZCtvqzE?Ht2rES-)%iU! zLzLOhhII%!Ft#$A`5R(ymN}VqLs-;n)z?+J!oVV*=Hb?Cao1^Pk{PppdZ!{+m22wg zXl;EX$7JKtxzOl}iyQH2N`&6CyLLQSz(#(#LuoIz)1nSE_2W@Qc_OovJ!DjRIWgU# z<0L0$%OIx@Dr;f%OU6)g|Bu3lz9X<05AkS!LcE3re&qZn;lEJ}e7$z>XDohzd`qxf zPWp@K#&?%)0sjCS!>wO`+!VS06Kn)W{ZIGsKi$Ls#4x|ZnE#1k{v?n7jY8@^K3u5t z{~MjwpKtnGsOf)(hp~)=W^RO(3O}3qpZ=3D>KC!|H!%F=r@oEtZV!Gn1Sei(s(90n zk`Q$K&ei1KiK@i(-a(Sou3EYNLws9&`EKJx;`Nt@gi_1Di@M%X=>8{h+TqZxYia+a zgd)CNvU2e5I}7D6QJK$Iv41PjlcmZ?&r{g_Cnc5y$s5UZ;up03zeH`bS4RJX4(rmn zfNX%(KPkbU{k-mbUr7EG)iIa-Cmq;oJ|~sLKPk~D2n_mGE=S4U`xVFVx9mUY(4I=G zM$PK|qY}=Oa@I?V;<rcmTKo_F*jM7B|Dc1rd}<R)*!NFLyueFi2cA#OZ~m!YlQLoa z4?4Vlbxl@}e^LT65mu-5U115sC%HfLbGw%}{(}w>Z)%q2ihooh?%(^0_F<ybBm7gp z_diqrBIod3u~63knfi~A{{PUaetuudB(f2qObYRNy5lMh<hQ(`)wkWNG%4<Rn1MN8 zA-<U6NY~3tYfuAcFA-1F9?rl`n_SKT33lH-*}&b*^=DDjSl?`N--nfslF#ZQ`*wWQ zaj^J$s-Zg#Ue@i!S7IRwSFn-8e*O7q^hR$dQ~r1a7PPkjSr%<@m0RPOs4B9btaMxh zbff*JeYY|$78|?<3)h{E^hgi(T-g1yOSj;Cp@A4Zr!RSsgSTkT9s!*(@9kCpDs(S1 z4l5$IoY_}hu~`9^2c_rA@=2e@L&|2!8X$+%r}H!C>V~cmI#lmRiH;DbcJK}|rt`o! zy+5DJ3+62@oh6Ql?@ba%-(kA&j+y9ChxVOVxsSG&r9Hm?$&1Ht6IUY4+}~^5kS&Zm zj;c*RRZR6ZWk&DBH1#cguUzVBI8+lFgBZ@Ibk^T2?2Bsg(Pk<g(@3nWJ+6>Xsysqn zxsZ#;&$aLDV=kEaJI<9#s$MkoZ56BO+eI*_9{60lm6gtJJlX#C3!OE@u9W<41qS6+ zup_#LI|&!u8gX>r*49+v;^fq6Te>oWjr~kNV;?J-JLHW4o^XzrHa!5C1=Ejsd<VgN zuj)0aC{{(lEscI1w%G;1SM*s2_PFARWKk1evSue9Q6K{yt(S`$pa-Kv`N3{|jSpo= zTE>5)Wsh_?*8xf}QHU5|KS1<(zo^^xW;3s@5;LC+p}Jl%5|rYOajQ_{vnnp0?d%nY zt%RheN_qLCb-SVIe(7<ExCHcwvoX%a&N;uq?eObm#!8Kko63#+UKS)my0h~Q%O)W2 z0&g!aR&b)>Mo3kqdDe%x`tWsU#B_?}J>LV&&R~su)0VU}`t(3>VPbmi0Dh2|UFx9I zmc4W0JcC7dxgJ;)E=(r5+HFnLtVi^Xo&_}u`Ih=^ujcT>vDhmWQZwR>`wI<i@)M^G zbb|Xw(~y)RV*qneT1Ok*BC~btq2CDHa&mKF`Lka}t>YQY(kopv*J7e!H~O(>T4R-G z@?)PLks)jH6~U`esg5BXk&fW<BZn^Z3YxjG0ETG8<w;hRDa92=t|I7ABNt3TQmv)* zXEx`n@r@T!?~k1JhMR`bbjv$kXNail62XSj4eq-NK5V)9Adf>2uXGw@yRpw|!zQGi z?)1!eOZap`2D9Xu&Id^I4e8xQbP!}1d#|Eaom0Q=PB+<)eeh#$q9xT%=n;I|FLdsH zIPvyq_W{5Nn_DF*m3GZ9!sWQ)OOK(1QEBGH6mO+l@r>I>OZQFhEk&~A>M3K76J#!w zSyS&bji@qNsr!DYYVDqnRB7vrpKA{=1O%8|ZyV3GYjkIw-qNbKOW#GRA1*{Q7^<jG zKT+x0>Z|oq`#E~c<$8y42vfVWj*zdC)#mM;#%8PQl|p&<`ZAol=mky#v|!)6J=2he z!q2FgP+(=i*x<@Ka9q(pNn+<}n9MIJL@3LfdZRu%qOdrYcTZt>>~lBm4Dyw!e_`f0 ze0yJpsmAYR!$B}ke$1f)N`k347Q(*f^gOzdKh3Y<S+~Q^i&L*Xf`Eg2eOEIYG_n%n zDPE>yd|o;<$0yR-@3n}GP0)e3sf_L05~fF+GI^dpLhetsa1S*ulDga1Jqt&~PtzDt z5X<SG2JE<sYwMhJtjC<@x8an}ok@1?o^O!@AMHhC3iu5!(R<qTI}O#kc5PiRxGm<c zW$EwlX~_RX<Ej599oYDxI$WdQ8Sy?UeJB6KkM4SjMbogFwM}!p9{wuS2JmhbjHv0t zuLJ=+IqdQ<S*>;=!`I7!P9EMBes>8K*s%4+*6Byh@-E`E<4eDLPpcnJ6T5oBXxpLY zwx`$PH*~<DwK^|8z1>6FkdWG!^*p_)@Qv|0{pl*qP4%$gh<GK&E&QZuu!MKA0mPWJ z_YPt*cHn%zaiZ1glg2Z5&|inB*RBIqW0Z?=9^SF1ch`=sERwNaQ${kCl~%>Z8&xB< z8l@f6x}~O7kM`+|MQw89BZ?jlLs`0h_mQil2$xw32XjS^`4<oGWn9M&`Yv5N%Jqg| zZNxV2itI%yJ4Evqr;DkCLClnE{#d?8^o1O((_=i7$8JTmXVN8y-^L*wD0Wa`;&}cD zRgWZ{(6U`}Rt7%9x8TJ7K2HK5y_-IE0N9}@#Sew;{Veq{C)ju4dgu?uA?u`rp_4(Y z6DiwVq&$6Fl#ofWDfc$<De!T^3<Srs;9lv4wKRUE3jY*(WZ|iN|3>gv#~Az)ffF`& zQsezxF+^ks&-d4~EEDt;H)}>OFUp7OKRFQul&}2=>nm3h6?Mbtmn}`bD6=Rh0+mqU zSJ72G#w*Rbu3ineGExa?!X644A_ic+d)JDaa7u=w*>+&#E)ezU;6b(Ma!0ce4wBz{ zp5~6t62Ln0436QBoSdJts>LmQ6)DfHx$tUmfR&tDl|HJ$R@H2=xz{uWGk2IMKa`*+ zKY;rlN<DT)dY?Qd<!Lm-Zd?UX0WV92Snmo+3w0jJuR1E{t?XAIwBrZu#|DQM#s;|n zBc;p8vMdh0+;0@h!;(BSkik+wU2t#Lb0p$R6_Gcm=jNB=B73{+h#9*A1m@9U75tI| zxVRyAto1T=006-0iaFo~!{2=+;JNoE0J4_WgrB>S5aPIS>Qo)_*@hpu!2oU75bwDK zfDuXg!5!rB_9A?#ul*5KLUzc{H5X7jz@kuA%yS3)G>Z5HT<&j*rpT(Vd!CZGJt@mg zNdiOQPbSoSAALEwwrd!g<}(dVJ2R|LX{x9_Q(>CQF7271V-{PjpZ40GTnUb!EE22R z@XJGAhSyzxL27LOfp+3YD?;2vlW}sI?!KQ5jY35BeX{4H#?0E8<Hn*KJ@XC4O~W4| zy%)adW~@!pT8ouxSbPChu_L41tZR3viHmE8B0OC4)zQPrM{a70M`!Qe_qO&YM4srm zWyTMpt2|dIjD{<l_JgX{o>mq=ce1FQDsfC1aagK(nSk|1w#?vG-GaD-m+s_{gyENU zvmyt}uTV<z?E6Y4T=zC`)nh(i-PoHGaKHEprMvh6rGr3&&x`8|%otL(rsj@50JT6- zJE69BN&u}ZY|Zfq@~J%^vXRlo4;S(HO%oy-Ly1882{9$Z1vItv)2LGX{g*Vt-+#_n ztK)McY^y5$-r93?A>0o?a0Q<U75yc<xvVpLT%YEC6ktP0xqAI)xtRSafkL;g!Z{B$ zzDBn6K=0%bzm#f7FEWW@9gR{IbNMQ^q7E3yKRru4J>(4Qa~<9$IRDz%FHxa|3d{_Y z3SC>hzZ0>mUf`|ALNYj2l#R(<@ou`Pe5_2!S>KDJ5k88SIy2vYJh+%}sW%m|&CZtJ z%6J@Dd<93#K((~`YzvF>TT4B%7cVkHYc?p2;La*yRC6Nj<0*#Eb6TOvb;|tbQO;6@ z=nCTXmceh0J|>gigB*vaGmh%yg)TcY<o!Jfsg_+5BZ#rd@#D8=MCq~B)T0$%Jw@af zRXs=7QrC*H0n?nx{n|N9?T6DlGb4@X%&VXD+@#SlVig^Q>j!kBkB7>hrdepbzR;SC zXZ5iSna=igv$|NJa$lAf?o*oOAlI`k`J7f~2V?hg7fMLWM3EA6fnAw>Gu-`-N~R@t zIY9YakzgGhY42Xu#_BU3N@}t8>42dKU-6=FzSCTVdD8qVjvHv4JqBRWm@dZSGVQr> z9YPQ}dz-K?*v~47!)4pU-L1(+=H|(YS8$}UhioD<Gis(_%+C=!&o~pac|74ckUzgE z)Jy8j8|ZuO%8rjjMR2M*4IqVX8X9<hqc`kI_{7P&-`Xel6#IsBu^oHwogk&mN$(}} zjL;gRxN*#+#ZDaj;9fnb^L}g2_g#Yzy6$BvM-rq6j^nevyg*-aqXR$Uoq<^iGT*h= z&GEu?6TCVqJB=8`^f-=#@yk&hZo0zx?4$P0qQr)=qb)U`UXPvdFEJw>K79}E<mD}c zC*-O;tH90^d9rsmD@4FSk(>O>fUU`ut?Z*anpw_UB1iBe=hH|#+L^I2V{G=c=gI@$ zbsp~FCiz`c$5KXAe$5bOl^C-N?K+*Ht4)vK8I*L}whGy?=(WhSXamXNBqxg8aR=`h z({;~|W5;L0wmCL5{Y*zMR^GT^cD1lG?uJt$^_mw8v$w}z*rj`CHoZi3QSD%74MO0` zfYQ2iKvh-pInoN}I5X<tZJgq{oQNM^Nw381n6@8fRdo-0@iiHP<0J0w^jmp|EZ!u4 z@+eL0#hCGN=ivdaK5gA5y%l`nv9h)8PQ7A0-!SxQa#7S#SyFHa+n=U>5gu#ETxoXR zeATO?rzCC~i+0?iUzfy<!yb!wlw>|CJN2(By0NqL-Md$6(mqXUWzxHZaVOc=aUA{I zx#6dCl*q|Ps#K@=^PcM^*Z}Z8BtKOh<9WI+CGJ>{7_bY<8283vY-V<-)2lF^C!BSo zYvbAIz8*|d0vOQjL=xdIjG91CDZ2SC7<PC`1Jdd+`uj*CKlKYg%=A^Uu6-4{2HFqr zRNfO%3nX8=#cGj4@rJM}hKAerN12XLkwZoYYFKH2?<yx5-1^hfwXIigbroVqH9}49 zWa@`6aF$69rkFm^*BAZRF{}N|-Hr0b9kur=CM29m8G0*T(=%A#rla%y1ERn;O?J&k z7ZOcl2M1D~+ZzoI+(8G%;;5;us;Ma&R8&}{Y>>iT*S_$D2%@O?O324VtGX`;_z(H1 zNi~zsJ~iF-;92p)?T(-#sfTdw&E?u5fRJDIXuM7F+>41-)AY7P%aS<#>TO{=#{-TK zy_kd4sd2Hcp2&lgk+B~7F+H=B0|j_(+*(YtQ_ERn{KyIYY?y(JqP=ID!SXG$$#90x zS3&?dxjS#SC`;UP_>xiSniqyNdr-#(`pQfMO@8+=zuj=k+->Q{YmqeZImrucfVu;2 zvfdE3$uiUJ+wgSoi}L|FJfMsC`0>Wa?-%s#AL*Gw@A!^;WijDk<#)EWK6;Ogd}m4s z+sy2A{@g7bkKFeZr%yCmD0GH+nYG{Z_UOj?dm{Fk8>9WZVVe@_{1@`!;UClIVuSY{ z{CHp&qlIfa6>I<Oo)rU;lVf*^;@v#J41Ejt#Z5I;+_>>%cm3vfrnvAqlt!TKO3KI5 zl-7u)nKn83atp(ez7t`Qp`2RTb{&>|!7bO8-m26SBT1Izt+;Rp^W>CO*~XY{DOK?i zsR?P}C*t6}PMcw7EJ^sc>BDiDJXPSpcq4bp=TkVuAkqsn=A2b(RZ$w8T*a|P6~h*% zq&vEB*LVe4nyA@sf{C#^;mI<tLklb(s|;mWs@z@qY%OH=(Wyy{z?eZY$oG+u@Q(lH zSe~DyRfTcny2NYm4V&eYn@J(Xs3y5L5+CPoA4Fr+ruMzIUbo+vT${p8`R`nqXVW+= zL+Q#6*?XfN1&*Za<!jILbQC9Kh^(zov1A>4l!vQAuCyUFUMpYXY|tRQby@c5&ELOe zfJk!c(sr~h@d6$V!pC-mu}CW0>FLiV=R8~fgW?>S=CxA=5`pK*(obKK;V3EaGR>05 zsqZQ#r^^j*N8NV%?b~nnZ;b5+U-^72AspgalqH^YB1{03&Y}ua#+T~faX!z(o1(hC z85F;SAW7nQ!?7%5G%sIHKkQ~6{MdqWoA!UhTCD|04mi6eaPg_znW9s|JMi)uEUNXT z=Y>E#@;Up3?@sqiHW8k|J5NaBV#Lc>uXDF^C-c&_&8TU&*c5tF<R&MBue?ua^n3Mo z<6-PH0Ci>H684e>CiM%^jZTO_n&8mVkT;@>gI*{?+QoOa&~?BdtR+~{XI8dzbK|A{ z!~c(}w+xCa+SYaxAh=6#Z`|G8U4l!HMuKZ_8h359aSZ{21PE@y8uwtq-92a{m%Z;j z_d8$Js#;a+@2dF@d7m-Iu*7fhQL|=!!<-*Q{0f%CIZ^B@tdZwqWEW0U&YlaU?AfQL z>1y|-afn!D1zwfYKvJ;QP7N24(QI%;V`7n#jk?SRskK1Qz74V{Vsh^FD6%_dHHgB7 zJN`h#Jg6pj>iITRE>76xN44C*p1fn?p~^QNXyMK>CXOWi#buPiYaF7EK`G0_Z*hTV zOB9$~aJOV=k2@|px>EJUJXsp1opi`9J0pJ34(Ffhwh(9qyr&Ybm|j!H6B{bMybHp7 zl|Q+My;}B53*S!U+N5zZ2E;g6c3bE0B630Nz9tY1$(7MJy4Am$07?=iqgHb)C`{cC zT>@R{F#T=sWP}FI{+MX;ix3V(Kn00~|EgQ=M+&o6e0$He#aO6iGq*)5OGyyohp)eZ z{f&E8Gwu!eeijbb@f;)j^rFgBNwc>enoC`N&$X%(U3NQYDREMri`dZ%qS^c7D)Q@T zQ*GkzSJm~R5kJNUA)A?xz(oBY&g1<KL5?@0U*JR(Hp6jP`vB-l*~gP5d#&DF`$<}X ze-ceBA0JkW`1ecBlG;^BfrKpQnH~#bp3Am(%b;?QB?)dZMyG4>Yy0;05D!e#_4imc z@4OxeetR51vlio^;tVAVh>kdZcDvMn4hc#)JB!bK5|0n$hzUsP`&ZaGKt`e9$TVC6 z{<Vibukh~`A%-F;b1gg^VDG!pxa~S8B|0QD(?Oex*~L@&QA7SkFjG^ym@x(eZB<BQ z=6RjCa;6hlF_ZNV7Z9r3F8i|-JyhVy3vJE2HZ<0OT<}VytJ}LEiPfKLLHXNV<Qk=F z`RNyOW`W$_kB~cpmWc}XcH$U^=bocX2khGnt%!5NK}{T-ASbSL4=5in(D&bUFN$Hg zNd|J)tZG)<GbVvYlAOW#&H5|5LC8A#Q-QbVMv(vb;f9b2N4i{9CXqsoQ`}k01Whg3 zgA7~3RsVKxL7lIDoEZIs^OD;#6)tP}R(+}i*N<}y`MErO;6~$u<x#&y=-BeG=yK1^ zCKT)E#cKKcp~l6$R>o}gP(iHLmwM;$mmgbCxswmAuw(Ts&3}Jqf?PCLe;PXo3Y_NO z82;k_d%j&_qaG*xSmX|ZYq;KB=cgyT_Rj)Z>Hi~Q$`L~RWUPMi40Of9F%}nx-WUd+ zJdRbpX9fkp*TbRlb~~D_kc><=FaVda8^*{Ch+5To?eLb{>CJDQo|dJ?PC+$WtiRab zbFHYNkFGvwBk-w4R1O5O?CIS)P0r~uY|E9=PSEuLyyt0DVOCg89Yze&E#Fbnocz#d zfh*y;pdhUImnt$O$H_S7H@E#RC+^}PY+b5}Gki24HHNMKE<M5E;T|&=vvkKKz95D# ziB)c`oa(u-=16?yE{zGM>Ucjca0x@ou+W$F#a;Kum*{pe!u9R>HP`SXD3lGB>OrpV zxMzLRle(<-I9uoBO$=>WDiDun2x=k{S&L(4O%`!rqA=w~T5`TWFb9bK+3f0tVMlZk z&~>A?>ucPNtb!h?_;Ihv&*?H3!V6lh$TKGLwjz>7n>fzCH)_m&P9osh+kS_Z-x5Ur z(W)!fI_W&NTpljzWp5wCFHC$7ZT2pDVjut?ziT4O5PxCZTe0evXj^8-`B3K)2qN+4 zuabSZ9ZJXh4eG23U@9{?&S)kVd9gsu7qu+L8iczo3QRYqfhkxz6Tfz4CvM{OGyDv4 zeppf#C7siNYU~>r<@07#!3Ak25mIstLWdrL7a4Y$Mno#`+ZQHfI|b;Skl|i!$NSJY z*nUU<CFBAYsrfO%PMuY;5{}O%*qkZ8);jmd{K!wpmD#Ia2_~HskF!qK<LI58BTZ)6 zV-Uc2*8N}cM-nGmo~rsLz%#{9|1AL3X#O_<-Tz`(+!MwnRTm_s=v8#OIuwj?`bKGP z9UelXgAPmKKK`0!C;)3oVQol1b3&EpL!~v5b+o9uiD4^B*opo!&t|b0i?+4yjqXdB z2zJz>w6kjL!-Te3?ANi{_suC)J;p49i8hk$5ij;WNMyF~Tz|cpw=5`~xxEzugp>~T zD={8WC=;1Kn2=msb-mDYYAO*bH@J8vxPZ!a3@AZ~R}b@%U6kTysu@yy4#U&?B$g`7 zRXkeFhxEUfe<hB}tzeZuAdAA?$@u`Syob@b<Cnet7D3!m<<~V$E<IMaaRbF>WPVt! zyv%RobnH>(+`u8L`JVBk2!Nw*`-0uGdzI#{ZNPn>Ay}c%EEZ;G?I3r1?OZ7yTp{9Q z8RmIzzE8dLG@kH2OYq-lPJpP-==nB4f2{lc^)=FCV2?Ur_cfjOYBHY@s?IVjkCp71 z#+~82NICbTA_d@NCzi<aSPNlMV|Qwd;_^35?Y2`3JEBg>SP`eb<k>7qqKcWK?0eSA zTA)<HM2Ml2vW#QQAv1O#ld~o1$jOSyW^l%}w;*5acBYJFh12Eya$o7QhmaOHx&+zp z%TEx|N>ahxc1;-PyY!8}Cu=N7Uz5{5a;k4wx)b}r`}yy45QGTtq(tLq5{Y!Y2;tSQ zlX>dJSA{`I7lyFz;^$2>+WYDWU>WUNR0q>KiZju%{th1cY~O97l13s-@&!!z{Bs-Z zVqQt*KxC=+^&!V#5u2FW)x+r$gE9L^HO)5BVl&py1(SV@RE9vPpoNHafvQ6*D=L?0 z+nWmS^F2b!1s?1#W#%cF2$G=J7W%W-JpxMYT*}4Yi}$Fb8jl`Ip8Or8xg4QiV-x;- zLkjUm1^$~bn4sGnqUM376+cdMl|NN1JG(h(6uAz1^0Sp3Ls1IAzn*PSXT01a*|REC zu21?s3|`+2*X31lsMu&waS645vQ!}+mb-=pE{1*mZidyp($n~@<2))+2(5!f6+&@q z_>xx-nno&*9+qEQGlF)@xtqw?BiZwx50Y)uRH{TB;E`>Q3PCYK1b4wY3JkvtSUx<q zw-j)%vWxv&(A2w#6K!I7c;9!zUUO4@c*eM&Jt$n@P}NOIepe29JsN2P5CbyJE&mx5 zAL8@~qEW0T`U-rQGbVYx2XwW&D{z|6%#n3m9BEsLM0yLD;jt<@+70IG$}t8tUeB;T z&avE2tly96nuSm^U6+#92q)YX-f-%T899RKI{fPxP#g=XMJ>=bO%wKs9#_F1v;Hwe zDLERFDVhB2<M_=|I~i8t2CEZ;xViXRafjrjW^AS3cvK07zybrn^WqpNl5tA!VvC}} z?K7gjd)G?Uyz2saf7q){r0GQ{*<0;??+|;S-9&ndt19)m(NbZURg_o;bR|>YF~?df zSMO>{`PI!c(JYt{B!=};S@67ru+X;-ds~v~FE|1+CIF=Uns*ajS$OanG73KB7^gjj zk~#bO3g<tcEqF{pVi$W2NWEMXw)!zwK<BA?s6DOk4u)4OafR=51`KYKOpmEc4;bqP zq|IJG{V&lfJVq{U%s=<zC(-_oX1)8bX6<+~7}zB<7P<ZW!-Gjr`gMMSB2MUo5RuO& ztNrJSf!ry=fF=^S)ptedW`kY3jIkFgXCncluCv-IhYv{_#TUL&Onn?dKhDOXQ~Yg` zt+yn~8p}CepsdHDSZLW(a2*pua4UW!+nt@;8lQmyB&-TdoYr3}m!&CNcO-OdPsUZS zZ2FbrgGOsXYZeEV2dloU(=#INB_BzO_#?i5!4_eJdM}-~6>uUP{a4@&*0$YG5}zLZ zxDb^@qO6!B|5_PKeAAD4!ZAmgNAM$<KfWO3xDfY*Q>P#1aEOkcktF0=z#qnJqOaYP zV_2;bwyl(Ubyt1wQ6tgD^#x{`8KB6Mh#_rHmF0-ZG{@mIYyAXKW6*bi3mrm_tWyl6 zddK|=TtD&hp?%ZI87_u}mbD=|`o*FGdZ%bG(q8s>y8rIlcu!;W*YQ-jluFTuF4lY9 z5<S_148^TDyX~L$@3e+E99H`Tw2{eV5bXr2zENzFG+7ZXdAF^CKu2I(>7IVSiCUQV z)Ndg!fw%!X>G26HEzjT0_{K;4@@nPV2qT1ZhR&uZo-pGYQ|GK9pX%{)-v<M#&+lQI zdJC@1$J_XoJBeBb_XSY%p<s{2*A6W+R1)`iBl(A?W7dJhG8syvBPsv976+whW>lPF zfL8Gl4(RzbaWXFbE(^<TG8Qo>{3CtMkgZ;pUEyajj89@P@%>_g+_<WmlSJxivs^#= za-%E3ZcdH(E&YGrkLsMl?qdZnZa`B%?TTx&v%-X$ZSdClZ?A!jz7+%O;g~IV$_zD( z4F}y$0LgLs_amz_s+yPP-*rR_xg2;g=FYToGZP}#w>lKP9WeL?HM`Up<q}5ADrXT` zzWg!Z#foLX>iLuVBiVlxVVwXxL|cAOH*)eZ*s7p<U|};O#<B3)*7cwu>BAcB`wvMa z=NA8f;;o~7Su&-&I(WCvB9V0Lhg4CO8rCam0ty;~d4Mewd!l7NmB;St$RmRs;}aMl zgMy)s*JtXWeTwf<xRMz^<6^z;?Kp9P)Qlp8!nAyz&8TeuP@#VtZLjIV+7+SJqz7wI zsU|Hi2O*9AdlJsB4oGo&a3LTd+QYvHlrHH9XJctyJ`wu>B$<85i~nY-AUoWXuil^D z?%Q5tvOdfcbrn2d26R&xH)9*0lQSYqkA1g(HHI9t81sI;8*-Bt8(hhhH}+Uvn)dod zp)hgVx3qA7=89})v#Ke){exF=T5j<sKq2P}g}YG6<1`QWK=BRMhPLl&bsnYj>w3MU zOWXJhi2E4QK4|&0P_t+7+`wlx)T&n5r&v`j4DlvM>G(w4yjy~$)pceSjWAVkmI|G5 zA|BV?*RVY2`PwC%L*(BnoH02?U_NqVf@#l;pv9`xnat;~n;j1@{W0ltPE(Uk>5rEF z{c)2dAhL7fiXXg0S<+fo&R>(8+qcqQRt@jHBJ}>c!gcyVG$-y;_e-k6XC8YYT{NiW z(R#A%*GLa@^8`g**%B!C2|8x?sL-Z#++6o~yXc}q{RQHvLpNS~!<nZ8PIps$rN+X% z>s!;uS~PLCVoh)t7V&(PF>DA}oF&&=MREMQRjV6kyHk9!Tv8Q_u&2Jplq(uK33U&c zH9d;KyMMmU)nB=bBj_t&fqz~t=XZOyeiZ&I*!8&<E1tu}bia4dOh~*tnGe72!Xz=< z-SexXN6lwNT~6;r)=lAk3g$(OP5;7(GjlId8N%?h0u;a{nOUG|=KSNHOA_kKY28{6 zK<duscs~hx4~7>q<1JP$W6^nE@|dYa<8HcD$`%CZu@cOj{r>RXYz=GV=fCb93xw4N z-U7k!pht-ei>PlT7M6RKt1KG8*inWDA4+GA$BN9If3O8}sZD(7x6!mdq@TA8yK6@1 z4f7i}NY_<Axy|gxYSvBFXL=|&#6D%nHC!dDHD>PtkuFS@G$K&rs34s3xOH?6!W4m4 z@5|yTL*j33PW+3=cDujoNAf8BV)`1*-%I7Pn;TVc#x}qUh2JI*utw7p-OW@Y>4o<t zq04%Gc2+GlCQe;13VIOBs0PjdP&st*0@{T8MH6mZ>;368)@XJ~XmKfm5qhyJQ@(O_ zi9>|-&4%~ZzXeDHOf=pL?Duhina*i;622ejX&9^>nfrPuP5J!A=4CIUtq#ogN@2G_ zP$HZ?55h;Y`MEwluH$hkp7uI*?#-j$6+Gke*E8vM8-NhFK9CW-!|}TfW?MhbJq>E3 zczr&Mx+ta6HQZr(L7DpIr4&+oa-KmmcC>pB8wMW4Ms4o|QT&!q#491UOzc2vwist^ z2%?64Q*lPQ9ha$n#hbJDGPoQIYLzfI4qA6|m|$uSB5cq7-q+oVpR{^+N5mrvUrkBb zn;2`Y<K|Y9;&Uq;V>?fG9q5C|eA_;WdlEM4W*qt)w_E+1Y3lQ3S3Zdq&+s#@u~+IM zoTXp%nYLRRu!m`X3~3?x!kcd*Z}Rto%a|OrjvQbohi&X9*!-*OmB!}TwZzy5(4`-_ zyWX^)d|M`b@;I2TQv~i8qHFRoKa8O%L}rAG4gT-TRQ5k51>yCS`P&CqYpTNj3{8>m z0zKNepiTdY%tYQX%{=O!XLpZZa~*PFSuAtXp-P4nyQ2fPlIXMlxYO~&bMWH&U1`1F zeY4<t8lWMtJS&opZ(LGurZ(<#mVumYV!#fJO8fBp=;a~2pU8VPZ9<2~9R#wUj`T^o z$82J|H;+lWRt;`lWC$=!YL^geMp6PQ1(3<4eQBdA`K+7l6IA6ud{|g`cK6n6IpvAe zv{@Wiqjq21_!qpZx>mUsy$iqHBB%?=Hx`x18$zojbwFBvSlx_#f+_-1-0>@mwL6)E z4N8l3SjzjE=YwMEU2@HdJw_xga7f*(Y~Q(uZ1&6gb)3ch1A9?3NgRkL5!Ph|<Rc;v zs4?v{FJ?aqDwjZ_6^^rNXWsmbIZz0C3OgJkVWk#XF-e32?^pOy&?d=E7@}^Q*9PHp z#t&=(+@PG>j+hFLR;beY1}?pC`W4F=E@<GCQYs?#r*=FF!{FEC6Px^|nFK`B*sKa_ zM@1})C4b+zCScPH_8)n8_Zm*B9NY}8^lyUeSwp3Mp$eKPWrQ50o*4gg7l4q>Qg>!U zkg=K7=!>>W{eW<RBhH)xjyu}U&8+8E<m34zgYyQN+SQWHLZxgU*<2w%3Lhg+^RQd) z3I&47d@B0~6Kzc&R?9`~Kcdp!ayTQnQ3XZyvmuiZ14Nj8*TE0!-0^FMdr{szB&ByC zvka)j`n|K!qLA>xqdoZ43#~Z8Px!3YqyJlYo$+qzI;Qg;hdV~NlzRk$-oIA3%dVS! zEz0wY6$|_*uQWAkFq0sX_e~(<I!cIpoUe4`p`HJz`+uU^-&X$}TtkRWo3UR@56_C< zh>a6~ko|Hvf{r&jQy9^WLpYs=|I>8MiXr`nG(sZ9%K2%(sBAu=aw7{oB{h-(9y_bo z3@59*nUkX!s-gREO9t*3FabcmO@5p4D&7Rkmsvlg3t#)(BP9dkcTG|-42ulV>hsR< zq-HWrCtjdC6W!Jo(6lkbC~Jnglkcl|A1TiT!C&V$t6wX}WQcjzJ)~5BCeVxFE_&i4 zNcTCApS>E|Ya|%VR#0!6Mc=V?j@Vx+iBdW%xmhK{X~|y3^<S8Sv|@2dAi|<^GY!kw zYelMcl*(hwj3bZnZa`_fH;<Zy&m|~k;6VOTqun+`cV+w6WKOZa)ON7zu>Rnk{E8>z z@bJ+MsSjC$x3E&0%~-|xBKIZUn!Lbf6Z(X*Or@qJ>(}w*s?s?mhw}VHr-?a=x`=aw zYjt#rltLPme-#Ul?g?3?B-YlF(pSnUwdzZ)tqyIjugWAGJ-u|MA27~5>t#y(vaEG7 zr8Kq&f*^4T3Mc+CbQ-`u6PZVWBW9lR8q4*9hNBOxbkhv3nx?=Hb9{~^VoF@E38j#t zcw+0ZvbZewHi#PvDG%kEe5mCCe8ePao%N>orK7fCZ+}LXC!x+!J6b)eoIVqs=cy&} z^#`WCeu|YBvCNa?D2&=FC3g#hS5y>%q;|S%jLnqA`hNnR3c|vg{=8jAiRU%-+v7!l z$7hoNs&W4Emorgf-6+Tvg)BI?DY?Dk@8(fGFjVH3DxI!}o{OKP*gsvh3H`fqF@o_@ zTaJ3(rq*jp*wxY*S{A8gD6UMt7^SV4MNKlx%!PG1Fc7A~Yph2RbXPZUz{d(yEDt15 z-mt*@Q;d>hF1TRk;8~>on!aO|vWqf66GYN8L|2W_fI3sC+C?JHP-4jv?&5;LjKr+k ze7(Vrt<P3$q%CsQr7`6<_bBbpG1vo(!SBv*UWrk}Yd(tRtG5^sOCP>1<YWaXN3rmz zcR4Cx<QUs{#d#SNK!_qopogkbu#_MKTxH<$kV@MBsD-$f0So&IcqC%oolXo)BHa95 z+p?3P;u0`4bJY63<vNoF&aQf&V*u4I>&=)boWy>!DUct3(HlHO@UH6rnGTHTe4t$U z$JTl6m!{fHpT@(nTgH$;Fy~OV)K3Ji=>|J0WFjWEc<z?fHDBiCwg)K?jj+Z%sqt3c zYn<{(HKAlE&Fd09$Udd*qU<=upEZB#k(Tw+XmvaP;o4%LWKBv^mf#NU#8cG16p*^$ zT9wWFGAPL`5x;+3L(wHQG|ocyiKw%aBPov)js;i+0@4zAhr(|4BwKwsxYBbbdu~+{ z8siB&m&P5%Xu$xn7|)0h5rb_Ar(L5NXVgaeP!bkRLM1&M#t#C51kSP_PcEiOOAq=F z2xM!<d<D+%S2C*a@Fuaz^=2AF8!pe=h`{on(F=<<GcCSR*tr&lfPwQjg%)%UFLAsG zLK*{$w^yFD%B=oEE_TRZ0Mew7Xdxx)mz}>V^_jdIDl@W6rhtwW8)S~2rWoGHVa{TW z;nv@DG_7-)-59z-G{k2-#~H@?o?D0`s#hy(y_opO+A723KrJJD?%1DV0VRL1|A=u7 z@SKg*E4wGhRg=X<Zea5d`CSfl?9I>m({t^N7iPy%jyQgS?MS~RRI`+8J&7{>{w_z& z^r`05dvbWDDYzZ{s7+1_gLzrTaw{q*Kos5nR={8cm$>wdR*0PN78zhD4rGRZE-D1d z(jfB!nFt|?e896C@|G@K<g)OaUsDyL7c*49-u1rW2E~%O-JdJ3|0X|peLwe26V9^c zA2QA7WE)4=w7-F!x5atQR~mxIP>nWEx=})?p*Txn_VPS{Pe24siK=PuH<+RBdI3Yw zA#D^f>GxB6UnEFoo;qe+>nY{jE2dFmGPW}M&g)9lqBo{)@B!+TM0Y-LH@M^d<qNC7 zN0=#vp`IZU%#Me@VSJ>T9}Um7e5}{|O!_#F6cD=X_F-6d=Mcw^<`L}pquiI@VBYG6 zSHvtum(pj@jhGo(iEFzz`BR|Wz*()x^JPj$Q`*hp1c^HISg&CG0iAEMGmfP1vXk?j z$H!G{Djnj09g^RqEd5Y_fik~tr3eZoN1SWs@<r`V9~#`mt<pJqr*T2|@(8jT^qmz> zRQxyYtII&9k?+>gG0KECePT%Jvg(*~$~uNPz~OjW(tSM{Y&dkOnCyNM>m45<ePPHq z{22wDkMxHagizP}f=naD*J@umJPg9+``ppO#W1shIo5Z(Kq%-eCyfJm2s=~wTm%EF z;-Y{2B-A$}S>)y~kg!}t5R)Fw+c61v_?EUqm{t2@k><RICnIX4XY>}xo3ideI=q<? zaYr}YKh8kb{*q1rC@0EJa2dNj2Mb?ZpaGP^hlJ?C!OF3e%{BI1XZ|D7!Dsq==6PDt z#B?v>b`l9~v<biUxxr!}bnb3kcC9~+yc00rC2Be$Bm+tA-i{$GQ%I!dYBUyM`s+Y< z=DfIC@FGpRylksdijh=G+T09#o!srh&#UBUR2+eF&9q8WE4bnP(?*VzFWZ&Tn(ue_ zt?&IS>mRoxlo=bpet8y!?;G5s5!r|xQg@lK$1S;%LB~4=16EoBX=oL<XoQ$IZTAR& z-cX(8G>*9k@#V%UFISWU2DJbvgRy}mB6`&W-2v{Hw9b#z%KP*_`WtxkO|m#kx!OZ+ z=Mx{2o#ygdch8NUg<=2&PM$J+^p$I#9E}j??h`O61yEenuk8P%tZ#`bc7mkQ@xuY& zrsho?O^T2i>*)Sm9IF0&+hkLC^k2`CG*2RQSKp^-YyjHITRh59+Xr>ABZ_%US=^x- zC9pL?OOwr@t)kgP#JA`ecRDt7P5pX~r=x}g^Q4bv)kvY1EsaC&i^%DGxJkzd2rE=w z#>gR>FE~q#v^?6`gb0FjwzP7(oHvHdEHvYI3Q=}*OF5DT^m}85J+*!<20RnEMe_p6 z+^>bA_3f*yJ0yef4M#aae`!oDG;ybWNbu;#Z_)OsYwjaX{Fs>*m#1F{4`^in+1-yC zfo|Bk12Vy-l_|F9xHmDhpYH?N9bJEZ$|M@~;?oEOev!>%w^?&nzk2*fTshbQtQf>! zQw|%AkRRic50Ls(S@bwdrt&<@myvB0-DR#L3&%{m*D54SRI33-hjO%>3)x3S=e)I} zX5>-`Uj5pF4(v>11o3z48VFx!f8Qf0MHKm>VNez(J4aWItETMgCB*%`EL90HYO8Y9 zVORkHV3Lv_BzNr9jc>b^GFh73HMuG3$EG9A1%%8FgLgs|fug#V2hg)WF?wXL2cn68 z3S@k%)yV2+T$jtgZ%-)8W-PE}!C(WHju!<^I*91QQ~^^5pi%OLqN<^m=WXh}<HFb! z&Y7ra8?Z+(QMWt#Qr7(|%<cIOa;H;@lP}Un5D92xZ){fLrPnZ=&>a9Et7Bkcf0xys z8$MKElTKhid_K_a&qcoZkd#af7hn?S51RkduI1tK$#*+}p?nX=ua>fi+vI)vCN7Q> z2;#)PAnhIy>6UTKu`SOWRQjt@B*L7cmi)`j$ZogFs`ORn8Fr5PuMNTKc?^so=!=YJ z$iWyMeOmlBkep}2nsin8W6l{S_yX=a=lXMTTr5SWOf_?K-N^*T{ImMJ2l_UiK>Xu6 zLfdyY^lo=`N^gwSCe!oMgV#S*+pw}G+Ks={ee{-2%*$N9`RVLI@$KoVJF@>0Lg2;w zuHc(u<GF5^OQ|xHEGLA%rcw#|T3^MfYy0WX=T$6Z)Qhhg_T3m2oC<2_^V=?(J>-9R z;z=ZPmK$I)exBBuBV~~uX3hu(TJ(W-aH5}Yv?ax$1Fn)mX(mB@t0x#z><i=XL)%Cr zy91jdajg#?7c*+eo)J(LFnh^^MDSDTF>TF~?hmN#McZdxHpo{gtv?~j;W|(MjZJS< z&!1S=i}XBgQ&gki06lC?lxhhbKmlYW>6L5^WOE-CPIpek$G(x$sN9*)c(UFnZ3>N* zf<tCu{C+j@?n>M~*+<0OW(yED0{XJqK-H{mae5Qn>qI4Hw3v4@RFwO-gIL=n4GBl8 zIJ&l~YyomvJE9?BI#&iZOuj8{b|Zu%RG)LJ5NswOiQVm&$3xE!DfkES75-6F$jESs z>4*dl%w30Vnc%au6pt@~1<Di>ztTlbR#Ihd#`8RH?a&W<Jmk{MB3FN;>grn&>DSQ} z%3i5Kjfrt4L$)tmJ_0W#{{BL04nmA3-Sj#{muDtqD{}|Sgt$v%DXdjxL0-HCXaw$# ziDbMLduSK2_&cQCl?9{mq?pSMoC0m>^Q|P7EW|X-*RZY-V&r$O&P9G&x0je~B@bhY zi!W&L5GU4Go<b;YEK(GEB?xxaG8d%<WW}<K`F9rlYs%u4$Gs~5$WpTYP<Xl;^zbz3 z{PBMa-+vuIL9R|c1pE*dlJ|5?;n@;-D0<G$E^MO;A=h#N%gab$7=AbZ&ZZMW)Kw#U zM19l>*=@qGr^UY^fpYUL61^RIyIiSOc)sHoD`KQ7jw_mIdL=n9={;B;51MQNm-E#7 zj;3oU%~vtElxq+g%&u|}w${Q5CK|dwd)WM1TQap&elshS^h}Cbd|+x(`ju9&`vWaf z$uEdmxSyF!BwRShfc_3hyhl=@oKef1Nf}ut8c&vlq4$gct|Iz2^H~;(wO8;~X={*N zTIF-c7c?mfSoL3RL&I^Ni)~N$_pt?2&D!K!c#*@?31>baqL6&;?qKqpEpP*Tq<AS7 zUlYp`pL~8fA+@(k9`aNRhTPt6eIDz8N3>FqJE%IxwK#ni0ICnd5@Eb|D*hIWSVRPJ zX3<WhIMCxy(z}YxI==6s@j@a_{o?ySPIl_Qop2f(^O{&M<B!NrW<FMwuZE?U<3VJ; zd$+_(NWD9<5;R=y2_Opjm)Unh$T+f$IKP};-?ydJCp0*}?MK5H{CWC-XW+{V0{!Z3 zeYo>nF^q}kC$zp+@0N@gacHNqQ)A{wwhYlkWTe5dsa6TMh@jbjH*H&D>anPJ?-sU$ zcwC`KJC#TgEviIN)_&?Vlc1!L@u|keN~_9)89u&@JNT>Mbx+0m^z(-Ea=Ie164!uR zDMSa+grS6%^s_=w`^1MJROj)5`F4c|ffd)u%e<$-dl37u(0^s^MtuaZ7a5RA0eT43 zc_|{83+=}x7*E2REwCzu@Lz=u)$Mm=O6p>?h5g_UvD~+lh}g(doXjK5eTPeFh{Vwa z_=#L!4=@|@af-q$*^*0{Qq=J)+2mP<WG+z-^o_MO!z=i>)GDpCF3iZo$u5n5tW#<N zUWu|CZ4lHn;ML`;#Q0(@<mFYdSqHW?M5a2;7-FpM*JEVcV*-y=Jgfbn40SD=JGCNu zRzhJO73fX{Fl)4$%<Rhb-amOvh$zecv&|k_5RPcdz_v)?r2KfNU-`eAu7s<s2$Mu& z>60W6B~)>1P_5T7wro}?{kDbKdoBWP(N!!}u6$4wl)EwzQU%lTMD$piR>aYoJV=+Z zMfY0H&*+494@4-2sib?P+7`3!SlZ+sa)?;EbRw}4;0u0jwF6Nyd;cRr-{6!3L{rt> zO+;>>65?^^HJ+wD;T}6T_o8WRpJNYo4i5fOBf}Mg^h^$Gl*;F1zp*UO4~Q|Fn60ST z7SKx?U9MP0*i#R2IIk`z%??c5IeAO;bvM6XKIdVkosL?cm#oD$hN!_}0`G_KKqNHH zLr)%D=bLg60bs0*H267qgtwMm&MSUP<9JzPh8!#d<U-|p{eUA&lBM4-G|X80<VXL~ zzF!l!9TLkhgP|wO>ZXz=pk}E8uu$E>|7!pDVL!+_+Frd0?M+fT?=Q*Ho7VofHz$dM zOp`qCCk{#b%mf$vn;<b5*I1goa39a{%Qo13YCDf3dbg~0MHJH-!!Cd&A3VxooKOeV z*ZR2vr!;_4S3&AhE*NuzCgGaK-cKJW=;52^4!@2<L`okng8+uEFRD8Y!LRC*apVA0 zJ_=?!Q}?zs@fAppA2VD+Uj>tHz85DL562>h?Bt<=c1LR?<5=MmlD}ag+;Dl(b?pL| zYCiY^4@S(Z0!|9zFzgr1%_*RF1%C_%2d^9AF==Noi0hspTo$t3ir=4~0&;mm)B?;j zV&yJK6w@B3Xp}A9tqwkM{|$_fVXC{hAiTLei>SYZc?@lAgvY67P8!{k{qE0nypo!u zokg%1PdG^J@Dp)K4cngy*-yt(>pN+9g)d=)%P%Q&>&dL)C_($ag~Gs@J@RSK)%3)G zaE55L`h~_+tDn(lkr*NV)C;z6S-TG{Zg(reH+}@3l85~~ZPatwZaJAyV$45lXGukn zD|ynwzKGiRsPp2rvGWsW(Qc3P()t%Q2EnSJ0phR83VAI>KGbVnn_tF4Tzf5FpApmD zdYK8Fi`^&OV2LMD&MmSw5~{_Is+NCrA%ecxx6WmiVZH}Vz&Fb&J%qKkbvlZO^7-BF zWNs0fa3;Pz!PH}I!V&pH14FTSu?uo4GoG{Y(4Cr3hy28QQ;3M_`=^$Q^(beNM>_8b z%d0~z{~Q2tCiQKuL_jqH&$0_(8!*WhqvD8D(+?;DRIt0V$Iw9C#X0r^x`eR7$Juk9 z-J4jt#}!;@`cvZ?dg06p%MmY(Mxr0K+3ID-R?c^*m&u`W#)`!Bn)n{m^C6e(oT!q0 znx-!wKk_5U;A;-kf_aczg=D}UT__&q%s|Z6$jiD!(D(jEa6u}WzdA{voFg@{^()Xs zhP+XwxzUkCX}tiIFr??}9C#eSK6lS|_%v4VYF(g_ZyUxQHnzgRhznlI1x#96468xJ zz}H{LT9R?vo6k-HoQSI?)dF1ZJ<@VqbRhY6OJps|3eJyv&B3K9m$W>bps_hf+G=9& zzLQ?02*dE5n&lNyB`&neElY2tOHH?=59x)#<xg(kO9`NBL|Sm4u7RQO*A)NN-6~0} zY$HXYQ?oK#<KPAKg}y@%##BjzBAe1d!j->TL$yAw+CjBNzQ1?)lJ7YB`;kwl^>Ikw zQHg@X`QYA62?Tk$;BVWE(Kh9}RC@OiMeK7GE#w`;*4wE(@4ADDp|(N)W#fzdHH5M_ zR+%`Orpd=S^gunLKf_myzNw`&U2<<eLc_qdPtg)B{fl<F<-K#%N(;@iM$1_M>>Xxu za==EqScU`P<sV@+HL{eV4^mX2i(74rQu8!z;g6Ur&VWyx`}Izy?h1mcW~O%m1yG$a zeaDz;eObuuwx`8SpfS&{<I<=#+NMQ=+1)7^lG{dtgynkolZ0SEzm^IZL+TrNRfl94 z8M~!ywp!irmoYhfj3#D1CknQ)Apf8@KmXzIzmtW_>vh(Fo?Wv2^DMX<y1H++9-}TV z$3kO9U+|2DX*uSczLVA|UoRN-`|!^#$o#*o?f-||Qhf~hHGf@KaRmPc;kMx7ymh<E z=lsQc5Ctg29^A_~1oBn(*Mn1@EQ(CVtzECzVZxuBjSzKkiR6ZY265@b>;AOd3jOQH zM~@j2bNzuvdViVoBt<skE(b6vL>RF(RV<O5VobwtDj{cM$aX!z!Z5fQ)DY|Aqrrzy z*=nNLUP!)~*Pqy|{kQsaX5+Lm2R8MjOh{kTV<7H5@ePLkA59v5p-nK8`VeIWZxA3V zaecs9i~;OE`6y3g$T01#-Maqsv0Z`asPtLYO+>xWQY+8NQ{$W7^mP2Q$csd-b=oxE zp!WRp<l+-8Nuyl{fBoLHv-=niuG)*F0O#bgv$^P#TwsU4m+Sd!S|mwi3K7f>x$&D| zJcrSm`t%Zq!fa!rP^_&<R5993(^0a3hGy%Q!nrwJ9ZxJC!FD$19L?5La!X{5Ux%IQ zKf)!#T*s4wa!woc*O*c+*pG`5YXRVGIPx3eE7@{buSA&2N>`abfPrWHSaMX91J+oO z1{r6oMi@o4;*Y?CM6!|cDC@Bh27gj62*|s$qFI(wN}Dgn^d|7$FIkWGP9UxI<L-yu zhr0D?Y6S!ib%rUfI}K7Ki2&Jg4sk|R-UBH|)hA?)fmR<AYf1X*E;9H&7Ds;tb>m#S z5<+X4A}9qcDbnm#{K!ow1kX~eE(b(L&NKVF7~YbibYE0He#410v%4VGOj8LD6EC6X zp??bgXYaO5Di?KeYYfNkX}RVzCo@qsaNp$*ju#b~yJfluJQDpadaG3B?#yq08yZV% zXHyG#ZYCeYxpwG%+_${_Go^pW6-zEYUo0^!3j8~Sg-hl?FYM^5v0ha4pCV4(24qP4 zSc^v=%t7GAKmLLrfyHa!Q1>&|6m3o#^x9)f<atY$AvoeMml{PCgg~r3ZtFAo)~{11 z3hjNpAP9Ig3<|iO2><3xeI1i+8@Q0?=24YoK4bVD5@qSxbcVmp@8v{HCF_;9I5R6w zs`tv+N{ghjXF}+?u0&?Cl`WvRvrf!}a)|THJyAc=9rHIk$8~2sNvribzM9uc>I7H( z(HSFsViEHO7gm2Nnk`O)6SRQBio^asu-U1?6^~LP9BO0rdCSIjTMi*XG<_#(<-EFY z_D(GZ9f@~qSmf|;>9DAm2~Hpg`)=IG1}tcag2+`d9AGLJ4}I3yYR6ix#Ph{+?#niG z1LVy5+)lJE(v0G|%Hg||tJ62VgNZJ%r1WF6`%FDg{|8wd72Qs}ZAd8hzk3I2yi$5S z*DduT-}#;%y4dUW_V~<K`rFsb92*;R9!n_z2g`k?KK%LS{x6^)k}sO78ZgJgJaz~V z5%G>V6=s=;0H-FOdnw<>=$xkLgtD)GVW6(OT$DOlxko$knPg~9d-f72yKXNx)zPT< zsYvgcdNVQ$!R1-V-&@Q&jwknLwSk?rNgpv)pxKysj2Akv<1sg~6hA)uyGD;zh8VW$ z&~gKHH}FPy>^s_bqXXvu_O;42xhZ>pl9D#I-Ckn*@xuH+9_fFr(#8L9O#0Xa{}~6s zerq_%1zV`UDbYxRg7@~Ex(R5Us5!)`>wvOz?FDs)ySxoC&uGoecAcZx!l9bek*`w~ zIL&T+Nj)(I=qu%CM4@V{51}NL-@<lEQ?f(GIn2g&Do&BzY}u(jfmbH00eic`GgFA$ zI3cWQLE;`}W#j>=g{};n6}S)>S5#8LaUvaAGW5Y6l;GGkl1RIyIES6_b@0dzlKt<! z4$>`mo_}s_yI9!!)P(f_^@OhhqTQI&7FKONwH2L^nPh5#*;zY@B*x8M8g;9z`1fq` zH`4KhJ0>y%1zcOBt|j4ID0I>heUpU*x>y|%yNR1YY^&Dz#NNck;`M4zJ~N!;tLt>o z&m<U8O3Za$nOa^87>r$P#aDzZF0~ipZXfy(ix3KCZi1=nG<C}tU$!1EA_EzDBm2js z7|EZQnAN%5Q*aD_C7hsr7T*I1$LFHq;?-+)I!aSz_`BU_NfccKS9k2B+|R_2GGZNj z1dL<6jW4XGw9+PchPaXOuoDgZx^slz34Sqfe_bz5R;H@Qk|j2oo>tt_tCm|)R;3u= zSSyJ~hLhR*BnpJn?WEZgbjCh6X{A(AHNO10hVjW*6bL{>hZdQw<*K@t7Tr*!+*j4^ zbb6uhE#0_zi+Ox><M<HI#@qH-0MPn3n7CzO(A_%ROJA;M^?m<Njtj}t;wgI(w1R9I ztVrt|07!*=0ho&}+^=-r+JwmFuLTe=+cIl^3DdN_+{10{ia8FVKPG8&T5)W5;+0(y z#&t6d!9Q$6B#O`GTUu<}l8HJ|>_uOtujv$-fDHG4B6ANI5jNJ^5wRv)XTr+r$_p@1 zCJeGyu-u@k3Ibp)9=1!z`k&v+#+fg}0;T^kWLc|{K1lU1UZ=V2be?s{$N-meNKaOt z>Jg7OG6!;FeEE3rbRP<ezIdZHa^npc|G<IIJlMw}D_PL0CokDEToNdO)(y{RH<v@} z4!1Gm_nyoirU30&P>YE>X^r_jwzWsGHuf?=-W&tJDi*9t=OQ}CWryens=TpEWJbyR zDLuZ@WlzL=o$tu^B=Cd^<WUJv%U}}LIDq32{H|w)x+CwfoiFX=dX;4PiD;9efuBfm z!6?q9e(2Xn{4I%B7tF&py~Ndv+^IzSu5&`+bAMwTrY#qG5J0Odl$mSnSYkH)^Ki3A z+n;XP=@j*ETEtXZTe_9f0d!16rGGy_KQZkr=%5xElWB<cC-Z;iklV4}TV%&yRnZqS zT)N-<JIER6Xd|iCPuGMnlER0zY-S`m>vuK%_!0-X=}WkUZ)WX?rKt`FDnwKeDs$EC z<m36f!tNXe_`7=HmEI-2B5=G+dc{MU-X(z~Cf%rM-Jd%s2-b6xOy}96u+u`ZfrI!6 zApky<2Xsh-pGd}@Lh%kBDdd2Lc_V;9@4Z6W9h&gzgE$5nk(?1qrU)}S?0Ad#I<M71 zaNcn}v4inITu4<wJTA|*ejIRnxl`e)HTL!SjNvjhNH`pa_WS0v?lp}GDzUT@4hkKA z>i`8F@tdAbKU|>c=){s)EZ%UUaKcV=37>N96$EU|vCgNLS(5M((lw4WU!J2}lZ%|& z&-V?K2g>}Iv&Nd!R2OHrk+r};vyD{tIy&yacF@)9?ZparrQw(o0RCAZ<!$*i(Zqvc zO72UXjJq-k5NGoy<9|Dlv6Aoplaqy{{geI=(CPUfp!4XxSb_Nf6u5YC>@<}#_E=QO ziuE8Q4ec)ah&D?4%z-O5fFRi>i|q1eVd_A1@X?RYnbt5ZMks2PA-wX;4C=H2qqa;i zdk-w*DsMqV!O?d{tz{eDC!B&q12+@Ur6N|v=70$nztd$|!KYK?a(Ii$wCgk%RSuG- zr~UP+wsd~Uw+I&q4=LL{74Ep<>c-vEFNXJcfiF|%m4&~gE4`Tm^{NfL5}4h>&PtvJ zZ;3})O7FSci7>0%sLc($61-4AX#o&a;{2XqlzvhHD;PbHoN|)G%#$dKef7`J1e;NQ zX~js>4aS6GJ@!>Q2^MLQ#FGc?@A18;uL&Ky!ts<AcS*FokdGaEE$JkZmhYDZ7CGWW zcGOlp{?rsWwAka?zlTEVx4{9bo%~Zp(pRwF@wkJedbJa>lh@}LGJe6uNjj)ANt8e; zr#7%l)b=y!p*Fn%8N=4VS2-*0%TZ@ryO+!w>7C4VXXIBF%e%w_j(U!kr0R7Dr}k>d zrrs(a%C!qxeHVah3b5NMrNmGJFby9igVcsum1kqrdQ3Djhxb;L{ET5n?+LppjRR!r zY~e~-Q6f)n(}Rr1jd>52t18v7rpM9dfGJoZMK_#VroAvV|Fu%#$ZF9YVythZDT<a- zB6A*?K1V_}>R*S&#mK!wynE<^-MI5B&Sh@`u_mW7YhMI$JtPVDFh9Xbu*bY-T93ks z{RB05_{}xRmn71SkVe?HwC0X^H-nZwo7R3ZaeP?GvNIOpkmcW!Q8%Q8zRd!8ID1rG zk!F^3V(yyAeH<iSzBp<lM(xm`1E+AUc)ryefHdu!;Yp@L)d{W$Uma+xKJzxRHX=}d zTuZ9BdKKvccU>QonB!!AjQQOvaP@joDJ1<h{{|L*pi%!P@0LwS|K83dzV0NGulO~V zTj0rA!g<N5-So;iYGGszo`<0gz|g%8yZ&M@KA3nQkwm@Z`mBF{fs$l^)A%vjZivrv zr3E>@@eS>GOJLy77iIspG}8S5jN;y`aW*Dm&NhhWd{S88)d2hS&~k+!j9M4n884$$ z1r=fv*aSjLrapnWj~r@7)y1O?wzF^kO{AauoXZEX6C4G_A9b#)A+AZ$eMegBQ$8lJ zYZl8tf0NDH8k@bI!cplTLtH?S!hg6WL`zpl%(7xGwI7}y1bFjhg7lRdrO-)3v*$iZ zI{>?E`yZFo1lrDh3cdYssZu#T&+g_m8zV}^eFN0flWFwn!k_Jj`5hq+c-UCtVuYh0 z2hwdk34<t%^#U5;RW8)o!qe=Roj{iip%1rN=Avaq?~1xE5kth#KO?*7g0Gaff)=H) zQpOqOa?a_U%%r=`+u{O0smv4vZiN)dzlN{pS&yV2!z+HM*nj!vUuKx-Pk&pou4xVQ z^jTH-n)P;XP5gGR9eny{TvMv1lS1vNQ_M);(=y?BMLp(aNPX3E*ZWV>2nlWaBW~;4 z6v|Aii#`Oea2kGH8hz68V7*@JBovQAcXmC;W*7@STkq}7Ituu^QJurwoz^C{Dz>H< zN<~2UUpf;6-_!OwIGdW4$Qc)UJfBou%h3LhiRx7qe}g+5<ZR996JX7nhX;lXB5hce zpMe!9N&^(176?I?c>w7Iz}Hs5N12aVZY~k26iQs()y00QoRg3GESy2<Y74zpd_K=o zJhuO6>LMy`Je^T~xxHw2)cdIqnGz13_K`Ki@|gX$mpbRo{%3OZztwEW1h%4s*t+4? zqsf1SlkvYK{8_%n&zZtQm;UA9Q8gu)y4@P`u|sF1j9UImn=$@tT%b}ka{DVXvnsyE zcrjO6&I)af+)F~D#XV#9mw++7h>IagXZi||2wyg*dn~8>Y_qEgJ?bD<|L>l(1dd+< zK)9TCozU{JS2TJ^NT?7VXZV?B28U2&rR2k7$<>5bi}e=v#`+6+_xe(BdSZPH%3g&- zvTI#xC237NMhQey$RD4cL=e%o@bsYj17N(fb~piS+~TCDSy%j*Q4d*PV`h;fZjaQV zWvMID8ILAhpz5OcH12C&R>;U<A7_ee#x~!$0q764qhL%s>Es^w+@1$>)u#cE`WQ81 z(2`@TRtpaj-gu;eF<PaWa1845tpx*Z!hEq=i!Twp{KDTPt}o@CQISRqoFu=+a&Lpt z9ou+FTLE3@9lx7`5-SN4w_@dpDgYM!H2fbDD$7iM*u+csjLRIH6%y2*iH7WAL|R!= zz7MM$`qUIdI{)+-DYhQWSTO4Ka|W_bx$F7E3cUqHnZ}iS9S6SaEW*$dQZQJGe5|8# zZl$X-3KUtDZqeV<A9Jba7^14PkVfQ!G8N})T{_Wnc}j|`mB4=bV<H2;{3bURcKeiR z$lMQkIZilD4iV#W=hU09p(NuYD#*VVI0=XeoFXTc?oql8v4a10za?C%jT5YC$w-m5 z3Qp)Xe!&f6&mHvlkJe8}%KYIB9}fNfvu9E2rgmB;q(MOgI5?_iaGpS(DrowB?E7(A z0BDoxu_)asb8z*Izk65p<GT)u>tF>ToqQdwJ0^C^z&JVmYT9`p2u=nMaz0wwUeCqd z5HtfD6TQ7Y%)7mvO})+?9u|+K$136e+c-qL5)#?0vC(5%jcFG=DdQ2MlfhMoN6Vun zE<jrHT2HCoIquf*V<6`)?7ErPe%X1t$*&Z0K_)4EERSnc5*_LVE_o$%wixp<`+7V_ zwA4*0zb^hBrR%QOy7_2ah&jsIMNn3siQ}P0d*#MhP@Q;P$m4#Z=RxCg?L~gVp~*7F zm}*&U5zvNoyl^NYm#DNP?`#wzly!4yA{{Gk7jYU<m)rLGNS9KxveNEmPq^1AP$nyJ zHE$gHbXsN&`ZU=<FWb^RRXFz0u(4O`&UQ<T**P6tyzu13L_1x-NN0q45(>F9U-dO+ zNhiut3xSi>K90Pvy?*Rp5L$U{o3X{AiTkLw*WNPK5hu}i*(~%O0m_Ir@=)$~DGO+s z5MUQDU5L~pxOY5mR<M|9=?NIj?M+<g0&S3Q->I}F^0`&>X9-5zJ|EJiI80;?WP7|z z&t<NyGx>BoN5UNc_LFYkG202%sHusa-t_Si4PS>K_P#db$a!WSQMf;|a4EmEGxM&C z1i@CMy-fwzaoyc^f{>@vUv@L-j`VR=SN8j^_bnct4)6W+5GUp+p$$Jq-{2dbKiEug zJLrdxVJHS}=lO|T3!f8ilU@l;tEz5HtE|`xQAb7N6sfM?hWttskTaRfMEkA@3msp0 zt+2)=w>JY9TkK1AABWf-rU*2WV%Stw+i1D%G+w2c%91EUyk5kvw~i77a|d$Z;1|Be z09c8v<9)H%2mc{#6Q5=T)efG&UVg9YRst)0On3fVJd+TZeifAEY&j42v_HH=<TFR4 zT0$yF6T<M}{m@SP#wNEa5E8FJQg_~(u=uv!GqVfu>LUQVFWranvihLg(P@5b;VgQI ztvY1%KM+xTBG3&d!P+k1PXlJkN!NcuOHJ2qRw+aXiJLd7L}&BViM$7#`+tK7JReu7 zAae6$yIs8g4P|Iv7B-0dU0?KQhg*oC)vq#s2owk;CoU-H+te?Rdyr^Dpoew@!RNCp z3l_;d16Z)WNn}MaZQl#LA2verenBOm(J)&D<kqfsUqRy~=|??X_c>%ml@4$(XLKF8 z_>dcQ_4hx9N81xg;91ALvfu&*8RjT0Nnd%Vpf>6rgAGUx`Tsvt{oj5;>3_lMk+hql z{~#)M|3y@`-Vl{F`3|n|wwmyje-br)ViF?M=mKY9JL}pY6jRGU6t=E5)yJc3(tp|? z`qd)M3@Mts>e0o$yIsA)zC9(Z{wA!`4!65sEx5OKPA-4nK>VySSRI_Ebe95f+mEqR zblqN{X-dAZz!wn~iFGEIxr1+7#%Ey_SU`K5*Ml}LA|OsLrbb=Pvs+C09FV+O>$!r> zw8epz==t2RjAtY+H{-Yt0{^p&9t6e4hg?*Lj?<vP97omWhD0@y&?#(V0}G$4uFq$7 zuo#f_6<Ve-$dJ;QLcF}=m42*C%kh2C6LrRG6}2oxS-mJYr`?zkjVVBjVu_x+jO;G| zy%s_;Q4TLNG;fEnwW(NMcZv7yMs@=W4(YX=-u{n=G`(p;F$PlJa!>UuFWSOKtuX*- z(h1rg*t-;UHolVJ+@e(l`En~<J^pdhzEa?W4#bZ{K-X8bi&_T9RQpf*5<64&z1)q? ze%z5J3Vf!n^+P^)<_Y|!I7Si8MkV?O+$(n3tWJL>b!oHlQI4ih{ivdqpe-+eV7wpy znXE4@Y=AJ@tx(Uj`@+OcNGkx>nloWYNRl!7O;GiiE7qbA{WV%?Ahv(f$G#7qI>pxl zGWB@EB>g;*_L!4pcgZ^#hRoN(Fv&nR-TT^O?RlQkbj4Bs4}0$zU3b^54>xRVTaBGG zw(X{|Z5xekHnwfsw%Ihc)9}C3=RD`M_j5kH@AostZ;YmUud(;qYtDJiYc5=?$ZWp| z4NTm~13j(@N$v;=F&fDO{p(;8w8Y3rdpC1poCOBp;)@yn-v=1eQl?r4BF<m!(v=kt z$;ZIfYMX#^ydx-v86~B0!*=@hJrqRe)MiMg4_o=exy3CQ<ojE?NKl<YH?xV_FI3L* z-X0G>F6IT+A><zz2eE>plw8d_MKklGJHjuY8%#Fg=ibEHWjI35*dnb;@Lp`1p1n+2 z`&!wSBtbSR7So^awOpUDe6?h-vNS~(Y4|eZ-b-Qak?uZaJl?879vMIYspV$QRdLF? zZ2nZyfqm-lp%-S`-<VPHK<Udaq-9Cj4B5!sx!Gu5#5~YYI)S0e?y6YEK6a{P?rAPQ zCnvf)iM-H869<`@G?DQwR$%p$xW^`7Z&-&_<+=|hbY|TUX=J3Z1K++?YzpK#YsW2h z#}k1jY(7`u&U6W-l>Hp(k6;?o5Wg=}RVT$D6pBm(Z=&9<K(qd_{^tUpggOu@#IGd3 zWeI*tM3>yt%as&Bw2hSwAWSo3k@cGW`du9Ec$30?4|Nna&YSGD%<CR%OdGd{4@qAJ zzb~|T6agwGK1+UUnGXza#)7t(INdX)E|^AW`(~9+?@ZPsRvd@^TDkojSR=URo5KpN zZAi>fU1bdfuj9O)UN2^n;Oc?hkVn@RlCVa87D~)mF1cfD6uh48bdAit;$BsSq@kwZ zh?p(=K8-7u`Q9E!R6vfjHDK-6Om+`VF}b4OKD4|K4ISdI<K9`LzfVru(PGKH^F`3# zd~w%-RAtkVe=P9jJNSu50bZ&Z?=>qF_>JH)tB8()CsQI${TE`cB>wmpT5UZlPNBzE zYo5T+`CFe#0!iaI6h*Q753n6?u6<%!L4d+L6!w|uQBPZ)#PC<TPH~R|v;ICEPZw!P zG)5!G0wTT8RM(eVQp(pGio2Fc&7Ckw3x*hz<aJI~kS~+z{yX`-GNaGd9b#?Q9Ah0c zO|}ML4-Xg(FOQ&KG;<>4`jz}u*fO<6+`;X1>vVw=^#;q}u<m*4BHRJgHlgKhGuxTo zt=%%>oYJ<a+{cW0vetqyAo0hrs)|Z{h&24F)u%juM8-^dU1HP)r5*A-y(os{{sdVo zi=f^*-27}^L4A@tbxEWl?i-&|z<E_A(M1WCG>cMv&u?}O=7i!zyN!-IvrOwIywjC1 zQ!zC+%1>DHc-n^jmhr$PAL0RG6#^}fcK8kHLbsK?eLc>&!qAiSy&o3PEA$!MAIVwk zUZ_TpS<#3hR)|nTY`4q319}?Y=9N*QupxwTj_Ve$@xr8?gHY6yV~nYPx@K*%@5Th~ zeoKkC=Hjz}yaA*8Alru#24jyG<n0WB+IlD>AyPZ>lpUX1(C@s@;Yp2?MP?fSL`TmW zQWu~X*G%=Kr%toKYb^6{L`|f&-K0zY5+v@By^EX(sL`>)0~q-w1S^O6bi@>UBV#S* z<l7}mV3+#|w4B2QY^NOw+g8}m@r1JFNNmE=F<2m|!pMm34+vWr>^d==hXQGN%T{;J zX1bTkjT^l|JPCZ2wn<#_%y`%HzPk!zn43OR?{oGQL7{A50d5~Ypx6k4yOVZ@%enbf zY@#>Fto>X`7E^E4%c&xUTDyfa-+PDG#nW$x9UDaL46Ugl?VzDip3aMwYc885Rzk5X zEHDjv_x1xjdiM@{zvF4P?v2~x5m!7r(#=owNaq7`<IfH3=pD*T@kJjGynQn<qz_U& zmuGEbvj@5Pd${quviE)hUx>Jrv0pFX78KL-N7Nf1OcQJ()m+fO>_6*HIxYpNbY>IU zWsnb#4#c(w>RcmjW@+>N*inv!Pt^jP`fnX$gDHJu{}tlwXF=S_Y*&HcIRiUYs^5J5 zdTd0MK&xSheXn}ai0eLjzk_#onAM7%dV-{B9P8AiJmR=$uwAb};HNyt<qTn{G-%Ul ze~+hb?!%w~?Z42TuDdbsNQT9st=<wKZVzi5d+3z8%VD}tcl2;CcJ<h7vxeZ+{<>(g z^h_!)Dnt0mG`(>JZaydW$W?}k&F3Vu=DWU}%{B>?Q)&n9QIh5OQfq|1PpH1QWzQ5C zyT<DH8+OI%78Ui~E>=m9{wl$=f;~pUB&(}^R`WjYbE?feE<5?--O|<*=e*ix#F`s0 zCo6t0(rW}JPnq-cI&w7cbh<_>lU7eL`=XL?ll2*tB$(mGk!AAhFP`|yH6kVX6B_`T ztlFgRLE$Hfp=iM44W>ce?cfM=Nlvau89h(+V^B)6hd(?sI3#U({f^+V%-qrbQN1Xm zdOsLfFy-!gkG4MtpT1oOg?Wa1#QE!~o<HDT+SI~d0G27QyJW5HiP-681`Wsht2$6N zB@+MD1jz2VG1{Ug2p+V$AJm*Tg8NHnPi0XWqA=XZ%O3Fa15b&szsAr5yHFZHi=&mL ztUr+#ugkQNIxbP~{*j$WJfH;Iy}^?Im$meF7X!q6(n3(BeU-;J;pDi?=X+n=ChIp@ z<4h4G^((x!z|XZrN8~8#IX!i87ndiq*q3Fw7ED}W{^%c#XBU$;J3qMQ3gV9OEhIRF z1T^3}o@kqY{S-xqZ1~`ES8E7O|6;wyjR=_S$dDOqG2Y8MYt{yxa~VSxyh^#=BBD<D z+<%UJ2lDhLdsOY`=xOK92y6C`_g$sK0`Y1<WN!YZvV>;(CB={iI)2`u|B8nT1og=k z>!>t#2o3K%eH?5(UHwEtk?U>=$U>tLt#t!BN}^<=Oe4TF^9}F5oaH*;ykj_`wDUJ_ z{BIUnj0l)6$mB5fECK8Q{E7iAVFCHsMGd*k=6D;Me=_&*0Mo-Qn^)utT5k10*3Tn# z*(Go6j!z%VROnZa+USQs62n9}pj_J3m1!rRLt8<wExv2Z1bXtB{JzNfSw7mqq#c9- zki(Iz(=p7tIy<H`@O&S^AibgB?)1gNQ!cfMG(l|J1{-`A)W9h)(ZxtO=621f9U5GW z@yeoF#{Bvb@$6hwQMj}|)dJoa>~DCoq?8~HF^+PNnbHEn9u3Q`vme7jn-xj<bwY?R zRD7PcIve(k>NF052-jT9FfY)Dun?<5=Ea-c=DgDLLK>9o(jJ+fItZI?diju00%4AO z8Uy+|cKa}4a9lsH$fV~=49~A0pr@mjT<=@L!m`=jD8h^l54aF-R|fHAfmn`9n;biT z25(3ggkIXLIHeRh>_Zhkm@uV!%KENPEyy}JR75?|jc6}i!aOObdjvwsuK5`>1Y2Ap zoLgYvXvF%P)<zSE`N&qdU$<Xyl66z4)X2@7qA}Z>&DvD3Q3Q62h<#MUUYrU0sBxNc zZO-0uMkFVz-`VRO_`v%3bu7%J(^ImL#6&mSoAKzpY|?(K!wM%V8m`Bn9bEmB0(jum zm!+<FI)NCB%|mHR5HWg7LF8c)K@kQk)}TnSQ)uq`4P#>*;H3|d&GI<*#UoZnM`hXw zc)5L5hq<-Xo!@zzL{2EZ+U0lXT&N{u^EyS&B0_JNVXr5)R<6owd9XbkSvOc2T%B6Z zPI^`tNe>;YoLeVHI=UUrZ7cu>B)9W!H?W5oc!k<{+Za=L&Ld;aw#*g=JPI4+=B%;^ z@!>IsZZQ`>=y_-=m=`$=G+dvtc(<yWFO79>ZGybEF7?*5k{N07=q`L(*T8mW%}l;1 zH<sPeFi*X`Iocio6GuP35vP*LG;HQ=MDF0AO07`VV?69Rb^5V7md#C+i#zTy7*60y zyhEiKyfjX5dV2R96Qhg1(8A*QAOU`&9&3P*3vunrnPgYab`SZ)9XCvG%fv({;R-U( z^owPh25YtWh1r`)RL6xQ>myPp8@lP~?2S>(%Cfd>BeA^;cuMNT_R;o9<=0yy@M%-k zmzG<cCrEVY6SD7Lt20R=;&d|I-R{AE0_MoVH61^Tz!<L`Sok`pd)ZB3rh)`HRc9u< z7^jwdS$-PoY^)7(y0vc6L7Zucy)_chOjoBaV<%G;b-s`&t-@0MV|R+rD7KHJ5x2K% zZ&|$}Xa&S?eztc5;Ai!|$1+9Pp;oS1wU97|*VY2IUJvkY+IH(G`K%DI((VuSmDls0 zkcNelxXXufU+Bh1G4w|BRhKFfL%|O}Zq$9@XyUYP)_`&biH#|t0P4JmPd7?C@%U;# zX9Iu;n`S};qK2vU^izpbyVAl1Q9z$)IYBv!K<kE-fqTA5;XLk2lZ+k#PDKDV^(CPL z6_YYNf5fhOc?!uJ5&Hr;H9kVsnc<hm3lyh!7{LZQvsxG;d282-Pt>3kw{!&-ZAHt9 zQqS`@7_~=ztJrtPSCp1VYyt>*0Jh=m&Zg?XiW_Ernodtn^E>Ka%sxH!8}ba*-cc9z zwn*Vc0|OMAl6|kwGtDtGtG6mYnw1V^XL?zq#f%3f#qLF0=%D8BV_Vy(LumM&>9PbQ zZ+~cz9Mtr2s2vg++tZ*eq*PLkBc5ONcvZYn0e(nA5MXy=MH|Z^78S6z5onQ&f_v<d z38u^O_ui&K)t&e;lI=(Jicx<$`<J?t_hAwyz7WSnL*LkMo=myE;Gk}D3@u!net5-u zz6sjRa4+~?s#T?7t~H&U4^X1LGo2ZGmPFPJq0vq$nDPB{>E9-RFzfgiRatj^OK6v{ z5MKxlq0MZ%&Z?Q1!Lk%l*uFv$CSa93Xg8k!?1a4494XXVa?n_gsez#~fs{@H1K;h3 z<b$w<IX4=Q4a__^bxUHgy1k$oI&Zp<TQL`}J<RCWxm-%64B*)0yTHc*$~(Vbrni1_ zq;ACk`y~MZV80m#OTH8^hrkXo*WovPe859xLvG9ZAxP`DeX)F6PN{6PcYXM91C4iq zr5)L5&H*AXr=1x=+gBMG&e%Q<_oglB+ewT9oKEp$U2*5%d&n;8C>uN|)a9Ye-<{-N zC&5Fzc7p*%rW;hA=b!-g^n2e7+EmEf{dg8knY62a2kJ&=#Tk;`S=1k!TR|jBJ}X7p zyp|BwQ@rSp=Wu@YFL}A2{JTk?mAq_0`CF1C@Pp1w`W}Vri|G3?=s_Jj)9hRk)TKOA zj;l}6Z&h3=3-Dov_`VDq{FD_Ftr;}P3woa^@q&;;JYk^p#r^y_%-+=L*Swl}9-x!j zGN8Vp0R?a`RgTNj<jM38qpE~7^}iP;5h3O}AE~`+%p{|Sh<c<uy<xpH;tOemK}or} zrM)u?3faAzf1J8|(0V<FW-IUN3Es|%6;b8TeFZTy{k@&zzeFCJq!6cWpAA>4)M$jW z;D4X2ywUou!wE>Bdy`7i*`wJ$M1D-;Y**8rJ4)Ba3*$Z{jNxg~0cqy$AwyfcobkWz zkTJc7WjH5tPs<3s4Rp5X0aLq;f_Hw<xDW9I8PhwjNIPVCxeNBqK6$tDfDQZxpd1fY z?AGgeY-LFs*u&osaDT5D%!p>?qQagtXXgi)Z;bH|eNXlyw3ANrf=luJ{ezPrfKS;x za}e=Av*fh5<DO<-R4#2VKRjyh>ovtfxs^w_8D<tNO4yr{&8?V8_82Mje}(^RDFR4% zOM#DX@j6L>$^;X|XB6c99Knh_*%AW5Z@2rmNBoy#{MSEx_=H(c%$}faMt`44$bz^5 z25!kX2SfM_3HX|-_mL|iJ^;lA7NYxeeE-za<U>3l26f0Ri2Al@@sBn>TJK$J|Byra zj$ml-yvGqVT}SZSLH_Sw|G#$5)BoGq><!{YO8Gz9OhH2&xOJfO&5;1k%XSF>qBlD- z3)un!p<U?@m7@RJZuoDZ&nSc`&lDbDt=hlk*W^ImfPge7?}39;`~hF1@_SAX(ZLrM zC@1NE?bYuWZxDf7WM@UY%p3mEhL4T_04!P`<m28)2KwCw9KJGDgnT#eQc3@#JNjqm ze0T)-?y<uz^#82|VEPE*GOqlO_6J~~4&0m21ZGHpuhb!Y*K`n_f@A>=*7_6J{!oDc zG@BBIIN*`S2dZ5DXPfqK@7NC{B>leNPyKtnAA+Mh@WZs^Kb-21jy^&Ftrs2=Z+%w( zN1H5kgsEE(x^G3|@4yrAd&fEd|2f{j44C!*%kgGXbvUQ&>JW|T{E=X_wGO(nvcC_F zV4``=kS$t{li40^@_>NDh)gs|=1Rrz)ur?Iitd+-`n@tjs}eI3`GHx5vSH9euoFLJ zZ~LbYOvx`}#4ghzJdZkV-#7AmvxmFDG=yzRq@{7dVU0X3a@==nB<P#2PCL{=W;(HC z5FO9M6WiA^T#T-@#oQi^NOx*$T<Nz^%}>++!_R-`;^+;Yaa7oJWvzd@s{OmG?n`HZ z0ay(7Zw@tbL%MWb^f;ZWvSBFb;jOgch-<W&h)daz?(X{YyC*r@RJYWV?m6--J<oO6 zcxP!d?#2ZN)TX1rzJ}k9;i5A@WBEw7Y4>xi(^w2UjH9!6<XWLx+31&kR^8V*E2W0_ z;>JU-UwChxq~F0uML(!R>@Doo=;*Ew7Go%FWrOEno`Jy;rX*}oEAN@ks>U*Cga7Q2 ziF+dNT?_F*<ob>+SCTg8039SS>nusJ%u5&bI`+6X3CBf^;2+)&*tFb-AZDGphg2Gl z_D<CPjOwNyKqx$;E^Mi33U3h+0iqP4=}@|AzuLY(Rb@t6-D7(W$AYqhRw<V5>}tr~ zTc8^s_E#=%N#?`ACrNM!BwWU-Mn?P{*f`=l6XAIfYhBk;+^mxdY<llL+bHVlyVq1X z2mQtG@JV>OLN}~{Gt&OiJ#E!X4(G`#{<OOvk<K&XuO&zuT&}0+kunyR{K@>X`))?1 z+>XS(r`Z0(h8Md+1nr(FbjIoRbN_g=YuERkI3y*`xsd~VM!m<hW%LFpRWP_zqk{;X zk?a^>s*+9f1!g2ZPe>@QS7<NMxitK4u8qbf`8P4WQGmb=?U#PEEs_Pg=MSiGR_T-# z9?w8f-cB>!&AcJ>W$Npk7^g+wlwy|{TRHm@B_rvH9#;*;EcnftBIjZfnE4)&kAfO< zVaeBSi`StUKW0B};84b5^b^_w%FQ%v5zXw1;3YccSRLn37yl5NBn^Bt%Ywpx{D}7? zCqw{nQ)wYzH_3mPN)EJx9^j{M0sQ5d6u?Q`zl(8OH{>z`Ec*44*i>-~Oq`MKW(!Nc zeh_@Uc6(Jm!-#Uvyt2z(!iEn)nZJ;s;Fl@_kalY1U#9#`JX{;Mou6z+&zz23^?-Y6 z!{D(~gIx$v^=V;0p-gYmit2@R@z_Y%1xm^=_C@R{kxb{BLuj~pHkt1Nw9@}h%7Eb7 zC3+98gs{|w_l*UAc^JyOhviQ}seub`UGcpqKPM?`UsNHGg4OS(sSPjIgwCm_WMnCM z(~*g}(k2fNToW1RU0vOn7#w-Lfksh$3&9vY;p&-8O08^<=WOnKOm*^?dgQ(P9yHj3 zjQNiNxJ~wYlAJ3OOQ47_7~wvMrgfiLbKWJ+Rb*feqGH&48NAl$8<~GJ`kAKhJMzNd z?9FB0!bHx!V#}l-bq%H3Gk6KvVYY)tb_7jFedbImUPA<1M{u>A?rur@?1=a)bxuv) z(lEWdY?F`k4UN)o4wpNsAsj|3oe_%W9It22l16z0Oi@&K_F4Wz>5s);aeY2;hEVxU z+v^bM*@e)8s1)0y9jCPXnaL^L7u5`Yj9>NUL@P2kjcj_O<%_zr>+I2|On`@ZztkcV zQCU;rb<q}2+EH4@^@NAbO#`i_BEn{SPNYogDV4awOG&wUHB%SdxW-EP!0Lr;7!%<( zQYOz&{{R#Vi|12@%r7#H+5F4d3wdandYfnZ?QDxlAElt-;dWA0Fu>`<6KKH@=vLX$ zX*Zk_!~Lx#Y&I7J5$()~GTj_mW<~L$hJNft;$=K`cKIFQxe{#smGeosfdWg~o2c_% z!6(ig-(UR==@em`URIjIkhe<zFgC#SK3byhF{(uuNm}#=vHzFHtiRK$^$(JMfc(xU z@s6~<WbKg32(ZZ&q6HAU+nN%)A!CF^?s`y~B}<|Ju?qgfYvZa#XdEtzEX1~}ZESjy zF(6ZJpAv14;9Xe4MQWLw9!O%j%N=na7m5%X+=wL&wJ^I>?_MRwi-7@;pH08KJYZ72 z<)f~cy028fl7J}DysH0<x)x{Sp~%M91d#^OV*lp59;uEgax~YDkW&3i^gMgb_Pnm) zffPkLf<P5?4FOhQe1OZKdd%{-v^WcUz8xm2BWZF?^*UbGG1@{k!8wOTdo9SZw-XGi zRl2lh?si>?X=}{mm?Q|uQex-L>I{^@%l>{G&K{RphC90bK@Q~^dGqIw`Oey8cww)k z5O_QTWs^;WO*;Zq$|83`uS*WzzyYixh?Fa~O-BTH9yAAxqoZjgQ6>FxAeO6gw`6Nq zDdh$FJzuyPVSg>Q;PyvSpgPAgTqwx85*;UnF3l+PdR+muzVoQ)$#wy1-#8x?qfyT| z$|IJVv*9Eo2R^&-Dox1hICaQE#d?}qUOHm@3es;XWMTJ`-@qtqzb`HFI^m`cm*BOh zzvHp9uc4~4iZY#^#1T#<o;(rk_W8-!%xC?0CP(eDU1mRgSrf9;?@8{RYR>SuE%Fpu zvMXkA^G^@}<W(f#!_!%fJOR_1|3HtaPw)BnQ!;Zj0RJ3--bpB*#D75qW_5mfU?@$h zW`Cmjf%3jvDKlVQK<7yE67*x`5c}em%Xi$t7Uu%I(XTjy3FriS27IJ&FIS{6ws?a` z>MJrjFCdOZ7r{W7MOx`W{-s5BHy|iHBD*2U7Hg~O_#<T9J<6pQ;*kHA&plpduLffi z02cNU%nG(=AX!I1l^X9>MuHpL-ltm~v~J89?u~Z5fmvwHLqje`)(g|z^IB^5{fQxX zk=@-Hd1k8-8!O(!^X%cP%TeXM&Vw@Fvi-w5%vgqRxv?g0HjJQw1f!(3fdR6-#T;pG za}W75%yePPvoy7ZO^x_vZNmdNQkaI`7^V{U1zck5QoxX!rFEyELd@j1*cT#UH1Q|{ z>;XjeloIwpC-5g_1%V4l*@fE3IF-%=5G9h2QZ2Rh;hr31YlU&Xj&CAO=Qk#ROQ!a2 z!UAQ2X-Y%iz(F#-H_cl|p2QzprpfY}QB8B)D~luDD}P`%lRw>&-^cvpyut6f+(!O4 zd&of%NB(Cig5pC<1SlV9f%Cfoke{XaJD|w{0gVy=-O5m$$4D0COw>S&a7K)OL&c)q z876^WCd)$}mxWU|tiUMyr}`TZd+#f-<!^CMj8Hf>D<6|&Z$Al=1~;f{Epfem3RYw! z(K9SR-(m+{rYv01yH~pS6N}4WIAQ0XdX_Pk@sT7Abql#aeDqb$Nm;+Smg{O|^avAE zqAj>hA}d9!@_I85MBxM{Mq$a{O8LpzUZN5J=Yg_XzM{$E`4+Q(CA?3BEY?K)&Ia^3 zG1@mg!DtFrewVSK*WUoiSC$K^AvFQ?O>)X{?76cYYZ>HQC(iwsG|yAPC=UfbR=~9Y z9Z((u_u`9D*{R=UJ@vu}zBidJcM{=al5S~*2*rJ8PqwF87m4{gWmf{}-iX_alw=Sa zC(Ia^U6xGD!5w1jYsf357ken0ziGsNC{j`!S;8}!c7bX-v{tOe6meUxn2<+cKX~S+ zzw{CF{>9B=T>v;()afYdh^)iMf0ZtUw~rg1)kQ*3*jZ!HD^XAc@u@c!zTHbxz*nYN zbgKIL^ysa|E2b|o5T3r}IWI}WR*MDAiz>+RoKJ9^A>P_tr2ff418~a%b9YN@9&8qG z!vubqI;n9?)|{1YgDLcUSel!pf@l_(vV@XjvpF@?bwzeqX<Sjs0|J#NPZVknfLHCk z72?E>zJ~X{X@m*L){FgEo@Gd1qvKl?11Ne*E(h6eNk_q;NMpq9P%as3u-(3khX2V9 z-V?@#$a})rpp7Uf{Lh5J|DG`TC41i!2Iaed3A`tacmJ9$&y{<`|G0Akwg@K1i#5zE zC}@eya&C1S{#F2ydVp3q)zojwCY9?Er&(gFWMHeLae}?~=7dCkw>m<=+~J<*`++@& z*NN*2R;qm=%5Y-E>>$v%_B8OLfHX0mMe#HEKxW~kw{W|tKvxxEk*ahfO;4%R?5I-T zk|C8IiHgiu%Yn)21fkSMt{my*XKcANUh1r5y@1cAynyweUFqk%*oizJP0C6(pih^E zT{<PRYbV9CVn_m%dVmdaq;mazUqozY$~`~kE-u3a^r%<%7PN{lUBFG>#n%1cW+j`} z&1(_+edC3gfIk-pR+YzePy>=I!Rf(`0j@M-KS@$Nrk(g!R#?WzjcXJRC~Mr&$7mJd zo-e<UGF83^e2JW?qWqX3&64D`)m(V>gX6IA#2Xs9vAKrEL0riR<l>o=oZ|=-BHA7} z;AloT%L|B0>c;7WW;4nihe+=51d^Nrrk+?_eN=p<CL!Wc_x)TChi?gcl>FyG3jHsb z>*TJl4QYCii@E_MIhKq<%y>Rm7aSB;_PE15WNnvPA^~YXz6r>D9BrGVsx35_-C@98 zrz`6zIO?_RGYkon^lpLL(I6Pi$N6g7ko^ViMfQJj4BFpR7@cv7;6GA^&Gb8~6!ud_ zRtBwL`(3hK0j9lm<>2yDk7{&|$XiB+>;0JLbXP}>T{nEPkp}^{6%fXPkP!L|7?&7^ z7peuy$^gZRqg$PgFR8u)-8BNKB8#;&yO-T|MM-`Y9Ifb%bcDq#{={Gfs^wu4D+*Js z7<)_790-2l&-|@*IX#=-JHT>ERt_^aWdwsCiO>IXEn;=pdUn(yq-IpPLcEH0eiY{! zLzXhqzdHKYAfkGY?OM)IQ|yusFM2Xb49yx!PA~JzHtq?VfuxVr%Yp&rqQ8<?k#9{j zC3)hA*l#nl10lJy{OZGNBw45=kzqS429IrvY2AoHNBmjH$7N3_h6mByz!+uDa?+dT ztSOMxyo0A;IMlw_zRC9j>_U$l%Y+u2rmO!M)KOL{#0Iiohh+07$4~53DdyjDRw>s~ zJ3Sx9R2>Ar4H-(1Lvq%<7`pa&PWM3rWCU~!eZ}t8tU7N74V?!a96GB)iB`TYbaOEU zSv1zPiixz2J2Lg#3Zv^Zve9<6{9qiDk$?O8&(H=ECg6Ub+ZU&^j`(wy_g`f2@O@7E z=HlsX*&X|Ua+GQFNliiU(x34xjm=1Yc)BKkHp`xGl37qYCWhH~+8{k;jGT>m28p;Y zJWs(Fhji*oY=4fwZ#Sd~v07H5+*f2{Qi}7wsqBZu0w$=^1c%USy{a*h?|nq>21`ss z?(38Lw`)(XvFYjQ@Ud@N(0A9i-mhoJ9ht_bPnpL8RtO(}l0Nv;&_eH+m_U~;$t{fB z^0r4d@LXW3#j>uyv1qritxBF}{)*o4WR)=9cyWI8_P)iB-2aG5+mF)V(k|^0)h@kO z=$;Bu)=d>U9XHSQNLF`3dq+adi!XX`c%`Uhtnmc;W%E{C`|^WuZryf#!ZeaNIln(m z+EDW~8i&#)rmEeKK|DGP1?uhFy&U(+Xd+N`zOBo=9$i-{c)UyL7}p(PAiWdE>HtM0 zB2%6M_{nzB^UU2#uYF>-(tV=&j7PdcQ0oKSw<`nA^H!=<Va0-P!!&(7v1L-{ysR&M zw|&>-LC_^|Fz6_mi;$uQD3e;6uc7TNY=mKB9JtmbPROwji7(ezTRm(r(?oEBbNM5? zatfatO^FC|JB|-}74bQ;lhf#R2Dpzqqj-NrtKlbK(_Wq5D1VJV+HelwuzNOiH(O$w zX1tU7`4Vi~aw&4OaW!arEgY&M)!Np*!*66`uQpe>oMTaX;y0^B;dJF<`0Lx<>pY#Q zA43L?TDV}AIJ}IE7tXg25Pv;<p^z}A&M7FY;Qc;-zXcQeVPpSe0CWid2hc~t54vIC z#=niXXIFYvYdU<wj2JppZgB<6Iz@8=+kbEWi~DhSW47+xkwWiM(iB?Vpxy7@mxy(K z$2=wn@t8KqPPIE*1Evz=67#uI1^Yx{=?5L~#U!40!c*IJW}2L6q}c8nh1$({Fong% zB^wdzT{>3=0{@}I6{oW~p4r%n;f9O+Hw+MIsjY_gOy={9f_7duN$d?YA~e=q_n#E2 zom|TkgX}1>33#D{6sI7MXQA2(<+fHUGe5oAM6^v<xwn;g-B`KZ&|5*SUV>Y2eG(Ec z`go_qjpLzFj_qF}9QLf)sHYKlYrI>kcCR4OWVrQR)5NRr*c11)&vVY(=Okslw?b8( zLt|VG+#4#Mk<}PQk$qiH!UAYE#f6saaD#C4pIBNLm)L0r2K4Eu<B@w9mp?W}rRbPK zyXz}(;35)@^Jc08NAi6D{p%q}01dq3l%`bot@-Qq51`<ZAI`7+J_X(od;sPLC9s$t zg0b{L#U9Z(n;3ips7aSw+nJ*t6;fjr8%_^7@7^9)<_fcV`3lZ?#2QVch~RfT(w4h@ z{e*$1D>={2Iujs+#;vl!@}sBJq$lxdrZTSlmfP#x4vV|}Q<9bI;O%dVjGwt*_D0I2 zyv%rG+}oY~v=KtpmBk?9jUu+w-~76Sv?VY2h3I;~`Yfz^u@BU0=Vf-t?zE15>;~?R zEtbg>YP{n*?k4WMCJD!JR`ITDmpcW&;D{Ig3Zm~<XZMegBFZJChB{I#E0MX=rEJQ< zR}Y~ev$qgs3@0;fVyu+pVd}x&(O$p7gFaid1`iX`wv2<0VUXp$!JCZ;%p1E~TpY7~ zjP?7df}%mIOV7j1tnaM((_<&a4x-B8XfItT<3pE8r?!?OwEUjX%4+VXN(vfAi41Bz zXgSwGOXicKdu@z>+>lK+_x%iP_za{2;M{)=x(*w}dpvBLAdY|n0dVVo9<g{pJRpAx zZ~zzs1o2yyFfnr-n6ibAee-MTnp(ihp*r2Ow}W=!ZvD=q>`XS9vEl@cRwd>cX%me_ z$h53k)bv*xM1Gs4*r>zuNLmh8p94iz!WQcc3KyGE;u0fx{3yUqnr79?l%|AsXKLFv zXAeH<&4*9rUwnhVMYxr#PZU$LV)DrF9}&2va1Y+7WazVTjnq2NOyXpN2cfJmW}eOD z^gJxm4U}iT4z(#P=`@JPBa%mk)I|UMtSI(luJ>0OOD)1q19tJ*G;fX+T746~d_$b< z`fVresw;kw`=gdlQ{nxADIB_zF+_5ioKQNoSyi8a<SVt5dJ<@eo*O&!IJUA07E>jR zu*2(l<g})xR!s0RzKpp$kS!-$5%F>-+tbrl<ITL|Io5W|kHMl$Gv?}r9d9S-a>_>- z=?v;C4I^3MQYl&C8jEE-fQm9cnS6~Xn_glJi$6QAM&>(oSwM@US&SMtcmxhUezq?I z)Z~i5GJhEeU@rp0-vKj{;^X^|w_*vt-TxxVB7}zc_Kgk*LY<jfP+g}#kTL1FbGZD= z0sHNq_2U9?igPU)P^ODu!1GVeH~4Xb^)Qq|P%9N}ucU>FN1D%=!jyz!w1!vJsf*ZG zKW_tbm2RjwNhGmeEcUrt`j-x(rn6xOP5PgVR)GVUN1n!7W^b5e?(%t`V7OoR8(lz| z{Py)1_FvCYZ!Bn<VqU9HK@<<{6v5Mrn|r0raEBv28@;;MiE%ECl3aH%!x)DQk14v5 zNr$1tiTjWoUSJ)rtY1lZV343)I!1sqGK+e+PLUl$k89F}xU5=T*Pd~b(jGsJFIfeg zZdXZ@buuOK^k<tHaan3Yo58d0Tpgca?zScxqj3M6ZG966Guve9<+oiSy$ig;ci*(} z|H>?6>tE=dvk3(cw$x-R`&>BEq<wq+C_7b>@D_KLyQ#2r<UCPE%~9u;C}xQ_!ZZ3i zo+OO!@yWjTr2Cz<5LOO98t}Zmf-jP-VyTdRy?DGMR&tP-zkz(*(3Z*PxKo<#H~s>@ z1`xgl^OsW`z6AOsh~5Lr2L%~p<(!$q3MLff@3$~efZ8VEq0o{1K0w?Ee&|7iotQ#X zsm>nTeSAkcHyOj%<Dx_L>m7d@MyX&#9wSz0b(J~-*0L`#o9=da?r+gryulkUtul`S zshE2HR--vgvMH(eXW%WTKm%rTgT}=TZL5%BB&^T8&xgFzC-@!)q-~dqH;;SG@x>uz z8)ksp3*JoJGOJmq4LLtf4w@xBJYFoBGrQBZMs8Oz8MxpvSc6-3JuT8T9ScCpFYY4a zh#X>aqKq3KELW}*orN+!98C=F+hR}-^NwV@YS{~3FWrirV{{0_VgPOr7MGM!1t#wG z8^Bk;4dpn!dWby9m2lZiS3Rj0MmF<!#`AQZ@02U=x0vQ$%d9MVtwK*iJ?R%V{5hG^ zYL#t_{}S%1_x9#Pp;FUp=-P{G+k65xK<f;d)cPgi3CMj>)!2QJ&@DbdW?qtnxAnrO zllukvrNO>qqbny|`@3=2S<1vI{Ay#F^<IOIAiZi2H7ZhRa7%i11ay18ohA<;z2&Z6 zS@mk*XlZS{vYhhD)X1OVI4r`-^0M3hu;*y%c(qiiJD9_!b~{2vpUeLGP_W)d@i&|J z009H-ll>yYL@h0l4Zz7iA4sIGClBAOXc$mF9X?=$29w~xhOSUpL)t~}IQ7yg`$vW_ zjL4ec?v4jYH>YJ9hkKgLytju&_(S7UM75`eQ~rJ_eSay}Xu$%F{c`p7^5IMw?WWT> z=F`BaLu1SHnG!|iVB(JZlOxwUlSGO(8`k;Hy3mDjT9iuPt;C2bKM1&XEV=S7vK}kq z5C*NTI4RE!>iV$Qs}MNd5U?J9oD{9+dvf7&Si1l5q`P@psa<uAD6!<)o*l)*|M^}j zKb6N8cU*-&%+5+C*I9Mw8ccFX&;j?<V+$>1eDUxq$l)OWzG%YEUoU=tF4wm065LFe za46hV2z}!$H?fmbR<<-+b|Pq06RqHB-|!Ok&1sZpW!cWE#fJq&ws2WBGwXiymDTLA z+x4-681yO->9Hy|&PaVbSm`w_b*8w1EzIco{`lYp8L`CtY3c?~ABC3t7lNbbJvoir zdd>8W!yT}F<Brc>FC3a+yFo}cTV<wPFS*^fH?9|Zwos`VCOB=DM=x)*fWl3_H`}|- zgWaSi_&XJiNy}$!s~z?`#%t-t(Xm)gCN`2qY39?%w;U!imvAo6J%L$vDHX6F$W|I| zpm)fg*4zFpUV%-NnZQ=fPIGnW!L{A`!*a<o4uaK4^9J>~3DXAjFS`SLpjSZ0q;nQV zGER>CZ-3$Q1-;<OBp@dN00BlcphUpR$)>52cl(81IZY`U935`cTWeZbPjgUbw7Xts z0XIlI!(|GZuWdJ3ej-e~+Pt1w6(EMbnl~-WMlvmh8hfyAr6%vb0Q0gFkLE4s_(tvK z5rd=$<5v|h$~B;?sKI~$a2fbz>~Z|!qaQr6m7F{;5I_cyC*4Lg?o|we?9HrZc!sae z6tA86l@;z^gL&4NZAAra2)I}K@}Zk-4mhF7$<{m98@@*3OqBKv!rUzXI>4WOab72n z^_0@2!^ss+uRxGkLkT+haxkosV(be37~P9J-q4F|TT)<l$M!SC=O-+#Fr~q)6<koh z>mwrS1KtS3O`wroT;|)Mxx*qnS17@K0h?J##-ODVFr5)aTT?K}Wl*GZmaP1Jt$m0; z8UA8{0n3|hEX5i-c>qlsQ8D|vtS88Fl}Y>}CyG0v+6$S(TN$<x6pruTbpBh{#c$Z{ z-Q=13J1_|lqyRLt+rs7}ATn*<X{HOTrH>(hm$NFuMGFPQ(y(vbQ^J-(bmsM-m-xIp zZ!mgz)z|p)d+)$dqnC`cO2>9d7nWJNPEp?FC-o9{ZZtYGG1*+>w<{(btvz^d8n@Cz zj3AiM%lZ$pWGATkPV?63(LxzhOw+YDSI)A~=hRly?5tj~EFOkv<Ef{iq<Q3osytS( zdoeUWt14Ty3{R+jJpH6I9hfa>g=>6`IzR}+QZAZe#yKi<AH|QGIeqZt@pws6dIGsK zB4kFkVy9kneL|W4EOgNNqeC7Ja4!emWcJ0dcQ#!e({XB3239K`UTMKj-2r|%y?l<I z-*#>-#q*tb%jji}9WL(UgoomiUKoQx>$3jv*G^0ZP?mXkkHE91$@`+aU6Zse()|Ki zh112eyjH7gbgDGoJ8<r&T&+Sn1@c;hg@~Jn#n)sj+rT@Jm8Y+rd9aD-$)eZnb5og5 z{#bfZgyx;oJHdW<G|9sAZ-Xe@Ay)V9<d#L9mn|Nly(aB83%3(Q5}FRH5lXj1xXes~ zMP@E%ZO=-q<!+o>Q?&;Tvht4o#)s?YuW?j4Eg1nc-b_iPo$JD39iAJ>)|~jpmxC7R zg$OA_wn(QjJ!qz~BC-6Fri3$>#nuGaPAT*5p+;p<$%PHZ*!!e#|DaBMItIU)Z;UCi z**`M&1=+WIS8v)TC}0A5mv`hI8<+roV$eK$`Nq?h1xmI!{nJ$OP!UtFm+KKI-8(Y? zVbMF5QPa_9H8o2AX8Q?$YB#E^iaw2(N&kWfyRi!>lIJy;hs!;N_N}laYIPL*D6?f6 z#*vwC!q)Z4&YI5iA#>3d0}n6g_)T5!WH(vUn!$h}_N96432znTI-MnA6uCi%?BHI# zmJDsdLn40NdI5fEfmU1gdmP=YE82;NnHzXe#}Vt`QVV9pOb|Z#s?zumhVL2TaZkrx zhB9xjov95To>-noq-T}64v)z^9{1e2Wy2oax`D+6M5lrYtYh|SfrRR@_yy(OJlv@5 ze3*YGviHB~$$|Cvom2QfW51Wje-33bpi0mM2ec_B0@TbRNYG{ApoM_{B1iLuw`1Tk zwPRFc6d8_sTnUw?d=r{7{GS5jH#eFl{I+Q-62xf+_9r#+Q9=MDPfGF}7(jDj05KYe ztLif2vw63OE?`d`s{r7NpqZ!2jJ&6nvMH6uXTtR2*IdZn54eAQ3;<-+K`%JRm$2aL z!2jwsxZr!GnH^9E=;_OQag*x@rVQe%2w-a={99M8b$avGhtUhG=iKa3XRYI~A^GbA z|C#%#fSzTT%3S2x{z7>es&`gLrG)|qj2sHU_!S#{pZRZFC;+t4LkP|&sPxJW@*;9m z|AJ63_%`Wa3l{V~!hb&WHSfJ1x)QPc>*Z((V3$nUPtx&Vz{siZAN=s&AMA?|JRMX> zbYpeyZR^d;&pJMmGX~>g_MN~l%IYs*>`MLw81R9UsVv>UKAWE4z0<)EkO12vk-X1- zK>gd2f3^EpH|ZtbJ4o&$TL0IZ(ZKH=1QJ340w&Nw0E{XVD0LMULfT(F_-~l*B1h~x zXU+x1oB!*5J}8JSPaZG?c~C%6!~br3gn!%q&oTP<-?>5`I%mU?T$G^y8bgZr$_Rx| z2ocah@b}6{unV{psQW)`_^-*KaHMxjN^Hr~{AJ0!Zvf|3{D3G7Xoc~fC}4p8Z&3bk zQ2sx8if$WS)pRZQoV&0iM?{U0!R6Zn45yEz{1N-6xf0W7rc?pN!1jTkR5mLdTzAvX z1z|EyqT~ZKQkjX;_UCZgaV!|E2-!nm^U!<D>HE`pKVyjZ>5+nkDcr<i6*=<B*v|E) z$@}N9*eN1rW)&L+23)NA<A*QEEG0Pd^D9hhr@EiLv%`*@&k7-S<$k3gjmSig>y(Iz zs~K|>VI9^pnM86<PKjg2b8~ZlT9+z7XvH<1tsysGF~L$~ESKeqGRCP0a88u3Tkb1{ zQygJfbB@Bz|M?v^cL?)ZlhkkX7|FBa;3skAS>dCgX1td@o~P#*yoim^oJN@acSxYW zg9yI|;0&H^9mHS2s~`#h-eUcbSU#N`WB@|ce!Fb%8aUVj`BnGSwtRSHylQ$`w!Mj< zh}|+Rxff}r<`%5b^tCKPi>Qzx^zIV8R)T{fU4XcX5QEb(`s(Wm3)a_`(gX<}R;NZ< z19e3+{I5g~Hoby%PsupB2%mAx3eu`uifL0zaGhBb<d>P&J#JS{{TA|VU9fT+2Cs|H zVDa*IVdtK0WNh&DJ?Ey|f}FT#MLaW<2uIY_B=WT>vdZ#Km_^ou)DMb{ofMPm&sO?_ z_7mh>g(1h&X&1LJ94$(-G&>0^WVIUYRW~KddQU^r!{qL2aFsNZ%Re2QGmmIM!P3U7 zN{rJbRG~(VM`=WfxSif)?)<<^QI#pDqruCMFqw}0o-p^SG5whWL8|X)&6c3VBRf6R z>eN_^L_r5?rjPbUehvwuFi0hjbOc8_6?GgVp|^U?c`;JqW~^gQ*f5MztR2k%D~rNT ztc~3mo#Skau;JWra~KPL)`+X>aDt!4Z<_!?gr9Gkl6HN_3HuYaky8LDM|N|Odrc6n z@J@Hw2JeB7t!_%Jl6Y4~dJ?zMRhzJ(goxYOi(%<vmcp|TSCYfit+Jmh=dq<RDfVn% zWG;Ga>OViO;8AMSYMTq=omy5FSTs`=<zti<a*rRIEX&lRCJ06ZVUefBALy3dS$Wh^ zITiR_;a7a-i0j3Ug5}4K@*FhPyfo9-XK31IuWN7i*@Ke+$`PWJENYmiN|-(-2T0F` z?Jt217VXA(lz2<ZqIzstZ+g@S%U)=B^rVI93zKinO6|<pl#BA;4j;eTrws=6E8J2i z=5VUWUEP>KO7zvH1<;gJTVTGDHRmze4W6-uuW?GgwIk;cLDjO=P7_Z6hW4~`z1Q2B z`hLAW7lpf4pIU5~6^z19)9*GWxNdPqFqQM+s{TnP?;i4BUXBAgaDUF+%MWAtR|@M| zA_QcgY9=%jNC=JN_rxJ$<3U%Y#}xj=tw03rEU5eQXfAM`8#NV?xSoMMk=0#;es9{Q zzP`2Cmpjb?Ga>#$`%{t^k6&+lUW64JTKlyho3kZ{aH@e{5w`e8qAo%rnKl9J%p#`O z6s>%?4VRN#Zs^eA1Pxo04A^|;``I{(nR$NMQwv+}CKv?>bl3Vwyp^dvW)=+<nO*G^ z$(twE!ywM1qS?!>*wG(FG>L4X{q&ry3Zv|B?K?kj@W|m2am&q+=blmKaI#9=kzT0Y z$WOhqqVI}YDuMWgP8_hqfRDo?m1_`cO+fvV(Uh+;cb;K1C$+vs+LkboSYS@#sjt~$ zfSkhz+78_pJ=}UXWn?#KM(&>f_SzqV)D#6jG#MX$#p(=K<Dm^xGxa41(o%I(#sDTu zK7dvT1MfUJr<mIcO&R?~7sb-vr=*Po;sNga@{S%mOdaSd&4f&LsX}Lgz9sesJ@}@* zM;W2x!7(ezIHRfDv>4YWO)Ez$e6;SS%XZRkrZHt}uX!eMQfQGo-N?bVMWyNP2SVEZ z8(a&!q4H(1zAVt~KjOI1l9k-s&#PFIpzikcBx=BGy{dKgfY8QNek8Pgj=-T6^Do(& z(r{Pi5_+PUq;5XGpGkb~>w%<@WtLn*j@bTaq=i~<MJu+X9t4A`P}lsuS8FLl4?N1F zZ69ORUW03N(3PCX8As$SJ>Pp3?ZlJI33idG?u{iPqE)~7yaG4>;5*I6C%+6jKg@)k z2*bKZVbrDIfXL@aln!w2W!QpFvEO887y)CmbCyI9)b&q7&bPJl?tSLQWm5_W82|D< z6M*;G36lPj&QYn0A~GhPbH8NlPu`rvE>LiD<1mz-%&8Nnom$E#pUz|ESbhdAZ)kIj zx8mdrvoEmgaFDo%-t2L8lj#(1?~JldVNOX&5Z=bzuv^C(%f+xZx=#z65}wG__$HN+ zqFeVVp4JJxqL17y#ClL>2Ki3pcFc~WE1QJz0WUuve#Ko(X@0f$R_jNiT{|YLVLyW$ z&5hMva!<w**u*HzIE!q4xU8|_-8cwn+?JEb#Eo2DW0GFUuy?d@<7Ud~<TMC{h^H~p z&BPNWexoDQV$!a5W@Gtlc8T6}5yROUFrIVwl47Cj4`Yy2EsOj$)06Uky2_&+)w7)^ z^z;TJLt{lW_u`AEqAUHcO`r6hbJE_V@sgI}sYlY|l2y9MInh2JN7}5fHP-RcpOS~I zmUwfe8l2*U2FD3a-pa}5E!G85q}{VvH3HzC8V|j}2O=s=SCETV@$K8baPa96nYM;D z9YE{HHHgUKe&n?PunJz<{6l%m-QZ%|DW#$76vm#@l{)RJ@InLOS_MsS>2#IretB=+ ze|V%Ny{7OfD&o8BIdLPC-;=XF+Ar8n#*-pOtK02*V$Tu2c7`}NfpFENpGj{6`r(la z)Y%b1<8u7Mt11V!&TUh~S7zMqTBZzPsb8f}Q?GFbSeP6YR|wLNv%n<B=*8ky1ppZ+ zR;%VlM8H|eRwWg<P-EF?(zY&)5{imCTN)9UO+#E2NPl<OIIW5`ImM%dyG$l82}3Kl z%=PD(>7<(eM8F#ZaVl^@c40~PQgC}>9y`n6^_xQ@L)1*o-pm@NX`2<5`+;})<rsH8 zn(+&~R+u2jb=}kOHUILpLBqI(S0u&i&6q8s)tJ#PrZqg!UU5c@@diVtzL}Mg!Nnub zlv?>@!s`OaB{jZ(Re$B_quXJ4h>BwUneE${@wXr!Zs-2C)1CT<bco7+h6X~dO>iyb z+mxSd2+P^EZRQwB$M@k?fIDpqGdmDg`G{Bw)CwM@<7gE|SAt9$p+x(85>KT$O`JGZ ziwt`=j1Nq>&cC#J@MIWMF@0xTb~DCw$q0XFg=6Kl3b%%S;z0)-wKC#)TCORSvtNt& zBDNy$+mk5tgvi;uQH;mZt_V8;owT6xyRhkEBc<=~F2o!J399&eNg288iEHeA{pQPi z3J{At2P~fj+ID`#1zc<HuZG2<;92@us?aH$OzG^A8oF0RvxZU66)St2DC+w#=UR7f z^Vx7UwdU(%(ax`Or6)aO4+SX2UwhJZE*WT6xs_o@ovQpa1K^4t4K});EY-dUskVtz zaHIAWl0eZ}XAK0|KU?){hNU0om8UMq2U%|lDAjcYj$GTPNq?CXS!@6wVY@?_XL+J; z%Z<OYqRF<v@0N9b!gI5`er1zIDY12>YMfp9WS{<M;O8ERo40b?njTGkm9Y|Ey75KO zHPgOvjoWf}3O|fHn^$jcS%v>Nypxhevc#)8{i@(&2>fHCkK84inO1`NX9^L`@>bJc z7Q{zk7AGSh%U{Z$cHNHbM&T>hBqOvV<zIFT=k%f^d$RR&=9X_z%H0bD7Y=ZO&d9S< ztP|v9hE5Ax57Q-AGd-iV%GFO7j(-~TNU}~x*8H;7M|Ld_V5umE$3Slw4ES<$dJBe9 zvmZpJ)a^tm%_~*f*sN={Mrm&{+kwlR2?q2?=JrTFU$IUuu+>CyrK~(X7s*izpW@Oh z)^Be)$;vwQ$|{8zoEjHpw0F5wHa`$pbiRmNw_U9^xEewRpNUeoB9qXs)p}}0xfA_m zVNJ~Cc`Vjl%Q8E1^G1HfVBY!l{*`}a)~tb5Y-#3-tx|pg+z})U-OghV?-JZd*z5Z; zJX&u(Pvg>6^pBNHGan7XpKipJsWkPkoil><&`B|-j%|1i*KQcR7DSTqYIt;YE0Rj> zQTrK_Y+*1Py$80GR2r5m8r!5CHAWqd+IPf4`E5pchUct2R4BVBUlpZ=Gt84}0=rj+ z@~tS<m5k;TUj;aA%atzc)e1KdDu<;rdBuNGIbqi;*?L3Qy^6@x$<qX-)o>pT?Og=R z?KVg&IW*p_RUtXz?|rTx@Rp`op5n8oJt>^$oWB-xb3rJ3?h{LLJJ@PaTk%|q!b?Kw zvYt8y;?-VVaypJbC8f5oUBzqCI!l$5RnbQ>Y1CUYz;ZrAlk4pWxY@BTD_|MbkHJaG z`Yc}%GkB&pYCbR`k%K?~lxSWyTc01#G(NUI+Y*^*S-U}oR?}`>b*h;-0UWw`RBRJL zp)so2n-K>E(ifexxq(#1WWJs^OM}Bxy3wS<(=+M5=~P`_WNZ$`tNy~<eQm(J;W%fn zf6Qv`nW?xPuv=$3t~YX}S{RoysV9|B<IV<_kIA>h_~0c}<kc-`5I*x6fpnr5g6ua( z7WmERh(QtO|JpY4K3DPd{CmQK9uAUkDF^oGK})CK2;<&et_KY+UA}YbaavQqAXAz3 zGVpl(r&Ze_WcW3LCGVV+{X95W5Mr_Rh~blk?{Ha0r=H;?*zuCRPbQ4WUNtx2RI%R# zc=3LRV-AaaDl$TYkZisDHq>>c*~>_EWk8Zu;XqCEKru?#(mhD$4vXY+Y2O6Y$^n@_ zVt~I(Zc7Mj$!>=WtMy63GPXNWxtB^$2BidzENV@;)|1?+&N<q6MOC)lS1MG`3U6!N zkN87{>pnYb66K;2DkNE4;?%mbNLI^k*r(Ta753GNh31pZl2jBs=xy7kVQNZ&{{D#a zX6o8vj)Nyyz8$@FFV@(m744=gW2prL1<rDA_ihs<?Q?P`R*52!)gPm8`BTHKcw$ql z+nSZTu_s=!ABduCG4MwS9*@x|J;v57<`vy1n0{HPeF|d@O}k*Jt`#*Mo{8wlp=7lV zF44BI6Ox%$)YuI5IUZG=AF^0O;I>0{KgjNJGg<dF9Kb>(v9Rp}8u1gCd-#avPp!ir z{A-x->xZ3{%oeia=oj+!X^Btv&wG&2u>MsA@-AT2l-C}&0NP$NUI0Vd78~FqX~%W{ zks~ByNj5<Cgduj<l8tX3+Oj)n9sZLIwhP?Mm;%Rz2IO+{7oXv!U?iAw{cbt3ry2^? z`eY7gH!zpLs@)7$&6sbbb;qWa`gmSHXmi6Ryqm|&!Um2WI-t~EJoIYC(Hq!Ua;<qp zn|T9D{vUg9+12J6bqlu?TBOCHxVE^vQ@pslyF+n@;ts_<6nD2$w77-f1b24}4sY1| z?C05goG<SWIAi2Pk~=VxOV+j4TyxG_@QpW%^jx5P_{JZ~k}DEP!^kB_=hb;{vx;?8 z_$+{*-?0yvAwJ(q*#-)4r?~s%!0@3^=d;=T^2k9w%a-)vl11Fn($|QD%-q}W+587{ zk#P-A*R<Fh=R?2v{08G`CcOa#2!@g6gV$Wa&|PqTYs4v7HiYi3rh5KBgDyN1=Qm4w z?%t2Mk1D<DEUzjF+Igi7Q6WsE*yS;o`%NszMRsx@QpC^of`9uX$QXD(%dz^u!`6NG zFDy0{722{ABn`pMg7rsxp+$vwK$A(x+rl}^s&7JXa<atTm9I#xl~sdlikB7TnzL06 z<&CDiwm%(}n4wT4e<!tn)GHm`iGHvM`VE4Nk7Hrguh3K(0I`1y@+C3&CW<$$;1)VV zzB)KBz|4cKJ`b3H2paTrnw!k37oOo=p1yiG)NqoB)R&Z`ZP!`!)y);OdOTdITR?!g z1Xjf<a!>31_33RHVB!tNN0GLvX`mr&u3#Y|Z~0d<G~232=$$8a$qJU7d4umilyns! zRN;!xv2s7_3x2KRb`D10f!?(sC%Wq(^vLi_gxCm2aB*v4NIMs$Ob*+V^}afa5}X%u zwO}FBKw`0|Ud09z6=a)!XW_w?X7!ZEQa#uCTqCk5Tj_>;X}-*{yH{1^akVWmX^`Bt zJ#-!~+oTExLgC8b6$v(SkNjclazsAVl@J<y`e|gD3=jPr8;yI~)F!Fp0!3aii*yu0 zdAhM`@`&>rPMM@;A}ej=W=NZr_3^nC4dV!V*TyB_IR8Z59@8&}n2t`tW17-gf{6ZU zCG&Zk3D~iKm6+<*_U!dknr)9&F(-$@kZS9G8~$y{>zCa^rKCH{891AUg*BGLrz~-M zl+E^Z*I&!939c1Q-83ZX%zf_^!tNSwdp$<9#$EWm4No;qFS>^!eJQXtDWjOpkHPdC zICok3Fj~xAg4$qBIEh|oOpN(Lsw5}(dsiAA_5P%-zx1{H_b>&*XRKype<a$y1ylWe z8;BkTzgxT(SQ+TsZ;WowMYJ}?<v5uYsSHRc?Kl@Bj}nb)6L5L5XgVF)oCoZu99;R! zYoty+O&G;$NEb-nkf%zHhiB*`N(<K)G^aUEhx~fl<CW^|ZLF5C`_cauu}PQ~zr-V) zdLj;@_*9M?Bg&|j<z`1)=n|ry_L_r*pEL~p>=<2N+f5nHtDAXNi8ntoO-kUSjRR8E zSqqJ&zyfOt`_%x-oX8K_zH?8`uYKab%$Nmg8@Q3Accrs;PBqqa(q*e|5VeiWdAMvs zvGyfR%`%qTYrki|E|l%)I?!&bYp)4YhF{O^5Evk1oJ5KmO0TO=pLuF-UhWxnQ(m~h z@0qvACsB9)q~WoRpl|LUMEhfS&Bcy>DI>3Ix3_rbqwVEp$Wn~Wz}frwLr;>O)FQ&t zHX-71*SMZKy=C0G9&x?#h_A=EoZMCUK>R%nT@3!<{_Fuq*#na*VSKA%3q7#=bC~mE zVq+zmo>$P%Gb&J3bn<LrE|9>=2Eg&B;3gPOqJoa=JmDv9#k#rOb(LqBU6{fg)R}fY z+x#5Y3SxGXeSJ1nPRrL%V6W_5Vla(;H`Fzk_-C!g6O^4#Jba}cVI#h#8#+q3b!v;B zRk>NQC|nSEbITFjo#0ZF(n=Y0UDZW@=rD8%;mE(Gn<23rmLs1MQb_-KAPEss{k(D= z02fE|S>Uh3l^NkL0BSomclJL3ROkx;HL8(UM8dTAk}AW;p1{qt)NCPsWP=wdQu3}X z*$X3Oh#NF2T5x|eacPokk9t{OTjUQ_J-$8(p*g|L-1;z7FhhZcB#X>;*2fj8yD9P1 z>k!7D!&XO$**vG(d;*UJ{K4%WxXOg&U^T)M2_}~;*oq6<6kjKVB5%%$UHCgh4k%vq z7G_m&^BlM?HI&~GhcUjl-Im!q-#)7TI?Q8bSe)TORyB%1Y$akoT=wKM=E8RxdV~0k zb!W($1SKf!7zd*edguRe)h3dY^4Mq!;?EgqEIlQOv{%J%oXC?zeiri%y#07)XZVJw z83rBuZ9S&~*p<E;-=g8xl?!{>-B?j230-Uu#S3Y^Zk=@AzG3?6e67Jesla*RH4Oqh zKUpMOOac8V++K5^B-Fs;k;&`8f~{-%>-~mW9a9(_m1}m?h!PuV57!Ql`^9Ljn>-gz zi})O6oV-nLNn(uq$Y|dRGbBFV-a|6ZNnsRj3$7r^cDco)tWU#cC^Gtdzz|z)S_6A` z1MBNtTzxD$L{5o^61Wj=auWA;LOd~MraBc^Ee~0|Y&vWnJP*P+h*a1V9yy#&d_QEC zBRoO;N9O#;mP-vduM6F4tjo%3<wsG)yWgCo)Ha6C6y~10>sWO?^)lGT8o(pVN`qK| z<glP%da*jbzBRT#Ssx$0#(0h&K6gm*-eCOW1%T%TX^dxlEa2+Ba$0SWP%qA@{hFb? zLzl_jV;EQejd)@s5}lKSXkOS*E+I3TiHcdER84goQYg!IZI+T`&hN<A=sw$|V94%O zHqjp~CNeUDkg*MJYpPn?I@CN^Yc{(YeLl>x!uKkwg+-$~!%+aQd&D?+cCb&>y|xdn zmvZI*VN9`IHVL=##(qUL{@0aKl;l`u+y=$ur#6ba#_6_Q`jp~`Y-zZr-yBByt=}?f z+FR$(EL1Il+?Ilk*Bohev2Es9+RJsVdQppa8?pH*ACElx!ueg!Z%+kJHnewj*3O)R z=vm8l2b|zW=`X%SKwZdhzm}ZIv93dffS~iNg5vF0s>^v54s>HW{d&VPv0oce$E+s< z0U(iTw`Y$ZHi9GLKN`t*k~u86UOJ!t2-1HY;)bDEg#S6jNnQ?dp|^NT&_kT$rMvfX zh%d{&lK7It93~h&ezqOx96$&d+d}oR^bpFt5w-K&7aSOlrf!pKeob&VM<R8v8C27c z%8{x^n%i~%iW)>cq#bhk3;iJPxQR?OVS?J)tZ@yuZ#M-zaOznYcG7Sik&?wQ<}h*o zR$KQ9r6h&X+xJ$BCLQD4#<}E&5Ric7>+@F>S`PB&K{PXa)aYbRc>b!EJzI}@gm7TF zuW-4jeEnDg=sBQJ4w(BcyPT~Du6DFk*DJieW8_M>bJ-bBzc}|By4IW7x0@6-jR+R@ zkbS~UC+bWx($yLf>teb<1pAzc;r2UQ&r-I1r`D1f$U|vLVaRb#gEeAQv|y7Uo%NdR zFB%_=n2Y9IxF%4IQ~%!T3hf_}C}F2|Q8)*(OaW{HEbRbt&g?}|;|>-m#c-PE49(B< zWK^h8n^ddBH?BKKHbuKd%@;eBz8cPKRJ>XJ{di|UK0$VQPmbphmr5++INEwgzP%o6 zhL(H#%z|+Kx>c#3z{+W-ag&-y#Gb&%g8EB3M9|olp=&9rZ)EfF`DyYV)+eeH!i?R8 z;ceyL`;=9rgkGHRAYPg(91MF!0BbXIW?fDi9`@a};(Q$c2|rv3hMsbS$K>*5RZnh0 zHyzJ-kDr6bI)kXDO^>mW`z%@jHF=hs?ZuUiVL^hSwoELH9-8txN7piT&rR|A<BSTo z1ff7CXs%p6$6Sm1GHNCL({><Qu6TiTf=AnOKorCLv!px`fcay2rpNjf33e;;m7+9I z?XI^VGST7MSVc8cM6&7~HEQEcqw+ty<Eu8&NV)|%%3bnSNQ8%vrm5%t*yJ$x4kE#w z1?Ww0{mLnYc_is!rk=l)2yK<Uud4~ATYK;acbje*5?fbM!1duDhSNNc0~)Q4EUAwp z?6aJ-$}4Gh5vMJ>o>UpZL49322;_U5jM3%P-m{7vTO*dfC>DOBE6OR}AU2!B3q?-i zjsq}YXWbnZxI+qVIpO=-NDR3TBw*CfG1UQmd;J13Q(*d^J@NvB@T8ovUta&8hXD+f zw)X%_;OvYG8xsD)&;mmnR6`%qp7>!cG+K+)ji%gU_-RFNR+@?Sd1i#@`==TkZ{sp_ z_ahcl9XTi~>g|fZqi)gD=N=Bud^k%=c8zfrH1>>Ez#sk)3f}0)o#hQqU}FtMJipkz zaN;T-Gw%jOJ5xr32XGRrgWE!;7`?+r3<${Tqm;j$`Y-M}3M*I)n&M?BZcck5i<rz5 zcR6i(>IS5KJ{6c6H;3Tl!nphy;Em?&nk(q2K|4Oc5-roo9C8gC?lZLD4%PAizi-H0 z!QWkMcwNQx#nWr|nQ^-y6xYjGZ@#YGl3O7%altR8iqaX>smae_8=5&$2Y01e7^%Cv z!QFGQ>xQ=P(Gtm{XXDT}L7w}=l~$N+u-2P%K7W=N8<yRv_=8_~F!)s?=OI5ww#esU zCw6-ZwWALE9Dbmh2CZ}^reW-7)8u~imgpQ_$C6bf54KQ|A4`=zX1-*&ybd(&aI8ME z@x5+P&ixnH`wINEG*aw7O`rI1AC6l7rV0$VL(S^(?Ed6!m&3W<OCgf(tpSz-b=+C) zIGMQ4nnfm4d*zBl+o7fIl#8$(H9`D`iGwiGMlTZG^2ortIA>;oN)6z`$7Z6rgItLy zw$AOU%bx}3A7%HPg>m4*kw>tZFeFeZX6gP60Vp$t1o}(4b@cT7jNaIP<TppCdMAS2 z2wR?FBm=V}^99fHLPQgT|I3YNvb7iX<Rs1xi_XVb*#oCSa~f**Gk0F}06x4aCnfNA zkmuhkxNb3x03?Puzu3ZkfoSm*0GhP%l}7|Akbds%uRD$%X^BA;*=()*M)hanx#0dr z=}0=SJ+Gyt7hR_Gs>o0eG`8*ZogN8~=rsW9p}HkoOB`dNnOL$cZ;KD9fA=?1;s19s zb=sMG@SkKV;3b*rVaiJ&VIq4;rkJ3~l$zbZdp$7vt;;(fziS~YuWqawi<>BAQ0%j} zn4QdAMuM5Z9$Ht`rw;4JVj%<!NZqM%tUlSr{D@9zWpREhcUM7Mqr=!}hCV<x>*vH~ z-zkX*&R}%q&ko;YOB?Yef%We{x94V~f!dzEA0+Fn7}+uJZPDkrTUTlcmwC4}fA*tv z^sJ{_zi~`Rwav@wR<S*1QcC{Dm9K;xy7?T}Xq`e@*=sv<pF&n8)h@I_HaTqEBxv^) z+e4qQ#qtoMMQwz(Z*eC;=-n<Grg6Erud|8aice+t!*Z%H`}{PadPypoAXgfQlr~%C z;X9iN{Dl)5;1MA5Cw0yJAwC4!uDvZqm*2(haF*1+*jUrX2?eY*+P$}c7FSY;&lkS) z&mri)e;vfyE6#|y9p3Ak$DWk^oEG1$WwN!j%h%C$*+fXe%B3f0q@G1wn9_fAxQ0c- ziW$NWkd10Pf9uR8K#-}ccPYw`C14nSlo;)kRvgeB2pe0QrR=@HK{mhX2}a$!QK*!F z{Knz!UOOP-==KOs=J;muo4}sJp)giN5w9v*zl>7}oU<<K2+GM&9}&?P3ipmV^Bfx` zO-J`E)|mcWM|9KJJ?Wi|!8|H-P=JH+$bF27^P_JosV99GlgMv1d3fz6Jzawh^HoYP z4HDQX@hpym0gkSVR%25YxvudK=E!^_mVV0$)*r>naWy5&Iw25NT3@BMK<tCnRg2lq zRm+Y}%aq9dEJGfDNE5|Q=?;mTCA%uaa2{Q-TIGFw9%blr_~ER<9Ygo-Z3=;(>fBBY zD4Ss38@bw4-d4!cyOMGNWka)q2Fny#%KgZaN$w?}8a$xCw5Xz197I6>8)KmtzChtL zzQg}w<8}j=9c!hAYt=M#U%+OFsE1x_Y21mAbIl=ciKoD}de7))!(#ieW_)GOtcTei zG80J)vs9MDt~c#ow^c6E`W8O}v@3uWP>Kc5xMWuUjlOkgl|m;5HtAe+Af_z@)>d@z z11Ya;)BC2xK|f9Yu@FeG-H={m%FH%_8;6&7w=8V6YKkfEl*g~sV4;tY$>Z+i>xdC_ z$ekkI>XpdW>GLlR63%eVhw&jI+Qu{@+Pg<<@8-Az8wx}(qRqFNRt4_^vFZ_aRx*4= zX~_cZv*%*0G~rj%B>5V-*KE><{rIyVo0)V4>eKg;%K~6&4V&&B97`{y$&b`*_IW%q z-<+j9((#3TYz(5}bNV?aIpwwHI$u*2QCpM>*UxY{cBbz<Q6>?iw7@KQ`^H|aV<2PN zcP%cn@w3Nje_nR3ihKSBrJU0BoIr$bjH2h;*umCYOtTaGcf^BDT_RVE57m(=PO|_I zg#TI_k*r6f1%b+SpCoe1HA6kV+M$Tb@}0w0n1?9AesPuvA)Lj#&Atl5P$I)&5?d1` z&Wd41a`yW`8?8zS4hh^wdIyJy+e2#f+zx+H=E|`zG0_I5APl_>Eh11;7vBdZ@Jlf} zD^f%_YVnRBtg#<@GnUVB+!#Ol+}b9!;=kh2N20=`tDbBqSg{5~DF@Y!-|cu#t+AxX zRC9?}!y_IQa`teicof*CB0Sj43|bN16vSD-{jlz#ubZ0sjoq_w*j;}A2DgLuHX@;- zA-aDSt;~|(%6E6i_fhIow0YL>ri;n^7f`z1KF~J`!tWl3sGfR~B?){%zv{WEqCr<C z_v7`XAWV%&mJPTtfZ7`DUm3xtzcT^?C1<>U(t(#X4D$m0!s6LDW5I@`y<`Nde`N%? zx+b~)KZ+cc6RSR!&&h4wI<@79-n_d-T+Ua~p1q?eXi3A;FT$q@;0&AR?osFjB-zOM z_17Sw?LVnf9?dH-w!*`^-8pWMtbGuwR19(61C{+r64>YS&dkmHd^x9+&P%>Tj$OlP zekE{Y3oj;rXnq1;D3N~tao)0qetVqNdIz9D_!z8VKq}K;#(%gb7~R$CpA8&UGU0Vh zw#y+jCGZtz+4$|K#!=1r!+;S%%PC5E_H8S^f1EJ^vPIk8YceXEKutYjXk$MWlBsUq zIQ!lZ6o@Nb_a&nKLjTa7<JoA1+_(04L4RC1>v9r6B@4jJU4*l_PKf{5=+4O)X>mVU za9GoGP|%l>g!9J7ckU?B@8~H1EGVhEnVWktP+C`|vA7E}gqu$6hH@u8!*oo7po`8^ zK)64)O$JI%U=}eg5q=9#$-3)#_&%IzgQK_dTZp7(V&BI8eH;;SK-U*bT+;!7fkPVn zv*?o^Lkwr~`2I&(6ittVYb6(7qYSW?(+wN6FcJL~8tjir`3?Odj7wD3njCnQp0BJ! z44O5vZcpb(?#;~>R=#A_z?U@e-t^oo&+^Gq(P<s6&wkw}a?W~g4sgDJSi32elfC2u zd-hR0R_7%%sCm>?WPftPJh^OEBz?JL%+`dLGi{_i`Eg3Cdo5d7>$m+05=iXzTh&xf zwQ>Xxd}iq@ZbT<6H2J!cCkQK4SSSa$xHDyIumWQ5DZ77t<z?C4$kn6KtDmpV`GTV1 zDU#`A_(sXwVkyOio8w@U9pz!-(|zk~gxnz;_6Dl^($wuaL#e$hT&Or#CmeIB_OGZB zN@GFccFgvJ9~#D4=IUhpan?dC7as7C<NH?GMq*d}-o*(0q9f6pw=acY_}_(~Lq8V( ze+ogImqL)a4{A{aMRUJl5u^Ce>UkZN-f;>Drc^aPO}D9^w9P)uUS>ohxLlks0ObI= zciH#b&5P5U`5uRz834AEhh51XfZh(T-^ucV=cPXX?IMQVb)iHh_M_PNbpO6yv*+3V zR$0{)zw1@pghZu4^YxDR_Qh?LTcusYoySRAtS<j;T+;S=hI)2=RSL)b&K31BO_2?x z`l8}$e+!^iRCR54SE3ldS#-TpIm8%URL)aJ$J_ScyK`b)xjbwWA(j36E@q$d`i!|H zw)TVtgIF5Ej_oxUv)!~L0C~D_vg`PDsP4JwrB%~jRQZ9=^-9)@j;o;jWVyrr*s99@ zxJ;c9@&0#HeYouxpCEn|D>|SQpUb=Lk1oZ&5+kibkIW};3*tCboUeA;v)bGnN-p&x z8w@@ls%7iTWwl#E?;&!W{kZec;cDa3KWq5s;_!LimfG>|c*>mE`*M34&(!bXq{PoX zG&FdJ2qeocc>OryC#V0kL<_ik&^A^7vDw6kVy{`davyWwBwSdc_$a-)vA3dsSa&#` zG0xgSxJ?H1do0uFj;MT^s^yO}LJggO1nJ^_cDK#nCVuE2Nwt5TZ4C9QN^gy?M^m+j z*&yF3u5+#RX+F>%<6A!$<e{F>1iczPD1W{daJ;%&DGRyr_I<u66XRPsVSkd;3rNDL zbMw7SH3t2;P@ZYK+V9XyGDe?@{eJcRf(PU{j+_k$lSbG?Ge*BGKY5%}ZugP3lf?ug zaXAlfoq;c<zR;Xp9LBX#HaNGbXWt`P^GRRpKHds~eO5iTT9B>h_=^I_1@*TsWIkUs zXv+IOvjMIQm_S|?HXfeMJ4t1+55ZcI)|F3}ZciYa=JvEk+N1O3GTDwZ(2nH^>Wa%0 zYj;+PmEDaWL&wt4g%ZCtQOn)XLaUzF`Df<rP=k~9gOnovz}?VkT}$5BL!TvLn93LO zRVVCUZTPg#H<6W4Io<zs?_}VioaAiO?kKr{&M?&P{n)YsZ0$*b=Zw+er4YiL09?FR z*~+-SWGby$>FU6%!iXz{#|daZ+I`Z%4{u)IvxSrpY#e#)vDxK7^Hh7AGC73N57~a3 zjz1A0xYU>9vOf~pr=RW@H!liL{(K61xVC`?InCk2<RTKdQSi)0xGQt1EBy6r3MLrZ z>@cw_&8Le^dG|E@X#2u!d%s}p_4@4oz^3inGuuSon^1%K8JW*+2j4uoGW%J`Geh^y zH%K9#tik;rJ_6H(tkwuv_PK?s7qaTtuDyI_E}5W*vO`o`E4#v5oq9iB6^gy2@ABNA z#$O{#CYq*jcDkMF?@RpE<-D_5BcfZ8`+#B%!P+|I54O7@nso}U-Vur^7+;hgv5N!7 z6#oS_Z5$~c%DkiZ_%(CR&}Hl!)St=v?z$fiEnD2vAAT}<TYP9bg!P=pt9s60a-g6s zv`L|{miabiixz**SPon<Ab|KaFJ*4*cd%p7WFUAhPo>70+{N5c$O;)Ld3+Y4u$KO4 z_Q5T2(!U7Xngc{9%0<0Vb;Q4BiO5y|A(Uc*pZTnnal^y@hHUN5<^-`u07CYStV=KG z*AVqwqL*9atQ|1<6U6ToN}6U!gJKS`RyG5fe@GZVOk#~2>ZExDulym)og87&#)(98 zG{NuP$-|sIHD0%%eQ+fZYB$!9W@`<or$@UBN4mJeBYnEl2R4}qf1f*2S*g56ZzDD$ z!o>x1WZ+R<o1Od=i#akpkxHhAM`4wm3#(lb?b~sV#88v<?ATq@lsQPRIJK}z0m?JZ zbmfVaRBRg}@0k{$0d)C1cFt1mXZkYR7V66x^F6H}oo7|yB&yLbK2c;VE~0mwYVn62 zSZGF@q6KU34x~4e1&x!;27Y(N>Hc_=?YF=`*qi!8UxS9;IsUQ|tz+3kibD=vGH=K6 zBGpaGogv9{8(m+p|H3((Uq1Xnc=)Q`iK`a~Ao(WhrlNR12^Xkiyvaj!V##oWyAK%= zl&uAMHR(JKVBk@9=1E?%L*6&_UA{MuEz+5k*w&S(kncUr8p^C{KY2a0-RmWLTX)!N zr-t{zQUK-8a^Osr$$d_roafP?DT=OkJY=ju8)o!H0Ak?%7xyeGmRXqbKZ!j_7_|Hh z99ZRn?nr}|MmZY(3e*Av%yO3{T`=5@*-|d_O^(~FYl^$xopih#MT6n#R_}Piisl(w z3mzM|L3Fd~Tg;jo&a6!{2T9f1dr8#_GcsDomEV<o>$SVs9)T(K{)TM-sbDgjVWa@n ze%_0N!d<!A1gJ$W)2+hr44l;~bXhoz_RU4dc1x`N)s4~hXEY(<k2Y~D?)^Q{-Pr|x z$<~K5{<N*By9p!f?sQIiLPeP{#N?DQg5^%x`^)T!2aqMr8`_qOtvT4WvNR8sM-wzt z^L(dY0QfeYrWmdFq|rlh{rGoKdPw^-MY3|K18Smp$ddwsQ;M3R<g(6Cx;W-7&|$uz zeH5V?Q)?(Uk3|`iY*_hL7}_zrqjjPt=NGM6ahXs)5G$sr*`vJ}j5bkyE5;2gmV+B0 zoP|vBDXxXvGSXfJVO!!PZ+yn|qB+*mMqh&c-m&?uEz80d#re@(=f?Zy;WDU`6|!kH z*DjFU#*2WZ|LIpix=Aqo?}{Czs~DxB!S!#d1j1z(CvKC+YRbZfvz9@RT0LvAmCkkF zOGZ$c<}zYk@piPqMV!&<e4+$)h0Z<*!IP6zp4+OWK7Gmh-z23LSt{b^vuSHNyc$~5 znpLhu5rA#cVt6(e{oILSSr|hB-QWlM(3&)gom8615mw&7*rI%8dyvCCxo~iB3a7$G zH@A0!yIu;Ed5!%B)XHv$a@_HSC>IBLTBT_W>nCcJ{4^Gd<1@>y(Y1Vut87+FBmJVN z1joq7G>^c0D9^WP+dJ%j+~!K;^Moy}{T2ny7OI`|n(W;fWV(JuFI(k?I52}M9c4>L zB{#zrd&#|kV)^n-)}V*l??{o~-lN!SyC68#_y*(^AKn7p=C8V;*UCp1l~g1nYXf*$ z-%JL<@al1$H(%cZuD*tlC<57M)_W5#ECJGS40nbi^bOqB%yAMA?#ER08nsX_FTt7A z9TWKi4Upt$%Xk7Onqj0lJ&V+bGlH_h#l!bfI}MvR!}8%C>y7>Qhxk37ouIzPe$Ccm zo3HRT<wS7apW`L+6$?)5yodK06_d4S-IqN@9!ku=)7Bo?M>pXoe#PUhcs$y!snP)b zc?N=n0H`O<E(*3lB5Cgd%OHhO;2#MkDzhc3`Nffdy4Qevfba;$?NgkxhLrwq)<}vv zRQo4>Ixr%t@t{$_q1LEklEC;*8{L8voyfvz^jIsp)_u}#e)2jS;EBKLF_k02JhP4= ztl2V=6Xt|RN^~~}$7w!YVvh5omG7FOt<{URV^UMNVMGc0F6oq}H(Ld0t~x_<$p7t8 zs*zZyt)5oUA=!%T@4jB#-%!-~K<>$ZpeX+rD5{GpFP4Of<pql3dV!)AzRlbbIcwe7 zum(f0d5OLROyJH=_x)OHF36mZrQ_f*;@3mV95J-wn)=GEd;??8aH4<qV@tPJ64h<> zjIYaM-$P_RiLmFh8-q&6n3P8hB^-pW%kN72;DNn8O=cz0mBsqqxUwzXL``eI#r3A; zR$YY(+wdY+GLb!BMje^Rn0Shmqqja>g>SobK7?C^NF^N{h=>$?DDP%XpJeOAnRj%s ze8OjCQ(+bt=+V&OT8w$umto!w)~?<eS;~z1*jOCYpD{DOZ_dN-u`b_Lzt{UVU2ti6 z`J*3q_UU$|Ug`Ov!T^Bq@?ie9l?HOCu<CxXYgzfzly^FHvzm}I)wSF-&ZlwGouAhN z7e-EcE?LSh`n?di3+|e*C}Mp&2A<|8%|-3#Il+!D%QwBfGm5^9XlV^T16vV@GNG3< zcMp;76i+8{3T`&6tpYwZ#*MtYc|889=jd(;HemAV&h%&zbP=Tvi>fa{OlVT2*b>|+ zOgqIz5B~PO6kE!k!Hnj1_WsQDK8dZf0jbsDVaug2HE51iDQ^RJ@Hljyg2=sR05mL# z&Oz2@4tG`6aaDZMBShodg)Re`yh4ZcsFZpbMO3Fmgwio$J(@Jw4YHSIvrAmiVX4?1 zmx|9T*?8(e>m&ntEP6Vd65{;o&vAU?`gN#RHU7<|PlFE9uCnjfP4rVT9w7~@Cpr`S zN`v(hO<0rS!+Cha;u_vVL^X%~;WAvE4)XUrkf&V!Dmqd<yei7u8BdmY(EU#eFMe0J zg7t%RiIj2oSxFnc+WwM4igZRksn5xv<CaWNxtr9)a#D3cKyP86_IFhG5-oJ=*kzQO z#`k|Xj`Y^?Uuye4^1o_*cLL^1gn!lguV8hc*`k}~Dpa&$VDYkKZ=$c^I7s7y`g%|; z7d_+VU1yYZty??EimEeb)G!tE9m4U6gfAM$rnThdj~=OAvYR;NoVaa9v5_;3)v*gU zfL_JP&z@j8!<C#7f>LiIdMx0uD+BJk8i9R_d9fC7!WSJPIaEF99%kI=SpSGmBHrH4 zQ2M;Bd^ySaJInhlN4QmWunuQO5PXVx#C>>GnKJ>MtD#wSkAtYJt#2ICz;7I?1Q8{x zGdEdm&He`|g*y${^N&ZK`)r~jwd{v3X46_U&yEZQNQ#kJxi54^>wAWMcUph~k=HV{ zZnF8qbW4_=UA>e;jE}wt#cuK1H)#P<s1E#0qS8Q!*p1V6Q}o@Dp*#{{GU^w*x*cqF zrCUcxj4^K-Q!PT=#1B5Lp5n4c68;8{*n_NYOSM#~8NV#4^Er_?r)bVfuJQp9c3W>T z&mU+AH)BV2oU)su_|pPwp7RclHCZWwin3x&E?%OfecQ#TjhmHgsBppaItsyI9kti8 z-9&0U>FuD40$`0-61@a4Ap&OKl4{#w3(1#`+eTS>!>-hRhQo>5V>bpytL1m5BjH&p zO;U#ONP;e({QB(sEwoSex5g^Jd#wE!SQ)-7Sg<1!j`$JSl_huEQd_26Hg2ek9uk1| z#Gkpdv~|RiOyLr@%2izv8cBNiuB*tUBr;ql#rLrKM@IoRr5&o09@&u}8;U<Uip+DW z#Oca)tvGH>eJI<y;)s`6(5K2hJ`oga*_df!!m6MyI`3)*G_R@%YT%=7U`%!R&*b4C zSwZS_kDKQ4hD<DD8pK1kvBu|<3KDs{>nyl{(Eu}h<Ao-rj3c<N=I&)Hj;XN+TEW6v zpjFH;dt`rRaGZE5XNQN;NDcoJC_n9R&DzCs(Ven^sJgmf#g)q^?p=6QN}TaK%MDK; z2L8taKHo!)j?~|7n0VH~I_4p@6hmtJ{XPURWne^q)%Lu&+POE2zs=X-GX7jl(KCCN z#~{v@F>kfQqnO)8z{XZyDr$GD&0km*8QVjCOXl6QqFDL(oxDyQBx)UMmy2vL&!n-2 zk}Px0!FlSs6$e>j&NM~U@iWP1Ua!2$Cj|$A=5>iChgnO!+=e8NGgU&@BA&C<CMO2g z`EE>YO<XU4gnziCK`WGQ#w>x=_5xV^^GKz70Vov3@g8CQ*C?T#>OLH(<Wf{HTCAk% zgiN=+i<3gOFiIh8q9?}hQYVPvysd;3D?n&*Y<O>n&od{MLA>JTt8$@|+JK+&1ogU9 zRPH#HZmTF;TA55nPfqXzH{XxgvF^cyh&O`)!x=o$_amhEAr}}Mz7V}%7HZ6vG^QpL zGxG8R=`zZ!B5WhFvUq{xGdPOkT2Y?dcxrE(T)_PkRu%ma%$1BZ`w9L%!Mt*7N6)vx zT$k||&6ox7AXX_ce0SfTDeo-+*a^z2dX1j~1?DN$-4pEASjeXoI{->kI=m~^BMwPE zEDPQiBq9+dw}T$wV+tn#TZ}*R;)Q4feVTk!^EIT`ouTLq4>MAGC7yb6An%v1!P{2x z5_#dpk$mdMjuUolgz`E2#J!N;KVS$UW@F1=3{4|Oa${%lj4O6rxB_Pl4Rih+N%e^b zNJ}5a)L{2h@h6J6?J%BSP)248hMQqo?;G6B>7UKJEAt5U7hXLR;MZLJ>~Qrut^q=z zT!-18_0p}_XL#&p+ZCG!7ewoOAzXV_r9UIgWpZ?Lm-|E^Xo8n~P4CX2%cEFpC3pXk z6sQqS9lbJ+?kSHS>_!N>>n2Q3A9UjJha2d&QMm9(J=Cqtd%P4u#2wDIE$XGy>xNn| zK&y#PX{d(R-DCAH_0Rv56P2H#vA82y9LW~WzeW}+1h)15M+p2)7UP>p5Ngu#dbN0V z<ch(`TD9tMd9^A_>j3+b1KV=wm!N%YKG7j_vEpw?>{WwX<g(zdoCY0vEdjArba<Ue z*nD@!x<oB~8VBKF-N+@OjD8G%s?Z8rw(glf9Q~7>xs1?6hMEE@l~#I>`Cq5FPWYD& zF?^S}Dhbo*UsPZwY>f}_a?rA<(h`Olc`2^LsA)QspmbSP_QKp$6QITQesXO|rKY)e z&)8)WZK!3AyY~+l`IuWdK%}Mk40#eVBc7gtY&gt?Z{#e28kQMe{VscO>h>W)Wx*x{ zh3>C&`!4hqhNc5N47o6gYhg50ImfzB1H}rG+{(U0-TV!9>_Ro!(Q>dm|4zY3z8yi8 z^bZZJY8KS+Q7$j)KJuV{l<wA<UtU<|`FEVHOYp$=$}8I2;#EGBt=_!s0(`Rqz1P1! zt$MzLXWTkt$N)m(?C0Kvk_Gf9J8<t~)F>-4twK7!BNJ5SmaieJ?n1q2P<KOLAtBA~ zC@(R~#cPfNg0Q<26a?$PAwkblBMhk28^h~i-0Oe0`YV6y3}}K_b#x|jAY?%IqQb}j z@Q+?R>J5zIKKL4QT3`ijEQKk_zOu0QqV~=4#<@EgD(~bUA{eV^2GtI*oaMXZvA!7r z0Tku#9Pyzv7Jz4DyNn8qp1o>>aBAr_yTWo*eRu@yBatzzQIR&)v-OpD*_2i$Ct)LZ zUkE%9N`1u<c@eYY;Js&q`%fzHR`SIo05)V3I-ve9xxkpgKRW&gRHzcykwZA{D`PKI z>x4&+=);p?1{&cI!HCWV<Wjyt3p=~fk5HUXbe7s^o3dcD+WaanPfSI59N5_)v?`V8 zxxAmV9GMbsH}G@8BTG8eZgn1~1z~Ckr>d<63V{p2^>O=$5b8oXJzoP}`4&mS;MM*Q zqV@8m6X!+a#ms_g@fIFBRM2S+4EsOR`cEYNpO6ZDg7X>XCd(|bGf(SZ!w>!6uc4y< zqE}=Q(2p>|LyL7>n17b?|Lns5ePWOZzv`B*2or1d9}5T)IB3Mqh6$sBfo|j%Zjl+h zh5<XtUwowh`@8rnlD!x{An=v`$Em>|^TqH1kt7!$`UL}_O_p@he+C;GAO5e0csO)W za6g|G|C_q;3RdY0bjGN^hmk@5;{D5@gna*hgYy3d<^R`8VOqlm(=zXKyJX5el}7qL zwg~+8-eZvkuq4?%UCInKJ8=L3NwSs+Y+q+AFKtk+^hl+oLAm7$>3(E7gg!7Sxl>N< zvljhRBQ}V#xQ`TYjh&X(c&5OCT+s>|S5o0PBxZ)>3)vm-*Btm7C-BSFJ0E0+eje`a zk!xHu=&44LnUm#<a|c52gN1X%g&nOlqOma1Ur(=lKpp}4H=O<b3mGiM;t5;$7a_d= z?B!qLP}__rJX|U^4A{!oe?<hgIBYPW`+hGxoqwu``4kXR+-mlYzMXQxi+e`a^wx9= z2sJ0hFTPzPIPuAh#)YX-en;)sYnR7g(4tkc>13=fL%N{#WW!4jNJ_0QXeo&r0x*}y z;UTjtk1|CNg>Y0e^W1z9I1&IAm?SG7NJmm*<)O8VNho3)Q5nj6hV|lzSZ{(yd`cpR zuvKxa<=jol*%=T}<aw(u6?(f&r+N!wuWniRUMbN0FIo?cZBg_v7<+E%HDW{+|MBI4 z8ZSdnvN7CTSm^IgcnJ}oWuo9X#0hy*6m07lED;plDHN}@?_6?ECyu5xIA#l=nm-ph zo4rk1?$*IYCY_8CyJ#+{_%DafNLzjt%LBSkHnfpqN~8r}Ynk7eNH<peEmiNvD>+km z6Wk9?t+&pgQu9EeMMcRY`Hux(g2;MUFwG3*H*l~a?+so(E)nIh7ZtT7CqwBhS}Zd= z(tf|bq5LOW^&$C(pYa0Sap^DL{O3X|G-jS``LjY3;mwyEq9y|#>F}(NMe8y5+|JNf z7-_h~%;WVI*iey+PjPd^;cgA$GL_4*S|Kk4d|mpRa+nW4N7k&x&YM!6M6>4WIXgu* z>s%wGz81$Y1D$-cw%T+!6}z#%0#x+dcyS67QF~s4PT729I+K~<P;!~W;@4~@ts;-F z1!u+b%r+Z(7xp_i<o|?OgDH5KAZVcez(Diw^!$~-AqDi{F?<`fE(C3izZ}_zXYHMR zqxFhU-7a!fPU`Fv$?K~>i2AQ<;I}=rVG|_0P}G$npGE~1Ge+c)9GFyK1|!5mwCq`K zs|p$^COg&!G05Sy<H_-P7bLGfFe;z)>g{`X>+LMolGr%>Rfzv9`in<)x<6-`)&I)X z`_JOXL4c-;#0W#hZ(u22++OM(h)$4fB!Dob{5GyUD!;<hXGdn?EsE$2N>+b}=+11F z`W&e+k;`H<9&Ra!&Uw>I@fUfyC)|+ra&=1e$!aF@lb5Y1(AHQGi;aqNflNn5*selK z5&-}?%}MTT^sxbXI&sA(iG&F%AH*hqK_7Fk-K?)cMm20w87xV)cEg3`mfQSk(@x&u z3m)6D`$y4fM-TN&atwm|^eYMSSvbo!o>UVH!!GCrk3!f>zSbN~lne!4Yf8kkMRyjC zk}afxwRYQnIXS_w5fHKBB1++pjLb)D2~EVDRT}wOB4`DQhcG*)#~=Nwc$kw|1hQo3 zI8hb>R2ROixp$*3c&*)UF3g5}7N6ag-7ZW`ZfAFF%lyFk8f;czM9xgxUOa2!1%)@L z8#OVyYl)V753!8JHC&I#V!u`*=B8k6RFXE1IAe8FkD?A-hqAl24j`p0cix$Nt{EzL zjb&7^d3X7mroHaoEm>z*#N@pJ6uSAz4JhMw!^XpqLP9p)tYJip1ZIeR9e?Rvs*u{u zQKGGvHH+5jlX)$6=JX=>BgKMW)YJV@-QM=ISv{EW9cP)-=7Rn`LlthE6Iw(o$Vr5K z2ZchpFA>#rF%wI$=nieNnPcs|u59;&7fM>$ssa<HeuA>KS@p*2mYn08ORuPHBdp0? z*CM<)S2(w6L0Lb!4T}0X{}WfffB&oE40QPKdOmwGgWK?M9_K{G(R>M;t^HRpUdL2e zjB{Uo#Ir@}x9l^h-O}H7?$oz5004{k%I%X9e!m?VRq0j8lI^tm15)JL(_0*Q`Efjx z)a>of2D3ymAV)uMrQVYZrjSidRLAXWZ?t_%9qdwR-dIp!qukuwx1-6cHCMTVu>v>! z@O_A$o^oAoJ|ftpTN33R+P;Uk%5`?ur?>UiYtXtk!B&_Su~ccAJPagXMH~FRa6Oig zajpH(^Fd(5_^oxy$kmKTK`aj*2Q&!MBb{&Oq`}p<HO6l*m)DHP?-kXsX4Sh)^6a}y zcjS$V{G$MFbnhWsz@yp#D=$(IAG;+^ELVI^JR+aiyLWkK`)Ee*a(9aCL{%nhjjfz4 z-wrT-SK|6;cU}^`kS;RaVnuc0bd2LQe^<_66Rv1(3|E0+SPxb26}9eJZqAD{9NDf2 z&mmfthuS))8Rl{G2^8#w@*A3A(qCX0<ax9HEy3MgIB88%WoyWb(VF5KDJz5kJ&>Ks z46>{KmO#^h2vwoF4F5O@M7kljQyju==JO1E$0!CD<+<G2SB(O;`v<xFD~n(5SD4ga z$#0l#k0;w#6zG^)`YqPLD;s-}7Z8>dnHt4B?-hmnKJl`;{Cp)E_1ZL9=|K9k$xxAz zb89m|?ZmnJ34Arb0$0|kta_$%KUKHAS#D#(oV8^swW090uT1sVVXD+_6hfbp;NOh3 zBxbe0<HdKLe4FYjVXuZ+^;#fG;t~}nnM1mBU$iwYXKRiSp3gEhg}t&FuCko$`W^mj z4vCS``Rggm%m{_v6XjoiRZOp;hqo`xdzRnO3QrVT>VCL%*E3j(wmNq1!au_!xmSVL zK9v5m(%j129^3^1+$O<KLy5u<CQP2V)3S6r)j`C6A6~?Y5rA-zlUmKkG$ZU)u579X zKE1D3A?ipwMyvjABD~@fZfaxVg3Mu5LLQx#MkrinoER0ca|A{l0=cM)^-eha)8fIj ziwa7kAC5>`oq5@l({f*dep&CW%LRkG+M!M&0HS%OF$=75|L&y3&#lSMO_h1Iwr^t9 z2OG_3+7>XI1{(Wf|DY4SQBPDHgb5*&?p&Q0M}`{l{3Pg2fJ4Eedw~CeHMdmP&W^uT zHm={Kux5Ov#gjcL)6P*5uLW&2iQ)@bW=fOUjLC4u9yTSg?RFC7N$Wz9WO(dGR3yom zRN;7NSGnG#gx(5?hD&sskpowlG^xv0nL)L3<ma7vD_P>Zl$}YGY<o^bBrN-)ZB^kQ zBUQA=D_^r;{ai?l<{92#naSq5)S2*_`uKjIzeS*RBL_ynGkEPDm!vUkP6sh$?=>5I zdJU`5nxC~g9B)2y8bt7dkpXf&u5alOUOdwN_hF!ejst>n9EV?v6#ehJ&`*4UmNc#3 z{Y9W>Jn73x+06;~2qwbDqpJ&g3y3z177{L+H>({=XmZ3z+6EQ8M~0j7is0AfQ#%Ml zM05}QJv9F_=5N!Pax2FYPYLcVU$tPm2*s1Mg!-cNwm1!d(D}?s!M?Zh&-I9p<>hG} z^?TX{Y;I<63wk~Gc3(r%Pjl&wsSI+&lE~|!9S8%(D4*D3XOTBpKqPz@NTx*|<y=`9 zZQ7|_jD%i=v0-Ri332W@aHTMSdoHnWnMjVv+EAYTzT#~SV;bJ^4!@=_=1;qt>olPC zUZk5NK$1D)p)kQ!@XxY*xlXe+WFlFZy2~Nrg6QkX$NkX}viYZ3lnEQ;1<@LKmlu&G z2&@xsQ^k6gak?0qj(4}7$rL<cG<CHvR9ftCPtq&eqvwlVokDyM9S@`=hIM8@*W<1c zh<Onu)M^czr<P(C+8>(~zeQ<*$^7Pkr7GyoXli;+m3@-a*hgu3ZJ6=vz*MYp8VgIb zBoEq(&oM1RQNC(_JA|S4U1wpyFh?Pf8WS%dx-Z;lJ4s1I>~%2fB=t;DlYX?==Z3oK z-Wj{O*7c6IE^H{Lq$!QkpLr-s@gKEZgjQK8ldA1K&yw$(P)K^B7<XMF)hA&WBqFl@ zfRAbuO~dV9=W^I00KAg)E@g9(kxNS0RD_29=-GWuk_8Bg%M-ncUfS5f&s2epPo}}_ zPk(zmAQ>h|(ZkU-x@CdqkcafGnmBu$YSIw}1T$1rsCyw;jnST7<sWM)Ge0C#5-<Y* zSJD_aiM2)9@tO#pHj2?x0<|lZA3QMz*|rG*8w;f#F&8|2%f-lQjCuUX%B*7Jo)A1| zkc}~L&({S-m225P2xnOP!{~pO=quRNPWPv*w{PD6D;T|k*~o(8GX3}Pd442JjxWfE z2GrYnX6b>FW`0p7=|YAP7cZbku9u>2hy*G-dtIYUpV-lL=}yX-8*8Wi1z#Jel93)W z_K<Nzu<drp7D?7_7C~krFz1UEV`1-=gzMNhIBKXzw8O;M7g7tRYyaE)fd2LeK;W>v zR?Y=DH@4mCk~xbB=gzMM_Q+cV372KN{z|H!T)eK*^ohM7>gEQyR2%fnFPhtbl<;oV z1#c~^5DATqC|UVd2ARHHmY;1$EOlQ_Ob<%otPYLJ<nkB35`YAdi;|WG*+D{-%{;mt z?nZ_4V$!{_6H{F<Yb=W5#drZIUSgX4dWte}a;c5aw&cL9Z6IY^|1Xa`=hHah`Nw3B zUSwi&xHnsj^^@z`n((#lKlWqhxScG#oZbMZd5-7BtE)|!IPkbf*30mQjlB7-ie0x_ zj-+a;Kc6ux>7;Tt70ej)JldNZ#wvhCk?WYs`f3eg)k!lfr@DWcNYEyY8orLLHYDF7 z+;U#!C2$;~Uf><wIutUmdH?#;P8Ph#r(mN-)DgSzGvMvaSthHElzT(m8ff$P&pTpn z!nJ3hd|#A})GRCq;QSp|+@tGG0B3?sUXMUVdV1RdICw(^vNavUNw}9Zz)+HB=Fi^r zFpI@Y_}^OsKwa5hqM6KPjo9<QVV*ugC{z^t%q)%~WRU*?6~z&Okjh(b<y8iA{d2Xm z2(6-pVTy<hBM-LzBq+P%IB@0~JGb7FWQ92n4U^tYoWt~&MPzY$26U(J8HO-AT%Zj? z?(M>yURSE)sjse{5p|KK#@LM3m7ROH;6ptN#Ow@0|1vbIri}G*Y^{k>>i`3bwkh0> zg9GXI=WLfob4m#hfrc^XQpSEpQ%<EBx#|;C&eo~5Z{Lf3;`8~2=D*R8zwa_Fn6D>y zal2(*Vj(v`uAs0MpU$ll{}dOM3G^n~i14OO1dTXCzSe5guh0v{q%bpN$Ns*h66lG| zV)e`o26#VxWOK2?=D#udjAYcRCtT`!^!e_IMV&8R^Gh_NiXyllH`E&c_?I*(taLMh z{3qAPKDY1DQsWUvmOao!zj`MQu5l+0T7SJ|7dN9Uj)v29N&Y!}reVBv5!R-08NY$I z_6%CS4OMe7_44*drPc_d^-#I9*j=@iKH(Z0>xVVW4Dj%`JjZ$eo`z$H?E`zrIL$oT zASU3g175hSv`nZBPch*X@+W$XB2==lb8i8vJ!0D-F6zsIdYzn4d}je8aBCG#qx?JN zUdP<G<BO2_3=rJLZO!$(m*0#)M)#cljHC1~KS!D#i?bjc>gZP1+&H(x#S~b<c@>co zwTdQCBzOZnvh+JYfbj&kS~0wqSU0)D=TL0LV_UFM(uZ_fV+=Q|TbBmWVM{Z)Ow;M` zH|iAaq(7nCDV?az0!xi$s<Yk|8&;3A_>?g)$XfN+GWecA<P{9+_gAnauU^A{c?Cn{ zZ}lV>7)$#1tG_NN9KpJ0SGl6F3c!2&!9qPTG}JF(@a>)=P1bY6L^VddtT@udddW6u zu&L)5IZe?yb5Ee<kgHm)=A)aJc%hxl!0rbLlJ!R${slilV2u9gvmhM?B7sd$#IFGa z-=#%~?g_^M>A?+q3-hXLYrI^=rmtqw8EjKYQA(Nq`d(gKVWX=vK6JFYc!NEWS?f(d z;zN?nEFbn*<K+ZNU1EEv*dB7npHIvS{DzUwJe4xdsI}NU?KsyeIy;l=Odo1^EyJ|f zKg7`rfx%Qq&)6vpCF0waABHSQ&m(A`JQ(n2lu3cpIHb|G3q%XP;Db?z{a#YsIV?uH zhzqZ{YEx>bDe*l;#jXK;De?_>pNxbx{e~eAO50>C19wi0Cp`c7665~1PsGg?I2q`p zUe{{lt%F||B0m&>N|aBZ#ZBFNFfzg-Qu_$d62igp^K+Esgjbb=xq=)tkrq6;4zdy| z?xGYcHc5e%vV!sQion%RoI8B?nrXLE&ySD4Gl|a<oGsD12ks^-q3-r9gc|y=AmN@y z`pHT(yLq-Q*)!0MDEU)VhiZBuO=caucElXCrh1vlzbDn-2xj^rtI$0^Q|O<!pjUt1 z!Ji7~`v{ndq84Mm4x&dppKk3Ojk+E<#?bRjDzJIKV=q5c&><%Yw2EVw=ajmrOONS` zP=kCJ{9+xo+L=6VLHUMaUJ_D=;Nf-}uk-W?vqn^B4KVK;g8v5(ZnHZfJ|^4|JsE-X z#$5cj$#n*x$K;uqO$nI5ypCxLv{SpspP$rf%2VL1^mCYf_<dVdHRzvJCDudVD6Tah z<0_@C?9&SF#GXzR^jDxT%v;26>UY(VjMKA8`}s_fl-R(zQnOJt3G&7({Hc}ueF#Ec znU%jw?cn=7<K#SE9_{`Ik!hWWNGGxiIy0EW9%j+N;_BX*&%50)?|71H1WQr7;kDO$ z@c~&SPK4=CLtZhDiAqLrjQA*J)p^YpG0<N>Sl|X4IMt}REXy}fKHxi$lx#EAsct{b z4lZt9XGv!%Gm&K$s4->=>Ee#8?lo9L{r4vN3|o53D?4b={I6Z~%AbZDimE4ZC$4?@ z8St`=R-xO-n$x(TQI=e>-g-SV*pI_h{I2&k?tBt8cB7~$t$%M&^lln67C7@9mcw`M zG9+q>UzKsMXd>R%L=Bl}-_5=kNn3b4LVx91aFGsqSi?bTCyjXy;>`9tK%Lh<h~Oy% zaw&$@2tAU$tESs6e`k95xfK@JU2E>yo#ka%4CR0*wzmCrQ>>paR#>h)NNGaYa}{O# z*h?i_7Yh}}5HXWUZO-~lGu&d17Egya*^^{`$dzyu80&wmz~;_Qn)}`6cpTg^aeff+ zoJ?&a*>s%J$Gc;CD&?=;)f)ZJ=BZ^6Wem?|=Ei-LjlATg{*K;*g!aV~kI_ABgSa9? zrw^Q|4$c)=tp0%_W_H3yS_C3YzG{*vC|T{7!wO1@;6&tSqfQH86W`XH_cRiP*dwZ^ zKYUD?wzD5URl=V*7hS@LmlUK=%Pvo#^@<%ZEehI7uLfY^(sWC*?2O%XnMTPU;s|4i zl}taFk1lTiXP!{0P>Z)u*tl^2J$ch|P)yD0nrS1j^IGDSp>&XoDr2=9MZreOyTC;5 z3o%B7n%%cY;}m;sYq|(zEOcfG+?7#SABqRJMSLbo(4=QHR6}PDtj;HH5=FpDiE>oX zd-?gK@yr&)QSzZhc8q7<-?Y{f;JCh9xuslM^jmbDGOkVRxb@;5^kt?#L1`z=%MKz- z$^ZJv-!_9tqH!pg_TKcdbk)xNo1dJWURq+No+SS?$yIDcI95dvR%;$O`Yv-c1>3$| zLs0ZU9CShBY%xE#p$lNdii`M8Q3<l3DZ-PqpQm#vC8~KGIOL-);$?G*Nt1{f9|63M ze#%>?xu7kp{v6+KzS{kIut)S=yqEICStP@WhZHJfDg!q11{{j(;*-(SkJ?wSP~9X& zg;W+JXJi?SZN!7=c`z8-rpN;2N{hv=$E~@W|3CKLIxNbs+Z$IzQbG}s5~LexY3T-O zhE^E51OaJ51nHikJEdE4K<Q@a&Y`<&hIjnF&+~qL&U23ET-Wc<-}#4YbI-o_zSp`} z?Dbh|-@Dmz$jQlQ_L=Lb8gK8HqIoX<95n;PuGIUHO@&obL#B_m$6VLyv8RndX((F| zY%0wceAa>e2`jK#N%N)IdYk&XX>}cTDu?+THkeaXe(CujfV!4-jbQ&bFI8-dq6JSi z2R4F6e!qGTrD>?_9s{=&hL`Fu^?I#ygW`FjSwv2Poo#IJed;+!6r*E>n$ia{z3a}v zoCQqdiUj5L1TI&}SK}V)GUvQf!WnsDqjE1i(dTzu9|+B1;AU4yv2?}v_!d5<b|s{i z8msM_GM>qyMF|Qa@u=H9%#tclGd6gm>GnK2knGF)Zcfew!axO5W4z`8A^&)w0l45u zhD{ySKI?Q(eAQy;ffX%xd!Dt5Ii!WZ<Z#{y4~@)F8(U=STH8M0BMz31nW^x>>|L{1 zlN+_K-*U|YJj5pLpxJ%nxF)qUg|H#K8!H7jm)#kWQVyW~ppDOzi+R~DgJLc0Bi`U! z+fq=*M>q7#mwIe^4Vz!ozqj&YeWRGLNo;Q4-VbU0<cqK0`SnS)!E7O?m2a(Cr`)+h z+3u_TPC|gcW&0GLe~>Q1hZ6ga0nEv#7{Detq?s_`{F5^#W<Qh$dMVdl?)=TaD$NiQ zFE4WI-eontsHw9SYNFDv>B0`=9hi=gNU9nf^^OsG|7OrPo2_<}+oxN2wRe`dgia=0 z;mM<pYvxSJzV9jh0z3_lB&!6g8^ity0%WE9=b~M|tv>KSeUi<Xfs8I${O!T+V`y^U zU)U&`ZVbagS>*WTtroN(tqW;U8@0q)R<BGKr`U;&be5%+q(W}NlQ}k%HsS%`u|ZLi zt%8fMY)JLY3nT2!(HmcA@fTUdW6s-Ltk;)u(U`jeDlsR&8VS*1z9loJXMqpxMU6;Q z1bRz4Rq|43Lr-5$F6_ok%H++DDMjou%yp;#^85|Srz&60HE5vcwh7uDyy~>~jsgge z#S?xMT)A1m4vEBgqxFBnxeL|Ua2wRvY(1CZo6&^+awRf$_0Pg*vZw<!m_bY!;3O?p zr&rWOm|a@7B39WxP6b*wo0yqg9Opf)rC%W_V}kTqk>E<1kkVYe$es@GXidf5VjXGj zG*()=E*TlKs&~rUK?`axqOf>MpI(<R1+!Z+vl&|w>|7*V=?GhkC^DL6-@a0lMe9^i z=(N;7Hr}bK&`1y0t6A<JM?I2|_r&EOWIU6}il&Ves*W<~3`zTd2**pnV4@Zvd{}dt zl@Xrmv>a|nC&40A=fw$d@_d`_PeU-z@I4Qm?qop5Hbj|)P&BkOH9QD-TVl?ktm9vn zQqSqVnrC)k6W$~@UxlMy$M;lZ8o|2$k#p7PyHZoS-OX}J__7(c)1%*4Cxj{)+mO*> z$2%^szu&muHa*f)y4-+A#FuVpKb6x-c+#<!kDAKnti}-s{Uq~IsNJ7t2^SmazOE^P z?epKUq#JpvdfeIe@pMn)sVby$e3G9t<9of@+iw^<F)^8g&n-jh>Z-VLLQ)8b2k(w4 zlL(7G!>}??B&$_e^sQBdXWJ+RJRpew$+JNonB36;4EcgZ>S?anSZyb-H~>#E@GX;N z7m|2zQbl&`%zvGGR=^RemiTk<Cv-x$te8i=W03*YKVo$B<e61Ki2o&n+fGb%)2?*t z`+g6XwBhgzQsqV-mRMg35aKaJTQ585QAd6wr*|dwqYEdy><@RYMPnuU*;^i!$36#- zN!W5eKDLUhTAf$Vzq!G7_%WnmzMpr!BezsGmdEFQ_C==9bM0-<A|fbH(?dk5FlWS3 zhKDqQ=BC0<&|BHg8oW=u4V+JkTZ1$(Igsz+CG_OklZcIMh7j9|>^yL5s%P4=-oo0R zj+3hJiA?q_eR0B2p;Ym#H&}bjr&<}B#Kmv{bJ=pAja~Z=B7fgE1Ls0?m89MKnZO|u zMl9SfwC^8%)vILu=!<3|$kiReume1kbg8_u5bUDk0?nWacx5PW`{q<qrSiufq(>WZ z6W@pq7bpqVZP;+w8@x4pc2^owR{HI-SIp%u@)T&Ad`jW9KsW(wNs75xoUq_b_^I-x znq1UdDJlK^wP4BP0Kqv7iI&Sw-okf@5yl@-cVwd22b$|o#X?CgegKg{g(txvAb<^o z{V!(Z>l0nfMXM~+b@G4l>=M5``w{Kxr`Iq{D%;>olU&wv4O0=Qi#0XZb<QZ-R^vyd zZAwlx{20E(lHe(>hGiRSuc;Nft_YLX@Hr^cs!pA}YmTBTWb3Q=y1WColT_a;{}d=! z>_)@dl8_4gi?5nmN7lBWnw0;TippB>9_hnQ@F8v8^vBcU4>sH2j$5ZX_9Bx!x3;XC zyO;F(>8BE5Q;Y&5@2>*aXA6dWJ{Y-@Lp3E&5Iozx9if%e{n1vbrWDwN6*45GJKAku zExcNMUeRSy(}>ZjF+O?epEq?yOw#TJT&K@1Iy0fl2_9n=HI!%vQRT)JRvAzZgzYqm zz5QZ2(>$Z1+*mW9*yy6)Rq4H4VLQ$!cEj5nd7|G<Y>yOxiwc=Q0sOpBg#(hP%smo~ zA41h5Zx!t64W3;delyelVigt=z}6Y0a+V{IX40^B{I0XP9D-jP_X&pb&$#iI5pSXM zi$6|X*I&sb{r&QDOQdHO8{W@!#=jJQ{Ceui`$+{o6K7+U-rPEL*lqY0#=|>JntJkW z&^gG%!Fdj{d+Wd#ONN^oAIrx1BP@rDly2oXSp+Ji&CJzP{h_zWP@hhy+A!iWE9wUt ze4eGba`h5uCmbg8u5pb#2qox}YkG)&ZN810G_wOk#hM%1vO#Et7!k`kn@qE$wRiSf z&sHP3^@hxS=-{h`#qk_?Y6<#IQ`u-w?<7&fdg<KZmyY<#KNghjEaRHdXLFCXR*>mi zrMdS$_6qDcO)q}xD8NAz-Hc_sv-Bi1FME7NUd+0ke^=ANy|Xe%qU1-(m3ZLFEmj)F ztrO_!`D2qc&omJPKei5%i5Ov|99c{`79Dkyp%>+E!u~?atEYOiF9UFBh`n2><RSDj z=@7^?WT1=A({E5O*ZF!LqxE>eUPo$_N|F@7xF<!VkmQ?L@uhFmAocrYX^Q)X6Mju+ zVcN)7v9b@mef_VCz|XC+Wo+GTq95yfy#*Im*;3A@$M!ua>pMJ4=GquiHC?1QZYCk2 zARUtve|$e|LCMY*q=V<G@N@NT3!M<diubY}4)PSb!sp5yupXE?v_v9bh8s^=JdvC% z?sNVRMmdB?9i^;buD!XgE2>%y*5h#P0n2vKyiq%mG6UaIJ^{Cn>+a<{hQ)RDyCGkJ z7s`!IAME67iO#`~Yo*|CHs5^L4rUEGP)C<=|J&drT|A~={Ap^Qf<foYe*h7GtqSn* zk*ANmZo7|4Rj!1Bp-+8JXAQ-ZgJIgi9BA*VjQ}iF*w1?a?lwJ?A3wdXIXLR2vcA6G zD|S#cqE!SmWTxYlS&M2+jc@cgSRNAuoJ7?hv0X<EZOrTO`aJMRbDJ4AR&J}Ew~QdD z{g|tT9o^Tno7%Xr^(_c!SdxdL_bFDN!A(bdvUsAxS}-f9dhj@K?E~#vezW_>5+|sp zz~YwbMsG^Q{8{3t`JRVzNws6BbiY~6gd*Fwg&!bD_LB?vl^Ve%lkZTn<lw`}#S1OV ziVgz3uQJ9Yqnc8gtZPEsIs*OMQ%=`SLPMYv{gM;<nr93i9eo#*TU``;T_U`NLy<zh z1I}rX*!by`1^p_OQ6IK<G4W*<y8izUvH8WQ=Ts;x$3g=S+S5z_U*wN;vnB#a<i;3R zWLx4M3J96VQk0AYn9#ibwya4b_<`5uBNNbimRCekzwllr<BXIQX|{E1>oX!%6M8vM zI;fAi(o7nAd~rXj+B+WqzUSdol_JfTXpES@`R~7)q13HzNz!k#@c%{W<$fuBlzpZK zQt6-kQhG9MTU0r%ly%@~F8$Ws9GOyHjedih18&yqHDtJL;sy>Q+E?u3toN{V)(T4z z_Yy+6(g){k!P+EXVIR`BKm)2o)X%JPq6=9*LtUtqa!0+7zU9qdx!S2=|8C@eu_Ffa zFqJ+L$L)7fI?NzImgI<E;KM(+;sxFN0s2~|`->NAJZ?6cdPe&k&%^V6%J-!x`I>U% z=N^21QD|&a_P*&DW6kW8pAC8^f7Go(_My{D)bIl*{9XE^y>A>1otVFq{A;$jpnHo} zy+0qb{3X8s2>%OEk?U6$@l?JSZ&H6nCbzvPWcSsj^Xv5qpri9N{GkD?%lAh01#@p& z`3hME1PO>%EFV7Z?rE>*&)G-~4&cnsJ&~%joz(<8ruY3m@Gsb|+yKQZAHXiY{aY;b zI>YG~WJm6)7x=p7m&H9|{Kb62wDtAMnAD!$-R7pXgAFO|+?@SFN=3tOd04W2Q6Oci z^w`}=L5s>NLF40?zR(;*jfziGri!&T+pHk+P^o`??<UWY^CqI>*8Tp&;iq3rzVC)V zk7V-KUret0#pG9C{zY2<aR=cqxxw<w2mEdb;{1>m0KiXQF)?1Z(jk|AT#x^EfdAj~ z;PCF=y?b|e@55;&|M@w>-FZAqgUQ58_(qU;r<j?6jAeyfFkeS(oRWHZ5_t1W(eSfY zGc7c-2@0L*)KV%Aks8r2I@c>b>}9X1=?o4tXzX@+6KB%c>H1TFjioCizHR4_o7s%e zGW(4VP~%G=C(aWa;o_c8?u#1;v5Udf5l97$c9Cg(uHJdSe#2+5UWa~T#2L|bm(Q^b z!@lkEy$x!H?>YF+E_R`zU{HO!_pg6iKNBxOMuk5*4}Sgom)8}jmls|Yw1w#RQ4#2V zY|G-U5BPT57*O$F-@E@We@yC8FAsS7=!V=M|NWD0!@avS<AxW!RG&W4yf#rZqdoi- z{^{`Xzux+5BwhOZ2%!P4HfO!xMh&5Ag=~a=k|V^RGQq~5dP0IBY(hijCG{VsM*a(u z|8%EPrF57=^!Lzy)EI{cSJYJM4^c3tP*7{7&`|KEFfb^8d%k}>sUPqOl5|!A;e6@8 zht9x2x%F(p_^Ro552f~=A6v8^l5~_GvcEmwKbT;W_!sG@Lsq{H&FGILodbnh3rRZL zFVd<0Ka#%ifUhz+^55Uv-!JPQE$pY4=XH?gRvN|#<duMj7`B+67=CPz@kOcs<2(Pi zdqba6l>?(4$pi19v><5~eMt5{nDDPIc(KU-cp47FME}m9znS`b%lK0(QMy0Q|FFAX zko>1sP*5SiCHB9{?Z46R&nN!G@!BL*we3HX_5bXi)}OSmP5OS0kyStZTZaDFY9*#B z@5ncK@W)PnQ@r%{2~|1l?KaMg|9>|Be{yXJDfBBE<wybiCry8B9lpfGpE`bdhGr-J z_pE<x9U_I}h-vC?h5d8uV*)CMt$TvU=h}a>9{<IIT_W}F@~Q3rw7akpvcIrWv$+1h z*_Z!<4zK$t`d(Ok|I_Zz>5=`P=PhKg{f{_`)R&gmM-TKXNfOg;-_YBu^rqhlvZOB( z0_wj>P598z6>2J^d1Of_+>WA?P0w1%FAi=;JSqGr)mMzsa`VmMZB+^l70W24H=~9i z2q+y)+maT?O!2d+MG(b!`{tljv`j3yLde<0J(pJ7+vVEjh0Znb*@HyYeBgST(OC#r zp;yj_7vQ@$paFB}@$vx!(Ar5|bi`N4%jd!wUe{^uewuuJ5aysIzda(==6dt|q2d<^ zD?sA~q0OoB%T8|scD2n|#O(UWrSIKS!H|PLb4e<MbczeUATaH1@`eXBqqRs6w|Sn9 zj1pV5SlQ4v8Z@fmVIXl``ba(mQ+pAgEPbWTzF$SoV)Z!*|B&7SGtGf*^x-Bib~zkK zpxbi8!IC%~rn~G@nWgz;BETcscsd!Ja}M)qoLEOflc%&aLJ=RYI$s;u5LI!ofLn}N z;OScx#-|oj^HwDLo`x!6N`v>KV<J`!)$2sr@kb65vO&X>JA!7X1A>oNTQI%Fx`NJ; zIhf^&mBlXS6j0f3ruW~3*pH*>^$3c7UZ7wu%#0DWwNpNh!R)+h?hQDiDqH=+@?{%$ zN!LMnq-sxVyr}$>sTDkSTdxrG22RdlM$bXn&V6EU^-Di29|4tG+l$3{c`Nr)<zh$3 z4PjUm{G+b5vEW-b%^fnDN*E@J{))_AWw_t>PF8DU?Lc1x76wEHy4XB>HpKSpKuT@F zH_9dPY1J~t+4IkXBAi1fc}83DEhSpfP(Xe0a}iLNgwf6na80>}dq4RL`JhNGK3ne} zt+wB5H5C2IbOX=~vFELxMz|rg#xy&&a&g8}72J3^50Sq>5OfA;#u|K|U|m>L_dR03 zh4*n>qwz^Iq{@CFAwj4$r(9NP@zBW*LFmVA6lt>+ZQ?;__W>sbU#X29{eX>kl^RgM z?26f=2GuqU)Y^UrNA}rg3C1VuY6=eo&TXi=aM(Q3JE6j)71h*9;ziQjmeYPl*u_jW zMXJ}N8l7sWwa=c}{*eZ}=3hkQ1<mlxhE%b>&O$^z+M9poyIi#@$T_~Hs+4GT1-T>$ zIszMnHBUX2e4pv^j38Zg=a>Led?R80N_SIBLsZ9PdS47h-$}?c@tk$`nQq>W_oa%B za3oE5(eyMO&Z4}6#466{-Bsr8wOM4Cz9PG{k>Q4H?)qa6M$VR&hE9}3+e$zWV!jHB z$U@xEvzzt>3R(>>b$ONT?iC9+RvGeL+jZ;2!2fJE)cmqgYn2{VZ^p0<E~+KBF^|Lo z(ivRb!F+D+;Jj5DXww4VnwsbRt8a>rw{G98PgE=ATdWPv7snMd$A&m)q5(`+nCs5x z$9G?*EA{oK3dIb7<a#E1*A6I4qNJ2S;kNWNfSm+FI`sx-Hwoq<7vKTlq12EuGaXBc z-Q7lWvH9UJ=`r~MICQq#oEE-SoijS4f|FQ212~eC-aRAiqGzc}&!dC$4>{KqBlHU6 z=vRie3_az8jq0SG-L&(>5TQADiuy%D+INOuG{4!D>RrC$_6YZdiuP~kWXuQ2?@8`q zLlCcY>Oyw+s+I06^vqdJMJ%K{R@JZMGIQ0lCJXjhM|bq~UvSP-+7}%4kP=s}L_9i} zrH7xZ6XG~6D-^|T=`y}&Iqp<>$zB<Q_}KfrjE+!C{VZWbg@VD=_-=qS7WC7)us|~? zK&|r?geWEqu}G;SsGUbI7FTT^TCv;bw43VeX=>#HNYoV7uFtT+P4&^9cgTfBoY%lw zoNBoFR`)YgYV{_sd*Z}OH^zx}jD}Bg?I=ZHliCW?-vZ(Qa3aH){>F{!wuLF4uHZe5 zqYFWmC+l=D`=D#79lhKQ%}Fc~cEP+*=Q}Hc^&8vDGPT(__#0Q7KrA6MN5dk6VVG&} zsSrhgb{*>`;arf%_amhgolc@Yh4jKLk{!|7h_a}zk|V-BvLfk)DJ^M^DmBM__b~61 zZ>(jJceLDsxMy+zL$w$3JBb9|xcd1n>EjCtx??B3jVj(o)2l}56!F(ewf0xT&${b0 z)7)+)QkoVi&MUB+98Md!Cz=IIF20=!LB08OA+qa0Grh*y^=31Yr|`s`NIa2Dw>{3i zulrnGR)>b_xTy!Bm`{7Urz(hZJ!vb$=GG;h_C67RNG3zpc(}+^HE5!Z6HoQpsn(>_ zduTG7cAEQHUt;}nF=LX3B8_KTIPELbV11&B3lvL@awabA-JK_qx3!F4A5fV#St-}^ zSiJOWnyiuy+yk2Y(21Gxk&CFa?N9Uq+3K;U?}O4_FgPn+GDe$uH-4z$mCNNPNlpdT z&QJ{IRM6%g^nS`|I@tZp?X-V$#<hun)sY0Oj*EyunS>(3XDK(ZHjg4k3gt*3m)Kjv zB1F4fwNF&}dzRDr<$JGBoG)rLlTUAcIysirKZ?_-I!T+Gdr`Jm78}6Nl+TxHZE6VE zjyJMmZ)Wz4FvO)a^Hu1{tm*=;W{c}LOC&~?DPFXEuJ9EwK2ZoNe!lbm+D#H1_Ph}D zVq-Vw5n}gK%8jJiJLoqr!*Fu=m1tqa?fA{Etf|w|xP6^ivo`91OQT0_a|N?k+R~26 z&VF3A@Z^dGAy$iHEop>7)cF|+L}_O>8%i~qyO(Q!m(Y$(|9On)ol~>K(!iaTrpnt5 zf{heYjTAlC^ujQ847t|&?;7<QjB&SdXEfNnX#}IMw-R<E;6^!Htt58{tO%C!+<gY0 z3HqO|FIDXYcAg7X7l||9?&H?Em{<hgesELWt>L4XsP$sFHt6ncAI6+^=CZdH*r>ZM zk-Qo31UeYS%z$t9B7+A8pyk^Qk0RRHRAORE`Hf<e7_!<VRnn`i(%T_1P@ml>9^qBC z7;`jU;RK6V_we_2O52yD<y|^+b<5s~$)?cxaSBh$yjr&&)wIND(0qi&FJDNv!pkej zC??{>UaM+zI$iEybD5UZFh$LlpNg<tSbQ=1K!l4ZR^+G8pbNjEwet7o^L)=LuJef< zsP}?<ZJ;7;?pgPX>B<+IluSQPthc`zZ7g5z*a{9a>^P*4zPA>845Xqj2fkHNY<4*9 zIqv!1<Wr#0`OZf+gf{2x-CL^?Ws;%BV)hd49o7;eu;2E55$A!U7qAkp<3Xa}h0J9{ zttb$v1XkN_d5p*dJTOh3Yn?jepUAIHnW|RKa&wQW>DYX5u{6f=09wbJsIS$ZHrEP@ zLy%>096NkXcrg9tzgY18-<57T<1a^$p!gV2VmVdThM!!NGlm_PAUo>66kd<LaSJ?~ zx7u>I4_Zrqez83kytVi|p4pAd<yJTQLxb;lDz`i+F$#1o;!`f+WKpI<k4~^VVKxh+ zoK%RUK#hu7h!!nOat>st0bfiis+#!^+87?Djk)4p?iqwAUw2|o*NO=?6Q}ena@{2v zeioYH`A#D$)h+g8z5wJmlI<Euagf|E`&0dH8}q;vap45FR&ESynqE@1Hy3MW*RP`t zOO?Z8R*;*#3Pn^tNlf-=0dI&JTZ2^$_y#%OySu4>)}Fcb!5iGNrK`0W?u~eYb89uy znjXNjH$%P3a3cvzZ3X3oQ7kae>zGRFNsQN~K|lF3G`D3F3=5X3tYNZaQoM@9+aoO= z#>dqDD#FUmlzL|8`ch-}VqtJN=kmu4DGq{EtngxScutfTon3CyoFS?$`AzL{MZb5B z+)2d?D-Zha1uot(CN|ek{%+z&2YIvV`(l9hDyz~~5S1fy%ihAm^u>_;>Vo*eYRbWK zE2!8&Y?>ZDXvH6S=x1^62KzSD*{FC_qL^pyjYrU_0P%-NQEgtTw~c7D?WjLdEeH#R zyu<}tR?+HMkKB3R*D9Yk@j~)b1Fxk~^odrht8eI?Pbx(ZJd`4)_SRhCspBi~K`tNT z68#nndrL3NrG*0X7f27cE3GTU>sYA&fK4(p1E$P%s!}EDcLIUxc$&>FA40JF7f%9% z^rZ(OEXO)*3(ky;5}lw{f3`mb#2J?;(wMf<v!tlU68NYqyxcYQ;?{h^EUJLMq5cYT zCCeXu-!htHaN$jWZxiubG34A%aEUs^LkRzsE(39?tK1igSFtyfa|7rex%<=kJmvJr z=)?e&zJGv6-{vA88O@&xc{1eXsIu)QL;%4|MI}FGxX)V_a+K;V0vouVgem*n3$(l^ zm5la!iVaKo+!OglM|<;+6)kpCvn*m$r*WzGY2ZiSAGuOIsw8`ss6=Gvtjd7Ok51q} zF4UM)(=ua-Who=t#ARs~Q8=3WR4^s?X{Cn!l8hq`Zy9;a`V2FZz6LcnKQCEmG)1n; z13baG)(62VTn?6?mRdo15Lm(0RgWF-R`Ytm1TWQ$V!V~e!ik$r<XY!^LDTG=b7RxQ zu}I<AE>dGDd&|v_1UAsUHjiIV&g4=*HCZ!XzgoW7rAw`J8|6Z9z-89aQ@zHhQhNQl z3kA(ZlVWy5hG2#qHgDWNpSp^1u-x55#NE!Xda!MgQz|mo)XS&&YIk{5>h<RNyby{& z)u_mWhn=65RhMzx#9pi$-)yLSr{59EvDt9j^HGHO%De7HqOw?m(iaBVj>q&2SGKB{ zC}fjdItJFF##m7woODazlbUMNC;DDzPHfD1QX=*Zr?UY<O*&oEYK2u*r)#ym74=%U z2e)aYbkz_B7*wq8p|?4zDv)<nY46;=t~Y>(a?@!aut#Q-a+@3xOR(^2x)|V%`wHOQ zj|r2iN2@Ey1kNJ-lXjfmai{w*LJ$_*v$1HZVU~vhg#0<H4ayH<Zu7fKvyXocsLCg@ z*K?gr2f6y*toD7+m*mq9J-Dc1iUsvB8RD{>lvYzXeuie5mM_H^%ye3Q0`bZSl2)sp ziH_L<2s{ob!_30D9_T|4tlqTVzf&1wWh#@OzgA$X2S?*MJPPXkOk(y<4<L?SMd~r^ zwN%byE4M9Dsz|DgXl!b!>pJ*sIT5kb#n;pJ7#m;=6U1%wE$H)zm)BPAyzA&)SvfP3 zz%?X~3Ad@4dy=M;7|CvhpB7uuDVQ7IVZJE#eMqhu%nos(x@`(Utz{jwI=To?OzpHT zD;~8N6@$M{gTjJ}Gct~%9U+|yMSYk3;pVm^<6&$MDZ3_kNlDy`BPVQ(0HM@vh3D@P zCol8xPTj_fh5!-gOh3dvkTgJhnG1b>VCHhBOR9)dY<L>iaR2C_V82kvwRU!iB4jfV zO8;|My^hbQViKB0ds4w3{EoHjiQB?jprE_YiTTxjAhUb`2+j$<DUTSV3RT0Y#2EOP z=nH#}iee@<f_Y5*8S}WbDyfI2foHJfz18&0mc{rXgQFxt);00cq(9_dy6`NuokQX@ z)(?PYKjz3A6WO^h`Zv_#^vX%{S<~ILZz+kA!f-*dTnwSa?`Y~e%|^8+Ww==kM*Fdr z!2<Qf2{H^Js~~W%H7HJxUooUUK=RtU4iVo(Hk|1jEtcgQeE_3=KUlIc2Bf<!=Ix{{ zx*|RwQNkarSPtVKJbptb6BrwpQa`~k^3b7_a-!$BNE-)pAb@+#;>Y{#{)^G_U~?jj zaI&3`1E?R4qBN~cg5e=%&k9Ci^@3S_&hv_WOMSCzDP*6Xn8k7q7RA$%;`I!dIzp5m zRd=VI>`#q-DtdwQ9Sg`loDr>TKP=ajJ*sq)FVHzNWE2}HJK*5*7BAbF?89#DtSSGT zHYduP+ic$9LXE1ssnFhMiPZg{?s32TA*ONwR>A2Fc}|@ArgXYUF@0Rt(@UEjUZ8fJ zU2AUA*MM7pZl3BZXz}w=F;*IS-hjkDgia*67%g!qZ1Y)IweU6P*t(0L%tBb$V-YHN znz{2aip6Qwox#}2c|kM5#FN2@wN!>Ux*m*c>{K0Ww@r0Jm&h;A*WNvpsI{WXA<lv# z0@*jt0s@;8+EhrpotLxFN~J4(5=q={P1?KRukJRqKHjdI!zxR)xhu(MzqRoh`B2fA z_GP91*f1RS=KeOM!(qa%3Q@5}OXA~ypp1X-U5YbFdj0ftb&f-0CS_4?j{1X=b+7pb z_Hg~5fTmr#<$hSf3UhE6c9Gm+WAEWtAwKi;L?)(d@(`xy(}cI8kzQ^835NX}yyoYQ z@szE+LllhQy;}?Sjdd$)VgWlOh`*?3vl4Wa0kdGy=L}$uOa<GQP<MZPqQsumNA)oF zWBmqp#5m;q9Besk%MoPbQva-|Df<3vE<sKs2h}i!iCig!u$6_El^|bM8{?qVTmV|j zZp8!RANM)xEnLq7=zoOS;*T5?5F^h%zTmDDJffJcs~g1C)h$*&p9nCx*0H&M#S(lr zq&UyL52ZlJ58V6I%0oW20+czzbK(nwWZ@|jk&3e*gL*j3UqY75k9bA3QU(Pqb3;p* zh*!7s5`iVA=BpWaE=u=vMu(w^DzKA%z`k;1(0(O#wD%sD3kwZhE@6xp&r_5Y!eDoP zdQmuELkBfM-Uywmgtwg;Mo1bh@+)|S-i2M$d+6xTHU<d3a*IIOgdzlxi)BYuGpDId zvc5@!ZKfHtgOjliJ}ZH}KvG=*Rk5wSxpvfUu@YQ>4GD%ZPiQstg?*XbwirHSu2~G{ z3N*cj_Z{z}tCY81-__7zU>!&Bex?jtm8gA!n*K59>R|oZi7m}^z%Jb=-&TxO=c{D6 znF2J4HJ3-NFm`{CIJEf=bZ!e};p|F$yJT#-fOBH>BsgMdseDPmV($b+Uuji>#Ml2` z(bBY)9v$f!Vor-9WpGM?>^`Z{>)@^NZ*A=QJX3TR@zKs65WJa-#v5C%RI~d-EF$dP zOBz(kv5BdD-BXnx8CKIU;0v5(6O5}D%@wMl>w7xQZXOLjY}|V5)2TN(Z=28hxg&VD zu|XoEt(`#M^`uD$+b+~vo~>iM0mQML48WP2hdqTu0#bCFi#qW6*a5xk+j<x2)D?8D zZ}DLb3B>qws_lzEW+?hKGQRt<t;<(6?6$MvFkY?(9k(6$Fx>gL2<zf@vss{(ClF+{ z9b=k*G1n$`h>?4saay+3I1kAiB9nWoWr`}55DTw5z*AT?vPg_4HB`^<(^Kzaob~W} zom19<>2w5UNs4bf;O`YMMC&MKnVUIe;1>GP#MSgHh-0v`pmn}~A#GfA1d?!PqnCH* ztll|@cLT6Jb(jV&DWubuC<(3yWK__q7szCXi7i{0zx>)qyP|`CUInIxKB8yfb0Dx- zj*sKnD~>SET7d)t9lHn8me9g;f_NBLbHI0P0`e<c)`d3^YcqIV%<*@^uaEg<_v;w! zY3!+|*enbhKZ+B`5Sp)(_$rYsq9>c1_<=dQgdNIlwH=i{s`K*QYqdpwrOR$2s?pAT z=?KE6DsN~PF5GAYHoi9Jddj*M$2r5yn*=Omi2?R71LK&6L1FPd;$7?2ynJ_;X(?ot z&NZ*{IU~3k;;<i9ZYl4g=L1X|Rl8iRwPdPpEb-$YDe)TK3f%H`b2*B6TfFp?CEX-$ zp^bMSge}&5P@v!FHj0=e$!DJ7Rcrfof&)wLr6Fuv&UCGbW4-a^F~DG^hnS(5$flTB zlc{o%IgY4hFR@qDNbcPBeD2)oOz~1tuxYrxd0fDltwU6Ayb;Uii<lUFsPA=U<IlZG z!cM3a_D7>c5|`qB8A$<>lBSdGXXg*j{WsQDQWe%JDK#rT-O!(g@qkxPW&oQa>!Odw zFJ1~epHz#P7ykS)q*eEvyLD(Dc2~-kuIR2pHs4$w#)j#QhO@=ZsK=82C-C?_>N<_% z9g2RI1q2+wg@;f!TAW?w5Pz%uDt!d<q;6gLGv<gjPWh{CR9&fUjNXs2q2`^011Vfw zR9ew%gg%7pW{~>gpsUGCK_-tqxp36JM_b4Dvq`6%WWaQlARng5M~@FSousQ)p;J>< z=-Zk*T->tRef^gVIDC0wOQB7^R+LZi>>f@w<CE2e*y?q%BNW)1U8d6maJBY*50zYk z-V(A#uM&UY>*p$aB)2$`^EL7DPo4;JQnFo>=gAtPL%41dO_~f$UFgX2(kn;DP<Kry z$=K?B>)wG!?})JMx|C2o7s)2~fysw0l?(a2WF5F}^-(_(ABH(!`bl@T2nU)w1`)q8 zNn6~7P|>IqNbLrldTxBMN@|-r*iGH}mRnR}Xg%SX=(}!jV{6=K(Y=rqrw9?G`%H6n zGa%s5IMt?l-PYvF{c^Ab`mwKjDbM4*#6(zyx0~MJ-t3Fd(Mv?DuL~Cz==OxHbAI3i z>dnD*0xXaV0wQQ+=1sZ5=j?^)Cjea5?|P%7WQyxm%#47KeL{TYP`WVo?MlamV}p^O zydNDk;Lk0}L<V<uO(HFa)lSO~H<0oA7vZvg8xC?>Ai@W$6S|Tb)(R57__*tBDoS(m zoR|npl;q+YF)eU{_$h0Xi*b6ryGqH0cod+EDb{j#-1fDWJFcT!mzf7<XVCI8k*d8I zZ5e!t>FRcWqvEWTl`S@a?1fbXMZTjtZnL*s8niWDSXOa*MoMMaU^jRw_>TZV6ixYB zD`+==5_Z<IQ>o7IVZz=Tly~qkc0pjn$#v7%*sY~pHpT1FdqrJTf}jyne|e3vFqP*! z#!$D#as_Mr-gv)T-^X?;PlD(l4hWu>ZIrplPw0a>1~8~8A1T1?Z9;@I+qfl<FAr4Z z;65yMUu%6W<@g3oUC5jh!#mKC=N#G@I$XxvWH0Wt123G}R#^2`K^&?I%m5~>q|~hA zo*XY9VC3nPA}5IpnRc7;_n;vQG}TLBe=rn9@lbb~=eD1uBDNS)zLX_2<>kd{|6UjD zavHbr!yT5Wr>7ph4?p{XVPmP{+m45dn`SreskXlD;kw-=&?!?TFAuxZmeikJ{r+k% zZKN4(K5ZB;HSJ#w$ZK(AwAv)W?W-Nc??0Ysb8``>!0QCw1|odTSoxkYV=yK*mQ)a& zdL#{VDY<5!+3V#`yD(Eu9$n?+v}n=m81Fq5;tyJOF!BsXi+6$HFpt7M`e^R3tHGul z7@&3i46*0D5paj*L9uqWWFj-c;O092Z@VRPT<gxj=%Kuh^K5s@PP3<6$@b>kN1f`H z0A_C^+Q|gjcH70Ym|lt*;<I>}Pg!!40K<^o5#fs@qh!ir6R}7L12~+nqqySbB!P(x zn8w<tQFZ%yB4}`i=*BJNjx~gDwEVO;VKQxMfkBe3Vb>r{2fzJESZ;@q7AlE;SOtZs zOMf%)+-B2F_p<v^)p;x*(g(UrBwKVE>E{wj8tC&Ox|BY3JJTA#ulcbUUG;dI@?utd zfV#S4klO6y_r-_e90FP}WWGRh5G=^fBgda;@qI(H757gl!acu-n5+Wj(xMcx%Cn8B zvFrM1)MGh^0WthX=|Y_3g53yw9rIhW&=0r*1fy4=mz8*YVD8}_DVr^9j{4C09I44! z;<b|nJ7_iu#VuroKf+GbM?B`BW=p_DAVq*ae1JtR^1Qp2W^l{^|CtHMv6h>^3$~cg zUFjq(@r_?gzEEYZ!_e)t`#V==F!DsKEjX~sob{-5rtro7_o<BdO-xhzkP=KeXMq<M zSKv**Ye3Z+5=>o3RlX!>?1XY6S`th*8Wp)wfuf3i?cs~v94ffzeI|DMF(VInPcHl1 zO;coM3EcK%8ln6u-F!la@;M%5=BFc=cbAjJDWh~HXeD$dw=gHHl*y9z6wNdL#}a2` zd-{$hiUrg-uj^Amg^Q7Wg%23QloS`Z7@g~QMaw%L369(pw@BhPA2)Za%j(I1Z7R4w zK0~b6Ft}Ki`+>XwWFJ_4jKQ^7(=zOXH<ld9d~~Z20Xl|2|4)n#^|4c)?LrgYkt|hf z7Nc1=oF$66cFrJ$zDB9I(L*W|$#ycuM7%*OWOZA8{@I?|^zqcK#m)nC96^Cn#m6Oh zVh&!l$jaZd?F?sQ>pQ)n)vYQ!=s5@mX{EaVvj<!6XlT{0J)V=xLB4InpOXmQuRuy( zW0^0#z`w5U@C4P!9lQxyOpZS)A|MqlXnVI<4EiQpBKlQm<L7z*Ss9gu>55tQ?hz=% z8KT?_%}@Msj7np*SZk?W<JhgI;Nd&VpyiqYT3(*qFn``B;JJ@`BCzH~hAIpLndAMj zGND!dA?W#37C|7wcwr~U_#jG!oUq^Iol+ivM3vpTGqxraZ{a0_IzhOsi@X1}Zmj&k z52))*VztV4z|<#!7kPc}sy8d2P0;FoYY{gyn@VfH@V761M6=Oi?0`;1%g-+dI|u?Q zG4yLR4$2vuwq$&9<dz_K+bQLpqj?Cvy_TNruxW_vdS}<)GZjES-p@5I0DpJ>g_Dz* zACug^U@%st!%QASm57gmEPCC-iJ^8>hqrs9oM4Rr)hL04y%?wzxN8%cHZdr1vZ4x< zfLz-5y|-GVg`QZ~-O7tO%(=@Y@vWIZ>a{-9Dk1iQsbp=`GJDXk>Se(RJ@?v<GF#3; zWmqleb^df^AHeC$d9CjAGy~VoCa4f~o1d1(OJvNCuQJZNT>Emx%yVr`tH?bn1o;mc zcnbH~?^jvx*LJED*xcM&$cUy-Eishrt-dYv-U^sS+ycn{k?>7%Dz)ojFom8+f~6)j z6-I|HdO8#OMb@WI{b~Iz!rn(pp|19#-te@Va1P}?yvUwp%r^d@({l5Mr`YVxgQCId zHZgG%#qLr>l)-G{NYSfPQIRY~`_#m!_N0T}BjeiH#MpkDT7T(MD}2CQU%&O*L;R$h zWAwYN8VdW^w#6a2j;gX=8&8{@F~{R;){T_+z)I~rFopg3OT*s%x`sGI1J|V4hSNFh zL8!Cq@BraJe<mP{=)mk$^>liLU$`{vN~!Kz@pD94H;y1yjZM}0;{Bq#l^txZG?7O` z26rpY{QXq4tFsNw-cX}-ERnLxbd~P5JtOV!8Rh(gDI!Sll=ff>^V?zFkD(VfZU~Fd zzWD!5y;3NVu7^ozO>tO7K!9B8DZExv{XIdzOuyBDLFLZ@gLkTE^;<W{1>G%yR0Xgf zayxmQ9El@8%Ds#c(Ld0qepe~fQv!4XcXy|*RnAQCLm8O(QQocChVHtv++HjiZnzYN zC-fXmEqpJEEf{i-McR`f4mnS=>AYf<CI|0|*#UMWs^VK>So|`4Y9}Ivwk}KnGij_9 z<d@P)#H|s&PBfBB5h183)UJ#oJBakS2?YKlf;Tb|*MZuE6HqO?S-f7&dY^LovGCye z{+ouiQ6rlk25*shW@4WTX=Z9g<%HP9b9ZBWt5FyzB`Q}?fcu*wf%Jw)c$m<{Rllvs zV9$yVsp${PY(pm%$^oKE`KmA9$Mamz6&6FI`>9C`>A#8U(lhI7=ObnHx?g^L1+_Nd zV0rH5r(lIS_$t~QJOVS`^^|0|&<Mq`<pgU6<Jk7}p2gZZ4G*-_s=9S=a_sE(*qqFi zfN1L|$BWsbP51`LdA^VL>1LI<JQ%Lz=aAp)gHODT;gFPF_a4x$ob1tF3E!FX>?{0n zOQLUHI7C0nB#1T;+hsdsJ&_^9ZxiL>AbTLW6V;QcVkNZ2ie=%A+o}F)iEclUIWr?_ zDUsrpF0b{QfoN<fISyZA?ley=8gg}#JAEo@HwN71AqKUqe5RFD)ODwKUWn8)OygQj z!fYRG0j4^A7A1>7O>8PQJg>C6*@3m=Y{ZV2-sdl;BYno>n_qu$bou%z-0<bE%wxTG z9^gB>!Pw&COp6@CoLa30S@I65*Nli1yz9i|)bV~f%AAgtL>(=KGw%4zjHjvs``+(f z`=Y1g-Ql|S(&fIj2-gj^Lfj$}*d>W|I<Y%Xkf8mX;R1X=p7Hd#H}01%=}ej{+&|}D zIZ>oBY)3{H8rYL-pFc{4n0p2ZLynjL-W*8eA~)u0HZBY&HD;M?Fd$iL%0PiC0iTxv zS5j*o=MY0#W&6c10N!0g0esZcyXLu(b91WuMlB5%)31c%`c~|7pmRa}Za_1GtAyw) z<vDFjb#?5iy}6VaE*$*J(V9iMeD=iEX8+eg9cZ;*0}Q|A?tHAuVOH3K0Xy$%jIU*X z5PWj+^vpdIFhpz`8SoL60rx%Ag5O0uz6lC^E_Z^Umj{95)?+WKIp&nuw0X51`;uHq z#({Dvx^dkVuyJTbqx`p)%w-XPp|%`2Wa|hVa>T_N@R_S!WWA89#8a!VUrDt)qasY@ zvh2J>X3dj?AbkO~L5Js{#`EEaUZJPD86-k{Jc^SM;p!E6Qqb7R+&f1|g;JpTbCNx$ z2Y-3`g%nL3|HuB$$+4H_OHpdn7Tndg@#gB*GmWa&>cFH8anE%~9&El2x3`>q2ngxb z2d<^EHN;KM*@dTPM4q0EDnlDL+zW?UpCv+6dL2~U`hY^8I&I9=1tTb98qNr#!`KEd zf^n299c06Wjf|+>@)%%q(e^^wF()OQnI!;|nGcw(3>dxJ1S0!EWF4f;bb?Hxa73fi z@OSj)Fy+1rTdpowiEUTDp6ePq_2aWU4L(s4+=Y`I|BJ5`3qd95dO*|d0~e-pNcWj< zPxIYC#ZwB%__eUZw?gPqk=rFD!`c`ktyK*iK<Wezz$*3!O?4p_J&JL2AxaVQ7t7-O zAEo;?n}KLaU(x~luMCWtip~It{EIUZch-+Gd{+3TRfO%YB5yby5;qS@U0k5!=MUty zN++gL@nDnQ=rpFBw>MVrRYIE`#`?Z%>wj;OY4G_5Xzx|Xl}e9>Y;DE8y<12ea;D=_ z*+1cS+kO{Xo#N_ya5)rhQv7s5!Nzf(kN<nAW6x&YUcOAuvOKpccm&=4Ei$gQ_LBJx zef&2ac>dfEX@xe=`h6VbN!=Q!@z>vb_jF1^>uj>`CTB(^?J8Gucwx3mQnK5a^vc;l za~L#|EO#;aV<h>8ufZfOu?p`jK`}zqfu?#cAkcJo3>IRf<i5Ba=2>nKUBhi5key-X zR}#jat;QjugZ;FkWo9@t@xeBaW2-yc1by6mYl%&1-8#Qa&Q`^TelE#qnsCgC6wJ11 zOe>qYRaGz9h)2F*XvnR1rgekf#feAsMX{s$yyeUoiCF2>mpLScrIs?pI2j2yKqW7k zSxYl$cfD)&N^odu<;I7o$3HK7r<8g#PrN%TUoD>`#Ud8OFKEi8dHQ;S2gE@n2L|sC z3>_ln223Y5QyNRIdZj)$tqc;(PrAX9XdMKQ`Q^71&KGrZA0&iQ)EGU`R;$>vxxe*o z>fYBu!h$I?pkrGu@CMclXxL&j>dF?Y1<OI2D?0$v4>v=r)m>Ccu^VO8GJ5vL-rX}2 z?b7gj!H_1ujoe|_poVC*5PfV|#7}3AA&RD`;YCW~=0(acY0?W<SaI?;pfo#s(DSm7 zhzm!PP%Zmql~9O7@rg8d6yRpXXz!ZU;p2}Rws&TSA)-Uim$><PM5)D<-%mzW9V`?Z zh#u3xDFo9S7X<~G3?0b9q>F7uBZrP|gdQMIS@(l=?x|^FIDfECjN6|>n0J4n)b>i| zdhEuV;Ixw~h7$tS$)2JTvA86L5@}a|ohZ(ZTb7e0PaBqmr=cvd@xdd`P~WwbWXzu_ z*Aux|t~CnI+2%BuI#yo2mX1ozl;i}dYc-&pmyk%~(vAZ5gFN$Sl4e@SD`d8E_YjLA z*Xm9+r;rbZeyh94+CdL*18yx)nCTo2(!!Xm=I4<`W(imizf4Wqq1I|1h|tLHu)u%b z;+ST=stq&8d)9c#B5*bVdvj01+PUgBr$i<1hBS8;>(E_~yY?2^H?=ZR+Q)~3ciI=6 zIrrWyJl)$<FLwsF_)wo_dRo4I%uNBUtW&w2A;)~92-;LbFIvD<&^g6LpPr3$bGi*S zZeQck8Eb4_Uz5gmzF!_VMK|S|$|sSUW5rr8D7Lo+PoyT<z2IRCKe7HaT7dRSVA|H- zV?ciVaIHqab2C|YG2`2zwyXBdZru5_ZoyEKgnZF~Uag!$Rp6_#`dLyeTTH{qg)$m= zWmk9Wa%$K9>Y#RE%JVoogp;8BRwLIEdaW+7$n8wwWQNJz8<Gg`ETpT*6z6uRR?zBK ze_KTv-cz`sF~h(ay9!HsTL5FI?D&ojcDfTN0sN?v?>Y-khf5&fcp5(GJe$X&dm}LK z6apAx%;GqAw9LjeZ|)|`!xLO>|8yE&S#=AT(@pa6)x9<rda*iD`8E@59yMK~s%Km< z(XZP^+{Ud3<`d+jiuY}yO*QXit+RA74XUmin+ACJXE&FGDLukbs52kx*?Qq^Uvsd) zfI}8$5yQD)nl7zf;~dxHCCm<QF6)DdNevYMOmWFU;TH?>M4p(<)`lUQ1++A6@3Ecr zdc9Yl2@EwFZ=SHHxb$7~6;5aRRQ5HgmNa_|!fT+;lKk02+&eqyr~SNLvMsRI;`RQs z%CsVg$Bw3wue<E_!L3fx8hUsVU7x3cyYcivU{E7O56mhwV;NTT=IStLE<=riI9rhY z-4LNDNcGPphuFl7_9mfj2v0zd7az^mY?adnM2r|vuimRbpssC%+;+Qv*RQ(ns#nR< z`@t%Zq@JcIm-=xC`JrC@?g2?3L$>IIO@}p;eo>$NtMm}WsPJSjluLdy<`rVcUItp_ z7BY&qce5)}WNygSAtHTlKOqpm&sag<cA%`du}<+WsO0H&k+&Q9e8tY_+iIEF5=Bx% zFQCgVu-M1A@NQIllaxExnL?xd$BI|tfSH*LNv}dBSM12eae%2>%66!JD6Dj^*;!{G zzR~Q<c``eL`Gw*8p&V23As77{#UVODK5ZMy<e{&{3w<E)W<m|<J=bTC{zusBmqw`= zlhI{80E&ymS;2k9-DqmMYg?|N)PwK2yT-K^8hkWW9+AHG^NK8|?kU4Z{9PqxM)@K> zY%DuKk)qz!uFoXjhp#&eY~3YPpKPywNuAx*0l3_y!!mcqPU5!?A|Ae!-@HUo!8LpA zlLY@Zj;tq9PjfRaw<vYN8=6y4ytWS(E)};OO*f~ls9ni~ry2)5&&T?c#ad!va`Z*f zZ;6RBsHVebou!6)DS&xBxcCb!J#zG2$*Yc2Ejwd%cvgERZb?*kC2n805_S_$p$z|g zfsboTGSUi~ySZDoWGeZ$^5*~GGW|G0kXtc~<I=AEtGPW-V#ZqL4r=-64D%bzRtX60 z^N0)sx2z%66eQ<mc{?k-g@7Gjvj=|uD5$kh*8t}nn6`j(_Kf>~mO2ctE#y{!E2zts zlkpoFWSuhy0|MV(_MM@+`JFJ~Oyb-$%L5MWFXu=1{UlJPlYf%Fa{0k7QJXHI-gh!T z_9nSHC8b(*;TnxZACyo0isg?e!aWpYc4XClivj#9%0OABa}XiXu;>IL>$THV*Ngnn z1Hy@~H?BZOPE=Q_xH|Efs|ff+=*DcbLo*ZVb@AyT^dL3L4m~AI=?X;c*{Zzq;lCk` z>hK|QV+Ra-!4J>nq>4n|HwpB?L#FbgGN#A+<&Q}gSfNY&AXEy^Wz}j<lEsmqCed@I zfiPFSVLQ_frc?WNT1n<q8yusRJGWsxt=9U5=8riosyD(&;zBIsmH)fP`sXmx$UQo_ zUlTO{T!Qw`-WdNo!5@+MzxedO@8G}D!2gw^zxC<AY`qcw6{*Y(be~#qW7}#4YYOYV zpu-ma_N=3-ZZxJPl@OptA0HV<l-+wZ{`OS~ds$rjw<`))F~uvQ83MvcOW$I~iRnr% z_(%}f*(AV)J-U4|R{cy$x`NsGwFp4oH->1>j!EMLnw5a=B6`SK{fWi*jWnF|G~*y& zm^k6;gP!?*a9o_Wob)?^w3qIro%Y65&Nh0Yx9|WZ#L*C!=Z*7~fp+gUFD3x2(4(=F z9@8t8xl#H4?uvJ?S*=$4z?T9S@iFx#Dnlw5QL3w7pe(Ld`{&vw{MQ-Ze-$M5EHu&9 za9nVF2ktpUD*QCX^I38KD*{Y|p3?)DdOy*IKG}VF0ZUdHKn8zXJ+O2}9M&gLH=vw) zM|nbO)L^FwmwilJU2nIL{+gfh(f{3Iv%BB}e2rF157!1d3@OMwpyEN5P;jC4UZ5E% z&;ac;+!pEXhZjG(E6`TC1<W43)HTb`$*t|!KlrP(nzLr^b;=@sw~ycp2A^74cKy}d zR+gg=pFhAgiZn~Y>sbbF%3f29l&Sv(9_OMCHCYBrq-!{tSF19cCTVOkwn+XdEJZTL zFBkhMLpkg(T(;d`zsjJEVpK8}8IBUVMng>^T2@e<`&YNC0yX~H8x)NGd_8(pVf5W= zwvfkb+<$E?vdJSlsWA}8Bi$S>^uu*^urX0gr<{t3S6nQMM+_Cq(7TX7LY_hQ%%yj9 zkL$WG@Cv;nf!;V|uh;<bzU1^)oMZiM`O9m1!tDc&hv&rC)X)Q*-r5HnL?3WUx`NF5 zuB9%YWk>!reu`KN4_Zpp`R;W&i+<Bc?PV|e=Rymr!*L=;A7phDGB=ZdC)>O3IAC6- zer>7F91{J)EW%kDf=kb*kyMfUs*QZax!oIKjaqBQ^I5hzwoURuP(+%q@;BZciS<&s z!W!J}&psrvOAGC_qo_1glC$+0?@h*-c6iER$|(A~$Q_++KQ@yceZ@BYx~`P`{!zB; zJlRyI&)Yao#N8M_(sfcQg-t&nrrdVo`$Cprs`9_v6NNNZN`5QowZe}8Wb61?^nAq6 zhF{7yJA1>&F>E<eWYYGBZRuV5k_XxoQ1Q?OpY0jEGwJ(^R?F(UpIR@o2)|x%q%DW} zyzs5qX)Xf9ra4#Af8n5I8n{UYuJW^-kwixqE*gW4$%PoA4OBhkQd8<@Uc|G^WruqT z7L@6clCt<mMwi&0M-+S40+L!ZUbLNvF~)s!i0V4&oCm^GTuXTNtlu$ZeG2<ysV`Fa zo+td;d`Ki%Uy`WLb?tjolO?5~(=o(u&P`IG5FZz}edp|5nTWIu$Ha+OWyNMSt=pAc zg$DYCXD|>BJ>UOf?=9n^?zT2y3lR}eQIJ+rVnDh<1?iIR9J;$fKtNjQMmmR~duSNx zh8b$;?iyf-ckcU~^Tc`1bG(1=hxg0-d}H7b{P*5#t-aS;*LCd<KY(LeN0GUZF<XXQ zU&biAp^oZ5$V6XF7?afW`yeH{(5f8Mre(&JL+BEi3fX(KbGS9mrQycd$B=XM<8k@( zf|bfg6DwrG;weld8usErNb49MOLJoL@7QXZxjX6UTy$E}swTp+(wAtpp>-QoDOFJX zgdStusA!;aNzd-WMIAJrm9`CnKEJx;<sg^r-HVj@t>PkCZ0`wv)%SY0^@7E1-9`+} zJ&Iw!aZ2`a4kWg0N$8%)O(%kwuy%W%xoGC)jk0Ao7N>(AlO-gn<ZGGNXB*AzwM-Z* zHgppsSQk0wuYu!&#mk2*n^lp}=QH(7Byr{4-7mLzGWM@u5W);24DxM3o~_M<AlB3w z&>B6q%}}GD7$QfPH(Od>MUxwJHc-_+Tc17j{W(2~Ki~E-mv~fp|CsNX5z`qM6kDN! zg-(#XiM{jOt_#%^mLfAs&fw!!XGxqj(yG$%DaK_~Uz3I96Yne|2~5AaL9plU_+j+9 zMV$3Nv;aoLUU^%PuUTUbk*)g_od=n8hSn!E9U0C|@o`;QYUfTBaJ`J8HVhc4m~KYr zI+KhDN7x0|6}wyaD^y>~O8bRL;WwA|zmW#Cxk5El{sxTaw(Ht30;{9opUvGkG?S3l z=Ysiy^Ma(z-T#82|KFpTo5X{7!7^iy99b9A6er&24o+qgMfe73Jz>`99vndFPeLaa z8*oE(BiCqd)YqB8>pO~m0!9-&V?k~3;MD{C6fylUlb2>ACHGVTJ!#%-2Zju_&Ah!p zn@CAlwc2pscuzA6&xEU$BqDS8oUJeXGKd*`D9ZEBz`{wv$Ag;L$WLykd6W@VquM3M zvz`usu{*153y|uWj`;~`_@YvGczH`PUlFt|vh8ybadj`=m~^14{LO7iiE=H%Oqj^@ zGSKzCZZQYP;HH`u<_-4jJq%<7E0zsrP19>1VUqkOT-;7Q8$XiU2gTB|q;0Eho2cmK ziLtj1YM+l*-Ex|j%3gYwL~OnxJEn6MNZ4i*+xL<$rI-QCQO%#rN+IIzN}3;to{eGg z9##rETnuG)1mLYYkD|nam5Gpj<6Q*iyw(#cbl#@ieT}yTP-rAn#G%R9XwRAX+=uO+ z7FShYE1p{4HrNGvW<9pZK6*ul!=drZGIN*pGEZ|qiGq4QMo>J+XfQEa#5Ag}J5~Q% ziOiF<VNXh8&1cG=Ym3$Rh>Net{$$M>Bb$Zh>5SEU4Nmg)WL7p!c#j)QuD?C(Hmix= zHf>y8(3<pq<!(;lYQ^{?J!X*8$?T4}PR_s|WtVN?FyB3D?%Li=h!&-Ev$3&5j^1=+ zSH1eWycDWjWb`0B=`KyNbofMrbofg*F|lM8WL~c4F)kK@Omg#j_lq(pguq1@@dvsT zPmHa0ya!`oTG2od8X<IM@y#>c1MvwFu-<}-cxdEPUCI0@@I3tApSD{&XcVqm<1tu1 z#r}{ME=usRJ@QF=SlUGNpcH6}yPb20r3c!+Di{}7x-s?<OQ<V|(pqX~*|Un}?i=Qp zT^hK>MBClFU{;MS<Fjw$&yy7*;*-2@Q#tm?`gy4lkq4qys-+oLF##gFb|P1wLoP)e z>}_S<ee|+V;+diKoImmpI(l*BN<whfj8U_>m-8^Zs_P+#`UFi4vPVH$>JPj?&GiNC z_;vR;D<SGBTq`FRrd-=BX!CafOzwvXQT^nL2XaKRN8Av;K4*EE;ct3_a}s+y6YmRO zKW(S*B}vZVWM#hgQ3!MXLIQK(w{Z~GtUQG$9!$ym%-MgULMb+KWJ_j0Gpi^-^*pi) z8K*#&Ut1599Kx>HEPokJFQ3ZJ_BfuY^tEn$mLwh^5{AD`6R8hd6vg9Y|CX4Pn6>I4 zv<}4V`E?Mrz4|q6@om1-VB~?L2=#UPygcSwLk5TA=!6U1TT#nY;;mQ${zO3j<#416 zPP64fz<&ERsrOAFE{70MxSpw+<?NN`iN-LDQKZoy_2wiOwRpKG>u^wX5%I7i-0WTW zOYB!;P;4SKUZjLvM&i0L$v;&Y{>R67t)J(9fbC=s#t#9pKw%a)Yewn5omKapkF|6; ztAT<(3Zkd;><(4)njb}Pr(3wrEpPdBBC|TQB0myt*EO}Mdf2$-OG-k^y^rRU1DR=J z;x-XF@fqYB$lEOhSSjou3!m&d%B7cNrT|4ZWM)QQ%Wo>O!W-Gy?2Q$0({b0C-q96| z?VoO}R3*Hjd;=2KjcGWIQ*>aVqL_a*8IHf+6c*diVR1ml9^-$jVn%g5LR08F(L-tA zZD1S@N8(K=8UR90;IZ01+h0uTS?LaNumLRxTyZ@o;!4pvhxJV}Xj&uaeJ&cbvg@O( zdV?gRzi5Qg)Vt8eLNYx}6RIW~trhd}CJM(~i(=T5Gc(zuGY#6j@pmit)qaid=YP5} z)kG^f)tH^cjh7$eyI=YGl<tDRkK;R@6FW=Q2T6P9MUo`vf<YgmSGS7$hObayy@d44 z*98R^<KH+0H-Q^i-5HK9C{uT-<eNoz&ya#G9QmGeKh4dv?wZLtlvJ8vdWo}ro-f$Q z)AwD?fIc|2q0e$<cqk>;LMLfH=1)41QwDO{_+b~*na^WP0rjcqVWv01u0HaB=N7E= z2{-k!gYJGLCaux-7xgJ&R#9+nn_M(GXS9S@MKQ1MsDHMJc`o^LH{rW<dbm6^$EA^* z_W7vSPwB06?_S-H^!)sQTdo5o-o-ig6wb<_yL6TE==$V*M=)L=a*~eba~Aybd?U4W zGG~vcv(ETJQ?(pNL<R(UU7=C=meWeYf|hJ|9k2b`>LqIiNmi09m$?c4zRGd$XLBF) zZDDcDtQ@?|;C<XurLCymYRH6(f`pc}wB2=MWG^1KFpY78D7@d4Vj5YBP|N%hRib_A z13GE+(+*L42sE?g!T&LZdn`C5CISujY-6&tF%{yWJ8kUn^S`Nvp4gub;=13I$DLJt zHW56lVa`y#=ogcu6*!g~NCX0*Bc3_SaS>VK>!cR@>MHakyFwwi$&laGZ0vk7LMdQu zLua&3^%-xB>N5^RP0(Z(0Y;h@kI#JKvkTZplyJUJZqNB>AR^wGG#VvrnG3j7_%iP< zY#%tjipj;sNq@987E?O5^Un4m+@Qoo9c*TT;Tx@*u(dIg%a>Xf|J5n2<rOf;9yc!B z1XPHum^3>}dNv@0uiN<xu+b72fRjZel4_XzV-=>#yK#{${R~hj+g+ax_q2)F6m25m z`3W~IH9t!_=;KkH8FS4Y(v61p50?!$_xM_=c5}Sz#UdZEe>Y9oJNwK=Z6$_Pb;p*{ zXpE7pH_=G_Yj+rdoVi%Sa`H%5lFJksa+Hs@rrzjdrM32$6^U-{UZX~^aQq3sV@uq? zYJb5)%!`*=nA_28!jm+{JMUv!-42m4a8ph1RJ6NK6!v++GanplpBazrhMdR_+^~<T zSORm)AA~b0thuoT)EnOab<(^s?#byvHnI>=T1i~@T!Z;nfAkVk4VaYff^%+W7m!hs zUZD$*;#}^L{?LtotG){@@8I*9E1|_9KA0rOabut3bnDZ-F`bD0BUbUPOs6;xhFoRv zopHGvfhB`VIZ;WaCc;Va{KV9T5UE~9PKiM{^9lRq>{uC{cMV=ocXeQ7MX46MGvozu zt3nDjMZUS*&dG~NZsS<=1d@x3C$ywM-@N#p{)*ocmH>wzV3Ou<To?Pk!&h+rSxas@ zI>&hBLvIt~^Mmc9#zxniog}r~Y*u4md{V7&G(tq-J@sw$t3{fGCP_`ld)$Q@Pahru zKRmKpV`VMDZ@F2iR<^Y37?H3Gz|KiBnRdE(P3QSZzr2cz$Pbse^W9~h$-cdO0)+ET z!p#Jqmg@8EjD!Z$tVQC=1}2s4MkbZv^s6>{o36<eR=D*;#+5m+bzR9_azUFf&@T^1 zsMUy0Uruuj8q1DTkP$~)*rqWa*C{M~EQ^(TcT;8emNCfFjth`5)WlfHc<Q+60UtGc z0IB=b|C7j;NkcEm8T!yv-B^snsEd_Rfa)Drlosq7$hSt4B9`<kv22<Ysp;hT(Ho!Q z1<=@kYg|U5=F7aJ_nu&a&uv8$$`4<n_Qu!x2LpF;C_-p}X(BHvcL&u~hkNW(9*<4Z ziv=59G-v8rK24~X=W^<)rsBLQ?2lm8iHBnAA4XPpSNld;4$l`bBi80j*UC*=e+rVP z_iPAK0Iken2*!bwqMZ_sdHc!?8A-lu5th&Nai8ylhXoMJ_q05~Pb4Quk;&#;X}wKn zaszxun6KRR1`qcridXx~IiUuFQ(_9!O}$Ew{>O&+Po<MkhCdEIM|`}O$Lq$Y>luCP z7|9LOn#pTFHZrdAjSo<0E>z=epre}?LCiLkc+QII5@K?vAc^Y!7kI3`A$uZhh~ka` zskuxtstrGLHQI^ty2xazEPg1&9pf&>hqJqmOWbIZVo}E?XR4-C_vPj02j4<k$7rrK z4!)35>7u3$pjZ$0$R26_UCiX_PK`nOGIh<AHHyyf5JARGEpy3RPQchLFTK%v@U<mJ z05icH_vEMU(<JXhG5&}<cu?cW46!sr;Jr|OizCC7sx+66!A(Bc-5C;N<<HE0Xgw%I zEgDjOoS4RsRpoG6c6%DF17|h2dc56FH7N!f_&FRUbf_IA>STu3!&)+Apu{*?TcKE4 zY`w4UzOgwrLJ-W6SK4x@1C;|lIouNpXS?wx9SaR-rZ<ilGPm@)ITYmO27Xn1HD&P7 zAW=F!NhR61=|)O#g60>lUQHM$8Of;qQ$n)br2Kh`*h|QuqS$=-B%5eN!;>FmLB~!J z9JdsUB^-nG(!ev1mP)3?J-d7B3>-%Ckd$&dGXo2eG^^Q@5`oi!9BPV*)meXVd=+Q0 zwXM_4o(hmTZFM)SS)6@B9f6v%Ing_*^UCOfMau{MMhoPTz}3AjJgbnt_vLqjcLqKb zdc%`CtMM48R@vr5m=g?4Bnu~vfsup0L_{Et#49}7vt!KnuOhf<m9Mevb@n=jzPy7* zzqF5;Q4+Bpbr{9+dN-(SH<qz5pwufMubALP{4U-rl>E6V+Pw#!b^e4){DT?r$S|a) z_fq?7b9qt7HoK+o54M^YxTK>@qIBFn>2FY9Z#up7_n7f2yDx;U*coHgSb7Sv1K7+T zlz;8}x?L@V;k@l_|7kxgvH#Tvq9HeWWXuS{on7mdarl?-b(Z#LfJ{LX-~CZ5rih-| zu|(tWaDZyt4oI^8q*#fKhYc!dt{v>&vf2j&#vkq>%ppkEI;0PZBzyEg)Qd-QwtUS& zs-Eyw3!R&ZY+t=MKX7<Z^@U!|AMM@!f*+yhv|SW0DyOU(k<OW~$-&`7+UvW=5#cw- z&6a##Vl_EZD{_-F_&$1R1qYR*50(*t%2LU}rqZO`3ipq!=v@4hVdO&P!RGnbf1ici zx%cS>y1o_0y4ZN&Vq&~=psM52p@G}U-+XcYjRV9@N09LD5ES<iKV`nNd5?ou`Wj0g ze0SbcJ4r!bx-z_JjM_vRA_8)CWSdTzO&<*>2iS<=(N9@nm4Cn$1Jvf{I6#Rui=z65 z7h>6mV*W&a4?dR>1KgOPvES-UAXyCmSK~!m2_J}#he}C21`2_>%I10Bdg)@0F5(17 z9VZx`R+)}?8>!$=nNHqNV$}RH8F=jQnwIgKH!hjwbPNBHi4|+<2w=a-_(Z4xnUG<B zMnipZvV3%2t9Z1+t*B^^)PXzp|2XN6R$+Fr;(vKA?AXV&>ccRMxFK3s>Sie+kv5Z` zzv0>%Qle#+mO%II$iZIP(2bbrOVuQ8?`owTQpRq_!6)<YQ0+X~opD%uf&*d>7NRu* zM7JyN_D#VzI|I_hcVPReS=!L<WVT}`)){s-rHdkMj&6&!7)hcQR%WAHPwnp8r?n5X z7oRAz()G+aTgq@*J6DKb=&kkTEEE1hXE7YbGH-t}(s(y$tM@)0XS*EY@5J*sba~;1 z*WIG^*7m)spVV(8N&YO8wTiriMK@1_q#eJulWRXp8z&u+l=YpTdi<r(neGOg<r9au zk&ICPx03NYp~<Im?<C%pn?E2xAFm2^OgY9xWEOtSNe&E-(yB5CzdrBM7NSQeG7TDk zrL8~=hwRWv(Hyt&79s@A2+h1bm1_iQI$vO^%Kk~%*<?arY=6-H<n<$__{qGh4^I}q zB>jnJR|cK(PjJ1pL72svv;<W+zS`voFxye>KkO(_>cz%nkI1l!9ehKl(1$Jc4I;K2 zoB0z%QVLoqas;94=<DdjkWyFaS8?@9%AJ)D%6_(EpdD#5m>=%m`Fz^wMAj}U*;#8K zDH_c&C?_Cz+`9oe$kr52q|`vX3D&(xSB_0aX4|*Cno0(<^jCJru~tSu*nJn}P(wGg z<)CWIO9X6UrB1>!FGLub3NkoZ*;u=u0nwbg(b(|Ywb;~Gk1Hm|N$Xzgq%a<la%9X^ zHZ*A)0p07{{RHg$2m|A<(92}$x4*Re_JDkr%H~Zr3pQ!D+V4)nXmw;HO_}k^Kv0v0 z^pWm5XnVBo^e2A!8!TR@L)ji&j)xkIl+vV0eQqmhumQR42WPmR_q1~4n6<Z`T845Z z!k+l^_V?_GE`KJPR!JKhhm+9d*x!~xgwdomb1;JAPYic^8?oG{MJ!!gN-k6nnyXn3 zrC0QoDBYdguoCx?i*o9VWXF$IKi1*B>2oOz*D&lBrgoach;OV1-F?SWclVu`9dvXW z==PO1JmTk_T|~Bsh+^7-){YHuCECPdqn4fXMYe5~rqOeO4fbs(^tNc}N}_l^P%y>- zbG}I)7kKU{QAHv4Fh?p_Z0DRE7q6MnoQI8im&D;GH5cr|_M=G7tMCTUKph);2Ydom z@J*phlP9Wdn&{R~O1EnvTK(9(cWr$ld$VkKPwS+P3&*8ggs(RRxRGW;mir^&VNJD} zeoER*XWeAo&$wSd%89f-A~l-t6ndI(!kY$qo@d8-4B><{o^42;R>lRIY)cdKsOi1| zH{T>%X|pn0-?~WxWpg>My)vx4I-ktiGf3#|j@;?!I}2_KVqNd8?ensEX#AYGY=X|2 zxXieDbYCyp+H+2Zqnj|ZL`RIm^OF~$t+*dj|Ee)CyqU@FmELc92wz&+uwDq4eY&qu zdR<}TmtbTf_^fa;oL(FhPER!OU2z{MQO-~TCt+&C*X0tetVwMtXv0{PoHkGUIkzY` zEOq@EhuGd<#Xm&W=t!7DgE+>WrXoC&cabE$4m7#LCLXcFhTFBGkYANn<sixf)~Dnm zJs9<}l1NSuktqzOEsx;xjO%JjN%{yBX$&U~c}TM9K!I|uk0P0GGl58(D>c7<$X-TM z=m)sZ>jyA-h)ss!u(tKNP&;#1>mwo&n(S?YQS;<ho!#lGt-%L!HX<Y$6dZ*agCe(x z@`02}GB=Gdy;RkTm^yzS=9KQ5;Kq8d(h!<qpPB^Elf18$OyvjoyU?55mq7BV(j*_^ zSs7u+3F|c4(*C9We6MS3?e9dQ97C`DKh;A2=z);zhA`r5Dl##b(J)TQ*Yvby&faKS z>4!;Z%2`d*$`z!Z&XNqT>yBC#_{wdE=&xR5rIS$N6Q9?vH^tz*t*%tN)Gc9)tmdk= zJwq$Sct+JWXD*8lt+5!y(xoV&(bkmJQ$3W%#Dnvx-$PoAb40fR*B;f%f&_%Egy#O& ztXBe9aq4P-0nQ<d*DEDgHan@|!SNIh(p!mG7}CVo>l4NeZm1&&=CW{suW|tEx+iMA zIN^7Ppx1W356~HK)^5rCd<k{|5W9xQQEdh8YZh&RBZjWYQF_ih(1lNJjxyVFT@dM+ z*gipv5jgtjpn2SLcL<C=&fRdm89+7WG*rk)sTmtDakqRYH<CnWe;%{hgX6~NIR4O4 zbW3aMwK!71mgQ4)Qu=o#OgSDn>1=!=e)9;H#YnNO;4lM;k}rz`lEvX#?=si76C#9k zb3~iVE29f%2_@M$<&u%)+k*9Z#Bv6IIYcc;GYcPPle?B;(hAQZvb&mU;M=r7`Q<RE zSylx935H#DFnbQK8kTgT;*U^)Ud;e`#Qa}<Y~v!X8+C5dP<)vi4M~eX^c~<Vnwen) z4XH?OKF*daX2sqlLC20+Q%aLNXt=XR`mJhUi8i{H&=SKW&|^Jr&Ixr_k%s=DEktK( zKkKduiBKxFPjsFAaZC2K<Tpo^<oW#W94-%m#1L6$vMA5p8c8my7;Yb`x%@OM;`wKT z6}--Ts>=bYO%C&(R~J;>$zY%lGR9szrv-8hze_+YI&OsVY!!eX>rxZ$u}gMr6*a;= za&tEHREw4rNGZ=P33k4<G|B1Lqg&<9Z=^zoF+X#@`aTW<e;ept%IKT>MR@fbcWsmo zx@KZNU9!BdD>jd+P9MW<dTha-L6S)Wt&%VliP=FJL@1X|cwS9rtZ-kWW&J5;Sqq2^ zg67Smzm}&as}wu-i_wqmKDWGTx-BIY*bJQh#<5*zT>%9>^e2+$q;Wax84jZ_4!wYw zIB({NnQrD>kS)Z8V!hzF9AbRwaOkq;{>SM+f8K~qK5*yXVu$}|(xMm?Qd{Fw68xF& zV4Ib4nos`>vl?&N0tgxaK5$TzOeMzwjd$#<%cy^l+b>!)#*k65)6AU$*h~nb;E^UD zAEEnbZKP<?5hCl5!e6jBc5@#~ZOs~&OAU_jtn!o*G}E)vnt0ZT<?C~;`T0WW9PPTq z6e4QGUGssavVno7?_ilSVJm}OJ?)h6FJFIswdcVWw_E$DHDJ5Zd5ND}vC%vtX=fXf zWR@Wt<<c8T^?`t_k?e0eRl;QqHP*T=Q4ZH<m9XcTX%mf?9Qfi-AAGmHy1)!%J303> z;%<^5uW)={3Q6RMKai9}pyeyOm^6&jg_TV{BbDk}M3OkK2!`^*^>|?FGM?c-gUx(V zFW2eW1+$hH)qw)%m|eCfI`y<Y@+C}f>2~gopr-j5^z_3{ubcMRYqQL*j~k(&^{r3d zrF?$gBl^VP2;Tk7aAq+Ii?*g3-ndu%Hu4fkY|k|>U6gn%_pjEO-RN-IAl5x|u+@0i z3<Z)r+!v|kE!Pz_Q<n`7{@s}zPxI$nKR_0KJb=%DXi$=EDp$P^6GFe4!O{DZgjAtY zFM+sdg63Nm%K+Q(g?5UY(%|2^U<2U>kP366MxM9%^Td@2TXrrD!c!9xQ|Ts!?xTS1 zy>#-;Nh~Wy(mc(FrKE8=tQQ&0_L8`J`$P2vjFoMN*IK|WHwYO}3DieP28ycUWCtY3 zwUoj&9PTR@)w)V<i~X2mah=(<n)(v)5C`^7Z)_h=`qq*TC_tx9`Np~NOmZ80A{o*t zV7Ry24_zKbpc+hk9#sVMh|{2@+6>@s`#R>lhQ@b#s>^x-O|sn&&i`!YA3Uen#AB95 z?!CSrF-CB$ksducr!#sGK@TrVGHIGj#-9w^BB7F?&XtCoBuPVNQ{wu(!F>y!%WT_8 z&?>lXcFQxSw76*><pzriw(}uOW2V@<&<5IprK2&ILQh(@8z+q-va<^1!?j8Cidx#7 z+l<D5aFUyPXQrksqYnvN#3eZK<&w>8ukUNcL{F~P*1-F0yO{D<C!fjeKw~uyu7M}W zAY39rMZ%a}6CvX(>?gKNRf1x}Qagec6X~_#CLY9_34&1na2j2s=V;({^WP!CD9C;c zu>i;G9ylw!VXhv`@1#+{=c@5`UmX=oVR_IeEq5TTopd5@bX0t!w1`sP4_Q<5p>#%^ z$8a={8>yMj<LO=}$<qSM=xj>N?nrqz?pT_Cmm0VMHk+J!<$K6)CZ6tbEYBR}aMWIj z){N(cH*;Jngspk2l1y~kngEx!jEMy1SYqY{2>}I2+3ivj^Ir+PJ$3mIk%85^Chv=R zbiYcAa=&gs?LO+?^ZuW{U-<C&4}`~u8XiRbo-vK1r`X=cbMdocr)uU^d|c8VSF=4I zkfn=Q1*58T&m2ExZbK7Vlw<cbTJDfsht0(0EYizIzD28CvG+L^y~gk&QBpl<y;^rV zsNzVGUPJ$Vn4{eRdkX88cCIsR)!@Q5Z|z4YVWw;n8pTU@T<<*}x0Rx9RJDc%;%=Gh zp{C9F6JXqqx|>VbFfk(Q+B45VPC$ibrCi8aO60`}h^TR`;wTg&qMSEHX&hxfSUI4x z@Sz4OkTCCBJf+^3g0VcN$!AHMEjwwiWe_=252nl)<=SR~t1bz?K5?A%u-Pc?6f}MM zEk|0@{QYda#QRhwP2VkV_TnKNRDCvu+IC{%c6r={5!+;C9x&Hg43)Z8ed&w{#_41A zwp3-K!73bIUCy%&Q!W8L62{)^a4&rRyP{aL`aQk$)_9h9e$b~oe&B{L^*M6xmCSw< zv5gPnP3SgD=N6d}F~07FU_P3usNV$;J>5TWqD|g?ac{n~iU7XHEmBPMV!2`!D;p&^ z?ZP%p{d&;i1UIEzL}&4JMZ(lmXIma7P5)G<`=1~Ez~BD>)MgH@DL#9@u=xDfENT2@ zg8Ww!mGtj9{k`L+YkN5-H!kmsCKFMx-|a_tA2eT~p|)NZs6<B5JAT3HuN@s_8X6mn z1z!Am&cRb(uhQUR`=fVMpF-<*Db<%&wNGeGbg-1XW7?zF2MX9gld<S@xxW6n65zhE zs48{NQHs2zan?$v4R^%vz)W`^?B%0JiBw8x_?=h$14uxC*0t};+T?lqyH)=ClrH!@ zehPCCb}syFFY)icpg)41DW>Ge`+xO~{{K0IgWF2i{Sl2g*ZEuF;!CQUdlnou%8U#- zX8x*$Y5rptm#w1M4EK)%l5@XtzN0LW`T&yPeM=c!lnK*Qz#hNvTyQRsN#4qeo%fl) zwMvQ%Lz7k!$IvJ<k9cWuFuN4tihyoUBUzum?&Y_f@I-i`1JRVvuD9(CEW?MzAApj9 zM*h}P|L(b%ieL2m{Kj)_{~b{NALfNN0zYqp*RYBqr=9<DCB?rD0(P%49@UUa=v@BZ z4gY3iFw?vLH-!H(<NwN)|KF?vA06!ILrU^lQ<`JyT;v8V+2<T`sFNCUXvTr=wi*J@ zsTHn~i{jCR$Zw_Z2$na`utLVS6LHC>c){c}5S6P7U@ZzVd}C9YjIgftX(*hMgpBWg zyWV4)|InCRWBqx#l%R4WZz)Ea^QRtoaI5M5bycyuX{A5A!2C{wYp71q(1G(_YpW2u zYz)%HwXrsg-_6!F>*I`;?DWx*iS_kZv4uN#);E8Id--L2Lh)_=^+Y4jsi%x^iKFZ? zN#o0z3#TCmp+Q@=$)-wQ;Y}(a&TkRYUs^NqH)8drQD@>R?z@n{j88r92NL;3L@rl7 z7IoZQE6zK!vl*QC$!GFc_ykX3$QRpi4TNjORzgJCE6GLQJ$DrrcPXP@KFcP>WpKCU zm3IVJqTz&)PX5v0BcCd($*Lbp)jfirhC1f#z9b04iVhKJISWsu>6j))`=nzqt$b@g zS$}xcQ!3_)E%?GqHdW|)J9X#sK*P*-{Ji(@Gh)foLd8|(;)5{qjGNo?aHml7*kVtF zFoW|WyN_4eLofP{I2W*aMG9+?WkHRe*kuMPCER+q6Cr=Os2=cd-R@6FwB0w1KURI( zLdD0|K3IO04?D~Ytkh1qt9czD1@P$#vWv%1_lbX0R%IChYGGHmZHv!mf{p$#lWKI- zotm>X+O2vWIj+ntYqXC=`F2(F(g`HR{{~j!z9}K=-N{g0=NrrbGi(bpCusVXo{6Dl z5z|IMXO*LfeaZw77+*fw)H6kX#fve9X3ZW8@~k7St{hYbv_~=nbZQIa5d7RP)a(a4 zcC8j7@XXt2Aag1s#z=0W8JK%ZMpZ!hy?<r+|NVOl-?5#1%5wJ~O<bL4I5#<3?C$Pb z`1*pAYlXoyNRTRn2dgOK)Q|%BIz0$_k7*3hTG57^OoeVuh5|B*^rcf&qZ&oSvM1Pk zs~3I*5}Unbn-==sV45=7RWFv-yzzkGY9SDxYs;(vy2<{C!TH3)<&u}Y7nckhfo#Pq zS`B<j?7n>D&8MK5IKYe7(xC__&?@p<Bn>}K39qJuEj1qE{P*|$7hZjCg@qnM7j}G( zQFY5jDy<GHBVS;stYUU@e!Rtd@!o<Q*Ce9|{47}T>#tg5S=(w>_JgM-DJ2#IW$pRr zJ#XrUQc_#}DVprM>oeNoBUKmR>yDeD{3fS@tpV4q42NFasv%He#loU|wQYZPj~VZ& zyzYdIG5LMX#jmjEpy18SQ|>}n%Ko)f@vKir$6k$5>les!w3$^?!J<zL@BV%OPadNO zKx6x*6NgJ;f{Sb<vC~OZ6`nhAL+8nvUfnAZ&$UZYRd{VQQ>o>O(p!?^h4!+R)^Mks z2oKmY@;KERMNJjvpD32A@Y?HT?JJ?t+b*2@R*IFUWKW7V&ULrE6<IJalpiODzAe9< z2`N7vRg>Qa?PZ#WP0vi{P@P$vMin{PzT1r!Gg}>-+B|Qi0%=M&YR+4!9`DswBLiHV zQC@hbJT;9Cgh)lOQM4V_dkk-J@VE8kSyG)}ux>0SYJb4yGLzZ>n4r+tmA`#`w}GY| z*9Tc>E0-bl)pe(V8*(P>fg&q@3`ELC>6%zgfj#q@`zr?qHN;`prx&pLnwFW8?rsx^ zbup%w<Cj`JtuS85L<wZl_2lxDM|UoYR~OO}`z9o=jwP*GYp2-*QV-uNw)woSn~xkc zOXd5J<Qg`|4u%dw_maq=m{94KH3z0%Isu@PAiPR&*Y8uz{Cp#~h5c0sYuHJ#h3s-m z0{Uua+io)1ONXsy=bE_ikzVnl2}ZA<c*#!du274JF%ET7Hpg6(Cwniowo}CmG)}e? z8@H6bb&IUR{#aT%SaeT>^KXv`t)`zAo?>d181^lzmaithGW~lDJj+$CmS<6Mf7|-3 zs&_VTE^o0gT(%?Tk$`ApKbe*JOtYM$Y5zo?;7IqpZ!b78lOi2i(=A`m-O!xf7T<l^ z=X|`I#Goo+WHPxm>#An9g%<bR?`K&f*|xrQPeM|#Wr_(mc)c&73{x3?W&4ujUbT!b z)f#Ag<=E(r{~DpH<zz%yWetGLD~3RhB5z6bZRcj=NwOvYQY3Kw6h6)47id;yT;~v} zv_4d}MJi&r9_teeBhHtH$EwA!z>2$C)DtqD%e!Ut3buL`ZMBr<s3Rbz#ma_buLRHJ zJ@!iJlTpeanVpBKTk18!Oywt%H>%`x3Cme%I+Pu6Wr@G{YVjaf-%SV!s9V~WU9-=t zIaZlnVQj9Ozxgh{pIq!YMc2JdQR}txWKPIjVr!a*;Qp@9E1j#Ryg{wq{TJ7&rM!47 zqZs*hh4|}8L+c9N89Q4FZu7l`@}sV6gq<59<TO=GSBO!$-Z)YAgNu^YW43jH(X)us zS6RVZrUkBE=MS{l7|Z|5wOap+kDizO>6!b=qT5avFCCXz8qx@7X;X_H{@~qtrv0_w z`s$9fMJTba_jSdyp7$U6uo*dyx>qsurXn9`aS01ZD)}1R4fVfiU!N{r-%HBTa8A09 z8^RpMl9a7CXLdIPuSQcJs5n_Bb@;Nnh(xb+4JS;6Q&8#P&4|&J;{hpWf79!;E-W(Y zqSCLLTAO$&$$4yCoDoyBO+Id(gZ7%c<bo6L#E2|1b8wS3Dmzt;A4TL4cgIVC3(MaP zep%UCfjHj0(ot)YMAC`?KE$|{t<K4O2nP}leys7FGLJSczw#(9V;f~Cp}v{!KZuqY zLs1iV3QHHMAYrdQ9dlrXDa7>aVOp49-;1NI1Pt!CyBw5it>I=_&bXF-UR81R0ECK9 z7VKTdme;c0tk%yka#%tdyOR7%z8t@8ZjWRYa(UtpD5dKA3tpo4^Ed!NoR{l7u{BRF zx#`RpJv~1;iDSu$Y*wx_gzYjqkJT<KMXPTE4_-^ZjQQEoZ=FhbIv*>dF&W(P+BD+x zfGpKGA}`VWcEQ@($D`h4Zhb2EEeCA0X7{rW8>{Ln%`01li&gPkHU)@(VZ<4S#Q=+m zrb=YIzS7kYUJZw^Z+?*pEv+s6r1LR>1*{%2vAfJ=4KJH6aww75DM&;dT1-zCoKaC~ zdaf&jaEroY!xaW*GZ{R5!3}BWDseuW*5J|ZR!ftO2I(cEisL!Mb$)<*bH~Ydm9Y&n zWo!G7m>L~;@aeBpQCqp)2`M=&9F|wrj?3!`MJaoina!7h-y&KPdQrK1fh&>?*m4;R z<!(@NM}Zd2>KL(ts!lKKt)Hf9*P^bIxgS66DXSHFLecl2XdB%an>mFR_^l(S@{;0` z8{ag~U6v-jWAe~@aIDM;X%gd>Z{gPP26j`O5<4g|0iq{ed!7!|gEa47l7nq_ZMW;= z966CcI_qW?!soKb7@bX*5?%HYPE%1%2JS2=$vu%5dM^D*g+{ndhi?FN)QK){U%r(} z9r%vrSRyrWhs;(<3Ie(29Z2I*>!F%H5$2}JyDbk1B_~rU^ju#2xr8OH;##jaM>~>_ zN+M^#lBHSWa*3b0Df^fpb0`ArK`2eT$6CM^Y&0u{SdY}jxdpYs2CB}q-cN4!p}b6C zzcrjY_cHGK-G6FDuh7LH$nljyFsJ=4Tu;^1CWfZfkmX?Ns`cZ2Ff1{(Rk|ojAEMHx zP5|~_d;+;}FScW2f7veC{LOVbhlLMX8L=4pru<Cx$7*RG=XRlJT^Fxf%GRn}%9gQg zl|i|Qz)>;Kj?%uQX1Cb6r#j3?59AM3Qf;GBUG3y`sk0c=+E%uA7mzWG(<Lq$4ZB_6 zv1|*S&bKrgd(WF0aE)6-9e}^9Y5E~j-K}#F(mYv6y%fc;o5G&HQPaldJ<@-&8P*ia z8yV<22MTZ~-l+J+&_Ioy<TYz`qhf#iOcVZ2W3eD&CfHNHZrgaVG<XX@8oR^u3M6}L zgj`x$&~*x*L1^bo73;r1F{;VxfVjIpm(62KpF-s10jP8g=#_ro_f0%=v0NpL?la3; z&s;Vi@K>;2-yrSoHIK`<4Gjd~_EKx`6mektQI+3h5WMBomf)~!yzDm6eRzE?NMf5@ zg`E}*RKgP!5^EtBQZ3ZW*nQD5)tGy_dgbGQ7XbPz3-!@YgwTq$<QY4~=t^5*!eOD^ z`?G|Jq#2&JCv>gPzhaFB0Bl;{CttmXh^4O4JY7mCmyL>S6h%IKsj$OxK`C^`dF;DO zb4{HRPp4{W_%o1%;A=b1;arJfKXr=G+ev2UQky$J$BWFEWP?6jby(~2=_*lR<uNz} zU?dH4*65+MQcgEw+D4{Ty!I4u_*qD&%*q|fh=ixc-DZnkFY1drh|0Zdvy8EZc*;5` zuSuTmGxK;qTyOqaDtABo_^2+z3V!dSBjELm;`*56Gg{|;^^{5*#p|J<+>d|{gu4Tp z$HSV{>V9vWh1C!wn_qSPchA;?OlCdXclotL-qz%+ka$=mch6V%H0OoSU61CymD(}m zG*m_0;9pN+dOBaZ<2#T2av&)tvFagh|Lhqfi_fV#LN$G@oU-a8MNT{PF;8E5V9c5L z;9{1)0qLA&JUYl9rC$s$0jumMs1>j&uNr?-NxK*!N&!4tkqeHkkU1Hk`wQuvsrVnE zm!_j?p(b<dS;*TZKJVGm_}b*E%_*dXjsVkhD{@D*w4$M~Tzo~Ai^`Ug!C6|Z0;&!V zPq^@u?iutW9>F7ZTNPe^b62*jT>nRb7+TY=nx_%Ph7;VOAT}u-P2<?k4_4Yeo2H8E zTMsdNF{4J_x2%X;nf5IRxFQ@d%HtPUh@RTrr_!yXn;g8hMKuB}e2O&&8j~kZ)<K%c zUt2(5n~ioHdAH1$;7aAzcFW}l1Wl)VJZWEoXN)I}^W|w65`gASr)n`Ao6YJ@Zw+D_ zT>Vjd^o{#RvGf-|Wd}U(<<oL%1;(sTfre?<=Vebwp0w@qvs%l!nH6#sTHeg+P%Te* zmVAs-5hjYxzm%+ypIY)N)@EmcILLmOVu2gn1jZA_TdqVD7MA%7&Tb}FoDSbi6Boml zf<C9BCIzF+FhfE=sKVD>igzmKcb$Kl%-+ZXlInSQ$zokw8e}#8Lfz(E=FuNHfD+A< zs3M(|c)5`(al_1jex(Pwx>uf!(+M(*U;5)T`~}$`XbF`SF(4w;ROrjib;v8tb=omQ zd|er3>)r%04M6DC(A)pSXmLq}SbU4j`iMHW<nn$<BM{Eg#K&3sWPOXP#)5j==Tuto zGK^F1TbK2Bb(fvAVLu8v$*SrhE9(l7E4at!ftCYia7jh4;LBu9LK4&Vx5hRq+T?mg zccDD%KeVl;CQqX*dU{u<x4x=Jr=$gnwzL%~Bkot9Y+^7BD0ERz&>HNh;#FLiw9A|4 zEqxedjR`B=KUIw|2AVr4IkZ`iVZGFvMTjiDvUvw6XTI8eSo3^_7GWC~eF^X3GYYqs zhQVrGxh<~_3Ih?~kim<8aX0GUi>d#S4xab_Ie+ri-wRS9{c^JKn1bPjp!=x_GjFy| z?A{N*{?lezV2ajl@vQIwz>He)(RA0yGxV$te~;FiNjvLO8!xi)I@6bC=#1u@5-Vn7 z6Vf#nrO9O&c-169KB#-eU4(=Mb1X;e^W{HTPd2ky7no`nC}-e2jGOdzH@C&%$ySE+ zNxgLUDB25Gg-S#~ambvi^}`-&#YHC(6~%VSgL{~uCLq{Ss!{vfOSp;3M`kQE2TyfV zLvKQDh*=H3xw>`QrYQ?yq}`myPuiCTJJMZ6^Z3wVXjKHNrVdL?Zm;99B5P|W3zv@6 zKV<<stR@Vjai*)L^G-B(0>3J@xFgBKcB9Keye*3|ip!6i__^VZd1sjsUjO9=*#DTZ ze^T5ykHscU)|Z~4RncYx$R&96q&>z2f<1mb_N`-StqkO21KCa<eOA#dr{lSLDyS?h zl4Np)Rg>3FH#kn;7G&iMNa1i;se*CP^9B&w{Cwj~Ztbg{DV@g@b>=g7|MYU+JTQL$ zkxP$LX}Mos|Bh!5y5LZvdB1sOs!$T1-@P1!+Y9#nRpkHRZt^e!Qwwx&kQ&3;r0GC( zQX!Ci@VWq&6+N4oBZ~|luWE?j(8s?U8@|4gDu*sh0e(5zddU{rXtIglDo;x9sn`|A zQ(xk^{F-uI<JxoLug|Bnm@bpkn$DrbrpDo&Diu*hoF4>4eVpbQIA*DV*_r~cYGW+C z=c4mZAZ)ijQdR>T-aoh_V%fW4LW9?YIwM&xUHVr?5SCeLNcP$Jxo)<<5LWYb7QQ^t zO4sC~w0s%+7N#|1zOq_rc=u_<Fj`q~V*3#{sX_^_vvb2wp8lDvu9sBRd=1mynY&+U znnGEVCi%BZGFV*&bGMG!AhAfjrN%cw2L;iHnG_C?LkZU>wUxxZH685MCsCOCsdnP1 zLC&J4twD9yg#OPR5rou@E`-VH6$}J;)~biBgcc)1w8gGY(<JLnA0HO`Din5s9|*p% z^sC2}akL)GR#jP^H&elZPGFI}h|>Pqu#MT!@r}9GO1<RA*s@wDh;(UZ8$);YPNd_W zIhm>E;t7#e`k_QXP-<+Z!8xCR@fa?gW{^-w(mFw`zj$orc<g7@>7r!vNf^xO^Pb?3 z>8V3(9Dq^^ZHkYDmDeRbq6ZG=&oI!0+r@bB62Os`RVaI}6QBO+ZeE!;VSA@?)hsnn z6+l56kA7WS`Ye7{nM-{1IJZWb#Y4(yFyeMC_4r%01kw^wKj=f4DaG2eH#$SdUH-qS z7yRcB4hji3&<7z6?!raWj*1T032zuQVroki<6*JYsJ>F~1K&cz+tF4Mic$ZK7yN~# zS$>h{9Pd;qM5QxIRm{^Bpv2hDvqWFf<dooB2cMr78Ja(j6l#nu=Qv~==m<Vzi7f=Z zQlyg7b6^bIxa#q+(B)Y%QmT}xE!5zmK64)Gz#CIWsN}P*2e!Y|{na*C`(0nU5JM|I z4?`<CL$9PLsoXBKXFKy0dwj-U%%&?Ue8T#p5~=$l7G2o_s1_ZR%#4=7wU!(4qLO96 zOQ*|ln>~Ip#(i*PP}b~PN_^y0l{m3c@s3YPEsB*#bnC`pPSLX=&bnK@ESK+vmAUUR zuWW;1{F0z$g~|lcGjLH1cz@w-(sWgei9y~zv_pnKAo=hYn5kqrfCJQ`WMr#{PqIOS z&2#{~O9gF5%BIPeasg(zEsyuO9L?2`F_;#u=9v^<#v)oa5ZUuJ&G%IVS5gQpEJu7n zTA8x*CnAUOXZ$DrwuA1Sn!skRl-*=GS#72LpGh;Gvgd!{rr?9Zm*~|B`~0N7z5U@? z`z(raE3alwtNOA~S)CdtwEW|81zm?V46!D0S-uy+j92u&%KSJ+x~h&@m7WS_>+26t ztW@zS3{~^Nx@4GeW(SX9tmaEmG?lL33_%)@g`!?>V7hK)pHw6A+KWc0Z!dAj!X>j+ z<{N{jQ)<jqc9}qjy5}gCwd>)CE}7CgNu!`A3Sc9vao_0@nz8+GITZehp4X>{t!}(; z6bxErpN`tO2(**R3p7_D4aL`UCe|Ko*V@5z>e<`P{O{+Y>@J@~j=Fv&kRdD5o!iyq zf~%V_%SF<_b}*RGrN`R&>H53TN76-{Cp)?fmtM9y2fK>4(-}YI_lGvwt9^djBy)@1 zA1p(y%uQAAB{)`ld0Rcs`WeA5E0?D)Swul^C2Zm$>ttnNJ2r{aGC7M{T8uuI%T1Wg z;l&S15?>n*opCKoy*Phkgk7sFpONVYi9+`*YAuh!zD4|LD4*_*Gf&<wf0oEkFmCtR z5^E-Hj=`ey&i#(R)z;k|YMZbDDV#nl<G@xrTNE(h$s0D)@N$!z{WtZ+7!7NhoH@=t zFGB*EcJWjG(q65M?Ic%bjLI%*;_~kO;l(!L3aSdF-aDb$i{-gEV^#yHSkXtRSxKti zwP&b=&D<(GKedINUQg0Sw0LQ@v8-c*V9&!FE&^Y2Ve}n&(LF_^-x&H-%DS?13eCw* z%1M=I_JC(CXyo2gI+gmUd@m97ASv3f-88&(R-362ckbzIF9i{nm9@50r#z(lM(Mu2 z>#20j5s|iznX2rNmhQ3RS)X54@t8HH+0r{+oh~F)c)sA8<vtiZ;s2wsRcuW^q%ukk z2da@_z*>-vA2Fm|sf?o*r)fsRn)}^T?~=a(DnHjanFspp$U>CyrfP9t_~0_vMJTsC zPVP1JPRcB!CCR#OdA9~q-X+#xac&@)-^*g2l@7^7l$nbsqiSCFF5EGrbJ_%H>26Rj zHeW{xH_q}da!@kE*ZT`iW1-V~Y0s^GKvu|YS?aHe>5{BNrKLDGMtvtYq;Di4Vb}C( zS)Ntg+arOMPWzX3wq3;Rjz5~!rVFG?lPzU~H!?4Yw#atdb;spv>4UjoTa~mk<Lp#R zal#d#s3;IfGHM=)Up%;^>i-5FX!{Q>0JJB%bv@B>_2XEbu15oKf!H45Wk1C;eXYUP zqYzHvkz_T+2@ylo!*%;c=5set_YgM2mnT*9aRi<D%2KEEC+!w<jdtZ+xfnd5oI95k zn+=QiL0M8o-cOe#<r-IrI;S~q4I<X$Bvm{m_cRnsxAXdkzm1VN*Q+E;hEL)gaoD;k zSLPv7T)e}ED6&6|wd8kyN-*2I96tFhCy_IIkElB2y_nrXlvY*V8J*_M6>T;3AWKJL zjFAj8hvh{91E|cq7mOBM6`8KSiqz0tS7|Nprcv!$UF#uU3(T7hrB50N=%{L`)<Dj) zsui<q*BapWdjo9&U>Ow@eOj5aGz*JLr7WScv!|Wl9Exp&^)%se4baR8dEKA~n2Odb zk=6}ZN%sym>mIkjp?CbKFK0$GR;4rIU0Gwl_tKIFcqx+n8P4xs*G^axJ$lKh>4Shw zC)Y(TrtNBKyLwlP0gJnrXX(my*kRNttEq+=mRe7MeZoVM3cbD+8>YW-7rB?kADt|R zJ8~`80bG!4n??`yc%ZEoH`#6OUVVNcJcAXc%nkr}zPy0(@n%Ut2?>j}g8B!VNwXjT zo+wDUjxeI*au4S2hN3V)CBSZUf94uxTX@!X2~drsg*H%tmyA;JIgd>o73@+u_Fby0 zn?Nozle_mVjZiMN^dSxHdgBEH-M}f9-PAMtFE$yE^=hMLCaxxDM$)5LHYd!HQdJ_` zjk|MybR5oG8<Az^1&{HRcb7N!kTz{qsspyw1t6_*kC_)zvinky=JCFkmNV2_r~lmH z|JSeV>ad*P`hANoZ+P_nVvqi=-WUC_{Wk8u__!Z4<@>VSFzrV{fAw1X1?;C*hl1xp zzwbc)IjrGN4<6Mx{lIQ}_s@yXKON)$<D(ZE0?>?!_^XdMe7n;Y&+PE#)x+N(ZvTAe zFD&oNx{wPbfAR76gwI~XMn5q>==hH}{LQN!pg|Ak<X*pr`26kfY*5~Npw;jzQ2*6m zC`SGHNb{XG0z`oAUwvFh^ozbUVg1u5_y3n>!9NeImGCue$@Ad%4a~p&;?J;0Ppvj7 z3H=TJf;0d5$T@n%UU<#FV=Vl`#GIa?O+sho<GUw+(W?K?34XT{|K|k1apL#?=LElt zFALZ}oSG)ojku5WUv}l!c2EC+go#?={$;()I&^$*2bul*8=U@g3;n-;@Y{{;|BET& zV}TugE<W42C_BhRGr_Z{a<f=Y!hHyujn=DY$C~&j;3ITJIi_2dWiQO(ph*cYouFNx z?RzcNdz0zNCF>{wDVoIq0+_63WfbLfwNcnj*#&a?(jj}k%+WH6i$PHmtTev9Q>lDb zeM5XOF)Ff_#<e!I6pGZW-d#ml9`EZ7*X%~PfR?$3M?P(hp_op2J4)N&2!#wK5$+k& z5r0QMyL)Npq=)GND3pu?)YueJITgadXZQHzH<C$r?gjh3&&SZBoKY*f{lvXPq5;=e z(GyV2E+x+t!rb=u1%`Dai<L#ZI*n^5w-1X^`Q5jlvuRHu3a9Xzd`%ZKb2J8~;XMAd z+`D&gGQL^`b+N>qWj!SDQ>!#B+ZrPxrzLMrFMBI2)e&GOOuYKS%zWIakHF$Gx|%nI zhC5!R(4=jk;baFtrda*`PX#|Y&&aRo0n<aK(cH|ZQ_C~kDq<D6!+lcxzuPN+y&iUN zizh3d@IA<R61)K`N;cIU%e}^JPf@@wm8o6mH9A~W8T3`HR>>`F3-Sk;&nN--tE#g1 z9_k1<8(U=<R8K4N8zKS#6uXm0_UmRJM1q5!3ZKn+l-EeX9Yj6TTjXm?=Rjbu4;J3H zqOwii{&F>s`LA-Zci4*e!;@l~Grw>ePgHB#_dPo8thob7rhdS;%lq5|*Frc$a=wm3 z`L@|R>5}v-)V)1W{&#~p-@$UK*AL@RFXjRd*LPvQ;y?Mw4XBH@MG4^!c^+yRw8dj0 zIbqL7Vq)aR#yL0d6RCJt_FkrE;fIA;@#UsXpZAjrPJW-4!&fUj6i4)yeVG2tJ$R2N zWQ$4!bkxqqzyka}eb`B=<8|##RC6*_5JJVd5zbQdOLwOQbt%Uw(5!Hp)Vrmu{%fOc z=S}vLw92h_gd0`s5*xhv*B-POLpXGGrfmf2B*7OEy_>($ARflLhsgv}wBL@oye+NT zw4vP04)-GcOnsE8iM)#9y2(H}&m5hP3xwoNFpl#$+AYoaT~rY^>?w;(AZ<sh!sH~$ z7*E={0q4;c@JyQhu6>^-(fQ*m!!%)&OxK+dPI-$ZV?DLcL0c3ca7%&SyhkAcr(2`h z{PYwDLx=X8d7i?ih3u{t<A#T9#mN)g#YZKh{Zj@|+v=;c5zXffxG%Y0PAa-Gl!S`| zY3{M!-AC3_3_S}>cSKQG+26O1IZaWs%^St%2K+7%?Ig6`#jbIpezXM1iAa}=lQpnM z`en2)Q9+qWA7Vicc7I*)K=J?{>kUIJIaD4yTVouMHxt*LsEmo&u++j>#gx=s)#4+E zAiY&%7#rs#uJd#!0mS~fmE`e=rxr(ZlOoPue5l6dK*h&At5CCL!DT0v2#O8OhC`O3 zja8RlZ1<8dnh@(k!r~?S!;Ut-0RV@L!nWa#p^5(dj_Fd$gLzaBlf}pg7oN@%i{W<m z)S1LfvN=F`{O`;WH}rkNqZ$d&<?1lIla@m=K}x$}v8=b_$p_Y7Uf+kY5zH^GLe#61 zd<ct#c#p7Di40T?;+|>x6ffQvW0ch4k|vpyQ;@6x!~Bs;0*`8%8f3iPB-50q&lX<c zv`paSIaTom&K;}G2qM1kD5g0_<$3@&D;XB9g&GyhRx2O-sHaY$H2IAxZG2dG;6vsU zv&YURSBM2+;ffC(dgs(dWe0kgW*bRz8>?kyi`4(VGJ~7@o)D`>v?ThMxh~C*<WunG zsL-e80Z)*{HBU{^2DTu(-09NZ)AF<bhrRcVYI1$nhi!n0fJ&1tO{4^rUIbJ?I!G5n zlioo(gd!-i>Am;f2^}d(1f-YHI|KxzhR{N2fj6GB_d4%~^K<+0eb@j0A!}u=<jM2o zp1J3qxn{1J7*9}%oH*#`2Ds<UMF=HT#X4F86l;Lx(hatt->*KUb90SRIZ-I-gXxuK z?o)owICw3}FGy5YU&_fmuK};No76^{+eqd18jC}HgK}#h$S~Q|Uy)ONZ%ByaKbx%I ze<Ow7>!K#Aa`|hJE1`{d#9;4Kt<3#GHP5}ZSpx;dym#$a>trich1F`hZ-qGYAFZ7{ zGNDoLmY-=ztw8I##w#c&Of=$#Z&J2UazpwzQloa}7gYztw8)@~y6*j7MFH<v%v+84 zcGLB!W}xa=o@U1S+#fhPepTP@_>O;!xL7?>HDb1&Z8tm5RY^YN>_{BPrbDLqc7IRg zg5}7Cp<CR-+>zcoZRBEG8>X(#utUvB)c3l5X+5OGm17IsW5$=>5!9}uqJ{t;>&Qnw z)61XmiyHZmUunBnk46J#n-_*kSU-S$WXvt+PLC8MvnGGOvG<+nO0fgwsx%<p&FHB1 zp1=5uUi3sYU#rCsQ6jWBT>?Yi84|h#idPmzid=??Hbr3#UGzV<4>2!VB2G}Sn>khE z5WkOE%mFedx;2uFDOUcwr~%ken}rBW3MFJUWj5E4RKHR$w1ct7WMQFU3My(@d}n2< z@{wT=kmFaX+w`DgX@6#S`%g67p4vw>+fMGg=VPcfrwfa=#5u0%0~M!T*{%Jin{M7r z(=|46UmU{|R+^BhF8l}OyYksR42>JDS+G1lB>mM&b@x^f14b2O!9r8}KQ7z<`tF;= zZPyXpIFs8m4&<-rF)2BeRkc&lLe4zva63!;G4#FqP49;V@_k(VRg-s!eCjmD&WXoO z_ZRvdDyCL+Fsg18qK1_=)G^|~x{JvYy*dj;o2y}U88lrgHV;)+yo{gWkL;VC^z{v~ zGff+x0#6^Hw5tn-LpfS9b<0mxcgCNKBN8HM3aurna~{90GF^LQ;1dQ6VsU*K0)F5B z-J7tE|KgyC+JD<OM1V>nxb$a;7w%M6x}Nm*Td$8{Ir{`pk+zMR)R)SKWnYvhOQ|Hs zn;`QvPpU^GBxfsReBmPxEwyIR?hR|e`TsV}?@Lqg!W!OHJ?$USK(;HolW<pooV-kY z--@r_Da(vwyj5*Erw3^MkWQ~S4-fHeg}0?b>=G+!W9=0<B**z3u}1t`iV=De9<dbV z1MVnd?ZH_+13e25IkO`A^WG={U$0|O{y`#nsy}jR1G`Ez*#2^*qVKJg>zZ-dwYt}A zLKRc?l8@rB>3vVO_l*|HH*(Va%VZkEClB5c7*2)oj3tVfZI!R%#*DY1SFwZw^-nI( z6?c-CUE(vk>xM*0wk1*1fy;C|>vB$uIqUP6Dl&E3DKtkJ-w%~lthj{}u}$#gnp61J zeyPT|)0JyPR@O@Dy|e=VtKM7a-Uq37&m0z@hKhyZBL}pwn7)$wX15=Ig~O_|qdLyP zRmS~C)$7Gu=|{$j<GWUb4Fjyx&YlR_bn)MvF~g@f449`)cupv12ro7FjB5m2y=$)y zo|FAd#thg}Pw?o(KPHR49Zd3COK3EZGlvptJ-0HIi(X4OJ2O|Ah)AEZs^Z|BEQ2yG zT1f^1#sJf?x7Th#5|s6Gv?QtL_nl;Xp0)++D0k^*H9Ts#M_uPI5?ITr!5C4OaY3GE zvnAk|Ps$SNKy1M0pVW%50Q<@7WP(h*TZZe2sm)q4H^qv;GoGM=O1;dxfl5Fun^snu zp#h68oXgfE=zbv69jdF#y(QryZ<Vemmwg<Bw+5qv5-y0KsJinc>+X7r#C;m`6YT;m zB7}~VOu-?|;4oKpsdo^yC9#T6n6Edih+|?NVWa`ZRwJH_3AIdJV$YZid`7-10mmk_ zctG-FU(CJ|=oyaZUr!RnwVFewLUX-S8U|>$t_oWZle2?$G7HK|pA?|d-YcWU;Wo48 zDN?e*t0E7>N5mM;p<sCa$>|w9`sibBi|_b_7WL7Vm9p}amLC~r7s<x&WeHK{UaO8} zX?e>UE_hq>Ds0o59<{_sO^;ot<^ktpToc06vP+OH&^4beKC3V;607e#9uf)|A-@HT z<^C5~*fsN80Aa)Ui?Z366r&$!9Z|*0Y)Lj3v6^qQ+b^>&6w6+pe=+>#E<F9v?>)^H z4`3tOu_Z&=?A#_z;R&|DT~{W7yL1Dbsm*AzvJ$41RT22oQ%OQ;$dShJswRl@wQ?WV zvu7@W+_cdkj)Y;uUN9&##dN~#uBQlXChs}~kZNd{LJ?hDoLU|rn4r8GaW$U1W*gTn z&!wb$8vBIUS?adm9@7Z-sji?VY4BB^g4tN2oqlmQbu2KJP=La-nV;74u0enHhgr1B zakOKOR(~*#K+$U}I$r3kN0HXYj;K7Z!jfR3MmA12$<+^L@W(VDR$68kUzHsYYNQpS zeIYWl=yOp3T+R2XaKzFHWu|Ya!5n3svAlPEL|sV=ul^^pZe!(io2mMzxe<qyKZ&x! zQ-u}R{W`l&5B#lq`>K=^v_3V7X+ny%V0E_cz=PDzDE;@CvFyWvo<jHxL_;yLC`)$M z<;l9&w6B)9?kAk1JgGB<8)eIf;0!(xaen#<P_oTn6nX_!<*w;dE!&Z}Z2-1|=?Zbh zZMjsHA~Qurz83B1#@r))LVar@W>U{B|GS5T@?+U5)+Bft&{f;s^^&Q#kjdNJUAQXQ z*0SMWpulLOrH^<(4hP+W7VwL?Q3fjf_X+GwD6AIv^0M))6D=93sv2wMQLAN}vZG^r zM=;3nX%WOpWhe9E9^^You-t2G0fc|B(V(S%b=;-ysaLD<`#^2`RuOxJbmP!)AUAc~ zWxK?SCt&akBb*nufAdZ7j{3Rgy|nBAgs9?8=%kUacUEqutR=f!^ek%wnI=i~_F?cj zC*W<&ZJHUv(<DIaK3-9^hCzPYYr&O;=)o$nBh(=bEa6bvUdTTC)u*&F6*jr~y^v$3 zxxFO)ezQeyVw<b5$DFG$+moqVgcaZ`Z9<MW!8ZiluUZ{2QFFXCorP^BN97z`p7nLv zO9^u^fZ#INyPow<g0k1wV}~WqPXtVta<&|>7H<+%BxX1HtFQ$#i(9h_e@6fxs4b2G zWt9`WX_2Mhn`Dk(_-83M@^{Y&LEn9-rH8o$_RV(*PK^C`+*axZMQG%jqs7sw&M9JU zA$SjVsfx;M+5^Z5$CUI7z2btsSHh>sWHbmOj{ShkmQvgOB=59Xi$uefKh)WHeJLs1 zd6Aj!U!ZkgejY=0<899R>mM&T91RLib^H{?GY~;~<)I_jV4-T>GAU9Qw0E-LmoMV( zb&#a2R!+xO#g!iIoy}0Mia*Og;^3m<@Dc!PZDxNcskE~`4z+Y!Ys4Cx6<RuVR-pB^ zR3z8YqgpVZTo~ja)vxgsHQTVwj3oM^>zY3#3<>5gu2SIWTyQ3SaqyGI`%)4y$>8Bv z44Z)sirXRLR7CU;7u}1Z*!;Y@;|8K;kyJGi^(Z)9@z@GH1p<Z^+B@Q33Hzw{LfunU zgtfg7J;ds^uk_Xug{~?;&`5^UVS4iFR<ois;87AI!C9zE$4e=2`pSFe-<?4?-zMlb zZI!ViBY~<dsZx$}i&l!05iuKekm0v4Muu#u1rky``yD)XQrI=n1BONV>ZCR7Leko? z^YMO#hZtkTxLmGcg&=v~Oisz$cGJ7aSd^_<w_XJO3zeL9{1lH`o7)<1NXD{XT@}|z zu;HU#yIih;US-UST$qTM7DSub+5^2leL=*QhO2FA9p5pi-EhFxyP85cY9I{t*}Z{& zl-?STm8(kvo-}LR^d%dKyt39@y}iA+@)+_!O+M?=@FkN#`wPXK^C!jOHJu!J!YR=& z=*XHy7MKvO8e*Brd0}7=&fU+Su5J2qjJb;KGfpB7%#{@kIDlfhuxj>pl_6KujxKoA zF<d@V{{-`pxDbzM?32*`g1t=*o}fTVT7r7vX2g#{OgXUlup1ERAJ-25Lg%*Px<9VD zVY!LA%Du~T8b2>Uot<Vj<}=Z)L+(tUaJa1nOej#0*}y#5MMX=>wqp+cB;pRlg)WfS zop;v@{YeUSTJHpJ{j9*oy-8>a5nZ1x)Jjw!Sro2lS^Od9xUudbuxW`hXPAXuf)~%) z3XFP(vz6gf(DD$lU+jCJ-NdwucX9Ctupd1VLDFz>8bd^V`PvS#X$n`H5XsV5P)-vN zdmf=zXc)DVL%Dk~d)-seLiEx0?=fYG{u>6I)9TN4N#L#A$g3s>$Tgf(yPPz&Ny&cn zQ1YT(aNOu5$mK-F#}jlCw8c-Tq1p02^yqqt+lq-V#OA$?qNh>`Ac#jdAtWM7JiE+6 z9x}~iwjOe*Q{t^z-2S;X@9Ku=IiWEk2S&fB4}R6DB5NI%Q{vONI~-;UV*q<TY_@1X z6@vt=7tI|eV(N&=XDk@=a#Um@Z&C<Wn*s~cm$lj1sGe+v+a~)dsMq4j;1>iky}I_; zH#B1}@`1QJ+B$VHS`Vd)Av-408IVU(as}OF^fU6CTf&Uyyp#(vzz~p5iH|4YMP;VD zrWRJpm&1LHWZb9YjX!B<1O{ah&Dn_-E%$DwTWoetv8@(Y)dIuHACASI<aEH!_goln zpW9Vcsmd2tsn(IC;cwcc;g>K@zW*wDg<+;U`URyFV_UNhe@U6bLGL)WkVxctWya;Q z&fFb5;Om^6nv$}k6Es2r^<8(Yd0zsAU&Qf%{0DN!Z-WA1J-Rcu_}0McmgTH3ru*$z zGdpvJg%bmzJJW@39<BN8{)9-o^GxgW%jb2X#{y(_y7lrMLS4kJa{}vDtGal%fGVPf z;CWAru0=>fRx21H*g((L%-Y7~_Z1X1tNK)pg!66(!*A`tw`IU^eIQ`pR?YXSRxl`3 zGC}$z$oXW=?acfhgq8$WMFbfpf;ka0z~?fx)l33|h%HJ~CzIy(M}jbfQS4ZjyGEv3 z^2huFTO?Olpuh{YqHb#Su@W<sSuy?MSEWz$9@+a{mxLR3Z4_y5%!`$~<K?_oi%XXy zbI_+jXJ^Tp_lp{qc}iahSUqUA=%Z_uLsMlAu^!!cG2wKTq-U>}SDRrSA$mwHnm1?q zW?k$}-mcf=4T&7Y=P`-uN0rxpEHu7Hl$zV5OY&FS&K5CnMB50>y7f7Mzq=36E#1D# ztkJd&i87h{MDeD{&G!Nrsqp+&*swtFk=<W)4YM<IhzBwvMQgM5``3MoILKoUuy$9& zF3eZ1f;pgBh*3NIW?J7)wxsOqbr+{kfKz`&(`!W#*Hcd@DOq{F!i$6%j{RFx5@+iK zN%8AK(bL<*eo#k^TlSHv56Hq-<p52EQBYs)9W&+@z+O$A{9*c1Ukwd>N=P-7_4Q@L zE}pNYvQO#bx$}Xz$cbEAl}78Zz{kC8vvcG5xZy70+JSdWo>pfoLX8zMR(odPhyrvJ z*!l#FXcYehW3Jyy^y4^PVn&}RgoNI`Q_wn<Kf<>-{Fgts)<lp|xSQz}_E3s~$!GIv zMXJb4OA5+SHD?`)e=!B7Hwd_=dF@gRFG8@e^*qNoz7pT!Nf>I92IyaAq%SE;l=GxE z>m;u7#axOy)6osVv3^@v7%flyr!P5|2as>a4Rc3Aadu~E-(6Xo3g!2^S?pVj)O9Al zOR?=L?mBf~vGmp1{grPZxKX(FXDGB@jgNgIy*)=XQZPu}iaR4P5b&NrtbOOyWA*FL zw)>HznO|t?@)_SnVhbwGPf`~u03_Pv{0W_r34#j)fDo5D<NitWnW7*CT2CVhDa>F1 zj*_VlDClaJOv=>z_R%F0jzJd%D4^y@$XClAk#2!5YX!xlNWb5SD6_!YHrJ_c6uNv_ zTJS&R*!z5@vY@IGyez{h@xTkF1v=gtr}3XDF%YAksItk~B4w=b1fe__$_eQ>Ey>fY z7@%Puu+RRIc=#QG4q`ZfSTySswH<p}0g)}+Qyq#<7y;J0@B-1AqX{2v1(TUyv2~}C zSvM9UQtwV6QK$G*KVDwRTz-{V$6jQdyyp_;1!WJt5cC-rtf(*L66)>%Ah;#v6}vJl zA{Iyba3yqx<<p_A?H|0CyVs~POF&1%;mGD~h&1f<6Cfn9W<Mk05#kq$F@xnh%CgIV z-uIHKEfSC^8@VU49;WxKfxr1GD}&=XVRxeKhDdh-s-OC|&~-q^>tCMj0fZmpDrqwj z#|IxCPZ*jFZLu$nEgg?%#2pZ)Mux$LPlKgc{uX?&p`6F6K7{gk`MF3DVlzy8#Jrnx z8$BJ>ZSA$O26<Acz7oatdG*3;MKduJz(`<;AqEt_CcYHlG_#5M9?<?O`T`?s0w?w> z%y5C0SREW)Wd?CBM(Jn>|9F%@*4<7I^@qL<ak*D^qox@3ZB<kBG7N;6YAMR#ei-Ig z{J38{+KRRmKW@@v1Cxk4^IXqDd8k_<Dg^DPx~|3x5f!};jubNAx-ufX#$T9T&+wbM zDQd0t*SyP}1;t;{W6dFo5|JD2xaiiuH^0}gPRKQL9SeF!W>-@CY;IgSxgvVR+)Cry zBi<di`#Qe4S7)2}5w@Xp2S&l@F_JH4AvfxGhQH6Hp?&H$)y@VN);B*(I!@@;`>RHJ z%mB1|*S>R2sLp>3)iU(**?pPe=W3@TWcDyEv=~&Q%H!!$hX?%W&Od!nSf~V2-hL=f zKW6|-@rtbb>2WsXU&l6Svy&a?y0Y=O{9mp46Q`v>z;Y<jsaXflYRA~{XTxtlLC-S} zgPflwzV$yfGzQJ3O_jP1e;udN0zNY<WVk19f0Wcp*|MwX0Mp%d47tMi=4wINqaPx3 zvmQ)bt*R^Q{ZP@0r%&JON?FEpt1J77{`stH+t&!Hq`x0q=yNVTCqUL(TwTh*oKeak zB8qVLFZcpiO^?&E^P1sk5XSR&-kEJvzKj=B_ZM$%GW--OHm%(1)d4V?^kf^>8Z&+s zq7k-wu1EsApd{kh^T|v<GFLVrmHg-t736bx@do?0tw?OTrotiTi>e!kn^}`SIXQM> zNoi#byZg!aH9P|AO-#47F8Ae7q_~X&wK(AO>H;*3qae;3mhAVF!cGUy*Ns}T+UhO{ zrr{Kq{L-cb30Bi3vZdIoFD=;g=1uX4ON5Gf(&OZsv65qFGY|W(hqUP1sML!~4{_Hq z?FDiyX6-RPaOdPf+8f73)hp_X*@twIcxHyx9|y9s{9bizYm7Y&k`n06`4{YPFNI=5 zw2i{FvN7o*E<NdDQE_F+Cx=#l^l!OzoV!2%SiKTL<GPRDkK<bEbU0gB4<<cE${aZW zMA7M*T2YVF_d$e~!a>(AjAatvO7-N}O%GCgjIdjzNo<wdGBK2HgtwKx5E92VOkmG^ zp(8fEQxD$k+q+QEB^aqD^8e}|{swN8HE%tR15OsrgYcYU#bhX%{!U?3Pu>uj14NtR zz4Y-Xq@QtB6S3Hpca3&8I>!Y2qdYOLrNOJQ3>-bqB>8&Vz4Aq@HwCPHgLlbMjTt-4 z^-CH4P=tIY6atM6-T<qS%GwN56^Jg6^K5al7QL%a&*b0*VMOX+>ko)+y{4G?cZs#^ zW>D*Lv`qZ?jz02b?UX*-N1(2`OjPsid+aX>p1@8oQ+cmMXOyJr&d#5y=ZC6EX^rMM z83z+rXGI{?7Qz9k8R<;Ld%J=6dnA4LN{5VQC>Ayc7FqSs9eyIBPEz~?Lemdv#*N&j z;@{w!U3}nxNgH~}uVb0qiE)e^eF?$e#`jt818@nEnd2p4BA9?c{b$U9*wKy2xy1b& zxXfbCx>Z}lN!Om@_}|i#()g?R=9n)3yaTytq9v6^*WqpOQO6y1@A`y2`b|WKZ$81R zR?1=AmPlUChvG6Uejoc%m9^h@;yTM*P*Ur7ik8x19crt3_spih-(Ug)9zV=_!`$s~ zUS|zI40F3o4jO{i9{t!RRUfku0XlOxTxxf~=_|eiN_n>}?aQ<1IPFstfa<WIaaUy# zP&htt-u6fECm$nJ=Fo5j1BV<5`$@~{rq~gvA9If0h3z>`Njm8zcW<|#W%!`{=62^Q ztwn~UJpF<O3hSA&L&p7#zLDP_NKLJ2kmGD%w6XJLv#%HN7sq_=6KtHtf?G%AyXm}7 z9cdEBv<7=!f(Eo%L+b+vadkHOl_fsJ=2Zm-SJ)oK=7XS<aVgp3VL}f-Wf@d!NiYSh zu;oXPRiI0$D4PJ0I)S`Z<Ua*f|7&&79y|HQ>$XHEbm&|1m|?={R-Q8iNNuH`M@#BQ z`)8xb;4?)~Z<Y(FEXZO=F36&N><Mcm)#W`{4{;RxyhOi8W3Kct3s^=^^0NQj*u}oX zNYl%vG>4L_hr;eoA#qJ8vj)wNb8>2FYwPi@3jc&$t%s2lA06NIJZ`3?*9jQA@G&E| zI%_7kQcqA-w;T^qT;8@aC@R$8xDa0M<1yFJ+1%fTkt4I+R(#LAC(_L<$r~qaHz%-h zh+4pBDIs#fh2hasX#pyP5Hgd*?MxR}gSY-zYY41kuSG1I_R#(nB0#|mJ{tZSj>jWS zdJyJ|9>gy7<oHHPcT<Wo`1??)K3(tgffG4`uESw_Xcq|ce<%1^y7|sSBscqN58+ew zD<rUqU1N8eGA_3P9cT`3+F9B5Wz+jOxb?{NnCsAotbU1k=9M{#Gie#N_~Py%d(rLn zea)W#au{ZA7`#f_ttPhUOoZ7Y>40vB2=yWX>=m*ohON=6PZhIqy1M0{Cvg5E!^<x6 zP_@DQ_YF9fYFUQe0s&yKmUX9ax1c5?&P{Cao>5E{T$L_@z&2Dh-p{r3sQtnf0_YZZ zb#C7=OqR6e86drW!=Ed}u_ZGl52X(>`eA#Ptd3K2q^^+cdX&rA$l&bW)@pmv*zJrK z-dj4jokZ2ZhW{1$sx02w)<%yW)9I3{eB!dA3N6Rcl_rTBHa)bZixBc<4)2vY9K6&O z!C3Fy4_)v{$#=KSq&aSl#@rR965}#9KRN3!bSbs>9BqFU1YyAiJS4=Mc=3AWsr}cA zQWak<mn`U+Xea@kyCgvskR2Yy)*Xx##p$lDe|Qce&n0}?Boiuy(TARYZ@FrRE$mgh z9MKWq_Uc;p+X3N_T|z}A1qXS)z7OTADvN=rhknFCsJyxrFW*k6>!b_IEO5i8eWl;& zB)zP4J8`*b*&gm;fRwuw-%ypw$27e2tmY**<jQwW#8xUGJrYhhThO}Ver~(#?zzaE zQy-)4-RW}n{o(GT>YL>zy_7Y?=BPA(EtcfFyFE-9PNUVKtvJMPKZF1{t{la4LXeS( ze1JBLD;)5Y+RlYAd^hd~IZl5_i|sZz?x;l%E*cGIG0fyI^W0)%&ahsu@v-qoKOTFC zUXuJ>&DFQ%|MEEmD2^WKP7`*>9Xh(rWsi6dOn?n@x>7!A*tTo&_U%?#1EE=7XGv32 zww|4j9M59vC>wGpo2_}`5A6}Ph6RX6anxCW!P@(6#b$qfn~OgV6l|{lNZI1Yv+uY} z+1$4E-osW(IYFTYQm5oTUdqOnkyBzD%V~$uvoE1z^w2@!x$Xs?O_*<yR+RqOq2&5v zNJgN+EPi>g(AR$79)%~^Y8w3d+P;)B@HDoR!2HhhdWVtxTF$sJM!c54lN`5QzKhN@ zIMlnhGN6VR6OM&Vt2k<ic^A2-f|Wn;Ef#*Y-kUwr8RWYHCLJF}AqA>=V(4rIy!V8! zF3a@_yH2Gbg?`t11hwXKi29*ftl!AgI>cA_p-;$p)n^^QW0YIgA$h@4cv+*y{rw~x z+euhqFAGw@eIZuh<DuOGJa-<}()wFsT3@nEaY!ZfV<h`5YOs`=)z5JmagpN_d5i6l zXx5VMuoXPe7pn+zuxniZa%jBY5Deg@<+rTroOQgAF9=#~V8PI8X@I?$YjGWvJ)`Qu z^7U{^R|R*U+mx5bN2sHWvlB9LHrgT`KmANEe(gKk<#QDewU5AQel8fvjn7x-g%+wH zWw-tMD?Qy(1|Lk=zT;(gnj37a6W$$Vx>iS@CHA(cyU6AIkb^MAE<8xdq2(uS#EUYJ z^Lh^h;Dv^hR`RMt2_E6NQr*kJ!*2H}$HI&}(jS<9oN5`jC8{2Q5tpHU&uTnM#T9?2 zR=9$uj9+ya@mh!qV6eXy0~GV>&3InqS*wH{NLEa+a@<~VvanwF>>O5{``uun)X32H zi-WCP1!q~M7IOT7sL17kGJ{Mx%zv!YRGp_LuA&2Hb$DFI3=h`l9O#7RFU=!75P@^e z?3foNoIGdE-cJmF`i+;`6I~T9ucU`Eg}e&tj(=zL%~EgT%Z3D20GX-VyaPnMmH%LJ zZGVWVVz$}~lBlD6a8tTLWUPO|sWVOOP{-P&Q)fj3pROP_R@0Li@bUeGjE(k?`kIi! z3KIFat^O3N2dG*R`W{T?bHW(^_Vzbx9s6!DbO*>GZ)j@`Z<uIC*T@?d%e+FTPE~kE z)PlLl1fYnZ#Sfh2>K&ul^6{$fLPAkQ3is0wJ)t2UwtX9I9AY!=!YYrRn($<1`Tmel zZgw-zwZ3qv(uTCY&f$v8$ks|a>DqWZ$02?(Fi1TPKa0Go7jzskb>Xak{2=o$aF&He zttLpL_5^B;@yYEt!GS0zuK2)q@^^uKqKDc%W5q72@);Fa!3L~Dgaeh!CkDa0dY^B) z=d8E;5de4Y;}S2i6u8K@yujn$$a4n2Y~zN^z)LQa(~l`=fyA-gULYqyvx(xfulL%r zLqqCQkFhyhEBP0J2t#a*NNO{S&R$t|t@ugAqL(tMBZyCg72b2GGHS1rPC?y$?tNL5 zCQ!`|ZT1K;Jbe$_NRs5n85f|We1nmvvOkgd_Vg;o_&rJy=z1v?(#PGF+WraP?G`pv z8i4}2l0cqeYz^gjHvkx;w9E5N*j6~|cpn3*mA^t;sQMl<MD|0(fWNOZkvRNS^i(71 zOqyh0Q+jtOY~9lmlxc(mg}GF=n@y(Qx`7;vwrJF^R4<O+XeX?`D&mmez;l~by!4s- zbn~6DNdVrH*E5M5IsF`8^p>9Fo(T+vjqhb2GfzL%47B=+t*bMR0R45BMoNgLgPW#9 z(Bo6BJ`RaXbyxE?r;{9C+PTk_h=V<B%hY)oT}0yL=XREkV<f)Vl&SNMRjB_U;CU?@ z;WxOhH@Amth4wPXmdZ8W9l}Rf{?V;v5-{n}1sIs+^>&<{G_aj4%<}gE>nHfRR{*WB zMTo;!FY`>M*=I8f5Ca;*r_j@T7oepvD!V&@G=ygsml60d66+#rXK|r&87CBRbGIK` z(hQ2lmB;N()mpR!4iY1Uv5H+h2O(_**R)33NE)W)Jf_JUDO)sJS>G60Bmf&`V0Wk( zBx*`JcwcZnJa?~#OU~B4$XgjZkPdct6#`szuei?kE{r#C(^X)jAf;jCnjsE`M;-pd z(TfWvmiv*)&s~8gp*ho~j1bVqfg^2M<`q2H+qwfG0PdX;na#i1miU)4D?i|QLbNiC z>rTws@$)Q={PX8$ZD0LL{Mk%`f5LumVQ#y=%MQZ>+HoXJz{U&K3rp2bEX~F?=1s;n zJ`)<AMC2kk)+I~iJ8k)2?6>pLGTng;E90C^N6?RClz@%eX^>v*N#=HKxq=2hax!;q zzX}J1Hysbw*aH_{6J@2cpG2DzSfY2x(_GgY$8JiGJjprqaIa<m@R~8lI8TI&$}NY& zTyfZwZaS${58`=#8|})Gny)-(l3-L?c3HZ{>2fPE7JICN<WnuJF)CJ9t`hHP(i~_E z1!!#sWSV)<y|eQ5s_%NYmi$^(e5PKj`yG0i#H~_8m#Jw`ce-}}dfC0WoVzh&T?VuQ zh(gnnK7P9XOFSTbqqR9#OY|C#Dk8@=n&<uxt;-%)SW{lln8$WMr@d${&AfOGw~kW9 zgt_2{eoYSrHrosziB%D8?{27K7eb|KEXO-?`c$cAN!9o4n^@hG58{w*3vysPCcIG` z;a30PWSJvv7n$;_Y|qiBn=cG7A1iK5A(7&xJ!loLGx&5qx6HRO6gOSc`bSwwALq=Q z6L5mBU2~4%;?JHk|MBG6MzpM>eIidA-)SCmeP1DyXzj<6zm9s1(6uzw=tCzDSv_>3 zn3x`fb^Z?G_uKb=bTf`f1mh^f-~N%);kulCnUgJ5s7N-_l^{8x)o6CdC7x)a73eTo z?3iSuvp{sF!i2{+(Eg}?hO<FQ|2S4F<iibt9Lj0yIY^GoQ7{|*aP0QF=h(tm<u@~g zhwP-Xa<-1cr&HZ=BFoR4#9Ymq>eW;$^-IhTQJjzUpTE=iX;h}hY_FG9&KPvkhOryr zL4jVv9eiYnUafsPF`D_V<$WQGQ1Ee+V4iKLRH+vbDwY8D<(UL3GYGs&uoRo@rGL$M z?a;c;w!w5kVZsbq3oCUz%_#-br(%6xPw@)R$0r=edcG}u&O$I&jhE(Zvoh<?2Ns!u zi;v_j<O#S(8QNg1+WhhKSNgWZ_#Fmd8}k|(W74PCb7+D9ywu$+@_8#%uYf%6hk?>C z3?{1R+xj?m4utb*r?R_l+)c8${glOf9{ruxcm3?##HcLMy8j|)hEtMk*kcuqu<5OE zsbf)eOXO|g=~jl$zILNHs$tLWnj?El6w)?r$$J||`%7QQ4I^sQ(K9bNL9wknUfzH4 z%XZL%auBvOmnI3Z?HUi1C%@=8YKOSMJ=+q~DfXF#{wvkm`+l|Ak?FYA`$s^QjrW%l z<U=}5MDswqvq&a+$QOfyLsH1;jv)4;#G`eKD<mh=t6i;m8DzPU=G(%ieVPSuEZtoe z;uotB4HKxn`>a23GvcyVZ6$Y%!fkAY@bXnr_f^EnTrJOr7%Wm*rG78f#g2pd>QRgi zVEUkkUi@l^t#@yru^(jJ`&Hud(Z4ave$|EPRhctHLi}5N$ketGSEb^B2Qm_oa<XJ4 z`Kx3JWb2ByJBas(NIG0$xdF(1F1frQqQr8aQp;Iim0X0!;}BgfIR`{ex1=J5cYnfc z9KY-DfHw$PIZh8K-42q7Ggb5Jaj^7-R>l5vX|O7fm>*n!s+&aia~aUnm;T1wYp|jd z$&S?-19EX8wH3c6MZ$X;dzt_(*c#&m?&W`EekWPskFdvJTdL0&f6$9ZiFNH_Nl9kK zwZA=WafrkGz^t7g&p&I)<@vtj-NmWFLO^dl5lJUjp}co4BI8^0B`6l;y49ZJ7wNjy zOS>}^=ufjVQ@f6;7}=(zg>HP+aCPo&0}(T9XhgOidLXgDme5dpj@(3d^owO-w6LHA z`YrU6?Ceov<D!OI6qC&HEO;rIz5zvffb4YtEgF6O7IDhABB5#Lo*v=70MZ^hI}xYu z0?U87=5HEX=r0=E4=oY9Zt1GED#%f~@Ne^Be`66;IC`Mj%l8vG4<AoE7q5zN|H(xL zYB)xlPAf++G8soEX-LW>mHkiMLH=Ldw#T1vOp<#~%SAPB<QVr?{fcLDa-{@lBg1}+ zi~Lia7_5owmdv=ez68Yq_LUOKI5@+W6Ia1cP=<pV<o<~6w^W7W5;{-oZ>jc%_>obs z$K;^?q{9iW^K!=<+|A#+l!&PPkuY8^jj_J0S{rkNJo?uv?EeOXoThOkJ`p=^0k+UT zT8-O2%{a;VG*?pQ{XvhGUs52Z!Lj&)2Mc~m|I118x5xrilW_7<okE+`{fl$)H=OnD zJ#(}GZh3Dz<^I_P*KQc#I$$d%wQ}9N`-jxXkH&<UKU<&2A73Vs;h3YWJcOTK|ABV? z`pV<!cJY7I?ce^wFe{Eo<=Wfdp8fk&<NthmyTOU%e?|WOms`5Z|Ds$T)I59oXZm&x z_x1Uk|MtxP-01&H%kEZ!75b+a!2iER5HLj2P}f*uy-i`i2-O1b+NiDGEZI0*I4T(H z*D^G$yu^B!%vmmAS8x>fdPP}R4a{!VX)U(gNO_3lkJO(y=4BB+Fg4RChn+8}jCH;D z-gr8J#YW&*b5Xs`)zwT3!$xuC#kWHkzr0sZ=m+&sQL6>p`i1y~>YYr1IeAVqWfzKi zcYEtb0J=Fq>Q;A8XvHM;%)M!@2S>Na@PS<KcA2YW6Cp2sKDslxp%mQT0EQmEc<(ex zpgP+#_D*F?CY8M_vNY}OTsUWknLi5Rjov-iV7(*%ju#<HP`U*Hp;}NbD3I#<ywL)P z9gtEsX+d;5BxzvgTC$l@S-G#Dbbh%Ez9EotnU5$#l;(eS#_!+VxG_dC%{$wuo0=s_ z{?w4gkRs_wcKL0RGC^?uv9^m~Tsf_8@tb3RGxC_|T_Nv$XTRdFGcd-q_{h|HUb~5- zOhKwM6>K`ua0+&M{LiK{NDST>dpI2{F8NfzR`gIMfe1MYbuWoWq!a2lmG+ZD&^I@6 zmL>00Gs5}AGcJA|W@)~+Prd0gHT#xb+|gChBoeQ|j5|FMt7;ehN=#T*)iegbp;g*g z5gKy(&nEnr&8qa;Snme#KoPYOu;MmX;J7ln!I7^j@6z$p$4POHQ%c=GP0Y4m|DIiM zUkS6p0fZs4cY1@J%I&7!d@Wm5XTlQQAL-Qn<hpNlw;IxStrLmBqAt}ZpS0T1RGZe( zlR6m%A=DURxiJW9?4X(SPlLqEBJJMG`EURzawnlhv4-hTkwuV4U*%X`Ay!hQcbZ(8 zG)&&>lurGFqP+0(M7dcx|5<2f9alu&^TRGzDeKd90mm2V9`k^o2l5X>!tfd%p+{5Y z<wIzeNY#kbey;=nd>TOW)_C?Nu(Xjj`ZzT-FkaW7a(#H&G#1MHWS<o<TF1gUh!I-1 z{BXxyf0SEFtW4mD8KV#-hiYu>%kjuqdgM`yg%<0%V@EX9-4rG2&EWJ2sj`^4mX-dr ze80;(n{;~=(gz1R3g=;PIdsN@w&#Yq!$kv4q|UCMnkGUb-Qn`;$FLVW`J4}@O(qpt z7#AFm<ko0`-t3>-@c+zG8&l&IvQ~BKhxU{Lv5DfNbw1Vc(gSr5OV1M?5ZPG+Xs4N! zd7WC-%AMkNf=Fwe(Sjkjt)GWRD4v(e=8IC|BFrfs0TPc80S3i=AC(8nE$8|B{ZqW4 zFrA=f0B(?Iz8??8bZl8tT$#G};zr`F002Ex)<4VlTa{S)LYbWSjiSj_FBJx5BuiIs zYBelP@{!q9(Ud!FcMj3FU$=Sl#y^?tbRwQ#ayG^``m^0E_VfIH8H1v`VUy;fZsnZD zXp>#Sy`SpelNx*Z294rEJ(YMV;d1`#_!*s@_Hb_zpH}5^eFx*PdN#wtHULA2W`%81 z16W6X^CCIiK$sbUT_GC13P=-T1mSy|?XNy@_`tUf(mrDV$8eW%cisSor<f&IcP_2` zThZs=yDOSBIrAF@fXl_<U8c`hX0mw`1-8WTzMK6?{W?ipiJn&OvE}z1OFmeLKFDY@ zle2ubuT2&^Uag{A-*Lw_WXe8?nI_4*pLB+xw`VC)bhFMvVMJ$T@w#<$<9Etw6MOJt zu_EgPUXp@B|A;KLnLqc}0%zYSS0R@2)v3L{zHIyk*GST7CY{mPR?iuB|HT_6U)^kK zzw1lM^!`CFt6!F4z$U<&(5@P;ZfQg%a(dGX8!=_Rw`w&)>NxNHGKrJ-rc(IF`<zvs zjr>v12}5_cC$p0jm^WDcv%`mIHP#1cNx^fhzBFYw0ss-C9<9BGiBGe-u}<&bB~}a# zKGG=cXMp_V@?YJ}JZbqrFJobs;^~$D2Tc=yxrh!*0h>g2&xvYv<qeejHll`l#2g{4 z{vUSY^9QkKP43<AXI!)Djib@LH(mz@0CY4)>wOZA<~BJBJ{V{jH&B3rd*J5<jXWOl zG63Ga(YqlT+exXxEjzbD+!jV_3we`-PZCFTfm_bC4OV;M_>-DnEE4Yg3^{X1CkOzj zy|nwo{vJ<Qp1A}7+B%E|6%H~OdTMFJ%voSyb>fX3PV(a&&NnaRo>i^&71u2y>{k0J z-=2KJPq^2ri6XSyCm6j|Ymx7vn?YM6L|_?yrx0+wAWU)t82YOE&(7=nPdT2geM`h` z;{!X)ohErpA>FU#^3;cXRb;}u1!Fa*+cc~35Haq#sH5J|ph-&R$N5&qiuw=36bQ+7 z?de-wgLlNg%J=bj^EGHXiabUN{5+5~^xi(fMvco&5ljl+04h;Q{0o=$pVKDm^SAh$ zz}5CDF5trQxUYQ6J!E;L;ghHS?iSa=<i?=aty{~aF{yK(0$96vU&W>4vD$LW)Okl8 z@$(E#eZP8@B<3xbBzD#_+ovw=NAsus2BwURw*mmV22YB+a4+@aBe(t^p4Ft!12xS8 z`5LT-`}Y#5H-)VeXp-DB)(U1b*I1os4Qh%_2gjWCg#7Ehz;&BDTo$;QpY^oDlicKo zH%^aik1w*v%Qs!!am-NjaP7ay9r#X@9%S?NK2Gmt2&4U%Q}v%vrAX)3gT;=p`fNEX zp1gZoKZ?aFt9!Zd>p2%|OzzSSAjea5zcjNxsD*B+zl_>ee~Hq|8bnTd#0<<q)EoDs z57#m&L@ws<vXk5@W+4#lpIsPYl1+$0%VGMYA6Ln+RC^~4&8n}(uUz^IutGR>dKp0t z6yj%RH%AxVTJ<ssY2;w;;5V3!IiFSVm0D(ag>V_xy!#Pw$nJWp;SWVB6!?w*R>RY= zPSP5?HNh+$^p^6$x6u~!wu$iX3JNTT%f<IF$hgb6O`qnz?q-3LeBLYHBe^nu*fSG< zaJg+P0aTM)Xb>D-fMIp@Vm9EgO5rA7E#xkXRaO=3`!Uxqz{|o~1Zz|kJx_0?hBASm z2<9+>uU(R+VR0hRe6>tHAiyKObJf{dni#ngy{!MXe>{<~rZ4NAvEuQLT8Wpd|E}G` zQS6&2%^|q&+Mjl_d0EI-CBry|qD}b1w(v4y-<*_at^kBpCwjMU*vpvl!MuoXMZwQD zg`4n5&p|gktf;_k4gW)j&Vls}hAj`;#D;VJB^je%CyZz;rMf99^a5;;_&APmvk$v3 zf=A5<-%yvn$ul9#ZM{0#->ZQec)M_`LAv2K%^yX@OK-@N8@^G{Jd2BO>o_ksoOtOJ znnMFC(uPhPoU8jLk$Rf!JZwr$Y}>Ugzzk}{x?8?&DpLLe)j;8W)0bE9hx=`A5i)de zoR<&*)ZNl3lTGlWH7gLz%7n6OGk|mRaS!8|lUQ$SNBfx0#^fBq0BO>*)P!X^fzc02 zq&$vEITaIz3lSF<kn*)O;(PY7p(XUQPqU)_Q0w(6lNY~H=&aai^D;!pZ>j5XU;QwR zNppxDjr|&*n4r*mVI8{IL$`9EwVo}spwF=%>okKK&bnqQ-h8CiJ``QOl{nJ8Y5U5D zdfPmy$N$gndhLb=d2-6P#F9xH>O;!Ab}3y_Z^`}yWy1aZw|lqmPxIa^Ci~OwBhTCd zRQ-+nXZ%XM>iQFTlbBLP=~(|X=pM-bRwPj+!<`xZC1H-GB6J^j5H%J$KM`mD;}LDC zw<NFu0E+R1aI?y-^VWy#DU!<0WPdO&=)dgrv%DKZZ;boHAFBTmcK2(6lzuG`X=(f) zFOWHIC}5$I-1R>d9v|aN<9?-L^(TKSvUt4Pb}77!cz?X=pK*is_;M6d{`847C>~dt z_kAY&=V<%4>z<L~=H?B2<}hda!z+|@adQOON!9-pX!^fG`1h6iKUN4#?|;5l@2XVE zk4}#7QY^@45sdks|H@eX#*C7}(1nxq8`(Fj7X{@$J~FF?X)84wVRxEZoU2(J*i$sU zSTgBuw4L_{*4zz&XT4mgG-Ej(Nsf8;WUVn?(Jr&Pq^EnJGd|qBwuvmRADBPAUB}7% z2`<UzXh>G#w{xciI<axC>qaHQTm+BoA&^uSo9ewt=4yqgb8vF5?TSr2ElvEg{(0_k zY5H~@0L0G94k77jRWDhZg{f@0pr7f=XQ+m_)pslO6}+JL!W)=~OY=o%5@BNP6o|25 z-0}(`^DW1BN+4rjWrrl5+kF0yO7QX5WXyQc*V>U1n#|{tsh*4>Ysv@Ghj&Z#dzMDN zPqfDC(vkJ)f54wNW&O~!yz;q{r2uxWyGi|MKRQ<eP?}&cr<dPHyBej?-Jr{I9}43~ z(nNQ)bTND$$Q0)gh}snzV&%p~;__>^0!?bxg9|K_y9L$+czsP6;(XK0k%vV`CwFGX zrkKN4RJ39p>0{X%j}@A&220J(IgvF-g0SjMkrBbC-pN#pBHsDBsYZ_`@>ufMBk1Lo zvKK7BDv(J6@hZdR4zU#`=){v|hfSb{2+&qkb}J!4Nz|0!Zg1<u5X8<E(6M1&vGv>x zLMyTOWX(l7$>u*AocXUflcZFFtmQrNjBtgDoxT=?@Uql5o)WxxV$>Ir)In24o<ewY zfN$pY3?W;-8(I+b(mA)=dj7+^)Lqltwz-B`cFlX(g0;@;y3YfQrYzxT#la4PH)u|Q zZ#kgX*NN4<S_DwifhOTM{dgI8G7^7+9jm}0rDy^(9jPFLC^aH?>xNGT7ZagLovc_j z;c@e^R}e|W)<TwYTu4K}mE062O~}fi<hrs;KC+VMfvgK&O<qk?p>Fxxs=jXTe2{tj zLdSXi?MDHx)hC&5f-8o-)LN&?o09aE6}k`VdCRrRW^*xp)a!<u6Y;A5*+36)|2mDv z=`RD;&j6s+HlD=L&xud^`Zj=wxJXL;h&%xW#Qu|B<tN5=>!#1IJATtP<G%NdQY?ub zsknX3?-Sog$r<Naw_)h)qq;0RzfmKe>sQ!L(JkroRuRvwarcJ-fSegaepEDmr{@Ry zDMI7XZjpsCE*iu7pP73%L~GUw-0)L}e02W-_*(eb^(WRs7S94)?KXJ>zf-$Wd@8)) z!k=-`>*`RUvZvP9lnhwPy|^wJK(grT`~!J;M>9@p2>;i=Xe7U<`nRtKT(lEhP>j7P z+A`rFmLGEM>n0K}{y%o?e0KAfGTfPv+?y|~ts19H31S6l6UZ{S5xiTe!OCTE83-5L zop(xsTnE}l`^#B^lW*oB#}*YX{VXYrAe9DNC`CD+%$^OB;I*cO;C4lDyuc>7hsGDi zB-FojX!qcD<01OCT@0tSyr1igRI&~Sd1JB*v1g0L1X~7sj#iRpHN{$}&`vBAt>uo6 z^{r^;kEzwvX?18hve&0JKpwFZQOu>2I8dSd=nZ;yrneT@?%1W!0eHh~-`_HMX4=nR z7q?7BKFv!cn+#<Nr>f*|`%<<$e@|!3<C?;M&b%0(-NN|^u?7B1UKg*{%a0`0nGG0( z2?WM0`KWrge!eT0zLL@5;8hmnq{6ZtnyB+4dXu5i@mcxmv4dSKg8l*V2*c$;6=Sjt zNN)G|jQK%#9ey1gE3GaG-)czaI<afgoY&huudj{~zj}@{ZoLdeW;>yiQilmi2sNk2 z^CAQlw(`3y^~Aj{C`B7C&NZXb*wD1Y&NGR3ZuLX^N{G0cWjxF1W^2rQUA3l{3kvyW zhC{Dh*5KVbuXp>klr1MT;C&UJwxbb+*6QnVdPUE>_ofuq4jZ-Qd~TSY$JO+l0tGnr z*7YYA8u#pICo@0W`PTyz7awlCNKxA?wrxnFaXJK|kl?LyKwI5pq}?0!S^ro`y4v#u zE$}E@%L<ejHfN^Id$@M2XbZf2QO6Sz*~-(aNCg5~%LK6uK=Zq)=tP)H>W*I_`SwTe zHmx+=MRr*94y}h9((H0-=S~It^%llC|CE)Nw*_|n>@N7>j&vb};MdG95A+n*N_r57 z%!Oji%NX7vB?^(5(A;%iqw@*y0!x8VlHw^~f7opaO;hCVurRtVyM{GWz)Hi5q`{K@ z3-d1fiy4=Rb%$1tlPg**54{H!tV;L}Gndy${O@97dhvwKkhb4Bg%VpDH}IC{9i3a| zkB6*4t&VlFo9lg8B$9m1w+39RW@N+(ep?3Ym^3VG&r<IeHJc!|eNXg&?`daRXD3X& zG(RR2-`aOVH?{Z!>LdR`+P20643QXYdwJ1+!OtGefSfAG0Tnl(o7ChBxVL>3QPl<1 z{ATF$Z|0n*D_&FaUXIoM+*hrJNh2<P%1^6UJy3LG=MaOW1N}7XxAXO|nplaf*eoBb z1+fZSmw@=hZEVL^LBfQLreaLSc(Q&&rFFjwoM)@K_K;u!eNWvI-m?*$sx!w_Sb2>7 z?o{9BZ-lZ<)iQw<!aIRaj`dwptcfuOU^rf-rTyV50ZMhNDMh}B#qBw3(u5&lLK;Q< zmK)fYv5(!gl8Mx}D{a#7YD7xUpHg$fchI|dGnT)inI!_P37Pyx0k&KBxr-%Q0%@=A zu36Ce+LtZv@`)xt$%7YT>cL-q%P-uw{jB-jpGobutT`-L9{MVQ;m*Ddoq@iKt(Qmi z^s|l$luCKN&rA(4Gkgd6LxmPs2{pws#M|M3f>iB!81mrsZdR7o#du|K$Z^as1T-cx zZt{Wc+FrG?I(=Q0`~Gh>F2%2qqu@=low4E@VsTA22!ja0Ac?vWRl?8nG-S$+huh5s zmdfT|wed#7>8%rgQkEA8*%X{FIeTHV9HZOxPc0Y|${PC@e-<n*`3SP7*-nOv-@%%K z@=I2e?WV=8EP8z_<B<fIzR}_W+fnAxb7Y0{hJoed=_D_;`kk}9qWr$wnS1ziq|J5m zQQspydS^4Rr*_Kc`1$+XJi?4HDT45UkB=Q&&P((z*S>^bpg`rdBU1-RXCK?6@_Q+b zE%^?4E(4_zxU<lpNzGk9b#kgdWF2%^D=3U7dIeNW-m$7^u#|e<IG4p{os&b=^+ABE z;B8AVu^F+nmspzXedq|?XN=%nR-j__JDRda`o!b4wKsj`>ATypL~vR3bv9kJY0GLz zg4Sh<A@{xhnh82X5ye?E_(7fB^oO3g#4AmJxMQ8-Y1EndV4T5niW$Gb%H++_x>lyF zj(gfwg4z`b)`=9U(ft~6yJS^M|93U=`0kSmHDD>dERP$s7k4-cunCs=XALhI`dJFD zf-DPcALkDET)$&I12NF{nGrZ_%t|QtGi~X?h~`UDeochi_`Xf*5ZjXa^kwFd&1^2! z{@86p5o}aCRo@#(Y5+Yrz=RwB_~wDqbMa7Os$!ikq~@Ra1>D#S$9TX#^eOY(#S*N7 zMkg#6J_UkpX2vk_T#>;9>9SGizOh+Zrd?XSzZ%A%bn3o3uETHko(^HcX?^omj^~ci zqA%wX8wLN)*ieK0@%sA=g#p3D3}fF4pNH^R_hLHBt6z*2ev(qRMUX_C!?;D9m;8Z` z>7v}F=fz6%LB>g%#oKW)=N;I^7luAwapQ1FM#xRIE*o_2@#eQtIhmWl%0ly#HOqpP ziFxd3a5mPb==hM;K@x-HI%D-ZDCS<Tll*Z}VHY&Vj~>c)eKE6n>&EBE=x9O6?$+T{ zM%=gU;QCRQ)mL5+$c#tE*Uq{PKJ(5B_DydlZ<w2^zlCqThbmuI*fyqzR0zgCDAsBj z53F<(C)p`a8h@F@kBXdj%y9e;>Dn?fKulV?j*GW*w3cfhw|<oer(DE@+d9O;Jsba0 z%p0A%bUku8%X~9ayKH#6+d<>(Pk4lb3qPm1Twr=%VE8{;)Z!0+g>XZ0sH*_aF#~g6 zE%$^-Ew`>%pg(Cof+o=tw!m1#blD}(<rssc(UJ3#b}~D@VE1xAx1fr2jZ(xW(v7NX zq+Ff%v|a|fIdRe|)tY1qFeCgtJT?|^7U#4T6q4jqI@OVXNj%<BsOm1?K~Y4adUX0@ zBJnp)n!e;O_r}cro}G=z3d!C40!$9Rh#5)W_X2|?rc%RVs)&+p!b_9pm(-5eTrNoW zl?A{7ycN_+8g@?+oYe|9)!gOVA7u?03Nv!*IC4IFhWt71;)9m+v$*eA1yPu#=S--i zym&<xgdbi0IJ&LdHviC|aefJ;PcZBu=lDtNv9{HH1OwS<<<0Sl#^zd+cg!Ip9XrrG zfK6-%k3gu%4hTTe=E5<(3;ncBN#}_i{+R#X1*DsI1es*%dRN?}<FA{UNa}b2%%EC( z0y^(LTiI_xl?hsO%lD6T)0p|cGRhO)zAzd;gkwv^Kn+F&ht27?%+DyEFIlZ-4$Fd` ziBc}{m-hGYuP4T&y#4usRLds%RikEeH2}||j$Kn}WvFA+jN~k8ij7%e*xV_Srhmx{ zPNFzS&HVH!lcLku3FZ-7ut!A`D_QfCdF)~fSQ$BJXn5$ySIybQV3vD$zh`e(VD$O3 z%le<XAUDnvb{D<WZ9(Bz<o$EzR<>?_(X+T*VV@C9=H_W4&!leV-9(Dn_uk(2*=@?+ zMq8;pZloN~TXT?|*Gu4d#b3MAlB@Br?d-;N@qj$8fiqegYNL`T9!E`-<@@8py#LP1 zcqI`|P0jO)R_We+G5`NC_SR8NzwaNgihwAgC?Jhe(%mW2sdNscMkCz}L_`Fn8I4Gn zbjQG;M%Ngvz-UGf7;Mk{e15;@Jiq50zvp|-{@dBvJFfe_uj_inm4NRRkM$~;sUN7^ zcv(UqcA1BVp&Mx~?`yMz4Gv!MBCn3JzFxdo4<tc2^y7PJZnugrJvnW~)doZ;fY;$W z;YvDWhGXhho`j9y#&%GznNpFCMuk++htrU3*t@(JrX!8gC_yBBYMXmN4<n*;sZH!e z4zOXN6TTyUY7efQqoGi=&DB2$EhyS1Pw=^5Wg2e4j1rMFYz^SgwZQUHzqK!2Z$&t6 z7y0ABkq9HSu!BUpd*p+Zv<_0(i_-YV&<7a=nELhqU?`v0fon18IpJYfnp&@vN{x4n zj)E8u3A~}1wkwUw8{psgZw-U(9;rU0IpM5G+XGFp#89Pfr<~h({(cjM5nLv*6d)Li zJz7}Rmus@fbfVmu;1Zyg3Q~~lnocAOE}N#76<r6OtEz3(8A!&icKn9UuVo;r)gniR z5?cM0FQvpbtG_Sm`h4DM8Oi-@Iee4eui8Oe`E;8?*QcE~;&8o4xh4|)4U?iau!&DH z=HFnj&?@gFwx2}!@ZQ=HpS5QnnA|haJ;DV_k`6=eCO5Gz$yZzSQe2CiU$?G+J0S4) z`~04%Bag?~G^Srp9Sj{Jw_QY+!ZOiN=aTm@`+R)pc$5=v7+#nJ#yI{&YYlwV8++?( z0z`IyCK{3@WSZVe9z!m8`TPg>1D|$b`GP@hn#E#!4%k7!t1RM9eRo2(cb6!UM^r=B zq`NtDi%eN~&nctV<BnF0C<lKw1Hdo(7M$6Q2FXb>XC3ji(y!V4-zh9VtOI^lp`6EC zq_O%8OMq2$NJlGq_{5W5JrnNVUiX!aoM*kia(~Dwm@iFiioq_^Bb$jx$ciUrS=P;* zJg_PfZED`+e6Xy`b?%;Rqzu$AgAS)zHC5*fKW-6;DKiJ~O>1;L^<(!|%Z!W!&($5J zvjJ$|q2<50B{x)~%Tspd6v~?82j_S?5l@sVsRc!=6WXbq$S(Uc)e1!9CRG)XH)UFb z!U8&4XiBDAoGjWKLORveeN0Mg?*Z4^K^;%>V5T33cFexiQ@W-#j+%wDVSMFkgEE$w zy$mMc&wYKay12Wl^o^J_2Fm2>?L9ou=pTC#LJB7J=M5k|lEF$Z%|WZt$vSNMd|t&` z7=fChLxSzI8fUfS-GE9%SM}YZ-q6n%ZATZv-QAfXtW*bx9Ls%k$}LUy`OMvpj2KBN z6$eU|oac5(y}AZn;Li9;E)D=lCiP2uvKnebkkLkB)cy)DAE%iJe@QKIJy&0MVF$Vq zFS4V7o+~=jd{Rc{O~4l7*5)^yMipiIGsjS|RIXGv)~j(wSsnA{W$p~z&79S%tYxfK z`-HkW{OJ<6@(f&@z#z5l<P&d{(B;`@m&I-RN$vcQH`YQ;<~v?GYbQO1@Ps^%3RCop z_C>}dJo-A{X4*OvE<$gU?7L#;nh|f)9A74&>+H##+bpq$8Pysu;~awIwyvw5_8t%1 zz3l@mu0Q522g`uYwOY-<jCGeiW#It$+1nt^2Yv(;$Ct-n{ZN}DLC=PHz;?F!;9+P7 zZ<X5(?F@$M)tjwbRAAOKxD<;=%-Nn74e@2oLt>{inJU=#cjynfP=gRko>7^YBM{Za zXsY{v=s5gSt54m<gb%+XP2p`MSU<8WUOyr0D-7<jqn6zwe%uz3k_8xF=XQf?g<Idw zcy#sCJ6ss^oR6NEW}=75#-74iemKiO9$4Z30$5Q~ye&3ZUryVo7$xBqVN(4Mb--p! z7TPkR;Gqc2KcLqooFZtRQrl3IiWc4$#0}HZ{3P+&2H9GoM2cl>^A3}%PcG}mB36v} z6Z(xXGFi5pQjJ}K8G8Fc8i(ieFIm^Zc)@xPj7OM`N1l`gP0$z4SpJ6OLw>-7VNS1e z0GGkKyp}%N!iL2WJNta-d)e)s62FbGr;;(M^CH~z)?lzKD+x)~F<$wZs53mfs?Fuo zqK>ZMxn_ko4c?F;jo->N&<)sxnPhbUgeXw%FaeI%@()(Jic6O#3N++4xry3{$1v<O zG<YX%dW5h`;Z5jWp(B+0qE%<*rEA&rrQP}zR0oQ<vg)Xxr&;q$14e5gvU#ybHDY5f zMF*j&xrs}5J{R&F&Xz?Z#N)0*!~*3vZw>o~g*6&kO5TzE{9J6tfI%eYWh1ZU(G-lz z83OH(-e<SVlJehQ8^K;KFXv_F5IMKj_-O29DAu+8PyrKo;DafI2o=1Pl)ED5e=@Gz z&){gTHC`$`tGPAbCMJ2!TBbo<MZ*0em28$D59--hK4CXD$LMLVGXR+I3jF~ZIV7<7 zYJ2_Ldb$ynQD3J>t#le;l^@O8c+`Egel*P*!^+Tt(Rx@N3}XBsh8vl436?*`kE6bp z1i9G2*^dEE45R91RnX!_7(V#rL`E9Jct)Bhv?5(7-hXecF~~69V3n7)7;ir+-XAK` zdMbbpTGJJ9`*zh%;Idnq_{nC30690vK1PPQagTkB0|BL~c7|<y5QBcoLhI|)1D0F) zA6V==u1L)^Qnm0YW@{k!02ZDjB;iw^^N`N+@L{*I%dgPi-rIHJBYKr@x`CY|=97r5 z)?P@q)zn4i=(}L~QUWq>r-LvrX};OX(nKU+<FvNBb=!p(S9hY(FN<ir(Ih7;hIz(i zA>T+!1@eyV7vJU$dkLefz`U34H-I2hQb)+%@aeq&cV3C};mRrMaIXF1pK3^?%`ee$ zeaXoY`<(C*B8j6pDUqos6~2gDM&3=evN^6i_xCxOX&fdq?=^TtC~8U7^K=~RwconQ zX}G*S)@8?NfZk0wGdb4D-VDZgWlx;)N6Y@c3>+0ihQ7|_%KJM4n@;jizm(z%FY6%> z=i`Le1R0O$j0JDK8WLW*QOs-g((2+vA@9T5835b2#|`|0ll&1^m7HB({Gofh^g{Qa z2^EG5B1+@T!fJ(8%|Xu>ON4^c@gya&@(uyaV$QXG$HCw6v=O>GODk!5xfd}3UJ^7Q zTIG=wYbq-QtVmASxa4ptUCzOQobu;L?QB=&h~}&0tc-73RNFfHpNKlLa<x5?R3{g^ zUC&K`6||Kr?s~wy`X9;j99I!@z8|kD*|jeZBm!<4ug>ss8Y@KH@TGo!qd>)5qJS#9 zTM+#r##C6`E|NamGtl8>B_n*kakzJFAMMQgnm8;T#|Uv|s`;6r)w}Gza4h+?zIDyA z_jJ|G>#`E`a(SsF;wzry=5~y0n|NjYqjNClT~t7`EjFmdBG!31Pxz$Dc&YzPyg1xy zf9URmn{xY|%w-Wn&Wq3OcS`5Tf&nv4#}RcdS|z6(s0qv_*Ye^%NDN%b>EJEG%*+mA zs)ii45$AeuOdWt%L!JL&939<K)5I-}da_MVhh^kFeA4uAf48u_AY%05F7w4_4(#XF z54<A29o@P%%2u%y_Yotv5RJ*Oeas4@AKL><*OM3mH)&n)J;`SW=KS@WUWJXl7873& zWMq!DA=1}JW_4E2TZ50cL`|fZhc@zDd%2h7R^Nk1q~xaIRpH5&XBHBYw6VPRl6O>I z^{{ig+%674(H@&{xBZw8<2|H&X7aw-foW8&A`K8SBnceds%7-OteHnu!JiY5b?`bm zi?k#K*(pU(Tp>UiLK*%cLyWV68Nd$sQoc!S?2Gu#>sk>%&=3qZ%ZTyc1L3VfIr(Ff z8X>0DoxZDc^>ZxCeJ4vYg{b|{IjN(>l-}9uaiWwQ=h;(j-c2B*-iFxf${_V^WE>h} zC@}v`@)P=F7yBmQ*qzHu^s{+ye=tIVa?{Ay_c-)*p-^?yz{vxY`4GB9uC!mPN9ykY z>;LAjUT<8;@l7E7AOjE&^3%v;yeIgCX?F_+2!$6MPa;GPC;TI_yL!O#pP$QurUZr^ zcYGWpdVLHMBQ%eWL$~&z*QC-^s`rILe@WNEZybpXfDT5Kz{UQrz{M?-a=Q)~h4w(` zYsczZ%I6c{2M)}V&>@c;yWW5dR|kTQHD6ly43u|kvin|h^K3XhS*pL@xz5BlOXpRl z)sWc7_hU0%fgRQh*NCvRMxMa?#y{w;geNm1ytOlWaD#hcY7gjaNx;8O_3AtK7J4%L zV`aBf7#O;V!4EJLovC8~bZFUG19}3n^4buIXUsizzDIbezmCiA-kv%q9L<@N2$>=N z;Mqi|m0d+ml3kws^{Ngq9<rpigN3A*$=RKo)pk6Aeh5<Gj|<Yd=LS|v)jfsdE90M( zKc-L9lRbX7yS<ZGz9M{2nHLJrO67b!hS1my8DF>5rAijOED$;xF>@cVq?1a`Yy75V zOL{+xZ7HO06Ys)`L#+9Df0XKhruEr!@bZL^;C|{pH#sJ0(cOL}o$B*1lOWgxk%ceR zq<q*EQw89xWQytLqHKSLwtR!2s7?DiFnU0t3dTB(Fs-*&BlHwQ4~7})&B3TSn%t_N z!ww^*zvi+wnt}4br$kFHNsPSMXqz>$ja$?iqdyh)5w$_y1j5b;-ebF_oO#sn_1Oj& zwOU9@(v(he(nLo45}hndiKkGyF?#X1K{lxGIBl@DDT|LUE{GRF%;ez+W9=-z$Gv4o zaFe34I-rK*io{A(@6xtf*u?`l?Lm59LN6NLw_lc4ynJ?Rq{HbaONccn6j6O}3{Ow( zgX$k7!{6JRrBmN67P!n6`3`Qc%*_(xTt2ZNOWtC3i@OS`9J>fCyZAfw*UirS2m4!y z3)kW)IS30Q{nCZPbG$YLh8|3r-Bl5y`JWIzBxvYZ_jp^fR^&n0d8^NSnR$_<ja&18 z!bdab2x3rjC5Dr@BJP4<J@n2OltQ@u5H}10aTgdf_d7@9rn^ws&&Mv>on=sVS04hG z>pk11d;&W9dwiq6W|)t)!MrL{?x4o`tsT!{%4E4?bDjpRBM4yBl?K#GNxv2xnni5M zok&jqZa6r7;99U#QF|AVLAyIbQLF)>i#NWsQv~03^a0<lO;WziCBgbQWN69i5}_+y zeC=8UTOJDUvZA&Rnn%CIi&SRxIeL#)8W;4YjQ?enm;4Fr1vO}id=xm!C>IQH<s((Q z&T(tVG>{jMn?zZ6W!$bz`PDHq6YIUDtEL@a-xW1F45z_B(jCPcK^nCk&!MHC!(Y<0 zcXGvM@Lu)Z3&nLm7K&a~hG2F?(&sMSBni=$`j;PEjp~zvHwce*d$m`W49lQh-t!vm z8Ek-%*i~h232WHUotKA4)O})T_b&G>YU+!j8??;8{esr)G{1cSZOi=7O5PieakE}B zmqQ+-W=xo@%9ppK-->{vJ9Vng+3*j)E82^yTLrV9HUE^Ns^;^bUpT&JD`sAhSEfAg zctb~4-fkh-{(e~EsCWn57h?moTbq3a_iHgyj%A``cE%LIjXJz?hJ=<}knaedor-JR zN5oqNr*})xmhIVrzMi_@z<Tj<MWs!DXz$MRiEWDLE5aBqkN?=U!N^2HB6D#a^-%@Z zbXSL_$c!#4n(toU!g(frWi*T9{ei2e0!W(Uvm>IvGMmHUe+Voob3Jr)v><sVAI%6Z z-?dN@_YrR^;&<nS-(m+TR98t<70K#MSQU#oUgmoI*bJk!{FjFrV)CUc)}rmj8N&k0 zIu+U{`aQ3dS`5L>$^-nHitEJg$0J2G&0<2~n|#ypJABi_zIS=6U+>2lzwax3E746! zBc429qJKMd-JP!ZyzhfuxcA}v-_XYN9@*B39QYmb{O&Y`h@k?NOdknGn~O9ZC94=v zKp9i8Iq(t3wUuIQ{Y)4Git5}R;^Fz8Q2t&K5n+=eVc?bv9oh5%t_Dm#5O~|@+m#jZ zbtLT@D$0uJ=TRoEU&6N?N|B?CXXd*}&fE7^g%%r>JTf%(I6Y$^PXpLAzV6kwYjqPF zV9%GG0BqOk*9z?9F`r?HL#^AtIigw#nWRn>1%*Up*ERpJYaj8h)d#lmYjue7&xtMb zb$qGR8NY}X?hTpUF~bD^1lmsAc(3B5u(975zVn(U`Ue%OZHE*pJy5iBf~T=LqsLTv z5pRP^W+y?e6Fr>GS~xcJ%*_;O-VxN*JS-z8=Ci-}CT_a`cZ`Fn?P9a4yN{=EF@#vE z6$x`wvG|PL5n9caTKmLjFlf<iq<)bKv-|GG-aWEov&uLs={@_MaTeEPV3)3lGXt(> z>`%iMsSn)>VY$L(kefprfU|4@F_~RUr(u$GVLYo~jp@{_LpO%zjX~p|&1?O=cLOF! zzU7>T^Yl)b{DCZng$V<d&K^{|c4Ag7Y?c7Be>ctIm-+)<>Pn?Y*gSlEpC6nkK&UX> z)1Uwegb04Ak7$^yCrXddSqgh6AWkJ-(l3k<z!P#<t5+!&NbBMseUevpK<L#yO4q`b z&D_x^1^%{#@YwB{LH8B@!jPPC-~UC;HY7S_r}>fi2ChrHH9^!H%fkg-FC{HSHWN&- zJ3f%Dk9L>14vuhn0}dFps|c<%13r&tAl9JY84KeCc2CKu{|`z1@qM4OAGE$|%a@#D zCYbAnk=eSQ^jg+hw|LSno->jKspyF7v6JDVJ11iGop0^Z_gs<pBxysY259%GA_wo= z7!r%Q2M5GR*Y7*)=HrzLI7?%{ea2CUxAsNnB!U6IWG$Y>Jq~}YJw6_Rc9b}I8F3QI zdCQDEzssH{Xu5OXjjOjC^$~us&*oer`a>EObb{WBsH*#A=gd&1-uXVR$dQ-W8NE(0 zI&AfA)7rZNGMstl_;T2SwJUVLu|83Bmd|TFD`XxDq+8g9C{x>aDL^A6iV6#N@(m{3 zQ4ieTQ&f)z!3vrS<J~4R9LOVA4Px(7VmHkcie_~c!OC{$!-b-Dn&cX3>PlxR!on`T z_6X_{i=m)+=f^&wU70jr5yul6HVunDI86an_7fs_gL`}M-dE3M!BG3G_6^5rzXdOz z1jN+wa9!&t5!6{uoMpOMS<L^L)nvLB^jJ{N0=<0WLia0Mk=KRkK;#8N%#2ZCRFIip zsEsEC-pSWx^C%;3&&gC9r!GFWaZDefs<1t*!t8YJQRGB(J#B%y;L@QX>hmuc-VZJt zC&ZRyfo?x9$2SuVNz5Df^L}lVbS7f|F5XDT|EDZ^Fw|2^M103KdE!;Q;qLtiC9O7T zoq}12rYOO$yZDsvA~>^)%s-MCwv<q2^orZ}^nAfZBsY~u&VwQyprS{-ZO2Y^o79Xn zPl?Z@Q5H(wOiL-e=QZ=_ZP~yL-61KSPMZ5~`e}9zHY}Dkp@<wq`Hv&rV<kfT#?Cow zmKf2>B~Rly=P&j?W8P*?g~x@-;~B4+?YXN3C1S3ARj)@#+_7J)UYzA|^-1mOnV6ba zv77F_R_5F(pz2Pho8@-)lRDNDkG>Utb4J+}I(!NBvn)4%^HD-|12M|C^V<CYZJPD= zy2|*^8T*qu0;_#!+Drpl433D+EPY9x-%WX(*>JD<sA+I+Bj=_Z_VD`#g|r*L>bF5; zu>j#t&I<$Qn&<6&v)y!Wd?)-b7Lk!l1)A+5D+Qh%8E=KdSU9Wai=RWS%uG)?QrIM> zo;dr_+%&Y4oW08Ay<V4!jwRj?)n00~b{*>1q99Y9&n)Va-P6cLTQ?=Ui$3d&3efO# zT;8AjOtpN<$UXeHp?ROG-l{jvT1YTMC@;O<!ryfTzbPFS_-j3`!4m0^y2SWN?ZT*w zb=0NOH}}<ZHdIh|GdgZl)}Em~FlxyLk~HmWl4W+r!P|b)Wlk~8t1Mqa(Xf`r=o9Le zx{K-uf-}B#gvu}rJ$q8_ZpIqx=W=}M0X;bSF!fJg_*e4jt@tZgD;QQ<62OVSZJXIA z@&T9lc`$*GPa6ojUHb96TTbIN)0h7gH!Vu(_2nj@W4bG4<?V$V!dh!)nOa!4xyq2A z0hp=5U#pVnEVG2eTp6)vT#Pf3af5^FW}~vq(=@RY*p?CdldsABewO^lIVgLL#P#|0 z^O>TqAgk+<?{k1(%()XcCWl*Z=%KpYsGLtaaVOWN#K`99X9})`_#x-#Skd#Yk$tcF zn?F?kE}OEC{-<q!$4kCj?lFZ$WyTV1p%CHZ?sHB0m9P9Db65Om2di)?78g=k3Wmx9 zr~4VbkAnrE$DUgyw;ToCQR<7mFSI9uOxF&)xC*8D3*JhUBGTMR&o2nx1{3mN?DX+S zGQGkHcrG=zDIP!yo7C@+d@-X%!dYG{myr-BWw~0js`r0oUes+IbGeZ?H2^SaWc3@- zWtDN?O?pQ_WL^>JQ+NW$QTV^d&aiW_=1p3DT(;-!wkmpdb(c`N#qpso<f|#=R?Aip z_Og_?E6dk!ZTX>OyGFcJyM{9GR=Jn`twDBUeZEC{E#1}{ML{Z+HHV-Ix=SXAk(_^o zrG1tp$J>bN=gTH^vtRbwHqh-y5rOb~B{(`5g4+0_D)2Txp`OK@QryI`O99Jo0ku4- zCuWRGX|(5l4>i{qRtrg*V~mt*b!L1_7}3u|2l&~mV8u(FEY0lv=ueG}Ry39gZ<FP^ z3YE^>D#3SUHe4h*A{KSjVFCrC%7A)pz%jOADVfF-#e$V@01+`Hnr>k*Y-Qa1Z?fpN zr&ehF7>Hz$3qx$hC4NZ3OJDvKPNUY%VCCVsph}55Zisqac0*)RE}~mgy^Y%hIcT7L zBd=HheCueg+gWOy`a6wx2CIsgWPjgX($WBNu@|qxy#$@A8K=ANoX3c{fSGsj!c`?5 zmdnD4K9y6MI}i|jkX5<ts#kasJp?9@*fVC%aRc$&`$kL4303^smIVzhVm=Ffcfe($ zSkWWu$Sl_lhWYFV1+VbTGI8RknIw~{isp5s2!i{`YHkICl%N*VjXEtLV>t{SHDrY7 z3@t;a)k}YF#0|{LVB0=U$ql;XcKzU=_Gz>7NmZ-Ki?<-coc(c=LBQ~-c@7WmyuEh} zxw;-Bu@=CRKHy5&|3ENtfiWCs%30(pvgziSCpj0Ke;FIP!7%BUv#E^4!9GJpnNPny zsdo`tjs=jJR`ttT=e<-W-5T=hJQM0V_l))R#Qa^-wDOP~M|xI2=<O~}vmw=0q{<Qr zeO`I<QHV^dWf>a!fP{Ot@z+fbzGyYJ0Mj$qy(5x0SrIysgj^joip3e-HvqVOlH@qy zt6kewWYC8?PWXv!0e6=LXgXVKU<<jIJR<9t7PHCp;jn7q+ch$yUZrS%e1VuH#;Is8 z3*}^`8hy2Y#2KB1XV`m$??yBZNg<n^k6xW<IpiqA9MO}v2bw5<qEGq+UaWaaZ!3!T z;_LV~8sj~XB1kLu-s9-%owP2IR5t_mgWQRpQiIl>QX-a7b|SukmDBj(FJBmk?7W7a zOS0>|sS(?CKC|S~sTEZ4xkvhl=6bfuyT+Y@lUdkC<7-%Xn<+=<(L-u!#M$d++Ym^J zRz$(}o>k%V9FosMVzgnYPyNlYE3JC(!OD2N4Asz4wv}CaEQk+u*zkJt_ts*k;e`<8 z>=(jA65)12o+E$@5rt*b36aH|eHMMg>oXmx;eVwxmPgyuS!>}%e$clSG{%NsZkjW0 z>q>;63$cY%`Zm1L);RRl>SWIfGDOcKnfHpK9!q1Fez7oh$QpMvHRse?z|96uX7+Rd zMiI|z+&AHfl~=n)oCaV|H)*9|{N!j^Kle!PbZ{za8I$X>lmn^ISal=mKChFT`cV~g z!BFWOtd`t>#aMIjL~ERtl&rP#^d3Wr$?x0-sG2l3$aN}k%9Vs$mOZ#|^NS*;x#?qX z`OG`?B9QuP4>~Tn*P(r<=24==YNpRsFOE|g&Sx?Tjg8H|%JuG8A<&a()R=Nj+KZpw zUcM1IKY`O-TK2C_x#bwJP&K?Rstj>ym-esb4HuSU8%SPGbq!xtHp@`)l(U>)zG3*r zpq{`;;vP%1xKLhek0?!P5!4ATRAmxnvc&tstRhE#O5U=zI&!%>?PKIUmY~CsizN)O zXqn_Uw{ub#j3$SPqkwT%q#2z~Fp-+3s);qc0BqQAjiLmYOTUY0#L6B!wWPlJUoU`0 zncVZ<McpqT8<tZ^_*sWvj`4aR>h?|+wI&sK&L_^ZnqaV37S&#N!rRFf%X$!eace`o z3KlU_{*v*5(8`;);qPWlj{Z(#S_!;|qcO31c->$YZ+T!)BavPlq1ndry%?R%u`h&l z?Cx!TtI?~N`U`8&*nB$*WHmYDNb1m{A@PXRRKSxaLLvWV^}pgH%kH>DA#5#Rw3f&3 z6F#B$QCT1MzQknY2op~Hq~nl5;nj*a4i_gS-a8t7XTvz+`q23XjCP9GIGNQ|u%><q zBHbrqd^>_cp$nhOYPSU^9?FUL7ovIG{#0(8Z-$J{CHdo+r?82{VQ_^Dlt<-3hFG%z z0LDugx2`rM>XUREoxih_N+S(BNRk3j1D1!^VLjMzFfphgzD?zTgmPQitLe6sR#&Vu z5w8b2k-88;C*f~i5jR}KU#Z_EENO;o=JWKK{~q8dJHU2bMJ8Vm=)|zx+p8Olzw6?G zq+Po19iVa1aCSZveu#9ow^A$pl26imWFuK4^BHe`|4nPE@b$<mM}JRilo3~m0+3-# z)Sf{A-3lX6ULHYla5bYoj%@6SA-}&8YSKLT%F+WD@7U>OoP8<@h32dDk$s5C4)|H> zd$77GA0>=Ddy9RG&Ox><%!Kha+X)XT&KJGPW7cZj_+XF*>+1-LM5gzKJSmUAL_*$= zw_JR@eP@l+swn_78!k^|X@O^X<l6OB<x{m<Ea+?IvWq)z9&JpHRZzP@KMc0`ayMjR zRK_cVkEcZ&d<}1z@_V-%`MOLXjYSZvtlk--3Z9-UdjGMja{c?KeqEd1#v%A~lJ~>I z3i>SWSw6`2$(?Lw!mOfGJF(j(s>+M&iw`Tk5xQCcSuy|VT}DjsLx_&nW#E|8qitsU zkaAIm1PdPuK+%8dj&c9l)j!60Tv}DQ_`@^cPsI7j4ZL*;Z@}8{!Y<&9*(qhoDt7Z} z*B6#T?H5&+?8wDB1!dHXTAu*PI6na+jx}jFO}YbH>aC7jjBWLEm;bJ6L%fo)eo^-c zj8NCT3_8;=vh;V54b`cVZp>FIk6rf}x|tGfe6ejEOijI+v_X0m85_Dr@Wo#Pk9vT` zt4?pbNgVPnzIur{WH@Gcv30a}rGaKYpa`IhU6X)=xWzvgX<WIuB&N0f9O3JaVAY!V zCRbBl)w~|o05hKt)7{Q_eUS`CDe+3J=?gv4GRsY%5J?^P8O_ny-g~|kn6Ib34(f5s zE*u%0JhP3N;yZ+myXZ;zIJ6Q@!Z@n`6;F43I|XkKlk_IZDdXbVC#mmG0UKzeMv04P zd;)Y@t7cqkuhDyq6X@WAbc^oI*VoO&Xba%&Im~RQr?*YigKj&LY#cePj1;gx#>%~5 zrz`xO&4Q+4rdfFA_JnPcr?<O`A_zBEBNQzC`Cfvn|I)q3cNo7LtzLmwbg3`smE?XD zT^rCp8Zm{A`$Ln{HT?Ziv?ZTQgZdOFSai;ym`)2%PPx?&MgluahgE6I;O+M8&vNcM zhdKbu!?gCp^_M&UiUSX>2ephgXNyZ<kl3zHMX<y?wK+nw+SA6DfG;mdI7AFxeJIU; zZ1BGVz<%J1&W7fu{@-R-8YKav8Kprs%G#(?^{5faUrW!AMK~*_cCO0Cd~%m9*Irz9 zzJ@mg^N2zBIStB<nl+L~MD_Noi!DqI@mNT=yw+as=hE^`-o%(gKJb-+OBkG!%FQ~% z@VJs;eX+ny6S40i-Vl#ZoJ+A9?-LXGaMgrKXQ=&}&?na>od5BTGz#kxC04I08$Ysr zIIA}?@$yNh$daZ5kp-dxXlH%pbvn&4$jn^wX%`Ii@lCUW{y;jW&}Wseor0D)Bb?l3 z#4J0l8QBgOpdDVS+qvF&dSAA;=o}i{>v_dC0R@eoE3<56{lmR!5+Kt+sRH80eIM5& z{rZt!^4cL|(JGB?A365U{Eaq(+AZQ2I+d`Dx3N}_OV~^#Le@;+2XFnbJ{;wS?%*>6 ziX-zy)1c`7u@IAZ*y-NJ8s8HAa8|oUq0+L(Legm(|3g>=CGyk^(n);|4_#}~=R4W{ z#{M6Qj$~ZXQC}vq+h)s}%#gg>fluD<X;N6IukNk(#pJrJ+y~>JiG$po0w#xx$n)@h z7$hb*tN6rk-a`mdhHBWnnKMnYE;S>kM5V?S@>!(CS9xVZ<keT(yu;;ePMUSbo>urU zw5KOcrKT_B<1G%{Gl}NoPW7xp+XCR4ro9tjR_7daM>==S+%bYE=h~K3sA6KycP?tt zi#N`4V@G?Qcb!3wGI^rTGXozy7Tf&lEa^-HhXAASw?l_fpEODef9+)Lg|7{s5(@hd zGQLZd%UBS}oUpOP{Oo%wwrI<jrDs~~`c<Q0=slQETmg@+O{BXg(5_Mv*f4TgS6OUo zSuedKD+UjWv`Fj*!DE-A8nkj?T6LefWox@Cp+|+2CLGaywz~z;z|cUFclO}BbS|W! zjUj^D4^LgjyE59u?ekK7$i~ciPC6??L27xEMh&VYk81aK^!DT~1}%^qxfj7R>fGs@ z*Ax3Tts8Brqk@l-%2~rs5V}cLDCK4&cn3TQ=MDJL9kt^r^H@WjI@~8b^MK;-9bS_^ z9o|X@0#1RwTSm!s0T-sg4Dg2{wT@N%TV_jR-Dx_%tjhhmf)!RKx!zc#1mU7qIhOyZ zbds}<?ao>r;Y6u2B86;snD}A%f<PalA(b4~xqrP+lJC9E+1b#!{wp?(NW;a8S4C&( zp7^b@V~*=0td{5YdPz~isEKx|@6Ky@L&w;Cv2dQ%ggV;rR^|lRCnO~EyC!CcBY7U& z4@;o0^ll@H!+2Ahi<Bj`o%WzKMaV|B=+WVa`7?i|v50-Z{i&Ghi{(2d8ULEp;FXwi zMa8=&d0GTMxlB#P;AoUP7S7eYN<U(G#x-4(tUld|rJG{y2h6bce;k<-Zr5SMaUGo) z_UgDy9J!T*+nu%c?#o+!y<<DNwX8uV1>zIga^Z;^nh`Y0{1o^%A(L3;pX+d$1YK%N zS4?ih){3Y7MtGm>5w;gy&KQp;%ha|%2lJ^pXTI}>j5DWlE9p<g<oxlpaM6`?ni;Gy ztaF0Ch8yTPG!>f!Q&RaLGEzr|g#Jf&OKFr={v@n>ft=sIykegB1ua<p5R!zLfxj~Q z+wu+9DZyP(-iU9f!05J<auOqp-R@D}Q-~?2A9r~|649p_TS4mi%EH36-iFo62j}`k zxJ5qjaVSP@;EHJJw*CBt<$x-p+|UUSo%`LTg6{PBjc^H`gz2EQ)XE=jyiZE)w8dCb z|7LdQMu#KHx@9*ZH2)ec|EHH1F2RZm+-xUa&i~E<@6LiauHUyH?mC?Dw-@sNix@9; zoRU>y+FYOVudC<(e9_{8>ua}q%w-Dwm!@)vlt0m5-df82cl7%IdrfavapD2b)dmsZ ze`#|!#DROJ2z{?tCVzY9|K|qeS9%{X)vWhAI*&a1zhC^#0xn$-_e_V%5MS#4zt{P9 zrEquLA4D^5awePOzq@7rl0R61-msG0e;F0DD!7+MTT&&V_ut*Jl{OKsk}1iI8T>D! zLhRF@RjX~bTm!t!tHu;$Umh+GlzG{Bp8Z~i&SFuuSA#%V<|0;s)=ro3tNp#AqtyA( z7oh=5e2X>8|DCO5{VUu(z-Kw99OrIpUk@)2U;~c&ju?5bOTO4)U}D&ZChcp!7mIvX z%H!U<|CQlP_zpYnxu4b}RAH}HAXlq$gZasFiE=?3?t2BHTV4=egXW*>&F);O=OBuQ z&XnNVp}wP$WsK&MBsh%`a{}~jb6-F&tF9)ELV=;taI>#AULOCIx!zNpo;}+3^{P3Q z_yKt1=sC|$DAG6JU}=;>rU;2`&r?T2E^2dn@4A_wgPJL{Mz#N|x0W7&i);I(bY^p4 zIOJ-DIRG(=?F^X$LJpS)si4@h>kGzHtdQJwYw*Eq<<NDo9J6I>r~aV2+aPRTr3?Zt z!R#)>m-8@rp&Fs?uS`N28UN4L^0(Muxx`hyp4Y<?zlrY}YY<=e<U^7mlXmYJT9NmT zAXoKfy9Fj14^4V_K|XGplp#%up_mv@Lf-XLuJ{n2M1Abcx8OKTHKdD)uk%7o*OWXt zx3{{VZ`4NZi!|wfbp<UWe;|to(q2zEY>e2ARCf`c91sc7R?WiPgzm$7#=%_1E7h)( zR!i_FLgc_kt-Z(A6-+J(=uH5YqT;>pe3rJ41?ppd?}Abyv>;r^AUlApD;l+w`sW?j z{c`pjtdjx>K|05xc8gL9dF?tEkJXEQr;#Ju4+pffW*UyI$tPd%wzTT23xBY;2mGUP zHmXlgS=M!9H1c--6(XdUWn$?h$~+KbbK%shej*t+sz1L*_B~4C+5N6h&{IiLfL>q- z*g!QHBb>cLd@{UJ?>x6HNmAlWAuzuqrd1NKO6g@#4UV}Co`B?8UrMJ0+$;2c9j&?b ziMB=ihd(7@-sA#~%JsD`<F7t1Lt1|n7gKH~5|=OIcCijgk=%1EFZialU2g!BqOR7G zfUL<Q;yo0{>MXL~Z_3P6avR>)fY!ZR0Qm)A8kQyU($;4A)_Q{Ez{|ed?ig*~uEX4p z*>foxhZCKndF+*@`WZcADy!wQ<Y5%nFf=Hi42MA%T|~Ze_cMth?r2g7&gU`G_4G!G z!a+l-B@(}J@Tj|15!jDL&Tf=UeK=FQ;71GYL}yQx90R!ICH^9~Oi%sAgEJ|akXp}h zp+!FPI+?_!zty&TOl7;%=_x--#F=D_9^VD@5uQkns2|ta3sfHzhu}^4gOS>ANPv<L zLxiq&GjrPj-?x<PGxknnDurp;pCw2J=r_5-k?n?x<d?zQwRt)Zx!F><C2CA&_GQ;y zN9AJvM?k%^_Zzcsa_}Em0If{8-6O@6L)uud_P6lCFMp<k*Vfb<fO0P8iC|ELP*^IX zZD#AF|5~@%(XaJ*92$)5cgN`Q8MFE;I`^h6zK}~oVZM*97l~LV2IL*4(Ot%auz7_S zE0zO5ss$Fls%v$A=S|#@Gs4MSF@ni`$K-tE6m7W1zo4k{ZFvLP8RkW<hxvjfHZRW1 zAyd)|c8?7HF$?^5*M*~QwEqoW$dEdOG}xCKFHZ<A>P2(rq$`<Lo%-uaO*2GZ(sHU2 z^KwlR0FrN`RWt=xr9N1tGX>BkQ21%f)Yx63?a$#NGCm^Oq3VplpzC69Pcd)AkW{BG zYAyc`9`fQ*t(QX9UAdT6h|Zk^#lIhQL)QO<o;aqb`F|DJk1R5uahc>W$ay#itE=P+ zWz_#81>dcSf7#u4lJ`^W3`=_vRe_uG*RT$O!C7P<287{uj0z}4PAZvf2RG<kzGxu? zI^5-L7+R5SnTyhxfO+P*TTX$;tmdAQxC9K`b0H#3^e-A(tM2{YcS=ASvv=&|#~gBZ z^nT))Rb=k_kF-Rutv3Sg^i7fOqPN65LPctCA?(W!L{@WDf^$S{V*2fIPGkxTh3lzL zOg!dOD2>J=h7^}i<k~BRp49ww){z}fk#AWJP{|AoGyetjIB&Vl8+a7__vWA#?>`zx z!y~e^hAk%h>l8wP68(HQ_(GDfsq)+i#9>rtwBFBnm3!sn0x0Y&mJ3ml#YADB?)mu5 z*Vo;CsO4v+;UDlWP~t#6Mt{@4nHTZ2w(L_7p$-#DM*2PypXt%O(dQPOYs64wVJ!7? z$D(^&g|_eK?6qw&VGSWq0g%ke4H4~ic29aBuM^{78~)G2s~Jxl1e+gvZMg*Eewk-s z7>CO$g4+{pl5W8Z3ED0rAWqE;2~BowE-Ms?xbXxnxNWvhM)mJAr@HC>ffVA_8R@cj zyRAf%$GZtOD7ZMH8Ey>Qvld{z`&HEM5?>le<RVLYSt_=ykEv8I_J}wj0ap($G$mOF zY}I)!$Af7sUR}a*d$<yzb;Kc)Q6p()Z{SaavrGiKioQoU(4N})GiQ);uFLGo(0<Jy z2`ae^PJ*gZ^Au0A4&0!PGmcF6k*?DF*EjM+mjTYT4Zf%NVSUi~A{lGMdv*13*YbMa z6I#8KDHRSIt-gw=+`4YATgS8)Zr_7EnB57^Inq^Zr8ZOC!O6rui;-%$_CT$CwB*TN z1vsgKW{Ui)wQWvzoKxVdkcO&0&k**ndmfW-b=wzzhhtuG`xni2J*7Bktj}=+M5h>Q z&^lU59v8e)n-3{d9OU9GeCqUad6Qi`bPsl1)s>mL1{X@Yax`Vh#kpo(0@Z6Te{RN$ zI54?d2xYPZc>P#7S-eM-^J)hD(2+QmE@(U5<FY=7ZMnoply$HE0^DTbJ@(3Qf=c%& z*>*zKlIvARgMw`J25n`$Sz17qbJf%8_2|OdIXNE=9&leT-Ohzar*ig==-AbMejmuF zJ|!&+b78k<<Tx(|_+n?c32E`zgS(bAid8$dpQyvVY^xV6bkEzGZpkje&gw6t_D<n< zTXEK-q)H1KLpyVvOI>2ywR()%iQ{CAp(Z8QTn*RIn4E@Gl~FD)wQ6u}?2?L-y4y^b z2_~Qu@OvCJe}|_+_F?Cz`c|}U*W*3fv+KH-5F_OHIEuCCdajK<EyW4aWUkPRBsv+6 zZYr>lz}7?O)<$@3<a8>V>N-y5o<S^-J@?{56XYaTBN(It_CwUl>yPO^YW$=U$%BJp z*OpXV3y#&$61FlM>TbN?kMB;e$f>7_dL-kDdf3pxjk#*cj@XwF=rUF8+;%|QD4nx& z&&F%R>N2lD0OKe4DAIUevJn~mAY@7EZD^)CU?+Ptemg|i&wNjBonnqu@`ZV+Mh0Py z{<46ews77ecACo@dEaqvo}H_!6ht;VdUNNbDyRdUxzOo35zZsY3_eB~?E43f`sJ$Z zA9^9@#D=}`v4DHFt6cvf+1Jd&<<oj~CuF4BPAhxm7|(!K6m<Q3TV?{*F>9GM^r2y< z5dpq(m=j})^9#U>-9o)zhr9drm&ISfE8U~ldFnz|?{dW7$?ngUV;yx{=Kjw3?$}X3 ze99gEghwRxBD`i7UZ8ut87k#bL+VD<Bg};$K^(U@4xxVF%t%c1wp{;Ti&K%BC+DX6 zJnfiGj<U9&beT|fEVIZ&suW>!2M}|$47ChBNNnKN=)d;csqV(B=EA-)(9XVo8M<+% zdvR(h0zD?jTx6u|O389+biHKDLSlK`Rl;?~BODtA9j2<~4IM!~s^uXY6gh$cb(WGi z|7(X6w;*ThfGihK8(`3@#Ngir6?MNpC&$}hVv1>E9?0AMJMAUwUUh@UsVg9lWE}!b zrdu-Sw5SjZ(r8I(?C*Bw`Z40;s2`XYU`m=3yGa$8KKR}jK5ok65mYm~%)V>N?Fi1# znZD?9afNnFa{1^m)cMV0Q$^JB7?3BQa0Y@1S6_5Wvl7c`Q`7g}uU8_D`}MMBFbi}t zSK&7)yPRk%{Y;-NhU&eiX$z0pwGg{C-VG|2J8tw&Fl1uW`=4E2J}4y!(6*)Ig(M)( zsongOQe$07ffglStWraWVp+IdOK*kWb()*wWKbOHZu9HuZRJEGvViOF8r%jI%^E?+ zx+T?*=l@YdOOdL1SJ#pos?RU^mO;dV<M}_1$N#!KM@cQuS<3KE+s%!%?PkJ8BpveF zfl-&&Uz8m|{LJ+2Xy%VG8qg&-lf-H>!}l>~!vl>4Uh;p|(@b4Z{Eth?LauF7vkA5+ zzs*k8$0;5nJm2}`%v#76_4pP+Q%_S54?0DIFz;N<>UrucD*n}VPq<4LupI~I1f!$o z;jU8E;cRILZ%eR?f9M#L@?0O{5#KPSWKm+$de-su=V+_$9BMCNyZx;O6F_6RR@=ez zLg8A@${JLK>%CO1p9un&M1)&|>`v-uO)2>omaB?B<R$^__U<i>SE3b0UpBJ@FB(+K zk<@MTzpeaDa*3L|>|S<$wedsrKNLjiqJPp2#Vtl|$Dmi>r)`sBPjwqkhJtYTvzd1H zhtwJ+!skY7ct(N~SpOXF)(8%$PgrP$n0#Jfy@sJ{9L*yUG84Y2_{IwYW+5OU4z$)5 zdbPIkj$rO&?Uw5h(+7o!m>%I%UFjOuui-o)t^b&D;yiVmo<@urQmoS4_WW_@*5SNa zgg!1c^E8hzJiA&^IVu{xZu6G**I8?gYxdYdEvG^-^LYdBs~0(-`&Yw<Ng5|snFLLn zR>ob|L%M?}8oZCo5=t_Hy+6Om^drm4x(niUPWfIf5-nox-V~kOV<uQU+x0Dya8P)p zz&N*witwcE%~P3geR2I;BmOvJT0_|d0d2_G)r<t=xYx{c)Ko1g&VII`d?I|%qAPq* zZ&a)wA&X1rsS7*Is>MJ-ts#R|zqXjGFd2Re^!ccFyOI+;1~kOh5VksRokU@{S0Im! zG)Bak9@^oS6G3%pN$A|XX|*??fF9lplns%oJJ*HG6hIdqU@Be34w6Qc3xkqg<ka~B zf87if!zr_QNwzBnLryJWZkb<@8lnT;BXc;*Y0uIZ@y=)A-&$$?7}JXRsP4IqTfLWu z^n>kBu#}ysYU7k6d@j?ig`IgAGA{U{?y0PcoTqsjZ-ei<ot4w!fo7Xj`uR5`BQ*YR zf>(8`i;a>d0<fl?lkup#=43O}IgDwUBJ`_vCwqQ8A+*e0=4R+9+%ux((=tV?zc`VR zGai-Cqv(WM1OZ3{;hoBo1RX)92XFRKy*YEs;Fjy_IrK>EqSV<U4?PVXB62QZlp94? z*xxC5X<{y3Qxs&Pn^tv#`d-{gBOhG-Aj4k?FBXZq6<ZZ3yw5O(exJx@DIxnG9P7F@ z|MXZ`O|bGttDo@dz6i2`I|ELb)gfx?RDsZ2*|Mb(>wNKR69&-meBZLM!-GNsp~_)G zp{c=eo2<fb*Ns;{A4)#1=dtv~Swj?VVSegLT7sWE9)}y}?jG2ul+G7LB(^?ZtsEiO zTOB56j@h;wWenBZpIMJ$$x710>#W<ucbE5{?0HhwX#m;@9-$p0B|DRtzEjk?UKbm? zeMFN1E1D+h=9padk!BLR{$2M&HYkc^m-W3a&XCz4^o{V>`cKl6S0WbQo)$y*vlB5R zB$6>PLFF{1Ugmf{yVd_znxpt1eu&f*>EM}Rj;BE>a^fdOM}8UcMHgLs{n)EfoEP&v zk`aJ0&ZWg9R$ed8ua89D3r1J+VNsTr3Ati85Y>k#0W^Isb;NZn`%wMi!hM-^L#`6v z=E0`sUf~a{*4?$-PY&aI3lCG7bwOr{R;3M1J`u2)k=ln7Etuyf&#2Z<H^>59b1ID6 zo6LMZFJ@aTG2slHdO}*QpDrt040@+X`-L7V5hap&OMH2$y$9=Suyn?ftdrqxzD<9! z+m8}DDG7}ZvRg~u5+DyGJ{CJWll2?Bo^W(Lza+4v4;JFv)KsIF)JuXvm9oPc4kp+E z2VuUe%|2=1xTvG)H*$|;fd$o+)E|7HxKfc;<ecswu7Q!7@=|c8k#<M|-%rfg*P9Qf zedXVQ+Any501<XG=Mi?lQB&%xSbwl>=#{-c0fVz>q`Ucyd;x%Cx;u9KW!@)^FWfvf z(ORC05t=_*fa!f&4(K>1G`?k{6e+YAUCA{M(rKJ9@p!DAH(|p)VFS89{=ErjaZY2= z#pxekfA?8MO0fZ%su}`k0KJZpUoM*t8Z2Ir`KeA9Y`6YHv3k`kd7^D$8MuhHYgrBg zQb>P6FJ=imbNPKX?Chw*F3xIR9JKHaNdy=Ad{g_(KU5hHwH>U1FL7~lX<i5ee%AT; z7#2}jsDZqA^*SS3>9GH-anP6N9!v*i?)A?)<jO^y^w@`_MWKE3Wi5+Be8JPeQ<2n; z{Ec{vFFsW%%I3}<@X*3h()6~OE-#*o_l9;wKBuzd_*20s`}Xq7yy<<LJl7;<>~B)I zuMD1<VH(abd)pQQw_F6Oef4zgM2Vg6UoRaGRmma$UYs)VAOGnd4TwvRiG+Iel$}m` zZYC0J4U<&jIL-q-?)F6^cgzp@j0*4;d+Q#ZN-{0jlii_JnX%Inb$%IkTmhtyz3L)W zUaG7&+0-PcSjZrz+&bdo6Pb(XRo12+m(Q9p{~RY(<3u|6o)DeAfIpcYejC*=Fy>cj zsT1@^+ne+H`^7NGoG|6nX6y|_sPjNX507M6;KaaWDWuqK@H$g6M3w_wEje#vN1>aG zzS-FLD6x?x@pSvj5_yVWbLDzTRd<S(OX<T#Nv%ODYD#$D+#SP?0y?;}FemhAG<I|e zEw2)ii^^R#%k)rFDpjd?WWoN-ms(29W+Ag}hr`uabaTR|u>I@Q>J5$Cu>Lk>hX`W) zN+?BxlBuEcZSK0d-BdfON0c8%sab<q&~yfE8u?&@ppM_!Km22qUc66{a_P`jNT*G6 zbVLP!Ksa@6B7x&MJ7|MW7;<sFBsYo<z!GmrF9+m;vF)J9Wiu9rD`~*ZzAt?A8l3R3 z(<tHS_s9!di`x?j)$(^E80{Z>j4{yafvh#y+CJZc1!0XWyFFv`^I2=*Z29?d8T<0m zENYw?47JuLW9V+HlRJ5wMnUo&GtJuG<fr|QM^j#VG!bS2VChf7@l>*Ef82jzCm=c- zE~z7&P^w6w_VfYCzM71yVnXyCT18<)Np|B=O0s7rN~2!Wn~jS4h!2AvE9a!lO7Y}2 z**nWo1S%iw(@JMqt>Y-vh1t*^b0c$B4W#Z3VZ?!X6^ilpW|1{Zyp`-h_~NQlS)tJ< zHhdLBQJv&k<tol!?y5aVrLKA(TXHO8lB_*fuQ_JY(ZJB>Yf?5|m(+zAgOa~ipt?Dw zif)_;eZ!FQ;E;sy&6}KzE>`BUDF6Vr_E5&;8<7N>M*8hDi`XY5c8cfvTNJX5tU7~j z<L@(9JqJVRRs`XI6m4~u;mPK0I}(Z~%;V8bs@_j?K0G-H)GJ!MD_9FdoNNf-+;@Ci z3+v|&D}QJAl#TGr=A0O>eb5k0%KbW_t^-^x2XBg1RBnnrOp@G*r0N_`+ZAH+GMt&A z3~?<}eG&BLO+;ae?r$+Q4cMVI9zlah)n)(bq7BNuLnjCmA^jHTbFDmMkW<M;R`s(E zfiiKHO;$icEaMqe3OQytZ{}q#XH1bqvn9>?-xwa{5ikKzr1ANi%x(PghG{2SHu%N> zRU)z@F9+NdrRta$@y`;_IqO5mEOwqCD#DGCr5Bgj=R>mOPx;-1Zuf4xz_5^_+zmzw zXl*(bi~Ozs{K03Ee+`XgBFJIY6WgF_QYDENe8v8XO<G%^BLB#OJlZPqqQY%8P27jB zFG0MQ;HLnB;%z#G&qh8qN&c*A+@zbt49#*{gWBsvg&%2W2xLEBMR<wWuKaW|KtN#( z4m>N78j!a0X4jV=%a__ysu6fLayZu0qW!&8@w3|81BaonFR+*kP}_$!I3w*S;QV^I z8-z6@i%hF`#~{he*0rLiz5u3mLK(1UD266Rt&80G40}V8Ah#0djPk?X^;ai33@=!$ z!!xkr<%X)ZkI<~g(=5&#Zg<Vza<nMCBZ+B_DdkXMA&Xw~I#*>Lbb0+w(ZV6MU*W~s z<Mj}9VlugmYWoxL3n_4r?pBJ~E2)VRCGJLNc`lb2qm>74Ww*X23$}n=`%1c+_LQ5U zn6iVty!<q$22$s7#og1d$eRV>W*#%!K|l6o-d|dr8lSBdJd69d`^$-DE1J8`<ibxV zrvFNiizdlJ_MAbq*w{{H8|y&Lka|a3=|MEcTY$&SqJ8nsAVUoG$Ps`3CtepKW$!!D zZ<yXTvqfhYRGSG+yyW*JRk-be5q5KW*PGEK|E1Xf9nX=~EBs8_uJ^39x{9pidI-<E ztK<ey1ck+8KSht{y8AgCC=aV#3jyWF?oxG0i!VNh02i8@M31xjtg?*fVv~cQu3onj z_`ZRq1xC+Qnc@trvlJQ2rn*WBUCJS9Up_esaqp4sTfEoH<e%KsR7|^mTGyat(A&xN zBK(m+E|Q|)Wq)2+jnd$n2=+Nc55^Nr6l*|qU&flRhx$X3EynV*!))J{;dbs>(c;l) zz5>fNFG>+8h_cyY6(i5m63lCSm|-u&YI--9{w%Z3Uals}ZM`x@1pFv13I|i>^(24z zo{*^jB6Ugsg|_6EFq!T4{#aX}(5e(s!j1p<>CSobC!EED=q)Jb=MJV-5WjlkXp<Wx z$>L>SOMGb5eF$V(xYl+rPj;}YSLEkF-8Et%dDW=sC9tp&1AT>-0sz0jZErs;X&VD7 zg-5Gp=I(EN9IO4Nja`wv6nW?g*w%)Bt{<&TtB>7(?3t};Xe7qU8fl|PCqhfUR69p` zU8$p6VEpzb+Gzi*o(_rqf7pA=pt#?qO*kQt011#mgNMQ0JwSj#1`Y1+?rtFjcXu1y z-8Hzo+u$xCxbOVW?mks}w%(KH>sz%|^I@ju%lzi<`|9qiukOAae+lE1eImT~`JEY# zF6((J7~J_sM{ls}o!nyy+NYbomtmAJ?R)CyY5x}-=*vSU-VF`*i{uRb1Ipu6$1M)G zI_lcki4^Ow%+;3#{Rm#5rnnB6BwiwT|Fi#lAKnmO)_WW1sQWd+frCE3UHZ>hzTwFh zJ6=^;S?0|-sm#-lcEJgjJ@!+9d4)(prI+jm?6^89-zn|lf^<a#*x%*H)sO-T3kjb0 zk@7#1V+6HsUZ1QE7i)+u*lQDXGCHd!3}^&%Z9>nvH+P)BT9WL<$TQ%5isVI;$>ARU znFq8t9~8k19-@h3l+^`mPH8M|er^*VaGDrArN`7t`#S5R5z(U{`B7v4y-Ccpa!vR; zUNA{j?ZUKRw77b}n5*@#uzk60z<LpSwp@|W)Z!<&lECRTM~gLvuv!q-OFjW@hRphT zzeM*qz7OHiMce~dXRp)JyX2t8P6=KU7aXdsw8Yrb(eJ8V)}x-|e38F6{5IosaW5=` z;diMhj`CEYSq`DUCx1tAo`iv}zddX)c2uDgs&B{K?so5&Ui(BEO;8p^T-skZ?Gk36 zDFl7$R}h+#_aFBuuR63(T`_vJ5Ejvvw62$bW&YN%!UXhfXDw)iQD}*>FA1zg7eacj z<^}9|t|AF@g+P1An&Uxs!|>D5O$md8F<T#~ju$sh0Xb)#M9uLv_9<Q12e*pD_QynX zqBeP?QwUvs(*!0R%CU+68J=O^HUz)&r)Pyba&l~v`E$UQB69X8egcDyO(HIYMkg+$ z6grq8rV`-ytkxL)Ax-?1n_>d6xtl%Ff!PFiRc?pNyv)1XTT37wJSEybDWj-h@_cGQ z!0iBdxjTH}G#h@gf3C>dbs-+(eTrI3f)*h`xeDCN8?c<yqicyO>KpV2&}sbRC(jlg za>s-3R-DjfuBB{-eFzH^4d{&+L#8k9oXeUKbp!C_JO_!%Kl@sPA3jb4ucUUkobZ)? zyyp`NiC+@-P8X<k$fHb=^vvNJ&jjn;)wHZ0P9SKnwUr_-b|vT*BZHSo%^VyP8)%57 zpavpVNvyGopkh5RCpiG2m4#^5;CG(<Ae#y!5<g;-gABnTio2s<6iZ(jI=JOBAXh6y zJvR5uEay8cM(bDX07d`KGhzw3dx;xB8Qri({H>gb0K(YVGq-IY8Bok)LGy|c1!Dm3 z9-R2aCS89^lhVXHSj2?FAoF|ZQSG=16n=<nPu#ZjdP#9t#)inx>MbcF!tf`P;qEQp zAc<JrX`-Sh+m8ZERp`#!Ojk?`70s!F{eL7(ry3vS0Yxd(DK7*DUQ*DVrXhIJg&t0q zP*t(e(!2o7dt~ks<8Pd`@0$*IsR<LNHF&4B9P|gsJbEhmey@1cODR#@5TT5vw+F&O zKyh0OgT}dNN(LpcVa#KGn~dGSXOh?Gpa0{l@eMqcWir69qNWEMQ>tL_xR(R~SL<F9 z0HPes5FnW(Z62{Fm+RT}ASH3d|CZUutX&TVcEst0rb9>rKar@;x90F_I)wk1<z#&6 z!p0qj6!igfn(nDki55@u%La{VonMG;o>`v{yZS%fZE!uGZdrU9PXaiFgc5by#El4V zM(aO5L(m`pq&?=;nvTlGJa^K?FE8ddpnDTy2JP=af+Wep986llrN`V;dp)H)JV=xt z`8Vqws58S=2|t`u0W=bf4?pRvDISILj*S-ITX=c=vJqd{LkHBi)(m}2lS(^?LKIKY z@U)}9e*A@XymppP6=KEp{nV)*v8N?b>7ss%^|R&Rd5PEf8r$(Oxg~&k+yl5fnNza= z&{MojUnG^r!pZuH?+)h^k+%xu(sgf{s{E-6foQ2LEfE*&bcJ(<y0!Z2b(k42Ru@4b zNf9qarbkPqSlj)Zyx@rw_q%1}4vgi`(Rp*yIt%&*5Ek|ETxPaghJZD~&H)7JN6e|K zj4jG4OTmFR(6WC#F)AgX{&rmGfVQ$BjiqTm-)ggL+@MnWVWn~zGZYR;nll2itChqn zG8?Ik&gf^fw3}*gBpi;<W%VdW*IG*Xu(VgS{$x9RK}=xr%@%{sU<or!7lX*Z&jNBs zy|7z0L-?n_3Hb=Pt$l+3R9FS#ZD@BMd0U`l6T_!pi|6WXVPbU3hu5VBTy!e0?-4`i zE7yYbA6PVdzr5CTGormuWB=6cdj`%;y(9VR778!^{Xf3e>oKw_jYNam#$q(=TMwSr zq;?!J`#7CLF33+4=B7#)B3y1Z$W$`;*(mEehDMRV=PWeVB6smOIOJ`EUBJk0_Al-~ z8o#pt3J>%<Ewm@7b1v9y^%P7?q(KL-Cu{Al`HaIno>k_d+bO_(K2eP!<UT>=cSR<h zaP2@?7IUpb6D3dZsK7c^Ann(rV>N3Jp|rD%LQ3n=Rt13nXiK|s7)5V((s2(u;D@Q& zm+#yFP~1e9yO9kXfcMYvl>>Tq;p@HQK$0_KcVLT9R9#yKTq#-JP?d|h+@S?)RDBnA zK0+Txyy9mtnc^pe2PdT|O1>7Xa@aU8+Lj>L2*FS!F!<`%BB0fyu|LrmB;n8OM6=gE zU`!E(_wb6e02)7|^Xr!B%I1UqtU(to6H!H(pmrUXbM4z+{f0gASfgo`o7w4swDm7> zXFLJBSl&x9eU?q>>Z6wI^NaA{mzefTfauFTTl<4@X5T`o$#~5j^$qkNY#L6-sNYxK z<BUYaDci=)HvBq;bRef<eoZWVg3<fUW5R84Eo^|uN!$FHRPAyw8JaDU8Dh1MDHwZA zXrh?(^$eE3*?|xkBn#R+8ULibWMvIWh3DB!g)J!Jn#cNBfym>f?Uz|9{9`DJ_GDY4 z64;~<<D0ZY?gh#a?o%tZL(|w|o2%;HO*C!TK?RG(M68HL(kb=|=D%D~chu!H7}ZC+ zw1KaKCgs=f%F^SX-E7CZ)|)n=H+vCmSsP{GcIE^Q1KSEl_FQhyXY&6DV=$2WKagz2 zJhtFk#lWQlSLw6*Y5=KEoM0YyRoBI^om~WbnWjx1d9)%8Wy3py<6<8yW`nDXn1#Yz z%+%|)AAbT#_c2Ti`_ZJ12q^2uRb}y#usm$-=UE~v^UTkf*%+>PlYIe5i%>)V;~U!v zLZ#P%Eg1nMA-h}PxIht^r~!tuBkjJzg?s1>A!uueC3Dv0#=zPn#cW=2+(Cm;M%QXg zvFWShn~mkl>M_#w%DZ>)ZyQ7w;AW0xA=lIuZx#S_i+&odgnrQCR}61S>p!%s?EtvG zf>g`U0r~^wv}b~pH4@w`-{)*HMWPY4S>}m5RX92H7lmLuyDTiGOy2@ec@_&#2+y>Y zwU#4f$1^G|kw=8Z9pCpC9R^Doa;y`}ntz+RIi3}>3>LA@5H86jvCn|N{>ZeX6<8*w z1r9r$Cr0RJS$4yhtcRRNO&8}<RDo!ngM$GxN}O(>&)3b!$QrHDAF30{Hph7QHf1n9 zKm#>WI>4#%rf1a4j5cG?!r<qCd#e&MbOl?Y&q9z~#Nf-r<QmFvO}!zSMvJ9C>0fww zzYpQ8vVpD%mbznHS@ym3P}~_BU49s?nB33CJ*WyCm4<NCbZUP{?q4zbA!V6bAQ1VB zinPA$G|BHN#pp+o%gl|ky+c=7aXFd4a{rpPrh*VEATf?lAu@$A5n;Y0*Xw}D@;aaN zJ-7*{c6>Q~GH)hz?J*HyY{@h)%q*3ILT!GS?`R2YIX8~WsDt5c=+@Vcpz~TO(M2@! zr6mfl(G<B-CN95bO0PZ9;53V~{k;@Hgf|a5y^BY?S8t4TM7ElZ(9JB}O*&&7DzJYa z+v4KYaL3ljx4*MLn_O3~zloZxxF?P7O0al2vp?0q`E|zagXB%|R~t_Mmp9g`s4;{k znuV&a7AP`l2hnlVZOY`F$Ine$e~vchPjt{yQ7c)7O$3&-=p!r@5HS)RY0_nQuv%=Y zED9bW&tZ3q&gvd%HbbwSH3@VxbgV)@>AslPssr(P^Md;~@cxt-`7Gf^zL9rP^yhM5 zJ-f-WPi24Zz2dq)q{)=tES*XVXl6Cve54Zfi2=xguthRs_gT;^v_bg2gs%S}EiVjd ztug$%5`Kbyn>he)4VkCf5TwOUob>ArFK$Ls&j-RwnHOtTuBm>-$tLMzMnLRd1QoxK z{3tl)l4)z#n2VyQjbf>fBK;;{C|yX=Z}>FNeWbG*Eza(N25UfIF=$ut;rmX{%d2|| zcSZ19R2R_E++IHd9E0k{A;JtBVYMz_1lwNY>xG3!<uNnv#TA<jp@m3^4H1D@VbG+y zNZ9U>c-Y+Jqv-pD;B`8ud-y~3W7f{o&J@~cx;xVGnOXwTGDP?h6;b#vM-x1y(W)fT z2+q<(YM(n@<WNw3O6I`l@zFD;M`Y|Nb2KTDA0V1YfkN;ERfi|82Waiz#pQ7I(F8$o z=<(g?leo?aaR%e<(k$B11)7P4-_F_sD5O>2klDIcq8Oo1b`zt3W+Tf@dwz{#QDN;} z-THTQo=Tq(O@<GYM14^U1=8Ec4N^w%iD?6V#X4~q_DyK3?SZ*B!Fq<u$WOdG{HPl- z4vYb%4=Wy|13lWQ)0zFrAj@bfZIZ6oKjBsjmzHpH$vMHHr2C7LKVQ>tO6V`^)hZ>B zNKw62^I3f`{}?KodrE!m?%g0(T0qfbjLXA4C(UP{<VFj<W9*IcG^tmICOZ?ew=|<L zk2NmL-0NFdr`C#_J8RJu3+=VL_sk}Zq3I=dv>#8$R?9NSHj_jbK_rjtY&Ecka-qi{ z<TvRW6WN()2?I<!0tOdf-VBXdo@b1@%?&#_yY4zsnCwXT)6+b~6AF$cgC4s0GmpnT zDgSy8rvG&h>^i!ceV0&}4Q-_63d!!0Z`jP0DL<a)5uc0tis$S#vG3Or`Zd?6L#P!c z*$|cw2(;Aw2z4067Js-6Xx|}1PnH7PiB)AK&B>Pp!*NeK&s?!g94>}8U(qted;pkv zHnbsm$&kH~mf8wNf73(L8~h{|nIjHjF1qOmT@Aed^5&YWxJPX}KO+dDFN~6*`I%ZA z*2}1RO^)UFD^Wg|%=bjYymA{r9wTmW*;0|sXZD`+a^NFPo<At7>NwnbAH)(h)@3kf z^}rP0?NPkfgmO{ASh5ZI86+NZo-_T1%cKIW48YqZ+bQRr3amHP+G~s(5b8!(6Q7gp z%>VeVV=~C6Y}a(Li4fTMgQ3_SIR$4~Bv)<&<RW+TqtxpB`#GE9gh4&l{k)8@A>WtT zYJ!$PVaeS_v(Tu^ryMLTOffe#YWZ$qe&0ZG5Z!BEWggpPz-#fHQ1?s38gWk%ZV8{5 zt_if(E;1EY;10z`NR0c3_8JM`#RuJ;ixXdOhgI8N@?UNPN@5*4BnKh&C5|E_5#CA+ z^<2Ky<J#R5m0k&rb$%AVyz+IVn<9nhO1-dmYfc>!k^YM!wJPD=9UOwsY`W?y-+nM` z#5J;i8x%uI<%wLf*#ZM*m9JiDza9$$m#gxPKIcxZG&rXA#Q^(wF*S9X%sGj%vKNGb zn6dLxhlgF`nqCJtR=!Ixe)GH+H;pj%7_i)TkQvV!wg7ya8>nG~;z}MgRBn3pI#|56 zha>vzuUWE-?>|}ckBshvFG{JKk0(9_aBuD_{AkHf#_NqTQq+*bJLKPo+lYOW^Pf7q z(I4div$GvY%6}&ih%f?@Rp}&O&?xoKpzif?-pgGj;lJKliRNKz-EnbVE^~)EnPj4W z`1ypsMha?T2??0hc+(MZQ%@r&piYJ|mDuZM)!G`Nv^;rK;XuhB$lZFS$n?4(Pxg{2 zIUHBVJbZ9yY1~pzxKoayD`D)02au>!FMB;=O?kYkPyv$oiD=P!Mb<kLy#-76+}4XK zkV7g(O!DTHsIBnGuKH(67<|W`IeJ!i4%skH$*u}W<a^tWz^lPl$D%ifNzH89MH{H4 zHs>LY$0iv!F~|h`)vLkYkc_(=Jh!1hZ`(a&;CBmG=ffvGwi;De?~)<$GmNED=V^Q_ z36GEVYA@;n%3gzS3EB(7&8J?nE-PfxX3RF~XwkHZQvEJI>POrt=Ya|rcSQ@4Bo(&H z*1ba{;d5mu;bJ@lj?H2GI`Fn?yvuXW>y$;1;(jS@?aSL7!NvM!gG@*mA`$OgxfnFg z<U2^?yp;Gra0-(h9750M7P)M5t2EL6+kQIZ<>RD?D~xEYkgjG#WzS;gz6w^VI;uph zIxdtfZcCo!BY!#_%h7pp&s<xIX4B6IvS)~_q#a)gJOMzLk_Oe1A6i`h@NF*;V)Ka+ z6|<Qrp=*UQ{v}EN?As#ty(<B?nwW3udzsD73$4|xmLjC0RV`Wc3R@!yA|iIa$eLgo zqvN}LDqxo+x&8h^<!lqbl`SOWTA7n4RGCwIF^JF!J>00>dAfN-CapVoOl6Xlz_GJ8 zVQw>TwB+M_50h~nooM7)_uRZ+hp|lQs^2cVk!#(QRKun$(wl>dEm`ee9SKZC-XW=3 zZ9oxSoe0fT_Z8-SbIU|@ZU5mCp_ZmEp~g}4?_9h;JjE+PXx44KPVt8}z4uReiFwP+ zjSXG4r?mJ}o9j9`+_wf6Xjv@`FFHO2<JWpO2@&6X#d>%7T<sr!QliMzHcNYJWgv!# z*Ip{Trfj~pWU=;jm&BiZx^i=MQecu6bF{-sc@gGIFtq>&*C~gp4r{+d46TLWM@2iG zE8jMMI|!!Xu<n8lxuPNk&LMdija@^g7EO$UZ2@sEd_^(ZB=KsT4r<q$COG$F@HY|F z1?Cs1Gs=`g{^S@ek&J<(IUs8D2V+u}z+URp+z;pJNHM3T`^$VR<4ZiO($&v>-|EVU z>f$AZ9<DKG`C;YEL05HVN5PgNtv)h5MXzoeI=2DrI#o3Cl&Q`mLUifD1|2VeD@!67 z`REb4;9(f+mim$1%-Pb<Vk|q8il0bfcxcWBYX>SKOzQ$B{x|i;Gs8(w411*`3Kb&? zHv3<Kk<hP9ANoWUzvQJ0rWolZDx7U0UABJ<Cko7?r5iC>-D6<AT57#=!z2+2%}sZh z(_o5EB&koTmU^25R!c;$qje0RJ*ql5QX+v;3aMUS2m6)nBi|9xKvx1PB>t3_sW%sQ z-bgHvsomuBy<p^+LaVUej1erQgXCz7CeV|$XHJ}Mbd#iuZXPDCB;JV%!3#|0*;81T z_M-E$C#<$!@#i#~<U;+p@8i!Vq_1?u?h=0-J<ZKWm>t(1uErr+mCT#!7k*lbSrso_ zw_37jHpzpL5I#5o>9l%#9;)2Dqsil-QFZN@|IC!XLRvwB!>nIH8fs{XJi?XIYzx32 zd_?E`-?IQXM<aIQ;~)cP2Picpv{w|h?iZnQY)ZYB%7<a3@@#1HEb~l^DJD94Pl2l~ z$s)U3cA7PPf4(nZrVr&;IvcO@Z2(vLD~!XVMRu`s8bR{nxJ7)YE4pvGu%!p0nqvBH zou>Kg7$6rHYCqkUtjk&~lpms-E({+hdHKEj)fXMilF^ulT}2Gj6GXi>(F!WP^+pXu zX@>B|J2GYimWWl12vx6`DSx<K>>(X_-p`%<);2NvvUTtJ^Q`qw4s++@hl9Er<R5i9 zfM_-Y5(}0IZy9YtfY=khpX!w=yePgshoKToRZgW9)&KY~7hYY#mFXZuyzb>lxbFG> zf~!W)eVo#-=H7b1;OXlLxrw%s_n)Wdq5gHVF`w(hpJ{dTD|OdVrFEY7(?f+EQ&RzL zoHIA}?NB4uvZICau|QLAX!f)g?{rx~_K+QScMXeJN$gs?J8IcDM^NsNS1%{As7W1> zR=-yt?O)M~_aC(4?N8y0?(~w?Wzie<65v8zC;I%6!ZMmoTwT4^qf<NuR_0^UK-9z) zTs@=+3;kxlY2dSxT?mQ;zXcABBxE}f{KbLV3IMVycf3>Rmn7g^l3}jY#SPBb>jtxa z<eqx>6?mNp7{vz-jAwNIsZpzsCUdHe{T${3{?A0wclcAP*T@>DRMyU-a5tR3$9EW; z@W=M=NQ#2)p`~3T=o^ir=ZCQ}pZzcx6(L7IhO?hhL@n*ieuuz|XGOuoLCs{gcJ@zg zM8kBfQ32Y2EB&mJ!Ad`?x#R8Nb#GEzK7Wk#w#J|Ddj8-yGW*~<&(I5Rd*i=5X){5} z9ZUOqR#{rvRNX~kt-IJqs9GOIdz_KZga`YX%)ZC*a+ltFY%Gg()#e1z2(EvM;L&CK zzp?G{6Md5YOR(#!CJH+&HI8fo)c;tg`oHex2sZ38jwB>+bNz*V`?tSbHvx8TMhVhX zfx>?&^!}Rx)cC^=xyFcs8})An_<x4?Nk;z!^F|m$8-F>Ee|yAE%YQ0!mdW4<zyHWC z{@e3?hd0KB*^u$#PkXL^dxF1wgk6Vk3oIJOF<bwcGynH*|KAb*+sXac$NzVP|Ce$8 zugm)Xvs+ke!V-G9!&c4dJMbtUHx{{V3Lesmv7ejXL@=TnQe*R*iMOlSPIII3pi0RZ zg<EN7@bW6X56N=WD|#F~i*HL2y)VWKpYaes938A!YttA?&lHayF_-~v{C*7!8c29< z)(BtIllm^ocCHres-7iYQ1+Z^aM_r=w8EXbgs|5vaUc8i)!fEb0=Y#04nK(KS(W4i zWEH%yMOu}AdKqetA)+uM6^j8i`O~jIhZF^)e-aE#pY4k-)H=j7t@~57-t3nBPn!41 zPO!r1;RyPvr?~%5Y<(DEh4AW;fxaYW`WZQ(1ByUAKc0P>{Pq*+(nRofbK@_yJ%tB# z0rPf6#c$94mUOhhv=Ju-9xUpRU2GYwYK3|cIG333^|GVZXR#NQx||cY*Pn}t#?D&X zVuKv6;**oUI!7#cz$70lK+IA4(vyEZ>@~M1tN$F<5pyoCb46xvN>QKD^&vcq#3M~+ zwL{3qQR?qk^V=qW{~JEPPKQA@Pq;?YSQw<-zJw&`6*||Kg@EdhKG2?IRK>Gn2aOC+ zC5wF_p7bD6j^*exnR#Zj7eJ#L=b`e?9coU+J?Fj1LQJMDX}o3Ey)dafW5g*e9c_X7 z(=Rf!m6iH2L&8`0H3?ahq!J_L?oeMQ3A=Anw{B2#^j&UfUt49S2sg@(Wqx1nEK6%} z@o1L!D^u;5k52$uO@d#eICLnKCfAK`92uCp=A-V_wx3cuFG>olHkHrTwdWE&os|lC zLu;+swWI$FQ2xK)yuz%P^1w2*-Sn4m)MCP4@HYI2_1<qNLE)jKss)N!l0;5x>*~ro z1V`;TwXfR#HXoiM;0^SsFXnEV!+I!W8p}HOzIU=ohnoijXla((+m-Md@LY>efG={Z z5MS`yMB;Zt_V?3I?U@7}4X+VW)5_rC-~g~trAP6|B=nHcI#dRE!EKEH^um<$-lf#n zq6*~vpd2w^jj%nK|91zi%K@`kqqj9Y&aHw|f08;V8KG{UMrnsz%T{3<0(<d3#0{K8 zu8NHUe^B3q>XI4B)#cK$kTHdBC$8G8t?4))$u!8;eiCv>f}$3b@g6mtNw|D~N~jkt zn*cN@eBm%Au8S5~{OJ)W2$s^k>kHu;w!%hM#jp<~&62=#if4d0209eky8<Gp0pk<z z98-8#f`?^*>0cv~&L_}6dGUzy?jw?7`+`w@B?Q;6Wr$Cv;n)Z)QaL9j@=+({>-|U& zi6+>RH>_Tw0?~L=Dl(VukbNlx+#Go7WEW|)SYnpTP+)grqGm`67@=hlSrpErLVg>} zd}zdqYlkTM%@C(CL-24@Ogz#=?j8h}hoMjagw5?6H9Ik^85j^4iS}?<9jlr0zRr&e z!yFVSviB0Ye*jGB+kh4y)T&%)3bv(p2Bd<+w+4(!gD`QnCIg4VnBVppgt5E`yzL;) zXZF^zOyfn%Gs>e1myi!irDiKtwaIPy&1Kb_Fygc$KikKU3AYvJkvvT88HfJvctxHp z<8rLzoUW{olt8f~vgaEQbSJ?AJ{c+5#_S?xA?p_FeTRJVSrGPt*dk<i!*3hgvJPIk z?jcf7$uncbD|$p${K%XTaqHY-UaGG{IgD|j6?EdXS)yOzJD{1Yl4Fyc6KWtnnB+}; z|LLDDYj$%`$aYgj`31A(=)#R62~^$wP}(_rZYZ9OMWvsaKO>qQ33HTD$m{^;rvh68 zeX;Zbub0T&qHJGYJ5wCHh9Vo<g*Ux96RL1@^pj!7ag{Np{4H$#MbbA1HqMZ0F(Q#g zIL^r+bqC@!eAY}!;@(VJ;p2@W!VBE0lN{odlj2d#Crex+EwYENsUFJ-t<VBy;}$FS zh|Bn}Qrz&w(tgGP_mMj5<L1~76J`>RJ+bOBlmK%g#g_NOAFnD_ne>LUa)m+*uWn!W zJ$rZYoNcEC$7i!yqB|LsUNDhc^sl6{_~^vlDVTIAR#=MOOOfQwMcOJk=%|~g+dOk4 zFA&Crh(q5OpJ_e_UeUJ7``BDrlob_qygPpFHqP=;-qt@lZk$|MBf=MH#r64MiAY6b z;K{lQKV?%(Xa3$Bd?o4L@<fB1cK0W(dn)=~+fKWhILu*yJF|=uwT4c9PvD~{5D?y1 zIpRW8Qul?z!@{%c-a9N|Q%;TXu5`;%w0)Xk&?TkHc;zBrY7Bo|a<pK<^Tg(%(m3?$ z<&Dx;_>z7y{oyZFt9-I`DF|uMkvwM4C<&5_$jo1x<T_myOGi^1xmP6&UKSJlTb_Bh z(SMI-Px1bVV1H=Kle2x9)(rxFM<$5H6wa%E174Cwkyy%Tqp^z2#pY>#(`|9Yly$Gs zswI!E=$dwx6IfiuZkA6sMOtV`DLQ#YS+@V+n=vNNuHR0>LHyO=3SCy?l(E-fpXgY0 z+c0oJkAhpi&RplHzqrYVq{x{kO!V?O41W_ybYT5;dXo7f=h2FvM$VWhMEBS=9aJQD zgYl31V97Hc$e*aS=ZmvoX+M8u9vV>P)WIy@l+&@f;IREU;Vx%ZJbLCp+j4Q%K(utS z1hM7bN~d??8TC_JK+umby-&pD5!nTIMwbES8k&A@G%|Z!GN9&*YxFY9Ns~g#AW2&K z$(U4Qn$UI}Wr*;UY%d3q=uM59qh}7Pmog7coOo`!%ZNBH1~IB$=E!moc2PeEeLaN8 zqrOb22<pa&P@O1RX(NjfaLjQc(dU7w#H;bGgN5PZWNDLn(~~MOPG!`3sKgTQO+^EQ z&rI}_eTW)P)sQF~r((8L!@>Qh!;B)<#`zAuAeuCx?u)WM6Q#2Kd6Aimmn4+91_I%W zM9H$bR-5~!dbQ>w@geh-R`zazaFm<%orJZhI{n1RoO4~);*87X*k1$Z3~X&g^&BV7 zUz<ud2uoJ^;)$$#Q?TnIM^*G4@P}C2OucA-?o6HRLp6LAtFcf5S9qMY7D-IKAF$#C z2r$1Hj-h4OaeIyy-YfC)PEtAeSX3N@FYXJUq^lU7r6CD;C?>1!I3F)+`c9=4=i6FL zpWW!)a5%^Y#s{g`h&iO!T2%CZ|C&o+RS|Ds8hacc^%k8a(26C{cYYM<Lt7mhtl&%H zUof&s<M^z`w>eq)+K4&jxN}apX<l}={!L+p<2)*yGfY>bBKobNd2mr7pZ;0VQQ=0T zy$Xe~OeQEz+QaN&-n!wU&AP`b|IpYpS;q4c<sxlb{k`TcA>pAravQzI1V(iPgw|Y+ z)d!w%sc9Qg<2cAfef+ScWLHvTV%%h_$`dyAj7GG7iDHY6^Axsw7}J7Vdo?T}z#de0 zW>cV1)luO<%yTb%-6BU7abmxwsJa)vXX$`<uHD1olGC#ESRSq5GvpKxee9cb^L)pD zn>m+r^v>A_ZJ-zB!LL;^msI#;{%Xu~pkcd4Iu8V?nE(6sZq!qb$`<?I6Ydqkf0ArO z=eJ(aLQvq&M{|CL%}9iLVYX1;blOR8Q68!ytY5+?qRtFrCHHiYC~JU!&oN{Za^_Z! z*A{>%l+i{x-gB4KMg`CTi8Jj;$`f1;GybwF$fvagXW8X&J$Obu4*JuprSa6_wa`b0 zAGXM)1uJbzDKc_e{p6ZlJ7P=E-6XL3_!`8}kSRBLw?)ir%dkiW{7w*IT#(_m!Nuow zBP<X?RhaE=k>Tt%ZQ1z2Nvw9Hi0jp|Q9FhOzTD$H;im}%ssz%jr32K`#U12eAuEjJ zfvOGB$d5D*-d};Q>H=}*Py6PGzPhY#MbIyip0I?xIU}zEaaZ*+FF%jCD=6m0BWhFF zu6tOivOwK8xps027h91@1Dn5~-oB$PIiG&cRpU}gK?x3;rUBSVo%;q^y%n(}JzCQe zljl=e&GJoArQ6OvQw|4J6nPC{Hy9cUD5pG3sxTbqoGuVbN(@yA-<6$K*8jLMJi8oT ztKuxh6i2BKy`^i=?Xo6qu16Vc{`q7Va&r)=R+g-+#;OO2{#sz)PROghr8ex#vJ~#n zZ`9F|G49QnSW~&k^}ZV(s2-c0hy|=)Di1CDv-Xa;mhcSJ#XYQafnh(V!fWDX8h9-& zxnd|)Q4@F^xa5ZJ&Mz|Qx!sshYz;@5tD{l~(<?QqlU@7{;6U?j7oOtuPv8zha}KH$ z!Qg?vkHHrdG!&->@YRRxGgmknD!Gi^Mx9}`$Ub?Z9?Z7Z6$1QhlwbehYgTU;a~Q5E z#g;HPB%F7jKcAIj<Fh~}cDOd+6Sq7{5VvGLTTIA_VHK?^w!OfgTin~;g?bRp5MkO) z#4c@Y0rpcwEUs^c7mMQ0Ydg{Y!d<}FJlj1a7=0nUYXBT7tO4N?i4}A0q=1gIR~qs^ z>LE>apP=9Ua@6K*Cjl@K)x^<neksA;OWts;$!T(he?2q+pQ2MDrXQWl(!?JzdE-v@ z=jRbam{r`RNXe)v>V`}Q)zEyo&}OuJPlkE|DVE$@VR~5U+_L4B!KUHKOj>F4XF-RU zw`n;vhrL8I<(fbA!7Z%b&zS0*bv$sfAzGWZ+Iq;SkM$HBY&qwP@FC=*leaJ>{&7^$ zhk*6|G^%+R=#4#b{x4onO9*I0u;L5Syam$)Ro%R+v`|UxUo2`UTQ=fVm}NY&(hFTJ zc8_FW=r0zCx|DfOcGbHluiEb3aH0A%)qah;!K5OepB8IMr=f{jXxTkzl^`w{>TaN@ zt?2*eWy8W%bE@qtq%7?6Mz?_jD!LuJ&(+5uyFL?&vR~(3x-b_Y5H{Lfrvv)EkHHMq zA?@hH@r|c0WO+Y(%JV&>fS5BQZwz&PCmrt{IC1hNAJ>T@G3j$V<gJdE`czvFQQyIy zg`R{f#8i?Z`nS=}fG5>KGe`0Pmm*&5sgp70D_O-i0C*IMTzs*;orw#rTil|4a=V%G zJDLy{oZqJ!UPK$=0Fi@SkX(#Dh6xYZY@)1XZ6U#x&n;OLe`tBmsWywpC`lJH@z|}6 z=Y^i5a;jO$WnDfefd*#x0s^Ob%+rX&*aD~UnhBe+j{B!s&(>;eohN+&Lz)|omr1Mh zj)lUmB_mD4C46c4kSd8moh(s7r#$$)UPZpuKaE)?Srg}8Js`*v^s^9Twx;r-O2nXR z(L-f(YkdI>$WUt#i=5Fr(pY0I5o_9|s#2I5EsMKDscJbti7li7OlsxnIPT%py~<gg zs=($Ru4hr{SYs7w_ft-R3L5jBjMU>JFBA+BfXrcn6mOle`bbJR2gt7ZW)~M8ls}?4 zkP=!)`cN`CL!6|PWCia=Q<LVvrJG8dKUimStcQDM{@hUq&lniYVDy1m&F1xcnwx>- z))8|GzqLJ@$sDhjBs2)iSrj`4K_X8g@yjzmxQs2tG`R9&o<109nwc(oz+f~cqO$Vh z2)FHOgY(<d0F>lT_$1jR%$}p2(d=WxBJ^`{8sk!;a{S*_)?~H~|L}#vf13U1X@vZ9 z$rUFQ$QKSUY>i-hYK-Br``sv?OnRym&A1cLm5T{E!=qU$g@9U?oYT*y*ZJd@x}!47 zBs)CxPN`v=p+|PdsWJDW7lMaIiYduTXeEfO?x0XER5ISG9!f=9Qme+NyYz;g%^53Y z8Lg9eJ}708*T{_6>4J#kBoGp+SEH-%K)F;bZ5N@S1TR#!nN(}^&RVMgwC~T)AMd@< zd1FZDOom<}dR_e(<5Tt^>D>lfpkmmSpdO4YzXd`#k0_7;in1L7NEJI$*1;>A`YH{2 zD(X|pWz18`VBFx=D9@U={FhuVxvx=_?^74v0$9pe)$;DicV@j~zvW2a=5nXjB$6GD z^Y9+ZPS{yz{mv7%>%+IDlLRGhc~pWz4L8c)MQi)#22T+#JM+-anm7Z)FK0_9`Czpk zOF^Q^*Kh!WpE@1CYf6kkpDFZTudc2nd@&2M5^W)$otHZa2082}nxe`msb$8`-Lr+; zlcFCOuw@QH^TN6674n9nYqf0J=*(Ik0a_r;>wsJWce;=;P}l+_&sN@QL7#K+iT`zi zxyJPo1Fe#hviu%_J8s!i^ZWL<gRynKSJ_LmI{pL>iV%46BPqF<!>u$#K0L?lK!&NQ z@ZXxD-@f)3^AQ2Sa8_bBpGnNdY+3yjy6hVQ^VrcG9)T#cwu<sHPASv{EYz2<X0*19 z`c>``aq}t(+PWkw`L^R#rMb2AD7J5mt@{}W#Zt3tWO#`~3~^3Mlt&VouM1h7GTFtZ zT>jPErNw3tY7XZ?1=Fu4+M3N<>%ixIx+Xa3Vd?$lEghEC+&oy55$@DbG9)#bI~CeC z_1#%4$W+<!S}n^4cC{XoAYncy{Tvd=gtS_ztDvzPChJgh+uK?7xT0{A(i0p*D~ktt zYu-KE&U(+E^m2-pg}-9oe?OPP#WwM%JaF=|8Nzk0#g!yt`Ovwb`|j{dbd092b`l~j z!)B`=a7>{luE`OZv10iIkpt`9ljdB9@C>Uez%UJ$;r0=)?UPR&V%cG^e3(v?FXQul zpy^}gmFYKiJi+(?@ds4p_|=+0t4Njqh8t`6$Bj+nPNdt!41K<fII!h+(F7p|2#-3I zOPC@$(&-q8HdYd5PIWw&SdpUl3yCki=fnbicKU8mlW;12y13JdTBmzRtfa+Q^HkT} z*)ZQ?rY=D<@pSFnV_DHLt-}w1=@(Jciq&gT=IxSWg5ZwA3prw+B);&`K_amg8aHN~ z@K8I%!S_j5%J-l6cmg_Vd1X_Cm5>iS39<tj^(C{k)ZU|@ll-#H8G1yO*v9A&E^;d6 zl^PYt>CF&l^0o_6Py#;Ga{9d6vfnyD;qA$`k${0>jYWx?<X#r9Rys#nXdHHSx1Hso zg~pKoQl1!owY)X=uxP4->Cr0GWi1m{@+@j9gd0WC>5fsQhKK+R848#f+><RiLQ6rr z!3<$JiXS981b!;ul#}R7iDUPkBhz_|RADBgi7ZqPVrnN}Hv(U!SKN(+@9KM^f_FA> z?!pG$z7_B;&=W;Vz5#wQ=Y$FV0zi^c`_j@eV_?~}X}V~VA)J6RhK8c92(@h|{M7S0 zMn=H{VY%R}7{SBpQc$Ravkc~W|M4wFIm*2f2a_^@Mm(iPNjZfz$8tawMQ<Ha%XlA@ z_KE+s)-|NkQ`^LBT#v~-+Q(ZFdQZe;Sq16Mt!vX;!O2dG4H#|pU0=|b&&Rim{492& zQW4Z$%CJcU2y;^)J}@bp4GziG%llJ(wr-4fLObUQVu`rzY4C~ftk9V1FJf~Uvj|~% zuFE{TD_NQ+jZ1!N65=oLxs$O>JOgPtZ(IT@t&sI3!C0uoW}sv~er}&fv#5Gv?qK9Q z?^zvTnUJp+<xS-hd?wZBJ&Av0SKpW7(h{cgs9m0Y%xRaE+B326d^cw5t;9&O**n4= zj5@OpSYLQi`5h{+^nUk6kU~I1k-Poxgx<Q$KZIUi?bRh4b1fJ?qQ{dS*)Lsv;LzkU z3KStuvzJe3B_!*j%Uu^=Gj6A>yuMJGtB{OgZMrKAKB*d%I?>~0a|%omnEJ6AqTSbS z(jms_NZKSL@AtD+(<E(|Y?d&}`S7EUR$16dqar{-S)vE?YRIVI{96x(Q%o^fM5^)# z@5bSI(#M}6q8%np9%j7l)@~M7x6#<!3K3~_uoBa-TWYgMo{b3@u+@@uhb%$QMa!6n zMVRc0-+L(=A{mTj&<X{PG$d1*{JC?!pJG_ywj=D=HQ30K4^agG(!^2Kwf5vA%XN8m z>$v@NYBv=xL*8EU|A5OF^hcA4ZDMfDmQuw9ODdk*3{`C&z!Tv_i!jVvUc0|NkR*on zqYZbw=el|7=ovtJ{PD)c>&P?Q+RKAyg!>rhHNvuK&w4}g_fYh~eK)Od7{dByRVI!i zKr>vPt)?AOjPtdzyMu&&f{zZasS%82U++S&RR3&mQHAaTPs(!6s4u|bxerB7Q%_uZ zB6P7$)*=_tsnJa$EQ!B@=wH8UZPyO(JLaB&Z5x%etjgt0-Md5-CniQgb2Fk$_;#L> zo2p@xm#V-HnMF^wsEHSnvJhg%o`xmd?F)pJgKo!~`_b)bsrJkio2@*OX$7aeKUmwM zG><mF$Toe2a-fy@QV-qEmwAhtm;KZ}gz)5i_kpU`Jwg}@BEMUm-eGG>l6191-Jj<n z?N6fueuaHFieYB&Ku<Tl*m|uOit($TbLm(q*=0`~UL?j_whfNs9$1g*?M-f;kjrIJ zBcH}iG1yy_u(Mz#BFcKIaS(LLy409?kv6aK-%4lQVCgL8_onBPlN7(F!lzBKLXSR7 z{aeyE`(}ZUMpY18N|*RhF{y{VJIn}*RX1Z^_$!Yw#u~4!nc-U^Tw*8RAI~dJj^;A* zqrRV@E8$~@ALYWdMW@spC3xPi2Bcjn?xke?BFeE=_{~!y(pm+iT<F-m!9lH(#G15v zk5w<;oaGJ1+3tIc;!$rV_u*{f$KP_pHjQ$W6wSp6M$Upqy8|PPD6js@)G)Nx4c-^o zt3vF)TlqONQc!a>lOu>N&|YNcx-HHaeVNMXN?XziUkxav__P5mP4_%SAT8N0&YPNP zJpk3o<@E)4R8{2lr^-{PIMFxzkIhq^I(!R6(pX_PaE>YouT2o8DWE<S41RoApw|ms zSmE7JnI^1}h@PP=8szc(ky5D*p~ahQQkdG>{s>)kx{Oon<MT*gM4<4PpM$7L0p;4} z6Lc=4xtH8{)QEje%vXs(>UrjqTvG1Jcgu(iCyct@*A+P2(zX&Hv)$*a!=Uxe?cH^v zFZ1+f*%9W!F~|GjzU_6a%NzzUJabBg-dS)E6{c>r=sCXFTb?waO!b7mhAnZF7RVe; z`88nJY&vPhcRYjx7CZN#_f;WJNy4QZDc!;;@vqB;zF*kq=CtmA3<&a|^Mjd0s}cjG z+BlamyUcC=<ps;@OY2{?=P;2Q7)Iv9P0SOT4sARRVUQNqLki(x$+Y1IayYKr%XfvI zlb8reW@co?{uJBa6P7-YDE?z2gjXK_vv)->`KPvM9e#;5=x$cq5k(`KwzgKny`#KF z-XX>uRebqvTZA2<yeQ6(9u8-ShtrpDqm9{lS%Zu11^Frq_E{bHl8y)=+8kobJjC+{ zr6S&lc0(rPnVk|A407lqmhGH>0@ljh_#)1$rMcS6K4@4cRvHzY#Et8$V^CNor?q6r zfPiCZafrf8p4}m+9|>OA&J3qM;d$Z+pP}k*{}7l8fo(JFm(@=O9ZmL{tf3#qg1~BQ z6jleaD_1AwZbwc1g7i0+Rq7%z16doG?Yq_Gojabzs8U6dI>(MJlvw44&@3vMuo$<5 zUoI-Ry4-4gxQukoNnSuWzWK7t)%n>FZE+M~?M>L~o!!tb4F(ttUwW0{$SIQ!W}L}5 z=!tYL1wEjx{P4vzJk42G>de;#T*x4xN*b24h!J37@`L7`foeEkNc$t^!6_xM0IlKk z+v=a+pSe>X34TY6>To7<Ssw>2yd+q3Op77%dgvVN)l8Ng4?c62v<eB+1C!>fsrie} zR&pfC!sXH_pXN`n>qk7jDFGh?a!ZS$KCe`?7en~Pm~awk%#oEnrT(t|a0!By5B*=2 zy_ZXvgPd;w90`=pIlHEY_RT`fE1z8YCY}={{6F?)7@`l)MD~+o$&EW$OjvNGk?~FH zvJU-N!c_X`4*zMHq>%T?QY=eO^&uxQxWcOYS2O6dm8fP9MLK^~@KNau!Enl(sd~Yq zq1F$yIR&TZp$N5aFLhG)EOlrr7{pL#v#HH^BvWB3d`~^DuUeWp4P_U0xaM66Odjl$ zF>49qwd?(<&0B2}^0Mp!VjYd#BxbCl<Ou<#35*n#hS^1Pc6&YHrn)W=2gF?Ks`o`M z^s5+_ly(bg2TrvXs{x`LTFh&q@fz;o=;6TfVq}1d*=&K2SsoVN)6w)TEFbqZrR)2m zC^kVhiSq?X3`SQK)G2?$&M_@7MM?If00=Z1tz4Bwjxx;%+~84qd_GNKKHD}YjS3M5 zvJvvC`)#IL+hgSTi}zskit&YW0TEkNPP7DKkCz*mj9WsUGm^!(avXBFp4MC@UHY(q zNk*F5?u1Y3P>WqJwIfQSvLk=R+?Z1@*Bj&y(L%eFxN$a6(xM(i?=M1rQO|G}x`~t5 zWwR=y&jy8FkWY)L>U&+REMmNrGX#h(FDoJ<J+UkGQYBQ0T`m7=(TWrO-z{1qYU0S` z17Bv!N3!+`Tb2|FSrH=eqsb?1A~3~s(5s9}u&a6jQSh#yNeU=4(iX4i6&0fw6ra=5 zxG%7C!G>HtT%h+GLv%jWd++$e!dZsR{hg)iAvE^TIIA6zGbUXX2q7Fljp3fZiBZRh z4q}L4Q{(DVxX3x@^ti)xZfFaIj2F9&e`eJgiyz(T(?(g?$FRrp_HJ`1NH){V;GOy& z&=A(B`z*G*r)dV?EqTH4-(YLy{&8>c4Y{6nKm${h-5~vswzs%S=CD2s+CSJ=e|Ypu zt|=xP6>miG{I?@1VxncQDy|G>6GQBCC##N<&YGvCU&!x!9{38^jFHh5!5vgRPJL!F zY@@#WT;y%5ZfRjMxRDopHx<2s>Ipec3zic_M>fzKwMb=vmd95hVI!(R+kPRUZoN9( zr#7qfNLu-cUGkae;<U4RuC5SGh>Nk72_vfR)dgRScK-kFHd8+&+i4vI80}5HQZBdP z)KIGun^I05b8?Z<?5|iYd!|e2W-cGf;AM~*pO-Euz~H0IbgScSrjZNDuwsF@_i(To z%#LddTgZzjAYm{r#9N>6krrjp=p5V999$T!N#)%5v+qv=D?S+&lh4Km0W}k?ndoEr zp~f1g_j9;-<Btv%cGcky^I>k3D)^0TWDZN_DzPqF>$_|G^HATlnt7?JKu}T<v>w^0 zY09F=Tz~qqKkZlNn3Ji1fmk;H+b=!HECua_n*_-)Y@gyBY$<=_y>l^lUl)Ka9`F2= zmTPD68!_&K;M@m)`sWL7M@GZ3Yy%s{a%#H}#QdR*BC*lLVIjy<k6o4yJbHdW?<cVG zlwDcvlwGoL4SX<37q)|siQPX{eKQNCSqsk`9gwbZ_dTw0J?=3Mx?M3C!gqj<YocR1 zSvYcEjqe2|FZ!ii3N4{rv72uz-qLCCJ`Z2DUhw!A=QY4x&{p3;58>oKOPe>mmaVRU zdzkH@RC)(gw!o@N;pcg|RjL{Zd}I1_tp;eM7Myx>d)OyRr-Asvvm3wYopT7K(x5v+ z4={y`Og9H4c;r(s7fi#tb%*l%d@LO{Ba;DOnNTr1j<*+VCs!j7yj0NjoVh{YFZ<uf zdO2ZSlKkgG!FPHS!KN-)wyuM3I=Y#>^50lEU#ltgWEXjxonCN<Uo}9iJ5K5yNL%(# z9te;1I9!K=#0x~G=2eBzgIG_KxVDZ9k;`)w93W<>9Q{S+E`}X@RIJq<c+yV^Z@dni zFVD(s34Dsp?`v%rW&=%;m`DJY_VqS51|70N6ObiL^+Jts;C&JLWaRUZCzVjJ^oCHd zZGZxzM(+9Ksd;dQZUklf#w(urI|TNrfS|0U@uY+WAa-PI4XEdH|C5}Cq4sr!Xi2X` zBoR}B<=0gbg?c&0h%Ke&E!WLB+l7<d=pw8=qwsOJWNv}aKL9GW>p{u(BgtbEZKyad z<Q&AJ8cxX?Bh5oH;)j_vW=P?mId>CC&J~j>f#9qkE5CEyS&)0G_6BG-f7b7^lTJp` z9DSiS8FC>Kz4%iqyG;U@<p(ZxpIZ8+793Rz29mjf-k#n&&$k-ILxaohs!y&@i?Y6c z73sx|o1q2(3a-3zV8b1X@v$cVY2Z@5u3T`@f?T%V;H980K4@M=MN!FEap!R1as)|h z>kXHMEz%|_ob=9}Mi<Hqr?n-=U`ibEQOB)Z^zRE?%2sN{zb(E)2_E>PN<EXZ{}jt} zc}RC$sKP1I$$Sz-Z+>zKPGNGXpuHI4tk;{aK>~?PFxlC`^YNxIeKrYulCX@e)1bCc z3GFcy=!VcZo|cGx!TZ&7M{?|5rGy~^F2WiGexbcVygzOpTSCObGo=m&nNELOT(?rW zqKyvNd><0kWRFUjg70~xjDZ+pTdDNZ`F=<aE_atx-Ovh5mNHHGZGJQ46Rd^Yse=FA zT>A{P-3O!n_W>}DPdNah5sqhg3H>tYX<_n6_8=jUiP8dFYZKA+jE@;DD%WxIxi~|4 zPa3<ZgQznhop9`~@NjW6btDitQYDYPbkbX#T2)X^kcU2LbZltzUFWXcz*Jk$TjQ-| zoM>@<-9|~|i11`rqi4aGqxZ!EM*T*g$HH^X`)#}Y1(7?M|3)D4Ppb~Xj|>!$_5?xL zGyj)piIG6|hlic{spj9n@Q57?T}cf^vcRSEQPpb@HE@2K>*|ET5vAqe>xXyG5(;0l zcxMPGi^l`N!?y&*?h?TH$s+Er?C%U^Ho)a9F%hPBhpXjIp+i+(Pb`?B-E2;~@XhzD zT=>P`#;#Yf(`X}2MNgG2SNsG#<!`}<$ur4kx;IB}WYnCp8wkft%=O;G(uMsgyyIJU z?jh_E;p-u>TkCoL%coBCKjKTt+q~??aYW&fdT~McDLUmsYIf1NK@wXnC(`>4KXJ4H zf-v<AAm1_BKuyuNuY!+SW*PW+ifp&^zCT(RNW=muND@Ium&<c@(@dLEOXFP)ottN$ zZ@{+uD!Y?i!>obyjKcFnSUyvAwl88n`_#$eDPcyE%ugx86u40BBnEL~6K6v^3;Af) zvk5=M?|~xR{Y<%;%MSzq$(90jwzJj4=;`}&CO<rnKLa8SmXGOuPj8k!VodtA?9%f- z$~eBPfSF&~Q%l1u#VM3!vu*CR(de_RL!?=89lm|c!V4#<f_#{l7v|b46>-wh4ozjg zrDsJ5bt8SWN$MnP&2^gxAj5yM*o$24%r&ZQvq;Rm)VhYT9p7ty;y1fmPMObj@8-lj zACt&gAz1z?51%AOXFjCAAyApULR9c|Vinn|LP_7(#&MBIk1<tgv5JN`xKzJqoFDAd zqMbA{FWqNpQco-OF6S9jV@2Y9^5j@LKLfX%M{yjBWuM*O;ZX3rFEfPBfWY<^)pbOx z6XDy<s=qC(Qisk@lcAjptqwSIAooTr3-#KIHJWXlxq#UnzQ0TB8dG7SW@=0?pQSed z`pZyL!NlT5t-Blzc!iu#Mlk7xV%u!2ahFwhTS%Feu!&YzuxmE&(<7>L%bcPS1)087 z9R_osG<cgwot-jeSJxpe##!w8fy{_vEaU4Hwq%lC;`n(+%~RzcPIC6q(6t#hz20LF z_vH=GYU`ma%?L#^x+ibOIm?Uu^~wiZDEZFF`Ic&Zr}XefWZGuJmG;4b#7t~y24sL5 zFLs7$l}VvnYQ2ZEcycHB=LV)DBR1GEW1fr$wumTU2xPLQ{9EU)N0o@Os-d(cV!OTa zIB}nR!=qP&k<=oO<*aThcx*O5)`xD9OwQ`^C;ggpH~(TZ{+IgVAKo5ybyf{qP?y)) zK^5U~APRNH=-_-$dTeFrP~@ysA04yQ9}U)kUr3JE4I~-k@Dg`3m0@*8hgG7qsdk>J z<O!2=kU=W4t4T#8(6@yuXTJN|Lb@i`WwX_lJ$qwf^QcR8Z9vGwN?Y-Q)2C&TSB9-{ z9B%&fdI$E3d@hkDb`tli>0%ur^MH*!+3vECd__<qtXr<kK{y?zQ&8KjoY8r~bIIIS zAprzm_LI!R3}mo<YTP6T3F<wSs$>A;9ds1NH3xXw87z#o_$?@C%pM|gJhQ!ALlCk7 z4pPHu%n~z6X8)tT?+l7^>(=xrqJoIzB%r878&q;^6cEX=Nlnf<=hRBhNX{S`x@lr} zlR-d0a!w62l5@^^@SHn$?l(2x@yxHOn!5bxqIy^LTYEiwt@Z5nu4nH)8(k~6Wm%J- znt@`p(Sh!K@AF@={euc14V|!_R1>|(lMFyKv+=m3NX38?G|(xE#yUYq7EB;QD)Bvp z+d;JGiz&58phv&^@L8Nwa1O)ic*IGR@O-?xGT<=JeIU)d*mu~%e{1I<+dMV?tEl%H zgS2q&LE7q@WmkYDd-ll2Wp2S?h~6)*1B#%W@x~KOzYkD|Et&R1m&9c*Pw+j@4OoAC z;PPeN0sDD-ZK+&Vh1zhc&p<1u=|uXsTF8`c&eLF<tq&$n-L5pf;zTckzv;?jVJA}! znW<_SvW92n*N=qvW(kI?a_Nhwi5eu8Oe0t;h?+C^K?kM-t{aMFxky*DeP#&}!i_^s z$USYriv;qDv49*{+4G3R!wPch4Y4tdc2^T@aA#apzW}WniC%k2lV7!!I5IJQ<X0cL zr4s?aT#C^prmGAPe??~o#(rrfWvguMcFFAFMqHn!wIUeP0;*^Hyh%l+up65uEHx6p z%fMfH_=Q_Ca>DvyH~{&>Gyj2L@<~2)k({zolQIbU7;Y_cb3Op41bFgD<~lvuwejA_ zr2A%jw0rkhfIx?4v?EW6lxPO~Q5{d~B3;CpR*F25E}c6+DQsec*LT1>I2kdc&0Zt8 z<do&kzqZaSPakDvy=b%%Ic5a$3rC7BZ7;ef0XH>?W_8a)4mFaQY=-Hww>>*Q5=RW= zq~-^nrH+(LQkN99=as1XZ@mGr9(vQ(Xs>?z7{o(ggTU#bvMBp58*aq$%B(m&hC@}u z?Hc_fH7=GL?D@W`b#l?O&~}OM^6D0!woQ8wP%&an#MR#mpM1J2Be=rL)lEuVe*D=X zx?v)yTaREvZ3Z0uRbo(6B8Sq7J+Du4#v|9p>LGOV!Vdt=al__5r86vKC?g4XU8VS{ zmy$x?dFp+CgXJZ*bO^b;3M$7=qaHPq)*>P52&FYtT=9V6Qg^(z11o2_S^bjm5sPH5 zyY6usY<$Kmzvn0xHBdP2W<;zNSYw#x(FYxGvvw@uYP3)uFzd0=UY~yZ-3>QXQ`vW+ zLxbHuQ7Pj0rwP8WwfUtZ!X!sdjZSsb?eA7C6f%Brevb(aApi{4MOIs2CgsZ2qn`Y* zki{a1I}&MQstilGdEuyCBfmWA5BNazp*9INU*)VNBn8}GBFp|^KErJ1fhjh5ZFfj% zJ;jldp{f{Cmk0P$k=BW+W0n;R>mK2_X{3JH8nyFHAohcZK)Dh(ks{rn%?Dk!4IWC> ze#Ggg0Ch&9a<XErN-}AzRwX+{Cn4GSWT-yecje-JIAlpg5nyQ46V_Fg>h;thdEg0& zZubO?h&;h56|}BaCAM(EL~7lZp4L<vUe;M{j9}RmHRc<wvx?eRCXdt^8I@H&GA<~6 zHeN6nMM~3ubeP5ySwWF>kC&|5Er@(s&Cy$E=FX@q`&;cYH;q(e#e~|OD9^Kzaf!<V z5?+t6dInUN%S4)Pp8C_2E)QeTrCyP;AhCULdjse58TD4&J%K)dH<dP<A~GbzzBJ|P z!u><idCQ1{sTZp0aWL9{E(JgIs}fPv1pdiCpkK$2e~Gd(J5Cmo=nB2G)q)?1+<&&3 z_`<0-`jdfrXf)lYy-32Hj%>GIXAFpjzy&{T)x30>d~qcAi`r#a-u|<H?7=+U&m>zq z_lb{xwnoVRQFlW3uS%i+U08E7`q?A#hWZ`vEO-)1Q}JUy)r|EeiD)VN-hrTSq-e_N zOf?fYq^D~Kk`Y5Z%0I_<oMSuLFsC)*_ouo)5(m6m>Y;8ArgmCED&}&~0)y=(D4NOs ztRsAze*Tv{t)?(tAiikaH>Nh;&3gCFKPWPU-emr2GLyv^L#3rB$;?!*=O`SA%f!Bo z`#<QLMqf${3$$j$dwiW*#4o(UE}F4<5Mv2md4-hNN&D6KxyAfT)kbHzic^;PWcsov zXd0X}{(fTt@O#d2i_vnHx#}G2rhD=@&TEC&K-_pYNm(&MaK`gN7wO=g<>wA#zzFJ+ zm>_<1U7Ygl&cKIQv8@_2jz2{xLc3Vysvic<(}sTBv`sTp{x6-{_Z5?jlbcKQezQxp zZG8Mo@Rw95_bF|n8*4BD;&)KR^V6D{K@-c!D3T8KML}b0Vl{!6s`lWy=K0+nVLK*$ z{DjV;U9sOY{QrEm|BdKNN{^?U<oEXYm*sNP<o>lZ_nYv<lix%5FFG_~y<a<T@(4@+ z-}mMIOV<DT?H2`nEzc$Xe=)sZ^OPt5Ri+Af4*u=wZ2vODKL{CL-}oWU!`PmGB8d2} zlOzuKRmh$Fq4F;i_;=c*|MESK^siR}cZ?kV6Q6(h&ws=C??c;v!}#xA^#7SRW>0qZ z+-L#Bcbks;W?LFFzJ;%I?|hqbQ`@N)3j*%)&_IeFM)6wPY4_;g9%KLLC1Cx~R$GE1 z%fVz`?fL=mT8~oo`d!;mq1^m_qyP`qJ-5I%(Ri2p9JT+@$*UrNg`sa9l6c4ZQd0Qz z^j7RQT|hV5^Tl!rsp;Ur8*cGqN?A}$o){3_=t&YSe01@k$g`}=wEPI^J?vRn@VdvO zBJqb|7>dpzRG#D5x_64r_5yN2wei{ykkK@LU5<rMY#f{MO~sn5>y@|nVsgj6lEZG& zoLrwZDk)=bISKN%?c|$ptLsl1wJ+Rl?RFxY1Q&!t6`$rxChBkT^8Gd*;}iDs-MYmJ zkPv;Re3Q7}|BA;?MJvc}TASe#jX5tv#_4o7e6EEagFS9dJ4xXTo*z(l%zbxY88|G1 zQj08mOb7LK2GI>=D+OsxgnFr+dIk<CUs7G($nW+105!VwHJL;mPP^|D`Fps$KW}qg z;&ELoLxCqx+tA)I&GBZ@Sk^>c-C`G$K-pO!bFC2Pd8;@XM##S;EU`I09&$`PdhM)t zG>ymyEsYRBf=d_cZCFJvtW!8Hn@Z{b{fhiAlCvqhUxEA9si_M!iiX-jBc!-Myek0b zJ8gMgLUcN#ml^R4Z@*syEl;cbfc?YCM$I)$Rko`7Lr;U3XgrU(74H(FH#Y&C@6JT% zog0xEH`<a|PYRUj2T0bXZz!WmgBjdKo{v)Alm=J{P#2=+3gh+`E4OoPh`OklHpV>( z+Ch+vPrNldn~lw?ve((~TxQzxOV2uL;dBF7QYS_i?KW3Jq|;V0w=E*M|52p>iFtV= zv3|Hr?;-IWcU^kd$DFyWn#yXV+8;YxToh|R9^k{&K09k1+mn<@Fa(v=>q3-H--$c; z_}WEh+#df{=7Sib6H#37l?4H6YI9iXMuXQNd>Z?Y5-B~y&7&7Q^E~;6%b&nojLS?H zX<k$UQtD)#AL6mB+x9XeFMm8`CjAg5HzAF!ULA6yfzokhkBL`^(qqm4a@E0Un49@y z>Yn_?gkr1^u|Fo&{EkC$rcFDgqdEcj(Gy@$duYy}<|@Cmse_>Ja4vCMNg?Wa(1pgE zhSE~v0lIplv8AHeK8#~~bbWH$z2!DTPeoO1)r)Fz1(Yx@_)FXoo2TDFUyh$Z27_~g z#Q7||_R>$s=#3pO;7Oa^W(|T{70p8W2v;(yMKeFCTa>a;8C{gW!Eq8y{Y<*MI_T>U zYvngJj0WU=SqH&boqi@C&d6}ADMn(XWk1M#aRxr$KT>elq+#+{&O{VF%vA`F)RIfo zKA#jSni$O8dWxF;Bx>n4m1xucNd2C1Bh;_N#))OaX`ZZV7nj|u>&|}ej1CUVi{lOZ zj57`z#&Vnv_nKY&y^SF;*Powv+_~F^PIgZpdS{)T471HwWJKx@JjZv(owVwjmZ!R6 z3Z+sd;db+4rn?L*dejx)e`eg%-^g7Y<dp#V3<Jh}q}87(@mx~fIc1Ce$&MdzkXdQ_ z+&8jas4bU8KSem@`e(_{3LVA|5_Um}&9g5yXkJfTUIYT$#_|2@OTje<&%QBbmkqaD zy%}{AdV17*eNpnDPk;LDw*rRwYCDRQ>xH)%CAm-`-|O{0ns$?`cRb!`WDD3XS`J9v z?oWHw{nK$?>8&=!@^YhmNZ+`{Gu4r9x!w7)j9CUCne4T${n^Fy#`KhumZtJI&o9#x z&fWssTo*Ug4#rD7Jd~Wi=iy#YGNx0!d5%I{;9pBB5?n&N!%^CY8v0}Y`$S8w!xx3l zjmkI{?g!E6sRfH6;B1>5<k`^`*%O<~#xjxI_2?jgSC7;}QJmM)^H&I3o01FBf5h=J zTyFwIx8Va#UjMa`+BbR#0<p>C=#SkQHBDt#kLo;6*m8ejdArQ(S?VZYYto8LvpdO` zY3ft)4b-#JSTdR<z3M%5$<%}Blt$Pw1hidx$REb$2o9p}1L_bIz8+m#?<BawKaYV2 z(h<2l7>)m_T9Pw}mB}<)bPxMDaI$pA)$Gb_80j~TLJ(Yfz`l^uIAx;R2QH3S7$M^f zJ3GlgPdRpHA3Ix_JNb#E2kvFQ-!LoEo{Q*X{!-83<K>b3+ObJT#494p+yr+`wJpuv zdN`K6=3XrU@5JXrkLfp~4Wp4DhZo6xp?SB&$X<v4DUdcEPDiIrMy*-5_qR8BXNOw! z4{C%~A@dI0n+ApV2j0a3iQnBMtb84HnHA3xDmyRl_slx3=fn+f^>M%r(XQl>tGc3& zZ&Hy0yHYEYwGSJ$UL9YlDG~&$Naj{o4<DsqG*nsVAYPpQqZ#ftR2ia)_I0zBr3VB` zSbOvHH&<Ys1Et?Jt9sWygj{XY94VijCN(zA2SW6wS(@+J2>AD{ytKYhQ{1|khUZQZ zoHx8YLIzGSSV6?Tb8oU;(o5d<Nqg8^cj;9`Q|8B2Lv2qD*%=zY9<+JZ@Qt+X;(Bu$ zVmoq}w!J&{6wA<;RnNz`>Kil%LDLVmwWKdre%>XE<C5_6fDrQ3ob=0}Fd3CzU2qyJ z#l3e0esoxC%t&~Z?B_|`9!=81!+SC7w<7$9GvAs1FuHAj=ecpI1gFEyjLx!WZwIf$ zV`p=&KKAU>^zGyQOHbfT`!Vb~b*ygYL4KA`%E4eIKl17x0|M=^FXUUSFdx|nt>K8@ z+@@B%%EP@X9bd7GdsI^Zoo}kxb7{Nglt)IkDqkEveZ7!QMmuMj!|wcu!3LE!h*}mJ zChA!&W+92B)srQ1k}-b@y$o}<HXWYJZgP-G=h)FITTz*?dMVWF@QRf@w^g+gdcqBn zd=hDcH;l@SQRcyTKnNRlTO_E|-AxQKKZvidTY{$B@DV><R!2F7VGU^|gN3pwRcz&X zD0;z*lLwnp8iD&phQ+eQANQ}_Ozx-r&FwLNUh4gnz_L25@+pCJsf6O4X9;{IAbWM| zIL(XKKMcS{IO569A1K;5taXarI5A1nkoe&(#g0UJ-2PX4cQ{tX6U@e_92Ty7FA6Vz z>IkUT4&gf<k(zE^YZglA-D<(@dsY5L_KY#iL8F8V7hyCexmXMIG~p@PTzS-^R?6Bk z@O>*08H)ai2sP)gne3H9#7KroV>%(aa8!57!nU-)`E7ukrQfKPq{^NzK=rydPmr+4 zBy*yVhIUFcMzEy1-c`G4WFP5#PAbzG<&J}L9ZPj^KoMH(8wZ(5O=B+}KekkG@NH8L zT&0Ay*)OzLG6a68E9`|71SW9b0}h*jOAW)xUfDIXPPB|vEvdA!KWzuf@3Nb?d*W+r zsF?mii2ErOwF|u8-oAXy`oxoxtFds-SD{q@)0&EG*)0jjVVsyJZaSyyzJ8Je3j?HK z)l7D;r$<kT-1Xg*9{WkS2%t?qr+vWP_`WS=g;sYG4h4o_8=kHEL#{@ff!fJ*v&!yW zwu>~tl0$`pR(?So)T_!bUtDk_j2v~ev9h?YW#CnitR-&;zni&ze<h%tKuEI}Ke*`7 z(2**8u)*;I6HLpmmyI%pdtZpax8LfmMSO;`=c_5(w%vY)`|9zWYN7-+dhuL%6Lty? zr%K(~eEVWbp>m0}weA{g5{$Uo&DPiiQLHT~2|3g;hqTysk*N=5$f=d)GC7pCUa?J@ z&K7<580pdH@w@dm_dP!SBn%{dI&M#a-)NR_mpC2o_RBJ9y;w|d#xq2;qkGL8RG*a< zhu5y8plcsicqtbj+$3^k43@BF)Hwa6hokJhNBVhQviF#w)kh5un|Dq;UJcCYm+1{} z5n9x$i%eXY^EZ_u9vP{5YnQ<!u^{-!fsM5M5s2E{-KH{Lu=-7rih)5JV7NG=`_b(; zy?ogf`49-ab8D~HYAAC|#q6|^{+^wF1v7}(C1mf_rvdv789^hEs!uZgU^7~f6epNj zN0dG9YO{Z9&rE|F1JjXMYHC!%AXS<chDb-Q?X#f}8m$Up@Nv<wnvG<BO&D;#iV%KD zd#y$EA?Y&+RycF$la5AkdzTgLN!q)<;7iRe#P3#V3U}*l?AcnJilFfY#H+q(c@hVL z%S-4rfc(mw74aHJpxY&~e&qH&N63l6!Vj0304b|$kK%MRjV3$fgMY*EOoKkPPtm1< zx3t?)%OzRixW1PPVsrP7JKaO@Fe?DT{G?-v>}b@Y+2Y+|*y+$7$ZeYu>_^0C+f05$ zjC5}ra4mSo<z6+~N1bi={N8#qEf}%cYMdX^^_aQ{AYa^TvF<XX8b`|$#M~^3a^A4x zU-Em$yo`aK`Ue|!m66S$pzQDNMkMb|ayq<Eb`~CRJUSllv%CQ7wMJ|_Lm&OXOTOT4 zd3CZA98o`zGbgCvL|$lI*t4vP9W~YY7UM|b5~;X46RB9NwY9OGqI}*=VHNS7=()HW zC?c4v({4`|2l&RqiQ~BO(NJRD6B2KSDraXR%U#)EymH&n9xXmzRg&WfP%-ir-=yh? zvbI26!IeJ1>7qYU&^G|TC@T#42MdNmMSy}sl)rP2V?oJc)#1`<w4osXdm_BHvzcr6 zai8$W6i`Jh1|Hu3^%3>t@x8e1y2lVzsqNk|sN#10ioDi{Hy|j30iGzN@zO<OGV9$Y zp9<vtV#&+ieT^5K#Yx0|0%*X;3Lf5%?2SM90E{&7sVH^6bBqGW8WqBlsdws#`}M;2 z^4PsWto`bQVRO=u#3#$ZWx4P>X8uU-o~dS&n#JW%;bmW4;o$u2t^IKo<GxE{kI3GP zkp`XgkI=btxP1st{aZF2LmBpf2`>$`jkQo_G;u)N#>DUx5N#tiETmhYuY>Q)K5KvC z`}aP0>$cY2`zS}w)kB)fy$>BjlgOO@P$ti&NFwYG@@NU}Hat`qte*;)lwN)dmwd`e zN6pD70@bKs{03)x9$U2t+D-#on_VF1lieCY1ZHIfIw+qGStaweQT&v#tI^(<OyK_` zwv;)zLe@sDBSaPP-Me4b6Me8(X|m$KQ>k4^D9MqxcsNpHBPM^>$bE!mw75eMNV$09 zSC4Q}Mf<*hH&$K-zKSWUb=7mMf`>IOvJs%fi7nMcvk4{mdHN$?mibP^C4<BJjPFx; zK&>3HYs%ryAhf8{1C+F8f$C_tO1j8G#A>m=RBNaQ$0hc%==LBj?O+x}lM?^ot1{cj z<2&`&ywzYAK?Hgx41h5oF;Uz)7;-S@yOel+1l6PD&vV&coX{Du*xPz~OTqHlCk<Tp z7edzZO?YWMpYa&R=XyzMclkyD=NkIV5SHpS31UUN7J8DI^n$&@=RW&W=5J=D#VXZ6 z@nQ-fQtm{9cS+%-vBBux98KP{HEo#jDlu;HiwxT%)$^X`rku)pAo)%>P6(e|p}Sr- zS73}X`sx(peLS?JvR3+~gA(>CW|PO?Ky?a;VTM(0BiY-^!kAH_35k$n8R#o&YA?KN zl*a2-TY*Gn&t*KQ*K1EUK7c4<r$x7C6)l$A9eZ$iq8IL#$2r9*&+lzYVp=RmnR(<p z%51jpuWLdq&uhL65ATgJ2aqd2!S<aq;iesF83F8u(8FkIWpZ^Yzsg7ky&%X6$uJu+ zE#m9T`^qO*hU|qpX_#=@Oxgh8KFcaf+NOUnEH}dERgzYcb|3<z=Dcb{hk|x9p^5bd zP8fb?bqo9J$zbO07hC>-zq!;@_|_j-k5{xm=}H|7P188}0;FE0%12Ymt{iQ|`pS|o zMEd}ktRRx<2h7>hil}|?R&`AHji`%kg4cla=xpT^cs9qPHaTxIv`9<VKJmFx>y>Jy zxs1Tqxv5b5Wi@0}`PXPE&)eL}25@I*by!+#GXXV&GZ-23x^4hw&SQn%m19S2so4@V z-tNv;;cUHWF&xWj8?x%`M1?SWkGF7sc`GD>n^aVM!R-bdg3J#vDDNGn#ySH>Sv#1& zRW&`eA*p|WTIkj&+ziF_5zD`r#G76Knp=ILNnVJwUG6z4&gmY3l}OAIScogHBc7L+ zw%xXX&8c<-sXp5^mLY4iJ?cPrtHBc0YP?yNso=-~CgAwv3TAGnt~M#_oo~0_Fti9u zpEunhO~2oXB%Z8QT(+u#+oU4fttpK3{5arsijSvo*vdlyPNDRSODeC;Y(~nSla7;r z$sMSSC^x6&`i$hKBtr2kCXk8^+~phDnX85JUL_Ux(ByR*Rnk{lmg}{;U<{jLhHXRU z<KK)&?`dX9xkIKOhgi%9yiIkRR${lReHM9Oanx%$(z}L_Xw>SY21=6PW4<Wk<^Ry2 zsgKQEi~?WM(<s}I!3vV)I&mgb;Lxr>v~jJHFJLQqUN33qV8Ngg{Doc%L|e%x?|Rv# z5wowk*%;_$QRJl9dA+T;6;bj#D*E&OV@tc&tWHCCs2q5z9TO3s-j^^ve}uuSeg*5# z5iK2Lp(L_nv9%4E4|IAeAB(3Wt0XR~G9!j{L+{F^13-tx4p$O!z?tmA?3&)6w3hri zZtU^cAaEO?%vtnhr}HQUh)1H{y_xk8-SmTv5MzpX-COrMj7W>kME`T%%o~tS<4YYK z3T`f@o$Nj^Vk`X|(LyVrRZ^#&SqIBvuf1L`W?TM@L<_OqPpdMiHh2rNWb*J%Sei<m zRoy~i1Cq-a3($lU=(|&H><uhi@7?RCGrdMV)@GM}`cYblbFdc?I?PsXn>Vxhj0$vs zBvWZOv-?F&LPyyIpikpD<l|xju>i)3V*{gk(CpdXg26!l7hI6zQs||MP;e&;UdoKh z?mG)AL%nFP>m3sktHWqOaOaz?GsTvNg$dyewIE=Y7bS=Mq7GFaKfPwQC+?304cOCT z2UIT<?PujR2e6&`gQAj}!DPClCGAaAE}kt5%8`sv!kWS8Gaat{_d3-sJR_ccdL91h z$_11ln>sk1t^^<#N$U}rUUtlAdAvVZ{+?tyaf3Xg`N0b&jg(qU&STI;QI5x&SLw@B z@1>b&_`oQd>5$#E-^4vj$Z~q&ZiPVmJ6Vq$Dear(@Bo!#zfXM=3;qlU|L2d-G&f1? z;A5<ta1636i3(L#9sB8B`>KfhA%v5$3#w)~BLEt*sc?QFOa5YBGpWrJos*D}2qRN$ z25fcW(i99wS1YBd@CssqRiu@WGbjcxvAC0|-eeBD;G-foh4>1#q52DPEO6bC<RSP< zy$eF4oE%&-F!6&eHQPUQ*)&?Ux()731fQmuoX(?SWjc@YSE?grW}<bGKGO|Fx}uE% z>2n}QMf%eIel1eUJz($I4ce!9-NWl8)<&_SLCtt|IVeRtZ$zZe11lMo=|xfb>D)@y zh+gEb^~*R7+%e+F?NToOdly{%Vlg)TQpb?IKw6t4mU_`=DZUmn^1-yx9fSOw{*-CO z@1>KGsc?SXcX3|{rITBZXjg<sFexQ-&FdE})~%5@%naTmQxihFYHXiY?qt|wrPBKH za6W>fxQ(;&?DJFZam7Dr{pK~98E_ft)^v_T8N?g+Zt82$e5!LuPFk;fop1mMLovpp zdhAuEBFzFP8QRGSCeoQgijml+dPxA{2u-}2bVEIWTZYqCE_f)-v*f9DzP{YrF8han zkK-R$bGNa;bHoV^v)B*o;`t}xi?Xt8c@pL``zzQMZ-{E^bfsK-P%(JW8J&{)?P1uJ ztwC~JtQsi#r5-4n#s?s$QEJr4E!My_Y^AWV#xdkpoBFs*M`)a|sBC_op85=U=)NA# zjr4%jd<nfP>23WvI+Y&4oKB`JYUlHuVvED9@_d7AbZcOvv^<!f(XE@6ipWogFq5Wm zFJA@EL^{Bn)VS7EW9+bcUwc(I^gpunIX59n&(4SWjRmJt<*?QM{Dmp4KYi*hhC^&Z zQ1z5&C_VR(1=oiZAP%4IL+@YVNN&@VfL>B-l=9r~EJ}o=EXiI~puCU0K<c1`@sj~m zdgJKX-M~wnH@op4t|sa)R43gyhp%<&9d?K|f!3K}9Qk6Oqge<ogKt04DvoIzY^!RD z|BK2Ou$o}=Z(Ov`jOYXN=dl=5zkaM^mJFbXcHv*I&e81>8v)hB?$WwdsFxar-v!q! zHTXzXTZC$+dKHeS&8@E+hn<H-!;TS2eV_Z=G1MMxzEz5zqpVaW-S+QJt&)=<qZ+hn zA1BWky%pOyb9n|s7-ieA|8|pi>vlcC)A2#7TxkO#6qmp?Icm1-jnu23^3n7^zj)T% zm3+lfj>ZrFxU0e;EBwL$oGl0El(Fki&TAJI5f9Xm<%W7M?`u>F5^N=E9ELD&?=lNH zl37NrSuB~I9zA`cq&FM7n$%2I{BD@Fy*{BGWhzog<#(Tha5jQvEQE1__u|Mc5Z#Mf z>Ay;IFE$SJS(0?#NSEAndpn~+&@*BUDWE!&NLt-@fI=?6)YS?1s^W5(Njod@Kdqz; z^~j?VwrhW}HJuI#FlW0GSjG$&smtB9h_KxJ#BUS1{kit5wl%k<_YnHZ@hsaSLH#^w z=w56ir>V#=QZjfy+l$z8zztTq*Px@fIOsz>aJx@Ue$n@9Tolramj|X4!|nEt43=It zh;CLpj10g-warXW-qXtVl`0t(=}X<cBgwLafmZt`b^40#yBt?4ZNg2QHl~N56K<G7 zJ|cwJ;3Eq$1cRv(k-yepkMnGOHrnJ_Qj>20)U-{8Qs8Nt(pu7L`_0<O0)JS~730oL zC->&A+)hrp>+K2avKCuV(T;jsNw+p!R*%QGSLP_A9T9@FkAQ4WG7D1HiEv86%X>~9 z##w1l9qz>B`@B{-xH5bg#8Wxlli1xv>S2==uaZDKT(<7)P=5k_8)26YbJ6kv*uCZY zyHNd$)P>(_ipMZI-E5yH)HNDd!lcwj;#E;`{v-;68N+stfq4KmG8#wp1&`jBRCN}l zm)*OB2fdp*`Ra08JICUm10rHPkSn{Yxfbo_z4#gZu?ku+2%@e*;~0K_j%vV7@Gf|2 zM=bBq71wMW^)Zy|Zd1}ld(oM+**3KA#Zu$@ruYbY_?0a3O4lNJZ>7;R;<76JY?TM8 zIz)4y68Qr^M0%_-L2js~)L*HslZC;>0xbgbUEMk*t5@KB$)q_KpfY7q^9Qku^c=<t zan}-4ki3>oIwK37XpgAbr%yMzKy=OUc&iztn;kAQ)jPx*dk+%^5I5tnN~qfY8R1Ej zp)fS9%Ek))W4$;nXhKFmKi5p<R)fUiaYRI4>iw~Y%B|spYx5cE;I9@%f_*O<1^fIj z?{VnC$T-XA=QmFj_`N0c{6o>l-Onx$vSq`cK+;rtDkT(wD)q)lP>K5XHonGS*!lc< zrw*-hOve-SYJczIIg;lIDc1Wd!}Fr#kV>|#SobE!_zn{A3kxJ-Km(A=;xn&Yvs)CA z7&o)^<AJ7OgY%k(&$ji)7Y>K9#xUc(Or0K4986Rs<Omgl*-H;r1u^tN*K&4|26$`@ z@VPTxO@$`4`hy>M2^4f?Dk{Cm7#7sWo=MCob>o9#RiS;0(NQL?9#W4-Blna&YLpB< zM9TM+2UBj48#|kJ%8#_V6=Q)fTznwU{;V+m+Yei&n-sw+#xgxV<l&@hMjpQtA@^#C z1-8V<CbOO%5o2RMAR@<9;Hy6Zq)~%y?$h6`;A<i^gQB(yht;^V_sp`PaI0R7EuO;H z%=r}<Y3u~~#v$~J+Q(+W9{zskpGG|=SGZS+D*|le<<Du>N^LvR@j6}P9AW<BNk)Cv zW2uwTQ~)IPG@Jsr`CDLkaOH^I)=N9V>%Cpb%Vug-#&Lb2UDW$zYj2VcZ%o{fa)Q}3 zQqv&=jz1b_0Rp4M;K^CJ&ZgTHxzI-~QbVeBSt0!U(akTdO<(eLov&ldPrV8D!2i(a zc19AHi)|-6W}&^hcT!uvAO^#B6xsPSWvjeV23H|4De_RS-Ql%pb^KoPdMMLUhB-AS z6&4-nc)jUaHxkLudWnD58+jzFJKt<GGvcR%1=8l2f<grZC90Y9!VE~?GUA9}7dq5} zB(pe)Wl%p`JaL6wGxllMW*2)ptb9K#uNmgvg}EO}SW79@BIH}Opa7)#`g|aW1a(xn z&;0er`zMj&&mI-(FS*8%<@*&xa22?2PJC?zkstg3x#utB=F!HOD>zD}gRCSTggB-T zEVa@Wpi4&SNM_t(%xNF`zPGku^!UIqHkIr-Vcn3ceV%LN&s;NbN$c+~<_#+0cfJR* zbTmkpWvxJ_T?w}W??YEyhf4mcY>E!Xp=T<-e9;MJ7^j9{-<%~S@c<P|26gnQ(1tx$ zvLw;>VZ;b;p6F%L>ttN$(@#4b$m)zHr!Koo%)(x<Haz{etLx8!ew!OQsrgxa#&kBw zO@XI5gH8Npq?fo-Bf(99&-bun0=V`g<vMQ!h<}IpD)F`z99&qodn;^`@&|Sp%Rp!D zjH0%4JUaQ&>M7J|HnObAXZ|xmzF?Hgi+tONbXVJux{NOs<+*ux8b_5zeHhNZgJ~xs zKEP0K*@{qvDGGTu6ZlKMB{VQ5m!<RB#4}3RhYCSVo%r2I73fBBVtL7$d<&Qj=B`9s zQPzP2P~LYWhn`AdfnT+i&1V>!PM7V-I^Zhr_Bn7g`Bw3P;l?LE28q`NpaeI@>Y6Z! z@s=`(m1SU@V4`!)bf9;n3;8^G=)n^s9JrtA@wFjk45j5RHkp8YCNBgi;dVrIK}&T6 zb#KKDMoGw0(Lv^NOlXuQ^gZOtu~|xNL-cvoC2{zfbg0%)jHHmh3kvrO)qS?(^$0;~ ziFp)ARzWX8@!8EfRJi{Q*k#7B;6=+J&&e*n8nLS)vM_hIzT!NV^c<v8=X(b+zsi)n zu|&fMF4E{6DAfqzZfhpkw;7u1I8r>P#hp>B&3@`gxKUWTBkCsUO7|r7sP7GoRFPN( zcNbe3la`<LK*ZAGtK+QCnzz#jSPPUzyDPhm_TGs8lyHQLb|Jv?YB-9L_kf*xVzOwk zviVCObqWxm6L)jH1zcJd^KgLSGBM|?7!L=ReF4-se9*7%^V!PD^$<!Yb!6%FaP)A% z588|;b4(cmQ`g&b=*CkvX6g5lqqA2|qr_X<Z+g<_!$ll7`(-^MdU_pV=VpnWH2AZ) z;e&GetTU@A&z&}JiiuZN6*R>z7&Z%DC;Qg#x;sYxAB%o=c?7<C?eHv-#UscZ=eiSB zp{)E?d+gy#4eNFF%+(kr?~n8u{-X=;7+3GOBiWu~OktO1%y}`%Od@>F&X?15g_D_8 z_CfB;s`2-~DklHu4bq<jpXER4c9FP~P&$Jw1}bFxvnSnf5zdp1rh|vFFaMyLIXYM6 zoafg&jI-{mJfexTDwCu>y();W99?aIin_j>FJvOoN<LCUM(0nLhNmUf%GYYASUCyR z_3_qg2uV@lpX<E6wn#<lx??n6i&gHEJwT~tMh_i{xUVV&3x8}Q0gEN@!Bz+Z1Ql8O z4Ed}iHd*7s@D1Pkt4ukthf9!I+Vx3cSo;ICSV%(mo?x2#QV<vE)sk-ZA@8NOoHk|3 zbh`qi9-)3Pg9R+(07qh>cIaDTwLXoqJI|QL^~F=DkYCSY*P`WC_5fBRL{v_;n^erf z_nsG#^h?4L-wN2dXK6)MmaOl7|M3t^nyzj$n<Uzk`EcIS#p=|GIsLI97H)_dEV;EO zsr_91!z0!C5b))wgeu+m+(^~~=5R;Ibn<DXd7i&2VaCF!{J>Qr=v!eZ^G{L!p-Vwp zL>M}CE3u;FpqC1<_Kv$?0BY5RzaGr^WFbrj-A!Xo;$^M6_0x9SDB$A)$}mL7^wZj? z+D?~;pUSkcMe99@%z~5GCeMul(6xAPz_>$_h51!3QW(9T#9nK~r&qXe$5Z4t;Qpcd zNjDT`mo#a`fWJB-Lv^@!RWKpH=BLuJc&>72*p~B}C)!=peBv6K?rv{TcUOj^8TNfI zo52LOE6%QbSpzybxl)0rMx79xPHi8rog(`zw#!8Q<5n~mmtdBdV-63ESJg5D%gYFl z7UudLmHOT^JaIYAEWvfDR6A-u#Ili<=h>pIj5dGP3gs!YdY!ych2mEG&F;OJT|<d( zO5rO&rJ5d?n-xUW8w5Z-?kjrwohU71)uz1~yS`@Dt$xS7=Du)5p3oU}T%4?opKWun z&whHvevMG=Me|!Pn_bJ+)Thz4LfkuZ#jyGB)-oP1f@G=;2#;9-p3b3dG#;R?={4@z z7k4X|5r&upgcZE^(z{Xx?)C1lcR!+dwpb<!{k9rcruL?~GID-sOO9czjOQmQ1h`!6 zzZzFOEGC5*>I8tl7#I;R+-I=j&rM5_djUEOVkM&z5(VK$sLo<>`w>th=_u~O_u7_9 z_dX<7$3)bU011^2>P9e7FEC)rz90HHmqLq!4@}}<qhfi`ADhi}mC!h}CTJDBBj@@3 z7D$!~etH~W6?1V(1~QSweaq`_FsNQb0+!r<l6yJ^$yys@b*#3wTzCuu+K1B5B-W^; zTpT=rLyFZKg=Q!k`$B9WGK)$jp(Qnw;YaLC2YT)dFlLa)wG4B5s&#SblH>POR%i7R z)xvg*b<XRii`N%K#or!8#bUf-RN?{vaZ`7l`P;VaCTle=k1`N_h58kJ8WQ25<q|5h zt3Uf93I?I;j&57tPMKxNyd%}tm1FCzHT+=Yel@<b#|1m5sD<RdY;ENauHS6=?ql6> zw5#VBKe@?adlYC{13W_03)B})-}|u0v<}5+mWo&{YmC^9yf*SW3yu|hKXEi~XCp-I zyork3d}1LpkDU2Y!zVRy)E9Sx@S4)Mpwt7nYa9j#FtIUQvFyerUUl{k=ml6|_~46y zJ*h@sN$y7D19=Y1LJH^0P4)p=lOE?7jId&9u5+YuWaaXHHT>8Byq(Y01@h&jV`v|p znxr`YR@EC?W80~DJ!KY3{k7>R`--!rQIvapBJ*fJW2ITlZ09L>?rRfD$fNPzf#GD~ z(dd57j@`J5N&n-;2wB?URkJ+l_Gw)yyQZ5$`*&PK^%$od?2&^E+cj;}DqlU?MwU#7 zujD8c<ACTxw!~Uk)w*A~t_#AB{%GN-nod1b?W}L$UOp7qUktaUw#v(N2I_=3X<@YN zerMh5B&_?W3lsO`DXEOdA0MGM%5}REX761Iy&GdAOA;C%WMir_``b+LYZDfD1JT*6 z$a4I3`7f}_ue>(bZoWYi8Pxx-<ZAo!7eA7aS$hAK>~{DhnVGhXFVJ2OKmvAuH(C;i zXgqG%<4!xqBZLQ?aX#RV{M{?4%a1ozexUpK)LMeb*G0HfO^JD6V`BNTi&<|Eg6_;- zAc<|2IT<K#cSzx;P%yqw22FvqBsgZi!u|V%cQabGcQd)-Iwp3y{%m1!a0;KL^61D! zXAQJ{_TkF*?V|?7^~7Urypf+9e_U$$o{Rq`%6|5KAzYeED`;s=^4mxM^#Vicmzf8L z^x?lV>R*&p7)W?iEs3Pzstoy^)&BaygO`8!0K8Vs%2a-b_+QN6EA4~FmaF3UDPXbR z%=JGecou!LTW>f(sImOc>HlKY{gF4T^B_C02Tu3*Ec<_sdP&@%uj8&!^iNGH{>!8T zElVl{e?xZu7d)REeqqKY2pIjRCVhTm(#sV+2iQNvOy?J73F)L3|J0;WHzxHyD6Izl zL(JHIVJ0OPiu{Kr{ZEHt{)d<){K70Zzg6QOn)JWj;CD;o{|7hte2xF2%s*LQ(3SAk P&7XvrtZ4CjU7!B}WTjCQ diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 44292058d..6bc213d30 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -16,8 +16,8 @@ instances. This is also true for the [VMWare](/docs/builders/vmware.html) and the [QEMU](/docs/builders/qemu.html) Packer builders. We will use Chef's [Bento boxes](https://github.com/chef/bento) to provision an -Ubuntu image on VirtualBox. We will use a fork of this repository as the -project we will build. +Ubuntu image on VirtualBox. For this example, we will use the repository +directly, but you may also fork it for the same results. ## 1. Provision a Bare-metal Machine @@ -103,19 +103,24 @@ assign the new Agent to it. ## 5. Create a New Build in TeamCity -In TeamCity Server, create a new build, and configure the Version Control -Settings to download the Packer build configuration from the VCS repository. +In TeamCity Server, create a new build. To use the upstream Bento repository, +we'll choose *From a repository URL*, and enter +`https://github.com/chef/bento.git` as the **Repository URL**. -Add one **Build Step: Command Line** to the build. +![TeamCity screenshot: New Build](/assets/images/guides/teamcity_create_project_from_url-1.png) -![TeamCity screenshot: New Build](/assets/images/guides/teamcity_new_build.png) +Click **Proceed**. -In the **Script content** field add the following: +![TeamCity screenshot: New Build](/assets/images/guides/teamcity_create_project_from_url-2.png) + +And **Proceed** again. + +We won't use the *Auto-detected Build Steps*. Instead, click *configure build +steps manually*. For the *runner type*, pick **Command Line**, and enter the +following values. + +![TeamCity screenshot: New Build](/assets/images/guides/teamcity_build_configuration.png) -```shell -#!/usr/bin/env bash -/root/packer build -only=virtualbox-iso -var "headless=true" ubuntu/ubuntu-16.04-amd64.json -``` This will use the `build` command in Packer to build the image defined in `ubuntu/ubuntu-16.04-amd64.json`. It assumes that the VCS repository you're From 1a18957eeccb8b9e0b55e2a43214f8cf428deee6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 16:06:58 -0800 Subject: [PATCH 0295/1007] call out advanced options --- .../guides/packer-on-cicd/build-virtualbox-image.html.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 6bc213d30..1d6fc5bb6 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -117,9 +117,10 @@ And **Proceed** again. We won't use the *Auto-detected Build Steps*. Instead, click *configure build steps manually*. For the *runner type*, pick **Command Line**, and enter the -following values. +following values. Make sure to click *Show advanced options*, as we need to set +the working directory. -![TeamCity screenshot: New Build](/assets/images/guides/teamcity_build_configuration.png) +![TeamCity screenshot: Build Step](/assets/images/guides/teamcity_build_configuration.png) This will use the `build` command in Packer to build the image defined in From 383228fded1354d752bed6b7f535d2d9b7f104e3 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 11 Dec 2017 22:04:54 -0800 Subject: [PATCH 0296/1007] Add link to Cirlce CI article --- .../source/guides/packer-on-cicd/build-image-in-cicd.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md index 1604d91df..0b8b48c84 100644 --- a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md @@ -9,7 +9,7 @@ page_title: Build Images in CI/CD The following guides from our partners show how to use their services to build images with Packer. -- How to Build Immutable Infrastructure with Packer and CircleCI Workflows (coming soon) +- [How to Build Immutable Infrastructure with Packer and CircleCI Workflows](https://circleci.com/blog/how-to-build-immutable-infrastructure-with-packer-and-circleci-workflows/) - [Using Packer and Ansible to Build Immutable Infrastructure in CodeShip](https://blog.codeship.com/packer-ansible/) The majority of the [Packer Builders](/docs/builders/index.html) can run in From 6a91e5273f092e5b6aabb565bf86149c3868bfdd Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 11 Dec 2017 22:05:50 -0800 Subject: [PATCH 0297/1007] Update terraform links to new paths --- website/source/guides/packer-on-cicd/trigger-tfe.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/guides/packer-on-cicd/trigger-tfe.html.md b/website/source/guides/packer-on-cicd/trigger-tfe.html.md index 55d40c65b..48733038c 100644 --- a/website/source/guides/packer-on-cicd/trigger-tfe.html.md +++ b/website/source/guides/packer-on-cicd/trigger-tfe.html.md @@ -48,12 +48,12 @@ complete and uploaded. 1. Add a new step to the CI/CD pipeline. 2. In the new step add a `curl` call to update the variables in the workspace using the [update variables - API](https://www.terraform.io/docs/enterprise-beta/api/variables.html#update-variables), + API](https://www.terraform.io/docs/enterprise/api/variables.html#update-variables), so that Terraform has a reference to the latest image. For the sample configuration above, the `aws_ami_id` variable should be updated to the AMI ID of the latest image. 3. In that same step, add another `curl` call to [create a new run via the - API](https://www.terraform.io/docs/enterprise-beta/api/run.html#create-a-run). + API](https://www.terraform.io/docs/enterprise/api/run.html#create-a-run). A run performs a plan and apply on the last configuration version created, using the variables set in the workspace. In the previous step we update the variables, so the new run can be created using the previous configuration From c2ecdd98c6a5987e7af27acd1064e12cbee48a27 Mon Sep 17 00:00:00 2001 From: Arjen Schwarz <arjen.schwarz@bulletproof.net> Date: Tue, 12 Dec 2017 20:12:53 +1100 Subject: [PATCH 0298/1007] 5691: Invalid image URLs make Azure builder crash --- builder/azure/arm/step_delete_os_disk.go | 12 ++++-- builder/azure/arm/step_delete_os_disk_test.go | 40 +++++++++++++++++++ builder/azure/arm/step_deploy_template.go | 4 ++ .../azure/arm/step_deploy_template_test.go | 25 ++++++++++++ 4 files changed, 77 insertions(+), 4 deletions(-) diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index af5e2fa9b..878c45cc6 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -1,6 +1,7 @@ package arm import ( + "errors" "fmt" "net/url" "strings" @@ -80,11 +81,14 @@ func (s *StepDeleteOSDisk) Run(state multistep.StateBag) multistep.StepAction { } xs := strings.Split(u.Path, "/") + if len(xs) < 3 { + err = errors.New("Failed to parse OS Disk's VHD URI!") + } else { + var storageAccountName = xs[1] + var blobName = strings.Join(xs[2:], "/") - var storageAccountName = xs[1] - var blobName = strings.Join(xs[2:], "/") - - err = s.delete(storageAccountName, blobName) + err = s.delete(storageAccountName, blobName) + } return processStepResult(err, s.error, state) } diff --git a/builder/azure/arm/step_delete_os_disk_test.go b/builder/azure/arm/step_delete_os_disk_test.go index 7fdd7468e..5a962dd8a 100644 --- a/builder/azure/arm/step_delete_os_disk_test.go +++ b/builder/azure/arm/step_delete_os_disk_test.go @@ -104,6 +104,46 @@ func TestStepDeleteOSDiskShouldHandleComplexStorageContainerNames(t *testing.T) } } +func TestStepDeleteOSDiskShouldFailIfVHDNameCannotBeURLParsed(t *testing.T) { + var testSubject = &StepDeleteOSDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return nil }, + } + + // Invalid URL per https://golang.org/src/net/url/url_test.go + stateBag := DeleteTestStateBagStepDeleteOSDisk("http://[fe80::1%en0]/") + + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%v'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to not stateBag['%s'], but it was.", constants.Error) + } +} +func TestStepDeleteOSDiskShouldFailIfVHDNameIsTooShort(t *testing.T) { + var testSubject = &StepDeleteOSDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return nil }, + } + + stateBag := DeleteTestStateBagStepDeleteOSDisk("storage.blob.core.windows.net/abc") + + var result = testSubject.Run(stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to not stateBag['%s'], but it was.", constants.Error) + } +} + func TestStepDeleteOSDiskShouldPassIfManagedDiskInTempResourceGroup(t *testing.T) { var testSubject = &StepDeleteOSDisk{ delete: func(string, string) error { return nil }, diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index b67dd5c1d..5978a8811 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -1,6 +1,7 @@ package arm import ( + "errors" "fmt" "net/url" "strings" @@ -140,6 +141,9 @@ func (s *StepDeployTemplate) deleteImage(imageType string, imageName string, res return err } xs := strings.Split(u.Path, "/") + if len(xs) < 3 { + return errors.New("Unable to parse path of image " + imageName) + } var storageAccountName = xs[1] var blobName = strings.Join(xs[2:], "/") diff --git a/builder/azure/arm/step_deploy_template_test.go b/builder/azure/arm/step_deploy_template_test.go index d812e0ffa..4250e9e0b 100644 --- a/builder/azure/arm/step_deploy_template_test.go +++ b/builder/azure/arm/step_deploy_template_test.go @@ -82,6 +82,31 @@ func TestStepDeployTemplateShouldTakeStepArgumentsFromStateBag(t *testing.T) { } } +func TestStepDeployTemplateDeleteImageShouldFailWhenImageUrlCannotBeParsed(t *testing.T) { + var testSubject = &StepDeployTemplate{ + say: func(message string) {}, + error: func(e error) {}, + name: "--deployment-name--", + } + // Invalid URL per https://golang.org/src/net/url/url_test.go + err := testSubject.deleteImage("image", "http://[fe80::1%en0]/", "Unit Test: ResourceGroupName") + if err == nil { + t.Fatal("Expected a failure because of the failed image name") + } +} + +func TestStepDeployTemplateDeleteImageShouldFailWithInvalidImage(t *testing.T) { + var testSubject = &StepDeployTemplate{ + say: func(message string) {}, + error: func(e error) {}, + name: "--deployment-name--", + } + err := testSubject.deleteImage("image", "storage.blob.core.windows.net/abc", "Unit Test: ResourceGroupName") + if err == nil { + t.Fatal("Expected a failure because of the failed image name") + } +} + func createTestStateBagStepDeployTemplate() multistep.StateBag { stateBag := new(multistep.BasicStateBag) From cd2a0fe8737e76350b465416962cd07a10cb03f4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 17:12:57 -0800 Subject: [PATCH 0299/1007] add deprecation warnings to docs --- website/source/docs/commands/push.html.md | 7 ++++++- website/source/docs/post-processors/atlas.html.md | 5 +++++ website/source/docs/templates/push.html.md | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/website/source/docs/commands/push.html.md b/website/source/docs/commands/push.html.md index c30eb1587..551aa9bf7 100644 --- a/website/source/docs/commands/push.html.md +++ b/website/source/docs/commands/push.html.md @@ -9,6 +9,11 @@ sidebar_current: 'docs-commands-push' # `push` Command +!&gt; The Packer and Artifact Registry features of Atlas will no longer be +actively developed or maintained and will be fully decommissioned on Friday, +March 30, 2018. Please see our [guide on building immutable infrastructure with +Packer on CI/CD](/guides/packer-on-cicd/). + The `packer push` command uploads a template and other required files to the Atlas service, which will run your packer build for you. [Learn more about Packer in Atlas.](https://atlas.hashicorp.com/help/packer/features) @@ -23,7 +28,7 @@ artifacts in Atlas. In order to do that you will also need to configure the [Atlas post-processor](/docs/post-processors/atlas.html). This is optional, and both the post-processor and push commands can be used independently. -!&gt; The push command uploads your template and other files, like provisioning +~&gt; The push command uploads your template and other files, like provisioning scripts, to Atlas. Take care not to upload files that you don't intend to, like secrets or large binaries. **If you have secrets in your Packer template, you should [move them into environment diff --git a/website/source/docs/post-processors/atlas.html.md b/website/source/docs/post-processors/atlas.html.md index b54f1e45a..c4355ef37 100644 --- a/website/source/docs/post-processors/atlas.html.md +++ b/website/source/docs/post-processors/atlas.html.md @@ -10,6 +10,11 @@ sidebar_current: 'docs-post-processors-atlas' # Atlas Post-Processor +!&gt; The Packer and Artifact Registry features of Atlas will no longer be +actively developed or maintained and will be fully decommissioned on Friday, +March 30, 2018. Please see our [guide on building immutable infrastructure with +Packer on CI/CD](/guides/packer-on-cicd/). + Type: `atlas` The Atlas post-processor uploads artifacts from your packer builds to Atlas for diff --git a/website/source/docs/templates/push.html.md b/website/source/docs/templates/push.html.md index 255f3d842..ef86d2e11 100644 --- a/website/source/docs/templates/push.html.md +++ b/website/source/docs/templates/push.html.md @@ -9,6 +9,11 @@ sidebar_current: 'docs-templates-push' # Template Push +!&gt; The Packer and Artifact Registry features of Atlas will no longer be +actively developed or maintained and will be fully decommissioned on Friday, +March 30, 2018. Please see our [guide on building immutable infrastructure with +Packer on CI/CD](/guides/packer-on-cicd/). + Within the template, the push section configures how a template can be [pushed](/docs/commands/push.html) to a remote build service. From 738e378e91ceff3e95e663302d9ed1b03cd7ffcb Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 11 Dec 2017 19:21:47 -0800 Subject: [PATCH 0300/1007] complete the thought --- website/source/docs/commands/push.html.md | 3 ++- website/source/docs/post-processors/atlas.html.md | 3 ++- website/source/docs/templates/push.html.md | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/website/source/docs/commands/push.html.md b/website/source/docs/commands/push.html.md index 551aa9bf7..c2cd190e5 100644 --- a/website/source/docs/commands/push.html.md +++ b/website/source/docs/commands/push.html.md @@ -12,7 +12,8 @@ sidebar_current: 'docs-commands-push' !&gt; The Packer and Artifact Registry features of Atlas will no longer be actively developed or maintained and will be fully decommissioned on Friday, March 30, 2018. Please see our [guide on building immutable infrastructure with -Packer on CI/CD](/guides/packer-on-cicd/). +Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these +features yourself. The `packer push` command uploads a template and other required files to the Atlas service, which will run your packer build for you. [Learn more about diff --git a/website/source/docs/post-processors/atlas.html.md b/website/source/docs/post-processors/atlas.html.md index c4355ef37..e53bae48d 100644 --- a/website/source/docs/post-processors/atlas.html.md +++ b/website/source/docs/post-processors/atlas.html.md @@ -13,7 +13,8 @@ sidebar_current: 'docs-post-processors-atlas' !&gt; The Packer and Artifact Registry features of Atlas will no longer be actively developed or maintained and will be fully decommissioned on Friday, March 30, 2018. Please see our [guide on building immutable infrastructure with -Packer on CI/CD](/guides/packer-on-cicd/). +Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these +features yourself. Type: `atlas` diff --git a/website/source/docs/templates/push.html.md b/website/source/docs/templates/push.html.md index ef86d2e11..4934ae16d 100644 --- a/website/source/docs/templates/push.html.md +++ b/website/source/docs/templates/push.html.md @@ -12,7 +12,8 @@ sidebar_current: 'docs-templates-push' !&gt; The Packer and Artifact Registry features of Atlas will no longer be actively developed or maintained and will be fully decommissioned on Friday, March 30, 2018. Please see our [guide on building immutable infrastructure with -Packer on CI/CD](/guides/packer-on-cicd/). +Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these +features yourself. Within the template, the push section configures how a template can be [pushed](/docs/commands/push.html) to a remote build service. From c62f00f47a2d597cccde308a8f1b78fb344ec7b8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 12 Dec 2017 09:10:38 -0800 Subject: [PATCH 0301/1007] fix link --- .../source/guides/packer-on-cicd/build-image-in-cicd.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md index 1604d91df..ecaaa6668 100644 --- a/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md +++ b/website/source/guides/packer-on-cicd/build-image-in-cicd.html.md @@ -22,6 +22,6 @@ builder](/docs/builders/virtualbox.html) for OVA or OVF virtual machines and require running on a bare-metal machine. The [Building a VirtualBox Image with Packer in -TeamCity](/guides/packer-on-cicd/building-virtualbox-image.html) guide shows +TeamCity](/guides/packer-on-cicd/build-virtualbox-image.html) guide shows how to create a VirtualBox image using TeamCity's support for running scripts on bare-metal machines. From 0efda5035439257deafb3408e817850ba204667c Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 11:36:38 -0700 Subject: [PATCH 0302/1007] Initial Windows support --- provisioner/salt-masterless/provisioner.go | 90 +++++++++++++++++----- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index dad5f7109..ebdc5eeb9 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -8,10 +8,12 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/provisioner" "github.com/hashicorp/packer/template/interpolate" ) @@ -67,11 +69,44 @@ type Config struct { // Command line args passed onto salt-call CmdArgs string "" + // The Guest OS Type (unix or windows) + GuestOSType string `mapstructure:"guest_os_type"` + ctx interpolate.Context } type Provisioner struct { - config Config + config Config + guestOSTypeConfig guestOSTypeConfig + guestCommands *provisioner.GuestCommands +} + +type guestOSTypeConfig struct { + tempDir string + stateRoot string + pillarRoot string + configDir string + bootstrapFetchCmd string + bootstrapRunCmd string +} + +var guestOSTypeConfigs = map[string]guestOSTypeConfig{ + provisioner.UnixOSType: { + configDir: "/etc/salt", + tempDir: "/tmp/salt/", + stateRoot: "/srv/salt/", + pillarRoot: "/srv/pillar/", + bootstrapFetchCmd: "curl -L https://bootstrap.saltstack.com -o /tmp/install_salt.sh || wget -O /tmp/install_salt.sh https://bootstrap.saltstack.com", + bootstrapRunCmd: "sh /tmp/install_salt.sh", + }, + provisioner.WindowsOSType: { + configDir: "C:/salt/conf", + tempDir: "C:/Windows/Temp/salt/", + stateRoot: "C:/srv/salt/", + pillarRoot: "C:/srv/pillar/", + bootstrapFetchCmd: "Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.ps1' -OutFile 'C:/Windows/Temp/bootstrap-salt.ps1'", + bootstrapRunCmd: "Powershell C:/Windows/Temp/bootstrap-salt.ps1", + }, } func (p *Provisioner) Prepare(raws ...interface{}) error { @@ -86,8 +121,25 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { return err } + if p.config.GuestOSType == "" { + p.config.GuestOSType = provisioner.DefaultOSType + } else { + p.config.GuestOSType = strings.ToLower(p.config.GuestOSType) + } + + var ok bool + p.guestOSTypeConfig, ok = guestOSTypeConfigs[p.config.GuestOSType] + if !ok { + return fmt.Errorf("Invalid guest_os_type: \"$\"", p.config.GuestOSType) + } + + p.guestCommands, err = provisioner.NewGuestCommands(p.config.GuestOSType, !p.config.DisableSudo) + if err != nil { + return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType) + } + if p.config.TempConfigDir == "" { - p.config.TempConfigDir = DefaultTempConfigDir + p.config.TempConfigDir = p.guestOSTypeConfig.tempDir } var errs *packer.MultiError @@ -135,14 +187,14 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { cmd_args.WriteString(p.config.RemoteStateTree) } else { cmd_args.WriteString(" --file-root=") - cmd_args.WriteString(DefaultStateTreeDir) + cmd_args.WriteString(p.guestOSTypeConfig.stateRoot) } if p.config.RemotePillarRoots != "" { cmd_args.WriteString(" --pillar-root=") cmd_args.WriteString(p.config.RemotePillarRoots) } else { cmd_args.WriteString(" --pillar-root=") - cmd_args.WriteString(DefaultPillarRootDir) + cmd_args.WriteString(p.guestOSTypeConfig.pillarRoot) } } @@ -179,14 +231,14 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { if !p.config.SkipBootstrap { cmd := &packer.RemoteCmd{ // Fallback on wget if curl failed for any reason (such as not being installed) - Command: fmt.Sprintf("curl -L https://bootstrap.saltstack.com -o /tmp/install_salt.sh || wget -O /tmp/install_salt.sh https://bootstrap.saltstack.com"), + Command: fmt.Sprintf(p.guestOSTypeConfig.bootstrapFetchCmd), } ui.Message(fmt.Sprintf("Downloading saltstack bootstrap to /tmp/install_salt.sh")) if err = cmd.StartWithUi(comm, ui); err != nil { return fmt.Errorf("Unable to download Salt: %s", err) } cmd = &packer.RemoteCmd{ - Command: fmt.Sprintf("%s /tmp/install_salt.sh %s", p.sudo("sh"), p.config.BootstrapArgs), + Command: fmt.Sprintf(p.sudo(p.guestOSTypeConfig.bootstrapRunCmd), p.config.BootstrapArgs), } ui.Message(fmt.Sprintf("Installing Salt with command %s", cmd.Command)) if err = cmd.StartWithUi(comm, ui); err != nil { @@ -208,14 +260,14 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } // move minion config into /etc/salt - ui.Message(fmt.Sprintf("Make sure directory %s exists", "/etc/salt")) - if err := p.createDir(ui, comm, "/etc/salt"); err != nil { + ui.Message(fmt.Sprintf("Make sure directory %s exists", p.guestOSTypeConfig.configDir)) + if err := p.createDir(ui, comm, p.guestOSTypeConfig.configDir); err != nil { return fmt.Errorf("Error creating remote salt configuration directory: %s", err) } src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "minion")) - dst = "/etc/salt/minion" + dst = filepath.ToSlash(filepath.Join(p.guestOSTypeConfig.configDir, "minion")) if err = p.moveFile(ui, comm, dst, src); err != nil { - return fmt.Errorf("Unable to move %s/minion to /etc/salt/minion: %s", p.config.TempConfigDir, err) + return fmt.Errorf("Unable to move %s/minion to %s/minion: %s", p.config.TempConfigDir, p.guestOSTypeConfig.configDir, err) } } @@ -228,14 +280,14 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } // move grains file into /etc/salt - ui.Message(fmt.Sprintf("Make sure directory %s exists", "/etc/salt")) - if err := p.createDir(ui, comm, "/etc/salt"); err != nil { + ui.Message(fmt.Sprintf("Make sure directory %s exists", p.guestOSTypeConfig.configDir)) + if err := p.createDir(ui, comm, p.guestOSTypeConfig.configDir); err != nil { return fmt.Errorf("Error creating remote salt configuration directory: %s", err) } src = filepath.ToSlash(filepath.Join(p.config.TempConfigDir, "grains")) - dst = "/etc/salt/grains" + dst = filepath.ToSlash(filepath.Join(p.guestOSTypeConfig.configDir, "grains")) if err = p.moveFile(ui, comm, dst, src); err != nil { - return fmt.Errorf("Unable to move %s/grains to /etc/salt/grains: %s", p.config.TempConfigDir, err) + return fmt.Errorf("Unable to move %s/grains to %s/grains: %s", p.config.TempConfigDir, p.guestOSTypeConfig.configDir, err) } } @@ -251,7 +303,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { if p.config.RemoteStateTree != "" { dst = p.config.RemoteStateTree } else { - dst = DefaultStateTreeDir + dst = p.guestOSTypeConfig.stateRoot } if err = p.removeDir(ui, comm, dst); err != nil { return fmt.Errorf("Unable to clear salt tree: %s", err) @@ -273,7 +325,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { if p.config.RemotePillarRoots != "" { dst = p.config.RemotePillarRoots } else { - dst = DefaultPillarRootDir + dst = p.guestOSTypeConfig.pillarRoot } if err = p.removeDir(ui, comm, dst); err != nil { return fmt.Errorf("Unable to clear pillar root: %s", err) @@ -304,7 +356,7 @@ func (p *Provisioner) Cancel() { // Prepends sudo to supplied command if config says to func (p *Provisioner) sudo(cmd string) string { - if p.config.DisableSudo { + if p.config.DisableSudo || p.config.GuestOSType != provisioner.WindowsOSType { return cmd } @@ -370,7 +422,7 @@ func (p *Provisioner) moveFile(ui packer.Ui, comm packer.Communicator, dst, src func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir string) error { ui.Message(fmt.Sprintf("Creating directory: %s", dir)) cmd := &packer.RemoteCmd{ - Command: fmt.Sprintf("mkdir -p '%s'", dir), + Command: p.guestCommands.CreateDir(dir), } if err := cmd.StartWithUi(comm, ui); err != nil { return err @@ -384,7 +436,7 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error { ui.Message(fmt.Sprintf("Removing directory: %s", dir)) cmd := &packer.RemoteCmd{ - Command: fmt.Sprintf(p.sudo("rm -rf '%s'"), dir), + Command: p.guestCommands.RemoveDir(dir), } if err := cmd.StartWithUi(comm, ui); err != nil { return err From 630b7466d6ce77efa7526b6e688582bee203de14 Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 11:49:10 -0700 Subject: [PATCH 0303/1007] updated test to remove old DefaultTmpDir reference Fixed sudo logic Fixed error message format issue for OSType check --- provisioner/salt-masterless/provisioner.go | 4 ++-- provisioner/salt-masterless/provisioner_test.go | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index ebdc5eeb9..1e9cffc48 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -130,7 +130,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { var ok bool p.guestOSTypeConfig, ok = guestOSTypeConfigs[p.config.GuestOSType] if !ok { - return fmt.Errorf("Invalid guest_os_type: \"$\"", p.config.GuestOSType) + return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType) } p.guestCommands, err = provisioner.NewGuestCommands(p.config.GuestOSType, !p.config.DisableSudo) @@ -356,7 +356,7 @@ func (p *Provisioner) Cancel() { // Prepends sudo to supplied command if config says to func (p *Provisioner) sudo(cmd string) string { - if p.config.DisableSudo || p.config.GuestOSType != provisioner.WindowsOSType { + if p.config.DisableSudo || (p.config.GuestOSType == provisioner.WindowsOSType) { return cmd } diff --git a/provisioner/salt-masterless/provisioner_test.go b/provisioner/salt-masterless/provisioner_test.go index 2b40887d3..a02113198 100644 --- a/provisioner/salt-masterless/provisioner_test.go +++ b/provisioner/salt-masterless/provisioner_test.go @@ -1,11 +1,12 @@ package saltmasterless import ( - "github.com/hashicorp/packer/packer" "io/ioutil" "os" "strings" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { @@ -31,7 +32,7 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { t.Fatalf("err: %s", err) } - if p.config.TempConfigDir != DefaultTempConfigDir { + if p.config.TempConfigDir != p.guestOSTypeConfig.tempDir { t.Errorf("unexpected temp config dir: %s", p.config.TempConfigDir) } } From 666796e8eb9a6a4bd128e7ac720ca88b665abaec Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 14:39:13 -0700 Subject: [PATCH 0304/1007] Add ability to stat a remote path --- provisioner/guest_commands.go | 7 ++++ provisioner/salt-masterless/provisioner.go | 40 ++++++++++++++----- .../docs/provisioners/salt-masterless.html.md | 2 + 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/provisioner/guest_commands.go b/provisioner/guest_commands.go index 715d6cb31..b186ef2bf 100644 --- a/provisioner/guest_commands.go +++ b/provisioner/guest_commands.go @@ -13,6 +13,7 @@ type guestOSTypeCommand struct { chmod string mkdir string removeDir string + statPath string } var guestOSTypeCommands = map[string]guestOSTypeCommand{ @@ -20,11 +21,13 @@ var guestOSTypeCommands = map[string]guestOSTypeCommand{ chmod: "chmod %s '%s'", mkdir: "mkdir -p '%s'", removeDir: "rm -rf '%s'", + statPath: "stat '%s'", }, WindowsOSType: { chmod: "echo 'skipping chmod %s %s'", // no-op mkdir: "powershell.exe -Command \"New-Item -ItemType directory -Force -ErrorAction SilentlyContinue -Path %s\"", removeDir: "powershell.exe -Command \"rm %s -recurse -force\"", + statPath: "powershell.exe -Commond \"test-path %s\"", }, } @@ -64,6 +67,10 @@ func (g *GuestCommands) escapePath(path string) string { return path } +func (g *GuestCommands) StatPath(path string) string { + return g.sudo(fmt.Sprintf(g.commands().statPath, g.escapePath(path))) +} + func (g *GuestCommands) sudo(cmd string) string { if g.GuestOSType == UnixOSType && g.Sudo { return "sudo " + cmd diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 1e9cffc48..16566865f 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -17,10 +17,6 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) -const DefaultTempConfigDir = "/tmp/salt" -const DefaultStateTreeDir = "/srv/salt" -const DefaultPillarRootDir = "/srv/pillar" - type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -102,9 +98,9 @@ var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.WindowsOSType: { configDir: "C:/salt/conf", tempDir: "C:/Windows/Temp/salt/", - stateRoot: "C:/srv/salt/", - pillarRoot: "C:/srv/pillar/", - bootstrapFetchCmd: "Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.ps1' -OutFile 'C:/Windows/Temp/bootstrap-salt.ps1'", + stateRoot: "C:/salt/state", + pillarRoot: "C:/salt/pillar/", + bootstrapFetchCmd: "powershell Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/saltstack/salt-bootstrap/stable/bootstrap-salt.ps1' -OutFile 'C:/Windows/Temp/bootstrap-salt.ps1'", bootstrapRunCmd: "Powershell C:/Windows/Temp/bootstrap-salt.ps1", }, } @@ -305,9 +301,14 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } else { dst = p.guestOSTypeConfig.stateRoot } - if err = p.removeDir(ui, comm, dst); err != nil { - return fmt.Errorf("Unable to clear salt tree: %s", err) + + // only remove state tree if it exists or windows throws a fit + if err = p.statPath(ui, comm, dst); err == nil { + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear salt tree: %s", err) + } } + if err = p.moveFile(ui, comm, dst, src); err != nil { return fmt.Errorf("Unable to move %s/states to %s: %s", p.config.TempConfigDir, dst, err) } @@ -327,8 +328,11 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } else { dst = p.guestOSTypeConfig.pillarRoot } - if err = p.removeDir(ui, comm, dst); err != nil { - return fmt.Errorf("Unable to clear pillar root: %s", err) + // only remove path if it exists or windows throws a fit + if err = p.statPath(ui, comm, dst); err == nil { + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear pillar root: %s", err) + } } if err = p.moveFile(ui, comm, dst, src); err != nil { return fmt.Errorf("Unable to move %s/pillar to %s: %s", p.config.TempConfigDir, dst, err) @@ -433,6 +437,20 @@ func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir stri return nil } +func (p *Provisioner) statPath(ui packer.Ui, comm packer.Communicator, path string) error { + ui.Message(fmt.Sprintf("Verifying Path: %s", path)) + cmd := &packer.RemoteCmd{ + Command: p.guestCommands.StatPath(path), + } + if err := cmd.StartWithUi(comm, ui); err != nil { + return err + } + if cmd.ExitStatus != 0 { + return fmt.Errorf("Non-zero exit status.") + } + return nil +} + func (p *Provisioner) removeDir(ui packer.Ui, comm packer.Communicator, dir string) error { ui.Message(fmt.Sprintf("Removing directory: %s", dir)) cmd := &packer.RemoteCmd{ diff --git a/website/source/docs/provisioners/salt-masterless.html.md b/website/source/docs/provisioners/salt-masterless.html.md index 443f37561..ad6920614 100644 --- a/website/source/docs/provisioners/salt-masterless.html.md +++ b/website/source/docs/provisioners/salt-masterless.html.md @@ -90,3 +90,5 @@ Optional: - `salt_bin_dir` (string) - Path to the `salt-call` executable. Useful if it is not on the PATH. + +- `guest_os_type` (string) - The target guest OS type, either "unix" or "windows". From 857e5d04d336a6ae1a491b04c4fc9b39879a90b5 Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 15:11:29 -0700 Subject: [PATCH 0305/1007] Fix command error for salt install --- provisioner/salt-masterless/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 16566865f..980a061e7 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -234,7 +234,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Unable to download Salt: %s", err) } cmd = &packer.RemoteCmd{ - Command: fmt.Sprintf(p.sudo(p.guestOSTypeConfig.bootstrapRunCmd), p.config.BootstrapArgs), + Command: fmt.Sprintf("%s %s", p.sudo(p.guestOSTypeConfig.bootstrapRunCmd), p.config.BootstrapArgs), } ui.Message(fmt.Sprintf("Installing Salt with command %s", cmd.Command)) if err = cmd.StartWithUi(comm, ui); err != nil { From aee67d393324de3dbfb0ba83637b36d94f9d1de3 Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 15:22:10 -0700 Subject: [PATCH 0306/1007] Add ability to move files on remote system Fix salt-masterless to use generic MovePath --- provisioner/guest_commands.go | 9 ++++++++- provisioner/salt-masterless/provisioner.go | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/provisioner/guest_commands.go b/provisioner/guest_commands.go index b186ef2bf..c50087560 100644 --- a/provisioner/guest_commands.go +++ b/provisioner/guest_commands.go @@ -14,6 +14,7 @@ type guestOSTypeCommand struct { mkdir string removeDir string statPath string + mvPath string } var guestOSTypeCommands = map[string]guestOSTypeCommand{ @@ -22,12 +23,14 @@ var guestOSTypeCommands = map[string]guestOSTypeCommand{ mkdir: "mkdir -p '%s'", removeDir: "rm -rf '%s'", statPath: "stat '%s'", + mv: "mv '%s' '%s'", }, WindowsOSType: { chmod: "echo 'skipping chmod %s %s'", // no-op mkdir: "powershell.exe -Command \"New-Item -ItemType directory -Force -ErrorAction SilentlyContinue -Path %s\"", removeDir: "powershell.exe -Command \"rm %s -recurse -force\"", - statPath: "powershell.exe -Commond \"test-path %s\"", + statPath: "powershell.exe -Command \"test-path %s\"", + mv: "powershell.exe -Command \"mv %s %s\"", }, } @@ -71,6 +74,10 @@ func (g *GuestCommands) StatPath(path string) string { return g.sudo(fmt.Sprintf(g.commands().statPath, g.escapePath(path))) } +func (g *GuestCommands) MovePath(srcPath string, dstPath) string { + return g.sudo(fmt.Sprintf(g.commands().mv, g.escapePath(srcPath), g.escapePath(dstPath))) +} + func (g *GuestCommands) sudo(cmd string) string { if g.GuestOSType == UnixOSType && g.Sudo { return "sudo " + cmd diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 980a061e7..7f116b82a 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -412,7 +412,9 @@ func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst, sr func (p *Provisioner) moveFile(ui packer.Ui, comm packer.Communicator, dst, src string) error { ui.Message(fmt.Sprintf("Moving %s to %s", src, dst)) - cmd := &packer.RemoteCmd{Command: fmt.Sprintf(p.sudo("mv %s %s"), src, dst)} + cmd := &packer.RemoteCmd{ + Command: p.guestCommands.MovePath(src, dst), + } if err := cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { if err == nil { err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus) From 887b7dc4767418a6e1f9af5ccbbd4e0cc5c6cd17 Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 15:24:34 -0700 Subject: [PATCH 0307/1007] Fix mixed case for mv --- provisioner/guest_commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/guest_commands.go b/provisioner/guest_commands.go index c50087560..441154a50 100644 --- a/provisioner/guest_commands.go +++ b/provisioner/guest_commands.go @@ -14,7 +14,7 @@ type guestOSTypeCommand struct { mkdir string removeDir string statPath string - mvPath string + mv string } var guestOSTypeCommands = map[string]guestOSTypeCommand{ From a1ba4e5362be1807fa21284ca66fa73eb6384235 Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 15:32:40 -0700 Subject: [PATCH 0308/1007] Silently continue on removeDir for Windows Fixed parameter type exclusion in movePath command --- provisioner/guest_commands.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/provisioner/guest_commands.go b/provisioner/guest_commands.go index 441154a50..1d2d1597f 100644 --- a/provisioner/guest_commands.go +++ b/provisioner/guest_commands.go @@ -14,7 +14,7 @@ type guestOSTypeCommand struct { mkdir string removeDir string statPath string - mv string + mv string } var guestOSTypeCommands = map[string]guestOSTypeCommand{ @@ -23,14 +23,14 @@ var guestOSTypeCommands = map[string]guestOSTypeCommand{ mkdir: "mkdir -p '%s'", removeDir: "rm -rf '%s'", statPath: "stat '%s'", - mv: "mv '%s' '%s'", + mv: "mv '%s' '%s'", }, WindowsOSType: { chmod: "echo 'skipping chmod %s %s'", // no-op mkdir: "powershell.exe -Command \"New-Item -ItemType directory -Force -ErrorAction SilentlyContinue -Path %s\"", - removeDir: "powershell.exe -Command \"rm %s -recurse -force\"", + removeDir: "powershell.exe -Command \"rm %s -recurse -force -ErrorAction SilentlyContinue\"", statPath: "powershell.exe -Command \"test-path %s\"", - mv: "powershell.exe -Command \"mv %s %s\"", + mv: "powershell.exe -Command \"mv %s %s\"", }, } @@ -74,7 +74,7 @@ func (g *GuestCommands) StatPath(path string) string { return g.sudo(fmt.Sprintf(g.commands().statPath, g.escapePath(path))) } -func (g *GuestCommands) MovePath(srcPath string, dstPath) string { +func (g *GuestCommands) MovePath(srcPath string, dstPath string) string { return g.sudo(fmt.Sprintf(g.commands().mv, g.escapePath(srcPath), g.escapePath(dstPath))) } From 57770de36f864f73cf7e92e189c6d992194211cf Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Tue, 12 Dec 2017 16:01:00 -0700 Subject: [PATCH 0309/1007] revert file stat --- provisioner/salt-masterless/provisioner.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 7f116b82a..53eb59aaa 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -302,11 +302,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { dst = p.guestOSTypeConfig.stateRoot } - // only remove state tree if it exists or windows throws a fit - if err = p.statPath(ui, comm, dst); err == nil { - if err = p.removeDir(ui, comm, dst); err != nil { - return fmt.Errorf("Unable to clear salt tree: %s", err) - } + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear salt tree: %s", err) } if err = p.moveFile(ui, comm, dst, src); err != nil { @@ -328,12 +325,12 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { } else { dst = p.guestOSTypeConfig.pillarRoot } + // only remove path if it exists or windows throws a fit - if err = p.statPath(ui, comm, dst); err == nil { - if err = p.removeDir(ui, comm, dst); err != nil { - return fmt.Errorf("Unable to clear pillar root: %s", err) - } + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear pillar root: %s", err) } + if err = p.moveFile(ui, comm, dst, src); err != nil { return fmt.Errorf("Unable to move %s/pillar to %s: %s", p.config.TempConfigDir, dst, err) } @@ -410,7 +407,7 @@ func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst, sr return nil } -func (p *Provisioner) moveFile(ui packer.Ui, comm packer.Communicator, dst, src string) error { +func (p *Provisioner) moveFile(ui packer.Ui, comm packer.Communicator, dst string, src string) error { ui.Message(fmt.Sprintf("Moving %s to %s", src, dst)) cmd := &packer.RemoteCmd{ Command: p.guestCommands.MovePath(src, dst), From 88b275715ee455604435e3c788f3c88a85116db7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 12 Dec 2017 21:00:18 -0800 Subject: [PATCH 0310/1007] clarify that there are cloud providers that support nested virtualization --- .../build-virtualbox-image.html.md | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 1d6fc5bb6..c1e5c8978 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -10,10 +10,12 @@ This guide walks through the process of building a VirtualBox image using Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. -The Packer VirtualBox builder requires access to VirtualBox, which needs to run -on a bare-metal machine, as virtualization is generally not supported on cloud -instances. This is also true for the [VMWare](/docs/builders/vmware.html) and -the [QEMU](/docs/builders/qemu.html) Packer builders. +The Packer VirtualBox builder requires access to VirtualBox. Virtualization is +not universally available on cloud instances, so we recommend you run these +builds on either a bare metal server, or cloud instances which support nested +virtualization, such as Azure or GCP. This is also true for the +[VMWare](/docs/builders/vmware.html) and the [QEMU](/docs/builders/qemu.html) +Packer builders. We will use Chef's [Bento boxes](https://github.com/chef/bento) to provision an Ubuntu image on VirtualBox. For this example, we will use the repository @@ -21,13 +23,12 @@ directly, but you may also fork it for the same results. ## 1. Provision a Bare-metal Machine -The Packer VirtualBox builder requires running on bare-metal (hardware). If you -do not have access to a bare-metal machine, we recommend using -[Packet.net](https://www.packet.net/) to obtain a new machine. If you are -a first time user of Packet.net, the Packet.net team has provided HashiCorp the -coupon code `hash25` which you can use for &#x24;25 off to test out this guide. You -can use a `baremetal_0` server type for testing, but for regular use, the -`baremetal_1` instance may be a better option. +For the purposes of this example, we will run on a bare-metal instance from +[Packet.net](https://www.packet.net/). If you are a first time user of +Packet.net, the Packet.net team has provided HashiCorp the coupon code `hash25` +which you can use for &#x24;25 off to test out this guide. You can use +a `baremetal_0` server type for testing, but for regular use, the `baremetal_1` +instance may be a better option. There is also a [Packet Provider](https://www.terraform.io/docs/providers/packet/index.html) in From 4ed60ba7899685ca97a7e3ee2b3ae58f6d93c405 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 12 Dec 2017 21:07:12 -0800 Subject: [PATCH 0311/1007] clarify support vs availability. --- .../source/guides/packer-on-cicd/build-virtualbox-image.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index c1e5c8978..7360e3931 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -11,7 +11,7 @@ Packer on a new TeamCity Agent. Before getting started you should have access to a TeamCity Server. The Packer VirtualBox builder requires access to VirtualBox. Virtualization is -not universally available on cloud instances, so we recommend you run these +not universally supported on cloud instances, so we recommend you run these builds on either a bare metal server, or cloud instances which support nested virtualization, such as Azure or GCP. This is also true for the [VMWare](/docs/builders/vmware.html) and the [QEMU](/docs/builders/qemu.html) From cba1a0598f393b73b31fc3788994afc71ee51ed1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 12 Dec 2017 21:12:49 -0800 Subject: [PATCH 0312/1007] document additional aws permission --- website/source/docs/builders/amazon.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index 8873dfcbe..e77e4bf79 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -115,6 +115,7 @@ Packer to work: "ec2:DeregisterImage", "ec2:DescribeImageAttribute", "ec2:DescribeImages", + "ec2:DescribeInstanceStatus", "ec2:DescribeInstances", "ec2:DescribeRegions", "ec2:DescribeSecurityGroups", From 284b06900342d5fa80cfc5b8106654a90eac081f Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Wed, 13 Dec 2017 10:20:27 -0700 Subject: [PATCH 0313/1007] Fixed stating of files on windows added directory existence check to salt provisioner before directory clean up --- provisioner/guest_commands.go | 2 +- provisioner/salt-masterless/provisioner.go | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/provisioner/guest_commands.go b/provisioner/guest_commands.go index 1d2d1597f..47edb1768 100644 --- a/provisioner/guest_commands.go +++ b/provisioner/guest_commands.go @@ -29,7 +29,7 @@ var guestOSTypeCommands = map[string]guestOSTypeCommand{ chmod: "echo 'skipping chmod %s %s'", // no-op mkdir: "powershell.exe -Command \"New-Item -ItemType directory -Force -ErrorAction SilentlyContinue -Path %s\"", removeDir: "powershell.exe -Command \"rm %s -recurse -force -ErrorAction SilentlyContinue\"", - statPath: "powershell.exe -Command \"test-path %s\"", + statPath: "powershell.exe -Command { if (test-path %s) { exit 0 } else { exit 1 } }", mv: "powershell.exe -Command \"mv %s %s\"", }, } diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index 53eb59aaa..f1ae1fe84 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -302,8 +302,10 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { dst = p.guestOSTypeConfig.stateRoot } - if err = p.removeDir(ui, comm, dst); err != nil { - return fmt.Errorf("Unable to clear salt tree: %s", err) + if err = p.statPath(ui, comm, dst); err != nil { + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear salt tree: %s", err) + } } if err = p.moveFile(ui, comm, dst, src); err != nil { @@ -326,9 +328,10 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { dst = p.guestOSTypeConfig.pillarRoot } - // only remove path if it exists or windows throws a fit - if err = p.removeDir(ui, comm, dst); err != nil { - return fmt.Errorf("Unable to clear pillar root: %s", err) + if err = p.statPath(ui, comm, dst); err != nil { + if err = p.removeDir(ui, comm, dst); err != nil { + return fmt.Errorf("Unable to clear pillar root: %s", err) + } } if err = p.moveFile(ui, comm, dst, src); err != nil { From bf7a4b33632136e965ddc7224edf57143a5b6d24 Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Wed, 13 Dec 2017 10:49:38 -0700 Subject: [PATCH 0314/1007] remove erroraction on win removedir --- provisioner/guest_commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/guest_commands.go b/provisioner/guest_commands.go index 47edb1768..3a361a208 100644 --- a/provisioner/guest_commands.go +++ b/provisioner/guest_commands.go @@ -28,7 +28,7 @@ var guestOSTypeCommands = map[string]guestOSTypeCommand{ WindowsOSType: { chmod: "echo 'skipping chmod %s %s'", // no-op mkdir: "powershell.exe -Command \"New-Item -ItemType directory -Force -ErrorAction SilentlyContinue -Path %s\"", - removeDir: "powershell.exe -Command \"rm %s -recurse -force -ErrorAction SilentlyContinue\"", + removeDir: "powershell.exe -Command \"rm %s -recurse -force\"", statPath: "powershell.exe -Command { if (test-path %s) { exit 0 } else { exit 1 } }", mv: "powershell.exe -Command \"mv %s %s\"", }, From fc566a3cb4ddadfaa06452898d8bf399473e0eda Mon Sep 17 00:00:00 2001 From: Dave Sanderson <dave.d.sanderson@gmail.com> Date: Wed, 13 Dec 2017 11:16:21 -0700 Subject: [PATCH 0315/1007] Added test for new commands and guest os type --- provisioner/guest_commands_test.go | 75 +++++++++++++++++++ .../salt-masterless/provisioner_test.go | 16 ++++ 2 files changed, 91 insertions(+) diff --git a/provisioner/guest_commands_test.go b/provisioner/guest_commands_test.go index 50d15870a..08baca058 100644 --- a/provisioner/guest_commands_test.go +++ b/provisioner/guest_commands_test.go @@ -118,3 +118,78 @@ func TestRemoveDir(t *testing.T) { t.Fatalf("Unexpected Windows remove dir cmd: %s", cmd) } } + +func TestStatPath(t *testing.T) { + // *nix + guestCmd, err := NewGuestCommands(UnixOSType, false) + if err != nil { + t.Fatalf("Failed to create new GuestCommands for OS: %s", UnixOSType) + } + cmd := guestCmd.StatPath("/tmp/somedir") + if cmd != "stat '/tmp/somedir'" { + t.Fatalf("Unexpected Unix stat cmd: %s", cmd) + } + + guestCmd, err = NewGuestCommands(UnixOSType, true) + if err != nil { + t.Fatalf("Failed to create new GuestCommands for OS: %s", UnixOSType) + } + cmd = guestCmd.StatPath("/tmp/somedir") + if cmd != "sudo stat '/tmp/somedir'" { + t.Fatalf("Unexpected Unix stat cmd: %s", cmd) + } + + // Windows OS + guestCmd, err = NewGuestCommands(WindowsOSType, false) + if err != nil { + t.Fatalf("Failed to create new GuestCommands for OS: %s", WindowsOSType) + } + cmd = guestCmd.StatPath("C:\\Temp\\SomeDir") + if cmd != "powershell.exe -Command { if (test-path C:\\Temp\\SomeDir) { exit 0 } else { exit 1 } }" { + t.Fatalf("Unexpected Windows stat cmd: %s", cmd) + } + + // Windows OS w/ space in path + cmd = guestCmd.StatPath("C:\\Temp\\Some Dir") + if cmd != "powershell.exe -Command { if (test-path C:\\Temp\\Some` Dir) { exit 0 } else { exit 1 } }" { + t.Fatalf("Unexpected Windows stat cmd: %s", cmd) + } +} + +func TestMovePath(t *testing.T) { + // *nix + guestCmd, err := NewGuestCommands(UnixOSType, false) + if err != nil { + t.Fatalf("Failed to create new GuestCommands for OS: %s", UnixOSType) + } + cmd := guestCmd.MovePath("/tmp/somedir", "/tmp/newdir") + if cmd != "mv '/tmp/somedir' '/tmp/newdir'" { + t.Fatalf("Unexpected Unix move cmd: %s", cmd) + } + + // sudo *nix + guestCmd, err = NewGuestCommands(UnixOSType, true) + if err != nil { + t.Fatalf("Failed to create new sudo GuestCommands for OS: %s", UnixOSType) + } + cmd = guestCmd.MovePath("/tmp/somedir", "/tmp/newdir") + if cmd != "sudo mv '/tmp/somedir' '/tmp/newdir'" { + t.Fatalf("Unexpected Unix sudo mv cmd: %s", cmd) + } + + // Windows OS + guestCmd, err = NewGuestCommands(WindowsOSType, false) + if err != nil { + t.Fatalf("Failed to create new GuestCommands for OS: %s", WindowsOSType) + } + cmd = guestCmd.MovePath("C:\\Temp\\SomeDir", "C:\\Temp\\NewDir") + if cmd != "powershell.exe -Command \"mv C:\\Temp\\SomeDir C:\\Temp\\NewDir\"" { + t.Fatalf("Unexpected Windows remove dir cmd: %s", cmd) + } + + // Windows OS w/ space in path + cmd = guestCmd.MovePath("C:\\Temp\\Some Dir", "C:\\Temp\\New Dir") + if cmd != "powershell.exe -Command \"mv C:\\Temp\\Some` Dir C:\\Temp\\New` Dir\"" { + t.Fatalf("Unexpected Windows remove dir cmd: %s", cmd) + } +} diff --git a/provisioner/salt-masterless/provisioner_test.go b/provisioner/salt-masterless/provisioner_test.go index a02113198..a4bd64890 100644 --- a/provisioner/salt-masterless/provisioner_test.go +++ b/provisioner/salt-masterless/provisioner_test.go @@ -309,3 +309,19 @@ func TestProvisionerPrepare_LogLevel(t *testing.T) { t.Fatal("-l debug should be set in CmdArgs") } } + +func TestProvisionerPrepare_GuestOSType(t *testing.T) { + var p Provisioner + config := testConfig() + + config["guest_os_type"] = "Windows" + + err := p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + if p.config.GuestOSType != "windows" { + t.Fatalf("GuestOSType should be 'windows'") + } +} From 893d0334f183804efdbe984fb4015377bee41857 Mon Sep 17 00:00:00 2001 From: frankdannhauer <frankdannhauer@users.noreply.github.com> Date: Thu, 14 Dec 2017 14:00:52 +0100 Subject: [PATCH 0316/1007] Fix #5335 https://github.com/hashicorp/packer/issues/5335 --- provisioner/ansible-local/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/ansible-local/provisioner.go b/provisioner/ansible-local/provisioner.go index ec1eec041..e007bfb85 100644 --- a/provisioner/ansible-local/provisioner.go +++ b/provisioner/ansible-local/provisioner.go @@ -304,7 +304,7 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) err playbook := filepath.ToSlash(filepath.Join(p.config.StagingDir, filepath.Base(p.config.PlaybookFile))) inventory := filepath.ToSlash(filepath.Join(p.config.StagingDir, filepath.Base(p.config.InventoryFile))) - extraArgs := fmt.Sprintf(" --extra-vars \"packer_build_name=%s packer_builder_type=%s packer_http_addr=%s\" ", + extraArgs := fmt.Sprintf(" --extra-vars \\\"packer_build_name=%s packer_builder_type=%s packer_http_addr=%s\\\" ", p.config.PackerBuildName, p.config.PackerBuilderType, common.GetHTTPAddr()) if len(p.config.ExtraArguments) > 0 { extraArgs = extraArgs + strings.Join(p.config.ExtraArguments, " ") From c3eb54f183d801634faffb05cb7178c5627e9742 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 14 Dec 2017 11:26:09 -0800 Subject: [PATCH 0317/1007] log when loading config from environment --- main.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 0f00b9038..538f40d85 100644 --- a/main.go +++ b/main.go @@ -275,7 +275,9 @@ func loadConfig() (*config, error) { } configFilePath := os.Getenv("PACKER_CONFIG") - if configFilePath == "" { + if configFilePath != "" { + log.Printf("'PACKER_CONFIG' set, loading config from environment.") + } else { var err error configFilePath, err = packer.ConfigFile() From c338cb79d05629a5b6462ebcd122003d90e95ea6 Mon Sep 17 00:00:00 2001 From: Ben Phegan <ben.phegan@optiver.com.au> Date: Fri, 15 Dec 2017 13:24:15 +1100 Subject: [PATCH 0318/1007] Initial commit of feature to allow MAC address specification for HyperV builders --- builder/hyperv/common/driver.go | 2 ++ builder/hyperv/common/driver_mock.go | 12 ++++++++++++ builder/hyperv/common/driver_ps_4.go | 4 ++++ builder/hyperv/common/step_clone_vm.go | 11 +++++++++++ builder/hyperv/common/step_create_vm.go | 11 +++++++++++ builder/hyperv/iso/builder.go | 1 + builder/hyperv/vmcx/builder.go | 2 ++ common/powershell/hyperv/hyperv.go | 12 ++++++++++++ website/source/docs/builders/hyperv-iso.html.md | 6 +++++- website/source/docs/builders/hyperv-vmcx.html.md | 4 ++++ 10 files changed, 64 insertions(+), 1 deletion(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 2a2f0b810..571214acd 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -52,6 +52,8 @@ type Driver interface { //Set the vlan to use for machine SetVirtualMachineVlanId(string, string) error + SetVmNetworkAdapterMacAddress(string, string) error + UntagVirtualMachineNetworkAdapterVlan(string, string) error CreateExternalVirtualSwitch(string, string) error diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 3823cbd12..7d8e02c6a 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -67,6 +67,11 @@ type DriverMock struct { SetNetworkAdapterVlanId_VlanId string SetNetworkAdapterVlanId_Err error + SetVmNetworkAdapterMacAddress_Called bool + SetVmNetworkAdapterMacAddress_VmName string + SetVmNetworkAdapterMacAddress_Mac string + SetVmNetworkAdapterMacAddress_Err error + SetVirtualMachineVlanId_Called bool SetVirtualMachineVlanId_VmName string SetVirtualMachineVlanId_VlanId string @@ -318,6 +323,13 @@ func (d *DriverMock) SetNetworkAdapterVlanId(switchName string, vlanId string) e return d.SetNetworkAdapterVlanId_Err } +func (d *DriverMock) SetVmNetworkAdapterMacAddress(vmName string, mac string) error { + d.SetVmNetworkAdapterMacAddress_Called = true + d.SetVmNetworkAdapterMacAddress_VmName = vmName + d.SetVmNetworkAdapterMacAddress_Mac = mac + return d.SetVmNetworkAdapterMacAddress_Err +} + func (d *DriverMock) SetVirtualMachineVlanId(vmName string, vlanId string) error { d.SetVirtualMachineVlanId_Called = true d.SetVirtualMachineVlanId_VmName = vmName diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index 853aa7021..a6c1b7352 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -146,6 +146,10 @@ func (d *HypervPS4Driver) SetVirtualMachineVlanId(vmName string, vlanId string) return hyperv.SetVirtualMachineVlanId(vmName, vlanId) } +func (d *HypervPS4Driver) SetVmNetworkAdapterMacAddress(vmName string, mac string) error { + return hyperv.SetVmNetworkAdapterMacAddress(vmName, mac) +} + func (d *HypervPS4Driver) UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) error { return hyperv.UntagVirtualMachineNetworkAdapterVlan(vmName, switchName) } diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index 4a5b55566..24d731b02 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -27,6 +27,7 @@ type StepCloneVM struct { EnableDynamicMemory bool EnableSecureBoot bool EnableVirtualizationExtensions bool + MacAddress string } func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { @@ -117,6 +118,16 @@ func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { } } + if s.MacAddress != "" { + err = driver.SetVmNetworkAdapterMacAddress(s.VMName, s.MacAddress) + if err != nil { + err := fmt.Errorf("Error setting MAC address: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + // Set the final name in the state bag so others can use it state.Put("vmName", s.VMName) diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 02171d9c6..92fdbcb04 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -28,6 +28,7 @@ type StepCreateVM struct { EnableVirtualizationExtensions bool AdditionalDiskSize []uint DifferencingDisk bool + MacAddress string } func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { @@ -124,6 +125,16 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { } } + if s.MacAddress != "" { + err = driver.SetVmNetworkAdapterMacAddress(s.VMName, s.MacAddress) + if err != nil { + err := fmt.Errorf("Error setting MAC address: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + // Set the final name in the state bag so others can use it state.Put("vmName", s.VMName) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 849cbcacf..fd27cf94b 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -74,6 +74,7 @@ type Config struct { BootCommand []string `mapstructure:"boot_command"` SwitchName string `mapstructure:"switch_name"` SwitchVlanId string `mapstructure:"switch_vlan_id"` + MacAddress string `mapstructure:"mac_address"` VlanId string `mapstructure:"vlan_id"` Cpu uint `mapstructure:"cpu"` Generation uint `mapstructure:"generation"` diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 6a976b3df..ae0e4c61e 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -82,6 +82,7 @@ type Config struct { BootCommand []string `mapstructure:"boot_command"` SwitchName string `mapstructure:"switch_name"` SwitchVlanId string `mapstructure:"switch_vlan_id"` + MacAddress string `mapstructure:"mac_address"` VlanId string `mapstructure:"vlan_id"` Cpu uint `mapstructure:"cpu"` Generation uint @@ -403,6 +404,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableDynamicMemory: b.config.EnableDynamicMemory, EnableSecureBoot: b.config.EnableSecureBoot, EnableVirtualizationExtensions: b.config.EnableVirtualizationExtensions, + MacAddress: b.config.MacAddress, }, &hypervcommon.StepEnableIntegrationService{}, diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 25073d238..d26ec5eeb 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -319,6 +319,18 @@ Copy-Item $cloneFromVmxcPath $exportPath -Recurse -Force return err } +func SetVmNetworkAdapterMacAddress(vmName string, mac string) error { + var script = ` +param([string]$vmName, [string]$mac) +Set-VMNetworkAdapter $vmName -staticmacaddress $mac + ` + + var ps powershell.PowerShellCmd + err := ps.Run(script, vmName, mac) + + return err +} + func ImportVmxcVirtualMachine(importPath string, vmName string, harddrivePath string, ram int64, switchName string) error { var script = ` param([string]$importPath, [string]$vmName, [string]$harddrivePath, [long]$memoryStartupBytes, [string]$switchName) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index ff267392c..41e603129 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -204,7 +204,7 @@ can be configured for this builder. By default none is set. If none is set then a vlan is not set on the switch's network card. If this value is set it should match the vlan specified in by `vlan_id`. -* `vhd_temp_path` (string) - A separate path to be used for storing the VM's +- `vhd_temp_path` (string) - A separate path to be used for storing the VM's disk image. The purpose is to enable reading and writing to take place on different physical disks (read from VHD temp path, write to regular temp path while exporting the VM) to eliminate a single-disk bottleneck. @@ -213,6 +213,10 @@ can be configured for this builder. for the new virtual machine. By default none is set. If none is set then vlans are not set on the virtual machine's network card. +- `mac_address` (string) - This allows a specific MAC address to be used on the + default virtual network card. The MAC address must be a string with no + delimeters, for example "0000deadbeef". + - `vm_name` (string) - This is the name of the virtual machine for the new virtual machine, without the file extension. By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index 1aac29fc1..a7afe93ce 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -225,6 +225,10 @@ can be configured for this builder. for the new virtual machine. By default none is set. If none is set then vlans are not set on the virtual machine's network card. +- `mac_address` (string) - This allows a specific MAC address to be used on the + default virtual network card. The MAC address must be a string with no + delimeters, for example "0000deadbeef". + - `vm_name` (string) - This is the name of the virtual machine for the new virtual machine, without the file extension. By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. From 6410fd615c803fe213153eb08537ee556e28699e Mon Sep 17 00:00:00 2001 From: Hunter Morgan <automaticgiant@users.noreply.github.com> Date: Mon, 18 Dec 2017 20:21:26 +0000 Subject: [PATCH 0319/1007] typo --- provisioner/converge/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/converge/provisioner.go b/provisioner/converge/provisioner.go index 0b8b93e5d..16dddd73f 100644 --- a/provisioner/converge/provisioner.go +++ b/provisioner/converge/provisioner.go @@ -34,7 +34,7 @@ type Config struct { // Execution Module string `mapstructure:"module"` WorkingDirectory string `mapstructure:"working_directory"` - Params map[string]string `mapstucture:"params"` + Params map[string]string `mapstructure:"params"` ExecuteCommand string `mapstructure:"execute_command"` PreventSudo bool `mapstructure:"prevent_sudo"` From 1bc6a445ef20af597744cbd6aff0c63b49637826 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 18 Dec 2017 14:04:46 -0800 Subject: [PATCH 0320/1007] Fixing typo in coupon code --- .../source/guides/packer-on-cicd/build-virtualbox-image.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 7360e3931..056f3486a 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -25,7 +25,7 @@ directly, but you may also fork it for the same results. For the purposes of this example, we will run on a bare-metal instance from [Packet.net](https://www.packet.net/). If you are a first time user of -Packet.net, the Packet.net team has provided HashiCorp the coupon code `hash25` +Packet.net, the Packet.net team has provided HashiCorp the coupon code `hashi25` which you can use for &#x24;25 off to test out this guide. You can use a `baremetal_0` server type for testing, but for regular use, the `baremetal_1` instance may be a better option. From f88cd61e703dc23eb17c8de0fd3acef9571dfa94 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 18 Dec 2017 14:05:12 -0800 Subject: [PATCH 0321/1007] Renaming 'Packet.net' to 'Packet' --- .../guides/packer-on-cicd/build-virtualbox-image.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 056f3486a..0b5754f4c 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -24,8 +24,8 @@ directly, but you may also fork it for the same results. ## 1. Provision a Bare-metal Machine For the purposes of this example, we will run on a bare-metal instance from -[Packet.net](https://www.packet.net/). If you are a first time user of -Packet.net, the Packet.net team has provided HashiCorp the coupon code `hashi25` +[Packet](https://www.packet.net/). If you are a first time user of +Packet, the Packet team has provided HashiCorp the coupon code `hashi25` which you can use for &#x24;25 off to test out this guide. You can use a `baremetal_0` server type for testing, but for regular use, the `baremetal_1` instance may be a better option. From 37ce11fa0e1799c8c6f8669d09f6cb64bf914a4c Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 18 Dec 2017 14:17:27 -0800 Subject: [PATCH 0322/1007] Add details about the 30% off ongoing coupon. --- .../guides/packer-on-cicd/build-virtualbox-image.html.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 0b5754f4c..506db22ce 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -26,9 +26,10 @@ directly, but you may also fork it for the same results. For the purposes of this example, we will run on a bare-metal instance from [Packet](https://www.packet.net/). If you are a first time user of Packet, the Packet team has provided HashiCorp the coupon code `hashi25` -which you can use for &#x24;25 off to test out this guide. You can use -a `baremetal_0` server type for testing, but for regular use, the `baremetal_1` -instance may be a better option. +which you can use for &#x24;25 off to test out this guide and up to +30&#x25; if you decide to +reserve ongoing servers (email help@packet.net for details). You can use a `baremetal_0` server type for +testing, but for regular use, the `baremetal_1` instance may be a better option. There is also a [Packet Provider](https://www.terraform.io/docs/providers/packet/index.html) in From 7ee50ff9264dd25be4a76bb9d0d6554dd009dc7c Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Mon, 18 Dec 2017 15:12:04 -0800 Subject: [PATCH 0323/1007] Should be OVF As a side note I will point out that the bento projects will use vagrant to package up the image into a .box file. But using OVF as we are assuming not to be using vagrant. --- .../guides/packer-on-cicd/upload-images-to-artifact.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md b/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md index 9916fd871..ca0b1a2d8 100644 --- a/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md +++ b/website/source/guides/packer-on-cicd/upload-images-to-artifact.html.md @@ -41,5 +41,5 @@ In your build configuration in TeamCity Server, add an additional **Build Step: Command Line** and set the **Script content** field to the following: ```shell -awscli s3 cp . s3://bucket/ --exclude “*” --include “*.iso” +awscli s3 cp . s3://bucket/ --exclude “*” --include “*.ovf" ``` From aab786dd1ae730f208c3f901c6059c007f666500 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 18 Dec 2017 15:31:50 -0800 Subject: [PATCH 0324/1007] formatting --- .../packer-on-cicd/build-virtualbox-image.html.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md index 506db22ce..33582a910 100644 --- a/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md +++ b/website/source/guides/packer-on-cicd/build-virtualbox-image.html.md @@ -24,12 +24,12 @@ directly, but you may also fork it for the same results. ## 1. Provision a Bare-metal Machine For the purposes of this example, we will run on a bare-metal instance from -[Packet](https://www.packet.net/). If you are a first time user of -Packet, the Packet team has provided HashiCorp the coupon code `hashi25` -which you can use for &#x24;25 off to test out this guide and up to -30&#x25; if you decide to -reserve ongoing servers (email help@packet.net for details). You can use a `baremetal_0` server type for -testing, but for regular use, the `baremetal_1` instance may be a better option. +[Packet](https://www.packet.net/). If you are a first time user of Packet, the +Packet team has provided HashiCorp the coupon code `hashi25` which you can use +for &#x24;25 off to test out this guide and up to 30&#x25; if you decide to +reserve ongoing servers (email help@packet.net for details). You can use +a `baremetal_0` server type for testing, but for regular use, the `baremetal_1` +instance may be a better option. There is also a [Packet Provider](https://www.terraform.io/docs/providers/packet/index.html) in From 8bcb469b8b9d6ace216d454e4366ffbac382edfb Mon Sep 17 00:00:00 2001 From: Olivier Bazoud <olivier.bazoud@gmail.com> Date: Tue, 19 Dec 2017 10:00:03 +0100 Subject: [PATCH 0325/1007] builder/amazon: Added new region Paris - eu-west-3 --- builder/amazon/common/regions.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/amazon/common/regions.go b/builder/amazon/common/regions.go index 5cdf2caeb..9b4492459 100644 --- a/builder/amazon/common/regions.go +++ b/builder/amazon/common/regions.go @@ -12,6 +12,7 @@ func listEC2Regions() []string { "eu-central-1", "eu-west-1", "eu-west-2", + "eu-west-3", "sa-east-1", "us-east-1", "us-east-2", From 3e92b1374efc0582f6bcd96e2701e1de434cad1e Mon Sep 17 00:00:00 2001 From: Rong Chen <rong.chen@veeva.com> Date: Tue, 19 Dec 2017 10:34:12 -0800 Subject: [PATCH 0326/1007] issue5606: follow the convention to use AccessConfig to create new aws session for step_create_tags etc. --- builder/amazon/chroot/builder.go | 2 ++ builder/amazon/common/artifact.go | 10 +++------- builder/amazon/common/step_create_tags.go | 10 +++------- builder/amazon/ebs/builder.go | 2 ++ builder/amazon/ebssurrogate/builder.go | 2 ++ builder/amazon/instance/builder.go | 2 ++ post-processor/amazon-import/post-processor.go | 1 + 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 388061bee..9d3e8c63a 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -281,6 +281,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ + AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -303,6 +304,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &awscommon.Artifact{ + AccessConfig: &b.config.AccessConfig, Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/builder/amazon/common/artifact.go b/builder/amazon/common/artifact.go index dc50f7721..1c3817d6f 100644 --- a/builder/amazon/common/artifact.go +++ b/builder/amazon/common/artifact.go @@ -6,14 +6,14 @@ import ( "sort" "strings" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/packer" ) // Artifact is an artifact implementation that contains built AMIs. type Artifact struct { + AccessConfig *AccessConfig + // A map of regions to AMI IDs. Amis map[string]string @@ -69,11 +69,7 @@ func (a *Artifact) Destroy() error { for region, imageId := range a.Amis { log.Printf("Deregistering image ID (%s) from region (%s)", imageId, region) - regionConfig := &aws.Config{ - Credentials: a.Conn.Config.Credentials, - Region: aws.String(region), - } - session, err := session.NewSession(regionConfig) + session, err := a.AccessConfig.Session() if err != nil { return err } diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 791227260..89a388205 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -5,7 +5,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" retry "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/packer" @@ -14,6 +13,7 @@ import ( ) type StepCreateTags struct { + AccessConfig *AccessConfig Tags map[string]string SnapshotTags map[string]string Ctx interpolate.Context @@ -36,15 +36,11 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { } // Adds tags to AMIs and snapshots - for region, ami := range amis { + for ami := range amis { ui.Say(fmt.Sprintf("Adding tags to AMI (%s)...", ami)) // Declare list of resources to tag - awsConfig := aws.Config{ - Credentials: ec2conn.Config.Credentials, - Region: aws.String(region), - } - session, err := session.NewSession(&awsConfig) + session, err := s.AccessConfig.Session() if err != nil { err := fmt.Errorf("Error creating AWS session: %s", err) state.Put("error", err) diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 392162652..176c62d22 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -245,6 +245,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ + AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -267,6 +268,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &awscommon.Artifact{ + AccessConfig: &b.config.AccessConfig, Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 4831b8ba7..1ffbcd80f 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -263,6 +263,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ + AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -281,6 +282,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe if amis, ok := state.GetOk("amis"); ok { // Build the artifact and return it artifact := &awscommon.Artifact{ + AccessConfig: &b.config.AccessConfig, Amis: amis.(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 59c329515..f80daa954 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -317,6 +317,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ + AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -339,6 +340,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &awscommon.Artifact{ + AccessConfig: &b.config.AccessConfig, Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index c9cbd2077..982defe3f 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -365,6 +365,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac // Add the reported AMI ID to the artifact list log.Printf("Adding created AMI ID %s in region %s to output artifacts", createdami, *config.Region) artifact = &awscommon.Artifact{ + AccessConfig: &p.config.AccessConfig, Amis: map[string]string{ *config.Region: createdami, }, From f6c401a143911964c5abd07018f52900a5cf5d3a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 19 Dec 2017 11:05:50 -0800 Subject: [PATCH 0327/1007] don't pass in accessconfig --- builder/amazon/chroot/builder.go | 2 -- builder/amazon/ebs/builder.go | 2 -- builder/amazon/ebssurrogate/builder.go | 2 -- builder/amazon/instance/builder.go | 2 -- post-processor/amazon-import/post-processor.go | 1 - 5 files changed, 9 deletions(-) diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 9d3e8c63a..388061bee 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -281,7 +281,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ - AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -304,7 +303,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &awscommon.Artifact{ - AccessConfig: &b.config.AccessConfig, Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 176c62d22..392162652 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -245,7 +245,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ - AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -268,7 +267,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &awscommon.Artifact{ - AccessConfig: &b.config.AccessConfig, Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 1ffbcd80f..4831b8ba7 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -263,7 +263,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ - AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -282,7 +281,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe if amis, ok := state.GetOk("amis"); ok { // Build the artifact and return it artifact := &awscommon.Artifact{ - AccessConfig: &b.config.AccessConfig, Amis: amis.(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index f80daa954..59c329515 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -317,7 +317,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepCreateTags{ - AccessConfig: &b.config.AccessConfig, Tags: b.config.AMITags, SnapshotTags: b.config.SnapshotTags, Ctx: b.config.ctx, @@ -340,7 +339,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &awscommon.Artifact{ - AccessConfig: &b.config.AccessConfig, Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, Conn: ec2conn, diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 982defe3f..c9cbd2077 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -365,7 +365,6 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac // Add the reported AMI ID to the artifact list log.Printf("Adding created AMI ID %s in region %s to output artifacts", createdami, *config.Region) artifact = &awscommon.Artifact{ - AccessConfig: &p.config.AccessConfig, Amis: map[string]string{ *config.Region: createdami, }, From f3dea272d98a6ad8fa081fce6d20260ba57a9de1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 19 Dec 2017 11:04:17 -0800 Subject: [PATCH 0328/1007] Set session in state bag We can construct connections to arbitrary regions from it --- builder/amazon/chroot/builder.go | 3 +- builder/amazon/chroot/step_instance_info.go | 4 +-- builder/amazon/common/artifact.go | 14 ++++----- builder/amazon/common/step_create_tags.go | 23 ++++++--------- .../common/step_modify_ami_attributes.go | 29 ++++++------------- builder/amazon/ebs/builder.go | 3 +- builder/amazon/ebssurrogate/builder.go | 3 +- builder/amazon/instance/builder.go | 3 +- .../amazon-import/post-processor.go | 2 +- 9 files changed, 35 insertions(+), 49 deletions(-) diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 388061bee..80d6ae1b9 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -198,6 +198,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state := new(multistep.BasicStateBag) state.Put("config", &b.config) state.Put("ec2", ec2conn) + state.Put("awsSession", session) state.Put("hook", hook) state.Put("ui", ui) state.Put("wrappedCommand", CommandWrapper(wrappedCommand)) @@ -305,7 +306,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe artifact := &awscommon.Artifact{ Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, - Conn: ec2conn, + Session: session, } return artifact, nil diff --git a/builder/amazon/chroot/step_instance_info.go b/builder/amazon/chroot/step_instance_info.go index 00fd10dde..652808952 100644 --- a/builder/amazon/chroot/step_instance_info.go +++ b/builder/amazon/chroot/step_instance_info.go @@ -16,13 +16,13 @@ type StepInstanceInfo struct{} func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) + session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) // Get our own instance ID ui.Say("Gathering information about this EC2 instance...") - sess := session.New() - ec2meta := ec2metadata.New(sess) + ec2meta := ec2metadata.New(session) identity, err := ec2meta.GetInstanceIdentityDocument() if err != nil { err := fmt.Errorf( diff --git a/builder/amazon/common/artifact.go b/builder/amazon/common/artifact.go index 1c3817d6f..90d7dec10 100644 --- a/builder/amazon/common/artifact.go +++ b/builder/amazon/common/artifact.go @@ -6,14 +6,14 @@ import ( "sort" "strings" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/packer" ) // Artifact is an artifact implementation that contains built AMIs. type Artifact struct { - AccessConfig *AccessConfig - // A map of regions to AMI IDs. Amis map[string]string @@ -21,7 +21,7 @@ type Artifact struct { BuilderIdValue string // EC2 connection for performing API stuff. - Conn *ec2.EC2 + Session *session.Session } func (a *Artifact) BuilderId() string { @@ -69,11 +69,9 @@ func (a *Artifact) Destroy() error { for region, imageId := range a.Amis { log.Printf("Deregistering image ID (%s) from region (%s)", imageId, region) - session, err := a.AccessConfig.Session() - if err != nil { - return err - } - regionConn := ec2.New(session) + regionConn := ec2.New(a.Session, &aws.Config{ + Region: aws.String(region), + }) // Get image metadata imageResp, err := regionConn.DescribeImages(&ec2.DescribeImagesInput{ diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 89a388205..d3183c7a7 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" retry "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/packer" @@ -13,7 +14,6 @@ import ( ) type StepCreateTags struct { - AccessConfig *AccessConfig Tags map[string]string SnapshotTags map[string]string Ctx interpolate.Context @@ -21,6 +21,7 @@ type StepCreateTags struct { func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) + session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) @@ -36,22 +37,16 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { } // Adds tags to AMIs and snapshots - for ami := range amis { + for region, ami := range amis { ui.Say(fmt.Sprintf("Adding tags to AMI (%s)...", ami)) - // Declare list of resources to tag - session, err := s.AccessConfig.Session() - if err != nil { - err := fmt.Errorf("Error creating AWS session: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - regionconn := ec2.New(session) + regionConn := ec2.New(session, &aws.Config{ + Region: aws.String(region), + }) // Retrieve image list for given AMI resourceIds := []*string{&ami} - imageResp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ + imageResp, err := regionConn.DescribeImages(&ec2.DescribeImagesInput{ ImageIds: resourceIds, }) @@ -103,7 +98,7 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { // Retry creating tags for about 2.5 minutes err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { // Tag images and snapshots - _, err := regionconn.CreateTags(&ec2.CreateTagsInput{ + _, err := regionConn.CreateTags(&ec2.CreateTagsInput{ Resources: resourceIds, Tags: amiTags, }) @@ -116,7 +111,7 @@ func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { // Override tags on snapshots if len(snapshotTags) > 0 { - _, err = regionconn.CreateTags(&ec2.CreateTagsInput{ + _, err = regionConn.CreateTags(&ec2.CreateTagsInput{ Resources: snapshotIds, Tags: snapshotTags, }) diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index 3e86e5391..295d98ce9 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -23,6 +23,7 @@ type StepModifyAMIAttributes struct { func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) + session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) @@ -152,22 +153,13 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc // Modifying image attributes for region, ami := range amis { ui.Say(fmt.Sprintf("Modifying attributes on AMI (%s)...", ami)) - awsConfig := aws.Config{ - Credentials: ec2conn.Config.Credentials, - Region: aws.String(region), - } - session, err := session.NewSession(&awsConfig) - if err != nil { - err := fmt.Errorf("Error creating AWS session: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - regionconn := ec2.New(session) + regionConn := ec2.New(session, &aws.Config{ + Region: aws.String(region), + }) for name, input := range options { ui.Message(fmt.Sprintf("Modifying: %s", name)) input.ImageId = &ami - _, err := regionconn.ModifyImageAttribute(input) + _, err := regionConn.ModifyImageAttribute(input) if err != nil { err := fmt.Errorf("Error modify AMI attributes: %s", err) state.Put("error", err) @@ -181,16 +173,13 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc for region, region_snapshots := range snapshots { for _, snapshot := range region_snapshots { ui.Say(fmt.Sprintf("Modifying attributes on snapshot (%s)...", snapshot)) - awsConfig := aws.Config{ - Credentials: ec2conn.Config.Credentials, - Region: aws.String(region), - } - session := session.New(&awsConfig) - regionconn := ec2.New(session) + regionConn := ec2.New(session, &aws.Config{ + Region: aws.String(region), + }) for name, input := range snapshotOptions { ui.Message(fmt.Sprintf("Modifying: %s", name)) input.SnapshotId = &snapshot - _, err := regionconn.ModifySnapshotAttribute(input) + _, err := regionConn.ModifySnapshotAttribute(input) if err != nil { err := fmt.Errorf("Error modify snapshot attributes: %s", err) state.Put("error", err) diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 392162652..e22901a74 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -113,6 +113,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("ec2", ec2conn) + state.Put("awsSession", session) state.Put("hook", hook) state.Put("ui", ui) @@ -269,7 +270,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe artifact := &awscommon.Artifact{ Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, - Conn: ec2conn, + Session: session, } return artifact, nil diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 4831b8ba7..c622a4b73 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -127,6 +127,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state := new(multistep.BasicStateBag) state.Put("config", &b.config) state.Put("ec2", ec2conn) + state.Put("awsSession", session) state.Put("hook", hook) state.Put("ui", ui) @@ -283,7 +284,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe artifact := &awscommon.Artifact{ Amis: amis.(map[string]string), BuilderIdValue: BuilderId, - Conn: ec2conn, + Session: session, } return artifact, nil diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 59c329515..776f4fc67 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -198,6 +198,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe state := new(multistep.BasicStateBag) state.Put("config", &b.config) state.Put("ec2", ec2conn) + state.Put("awsSession", session) state.Put("hook", hook) state.Put("ui", ui) @@ -341,7 +342,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe artifact := &awscommon.Artifact{ Amis: state.Get("amis").(map[string]string), BuilderIdValue: BuilderId, - Conn: ec2conn, + Session: session, } return artifact, nil diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index c9cbd2077..90e87d6c7 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -369,7 +369,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac *config.Region: createdami, }, BuilderIdValue: BuilderId, - Conn: ec2conn, + Session: session, } if !p.config.SkipClean { From 93d201828cbac3d7bd07b8a34cc6f578cc7c46a3 Mon Sep 17 00:00:00 2001 From: Lance Lafontaine <lancelafontaine@protonmail.com> Date: Tue, 19 Dec 2017 19:29:39 -0500 Subject: [PATCH 0329/1007] Corrects small typo in amazon-* builder docs --- website/source/docs/builders/amazon-chroot.html.md | 2 +- website/source/docs/builders/amazon-ebs.html.md | 2 +- website/source/docs/builders/amazon-ebssurrogate.html.md | 2 +- website/source/docs/builders/amazon-ebsvolume.html.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 64d966a4d..a983305c2 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -255,7 +255,7 @@ each category, the available configuration keys are alphabetized. - `snapshot_groups` (array of strings) - A list of groups that have access to create volumes from the snapshot(s). By default no groups have permission to create - volumes form the snapshot(s). `all` will make the snapshot publicly accessible. + volumes from the snapshot(s). `all` will make the snapshot publicly accessible. - `snapshot_users` (array of strings) - A list of account IDs that have access to create volumes from the snapshot(s). By default no additional users other than the diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index c050cd070..02fa0ae2f 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -249,7 +249,7 @@ builder. - `snapshot_groups` (array of strings) - A list of groups that have access to create volumes from the snapshot(s). By default no groups have permission to create - volumes form the snapshot(s). `all` will make the snapshot publicly accessible. + volumes from the snapshot(s). `all` will make the snapshot publicly accessible. - `snapshot_users` (array of strings) - A list of account IDs that have access to create volumes from the snapshot(s). By default no additional users other than the diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 640710230..4e94362df 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -242,7 +242,7 @@ builder. - `snapshot_groups` (array of strings) - A list of groups that have access to create volumes from the snapshot(s). By default no groups have permission to create - volumes form the snapshot(s). `all` will make the snapshot publicly accessible. + volumes from the snapshot(s). `all` will make the snapshot publicly accessible. - `snapshot_users` (array of strings) - A list of account IDs that have access to create volumes from the snapshot(s). By default no additional users other than the diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 2b92c6b44..b77dc0571 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -161,7 +161,7 @@ builder. - `snapshot_groups` (array of strings) - A list of groups that have access to create volumes from the snapshot(s). By default no groups have permission to create - volumes form the snapshot(s). `all` will make the snapshot publicly accessible. + volumes from the snapshot(s). `all` will make the snapshot publicly accessible. - `snapshot_users` (array of strings) - A list of account IDs that have access to create volumes from the snapshot(s). By default no additional users other than the From f0580c6f3aa2b501736a32cd883eb13a3ba5d80f Mon Sep 17 00:00:00 2001 From: Davor Kapsa <davor.kapsa@gmail.com> Date: Wed, 20 Dec 2017 15:36:02 +0100 Subject: [PATCH 0330/1007] travis: update 1.7 and 1.8 go versions .x match latest patch --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 146d5858c..755c0ef8f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ sudo: false language: go go: - - 1.7.4 - - 1.8.3 + - 1.7.x + - 1.8.x - 1.x install: From 93c2f2ec93b5569752109ef5a0ff575a76d32a67 Mon Sep 17 00:00:00 2001 From: Malet <michael@nervd.com> Date: Thu, 21 Dec 2017 17:24:04 +0000 Subject: [PATCH 0331/1007] Improve vmware-iso disk_type_id documentation Referring to the vmware documentation might be more "correct", but having the options listed will make the available options much clearer. --- website/source/docs/builders/vmware-iso.html.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 343a685ef..fd56a475f 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -110,10 +110,16 @@ builder. - `disk_type_id` (string) - The type of VMware virtual disk to create. The default is "1", which corresponds to a growable virtual disk split in 2GB files. For ESXi, this defaults to "zeroedthick". This option is for - advanced usage. For more information, please consult the [Virtual Disk - Manager User's Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) - for desktop VMware clients. For ESXi, refer to the proper ESXi - documentation. + advanced usage. For ESXi the available options are: `zeroedthick`, `eagerzeroedthick`, `thin`, `rdm:dev`, `rdmp:dev`, `2gbsparse`. For desktop VMware clients: + + Type ID | Description + --- | --- + `0` | Growable virtual disk contained in a single file (monolithic sparse). + `1` | Growable virtual disk split into 2GB files (split sparse). + `2` | Preallocated virtual disk contained in a single file (monolithic flat). + `3` | Preallocated virtual disk split into 2GB files (split flat). + `4` | Preallocated virtual disk compatible with ESX server (VMFS flat). + `5` | Compressed disk optimized for streaming. * `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. From e47bd659865bb82b02fa992476e487eabedbf768 Mon Sep 17 00:00:00 2001 From: Sean Malloy <spinelli85@gmail.com> Date: Sat, 23 Dec 2017 00:13:17 -0600 Subject: [PATCH 0332/1007] Add vagrant post-processor support for Google Add the ability to create Google vagrant boxes using the vagrant post-processor. The Google plugin for vagrant is linked below. https://github.com/mitchellh/vagrant-google --- post-processor/vagrant/google.go | 42 +++++++++++++++++++ post-processor/vagrant/post-processor.go | 3 ++ .../docs/post-processors/vagrant.html.md | 5 ++- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 post-processor/vagrant/google.go diff --git a/post-processor/vagrant/google.go b/post-processor/vagrant/google.go new file mode 100644 index 000000000..a4d9dbf48 --- /dev/null +++ b/post-processor/vagrant/google.go @@ -0,0 +1,42 @@ +package vagrant + +import ( + "bytes" + "text/template" + + "github.com/hashicorp/packer/packer" +) + +type googleVagrantfileTemplate struct { + Image string "" +} + +type GoogleProvider struct{} + +func (p *GoogleProvider) KeepInputArtifact() bool { + return true +} + +func (p *GoogleProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + // Create the metadata + metadata = map[string]interface{}{"provider": "google"} + + // Build up the template data to build our Vagrantfile + tplData := &googleVagrantfileTemplate{} + tplData.Image = artifact.Id() + + // Build up the Vagrantfile + var contents bytes.Buffer + t := template.Must(template.New("vf").Parse(defaultGoogleVagrantfile)) + err = t.Execute(&contents, tplData) + vagrantfile = contents.String() + return +} + +var defaultGoogleVagrantfile = ` +Vagrant.configure("2") do |config| + config.vm.provider :google do |google| + google.image = "{{ .Image }}" + end +end +` diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index aa65b2292..310270809 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -25,6 +25,7 @@ var builtins = map[string]string{ "mitchellh.vmware": "vmware", "mitchellh.vmware-esx": "vmware", "pearkes.digitalocean": "digitalocean", + "packer.googlecompute": "google", "packer.parallels": "parallels", "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", @@ -232,6 +233,8 @@ func providerForName(name string) Provider { return new(HypervProvider) case "libvirt": return new(LibVirtProvider) + case "google": + return new(GoogleProvider) default: return nil } diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index 5f0a9bc50..8feabbbbf 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -32,6 +32,7 @@ providers. - AWS - DigitalOcean +- Google - Hyper-V - Parallels - QEMU @@ -100,8 +101,8 @@ Specify overrides within the `override` configuration by provider name: In the example above, the compression level will be set to 1 except for VMware, where it will be set to 0. -The available provider names are: `aws`, `digitalocean`, `virtualbox`, `vmware`, -and `parallels`. +The available provider names are: `aws`, `digitalocean`, `google`, `virtualbox`, +`vmware`, and `parallels`. ## Input Artifacts From e8bac9f4c8f52650827e9406e3bf2a8b89dffdb4 Mon Sep 17 00:00:00 2001 From: Sean Malloy <spinelli85@gmail.com> Date: Sat, 23 Dec 2017 23:46:30 -0600 Subject: [PATCH 0333/1007] Add unit tests for new vagrant Google post-processor --- post-processor/vagrant/google_test.go | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 post-processor/vagrant/google_test.go diff --git a/post-processor/vagrant/google_test.go b/post-processor/vagrant/google_test.go new file mode 100644 index 000000000..a66be8539 --- /dev/null +++ b/post-processor/vagrant/google_test.go @@ -0,0 +1,36 @@ +package vagrant + +import ( + "github.com/hashicorp/packer/packer" + "strings" + "testing" +) + +func TestGoogleProvider_impl(t *testing.T) { + var _ Provider = new(GoogleProvider) +} + +func TestGoogleProvider_KeepInputArtifact(t *testing.T) { + p := new(GoogleProvider) + + if !p.KeepInputArtifact() { + t.Fatal("should keep input artifact") + } +} + +func TestGoogleProvider_ArtifactId(t *testing.T) { + p := new(GoogleProvider) + ui := testUi() + artifact := &packer.MockArtifact{ + IdValue: "packer-1234", + } + + vagrantfile, _, err := p.Process(ui, artifact, "foo") + if err != nil { + t.Fatalf("should not have error: %s", err) + } + result := `google.image = "packer-1234"` + if !strings.Contains(vagrantfile, result) { + t.Fatalf("wrong substitution: %s", vagrantfile) + } +} From d47d3d8a5007039495de94d4b62a9a5e8b385732 Mon Sep 17 00:00:00 2001 From: Rickard von Essen <rickard.von.essen@gmail.com> Date: Tue, 26 Dec 2017 08:09:25 +0100 Subject: [PATCH 0334/1007] Updated CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0b095d29..114e5a910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,12 +12,14 @@ * builder/azure: Add sanity checks for resource group names [GH-5599] * builder/azure: Allow users to specify an existing resource group to use, instead of creating a new one for every run. [GH-5548] +* builder/docker: Remove credentials from being shown in the log. [GH-5666] * builder/hyper-v: Add support for differencing disk. [GH-5458] * builder/vmware-iso: Improve logging of network errors. [GH-5456] * core: Add new `packer_version` template engine. [GH-5619] * core: Improve logic checking for downloaded ISOs in case where user has provided more than one URL in `iso_urls` [GH-5632] * provisioner/ansible-local: Add ability to clean staging directory. [GH-5618] +* post-processor/docker: Remove credentials from being shown in the log. [GH-5666] ### BUG FIXES: From ab69f619e552e4a2cbfdf1209365bcaf32a4fa1b Mon Sep 17 00:00:00 2001 From: Rickard von Essen <rickard.von.essen@gmail.com> Date: Wed, 27 Dec 2017 09:56:33 +0100 Subject: [PATCH 0335/1007] Fixed CHANGELOG.md --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 114e5a910..5ee5c5f4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## (UNRELEASED) +### IMPROVEMENTS: + +* builder/docker: Remove credentials from being shown in the log. [GH-5666] +* post-processor/docker: Remove credentials from being shown in the log. [GH-5666] ## 1.1.3 (December 8, 2017) @@ -12,14 +16,12 @@ * builder/azure: Add sanity checks for resource group names [GH-5599] * builder/azure: Allow users to specify an existing resource group to use, instead of creating a new one for every run. [GH-5548] -* builder/docker: Remove credentials from being shown in the log. [GH-5666] * builder/hyper-v: Add support for differencing disk. [GH-5458] * builder/vmware-iso: Improve logging of network errors. [GH-5456] * core: Add new `packer_version` template engine. [GH-5619] * core: Improve logic checking for downloaded ISOs in case where user has provided more than one URL in `iso_urls` [GH-5632] * provisioner/ansible-local: Add ability to clean staging directory. [GH-5618] -* post-processor/docker: Remove credentials from being shown in the log. [GH-5666] ### BUG FIXES: From 7250c4f7f05945e2bb25f6e7e6bd0dd0e81b2028 Mon Sep 17 00:00:00 2001 From: Glenn McDonald <glenn.mcdonald@iress.com.au> Date: Fri, 29 Dec 2017 11:51:57 +1100 Subject: [PATCH 0336/1007] Add Intel HAXM support to QEMU builder --- builder/qemu/builder.go | 3 ++- website/source/docs/builders/qemu.html.md | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 43ec6b4c3..d2cda5d98 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -25,6 +25,7 @@ var accels = map[string]struct{}{ "kvm": {}, "tcg": {}, "xen": {}, + "hax": {}, } var netDevice = map[string]bool{ @@ -259,7 +260,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { if _, ok := accels[b.config.Accelerator]; !ok { errs = packer.MultiErrorAppend( - errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed")) + errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', 'hax', or 'none' are allowed")) } if _, ok := netDevice[b.config.NetDevice]; !ok { diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index f3de7cf9c..e57cc15bb 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -110,9 +110,9 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). ### Optional: - `accelerator` (string) - The accelerator type to use when running the VM. - This may be `none`, `kvm`, `tcg`, or `xen`. The appropriate software must - already been installed on your build machine to use the accelerator you - specified. When no accelerator is specified, Packer will try to use `kvm` + This may be `none`, `kvm`, `tcg`, `hax`, or `xen`. The appropriate software + must have already been installed on your build machine to use the accelerator + you specified. When no accelerator is specified, Packer will try to use `kvm` if it is available but will default to `tcg` otherwise. - `boot_command` (array of strings) - This is an array of commands to type From a90376f12a39248f34341f4513eda570a11676bf Mon Sep 17 00:00:00 2001 From: QuantumGhost <obelisk.reg+github@gmail.com> Date: Fri, 29 Dec 2017 10:03:55 +0800 Subject: [PATCH 0337/1007] Attach keypair before starting instance in alicloud builder [Documentation of `AttachKeyPair`](https://goo.gl/gC3srG) states that attaching keypair to running instance takes effect after reboot. So we need to attach keypair before starting instance to avoid an additional restart. --- builder/alicloud/ecs/builder.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder/alicloud/ecs/builder.go b/builder/alicloud/ecs/builder.go index 8650dc2d1..5f7973723 100644 --- a/builder/alicloud/ecs/builder.go +++ b/builder/alicloud/ecs/builder.go @@ -6,6 +6,7 @@ import ( "log" "fmt" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" @@ -146,9 +147,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }) } steps = append(steps, + &stepAttachKeyPar{}, &stepRunAlicloudInstance{}, &stepMountAlicloudDisk{}, - &stepAttachKeyPar{}, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, Host: SSHHost( From 4e1beb009c3c13fc15fd17b9be477ed9956389e7 Mon Sep 17 00:00:00 2001 From: zhuzhih2017 <dongxiao.zzh@alibaba-inc.com> Date: Fri, 29 Dec 2017 15:11:18 +0800 Subject: [PATCH 0338/1007] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ee5c5f4f..7476b23b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ * builder/docker: Remove credentials from being shown in the log. [GH-5666] * post-processor/docker: Remove credentials from being shown in the log. [GH-5666] +### BUG FIXES: +* builder/alicloud-ecs: Attach keypair before starting instance in alicloud builder [GH-5739] + ## 1.1.3 (December 8, 2017) ### IMPROVEMENTS: From c3467b686ceeca7b6955db18195e01467c4276e5 Mon Sep 17 00:00:00 2001 From: stack72 <public@paulstack.co.uk> Date: Fri, 29 Dec 2017 15:00:47 +0200 Subject: [PATCH 0339/1007] builder/triton: Add support for Triton RBAC Fixes: #5737 Triton allows for subusers to be granted access to your account. This PR allows a user to be specified --- builder/triton/access_config.go | 19 ++- .../github.com/joyent/triton-go/CHANGELOG.md | 58 +++++++ .../github.com/joyent/triton-go/GNUmakefile | 47 ++++++ vendor/github.com/joyent/triton-go/Gopkg.lock | 39 +++++ vendor/github.com/joyent/triton-go/Gopkg.toml | 42 +++++ vendor/github.com/joyent/triton-go/README.md | 89 ++++++---- .../joyent/triton-go/authentication/dummy.go | 72 ++++++++ .../authentication/private_key_signer.go | 31 +++- .../authentication/ssh_agent_signer.go | 74 ++++++--- .../triton-go/authentication/test_signer.go | 27 +++ .../joyent/triton-go/client/client.go | 137 ++++++++++----- .../joyent/triton-go/compute/client.go | 8 +- .../joyent/triton-go/compute/datacenters.go | 2 +- .../joyent/triton-go/compute/errors.go | 6 + .../joyent/triton-go/compute/instances.go | 33 +++- .../joyent/triton-go/compute/ping.go | 56 +++++++ .../joyent/triton-go/compute/snapshots.go | 157 ++++++++++++++++++ .../joyent/triton-go/network/firewall.go | 55 +++++- vendor/github.com/joyent/triton-go/triton.go | 1 + vendor/vendor.json | 30 ++-- website/source/docs/builders/triton.html.md | 5 +- 21 files changed, 854 insertions(+), 134 deletions(-) create mode 100644 vendor/github.com/joyent/triton-go/CHANGELOG.md create mode 100644 vendor/github.com/joyent/triton-go/GNUmakefile create mode 100644 vendor/github.com/joyent/triton-go/Gopkg.lock create mode 100644 vendor/github.com/joyent/triton-go/Gopkg.toml create mode 100644 vendor/github.com/joyent/triton-go/authentication/dummy.go create mode 100644 vendor/github.com/joyent/triton-go/authentication/test_signer.go create mode 100644 vendor/github.com/joyent/triton-go/compute/ping.go create mode 100644 vendor/github.com/joyent/triton-go/compute/snapshots.go diff --git a/builder/triton/access_config.go b/builder/triton/access_config.go index 2df0ed150..3212c37a1 100644 --- a/builder/triton/access_config.go +++ b/builder/triton/access_config.go @@ -19,6 +19,7 @@ import ( type AccessConfig struct { Endpoint string `mapstructure:"triton_url"` Account string `mapstructure:"triton_account"` + Username string `mapstructure:"triton_user"` KeyID string `mapstructure:"triton_key_id"` KeyMaterial string `mapstructure:"triton_key_material"` @@ -65,7 +66,12 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { } func (c *AccessConfig) createSSHAgentSigner() (authentication.Signer, error) { - signer, err := authentication.NewSSHAgentSigner(c.KeyID, c.Account) + 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) } @@ -94,8 +100,14 @@ func (c *AccessConfig) createPrivateKeySigner() (authentication.Signer, error) { } } - // Create signer - signer, err := authentication.NewPrivateKeySigner(c.KeyID, privateKeyMaterial, c.Account) + 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) } @@ -114,6 +126,7 @@ func (c *AccessConfig) CreateTritonClient() (*Client, error) { config := &tgo.ClientConfig{ AccountName: c.Account, TritonURL: c.Endpoint, + Username: c.Username, Signers: []authentication.Signer{c.signer}, } diff --git a/vendor/github.com/joyent/triton-go/CHANGELOG.md b/vendor/github.com/joyent/triton-go/CHANGELOG.md new file mode 100644 index 000000000..c0d740998 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/CHANGELOG.md @@ -0,0 +1,58 @@ +## Unreleased + +## 0.5.2 (December 28) + +- Standardise the API SSH Signers input casing and naming + +## 0.5.1 (December 28) + +- Include leading '/' when working with SSH Agent signers + +## 0.5.0 (December 28) + +- Add support for RBAC in triton-go [#82] +This is a breaking change. No longer do we pass individual parameters to the SSH Signer funcs, but we now pass an input Struct. This will guard from from additional parameter changes in the future. +We also now add support for using `SDC_*` and `TRITON_*` env vars when working with the Default agent signer + +## 0.4.2 (December 22) + +- Fixing a panic when the user loses network connectivity when making a GET request to instance [#81] + +## 0.4.1 (December 15) + +- Clean up the handling of directory sanitization. Use abs paths everywhere [#79] + +## 0.4.0 (December 15) + +- Fix an issue where Manta HEAD requests do not return an error resp body [#77] +- Add support for recursively creating child directories [#78] + +## 0.3.0 (December 14) + +- Introduce CloudAPI's ListRulesMachines under networking +- Enable HTTP KeepAlives by default in the client. 15s idle timeout, 2x + connections per host, total of 10x connections per client. +- Expose an optional Headers attribute to clients to allow them to customize + HTTP headers when making Object requests. +- Fix a bug in Directory ListIndex [#69](https://github.com/joyent/issues/69) +- Inputs to Object inputs have been relaxed to `io.Reader` (formerly a + `io.ReadSeeker`) [#73](https://github.com/joyent/issues/73). +- Add support for ForceDelete of all children of a directory [#71](https://github.com/joyent/issues/71) +- storage: Introduce `Objects.GetInfo` and `Objects.IsDir` using HEAD requests [#74](https://github.com/joyent/triton-go/issues/74) + +## 0.2.1 (November 8) + +- Fixing a bug where CreateUser and UpdateUser didn't return the UserID + +## 0.2.0 (November 7) + +- Introduce CloudAPI's Ping under compute +- Introduce CloudAPI's RebootMachine under compute instances +- Introduce CloudAPI's ListUsers, GetUser, CreateUser, UpdateUser and DeleteUser under identity package +- Introduce CloudAPI's ListMachineSnapshots, GetMachineSnapshot, CreateSnapshot, DeleteMachineSnapshot and StartMachineFromSnapshot under compute package +- tools: Introduce unit testing and scripts for linting, etc. +- bug: Fix the `compute.ListMachineRules` endpoint + +## 0.1.0 (November 2) + +- Initial release of a versioned SDK diff --git a/vendor/github.com/joyent/triton-go/GNUmakefile b/vendor/github.com/joyent/triton-go/GNUmakefile new file mode 100644 index 000000000..cca7f6759 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/GNUmakefile @@ -0,0 +1,47 @@ +TEST?=$$(go list ./... |grep -Ev 'vendor|examples|testutils') +GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) + +default: vet errcheck test + +tools:: ## Download and install all dev/code tools + @echo "==> Installing dev tools" + go get -u github.com/golang/dep/cmd/dep + go get -u github.com/golang/lint/golint + go get -u github.com/kisielk/errcheck + @echo "==> Installing test package dependencies" + go test -i $(TEST) || exit 1 + +test:: ## Run unit tests + @echo "==> Running unit tests" + @echo $(TEST) | \ + xargs -t go test -v $(TESTARGS) -timeout=30s -parallel=1 | grep -Ev 'TRITON_TEST|TestAcc' + +testacc:: ## Run acceptance tests + @echo "==> Running acceptance tests" + TRITON_TEST=1 go test $(TEST) -v $(TESTARGS) -run -timeout 120m + +vet:: ## Check for unwanted code constructs + @echo "go vet ." + @go vet $$(go list ./... | grep -v vendor/) ; if [ $$? -eq 1 ]; then \ + echo ""; \ + echo "Vet found suspicious constructs. Please check the reported constructs"; \ + echo "and fix them if necessary before submitting the code for review."; \ + exit 1; \ + fi + +lint:: ## Lint and vet code by common Go standards + @bash $(CURDIR)/scripts/lint.sh + +fmt:: ## Format as canonical Go code + gofmt -w $(GOFMT_FILES) + +fmtcheck:: ## Check if code format is canonical Go + @bash $(CURDIR)/scripts/gofmtcheck.sh + +errcheck:: ## Check for unhandled errors + @bash $(CURDIR)/scripts/errcheck.sh + +.PHONY: help +help:: ## Display this help message + @echo "GNU make(1) targets:" + @grep -E '^[a-zA-Z_.-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' diff --git a/vendor/github.com/joyent/triton-go/Gopkg.lock b/vendor/github.com/joyent/triton-go/Gopkg.lock new file mode 100644 index 000000000..b61936ad3 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/Gopkg.lock @@ -0,0 +1,39 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "github.com/abdullin/seq" + packages = ["."] + revision = "d5467c17e7afe8d8f08f556c6c811a50c3feb28d" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/errwrap" + packages = ["."] + revision = "7554cd9344cec97297fa6649b055a8c98c2a1e55" + +[[projects]] + branch = "master" + name = "github.com/sean-/seed" + packages = ["."] + revision = "e2103e2c35297fb7e17febb81e49b312087a2372" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["curve25519","ed25519","ed25519/internal/edwards25519","ssh","ssh/agent"] + revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "28853a8970ee33112a9e7998b18e658bed04d177537ec69db678189f0b8a9a7d" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/joyent/triton-go/Gopkg.toml b/vendor/github.com/joyent/triton-go/Gopkg.toml new file mode 100644 index 000000000..3b85ddf9b --- /dev/null +++ b/vendor/github.com/joyent/triton-go/Gopkg.toml @@ -0,0 +1,42 @@ + +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + + +[[constraint]] + branch = "master" + name = "github.com/abdullin/seq" + +[[constraint]] + name = "github.com/davecgh/go-spew" + version = "1.1.0" + +[[constraint]] + branch = "master" + name = "github.com/hashicorp/errwrap" + +[[constraint]] + branch = "master" + name = "github.com/sean-/seed" + +[[constraint]] + branch = "master" + name = "golang.org/x/crypto" diff --git a/vendor/github.com/joyent/triton-go/README.md b/vendor/github.com/joyent/triton-go/README.md index 1089c72da..5dbd5de0f 100644 --- a/vendor/github.com/joyent/triton-go/README.md +++ b/vendor/github.com/joyent/triton-go/README.md @@ -3,6 +3,8 @@ `triton-go` is an idiomatic library exposing a client SDK for Go applications using Joyent's Triton Compute and Storage (Manta) APIs. +[![Build Status](https://travis-ci.org/joyent/triton-go.svg?branch=master)](https://travis-ci.org/joyent/triton-go) [![Go Report Card](https://goreportcard.com/badge/github.com/joyent/triton-go)](https://goreportcard.com/report/github.com/joyent/triton-go) + ## Usage Triton uses [HTTP Signature][4] to sign the Date header in each HTTP request @@ -13,11 +15,17 @@ using a key stored with the local SSH Agent (using an [`SSHAgentSigner`][6]. To construct a Signer, use the `New*` range of methods in the `authentication` package. In the case of `authentication.NewSSHAgentSigner`, the parameters are the fingerprint of the key with which to sign, and the account name (normally -stored in the `SDC_ACCOUNT` environment variable). For example: +stored in the `TRITON_ACCOUNT` environment variable). There is also support for +passing in a username, this will allow you to use an account other than the main +Triton account. For example: -``` -const fingerprint := "a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11" -sshKeySigner, err := authentication.NewSSHAgentSigner(fingerprint, "AccountName") +```go +input := authentication.SSHAgentSignerInput{ + KeyID: "a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11", + AccountName: "AccountName", + Username: "Username", +} +sshKeySigner, err := authentication.NewSSHAgentSigner(input) if err != nil { log.Fatalf("NewSSHAgentSigner: %s", err) } @@ -34,17 +42,18 @@ their own seperate client. In order to initialize a package client, simply pass the global `triton.ClientConfig` struct into the client's constructor function. ```go - config := &triton.ClientConfig{ - TritonURL: os.Getenv("SDC_URL"), - MantaURL: os.Getenv("MANTA_URL"), - AccountName: accountName, - Signers: []authentication.Signer{sshKeySigner}, - } +config := &triton.ClientConfig{ + TritonURL: os.Getenv("TRITON_URL"), + MantaURL: os.Getenv("MANTA_URL"), + AccountName: accountName, + Username: os.Getenv("TRITON_USER"), + Signers: []authentication.Signer{sshKeySigner}, +} - c, err := compute.NewClient(config) - if err != nil { - log.Fatalf("compute.NewClient: %s", err) - } +c, err := compute.NewClient(config) +if err != nil { + log.Fatalf("compute.NewClient: %s", err) +} ``` Constructing `compute.Client` returns an interface which exposes `compute` API @@ -55,10 +64,10 @@ The same `triton.ClientConfig` will initialize the Manta `storage` client as well... ```go - c, err := storage.NewClient(config) - if err != nil { - log.Fatalf("storage.NewClient: %s", err) - } +c, err := storage.NewClient(config) +if err != nil { + log.Fatalf("storage.NewClient: %s", err) +} ``` ## Error Handling @@ -79,13 +88,14 @@ set: - `TRITON_TEST` - must be set to any value in order to indicate desire to create resources -- `SDC_URL` - the base endpoint for the Triton API -- `SDC_ACCOUNT` - the account name for the Triton API -- `SDC_KEY_ID` - the fingerprint of the SSH key identifying the key +- `TRITON_URL` - the base endpoint for the Triton API +- `TRITON_ACCOUNT` - the account name for the Triton API +- `TRITON_KEY_ID` - the fingerprint of the SSH key identifying the key -Additionally, you may set `SDC_KEY_MATERIAL` to the contents of an unencrypted +Additionally, you may set `TRITON_KEY_MATERIAL` to the contents of an unencrypted private key. If this is set, the PrivateKeySigner (see above) will be used - if -not the SSHAgentSigner will be used. +not the SSHAgentSigner will be used. You can also set `TRITON_USER` to run the tests +against an account other than the main Triton account ### Example Run @@ -94,9 +104,9 @@ The verbose output has been removed for brevity here. ``` $ HTTP_PROXY=http://localhost:8888 \ TRITON_TEST=1 \ - SDC_URL=https://us-sw-1.api.joyent.com \ - SDC_ACCOUNT=AccountName \ - SDC_KEY_ID=a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11 \ + TRITON_URL=https://us-sw-1.api.joyent.com \ + TRITON_ACCOUNT=AccountName \ + TRITON_KEY_ID=a4:c6:f3:75:80:27:e0:03:a9:98:79:ef:c5:0a:06:11 \ go test -v -run "TestAccKey" === RUN TestAccKey_Create --- PASS: TestAccKey_Create (12.46s) @@ -116,7 +126,7 @@ referencing your SSH key file use by your active `triton` CLI profile. ```sh $ eval "$(triton env us-sw-1)" -$ SDC_KEY_FILE=~/.ssh/triton-id_rsa go run examples/compute/instances.go +$ TRITON_KEY_FILE=~/.ssh/triton-id_rsa go run examples/compute/instances.go ``` The following is a complete example of how to initialize the `compute` package @@ -142,15 +152,21 @@ import ( ) func main() { - keyID := os.Getenv("SDC_KEY_ID") - accountName := os.Getenv("SDC_ACCOUNT") - keyMaterial := os.Getenv("SDC_KEY_MATERIAL") + keyID := os.Getenv("TRITON_KEY_ID") + accountName := os.Getenv("TRITON_ACCOUNT") + keyMaterial := os.Getenv("TRITON_KEY_MATERIAL") + userName := os.Getenv("TRITON_USER") var signer authentication.Signer var err error if keyMaterial == "" { - signer, err = authentication.NewSSHAgentSigner(keyID, accountName) + input := authentication.SSHAgentSignerInput{ + KeyID: keyID, + AccountName: accountName, + Username: userName, + } + signer, err = authentication.NewSSHAgentSigner(input) if err != nil { log.Fatalf("Error Creating SSH Agent Signer: {{err}}", err) } @@ -178,15 +194,22 @@ func main() { keyBytes = []byte(keyMaterial) } - signer, err = authentication.NewPrivateKeySigner(keyID, []byte(keyMaterial), accountName) + input := authentication.PrivateKeySignerInput{ + KeyID: keyID, + PrivateKeyMaterial: keyBytes, + AccountName: accountName, + Username: userName, + } + signer, err = authentication.NewPrivateKeySigner(input) if err != nil { log.Fatalf("Error Creating SSH Private Key Signer: {{err}}", err) } } config := &triton.ClientConfig{ - TritonURL: os.Getenv("SDC_URL"), + TritonURL: os.Getenv("TRITON_URL"), AccountName: accountName, + Username: userName, Signers: []authentication.Signer{signer}, } diff --git a/vendor/github.com/joyent/triton-go/authentication/dummy.go b/vendor/github.com/joyent/triton-go/authentication/dummy.go new file mode 100644 index 000000000..cd16273b6 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/authentication/dummy.go @@ -0,0 +1,72 @@ +package authentication + +// DON'T USE THIS OUTSIDE TESTING ~ This key was only created to use for +// internal unit testing. It should never be used for acceptance testing either. +// +// This is just a randomly generated key pair. +var Dummy = struct { + Fingerprint string + PrivateKey []byte + PublicKey []byte + Signer Signer +}{ + "9f:d6:65:fc:d6:60:dc:d0:4e:db:2d:75:f7:92:8c:31", + []byte(`-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY-----`), + []byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6L2U2MIlqEd4VIULodeL8I1fnzwL8vaAlTHrluc2mFUL3yFbXDOhG89cfHlpadvuURuk2E/oHRSgIENNo+C32Ed8P+g1D7odPVCkMgZ9mZcj3X+1yMZVIFvE3tZpi38ew+saNtqXC9A8KE3newxWYWQxMQNHkbfM4E4Aas6KaUJPzTAjZLleDSyl3yOMozkjWzANHTG24NacdNHU6GKf6kRAgTqCUtN9iruhDHqeYxdcE2aT5Jo8PUUDKOQX/zWKbYQdcHKA0TCtpWsNwDEraYqVTZcwmKiBAo1haWbdSRs0HpY8t7Xb4prTauYhWxKoilz9kIGtoCUJpJaVgKRT68naEf/7KnLltc2VtpOJZkr6+4js8LztPnTIs15dW41kDKfMOkEK+yOKIesH9kVF9V8Xo++JXwJX6bsZPN8DAmFV5JuWtHqe2zXorQdMPjy/nsNTRvS3lU68LtxY9KGz5p91IvdnxF4vkRYyBTXB++3JxEp6GINUaPcyzZx/zdEgA2vfzsb7UtxNBg/skm4HtK/LmP5Hr4eMjRyC7gQxQ91Z8I0YbKuXHAk20+ZRJ9qwfXFQqmqvt0L7Sw3j+B8nDvlZMBisBOQ/N7Ghg1oywYN+G6iGRhrdOfarWDeSqGxf9HQV3l3x3mpzXfupxELGJljP1/dtWRdBuFiY711rcqw== test-dummy-20171002140848`), + nil, +} + +func init() { + testSigner, _ := NewTestSigner() + Dummy.Signer = testSigner +} diff --git a/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go b/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go index 43bc286f0..35abff0f6 100644 --- a/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go @@ -9,6 +9,7 @@ import ( "encoding/pem" "errors" "fmt" + "path" "strings" "github.com/hashicorp/errwrap" @@ -20,15 +21,23 @@ type PrivateKeySigner struct { keyFingerprint string algorithm string accountName string + userName string hashFunc crypto.Hash privateKey *rsa.PrivateKey } -func NewPrivateKeySigner(keyFingerprint string, privateKeyMaterial []byte, accountName string) (*PrivateKeySigner, error) { - keyFingerprintMD5 := strings.Replace(keyFingerprint, ":", "", -1) +type PrivateKeySignerInput struct { + KeyID string + PrivateKeyMaterial []byte + AccountName string + Username string +} - block, _ := pem.Decode(privateKeyMaterial) +func NewPrivateKeySigner(input PrivateKeySignerInput) (*PrivateKeySigner, error) { + keyFingerprintMD5 := strings.Replace(input.KeyID, ":", "", -1) + + block, _ := pem.Decode(input.PrivateKeyMaterial) if block == nil { return nil, errors.New("Error PEM-decoding private key material: nil block received") } @@ -51,13 +60,17 @@ func NewPrivateKeySigner(keyFingerprint string, privateKeyMaterial []byte, accou signer := &PrivateKeySigner{ formattedKeyFingerprint: displayKeyFingerprint, - keyFingerprint: keyFingerprint, - accountName: accountName, + keyFingerprint: input.KeyID, + accountName: input.AccountName, hashFunc: crypto.SHA1, privateKey: rsakey, } + if input.Username != "" { + signer.userName = input.Username + } + _, algorithm, err := signer.SignRaw("HelloWorld") if err != nil { return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err) @@ -80,7 +93,13 @@ func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) { } signedBase64 := base64.StdEncoding.EncodeToString(signed) - keyID := fmt.Sprintf("/%s/keys/%s", s.accountName, s.formattedKeyFingerprint) + var keyID string + if s.userName != "" { + + keyID = path.Join("/", s.accountName, "users", s.userName, "keys", s.formattedKeyFingerprint) + } else { + keyID = path.Join("/", s.accountName, "keys", s.formattedKeyFingerprint) + } return fmt.Sprintf(authorizationHeaderFormat, keyID, "rsa-sha1", headerName, signedBase64), nil } diff --git a/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go b/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go index ea84c5070..c068dae27 100644 --- a/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go @@ -8,6 +8,7 @@ import ( "fmt" "net" "os" + "path" "strings" "github.com/hashicorp/errwrap" @@ -15,21 +16,32 @@ import ( "golang.org/x/crypto/ssh/agent" ) +var ( + ErrUnsetEnvVar = errors.New("SSH_AUTH_SOCK is not set") +) + type SSHAgentSigner struct { formattedKeyFingerprint string keyFingerprint string algorithm string accountName string + userName string keyIdentifier string agent agent.Agent key ssh.PublicKey } -func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, error) { - sshAgentAddress := os.Getenv("SSH_AUTH_SOCK") - if sshAgentAddress == "" { - return nil, errors.New("SSH_AUTH_SOCK is not set") +type SSHAgentSignerInput struct { + KeyID string + AccountName string + Username string +} + +func NewSSHAgentSigner(input SSHAgentSignerInput) (*SSHAgentSigner, error) { + sshAgentAddress, agentOk := os.LookupEnv("SSH_AUTH_SOCK") + if !agentOk { + return nil, ErrUnsetEnvVar } conn, err := net.Dial("unix", sshAgentAddress) @@ -39,12 +51,41 @@ func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, err ag := agent.NewClient(conn) - keys, err := ag.List() + signer := &SSHAgentSigner{ + keyFingerprint: input.KeyID, + accountName: input.AccountName, + agent: ag, + } + + matchingKey, err := signer.MatchKey() + if err != nil { + return nil, err + } + signer.key = matchingKey + signer.formattedKeyFingerprint = formatPublicKeyFingerprint(signer.key, true) + if input.Username != "" { + signer.userName = input.Username + signer.keyIdentifier = path.Join("/", signer.accountName, "users", input.Username, "keys", signer.formattedKeyFingerprint) + } else { + signer.keyIdentifier = path.Join("/", signer.accountName, "keys", signer.formattedKeyFingerprint) + } + + _, algorithm, err := signer.SignRaw("HelloWorld") + if err != nil { + return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err) + } + signer.algorithm = algorithm + + return signer, nil +} + +func (s *SSHAgentSigner) MatchKey() (ssh.PublicKey, error) { + keys, err := s.agent.List() if err != nil { return nil, errwrap.Wrapf("Error listing keys in SSH Agent: %s", err) } - keyFingerprintStripped := strings.TrimPrefix(keyFingerprint, "MD5:") + keyFingerprintStripped := strings.TrimPrefix(s.keyFingerprint, "MD5:") keyFingerprintStripped = strings.TrimPrefix(keyFingerprintStripped, "SHA256:") keyFingerprintStripped = strings.Replace(keyFingerprintStripped, ":", "", -1) @@ -64,27 +105,10 @@ func NewSSHAgentSigner(keyFingerprint, accountName string) (*SSHAgentSigner, err } if matchingKey == nil { - return nil, fmt.Errorf("No key in the SSH Agent matches fingerprint: %s", keyFingerprint) + return nil, fmt.Errorf("No key in the SSH Agent matches fingerprint: %s", s.keyFingerprint) } - formattedKeyFingerprint := formatPublicKeyFingerprint(matchingKey, true) - - signer := &SSHAgentSigner{ - formattedKeyFingerprint: formattedKeyFingerprint, - keyFingerprint: keyFingerprint, - accountName: accountName, - agent: ag, - key: matchingKey, - keyIdentifier: fmt.Sprintf("/%s/keys/%s", accountName, formattedKeyFingerprint), - } - - _, algorithm, err := signer.SignRaw("HelloWorld") - if err != nil { - return nil, fmt.Errorf("Cannot sign using ssh agent: %s", err) - } - signer.algorithm = algorithm - - return signer, nil + return matchingKey, nil } func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) { diff --git a/vendor/github.com/joyent/triton-go/authentication/test_signer.go b/vendor/github.com/joyent/triton-go/authentication/test_signer.go new file mode 100644 index 000000000..a9c2c82d5 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/authentication/test_signer.go @@ -0,0 +1,27 @@ +package authentication + +// TestSigner represents an authentication key signer which we can use for +// testing purposes only. This will largely be a stub to send through client +// unit tests. +type TestSigner struct{} + +// NewTestSigner constructs a new instance of test signer +func NewTestSigner() (Signer, error) { + return &TestSigner{}, nil +} + +func (s *TestSigner) DefaultAlgorithm() string { + return "" +} + +func (s *TestSigner) KeyFingerprint() string { + return "" +} + +func (s *TestSigner) Sign(dateHeader string) (string, error) { + return "", nil +} + +func (s *TestSigner) SignRaw(toSign string) (string, string, error) { + return "", "", nil +} diff --git a/vendor/github.com/joyent/triton-go/client/client.go b/vendor/github.com/joyent/triton-go/client/client.go index b01f86baf..cccf3a25d 100644 --- a/vendor/github.com/joyent/triton-go/client/client.go +++ b/vendor/github.com/joyent/triton-go/client/client.go @@ -6,6 +6,7 @@ import ( "crypto/tls" "encoding/json" "errors" + "fmt" "io" "net" "net/http" @@ -19,7 +20,14 @@ import ( const nilContext = "nil context" -var MissingKeyIdError = errors.New("Default SSH agent authentication requires SDC_KEY_ID") +var ( + ErrDefaultAuth = errors.New("default SSH agent authentication requires SDC_KEY_ID / TRITON_KEY_ID and SSH_AUTH_SOCK") + ErrAccountName = errors.New("missing account name for Triton/Manta") + ErrMissingURL = errors.New("missing Triton and/or Manta URL") + + BadTritonURL = "invalid format of triton URL" + BadMantaURL = "invalid format of manta URL" +) // Client represents a connection to the Triton Compute or Object Storage APIs. type Client struct { @@ -28,7 +36,7 @@ type Client struct { TritonURL url.URL MantaURL url.URL AccountName string - Endpoint string + Username string } // New is used to construct a Client in order to make API @@ -37,61 +45,93 @@ type Client struct { // At least one signer must be provided - example signers include // authentication.PrivateKeySigner and authentication.SSHAgentSigner. func New(tritonURL string, mantaURL string, accountName string, signers ...authentication.Signer) (*Client, error) { + if accountName == "" { + return nil, ErrAccountName + } + + if tritonURL == "" && mantaURL == "" { + return nil, ErrMissingURL + } + cloudURL, err := url.Parse(tritonURL) if err != nil { - return nil, errwrap.Wrapf("invalid endpoint URL: {{err}}", err) + return nil, errwrap.Wrapf(BadTritonURL+": {{err}}", err) } storageURL, err := url.Parse(mantaURL) if err != nil { - return nil, errwrap.Wrapf("invalid manta URL: {{err}}", err) + return nil, errwrap.Wrapf(BadMantaURL+": {{err}}", err) } - if accountName == "" { - return nil, errors.New("account name can not be empty") - } - - httpClient := &http.Client{ - Transport: httpTransport(false), - CheckRedirect: doNotFollowRedirects, - } - - newClient := &Client{ - HTTPClient: httpClient, - Authorizers: signers, - TritonURL: *cloudURL, - MantaURL: *storageURL, - AccountName: accountName, - // TODO(justinwr): Deprecated? - // Endpoint: tritonURL, - } - - var authorizers []authentication.Signer + authorizers := make([]authentication.Signer, 0) for _, key := range signers { if key != nil { authorizers = append(authorizers, key) } } + newClient := &Client{ + HTTPClient: &http.Client{ + Transport: httpTransport(false), + CheckRedirect: doNotFollowRedirects, + }, + Authorizers: authorizers, + TritonURL: *cloudURL, + MantaURL: *storageURL, + AccountName: accountName, + } + // Default to constructing an SSHAgentSigner if there are no other signers - // passed into NewClient and there's an SDC_KEY_ID value available in the - // user environ. - if len(authorizers) == 0 { - keyID := os.Getenv("SDC_KEY_ID") - if len(keyID) != 0 { - keySigner, err := authentication.NewSSHAgentSigner(keyID, accountName) - if err != nil { - return nil, errwrap.Wrapf("Problem initializing NewSSHAgentSigner: {{err}}", err) - } - newClient.Authorizers = append(authorizers, keySigner) - } else { - return nil, MissingKeyIdError + // passed into NewClient and there's an TRITON_KEY_ID and SSH_AUTH_SOCK + // available in the user's environ(7). + if len(newClient.Authorizers) == 0 { + if err := newClient.DefaultAuth(); err != nil { + return nil, err } } return newClient, nil } +var envPrefixes = []string{"TRITON", "SDC"} + +// GetTritonEnv looks up environment variables using the preferred "TRITON" +// prefix, but falls back to the SDC prefix. For example, looking up "USER" +// will search for "TRITON_USER" followed by "SDC_USER". If the environment +// variable is not set, an empty string is returned. GetTritonEnv() is used to +// aid in the transition and deprecation of the SDC_* environment variables. +func GetTritonEnv(name string) string { + for _, prefix := range envPrefixes { + if val, found := os.LookupEnv(prefix + "_" + name); found { + return val + } + } + + return "" +} + +// initDefaultAuth provides a default key signer for a client. This should only +// be used internally if the client has no other key signer for authenticating +// with Triton. We first look for both `SDC_KEY_ID` and `SSH_AUTH_SOCK` in the +// user's environ(7). If so we default to the SSH agent key signer. +func (c *Client) DefaultAuth() error { + tritonKeyId := GetTritonEnv("KEY_ID") + if tritonKeyId != "" { + input := authentication.SSHAgentSignerInput{ + KeyID: tritonKeyId, + AccountName: c.AccountName, + Username: c.Username, + } + defaultSigner, err := authentication.NewSSHAgentSigner(input) + if err != nil { + return errwrap.Wrapf("problem initializing NewSSHAgentSigner: {{err}}", err) + } + c.Authorizers = append(c.Authorizers, defaultSigner) + } + + return ErrDefaultAuth +} + // InsecureSkipTLSVerify turns off TLS verification for the client connection. This // allows connection to an endpoint with a certificate which was signed by a non- // trusted CA, such as self-signed certificates. This can be useful when connecting @@ -112,8 +152,8 @@ func httpTransport(insecureSkipTLSVerify bool) *http.Transport { KeepAlive: 30 * time.Second, }).Dial, TLSHandshakeTimeout: 10 * time.Second, - DisableKeepAlives: true, - MaxIdleConnsPerHost: -1, + MaxIdleConns: 10, + IdleConnTimeout: 15 * time.Second, TLSClientConfig: &tls.Config{ InsecureSkipVerify: insecureSkipTLSVerify, }, @@ -158,7 +198,7 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu body := inputs.Body query := inputs.Query - var requestBody io.ReadSeeker + var requestBody io.Reader if body != nil { marshaled, err := json.MarshalIndent(body, "", " ") if err != nil { @@ -217,7 +257,7 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h path := inputs.Path body := inputs.Body - var requestBody io.ReadSeeker + var requestBody io.Reader if body != nil { marshaled, err := json.MarshalIndent(body, "", " ") if err != nil { @@ -270,7 +310,7 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) endpoint := c.MantaURL endpoint.Path = path - var requestBody io.ReadSeeker + var requestBody io.Reader if body != nil { marshaled, err := json.MarshalIndent(body, "", " ") if err != nil { @@ -323,10 +363,17 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) StatusCode: resp.StatusCode, } - errorDecoder := json.NewDecoder(resp.Body) - if err := errorDecoder.Decode(mantaError); err != nil { - return nil, nil, errwrap.Wrapf("Error decoding error response: {{err}}", err) + if req.Method != http.MethodHead { + errorDecoder := json.NewDecoder(resp.Body) + if err := errorDecoder.Decode(mantaError); err != nil { + return nil, nil, errwrap.Wrapf("Error decoding error response: {{err}}", err) + } } + + if mantaError.Message == "" { + mantaError.Message = fmt.Sprintf("HTTP response returned status code %d", resp.StatusCode) + } + return nil, nil, mantaError } @@ -335,7 +382,7 @@ type RequestNoEncodeInput struct { Path string Query *url.Values Headers *http.Header - Body io.ReadSeeker + Body io.Reader } func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEncodeInput) (io.ReadCloser, http.Header, error) { diff --git a/vendor/github.com/joyent/triton-go/compute/client.go b/vendor/github.com/joyent/triton-go/compute/client.go index 8ce726cb1..73582e2ae 100644 --- a/vendor/github.com/joyent/triton-go/compute/client.go +++ b/vendor/github.com/joyent/triton-go/compute/client.go @@ -38,7 +38,7 @@ func (c *ComputeClient) Images() *ImagesClient { return &ImagesClient{c.Client} } -// Machines returns a Compute client used for accessing functions pertaining to +// Machine returns a Compute client used for accessing functions pertaining to // machine functionality in the Triton API. func (c *ComputeClient) Instances() *InstancesClient { return &InstancesClient{c.Client} @@ -55,3 +55,9 @@ func (c *ComputeClient) Packages() *PackagesClient { func (c *ComputeClient) Services() *ServicesClient { return &ServicesClient{c.Client} } + +// Snapshots returns a Compute client used for accessing functions pertaining to +// Snapshots functionality in the Triton API. +func (c *ComputeClient) Snapshots() *SnapshotsClient { + return &SnapshotsClient{c.Client} +} diff --git a/vendor/github.com/joyent/triton-go/compute/datacenters.go b/vendor/github.com/joyent/triton-go/compute/datacenters.go index 7acaf20a1..365474e17 100644 --- a/vendor/github.com/joyent/triton-go/compute/datacenters.go +++ b/vendor/github.com/joyent/triton-go/compute/datacenters.go @@ -81,7 +81,7 @@ func (c *DataCentersClient) Get(ctx context.Context, input *GetDataCenterInput) } if resp.StatusCode != http.StatusFound { - return nil, fmt.Errorf("Error executing Get request: expected status code 302, got %s", + return nil, fmt.Errorf("Error executing Get request: expected status code 302, got %d", resp.StatusCode) } diff --git a/vendor/github.com/joyent/triton-go/compute/errors.go b/vendor/github.com/joyent/triton-go/compute/errors.go index ae2a4bf5c..db31472ff 100644 --- a/vendor/github.com/joyent/triton-go/compute/errors.go +++ b/vendor/github.com/joyent/triton-go/compute/errors.go @@ -94,6 +94,12 @@ func IsUnknownError(err error) bool { return isSpecificError(err, "UnknownError") } +// IsEmptyResponse tests whether err wraps a client.TritonError with code +// EmptyResponse +func IsEmptyResponse(err error) bool { + return isSpecificError(err, "EmptyResponse") +} + // isSpecificError checks whether the error represented by err wraps // an underlying client.TritonError with code errorCode. func isSpecificError(err error, errorCode string) bool { diff --git a/vendor/github.com/joyent/triton-go/compute/instances.go b/vendor/github.com/joyent/triton-go/compute/instances.go index 337e6a482..9be14bb21 100644 --- a/vendor/github.com/joyent/triton-go/compute/instances.go +++ b/vendor/github.com/joyent/triton-go/compute/instances.go @@ -97,10 +97,13 @@ func (c *InstancesClient) Get(ctx context.Context, input *GetInstanceInput) (*In Path: path, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) - if response != nil { + if response == nil { + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + } + if response.Body != nil { defer response.Body.Close() } - if response == nil || response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { + if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { return nil, &client.TritonError{ StatusCode: response.StatusCode, Code: "ResourceNotFound", @@ -962,6 +965,32 @@ func (c *InstancesClient) Start(ctx context.Context, input *StartInstanceInput) return nil } +type RebootInstanceInput struct { + InstanceID string +} + +func (c *InstancesClient) Reboot(ctx context.Context, input *RebootInstanceInput) error { + path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.InstanceID) + + params := &url.Values{} + params.Set("action", "reboot") + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Query: params, + } + respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing Start request: {{err}}", err) + } + + return nil +} + var reservedInstanceCNSTags = map[string]struct{}{ CNSTagDisable: {}, CNSTagReversePTR: {}, diff --git a/vendor/github.com/joyent/triton-go/compute/ping.go b/vendor/github.com/joyent/triton-go/compute/ping.go new file mode 100644 index 000000000..c0f62dfaa --- /dev/null +++ b/vendor/github.com/joyent/triton-go/compute/ping.go @@ -0,0 +1,56 @@ +package compute + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" +) + +const pingEndpoint = "/--ping" + +type CloudAPI struct { + Versions []string `json:"versions"` +} + +type PingOutput struct { + Ping string `json:"ping"` + CloudAPI CloudAPI `json:"cloudapi"` +} + +// Ping sends a request to the '/--ping' endpoint and returns a `pong` as well +// as a list of API version numbers your instance of CloudAPI is presenting. +func (c *ComputeClient) Ping(ctx context.Context) (*PingOutput, error) { + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: pingEndpoint, + } + response, err := c.Client.ExecuteRequestRaw(ctx, reqInputs) + if response == nil { + return nil, fmt.Errorf("Ping request has empty response") + } + if response.Body != nil { + defer response.Body.Close() + } + if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { + return nil, &client.TritonError{ + StatusCode: response.StatusCode, + Code: "ResourceNotFound", + } + } + if err != nil { + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", + c.Client.DecodeError(response.StatusCode, response.Body)) + } + + var result *PingOutput + decoder := json.NewDecoder(response.Body) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + } + + return result, nil +} diff --git a/vendor/github.com/joyent/triton-go/compute/snapshots.go b/vendor/github.com/joyent/triton-go/compute/snapshots.go new file mode 100644 index 000000000..72873ad39 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/compute/snapshots.go @@ -0,0 +1,157 @@ +package compute + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "time" + + "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go/client" +) + +type SnapshotsClient struct { + client *client.Client +} + +type Snapshot struct { + Name string + State string + Created time.Time + Updated time.Time +} + +type ListSnapshotsInput struct { + MachineID string +} + +func (c *SnapshotsClient) List(ctx context.Context, input *ListSnapshotsInput) ([]*Snapshot, error) { + path := fmt.Sprintf("/%s/machines/%s/snapshots", c.client.AccountName, input.MachineID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + } + + var result []*Snapshot + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + } + + return result, nil +} + +type GetSnapshotInput struct { + MachineID string + Name string +} + +func (c *SnapshotsClient) Get(ctx context.Context, input *GetSnapshotInput) (*Snapshot, error) { + path := fmt.Sprintf("/%s/machines/%s/snapshots/%s", c.client.AccountName, input.MachineID, input.Name) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + } + + var result *Snapshot + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + } + + return result, nil +} + +type DeleteSnapshotInput struct { + MachineID string + Name string +} + +func (c *SnapshotsClient) Delete(ctx context.Context, input *DeleteSnapshotInput) error { + path := fmt.Sprintf("/%s/machines/%s/snapshots/%s", c.client.AccountName, input.MachineID, input.Name) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing Delete request: {{err}}", err) + } + + return nil +} + +type StartMachineFromSnapshotInput struct { + MachineID string + Name string +} + +func (c *SnapshotsClient) StartMachine(ctx context.Context, input *StartMachineFromSnapshotInput) error { + path := fmt.Sprintf("/%s/machines/%s/snapshots/%s", c.client.AccountName, input.MachineID, input.Name) + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return errwrap.Wrapf("Error executing StartMachine request: {{err}}", err) + } + + return nil +} + +type CreateSnapshotInput struct { + MachineID string + Name string +} + +func (c *SnapshotsClient) Create(ctx context.Context, input *CreateSnapshotInput) (*Snapshot, error) { + path := fmt.Sprintf("/%s/machines/%s/snapshots", c.client.AccountName, input.MachineID) + + data := make(map[string]interface{}) + data["name"] = input.Name + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: path, + Body: data, + } + + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing Create request: {{err}}", err) + } + + var result *Snapshot + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding Create response: {{err}}", err) + } + + return result, nil +} diff --git a/vendor/github.com/joyent/triton-go/network/firewall.go b/vendor/github.com/joyent/triton-go/network/firewall.go index 60054702a..8dbd969f3 100644 --- a/vendor/github.com/joyent/triton-go/network/firewall.go +++ b/vendor/github.com/joyent/triton-go/network/firewall.go @@ -6,6 +6,8 @@ import ( "fmt" "net/http" + "time" + "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" ) @@ -227,7 +229,7 @@ type ListMachineRulesInput struct { } func (c *FirewallClient) ListMachineRules(ctx context.Context, input *ListMachineRulesInput) ([]*FirewallRule, error) { - path := fmt.Sprintf("/%s/machines/%s/firewallrules", c.client.AccountName, input.MachineID) + path := fmt.Sprintf("/%s/machines/%s/fwrules", c.client.AccountName, input.MachineID) reqInputs := client.RequestInput{ Method: http.MethodGet, Path: path, @@ -243,7 +245,56 @@ func (c *FirewallClient) ListMachineRules(ctx context.Context, input *ListMachin var result []*FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListRules response: {{err}}", err) + return nil, errwrap.Wrapf("Error decoding ListMachineRules response: {{err}}", err) + } + + return result, nil +} + +type ListRuleMachinesInput struct { + ID string +} + +type Machine struct { + ID string `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Brand string `json:"brand"` + State string `json:"state"` + Image string `json:"image"` + Memory int `json:"memory"` + Disk int `json:"disk"` + Metadata map[string]string `json:"metadata"` + Tags map[string]interface{} `json:"tags"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` + Docker bool `json:"docker"` + IPs []string `json:"ips"` + Networks []string `json:"networks"` + PrimaryIP string `json:"primaryIp"` + FirewallEnabled bool `json:"firewall_enabled"` + ComputeNode string `json:"compute_node"` + Package string `json:"package"` +} + +func (c *FirewallClient) ListRuleMachines(ctx context.Context, input *ListRuleMachinesInput) ([]*Machine, error) { + path := fmt.Sprintf("/%s/fwrules/%s/machines", c.client.AccountName, input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: path, + } + respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if respReader != nil { + defer respReader.Close() + } + if err != nil { + return nil, errwrap.Wrapf("Error executing ListRuleMachines request: {{err}}", err) + } + + var result []*Machine + decoder := json.NewDecoder(respReader) + if err = decoder.Decode(&result); err != nil { + return nil, errwrap.Wrapf("Error decoding ListRuleMachines response: {{err}}", err) } return result, nil diff --git a/vendor/github.com/joyent/triton-go/triton.go b/vendor/github.com/joyent/triton-go/triton.go index b5bacd255..f9202984e 100644 --- a/vendor/github.com/joyent/triton-go/triton.go +++ b/vendor/github.com/joyent/triton-go/triton.go @@ -14,5 +14,6 @@ type ClientConfig struct { TritonURL string MantaURL string AccountName string + Username string Signers []authentication.Signer } diff --git a/vendor/vendor.json b/vendor/vendor.json index 35704c419..a229cabce 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -823,34 +823,34 @@ "revision": "c01cf91b011868172fdcd9f41838e80c9d716264" }, { - "checksumSHA1": "EqvUu0Ku0Ec5Tk6yhGNOuOr8yeA=", + "checksumSHA1": "oINoQSRkPinChzwEHr3VatB9++Y=", "path": "github.com/joyent/triton-go", - "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", - "revisionTime": "2017-10-17T16:55:58Z" + "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", + "revisionTime": "2017-12-28T20:20:46Z" }, { - "checksumSHA1": "JKf97EAAAZFQ6Wf8qN9X7TWqNBY=", + "checksumSHA1": "d6pxw8DLxYehLr92fWZTLEWVws8=", "path": "github.com/joyent/triton-go/authentication", - "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", - "revisionTime": "2017-10-17T16:55:58Z" + "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", + "revisionTime": "2017-12-28T20:20:46Z" }, { - "checksumSHA1": "dlO1or0cyVMAmZzyLcBuoy+M0xU=", + "checksumSHA1": "GCHfn8d1Mhswm7n7IRnT0n/w+dw=", "path": "github.com/joyent/triton-go/client", - "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", - "revisionTime": "2017-10-17T16:55:58Z" + "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", + "revisionTime": "2017-12-28T20:20:46Z" }, { - "checksumSHA1": "O/y7BfKJFUf3A8TCRMXgo9HSb1w=", + "checksumSHA1": "U9D/fCNr+1uD1p/O0PW0yD/izqc=", "path": "github.com/joyent/triton-go/compute", - "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", - "revisionTime": "2017-10-17T16:55:58Z" + "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", + "revisionTime": "2017-12-28T20:20:46Z" }, { - "checksumSHA1": "gyLtPyKlcumRSkrAH+SsDQo1GnY=", + "checksumSHA1": "9OdR/eI3qbmADruKn6yE1Dbx3LE=", "path": "github.com/joyent/triton-go/network", - "revision": "5a58ad2cdec95cddd1e0a2e56f559341044b04f0", - "revisionTime": "2017-10-17T16:55:58Z" + "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", + "revisionTime": "2017-12-28T20:20:46Z" }, { "checksumSHA1": "gEjGS03N1eysvpQ+FCHTxPcbxXc=", diff --git a/website/source/docs/builders/triton.html.md b/website/source/docs/builders/triton.html.md index 80c54a5b4..2a62dbe12 100644 --- a/website/source/docs/builders/triton.html.md +++ b/website/source/docs/builders/triton.html.md @@ -92,6 +92,9 @@ builder. 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. - `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 @@ -149,7 +152,7 @@ builder. ## Basic Example -Below is a minimal example to create an joyent-brand image on the Joyent public +Below is a minimal example to create an image on the Joyent public cloud: ``` json From a8e30bc79627ad48a338b1f104b52f3c6070459b Mon Sep 17 00:00:00 2001 From: James Nugent <james@jen20.com> Date: Fri, 29 Dec 2017 13:34:05 -0600 Subject: [PATCH 0340/1007] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7476b23b0..0c42f57c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### IMPROVEMENTS: * builder/docker: Remove credentials from being shown in the log. [GH-5666] +* builder/triton: Triton RBAC is now supported. [GH-5741] * post-processor/docker: Remove credentials from being shown in the log. [GH-5666] ### BUG FIXES: From 4fcd542d0c233e64dc6a984bd66365a1cc60af7a Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 2 Jan 2018 21:07:01 -0600 Subject: [PATCH 0341/1007] Fixed an issue where the VirtualBox builder was checking for whether guest_additions_url was empty or not before it actually interpolated any variables. --- .../common/step_download_guest_additions.go | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 8039d0fa4..e73642703 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -66,21 +66,25 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste checksumType := "sha256" - // Use the provided source (URL or file path) or generate it + // Grab the guest_additions_url as specified by the user. url := s.GuestAdditionsURL - if url != "" { - s.Ctx.Data = &guestAdditionsUrlTemplate{ - Version: version, - } - url, err = interpolate.Render(url, &s.Ctx) - if err != nil { - err := fmt.Errorf("Error preparing guest additions url: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - } else { + // Initialize the template context so we can interpolate some variables.. + s.Ctx.Data = &guestAdditionsUrlTemplate{ + Version: version, + } + + // Interpolate any user-variables specified within the guest_additions_url + url, err = interpolate.Render(s.GuestAdditionsURL, &s.Ctx) + if err != nil { + err := fmt.Errorf("Error preparing guest additions url: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // If this resulted in an empty url, then ask the driver about it. + if url == "" { url, err = driver.Iso() if err == nil { @@ -93,6 +97,8 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste additionsName) } } + + // The driver couldn't even figure it out, so fail hard. if url == "" { err := fmt.Errorf("Couldn't detect guest additions URL.\n" + "Please specify `guest_additions_url` manually.") @@ -101,6 +107,7 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste return multistep.ActionHalt } + // Figure out a default checksum here if checksumType != "none" { if s.GuestAdditionsSHA256 != "" { checksum = s.GuestAdditionsSHA256 @@ -112,6 +119,7 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste } } + // Convert the file/url to an actual URL for step_download to process. url, err = common.DownloadableURL(url) if err != nil { err := fmt.Errorf("Error preparing guest additions url: %s", err) @@ -122,6 +130,7 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste log.Printf("Guest additions URL: %s", url) + // We're good, so let's go ahead and download this thing.. downStep := &common.StepDownload{ Checksum: checksum, ChecksumType: checksumType, From b894c925d1c85a8b42e95d3b9cdcb5dbdc25e7a2 Mon Sep 17 00:00:00 2001 From: Aidan Feldman <aidan.feldman@gsa.gov> Date: Wed, 3 Jan 2018 02:33:32 -0500 Subject: [PATCH 0342/1007] make user retrieval for Ansible provisioner more robust Previously, the Ansible provisioner would look for the username from the `USER` environment variable. Unfortunately, this is not always set - particularly in Docker containers. It's very confusing to understand why the error is happening. Switched to using Go's built-in `os/user` package for retrieving the current username. @rickard-von-essen had done this in 7369841, but moved away from it in d59844f because, at the time, it wasn't possible to use that library with cross-compilation. This was fixed in Go in https://github.com/golang/go/commit/795e712b72802ad49b7c077964046f79c4f6586e --- provisioner/ansible/provisioner.go | 8 +++++++- provisioner/ansible/provisioner_test.go | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index dfe5aa6d6..18965d220 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -15,6 +15,7 @@ import ( "net" "os" "os/exec" + "os/user" "path/filepath" "regexp" "strconv" @@ -141,7 +142,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.User == "" { - p.config.User = os.Getenv("USER") + usr, err := user.Current() + if err != nil { + errs = packer.MultiErrorAppend(errs, err) + } else { + p.config.User = usr.Username + } } if p.config.User == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("user: could not determine current user from environment.")) diff --git a/provisioner/ansible/provisioner_test.go b/provisioner/ansible/provisioner_test.go index 47f185c9e..c3300bc6b 100644 --- a/provisioner/ansible/provisioner_test.go +++ b/provisioner/ansible/provisioner_test.go @@ -76,6 +76,16 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { if err != nil { t.Fatalf("err: %s", err) } + defer os.Remove(playbook_file.Name()) + + err = os.Unsetenv("USER") + if err != nil { + t.Fatalf("err: %s", err) + } + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } } func TestProvisionerPrepare_PlaybookFile(t *testing.T) { From 0ae1df2071ae4716d333f059ad4bd1b3c8b78af3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 21 Dec 2017 15:31:52 -0800 Subject: [PATCH 0343/1007] clarify that ssh_interface works for winrm --- website/source/docs/builders/amazon-ebs.html.md | 4 ++-- website/source/docs/builders/amazon-ebssurrogate.html.md | 4 ++-- website/source/docs/builders/amazon-ebsvolume.html.md | 4 ++-- website/source/docs/builders/amazon-instance.html.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 02fa0ae2f..6b48621b4 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -336,9 +336,9 @@ builder. private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name - will be used. + will be used. Also works for WinRM. - Where Packer is configured for an outbound proxy but WinRM traffic should be direct + Where Packer is configured for an outbound proxy but WinRM traffic should be direct, `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included in the `NO_PROXY` environment variable. diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 4e94362df..7b995fa87 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -329,9 +329,9 @@ builder. private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name - will be used. + will be used. Also works for WinRM. - Where Packer is configured for an outbound proxy but WinRM traffic should be direct + Where Packer is configured for an outbound proxy but WinRM traffic should be direct, `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included in the `NO_PROXY` environment variable. diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index b77dc0571..b500aa2bd 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -233,9 +233,9 @@ builder. private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name - will be used. + will be used. Also works for WinRM. - Where Packer is configured for an outbound proxy but WinRM traffic should be direct + Where Packer is configured for an outbound proxy but WinRM traffic should be direct, `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included in the `NO_PROXY` environment variable. diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 198345ba7..f8f72708a 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -337,9 +337,9 @@ builder. private IP address, public DNS name or private DNS name will used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name - will be used. + will be used. Also works for WinRM. - Where Packer is configured for an outbound proxy but WinRM traffic should be direct + Where Packer is configured for an outbound proxy but WinRM traffic should be direct, `ssh_interface` must be set to `private_dns` and `<region>.compute.internal` included in the `NO_PROXY` environment variable. From 54bd057bb90e40c3e5c5a5b40002f9e11b2e8520 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 3 Jan 2018 14:34:11 -0800 Subject: [PATCH 0344/1007] fix nasty edge case where we can't find guest additions on windows if they are on a different drive --- common/config.go | 6 ------ common/download.go | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/config.go b/common/config.go index 490553388..4ee68f970 100644 --- a/common/config.go +++ b/common/config.go @@ -74,12 +74,6 @@ func DownloadableURL(original string) (string, error) { url.Path = url.Host url.Host = "" } - - // For Windows absolute file paths, remove leading / prior to processing - // since net/url turns "C:/" into "/C:/" - if len(url.Path) > 0 && url.Path[0] == '/' { - url.Path = url.Path[1:len(url.Path)] - } } // Only do the filepath transformations if the file appears diff --git a/common/download.go b/common/download.go index 8eaf236fc..ada4c9756 100644 --- a/common/download.go +++ b/common/download.go @@ -15,6 +15,7 @@ import ( "net/http" "net/url" "os" + "runtime" ) // DownloadConfig is the configuration given to instantiate a new @@ -129,6 +130,11 @@ func (d *DownloadClient) Get() (string, error) { // locally and we don't make a copy. Normally we would copy or download. log.Printf("[DEBUG] Using local file: %s", finalPath) + // Remove forward slash on absolute Windows file URLs before processing + if runtime.GOOS == "windows" && len(finalPath) > 0 && finalPath[0] == '/' { + finalPath = finalPath[1:] + } + // Keep track of the source so we can make sure not to delete this later sourcePath = finalPath if _, err = os.Stat(finalPath); err != nil { From 4f3b4708046a2e299547bdd41dc077d57e514e4d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 3 Jan 2018 16:53:47 -0800 Subject: [PATCH 0345/1007] add helper function to manage validation of filepaths created using DownloadableURL --- builder/virtualbox/ovf/config.go | 14 +++++-------- common/config.go | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 3e4b9b879..9c6d5dd06 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -2,8 +2,6 @@ package ovf import ( "fmt" - "net/url" - "os" "strings" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" @@ -103,14 +101,12 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { if err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) } - // file must exist now. - fileURL, _ := url.Parse(c.SourcePath) - if fileURL.Scheme == "file" { - if _, err := os.Stat(fileURL.Path); err != nil { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("source file needs to exist at time of config validation: %s", err)) - } + fileExists, err := common.FileExistsLocally(c.SourcePath) + if err != nil { + packer.MultiErrorAppend(errs, + fmt.Errorf("Source file needs to exist at time of config validation: %s", err)) } + } validMode := false diff --git a/common/config.go b/common/config.go index 4ee68f970..c9c8f9e7a 100644 --- a/common/config.go +++ b/common/config.go @@ -119,3 +119,37 @@ func DownloadableURL(original string) (string, error) { return url.String(), nil } + +// FileExistsLocally takes the URL output from DownloadableURL, and determines +// whether it is present on the file system. +// example usage: +// +// myFile, err = common.DownloadableURL(c.SourcePath) +// ... +// fileExists, err := common.StatURL(myFile) +// possible output: +// true, nil -- should occur if the file is present +// false, nil -- should occur if the file is not present, but is not supposed to +// be (e.g. the schema is http://, not file://) +// true, error -- shouldn't occur ever +// false, error -- should occur if there was an error stating the file, so the +// file is not present when it should be. + +func FileExistsLocally(original string) (bool, error) { + fileURL, _ := url.Parse(original) + fileExists := false + err := nil + + if fileURL.Scheme == "file" { + // Remove forward slash on absolute Windows file URLs before processing + if runtime.GOOS == "windows" && len(fileURL.Path) > 0 && fileURL.Path[0] == '/' { + filePath := fileURL.Path[1:] + } + if _, err := os.Stat(filePath); err != nil { + err = fmt.Errorf("source file needs to exist at time of config validation: %s", err) + } else { + fileExists = true + } + } + return fileExists, err +} From 7fe1ec03ca8c46628c8aa0a309bb599df3685ae7 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 4 Jan 2018 11:34:05 -0800 Subject: [PATCH 0346/1007] update winrmcp to fix #5752 --- vendor/github.com/packer-community/winrmcp/winrmcp/cp.go | 7 ++++++- vendor/vendor.json | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/vendor/github.com/packer-community/winrmcp/winrmcp/cp.go b/vendor/github.com/packer-community/winrmcp/winrmcp/cp.go index 2890e55ef..4d089c13d 100644 --- a/vendor/github.com/packer-community/winrmcp/winrmcp/cp.go +++ b/vendor/github.com/packer-community/winrmcp/winrmcp/cp.go @@ -176,7 +176,12 @@ func cleanupContent(client *winrm.Client, filePath string) error { } defer shell.Close() - script := fmt.Sprintf(`Remove-Item %s -ErrorAction SilentlyContinue`, filePath) + script := fmt.Sprintf(` + $tmp_file_path = [System.IO.Path]::GetFullPath("%s") + if (Test-Path $tmp_file_path) { + Remove-Item $tmp_file_path -ErrorAction SilentlyContinue + } + `, filePath) cmd, err := shell.Execute(winrm.Powershell(script)) if err != nil { diff --git a/vendor/vendor.json b/vendor/vendor.json index a229cabce..4438b367e 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -983,10 +983,10 @@ "revision": "179d4d0c4d8d407a32af483c2354df1d2c91e6c3" }, { - "checksumSHA1": "XXmfaQ8fEupEgaGd6PptrLnrE54=", + "checksumSHA1": "/NoE6t3UkW4/iKAtbf59GGv6tF8=", "path": "github.com/packer-community/winrmcp/winrmcp", - "revision": "e1b7d6e6b1b1a27984270784190f1d06ad91888b", - "revisionTime": "2017-09-29T21:51:32Z" + "revision": "81144009af586de8e7729b829266f09dd0d59701", + "revisionTime": "2018-01-02T16:08:24Z" }, { "checksumSHA1": "oaXvjFg802gS/wx1bx2gAQwa7XQ=", From 98c2a2d1f76c80a894509d6df69c25bae76bb18d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 4 Jan 2018 11:50:27 -0800 Subject: [PATCH 0347/1007] builder/aws: catch static credential errors early. If we're using static credentials, either both the access key and secret key must be set, or neither of them should be. --- builder/amazon/common/access_config.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 1ecd9dcdb..b569d0314 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -53,17 +53,8 @@ func (c *AccessConfig) Session() (*session.Session, error) { } if c.AccessKey != "" { - creds := credentials.NewChainCredentials( - []credentials.Provider{ - &credentials.StaticProvider{ - Value: credentials.Value{ - AccessKeyID: c.AccessKey, - SecretAccessKey: c.SecretKey, - SessionToken: c.Token, - }, - }, - }) - config = config.WithCredentials(creds) + config = config.WithCredentials( + credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token)) } opts := session.Options{ @@ -110,6 +101,14 @@ func (c *AccessConfig) metadataRegion() string { func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { var errs []error + + // Either both access and secret key must be set or neither of them should + // be. + if (len(c.AccessKey) > 0) != (len(c.SecretKey) > 0) { + errs = append(errs, + fmt.Errorf("`access_key` and `secret_key` must both be either set or not set.")) + } + if c.RawRegion != "" && !c.SkipValidation { if valid := ValidateRegion(c.RawRegion); !valid { errs = append(errs, fmt.Errorf("Unknown region: %s", c.RawRegion)) From 89ba76b4aaa5c9a491d1deb1be3b251162d97171 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 4 Jan 2018 14:39:26 -0800 Subject: [PATCH 0348/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c42f57c6..9815039e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * builder/docker: Remove credentials from being shown in the log. [GH-5666] * builder/triton: Triton RBAC is now supported. [GH-5741] * post-processor/docker: Remove credentials from being shown in the log. [GH-5666] +* builder/amazon: Warn during prepare if we didn't get both an access key and a secret key when we were expecting one. [GH-5762] ### BUG FIXES: * builder/alicloud-ecs: Attach keypair before starting instance in alicloud builder [GH-5739] From c5bcb97d06e2d66b9b433ae1bb18f3c832d67173 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 4 Jan 2018 15:04:07 -0800 Subject: [PATCH 0349/1007] "borrow" access config code from terraform. This gives us a few benefits: * timeout early if metadata service can't be reached * report which auth provider we're using * give much better errors if something goes wrong --- builder/amazon/common/access_config.go | 99 +++++++++++++++++++++----- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index b569d0314..e3875d26c 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -1,13 +1,16 @@ package common import ( + "errors" "fmt" "log" "os" "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "github.com/hashicorp/go-cleanhttp" @@ -16,15 +19,16 @@ import ( // AccessConfig is for common configuration related to AWS access type AccessConfig struct { - AccessKey string `mapstructure:"access_key"` - CustomEndpointEc2 string `mapstructure:"custom_endpoint_ec2"` - MFACode string `mapstructure:"mfa_code"` - ProfileName string `mapstructure:"profile"` - RawRegion string `mapstructure:"region"` - SecretKey string `mapstructure:"secret_key"` - SkipValidation bool `mapstructure:"skip_region_validation"` - Token string `mapstructure:"token"` - session *session.Session + AccessKey string `mapstructure:"access_key"` + CustomEndpointEc2 string `mapstructure:"custom_endpoint_ec2"` + MFACode string `mapstructure:"mfa_code"` + ProfileName string `mapstructure:"profile"` + RawRegion string `mapstructure:"region"` + SecretKey string `mapstructure:"secret_key"` + SkipValidation bool `mapstructure:"skip_region_validation"` + SkipMetadataApiCheck bool `mapstructure:"skip_metadata_api_check"` + Token string `mapstructure:"token"` + session *session.Session } // Config returns a valid aws.Config object for access to AWS services, or @@ -34,14 +38,78 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } - config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) + // build a chain provider, lazy-evaluated by aws-sdk + providers := []credentials.Provider{ + &credentials.StaticProvider{Value: credentials.Value{ + AccessKeyID: c.AccessKey, + SecretAccessKey: c.SecretKey, + SessionToken: c.Token, + }}, + &credentials.EnvProvider{}, + &credentials.SharedCredentialsProvider{ + Filename: "", + Profile: c.ProfileName, + }, + } - if c.ProfileName != "" { - if err := os.Setenv("AWS_PROFILE", c.ProfileName); err != nil { - return nil, fmt.Errorf("Set env error: %s", err) + // Build isolated HTTP client to avoid issues with globally-shared settings + client := cleanhttp.DefaultClient() + + // Keep the default timeout (100ms) low as we don't want to wait in non-EC2 environments + client.Timeout = 100 * time.Millisecond + + const userTimeoutEnvVar = "AWS_METADATA_TIMEOUT" + userTimeout := os.Getenv(userTimeoutEnvVar) + if userTimeout != "" { + newTimeout, err := time.ParseDuration(userTimeout) + if err == nil { + if newTimeout.Nanoseconds() > 0 { + client.Timeout = newTimeout + } else { + log.Printf("[WARN] Non-positive value of %s (%s) is meaningless, ignoring", userTimeoutEnvVar, newTimeout.String()) + } + } else { + log.Printf("[WARN] Error converting %s to time.Duration: %s", userTimeoutEnvVar, err) } } + log.Printf("[INFO] Setting AWS metadata API timeout to %s", client.Timeout.String()) + cfg := &aws.Config{ + HTTPClient: client, + } + if !c.SkipMetadataApiCheck { + // Real AWS should reply to a simple metadata request. + // We check it actually does to ensure something else didn't just + // happen to be listening on the same IP:Port + metadataClient := ec2metadata.New(session.New(cfg)) + if metadataClient.Available() { + providers = append(providers, &ec2rolecreds.EC2RoleProvider{ + Client: metadataClient, + }) + log.Print("[INFO] AWS EC2 instance detected via default metadata" + + " API endpoint, EC2RoleProvider added to the auth chain") + } else { + log.Printf("[INFO] Ignoring AWS metadata API endpoint " + + "as it doesn't return any instance-id") + } + } + + creds := credentials.NewChainCredentials(providers) + cp, err := creds.Get() + if err != nil { + if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" { + return nil, errors.New("No valid credential sources found for AWS Builder. " + + "Please see https://www.packer.io/docs/builders/amazon.html#specifying-amazon-credentials " + + "for more information on providing credentials for the AWS Builder.") + } + + return nil, fmt.Errorf("Error loading credentials for AWS Provider: %s", err) + } + log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName) + + config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) + config = config.WithCredentials(creds) + if c.RawRegion != "" { config = config.WithRegion(c.RawRegion) } else if region := c.metadataRegion(); region != "" { @@ -52,11 +120,6 @@ func (c *AccessConfig) Session() (*session.Session, error) { config = config.WithEndpoint(c.CustomEndpointEc2) } - if c.AccessKey != "" { - config = config.WithCredentials( - credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token)) - } - opts := session.Options{ SharedConfigState: session.SharedConfigEnable, Config: *config, From 7a4709400b91d501b60a0e15ea291be5c3c5b714 Mon Sep 17 00:00:00 2001 From: lmayorga <lmayorga@lm3corp.com> Date: Thu, 4 Jan 2018 21:49:36 -0500 Subject: [PATCH 0350/1007] improve documentation when vmware-iso is used on amazon-import post-processr --- .../post-processors/amazon-import.html.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/website/source/docs/post-processors/amazon-import.html.md b/website/source/docs/post-processors/amazon-import.html.md index 0150d4a70..38ab9bc24 100644 --- a/website/source/docs/post-processors/amazon-import.html.md +++ b/website/source/docs/post-processors/amazon-import.html.md @@ -104,6 +104,38 @@ Here is a basic example. This assumes that the builder has produced an OVA artif } ``` +## VMWare Example + +This is an example that uses `vmware-iso` builder and export the `.ova` file using ovftool. + +``` json +"post-processors" : [ + [ + { + "type": "shell-local", + "inline": [ "/usr/bin/ovftool <packer-output-directory>/<vmware-name>.vmx <packer-output-directory>/<vmware-name>.ova" ] + }, + { + "files": [ + "<packer-output-directory>/<vmware-name>.ova" + ], + "type": "artifice" + }, + { + "type": "amazon-import", + "access_key": "YOUR KEY HERE", + "secret_key": "YOUR SECRET KEY HERE", + "region": "us-east-1", + "s3_bucket_name": "importbucket", + "license_type": "BYOL", + "tags": { + "Description": "packer amazon-import {{timestamp}}" + } + } + ] + ] +``` + -&gt; **Note:** Packer can also read the access key and secret access key from environmental variables. See the configuration reference in the section above for more information on what environmental variables Packer will look for. From e164621bfe6b57d9893ec2ceebe53df528fe1d58 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 5 Jan 2018 09:19:38 -0800 Subject: [PATCH 0351/1007] log line to help prevent confusion when guest_additions_url is set from env variable that is empty --- builder/virtualbox/common/step_download_guest_additions.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index e73642703..93f3952c2 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -85,6 +85,7 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste // If this resulted in an empty url, then ask the driver about it. if url == "" { + log.Printf("guest_additions_url is blank; querying driver for iso.") url, err = driver.Iso() if err == nil { From a3d5d40f78bfa16b04ee5b48d08363fe5ce98270 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 5 Jan 2018 11:06:26 -0800 Subject: [PATCH 0352/1007] reformat TestDownloadableURL into a table test to allow adding more URLS --- common/config_test.go | 59 +++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/common/config_test.go b/common/config_test.go index 8bd684739..23aa25dd1 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -38,36 +38,39 @@ func TestChooseString(t *testing.T) { } func TestDownloadableURL(t *testing.T) { - // Invalid URL: has hex code in host - _, err := DownloadableURL("http://what%20.com") - if err == nil { - t.Fatal("expected err") + + cases := []struct { + InputString string + OutputURL string + ErrExpected bool + }{ + // Invalid URL: has hex code in host + {"http://what%20.com", "", true}, + // Valid: http + {"HTTP://packer.io/path", "http://packer.io/path", false}, + // No path + {"HTTP://packer.io", "http://packer.io", false}, + // Invalid: unsupported scheme + {"ftp://host.com/path", "", true}, } - // Invalid: unsupported scheme - _, err = DownloadableURL("ftp://host.com/path") - if err == nil { - t.Fatal("expected err") - } - - // Valid: http - u, err := DownloadableURL("HTTP://packer.io/path") - if err != nil { - t.Fatalf("err: %s", err) - } - - if u != "http://packer.io/path" { - t.Fatalf("bad: %s", u) - } - - // No path - u, err = DownloadableURL("HTTP://packer.io") - if err != nil { - t.Fatalf("err: %s", err) - } - - if u != "http://packer.io" { - t.Fatalf("bad: %s", u) + for _, tc := range cases { + u, err := DownloadableURL(tc.InputString) + if u != tc.OutputURL { + t.Fatal(fmt.Sprintf("Error with URL %s: got %s but expected %s", + tc.InputString, tc.OutputURL, u)) + } + if (err != nil) != tc.ErrExpected { + if tc.ErrExpected == true { + t.Fatal(fmt.Sprintf("Error with URL %s: we expected "+ + "DownloadableURL to return an error but didn't get one.", + tc.InputString)) + } else { + t.Fatal(fmt.Sprintf("Error with URL %s: we did not expect an "+ + " error from DownloadableURL but we got: %s", + tc.InputString, err)) + } + } } } From 37ab70c4ae5e4b14fb43755726e0a243ebb4e31d Mon Sep 17 00:00:00 2001 From: Rickard von Essen <rickard.von.essen@gmail.com> Date: Sat, 6 Jan 2018 11:23:41 +0100 Subject: [PATCH 0353/1007] Updated CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9815039e7..48cafdcfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,12 @@ * builder/docker: Remove credentials from being shown in the log. [GH-5666] * builder/triton: Triton RBAC is now supported. [GH-5741] +* provisioner/ansible: Improve user retrieval. [GH-5758] * post-processor/docker: Remove credentials from being shown in the log. [GH-5666] * builder/amazon: Warn during prepare if we didn't get both an access key and a secret key when we were expecting one. [GH-5762] ### BUG FIXES: + * builder/alicloud-ecs: Attach keypair before starting instance in alicloud builder [GH-5739] ## 1.1.3 (December 8, 2017) From ccf404ea754f5c5bf5a1a3ce3d3642bc118692db Mon Sep 17 00:00:00 2001 From: lmayorga <lmayorga@lm3corp.com> Date: Sat, 6 Jan 2018 13:13:19 -0500 Subject: [PATCH 0354/1007] fix typo --- website/source/docs/post-processors/amazon-import.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/post-processors/amazon-import.html.md b/website/source/docs/post-processors/amazon-import.html.md index 38ab9bc24..85d139093 100644 --- a/website/source/docs/post-processors/amazon-import.html.md +++ b/website/source/docs/post-processors/amazon-import.html.md @@ -106,7 +106,7 @@ Here is a basic example. This assumes that the builder has produced an OVA artif ## VMWare Example -This is an example that uses `vmware-iso` builder and export the `.ova` file using ovftool. +This is an example that uses `vmware-iso` builder and exports the `.ova` file using ovftool. ``` json "post-processors" : [ From dfd5f0714562285cfdd3c5716bf99420f6e834c3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 8 Jan 2018 11:54:33 -0800 Subject: [PATCH 0355/1007] fix ebs acc test --- CONTRIBUTING.md | 6 +++++ builder/amazon/ebs/builder_acc_test.go | 32 +++++++++++--------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index acababe3f..85c0e04dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -153,6 +153,12 @@ specific package / folder. The `TESTARGS` variable is recommended to filter down to a specific resource to test, since testing all of them at once can sometimes take a very long time. +To run only a specific test, use the `-run` argument: + +``` +make testacc TEST=./builder/amazon/ebs TESTARGS="-run TestBuilderAcc_forceDeleteSnapshot" +``` + Acceptance tests typically require other environment variables to be set for things such as API tokens and keys. Each test should error and tell you which credentials are missing, so those are not documented here. diff --git a/builder/amazon/ebs/builder_acc_test.go b/builder/amazon/ebs/builder_acc_test.go index 9ea9c87f9..b42472a39 100644 --- a/builder/amazon/ebs/builder_acc_test.go +++ b/builder/amazon/ebs/builder_acc_test.go @@ -1,8 +1,11 @@ +/* +Deregister the test image with +aws ec2 deregister-image --image-id $(aws ec2 describe-images --output text --filters "Name=name,Values=packer-test-packer-test-dereg" --query 'Images[*].{ID:ImageId}') +*/ package ebs import ( "fmt" - "os" "testing" "github.com/aws/aws-sdk-go/aws" @@ -58,14 +61,14 @@ func TestBuilderAcc_forceDeleteSnapshot(t *testing.T) { // Get image data by AMI name ec2conn, _ := testEC2Conn() - imageResp, _ := ec2conn.DescribeImages( - &ec2.DescribeImagesInput{Filters: []*ec2.Filter{ - { - Name: aws.String("name"), - Values: []*string{aws.String(amiName)}, - }, - }}, - ) + describeInput := &ec2.DescribeImagesInput{Filters: []*ec2.Filter{ + { + Name: aws.String("name"), + Values: []*string{aws.String(amiName)}, + }, + }} + ec2conn.WaitUntilImageExists(describeInput) + imageResp, _ := ec2conn.DescribeImages(describeInput) image := imageResp.Images[0] // Get snapshot ids for image @@ -243,13 +246,6 @@ func checkBootEncrypted() builderT.TestCheckFunc { } func testAccPreCheck(t *testing.T) { - if v := os.Getenv("AWS_ACCESS_KEY_ID"); v == "" { - t.Fatal("AWS_ACCESS_KEY_ID must be set for acceptance tests") - } - - if v := os.Getenv("AWS_SECRET_ACCESS_KEY"); v == "" { - t.Fatal("AWS_SECRET_ACCESS_KEY must be set for acceptance tests") - } } func testEC2Conn() (*ec2.EC2, error) { @@ -298,7 +294,7 @@ const testBuilderAccForceDeregister = ` "source_ami": "ami-76b2a71e", "ssh_username": "ubuntu", "force_deregister": "%s", - "ami_name": "packer-test-%s" + "ami_name": "%s" }] } ` @@ -313,7 +309,7 @@ const testBuilderAccForceDeleteSnapshot = ` "ssh_username": "ubuntu", "force_deregister": "%s", "force_delete_snapshot": "%s", - "ami_name": "packer-test-%s" + "ami_name": "%s" }] } ` From e4c1805f8128cb9ff079c7df5a2603688dd1074f Mon Sep 17 00:00:00 2001 From: Justin Campbell <justin@justincampbell.me> Date: Tue, 9 Jan 2018 13:11:22 -0500 Subject: [PATCH 0356/1007] Update hashicorp-middleman to 0.3.29 Also includes Nokogiri 1.8.1, to fix https://github.com/hashicorp/packer/network/dependencies#30455077 --- website/Gemfile | 2 +- website/Gemfile.lock | 46 ++++++++++++++++++++++---------------------- website/Makefile | 2 +- website/packer.json | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/website/Gemfile b/website/Gemfile index a2c4d1525..bb10a536e 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.28" +gem "middleman-hashicorp", "0.3.29" diff --git a/website/Gemfile.lock b/website/Gemfile.lock index dea170939..3f43b760a 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -1,12 +1,12 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.8) + activesupport (4.2.10) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (7.1.1.2) + autoprefixer-rails (7.2.4) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -39,10 +39,10 @@ GEM eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) erubis (2.7.0) - eventmachine (1.2.3) + eventmachine (1.2.5) execjs (2.7.0) ffi (1.9.18) - haml (5.0.1) + haml (5.0.4) temple (>= 0.8.0) tilt hike (1.2.3) @@ -51,7 +51,7 @@ GEM http_parser.rb (0.6.0) i18n (0.7.0) json (2.1.0) - kramdown (1.13.2) + kramdown (1.16.2) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -78,7 +78,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.28) + middleman-hashicorp (0.3.29) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -101,11 +101,11 @@ GEM mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) - mini_portile2 (2.2.0) - minitest (5.10.2) - multi_json (1.12.1) - nokogiri (1.8.0) - mini_portile2 (~> 2.2.0) + mini_portile2 (2.3.0) + minitest (5.11.1) + multi_json (1.13.0) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) padrino-helpers (0.12.8.1) i18n (~> 0.6, >= 0.6.7) padrino-support (= 0.12.8.1) @@ -115,14 +115,14 @@ GEM rack (1.6.8) rack-livereload (0.3.16) rack - rack-test (0.6.3) - rack (>= 1.0) - rb-fsevent (0.9.8) + rack-test (0.8.2) + rack (>= 1.0, < 3) + rb-fsevent (0.10.2) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) redcarpet (3.4.0) - rouge (2.1.1) - sass (3.4.24) + rouge (2.2.1) + sass (3.4.25) sprockets (2.12.4) hike (~> 1.2) multi_json (~> 1.0) @@ -134,13 +134,13 @@ GEM sprockets (~> 2.0) tilt (~> 1.1) temple (0.8.0) - thor (0.19.4) + thor (0.20.0) thread_safe (0.3.6) tilt (1.4.1) - turbolinks (5.0.1) - turbolinks-source (~> 5) - turbolinks-source (5.0.3) - tzinfo (1.2.3) + turbolinks (5.1.0) + turbolinks-source (~> 5.1) + turbolinks-source (5.1.0) + tzinfo (1.2.4) thread_safe (~> 0.1) uber (0.0.15) uglifier (2.7.2) @@ -153,7 +153,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.28) + middleman-hashicorp (= 0.3.29) BUNDLED WITH - 1.15.1 + 1.16.1 diff --git a/website/Makefile b/website/Makefile index 4d3d361b7..ccc3ae634 100644 --- a/website/Makefile +++ b/website/Makefile @@ -1,4 +1,4 @@ -VERSION?="0.3.28" +VERSION?="0.3.29" build: @echo "==> Starting build in Docker..." diff --git a/website/packer.json b/website/packer.json index fd2618f17..cbfb5c565 100644 --- a/website/packer.json +++ b/website/packer.json @@ -8,7 +8,7 @@ "builders": [ { "type": "docker", - "image": "hashicorp/middleman-hashicorp:0.3.28", + "image": "hashicorp/middleman-hashicorp:0.3.29", "discard": "true", "volumes": { "{{ pwd }}": "/website" From 2e8561a28d1b4a643c855201bd094f7fe0876d07 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 9 Jan 2018 11:39:55 -0800 Subject: [PATCH 0357/1007] update middleman-hashicorp --- website/Gemfile | 2 +- website/Gemfile.lock | 44 ++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/website/Gemfile b/website/Gemfile index a2c4d1525..bb10a536e 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.28" +gem "middleman-hashicorp", "0.3.29" diff --git a/website/Gemfile.lock b/website/Gemfile.lock index dea170939..e7076767b 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -1,12 +1,12 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.8) + activesupport (4.2.10) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (7.1.1.2) + autoprefixer-rails (7.2.4) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -39,10 +39,10 @@ GEM eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) erubis (2.7.0) - eventmachine (1.2.3) + eventmachine (1.2.5) execjs (2.7.0) ffi (1.9.18) - haml (5.0.1) + haml (5.0.4) temple (>= 0.8.0) tilt hike (1.2.3) @@ -51,7 +51,7 @@ GEM http_parser.rb (0.6.0) i18n (0.7.0) json (2.1.0) - kramdown (1.13.2) + kramdown (1.16.2) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -78,7 +78,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.28) + middleman-hashicorp (0.3.29) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -101,11 +101,11 @@ GEM mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) - mini_portile2 (2.2.0) - minitest (5.10.2) - multi_json (1.12.1) - nokogiri (1.8.0) - mini_portile2 (~> 2.2.0) + mini_portile2 (2.3.0) + minitest (5.11.1) + multi_json (1.13.0) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) padrino-helpers (0.12.8.1) i18n (~> 0.6, >= 0.6.7) padrino-support (= 0.12.8.1) @@ -115,14 +115,14 @@ GEM rack (1.6.8) rack-livereload (0.3.16) rack - rack-test (0.6.3) - rack (>= 1.0) - rb-fsevent (0.9.8) + rack-test (0.8.2) + rack (>= 1.0, < 3) + rb-fsevent (0.10.2) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) redcarpet (3.4.0) - rouge (2.1.1) - sass (3.4.24) + rouge (2.2.1) + sass (3.4.25) sprockets (2.12.4) hike (~> 1.2) multi_json (~> 1.0) @@ -134,13 +134,13 @@ GEM sprockets (~> 2.0) tilt (~> 1.1) temple (0.8.0) - thor (0.19.4) + thor (0.20.0) thread_safe (0.3.6) tilt (1.4.1) - turbolinks (5.0.1) - turbolinks-source (~> 5) - turbolinks-source (5.0.3) - tzinfo (1.2.3) + turbolinks (5.1.0) + turbolinks-source (~> 5.1) + turbolinks-source (5.1.0) + tzinfo (1.2.4) thread_safe (~> 0.1) uber (0.0.15) uglifier (2.7.2) @@ -153,7 +153,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.28) + middleman-hashicorp (= 0.3.29) BUNDLED WITH 1.15.1 From 216c44b153e92752580a682073881b65238c6ad6 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 4 Jan 2018 10:51:59 -0800 Subject: [PATCH 0358/1007] fix FileExistsLocally --- builder/virtualbox/ovf/config.go | 2 +- common/config.go | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 9c6d5dd06..ab8eccc41 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -101,7 +101,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { if err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) } - fileExists, err := common.FileExistsLocally(c.SourcePath) + _, err := common.FileExistsLocally(c.SourcePath) if err != nil { packer.MultiErrorAppend(errs, fmt.Errorf("Source file needs to exist at time of config validation: %s", err)) diff --git a/common/config.go b/common/config.go index c9c8f9e7a..7f05f7f60 100644 --- a/common/config.go +++ b/common/config.go @@ -47,6 +47,7 @@ func ChooseString(vals ...string) string { // a completely valid URL. For example, the original URL might be "local/file.iso" // which isn't a valid URL. DownloadableURL will return "file:///local/file.iso" func DownloadableURL(original string) (string, error) { + fmt.Printf("Swampy: user input was %s\n", original) if runtime.GOOS == "windows" { // If the distance to the first ":" is just one character, assume // we're dealing with a drive letter and thus a file path. @@ -89,7 +90,7 @@ func DownloadableURL(original string) (string, error) { return "", err } - url.Path = filepath.Clean(url.Path) + // url.Path = filepath.Clean(url.Path) } if runtime.GOOS == "windows" { @@ -116,7 +117,7 @@ func DownloadableURL(original string) (string, error) { if !found { return "", fmt.Errorf("Unsupported URL scheme: %s", url.Scheme) } - + fmt.Printf("Swampy: parsed string after DownloadableURL is %s\n", url.String()) return url.String(), nil } @@ -136,20 +137,21 @@ func DownloadableURL(original string) (string, error) { // file is not present when it should be. func FileExistsLocally(original string) (bool, error) { - fileURL, _ := url.Parse(original) - fileExists := false - err := nil + // original should be something like file://C:/my/path.iso + // on windows, c drive will be parsed as host if it's file://c instead of file:///c + prefix = "file://" + filePath = strings.Replace(original, prefix, "", 1) + fmt.Printf("Swampy: original is %s\n", original) + fmt.Printf("Swampy: filePath is %#v\n", filePath) if fileURL.Scheme == "file" { - // Remove forward slash on absolute Windows file URLs before processing - if runtime.GOOS == "windows" && len(fileURL.Path) > 0 && fileURL.Path[0] == '/' { - filePath := fileURL.Path[1:] - } - if _, err := os.Stat(filePath); err != nil { - err = fmt.Errorf("source file needs to exist at time of config validation: %s", err) + _, err := os.Stat(filePath) + if err != nil { + err = fmt.Errorf("could not stat file: %s\n", err) + return fileExists, err } else { fileExists = true } } - return fileExists, err + return fileExists, nil } From 2838a2371dc98237f506da305af1b98d407149a8 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 9 Jan 2018 14:27:09 -0800 Subject: [PATCH 0359/1007] disambiguate url variable from url library --- common/config.go | 65 ++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/common/config.go b/common/config.go index 7f05f7f60..3f618e58a 100644 --- a/common/config.go +++ b/common/config.go @@ -47,78 +47,87 @@ func ChooseString(vals ...string) string { // a completely valid URL. For example, the original URL might be "local/file.iso" // which isn't a valid URL. DownloadableURL will return "file:///local/file.iso" func DownloadableURL(original string) (string, error) { - fmt.Printf("Swampy: user input was %s\n", original) if runtime.GOOS == "windows" { // If the distance to the first ":" is just one character, assume // we're dealing with a drive letter and thus a file path. + // prepend with "file:///"" now so that url.Parse won't accidentally + // parse the drive letter into the url scheme. + // See https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/ + // for more info about valid windows URIs idx := strings.Index(original, ":") if idx == 1 { original = "file:///" + original } } - - url, err := url.Parse(original) + u, err := url.Parse(original) if err != nil { return "", err } - if url.Scheme == "" { - url.Scheme = "file" + if u.Scheme == "" { + u.Scheme = "file" } - if url.Scheme == "file" { + if u.Scheme == "file" { // Windows file handling is all sorts of tricky... if runtime.GOOS == "windows" { // If the path is using Windows-style slashes, URL parses // it into the host field. - if url.Path == "" && strings.Contains(url.Host, `\`) { - url.Path = url.Host - url.Host = "" + if u.Path == "" && strings.Contains(u.Host, `\`) { + u.Path = u.Host + u.Host = "" } } // Only do the filepath transformations if the file appears // to actually exist. - if _, err := os.Stat(url.Path); err == nil { - url.Path, err = filepath.Abs(url.Path) + if _, err := os.Stat(u.Path); err == nil { + u.Path, err = filepath.Abs(u.Path) if err != nil { return "", err } - url.Path, err = filepath.EvalSymlinks(url.Path) + u.Path, err = filepath.EvalSymlinks(u.Path) if err != nil { return "", err } - // url.Path = filepath.Clean(url.Path) + u.Path = filepath.Clean(u.Path) } if runtime.GOOS == "windows" { // Also replace all backslashes with forwardslashes since Windows // users are likely to do this but the URL should actually only // contain forward slashes. - url.Path = strings.Replace(url.Path, `\`, `/`, -1) + u.Path = strings.Replace(u.Path, `\`, `/`, -1) + // prepend absolute windows paths with "/" so that when we + // compose u.String() below the outcome will be correct + // file:///c/blah syntax; otherwise u.String() will only add + // file:// which is not technically a correct windows URI + if filepath.IsAbs(u.Path) && !strings.HasPrefix(u.Path, "/") { + u.Path = "/" + u.Path + } + } } // Make sure it is lowercased - url.Scheme = strings.ToLower(url.Scheme) + u.Scheme = strings.ToLower(u.Scheme) // Verify that the scheme is something we support in our common downloader. supported := []string{"file", "http", "https"} found := false for _, s := range supported { - if url.Scheme == s { + if u.Scheme == s { found = true break } } if !found { - return "", fmt.Errorf("Unsupported URL scheme: %s", url.Scheme) + return "", fmt.Errorf("Unsupported URL scheme: %s", u.Scheme) } - fmt.Printf("Swampy: parsed string after DownloadableURL is %s\n", url.String()) - return url.String(), nil + return u.String(), nil } // FileExistsLocally takes the URL output from DownloadableURL, and determines @@ -138,13 +147,21 @@ func DownloadableURL(original string) (string, error) { func FileExistsLocally(original string) (bool, error) { // original should be something like file://C:/my/path.iso - // on windows, c drive will be parsed as host if it's file://c instead of file:///c - prefix = "file://" - filePath = strings.Replace(original, prefix, "", 1) - fmt.Printf("Swampy: original is %s\n", original) - fmt.Printf("Swampy: filePath is %#v\n", filePath) + + fileURL, _ := url.Parse(original) + fileExists := false if fileURL.Scheme == "file" { + // on windows, correct URI is file:///c:/blah/blah.iso. + // url.Parse will pull out the scheme "file://" and leave the path as + // "/c:/blah/blah/iso". Here we remove this forward slash on absolute + // Windows file URLs before processing + // see https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/ + // for more info about valid windows URIs + filePath := fileURL.Path + if runtime.GOOS == "windows" && len(filePath) > 0 && filePath[0] == '/' { + filePath = filePath[1:] + } _, err := os.Stat(filePath) if err != nil { err = fmt.Errorf("could not stat file: %s\n", err) From 40f0cc6dfe00b8da21db8de73ea285134ded6f17 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 9 Jan 2018 15:53:54 -0800 Subject: [PATCH 0360/1007] I don't think this is needed anymore --- common/config.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/common/config.go b/common/config.go index 3f618e58a..5ef4d3369 100644 --- a/common/config.go +++ b/common/config.go @@ -69,16 +69,6 @@ func DownloadableURL(original string) (string, error) { } if u.Scheme == "file" { - // Windows file handling is all sorts of tricky... - if runtime.GOOS == "windows" { - // If the path is using Windows-style slashes, URL parses - // it into the host field. - if u.Path == "" && strings.Contains(u.Host, `\`) { - u.Path = u.Host - u.Host = "" - } - } - // Only do the filepath transformations if the file appears // to actually exist. if _, err := os.Stat(u.Path); err == nil { From 154973241f65913b843544de044df153a23eab7e Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 9 Jan 2018 16:11:29 -0800 Subject: [PATCH 0361/1007] add a bunch of windows filepath tests --- common/config_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/common/config_test.go b/common/config_test.go index 8bd684739..1a3920733 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -71,6 +71,67 @@ func TestDownloadableURL(t *testing.T) { } } +func TestDownloadableURL_WindowsFiles(t *testing.T) { + if runtime.GOOS == "windows" { + dirCases := []struct { + InputString string + OutputURL string + ErrExpected bool + }{ // TODO: add different directories + { + "C:\\Temp\\SomeDir\\myfile.txt", + "file:///C:/Temp/SomeDir/myfile.txt", + false, + }, + { // need windows drive + "\\Temp\\SomeDir\\myfile.txt", + "", + true, + }, + { // need windows drive + "/Temp/SomeDir/myfile.txt", + "", + true, + }, + { + "file:///C:\\Temp\\SomeDir\\myfile.txt", + "file:///c:/Temp/SomeDir/myfile.txt", + false, + }, + { + "file:///c:/Temp/Somedir/myfile.txt", + "file:///c:/Temp/SomeDir/myfile.txt", + false, + }, + } + // create absolute-pathed tempfile to play with + err := os.Mkdir("C:\\Temp\\SomeDir", 0755) + if err != nil { + t.Fatalf("err creating test dir: %s", err) + } + fi, err := os.Create("C:\\Temp\\SomeDir\\myfile.txt") + if err != nil { + t.Fatalf("err creating test file: %s", err) + } + fi.Close() + defer os.Remove("C:\\Temp\\SomeDir\\myfile.txt") + defer os.Remove("C:\\Temp\\SomeDir") + + // Run through test cases to make sure they all parse correctly + for _, tc := range dirCases { + u, err := DownloadableURL(tc.InputString) + if (err != nil) != tc.ErrExpected { + t.Fatalf("Test Case failed: Expected err = %#v, err = %#v, input = %s", + tc.ErrExpected, err, tc.InputString) + } + if u != tc.OutputURL { + t.Fatalf("Test Case failed: Expected %s but received %s from input %s", + tc.OutputURL, u, tc.InputString) + } + } + } +} + func TestDownloadableURL_FilePaths(t *testing.T) { tf, err := ioutil.TempFile("", "packer") if err != nil { From a04a921c2d04d88bd4b6dedd15ed7e1ad119ca09 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 9 Jan 2018 17:14:32 -0800 Subject: [PATCH 0362/1007] add UNC path to test cases, so I can try to enable it in future --- common/config_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/config_test.go b/common/config_test.go index 1a3920733..ad577b3b0 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -93,6 +93,11 @@ func TestDownloadableURL_WindowsFiles(t *testing.T) { "", true, }, + { // UNC paths; why not? + "\\\\?\\c:\\Temp\\SomeDir\\myfile.txt", + "", + true, + }, { "file:///C:\\Temp\\SomeDir\\myfile.txt", "file:///c:/Temp/SomeDir/myfile.txt", From 38b1cdd8c412843987f553ccfbe2fcbc9fd63b0a Mon Sep 17 00:00:00 2001 From: Diego Goding <diego.goding@gmail.com> Date: Wed, 10 Jan 2018 08:56:59 -0600 Subject: [PATCH 0363/1007] fixed issue 5779 --- website/source/docs/builders/amazon-ebsvolume.html.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index b500aa2bd..319021e5e 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -121,15 +121,6 @@ builder. profiles](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-profiles) for more details. -- `region_kms_key_ids` (map of strings) - a map of regions to copy the ami to, - along with the custom kms key id to use for encryption for that region. - Keys must match the regions provided in `ami_regions`. If you just want to - encrypt using a default ID, you can stick with `kms_key_id` and `ami_regions`. - If you want a region to be encrypted with that region's default key ID, you can - use an empty string `""` instead of a key id in this map. (e.g. `"us-east-1": ""`) - However, you cannot use default key IDs if you are using this in conjunction with - `snapshot_users` -- in that situation you must use custom keys. - - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a From 898dadd53c3011e05764e32f2936ae6e95f3e8b3 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 10 Jan 2018 10:03:36 -0800 Subject: [PATCH 0364/1007] re-add this block. I still don't think we need it but I don't want to risk breaking things with this bugfix. --- common/config.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/common/config.go b/common/config.go index 5ef4d3369..f1666058c 100644 --- a/common/config.go +++ b/common/config.go @@ -69,6 +69,15 @@ func DownloadableURL(original string) (string, error) { } if u.Scheme == "file" { + // Windows file handling is all sorts of tricky... + if runtime.GOOS == "windows" { + // If the path is using Windows-style slashes, URL parses + // it into the host field. + if url.Path == "" && strings.Contains(url.Host, `\`) { + url.Path = url.Host + url.Host = "" + } + } // Only do the filepath transformations if the file appears // to actually exist. if _, err := os.Stat(u.Path); err == nil { From 55ddbf476574fcef8344f2cafc6703e3673c158a Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 10 Jan 2018 10:08:23 -0800 Subject: [PATCH 0365/1007] sloppy copypasta --- common/config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/config.go b/common/config.go index f1666058c..2b0de0c5c 100644 --- a/common/config.go +++ b/common/config.go @@ -73,9 +73,9 @@ func DownloadableURL(original string) (string, error) { if runtime.GOOS == "windows" { // If the path is using Windows-style slashes, URL parses // it into the host field. - if url.Path == "" && strings.Contains(url.Host, `\`) { - url.Path = url.Host - url.Host = "" + if u.Path == "" && strings.Contains(u.Host, `\`) { + u.Path = u.Host + u.Host = "" } } // Only do the filepath transformations if the file appears From f5ea1e8312c8c8dad32ca3d47b265f55dd9e52a3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 8 Jan 2018 14:26:40 -0800 Subject: [PATCH 0366/1007] Use WaitUntilInstanceReady waiter --- builder/amazon/common/step_run_source_instance.go | 9 ++++----- builder/amazon/common/step_run_spot_instance.go | 4 ++-- website/source/docs/builders/amazon.html.md | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 43a63493f..aba0e9ab5 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -175,19 +175,18 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi ui.Message(fmt.Sprintf("Instance ID: %s", instanceId)) ui.Say(fmt.Sprintf("Waiting for instance (%v) to become ready...", instanceId)) - describeInstanceStatus := &ec2.DescribeInstanceStatusInput{ + describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - if err := ec2conn.WaitUntilInstanceStatusOk(describeInstanceStatus); err != nil { + if err := ec2conn.WaitUntilInstanceRunning(describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - r, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesInput{ - InstanceIds: []*string{aws.String(instanceId)}, - }) + r, err := ec2conn.DescribeInstances(describeInstance) + if err != nil || len(r.Reservations) == 0 || len(r.Reservations[0].Instances) == 0 { err := fmt.Errorf("Error finding source instance.") state.Put("error", err) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 323032de0..27938ece6 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -231,10 +231,10 @@ func (s *StepRunSpotInstance) Run(state multistep.StateBag) multistep.StepAction ui.Message(fmt.Sprintf("Instance ID: %s", instanceId)) ui.Say(fmt.Sprintf("Waiting for instance (%v) to become ready...", instanceId)) - describeInstanceStatus := &ec2.DescribeInstanceStatusInput{ + describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - if err := ec2conn.WaitUntilInstanceStatusOk(describeInstanceStatus); err != nil { + if err := ec2conn.WaitUntilInstanceRunning(describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index e77e4bf79..8873dfcbe 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -115,7 +115,6 @@ Packer to work: "ec2:DeregisterImage", "ec2:DescribeImageAttribute", "ec2:DescribeImages", - "ec2:DescribeInstanceStatus", "ec2:DescribeInstances", "ec2:DescribeRegions", "ec2:DescribeSecurityGroups", From 3ace5bb91becc645dd8acfa0fca0199e8ceed115 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 10 Jan 2018 16:11:17 -0800 Subject: [PATCH 0367/1007] simplify FileExistsLocally --- builder/virtualbox/ovf/config.go | 6 +++--- common/config.go | 17 +++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index ab8eccc41..41a013ebd 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -101,10 +101,10 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { if err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) } - _, err := common.FileExistsLocally(c.SourcePath) - if err != nil { + fileOK := common.FileExistsLocally(c.SourcePath) + if !fileOK { packer.MultiErrorAppend(errs, - fmt.Errorf("Source file needs to exist at time of config validation: %s", err)) + fmt.Errorf("Source file needs to exist at time of config validation!")) } } diff --git a/common/config.go b/common/config.go index 2b0de0c5c..7bef253ee 100644 --- a/common/config.go +++ b/common/config.go @@ -135,16 +135,14 @@ func DownloadableURL(original string) (string, error) { // // myFile, err = common.DownloadableURL(c.SourcePath) // ... -// fileExists, err := common.StatURL(myFile) +// fileExists := common.StatURL(myFile) // possible output: -// true, nil -- should occur if the file is present -// false, nil -- should occur if the file is not present, but is not supposed to -// be (e.g. the schema is http://, not file://) -// true, error -- shouldn't occur ever -// false, error -- should occur if there was an error stating the file, so the +// true -- should occur if the file is present, or if the file is not present, +// but is not supposed to be (e.g. the schema is http://, not file://) +// false -- should occur if there was an error stating the file, so the // file is not present when it should be. -func FileExistsLocally(original string) (bool, error) { +func FileExistsLocally(original string) bool { // original should be something like file://C:/my/path.iso fileURL, _ := url.Parse(original) @@ -163,11 +161,10 @@ func FileExistsLocally(original string) (bool, error) { } _, err := os.Stat(filePath) if err != nil { - err = fmt.Errorf("could not stat file: %s\n", err) - return fileExists, err + return fileExists } else { fileExists = true } } - return fileExists, nil + return fileExists } From bdd186fa2b2b0465f507a6f05de10a13ce691ef6 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 10 Jan 2018 16:44:27 -0800 Subject: [PATCH 0368/1007] add tests for fileexistslocally helper function --- common/config_test.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/common/config_test.go b/common/config_test.go index ad577b3b0..0320b86fe 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -208,6 +208,43 @@ func TestDownloadableURL_FilePaths(t *testing.T) { } } +func test_FileExistsLocally(t *testing.T) { + if runtime.GOOS == "windows" { + dirCases := []struct { + Input string + Output bool + }{ + // file exists locally + {"file:///C:/Temp/SomeDir/myfile.txt", true}, + // file is not supposed to exist locally + {"https://myfile.iso", true}, + // file does not exist locally + {"file:///C/i/dont/exist", false}, + } + // create absolute-pathed tempfile to play with + err := os.Mkdir("C:\\Temp\\SomeDir", 0755) + if err != nil { + t.Fatalf("err creating test dir: %s", err) + } + fi, err := os.Create("C:\\Temp\\SomeDir\\myfile.txt") + if err != nil { + t.Fatalf("err creating test file: %s", err) + } + fi.Close() + defer os.Remove("C:\\Temp\\SomeDir\\myfile.txt") + defer os.Remove("C:\\Temp\\SomeDir") + + // Run through test cases to make sure they all parse correctly + for _, tc := range dirCases { + fileOK := FileExistsLocally(tc.Input) + if !fileOK { + t.Fatalf("Test Case failed: Expected %#v, received = %#v, input = %s", + tc.Output, fileOK, tc.Input) + } + } + } +} + func TestScrubConfig(t *testing.T) { type Inner struct { Baz string From 5189d65467d9fe857fe1f286c2649c1e1f0063ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Thu, 11 Jan 2018 18:57:53 +0900 Subject: [PATCH 0369/1007] Support Naver Cloud Platform --- builder/ncloud/artifact.go | 46 +++ builder/ncloud/builder.go | 117 ++++++++ builder/ncloud/config.go | 114 ++++++++ builder/ncloud/config_test.go | 149 ++++++++++ builder/ncloud/ssh.go | 30 ++ builder/ncloud/step.go | 16 ++ .../step_create_block_storage_instance.go | 101 +++++++ ...step_create_block_storage_instance_test.go | 62 +++++ builder/ncloud/step_create_login_key.go | 71 +++++ builder/ncloud/step_create_login_key_test.go | 53 ++++ .../ncloud/step_create_public_ip_instance.go | 167 +++++++++++ .../step_create_public_ip_instance_test.go | 62 +++++ builder/ncloud/step_create_server_image.go | 77 +++++ .../ncloud/step_create_server_image_test.go | 58 ++++ builder/ncloud/step_create_server_instance.go | 129 +++++++++ .../step_create_server_instance_test.go | 58 ++++ .../step_delete_block_storage_instance.go | 95 +++++++ ...step_delete_block_storage_instance_test.go | 57 ++++ builder/ncloud/step_delete_login_key.go | 51 ++++ builder/ncloud/step_delete_login_key_test.go | 55 ++++ .../ncloud/step_delete_public_ip_instance.go | 78 ++++++ .../step_delete_public_ip_instance_test.go | 57 ++++ builder/ncloud/step_get_rootpassword.go | 57 ++++ builder/ncloud/step_get_rootpassword_test.go | 56 ++++ builder/ncloud/step_stop_server_instance.go | 64 +++++ .../ncloud/step_stop_server_instance_test.go | 55 ++++ .../ncloud/step_terminate_server_instance.go | 81 ++++++ .../step_terminate_server_instance_test.go | 54 ++++ builder/ncloud/step_validate_template.go | 263 ++++++++++++++++++ builder/ncloud/step_validate_template_test.go | 54 ++++ .../ncloud/waiter_block_storage_instance.go | 80 ++++++ builder/ncloud/waiter_server_image_status.go | 43 +++ .../ncloud/waiter_server_instance_status.go | 43 +++ command/plugin.go | 2 + 34 files changed, 2555 insertions(+) create mode 100644 builder/ncloud/artifact.go create mode 100644 builder/ncloud/builder.go create mode 100644 builder/ncloud/config.go create mode 100644 builder/ncloud/config_test.go create mode 100644 builder/ncloud/ssh.go create mode 100644 builder/ncloud/step.go create mode 100644 builder/ncloud/step_create_block_storage_instance.go create mode 100644 builder/ncloud/step_create_block_storage_instance_test.go create mode 100644 builder/ncloud/step_create_login_key.go create mode 100644 builder/ncloud/step_create_login_key_test.go create mode 100644 builder/ncloud/step_create_public_ip_instance.go create mode 100644 builder/ncloud/step_create_public_ip_instance_test.go create mode 100644 builder/ncloud/step_create_server_image.go create mode 100644 builder/ncloud/step_create_server_image_test.go create mode 100644 builder/ncloud/step_create_server_instance.go create mode 100644 builder/ncloud/step_create_server_instance_test.go create mode 100644 builder/ncloud/step_delete_block_storage_instance.go create mode 100644 builder/ncloud/step_delete_block_storage_instance_test.go create mode 100644 builder/ncloud/step_delete_login_key.go create mode 100644 builder/ncloud/step_delete_login_key_test.go create mode 100644 builder/ncloud/step_delete_public_ip_instance.go create mode 100644 builder/ncloud/step_delete_public_ip_instance_test.go create mode 100644 builder/ncloud/step_get_rootpassword.go create mode 100644 builder/ncloud/step_get_rootpassword_test.go create mode 100644 builder/ncloud/step_stop_server_instance.go create mode 100644 builder/ncloud/step_stop_server_instance_test.go create mode 100644 builder/ncloud/step_terminate_server_instance.go create mode 100644 builder/ncloud/step_terminate_server_instance_test.go create mode 100644 builder/ncloud/step_validate_template.go create mode 100644 builder/ncloud/step_validate_template_test.go create mode 100644 builder/ncloud/waiter_block_storage_instance.go create mode 100644 builder/ncloud/waiter_server_image_status.go create mode 100644 builder/ncloud/waiter_server_instance_status.go diff --git a/builder/ncloud/artifact.go b/builder/ncloud/artifact.go new file mode 100644 index 000000000..52624e437 --- /dev/null +++ b/builder/ncloud/artifact.go @@ -0,0 +1,46 @@ +package ncloud + +import ( + "bytes" + "fmt" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" +) + +const BuilderID = "ncloud.server.image" + +type Artifact struct { + ServerImage *ncloud.ServerImage +} + +func (*Artifact) BuilderId() string { + return BuilderID +} + +func (a *Artifact) Files() []string { + /* no file */ + return nil +} + +func (a *Artifact) Id() string { + return a.ServerImage.MemberServerImageNo +} + +func (a *Artifact) String() string { + var buf bytes.Buffer + + // TODO : Logging artifact information + buf.WriteString(fmt.Sprintf("%s:\n\n", a.BuilderId())) + buf.WriteString(fmt.Sprintf("Member Server Image Name: %s\n", a.ServerImage.MemberServerImageName)) + buf.WriteString(fmt.Sprintf("Member Server Image No: %s\n", a.ServerImage.MemberServerImageNo)) + + return buf.String() +} + +func (a *Artifact) State(name string) interface{} { + return a.ServerImage.MemberServerImageStatus +} + +func (a *Artifact) Destroy() error { + return nil +} diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go new file mode 100644 index 000000000..580514d53 --- /dev/null +++ b/builder/ncloud/builder.go @@ -0,0 +1,117 @@ +package ncloud + +import ( + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +const version = "1.0.0" + +// Builder assume this implements packer.Builder +type Builder struct { + config *Config + stateBag multistep.StateBag + runner multistep.Runner +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + c, warnings, errs := NewConfig(raws...) + if errs != nil { + return warnings, errs + } + b.config = c + + b.stateBag = new(multistep.BasicStateBag) + + return warnings, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + ui.Say("Running builder for Naver Cloud Platform (version: " + version + ") ...") + + ui.Message("Creating Naver Cloud Platform Connection ...") + conn := ncloud.NewConnection(b.config.AccessKey, b.config.SecretKey) + + b.stateBag.Put("hook", hook) + b.stateBag.Put("ui", ui) + + var steps []multistep.Step + + steps = []multistep.Step{} + + if b.config.OSType == "Linux" { + steps = []multistep.Step{ + NewStepValidateTemplate(conn, ui, b.config), + NewStepCreateLoginKey(conn, ui), + NewStepCreateServerInstance(conn, ui, b.config), + NewStepCreateBlockStorageInstance(conn, ui, b.config), + NewStepGetRootPassword(conn, ui), + NewStepCreatePublicIPInstance(conn, ui, b.config), + &communicator.StepConnectSSH{ + Config: &b.config.Comm, + Host: SSHHost, + SSHConfig: SSHConfig(b.config.Comm.SSHUsername), + }, + &common.StepProvision{}, + NewStepStopServerInstance(conn, ui), + NewStepCreateServerImage(conn, ui, b.config), + NewStepDeleteBlockStorageInstance(conn, ui, b.config), + NewStepTerminateServerInstance(conn, ui), + NewStepDeleteLoginKey(conn, ui), + NewStepDeletePublicIPInstance(conn, ui), + } + } else if b.config.OSType == "Windows" { + steps = []multistep.Step{ + NewStepValidateTemplate(conn, ui, b.config), + NewStepCreateLoginKey(conn, ui), + NewStepCreateServerInstance(conn, ui, b.config), + NewStepCreateBlockStorageInstance(conn, ui, b.config), + NewStepGetRootPassword(conn, ui), + NewStepCreatePublicIPInstance(conn, ui, b.config), + &communicator.StepConnectWinRM{ + Config: &b.config.Comm, + Host: func(stateBag multistep.StateBag) (string, error) { + return stateBag.Get("WinRMHost").(string), nil + }, + WinRMConfig: func(state multistep.StateBag) (*communicator.WinRMConfig, error) { + return &communicator.WinRMConfig{ + Username: b.config.Comm.WinRMUser, + Password: state.Get("Password").(string), + }, nil + }, + }, + &common.StepProvision{}, + NewStepStopServerInstance(conn, ui), + NewStepCreateServerImage(conn, ui, b.config), + NewStepDeleteBlockStorageInstance(conn, ui, b.config), + NewStepTerminateServerInstance(conn, ui), + NewStepDeleteLoginKey(conn, ui), + NewStepDeletePublicIPInstance(conn, ui), + } + } + + // Run! + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(b.stateBag) + + // If there was an error, return that + if rawErr, ok := b.stateBag.GetOk("Error"); ok { + return nil, rawErr.(error) + } + + // Build the artifact and return it + artifact := &Artifact{} + + if serverImage, ok := b.stateBag.GetOk("memberServerImage"); ok { + artifact.ServerImage = serverImage.(*ncloud.ServerImage) + } + + return artifact, nil +} + +func (b *Builder) Cancel() { + b.runner.Cancel() +} diff --git a/builder/ncloud/config.go b/builder/ncloud/config.go new file mode 100644 index 000000000..e18ab822d --- /dev/null +++ b/builder/ncloud/config.go @@ -0,0 +1,114 @@ +package ncloud + +import ( + "errors" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +// Config is structure to use packer builder plugin for Naver Cloud Platform +type Config struct { + common.PackerConfig `mapstructure:",squash"` + + AccessKey string `mapstructure:"access_key"` + SecretKey string `mapstructure:"secret_key"` + OSType string `mapstructure:"os_type"` + ServerImageProductCode string `mapstructure:"server_image_product_code"` + ServerProductCode string `mapstructure:"server_product_code"` + MemberServerImageNo string `mapstructure:"member_server_image_no"` + ServerImageName string `mapstructure:"server_image_name"` + ServerImageDescription string `mapstructure:"server_image_description"` + UserData string `mapstructure:"user_data"` + BlockStorageSize int `mapstructure:"block_storage_size"` + Region string `mapstructure:"region"` + AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no"` + FeeSystemTypeCode string `mapstructure:"-"` + + Comm communicator.Config `mapstructure:",squash"` + ctx *interpolate.Context +} + +// NewConfig checks parameters +func NewConfig(raws ...interface{}) (*Config, []string, error) { + c := new(Config) + warnings := []string{} + + err := config.Decode(c, &config.DecodeOpts{ + Interpolate: true, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{}, + }, + }, raws...) + if err != nil { + return nil, warnings, err + } + + var errs *packer.MultiError + if es := c.Comm.Prepare(nil); len(es) > 0 { + errs = packer.MultiErrorAppend(errs, es...) + } + + if c.AccessKey == "" { + errs = packer.MultiErrorAppend(errs, errors.New("access_key is required")) + } + + if c.SecretKey == "" { + errs = packer.MultiErrorAppend(errs, errors.New("secret_key is required")) + } + + if c.OSType != "Linux" && c.OSType != "Windows" { + errs = packer.MultiErrorAppend(errs, errors.New("os_type is required. ('Linux' or 'Windows')")) + } + + if c.MemberServerImageNo == "" && c.ServerImageProductCode == "" { + errs = packer.MultiErrorAppend(errs, errors.New("server_image_product_code or member_server_image_no is required")) + } + + if c.MemberServerImageNo != "" && c.ServerImageProductCode != "" { + errs = packer.MultiErrorAppend(errs, errors.New("Only one of server_image_product_code and member_server_image_no can be set")) + } + + if c.ServerImageProductCode != "" && len(c.ServerImageProductCode) > 20 { + errs = packer.MultiErrorAppend(errs, errors.New("If server_image_product_code field is set, length of server_image_product_code should be max 20")) + } + + if c.ServerProductCode != "" && len(c.ServerProductCode) > 20 { + errs = packer.MultiErrorAppend(errs, errors.New("If server_product_code field is set, length of server_product_code should be max 20")) + } + + if c.ServerImageName != "" && (len(c.ServerImageName) < 3 || len(c.ServerImageName) > 30) { + errs = packer.MultiErrorAppend(errs, errors.New("If server_image_name field is set, length of server_image_name should be min 3 and max 20")) + } + + if c.ServerImageDescription != "" && len(c.ServerImageDescription) > 1000 { + errs = packer.MultiErrorAppend(errs, errors.New("If server_image_description field is set, length of server_image_description should be max 1000")) + } + + if c.BlockStorageSize != 0 { + if c.BlockStorageSize < 10 || c.BlockStorageSize > 2000 { + errs = packer.MultiErrorAppend(errs, errors.New("The size of BlockStorageSize is at least 10 GB and up to 2000GB")) + } else if int(c.BlockStorageSize/10)*10 != c.BlockStorageSize { + return nil, nil, errors.New("BlockStorageSize must be a multiple of 10 GB") + } + } + + if c.UserData != "" && len(c.UserData) > 21847 { + errs = packer.MultiErrorAppend(errs, errors.New("If user_data field is set, length of UserData should be max 21847")) + } + + if c.OSType == "Windows" && c.AccessControlGroupConfigurationNo == "" { + errs = packer.MultiErrorAppend(errs, errors.New("If os_type is Windows, access_control_group_configuration_no is required")) + } + + c.FeeSystemTypeCode = "MTRAT" + + if errs != nil && len(errs.Errors) > 0 { + return nil, warnings, errs + } + + return c, warnings, nil +} diff --git a/builder/ncloud/config_test.go b/builder/ncloud/config_test.go new file mode 100644 index 000000000..7907c7ee1 --- /dev/null +++ b/builder/ncloud/config_test.go @@ -0,0 +1,149 @@ +package ncloud + +import ( + "strings" + "testing" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "access_key": "access_key", + "secret_key": "secret_key", + "os_type": "Windows", + "server_image_product_code": "SPSW0WINNT000016", + "server_product_code": "SPSVRSSD00000011", + "server_image_name": "packer-test {{timestamp}}", + "server_image_description": "server description", + "block_storage_size": 100, + "user_data": "#!/bin/sh\nyum install -y httpd\ntouch /var/www/html/index.html\nchkconfig --level 2345 httpd on", + "region": "Korea", + "access_control_group_configuration_no": "33", + "communicator": "ssh", + "ssh_username": "root", + } +} + +func testConfigForMemberServerImage() map[string]interface{} { + return map[string]interface{}{ + "access_key": "access_key", + "secret_key": "secret_key", + "os_type": "Windows", + "server_product_code": "SPSVRSSD00000011", + "member_server_image_no": "2440", + "server_image_name": "packer-test {{timestamp}}", + "server_image_description": "server description", + "block_storage_size": 100, + "user_data": "#!/bin/sh\nyum install -y httpd\ntouch /var/www/html/index.html\nchkconfig --level 2345 httpd on", + "region": "Korea", + "access_control_group_configuration_no": "33", + "communicator": "ssh", + "ssh_username": "root", + } +} + +func TestConfigWithServerImageProductCode(t *testing.T) { + raw := testConfig() + + c, _, _ := NewConfig(raw) + + if c.AccessKey != "access_key" { + t.Errorf("Expected 'access_key' to be set to '%s', but got '%s'.", raw["access_key"], c.AccessKey) + } + + if c.SecretKey != "secret_key" { + t.Errorf("Expected 'secret_key' to be set to '%s', but got '%s'.", raw["secret_key"], c.SecretKey) + } + + if c.ServerImageProductCode != "SPSW0WINNT000016" { + t.Errorf("Expected 'server_image_product_code' to be set to '%s', but got '%s'.", raw["server_image_product_code"], c.ServerImageProductCode) + } + + if c.ServerProductCode != "SPSVRSSD00000011" { + t.Errorf("Expected 'server_product_code' to be set to '%s', but got '%s'.", raw["server_product_code"], c.ServerProductCode) + } + + if c.BlockStorageSize != 100 { + t.Errorf("Expected 'block_storage_size' to be set to '%d', but got '%d'.", raw["block_storage_size"], c.BlockStorageSize) + } + + if c.ServerImageDescription != "server description" { + t.Errorf("Expected 'server_image_description_key' to be set to '%s', but got '%s'.", raw["server_image_description"], c.ServerImageDescription) + } + + if c.Region != "Korea" { + t.Errorf("Expected 'region' to be set to '%s', but got '%s'.", raw["server_image_description"], c.Region) + } +} + +func TestConfigWithMemberServerImageCode(t *testing.T) { + raw := testConfigForMemberServerImage() + + c, _, _ := NewConfig(raw) + + if c.AccessKey != "access_key" { + t.Errorf("Expected 'access_key' to be set to '%s', but got '%s'.", raw["access_key"], c.AccessKey) + } + + if c.SecretKey != "secret_key" { + t.Errorf("Expected 'secret_key' to be set to '%s', but got '%s'.", raw["secret_key"], c.SecretKey) + } + + if c.MemberServerImageNo != "2440" { + t.Errorf("Expected 'member_server_image_no' to be set to '%s', but got '%s'.", raw["member_server_image_no"], c.MemberServerImageNo) + } + + if c.ServerProductCode != "SPSVRSSD00000011" { + t.Errorf("Expected 'server_product_code' to be set to '%s', but got '%s'.", raw["server_product_code"], c.ServerProductCode) + } + + if c.BlockStorageSize != 100 { + t.Errorf("Expected 'block_storage_size' to be set to '%d', but got '%d'.", raw["block_storage_size"], c.BlockStorageSize) + } + + if c.ServerImageDescription != "server description" { + t.Errorf("Expected 'server_image_description_key' to be set to '%s', but got '%s'.", raw["server_image_description"], c.ServerImageDescription) + } + + if c.Region != "Korea" { + t.Errorf("Expected 'region' to be set to '%s', but got '%s'.", raw["server_image_description"], c.Region) + } +} + +func TestEmptyConfig(t *testing.T) { + raw := new(map[string]interface{}) + + _, _, err := NewConfig(raw) + + if err == nil { + t.Error("Expected Config to require 'access_key', 'secret_key' and some mendatory fields, but it did not") + } + + if !strings.Contains(err.Error(), "access_key is required") { + t.Error("Expected Config to require 'access_key', but it did not") + } + + if !strings.Contains(err.Error(), "secret_key is required") { + t.Error("Expected Config to require 'secret_key', but it did not") + } + + if !strings.Contains(err.Error(), "server_image_product_code or member_server_image_no is required") { + t.Error("Expected Config to require 'server_image_product_code' or 'member_server_image_no', but it did not") + } +} + +func TestExistsBothServerImageProductCodeAndMemberServerImageNoConfig(t *testing.T) { + raw := map[string]interface{}{ + "access_key": "access_key", + "secret_key": "secret_key", + "os_type": "Windows", + "server_image_product_code": "SPSW0WINNT000016", + "server_product_code": "SPSVRSSD00000011", + "member_server_image_no": "2440", + } + + _, _, err := NewConfig(raw) + + if !strings.Contains(err.Error(), "Only one of server_image_product_code and member_server_image_no can be set") { + t.Error("Expected Config to require Only one of 'server_image_product_code' and 'member_server_image_no' can be set, but it did not") + } +} diff --git a/builder/ncloud/ssh.go b/builder/ncloud/ssh.go new file mode 100644 index 000000000..ee7d99226 --- /dev/null +++ b/builder/ncloud/ssh.go @@ -0,0 +1,30 @@ +package ncloud + +import ( + packerssh "github.com/hashicorp/packer/communicator/ssh" + "github.com/mitchellh/multistep" + "golang.org/x/crypto/ssh" +) + +func SSHHost(state multistep.StateBag) (string, error) { + host := state.Get("SSHHost").(string) + return host, nil +} + +// SSHConfig returns a function that can be used for the SSH communicator +// config for connecting to the specified host via SSH +func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) { + return func(state multistep.StateBag) (*ssh.ClientConfig, error) { + password := state.Get("Password").(string) + + return &ssh.ClientConfig{ + User: username, + Auth: []ssh.AuthMethod{ + ssh.Password(password), + ssh.KeyboardInteractive( + packerssh.PasswordKeyboardInteractive(password)), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + }, nil + } +} diff --git a/builder/ncloud/step.go b/builder/ncloud/step.go new file mode 100644 index 000000000..ba71efbee --- /dev/null +++ b/builder/ncloud/step.go @@ -0,0 +1,16 @@ +package ncloud + +import ( + "github.com/mitchellh/multistep" +) + +func processStepResult(err error, sayError func(error), state multistep.StateBag) multistep.StepAction { + if err != nil { + state.Put("Error", err) + sayError(err) + + return multistep.ActionHalt + } + + return multistep.ActionContinue +} diff --git a/builder/ncloud/step_create_block_storage_instance.go b/builder/ncloud/step_create_block_storage_instance.go new file mode 100644 index 000000000..ef7306264 --- /dev/null +++ b/builder/ncloud/step_create_block_storage_instance.go @@ -0,0 +1,101 @@ +package ncloud + +import ( + "errors" + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +// StepCreateBlockStorageInstance struct is for making extra block storage +type StepCreateBlockStorageInstance struct { + Conn *ncloud.Conn + CreateBlockStorageInstance func(serverInstanceNo string) (string, error) + Say func(message string) + Error func(e error) + Config *Config +} + +// NewStepCreateBlockStorageInstance make StepCreateBlockStorage struct to make extra block storage +func NewStepCreateBlockStorageInstance(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepCreateBlockStorageInstance { + var step = &StepCreateBlockStorageInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, + } + + step.CreateBlockStorageInstance = step.createBlockStorageInstance + + return step +} + +func (s *StepCreateBlockStorageInstance) createBlockStorageInstance(serverInstanceNo string) (string, error) { + + reqParams := new(ncloud.RequestBlockStorageInstance) + reqParams.BlockStorageSize = s.Config.BlockStorageSize + reqParams.ServerInstanceNo = serverInstanceNo + + blockStorageInstanceList, err := s.Conn.CreateBlockStorageInstance(reqParams) + if err != nil { + return "", fmt.Errorf("error code: %d, error message: %s", blockStorageInstanceList.ReturnCode, blockStorageInstanceList.ReturnMessage) + } + + log.Println("Block Storage Instance information : ", blockStorageInstanceList.BlockStorageInstance[0]) + + if err := waiterBlockStorageInstanceStatus(s.Conn, blockStorageInstanceList.BlockStorageInstance[0].BlockStorageInstanceNo, "ATTAC", 10*time.Minute); err != nil { + return "", errors.New("TIMEOUT : Block Storage instance status is not attached") + } + + return blockStorageInstanceList.BlockStorageInstance[0].BlockStorageInstanceNo, nil +} + +func (s *StepCreateBlockStorageInstance) Run(state multistep.StateBag) multistep.StepAction { + if s.Config.BlockStorageSize == 0 { + return processStepResult(nil, s.Error, state) + } + + s.Say("Create extra block storage instance") + + serverInstanceNo := state.Get("InstanceNo").(string) + + blockStorageInstanceNo, err := s.CreateBlockStorageInstance(serverInstanceNo) + if err == nil { + state.Put("BlockStorageInstanceNo", blockStorageInstanceNo) + } + + return processStepResult(err, s.Error, state) +} + +func (s *StepCreateBlockStorageInstance) Cleanup(state multistep.StateBag) { + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if !cancelled && !halted { + return + } + + if s.Config.BlockStorageSize == 0 { + return + } + + if blockStorageInstanceNo, ok := state.GetOk("BlockStorageInstanceNo"); ok { + s.Say("Clean up Block Storage Instance") + no := blockStorageInstanceNo.(string) + blockStorageInstanceList, err := s.Conn.DeleteBlockStorageInstances([]string{no}) + if err != nil { + return + } + + s.Say(fmt.Sprintf("Block Storage Instance is deleted. Block Storage InstanceNo is %s", no)) + log.Println("Block Storage Instance information : ", blockStorageInstanceList.BlockStorageInstance[0]) + + if err := waiterBlockStorageInstanceStatus(s.Conn, no, "DETAC", time.Minute); err != nil { + s.Say("TIMEOUT : Block Storage instance status is not deattached") + } + } +} diff --git a/builder/ncloud/step_create_block_storage_instance_test.go b/builder/ncloud/step_create_block_storage_instance_test.go new file mode 100644 index 000000000..101e94658 --- /dev/null +++ b/builder/ncloud/step_create_block_storage_instance_test.go @@ -0,0 +1,62 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepCreateBlockStorageInstanceShouldFailIfOperationCreateBlockStorageInstanceFails(t *testing.T) { + + var testSubject = &StepCreateBlockStorageInstance{ + CreateBlockStorageInstance: func(serverInstanceNo string) (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + Config: new(Config), + } + + testSubject.Config.BlockStorageSize = 10 + + stateBag := createTestStateBagStepCreateBlockStorageInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepCreateBlockStorageInstanceShouldPassIfOperationCreateBlockStorageInstancePasses(t *testing.T) { + var testSubject = &StepCreateBlockStorageInstance{ + CreateBlockStorageInstance: func(serverInstanceNo string) (string, error) { return "a", nil }, + Say: func(message string) {}, + Error: func(e error) {}, + Config: new(Config), + } + + testSubject.Config.BlockStorageSize = 10 + + stateBag := createTestStateBagStepCreateBlockStorageInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepCreateBlockStorageInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("InstanceNo", "a") + + return stateBag +} diff --git a/builder/ncloud/step_create_login_key.go b/builder/ncloud/step_create_login_key.go new file mode 100644 index 000000000..7dddebd25 --- /dev/null +++ b/builder/ncloud/step_create_login_key.go @@ -0,0 +1,71 @@ +package ncloud + +import ( + "fmt" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type LoginKey struct { + KeyName string + PrivateKey string +} + +type StepCreateLoginKey struct { + Conn *ncloud.Conn + CreateLoginKey func() (*LoginKey, error) + Say func(message string) + Error func(e error) +} + +func NewStepCreateLoginKey(conn *ncloud.Conn, ui packer.Ui) *StepCreateLoginKey { + var step = &StepCreateLoginKey{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + } + + step.CreateLoginKey = step.createLoginKey + + return step +} + +func (s *StepCreateLoginKey) createLoginKey() (*LoginKey, error) { + KeyName := fmt.Sprintf("packer-%d", time.Now().Unix()) + + privateKey, err := s.Conn.CreateLoginKey(KeyName) + if err != nil { + return nil, fmt.Errorf("error code: %d , error message: %s", privateKey.ReturnCode, privateKey.ReturnMessage) + } + + return &LoginKey{KeyName, privateKey.PrivateKey}, nil +} + +func (s *StepCreateLoginKey) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Create Login Key") + + loginKey, err := s.CreateLoginKey() + if err == nil { + state.Put("LoginKey", loginKey) + s.Say(fmt.Sprintf("Login Key[%s] is created", loginKey.KeyName)) + } + + return processStepResult(err, s.Error, state) +} + +func (s *StepCreateLoginKey) Cleanup(state multistep.StateBag) { + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if !cancelled && !halted { + return + } + + if loginKey, ok := state.GetOk("LoginKey"); ok { + s.Say("Clean up login key") + s.Conn.DeleteLoginKey(loginKey.(*LoginKey).KeyName) + } +} diff --git a/builder/ncloud/step_create_login_key_test.go b/builder/ncloud/step_create_login_key_test.go new file mode 100644 index 000000000..374d10330 --- /dev/null +++ b/builder/ncloud/step_create_login_key_test.go @@ -0,0 +1,53 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepCreateLoginKeyShouldFailIfOperationCreateLoginKeyFails(t *testing.T) { + var testSubject = &StepCreateLoginKey{ + CreateLoginKey: func() (*LoginKey, error) { return nil, fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateLoginKey() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepCreateLoginKeyShouldPassIfOperationCreateLoginKeyPasses(t *testing.T) { + var testSubject = &StepCreateLoginKey{ + CreateLoginKey: func() (*LoginKey, error) { return &LoginKey{"a", "b"}, nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateLoginKey() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepCreateLoginKey() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + return stateBag +} diff --git a/builder/ncloud/step_create_public_ip_instance.go b/builder/ncloud/step_create_public_ip_instance.go new file mode 100644 index 000000000..88d98eb6c --- /dev/null +++ b/builder/ncloud/step_create_public_ip_instance.go @@ -0,0 +1,167 @@ +package ncloud + +import ( + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepCreatePublicIPInstance struct { + Conn *ncloud.Conn + CreatePublicIPInstance func(serverInstanceNo string) (*ncloud.PublicIPInstance, error) + WaiterAssociatePublicIPToServerInstance func(serverInstanceNo string, publicIP string) error + Say func(message string) + Error func(e error) + Config *Config +} + +func NewStepCreatePublicIPInstance(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepCreatePublicIPInstance { + var step = &StepCreatePublicIPInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, + } + + step.CreatePublicIPInstance = step.createPublicIPInstance + step.WaiterAssociatePublicIPToServerInstance = step.waiterAssociatePublicIPToServerInstance + + return step +} + +func (s *StepCreatePublicIPInstance) waiterAssociatePublicIPToServerInstance(serverInstanceNo string, publicIP string) error { + reqParams := new(ncloud.RequestGetServerInstanceList) + reqParams.ServerInstanceNoList = []string{serverInstanceNo} + + c1 := make(chan error, 1) + + go func() { + for { + serverInstanceList, err := s.Conn.GetServerInstanceList(reqParams) + + if err != nil { + c1 <- err + return + } + + if publicIP == serverInstanceList.ServerInstanceList[0].PublicIP { + c1 <- nil + return + } + + s.Say("Wait to associate public ip serverInstance") + time.Sleep(time.Second * 3) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(time.Second * 60): + return fmt.Errorf("TIMEOUT : association public ip[%s] to server instance[%s] Failed", publicIP, serverInstanceNo) + } +} + +func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo string) (*ncloud.PublicIPInstance, error) { + reqParams := new(ncloud.RequestCreatePublicIPInstance) + reqParams.ServerInstanceNo = serverInstanceNo + + publicIPInstanceList, err := s.Conn.CreatePublicIPInstance(reqParams) + if err != nil { + return nil, fmt.Errorf("error code: %d, error message: %s", publicIPInstanceList.ReturnCode, publicIPInstanceList.ReturnMessage) + } + + publicIPInstance := publicIPInstanceList.PublicIPInstanceList[0] + publicIP := publicIPInstance.PublicIP + s.Say(fmt.Sprintf("Public IP Instance [%s:%s] is created", publicIPInstance.PublicIPInstanceNo, publicIP)) + + err = s.waiterAssociatePublicIPToServerInstance(serverInstanceNo, publicIP) + + return &publicIPInstance, nil +} + +func (s *StepCreatePublicIPInstance) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Create Public IP Instance") + + serverInstanceNo := state.Get("InstanceNo").(string) + + publicIPInstance, err := s.CreatePublicIPInstance(serverInstanceNo) + if err == nil { + switch s.Config.OSType { + case "Linux": + state.Put("SSHHost", publicIPInstance.PublicIP) + case "Windows": + state.Put("WinRMHost", publicIPInstance.PublicIP) + } + + state.Put("PublicIPInstance", publicIPInstance) + } + + return processStepResult(err, s.Error, state) +} + +func (s *StepCreatePublicIPInstance) Cleanup(state multistep.StateBag) { + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if !cancelled && !halted { + return + } + + publicIPInstance, ok := state.GetOk("PublicIPInstance") + if !ok { + return + } + + s.Say("Clean up Public IP Instance") + publicIPInstanceNo := publicIPInstance.(*ncloud.PublicIPInstance).PublicIPInstanceNo + s.waitPublicIPInstanceStatus(publicIPInstanceNo, "USED") + + log.Println("Disassociate Public IP Instance ", publicIPInstanceNo) + s.Conn.DisassociatePublicIP(publicIPInstanceNo) + + s.waitPublicIPInstanceStatus(publicIPInstanceNo, "CREAT") + + reqParams := new(ncloud.RequestDeletePublicIPInstances) + reqParams.PublicIPInstanceNoList = []string{publicIPInstanceNo} + + log.Println("Delete Public IP Instance ", publicIPInstanceNo) + s.Conn.DeletePublicIPInstances(reqParams) +} + +func (s *StepCreatePublicIPInstance) waitPublicIPInstanceStatus(publicIPInstanceNo string, status string) { + c1 := make(chan error, 1) + + go func() { + reqParams := new(ncloud.RequestPublicIPInstanceList) + reqParams.PublicIPInstanceNoList = []string{publicIPInstanceNo} + + for { + resp, err := s.Conn.GetPublicIPInstanceList(reqParams) + if err != nil { + log.Printf("error code: %d, error message: %s", resp.ReturnCode, resp.ReturnMessage) + c1 <- err + return + } + + instance := resp.PublicIPInstanceList[0] + if instance.PublicIPInstanceStatus.Code == status && instance.PublicIPInstanceOperation.Code == "NULL" { + c1 <- nil + return + } + + time.Sleep(time.Second * 2) + } + }() + + select { + case <-c1: + return + case <-time.After(time.Second * 60): + return + } +} diff --git a/builder/ncloud/step_create_public_ip_instance_test.go b/builder/ncloud/step_create_public_ip_instance_test.go new file mode 100644 index 000000000..30eaca017 --- /dev/null +++ b/builder/ncloud/step_create_public_ip_instance_test.go @@ -0,0 +1,62 @@ +package ncloud + +import ( + "fmt" + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "testing" + + "github.com/mitchellh/multistep" +) + +func TestStepCreatePublicIPInstanceShouldFailIfOperationCreatePublicIPInstanceFails(t *testing.T) { + var testSubject = &StepCreatePublicIPInstance{ + CreatePublicIPInstance: func(serverInstanceNo string) (*ncloud.PublicIPInstance, error) { + return nil, fmt.Errorf("!! Unit Test FAIL !!") + }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateServerImage() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepCreatePublicIPInstanceShouldPassIfOperationCreatePublicIPInstancePasses(t *testing.T) { + var testSubject = &StepCreatePublicIPInstance{ + CreatePublicIPInstance: func(serverInstanceNo string) (*ncloud.PublicIPInstance, error) { + return &ncloud.PublicIPInstance{PublicIPInstanceNo: "a", PublicIP: "b"}, nil + }, + Say: func(message string) {}, + Error: func(e error) {}, + Config: &Config{OSType: "Windows"}, + } + + stateBag := createTestStateBagStepCreatePublicIPInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepCreatePublicIPInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("InstanceNo", "a") + + return stateBag +} diff --git a/builder/ncloud/step_create_server_image.go b/builder/ncloud/step_create_server_image.go new file mode 100644 index 000000000..4256664f4 --- /dev/null +++ b/builder/ncloud/step_create_server_image.go @@ -0,0 +1,77 @@ +package ncloud + +import ( + "errors" + "fmt" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepCreateServerImage struct { + Conn *ncloud.Conn + CreateServerImage func(serverInstanceNo string) (*ncloud.ServerImage, error) + Say func(message string) + Error func(e error) + Config *Config +} + +func NewStepCreateServerImage(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepCreateServerImage { + var step = &StepCreateServerImage{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, + } + + step.CreateServerImage = step.createServerImage + + return step +} + +func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*ncloud.ServerImage, error) { + // 서버 인스턴스 상태가 정지 중일 경우에는 서버 이미지 생성할 수 없음. + if err := waiterServerInstanceStatus(s.Conn, serverInstanceNo, "NSTOP", 1*time.Minute); err != nil { + return nil, err + } + + reqParams := new(ncloud.RequestCreateServerImage) + reqParams.MemberServerImageName = s.Config.ServerImageName + reqParams.MemberServerImageDescription = s.Config.ServerImageDescription + reqParams.ServerInstanceNo = serverInstanceNo + + memberServerImageList, err := s.Conn.CreateMemberServerImage(reqParams) + if err != nil { + return nil, fmt.Errorf("error code: %d , error message: %s", memberServerImageList.ReturnCode, memberServerImageList.ReturnMessage) + } + + serverImage := memberServerImageList.MemberServerImageList[0] + + s.Say(fmt.Sprintf("Server Image[%s:%s] is creating...", serverImage.MemberServerImageName, serverImage.MemberServerImageNo)) + + if err := waiterMemberServerImageStatus(s.Conn, serverImage.MemberServerImageNo, "CREAT", 6*time.Hour); err != nil { + return nil, errors.New("TIMEOUT : Server Image is not created") + } + + s.Say(fmt.Sprintf("Server Image[%s:%s] is created", serverImage.MemberServerImageName, serverImage.MemberServerImageNo)) + + return &serverImage, nil +} + +func (s *StepCreateServerImage) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Create Server Image") + + serverInstanceNo := state.Get("InstanceNo").(string) + + serverImage, err := s.CreateServerImage(serverInstanceNo) + if err == nil { + state.Put("memberServerImage", serverImage) + } + + return processStepResult(err, s.Error, state) +} + +func (*StepCreateServerImage) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_create_server_image_test.go b/builder/ncloud/step_create_server_image_test.go new file mode 100644 index 000000000..41a40971a --- /dev/null +++ b/builder/ncloud/step_create_server_image_test.go @@ -0,0 +1,58 @@ +package ncloud + +import ( + "fmt" + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "testing" + + "github.com/mitchellh/multistep" +) + +func TestStepCreateServerImageShouldFailIfOperationCreateServerImageFails(t *testing.T) { + var testSubject = &StepCreateServerImage{ + CreateServerImage: func(serverInstanceNo string) (*ncloud.ServerImage, error) { + return nil, fmt.Errorf("!! Unit Test FAIL !!") + }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateServerImage() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} +func TestStepCreateServerImageShouldPassIfOperationCreateServerImagePasses(t *testing.T) { + var testSubject = &StepCreateServerImage{ + CreateServerImage: func(serverInstanceNo string) (*ncloud.ServerImage, error) { return nil, nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateServerImage() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepCreateServerImage() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("InstanceNo", "a") + + return stateBag +} diff --git a/builder/ncloud/step_create_server_instance.go b/builder/ncloud/step_create_server_instance.go new file mode 100644 index 000000000..040e72eb1 --- /dev/null +++ b/builder/ncloud/step_create_server_instance.go @@ -0,0 +1,129 @@ +package ncloud + +import ( + "errors" + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepCreateServerInstance struct { + Conn *ncloud.Conn + CreateServerInstance func(loginKeyName string, zoneNo string) (string, error) + CheckServerInstanceStatusIsRunning func(serverInstanceNo string) error + Say func(message string) + Error func(e error) + Config *Config + serverInstanceNo string +} + +func NewStepCreateServerInstance(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepCreateServerInstance { + var step = &StepCreateServerInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, + } + + step.CreateServerInstance = step.createServerInstance + + return step +} + +func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zoneNo string) (string, error) { + reqParams := new(ncloud.RequestCreateServerInstance) + reqParams.ServerProductCode = s.Config.ServerProductCode + reqParams.MemberServerImageNo = s.Config.MemberServerImageNo + if s.Config.MemberServerImageNo == "" { + reqParams.ServerImageProductCode = s.Config.ServerImageProductCode + } + reqParams.LoginKeyName = loginKeyName + reqParams.ZoneNo = zoneNo + reqParams.FeeSystemTypeCode = s.Config.FeeSystemTypeCode + + if s.Config.UserData != "" { + reqParams.UserData = s.Config.UserData + } + + if s.Config.AccessControlGroupConfigurationNo != "" { + reqParams.AccessControlGroupConfigurationNoList = []string{s.Config.AccessControlGroupConfigurationNo} + } + + serverInstanceList, err := s.Conn.CreateServerInstances(reqParams) + if err != nil { + return "", fmt.Errorf("error code: %d, error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + } + + s.serverInstanceNo = serverInstanceList.ServerInstanceList[0].ServerInstanceNo + s.Say(fmt.Sprintf("Server Instance is creating. Server InstanceNo is %s", s.serverInstanceNo)) + log.Println("Server Instance information : ", serverInstanceList.ServerInstanceList[0]) + + if err := waiterServerInstanceStatus(s.Conn, s.serverInstanceNo, "RUN", 30*time.Minute); err != nil { + return "", errors.New("TIMEOUT : server instance status is not running") + } + + s.Say(fmt.Sprintf("Server Instance is created. Server InstanceNo is %s", s.serverInstanceNo)) + + return s.serverInstanceNo, nil +} + +func (s *StepCreateServerInstance) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Create Server Instance") + + var loginKey = state.Get("LoginKey").(*LoginKey) + var zoneNo = state.Get("ZoneNo").(string) + + serverInstanceNo, err := s.CreateServerInstance(loginKey.KeyName, zoneNo) + if err == nil { + state.Put("InstanceNo", serverInstanceNo) + } + + return processStepResult(err, s.Error, state) +} + +func (s *StepCreateServerInstance) Cleanup(state multistep.StateBag) { + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if !cancelled && !halted { + return + } + + if s.serverInstanceNo == "" { + return + } + + reqParams := new(ncloud.RequestGetServerInstanceList) + reqParams.ServerInstanceNoList = []string{s.serverInstanceNo} + + serverInstanceList, err := s.Conn.GetServerInstanceList(reqParams) + if err != nil || serverInstanceList.TotalRows == 0 { + return + } + + s.Say("Clean up Server Instance") + + serverInstance := serverInstanceList.ServerInstanceList[0] + // stop server instance + if serverInstance.ServerInstanceStatus.Code != "NSTOP" && serverInstance.ServerInstanceStatus.Code != "TERMT" { + reqParams := new(ncloud.RequestStopServerInstances) + reqParams.ServerInstanceNoList = []string{s.serverInstanceNo} + + log.Println("Stop Server Instance") + s.Conn.StopServerInstances(reqParams) + waiterServerInstanceStatus(s.Conn, s.serverInstanceNo, "NSTOP", time.Minute) + } + + // terminate server instance + if serverInstance.ServerInstanceStatus.Code != "TERMT" { + reqParams := new(ncloud.RequestTerminateServerInstances) + reqParams.ServerInstanceNoList = []string{s.serverInstanceNo} + + log.Println("Terminate Server Instance") + s.Conn.TerminateServerInstances(reqParams) + } +} diff --git a/builder/ncloud/step_create_server_instance_test.go b/builder/ncloud/step_create_server_instance_test.go new file mode 100644 index 000000000..327228b75 --- /dev/null +++ b/builder/ncloud/step_create_server_instance_test.go @@ -0,0 +1,58 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T) { + var testSubject = &StepCreateServerInstance{ + CreateServerInstance: func(loginKeyName string, zoneNo string) (string, error) { + return "", fmt.Errorf("!! Unit Test FAIL !!") + }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateServerInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepCreateServerInstanceShouldPassIfOperationCreatePasses(t *testing.T) { + var testSubject = &StepCreateServerInstance{ + CreateServerInstance: func(loginKeyName string, zoneNo string) (string, error) { return "", nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepCreateServerInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepCreateServerInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("LoginKey", &LoginKey{"a", "b"}) + stateBag.Put("ZoneNo", "1") + + return stateBag +} diff --git a/builder/ncloud/step_delete_block_storage_instance.go b/builder/ncloud/step_delete_block_storage_instance.go new file mode 100644 index 000000000..3c6c44b82 --- /dev/null +++ b/builder/ncloud/step_delete_block_storage_instance.go @@ -0,0 +1,95 @@ +package ncloud + +import ( + "errors" + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepDeleteBlockStorageInstance struct { + Conn *ncloud.Conn + DeleteBlockStorageInstance func(blockStorageInstanceNo string) error + Say func(message string) + Error func(e error) + Config *Config +} + +func NewStepDeleteBlockStorageInstance(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepDeleteBlockStorageInstance { + var step = &StepDeleteBlockStorageInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, + } + + step.DeleteBlockStorageInstance = step.deleteBlockStorageInstance + + return step +} + +func (s *StepDeleteBlockStorageInstance) getBlockInstanceList(serverInstanceNo string) []string { + reqParams := new(ncloud.RequestBlockStorageInstanceList) + reqParams.ServerInstanceNo = serverInstanceNo + + blockStorageInstanceList, err := s.Conn.GetBlockStorageInstance(reqParams) + if err != nil { + return nil + } + + if blockStorageInstanceList.TotalRows == 1 { + return nil + } + + var instanceList []string + + for _, blockStorageInstance := range blockStorageInstanceList.BlockStorageInstance { + log.Println(blockStorageInstance) + if blockStorageInstance.BlockStorageType.Code != "BASIC" { + instanceList = append(instanceList, blockStorageInstance.BlockStorageInstanceNo) + } + } + + return instanceList +} + +func (s *StepDeleteBlockStorageInstance) deleteBlockStorageInstance(serverInstanceNo string) error { + blockStorageInstanceList := s.getBlockInstanceList(serverInstanceNo) + if blockStorageInstanceList == nil || len(blockStorageInstanceList) == 0 { + return nil + } + + result, err := s.Conn.DeleteBlockStorageInstances(blockStorageInstanceList) + if err != nil { + return fmt.Errorf("error code: %d , error message: %s", result.ReturnCode, result.ReturnMessage) + } + + s.Say(fmt.Sprintf("Block Storage Instance is deleted. Block Storage InstanceNo is %s", blockStorageInstanceList)) + + if err := waiterDetachedBlockStorageInstance(s.Conn, serverInstanceNo, time.Minute); err != nil { + return errors.New("TIMEOUT : Block Storage instance status is not deattached") + } + + return nil +} + +func (s *StepDeleteBlockStorageInstance) Run(state multistep.StateBag) multistep.StepAction { + if s.Config.BlockStorageSize == 0 { + return processStepResult(nil, s.Error, state) + } + + s.Say("Delete Block Storage Instance") + + var serverInstanceNo = state.Get("InstanceNo").(string) + + err := s.DeleteBlockStorageInstance(serverInstanceNo) + + return processStepResult(err, s.Error, state) +} + +func (*StepDeleteBlockStorageInstance) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_delete_block_storage_instance_test.go b/builder/ncloud/step_delete_block_storage_instance_test.go new file mode 100644 index 000000000..ce0f0cb09 --- /dev/null +++ b/builder/ncloud/step_delete_block_storage_instance_test.go @@ -0,0 +1,57 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepDeleteBlockStorageInstanceShouldFailIfOperationDeleteBlockStorageInstanceFails(t *testing.T) { + var testSubject = &StepDeleteBlockStorageInstance{ + DeleteBlockStorageInstance: func(blockStorageInstanceNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + Config: &Config{BlockStorageSize: 10}, + } + + stateBag := createTestStateBagStepDeleteBlockStorageInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepDeleteBlockStorageInstanceShouldPassIfOperationDeleteBlockStorageInstancePasses(t *testing.T) { + var testSubject = &StepDeleteBlockStorageInstance{ + DeleteBlockStorageInstance: func(blockStorageInstanceNo string) error { return nil }, + Say: func(message string) {}, + Error: func(e error) {}, + Config: &Config{BlockStorageSize: 10}, + } + + stateBag := createTestStateBagStepDeleteBlockStorageInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepDeleteBlockStorageInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("InstanceNo", "1") + + return stateBag +} diff --git a/builder/ncloud/step_delete_login_key.go b/builder/ncloud/step_delete_login_key.go new file mode 100644 index 000000000..b0cfbf7a1 --- /dev/null +++ b/builder/ncloud/step_delete_login_key.go @@ -0,0 +1,51 @@ +package ncloud + +import ( + "fmt" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepDeleteLoginKey struct { + Conn *ncloud.Conn + DeleteLoginKey func(keyName string) error + Say func(message string) + Error func(e error) +} + +func NewStepDeleteLoginKey(conn *ncloud.Conn, ui packer.Ui) *StepDeleteLoginKey { + var step = &StepDeleteLoginKey{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + } + + step.DeleteLoginKey = step.deleteLoginKey + + return step +} + +func (s *StepDeleteLoginKey) deleteLoginKey(keyName string) error { + resp, err := s.Conn.DeleteLoginKey(keyName) + if err != nil { + return fmt.Errorf("error code: %d , error message: %s", resp.ReturnCode, resp.ReturnMessage) + } + + return nil +} + +func (s *StepDeleteLoginKey) Run(state multistep.StateBag) multistep.StepAction { + var loginKey = state.Get("LoginKey").(*LoginKey) + + err := s.DeleteLoginKey(loginKey.KeyName) + if err == nil { + s.Say(fmt.Sprintf("Login Key[%s] is deleted", loginKey.KeyName)) + } + + return processStepResult(err, s.Error, state) +} + +func (*StepDeleteLoginKey) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_delete_login_key_test.go b/builder/ncloud/step_delete_login_key_test.go new file mode 100644 index 000000000..38ce1e22c --- /dev/null +++ b/builder/ncloud/step_delete_login_key_test.go @@ -0,0 +1,55 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepDeleteLoginKeyShouldFailIfOperationDeleteLoginKeyFails(t *testing.T) { + var testSubject = &StepDeleteLoginKey{ + DeleteLoginKey: func(keyName string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepDeleteLoginKey() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepDeleteLoginKeyShouldPassIfOperationDeleteLoginKeyPasses(t *testing.T) { + var testSubject = &StepDeleteLoginKey{ + DeleteLoginKey: func(keyName string) error { return nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepDeleteLoginKey() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func DeleteTestStateBagStepDeleteLoginKey() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("LoginKey", &LoginKey{"a", "b"}) + + return stateBag +} diff --git a/builder/ncloud/step_delete_public_ip_instance.go b/builder/ncloud/step_delete_public_ip_instance.go new file mode 100644 index 000000000..4a1401984 --- /dev/null +++ b/builder/ncloud/step_delete_public_ip_instance.go @@ -0,0 +1,78 @@ +package ncloud + +import ( + "errors" + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepDeletePublicIPInstance struct { + Conn *ncloud.Conn + DeletePublicIPInstance func(publicIPInstanceNo string) error + Say func(message string) + Error func(e error) +} + +func NewStepDeletePublicIPInstance(conn *ncloud.Conn, ui packer.Ui) *StepDeletePublicIPInstance { + var step = &StepDeletePublicIPInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + } + + step.DeletePublicIPInstance = step.deletePublicIPInstance + + return step +} + +func (s *StepDeletePublicIPInstance) deletePublicIPInstance(publicIPInstanceNo string) error { + reqParams := new(ncloud.RequestDeletePublicIPInstances) + reqParams.PublicIPInstanceNoList = []string{publicIPInstanceNo} + + c1 := make(chan error, 1) + + go func() { + for { + resp, err := s.Conn.DeletePublicIPInstances(reqParams) + if err != nil && (resp.ReturnCode == 24073 || resp.ReturnCode == 25032) { + // error code : 24073 : Unable to destroy the server since a public IP is associated with the server. First, please disassociate a public IP from the server. + // error code : 25032 : You may not delete sk since (other) user is changing the target official IP settings. + log.Println(resp.ReturnCode, resp.ReturnMessage) + } else if err != nil { + c1 <- fmt.Errorf("error code: %d, error message: %s", resp.ReturnCode, resp.ReturnMessage) + return + } else if err == nil { + s.Say(fmt.Sprintf("Public IP Instance [%s] is deleted.", publicIPInstanceNo)) + c1 <- nil + return + } + + time.Sleep(time.Second * 5) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(time.Second * 60): + return errors.New("TIMEOUT : Can't delete server instance") + } +} + +func (s *StepDeletePublicIPInstance) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Delete Public IP Instance") + + publicIPInstance := state.Get("PublicIPInstance").(*ncloud.PublicIPInstance) + + err := s.DeletePublicIPInstance(publicIPInstance.PublicIPInstanceNo) + + return processStepResult(err, s.Error, state) +} + +func (*StepDeletePublicIPInstance) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_delete_public_ip_instance_test.go b/builder/ncloud/step_delete_public_ip_instance_test.go new file mode 100644 index 000000000..b9fa04ec8 --- /dev/null +++ b/builder/ncloud/step_delete_public_ip_instance_test.go @@ -0,0 +1,57 @@ +package ncloud + +import ( + "fmt" + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "testing" + + "github.com/mitchellh/multistep" +) + +func TestStepDeletePublicIPInstanceShouldFailIfOperationDeletePublicIPInstanceFails(t *testing.T) { + var testSubject = &StepDeletePublicIPInstance{ + DeletePublicIPInstance: func(publicIPInstanceNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepDeletePublicIPInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepDeletePublicIPInstanceShouldPassIfOperationDeletePublicIPInstancePasses(t *testing.T) { + var testSubject = &StepDeletePublicIPInstance{ + DeletePublicIPInstance: func(publicIPInstanceNo string) error { return nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepDeletePublicIPInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepDeletePublicIPInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("PublicIPInstance", &ncloud.PublicIPInstance{PublicIPInstanceNo: "22"}) + + return stateBag +} diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go new file mode 100644 index 000000000..c5070d179 --- /dev/null +++ b/builder/ncloud/step_get_rootpassword.go @@ -0,0 +1,57 @@ +package ncloud + +import ( + "fmt" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepGetRootPassword struct { + Conn *ncloud.Conn + GetRootPassword func(serverInstanceNo string, privateKey string) (string, error) + Say func(message string) + Error func(e error) +} + +func NewStepGetRootPassword(conn *ncloud.Conn, ui packer.Ui) *StepGetRootPassword { + var step = &StepGetRootPassword{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + } + + step.GetRootPassword = step.getRootPassword + + return step +} + +func (s *StepGetRootPassword) getRootPassword(serverInstanceNo string, privateKey string) (string, error) { + reqParams := new(ncloud.RequestGetRootPassword) + reqParams.ServerInstanceNo = serverInstanceNo + reqParams.PrivateKey = privateKey + + rootPassword, err := s.Conn.GetRootPassword(reqParams) + if err != nil { + return "", fmt.Errorf("error code: %d, error message: %s", rootPassword.ReturnCode, rootPassword.ReturnMessage) + } + + return rootPassword.RootPassword, nil +} + +func (s *StepGetRootPassword) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Get Root Password") + + serverInstanceNo := state.Get("InstanceNo").(string) + loginKey := state.Get("LoginKey").(*LoginKey) + + rootPassword, err := s.GetRootPassword(serverInstanceNo, loginKey.PrivateKey) + + state.Put("Password", rootPassword) + + return processStepResult(err, s.Error, state) +} + +func (*StepGetRootPassword) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_get_rootpassword_test.go b/builder/ncloud/step_get_rootpassword_test.go new file mode 100644 index 000000000..b9ed6aa56 --- /dev/null +++ b/builder/ncloud/step_get_rootpassword_test.go @@ -0,0 +1,56 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepGetRootPasswordShouldFailIfOperationGetRootPasswordFails(t *testing.T) { + var testSubject = &StepGetRootPassword{ + GetRootPassword: func(string, string) (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepGetRootPassword() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepGetRootPasswordShouldPassIfOperationGetRootPasswordPasses(t *testing.T) { + var testSubject = &StepGetRootPassword{ + GetRootPassword: func(string, string) (string, error) { return "a", nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepGetRootPassword() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func DeleteTestStateBagStepGetRootPassword() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("LoginKey", &LoginKey{"a", "b"}) + stateBag.Put("InstanceNo", "a") + + return stateBag +} diff --git a/builder/ncloud/step_stop_server_instance.go b/builder/ncloud/step_stop_server_instance.go new file mode 100644 index 000000000..1c9252ed2 --- /dev/null +++ b/builder/ncloud/step_stop_server_instance.go @@ -0,0 +1,64 @@ +package ncloud + +import ( + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepStopServerInstance struct { + Conn *ncloud.Conn + StopServerInstance func(serverInstanceNo string) error + Say func(message string) + Error func(e error) +} + +func NewStepStopServerInstance(conn *ncloud.Conn, ui packer.Ui) *StepStopServerInstance { + var step = &StepStopServerInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + } + + step.StopServerInstance = step.stopServerInstance + + return step +} + +func (s *StepStopServerInstance) stopServerInstance(serverInstanceNo string) error { + reqParams := new(ncloud.RequestStopServerInstances) + reqParams.ServerInstanceNoList = []string{serverInstanceNo} + + serverInstanceList, err := s.Conn.StopServerInstances(reqParams) + if err != nil { + return fmt.Errorf("error code: %d , error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + } + + s.Say(fmt.Sprintf("Server Instance is stopping. Server InstanceNo is %s", serverInstanceList.ServerInstanceList[0].ServerInstanceNo)) + log.Println("Server Instance information : ", serverInstanceList.ServerInstanceList[0]) + + if err := waiterServerInstanceStatus(s.Conn, serverInstanceNo, "NSTOP", 5*time.Minute); err != nil { + return err + } + + s.Say(fmt.Sprintf("Server Instance stopped. Server InstanceNo is %s", serverInstanceList.ServerInstanceList[0].ServerInstanceNo)) + + return nil +} + +func (s *StepStopServerInstance) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Stop Server Instance") + + var serverInstanceNo = state.Get("InstanceNo").(string) + + err := s.StopServerInstance(serverInstanceNo) + + return processStepResult(err, s.Error, state) +} + +func (*StepStopServerInstance) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_stop_server_instance_test.go b/builder/ncloud/step_stop_server_instance_test.go new file mode 100644 index 000000000..d90bc6953 --- /dev/null +++ b/builder/ncloud/step_stop_server_instance_test.go @@ -0,0 +1,55 @@ +package ncloud + +import ( + "fmt" + "testing" + + "github.com/mitchellh/multistep" +) + +func TestStepStopServerInstanceShouldFailIfOperationStopFails(t *testing.T) { + var testSubject = &StepStopServerInstance{ + StopServerInstance: func(serverInstanceNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepStopServerInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepStopServerInstanceShouldPassIfOperationStopPasses(t *testing.T) { + var testSubject = &StepStopServerInstance{ + StopServerInstance: func(serverInstanceNo string) error { return nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepStopServerInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepStopServerInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("InstanceNo", "a") + return stateBag +} diff --git a/builder/ncloud/step_terminate_server_instance.go b/builder/ncloud/step_terminate_server_instance.go new file mode 100644 index 000000000..5d60236f0 --- /dev/null +++ b/builder/ncloud/step_terminate_server_instance.go @@ -0,0 +1,81 @@ +package ncloud + +import ( + "errors" + "fmt" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type StepTerminateServerInstance struct { + Conn *ncloud.Conn + TerminateServerInstance func(serverInstanceNo string) error + Say func(message string) + Error func(e error) +} + +func NewStepTerminateServerInstance(conn *ncloud.Conn, ui packer.Ui) *StepTerminateServerInstance { + var step = &StepTerminateServerInstance{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + } + + step.TerminateServerInstance = step.terminateServerInstance + + return step +} + +func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo string) error { + reqParams := new(ncloud.RequestTerminateServerInstances) + reqParams.ServerInstanceNoList = []string{serverInstanceNo} + + serverInstanceList, err := s.Conn.TerminateServerInstances(reqParams) + if err != nil { + return fmt.Errorf("error code: %d , error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + } + + c1 := make(chan error, 1) + + go func() { + reqParams := new(ncloud.RequestGetServerInstanceList) + reqParams.ServerInstanceNoList = []string{serverInstanceNo} + + for { + + serverInstanceList, err := s.Conn.GetServerInstanceList(reqParams) + if err != nil { + c1 <- fmt.Errorf("error code: %d , error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + return + } else if serverInstanceList.TotalRows == 0 { + c1 <- nil + return + } + + time.Sleep(time.Second * 3) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(time.Second * 60): + return errors.New("TIMEOUT : Can't terminate server instance") + } +} + +func (s *StepTerminateServerInstance) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Terminate Server Instance") + + var serverInstanceNo = state.Get("InstanceNo").(string) + + err := s.TerminateServerInstance(serverInstanceNo) + + return processStepResult(err, s.Error, state) +} + +func (*StepTerminateServerInstance) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_terminate_server_instance_test.go b/builder/ncloud/step_terminate_server_instance_test.go new file mode 100644 index 000000000..b5967fc65 --- /dev/null +++ b/builder/ncloud/step_terminate_server_instance_test.go @@ -0,0 +1,54 @@ +package ncloud + +import ( + "fmt" + "github.com/mitchellh/multistep" + "testing" +) + +func TestStepTerminateServerInstanceShouldFailIfOperationTerminationFails(t *testing.T) { + var testSubject = &StepTerminateServerInstance{ + TerminateServerInstance: func(serverInstanceNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepTerminateServerInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepTerminateServerInstanceShouldPassIfOperationTerminationPasses(t *testing.T) { + var testSubject = &StepTerminateServerInstance{ + TerminateServerInstance: func(serverInstanceNo string) error { return nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepTerminateServerInstance() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepTerminateServerInstance() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put("InstanceNo", "a") + return stateBag +} diff --git a/builder/ncloud/step_validate_template.go b/builder/ncloud/step_validate_template.go new file mode 100644 index 000000000..0007bfa40 --- /dev/null +++ b/builder/ncloud/step_validate_template.go @@ -0,0 +1,263 @@ +package ncloud + +import ( + "bytes" + "errors" + "fmt" + "strings" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/olekukonko/tablewriter" +) + +//StepValidateTemplate : struct for Validation a tempalte +type StepValidateTemplate struct { + Conn *ncloud.Conn + Validate func() error + Say func(message string) + Error func(e error) + Config *Config + zoneNo string + regionNo string +} + +// NewStepValidateTemplate : funciton for Validation a tempalte +func NewStepValidateTemplate(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepValidateTemplate { + var step = &StepValidateTemplate{ + Conn: conn, + Say: func(message string) { ui.Say(message) }, + Error: func(e error) { ui.Error(e.Error()) }, + Config: config, + } + + step.Validate = step.validateTemplate + + return step +} + +// getZoneNo : get zoneNo +func (s *StepValidateTemplate) getZoneNo() error { + if s.Config.Region == "" { + return nil + } + + regionList, err := s.Conn.GetRegionList() + if err != nil { + return fmt.Errorf("error code: %d , error message: %s", regionList.ReturnCode, regionList.ReturnMessage) + } + + var regionNo string + for _, region := range regionList.RegionList { + if strings.EqualFold(region.RegionName, s.Config.Region) { + regionNo = region.RegionNo + } + } + + if regionNo == "" { + return fmt.Errorf("region %s is invalid", s.Config.Region) + } + + s.regionNo = regionNo + + // Get ZoneNo + ZoneList, err := s.Conn.GetZoneList(regionNo) + if err != nil { + return fmt.Errorf("error code: %d , error message: %s", ZoneList.ReturnCode, ZoneList.ReturnMessage) + } + + if len(ZoneList.Zone) > 0 { + s.zoneNo = ZoneList.Zone[0].ZoneNo + } + + return nil +} + +func (s *StepValidateTemplate) validateMemberServerImage() error { + var serverImageName = s.Config.ServerImageName + + reqParams := new(ncloud.RequestServerImageList) + reqParams.RegionNo = s.regionNo + + memberServerImageList, err := s.Conn.GetMemberServerImageList(reqParams) + if err != nil { + return err + } + + var isExistMemberServerImageNo = false + for _, image := range memberServerImageList.MemberServerImageList { + // Check duplicate server_image_name + if image.MemberServerImageName == serverImageName { + return fmt.Errorf("server_image_name %s is exists", serverImageName) + } + + if image.MemberServerImageNo == s.Config.MemberServerImageNo { + isExistMemberServerImageNo = true + if s.Config.ServerProductCode == "" { + s.Config.ServerProductCode = image.OriginalServerProductCode + s.Say("server_product_code for member server image '" + image.OriginalServerProductCode + "' is configured automatically") + } + s.Config.ServerImageProductCode = image.OriginalServerImageProductCode + } + } + + if s.Config.MemberServerImageNo != "" && !isExistMemberServerImageNo { + return fmt.Errorf("member_server_image_no %s does not exist", s.Config.MemberServerImageNo) + } + + return nil +} + +func (s *StepValidateTemplate) validateServerImageProduct() error { + var serverImageProductCode = s.Config.ServerImageProductCode + if serverImageProductCode == "" { + return nil + } + + reqParams := new(ncloud.RequestGetServerImageProductList) + reqParams.RegionNo = s.regionNo + + serverImageProductList, err := s.Conn.GetServerImageProductList(reqParams) + if err != nil { + return err + } + + var isExistServerImage = false + var buf bytes.Buffer + var productName string + table := tablewriter.NewWriter(&buf) + table.SetHeader([]string{"Name", "Code"}) + + for _, product := range serverImageProductList.Product { + // Check exist server image product code + if product.ProductCode == serverImageProductCode { + isExistServerImage = true + productName = product.ProductName + break + } + + table.Append([]string{product.ProductName, product.ProductCode}) + } + + if !isExistServerImage { + reqParams.BlockStorageSize = 100 + + serverImageProductList, err := s.Conn.GetServerImageProductList(reqParams) + if err != nil { + return err + } + + for _, product := range serverImageProductList.Product { + // Check exist server image product code + if product.ProductCode == serverImageProductCode { + isExistServerImage = true + productName = product.ProductName + break + } + + table.Append([]string{product.ProductName, product.ProductCode}) + } + } + + if !isExistServerImage { + table.Render() + s.Say(buf.String()) + + return fmt.Errorf("server_image_product_code %s does not exist", serverImageProductCode) + } + + if strings.Contains(productName, "mssql") { + s.Config.FeeSystemTypeCode = "FXSUM" + } + + return nil +} + +func (s *StepValidateTemplate) validateServerProductCode() error { + var serverImageProductCode = s.Config.ServerImageProductCode + var productCode = s.Config.ServerProductCode + + reqParams := new(ncloud.RequestGetServerProductList) + reqParams.ServerImageProductCode = serverImageProductCode + reqParams.RegionNo = s.regionNo + + productList, err := s.Conn.GetServerProductList(reqParams) + if err != nil { + return err + } + + var isExistProductCode = false + for _, product := range productList.Product { + // Check exist server image product code + if product.ProductCode == productCode { + isExistProductCode = true + if strings.Contains(product.ProductName, "mssql") { + s.Config.FeeSystemTypeCode = "FXSUM" + } + + if product.ProductType.Code == "VDS" { + return errors.New("You cannot create my server image for VDS servers") + } + + break + } else if productCode == "" && product.ProductType.Code == "STAND" { + isExistProductCode = true + s.Config.ServerProductCode = product.ProductCode + s.Say("server_product_code '" + product.ProductCode + "' is configured automatically") + break + } + } + + if !isExistProductCode { + var buf bytes.Buffer + table := tablewriter.NewWriter(&buf) + table.SetHeader([]string{"Name", "Code"}) + for _, product := range productList.Product { + table.Append([]string{product.ProductName, product.ProductCode}) + } + table.Render() + + s.Say(buf.String()) + + return fmt.Errorf("server_product_code %s does not exist", productCode) + } + + return nil +} + +// Check ImageName / Product Code / Server Image Product Code / Server Product Code... +func (s *StepValidateTemplate) validateTemplate() error { + // Get RegionNo, ZoneNo + if err := s.getZoneNo(); err != nil { + return err + } + + // Validate member_server_image_no and member_server_image_no + if err := s.validateMemberServerImage(); err != nil { + return err + } + + // Validate server_image_product_code + if err := s.validateServerImageProduct(); err != nil { + return err + } + + // Validate server_product_code + return s.validateServerProductCode() +} + +// Run : main funciton for validation a template +func (s *StepValidateTemplate) Run(state multistep.StateBag) multistep.StepAction { + s.Say("Validating deployment template ...") + + err := s.Validate() + + state.Put("ZoneNo", s.zoneNo) + + return processStepResult(err, s.Error, state) +} + +// Cleanup : cleanup on error +func (s *StepValidateTemplate) Cleanup(multistep.StateBag) { +} diff --git a/builder/ncloud/step_validate_template_test.go b/builder/ncloud/step_validate_template_test.go new file mode 100644 index 000000000..98f45b4a0 --- /dev/null +++ b/builder/ncloud/step_validate_template_test.go @@ -0,0 +1,54 @@ +package ncloud + +import ( + "fmt" + "testing" + + "github.com/mitchellh/multistep" +) + +func TestStepValidateTemplateShouldFailIfValidateFails(t *testing.T) { + var testSubject = &StepValidateTemplate{ + Validate: func() error { return fmt.Errorf("!! Unit Test FAIL !!") }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepValidateTemplate() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == false { + t.Fatal("Expected the step to set stateBag['Error'], but it was not.") + } +} + +func TestStepValidateTemplateShouldPassIfValidatePasses(t *testing.T) { + var testSubject = &StepValidateTemplate{ + Validate: func() error { return nil }, + Say: func(message string) {}, + Error: func(e error) {}, + } + + stateBag := createTestStateBagStepValidateTemplate() + + var result = testSubject.Run(stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk("Error"); ok == true { + t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") + } +} + +func createTestStateBagStepValidateTemplate() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + return stateBag +} diff --git a/builder/ncloud/waiter_block_storage_instance.go b/builder/ncloud/waiter_block_storage_instance.go new file mode 100644 index 000000000..9cfa5562a --- /dev/null +++ b/builder/ncloud/waiter_block_storage_instance.go @@ -0,0 +1,80 @@ +package ncloud + +import ( + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" +) + +func waiterBlockStorageInstanceStatus(conn *ncloud.Conn, blockStorageInstanceNo string, status string, timeout time.Duration) error { + reqParams := new(ncloud.RequestBlockStorageInstanceList) + reqParams.BlockStorageInstanceNoList = []string{blockStorageInstanceNo} + + c1 := make(chan error, 1) + + go func() { + for { + blockStorageInstanceList, err := conn.GetBlockStorageInstance(reqParams) + if err != nil { + c1 <- err + return + } + + if status == "DETAC" && len(blockStorageInstanceList.BlockStorageInstance) == 0 { + c1 <- nil + return + } + + code := blockStorageInstanceList.BlockStorageInstance[0].BlockStorageInstanceStatus.Code + operationCode := blockStorageInstanceList.BlockStorageInstance[0].BlockStorageInstanceOperation.Code + + if code == status && operationCode == "NULL" { + c1 <- nil + return + } + + log.Println(blockStorageInstanceList.BlockStorageInstance[0]) + time.Sleep(time.Second * 5) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(timeout): + return fmt.Errorf("TIMEOUT : block storage instance status is not changed into status %s", status) + } +} + +func waiterDetachedBlockStorageInstance(conn *ncloud.Conn, serverInstanceNo string, timeout time.Duration) error { + reqParams := new(ncloud.RequestBlockStorageInstanceList) + reqParams.ServerInstanceNo = serverInstanceNo + + c1 := make(chan error, 1) + + go func() { + for { + blockStorageInstanceList, err := conn.GetBlockStorageInstance(reqParams) + if err != nil { + c1 <- err + return + } + + if blockStorageInstanceList.TotalRows == 1 { + c1 <- nil + return + } + + time.Sleep(time.Second * 5) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(timeout): + return fmt.Errorf("TIMEOUT : attached block storage instance is not detached") + } +} diff --git a/builder/ncloud/waiter_server_image_status.go b/builder/ncloud/waiter_server_image_status.go new file mode 100644 index 000000000..5ba640874 --- /dev/null +++ b/builder/ncloud/waiter_server_image_status.go @@ -0,0 +1,43 @@ +package ncloud + +import ( + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" +) + +func waiterMemberServerImageStatus(conn *ncloud.Conn, memberServerImageNo string, status string, timeout time.Duration) error { + reqParams := new(ncloud.RequestServerImageList) + reqParams.MemberServerImageNoList = []string{memberServerImageNo} + + c1 := make(chan error, 1) + + go func() { + for { + memberServerImageList, err := conn.GetMemberServerImageList(reqParams) + if err != nil { + c1 <- err + return + } + + code := memberServerImageList.MemberServerImageList[0].MemberServerImageStatus.Code + if code == status { + c1 <- nil + return + } + + log.Printf("Status of member server image [%s] is %s\n", memberServerImageNo, code) + log.Println(memberServerImageList.MemberServerImageList[0]) + time.Sleep(time.Second * 5) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(timeout): + return fmt.Errorf("TIMEOUT : member server image status is not changed into status %s", status) + } +} diff --git a/builder/ncloud/waiter_server_instance_status.go b/builder/ncloud/waiter_server_instance_status.go new file mode 100644 index 000000000..176cde701 --- /dev/null +++ b/builder/ncloud/waiter_server_instance_status.go @@ -0,0 +1,43 @@ +package ncloud + +import ( + "fmt" + "log" + "time" + + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" +) + +func waiterServerInstanceStatus(conn *ncloud.Conn, serverInstanceNo string, status string, timeout time.Duration) error { + reqParams := new(ncloud.RequestGetServerInstanceList) + reqParams.ServerInstanceNoList = []string{serverInstanceNo} + + c1 := make(chan error, 1) + + go func() { + for { + serverInstanceList, err := conn.GetServerInstanceList(reqParams) + if err != nil { + c1 <- err + return + } + + code := serverInstanceList.ServerInstanceList[0].ServerInstanceStatus.Code + if code == status { + c1 <- nil + return + } + + log.Printf("Status of serverInstanceNo [%s] is %s\n", serverInstanceNo, code) + log.Println(serverInstanceList.ServerInstanceList[0]) + time.Sleep(time.Second * 5) + } + }() + + select { + case res := <-c1: + return res + case <-time.After(timeout): + return fmt.Errorf("TIMEOUT : server instance status is not changed into status %s", status) + } +} diff --git a/command/plugin.go b/command/plugin.go index d9e7ea577..73a04a035 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -29,6 +29,7 @@ import ( hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" lxcbuilder "github.com/hashicorp/packer/builder/lxc" lxdbuilder "github.com/hashicorp/packer/builder/lxd" + ncloudbuilder "github.com/hashicorp/packer/builder/ncloud" nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" openstackbuilder "github.com/hashicorp/packer/builder/openstack" @@ -96,6 +97,7 @@ var Builders = map[string]packer.Builder{ "hyperv-vmcx": new(hypervvmcxbuilder.Builder), "lxc": new(lxcbuilder.Builder), "lxd": new(lxdbuilder.Builder), + "ncloud": new(ncloudbuilder.Builder), "null": new(nullbuilder.Builder), "oneandone": new(oneandonebuilder.Builder), "openstack": new(openstackbuilder.Builder), From 4f9754a75c79b70bf795a2286766571440bfb1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Thu, 11 Jan 2018 19:41:47 +0900 Subject: [PATCH 0370/1007] add ncloud-sdk-go dependency to vendor --- .../NaverCloudPlatform/ncloud-sdk-go/LICENSE | 7 + .../NaverCloudPlatform/ncloud-sdk-go/NOTICE | 26 ++ .../ncloud-sdk-go/common/commonResponse.go | 14 + .../ncloud-sdk-go/common/commoncode.go | 10 + .../common/parseErrorResponse.go | 20 + .../ncloud-sdk-go/common/region.go | 7 + .../ncloud-sdk-go/common/zone.go | 7 + .../ncloud-sdk-go/oauth/oauth.go | 370 ++++++++++++++++++ .../ncloud-sdk-go/request/request.go | 38 ++ .../ncloud-sdk-go/sdk/connection.go | 21 + .../sdk/createBlockStorageInstance.go | 87 ++++ .../ncloud-sdk-go/sdk/createLoginKey.go | 64 +++ .../sdk/createPublicIpInstance.go | 74 ++++ .../ncloud-sdk-go/sdk/createServerImage.go | 71 ++++ .../sdk/createServerInstances.go | 148 +++++++ .../sdk/deleteBlockStorageInstances.go | 60 +++ .../ncloud-sdk-go/sdk/deleteLoginKey.go | 59 +++ .../sdk/deletePublicIpInstances.go | 62 +++ .../disassociatePublicIpFromServerInstance.go | 54 +++ .../sdk/getAccessControlGroupList.go | 89 +++++ .../sdk/getAccessControlRuleList.go | 61 +++ .../sdk/getBlockStorageInstanceList.go | 144 +++++++ .../ncloud-sdk-go/sdk/getLoginKeyList.go | 77 ++++ .../sdk/getMemberServerImagesList.go | 87 ++++ .../sdk/getPublicIpInstanceList.go | 130 ++++++ .../ncloud-sdk-go/sdk/getRegionList.go | 40 ++ .../ncloud-sdk-go/sdk/getRootPassword.go | 67 ++++ .../sdk/getServerImageProductList.go | 88 +++++ .../sdk/getServerInstanceList.go | 133 +++++++ .../ncloud-sdk-go/sdk/getServerProductList.go | 79 ++++ .../ncloud-sdk-go/sdk/getZoneList.go | 44 +++ .../ncloud-sdk-go/sdk/model.go | 359 +++++++++++++++++ .../ncloud-sdk-go/sdk/stopServerInstances.go | 62 +++ .../sdk/terminateServerInstances.go | 62 +++ vendor/vendor.json | 24 ++ 35 files changed, 2745 insertions(+) create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/LICENSE create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/NOTICE create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commonResponse.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commoncode.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/parseErrorResponse.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/region.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/zone.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/oauth/oauth.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/request/request.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/connection.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createBlockStorageInstance.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createLoginKey.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createPublicIpInstance.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerImage.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerInstances.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteBlockStorageInstances.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteLoginKey.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deletePublicIpInstances.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/disassociatePublicIpFromServerInstance.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlGroupList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlRuleList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getBlockStorageInstanceList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getLoginKeyList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getMemberServerImagesList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getPublicIpInstanceList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRegionList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRootPassword.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerImageProductList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerInstanceList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerProductList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getZoneList.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/model.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/stopServerInstances.go create mode 100644 vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/terminateServerInstances.go diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/LICENSE b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/LICENSE new file mode 100644 index 000000000..4ae922683 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/LICENSE @@ -0,0 +1,7 @@ +Copyright 2017 NAVER BUSINESS PLATFORM Corp. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/NOTICE b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/NOTICE new file mode 100644 index 000000000..f495434a4 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/NOTICE @@ -0,0 +1,26 @@ +ncp-sdk-go + +This project contains subcomponents with separate copyright notices and license terms. +Your use of the source code for these subcomponents is subject to the terms and conditions of the following licenses. + +======================================================================= +OAuth 1.0 Library for Go (https://github.com/mrjones/oauth/) +======================================================================= + +Copyright (C) 2013 Matthew R. Jones + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commonResponse.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commonResponse.go new file mode 100644 index 000000000..33f12f983 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commonResponse.go @@ -0,0 +1,14 @@ +package common + +import "encoding/xml" + +type CommonResponse struct { + RequestID string `xml:"requestId"` + ReturnCode int `xml:"returnCode"` + ReturnMessage string `xml:"returnMessage"` +} + +type ResponseError struct { + ResponseError xml.Name `xml:"responseError"` + CommonResponse +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commoncode.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commoncode.go new file mode 100644 index 000000000..aff8bcf98 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/commoncode.go @@ -0,0 +1,10 @@ +package common + +type CommonCode struct { + CodeKind string `xml:"codeKind"` + DetailCategorizeCode string `xml:"detailCategorizeCode"` + Code string `xml:"code"` + CodeName string `xml:"codeName"` + CodeOrder int `xml:"codeOrder"` + JavaConstantCode string `xml:"javaConstantCode"` +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/parseErrorResponse.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/parseErrorResponse.go new file mode 100644 index 000000000..10c76f58c --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/parseErrorResponse.go @@ -0,0 +1,20 @@ +package common + +import ( + "encoding/xml" + "strings" +) + +func ParseErrorResponse(bytes []byte) (*ResponseError, error) { + responseError := ResponseError{} + + if err := xml.Unmarshal([]byte(bytes), &responseError); err != nil { + return nil, err + } + + if responseError.ReturnMessage != "" { + responseError.ReturnMessage = strings.TrimSpace(responseError.ReturnMessage) + } + + return &responseError, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/region.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/region.go new file mode 100644 index 000000000..eaa055f6e --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/region.go @@ -0,0 +1,7 @@ +package common + +type Region struct { + RegionNo string `xml:"regionNo"` + RegionCode string `xml:"regionCode"` + RegionName string `xml:"regionName"` +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/zone.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/zone.go new file mode 100644 index 000000000..f2ec78381 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/common/zone.go @@ -0,0 +1,7 @@ +package common + +type Zone struct { + ZoneNo string `xml:"zoneNo"` + ZoneName string `xml:"zoneName"` + ZoneDescription string `xml:"zoneDescription"` +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/oauth/oauth.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/oauth/oauth.go new file mode 100644 index 000000000..c6b917b4c --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/oauth/oauth.go @@ -0,0 +1,370 @@ +package oauth + +import ( + "crypto" + "crypto/hmac" + _ "crypto/sha1" + "encoding/base64" + "fmt" + "math/rand" + "net/url" + "os" + "sort" + "strconv" + "sync" + "time" +) + +const ( + OAUTH_VERSION = "1.0" + SIGNATURE_METHOD_HMAC = "HMAC-" + + HTTP_AUTH_HEADER = "Authorization" + OAUTH_HEADER = "OAuth " + CONSUMER_KEY_PARAM = "oauth_consumer_key" + NONCE_PARAM = "oauth_nonce" + SIGNATURE_METHOD_PARAM = "oauth_signature_method" + SIGNATURE_PARAM = "oauth_signature" + TIMESTAMP_PARAM = "oauth_timestamp" + TOKEN_PARAM = "oauth_token" + TOKEN_SECRET_PARAM = "oauth_token_secret" + VERSION_PARAM = "oauth_version" +) + +var HASH_METHOD_MAP = map[crypto.Hash]string{ + crypto.SHA1: "SHA1", + crypto.SHA256: "SHA256", +} + +// Creates a new Consumer instance, with a HMAC-SHA1 signer +func NewConsumer(consumerKey string, consumerSecret string, requestMethod string, requestURL string) *Consumer { + clock := &defaultClock{} + consumer := &Consumer{ + consumerKey: consumerKey, + consumerSecret: consumerSecret, + requestMethod: requestMethod, + requestURL: requestURL, + clock: clock, + nonceGenerator: newLockedNonceGenerator(clock), + + AdditionalParams: make(map[string]string), + } + + consumer.signer = &HMACSigner{ + consumerSecret: consumerSecret, + hashFunc: crypto.SHA1, + } + + return consumer +} + +// lockedNonceGenerator wraps a non-reentrant random number generator with alock +type lockedNonceGenerator struct { + nonceGenerator nonceGenerator + lock sync.Mutex +} + +func newLockedNonceGenerator(c clock) *lockedNonceGenerator { + return &lockedNonceGenerator{ + nonceGenerator: rand.New(rand.NewSource(c.Nanos())), + } +} + +func (n *lockedNonceGenerator) Int63() int64 { + n.lock.Lock() + r := n.nonceGenerator.Int63() + n.lock.Unlock() + return r +} + +type clock interface { + Seconds() int64 + Nanos() int64 +} + +type nonceGenerator interface { + Int63() int64 +} + +type signer interface { + Sign(message string) (string, error) + Verify(message string, signature string) error + SignatureMethod() string + HashFunc() crypto.Hash + Debug(enabled bool) +} + +type defaultClock struct{} + +func (*defaultClock) Seconds() int64 { + return time.Now().Unix() +} + +func (*defaultClock) Nanos() int64 { + return time.Now().UnixNano() +} + +type Consumer struct { + AdditionalParams map[string]string + + // The rest of this class is configured via the NewConsumer function. + consumerKey string + + consumerSecret string + + requestMethod string + + requestURL string + + debug bool + + // Private seams for mocking dependencies when testing + clock clock + // Seeded generators are not reentrant + nonceGenerator nonceGenerator + signer signer +} + +type HMACSigner struct { + consumerSecret string + hashFunc crypto.Hash + debug bool +} + +func (s *HMACSigner) Debug(enabled bool) { + s.debug = enabled +} + +func (s *HMACSigner) Sign(message string) (string, error) { + key := escape(s.consumerSecret) + if s.debug { + fmt.Println("Signing:", message) + fmt.Println("Key:", key) + } + + h := hmac.New(s.HashFunc().New, []byte(key+"&")) + h.Write([]byte(message)) + rawSignature := h.Sum(nil) + + base64signature := base64.StdEncoding.EncodeToString(rawSignature) + if s.debug { + fmt.Println("Base64 signature:", base64signature) + } + return base64signature, nil +} + +func (s *HMACSigner) Verify(message string, signature string) error { + if s.debug { + fmt.Println("Verifying Base64 signature:", signature) + } + validSignature, err := s.Sign(message) + if err != nil { + return err + } + + if validSignature != signature { + decodedSigniture, _ := url.QueryUnescape(signature) + if validSignature != decodedSigniture { + return fmt.Errorf("signature did not match") + } + } + + return nil +} + +func (s *HMACSigner) SignatureMethod() string { + return SIGNATURE_METHOD_HMAC + HASH_METHOD_MAP[s.HashFunc()] +} + +func (s *HMACSigner) HashFunc() crypto.Hash { + return s.hashFunc +} + +func escape(s string) string { + t := make([]byte, 0, 3*len(s)) + for i := 0; i < len(s); i++ { + c := s[i] + if isEscapable(c) { + t = append(t, '%') + t = append(t, "0123456789ABCDEF"[c>>4]) + t = append(t, "0123456789ABCDEF"[c&15]) + } else { + t = append(t, s[i]) + } + } + return string(t) +} + +func isEscapable(b byte) bool { + return !('A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9' || b == '-' || b == '.' || b == '_' || b == '~') +} + +func (c *Consumer) Debug(enabled bool) { + c.debug = enabled + c.signer.Debug(enabled) +} + +func (c *Consumer) GetRequestUrl() (loginUrl string, err error) { + if os.Getenv("GO_ENV") == "development" { + c.AdditionalParams["approachKey"] = c.consumerKey + c.AdditionalParams["secretKey"] = c.consumerSecret + } + c.AdditionalParams["responseFormatType"] = "xml" + + params := c.baseParams(c.consumerKey, c.AdditionalParams) + + if c.debug { + fmt.Println("params:", params) + } + + req := &request{ + method: c.requestMethod, + url: c.requestURL, + oauthParams: params, + } + + signature, err := c.signRequest(req) + if err != nil { + return "", err + } + + result := req.url + "?" + for pos, key := range req.oauthParams.Keys() { + for innerPos, value := range req.oauthParams.Get(key) { + if pos+innerPos != 0 { + result += "&" + } + result += fmt.Sprintf("%s=%s", key, value) + } + } + + result += fmt.Sprintf("&%s=%s", SIGNATURE_PARAM, escape(signature)) + + if c.debug { + fmt.Println("req: ", result) + } + + return result, nil +} + +func (c *Consumer) baseParams(consumerKey string, additionalParams map[string]string) *OrderedParams { + params := NewOrderedParams() + params.Add(VERSION_PARAM, OAUTH_VERSION) + params.Add(SIGNATURE_METHOD_PARAM, c.signer.SignatureMethod()) + params.Add(TIMESTAMP_PARAM, strconv.FormatInt(c.clock.Seconds(), 10)) + params.Add(NONCE_PARAM, strconv.FormatInt(c.nonceGenerator.Int63(), 10)) + params.Add(CONSUMER_KEY_PARAM, consumerKey) + + for key, value := range additionalParams { + params.Add(key, value) + } + + return params +} + +func (c *Consumer) signRequest(req *request) (string, error) { + baseString := c.requestString(req.method, req.url, req.oauthParams) + + if c.debug { + fmt.Println("baseString: ", baseString) + } + + signature, err := c.signer.Sign(baseString) + if err != nil { + return "", err + } + + return signature, nil +} + +func (c *Consumer) requestString(method string, url string, params *OrderedParams) string { + result := method + "&" + escape(url) + for pos, key := range params.Keys() { + for innerPos, value := range params.Get(key) { + if pos+innerPos == 0 { + result += "&" + } else { + result += escape("&") + } + result += escape(fmt.Sprintf("%s=%s", key, value)) + } + } + return result +} + +type request struct { + method string + url string + oauthParams *OrderedParams + userParams map[string]string +} + +// +// String Sorting helpers +// + +type ByValue []string + +func (a ByValue) Len() int { + return len(a) +} + +func (a ByValue) Swap(i, j int) { + a[i], a[j] = a[j], a[i] +} + +func (a ByValue) Less(i, j int) bool { + return a[i] < a[j] +} + +// +// ORDERED PARAMS +// + +type OrderedParams struct { + allParams map[string][]string + keyOrdering []string +} + +func NewOrderedParams() *OrderedParams { + return &OrderedParams{ + allParams: make(map[string][]string), + keyOrdering: make([]string, 0), + } +} + +func (o *OrderedParams) Get(key string) []string { + sort.Sort(ByValue(o.allParams[key])) + return o.allParams[key] +} + +func (o *OrderedParams) Keys() []string { + sort.Sort(o) + return o.keyOrdering +} + +func (o *OrderedParams) Add(key, value string) { + o.AddUnescaped(key, escape(value)) +} + +func (o *OrderedParams) AddUnescaped(key, value string) { + if _, exists := o.allParams[key]; !exists { + o.keyOrdering = append(o.keyOrdering, key) + o.allParams[key] = make([]string, 1) + o.allParams[key][0] = value + } else { + o.allParams[key] = append(o.allParams[key], value) + } +} + +func (o *OrderedParams) Len() int { + return len(o.keyOrdering) +} + +func (o *OrderedParams) Less(i int, j int) bool { + return o.keyOrdering[i] < o.keyOrdering[j] +} + +func (o *OrderedParams) Swap(i int, j int) { + o.keyOrdering[i], o.keyOrdering[j] = o.keyOrdering[j], o.keyOrdering[i] +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/request/request.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/request/request.go new file mode 100644 index 000000000..2f0d77d14 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/request/request.go @@ -0,0 +1,38 @@ +package request + +import ( + "io/ioutil" + "net/http" + + "github.com/NaverCloudPlatform/ncloud-sdk-go/oauth" +) + +// NewRequest is http request with oauth +func NewRequest(accessKey string, secretKey string, method string, url string, params map[string]string) ([]byte, *http.Response, error) { + c := oauth.NewConsumer(accessKey, secretKey, method, url) + + for k, v := range params { + c.AdditionalParams[k] = v + } + + reqURL, err := c.GetRequestUrl() + if err != nil { + return nil, nil, err + } + + req, err := http.NewRequest(method, reqURL, nil) + if err != nil { + return nil, nil, err + } + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + bytes, _ := ioutil.ReadAll(resp.Body) + + return bytes, resp, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/connection.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/connection.go new file mode 100644 index 000000000..27f8a6197 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/connection.go @@ -0,0 +1,21 @@ +package sdk + +import ( + "os" +) + +// NewConnection create connection for server api +func NewConnection(accessKey string, secretKey string) *Conn { + conn := &Conn{ + accessKey: accessKey, + secretKey: secretKey, + apiURL: "https://api.ncloud.com/", + } + + // for other phase(dev, test, beta ...) test + if os.Getenv("NCLOUD_API_GW") != "" { + conn.apiURL = os.Getenv("NCLOUD_API_GW") + } + + return conn +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createBlockStorageInstance.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createBlockStorageInstance.go new file mode 100644 index 000000000..3fd8e61b7 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createBlockStorageInstance.go @@ -0,0 +1,87 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processCreateBlockStorageInstanceParams(reqParams *RequestBlockStorageInstance) (map[string]string, error) { + params := make(map[string]string) + + if reqParams.BlockStorageName != "" { + if len := len(reqParams.BlockStorageName); len < 3 || len > 30 { + return nil, errors.New("Length of BlockStorageName should be min 3 or max 30") + } + params["blockStorageName"] = reqParams.BlockStorageName + } + + if reqParams.BlockStorageSize < 10 || reqParams.BlockStorageSize > 2000 { + return nil, errors.New("BlockStorageSize should be min 10 or max 2000") + } + + if reqParams.BlockStorageDescription != "" { + if len := len(reqParams.BlockStorageDescription); len > 1000 { + return nil, errors.New("Length of BlockStorageDescription should be max 1000") + } + params["blockStorageDescription"] = reqParams.BlockStorageDescription + } + + if int(reqParams.BlockStorageSize/10)*10 != reqParams.BlockStorageSize { + return nil, errors.New("BlockStorageSize must be a multiple of 10 GB") + } + + if reqParams.BlockStorageSize == 0 { + return nil, errors.New("BlockStorageSize field is required") + } + + params["blockStorageSize"] = strconv.Itoa(reqParams.BlockStorageSize) + + if reqParams.ServerInstanceNo == "" { + return nil, errors.New("ServerInstanceNo field is required") + } + + params["serverInstanceNo"] = reqParams.ServerInstanceNo + + return params, nil +} + +// CreateBlockStorageInstance create block storage instance +func (s *Conn) CreateBlockStorageInstance(reqParams *RequestBlockStorageInstance) (*BlockStorageInstanceList, error) { + + params, err := processCreateBlockStorageInstanceParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "createBlockStorageInstance" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := BlockStorageInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var blockStorageInstanceList = BlockStorageInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &blockStorageInstanceList); err != nil { + return nil, err + } + + return &blockStorageInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createLoginKey.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createLoginKey.go new file mode 100644 index 000000000..b2cd490dc --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createLoginKey.go @@ -0,0 +1,64 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strings" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processCreateLoginKeyParams(keyName string) error { + if keyName == "" { + return errors.New("KeyName is required field") + } + + if len := len(keyName); len < 3 || len > 30 { + return errors.New("Length of KeyName should be min 3 or max 30") + } + + return nil +} + +// CreateLoginKey create loginkey with keyName +func (s *Conn) CreateLoginKey(keyName string) (*PrivateKey, error) { + if err := processCreateLoginKeyParams(keyName); err != nil { + return nil, err + } + + params := make(map[string]string) + + params["keyName"] = keyName + params["action"] = "createLoginKey" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := PrivateKey{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + privateKey := PrivateKey{} + if err := xml.Unmarshal([]byte(bytes), &privateKey); err != nil { + return nil, err + } + + if privateKey.PrivateKey != "" { + privateKey.PrivateKey = strings.TrimSpace(privateKey.PrivateKey) + } + + return &privateKey, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createPublicIpInstance.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createPublicIpInstance.go new file mode 100644 index 000000000..6dc5aa0fe --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createPublicIpInstance.go @@ -0,0 +1,74 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processCreatePublicIPInstanceParams(reqParams *RequestCreatePublicIPInstance) (map[string]string, error) { + params := make(map[string]string) + + if reqParams.ServerInstanceNo != "" { + params["serverInstanceNo"] = reqParams.ServerInstanceNo + } + + if reqParams.PublicIPDescription != "" { + if len := len(reqParams.PublicIPDescription); len > 1000 { + return params, errors.New("Length of publicIpDescription should be max 1000") + } + params["publicIpDescription"] = reqParams.PublicIPDescription + } + + if reqParams.InternetLineTypeCode != "" { + if reqParams.InternetLineTypeCode != "PUBLC" && reqParams.InternetLineTypeCode != "GLBL" { + return params, errors.New("InternetLineTypeCode should be PUBLC or GLBL") + } + params["internetLineTypeCode"] = reqParams.InternetLineTypeCode + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + return params, nil +} + +// CreatePublicIPInstance create public ip instance and allocate it to server instance +func (s *Conn) CreatePublicIPInstance(reqParams *RequestCreatePublicIPInstance) (*PublicIPInstanceList, error) { + params, err := processCreatePublicIPInstanceParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "createPublicIpInstance" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := PublicIPInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var responseCreatePublicIPInstances = PublicIPInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &responseCreatePublicIPInstances); err != nil { + fmt.Println(err) + return nil, err + } + + return &responseCreatePublicIPInstances, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerImage.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerImage.go new file mode 100644 index 000000000..11fb9b308 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerImage.go @@ -0,0 +1,71 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processCreateMemberServerImageParams(reqParams *RequestCreateServerImage) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil || reqParams.ServerInstanceNo == "" { + return params, errors.New("ServerInstanceNo is required field") + } + + if reqParams.MemberServerImageName != "" { + if len := len(reqParams.MemberServerImageName); len < 3 || len > 30 { + return nil, errors.New("Length of MemberServerImageName should be min 3 or max 30") + } + params["memberServerImageName"] = reqParams.MemberServerImageName + } + + if reqParams.MemberServerImageDescription != "" { + if len := len(reqParams.MemberServerImageDescription); len > 1000 { + return nil, errors.New("Length of MemberServerImageDescription should be smaller than 1000") + } + params["memberServerImageDescription"] = reqParams.MemberServerImageDescription + } + + params["serverInstanceNo"] = reqParams.ServerInstanceNo + + return params, nil +} + +// CreateMemberServerImage create member server image and retrun member server image list +func (s *Conn) CreateMemberServerImage(reqParams *RequestCreateServerImage) (*MemberServerImageList, error) { + params, err := processCreateMemberServerImageParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "createMemberServerImage" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := MemberServerImageList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var serverImageListsResp = MemberServerImageList{} + if err := xml.Unmarshal([]byte(bytes), &serverImageListsResp); err != nil { + return nil, err + } + + return &serverImageListsResp, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerInstances.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerInstances.go new file mode 100644 index 000000000..a00da9145 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/createServerInstances.go @@ -0,0 +1,148 @@ +package sdk + +import ( + "encoding/base64" + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processCreateServerInstancesParams(reqParams *RequestCreateServerInstance) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if reqParams.ServerImageProductCode != "" { + if len := len(reqParams.ServerImageProductCode); len > 20 { + return nil, errors.New("Length of ServerImageProductCode should be min 1 or max 20") + } + params["serverImageProductCode"] = reqParams.ServerImageProductCode + } + + if reqParams.ServerProductCode != "" { + if len := len(reqParams.ServerProductCode); len > 20 { + return nil, errors.New("Length of ServerProductCode should be min 1 or max 20") + } + params["serverProductCode"] = reqParams.ServerProductCode + } + + if reqParams.MemberServerImageNo != "" { + params["memberServerImageNo"] = reqParams.MemberServerImageNo + } + + if reqParams.ServerName != "" { + if len := len(reqParams.ServerName); len < 3 || len > 30 { + return nil, errors.New("Length of ServerName should be min 3 or max 30") + } + params["serverName"] = reqParams.ServerName + } + + if reqParams.ServerDescription != "" { + if len := len(reqParams.ServerDescription); len > 1000 { + return nil, errors.New("Length of ServerDescription should be min 1 or max 1000") + } + params["serverDescription"] = reqParams.ServerDescription + } + + if reqParams.LoginKeyName != "" { + if len := len(reqParams.LoginKeyName); len < 3 || len > 30 { + return nil, errors.New("Length of LoginKeyName should be min 3 or max 30") + } + params["loginKeyName"] = reqParams.LoginKeyName + } + + if reqParams.IsProtectServerTermination == true { + params["isProtectServerTermination"] = "true" + } + + if reqParams.ServerCreateCount > 0 { + if reqParams.ServerCreateCount > 20 { + return nil, errors.New("ServerCreateCount should be min 1 or max 20") + + } + params["serverCreateCount"] = strconv.Itoa(reqParams.ServerCreateCount) + } + + if reqParams.ServerCreateStartNo > 0 { + if reqParams.ServerCreateCount+reqParams.ServerCreateStartNo > 1000 { + return nil, errors.New("Sum of ServerCreateCount and ServerCreateStartNo should be less than 1000") + + } + params["serverCreateStartNo"] = strconv.Itoa(reqParams.ServerCreateStartNo) + } + + if reqParams.InternetLineTypeCode != "" { + if reqParams.InternetLineTypeCode != "PUBLC" && reqParams.InternetLineTypeCode != "GLBL" { + return nil, errors.New("InternetLineTypeCode should be PUBLC or GLBL") + } + params["internetLineTypeCode"] = reqParams.InternetLineTypeCode + } + + if reqParams.FeeSystemTypeCode != "" { + if reqParams.FeeSystemTypeCode != "FXSUM" && reqParams.FeeSystemTypeCode != "MTRAT" { + return nil, errors.New("FeeSystemTypeCode should be FXSUM or MTRAT") + } + params["feeSystemTypeCode"] = reqParams.FeeSystemTypeCode + } + + if reqParams.UserData != "" { + if len := len(reqParams.UserData); len > 21847 { + return nil, errors.New("Length of UserData should be min 1 or max 21847") + } + params["userData"] = base64.StdEncoding.EncodeToString([]byte(reqParams.UserData)) + } + + if reqParams.ZoneNo != "" { + params["zoneNo"] = reqParams.ZoneNo + } + + if len(reqParams.AccessControlGroupConfigurationNoList) > 0 { + for k, v := range reqParams.AccessControlGroupConfigurationNoList { + params[fmt.Sprintf("accessControlGroupConfigurationNoList.%d", k+1)] = v + } + } + + return params, nil +} + +// CreateServerInstances create server instances +func (s *Conn) CreateServerInstances(reqParams *RequestCreateServerInstance) (*ServerInstanceList, error) { + params, err := processCreateServerInstancesParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "createServerInstances" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ServerInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var responseCreateServerInstances = ServerInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &responseCreateServerInstances); err != nil { + fmt.Println(err) + return nil, err + } + + return &responseCreateServerInstances, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteBlockStorageInstances.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteBlockStorageInstances.go new file mode 100644 index 000000000..c47f96bfb --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteBlockStorageInstances.go @@ -0,0 +1,60 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processDeleteBlockStorageInstancesParams(blockStorageInstanceNoList []string) (map[string]string, error) { + params := make(map[string]string) + + if len(blockStorageInstanceNoList) == 0 { + return params, errors.New("BlockStorageInstanceNoList field is Required") + } + + for k, v := range blockStorageInstanceNoList { + params[fmt.Sprintf("blockStorageInstanceNoList.%d", k+1)] = v + } + + return params, nil +} + +// DeleteBlockStorageInstances delete block storage instances +func (s *Conn) DeleteBlockStorageInstances(blockStorageInstanceNoList []string) (*BlockStorageInstanceList, error) { + params, err := processDeleteBlockStorageInstancesParams(blockStorageInstanceNoList) + if err != nil { + return nil, err + } + + params["action"] = "deleteBlockStorageInstances" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := BlockStorageInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var blockStorageInstanceList = BlockStorageInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &blockStorageInstanceList); err != nil { + fmt.Println(err) + return nil, err + } + + return &blockStorageInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteLoginKey.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteLoginKey.go new file mode 100644 index 000000000..7cc3cf257 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deleteLoginKey.go @@ -0,0 +1,59 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processDeleteLoginKeyParams(keyName string) error { + if keyName == "" { + return errors.New("KeyName is required field") + } + + if len := len(keyName); len < 3 || len > 30 { + return errors.New("Length of KeyName should be min 3 or max 30") + } + + return nil +} + +// DeleteLoginKey delete login key with keyName +func (s *Conn) DeleteLoginKey(keyName string) (*common.CommonResponse, error) { + if err := processDeleteLoginKeyParams(keyName); err != nil { + return nil, err + } + + params := make(map[string]string) + + params["keyName"] = keyName + params["action"] = "deleteLoginKey" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := common.CommonResponse{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var responseDeleteLoginKey = common.CommonResponse{} + if err := xml.Unmarshal([]byte(bytes), &responseDeleteLoginKey); err != nil { + return nil, err + } + + return &responseDeleteLoginKey, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deletePublicIpInstances.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deletePublicIpInstances.go new file mode 100644 index 000000000..5ea47602b --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/deletePublicIpInstances.go @@ -0,0 +1,62 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processDeletePublicIPInstancesParams(reqParams *RequestDeletePublicIPInstances) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil || len(reqParams.PublicIPInstanceNoList) == 0 { + return params, errors.New("Required field is not specified. location : publicIpInstanceNoList.N") + } + + if len(reqParams.PublicIPInstanceNoList) > 0 { + for k, v := range reqParams.PublicIPInstanceNoList { + params[fmt.Sprintf("publicIpInstanceNoList.%d", k+1)] = v + } + } + + return params, nil +} + +// DeletePublicIPInstances delete public ip instances +func (s *Conn) DeletePublicIPInstances(reqParams *RequestDeletePublicIPInstances) (*PublicIPInstanceList, error) { + params, err := processDeletePublicIPInstancesParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "deletePublicIpInstances" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := PublicIPInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var publicIPInstanceList = PublicIPInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &publicIPInstanceList); err != nil { + fmt.Println(err) + return nil, err + } + + return &publicIPInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/disassociatePublicIpFromServerInstance.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/disassociatePublicIpFromServerInstance.go new file mode 100644 index 000000000..6d1db9efc --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/disassociatePublicIpFromServerInstance.go @@ -0,0 +1,54 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processDisassociatePublicIPParams(PublicIPInstanceNo string) error { + if PublicIPInstanceNo == "" { + return errors.New("Required field is not specified. location : publicIpInstanceNo") + } + + return nil +} + +// DisassociatePublicIP diassociate public ip from server instance +func (s *Conn) DisassociatePublicIP(PublicIPInstanceNo string) (*PublicIPInstanceList, error) { + if err := processDisassociatePublicIPParams(PublicIPInstanceNo); err != nil { + return nil, err + } + + params := make(map[string]string) + params["publicIpInstanceNo"] = PublicIPInstanceNo + params["action"] = "disassociatePublicIpFromServerInstance" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := PublicIPInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var responseDisassociatePublicIPInstances = PublicIPInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &responseDisassociatePublicIPInstances); err != nil { + return nil, err + } + + return &responseDisassociatePublicIPInstances, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlGroupList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlGroupList.go new file mode 100644 index 000000000..937c877ce --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlGroupList.go @@ -0,0 +1,89 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetAccessControlGroupListParams(reqParams *RequestAccessControlGroupList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if len(reqParams.AccessControlGroupConfigurationNoList) > 0 { + for k, v := range reqParams.AccessControlGroupConfigurationNoList { + params[fmt.Sprintf("accessControlGroupConfigurationNoList.%d", k+1)] = v + } + } + + if reqParams.IsDefault { + params["isDefault"] = "true" + } + + if reqParams.AccessControlGroupName != "" { + if len(reqParams.AccessControlGroupName) < 3 || len(reqParams.AccessControlGroupName) > 30 { + return nil, errors.New("AccessControlGroupName must be between 3 and 30 characters in length") + } + params["accessControlGroupName"] = reqParams.AccessControlGroupName + } + + if reqParams.PageNo != 0 { + if reqParams.PageNo > 2147483647 { + return nil, errors.New("PageNo should be up to 2147483647") + } + + params["pageNo"] = strconv.Itoa(reqParams.PageNo) + } + + if reqParams.PageSize != 0 { + if reqParams.PageSize > 2147483647 { + return nil, errors.New("PageSize should be up to 2147483647") + } + + params["pageSize"] = strconv.Itoa(reqParams.PageSize) + } + + return params, nil +} + +// GetAccessControlGroupList get access control group list +func (s *Conn) GetAccessControlGroupList(reqParams *RequestAccessControlGroupList) (*AccessControlGroupList, error) { + params, err := processGetAccessControlGroupListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getAccessControlGroupList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := AccessControlGroupList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var AccessControlGroupList = AccessControlGroupList{} + if err := xml.Unmarshal([]byte(bytes), &AccessControlGroupList); err != nil { + return nil, err + } + + return &AccessControlGroupList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlRuleList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlRuleList.go new file mode 100644 index 000000000..c07f5985c --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getAccessControlRuleList.go @@ -0,0 +1,61 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func checkGetAccessControlRuleListParams(accessControlGroupConfigurationNo string) error { + if accessControlGroupConfigurationNo == "" { + return errors.New("accessControlGroupConfigurationNo is required") + } + + if no, err := strconv.Atoi(accessControlGroupConfigurationNo); err != nil { + return err + } else if no < 0 || no > 2147483647 { + return errors.New("accessControlGroupConfigurationNoeNo must be up to 2147483647") + } + + return nil +} + +// GetAccessControlRuleList get access control group list +func (s *Conn) GetAccessControlRuleList(accessControlGroupConfigurationNo string) (*AccessControlRuleList, error) { + if err := checkGetAccessControlRuleListParams(accessControlGroupConfigurationNo); err != nil { + return nil, err + } + + params := make(map[string]string) + params["accessControlGroupConfigurationNo"] = accessControlGroupConfigurationNo + params["action"] = "getAccessControlRuleList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := AccessControlRuleList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var AccessControlRuleList = AccessControlRuleList{} + if err := xml.Unmarshal([]byte(bytes), &AccessControlRuleList); err != nil { + return nil, err + } + + return &AccessControlRuleList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getBlockStorageInstanceList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getBlockStorageInstanceList.go new file mode 100644 index 000000000..48f1506f3 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getBlockStorageInstanceList.go @@ -0,0 +1,144 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + "strings" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetBlockStorageInstanceListParams(reqParams *RequestBlockStorageInstanceList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if reqParams.ServerInstanceNo != "" { + params["serverInstanceNo"] = reqParams.ServerInstanceNo + } + + if len(reqParams.BlockStorageInstanceNoList) > 0 { + for k, v := range reqParams.BlockStorageInstanceNoList { + params[fmt.Sprintf("blockStorageInstanceNoList.%d", k+1)] = v + } + } + + if reqParams.SearchFilterName != "" { + if reqParams.SearchFilterName != "blockStorageName" && reqParams.SearchFilterName != "attachmentInformation" { + return nil, errors.New("SearchFilterName should be blockStorageName or attachmentInformation") + } + params["searchFilterName"] = reqParams.SearchFilterName + } + + if reqParams.SearchFilterValue == "" { + params["searchFilterValue"] = reqParams.SearchFilterValue + } + + if len(reqParams.BlockStorageTypeCodeList) > 0 { + for k, v := range reqParams.BlockStorageTypeCodeList { + if v != "BASIC" && v != "SVRBS" { + return nil, errors.New("BlockStorageTypeCodeList value should be BASIC or SVRBS") + } + params[fmt.Sprintf("blockStorageTypeCodeList.%d", k+1)] = v + } + } + + if reqParams.PageNo != 0 { + if reqParams.PageNo > 2147483647 { + return nil, errors.New("PageNo should be up to 2147483647") + } + + params["pageNo"] = strconv.Itoa(reqParams.PageNo) + } + + if reqParams.PageSize != 0 { + if reqParams.PageSize > 2147483647 { + return nil, errors.New("PageSize should be up to 2147483647") + } + + params["pageSize"] = strconv.Itoa(reqParams.PageSize) + } + + if reqParams.BlockStorageInstanceStatusCode != "" { + if reqParams.BlockStorageInstanceStatusCode != "ATTAC" && reqParams.BlockStorageInstanceStatusCode != "CRAET" { + return nil, errors.New("BlockStorageInstanceStatusCode should be ATTAC or CRAET") + } + params["blockStorageInstanceStatusCode"] = reqParams.BlockStorageInstanceStatusCode + } + + if reqParams.DiskTypeCode != "" { + if reqParams.DiskTypeCode != "NET" && reqParams.DiskTypeCode != "LOCAL" { + return nil, errors.New("DiskTypeCode should be NET or LOCAL") + } + params["diskTypeCode"] = reqParams.DiskTypeCode + } + + if reqParams.DiskDetailTypeCode != "" { + if reqParams.DiskDetailTypeCode != "HDD" && reqParams.DiskDetailTypeCode != "SSD" { + return nil, errors.New("DiskDetailTypeCode should be HDD or SSD") + } + params["diskDetailTypeCode"] = reqParams.DiskDetailTypeCode + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + if reqParams.SortedBy != "" { + if strings.EqualFold(reqParams.SortedBy, "blockStorageName") || strings.EqualFold(reqParams.SortedBy, "blockStorageInstanceNo") { + params["sortedBy"] = reqParams.SortedBy + } else { + return nil, errors.New("SortedBy should be blockStorageName or blockStorageInstanceNo") + } + } + + if reqParams.SortingOrder != "" { + if strings.EqualFold(reqParams.SortingOrder, "ascending") || strings.EqualFold(reqParams.SortingOrder, "descending") { + params["sortingOrder"] = reqParams.SortingOrder + } else { + return nil, errors.New("SortingOrder should be ascending or descending") + } + } + + return params, nil +} + +// GetBlockStorageInstance Get block storage instance list +func (s *Conn) GetBlockStorageInstance(reqParams *RequestBlockStorageInstanceList) (*BlockStorageInstanceList, error) { + params, err := processGetBlockStorageInstanceListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getBlockStorageInstanceList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := BlockStorageInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var blockStorageInstanceList = BlockStorageInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &blockStorageInstanceList); err != nil { + return nil, err + } + + return &blockStorageInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getLoginKeyList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getLoginKeyList.go new file mode 100644 index 000000000..d6866ebaf --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getLoginKeyList.go @@ -0,0 +1,77 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetLoginKeyListParams(reqParams *RequestGetLoginKeyList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if reqParams.KeyName != "" { + if len := len(reqParams.KeyName); len < 3 || len > 20 { + return nil, errors.New("Length of KeyName should be min 3 or max 30") + } + params["keyName"] = reqParams.KeyName + } + + if reqParams.PageNo > 0 { + if reqParams.PageNo > 2147483647 { + return nil, errors.New("PageNo should be min 0 or max 2147483647") + } + params["pageNo"] = strconv.Itoa(reqParams.PageNo) + } + + if reqParams.PageSize > 0 { + if reqParams.PageSize > 2147483647 { + return nil, errors.New("PageSize should be min 0 or max 2147483647") + } + params["pageSize"] = strconv.Itoa(reqParams.PageSize) + } + + return params, nil +} + +// GetLoginKeyList get login key list +func (s *Conn) GetLoginKeyList(reqParams *RequestGetLoginKeyList) (*LoginKeyList, error) { + params, err := processGetLoginKeyListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getLoginKeyList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := LoginKeyList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + loginKeyList := LoginKeyList{} + if err := xml.Unmarshal([]byte(bytes), &loginKeyList); err != nil { + return nil, err + } + + return &loginKeyList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getMemberServerImagesList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getMemberServerImagesList.go new file mode 100644 index 000000000..f5fe9f8bf --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getMemberServerImagesList.go @@ -0,0 +1,87 @@ +package sdk + +import ( + "encoding/xml" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetMemberServerImageListParams(reqParams *RequestServerImageList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if len(reqParams.MemberServerImageNoList) > 0 { + for k, v := range reqParams.MemberServerImageNoList { + params[fmt.Sprintf("memberServerImageNoList.%d", k+1)] = v + } + } + + if len(reqParams.PlatformTypeCodeList) > 0 { + for k, v := range reqParams.PlatformTypeCodeList { + params[fmt.Sprintf("platformTypeCodeList.%d", k+1)] = v + } + } + + if reqParams.PageNo != 0 { + params["pageNo"] = strconv.Itoa(reqParams.PageNo) + } + + if reqParams.PageSize != 0 { + params["pageSize"] = strconv.Itoa(reqParams.PageSize) + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + if reqParams.SortedBy != "" { + params["sortedBy"] = reqParams.SortedBy + } + + if reqParams.SortingOrder != "" { + params["sortingOrder"] = reqParams.SortingOrder + } + + return params, nil +} + +// GetMemberServerImageList get member server image list +func (s *Conn) GetMemberServerImageList(reqParams *RequestServerImageList) (*MemberServerImageList, error) { + params, err := processGetMemberServerImageListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getMemberServerImageList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := MemberServerImageList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var serverImageListsResp = MemberServerImageList{} + if err := xml.Unmarshal([]byte(bytes), &serverImageListsResp); err != nil { + return nil, err + } + + return &serverImageListsResp, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getPublicIpInstanceList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getPublicIpInstanceList.go new file mode 100644 index 000000000..a781728c6 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getPublicIpInstanceList.go @@ -0,0 +1,130 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + "strings" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetPublicIPInstanceListParams(reqParams *RequestPublicIPInstanceList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if reqParams.IsAssociated { + params["isAssociated"] = "true" + } + + if len(reqParams.PublicIPInstanceNoList) > 0 { + for k, v := range reqParams.PublicIPInstanceNoList { + params[fmt.Sprintf("publicIpInstanceNoList.%d", k+1)] = v + } + } + + if len(reqParams.PublicIPList) > 0 { + for k, v := range reqParams.PublicIPList { + if len(reqParams.PublicIPList) < 5 || len(reqParams.PublicIPList) > 15 { + return nil, errors.New("PublicIPList must be between 5 and 15 characters in length") + } + params[fmt.Sprintf("publicIpList.%d", k+1)] = v + } + } + + if reqParams.SearchFilterName != "" { + if reqParams.SearchFilterName != "publicIp" && reqParams.SearchFilterName != "associatedServerName" { + return nil, errors.New("SearchFilterName must be publicIp or associatedServerName") + } + params["searchFilterName"] = reqParams.SearchFilterName + } + + if reqParams.SearchFilterValue != "" { + params["searchFilterValue"] = reqParams.SearchFilterValue + } + + if reqParams.InternetLineTypeCode != "" { + if reqParams.InternetLineTypeCode != "PUBLC" && reqParams.InternetLineTypeCode != "GLBL" { + return params, errors.New("InternetLineTypeCode must be PUBLC or GLBL") + } + params["internetLineTypeCode"] = reqParams.InternetLineTypeCode + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + if reqParams.PageNo != 0 { + if reqParams.PageNo > 2147483647 { + return nil, errors.New("PageNo must be up to 2147483647") + } + + params["pageNo"] = strconv.Itoa(reqParams.PageNo) + } + + if reqParams.PageSize != 0 { + if reqParams.PageSize > 2147483647 { + return nil, errors.New("PageSize must be up to 2147483647") + } + + params["pageSize"] = strconv.Itoa(reqParams.PageSize) + } + + if reqParams.SortedBy != "" { + if strings.EqualFold(reqParams.SortedBy, "publicIp") || strings.EqualFold(reqParams.SortedBy, "publicIpInstanceNo") { + params["sortedBy"] = reqParams.SortedBy + } else { + return nil, errors.New("SortedBy must be publicIp or publicIpInstanceNo") + } + } + + if reqParams.SortingOrder != "" { + if strings.EqualFold(reqParams.SortingOrder, "ascending") || strings.EqualFold(reqParams.SortingOrder, "descending") { + params["sortingOrder"] = reqParams.SortingOrder + } else { + return nil, errors.New("SortingOrder must be ascending or descending") + } + } + + return params, nil +} + +// GetPublicIPInstanceList get public ip instance list +func (s *Conn) GetPublicIPInstanceList(reqParams *RequestPublicIPInstanceList) (*PublicIPInstanceList, error) { + params, err := processGetPublicIPInstanceListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getPublicIpInstanceList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := PublicIPInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var publicIPInstanceList = PublicIPInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &publicIPInstanceList); err != nil { + return nil, err + } + + return &publicIPInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRegionList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRegionList.go new file mode 100644 index 000000000..0e1647684 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRegionList.go @@ -0,0 +1,40 @@ +package sdk + +import ( + "encoding/xml" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +// GetRegionList gets region list +func (s *Conn) GetRegionList() (*RegionList, error) { + params := make(map[string]string) + params["action"] = "getRegionList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := RegionList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + regionList := RegionList{} + if err := xml.Unmarshal([]byte(bytes), &regionList); err != nil { + return nil, err + } + + return &regionList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRootPassword.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRootPassword.go new file mode 100644 index 000000000..9ec595f49 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getRootPassword.go @@ -0,0 +1,67 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strings" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetRootPasswordParams(reqParams *RequestGetRootPassword) (map[string]string, error) { + params := make(map[string]string) + + if reqParams.ServerInstanceNo == "" { + return params, errors.New("Required field is not specified. location : serverInstanceNo") + } + + if reqParams.PrivateKey == "" { + return params, errors.New("Required field is not specified. location : privateKey") + } + + params["serverInstanceNo"] = reqParams.ServerInstanceNo + params["privateKey"] = reqParams.PrivateKey + + return params, nil +} + +// GetRootPassword get root password from server instance +func (s *Conn) GetRootPassword(reqParams *RequestGetRootPassword) (*RootPassword, error) { + params, err := processGetRootPasswordParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getRootPassword" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := RootPassword{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + responseGetRootPassword := RootPassword{} + if err := xml.Unmarshal([]byte(bytes), &responseGetRootPassword); err != nil { + return nil, err + } + + if responseGetRootPassword.RootPassword != "" { + responseGetRootPassword.RootPassword = strings.TrimSpace(responseGetRootPassword.RootPassword) + } + + return &responseGetRootPassword, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerImageProductList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerImageProductList.go new file mode 100644 index 000000000..645649097 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerImageProductList.go @@ -0,0 +1,88 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetServerImageProductListParams(reqParams *RequestGetServerImageProductList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if reqParams.ExclusionProductCode != "" { + if len(reqParams.ExclusionProductCode) > 20 { + return params, errors.New("Length of exclusionProductCode should be max 20") + } + params["exclusionProductCode"] = reqParams.ExclusionProductCode + } + + if reqParams.ProductCode != "" { + if len(reqParams.ProductCode) > 20 { + return params, errors.New("Length of productCode should be max 20") + } + params["productCode"] = reqParams.ProductCode + } + + if len(reqParams.PlatformTypeCodeList) > 0 { + for k, v := range reqParams.PlatformTypeCodeList { + params[fmt.Sprintf("platformTypeCodeList.%d", k+1)] = v + } + } + + if reqParams.BlockStorageSize > 0 { + if reqParams.BlockStorageSize != 50 && reqParams.BlockStorageSize != 100 { + return nil, errors.New("blockStorageSize should be null, 50 or 100") + } + params["blockStorageSize"] = strconv.Itoa(reqParams.BlockStorageSize) + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + return params, nil +} + +// GetServerImageProductList gets server image product list +func (s *Conn) GetServerImageProductList(reqParams *RequestGetServerImageProductList) (*ProductList, error) { + params, err := processGetServerImageProductListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getServerImageProductList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ProductList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var productList = ProductList{} + if err := xml.Unmarshal([]byte(bytes), &productList); err != nil { + fmt.Println(err) + return nil, err + } + + return &productList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerInstanceList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerInstanceList.go new file mode 100644 index 000000000..a4de2206e --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerInstanceList.go @@ -0,0 +1,133 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetServerInstanceListParams(reqParams *RequestGetServerInstanceList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil { + return params, nil + } + + if len(reqParams.ServerInstanceNoList) > 0 { + for k, v := range reqParams.ServerInstanceNoList { + params[fmt.Sprintf("serverInstanceNoList.%d", k+1)] = v + } + } + + if reqParams.SearchFilterName != "" { + params["searchFilterName"] = reqParams.SearchFilterName + } + + if reqParams.SearchFilterValue != "" { + params["searchFilterValue"] = reqParams.SearchFilterValue + } + + if reqParams.PageNo > 0 { + if reqParams.PageNo > 2147483647 { + return nil, errors.New("PageNo should be less than 2147483647") + + } + params["pageNo"] = strconv.Itoa(reqParams.PageNo) + } + + if reqParams.PageSize > 0 { + if reqParams.PageSize > 2147483647 { + return nil, errors.New("PageSize should be less than 2147483647") + + } + params["pageSize"] = strconv.Itoa(reqParams.PageSize) + } + + if reqParams.ServerInstanceStatusCode != "" { + if reqParams.ServerInstanceStatusCode != "RUN" && reqParams.ServerInstanceStatusCode != "NSTOP" && reqParams.ServerInstanceStatusCode != "ING" { + return nil, errors.New("ServerInstanceStatusCode should be RUN, NSTOP or ING") + } + params["serverInstanceStatusCode"] = reqParams.ServerInstanceStatusCode + } + + if reqParams.InternetLineTypeCode != "" { + if reqParams.InternetLineTypeCode != "PUBLC" && reqParams.InternetLineTypeCode != "GLBL" { + return nil, errors.New("InternetLineTypeCode should be PUBLC or GLBL") + } + params["internetLineTypeCode"] = reqParams.InternetLineTypeCode + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + if reqParams.BaseBlockStorageDiskTypeCode != "" { + if reqParams.BaseBlockStorageDiskTypeCode != "NET" && reqParams.BaseBlockStorageDiskTypeCode != "LOCAL" { + return nil, errors.New("BaseBlockStorageDiskTypeCode should be NET or LOCAL") + } + params["baseBlockStorageDiskTypeCode"] = reqParams.BaseBlockStorageDiskTypeCode + } + + if reqParams.BaseBlockStorageDiskDetailTypeCode != "" { + if reqParams.BaseBlockStorageDiskDetailTypeCode != "HDD" && reqParams.BaseBlockStorageDiskDetailTypeCode != "SSD" { + return nil, errors.New("BaseBlockStorageDiskDetailTypeCode should be HDD or SSD") + } + params["baseBlockStorageDiskDetailTypeCode"] = reqParams.BaseBlockStorageDiskDetailTypeCode + } + + if reqParams.SortedBy != "" { + if reqParams.SortedBy != "serverName" && reqParams.SortedBy != "serverInstanceNo" { + return nil, errors.New("SortedBy should be serverName or serverInstanceNo") + } + params["sortedBy"] = reqParams.SortedBy + } + + if reqParams.SortingOrder != "" { + if reqParams.SortingOrder != "ascending" && reqParams.SortingOrder != "descending" { + return nil, errors.New("SortingOrder should be ascending or descending") + } + params["sortingOrder"] = reqParams.SortingOrder + } + + return params, nil +} + +// GetServerInstanceList get server instance list +func (s *Conn) GetServerInstanceList(reqParams *RequestGetServerInstanceList) (*ServerInstanceList, error) { + params, err := processGetServerInstanceListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getServerInstanceList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ServerInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var serverInstanceList = ServerInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &serverInstanceList); err != nil { + fmt.Println(err) + return nil, err + } + + return &serverInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerProductList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerProductList.go new file mode 100644 index 000000000..b932df876 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getServerProductList.go @@ -0,0 +1,79 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processGetServerProductListParams(reqParams *RequestGetServerProductList) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil || reqParams.ServerImageProductCode == "" { + return params, errors.New("ServerImageProductCode field is required") + } + + if len(reqParams.ServerImageProductCode) > 20 { + return params, errors.New("Length of serverImageProductCode should be max 20") + } + + params["serverImageProductCode"] = reqParams.ServerImageProductCode + + if reqParams.ExclusionProductCode != "" { + if len(reqParams.ExclusionProductCode) > 20 { + return params, errors.New("Length of exclusionProductCode should be max 20") + } + params["exclusionProductCode"] = reqParams.ExclusionProductCode + } + + if reqParams.ProductCode != "" { + if len(reqParams.ProductCode) > 20 { + return params, errors.New("Length of productCode should be max 20") + } + params["productCode"] = reqParams.ProductCode + } + + if reqParams.RegionNo != "" { + params["regionNo"] = reqParams.RegionNo + } + + return params, nil +} + +// GetServerProductList : Get Server product list with server image product code by default. +func (s *Conn) GetServerProductList(reqParams *RequestGetServerProductList) (*ProductList, error) { + params, err := processGetServerProductListParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "getServerProductList" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ProductList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var productListResp = ProductList{} + if err := xml.Unmarshal([]byte(bytes), &productListResp); err != nil { + return nil, err + } + + return &productListResp, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getZoneList.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getZoneList.go new file mode 100644 index 000000000..42354eec0 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/getZoneList.go @@ -0,0 +1,44 @@ +package sdk + +import ( + "encoding/xml" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +// GetZoneList get zone list +func (s *Conn) GetZoneList(regionNo string) (*ZoneList, error) { + params := make(map[string]string) + params["action"] = "getZoneList" + + if regionNo != "" { + params["regionNo"] = regionNo + } + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ZoneList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + ZoneList := ZoneList{} + if err := xml.Unmarshal([]byte(bytes), &ZoneList); err != nil { + return nil, err + } + + return &ZoneList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/model.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/model.go new file mode 100644 index 000000000..02cac088e --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/model.go @@ -0,0 +1,359 @@ +package sdk + +import ( + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" +) + +type Conn struct { + accessKey string + secretKey string + apiURL string +} + +// ServerImage structures +type ServerImage struct { + MemberServerImageNo string `xml:"memberServerImageNo"` + MemberServerImageName string `xml:"memberServerImageName"` + MemberServerImageDescription string `xml:"memberServerImageDescription"` + OriginalServerInstanceNo string `xml:"originalServerInstanceNo"` + OriginalServerProductCode string `xml:"originalServerProductCode"` + OriginalServerName string `xml:"originalServerName"` + OriginalBaseBlockStorageDiskType common.CommonCode `xml:"originalBaseBlockStorageDiskType"` + OriginalServerImageProductCode string `xml:"originalServerImageProductCode"` + OriginalOsInformation string `xml:"originalOsInformation"` + OriginalServerImageName string `xml:"originalServerImageName"` + MemberServerImageStatusName string `xml:"memberServerImageStatusName"` + MemberServerImageStatus common.CommonCode `xml:"memberServerImageStatus"` + MemberServerImageOperation common.CommonCode `xml:"memberServerImageOperation"` + MemberServerImagePlatformType common.CommonCode `xml:"memberServerImagePlatformType"` + CreateDate string `xml:"createDate"` + Zone common.Zone `xml:"zone"` + Region common.Region `xml:"region"` + MemberServerImageBlockStorageTotalRows int `xml:"memberServerImageBlockStorageTotalRows"` + MemberServerImageBlockStorageTotalSize int `xml:"memberServerImageBlockStorageTotalSize"` +} + +type MemberServerImageList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + MemberServerImageList []ServerImage `xml:"memberServerImageList>memberServerImage,omitempty"` +} + +type RequestServerImageList struct { + MemberServerImageNoList []string + PlatformTypeCodeList []string + PageNo int + PageSize int + RegionNo string + SortedBy string + SortingOrder string +} + +type RequestCreateServerImage struct { + MemberServerImageName string + MemberServerImageDescription string + ServerInstanceNo string +} + +type RequestGetServerImageProductList struct { + ExclusionProductCode string + ProductCode string + PlatformTypeCodeList []string + BlockStorageSize int + RegionNo string +} + +// ProductList : Response of server product list +type ProductList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + Product []Product `xml:"productList>product,omitempty"` +} + +// Product : Product information of Server +type Product struct { + ProductCode string `xml:"productCode"` + ProductName string `xml:"productName"` + ProductType common.CommonCode `xml:"productType"` + ProductDescription string `xml:"productDescription"` + InfraResourceType common.CommonCode `xml:"infraResourceType"` + CPUCount int `xml:"cpuCount"` + MemorySize int `xml:"memorySize"` + BaseBlockStorageSize int `xml:"baseBlockStorageSize"` + PlatformType common.CommonCode `xml:"platformType"` + OsInformation string `xml:"osInformation"` + AddBlockStroageSize int `xml:"addBlockStroageSize"` +} + +// RequestCreateServerInstance is Server Instances structures +type RequestCreateServerInstance struct { + ServerImageProductCode string + ServerProductCode string + MemberServerImageNo string + ServerName string + ServerDescription string + LoginKeyName string + IsProtectServerTermination bool + ServerCreateCount int + ServerCreateStartNo int + InternetLineTypeCode string + FeeSystemTypeCode string + UserData string + ZoneNo string + AccessControlGroupConfigurationNoList []string +} + +type ServerInstanceList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + ServerInstanceList []ServerInstance `xml:"serverInstanceList>serverInstance,omitempty"` +} + +type ServerInstance struct { + ServerInstanceNo string `xml:"serverInstanceNo"` + ServerName string `xml:"serverName"` + ServerDescription string `xml:"serverDescription"` + CPUCount int `xml:"cpuCount"` + MemorySize int `xml:"memorySize"` + BaseBlockStorageSize int `xml:"baseBlockStorageSize"` + PlatformType common.CommonCode `xml:"platformType"` + LoginKeyName string `xml:"loginKeyName"` + IsFeeChargingMonitoring bool `xml:"isFeeChargingMonitoring"` + PublicIP string `xml:"publicIp"` + PrivateIP string `xml:"privateIp"` + ServerImageName string `xml:"serverImageName"` + ServerInstanceStatus common.CommonCode `xml:"serverInstanceStatus"` + ServerInstanceOperation common.CommonCode `xml:"serverInstanceOperation"` + ServerInstanceStatusName string `xml:"serverInstanceStatusName"` + CreateDate string `xml:"createDate"` + Uptime string `xml:"uptime"` + ServerImageProductCode string `xml:"serverImageProductCode"` + ServerProductCode string `xml:"serverProductCode"` + IsProtectServerTermination bool `xml:"isProtectServerTermination"` + PortForwardingPublicIP string `xml:"portForwardingPublicIp"` + PortForwardingExternalPort int `xml:"portForwardingExternalPort"` + PortForwardingInternalPort int `xml:"portForwardingInternalPort"` + Zone common.Zone `xml:"zone"` + Region common.Region `xml:"region"` + BaseBlockStorageDiskType common.CommonCode `xml:"baseBlockStorageDiskType"` + BaseBlockStroageDiskDetailType common.CommonCode `xml:"baseBlockStroageDiskDetailType"` + InternetLineType common.CommonCode `xml:"internetLineType"` + UserData string `xml:"userData"` + AccessControlGroupList []AccessControlGroup `xml:"accessControlGroupList>accessControlGroup"` +} + +type AccessControlGroup struct { + AccessControlGroupConfigurationNo string `xml:"accessControlGroupConfigurationNo"` + AccessControlGroupName string `xml:"accessControlGroupName"` + AccessControlGroupDescription string `xml:"accessControlGroupDescription"` + IsDefault bool `xml:"isDefault"` + CreateDate string `xml:"createDate"` +} + +// RequestGetLoginKeyList is Login Key structures +type RequestGetLoginKeyList struct { + KeyName string + PageNo int + PageSize int +} + +type LoginKeyList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + LoginKeyList []LoginKey `xml:"loginKeyList>loginKey,omitempty"` +} + +type LoginKey struct { + Fingerprint string `xml:"fingerprint"` + KeyName string `xml:"keyName"` + CreateDate string `xml:"createDate"` +} + +type PrivateKey struct { + common.CommonResponse + PrivateKey string `xml:"privateKey"` +} +type RequestCreatePublicIPInstance struct { + ServerInstanceNo string + PublicIPDescription string + InternetLineTypeCode string + RegionNo string +} + +type RequestPublicIPInstanceList struct { + IsAssociated bool + PublicIPInstanceNoList []string + PublicIPList []string + SearchFilterName string + SearchFilterValue string + InternetLineTypeCode string + RegionNo string + PageNo int + PageSize int + SortedBy string + SortingOrder string +} + +type PublicIPInstanceList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + PublicIPInstanceList []PublicIPInstance `xml:"publicIpInstanceList>publicIpInstance,omitempty"` +} + +type PublicIPInstance struct { + PublicIPInstanceNo string `xml:"publicIpInstanceNo"` + PublicIP string `xml:"publicIp"` + PublicIPDescription string `xml:"publicIpDescription"` + CreateDate string `xml:"createDate"` + InternetLineType common.CommonCode `xml:"internetLineType"` + PublicIPInstanceStatusName string `xml:"publicIpInstanceStatusName"` + PublicIPInstanceStatus common.CommonCode `xml:"publicIpInstanceStatus"` + PublicIPInstanceOperation common.CommonCode `xml:"publicIpInstanceOperation"` + PublicIPKindType common.CommonCode `xml:"publicIpKindType"` + ServerInstance ServerInstance `xml:"serverInstanceAssociatedWithPublicIp"` +} + +type RequestDeletePublicIPInstances struct { + PublicIPInstanceNoList []string +} + +// RequestGetServerInstanceList : Get Server Instance List +type RequestGetServerInstanceList struct { + ServerInstanceNoList []string + SearchFilterName string + SearchFilterValue string + PageNo int + PageSize int + ServerInstanceStatusCode string + InternetLineTypeCode string + RegionNo string + BaseBlockStorageDiskTypeCode string + BaseBlockStorageDiskDetailTypeCode string + SortedBy string + SortingOrder string +} + +type RequestStopServerInstances struct { + ServerInstanceNoList []string +} + +type RequestTerminateServerInstances struct { + ServerInstanceNoList []string +} + +// RequestGetRootPassword : Request to get root password of the server +type RequestGetRootPassword struct { + ServerInstanceNo string + PrivateKey string +} + +// RootPassword : Response of getting root password of the server +type RootPassword struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + RootPassword string `xml:"rootPassword"` +} + +// RequestGetZoneList : Request to get zone list +type RequestGetZoneList struct { + regionNo string +} + +// ZoneList : Response of getting zone list +type ZoneList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + Zone []common.Zone `xml:"zoneList>zone"` +} + +// RegionList : Response of getting region list +type RegionList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + RegionList []common.Region `xml:"regionList>region,omitempty"` +} + +type RequestBlockStorageInstance struct { + BlockStorageName string + BlockStorageSize int + BlockStorageDescription string + ServerInstanceNo string +} + +type RequestBlockStorageInstanceList struct { + ServerInstanceNo string + BlockStorageInstanceNoList []string + SearchFilterName string + SearchFilterValue string + BlockStorageTypeCodeList []string + PageNo int + PageSize int + BlockStorageInstanceStatusCode string + DiskTypeCode string + DiskDetailTypeCode string + RegionNo string + SortedBy string + SortingOrder string +} + +type BlockStorageInstanceList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + BlockStorageInstance []BlockStorageInstance `xml:"blockStorageInstanceList>blockStorageInstance,omitempty"` +} + +type BlockStorageInstance struct { + BlockStorageInstanceNo string `xml:"blockStorageInstanceNo"` + ServerInstanceNo string `xml:"serverInstanceNo"` + ServerName string `xml:"serverName"` + BlockStorageType common.CommonCode `xml:"blockStorageType"` + BlockStorageName string `xml:"blockStorageName"` + BlockStorageSize int `xml:"blockStorageSize"` + DeviceName string `xml:"deviceName"` + BlockStorageProductCode string `xml:"blockStorageProductCode"` + BlockStorageInstanceStatus common.CommonCode `xml:"blockStorageInstanceStatus"` + BlockStorageInstanceOperation common.CommonCode `xml:"blockStorageInstanceOperation"` + BlockStorageInstanceStatusName string `xml:"blockStorageInstanceStatusName"` + CreateDate string `xml:"createDate"` + BlockStorageInstanceDescription string `xml:"blockStorageInstanceDescription"` + DiskType common.CommonCode `xml:"diskType"` + DiskDetailType common.CommonCode `xml:"diskDetailType"` +} + +// RequestGetServerProductList : Request to get server product list +type RequestGetServerProductList struct { + ExclusionProductCode string + ProductCode string + ServerImageProductCode string + RegionNo string +} + +type RequestAccessControlGroupList struct { + AccessControlGroupConfigurationNoList []string + IsDefault bool + AccessControlGroupName string + PageNo int + PageSize int +} + +type AccessControlGroupList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + AccessControlGroup []AccessControlGroup `xml:"accessControlGroupList>accessControlGroup,omitempty"` +} + +type AccessControlRuleList struct { + common.CommonResponse + TotalRows int `xml:"totalRows"` + AccessControlRuleList []AccessControlRule `xml:"accessControlRuleList>accessControlRule,omitempty"` +} + +type AccessControlRule struct { + AccessControlRuleConfigurationNo string `xml:"accessControlRuleConfigurationNo"` + AccessControlRuleDescription string `xml:"accessControlRuleDescription"` + SourceAccessControlRuleConfigurationNo string `xml:"sourceAccessControlRuleConfigurationNo"` + SourceAccessControlRuleName string `xml:"sourceAccessControlRuleName"` + ProtocolType common.CommonCode `xml:"protocolType"` + SourceIP string `xml:"sourceIp"` + DestinationPort string `xml:"destinationPort"` +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/stopServerInstances.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/stopServerInstances.go new file mode 100644 index 000000000..e3786e5fa --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/stopServerInstances.go @@ -0,0 +1,62 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processStopServerInstancesParams(reqParams *RequestStopServerInstances) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil || len(reqParams.ServerInstanceNoList) == 0 { + return params, errors.New("serverInstanceNoList is required") + } + + if len(reqParams.ServerInstanceNoList) > 0 { + for k, v := range reqParams.ServerInstanceNoList { + params[fmt.Sprintf("serverInstanceNoList.%d", k+1)] = v + } + } + + return params, nil +} + +// StopServerInstances stop server instances +func (s *Conn) StopServerInstances(reqParams *RequestStopServerInstances) (*ServerInstanceList, error) { + params, err := processStopServerInstancesParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "stopServerInstances" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ServerInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var serverInstanceList = ServerInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &serverInstanceList); err != nil { + fmt.Println(err) + return nil, err + } + + return &serverInstanceList, nil +} diff --git a/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/terminateServerInstances.go b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/terminateServerInstances.go new file mode 100644 index 000000000..598f8efa1 --- /dev/null +++ b/vendor/github.com/NaverCloudPlatform/ncloud-sdk-go/sdk/terminateServerInstances.go @@ -0,0 +1,62 @@ +package sdk + +import ( + "encoding/xml" + "errors" + "fmt" + + common "github.com/NaverCloudPlatform/ncloud-sdk-go/common" + request "github.com/NaverCloudPlatform/ncloud-sdk-go/request" +) + +func processTerminateServerInstancesParams(reqParams *RequestTerminateServerInstances) (map[string]string, error) { + params := make(map[string]string) + + if reqParams == nil || len(reqParams.ServerInstanceNoList) == 0 { + return params, errors.New("serverInstanceNoList is required") + } + + if len(reqParams.ServerInstanceNoList) > 0 { + for k, v := range reqParams.ServerInstanceNoList { + params[fmt.Sprintf("serverInstanceNoList.%d", k+1)] = v + } + } + + return params, nil +} + +// TerminateServerInstances terminate server instances +func (s *Conn) TerminateServerInstances(reqParams *RequestTerminateServerInstances) (*ServerInstanceList, error) { + params, err := processTerminateServerInstancesParams(reqParams) + if err != nil { + return nil, err + } + + params["action"] = "terminateServerInstances" + + bytes, resp, err := request.NewRequest(s.accessKey, s.secretKey, "GET", s.apiURL+"server/", params) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + responseError, err := common.ParseErrorResponse(bytes) + if err != nil { + return nil, err + } + + respError := ServerInstanceList{} + respError.ReturnCode = responseError.ReturnCode + respError.ReturnMessage = responseError.ReturnMessage + + return &respError, fmt.Errorf("%s %s - error code: %d , error message: %s", resp.Status, string(bytes), responseError.ReturnCode, responseError.ReturnMessage) + } + + var serverInstanceList = ServerInstanceList{} + if err := xml.Unmarshal([]byte(bytes), &serverInstanceList); err != nil { + fmt.Println(err) + return nil, err + } + + return &serverInstanceList, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 4438b367e..c5714b58f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -209,6 +209,30 @@ "revision": "4fe03583929022c9c96829401ffabc755e69782e", "revisionTime": "2017-06-25T21:53:50Z" }, + { + "checksumSHA1": "N0jIjg2HeB8fM7dt8OED2BiRZz0=", + "path": "github.com/NaverCloudPlatform/ncloud-sdk-go/common", + "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", + "revisionTime": "2018-01-10T05:50:12Z" + }, + { + "checksumSHA1": "7lT5Xmeo2MhE6CJvIInZyLBu6S8=", + "path": "github.com/NaverCloudPlatform/ncloud-sdk-go/oauth", + "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", + "revisionTime": "2018-01-10T05:50:12Z" + }, + { + "checksumSHA1": "DpfU1gyyhIc1BuKZUZDRVDBkeSc=", + "path": "github.com/NaverCloudPlatform/ncloud-sdk-go/request", + "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", + "revisionTime": "2018-01-10T05:50:12Z" + }, + { + "checksumSHA1": "QnZ2RMlms/zYbD8jg+lyS8ncQOY=", + "path": "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk", + "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", + "revisionTime": "2018-01-10T05:50:12Z" + }, { "checksumSHA1": "HttiPj314X1a0i2Jen1p6lRH/vE=", "path": "github.com/aliyun/aliyun-oss-go-sdk/oss", From 6d6216419cc2f9ce36f7a46e51c9e24b2480f8a9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 11 Jan 2018 12:14:34 -0800 Subject: [PATCH 0371/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48cafdcfd..429a3c842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * provisioner/ansible: Improve user retrieval. [GH-5758] * post-processor/docker: Remove credentials from being shown in the log. [GH-5666] * builder/amazon: Warn during prepare if we didn't get both an access key and a secret key when we were expecting one. [GH-5762] +* builder/amazon: Replace `InstanceStatusOK` check with `InstanceReady`. This reduces build times universally while still working for all instance types. [GH-5678] ### BUG FIXES: From c5ec92c88bb154bd317aec5b81ba6cf9e4dff9c4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 11 Jan 2018 15:44:49 -0800 Subject: [PATCH 0372/1007] add note about vix api libraries --- website/source/docs/builders/vmware-iso.html.md | 4 ++++ website/source/docs/builders/vmware-vmx.html.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 343a685ef..4f5603bdb 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -24,6 +24,10 @@ Linux. It can also build machines directly on [VMware vSphere Hypervisor](https://www.vmware.com/products/vsphere-hypervisor/) using SSH as opposed to the vSphere API. +-> When using VMWare Player on Linux, you may need to install [VIX API +libraries](https://www.vmware.com/support/developer/vix-api/) to use the +`vmrun` utility, which is required by the builder. + The builder builds a virtual machine by creating a new virtual machine from scratch, booting it, installing an OS, provisioning software within the OS, then shutting it down. The result of the VMware builder is a directory containing all diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index ae5bfd29f..775a0072a 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -21,6 +21,10 @@ Professional](https://www.vmware.com/products/fusion-professional/) for OS X, for Linux and Windows, and [VMware Player](https://www.vmware.com/products/player/) on Linux. +-> When using VMWare Player on Linux, you may need to install [VIX API +libraries](https://www.vmware.com/support/developer/vix-api/) to use the +`vmrun` utility, which is required by the builder. + The builder builds a virtual machine by cloning the VMX file using the clone capabilities introduced in VMware Fusion Professional 6, Workstation 10, and Player 6. After cloning the VM, it provisions software within the new machine, From 6f2669c044a4679aca62e0369ca138c3fd36538b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 11 Jan 2018 16:48:39 -0800 Subject: [PATCH 0373/1007] Revert "add note about vix api libraries" This reverts commit c5ec92c88bb154bd317aec5b81ba6cf9e4dff9c4. --- website/source/docs/builders/vmware-iso.html.md | 4 ---- website/source/docs/builders/vmware-vmx.html.md | 4 ---- 2 files changed, 8 deletions(-) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 4f5603bdb..343a685ef 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -24,10 +24,6 @@ Linux. It can also build machines directly on [VMware vSphere Hypervisor](https://www.vmware.com/products/vsphere-hypervisor/) using SSH as opposed to the vSphere API. --> When using VMWare Player on Linux, you may need to install [VIX API -libraries](https://www.vmware.com/support/developer/vix-api/) to use the -`vmrun` utility, which is required by the builder. - The builder builds a virtual machine by creating a new virtual machine from scratch, booting it, installing an OS, provisioning software within the OS, then shutting it down. The result of the VMware builder is a directory containing all diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index 775a0072a..ae5bfd29f 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -21,10 +21,6 @@ Professional](https://www.vmware.com/products/fusion-professional/) for OS X, for Linux and Windows, and [VMware Player](https://www.vmware.com/products/player/) on Linux. --> When using VMWare Player on Linux, you may need to install [VIX API -libraries](https://www.vmware.com/support/developer/vix-api/) to use the -`vmrun` utility, which is required by the builder. - The builder builds a virtual machine by cloning the VMX file using the clone capabilities introduced in VMware Fusion Professional 6, Workstation 10, and Player 6. After cloning the VM, it provisions software within the new machine, From 26030d750cd47eba3713b4d85ab6313f8bfefb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Fri, 12 Jan 2018 10:12:47 +0900 Subject: [PATCH 0374/1007] update err format --- builder/ncloud/step_create_block_storage_instance.go | 2 +- builder/ncloud/step_create_login_key.go | 2 +- builder/ncloud/step_create_public_ip_instance.go | 4 ++-- builder/ncloud/step_delete_block_storage_instance.go | 2 +- builder/ncloud/step_delete_login_key.go | 2 +- builder/ncloud/step_get_rootpassword.go | 2 +- builder/ncloud/step_stop_server_instance.go | 2 +- builder/ncloud/step_terminate_server_instance.go | 4 ++-- builder/ncloud/step_validate_template.go | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/builder/ncloud/step_create_block_storage_instance.go b/builder/ncloud/step_create_block_storage_instance.go index ef7306264..7e4d4b54a 100644 --- a/builder/ncloud/step_create_block_storage_instance.go +++ b/builder/ncloud/step_create_block_storage_instance.go @@ -42,7 +42,7 @@ func (s *StepCreateBlockStorageInstance) createBlockStorageInstance(serverInstan blockStorageInstanceList, err := s.Conn.CreateBlockStorageInstance(reqParams) if err != nil { - return "", fmt.Errorf("error code: %d, error message: %s", blockStorageInstanceList.ReturnCode, blockStorageInstanceList.ReturnMessage) + return "", err } log.Println("Block Storage Instance information : ", blockStorageInstanceList.BlockStorageInstance[0]) diff --git a/builder/ncloud/step_create_login_key.go b/builder/ncloud/step_create_login_key.go index 7dddebd25..d200c3106 100644 --- a/builder/ncloud/step_create_login_key.go +++ b/builder/ncloud/step_create_login_key.go @@ -38,7 +38,7 @@ func (s *StepCreateLoginKey) createLoginKey() (*LoginKey, error) { privateKey, err := s.Conn.CreateLoginKey(KeyName) if err != nil { - return nil, fmt.Errorf("error code: %d , error message: %s", privateKey.ReturnCode, privateKey.ReturnMessage) + return nil, err } return &LoginKey{KeyName, privateKey.PrivateKey}, nil diff --git a/builder/ncloud/step_create_public_ip_instance.go b/builder/ncloud/step_create_public_ip_instance.go index 88d98eb6c..1ea1517c5 100644 --- a/builder/ncloud/step_create_public_ip_instance.go +++ b/builder/ncloud/step_create_public_ip_instance.go @@ -72,7 +72,7 @@ func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo str publicIPInstanceList, err := s.Conn.CreatePublicIPInstance(reqParams) if err != nil { - return nil, fmt.Errorf("error code: %d, error message: %s", publicIPInstanceList.ReturnCode, publicIPInstanceList.ReturnMessage) + return nil, err } publicIPInstance := publicIPInstanceList.PublicIPInstanceList[0] @@ -143,7 +143,7 @@ func (s *StepCreatePublicIPInstance) waitPublicIPInstanceStatus(publicIPInstance for { resp, err := s.Conn.GetPublicIPInstanceList(reqParams) if err != nil { - log.Printf("error code: %d, error message: %s", resp.ReturnCode, resp.ReturnMessage) + log.Printf(err.Error()) c1 <- err return } diff --git a/builder/ncloud/step_delete_block_storage_instance.go b/builder/ncloud/step_delete_block_storage_instance.go index 3c6c44b82..a077d4880 100644 --- a/builder/ncloud/step_delete_block_storage_instance.go +++ b/builder/ncloud/step_delete_block_storage_instance.go @@ -65,7 +65,7 @@ func (s *StepDeleteBlockStorageInstance) deleteBlockStorageInstance(serverInstan result, err := s.Conn.DeleteBlockStorageInstances(blockStorageInstanceList) if err != nil { - return fmt.Errorf("error code: %d , error message: %s", result.ReturnCode, result.ReturnMessage) + return err } s.Say(fmt.Sprintf("Block Storage Instance is deleted. Block Storage InstanceNo is %s", blockStorageInstanceList)) diff --git a/builder/ncloud/step_delete_login_key.go b/builder/ncloud/step_delete_login_key.go index b0cfbf7a1..c53dc3d1c 100644 --- a/builder/ncloud/step_delete_login_key.go +++ b/builder/ncloud/step_delete_login_key.go @@ -30,7 +30,7 @@ func NewStepDeleteLoginKey(conn *ncloud.Conn, ui packer.Ui) *StepDeleteLoginKey func (s *StepDeleteLoginKey) deleteLoginKey(keyName string) error { resp, err := s.Conn.DeleteLoginKey(keyName) if err != nil { - return fmt.Errorf("error code: %d , error message: %s", resp.ReturnCode, resp.ReturnMessage) + return err } return nil diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go index c5070d179..3766d86df 100644 --- a/builder/ncloud/step_get_rootpassword.go +++ b/builder/ncloud/step_get_rootpassword.go @@ -34,7 +34,7 @@ func (s *StepGetRootPassword) getRootPassword(serverInstanceNo string, privateKe rootPassword, err := s.Conn.GetRootPassword(reqParams) if err != nil { - return "", fmt.Errorf("error code: %d, error message: %s", rootPassword.ReturnCode, rootPassword.ReturnMessage) + return "", err } return rootPassword.RootPassword, nil diff --git a/builder/ncloud/step_stop_server_instance.go b/builder/ncloud/step_stop_server_instance.go index 1c9252ed2..f9cce7d9f 100644 --- a/builder/ncloud/step_stop_server_instance.go +++ b/builder/ncloud/step_stop_server_instance.go @@ -35,7 +35,7 @@ func (s *StepStopServerInstance) stopServerInstance(serverInstanceNo string) err serverInstanceList, err := s.Conn.StopServerInstances(reqParams) if err != nil { - return fmt.Errorf("error code: %d , error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + return err } s.Say(fmt.Sprintf("Server Instance is stopping. Server InstanceNo is %s", serverInstanceList.ServerInstanceList[0].ServerInstanceNo)) diff --git a/builder/ncloud/step_terminate_server_instance.go b/builder/ncloud/step_terminate_server_instance.go index 5d60236f0..208e6f1e6 100644 --- a/builder/ncloud/step_terminate_server_instance.go +++ b/builder/ncloud/step_terminate_server_instance.go @@ -35,7 +35,7 @@ func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo s serverInstanceList, err := s.Conn.TerminateServerInstances(reqParams) if err != nil { - return fmt.Errorf("error code: %d , error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + return err } c1 := make(chan error, 1) @@ -48,7 +48,7 @@ func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo s serverInstanceList, err := s.Conn.GetServerInstanceList(reqParams) if err != nil { - c1 <- fmt.Errorf("error code: %d , error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + c1 <- err return } else if serverInstanceList.TotalRows == 0 { c1 <- nil diff --git a/builder/ncloud/step_validate_template.go b/builder/ncloud/step_validate_template.go index 0007bfa40..d645111c4 100644 --- a/builder/ncloud/step_validate_template.go +++ b/builder/ncloud/step_validate_template.go @@ -45,7 +45,7 @@ func (s *StepValidateTemplate) getZoneNo() error { regionList, err := s.Conn.GetRegionList() if err != nil { - return fmt.Errorf("error code: %d , error message: %s", regionList.ReturnCode, regionList.ReturnMessage) + return err } var regionNo string @@ -64,7 +64,7 @@ func (s *StepValidateTemplate) getZoneNo() error { // Get ZoneNo ZoneList, err := s.Conn.GetZoneList(regionNo) if err != nil { - return fmt.Errorf("error code: %d , error message: %s", ZoneList.ReturnCode, ZoneList.ReturnMessage) + return err } if len(ZoneList.Zone) > 0 { From b909e9d4e672f7536afd0bdda25b3b5478463134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Fri, 12 Jan 2018 10:15:40 +0900 Subject: [PATCH 0375/1007] remove not used variables --- builder/ncloud/step_create_server_image.go | 2 +- builder/ncloud/step_create_server_instance.go | 2 +- builder/ncloud/step_delete_block_storage_instance.go | 2 +- builder/ncloud/step_delete_login_key.go | 2 +- builder/ncloud/step_get_rootpassword.go | 2 -- builder/ncloud/step_terminate_server_instance.go | 3 +-- 6 files changed, 5 insertions(+), 8 deletions(-) diff --git a/builder/ncloud/step_create_server_image.go b/builder/ncloud/step_create_server_image.go index 4256664f4..ea0784058 100644 --- a/builder/ncloud/step_create_server_image.go +++ b/builder/ncloud/step_create_server_image.go @@ -44,7 +44,7 @@ func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*ncl memberServerImageList, err := s.Conn.CreateMemberServerImage(reqParams) if err != nil { - return nil, fmt.Errorf("error code: %d , error message: %s", memberServerImageList.ReturnCode, memberServerImageList.ReturnMessage) + return nil, err } serverImage := memberServerImageList.MemberServerImageList[0] diff --git a/builder/ncloud/step_create_server_instance.go b/builder/ncloud/step_create_server_instance.go index 040e72eb1..d7decd4d8 100644 --- a/builder/ncloud/step_create_server_instance.go +++ b/builder/ncloud/step_create_server_instance.go @@ -55,7 +55,7 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon serverInstanceList, err := s.Conn.CreateServerInstances(reqParams) if err != nil { - return "", fmt.Errorf("error code: %d, error message: %s", serverInstanceList.ReturnCode, serverInstanceList.ReturnMessage) + return "", err } s.serverInstanceNo = serverInstanceList.ServerInstanceList[0].ServerInstanceNo diff --git a/builder/ncloud/step_delete_block_storage_instance.go b/builder/ncloud/step_delete_block_storage_instance.go index a077d4880..61f8b7c3c 100644 --- a/builder/ncloud/step_delete_block_storage_instance.go +++ b/builder/ncloud/step_delete_block_storage_instance.go @@ -63,7 +63,7 @@ func (s *StepDeleteBlockStorageInstance) deleteBlockStorageInstance(serverInstan return nil } - result, err := s.Conn.DeleteBlockStorageInstances(blockStorageInstanceList) + _, err := s.Conn.DeleteBlockStorageInstances(blockStorageInstanceList) if err != nil { return err } diff --git a/builder/ncloud/step_delete_login_key.go b/builder/ncloud/step_delete_login_key.go index c53dc3d1c..18256c7d8 100644 --- a/builder/ncloud/step_delete_login_key.go +++ b/builder/ncloud/step_delete_login_key.go @@ -28,7 +28,7 @@ func NewStepDeleteLoginKey(conn *ncloud.Conn, ui packer.Ui) *StepDeleteLoginKey } func (s *StepDeleteLoginKey) deleteLoginKey(keyName string) error { - resp, err := s.Conn.DeleteLoginKey(keyName) + _, err := s.Conn.DeleteLoginKey(keyName) if err != nil { return err } diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go index 3766d86df..b696e594d 100644 --- a/builder/ncloud/step_get_rootpassword.go +++ b/builder/ncloud/step_get_rootpassword.go @@ -1,8 +1,6 @@ package ncloud import ( - "fmt" - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" diff --git a/builder/ncloud/step_terminate_server_instance.go b/builder/ncloud/step_terminate_server_instance.go index 208e6f1e6..aa154812b 100644 --- a/builder/ncloud/step_terminate_server_instance.go +++ b/builder/ncloud/step_terminate_server_instance.go @@ -2,7 +2,6 @@ package ncloud import ( "errors" - "fmt" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" @@ -33,7 +32,7 @@ func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo s reqParams := new(ncloud.RequestTerminateServerInstances) reqParams.ServerInstanceNoList = []string{serverInstanceNo} - serverInstanceList, err := s.Conn.TerminateServerInstances(reqParams) + _, err := s.Conn.TerminateServerInstances(reqParams) if err != nil { return err } From 78ff4d1eedc28ca9ea1e68cfe6f538ee31eaba54 Mon Sep 17 00:00:00 2001 From: Jason Wieringa <jason@wieringa.io> Date: Mon, 8 Jan 2018 20:35:05 -0800 Subject: [PATCH 0376/1007] Updated github.com/aws/aws-sdk-go/service/ec2 Upgrades to v1.12.57 for the field KmsKeyID on EbsBlockDevice introduced in v1.12.35 on November 2017. --- .../aws/aws-sdk-go/service/ec2/api.go | 13641 ++++++++++++++-- .../aws/aws-sdk-go/service/ec2/doc.go | 2 +- .../aws/aws-sdk-go/service/ec2/waiters.go | 5 + vendor/vendor.json | 10 +- 4 files changed, 11858 insertions(+), 1800 deletions(-) diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index da2809630..4598ccd82 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -38,7 +38,7 @@ const opAcceptReservedInstancesExchangeQuote = "AcceptReservedInstancesExchangeQ // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuote +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuote func (c *EC2) AcceptReservedInstancesExchangeQuoteRequest(input *AcceptReservedInstancesExchangeQuoteInput) (req *request.Request, output *AcceptReservedInstancesExchangeQuoteOutput) { op := &request.Operation{ Name: opAcceptReservedInstancesExchangeQuote, @@ -66,7 +66,7 @@ func (c *EC2) AcceptReservedInstancesExchangeQuoteRequest(input *AcceptReservedI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AcceptReservedInstancesExchangeQuote for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuote +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuote func (c *EC2) AcceptReservedInstancesExchangeQuote(input *AcceptReservedInstancesExchangeQuoteInput) (*AcceptReservedInstancesExchangeQuoteOutput, error) { req, out := c.AcceptReservedInstancesExchangeQuoteRequest(input) return out, req.Send() @@ -88,6 +88,81 @@ func (c *EC2) AcceptReservedInstancesExchangeQuoteWithContext(ctx aws.Context, i return out, req.Send() } +const opAcceptVpcEndpointConnections = "AcceptVpcEndpointConnections" + +// AcceptVpcEndpointConnectionsRequest generates a "aws/request.Request" representing the +// client's request for the AcceptVpcEndpointConnections operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AcceptVpcEndpointConnections for more information on using the AcceptVpcEndpointConnections +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AcceptVpcEndpointConnectionsRequest method. +// req, resp := client.AcceptVpcEndpointConnectionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcEndpointConnections +func (c *EC2) AcceptVpcEndpointConnectionsRequest(input *AcceptVpcEndpointConnectionsInput) (req *request.Request, output *AcceptVpcEndpointConnectionsOutput) { + op := &request.Operation{ + Name: opAcceptVpcEndpointConnections, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AcceptVpcEndpointConnectionsInput{} + } + + output = &AcceptVpcEndpointConnectionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// AcceptVpcEndpointConnections API operation for Amazon Elastic Compute Cloud. +// +// Accepts one or more interface VPC endpoint connection requests to your VPC +// endpoint service. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation AcceptVpcEndpointConnections for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcEndpointConnections +func (c *EC2) AcceptVpcEndpointConnections(input *AcceptVpcEndpointConnectionsInput) (*AcceptVpcEndpointConnectionsOutput, error) { + req, out := c.AcceptVpcEndpointConnectionsRequest(input) + return out, req.Send() +} + +// AcceptVpcEndpointConnectionsWithContext is the same as AcceptVpcEndpointConnections with the addition of +// the ability to pass a context and additional request options. +// +// See AcceptVpcEndpointConnections for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) AcceptVpcEndpointConnectionsWithContext(ctx aws.Context, input *AcceptVpcEndpointConnectionsInput, opts ...request.Option) (*AcceptVpcEndpointConnectionsOutput, error) { + req, out := c.AcceptVpcEndpointConnectionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opAcceptVpcPeeringConnection = "AcceptVpcPeeringConnection" // AcceptVpcPeeringConnectionRequest generates a "aws/request.Request" representing the @@ -113,7 +188,7 @@ const opAcceptVpcPeeringConnection = "AcceptVpcPeeringConnection" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnection func (c *EC2) AcceptVpcPeeringConnectionRequest(input *AcceptVpcPeeringConnectionInput) (req *request.Request, output *AcceptVpcPeeringConnectionOutput) { op := &request.Operation{ Name: opAcceptVpcPeeringConnection, @@ -137,13 +212,16 @@ func (c *EC2) AcceptVpcPeeringConnectionRequest(input *AcceptVpcPeeringConnectio // of the peer VPC. Use DescribeVpcPeeringConnections to view your outstanding // VPC peering connection requests. // +// For an inter-region VPC peering connection request, you must accept the VPC +// peering connection in the region of the accepter VPC. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AcceptVpcPeeringConnection for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnection func (c *EC2) AcceptVpcPeeringConnection(input *AcceptVpcPeeringConnectionInput) (*AcceptVpcPeeringConnectionOutput, error) { req, out := c.AcceptVpcPeeringConnectionRequest(input) return out, req.Send() @@ -190,7 +268,7 @@ const opAllocateAddress = "AllocateAddress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddress func (c *EC2) AllocateAddressRequest(input *AllocateAddressInput) (req *request.Request, output *AllocateAddressOutput) { op := &request.Operation{ Name: opAllocateAddress, @@ -209,10 +287,18 @@ func (c *EC2) AllocateAddressRequest(input *AllocateAddressInput) (req *request. // AllocateAddress API operation for Amazon Elastic Compute Cloud. // -// Acquires an Elastic IP address. +// Allocates an Elastic IP address. // // An Elastic IP address is for use either in the EC2-Classic platform or in -// a VPC. For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) +// a VPC. By default, you can allocate 5 Elastic IP addresses for EC2-Classic +// per region and 5 Elastic IP addresses for EC2-VPC per region. +// +// If you release an Elastic IP address for use in a VPC, you might be able +// to recover it. To recover an Elastic IP address that you released, specify +// it in the Address parameter. Note that you cannot recover an Elastic IP address +// that you released after it is allocated to another AWS account. +// +// For more information, see Elastic IP Addresses (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -221,7 +307,7 @@ func (c *EC2) AllocateAddressRequest(input *AllocateAddressInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AllocateAddress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddress func (c *EC2) AllocateAddress(input *AllocateAddressInput) (*AllocateAddressOutput, error) { req, out := c.AllocateAddressRequest(input) return out, req.Send() @@ -268,7 +354,7 @@ const opAllocateHosts = "AllocateHosts" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHosts func (c *EC2) AllocateHostsRequest(input *AllocateHostsInput) (req *request.Request, output *AllocateHostsOutput) { op := &request.Operation{ Name: opAllocateHosts, @@ -297,7 +383,7 @@ func (c *EC2) AllocateHostsRequest(input *AllocateHostsInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AllocateHosts for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHosts func (c *EC2) AllocateHosts(input *AllocateHostsInput) (*AllocateHostsOutput, error) { req, out := c.AllocateHostsRequest(input) return out, req.Send() @@ -344,7 +430,7 @@ const opAssignIpv6Addresses = "AssignIpv6Addresses" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6Addresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6Addresses func (c *EC2) AssignIpv6AddressesRequest(input *AssignIpv6AddressesInput) (req *request.Request, output *AssignIpv6AddressesOutput) { op := &request.Operation{ Name: opAssignIpv6Addresses, @@ -378,7 +464,7 @@ func (c *EC2) AssignIpv6AddressesRequest(input *AssignIpv6AddressesInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssignIpv6Addresses for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6Addresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6Addresses func (c *EC2) AssignIpv6Addresses(input *AssignIpv6AddressesInput) (*AssignIpv6AddressesOutput, error) { req, out := c.AssignIpv6AddressesRequest(input) return out, req.Send() @@ -425,7 +511,7 @@ const opAssignPrivateIpAddresses = "AssignPrivateIpAddresses" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddresses func (c *EC2) AssignPrivateIpAddressesRequest(input *AssignPrivateIpAddressesInput) (req *request.Request, output *AssignPrivateIpAddressesOutput) { op := &request.Operation{ Name: opAssignPrivateIpAddresses, @@ -464,7 +550,7 @@ func (c *EC2) AssignPrivateIpAddressesRequest(input *AssignPrivateIpAddressesInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssignPrivateIpAddresses for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddresses func (c *EC2) AssignPrivateIpAddresses(input *AssignPrivateIpAddressesInput) (*AssignPrivateIpAddressesOutput, error) { req, out := c.AssignPrivateIpAddressesRequest(input) return out, req.Send() @@ -511,7 +597,7 @@ const opAssociateAddress = "AssociateAddress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddress func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *request.Request, output *AssociateAddressOutput) { op := &request.Operation{ Name: opAssociateAddress, @@ -561,7 +647,7 @@ func (c *EC2) AssociateAddressRequest(input *AssociateAddressInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssociateAddress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddress func (c *EC2) AssociateAddress(input *AssociateAddressInput) (*AssociateAddressOutput, error) { req, out := c.AssociateAddressRequest(input) return out, req.Send() @@ -608,7 +694,7 @@ const opAssociateDhcpOptions = "AssociateDhcpOptions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptions func (c *EC2) AssociateDhcpOptionsRequest(input *AssociateDhcpOptionsInput) (req *request.Request, output *AssociateDhcpOptionsOutput) { op := &request.Operation{ Name: opAssociateDhcpOptions, @@ -648,7 +734,7 @@ func (c *EC2) AssociateDhcpOptionsRequest(input *AssociateDhcpOptionsInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssociateDhcpOptions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptions func (c *EC2) AssociateDhcpOptions(input *AssociateDhcpOptionsInput) (*AssociateDhcpOptionsOutput, error) { req, out := c.AssociateDhcpOptionsRequest(input) return out, req.Send() @@ -695,7 +781,7 @@ const opAssociateIamInstanceProfile = "AssociateIamInstanceProfile" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfile +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfile func (c *EC2) AssociateIamInstanceProfileRequest(input *AssociateIamInstanceProfileInput) (req *request.Request, output *AssociateIamInstanceProfileOutput) { op := &request.Operation{ Name: opAssociateIamInstanceProfile, @@ -723,7 +809,7 @@ func (c *EC2) AssociateIamInstanceProfileRequest(input *AssociateIamInstanceProf // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssociateIamInstanceProfile for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfile +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfile func (c *EC2) AssociateIamInstanceProfile(input *AssociateIamInstanceProfileInput) (*AssociateIamInstanceProfileOutput, error) { req, out := c.AssociateIamInstanceProfileRequest(input) return out, req.Send() @@ -770,7 +856,7 @@ const opAssociateRouteTable = "AssociateRouteTable" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTable func (c *EC2) AssociateRouteTableRequest(input *AssociateRouteTableInput) (req *request.Request, output *AssociateRouteTableOutput) { op := &request.Operation{ Name: opAssociateRouteTable, @@ -804,7 +890,7 @@ func (c *EC2) AssociateRouteTableRequest(input *AssociateRouteTableInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssociateRouteTable for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTable func (c *EC2) AssociateRouteTable(input *AssociateRouteTableInput) (*AssociateRouteTableOutput, error) { req, out := c.AssociateRouteTableRequest(input) return out, req.Send() @@ -851,7 +937,7 @@ const opAssociateSubnetCidrBlock = "AssociateSubnetCidrBlock" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlock func (c *EC2) AssociateSubnetCidrBlockRequest(input *AssociateSubnetCidrBlockInput) (req *request.Request, output *AssociateSubnetCidrBlockOutput) { op := &request.Operation{ Name: opAssociateSubnetCidrBlock, @@ -880,7 +966,7 @@ func (c *EC2) AssociateSubnetCidrBlockRequest(input *AssociateSubnetCidrBlockInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssociateSubnetCidrBlock for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlock func (c *EC2) AssociateSubnetCidrBlock(input *AssociateSubnetCidrBlockInput) (*AssociateSubnetCidrBlockOutput, error) { req, out := c.AssociateSubnetCidrBlockRequest(input) return out, req.Send() @@ -927,7 +1013,7 @@ const opAssociateVpcCidrBlock = "AssociateVpcCidrBlock" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlock func (c *EC2) AssociateVpcCidrBlockRequest(input *AssociateVpcCidrBlockInput) (req *request.Request, output *AssociateVpcCidrBlockOutput) { op := &request.Operation{ Name: opAssociateVpcCidrBlock, @@ -946,8 +1032,13 @@ func (c *EC2) AssociateVpcCidrBlockRequest(input *AssociateVpcCidrBlockInput) (r // AssociateVpcCidrBlock API operation for Amazon Elastic Compute Cloud. // -// Associates a CIDR block with your VPC. You can only associate a single Amazon-provided -// IPv6 CIDR block with your VPC. The IPv6 CIDR block size is fixed at /56. +// Associates a CIDR block with your VPC. You can associate a secondary IPv4 +// CIDR block, or you can associate an Amazon-provided IPv6 CIDR block. The +// IPv6 CIDR block size is fixed at /56. +// +// For more information about associating CIDR blocks with your VPC and applicable +// restrictions, see VPC and Subnet Sizing (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html#VPC_Sizing) +// in the Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -955,7 +1046,7 @@ func (c *EC2) AssociateVpcCidrBlockRequest(input *AssociateVpcCidrBlockInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AssociateVpcCidrBlock for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlock func (c *EC2) AssociateVpcCidrBlock(input *AssociateVpcCidrBlockInput) (*AssociateVpcCidrBlockOutput, error) { req, out := c.AssociateVpcCidrBlockRequest(input) return out, req.Send() @@ -1002,7 +1093,7 @@ const opAttachClassicLinkVpc = "AttachClassicLinkVpc" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpc func (c *EC2) AttachClassicLinkVpcRequest(input *AttachClassicLinkVpcInput) (req *request.Request, output *AttachClassicLinkVpcOutput) { op := &request.Operation{ Name: opAttachClassicLinkVpc, @@ -1040,7 +1131,7 @@ func (c *EC2) AttachClassicLinkVpcRequest(input *AttachClassicLinkVpcInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AttachClassicLinkVpc for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpc func (c *EC2) AttachClassicLinkVpc(input *AttachClassicLinkVpcInput) (*AttachClassicLinkVpcOutput, error) { req, out := c.AttachClassicLinkVpcRequest(input) return out, req.Send() @@ -1087,7 +1178,7 @@ const opAttachInternetGateway = "AttachInternetGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGateway func (c *EC2) AttachInternetGatewayRequest(input *AttachInternetGatewayInput) (req *request.Request, output *AttachInternetGatewayOutput) { op := &request.Operation{ Name: opAttachInternetGateway, @@ -1118,7 +1209,7 @@ func (c *EC2) AttachInternetGatewayRequest(input *AttachInternetGatewayInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AttachInternetGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGateway func (c *EC2) AttachInternetGateway(input *AttachInternetGatewayInput) (*AttachInternetGatewayOutput, error) { req, out := c.AttachInternetGatewayRequest(input) return out, req.Send() @@ -1165,7 +1256,7 @@ const opAttachNetworkInterface = "AttachNetworkInterface" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterface func (c *EC2) AttachNetworkInterfaceRequest(input *AttachNetworkInterfaceInput) (req *request.Request, output *AttachNetworkInterfaceOutput) { op := &request.Operation{ Name: opAttachNetworkInterface, @@ -1192,7 +1283,7 @@ func (c *EC2) AttachNetworkInterfaceRequest(input *AttachNetworkInterfaceInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AttachNetworkInterface for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterface func (c *EC2) AttachNetworkInterface(input *AttachNetworkInterfaceInput) (*AttachNetworkInterfaceOutput, error) { req, out := c.AttachNetworkInterfaceRequest(input) return out, req.Send() @@ -1239,7 +1330,7 @@ const opAttachVolume = "AttachVolume" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolume func (c *EC2) AttachVolumeRequest(input *AttachVolumeInput) (req *request.Request, output *VolumeAttachment) { op := &request.Operation{ Name: opAttachVolume, @@ -1295,7 +1386,7 @@ func (c *EC2) AttachVolumeRequest(input *AttachVolumeInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AttachVolume for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolume func (c *EC2) AttachVolume(input *AttachVolumeInput) (*VolumeAttachment, error) { req, out := c.AttachVolumeRequest(input) return out, req.Send() @@ -1342,7 +1433,7 @@ const opAttachVpnGateway = "AttachVpnGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGateway func (c *EC2) AttachVpnGatewayRequest(input *AttachVpnGatewayInput) (req *request.Request, output *AttachVpnGatewayOutput) { op := &request.Operation{ Name: opAttachVpnGateway, @@ -1364,8 +1455,7 @@ func (c *EC2) AttachVpnGatewayRequest(input *AttachVpnGatewayInput) (req *reques // Attaches a virtual private gateway to a VPC. You can attach one virtual private // gateway to one VPC at a time. // -// For more information, see Adding a Hardware Virtual Private Gateway to Your -// VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// For more information, see AWS Managed VPN Connections (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -1374,7 +1464,7 @@ func (c *EC2) AttachVpnGatewayRequest(input *AttachVpnGatewayInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AttachVpnGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGateway func (c *EC2) AttachVpnGateway(input *AttachVpnGatewayInput) (*AttachVpnGatewayOutput, error) { req, out := c.AttachVpnGatewayRequest(input) return out, req.Send() @@ -1421,7 +1511,7 @@ const opAuthorizeSecurityGroupEgress = "AuthorizeSecurityGroupEgress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgress func (c *EC2) AuthorizeSecurityGroupEgressRequest(input *AuthorizeSecurityGroupEgressInput) (req *request.Request, output *AuthorizeSecurityGroupEgressOutput) { op := &request.Operation{ Name: opAuthorizeSecurityGroupEgress, @@ -1455,7 +1545,8 @@ func (c *EC2) AuthorizeSecurityGroupEgressRequest(input *AuthorizeSecurityGroupE // range or a source group. For the TCP and UDP protocols, you must also specify // the destination port or port range. For the ICMP protocol, you must also // specify the ICMP type and code. You can use -1 for the type or code to mean -// all types or all codes. +// all types or all codes. You can optionally specify a description for the +// rule. // // Rule changes are propagated to affected instances as quickly as possible. // However, a small delay might occur. @@ -1466,7 +1557,7 @@ func (c *EC2) AuthorizeSecurityGroupEgressRequest(input *AuthorizeSecurityGroupE // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AuthorizeSecurityGroupEgress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgress func (c *EC2) AuthorizeSecurityGroupEgress(input *AuthorizeSecurityGroupEgressInput) (*AuthorizeSecurityGroupEgressOutput, error) { req, out := c.AuthorizeSecurityGroupEgressRequest(input) return out, req.Send() @@ -1513,7 +1604,7 @@ const opAuthorizeSecurityGroupIngress = "AuthorizeSecurityGroupIngress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngress func (c *EC2) AuthorizeSecurityGroupIngressRequest(input *AuthorizeSecurityGroupIngressInput) (req *request.Request, output *AuthorizeSecurityGroupIngressOutput) { op := &request.Operation{ Name: opAuthorizeSecurityGroupIngress, @@ -1552,13 +1643,15 @@ func (c *EC2) AuthorizeSecurityGroupIngressRequest(input *AuthorizeSecurityGroup // peer VPC in a VPC peering connection. For more information about VPC security // group limits, see Amazon VPC Limits (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Appendix_Limits.html). // +// You can optionally specify a description for the security group rule. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation AuthorizeSecurityGroupIngress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngress func (c *EC2) AuthorizeSecurityGroupIngress(input *AuthorizeSecurityGroupIngressInput) (*AuthorizeSecurityGroupIngressOutput, error) { req, out := c.AuthorizeSecurityGroupIngressRequest(input) return out, req.Send() @@ -1605,7 +1698,7 @@ const opBundleInstance = "BundleInstance" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstance func (c *EC2) BundleInstanceRequest(input *BundleInstanceInput) (req *request.Request, output *BundleInstanceOutput) { op := &request.Operation{ Name: opBundleInstance, @@ -1640,7 +1733,7 @@ func (c *EC2) BundleInstanceRequest(input *BundleInstanceInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation BundleInstance for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstance func (c *EC2) BundleInstance(input *BundleInstanceInput) (*BundleInstanceOutput, error) { req, out := c.BundleInstanceRequest(input) return out, req.Send() @@ -1687,7 +1780,7 @@ const opCancelBundleTask = "CancelBundleTask" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTask func (c *EC2) CancelBundleTaskRequest(input *CancelBundleTaskInput) (req *request.Request, output *CancelBundleTaskOutput) { op := &request.Operation{ Name: opCancelBundleTask, @@ -1714,7 +1807,7 @@ func (c *EC2) CancelBundleTaskRequest(input *CancelBundleTaskInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelBundleTask for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTask func (c *EC2) CancelBundleTask(input *CancelBundleTaskInput) (*CancelBundleTaskOutput, error) { req, out := c.CancelBundleTaskRequest(input) return out, req.Send() @@ -1761,7 +1854,7 @@ const opCancelConversionTask = "CancelConversionTask" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTask func (c *EC2) CancelConversionTaskRequest(input *CancelConversionTaskInput) (req *request.Request, output *CancelConversionTaskOutput) { op := &request.Operation{ Name: opCancelConversionTask, @@ -1797,7 +1890,7 @@ func (c *EC2) CancelConversionTaskRequest(input *CancelConversionTaskInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelConversionTask for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTask func (c *EC2) CancelConversionTask(input *CancelConversionTaskInput) (*CancelConversionTaskOutput, error) { req, out := c.CancelConversionTaskRequest(input) return out, req.Send() @@ -1844,7 +1937,7 @@ const opCancelExportTask = "CancelExportTask" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTask func (c *EC2) CancelExportTaskRequest(input *CancelExportTaskInput) (req *request.Request, output *CancelExportTaskOutput) { op := &request.Operation{ Name: opCancelExportTask, @@ -1876,7 +1969,7 @@ func (c *EC2) CancelExportTaskRequest(input *CancelExportTaskInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelExportTask for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTask func (c *EC2) CancelExportTask(input *CancelExportTaskInput) (*CancelExportTaskOutput, error) { req, out := c.CancelExportTaskRequest(input) return out, req.Send() @@ -1923,7 +2016,7 @@ const opCancelImportTask = "CancelImportTask" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTask func (c *EC2) CancelImportTaskRequest(input *CancelImportTaskInput) (req *request.Request, output *CancelImportTaskOutput) { op := &request.Operation{ Name: opCancelImportTask, @@ -1950,7 +2043,7 @@ func (c *EC2) CancelImportTaskRequest(input *CancelImportTaskInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelImportTask for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTask func (c *EC2) CancelImportTask(input *CancelImportTaskInput) (*CancelImportTaskOutput, error) { req, out := c.CancelImportTaskRequest(input) return out, req.Send() @@ -1997,7 +2090,7 @@ const opCancelReservedInstancesListing = "CancelReservedInstancesListing" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListing +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListing func (c *EC2) CancelReservedInstancesListingRequest(input *CancelReservedInstancesListingInput) (req *request.Request, output *CancelReservedInstancesListingOutput) { op := &request.Operation{ Name: opCancelReservedInstancesListing, @@ -2028,7 +2121,7 @@ func (c *EC2) CancelReservedInstancesListingRequest(input *CancelReservedInstanc // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelReservedInstancesListing for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListing +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListing func (c *EC2) CancelReservedInstancesListing(input *CancelReservedInstancesListingInput) (*CancelReservedInstancesListingOutput, error) { req, out := c.CancelReservedInstancesListingRequest(input) return out, req.Send() @@ -2075,7 +2168,7 @@ const opCancelSpotFleetRequests = "CancelSpotFleetRequests" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequests func (c *EC2) CancelSpotFleetRequestsRequest(input *CancelSpotFleetRequestsInput) (req *request.Request, output *CancelSpotFleetRequestsOutput) { op := &request.Operation{ Name: opCancelSpotFleetRequests, @@ -2094,12 +2187,12 @@ func (c *EC2) CancelSpotFleetRequestsRequest(input *CancelSpotFleetRequestsInput // CancelSpotFleetRequests API operation for Amazon Elastic Compute Cloud. // -// Cancels the specified Spot fleet requests. +// Cancels the specified Spot Fleet requests. // -// After you cancel a Spot fleet request, the Spot fleet launches no new Spot -// instances. You must specify whether the Spot fleet should also terminate -// its Spot instances. If you terminate the instances, the Spot fleet request -// enters the cancelled_terminating state. Otherwise, the Spot fleet request +// After you cancel a Spot Fleet request, the Spot Fleet launches no new Spot +// Instances. You must specify whether the Spot Fleet should also terminate +// its Spot Instances. If you terminate the instances, the Spot Fleet request +// enters the cancelled_terminating state. Otherwise, the Spot Fleet request // enters the cancelled_running state and the instances continue to run until // they are interrupted or you terminate them manually. // @@ -2109,7 +2202,7 @@ func (c *EC2) CancelSpotFleetRequestsRequest(input *CancelSpotFleetRequestsInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelSpotFleetRequests for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequests func (c *EC2) CancelSpotFleetRequests(input *CancelSpotFleetRequestsInput) (*CancelSpotFleetRequestsOutput, error) { req, out := c.CancelSpotFleetRequestsRequest(input) return out, req.Send() @@ -2156,7 +2249,7 @@ const opCancelSpotInstanceRequests = "CancelSpotInstanceRequests" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequests func (c *EC2) CancelSpotInstanceRequestsRequest(input *CancelSpotInstanceRequestsInput) (req *request.Request, output *CancelSpotInstanceRequestsOutput) { op := &request.Operation{ Name: opCancelSpotInstanceRequests, @@ -2175,14 +2268,13 @@ func (c *EC2) CancelSpotInstanceRequestsRequest(input *CancelSpotInstanceRequest // CancelSpotInstanceRequests API operation for Amazon Elastic Compute Cloud. // -// Cancels one or more Spot instance requests. Spot instances are instances -// that Amazon EC2 starts on your behalf when the bid price that you specify -// exceeds the current Spot price. Amazon EC2 periodically sets the Spot price -// based on available Spot instance capacity and current Spot instance requests. -// For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) -// in the Amazon Elastic Compute Cloud User Guide. +// Cancels one or more Spot Instance requests. Spot Instances are instances +// that Amazon EC2 starts on your behalf when the maximum price that you specify +// exceeds the current Spot price. For more information, see Spot Instance Requests +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) in +// the Amazon Elastic Compute Cloud User Guide. // -// Canceling a Spot instance request does not terminate running Spot instances +// Canceling a Spot Instance request does not terminate running Spot Instances // associated with the request. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -2191,7 +2283,7 @@ func (c *EC2) CancelSpotInstanceRequestsRequest(input *CancelSpotInstanceRequest // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CancelSpotInstanceRequests for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequests func (c *EC2) CancelSpotInstanceRequests(input *CancelSpotInstanceRequestsInput) (*CancelSpotInstanceRequestsOutput, error) { req, out := c.CancelSpotInstanceRequestsRequest(input) return out, req.Send() @@ -2238,7 +2330,7 @@ const opConfirmProductInstance = "ConfirmProductInstance" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstance func (c *EC2) ConfirmProductInstanceRequest(input *ConfirmProductInstanceInput) (req *request.Request, output *ConfirmProductInstanceOutput) { op := &request.Operation{ Name: opConfirmProductInstance, @@ -2259,8 +2351,7 @@ func (c *EC2) ConfirmProductInstanceRequest(input *ConfirmProductInstanceInput) // // Determines whether a product code is associated with an instance. This action // can only be used by the owner of the product code. It is useful when a product -// code owner needs to verify whether another user's instance is eligible for -// support. +// code owner must verify whether another user's instance is eligible for support. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2268,7 +2359,7 @@ func (c *EC2) ConfirmProductInstanceRequest(input *ConfirmProductInstanceInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ConfirmProductInstance for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstance func (c *EC2) ConfirmProductInstance(input *ConfirmProductInstanceInput) (*ConfirmProductInstanceOutput, error) { req, out := c.ConfirmProductInstanceRequest(input) return out, req.Send() @@ -2290,6 +2381,80 @@ func (c *EC2) ConfirmProductInstanceWithContext(ctx aws.Context, input *ConfirmP return out, req.Send() } +const opCopyFpgaImage = "CopyFpgaImage" + +// CopyFpgaImageRequest generates a "aws/request.Request" representing the +// client's request for the CopyFpgaImage operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CopyFpgaImage for more information on using the CopyFpgaImage +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CopyFpgaImageRequest method. +// req, resp := client.CopyFpgaImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyFpgaImage +func (c *EC2) CopyFpgaImageRequest(input *CopyFpgaImageInput) (req *request.Request, output *CopyFpgaImageOutput) { + op := &request.Operation{ + Name: opCopyFpgaImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CopyFpgaImageInput{} + } + + output = &CopyFpgaImageOutput{} + req = c.newRequest(op, input, output) + return +} + +// CopyFpgaImage API operation for Amazon Elastic Compute Cloud. +// +// Copies the specified Amazon FPGA Image (AFI) to the current region. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CopyFpgaImage for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyFpgaImage +func (c *EC2) CopyFpgaImage(input *CopyFpgaImageInput) (*CopyFpgaImageOutput, error) { + req, out := c.CopyFpgaImageRequest(input) + return out, req.Send() +} + +// CopyFpgaImageWithContext is the same as CopyFpgaImage with the addition of +// the ability to pass a context and additional request options. +// +// See CopyFpgaImage for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CopyFpgaImageWithContext(ctx aws.Context, input *CopyFpgaImageInput, opts ...request.Option) (*CopyFpgaImageOutput, error) { + req, out := c.CopyFpgaImageRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCopyImage = "CopyImage" // CopyImageRequest generates a "aws/request.Request" representing the @@ -2315,7 +2480,7 @@ const opCopyImage = "CopyImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImage func (c *EC2) CopyImageRequest(input *CopyImageInput) (req *request.Request, output *CopyImageOutput) { op := &request.Operation{ Name: opCopyImage, @@ -2348,7 +2513,7 @@ func (c *EC2) CopyImageRequest(input *CopyImageInput) (req *request.Request, out // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CopyImage for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImage func (c *EC2) CopyImage(input *CopyImageInput) (*CopyImageOutput, error) { req, out := c.CopyImageRequest(input) return out, req.Send() @@ -2395,7 +2560,7 @@ const opCopySnapshot = "CopySnapshot" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshot func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *request.Request, output *CopySnapshotOutput) { op := &request.Operation{ Name: opCopySnapshot, @@ -2441,7 +2606,7 @@ func (c *EC2) CopySnapshotRequest(input *CopySnapshotInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CopySnapshot for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshot func (c *EC2) CopySnapshot(input *CopySnapshotInput) (*CopySnapshotOutput, error) { req, out := c.CopySnapshotRequest(input) return out, req.Send() @@ -2488,7 +2653,7 @@ const opCreateCustomerGateway = "CreateCustomerGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGateway func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (req *request.Request, output *CreateCustomerGatewayOutput) { op := &request.Operation{ Name: opCreateCustomerGateway, @@ -2523,9 +2688,9 @@ func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (r // the exception of 7224, which is reserved in the us-east-1 region, and 9059, // which is reserved in the eu-west-1 region. // -// For more information about VPN customer gateways, see Adding a Hardware Virtual -// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. +// For more information about VPN customer gateways, see AWS Managed VPN Connections +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) in the +// Amazon Virtual Private Cloud User Guide. // // You cannot create more than one customer gateway with the same VPN type, // IP address, and BGP ASN parameter values. If you run an identical request @@ -2539,7 +2704,7 @@ func (c *EC2) CreateCustomerGatewayRequest(input *CreateCustomerGatewayInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateCustomerGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGateway func (c *EC2) CreateCustomerGateway(input *CreateCustomerGatewayInput) (*CreateCustomerGatewayOutput, error) { req, out := c.CreateCustomerGatewayRequest(input) return out, req.Send() @@ -2561,6 +2726,84 @@ func (c *EC2) CreateCustomerGatewayWithContext(ctx aws.Context, input *CreateCus return out, req.Send() } +const opCreateDefaultSubnet = "CreateDefaultSubnet" + +// CreateDefaultSubnetRequest generates a "aws/request.Request" representing the +// client's request for the CreateDefaultSubnet operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDefaultSubnet for more information on using the CreateDefaultSubnet +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDefaultSubnetRequest method. +// req, resp := client.CreateDefaultSubnetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultSubnet +func (c *EC2) CreateDefaultSubnetRequest(input *CreateDefaultSubnetInput) (req *request.Request, output *CreateDefaultSubnetOutput) { + op := &request.Operation{ + Name: opCreateDefaultSubnet, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDefaultSubnetInput{} + } + + output = &CreateDefaultSubnetOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDefaultSubnet API operation for Amazon Elastic Compute Cloud. +// +// Creates a default subnet with a size /20 IPv4 CIDR block in the specified +// Availability Zone in your default VPC. You can have only one default subnet +// per Availability Zone. For more information, see Creating a Default Subnet +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html#create-default-subnet) +// in the Amazon Virtual Private Cloud User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateDefaultSubnet for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultSubnet +func (c *EC2) CreateDefaultSubnet(input *CreateDefaultSubnetInput) (*CreateDefaultSubnetOutput, error) { + req, out := c.CreateDefaultSubnetRequest(input) + return out, req.Send() +} + +// CreateDefaultSubnetWithContext is the same as CreateDefaultSubnet with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDefaultSubnet for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateDefaultSubnetWithContext(ctx aws.Context, input *CreateDefaultSubnetInput, opts ...request.Option) (*CreateDefaultSubnetOutput, error) { + req, out := c.CreateDefaultSubnetRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateDefaultVpc = "CreateDefaultVpc" // CreateDefaultVpcRequest generates a "aws/request.Request" representing the @@ -2586,7 +2829,7 @@ const opCreateDefaultVpc = "CreateDefaultVpc" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpc func (c *EC2) CreateDefaultVpcRequest(input *CreateDefaultVpcInput) (req *request.Request, output *CreateDefaultVpcOutput) { op := &request.Operation{ Name: opCreateDefaultVpc, @@ -2625,7 +2868,7 @@ func (c *EC2) CreateDefaultVpcRequest(input *CreateDefaultVpcInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateDefaultVpc for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpc func (c *EC2) CreateDefaultVpc(input *CreateDefaultVpcInput) (*CreateDefaultVpcOutput, error) { req, out := c.CreateDefaultVpcRequest(input) return out, req.Send() @@ -2672,7 +2915,7 @@ const opCreateDhcpOptions = "CreateDhcpOptions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptions func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *request.Request, output *CreateDhcpOptionsOutput) { op := &request.Operation{ Name: opCreateDhcpOptions, @@ -2738,7 +2981,7 @@ func (c *EC2) CreateDhcpOptionsRequest(input *CreateDhcpOptionsInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateDhcpOptions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptions func (c *EC2) CreateDhcpOptions(input *CreateDhcpOptionsInput) (*CreateDhcpOptionsOutput, error) { req, out := c.CreateDhcpOptionsRequest(input) return out, req.Send() @@ -2785,7 +3028,7 @@ const opCreateEgressOnlyInternetGateway = "CreateEgressOnlyInternetGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGateway func (c *EC2) CreateEgressOnlyInternetGatewayRequest(input *CreateEgressOnlyInternetGatewayInput) (req *request.Request, output *CreateEgressOnlyInternetGatewayOutput) { op := &request.Operation{ Name: opCreateEgressOnlyInternetGateway, @@ -2815,7 +3058,7 @@ func (c *EC2) CreateEgressOnlyInternetGatewayRequest(input *CreateEgressOnlyInte // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateEgressOnlyInternetGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGateway func (c *EC2) CreateEgressOnlyInternetGateway(input *CreateEgressOnlyInternetGatewayInput) (*CreateEgressOnlyInternetGatewayOutput, error) { req, out := c.CreateEgressOnlyInternetGatewayRequest(input) return out, req.Send() @@ -2862,7 +3105,7 @@ const opCreateFlowLogs = "CreateFlowLogs" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogs func (c *EC2) CreateFlowLogsRequest(input *CreateFlowLogsInput) (req *request.Request, output *CreateFlowLogsOutput) { op := &request.Operation{ Name: opCreateFlowLogs, @@ -2898,7 +3141,7 @@ func (c *EC2) CreateFlowLogsRequest(input *CreateFlowLogsInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateFlowLogs for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogs func (c *EC2) CreateFlowLogs(input *CreateFlowLogsInput) (*CreateFlowLogsOutput, error) { req, out := c.CreateFlowLogsRequest(input) return out, req.Send() @@ -2945,7 +3188,7 @@ const opCreateFpgaImage = "CreateFpgaImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage func (c *EC2) CreateFpgaImageRequest(input *CreateFpgaImageInput) (req *request.Request, output *CreateFpgaImageOutput) { op := &request.Operation{ Name: opCreateFpgaImage, @@ -2979,7 +3222,7 @@ func (c *EC2) CreateFpgaImageRequest(input *CreateFpgaImageInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateFpgaImage for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImage func (c *EC2) CreateFpgaImage(input *CreateFpgaImageInput) (*CreateFpgaImageOutput, error) { req, out := c.CreateFpgaImageRequest(input) return out, req.Send() @@ -3026,7 +3269,7 @@ const opCreateImage = "CreateImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImage func (c *EC2) CreateImageRequest(input *CreateImageInput) (req *request.Request, output *CreateImageOutput) { op := &request.Operation{ Name: opCreateImage, @@ -3062,7 +3305,7 @@ func (c *EC2) CreateImageRequest(input *CreateImageInput) (req *request.Request, // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateImage for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImage func (c *EC2) CreateImage(input *CreateImageInput) (*CreateImageOutput, error) { req, out := c.CreateImageRequest(input) return out, req.Send() @@ -3109,7 +3352,7 @@ const opCreateInstanceExportTask = "CreateInstanceExportTask" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTask func (c *EC2) CreateInstanceExportTaskRequest(input *CreateInstanceExportTaskInput) (req *request.Request, output *CreateInstanceExportTaskOutput) { op := &request.Operation{ Name: opCreateInstanceExportTask, @@ -3141,7 +3384,7 @@ func (c *EC2) CreateInstanceExportTaskRequest(input *CreateInstanceExportTaskInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateInstanceExportTask for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTask func (c *EC2) CreateInstanceExportTask(input *CreateInstanceExportTaskInput) (*CreateInstanceExportTaskOutput, error) { req, out := c.CreateInstanceExportTaskRequest(input) return out, req.Send() @@ -3188,7 +3431,7 @@ const opCreateInternetGateway = "CreateInternetGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGateway func (c *EC2) CreateInternetGatewayRequest(input *CreateInternetGatewayInput) (req *request.Request, output *CreateInternetGatewayOutput) { op := &request.Operation{ Name: opCreateInternetGateway, @@ -3219,7 +3462,7 @@ func (c *EC2) CreateInternetGatewayRequest(input *CreateInternetGatewayInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateInternetGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGateway func (c *EC2) CreateInternetGateway(input *CreateInternetGatewayInput) (*CreateInternetGatewayOutput, error) { req, out := c.CreateInternetGatewayRequest(input) return out, req.Send() @@ -3266,7 +3509,7 @@ const opCreateKeyPair = "CreateKeyPair" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPair func (c *EC2) CreateKeyPairRequest(input *CreateKeyPairInput) (req *request.Request, output *CreateKeyPairOutput) { op := &request.Operation{ Name: opCreateKeyPair, @@ -3287,15 +3530,16 @@ func (c *EC2) CreateKeyPairRequest(input *CreateKeyPairInput) (req *request.Requ // // Creates a 2048-bit RSA key pair with the specified name. Amazon EC2 stores // the public key and displays the private key for you to save to a file. The -// private key is returned as an unencrypted PEM encoded PKCS#8 private key. +// private key is returned as an unencrypted PEM encoded PKCS#1 private key. // If a key with the specified name already exists, Amazon EC2 returns an error. // // You can have up to five thousand key pairs per region. // // The key pair returned to you is available only in the region in which you -// create it. To create a key pair that is available in all regions, use ImportKeyPair. +// create it. If you prefer, you can create your own key pair using a third-party +// tool and upload it to any region using ImportKeyPair. // -// For more information about key pairs, see Key Pairs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) +// For more information, see Key Pairs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -3304,7 +3548,7 @@ func (c *EC2) CreateKeyPairRequest(input *CreateKeyPairInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateKeyPair for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPair func (c *EC2) CreateKeyPair(input *CreateKeyPairInput) (*CreateKeyPairOutput, error) { req, out := c.CreateKeyPairRequest(input) return out, req.Send() @@ -3326,6 +3570,160 @@ func (c *EC2) CreateKeyPairWithContext(ctx aws.Context, input *CreateKeyPairInpu return out, req.Send() } +const opCreateLaunchTemplate = "CreateLaunchTemplate" + +// CreateLaunchTemplateRequest generates a "aws/request.Request" representing the +// client's request for the CreateLaunchTemplate operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateLaunchTemplate for more information on using the CreateLaunchTemplate +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateLaunchTemplateRequest method. +// req, resp := client.CreateLaunchTemplateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplate +func (c *EC2) CreateLaunchTemplateRequest(input *CreateLaunchTemplateInput) (req *request.Request, output *CreateLaunchTemplateOutput) { + op := &request.Operation{ + Name: opCreateLaunchTemplate, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateLaunchTemplateInput{} + } + + output = &CreateLaunchTemplateOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateLaunchTemplate API operation for Amazon Elastic Compute Cloud. +// +// Creates a launch template. A launch template contains the parameters to launch +// an instance. When you launch an instance using RunInstances, you can specify +// a launch template instead of providing the launch parameters in the request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateLaunchTemplate for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplate +func (c *EC2) CreateLaunchTemplate(input *CreateLaunchTemplateInput) (*CreateLaunchTemplateOutput, error) { + req, out := c.CreateLaunchTemplateRequest(input) + return out, req.Send() +} + +// CreateLaunchTemplateWithContext is the same as CreateLaunchTemplate with the addition of +// the ability to pass a context and additional request options. +// +// See CreateLaunchTemplate for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateLaunchTemplateWithContext(ctx aws.Context, input *CreateLaunchTemplateInput, opts ...request.Option) (*CreateLaunchTemplateOutput, error) { + req, out := c.CreateLaunchTemplateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateLaunchTemplateVersion = "CreateLaunchTemplateVersion" + +// CreateLaunchTemplateVersionRequest generates a "aws/request.Request" representing the +// client's request for the CreateLaunchTemplateVersion operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateLaunchTemplateVersion for more information on using the CreateLaunchTemplateVersion +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateLaunchTemplateVersionRequest method. +// req, resp := client.CreateLaunchTemplateVersionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateVersion +func (c *EC2) CreateLaunchTemplateVersionRequest(input *CreateLaunchTemplateVersionInput) (req *request.Request, output *CreateLaunchTemplateVersionOutput) { + op := &request.Operation{ + Name: opCreateLaunchTemplateVersion, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateLaunchTemplateVersionInput{} + } + + output = &CreateLaunchTemplateVersionOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateLaunchTemplateVersion API operation for Amazon Elastic Compute Cloud. +// +// Creates a new version for a launch template. You can specify an existing +// version of launch template from which to base the new version. +// +// Launch template versions are numbered in the order in which they are created. +// You cannot specify, change, or replace the numbering of launch template versions. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateLaunchTemplateVersion for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateVersion +func (c *EC2) CreateLaunchTemplateVersion(input *CreateLaunchTemplateVersionInput) (*CreateLaunchTemplateVersionOutput, error) { + req, out := c.CreateLaunchTemplateVersionRequest(input) + return out, req.Send() +} + +// CreateLaunchTemplateVersionWithContext is the same as CreateLaunchTemplateVersion with the addition of +// the ability to pass a context and additional request options. +// +// See CreateLaunchTemplateVersion for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateLaunchTemplateVersionWithContext(ctx aws.Context, input *CreateLaunchTemplateVersionInput, opts ...request.Option) (*CreateLaunchTemplateVersionOutput, error) { + req, out := c.CreateLaunchTemplateVersionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateNatGateway = "CreateNatGateway" // CreateNatGatewayRequest generates a "aws/request.Request" representing the @@ -3351,7 +3749,7 @@ const opCreateNatGateway = "CreateNatGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGateway func (c *EC2) CreateNatGatewayRequest(input *CreateNatGatewayInput) (req *request.Request, output *CreateNatGatewayOutput) { op := &request.Operation{ Name: opCreateNatGateway, @@ -3383,7 +3781,7 @@ func (c *EC2) CreateNatGatewayRequest(input *CreateNatGatewayInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateNatGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGateway func (c *EC2) CreateNatGateway(input *CreateNatGatewayInput) (*CreateNatGatewayOutput, error) { req, out := c.CreateNatGatewayRequest(input) return out, req.Send() @@ -3430,7 +3828,7 @@ const opCreateNetworkAcl = "CreateNetworkAcl" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAcl func (c *EC2) CreateNetworkAclRequest(input *CreateNetworkAclInput) (req *request.Request, output *CreateNetworkAclOutput) { op := &request.Operation{ Name: opCreateNetworkAcl, @@ -3461,7 +3859,7 @@ func (c *EC2) CreateNetworkAclRequest(input *CreateNetworkAclInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateNetworkAcl for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAcl func (c *EC2) CreateNetworkAcl(input *CreateNetworkAclInput) (*CreateNetworkAclOutput, error) { req, out := c.CreateNetworkAclRequest(input) return out, req.Send() @@ -3508,7 +3906,7 @@ const opCreateNetworkAclEntry = "CreateNetworkAclEntry" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntry func (c *EC2) CreateNetworkAclEntryRequest(input *CreateNetworkAclEntryInput) (req *request.Request, output *CreateNetworkAclEntryOutput) { op := &request.Operation{ Name: opCreateNetworkAclEntry, @@ -3553,7 +3951,7 @@ func (c *EC2) CreateNetworkAclEntryRequest(input *CreateNetworkAclEntryInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateNetworkAclEntry for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntry func (c *EC2) CreateNetworkAclEntry(input *CreateNetworkAclEntryInput) (*CreateNetworkAclEntryOutput, error) { req, out := c.CreateNetworkAclEntryRequest(input) return out, req.Send() @@ -3600,7 +3998,7 @@ const opCreateNetworkInterface = "CreateNetworkInterface" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterface func (c *EC2) CreateNetworkInterfaceRequest(input *CreateNetworkInterfaceInput) (req *request.Request, output *CreateNetworkInterfaceOutput) { op := &request.Operation{ Name: opCreateNetworkInterface, @@ -3631,7 +4029,7 @@ func (c *EC2) CreateNetworkInterfaceRequest(input *CreateNetworkInterfaceInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateNetworkInterface for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterface func (c *EC2) CreateNetworkInterface(input *CreateNetworkInterfaceInput) (*CreateNetworkInterfaceOutput, error) { req, out := c.CreateNetworkInterfaceRequest(input) return out, req.Send() @@ -3678,7 +4076,7 @@ const opCreateNetworkInterfacePermission = "CreateNetworkInterfacePermission" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermission func (c *EC2) CreateNetworkInterfacePermissionRequest(input *CreateNetworkInterfacePermissionInput) (req *request.Request, output *CreateNetworkInterfacePermissionOutput) { op := &request.Operation{ Name: opCreateNetworkInterfacePermission, @@ -3709,7 +4107,7 @@ func (c *EC2) CreateNetworkInterfacePermissionRequest(input *CreateNetworkInterf // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateNetworkInterfacePermission for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermission func (c *EC2) CreateNetworkInterfacePermission(input *CreateNetworkInterfacePermissionInput) (*CreateNetworkInterfacePermissionOutput, error) { req, out := c.CreateNetworkInterfacePermissionRequest(input) return out, req.Send() @@ -3756,7 +4154,7 @@ const opCreatePlacementGroup = "CreatePlacementGroup" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroup func (c *EC2) CreatePlacementGroupRequest(input *CreatePlacementGroupInput) (req *request.Request, output *CreatePlacementGroupOutput) { op := &request.Operation{ Name: opCreatePlacementGroup, @@ -3777,11 +4175,14 @@ func (c *EC2) CreatePlacementGroupRequest(input *CreatePlacementGroupInput) (req // CreatePlacementGroup API operation for Amazon Elastic Compute Cloud. // -// Creates a placement group that you launch cluster instances into. You must -// give the group a name that's unique within the scope of your account. +// Creates a placement group in which to launch instances. The strategy of the +// placement group determines how the instances are organized within the group. // -// For more information about placement groups and cluster instances, see Cluster -// Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cluster_computing.html) +// A cluster placement group is a logical grouping of instances within a single +// Availability Zone that benefit from low network latency, high network throughput. +// A spread placement group places instances on distinct hardware. +// +// For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -3790,7 +4191,7 @@ func (c *EC2) CreatePlacementGroupRequest(input *CreatePlacementGroupInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreatePlacementGroup for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroup func (c *EC2) CreatePlacementGroup(input *CreatePlacementGroupInput) (*CreatePlacementGroupOutput, error) { req, out := c.CreatePlacementGroupRequest(input) return out, req.Send() @@ -3837,7 +4238,7 @@ const opCreateReservedInstancesListing = "CreateReservedInstancesListing" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListing +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListing func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstancesListingInput) (req *request.Request, output *CreateReservedInstancesListingOutput) { op := &request.Operation{ Name: opCreateReservedInstancesListing, @@ -3887,7 +4288,7 @@ func (c *EC2) CreateReservedInstancesListingRequest(input *CreateReservedInstanc // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateReservedInstancesListing for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListing +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListing func (c *EC2) CreateReservedInstancesListing(input *CreateReservedInstancesListingInput) (*CreateReservedInstancesListingOutput, error) { req, out := c.CreateReservedInstancesListingRequest(input) return out, req.Send() @@ -3934,7 +4335,7 @@ const opCreateRoute = "CreateRoute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRoute func (c *EC2) CreateRouteRequest(input *CreateRouteInput) (req *request.Request, output *CreateRouteOutput) { op := &request.Operation{ Name: opCreateRoute, @@ -3980,7 +4381,7 @@ func (c *EC2) CreateRouteRequest(input *CreateRouteInput) (req *request.Request, // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateRoute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRoute func (c *EC2) CreateRoute(input *CreateRouteInput) (*CreateRouteOutput, error) { req, out := c.CreateRouteRequest(input) return out, req.Send() @@ -4027,7 +4428,7 @@ const opCreateRouteTable = "CreateRouteTable" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTable func (c *EC2) CreateRouteTableRequest(input *CreateRouteTableInput) (req *request.Request, output *CreateRouteTableOutput) { op := &request.Operation{ Name: opCreateRouteTable, @@ -4058,7 +4459,7 @@ func (c *EC2) CreateRouteTableRequest(input *CreateRouteTableInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateRouteTable for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTable func (c *EC2) CreateRouteTable(input *CreateRouteTableInput) (*CreateRouteTableOutput, error) { req, out := c.CreateRouteTableRequest(input) return out, req.Send() @@ -4105,7 +4506,7 @@ const opCreateSecurityGroup = "CreateSecurityGroup" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroup func (c *EC2) CreateSecurityGroupRequest(input *CreateSecurityGroupInput) (req *request.Request, output *CreateSecurityGroupOutput) { op := &request.Operation{ Name: opCreateSecurityGroup, @@ -4158,7 +4559,7 @@ func (c *EC2) CreateSecurityGroupRequest(input *CreateSecurityGroupInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateSecurityGroup for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroup func (c *EC2) CreateSecurityGroup(input *CreateSecurityGroupInput) (*CreateSecurityGroupOutput, error) { req, out := c.CreateSecurityGroupRequest(input) return out, req.Send() @@ -4205,7 +4606,7 @@ const opCreateSnapshot = "CreateSnapshot" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshot func (c *EC2) CreateSnapshotRequest(input *CreateSnapshotInput) (req *request.Request, output *Snapshot) { op := &request.Operation{ Name: opCreateSnapshot, @@ -4259,7 +4660,7 @@ func (c *EC2) CreateSnapshotRequest(input *CreateSnapshotInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateSnapshot for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshot func (c *EC2) CreateSnapshot(input *CreateSnapshotInput) (*Snapshot, error) { req, out := c.CreateSnapshotRequest(input) return out, req.Send() @@ -4306,7 +4707,7 @@ const opCreateSpotDatafeedSubscription = "CreateSpotDatafeedSubscription" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscription func (c *EC2) CreateSpotDatafeedSubscriptionRequest(input *CreateSpotDatafeedSubscriptionInput) (req *request.Request, output *CreateSpotDatafeedSubscriptionOutput) { op := &request.Operation{ Name: opCreateSpotDatafeedSubscription, @@ -4325,7 +4726,7 @@ func (c *EC2) CreateSpotDatafeedSubscriptionRequest(input *CreateSpotDatafeedSub // CreateSpotDatafeedSubscription API operation for Amazon Elastic Compute Cloud. // -// Creates a data feed for Spot instances, enabling you to view Spot instance +// Creates a data feed for Spot Instances, enabling you to view Spot Instance // usage logs. You can create one data feed per AWS account. For more information, // see Spot Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) // in the Amazon Elastic Compute Cloud User Guide. @@ -4336,7 +4737,7 @@ func (c *EC2) CreateSpotDatafeedSubscriptionRequest(input *CreateSpotDatafeedSub // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateSpotDatafeedSubscription for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscription func (c *EC2) CreateSpotDatafeedSubscription(input *CreateSpotDatafeedSubscriptionInput) (*CreateSpotDatafeedSubscriptionOutput, error) { req, out := c.CreateSpotDatafeedSubscriptionRequest(input) return out, req.Send() @@ -4383,7 +4784,7 @@ const opCreateSubnet = "CreateSubnet" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnet func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Request, output *CreateSubnetOutput) { op := &request.Operation{ Name: opCreateSubnet, @@ -4404,14 +4805,13 @@ func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Reques // // Creates a subnet in an existing VPC. // -// When you create each subnet, you provide the VPC ID and the CIDR block you -// want for the subnet. After you create a subnet, you can't change its CIDR -// block. The subnet's IPv4 CIDR block can be the same as the VPC's IPv4 CIDR -// block (assuming you want only a single subnet in the VPC), or a subset of -// the VPC's IPv4 CIDR block. If you create more than one subnet in a VPC, the -// subnets' CIDR blocks must not overlap. The smallest IPv4 subnet (and VPC) -// you can create uses a /28 netmask (16 IPv4 addresses), and the largest uses -// a /16 netmask (65,536 IPv4 addresses). +// When you create each subnet, you provide the VPC ID and the IPv4 CIDR block +// you want for the subnet. After you create a subnet, you can't change its +// CIDR block. The size of the subnet's IPv4 CIDR block can be the same as a +// VPC's IPv4 CIDR block, or a subset of a VPC's IPv4 CIDR block. If you create +// more than one subnet in a VPC, the subnets' CIDR blocks must not overlap. +// The smallest IPv4 subnet (and VPC) you can create uses a /28 netmask (16 +// IPv4 addresses), and the largest uses a /16 netmask (65,536 IPv4 addresses). // // If you've associated an IPv6 CIDR block with your VPC, you can create a subnet // with an IPv6 CIDR block that uses a /64 prefix length. @@ -4437,7 +4837,7 @@ func (c *EC2) CreateSubnetRequest(input *CreateSubnetInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateSubnet for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnet func (c *EC2) CreateSubnet(input *CreateSubnetInput) (*CreateSubnetOutput, error) { req, out := c.CreateSubnetRequest(input) return out, req.Send() @@ -4484,7 +4884,7 @@ const opCreateTags = "CreateTags" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTags +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTags func (c *EC2) CreateTagsRequest(input *CreateTagsInput) (req *request.Request, output *CreateTagsOutput) { op := &request.Operation{ Name: opCreateTags, @@ -4521,7 +4921,7 @@ func (c *EC2) CreateTagsRequest(input *CreateTagsInput) (req *request.Request, o // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateTags for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTags +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTags func (c *EC2) CreateTags(input *CreateTagsInput) (*CreateTagsOutput, error) { req, out := c.CreateTagsRequest(input) return out, req.Send() @@ -4568,7 +4968,7 @@ const opCreateVolume = "CreateVolume" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolume func (c *EC2) CreateVolumeRequest(input *CreateVolumeInput) (req *request.Request, output *Volume) { op := &request.Operation{ Name: opCreateVolume, @@ -4613,7 +5013,7 @@ func (c *EC2) CreateVolumeRequest(input *CreateVolumeInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVolume for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolume func (c *EC2) CreateVolume(input *CreateVolumeInput) (*Volume, error) { req, out := c.CreateVolumeRequest(input) return out, req.Send() @@ -4660,7 +5060,7 @@ const opCreateVpc = "CreateVpc" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpc func (c *EC2) CreateVpcRequest(input *CreateVpcInput) (req *request.Request, output *CreateVpcOutput) { op := &request.Operation{ Name: opCreateVpc, @@ -4705,7 +5105,7 @@ func (c *EC2) CreateVpcRequest(input *CreateVpcInput) (req *request.Request, out // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVpc for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpc func (c *EC2) CreateVpc(input *CreateVpcInput) (*CreateVpcOutput, error) { req, out := c.CreateVpcRequest(input) return out, req.Send() @@ -4752,7 +5152,7 @@ const opCreateVpcEndpoint = "CreateVpcEndpoint" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpoint +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpoint func (c *EC2) CreateVpcEndpointRequest(input *CreateVpcEndpointInput) (req *request.Request, output *CreateVpcEndpointOutput) { op := &request.Operation{ Name: opCreateVpcEndpoint, @@ -4771,13 +5171,23 @@ func (c *EC2) CreateVpcEndpointRequest(input *CreateVpcEndpointInput) (req *requ // CreateVpcEndpoint API operation for Amazon Elastic Compute Cloud. // -// Creates a VPC endpoint for a specified AWS service. An endpoint enables you -// to create a private connection between your VPC and another AWS service in -// your account. You can specify an endpoint policy to attach to the endpoint -// that will control access to the service from your VPC. You can also specify -// the VPC route tables that use the endpoint. +// Creates a VPC endpoint for a specified service. An endpoint enables you to +// create a private connection between your VPC and the service. The service +// may be provided by AWS, an AWS Marketplace partner, or another AWS account. +// For more information, see VPC Endpoints (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-endpoints.html) +// in the Amazon Virtual Private Cloud User Guide. // -// Use DescribeVpcEndpointServices to get a list of supported AWS services. +// A gateway endpoint serves as a target for a route in your route table for +// traffic destined for the AWS service. You can specify an endpoint policy +// to attach to the endpoint that will control access to the service from your +// VPC. You can also specify the VPC route tables that use the endpoint. +// +// An interface endpoint is a network interface in your subnet that serves as +// an endpoint for communicating with the specified service. You can specify +// the subnets in which to create an endpoint, and the security groups to associate +// with the endpoint network interface. +// +// Use DescribeVpcEndpointServices to get a list of supported services. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4785,7 +5195,7 @@ func (c *EC2) CreateVpcEndpointRequest(input *CreateVpcEndpointInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVpcEndpoint for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpoint +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpoint func (c *EC2) CreateVpcEndpoint(input *CreateVpcEndpointInput) (*CreateVpcEndpointOutput, error) { req, out := c.CreateVpcEndpointRequest(input) return out, req.Send() @@ -4807,6 +5217,167 @@ func (c *EC2) CreateVpcEndpointWithContext(ctx aws.Context, input *CreateVpcEndp return out, req.Send() } +const opCreateVpcEndpointConnectionNotification = "CreateVpcEndpointConnectionNotification" + +// CreateVpcEndpointConnectionNotificationRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpcEndpointConnectionNotification operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateVpcEndpointConnectionNotification for more information on using the CreateVpcEndpointConnectionNotification +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateVpcEndpointConnectionNotificationRequest method. +// req, resp := client.CreateVpcEndpointConnectionNotificationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointConnectionNotification +func (c *EC2) CreateVpcEndpointConnectionNotificationRequest(input *CreateVpcEndpointConnectionNotificationInput) (req *request.Request, output *CreateVpcEndpointConnectionNotificationOutput) { + op := &request.Operation{ + Name: opCreateVpcEndpointConnectionNotification, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpcEndpointConnectionNotificationInput{} + } + + output = &CreateVpcEndpointConnectionNotificationOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateVpcEndpointConnectionNotification API operation for Amazon Elastic Compute Cloud. +// +// Creates a connection notification for a specified VPC endpoint or VPC endpoint +// service. A connection notification notifies you of specific endpoint events. +// You must create an SNS topic to receive notifications. For more information, +// see Create a Topic (http://docs.aws.amazon.com/sns/latest/dg/CreateTopic.html) +// in the Amazon Simple Notification Service Developer Guide. +// +// You can create a connection notification for interface endpoints only. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateVpcEndpointConnectionNotification for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointConnectionNotification +func (c *EC2) CreateVpcEndpointConnectionNotification(input *CreateVpcEndpointConnectionNotificationInput) (*CreateVpcEndpointConnectionNotificationOutput, error) { + req, out := c.CreateVpcEndpointConnectionNotificationRequest(input) + return out, req.Send() +} + +// CreateVpcEndpointConnectionNotificationWithContext is the same as CreateVpcEndpointConnectionNotification with the addition of +// the ability to pass a context and additional request options. +// +// See CreateVpcEndpointConnectionNotification for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateVpcEndpointConnectionNotificationWithContext(ctx aws.Context, input *CreateVpcEndpointConnectionNotificationInput, opts ...request.Option) (*CreateVpcEndpointConnectionNotificationOutput, error) { + req, out := c.CreateVpcEndpointConnectionNotificationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateVpcEndpointServiceConfiguration = "CreateVpcEndpointServiceConfiguration" + +// CreateVpcEndpointServiceConfigurationRequest generates a "aws/request.Request" representing the +// client's request for the CreateVpcEndpointServiceConfiguration operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateVpcEndpointServiceConfiguration for more information on using the CreateVpcEndpointServiceConfiguration +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateVpcEndpointServiceConfigurationRequest method. +// req, resp := client.CreateVpcEndpointServiceConfigurationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointServiceConfiguration +func (c *EC2) CreateVpcEndpointServiceConfigurationRequest(input *CreateVpcEndpointServiceConfigurationInput) (req *request.Request, output *CreateVpcEndpointServiceConfigurationOutput) { + op := &request.Operation{ + Name: opCreateVpcEndpointServiceConfiguration, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateVpcEndpointServiceConfigurationInput{} + } + + output = &CreateVpcEndpointServiceConfigurationOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateVpcEndpointServiceConfiguration API operation for Amazon Elastic Compute Cloud. +// +// Creates a VPC endpoint service configuration to which service consumers (AWS +// accounts, IAM users, and IAM roles) can connect. Service consumers can create +// an interface VPC endpoint to connect to your service. +// +// To create an endpoint service configuration, you must first create a Network +// Load Balancer for your service. For more information, see VPC Endpoint Services +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/endpoint-service.html) +// in the Amazon Virtual Private Cloud User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation CreateVpcEndpointServiceConfiguration for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointServiceConfiguration +func (c *EC2) CreateVpcEndpointServiceConfiguration(input *CreateVpcEndpointServiceConfigurationInput) (*CreateVpcEndpointServiceConfigurationOutput, error) { + req, out := c.CreateVpcEndpointServiceConfigurationRequest(input) + return out, req.Send() +} + +// CreateVpcEndpointServiceConfigurationWithContext is the same as CreateVpcEndpointServiceConfiguration with the addition of +// the ability to pass a context and additional request options. +// +// See CreateVpcEndpointServiceConfiguration for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) CreateVpcEndpointServiceConfigurationWithContext(ctx aws.Context, input *CreateVpcEndpointServiceConfigurationInput, opts ...request.Option) (*CreateVpcEndpointServiceConfigurationOutput, error) { + req, out := c.CreateVpcEndpointServiceConfigurationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateVpcPeeringConnection = "CreateVpcPeeringConnection" // CreateVpcPeeringConnectionRequest generates a "aws/request.Request" representing the @@ -4832,7 +5403,7 @@ const opCreateVpcPeeringConnection = "CreateVpcPeeringConnection" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnection func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectionInput) (req *request.Request, output *CreateVpcPeeringConnectionOutput) { op := &request.Operation{ Name: opCreateVpcPeeringConnection, @@ -4852,16 +5423,17 @@ func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectio // CreateVpcPeeringConnection API operation for Amazon Elastic Compute Cloud. // // Requests a VPC peering connection between two VPCs: a requester VPC that -// you own and a peer VPC with which to create the connection. The peer VPC -// can belong to another AWS account. The requester VPC and peer VPC cannot -// have overlapping CIDR blocks. +// you own and an accepter VPC with which to create the connection. The accepter +// VPC can belong to another AWS account and can be in a different region to +// the requester VPC. The requester VPC and accepter VPC cannot have overlapping +// CIDR blocks. // -// The owner of the peer VPC must accept the peering request to activate the -// peering connection. The VPC peering connection request expires after 7 days, -// after which it cannot be accepted or rejected. +// The owner of the accepter VPC must accept the peering request to activate +// the peering connection. The VPC peering connection request expires after +// 7 days, after which it cannot be accepted or rejected. // -// If you try to create a VPC peering connection between VPCs that have overlapping -// CIDR blocks, the VPC peering connection status goes to failed. +// If you create a VPC peering connection request between VPCs with overlapping +// CIDR blocks, the VPC peering connection has a status of failed. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4869,7 +5441,7 @@ func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectio // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVpcPeeringConnection for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnection func (c *EC2) CreateVpcPeeringConnection(input *CreateVpcPeeringConnectionInput) (*CreateVpcPeeringConnectionOutput, error) { req, out := c.CreateVpcPeeringConnectionRequest(input) return out, req.Send() @@ -4916,7 +5488,7 @@ const opCreateVpnConnection = "CreateVpnConnection" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnection func (c *EC2) CreateVpnConnectionRequest(input *CreateVpnConnectionInput) (req *request.Request, output *CreateVpnConnectionOutput) { op := &request.Operation{ Name: opCreateVpnConnection, @@ -4952,8 +5524,7 @@ func (c *EC2) CreateVpnConnectionRequest(input *CreateVpnConnectionInput) (req * // This is an idempotent operation. If you perform the operation more than once, // Amazon EC2 doesn't return an error. // -// For more information about VPN connections, see Adding a Hardware Virtual -// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// For more information, see AWS Managed VPN Connections (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -4962,7 +5533,7 @@ func (c *EC2) CreateVpnConnectionRequest(input *CreateVpnConnectionInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVpnConnection for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnection func (c *EC2) CreateVpnConnection(input *CreateVpnConnectionInput) (*CreateVpnConnectionOutput, error) { req, out := c.CreateVpnConnectionRequest(input) return out, req.Send() @@ -5009,7 +5580,7 @@ const opCreateVpnConnectionRoute = "CreateVpnConnectionRoute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRoute func (c *EC2) CreateVpnConnectionRouteRequest(input *CreateVpnConnectionRouteInput) (req *request.Request, output *CreateVpnConnectionRouteOutput) { op := &request.Operation{ Name: opCreateVpnConnectionRoute, @@ -5035,9 +5606,9 @@ func (c *EC2) CreateVpnConnectionRouteRequest(input *CreateVpnConnectionRouteInp // traffic to be routed from the virtual private gateway to the VPN customer // gateway. // -// For more information about VPN connections, see Adding a Hardware Virtual -// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. +// For more information about VPN connections, see AWS Managed VPN Connections +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) in the +// Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -5045,7 +5616,7 @@ func (c *EC2) CreateVpnConnectionRouteRequest(input *CreateVpnConnectionRouteInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVpnConnectionRoute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRoute func (c *EC2) CreateVpnConnectionRoute(input *CreateVpnConnectionRouteInput) (*CreateVpnConnectionRouteOutput, error) { req, out := c.CreateVpnConnectionRouteRequest(input) return out, req.Send() @@ -5092,7 +5663,7 @@ const opCreateVpnGateway = "CreateVpnGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGateway func (c *EC2) CreateVpnGatewayRequest(input *CreateVpnGatewayInput) (req *request.Request, output *CreateVpnGatewayOutput) { op := &request.Operation{ Name: opCreateVpnGateway, @@ -5115,8 +5686,8 @@ func (c *EC2) CreateVpnGatewayRequest(input *CreateVpnGatewayInput) (req *reques // on the VPC side of your VPN connection. You can create a virtual private // gateway before creating the VPC itself. // -// For more information about virtual private gateways, see Adding a Hardware -// Virtual Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// For more information about virtual private gateways, see AWS Managed VPN +// Connections (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -5125,7 +5696,7 @@ func (c *EC2) CreateVpnGatewayRequest(input *CreateVpnGatewayInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation CreateVpnGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGateway func (c *EC2) CreateVpnGateway(input *CreateVpnGatewayInput) (*CreateVpnGatewayOutput, error) { req, out := c.CreateVpnGatewayRequest(input) return out, req.Send() @@ -5172,7 +5743,7 @@ const opDeleteCustomerGateway = "DeleteCustomerGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGateway func (c *EC2) DeleteCustomerGatewayRequest(input *DeleteCustomerGatewayInput) (req *request.Request, output *DeleteCustomerGatewayOutput) { op := &request.Operation{ Name: opDeleteCustomerGateway, @@ -5202,7 +5773,7 @@ func (c *EC2) DeleteCustomerGatewayRequest(input *DeleteCustomerGatewayInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteCustomerGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGateway func (c *EC2) DeleteCustomerGateway(input *DeleteCustomerGatewayInput) (*DeleteCustomerGatewayOutput, error) { req, out := c.DeleteCustomerGatewayRequest(input) return out, req.Send() @@ -5249,7 +5820,7 @@ const opDeleteDhcpOptions = "DeleteDhcpOptions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptions func (c *EC2) DeleteDhcpOptionsRequest(input *DeleteDhcpOptionsInput) (req *request.Request, output *DeleteDhcpOptionsOutput) { op := &request.Operation{ Name: opDeleteDhcpOptions, @@ -5281,7 +5852,7 @@ func (c *EC2) DeleteDhcpOptionsRequest(input *DeleteDhcpOptionsInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteDhcpOptions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptions func (c *EC2) DeleteDhcpOptions(input *DeleteDhcpOptionsInput) (*DeleteDhcpOptionsOutput, error) { req, out := c.DeleteDhcpOptionsRequest(input) return out, req.Send() @@ -5328,7 +5899,7 @@ const opDeleteEgressOnlyInternetGateway = "DeleteEgressOnlyInternetGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGateway func (c *EC2) DeleteEgressOnlyInternetGatewayRequest(input *DeleteEgressOnlyInternetGatewayInput) (req *request.Request, output *DeleteEgressOnlyInternetGatewayOutput) { op := &request.Operation{ Name: opDeleteEgressOnlyInternetGateway, @@ -5355,7 +5926,7 @@ func (c *EC2) DeleteEgressOnlyInternetGatewayRequest(input *DeleteEgressOnlyInte // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteEgressOnlyInternetGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGateway func (c *EC2) DeleteEgressOnlyInternetGateway(input *DeleteEgressOnlyInternetGatewayInput) (*DeleteEgressOnlyInternetGatewayOutput, error) { req, out := c.DeleteEgressOnlyInternetGatewayRequest(input) return out, req.Send() @@ -5402,7 +5973,7 @@ const opDeleteFlowLogs = "DeleteFlowLogs" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogs func (c *EC2) DeleteFlowLogsRequest(input *DeleteFlowLogsInput) (req *request.Request, output *DeleteFlowLogsOutput) { op := &request.Operation{ Name: opDeleteFlowLogs, @@ -5429,7 +6000,7 @@ func (c *EC2) DeleteFlowLogsRequest(input *DeleteFlowLogsInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteFlowLogs for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogs func (c *EC2) DeleteFlowLogs(input *DeleteFlowLogsInput) (*DeleteFlowLogsOutput, error) { req, out := c.DeleteFlowLogsRequest(input) return out, req.Send() @@ -5451,6 +6022,80 @@ func (c *EC2) DeleteFlowLogsWithContext(ctx aws.Context, input *DeleteFlowLogsIn return out, req.Send() } +const opDeleteFpgaImage = "DeleteFpgaImage" + +// DeleteFpgaImageRequest generates a "aws/request.Request" representing the +// client's request for the DeleteFpgaImage operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteFpgaImage for more information on using the DeleteFpgaImage +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteFpgaImageRequest method. +// req, resp := client.DeleteFpgaImageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFpgaImage +func (c *EC2) DeleteFpgaImageRequest(input *DeleteFpgaImageInput) (req *request.Request, output *DeleteFpgaImageOutput) { + op := &request.Operation{ + Name: opDeleteFpgaImage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteFpgaImageInput{} + } + + output = &DeleteFpgaImageOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteFpgaImage API operation for Amazon Elastic Compute Cloud. +// +// Deletes the specified Amazon FPGA Image (AFI). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DeleteFpgaImage for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFpgaImage +func (c *EC2) DeleteFpgaImage(input *DeleteFpgaImageInput) (*DeleteFpgaImageOutput, error) { + req, out := c.DeleteFpgaImageRequest(input) + return out, req.Send() +} + +// DeleteFpgaImageWithContext is the same as DeleteFpgaImage with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteFpgaImage for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DeleteFpgaImageWithContext(ctx aws.Context, input *DeleteFpgaImageInput, opts ...request.Option) (*DeleteFpgaImageOutput, error) { + req, out := c.DeleteFpgaImageRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeleteInternetGateway = "DeleteInternetGateway" // DeleteInternetGatewayRequest generates a "aws/request.Request" representing the @@ -5476,7 +6121,7 @@ const opDeleteInternetGateway = "DeleteInternetGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGateway func (c *EC2) DeleteInternetGatewayRequest(input *DeleteInternetGatewayInput) (req *request.Request, output *DeleteInternetGatewayOutput) { op := &request.Operation{ Name: opDeleteInternetGateway, @@ -5506,7 +6151,7 @@ func (c *EC2) DeleteInternetGatewayRequest(input *DeleteInternetGatewayInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteInternetGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGateway func (c *EC2) DeleteInternetGateway(input *DeleteInternetGatewayInput) (*DeleteInternetGatewayOutput, error) { req, out := c.DeleteInternetGatewayRequest(input) return out, req.Send() @@ -5553,7 +6198,7 @@ const opDeleteKeyPair = "DeleteKeyPair" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPair func (c *EC2) DeleteKeyPairRequest(input *DeleteKeyPairInput) (req *request.Request, output *DeleteKeyPairOutput) { op := &request.Operation{ Name: opDeleteKeyPair, @@ -5582,7 +6227,7 @@ func (c *EC2) DeleteKeyPairRequest(input *DeleteKeyPairInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteKeyPair for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPair func (c *EC2) DeleteKeyPair(input *DeleteKeyPairInput) (*DeleteKeyPairOutput, error) { req, out := c.DeleteKeyPairRequest(input) return out, req.Send() @@ -5604,6 +6249,158 @@ func (c *EC2) DeleteKeyPairWithContext(ctx aws.Context, input *DeleteKeyPairInpu return out, req.Send() } +const opDeleteLaunchTemplate = "DeleteLaunchTemplate" + +// DeleteLaunchTemplateRequest generates a "aws/request.Request" representing the +// client's request for the DeleteLaunchTemplate operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteLaunchTemplate for more information on using the DeleteLaunchTemplate +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteLaunchTemplateRequest method. +// req, resp := client.DeleteLaunchTemplateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplate +func (c *EC2) DeleteLaunchTemplateRequest(input *DeleteLaunchTemplateInput) (req *request.Request, output *DeleteLaunchTemplateOutput) { + op := &request.Operation{ + Name: opDeleteLaunchTemplate, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteLaunchTemplateInput{} + } + + output = &DeleteLaunchTemplateOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteLaunchTemplate API operation for Amazon Elastic Compute Cloud. +// +// Deletes a launch template. Deleting a launch template deletes all of its +// versions. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DeleteLaunchTemplate for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplate +func (c *EC2) DeleteLaunchTemplate(input *DeleteLaunchTemplateInput) (*DeleteLaunchTemplateOutput, error) { + req, out := c.DeleteLaunchTemplateRequest(input) + return out, req.Send() +} + +// DeleteLaunchTemplateWithContext is the same as DeleteLaunchTemplate with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteLaunchTemplate for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DeleteLaunchTemplateWithContext(ctx aws.Context, input *DeleteLaunchTemplateInput, opts ...request.Option) (*DeleteLaunchTemplateOutput, error) { + req, out := c.DeleteLaunchTemplateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteLaunchTemplateVersions = "DeleteLaunchTemplateVersions" + +// DeleteLaunchTemplateVersionsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteLaunchTemplateVersions operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteLaunchTemplateVersions for more information on using the DeleteLaunchTemplateVersions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteLaunchTemplateVersionsRequest method. +// req, resp := client.DeleteLaunchTemplateVersionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersions +func (c *EC2) DeleteLaunchTemplateVersionsRequest(input *DeleteLaunchTemplateVersionsInput) (req *request.Request, output *DeleteLaunchTemplateVersionsOutput) { + op := &request.Operation{ + Name: opDeleteLaunchTemplateVersions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteLaunchTemplateVersionsInput{} + } + + output = &DeleteLaunchTemplateVersionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteLaunchTemplateVersions API operation for Amazon Elastic Compute Cloud. +// +// Deletes one or more versions of a launch template. You cannot delete the +// default version of a launch template; you must first assign a different version +// as the default. If the default version is the only version for the launch +// template, you must delete the entire launch template using DeleteLaunchTemplate. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DeleteLaunchTemplateVersions for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersions +func (c *EC2) DeleteLaunchTemplateVersions(input *DeleteLaunchTemplateVersionsInput) (*DeleteLaunchTemplateVersionsOutput, error) { + req, out := c.DeleteLaunchTemplateVersionsRequest(input) + return out, req.Send() +} + +// DeleteLaunchTemplateVersionsWithContext is the same as DeleteLaunchTemplateVersions with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteLaunchTemplateVersions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DeleteLaunchTemplateVersionsWithContext(ctx aws.Context, input *DeleteLaunchTemplateVersionsInput, opts ...request.Option) (*DeleteLaunchTemplateVersionsOutput, error) { + req, out := c.DeleteLaunchTemplateVersionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeleteNatGateway = "DeleteNatGateway" // DeleteNatGatewayRequest generates a "aws/request.Request" representing the @@ -5629,7 +6426,7 @@ const opDeleteNatGateway = "DeleteNatGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGateway func (c *EC2) DeleteNatGatewayRequest(input *DeleteNatGatewayInput) (req *request.Request, output *DeleteNatGatewayOutput) { op := &request.Operation{ Name: opDeleteNatGateway, @@ -5658,7 +6455,7 @@ func (c *EC2) DeleteNatGatewayRequest(input *DeleteNatGatewayInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteNatGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGateway func (c *EC2) DeleteNatGateway(input *DeleteNatGatewayInput) (*DeleteNatGatewayOutput, error) { req, out := c.DeleteNatGatewayRequest(input) return out, req.Send() @@ -5705,7 +6502,7 @@ const opDeleteNetworkAcl = "DeleteNetworkAcl" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAcl func (c *EC2) DeleteNetworkAclRequest(input *DeleteNetworkAclInput) (req *request.Request, output *DeleteNetworkAclOutput) { op := &request.Operation{ Name: opDeleteNetworkAcl, @@ -5735,7 +6532,7 @@ func (c *EC2) DeleteNetworkAclRequest(input *DeleteNetworkAclInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteNetworkAcl for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAcl func (c *EC2) DeleteNetworkAcl(input *DeleteNetworkAclInput) (*DeleteNetworkAclOutput, error) { req, out := c.DeleteNetworkAclRequest(input) return out, req.Send() @@ -5782,7 +6579,7 @@ const opDeleteNetworkAclEntry = "DeleteNetworkAclEntry" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntry func (c *EC2) DeleteNetworkAclEntryRequest(input *DeleteNetworkAclEntryInput) (req *request.Request, output *DeleteNetworkAclEntryOutput) { op := &request.Operation{ Name: opDeleteNetworkAclEntry, @@ -5812,7 +6609,7 @@ func (c *EC2) DeleteNetworkAclEntryRequest(input *DeleteNetworkAclEntryInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteNetworkAclEntry for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntry func (c *EC2) DeleteNetworkAclEntry(input *DeleteNetworkAclEntryInput) (*DeleteNetworkAclEntryOutput, error) { req, out := c.DeleteNetworkAclEntryRequest(input) return out, req.Send() @@ -5859,7 +6656,7 @@ const opDeleteNetworkInterface = "DeleteNetworkInterface" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterface func (c *EC2) DeleteNetworkInterfaceRequest(input *DeleteNetworkInterfaceInput) (req *request.Request, output *DeleteNetworkInterfaceOutput) { op := &request.Operation{ Name: opDeleteNetworkInterface, @@ -5889,7 +6686,7 @@ func (c *EC2) DeleteNetworkInterfaceRequest(input *DeleteNetworkInterfaceInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteNetworkInterface for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterface func (c *EC2) DeleteNetworkInterface(input *DeleteNetworkInterfaceInput) (*DeleteNetworkInterfaceOutput, error) { req, out := c.DeleteNetworkInterfaceRequest(input) return out, req.Send() @@ -5936,7 +6733,7 @@ const opDeleteNetworkInterfacePermission = "DeleteNetworkInterfacePermission" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermission func (c *EC2) DeleteNetworkInterfacePermissionRequest(input *DeleteNetworkInterfacePermissionInput) (req *request.Request, output *DeleteNetworkInterfacePermissionOutput) { op := &request.Operation{ Name: opDeleteNetworkInterfacePermission, @@ -5966,7 +6763,7 @@ func (c *EC2) DeleteNetworkInterfacePermissionRequest(input *DeleteNetworkInterf // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteNetworkInterfacePermission for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermission func (c *EC2) DeleteNetworkInterfacePermission(input *DeleteNetworkInterfacePermissionInput) (*DeleteNetworkInterfacePermissionOutput, error) { req, out := c.DeleteNetworkInterfacePermissionRequest(input) return out, req.Send() @@ -6013,7 +6810,7 @@ const opDeletePlacementGroup = "DeletePlacementGroup" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroup func (c *EC2) DeletePlacementGroupRequest(input *DeletePlacementGroupInput) (req *request.Request, output *DeletePlacementGroupOutput) { op := &request.Operation{ Name: opDeletePlacementGroup, @@ -6035,8 +6832,8 @@ func (c *EC2) DeletePlacementGroupRequest(input *DeletePlacementGroupInput) (req // DeletePlacementGroup API operation for Amazon Elastic Compute Cloud. // // Deletes the specified placement group. You must terminate all instances in -// the placement group before you can delete the placement group. For more information -// about placement groups and cluster instances, see Cluster Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cluster_computing.html) +// the placement group before you can delete the placement group. For more information, +// see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -6045,7 +6842,7 @@ func (c *EC2) DeletePlacementGroupRequest(input *DeletePlacementGroupInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeletePlacementGroup for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroup func (c *EC2) DeletePlacementGroup(input *DeletePlacementGroupInput) (*DeletePlacementGroupOutput, error) { req, out := c.DeletePlacementGroupRequest(input) return out, req.Send() @@ -6092,7 +6889,7 @@ const opDeleteRoute = "DeleteRoute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRoute func (c *EC2) DeleteRouteRequest(input *DeleteRouteInput) (req *request.Request, output *DeleteRouteOutput) { op := &request.Operation{ Name: opDeleteRoute, @@ -6121,7 +6918,7 @@ func (c *EC2) DeleteRouteRequest(input *DeleteRouteInput) (req *request.Request, // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteRoute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRoute func (c *EC2) DeleteRoute(input *DeleteRouteInput) (*DeleteRouteOutput, error) { req, out := c.DeleteRouteRequest(input) return out, req.Send() @@ -6168,7 +6965,7 @@ const opDeleteRouteTable = "DeleteRouteTable" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTable func (c *EC2) DeleteRouteTableRequest(input *DeleteRouteTableInput) (req *request.Request, output *DeleteRouteTableOutput) { op := &request.Operation{ Name: opDeleteRouteTable, @@ -6199,7 +6996,7 @@ func (c *EC2) DeleteRouteTableRequest(input *DeleteRouteTableInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteRouteTable for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTable func (c *EC2) DeleteRouteTable(input *DeleteRouteTableInput) (*DeleteRouteTableOutput, error) { req, out := c.DeleteRouteTableRequest(input) return out, req.Send() @@ -6246,7 +7043,7 @@ const opDeleteSecurityGroup = "DeleteSecurityGroup" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroup func (c *EC2) DeleteSecurityGroupRequest(input *DeleteSecurityGroupInput) (req *request.Request, output *DeleteSecurityGroupOutput) { op := &request.Operation{ Name: opDeleteSecurityGroup, @@ -6279,7 +7076,7 @@ func (c *EC2) DeleteSecurityGroupRequest(input *DeleteSecurityGroupInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteSecurityGroup for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroup func (c *EC2) DeleteSecurityGroup(input *DeleteSecurityGroupInput) (*DeleteSecurityGroupOutput, error) { req, out := c.DeleteSecurityGroupRequest(input) return out, req.Send() @@ -6326,7 +7123,7 @@ const opDeleteSnapshot = "DeleteSnapshot" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshot func (c *EC2) DeleteSnapshotRequest(input *DeleteSnapshotInput) (req *request.Request, output *DeleteSnapshotOutput) { op := &request.Operation{ Name: opDeleteSnapshot, @@ -6369,7 +7166,7 @@ func (c *EC2) DeleteSnapshotRequest(input *DeleteSnapshotInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteSnapshot for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshot func (c *EC2) DeleteSnapshot(input *DeleteSnapshotInput) (*DeleteSnapshotOutput, error) { req, out := c.DeleteSnapshotRequest(input) return out, req.Send() @@ -6416,7 +7213,7 @@ const opDeleteSpotDatafeedSubscription = "DeleteSpotDatafeedSubscription" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscription func (c *EC2) DeleteSpotDatafeedSubscriptionRequest(input *DeleteSpotDatafeedSubscriptionInput) (req *request.Request, output *DeleteSpotDatafeedSubscriptionOutput) { op := &request.Operation{ Name: opDeleteSpotDatafeedSubscription, @@ -6437,7 +7234,7 @@ func (c *EC2) DeleteSpotDatafeedSubscriptionRequest(input *DeleteSpotDatafeedSub // DeleteSpotDatafeedSubscription API operation for Amazon Elastic Compute Cloud. // -// Deletes the data feed for Spot instances. +// Deletes the data feed for Spot Instances. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -6445,7 +7242,7 @@ func (c *EC2) DeleteSpotDatafeedSubscriptionRequest(input *DeleteSpotDatafeedSub // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteSpotDatafeedSubscription for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscription func (c *EC2) DeleteSpotDatafeedSubscription(input *DeleteSpotDatafeedSubscriptionInput) (*DeleteSpotDatafeedSubscriptionOutput, error) { req, out := c.DeleteSpotDatafeedSubscriptionRequest(input) return out, req.Send() @@ -6492,7 +7289,7 @@ const opDeleteSubnet = "DeleteSubnet" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnet func (c *EC2) DeleteSubnetRequest(input *DeleteSubnetInput) (req *request.Request, output *DeleteSubnetOutput) { op := &request.Operation{ Name: opDeleteSubnet, @@ -6522,7 +7319,7 @@ func (c *EC2) DeleteSubnetRequest(input *DeleteSubnetInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteSubnet for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnet func (c *EC2) DeleteSubnet(input *DeleteSubnetInput) (*DeleteSubnetOutput, error) { req, out := c.DeleteSubnetRequest(input) return out, req.Send() @@ -6569,7 +7366,7 @@ const opDeleteTags = "DeleteTags" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTags +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTags func (c *EC2) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, output *DeleteTagsOutput) { op := &request.Operation{ Name: opDeleteTags, @@ -6590,10 +7387,10 @@ func (c *EC2) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, o // DeleteTags API operation for Amazon Elastic Compute Cloud. // -// Deletes the specified set of tags from the specified set of resources. This -// call is designed to follow a DescribeTags request. +// Deletes the specified set of tags from the specified set of resources. // -// For more information about tags, see Tagging Your Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) +// To list the current tags, use DescribeTags. For more information about tags, +// see Tagging Your Resources (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -6602,7 +7399,7 @@ func (c *EC2) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, o // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteTags for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTags +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTags func (c *EC2) DeleteTags(input *DeleteTagsInput) (*DeleteTagsOutput, error) { req, out := c.DeleteTagsRequest(input) return out, req.Send() @@ -6649,7 +7446,7 @@ const opDeleteVolume = "DeleteVolume" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolume func (c *EC2) DeleteVolumeRequest(input *DeleteVolumeInput) (req *request.Request, output *DeleteVolumeOutput) { op := &request.Operation{ Name: opDeleteVolume, @@ -6684,7 +7481,7 @@ func (c *EC2) DeleteVolumeRequest(input *DeleteVolumeInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVolume for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolume func (c *EC2) DeleteVolume(input *DeleteVolumeInput) (*DeleteVolumeOutput, error) { req, out := c.DeleteVolumeRequest(input) return out, req.Send() @@ -6731,7 +7528,7 @@ const opDeleteVpc = "DeleteVpc" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpc func (c *EC2) DeleteVpcRequest(input *DeleteVpcInput) (req *request.Request, output *DeleteVpcOutput) { op := &request.Operation{ Name: opDeleteVpc, @@ -6764,7 +7561,7 @@ func (c *EC2) DeleteVpcRequest(input *DeleteVpcInput) (req *request.Request, out // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVpc for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpc func (c *EC2) DeleteVpc(input *DeleteVpcInput) (*DeleteVpcOutput, error) { req, out := c.DeleteVpcRequest(input) return out, req.Send() @@ -6786,6 +7583,157 @@ func (c *EC2) DeleteVpcWithContext(ctx aws.Context, input *DeleteVpcInput, opts return out, req.Send() } +const opDeleteVpcEndpointConnectionNotifications = "DeleteVpcEndpointConnectionNotifications" + +// DeleteVpcEndpointConnectionNotificationsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpcEndpointConnectionNotifications operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteVpcEndpointConnectionNotifications for more information on using the DeleteVpcEndpointConnectionNotifications +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteVpcEndpointConnectionNotificationsRequest method. +// req, resp := client.DeleteVpcEndpointConnectionNotificationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointConnectionNotifications +func (c *EC2) DeleteVpcEndpointConnectionNotificationsRequest(input *DeleteVpcEndpointConnectionNotificationsInput) (req *request.Request, output *DeleteVpcEndpointConnectionNotificationsOutput) { + op := &request.Operation{ + Name: opDeleteVpcEndpointConnectionNotifications, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpcEndpointConnectionNotificationsInput{} + } + + output = &DeleteVpcEndpointConnectionNotificationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteVpcEndpointConnectionNotifications API operation for Amazon Elastic Compute Cloud. +// +// Deletes one or more VPC endpoint connection notifications. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DeleteVpcEndpointConnectionNotifications for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointConnectionNotifications +func (c *EC2) DeleteVpcEndpointConnectionNotifications(input *DeleteVpcEndpointConnectionNotificationsInput) (*DeleteVpcEndpointConnectionNotificationsOutput, error) { + req, out := c.DeleteVpcEndpointConnectionNotificationsRequest(input) + return out, req.Send() +} + +// DeleteVpcEndpointConnectionNotificationsWithContext is the same as DeleteVpcEndpointConnectionNotifications with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteVpcEndpointConnectionNotifications for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DeleteVpcEndpointConnectionNotificationsWithContext(ctx aws.Context, input *DeleteVpcEndpointConnectionNotificationsInput, opts ...request.Option) (*DeleteVpcEndpointConnectionNotificationsOutput, error) { + req, out := c.DeleteVpcEndpointConnectionNotificationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteVpcEndpointServiceConfigurations = "DeleteVpcEndpointServiceConfigurations" + +// DeleteVpcEndpointServiceConfigurationsRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVpcEndpointServiceConfigurations operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteVpcEndpointServiceConfigurations for more information on using the DeleteVpcEndpointServiceConfigurations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteVpcEndpointServiceConfigurationsRequest method. +// req, resp := client.DeleteVpcEndpointServiceConfigurationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointServiceConfigurations +func (c *EC2) DeleteVpcEndpointServiceConfigurationsRequest(input *DeleteVpcEndpointServiceConfigurationsInput) (req *request.Request, output *DeleteVpcEndpointServiceConfigurationsOutput) { + op := &request.Operation{ + Name: opDeleteVpcEndpointServiceConfigurations, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteVpcEndpointServiceConfigurationsInput{} + } + + output = &DeleteVpcEndpointServiceConfigurationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteVpcEndpointServiceConfigurations API operation for Amazon Elastic Compute Cloud. +// +// Deletes one or more VPC endpoint service configurations in your account. +// Before you delete the endpoint service configuration, you must reject any +// Available or PendingAcceptance interface endpoint connections that are attached +// to the service. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DeleteVpcEndpointServiceConfigurations for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointServiceConfigurations +func (c *EC2) DeleteVpcEndpointServiceConfigurations(input *DeleteVpcEndpointServiceConfigurationsInput) (*DeleteVpcEndpointServiceConfigurationsOutput, error) { + req, out := c.DeleteVpcEndpointServiceConfigurationsRequest(input) + return out, req.Send() +} + +// DeleteVpcEndpointServiceConfigurationsWithContext is the same as DeleteVpcEndpointServiceConfigurations with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteVpcEndpointServiceConfigurations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DeleteVpcEndpointServiceConfigurationsWithContext(ctx aws.Context, input *DeleteVpcEndpointServiceConfigurationsInput, opts ...request.Option) (*DeleteVpcEndpointServiceConfigurationsOutput, error) { + req, out := c.DeleteVpcEndpointServiceConfigurationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeleteVpcEndpoints = "DeleteVpcEndpoints" // DeleteVpcEndpointsRequest generates a "aws/request.Request" representing the @@ -6811,7 +7759,7 @@ const opDeleteVpcEndpoints = "DeleteVpcEndpoints" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpoints +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpoints func (c *EC2) DeleteVpcEndpointsRequest(input *DeleteVpcEndpointsInput) (req *request.Request, output *DeleteVpcEndpointsOutput) { op := &request.Operation{ Name: opDeleteVpcEndpoints, @@ -6830,8 +7778,10 @@ func (c *EC2) DeleteVpcEndpointsRequest(input *DeleteVpcEndpointsInput) (req *re // DeleteVpcEndpoints API operation for Amazon Elastic Compute Cloud. // -// Deletes one or more specified VPC endpoints. Deleting the endpoint also deletes -// the endpoint routes in the route tables that were associated with the endpoint. +// Deletes one or more specified VPC endpoints. Deleting a gateway endpoint +// also deletes the endpoint routes in the route tables that were associated +// with the endpoint. Deleting an interface endpoint deletes the endpoint network +// interfaces. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -6839,7 +7789,7 @@ func (c *EC2) DeleteVpcEndpointsRequest(input *DeleteVpcEndpointsInput) (req *re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVpcEndpoints for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpoints +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpoints func (c *EC2) DeleteVpcEndpoints(input *DeleteVpcEndpointsInput) (*DeleteVpcEndpointsOutput, error) { req, out := c.DeleteVpcEndpointsRequest(input) return out, req.Send() @@ -6886,7 +7836,7 @@ const opDeleteVpcPeeringConnection = "DeleteVpcPeeringConnection" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnection func (c *EC2) DeleteVpcPeeringConnectionRequest(input *DeleteVpcPeeringConnectionInput) (req *request.Request, output *DeleteVpcPeeringConnectionOutput) { op := &request.Operation{ Name: opDeleteVpcPeeringConnection, @@ -6906,8 +7856,8 @@ func (c *EC2) DeleteVpcPeeringConnectionRequest(input *DeleteVpcPeeringConnectio // DeleteVpcPeeringConnection API operation for Amazon Elastic Compute Cloud. // // Deletes a VPC peering connection. Either the owner of the requester VPC or -// the owner of the peer VPC can delete the VPC peering connection if it's in -// the active state. The owner of the requester VPC can delete a VPC peering +// the owner of the accepter VPC can delete the VPC peering connection if it's +// in the active state. The owner of the requester VPC can delete a VPC peering // connection in the pending-acceptance state. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -6916,7 +7866,7 @@ func (c *EC2) DeleteVpcPeeringConnectionRequest(input *DeleteVpcPeeringConnectio // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVpcPeeringConnection for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnection func (c *EC2) DeleteVpcPeeringConnection(input *DeleteVpcPeeringConnectionInput) (*DeleteVpcPeeringConnectionOutput, error) { req, out := c.DeleteVpcPeeringConnectionRequest(input) return out, req.Send() @@ -6963,7 +7913,7 @@ const opDeleteVpnConnection = "DeleteVpnConnection" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnection func (c *EC2) DeleteVpnConnectionRequest(input *DeleteVpnConnectionInput) (req *request.Request, output *DeleteVpnConnectionOutput) { op := &request.Operation{ Name: opDeleteVpnConnection, @@ -7001,7 +7951,7 @@ func (c *EC2) DeleteVpnConnectionRequest(input *DeleteVpnConnectionInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVpnConnection for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnection func (c *EC2) DeleteVpnConnection(input *DeleteVpnConnectionInput) (*DeleteVpnConnectionOutput, error) { req, out := c.DeleteVpnConnectionRequest(input) return out, req.Send() @@ -7048,7 +7998,7 @@ const opDeleteVpnConnectionRoute = "DeleteVpnConnectionRoute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRoute func (c *EC2) DeleteVpnConnectionRouteRequest(input *DeleteVpnConnectionRouteInput) (req *request.Request, output *DeleteVpnConnectionRouteOutput) { op := &request.Operation{ Name: opDeleteVpnConnectionRoute, @@ -7080,7 +8030,7 @@ func (c *EC2) DeleteVpnConnectionRouteRequest(input *DeleteVpnConnectionRouteInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVpnConnectionRoute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRoute func (c *EC2) DeleteVpnConnectionRoute(input *DeleteVpnConnectionRouteInput) (*DeleteVpnConnectionRouteOutput, error) { req, out := c.DeleteVpnConnectionRouteRequest(input) return out, req.Send() @@ -7127,7 +8077,7 @@ const opDeleteVpnGateway = "DeleteVpnGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGateway func (c *EC2) DeleteVpnGatewayRequest(input *DeleteVpnGatewayInput) (req *request.Request, output *DeleteVpnGatewayOutput) { op := &request.Operation{ Name: opDeleteVpnGateway, @@ -7160,7 +8110,7 @@ func (c *EC2) DeleteVpnGatewayRequest(input *DeleteVpnGatewayInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeleteVpnGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGateway func (c *EC2) DeleteVpnGateway(input *DeleteVpnGatewayInput) (*DeleteVpnGatewayOutput, error) { req, out := c.DeleteVpnGatewayRequest(input) return out, req.Send() @@ -7207,7 +8157,7 @@ const opDeregisterImage = "DeregisterImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImage func (c *EC2) DeregisterImageRequest(input *DeregisterImageInput) (req *request.Request, output *DeregisterImageOutput) { op := &request.Operation{ Name: opDeregisterImage, @@ -7229,9 +8179,14 @@ func (c *EC2) DeregisterImageRequest(input *DeregisterImageInput) (req *request. // DeregisterImage API operation for Amazon Elastic Compute Cloud. // // Deregisters the specified AMI. After you deregister an AMI, it can't be used -// to launch new instances. +// to launch new instances; however, it doesn't affect any instances that you've +// already launched from the AMI. You'll continue to incur usage costs for those +// instances until you terminate them. // -// This command does not delete the AMI. +// When you deregister an Amazon EBS-backed AMI, it doesn't affect the snapshot +// that was created for the root volume of the instance during the AMI creation +// process. When you deregister an instance store-backed AMI, it doesn't affect +// the files that you uploaded to Amazon S3 when you created the AMI. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -7239,7 +8194,7 @@ func (c *EC2) DeregisterImageRequest(input *DeregisterImageInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DeregisterImage for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImage func (c *EC2) DeregisterImage(input *DeregisterImageInput) (*DeregisterImageOutput, error) { req, out := c.DeregisterImageRequest(input) return out, req.Send() @@ -7286,7 +8241,7 @@ const opDescribeAccountAttributes = "DescribeAccountAttributes" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributes +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributes func (c *EC2) DescribeAccountAttributesRequest(input *DescribeAccountAttributesInput) (req *request.Request, output *DescribeAccountAttributesOutput) { op := &request.Operation{ Name: opDescribeAccountAttributes, @@ -7331,7 +8286,7 @@ func (c *EC2) DescribeAccountAttributesRequest(input *DescribeAccountAttributesI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeAccountAttributes for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributes +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributes func (c *EC2) DescribeAccountAttributes(input *DescribeAccountAttributesInput) (*DescribeAccountAttributesOutput, error) { req, out := c.DescribeAccountAttributesRequest(input) return out, req.Send() @@ -7378,7 +8333,7 @@ const opDescribeAddresses = "DescribeAddresses" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddresses func (c *EC2) DescribeAddressesRequest(input *DescribeAddressesInput) (req *request.Request, output *DescribeAddressesOutput) { op := &request.Operation{ Name: opDescribeAddresses, @@ -7409,7 +8364,7 @@ func (c *EC2) DescribeAddressesRequest(input *DescribeAddressesInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeAddresses for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddresses func (c *EC2) DescribeAddresses(input *DescribeAddressesInput) (*DescribeAddressesOutput, error) { req, out := c.DescribeAddressesRequest(input) return out, req.Send() @@ -7456,7 +8411,7 @@ const opDescribeAvailabilityZones = "DescribeAvailabilityZones" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZones +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZones func (c *EC2) DescribeAvailabilityZonesRequest(input *DescribeAvailabilityZonesInput) (req *request.Request, output *DescribeAvailabilityZonesOutput) { op := &request.Operation{ Name: opDescribeAvailabilityZones, @@ -7489,7 +8444,7 @@ func (c *EC2) DescribeAvailabilityZonesRequest(input *DescribeAvailabilityZonesI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeAvailabilityZones for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZones +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZones func (c *EC2) DescribeAvailabilityZones(input *DescribeAvailabilityZonesInput) (*DescribeAvailabilityZonesOutput, error) { req, out := c.DescribeAvailabilityZonesRequest(input) return out, req.Send() @@ -7536,7 +8491,7 @@ const opDescribeBundleTasks = "DescribeBundleTasks" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasks func (c *EC2) DescribeBundleTasksRequest(input *DescribeBundleTasksInput) (req *request.Request, output *DescribeBundleTasksOutput) { op := &request.Operation{ Name: opDescribeBundleTasks, @@ -7568,7 +8523,7 @@ func (c *EC2) DescribeBundleTasksRequest(input *DescribeBundleTasksInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeBundleTasks for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasks func (c *EC2) DescribeBundleTasks(input *DescribeBundleTasksInput) (*DescribeBundleTasksOutput, error) { req, out := c.DescribeBundleTasksRequest(input) return out, req.Send() @@ -7615,7 +8570,7 @@ const opDescribeClassicLinkInstances = "DescribeClassicLinkInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstances func (c *EC2) DescribeClassicLinkInstancesRequest(input *DescribeClassicLinkInstancesInput) (req *request.Request, output *DescribeClassicLinkInstancesOutput) { op := &request.Operation{ Name: opDescribeClassicLinkInstances, @@ -7645,7 +8600,7 @@ func (c *EC2) DescribeClassicLinkInstancesRequest(input *DescribeClassicLinkInst // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeClassicLinkInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstances func (c *EC2) DescribeClassicLinkInstances(input *DescribeClassicLinkInstancesInput) (*DescribeClassicLinkInstancesOutput, error) { req, out := c.DescribeClassicLinkInstancesRequest(input) return out, req.Send() @@ -7692,7 +8647,7 @@ const opDescribeConversionTasks = "DescribeConversionTasks" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasks func (c *EC2) DescribeConversionTasksRequest(input *DescribeConversionTasksInput) (req *request.Request, output *DescribeConversionTasksOutput) { op := &request.Operation{ Name: opDescribeConversionTasks, @@ -7723,7 +8678,7 @@ func (c *EC2) DescribeConversionTasksRequest(input *DescribeConversionTasksInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeConversionTasks for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasks func (c *EC2) DescribeConversionTasks(input *DescribeConversionTasksInput) (*DescribeConversionTasksOutput, error) { req, out := c.DescribeConversionTasksRequest(input) return out, req.Send() @@ -7770,7 +8725,7 @@ const opDescribeCustomerGateways = "DescribeCustomerGateways" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGateways func (c *EC2) DescribeCustomerGatewaysRequest(input *DescribeCustomerGatewaysInput) (req *request.Request, output *DescribeCustomerGatewaysOutput) { op := &request.Operation{ Name: opDescribeCustomerGateways, @@ -7791,9 +8746,9 @@ func (c *EC2) DescribeCustomerGatewaysRequest(input *DescribeCustomerGatewaysInp // // Describes one or more of your VPN customer gateways. // -// For more information about VPN customer gateways, see Adding a Hardware Virtual -// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. +// For more information about VPN customer gateways, see AWS Managed VPN Connections +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) in the +// Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -7801,7 +8756,7 @@ func (c *EC2) DescribeCustomerGatewaysRequest(input *DescribeCustomerGatewaysInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeCustomerGateways for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGateways func (c *EC2) DescribeCustomerGateways(input *DescribeCustomerGatewaysInput) (*DescribeCustomerGatewaysOutput, error) { req, out := c.DescribeCustomerGatewaysRequest(input) return out, req.Send() @@ -7848,7 +8803,7 @@ const opDescribeDhcpOptions = "DescribeDhcpOptions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptions func (c *EC2) DescribeDhcpOptionsRequest(input *DescribeDhcpOptionsInput) (req *request.Request, output *DescribeDhcpOptionsOutput) { op := &request.Operation{ Name: opDescribeDhcpOptions, @@ -7878,7 +8833,7 @@ func (c *EC2) DescribeDhcpOptionsRequest(input *DescribeDhcpOptionsInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeDhcpOptions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptions func (c *EC2) DescribeDhcpOptions(input *DescribeDhcpOptionsInput) (*DescribeDhcpOptionsOutput, error) { req, out := c.DescribeDhcpOptionsRequest(input) return out, req.Send() @@ -7925,7 +8880,7 @@ const opDescribeEgressOnlyInternetGateways = "DescribeEgressOnlyInternetGateways // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGateways func (c *EC2) DescribeEgressOnlyInternetGatewaysRequest(input *DescribeEgressOnlyInternetGatewaysInput) (req *request.Request, output *DescribeEgressOnlyInternetGatewaysOutput) { op := &request.Operation{ Name: opDescribeEgressOnlyInternetGateways, @@ -7952,7 +8907,7 @@ func (c *EC2) DescribeEgressOnlyInternetGatewaysRequest(input *DescribeEgressOnl // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeEgressOnlyInternetGateways for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGateways func (c *EC2) DescribeEgressOnlyInternetGateways(input *DescribeEgressOnlyInternetGatewaysInput) (*DescribeEgressOnlyInternetGatewaysOutput, error) { req, out := c.DescribeEgressOnlyInternetGatewaysRequest(input) return out, req.Send() @@ -7999,7 +8954,7 @@ const opDescribeElasticGpus = "DescribeElasticGpus" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpus func (c *EC2) DescribeElasticGpusRequest(input *DescribeElasticGpusInput) (req *request.Request, output *DescribeElasticGpusOutput) { op := &request.Operation{ Name: opDescribeElasticGpus, @@ -8019,7 +8974,7 @@ func (c *EC2) DescribeElasticGpusRequest(input *DescribeElasticGpusInput) (req * // DescribeElasticGpus API operation for Amazon Elastic Compute Cloud. // // Describes the Elastic GPUs associated with your instances. For more information -// about Elastic GPUs, see Amazon EC2 Elastic GPUs (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-gpus.html). +// about Elastic GPUs, see Amazon EC2 Elastic GPUs (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/elastic-gpus.html). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -8027,7 +8982,7 @@ func (c *EC2) DescribeElasticGpusRequest(input *DescribeElasticGpusInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeElasticGpus for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpus func (c *EC2) DescribeElasticGpus(input *DescribeElasticGpusInput) (*DescribeElasticGpusOutput, error) { req, out := c.DescribeElasticGpusRequest(input) return out, req.Send() @@ -8074,7 +9029,7 @@ const opDescribeExportTasks = "DescribeExportTasks" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasks func (c *EC2) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *request.Request, output *DescribeExportTasksOutput) { op := &request.Operation{ Name: opDescribeExportTasks, @@ -8101,7 +9056,7 @@ func (c *EC2) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeExportTasks for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasks func (c *EC2) DescribeExportTasks(input *DescribeExportTasksInput) (*DescribeExportTasksOutput, error) { req, out := c.DescribeExportTasksRequest(input) return out, req.Send() @@ -8148,7 +9103,7 @@ const opDescribeFlowLogs = "DescribeFlowLogs" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogs func (c *EC2) DescribeFlowLogsRequest(input *DescribeFlowLogsInput) (req *request.Request, output *DescribeFlowLogsOutput) { op := &request.Operation{ Name: opDescribeFlowLogs, @@ -8177,7 +9132,7 @@ func (c *EC2) DescribeFlowLogsRequest(input *DescribeFlowLogsInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeFlowLogs for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogs func (c *EC2) DescribeFlowLogs(input *DescribeFlowLogsInput) (*DescribeFlowLogsOutput, error) { req, out := c.DescribeFlowLogsRequest(input) return out, req.Send() @@ -8199,6 +9154,80 @@ func (c *EC2) DescribeFlowLogsWithContext(ctx aws.Context, input *DescribeFlowLo return out, req.Send() } +const opDescribeFpgaImageAttribute = "DescribeFpgaImageAttribute" + +// DescribeFpgaImageAttributeRequest generates a "aws/request.Request" representing the +// client's request for the DescribeFpgaImageAttribute operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeFpgaImageAttribute for more information on using the DescribeFpgaImageAttribute +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeFpgaImageAttributeRequest method. +// req, resp := client.DescribeFpgaImageAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImageAttribute +func (c *EC2) DescribeFpgaImageAttributeRequest(input *DescribeFpgaImageAttributeInput) (req *request.Request, output *DescribeFpgaImageAttributeOutput) { + op := &request.Operation{ + Name: opDescribeFpgaImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeFpgaImageAttributeInput{} + } + + output = &DescribeFpgaImageAttributeOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeFpgaImageAttribute API operation for Amazon Elastic Compute Cloud. +// +// Describes the specified attribute of the specified Amazon FPGA Image (AFI). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeFpgaImageAttribute for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImageAttribute +func (c *EC2) DescribeFpgaImageAttribute(input *DescribeFpgaImageAttributeInput) (*DescribeFpgaImageAttributeOutput, error) { + req, out := c.DescribeFpgaImageAttributeRequest(input) + return out, req.Send() +} + +// DescribeFpgaImageAttributeWithContext is the same as DescribeFpgaImageAttribute with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeFpgaImageAttribute for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeFpgaImageAttributeWithContext(ctx aws.Context, input *DescribeFpgaImageAttributeInput, opts ...request.Option) (*DescribeFpgaImageAttributeOutput, error) { + req, out := c.DescribeFpgaImageAttributeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeFpgaImages = "DescribeFpgaImages" // DescribeFpgaImagesRequest generates a "aws/request.Request" representing the @@ -8224,7 +9253,7 @@ const opDescribeFpgaImages = "DescribeFpgaImages" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImages func (c *EC2) DescribeFpgaImagesRequest(input *DescribeFpgaImagesInput) (req *request.Request, output *DescribeFpgaImagesOutput) { op := &request.Operation{ Name: opDescribeFpgaImages, @@ -8253,7 +9282,7 @@ func (c *EC2) DescribeFpgaImagesRequest(input *DescribeFpgaImagesInput) (req *re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeFpgaImages for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImages func (c *EC2) DescribeFpgaImages(input *DescribeFpgaImagesInput) (*DescribeFpgaImagesOutput, error) { req, out := c.DescribeFpgaImagesRequest(input) return out, req.Send() @@ -8300,7 +9329,7 @@ const opDescribeHostReservationOfferings = "DescribeHostReservationOfferings" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferings +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferings func (c *EC2) DescribeHostReservationOfferingsRequest(input *DescribeHostReservationOfferingsInput) (req *request.Request, output *DescribeHostReservationOfferingsOutput) { op := &request.Operation{ Name: opDescribeHostReservationOfferings, @@ -8335,7 +9364,7 @@ func (c *EC2) DescribeHostReservationOfferingsRequest(input *DescribeHostReserva // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeHostReservationOfferings for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferings +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferings func (c *EC2) DescribeHostReservationOfferings(input *DescribeHostReservationOfferingsInput) (*DescribeHostReservationOfferingsOutput, error) { req, out := c.DescribeHostReservationOfferingsRequest(input) return out, req.Send() @@ -8382,7 +9411,7 @@ const opDescribeHostReservations = "DescribeHostReservations" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservations +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservations func (c *EC2) DescribeHostReservationsRequest(input *DescribeHostReservationsInput) (req *request.Request, output *DescribeHostReservationsOutput) { op := &request.Operation{ Name: opDescribeHostReservations, @@ -8410,7 +9439,7 @@ func (c *EC2) DescribeHostReservationsRequest(input *DescribeHostReservationsInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeHostReservations for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservations +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservations func (c *EC2) DescribeHostReservations(input *DescribeHostReservationsInput) (*DescribeHostReservationsOutput, error) { req, out := c.DescribeHostReservationsRequest(input) return out, req.Send() @@ -8457,7 +9486,7 @@ const opDescribeHosts = "DescribeHosts" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHosts func (c *EC2) DescribeHostsRequest(input *DescribeHostsInput) (req *request.Request, output *DescribeHostsOutput) { op := &request.Operation{ Name: opDescribeHosts, @@ -8488,7 +9517,7 @@ func (c *EC2) DescribeHostsRequest(input *DescribeHostsInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeHosts for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHosts func (c *EC2) DescribeHosts(input *DescribeHostsInput) (*DescribeHostsOutput, error) { req, out := c.DescribeHostsRequest(input) return out, req.Send() @@ -8535,7 +9564,7 @@ const opDescribeIamInstanceProfileAssociations = "DescribeIamInstanceProfileAsso // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociations +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociations func (c *EC2) DescribeIamInstanceProfileAssociationsRequest(input *DescribeIamInstanceProfileAssociationsInput) (req *request.Request, output *DescribeIamInstanceProfileAssociationsOutput) { op := &request.Operation{ Name: opDescribeIamInstanceProfileAssociations, @@ -8562,7 +9591,7 @@ func (c *EC2) DescribeIamInstanceProfileAssociationsRequest(input *DescribeIamIn // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeIamInstanceProfileAssociations for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociations +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociations func (c *EC2) DescribeIamInstanceProfileAssociations(input *DescribeIamInstanceProfileAssociationsInput) (*DescribeIamInstanceProfileAssociationsOutput, error) { req, out := c.DescribeIamInstanceProfileAssociationsRequest(input) return out, req.Send() @@ -8609,7 +9638,7 @@ const opDescribeIdFormat = "DescribeIdFormat" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormat func (c *EC2) DescribeIdFormatRequest(input *DescribeIdFormatInput) (req *request.Request, output *DescribeIdFormatOutput) { op := &request.Operation{ Name: opDescribeIdFormat, @@ -8649,7 +9678,7 @@ func (c *EC2) DescribeIdFormatRequest(input *DescribeIdFormatInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeIdFormat for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormat func (c *EC2) DescribeIdFormat(input *DescribeIdFormatInput) (*DescribeIdFormatOutput, error) { req, out := c.DescribeIdFormatRequest(input) return out, req.Send() @@ -8696,7 +9725,7 @@ const opDescribeIdentityIdFormat = "DescribeIdentityIdFormat" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormat func (c *EC2) DescribeIdentityIdFormatRequest(input *DescribeIdentityIdFormatInput) (req *request.Request, output *DescribeIdentityIdFormatOutput) { op := &request.Operation{ Name: opDescribeIdentityIdFormat, @@ -8734,7 +9763,7 @@ func (c *EC2) DescribeIdentityIdFormatRequest(input *DescribeIdentityIdFormatInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeIdentityIdFormat for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormat func (c *EC2) DescribeIdentityIdFormat(input *DescribeIdentityIdFormatInput) (*DescribeIdentityIdFormatOutput, error) { req, out := c.DescribeIdentityIdFormatRequest(input) return out, req.Send() @@ -8781,7 +9810,7 @@ const opDescribeImageAttribute = "DescribeImageAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttribute func (c *EC2) DescribeImageAttributeRequest(input *DescribeImageAttributeInput) (req *request.Request, output *DescribeImageAttributeOutput) { op := &request.Operation{ Name: opDescribeImageAttribute, @@ -8809,7 +9838,7 @@ func (c *EC2) DescribeImageAttributeRequest(input *DescribeImageAttributeInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeImageAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttribute func (c *EC2) DescribeImageAttribute(input *DescribeImageAttributeInput) (*DescribeImageAttributeOutput, error) { req, out := c.DescribeImageAttributeRequest(input) return out, req.Send() @@ -8856,7 +9885,7 @@ const opDescribeImages = "DescribeImages" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImages func (c *EC2) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Request, output *DescribeImagesOutput) { op := &request.Operation{ Name: opDescribeImages, @@ -8889,7 +9918,7 @@ func (c *EC2) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeImages for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImages func (c *EC2) DescribeImages(input *DescribeImagesInput) (*DescribeImagesOutput, error) { req, out := c.DescribeImagesRequest(input) return out, req.Send() @@ -8936,7 +9965,7 @@ const opDescribeImportImageTasks = "DescribeImportImageTasks" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasks func (c *EC2) DescribeImportImageTasksRequest(input *DescribeImportImageTasksInput) (req *request.Request, output *DescribeImportImageTasksOutput) { op := &request.Operation{ Name: opDescribeImportImageTasks, @@ -8964,7 +9993,7 @@ func (c *EC2) DescribeImportImageTasksRequest(input *DescribeImportImageTasksInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeImportImageTasks for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasks func (c *EC2) DescribeImportImageTasks(input *DescribeImportImageTasksInput) (*DescribeImportImageTasksOutput, error) { req, out := c.DescribeImportImageTasksRequest(input) return out, req.Send() @@ -9011,7 +10040,7 @@ const opDescribeImportSnapshotTasks = "DescribeImportSnapshotTasks" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasks func (c *EC2) DescribeImportSnapshotTasksRequest(input *DescribeImportSnapshotTasksInput) (req *request.Request, output *DescribeImportSnapshotTasksOutput) { op := &request.Operation{ Name: opDescribeImportSnapshotTasks, @@ -9038,7 +10067,7 @@ func (c *EC2) DescribeImportSnapshotTasksRequest(input *DescribeImportSnapshotTa // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeImportSnapshotTasks for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasks +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasks func (c *EC2) DescribeImportSnapshotTasks(input *DescribeImportSnapshotTasksInput) (*DescribeImportSnapshotTasksOutput, error) { req, out := c.DescribeImportSnapshotTasksRequest(input) return out, req.Send() @@ -9085,7 +10114,7 @@ const opDescribeInstanceAttribute = "DescribeInstanceAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttribute func (c *EC2) DescribeInstanceAttributeRequest(input *DescribeInstanceAttributeInput) (req *request.Request, output *DescribeInstanceAttributeOutput) { op := &request.Operation{ Name: opDescribeInstanceAttribute, @@ -9116,7 +10145,7 @@ func (c *EC2) DescribeInstanceAttributeRequest(input *DescribeInstanceAttributeI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeInstanceAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttribute func (c *EC2) DescribeInstanceAttribute(input *DescribeInstanceAttributeInput) (*DescribeInstanceAttributeOutput, error) { req, out := c.DescribeInstanceAttributeRequest(input) return out, req.Send() @@ -9138,6 +10167,98 @@ func (c *EC2) DescribeInstanceAttributeWithContext(ctx aws.Context, input *Descr return out, req.Send() } +const opDescribeInstanceCreditSpecifications = "DescribeInstanceCreditSpecifications" + +// DescribeInstanceCreditSpecificationsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeInstanceCreditSpecifications operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeInstanceCreditSpecifications for more information on using the DescribeInstanceCreditSpecifications +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeInstanceCreditSpecificationsRequest method. +// req, resp := client.DescribeInstanceCreditSpecificationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceCreditSpecifications +func (c *EC2) DescribeInstanceCreditSpecificationsRequest(input *DescribeInstanceCreditSpecificationsInput) (req *request.Request, output *DescribeInstanceCreditSpecificationsOutput) { + op := &request.Operation{ + Name: opDescribeInstanceCreditSpecifications, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeInstanceCreditSpecificationsInput{} + } + + output = &DescribeInstanceCreditSpecificationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeInstanceCreditSpecifications API operation for Amazon Elastic Compute Cloud. +// +// Describes the credit option for CPU usage of one or more of your T2 instances. +// The credit options are standard and unlimited. +// +// If you do not specify an instance ID, Amazon EC2 returns only the T2 instances +// with the unlimited credit option. If you specify one or more instance IDs, +// Amazon EC2 returns the credit option (standard or unlimited) of those instances. +// If you specify an instance ID that is not valid, such as an instance that +// is not a T2 instance, an error is returned. +// +// Recently terminated instances might appear in the returned results. This +// interval is usually less than one hour. +// +// If an Availability Zone is experiencing a service disruption and you specify +// instance IDs in the affected zone, or do not specify any instance IDs at +// all, the call fails. If you specify only instance IDs in an unaffected zone, +// the call works normally. +// +// For more information, see T2 Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-instances.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeInstanceCreditSpecifications for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceCreditSpecifications +func (c *EC2) DescribeInstanceCreditSpecifications(input *DescribeInstanceCreditSpecificationsInput) (*DescribeInstanceCreditSpecificationsOutput, error) { + req, out := c.DescribeInstanceCreditSpecificationsRequest(input) + return out, req.Send() +} + +// DescribeInstanceCreditSpecificationsWithContext is the same as DescribeInstanceCreditSpecifications with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeInstanceCreditSpecifications for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeInstanceCreditSpecificationsWithContext(ctx aws.Context, input *DescribeInstanceCreditSpecificationsInput, opts ...request.Option) (*DescribeInstanceCreditSpecificationsOutput, error) { + req, out := c.DescribeInstanceCreditSpecificationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeInstanceStatus = "DescribeInstanceStatus" // DescribeInstanceStatusRequest generates a "aws/request.Request" representing the @@ -9163,7 +10284,7 @@ const opDescribeInstanceStatus = "DescribeInstanceStatus" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatus func (c *EC2) DescribeInstanceStatusRequest(input *DescribeInstanceStatusInput) (req *request.Request, output *DescribeInstanceStatusOutput) { op := &request.Operation{ Name: opDescribeInstanceStatus, @@ -9217,7 +10338,7 @@ func (c *EC2) DescribeInstanceStatusRequest(input *DescribeInstanceStatusInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeInstanceStatus for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatus func (c *EC2) DescribeInstanceStatus(input *DescribeInstanceStatusInput) (*DescribeInstanceStatusOutput, error) { req, out := c.DescribeInstanceStatusRequest(input) return out, req.Send() @@ -9314,7 +10435,7 @@ const opDescribeInstances = "DescribeInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstances func (c *EC2) DescribeInstancesRequest(input *DescribeInstancesInput) (req *request.Request, output *DescribeInstancesOutput) { op := &request.Operation{ Name: opDescribeInstances, @@ -9362,7 +10483,7 @@ func (c *EC2) DescribeInstancesRequest(input *DescribeInstancesInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstances func (c *EC2) DescribeInstances(input *DescribeInstancesInput) (*DescribeInstancesOutput, error) { req, out := c.DescribeInstancesRequest(input) return out, req.Send() @@ -9459,7 +10580,7 @@ const opDescribeInternetGateways = "DescribeInternetGateways" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGateways func (c *EC2) DescribeInternetGatewaysRequest(input *DescribeInternetGatewaysInput) (req *request.Request, output *DescribeInternetGatewaysOutput) { op := &request.Operation{ Name: opDescribeInternetGateways, @@ -9486,7 +10607,7 @@ func (c *EC2) DescribeInternetGatewaysRequest(input *DescribeInternetGatewaysInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeInternetGateways for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGateways func (c *EC2) DescribeInternetGateways(input *DescribeInternetGatewaysInput) (*DescribeInternetGatewaysOutput, error) { req, out := c.DescribeInternetGatewaysRequest(input) return out, req.Send() @@ -9533,7 +10654,7 @@ const opDescribeKeyPairs = "DescribeKeyPairs" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairs func (c *EC2) DescribeKeyPairsRequest(input *DescribeKeyPairsInput) (req *request.Request, output *DescribeKeyPairsOutput) { op := &request.Operation{ Name: opDescribeKeyPairs, @@ -9563,7 +10684,7 @@ func (c *EC2) DescribeKeyPairsRequest(input *DescribeKeyPairsInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeKeyPairs for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairs func (c *EC2) DescribeKeyPairs(input *DescribeKeyPairsInput) (*DescribeKeyPairsOutput, error) { req, out := c.DescribeKeyPairsRequest(input) return out, req.Send() @@ -9585,6 +10706,155 @@ func (c *EC2) DescribeKeyPairsWithContext(ctx aws.Context, input *DescribeKeyPai return out, req.Send() } +const opDescribeLaunchTemplateVersions = "DescribeLaunchTemplateVersions" + +// DescribeLaunchTemplateVersionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeLaunchTemplateVersions operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeLaunchTemplateVersions for more information on using the DescribeLaunchTemplateVersions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeLaunchTemplateVersionsRequest method. +// req, resp := client.DescribeLaunchTemplateVersionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplateVersions +func (c *EC2) DescribeLaunchTemplateVersionsRequest(input *DescribeLaunchTemplateVersionsInput) (req *request.Request, output *DescribeLaunchTemplateVersionsOutput) { + op := &request.Operation{ + Name: opDescribeLaunchTemplateVersions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeLaunchTemplateVersionsInput{} + } + + output = &DescribeLaunchTemplateVersionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeLaunchTemplateVersions API operation for Amazon Elastic Compute Cloud. +// +// Describes one or more versions of a specified launch template. You can describe +// all versions, individual versions, or a range of versions. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeLaunchTemplateVersions for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplateVersions +func (c *EC2) DescribeLaunchTemplateVersions(input *DescribeLaunchTemplateVersionsInput) (*DescribeLaunchTemplateVersionsOutput, error) { + req, out := c.DescribeLaunchTemplateVersionsRequest(input) + return out, req.Send() +} + +// DescribeLaunchTemplateVersionsWithContext is the same as DescribeLaunchTemplateVersions with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeLaunchTemplateVersions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeLaunchTemplateVersionsWithContext(ctx aws.Context, input *DescribeLaunchTemplateVersionsInput, opts ...request.Option) (*DescribeLaunchTemplateVersionsOutput, error) { + req, out := c.DescribeLaunchTemplateVersionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeLaunchTemplates = "DescribeLaunchTemplates" + +// DescribeLaunchTemplatesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeLaunchTemplates operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeLaunchTemplates for more information on using the DescribeLaunchTemplates +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeLaunchTemplatesRequest method. +// req, resp := client.DescribeLaunchTemplatesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplates +func (c *EC2) DescribeLaunchTemplatesRequest(input *DescribeLaunchTemplatesInput) (req *request.Request, output *DescribeLaunchTemplatesOutput) { + op := &request.Operation{ + Name: opDescribeLaunchTemplates, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeLaunchTemplatesInput{} + } + + output = &DescribeLaunchTemplatesOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeLaunchTemplates API operation for Amazon Elastic Compute Cloud. +// +// Describes one or more launch templates. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeLaunchTemplates for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplates +func (c *EC2) DescribeLaunchTemplates(input *DescribeLaunchTemplatesInput) (*DescribeLaunchTemplatesOutput, error) { + req, out := c.DescribeLaunchTemplatesRequest(input) + return out, req.Send() +} + +// DescribeLaunchTemplatesWithContext is the same as DescribeLaunchTemplates with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeLaunchTemplates for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeLaunchTemplatesWithContext(ctx aws.Context, input *DescribeLaunchTemplatesInput, opts ...request.Option) (*DescribeLaunchTemplatesOutput, error) { + req, out := c.DescribeLaunchTemplatesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeMovingAddresses = "DescribeMovingAddresses" // DescribeMovingAddressesRequest generates a "aws/request.Request" representing the @@ -9610,7 +10880,7 @@ const opDescribeMovingAddresses = "DescribeMovingAddresses" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddresses func (c *EC2) DescribeMovingAddressesRequest(input *DescribeMovingAddressesInput) (req *request.Request, output *DescribeMovingAddressesOutput) { op := &request.Operation{ Name: opDescribeMovingAddresses, @@ -9639,7 +10909,7 @@ func (c *EC2) DescribeMovingAddressesRequest(input *DescribeMovingAddressesInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeMovingAddresses for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddresses func (c *EC2) DescribeMovingAddresses(input *DescribeMovingAddressesInput) (*DescribeMovingAddressesOutput, error) { req, out := c.DescribeMovingAddressesRequest(input) return out, req.Send() @@ -9686,7 +10956,7 @@ const opDescribeNatGateways = "DescribeNatGateways" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGateways func (c *EC2) DescribeNatGatewaysRequest(input *DescribeNatGatewaysInput) (req *request.Request, output *DescribeNatGatewaysOutput) { op := &request.Operation{ Name: opDescribeNatGateways, @@ -9719,7 +10989,7 @@ func (c *EC2) DescribeNatGatewaysRequest(input *DescribeNatGatewaysInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeNatGateways for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGateways func (c *EC2) DescribeNatGateways(input *DescribeNatGatewaysInput) (*DescribeNatGatewaysOutput, error) { req, out := c.DescribeNatGatewaysRequest(input) return out, req.Send() @@ -9816,7 +11086,7 @@ const opDescribeNetworkAcls = "DescribeNetworkAcls" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAcls +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAcls func (c *EC2) DescribeNetworkAclsRequest(input *DescribeNetworkAclsInput) (req *request.Request, output *DescribeNetworkAclsOutput) { op := &request.Operation{ Name: opDescribeNetworkAcls, @@ -9846,7 +11116,7 @@ func (c *EC2) DescribeNetworkAclsRequest(input *DescribeNetworkAclsInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeNetworkAcls for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAcls +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAcls func (c *EC2) DescribeNetworkAcls(input *DescribeNetworkAclsInput) (*DescribeNetworkAclsOutput, error) { req, out := c.DescribeNetworkAclsRequest(input) return out, req.Send() @@ -9893,7 +11163,7 @@ const opDescribeNetworkInterfaceAttribute = "DescribeNetworkInterfaceAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttribute func (c *EC2) DescribeNetworkInterfaceAttributeRequest(input *DescribeNetworkInterfaceAttributeInput) (req *request.Request, output *DescribeNetworkInterfaceAttributeOutput) { op := &request.Operation{ Name: opDescribeNetworkInterfaceAttribute, @@ -9921,7 +11191,7 @@ func (c *EC2) DescribeNetworkInterfaceAttributeRequest(input *DescribeNetworkInt // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeNetworkInterfaceAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttribute func (c *EC2) DescribeNetworkInterfaceAttribute(input *DescribeNetworkInterfaceAttributeInput) (*DescribeNetworkInterfaceAttributeOutput, error) { req, out := c.DescribeNetworkInterfaceAttributeRequest(input) return out, req.Send() @@ -9968,7 +11238,7 @@ const opDescribeNetworkInterfacePermissions = "DescribeNetworkInterfacePermissio // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissions func (c *EC2) DescribeNetworkInterfacePermissionsRequest(input *DescribeNetworkInterfacePermissionsInput) (req *request.Request, output *DescribeNetworkInterfacePermissionsOutput) { op := &request.Operation{ Name: opDescribeNetworkInterfacePermissions, @@ -9995,7 +11265,7 @@ func (c *EC2) DescribeNetworkInterfacePermissionsRequest(input *DescribeNetworkI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeNetworkInterfacePermissions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissions func (c *EC2) DescribeNetworkInterfacePermissions(input *DescribeNetworkInterfacePermissionsInput) (*DescribeNetworkInterfacePermissionsOutput, error) { req, out := c.DescribeNetworkInterfacePermissionsRequest(input) return out, req.Send() @@ -10042,7 +11312,7 @@ const opDescribeNetworkInterfaces = "DescribeNetworkInterfaces" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaces +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaces func (c *EC2) DescribeNetworkInterfacesRequest(input *DescribeNetworkInterfacesInput) (req *request.Request, output *DescribeNetworkInterfacesOutput) { op := &request.Operation{ Name: opDescribeNetworkInterfaces, @@ -10069,7 +11339,7 @@ func (c *EC2) DescribeNetworkInterfacesRequest(input *DescribeNetworkInterfacesI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeNetworkInterfaces for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaces +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaces func (c *EC2) DescribeNetworkInterfaces(input *DescribeNetworkInterfacesInput) (*DescribeNetworkInterfacesOutput, error) { req, out := c.DescribeNetworkInterfacesRequest(input) return out, req.Send() @@ -10116,7 +11386,7 @@ const opDescribePlacementGroups = "DescribePlacementGroups" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroups +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroups func (c *EC2) DescribePlacementGroupsRequest(input *DescribePlacementGroupsInput) (req *request.Request, output *DescribePlacementGroupsOutput) { op := &request.Operation{ Name: opDescribePlacementGroups, @@ -10135,8 +11405,8 @@ func (c *EC2) DescribePlacementGroupsRequest(input *DescribePlacementGroupsInput // DescribePlacementGroups API operation for Amazon Elastic Compute Cloud. // -// Describes one or more of your placement groups. For more information about -// placement groups and cluster instances, see Cluster Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cluster_computing.html) +// Describes one or more of your placement groups. For more information, see +// Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -10145,7 +11415,7 @@ func (c *EC2) DescribePlacementGroupsRequest(input *DescribePlacementGroupsInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribePlacementGroups for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroups +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroups func (c *EC2) DescribePlacementGroups(input *DescribePlacementGroupsInput) (*DescribePlacementGroupsOutput, error) { req, out := c.DescribePlacementGroupsRequest(input) return out, req.Send() @@ -10192,7 +11462,7 @@ const opDescribePrefixLists = "DescribePrefixLists" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixLists +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixLists func (c *EC2) DescribePrefixListsRequest(input *DescribePrefixListsInput) (req *request.Request, output *DescribePrefixListsOutput) { op := &request.Operation{ Name: opDescribePrefixLists, @@ -10215,7 +11485,7 @@ func (c *EC2) DescribePrefixListsRequest(input *DescribePrefixListsInput) (req * // the prefix list name and prefix list ID of the service and the IP address // range for the service. A prefix list ID is required for creating an outbound // security group rule that allows traffic from a VPC to access an AWS service -// through a VPC endpoint. +// through a gateway VPC endpoint. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -10223,7 +11493,7 @@ func (c *EC2) DescribePrefixListsRequest(input *DescribePrefixListsInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribePrefixLists for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixLists +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixLists func (c *EC2) DescribePrefixLists(input *DescribePrefixListsInput) (*DescribePrefixListsOutput, error) { req, out := c.DescribePrefixListsRequest(input) return out, req.Send() @@ -10270,7 +11540,7 @@ const opDescribeRegions = "DescribeRegions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegions func (c *EC2) DescribeRegionsRequest(input *DescribeRegionsInput) (req *request.Request, output *DescribeRegionsOutput) { op := &request.Operation{ Name: opDescribeRegions, @@ -10300,7 +11570,7 @@ func (c *EC2) DescribeRegionsRequest(input *DescribeRegionsInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeRegions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegions func (c *EC2) DescribeRegions(input *DescribeRegionsInput) (*DescribeRegionsOutput, error) { req, out := c.DescribeRegionsRequest(input) return out, req.Send() @@ -10347,7 +11617,7 @@ const opDescribeReservedInstances = "DescribeReservedInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstances func (c *EC2) DescribeReservedInstancesRequest(input *DescribeReservedInstancesInput) (req *request.Request, output *DescribeReservedInstancesOutput) { op := &request.Operation{ Name: opDescribeReservedInstances, @@ -10377,7 +11647,7 @@ func (c *EC2) DescribeReservedInstancesRequest(input *DescribeReservedInstancesI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeReservedInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstances func (c *EC2) DescribeReservedInstances(input *DescribeReservedInstancesInput) (*DescribeReservedInstancesOutput, error) { req, out := c.DescribeReservedInstancesRequest(input) return out, req.Send() @@ -10424,7 +11694,7 @@ const opDescribeReservedInstancesListings = "DescribeReservedInstancesListings" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListings +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListings func (c *EC2) DescribeReservedInstancesListingsRequest(input *DescribeReservedInstancesListingsInput) (req *request.Request, output *DescribeReservedInstancesListingsOutput) { op := &request.Operation{ Name: opDescribeReservedInstancesListings, @@ -10472,7 +11742,7 @@ func (c *EC2) DescribeReservedInstancesListingsRequest(input *DescribeReservedIn // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeReservedInstancesListings for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListings +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListings func (c *EC2) DescribeReservedInstancesListings(input *DescribeReservedInstancesListingsInput) (*DescribeReservedInstancesListingsOutput, error) { req, out := c.DescribeReservedInstancesListingsRequest(input) return out, req.Send() @@ -10519,7 +11789,7 @@ const opDescribeReservedInstancesModifications = "DescribeReservedInstancesModif // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModifications +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModifications func (c *EC2) DescribeReservedInstancesModificationsRequest(input *DescribeReservedInstancesModificationsInput) (req *request.Request, output *DescribeReservedInstancesModificationsOutput) { op := &request.Operation{ Name: opDescribeReservedInstancesModifications, @@ -10558,7 +11828,7 @@ func (c *EC2) DescribeReservedInstancesModificationsRequest(input *DescribeReser // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeReservedInstancesModifications for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModifications +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModifications func (c *EC2) DescribeReservedInstancesModifications(input *DescribeReservedInstancesModificationsInput) (*DescribeReservedInstancesModificationsOutput, error) { req, out := c.DescribeReservedInstancesModificationsRequest(input) return out, req.Send() @@ -10655,7 +11925,7 @@ const opDescribeReservedInstancesOfferings = "DescribeReservedInstancesOfferings // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferings +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferings func (c *EC2) DescribeReservedInstancesOfferingsRequest(input *DescribeReservedInstancesOfferingsInput) (req *request.Request, output *DescribeReservedInstancesOfferingsOutput) { op := &request.Operation{ Name: opDescribeReservedInstancesOfferings, @@ -10699,7 +11969,7 @@ func (c *EC2) DescribeReservedInstancesOfferingsRequest(input *DescribeReservedI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeReservedInstancesOfferings for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferings +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferings func (c *EC2) DescribeReservedInstancesOfferings(input *DescribeReservedInstancesOfferingsInput) (*DescribeReservedInstancesOfferingsOutput, error) { req, out := c.DescribeReservedInstancesOfferingsRequest(input) return out, req.Send() @@ -10796,7 +12066,7 @@ const opDescribeRouteTables = "DescribeRouteTables" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTables +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTables func (c *EC2) DescribeRouteTablesRequest(input *DescribeRouteTablesInput) (req *request.Request, output *DescribeRouteTablesOutput) { op := &request.Operation{ Name: opDescribeRouteTables, @@ -10831,7 +12101,7 @@ func (c *EC2) DescribeRouteTablesRequest(input *DescribeRouteTablesInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeRouteTables for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTables +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTables func (c *EC2) DescribeRouteTables(input *DescribeRouteTablesInput) (*DescribeRouteTablesOutput, error) { req, out := c.DescribeRouteTablesRequest(input) return out, req.Send() @@ -10878,7 +12148,7 @@ const opDescribeScheduledInstanceAvailability = "DescribeScheduledInstanceAvaila // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailability +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailability func (c *EC2) DescribeScheduledInstanceAvailabilityRequest(input *DescribeScheduledInstanceAvailabilityInput) (req *request.Request, output *DescribeScheduledInstanceAvailabilityOutput) { op := &request.Operation{ Name: opDescribeScheduledInstanceAvailability, @@ -10913,7 +12183,7 @@ func (c *EC2) DescribeScheduledInstanceAvailabilityRequest(input *DescribeSchedu // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeScheduledInstanceAvailability for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailability +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailability func (c *EC2) DescribeScheduledInstanceAvailability(input *DescribeScheduledInstanceAvailabilityInput) (*DescribeScheduledInstanceAvailabilityOutput, error) { req, out := c.DescribeScheduledInstanceAvailabilityRequest(input) return out, req.Send() @@ -10960,7 +12230,7 @@ const opDescribeScheduledInstances = "DescribeScheduledInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstances func (c *EC2) DescribeScheduledInstancesRequest(input *DescribeScheduledInstancesInput) (req *request.Request, output *DescribeScheduledInstancesOutput) { op := &request.Operation{ Name: opDescribeScheduledInstances, @@ -10987,7 +12257,7 @@ func (c *EC2) DescribeScheduledInstancesRequest(input *DescribeScheduledInstance // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeScheduledInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstances func (c *EC2) DescribeScheduledInstances(input *DescribeScheduledInstancesInput) (*DescribeScheduledInstancesOutput, error) { req, out := c.DescribeScheduledInstancesRequest(input) return out, req.Send() @@ -11034,7 +12304,7 @@ const opDescribeSecurityGroupReferences = "DescribeSecurityGroupReferences" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferences +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferences func (c *EC2) DescribeSecurityGroupReferencesRequest(input *DescribeSecurityGroupReferencesInput) (req *request.Request, output *DescribeSecurityGroupReferencesOutput) { op := &request.Operation{ Name: opDescribeSecurityGroupReferences, @@ -11062,7 +12332,7 @@ func (c *EC2) DescribeSecurityGroupReferencesRequest(input *DescribeSecurityGrou // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSecurityGroupReferences for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferences +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferences func (c *EC2) DescribeSecurityGroupReferences(input *DescribeSecurityGroupReferencesInput) (*DescribeSecurityGroupReferencesOutput, error) { req, out := c.DescribeSecurityGroupReferencesRequest(input) return out, req.Send() @@ -11109,7 +12379,7 @@ const opDescribeSecurityGroups = "DescribeSecurityGroups" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroups +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroups func (c *EC2) DescribeSecurityGroupsRequest(input *DescribeSecurityGroupsInput) (req *request.Request, output *DescribeSecurityGroupsOutput) { op := &request.Operation{ Name: opDescribeSecurityGroups, @@ -11143,7 +12413,7 @@ func (c *EC2) DescribeSecurityGroupsRequest(input *DescribeSecurityGroupsInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSecurityGroups for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroups +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroups func (c *EC2) DescribeSecurityGroups(input *DescribeSecurityGroupsInput) (*DescribeSecurityGroupsOutput, error) { req, out := c.DescribeSecurityGroupsRequest(input) return out, req.Send() @@ -11190,7 +12460,7 @@ const opDescribeSnapshotAttribute = "DescribeSnapshotAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttribute func (c *EC2) DescribeSnapshotAttributeRequest(input *DescribeSnapshotAttributeInput) (req *request.Request, output *DescribeSnapshotAttributeOutput) { op := &request.Operation{ Name: opDescribeSnapshotAttribute, @@ -11221,7 +12491,7 @@ func (c *EC2) DescribeSnapshotAttributeRequest(input *DescribeSnapshotAttributeI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSnapshotAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttribute func (c *EC2) DescribeSnapshotAttribute(input *DescribeSnapshotAttributeInput) (*DescribeSnapshotAttributeOutput, error) { req, out := c.DescribeSnapshotAttributeRequest(input) return out, req.Send() @@ -11268,7 +12538,7 @@ const opDescribeSnapshots = "DescribeSnapshots" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshots +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshots func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *request.Request, output *DescribeSnapshotsOutput) { op := &request.Operation{ Name: opDescribeSnapshots, @@ -11346,7 +12616,7 @@ func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSnapshots for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshots +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshots func (c *EC2) DescribeSnapshots(input *DescribeSnapshotsInput) (*DescribeSnapshotsOutput, error) { req, out := c.DescribeSnapshotsRequest(input) return out, req.Send() @@ -11443,7 +12713,7 @@ const opDescribeSpotDatafeedSubscription = "DescribeSpotDatafeedSubscription" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscription func (c *EC2) DescribeSpotDatafeedSubscriptionRequest(input *DescribeSpotDatafeedSubscriptionInput) (req *request.Request, output *DescribeSpotDatafeedSubscriptionOutput) { op := &request.Operation{ Name: opDescribeSpotDatafeedSubscription, @@ -11462,7 +12732,7 @@ func (c *EC2) DescribeSpotDatafeedSubscriptionRequest(input *DescribeSpotDatafee // DescribeSpotDatafeedSubscription API operation for Amazon Elastic Compute Cloud. // -// Describes the data feed for Spot instances. For more information, see Spot +// Describes the data feed for Spot Instances. For more information, see Spot // Instance Data Feed (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html) // in the Amazon Elastic Compute Cloud User Guide. // @@ -11472,7 +12742,7 @@ func (c *EC2) DescribeSpotDatafeedSubscriptionRequest(input *DescribeSpotDatafee // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSpotDatafeedSubscription for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscription func (c *EC2) DescribeSpotDatafeedSubscription(input *DescribeSpotDatafeedSubscriptionInput) (*DescribeSpotDatafeedSubscriptionOutput, error) { req, out := c.DescribeSpotDatafeedSubscriptionRequest(input) return out, req.Send() @@ -11519,7 +12789,7 @@ const opDescribeSpotFleetInstances = "DescribeSpotFleetInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstances func (c *EC2) DescribeSpotFleetInstancesRequest(input *DescribeSpotFleetInstancesInput) (req *request.Request, output *DescribeSpotFleetInstancesOutput) { op := &request.Operation{ Name: opDescribeSpotFleetInstances, @@ -11538,7 +12808,7 @@ func (c *EC2) DescribeSpotFleetInstancesRequest(input *DescribeSpotFleetInstance // DescribeSpotFleetInstances API operation for Amazon Elastic Compute Cloud. // -// Describes the running instances for the specified Spot fleet. +// Describes the running instances for the specified Spot Fleet. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -11546,7 +12816,7 @@ func (c *EC2) DescribeSpotFleetInstancesRequest(input *DescribeSpotFleetInstance // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSpotFleetInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstances func (c *EC2) DescribeSpotFleetInstances(input *DescribeSpotFleetInstancesInput) (*DescribeSpotFleetInstancesOutput, error) { req, out := c.DescribeSpotFleetInstancesRequest(input) return out, req.Send() @@ -11593,7 +12863,7 @@ const opDescribeSpotFleetRequestHistory = "DescribeSpotFleetRequestHistory" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistory +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistory func (c *EC2) DescribeSpotFleetRequestHistoryRequest(input *DescribeSpotFleetRequestHistoryInput) (req *request.Request, output *DescribeSpotFleetRequestHistoryOutput) { op := &request.Operation{ Name: opDescribeSpotFleetRequestHistory, @@ -11612,10 +12882,10 @@ func (c *EC2) DescribeSpotFleetRequestHistoryRequest(input *DescribeSpotFleetReq // DescribeSpotFleetRequestHistory API operation for Amazon Elastic Compute Cloud. // -// Describes the events for the specified Spot fleet request during the specified +// Describes the events for the specified Spot Fleet request during the specified // time. // -// Spot fleet events are delayed by up to 30 seconds before they can be described. +// Spot Fleet events are delayed by up to 30 seconds before they can be described. // This ensures that you can query by the last evaluated time and not miss a // recorded event. // @@ -11625,7 +12895,7 @@ func (c *EC2) DescribeSpotFleetRequestHistoryRequest(input *DescribeSpotFleetReq // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSpotFleetRequestHistory for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistory +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistory func (c *EC2) DescribeSpotFleetRequestHistory(input *DescribeSpotFleetRequestHistoryInput) (*DescribeSpotFleetRequestHistoryOutput, error) { req, out := c.DescribeSpotFleetRequestHistoryRequest(input) return out, req.Send() @@ -11672,7 +12942,7 @@ const opDescribeSpotFleetRequests = "DescribeSpotFleetRequests" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequests func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsInput) (req *request.Request, output *DescribeSpotFleetRequestsOutput) { op := &request.Operation{ Name: opDescribeSpotFleetRequests, @@ -11697,9 +12967,9 @@ func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsI // DescribeSpotFleetRequests API operation for Amazon Elastic Compute Cloud. // -// Describes your Spot fleet requests. +// Describes your Spot Fleet requests. // -// Spot fleet requests are deleted 48 hours after they are canceled and their +// Spot Fleet requests are deleted 48 hours after they are canceled and their // instances are terminated. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -11708,7 +12978,7 @@ func (c *EC2) DescribeSpotFleetRequestsRequest(input *DescribeSpotFleetRequestsI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSpotFleetRequests for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequests func (c *EC2) DescribeSpotFleetRequests(input *DescribeSpotFleetRequestsInput) (*DescribeSpotFleetRequestsOutput, error) { req, out := c.DescribeSpotFleetRequestsRequest(input) return out, req.Send() @@ -11805,7 +13075,7 @@ const opDescribeSpotInstanceRequests = "DescribeSpotInstanceRequests" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequests func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceRequestsInput) (req *request.Request, output *DescribeSpotInstanceRequestsOutput) { op := &request.Operation{ Name: opDescribeSpotInstanceRequests, @@ -11824,20 +13094,19 @@ func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceReq // DescribeSpotInstanceRequests API operation for Amazon Elastic Compute Cloud. // -// Describes the Spot instance requests that belong to your account. Spot instances -// are instances that Amazon EC2 launches when the bid price that you specify -// exceeds the current Spot price. Amazon EC2 periodically sets the Spot price -// based on available Spot instance capacity and current Spot instance requests. -// For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) -// in the Amazon Elastic Compute Cloud User Guide. +// Describes the Spot Instance requests that belong to your account. Spot Instances +// are instances that Amazon EC2 launches when the Spot price that you specify +// exceeds the current Spot price. For more information, see Spot Instance Requests +// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) in +// the Amazon Elastic Compute Cloud User Guide. // -// You can use DescribeSpotInstanceRequests to find a running Spot instance -// by examining the response. If the status of the Spot instance is fulfilled, +// You can use DescribeSpotInstanceRequests to find a running Spot Instance +// by examining the response. If the status of the Spot Instance is fulfilled, // the instance ID appears in the response and contains the identifier of the // instance. Alternatively, you can use DescribeInstances with a filter to look // for instances where the instance lifecycle is spot. // -// Spot instance requests are deleted 4 hours after they are canceled and their +// Spot Instance requests are deleted 4 hours after they are canceled and their // instances are terminated. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -11846,7 +13115,7 @@ func (c *EC2) DescribeSpotInstanceRequestsRequest(input *DescribeSpotInstanceReq // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSpotInstanceRequests for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequests +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequests func (c *EC2) DescribeSpotInstanceRequests(input *DescribeSpotInstanceRequestsInput) (*DescribeSpotInstanceRequestsOutput, error) { req, out := c.DescribeSpotInstanceRequestsRequest(input) return out, req.Send() @@ -11893,7 +13162,7 @@ const opDescribeSpotPriceHistory = "DescribeSpotPriceHistory" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistory +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistory func (c *EC2) DescribeSpotPriceHistoryRequest(input *DescribeSpotPriceHistoryInput) (req *request.Request, output *DescribeSpotPriceHistoryOutput) { op := &request.Operation{ Name: opDescribeSpotPriceHistory, @@ -11933,7 +13202,7 @@ func (c *EC2) DescribeSpotPriceHistoryRequest(input *DescribeSpotPriceHistoryInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSpotPriceHistory for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistory +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistory func (c *EC2) DescribeSpotPriceHistory(input *DescribeSpotPriceHistoryInput) (*DescribeSpotPriceHistoryOutput, error) { req, out := c.DescribeSpotPriceHistoryRequest(input) return out, req.Send() @@ -12030,7 +13299,7 @@ const opDescribeStaleSecurityGroups = "DescribeStaleSecurityGroups" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroups +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroups func (c *EC2) DescribeStaleSecurityGroupsRequest(input *DescribeStaleSecurityGroupsInput) (req *request.Request, output *DescribeStaleSecurityGroupsOutput) { op := &request.Operation{ Name: opDescribeStaleSecurityGroups, @@ -12060,7 +13329,7 @@ func (c *EC2) DescribeStaleSecurityGroupsRequest(input *DescribeStaleSecurityGro // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeStaleSecurityGroups for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroups +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroups func (c *EC2) DescribeStaleSecurityGroups(input *DescribeStaleSecurityGroupsInput) (*DescribeStaleSecurityGroupsOutput, error) { req, out := c.DescribeStaleSecurityGroupsRequest(input) return out, req.Send() @@ -12107,7 +13376,7 @@ const opDescribeSubnets = "DescribeSubnets" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnets +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnets func (c *EC2) DescribeSubnetsRequest(input *DescribeSubnetsInput) (req *request.Request, output *DescribeSubnetsOutput) { op := &request.Operation{ Name: opDescribeSubnets, @@ -12137,7 +13406,7 @@ func (c *EC2) DescribeSubnetsRequest(input *DescribeSubnetsInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeSubnets for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnets +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnets func (c *EC2) DescribeSubnets(input *DescribeSubnetsInput) (*DescribeSubnetsOutput, error) { req, out := c.DescribeSubnetsRequest(input) return out, req.Send() @@ -12184,7 +13453,7 @@ const opDescribeTags = "DescribeTags" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTags +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTags func (c *EC2) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) { op := &request.Operation{ Name: opDescribeTags, @@ -12220,7 +13489,7 @@ func (c *EC2) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeTags for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTags +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTags func (c *EC2) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error) { req, out := c.DescribeTagsRequest(input) return out, req.Send() @@ -12317,7 +13586,7 @@ const opDescribeVolumeAttribute = "DescribeVolumeAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttribute func (c *EC2) DescribeVolumeAttributeRequest(input *DescribeVolumeAttributeInput) (req *request.Request, output *DescribeVolumeAttributeOutput) { op := &request.Operation{ Name: opDescribeVolumeAttribute, @@ -12348,7 +13617,7 @@ func (c *EC2) DescribeVolumeAttributeRequest(input *DescribeVolumeAttributeInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVolumeAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttribute func (c *EC2) DescribeVolumeAttribute(input *DescribeVolumeAttributeInput) (*DescribeVolumeAttributeOutput, error) { req, out := c.DescribeVolumeAttributeRequest(input) return out, req.Send() @@ -12395,7 +13664,7 @@ const opDescribeVolumeStatus = "DescribeVolumeStatus" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatus func (c *EC2) DescribeVolumeStatusRequest(input *DescribeVolumeStatusInput) (req *request.Request, output *DescribeVolumeStatusOutput) { op := &request.Operation{ Name: opDescribeVolumeStatus, @@ -12462,7 +13731,7 @@ func (c *EC2) DescribeVolumeStatusRequest(input *DescribeVolumeStatusInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVolumeStatus for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatus func (c *EC2) DescribeVolumeStatus(input *DescribeVolumeStatusInput) (*DescribeVolumeStatusOutput, error) { req, out := c.DescribeVolumeStatusRequest(input) return out, req.Send() @@ -12559,7 +13828,7 @@ const opDescribeVolumes = "DescribeVolumes" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumes +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumes func (c *EC2) DescribeVolumesRequest(input *DescribeVolumesInput) (req *request.Request, output *DescribeVolumesOutput) { op := &request.Operation{ Name: opDescribeVolumes, @@ -12602,7 +13871,7 @@ func (c *EC2) DescribeVolumesRequest(input *DescribeVolumesInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVolumes for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumes +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumes func (c *EC2) DescribeVolumes(input *DescribeVolumesInput) (*DescribeVolumesOutput, error) { req, out := c.DescribeVolumesRequest(input) return out, req.Send() @@ -12699,7 +13968,7 @@ const opDescribeVolumesModifications = "DescribeVolumesModifications" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModifications +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModifications func (c *EC2) DescribeVolumesModificationsRequest(input *DescribeVolumesModificationsInput) (req *request.Request, output *DescribeVolumesModificationsOutput) { op := &request.Operation{ Name: opDescribeVolumesModifications, @@ -12738,7 +14007,7 @@ func (c *EC2) DescribeVolumesModificationsRequest(input *DescribeVolumesModifica // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVolumesModifications for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModifications +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModifications func (c *EC2) DescribeVolumesModifications(input *DescribeVolumesModificationsInput) (*DescribeVolumesModificationsOutput, error) { req, out := c.DescribeVolumesModificationsRequest(input) return out, req.Send() @@ -12785,7 +14054,7 @@ const opDescribeVpcAttribute = "DescribeVpcAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttribute func (c *EC2) DescribeVpcAttributeRequest(input *DescribeVpcAttributeInput) (req *request.Request, output *DescribeVpcAttributeOutput) { op := &request.Operation{ Name: opDescribeVpcAttribute, @@ -12813,7 +14082,7 @@ func (c *EC2) DescribeVpcAttributeRequest(input *DescribeVpcAttributeInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttribute func (c *EC2) DescribeVpcAttribute(input *DescribeVpcAttributeInput) (*DescribeVpcAttributeOutput, error) { req, out := c.DescribeVpcAttributeRequest(input) return out, req.Send() @@ -12860,7 +14129,7 @@ const opDescribeVpcClassicLink = "DescribeVpcClassicLink" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLink func (c *EC2) DescribeVpcClassicLinkRequest(input *DescribeVpcClassicLinkInput) (req *request.Request, output *DescribeVpcClassicLinkOutput) { op := &request.Operation{ Name: opDescribeVpcClassicLink, @@ -12887,7 +14156,7 @@ func (c *EC2) DescribeVpcClassicLinkRequest(input *DescribeVpcClassicLinkInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcClassicLink for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLink func (c *EC2) DescribeVpcClassicLink(input *DescribeVpcClassicLinkInput) (*DescribeVpcClassicLinkOutput, error) { req, out := c.DescribeVpcClassicLinkRequest(input) return out, req.Send() @@ -12934,7 +14203,7 @@ const opDescribeVpcClassicLinkDnsSupport = "DescribeVpcClassicLinkDnsSupport" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupport func (c *EC2) DescribeVpcClassicLinkDnsSupportRequest(input *DescribeVpcClassicLinkDnsSupportInput) (req *request.Request, output *DescribeVpcClassicLinkDnsSupportOutput) { op := &request.Operation{ Name: opDescribeVpcClassicLinkDnsSupport, @@ -12967,7 +14236,7 @@ func (c *EC2) DescribeVpcClassicLinkDnsSupportRequest(input *DescribeVpcClassicL // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcClassicLinkDnsSupport for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupport func (c *EC2) DescribeVpcClassicLinkDnsSupport(input *DescribeVpcClassicLinkDnsSupportInput) (*DescribeVpcClassicLinkDnsSupportOutput, error) { req, out := c.DescribeVpcClassicLinkDnsSupportRequest(input) return out, req.Send() @@ -12989,6 +14258,305 @@ func (c *EC2) DescribeVpcClassicLinkDnsSupportWithContext(ctx aws.Context, input return out, req.Send() } +const opDescribeVpcEndpointConnectionNotifications = "DescribeVpcEndpointConnectionNotifications" + +// DescribeVpcEndpointConnectionNotificationsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcEndpointConnectionNotifications operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeVpcEndpointConnectionNotifications for more information on using the DescribeVpcEndpointConnectionNotifications +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeVpcEndpointConnectionNotificationsRequest method. +// req, resp := client.DescribeVpcEndpointConnectionNotificationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionNotifications +func (c *EC2) DescribeVpcEndpointConnectionNotificationsRequest(input *DescribeVpcEndpointConnectionNotificationsInput) (req *request.Request, output *DescribeVpcEndpointConnectionNotificationsOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpointConnectionNotifications, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcEndpointConnectionNotificationsInput{} + } + + output = &DescribeVpcEndpointConnectionNotificationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeVpcEndpointConnectionNotifications API operation for Amazon Elastic Compute Cloud. +// +// Describes the connection notifications for VPC endpoints and VPC endpoint +// services. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeVpcEndpointConnectionNotifications for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionNotifications +func (c *EC2) DescribeVpcEndpointConnectionNotifications(input *DescribeVpcEndpointConnectionNotificationsInput) (*DescribeVpcEndpointConnectionNotificationsOutput, error) { + req, out := c.DescribeVpcEndpointConnectionNotificationsRequest(input) + return out, req.Send() +} + +// DescribeVpcEndpointConnectionNotificationsWithContext is the same as DescribeVpcEndpointConnectionNotifications with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeVpcEndpointConnectionNotifications for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeVpcEndpointConnectionNotificationsWithContext(ctx aws.Context, input *DescribeVpcEndpointConnectionNotificationsInput, opts ...request.Option) (*DescribeVpcEndpointConnectionNotificationsOutput, error) { + req, out := c.DescribeVpcEndpointConnectionNotificationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeVpcEndpointConnections = "DescribeVpcEndpointConnections" + +// DescribeVpcEndpointConnectionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcEndpointConnections operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeVpcEndpointConnections for more information on using the DescribeVpcEndpointConnections +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeVpcEndpointConnectionsRequest method. +// req, resp := client.DescribeVpcEndpointConnectionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnections +func (c *EC2) DescribeVpcEndpointConnectionsRequest(input *DescribeVpcEndpointConnectionsInput) (req *request.Request, output *DescribeVpcEndpointConnectionsOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpointConnections, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcEndpointConnectionsInput{} + } + + output = &DescribeVpcEndpointConnectionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeVpcEndpointConnections API operation for Amazon Elastic Compute Cloud. +// +// Describes the VPC endpoint connections to your VPC endpoint services, including +// any endpoints that are pending your acceptance. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeVpcEndpointConnections for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnections +func (c *EC2) DescribeVpcEndpointConnections(input *DescribeVpcEndpointConnectionsInput) (*DescribeVpcEndpointConnectionsOutput, error) { + req, out := c.DescribeVpcEndpointConnectionsRequest(input) + return out, req.Send() +} + +// DescribeVpcEndpointConnectionsWithContext is the same as DescribeVpcEndpointConnections with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeVpcEndpointConnections for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeVpcEndpointConnectionsWithContext(ctx aws.Context, input *DescribeVpcEndpointConnectionsInput, opts ...request.Option) (*DescribeVpcEndpointConnectionsOutput, error) { + req, out := c.DescribeVpcEndpointConnectionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeVpcEndpointServiceConfigurations = "DescribeVpcEndpointServiceConfigurations" + +// DescribeVpcEndpointServiceConfigurationsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcEndpointServiceConfigurations operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeVpcEndpointServiceConfigurations for more information on using the DescribeVpcEndpointServiceConfigurations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeVpcEndpointServiceConfigurationsRequest method. +// req, resp := client.DescribeVpcEndpointServiceConfigurationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServiceConfigurations +func (c *EC2) DescribeVpcEndpointServiceConfigurationsRequest(input *DescribeVpcEndpointServiceConfigurationsInput) (req *request.Request, output *DescribeVpcEndpointServiceConfigurationsOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpointServiceConfigurations, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcEndpointServiceConfigurationsInput{} + } + + output = &DescribeVpcEndpointServiceConfigurationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeVpcEndpointServiceConfigurations API operation for Amazon Elastic Compute Cloud. +// +// Describes the VPC endpoint service configurations in your account (your services). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeVpcEndpointServiceConfigurations for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServiceConfigurations +func (c *EC2) DescribeVpcEndpointServiceConfigurations(input *DescribeVpcEndpointServiceConfigurationsInput) (*DescribeVpcEndpointServiceConfigurationsOutput, error) { + req, out := c.DescribeVpcEndpointServiceConfigurationsRequest(input) + return out, req.Send() +} + +// DescribeVpcEndpointServiceConfigurationsWithContext is the same as DescribeVpcEndpointServiceConfigurations with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeVpcEndpointServiceConfigurations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeVpcEndpointServiceConfigurationsWithContext(ctx aws.Context, input *DescribeVpcEndpointServiceConfigurationsInput, opts ...request.Option) (*DescribeVpcEndpointServiceConfigurationsOutput, error) { + req, out := c.DescribeVpcEndpointServiceConfigurationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeVpcEndpointServicePermissions = "DescribeVpcEndpointServicePermissions" + +// DescribeVpcEndpointServicePermissionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeVpcEndpointServicePermissions operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeVpcEndpointServicePermissions for more information on using the DescribeVpcEndpointServicePermissions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeVpcEndpointServicePermissionsRequest method. +// req, resp := client.DescribeVpcEndpointServicePermissionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicePermissions +func (c *EC2) DescribeVpcEndpointServicePermissionsRequest(input *DescribeVpcEndpointServicePermissionsInput) (req *request.Request, output *DescribeVpcEndpointServicePermissionsOutput) { + op := &request.Operation{ + Name: opDescribeVpcEndpointServicePermissions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeVpcEndpointServicePermissionsInput{} + } + + output = &DescribeVpcEndpointServicePermissionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeVpcEndpointServicePermissions API operation for Amazon Elastic Compute Cloud. +// +// Describes the principals (service consumers) that are permitted to discover +// your VPC endpoint service. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation DescribeVpcEndpointServicePermissions for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicePermissions +func (c *EC2) DescribeVpcEndpointServicePermissions(input *DescribeVpcEndpointServicePermissionsInput) (*DescribeVpcEndpointServicePermissionsOutput, error) { + req, out := c.DescribeVpcEndpointServicePermissionsRequest(input) + return out, req.Send() +} + +// DescribeVpcEndpointServicePermissionsWithContext is the same as DescribeVpcEndpointServicePermissions with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeVpcEndpointServicePermissions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) DescribeVpcEndpointServicePermissionsWithContext(ctx aws.Context, input *DescribeVpcEndpointServicePermissionsInput, opts ...request.Option) (*DescribeVpcEndpointServicePermissionsOutput, error) { + req, out := c.DescribeVpcEndpointServicePermissionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeVpcEndpointServices = "DescribeVpcEndpointServices" // DescribeVpcEndpointServicesRequest generates a "aws/request.Request" representing the @@ -13014,7 +14582,7 @@ const opDescribeVpcEndpointServices = "DescribeVpcEndpointServices" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServices +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServices func (c *EC2) DescribeVpcEndpointServicesRequest(input *DescribeVpcEndpointServicesInput) (req *request.Request, output *DescribeVpcEndpointServicesOutput) { op := &request.Operation{ Name: opDescribeVpcEndpointServices, @@ -13033,8 +14601,7 @@ func (c *EC2) DescribeVpcEndpointServicesRequest(input *DescribeVpcEndpointServi // DescribeVpcEndpointServices API operation for Amazon Elastic Compute Cloud. // -// Describes all supported AWS services that can be specified when creating -// a VPC endpoint. +// Describes available services to which you can create a VPC endpoint. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -13042,7 +14609,7 @@ func (c *EC2) DescribeVpcEndpointServicesRequest(input *DescribeVpcEndpointServi // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcEndpointServices for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServices +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServices func (c *EC2) DescribeVpcEndpointServices(input *DescribeVpcEndpointServicesInput) (*DescribeVpcEndpointServicesOutput, error) { req, out := c.DescribeVpcEndpointServicesRequest(input) return out, req.Send() @@ -13089,7 +14656,7 @@ const opDescribeVpcEndpoints = "DescribeVpcEndpoints" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpoints +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpoints func (c *EC2) DescribeVpcEndpointsRequest(input *DescribeVpcEndpointsInput) (req *request.Request, output *DescribeVpcEndpointsOutput) { op := &request.Operation{ Name: opDescribeVpcEndpoints, @@ -13116,7 +14683,7 @@ func (c *EC2) DescribeVpcEndpointsRequest(input *DescribeVpcEndpointsInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcEndpoints for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpoints +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpoints func (c *EC2) DescribeVpcEndpoints(input *DescribeVpcEndpointsInput) (*DescribeVpcEndpointsOutput, error) { req, out := c.DescribeVpcEndpointsRequest(input) return out, req.Send() @@ -13163,7 +14730,7 @@ const opDescribeVpcPeeringConnections = "DescribeVpcPeeringConnections" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnections +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnections func (c *EC2) DescribeVpcPeeringConnectionsRequest(input *DescribeVpcPeeringConnectionsInput) (req *request.Request, output *DescribeVpcPeeringConnectionsOutput) { op := &request.Operation{ Name: opDescribeVpcPeeringConnections, @@ -13190,7 +14757,7 @@ func (c *EC2) DescribeVpcPeeringConnectionsRequest(input *DescribeVpcPeeringConn // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcPeeringConnections for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnections +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnections func (c *EC2) DescribeVpcPeeringConnections(input *DescribeVpcPeeringConnectionsInput) (*DescribeVpcPeeringConnectionsOutput, error) { req, out := c.DescribeVpcPeeringConnectionsRequest(input) return out, req.Send() @@ -13237,7 +14804,7 @@ const opDescribeVpcs = "DescribeVpcs" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcs func (c *EC2) DescribeVpcsRequest(input *DescribeVpcsInput) (req *request.Request, output *DescribeVpcsOutput) { op := &request.Operation{ Name: opDescribeVpcs, @@ -13264,7 +14831,7 @@ func (c *EC2) DescribeVpcsRequest(input *DescribeVpcsInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpcs for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcs func (c *EC2) DescribeVpcs(input *DescribeVpcsInput) (*DescribeVpcsOutput, error) { req, out := c.DescribeVpcsRequest(input) return out, req.Send() @@ -13311,7 +14878,7 @@ const opDescribeVpnConnections = "DescribeVpnConnections" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnections +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnections func (c *EC2) DescribeVpnConnectionsRequest(input *DescribeVpnConnectionsInput) (req *request.Request, output *DescribeVpnConnectionsOutput) { op := &request.Operation{ Name: opDescribeVpnConnections, @@ -13332,9 +14899,9 @@ func (c *EC2) DescribeVpnConnectionsRequest(input *DescribeVpnConnectionsInput) // // Describes one or more of your VPN connections. // -// For more information about VPN connections, see Adding a Hardware Virtual -// Private Gateway to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) -// in the Amazon Virtual Private Cloud User Guide. +// For more information about VPN connections, see AWS Managed VPN Connections +// (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) in the +// Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -13342,7 +14909,7 @@ func (c *EC2) DescribeVpnConnectionsRequest(input *DescribeVpnConnectionsInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpnConnections for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnections +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnections func (c *EC2) DescribeVpnConnections(input *DescribeVpnConnectionsInput) (*DescribeVpnConnectionsOutput, error) { req, out := c.DescribeVpnConnectionsRequest(input) return out, req.Send() @@ -13389,7 +14956,7 @@ const opDescribeVpnGateways = "DescribeVpnGateways" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGateways func (c *EC2) DescribeVpnGatewaysRequest(input *DescribeVpnGatewaysInput) (req *request.Request, output *DescribeVpnGatewaysOutput) { op := &request.Operation{ Name: opDescribeVpnGateways, @@ -13410,8 +14977,8 @@ func (c *EC2) DescribeVpnGatewaysRequest(input *DescribeVpnGatewaysInput) (req * // // Describes one or more of your virtual private gateways. // -// For more information about virtual private gateways, see Adding an IPsec -// Hardware VPN to Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) +// For more information about virtual private gateways, see AWS Managed VPN +// Connections (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html) // in the Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -13420,7 +14987,7 @@ func (c *EC2) DescribeVpnGatewaysRequest(input *DescribeVpnGatewaysInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DescribeVpnGateways for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGateways +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGateways func (c *EC2) DescribeVpnGateways(input *DescribeVpnGatewaysInput) (*DescribeVpnGatewaysOutput, error) { req, out := c.DescribeVpnGatewaysRequest(input) return out, req.Send() @@ -13467,7 +15034,7 @@ const opDetachClassicLinkVpc = "DetachClassicLinkVpc" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpc func (c *EC2) DetachClassicLinkVpcRequest(input *DetachClassicLinkVpcInput) (req *request.Request, output *DetachClassicLinkVpcOutput) { op := &request.Operation{ Name: opDetachClassicLinkVpc, @@ -13496,7 +15063,7 @@ func (c *EC2) DetachClassicLinkVpcRequest(input *DetachClassicLinkVpcInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DetachClassicLinkVpc for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpc func (c *EC2) DetachClassicLinkVpc(input *DetachClassicLinkVpcInput) (*DetachClassicLinkVpcOutput, error) { req, out := c.DetachClassicLinkVpcRequest(input) return out, req.Send() @@ -13543,7 +15110,7 @@ const opDetachInternetGateway = "DetachInternetGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGateway func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (req *request.Request, output *DetachInternetGatewayOutput) { op := &request.Operation{ Name: opDetachInternetGateway, @@ -13574,7 +15141,7 @@ func (c *EC2) DetachInternetGatewayRequest(input *DetachInternetGatewayInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DetachInternetGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGateway func (c *EC2) DetachInternetGateway(input *DetachInternetGatewayInput) (*DetachInternetGatewayOutput, error) { req, out := c.DetachInternetGatewayRequest(input) return out, req.Send() @@ -13621,7 +15188,7 @@ const opDetachNetworkInterface = "DetachNetworkInterface" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterface func (c *EC2) DetachNetworkInterfaceRequest(input *DetachNetworkInterfaceInput) (req *request.Request, output *DetachNetworkInterfaceOutput) { op := &request.Operation{ Name: opDetachNetworkInterface, @@ -13650,7 +15217,7 @@ func (c *EC2) DetachNetworkInterfaceRequest(input *DetachNetworkInterfaceInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DetachNetworkInterface for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterface func (c *EC2) DetachNetworkInterface(input *DetachNetworkInterfaceInput) (*DetachNetworkInterfaceOutput, error) { req, out := c.DetachNetworkInterfaceRequest(input) return out, req.Send() @@ -13697,7 +15264,7 @@ const opDetachVolume = "DetachVolume" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolume func (c *EC2) DetachVolumeRequest(input *DetachVolumeInput) (req *request.Request, output *VolumeAttachment) { op := &request.Operation{ Name: opDetachVolume, @@ -13737,7 +15304,7 @@ func (c *EC2) DetachVolumeRequest(input *DetachVolumeInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DetachVolume for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolume func (c *EC2) DetachVolume(input *DetachVolumeInput) (*VolumeAttachment, error) { req, out := c.DetachVolumeRequest(input) return out, req.Send() @@ -13784,7 +15351,7 @@ const opDetachVpnGateway = "DetachVpnGateway" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGateway func (c *EC2) DetachVpnGatewayRequest(input *DetachVpnGatewayInput) (req *request.Request, output *DetachVpnGatewayOutput) { op := &request.Operation{ Name: opDetachVpnGateway, @@ -13820,7 +15387,7 @@ func (c *EC2) DetachVpnGatewayRequest(input *DetachVpnGatewayInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DetachVpnGateway for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGateway func (c *EC2) DetachVpnGateway(input *DetachVpnGatewayInput) (*DetachVpnGatewayOutput, error) { req, out := c.DetachVpnGatewayRequest(input) return out, req.Send() @@ -13867,7 +15434,7 @@ const opDisableVgwRoutePropagation = "DisableVgwRoutePropagation" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagation func (c *EC2) DisableVgwRoutePropagationRequest(input *DisableVgwRoutePropagationInput) (req *request.Request, output *DisableVgwRoutePropagationOutput) { op := &request.Operation{ Name: opDisableVgwRoutePropagation, @@ -13897,7 +15464,7 @@ func (c *EC2) DisableVgwRoutePropagationRequest(input *DisableVgwRoutePropagatio // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisableVgwRoutePropagation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagation func (c *EC2) DisableVgwRoutePropagation(input *DisableVgwRoutePropagationInput) (*DisableVgwRoutePropagationOutput, error) { req, out := c.DisableVgwRoutePropagationRequest(input) return out, req.Send() @@ -13944,7 +15511,7 @@ const opDisableVpcClassicLink = "DisableVpcClassicLink" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLink func (c *EC2) DisableVpcClassicLinkRequest(input *DisableVpcClassicLinkInput) (req *request.Request, output *DisableVpcClassicLinkOutput) { op := &request.Operation{ Name: opDisableVpcClassicLink, @@ -13972,7 +15539,7 @@ func (c *EC2) DisableVpcClassicLinkRequest(input *DisableVpcClassicLinkInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisableVpcClassicLink for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLink func (c *EC2) DisableVpcClassicLink(input *DisableVpcClassicLinkInput) (*DisableVpcClassicLinkOutput, error) { req, out := c.DisableVpcClassicLinkRequest(input) return out, req.Send() @@ -14019,7 +15586,7 @@ const opDisableVpcClassicLinkDnsSupport = "DisableVpcClassicLinkDnsSupport" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupport func (c *EC2) DisableVpcClassicLinkDnsSupportRequest(input *DisableVpcClassicLinkDnsSupportInput) (req *request.Request, output *DisableVpcClassicLinkDnsSupportOutput) { op := &request.Operation{ Name: opDisableVpcClassicLinkDnsSupport, @@ -14050,7 +15617,7 @@ func (c *EC2) DisableVpcClassicLinkDnsSupportRequest(input *DisableVpcClassicLin // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisableVpcClassicLinkDnsSupport for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupport func (c *EC2) DisableVpcClassicLinkDnsSupport(input *DisableVpcClassicLinkDnsSupportInput) (*DisableVpcClassicLinkDnsSupportOutput, error) { req, out := c.DisableVpcClassicLinkDnsSupportRequest(input) return out, req.Send() @@ -14097,7 +15664,7 @@ const opDisassociateAddress = "DisassociateAddress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddress func (c *EC2) DisassociateAddressRequest(input *DisassociateAddressInput) (req *request.Request, output *DisassociateAddressOutput) { op := &request.Operation{ Name: opDisassociateAddress, @@ -14134,7 +15701,7 @@ func (c *EC2) DisassociateAddressRequest(input *DisassociateAddressInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisassociateAddress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddress func (c *EC2) DisassociateAddress(input *DisassociateAddressInput) (*DisassociateAddressOutput, error) { req, out := c.DisassociateAddressRequest(input) return out, req.Send() @@ -14181,7 +15748,7 @@ const opDisassociateIamInstanceProfile = "DisassociateIamInstanceProfile" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfile +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfile func (c *EC2) DisassociateIamInstanceProfileRequest(input *DisassociateIamInstanceProfileInput) (req *request.Request, output *DisassociateIamInstanceProfileOutput) { op := &request.Operation{ Name: opDisassociateIamInstanceProfile, @@ -14210,7 +15777,7 @@ func (c *EC2) DisassociateIamInstanceProfileRequest(input *DisassociateIamInstan // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisassociateIamInstanceProfile for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfile +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfile func (c *EC2) DisassociateIamInstanceProfile(input *DisassociateIamInstanceProfileInput) (*DisassociateIamInstanceProfileOutput, error) { req, out := c.DisassociateIamInstanceProfileRequest(input) return out, req.Send() @@ -14257,7 +15824,7 @@ const opDisassociateRouteTable = "DisassociateRouteTable" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTable func (c *EC2) DisassociateRouteTableRequest(input *DisassociateRouteTableInput) (req *request.Request, output *DisassociateRouteTableOutput) { op := &request.Operation{ Name: opDisassociateRouteTable, @@ -14291,7 +15858,7 @@ func (c *EC2) DisassociateRouteTableRequest(input *DisassociateRouteTableInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisassociateRouteTable for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTable func (c *EC2) DisassociateRouteTable(input *DisassociateRouteTableInput) (*DisassociateRouteTableOutput, error) { req, out := c.DisassociateRouteTableRequest(input) return out, req.Send() @@ -14338,7 +15905,7 @@ const opDisassociateSubnetCidrBlock = "DisassociateSubnetCidrBlock" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlock func (c *EC2) DisassociateSubnetCidrBlockRequest(input *DisassociateSubnetCidrBlockInput) (req *request.Request, output *DisassociateSubnetCidrBlockOutput) { op := &request.Operation{ Name: opDisassociateSubnetCidrBlock, @@ -14367,7 +15934,7 @@ func (c *EC2) DisassociateSubnetCidrBlockRequest(input *DisassociateSubnetCidrBl // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisassociateSubnetCidrBlock for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlock func (c *EC2) DisassociateSubnetCidrBlock(input *DisassociateSubnetCidrBlockInput) (*DisassociateSubnetCidrBlockOutput, error) { req, out := c.DisassociateSubnetCidrBlockRequest(input) return out, req.Send() @@ -14414,7 +15981,7 @@ const opDisassociateVpcCidrBlock = "DisassociateVpcCidrBlock" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlock func (c *EC2) DisassociateVpcCidrBlockRequest(input *DisassociateVpcCidrBlockInput) (req *request.Request, output *DisassociateVpcCidrBlockOutput) { op := &request.Operation{ Name: opDisassociateVpcCidrBlock, @@ -14433,9 +16000,13 @@ func (c *EC2) DisassociateVpcCidrBlockRequest(input *DisassociateVpcCidrBlockInp // DisassociateVpcCidrBlock API operation for Amazon Elastic Compute Cloud. // -// Disassociates a CIDR block from a VPC. Currently, you can disassociate an -// IPv6 CIDR block only. You must detach or delete all gateways and resources -// that are associated with the CIDR block before you can disassociate it. +// Disassociates a CIDR block from a VPC. To disassociate the CIDR block, you +// must specify its association ID. You can get the association ID by using +// DescribeVpcs. You must detach or delete all gateways and resources that are +// associated with the CIDR block before you can disassociate it. +// +// You cannot disassociate the CIDR block with which you originally created +// the VPC (the primary CIDR block). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -14443,7 +16014,7 @@ func (c *EC2) DisassociateVpcCidrBlockRequest(input *DisassociateVpcCidrBlockInp // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation DisassociateVpcCidrBlock for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlock func (c *EC2) DisassociateVpcCidrBlock(input *DisassociateVpcCidrBlockInput) (*DisassociateVpcCidrBlockOutput, error) { req, out := c.DisassociateVpcCidrBlockRequest(input) return out, req.Send() @@ -14490,7 +16061,7 @@ const opEnableVgwRoutePropagation = "EnableVgwRoutePropagation" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagation func (c *EC2) EnableVgwRoutePropagationRequest(input *EnableVgwRoutePropagationInput) (req *request.Request, output *EnableVgwRoutePropagationOutput) { op := &request.Operation{ Name: opEnableVgwRoutePropagation, @@ -14520,7 +16091,7 @@ func (c *EC2) EnableVgwRoutePropagationRequest(input *EnableVgwRoutePropagationI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation EnableVgwRoutePropagation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagation func (c *EC2) EnableVgwRoutePropagation(input *EnableVgwRoutePropagationInput) (*EnableVgwRoutePropagationOutput, error) { req, out := c.EnableVgwRoutePropagationRequest(input) return out, req.Send() @@ -14567,7 +16138,7 @@ const opEnableVolumeIO = "EnableVolumeIO" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIO +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIO func (c *EC2) EnableVolumeIORequest(input *EnableVolumeIOInput) (req *request.Request, output *EnableVolumeIOOutput) { op := &request.Operation{ Name: opEnableVolumeIO, @@ -14597,7 +16168,7 @@ func (c *EC2) EnableVolumeIORequest(input *EnableVolumeIOInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation EnableVolumeIO for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIO +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIO func (c *EC2) EnableVolumeIO(input *EnableVolumeIOInput) (*EnableVolumeIOOutput, error) { req, out := c.EnableVolumeIORequest(input) return out, req.Send() @@ -14644,7 +16215,7 @@ const opEnableVpcClassicLink = "EnableVpcClassicLink" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLink func (c *EC2) EnableVpcClassicLinkRequest(input *EnableVpcClassicLinkInput) (req *request.Request, output *EnableVpcClassicLinkOutput) { op := &request.Operation{ Name: opEnableVpcClassicLink, @@ -14677,7 +16248,7 @@ func (c *EC2) EnableVpcClassicLinkRequest(input *EnableVpcClassicLinkInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation EnableVpcClassicLink for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLink func (c *EC2) EnableVpcClassicLink(input *EnableVpcClassicLinkInput) (*EnableVpcClassicLinkOutput, error) { req, out := c.EnableVpcClassicLinkRequest(input) return out, req.Send() @@ -14724,7 +16295,7 @@ const opEnableVpcClassicLinkDnsSupport = "EnableVpcClassicLinkDnsSupport" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupport func (c *EC2) EnableVpcClassicLinkDnsSupportRequest(input *EnableVpcClassicLinkDnsSupportInput) (req *request.Request, output *EnableVpcClassicLinkDnsSupportOutput) { op := &request.Operation{ Name: opEnableVpcClassicLinkDnsSupport, @@ -14757,7 +16328,7 @@ func (c *EC2) EnableVpcClassicLinkDnsSupportRequest(input *EnableVpcClassicLinkD // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation EnableVpcClassicLinkDnsSupport for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupport func (c *EC2) EnableVpcClassicLinkDnsSupport(input *EnableVpcClassicLinkDnsSupportInput) (*EnableVpcClassicLinkDnsSupportOutput, error) { req, out := c.EnableVpcClassicLinkDnsSupportRequest(input) return out, req.Send() @@ -14804,7 +16375,7 @@ const opGetConsoleOutput = "GetConsoleOutput" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutput func (c *EC2) GetConsoleOutputRequest(input *GetConsoleOutputInput) (req *request.Request, output *GetConsoleOutputOutput) { op := &request.Operation{ Name: opGetConsoleOutput, @@ -14831,7 +16402,7 @@ func (c *EC2) GetConsoleOutputRequest(input *GetConsoleOutputInput) (req *reques // the Amazon EC2 API and command line interface. // // Instance console output is buffered and posted shortly after instance boot, -// reboot, and termination. Amazon EC2 preserves the most recent 64 KB output +// reboot, and termination. Amazon EC2 preserves the most recent 64 KB output, // which is available for at least one hour after the most recent post. // // For Linux instances, the instance console output displays the exact console @@ -14848,7 +16419,7 @@ func (c *EC2) GetConsoleOutputRequest(input *GetConsoleOutputInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation GetConsoleOutput for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutput func (c *EC2) GetConsoleOutput(input *GetConsoleOutputInput) (*GetConsoleOutputOutput, error) { req, out := c.GetConsoleOutputRequest(input) return out, req.Send() @@ -14895,7 +16466,7 @@ const opGetConsoleScreenshot = "GetConsoleScreenshot" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshot func (c *EC2) GetConsoleScreenshotRequest(input *GetConsoleScreenshotInput) (req *request.Request, output *GetConsoleScreenshotOutput) { op := &request.Operation{ Name: opGetConsoleScreenshot, @@ -14924,7 +16495,7 @@ func (c *EC2) GetConsoleScreenshotRequest(input *GetConsoleScreenshotInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation GetConsoleScreenshot for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshot func (c *EC2) GetConsoleScreenshot(input *GetConsoleScreenshotInput) (*GetConsoleScreenshotOutput, error) { req, out := c.GetConsoleScreenshotRequest(input) return out, req.Send() @@ -14971,7 +16542,7 @@ const opGetHostReservationPurchasePreview = "GetHostReservationPurchasePreview" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreview +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreview func (c *EC2) GetHostReservationPurchasePreviewRequest(input *GetHostReservationPurchasePreviewInput) (req *request.Request, output *GetHostReservationPurchasePreviewOutput) { op := &request.Operation{ Name: opGetHostReservationPurchasePreview, @@ -15003,7 +16574,7 @@ func (c *EC2) GetHostReservationPurchasePreviewRequest(input *GetHostReservation // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation GetHostReservationPurchasePreview for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreview +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreview func (c *EC2) GetHostReservationPurchasePreview(input *GetHostReservationPurchasePreviewInput) (*GetHostReservationPurchasePreviewOutput, error) { req, out := c.GetHostReservationPurchasePreviewRequest(input) return out, req.Send() @@ -15025,6 +16596,81 @@ func (c *EC2) GetHostReservationPurchasePreviewWithContext(ctx aws.Context, inpu return out, req.Send() } +const opGetLaunchTemplateData = "GetLaunchTemplateData" + +// GetLaunchTemplateDataRequest generates a "aws/request.Request" representing the +// client's request for the GetLaunchTemplateData operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLaunchTemplateData for more information on using the GetLaunchTemplateData +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLaunchTemplateDataRequest method. +// req, resp := client.GetLaunchTemplateDataRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetLaunchTemplateData +func (c *EC2) GetLaunchTemplateDataRequest(input *GetLaunchTemplateDataInput) (req *request.Request, output *GetLaunchTemplateDataOutput) { + op := &request.Operation{ + Name: opGetLaunchTemplateData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLaunchTemplateDataInput{} + } + + output = &GetLaunchTemplateDataOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLaunchTemplateData API operation for Amazon Elastic Compute Cloud. +// +// Retrieves the configuration data of the specified instance. You can use this +// data to create a launch template. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation GetLaunchTemplateData for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetLaunchTemplateData +func (c *EC2) GetLaunchTemplateData(input *GetLaunchTemplateDataInput) (*GetLaunchTemplateDataOutput, error) { + req, out := c.GetLaunchTemplateDataRequest(input) + return out, req.Send() +} + +// GetLaunchTemplateDataWithContext is the same as GetLaunchTemplateData with the addition of +// the ability to pass a context and additional request options. +// +// See GetLaunchTemplateData for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) GetLaunchTemplateDataWithContext(ctx aws.Context, input *GetLaunchTemplateDataInput, opts ...request.Option) (*GetLaunchTemplateDataOutput, error) { + req, out := c.GetLaunchTemplateDataRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opGetPasswordData = "GetPasswordData" // GetPasswordDataRequest generates a "aws/request.Request" representing the @@ -15050,7 +16696,7 @@ const opGetPasswordData = "GetPasswordData" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordData +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordData func (c *EC2) GetPasswordDataRequest(input *GetPasswordDataInput) (req *request.Request, output *GetPasswordDataOutput) { op := &request.Operation{ Name: opGetPasswordData, @@ -15069,20 +16715,24 @@ func (c *EC2) GetPasswordDataRequest(input *GetPasswordDataInput) (req *request. // GetPasswordData API operation for Amazon Elastic Compute Cloud. // -// Retrieves the encrypted administrator password for an instance running Windows. +// Retrieves the encrypted administrator password for a running Windows instance. // -// The Windows password is generated at boot if the EC2Config service plugin, -// Ec2SetPassword, is enabled. This usually only happens the first time an AMI -// is launched, and then Ec2SetPassword is automatically disabled. The password -// is not generated for rebundled AMIs unless Ec2SetPassword is enabled before -// bundling. +// The Windows password is generated at boot by the EC2Config service or EC2Launch +// scripts (Windows Server 2016 and later). This usually only happens the first +// time an instance is launched. For more information, see EC2Config (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html) +// and EC2Launch (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// For the EC2Config service, the password is not generated for rebundled AMIs +// unless Ec2SetPassword is enabled before bundling. // // The password is encrypted using the key pair that you specified when you // launched the instance. You must provide the corresponding key pair file. // -// Password generation and encryption takes a few moments. We recommend that -// you wait up to 15 minutes after launching an instance before trying to retrieve -// the generated password. +// When you launch an instance, password generation and encryption may take +// a few minutes. If you try to retrieve the password before it's available, +// the output returns an empty string. We recommend that you wait up to 15 minutes +// after launching an instance before trying to retrieve the generated password. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -15090,7 +16740,7 @@ func (c *EC2) GetPasswordDataRequest(input *GetPasswordDataInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation GetPasswordData for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordData +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordData func (c *EC2) GetPasswordData(input *GetPasswordDataInput) (*GetPasswordDataOutput, error) { req, out := c.GetPasswordDataRequest(input) return out, req.Send() @@ -15137,7 +16787,7 @@ const opGetReservedInstancesExchangeQuote = "GetReservedInstancesExchangeQuote" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuote +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuote func (c *EC2) GetReservedInstancesExchangeQuoteRequest(input *GetReservedInstancesExchangeQuoteInput) (req *request.Request, output *GetReservedInstancesExchangeQuoteOutput) { op := &request.Operation{ Name: opGetReservedInstancesExchangeQuote, @@ -15156,9 +16806,10 @@ func (c *EC2) GetReservedInstancesExchangeQuoteRequest(input *GetReservedInstanc // GetReservedInstancesExchangeQuote API operation for Amazon Elastic Compute Cloud. // -// Returns details about the values and term of your specified Convertible Reserved -// Instances. When a target configuration is specified, it returns information -// about whether the exchange is valid and can be performed. +// Returns a quote and exchange information for exchanging one or more specified +// Convertible Reserved Instances for a new Convertible Reserved Instance. If +// the exchange cannot be performed, the reason is returned in the response. +// Use AcceptReservedInstancesExchangeQuote to perform the exchange. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -15166,7 +16817,7 @@ func (c *EC2) GetReservedInstancesExchangeQuoteRequest(input *GetReservedInstanc // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation GetReservedInstancesExchangeQuote for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuote +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuote func (c *EC2) GetReservedInstancesExchangeQuote(input *GetReservedInstancesExchangeQuoteInput) (*GetReservedInstancesExchangeQuoteOutput, error) { req, out := c.GetReservedInstancesExchangeQuoteRequest(input) return out, req.Send() @@ -15213,7 +16864,7 @@ const opImportImage = "ImportImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImage func (c *EC2) ImportImageRequest(input *ImportImageInput) (req *request.Request, output *ImportImageOutput) { op := &request.Operation{ Name: opImportImage, @@ -15243,7 +16894,7 @@ func (c *EC2) ImportImageRequest(input *ImportImageInput) (req *request.Request, // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ImportImage for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImage func (c *EC2) ImportImage(input *ImportImageInput) (*ImportImageOutput, error) { req, out := c.ImportImageRequest(input) return out, req.Send() @@ -15290,7 +16941,7 @@ const opImportInstance = "ImportInstance" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstance func (c *EC2) ImportInstanceRequest(input *ImportInstanceInput) (req *request.Request, output *ImportInstanceOutput) { op := &request.Operation{ Name: opImportInstance, @@ -15323,7 +16974,7 @@ func (c *EC2) ImportInstanceRequest(input *ImportInstanceInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ImportInstance for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstance func (c *EC2) ImportInstance(input *ImportInstanceInput) (*ImportInstanceOutput, error) { req, out := c.ImportInstanceRequest(input) return out, req.Send() @@ -15370,7 +17021,7 @@ const opImportKeyPair = "ImportKeyPair" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPair func (c *EC2) ImportKeyPairRequest(input *ImportKeyPairInput) (req *request.Request, output *ImportKeyPairOutput) { op := &request.Operation{ Name: opImportKeyPair, @@ -15404,7 +17055,7 @@ func (c *EC2) ImportKeyPairRequest(input *ImportKeyPairInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ImportKeyPair for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPair func (c *EC2) ImportKeyPair(input *ImportKeyPairInput) (*ImportKeyPairOutput, error) { req, out := c.ImportKeyPairRequest(input) return out, req.Send() @@ -15451,7 +17102,7 @@ const opImportSnapshot = "ImportSnapshot" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshot func (c *EC2) ImportSnapshotRequest(input *ImportSnapshotInput) (req *request.Request, output *ImportSnapshotOutput) { op := &request.Operation{ Name: opImportSnapshot, @@ -15478,7 +17129,7 @@ func (c *EC2) ImportSnapshotRequest(input *ImportSnapshotInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ImportSnapshot for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshot func (c *EC2) ImportSnapshot(input *ImportSnapshotInput) (*ImportSnapshotOutput, error) { req, out := c.ImportSnapshotRequest(input) return out, req.Send() @@ -15525,7 +17176,7 @@ const opImportVolume = "ImportVolume" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolume func (c *EC2) ImportVolumeRequest(input *ImportVolumeInput) (req *request.Request, output *ImportVolumeOutput) { op := &request.Operation{ Name: opImportVolume, @@ -15556,7 +17207,7 @@ func (c *EC2) ImportVolumeRequest(input *ImportVolumeInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ImportVolume for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolume func (c *EC2) ImportVolume(input *ImportVolumeInput) (*ImportVolumeOutput, error) { req, out := c.ImportVolumeRequest(input) return out, req.Send() @@ -15578,6 +17229,80 @@ func (c *EC2) ImportVolumeWithContext(ctx aws.Context, input *ImportVolumeInput, return out, req.Send() } +const opModifyFpgaImageAttribute = "ModifyFpgaImageAttribute" + +// ModifyFpgaImageAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ModifyFpgaImageAttribute operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyFpgaImageAttribute for more information on using the ModifyFpgaImageAttribute +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyFpgaImageAttributeRequest method. +// req, resp := client.ModifyFpgaImageAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyFpgaImageAttribute +func (c *EC2) ModifyFpgaImageAttributeRequest(input *ModifyFpgaImageAttributeInput) (req *request.Request, output *ModifyFpgaImageAttributeOutput) { + op := &request.Operation{ + Name: opModifyFpgaImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyFpgaImageAttributeInput{} + } + + output = &ModifyFpgaImageAttributeOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyFpgaImageAttribute API operation for Amazon Elastic Compute Cloud. +// +// Modifies the specified attribute of the specified Amazon FPGA Image (AFI). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyFpgaImageAttribute for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyFpgaImageAttribute +func (c *EC2) ModifyFpgaImageAttribute(input *ModifyFpgaImageAttributeInput) (*ModifyFpgaImageAttributeOutput, error) { + req, out := c.ModifyFpgaImageAttributeRequest(input) + return out, req.Send() +} + +// ModifyFpgaImageAttributeWithContext is the same as ModifyFpgaImageAttribute with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyFpgaImageAttribute for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyFpgaImageAttributeWithContext(ctx aws.Context, input *ModifyFpgaImageAttributeInput, opts ...request.Option) (*ModifyFpgaImageAttributeOutput, error) { + req, out := c.ModifyFpgaImageAttributeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opModifyHosts = "ModifyHosts" // ModifyHostsRequest generates a "aws/request.Request" representing the @@ -15603,7 +17328,7 @@ const opModifyHosts = "ModifyHosts" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHosts func (c *EC2) ModifyHostsRequest(input *ModifyHostsInput) (req *request.Request, output *ModifyHostsOutput) { op := &request.Operation{ Name: opModifyHosts, @@ -15636,7 +17361,7 @@ func (c *EC2) ModifyHostsRequest(input *ModifyHostsInput) (req *request.Request, // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyHosts for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHosts func (c *EC2) ModifyHosts(input *ModifyHostsInput) (*ModifyHostsOutput, error) { req, out := c.ModifyHostsRequest(input) return out, req.Send() @@ -15683,7 +17408,7 @@ const opModifyIdFormat = "ModifyIdFormat" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormat func (c *EC2) ModifyIdFormatRequest(input *ModifyIdFormatInput) (req *request.Request, output *ModifyIdFormatOutput) { op := &request.Operation{ Name: opModifyIdFormat, @@ -15726,7 +17451,7 @@ func (c *EC2) ModifyIdFormatRequest(input *ModifyIdFormatInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyIdFormat for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormat func (c *EC2) ModifyIdFormat(input *ModifyIdFormatInput) (*ModifyIdFormatOutput, error) { req, out := c.ModifyIdFormatRequest(input) return out, req.Send() @@ -15773,7 +17498,7 @@ const opModifyIdentityIdFormat = "ModifyIdentityIdFormat" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormat func (c *EC2) ModifyIdentityIdFormatRequest(input *ModifyIdentityIdFormatInput) (req *request.Request, output *ModifyIdentityIdFormatOutput) { op := &request.Operation{ Name: opModifyIdentityIdFormat, @@ -15816,7 +17541,7 @@ func (c *EC2) ModifyIdentityIdFormatRequest(input *ModifyIdentityIdFormatInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyIdentityIdFormat for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormat func (c *EC2) ModifyIdentityIdFormat(input *ModifyIdentityIdFormatInput) (*ModifyIdentityIdFormatOutput, error) { req, out := c.ModifyIdentityIdFormatRequest(input) return out, req.Send() @@ -15863,7 +17588,7 @@ const opModifyImageAttribute = "ModifyImageAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttribute func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req *request.Request, output *ModifyImageAttributeOutput) { op := &request.Operation{ Name: opModifyImageAttribute, @@ -15885,15 +17610,15 @@ func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req // ModifyImageAttribute API operation for Amazon Elastic Compute Cloud. // // Modifies the specified attribute of the specified AMI. You can specify only -// one attribute at a time. +// one attribute at a time. You can use the Attribute parameter to specify the +// attribute or one of the following parameters: Description, LaunchPermission, +// or ProductCode. // // AWS Marketplace product codes cannot be modified. Images with an AWS Marketplace // product code cannot be made public. // -// The SriovNetSupport enhanced networking attribute cannot be changed using -// this command. Instead, enable SriovNetSupport on an instance and create an -// AMI from the instance. This will result in an image with SriovNetSupport -// enabled. +// To enable the SriovNetSupport enhanced networking attribute of an image, +// enable SriovNetSupport on an instance and create an AMI from the instance. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -15901,7 +17626,7 @@ func (c *EC2) ModifyImageAttributeRequest(input *ModifyImageAttributeInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyImageAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttribute func (c *EC2) ModifyImageAttribute(input *ModifyImageAttributeInput) (*ModifyImageAttributeOutput, error) { req, out := c.ModifyImageAttributeRequest(input) return out, req.Send() @@ -15948,7 +17673,7 @@ const opModifyInstanceAttribute = "ModifyInstanceAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttribute func (c *EC2) ModifyInstanceAttributeRequest(input *ModifyInstanceAttributeInput) (req *request.Request, output *ModifyInstanceAttributeOutput) { op := &request.Operation{ Name: opModifyInstanceAttribute, @@ -15982,7 +17707,7 @@ func (c *EC2) ModifyInstanceAttributeRequest(input *ModifyInstanceAttributeInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyInstanceAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttribute func (c *EC2) ModifyInstanceAttribute(input *ModifyInstanceAttributeInput) (*ModifyInstanceAttributeOutput, error) { req, out := c.ModifyInstanceAttributeRequest(input) return out, req.Send() @@ -16004,6 +17729,84 @@ func (c *EC2) ModifyInstanceAttributeWithContext(ctx aws.Context, input *ModifyI return out, req.Send() } +const opModifyInstanceCreditSpecification = "ModifyInstanceCreditSpecification" + +// ModifyInstanceCreditSpecificationRequest generates a "aws/request.Request" representing the +// client's request for the ModifyInstanceCreditSpecification operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyInstanceCreditSpecification for more information on using the ModifyInstanceCreditSpecification +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyInstanceCreditSpecificationRequest method. +// req, resp := client.ModifyInstanceCreditSpecificationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceCreditSpecification +func (c *EC2) ModifyInstanceCreditSpecificationRequest(input *ModifyInstanceCreditSpecificationInput) (req *request.Request, output *ModifyInstanceCreditSpecificationOutput) { + op := &request.Operation{ + Name: opModifyInstanceCreditSpecification, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyInstanceCreditSpecificationInput{} + } + + output = &ModifyInstanceCreditSpecificationOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyInstanceCreditSpecification API operation for Amazon Elastic Compute Cloud. +// +// Modifies the credit option for CPU usage on a running or stopped T2 instance. +// The credit options are standard and unlimited. +// +// For more information, see T2 Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-instances.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyInstanceCreditSpecification for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceCreditSpecification +func (c *EC2) ModifyInstanceCreditSpecification(input *ModifyInstanceCreditSpecificationInput) (*ModifyInstanceCreditSpecificationOutput, error) { + req, out := c.ModifyInstanceCreditSpecificationRequest(input) + return out, req.Send() +} + +// ModifyInstanceCreditSpecificationWithContext is the same as ModifyInstanceCreditSpecification with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyInstanceCreditSpecification for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyInstanceCreditSpecificationWithContext(ctx aws.Context, input *ModifyInstanceCreditSpecificationInput, opts ...request.Option) (*ModifyInstanceCreditSpecificationOutput, error) { + req, out := c.ModifyInstanceCreditSpecificationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opModifyInstancePlacement = "ModifyInstancePlacement" // ModifyInstancePlacementRequest generates a "aws/request.Request" representing the @@ -16029,7 +17832,7 @@ const opModifyInstancePlacement = "ModifyInstancePlacement" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacement +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacement func (c *EC2) ModifyInstancePlacementRequest(input *ModifyInstancePlacementInput) (req *request.Request, output *ModifyInstancePlacementOutput) { op := &request.Operation{ Name: opModifyInstancePlacement, @@ -16074,7 +17877,7 @@ func (c *EC2) ModifyInstancePlacementRequest(input *ModifyInstancePlacementInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyInstancePlacement for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacement +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacement func (c *EC2) ModifyInstancePlacement(input *ModifyInstancePlacementInput) (*ModifyInstancePlacementOutput, error) { req, out := c.ModifyInstancePlacementRequest(input) return out, req.Send() @@ -16096,6 +17899,82 @@ func (c *EC2) ModifyInstancePlacementWithContext(ctx aws.Context, input *ModifyI return out, req.Send() } +const opModifyLaunchTemplate = "ModifyLaunchTemplate" + +// ModifyLaunchTemplateRequest generates a "aws/request.Request" representing the +// client's request for the ModifyLaunchTemplate operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyLaunchTemplate for more information on using the ModifyLaunchTemplate +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyLaunchTemplateRequest method. +// req, resp := client.ModifyLaunchTemplateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyLaunchTemplate +func (c *EC2) ModifyLaunchTemplateRequest(input *ModifyLaunchTemplateInput) (req *request.Request, output *ModifyLaunchTemplateOutput) { + op := &request.Operation{ + Name: opModifyLaunchTemplate, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyLaunchTemplateInput{} + } + + output = &ModifyLaunchTemplateOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyLaunchTemplate API operation for Amazon Elastic Compute Cloud. +// +// Modifies a launch template. You can specify which version of the launch template +// to set as the default version. When launching an instance, the default version +// applies when a launch template version is not specified. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyLaunchTemplate for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyLaunchTemplate +func (c *EC2) ModifyLaunchTemplate(input *ModifyLaunchTemplateInput) (*ModifyLaunchTemplateOutput, error) { + req, out := c.ModifyLaunchTemplateRequest(input) + return out, req.Send() +} + +// ModifyLaunchTemplateWithContext is the same as ModifyLaunchTemplate with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyLaunchTemplate for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyLaunchTemplateWithContext(ctx aws.Context, input *ModifyLaunchTemplateInput, opts ...request.Option) (*ModifyLaunchTemplateOutput, error) { + req, out := c.ModifyLaunchTemplateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opModifyNetworkInterfaceAttribute = "ModifyNetworkInterfaceAttribute" // ModifyNetworkInterfaceAttributeRequest generates a "aws/request.Request" representing the @@ -16121,7 +18000,7 @@ const opModifyNetworkInterfaceAttribute = "ModifyNetworkInterfaceAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttribute func (c *EC2) ModifyNetworkInterfaceAttributeRequest(input *ModifyNetworkInterfaceAttributeInput) (req *request.Request, output *ModifyNetworkInterfaceAttributeOutput) { op := &request.Operation{ Name: opModifyNetworkInterfaceAttribute, @@ -16151,7 +18030,7 @@ func (c *EC2) ModifyNetworkInterfaceAttributeRequest(input *ModifyNetworkInterfa // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyNetworkInterfaceAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttribute func (c *EC2) ModifyNetworkInterfaceAttribute(input *ModifyNetworkInterfaceAttributeInput) (*ModifyNetworkInterfaceAttributeOutput, error) { req, out := c.ModifyNetworkInterfaceAttributeRequest(input) return out, req.Send() @@ -16198,7 +18077,7 @@ const opModifyReservedInstances = "ModifyReservedInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstances func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput) (req *request.Request, output *ModifyReservedInstancesOutput) { op := &request.Operation{ Name: opModifyReservedInstances, @@ -16218,9 +18097,9 @@ func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput // ModifyReservedInstances API operation for Amazon Elastic Compute Cloud. // // Modifies the Availability Zone, instance count, instance type, or network -// platform (EC2-Classic or EC2-VPC) of your Standard Reserved Instances. The -// Reserved Instances to be modified must be identical, except for Availability -// Zone, network platform, and instance type. +// platform (EC2-Classic or EC2-VPC) of your Reserved Instances. The Reserved +// Instances to be modified must be identical, except for Availability Zone, +// network platform, and instance type. // // For more information, see Modifying Reserved Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-modifying.html) // in the Amazon Elastic Compute Cloud User Guide. @@ -16231,7 +18110,7 @@ func (c *EC2) ModifyReservedInstancesRequest(input *ModifyReservedInstancesInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyReservedInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstances func (c *EC2) ModifyReservedInstances(input *ModifyReservedInstancesInput) (*ModifyReservedInstancesOutput, error) { req, out := c.ModifyReservedInstancesRequest(input) return out, req.Send() @@ -16278,7 +18157,7 @@ const opModifySnapshotAttribute = "ModifySnapshotAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttribute func (c *EC2) ModifySnapshotAttributeRequest(input *ModifySnapshotAttributeInput) (req *request.Request, output *ModifySnapshotAttributeOutput) { op := &request.Operation{ Name: opModifySnapshotAttribute, @@ -16319,7 +18198,7 @@ func (c *EC2) ModifySnapshotAttributeRequest(input *ModifySnapshotAttributeInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifySnapshotAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttribute func (c *EC2) ModifySnapshotAttribute(input *ModifySnapshotAttributeInput) (*ModifySnapshotAttributeOutput, error) { req, out := c.ModifySnapshotAttributeRequest(input) return out, req.Send() @@ -16366,7 +18245,7 @@ const opModifySpotFleetRequest = "ModifySpotFleetRequest" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequest func (c *EC2) ModifySpotFleetRequestRequest(input *ModifySpotFleetRequestInput) (req *request.Request, output *ModifySpotFleetRequestOutput) { op := &request.Operation{ Name: opModifySpotFleetRequest, @@ -16385,26 +18264,29 @@ func (c *EC2) ModifySpotFleetRequestRequest(input *ModifySpotFleetRequestInput) // ModifySpotFleetRequest API operation for Amazon Elastic Compute Cloud. // -// Modifies the specified Spot fleet request. +// Modifies the specified Spot Fleet request. // -// While the Spot fleet request is being modified, it is in the modifying state. +// While the Spot Fleet request is being modified, it is in the modifying state. // -// To scale up your Spot fleet, increase its target capacity. The Spot fleet -// launches the additional Spot instances according to the allocation strategy -// for the Spot fleet request. If the allocation strategy is lowestPrice, the -// Spot fleet launches instances using the Spot pool with the lowest price. -// If the allocation strategy is diversified, the Spot fleet distributes the +// To scale up your Spot Fleet, increase its target capacity. The Spot Fleet +// launches the additional Spot Instances according to the allocation strategy +// for the Spot Fleet request. If the allocation strategy is lowestPrice, the +// Spot Fleet launches instances using the Spot pool with the lowest price. +// If the allocation strategy is diversified, the Spot Fleet distributes the // instances across the Spot pools. // -// To scale down your Spot fleet, decrease its target capacity. First, the Spot -// fleet cancels any open bids that exceed the new target capacity. You can -// request that the Spot fleet terminate Spot instances until the size of the -// fleet no longer exceeds the new target capacity. If the allocation strategy -// is lowestPrice, the Spot fleet terminates the instances with the highest -// price per unit. If the allocation strategy is diversified, the Spot fleet +// To scale down your Spot Fleet, decrease its target capacity. First, the Spot +// Fleet cancels any open requests that exceed the new target capacity. You +// can request that the Spot Fleet terminate Spot Instances until the size of +// the fleet no longer exceeds the new target capacity. If the allocation strategy +// is lowestPrice, the Spot Fleet terminates the instances with the highest +// price per unit. If the allocation strategy is diversified, the Spot Fleet // terminates instances across the Spot pools. Alternatively, you can request -// that the Spot fleet keep the fleet at its current size, but not replace any -// Spot instances that are interrupted or that you terminate manually. +// that the Spot Fleet keep the fleet at its current size, but not replace any +// Spot Instances that are interrupted or that you terminate manually. +// +// If you are finished with your Spot Fleet for now, but will use it again later, +// you can set the target capacity to 0. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -16412,7 +18294,7 @@ func (c *EC2) ModifySpotFleetRequestRequest(input *ModifySpotFleetRequestInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifySpotFleetRequest for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequest func (c *EC2) ModifySpotFleetRequest(input *ModifySpotFleetRequestInput) (*ModifySpotFleetRequestOutput, error) { req, out := c.ModifySpotFleetRequestRequest(input) return out, req.Send() @@ -16459,7 +18341,7 @@ const opModifySubnetAttribute = "ModifySubnetAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttribute func (c *EC2) ModifySubnetAttributeRequest(input *ModifySubnetAttributeInput) (req *request.Request, output *ModifySubnetAttributeOutput) { op := &request.Operation{ Name: opModifySubnetAttribute, @@ -16488,7 +18370,7 @@ func (c *EC2) ModifySubnetAttributeRequest(input *ModifySubnetAttributeInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifySubnetAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttribute func (c *EC2) ModifySubnetAttribute(input *ModifySubnetAttributeInput) (*ModifySubnetAttributeOutput, error) { req, out := c.ModifySubnetAttributeRequest(input) return out, req.Send() @@ -16535,7 +18417,7 @@ const opModifyVolume = "ModifyVolume" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolume func (c *EC2) ModifyVolumeRequest(input *ModifyVolumeInput) (req *request.Request, output *ModifyVolumeOutput) { op := &request.Operation{ Name: opModifyVolume, @@ -16594,7 +18476,7 @@ func (c *EC2) ModifyVolumeRequest(input *ModifyVolumeInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyVolume for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolume func (c *EC2) ModifyVolume(input *ModifyVolumeInput) (*ModifyVolumeOutput, error) { req, out := c.ModifyVolumeRequest(input) return out, req.Send() @@ -16641,7 +18523,7 @@ const opModifyVolumeAttribute = "ModifyVolumeAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttribute func (c *EC2) ModifyVolumeAttributeRequest(input *ModifyVolumeAttributeInput) (req *request.Request, output *ModifyVolumeAttributeOutput) { op := &request.Operation{ Name: opModifyVolumeAttribute, @@ -16679,7 +18561,7 @@ func (c *EC2) ModifyVolumeAttributeRequest(input *ModifyVolumeAttributeInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyVolumeAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttribute func (c *EC2) ModifyVolumeAttribute(input *ModifyVolumeAttributeInput) (*ModifyVolumeAttributeOutput, error) { req, out := c.ModifyVolumeAttributeRequest(input) return out, req.Send() @@ -16726,7 +18608,7 @@ const opModifyVpcAttribute = "ModifyVpcAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttribute func (c *EC2) ModifyVpcAttributeRequest(input *ModifyVpcAttributeInput) (req *request.Request, output *ModifyVpcAttributeOutput) { op := &request.Operation{ Name: opModifyVpcAttribute, @@ -16755,7 +18637,7 @@ func (c *EC2) ModifyVpcAttributeRequest(input *ModifyVpcAttributeInput) (req *re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyVpcAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttribute func (c *EC2) ModifyVpcAttribute(input *ModifyVpcAttributeInput) (*ModifyVpcAttributeOutput, error) { req, out := c.ModifyVpcAttributeRequest(input) return out, req.Send() @@ -16802,7 +18684,7 @@ const opModifyVpcEndpoint = "ModifyVpcEndpoint" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpoint +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpoint func (c *EC2) ModifyVpcEndpointRequest(input *ModifyVpcEndpointInput) (req *request.Request, output *ModifyVpcEndpointOutput) { op := &request.Operation{ Name: opModifyVpcEndpoint, @@ -16821,9 +18703,10 @@ func (c *EC2) ModifyVpcEndpointRequest(input *ModifyVpcEndpointInput) (req *requ // ModifyVpcEndpoint API operation for Amazon Elastic Compute Cloud. // -// Modifies attributes of a specified VPC endpoint. You can modify the policy -// associated with the endpoint, and you can add and remove route tables associated -// with the endpoint. +// Modifies attributes of a specified VPC endpoint. The attributes that you +// can modify depend on the type of VPC endpoint (interface or gateway). For +// more information, see VPC Endpoints (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-endpoints.html) +// in the Amazon Virtual Private Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -16831,7 +18714,7 @@ func (c *EC2) ModifyVpcEndpointRequest(input *ModifyVpcEndpointInput) (req *requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyVpcEndpoint for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpoint +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpoint func (c *EC2) ModifyVpcEndpoint(input *ModifyVpcEndpointInput) (*ModifyVpcEndpointOutput, error) { req, out := c.ModifyVpcEndpointRequest(input) return out, req.Send() @@ -16853,6 +18736,235 @@ func (c *EC2) ModifyVpcEndpointWithContext(ctx aws.Context, input *ModifyVpcEndp return out, req.Send() } +const opModifyVpcEndpointConnectionNotification = "ModifyVpcEndpointConnectionNotification" + +// ModifyVpcEndpointConnectionNotificationRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcEndpointConnectionNotification operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyVpcEndpointConnectionNotification for more information on using the ModifyVpcEndpointConnectionNotification +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyVpcEndpointConnectionNotificationRequest method. +// req, resp := client.ModifyVpcEndpointConnectionNotificationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointConnectionNotification +func (c *EC2) ModifyVpcEndpointConnectionNotificationRequest(input *ModifyVpcEndpointConnectionNotificationInput) (req *request.Request, output *ModifyVpcEndpointConnectionNotificationOutput) { + op := &request.Operation{ + Name: opModifyVpcEndpointConnectionNotification, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcEndpointConnectionNotificationInput{} + } + + output = &ModifyVpcEndpointConnectionNotificationOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyVpcEndpointConnectionNotification API operation for Amazon Elastic Compute Cloud. +// +// Modifies a connection notification for VPC endpoint or VPC endpoint service. +// You can change the SNS topic for the notification, or the events for which +// to be notified. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyVpcEndpointConnectionNotification for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointConnectionNotification +func (c *EC2) ModifyVpcEndpointConnectionNotification(input *ModifyVpcEndpointConnectionNotificationInput) (*ModifyVpcEndpointConnectionNotificationOutput, error) { + req, out := c.ModifyVpcEndpointConnectionNotificationRequest(input) + return out, req.Send() +} + +// ModifyVpcEndpointConnectionNotificationWithContext is the same as ModifyVpcEndpointConnectionNotification with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyVpcEndpointConnectionNotification for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyVpcEndpointConnectionNotificationWithContext(ctx aws.Context, input *ModifyVpcEndpointConnectionNotificationInput, opts ...request.Option) (*ModifyVpcEndpointConnectionNotificationOutput, error) { + req, out := c.ModifyVpcEndpointConnectionNotificationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opModifyVpcEndpointServiceConfiguration = "ModifyVpcEndpointServiceConfiguration" + +// ModifyVpcEndpointServiceConfigurationRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcEndpointServiceConfiguration operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyVpcEndpointServiceConfiguration for more information on using the ModifyVpcEndpointServiceConfiguration +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyVpcEndpointServiceConfigurationRequest method. +// req, resp := client.ModifyVpcEndpointServiceConfigurationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServiceConfiguration +func (c *EC2) ModifyVpcEndpointServiceConfigurationRequest(input *ModifyVpcEndpointServiceConfigurationInput) (req *request.Request, output *ModifyVpcEndpointServiceConfigurationOutput) { + op := &request.Operation{ + Name: opModifyVpcEndpointServiceConfiguration, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcEndpointServiceConfigurationInput{} + } + + output = &ModifyVpcEndpointServiceConfigurationOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyVpcEndpointServiceConfiguration API operation for Amazon Elastic Compute Cloud. +// +// Modifies the attributes of your VPC endpoint service configuration. You can +// change the Network Load Balancers for your service, and you can specify whether +// acceptance is required for requests to connect to your endpoint service through +// an interface VPC endpoint. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyVpcEndpointServiceConfiguration for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServiceConfiguration +func (c *EC2) ModifyVpcEndpointServiceConfiguration(input *ModifyVpcEndpointServiceConfigurationInput) (*ModifyVpcEndpointServiceConfigurationOutput, error) { + req, out := c.ModifyVpcEndpointServiceConfigurationRequest(input) + return out, req.Send() +} + +// ModifyVpcEndpointServiceConfigurationWithContext is the same as ModifyVpcEndpointServiceConfiguration with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyVpcEndpointServiceConfiguration for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyVpcEndpointServiceConfigurationWithContext(ctx aws.Context, input *ModifyVpcEndpointServiceConfigurationInput, opts ...request.Option) (*ModifyVpcEndpointServiceConfigurationOutput, error) { + req, out := c.ModifyVpcEndpointServiceConfigurationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opModifyVpcEndpointServicePermissions = "ModifyVpcEndpointServicePermissions" + +// ModifyVpcEndpointServicePermissionsRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcEndpointServicePermissions operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyVpcEndpointServicePermissions for more information on using the ModifyVpcEndpointServicePermissions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyVpcEndpointServicePermissionsRequest method. +// req, resp := client.ModifyVpcEndpointServicePermissionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServicePermissions +func (c *EC2) ModifyVpcEndpointServicePermissionsRequest(input *ModifyVpcEndpointServicePermissionsInput) (req *request.Request, output *ModifyVpcEndpointServicePermissionsOutput) { + op := &request.Operation{ + Name: opModifyVpcEndpointServicePermissions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcEndpointServicePermissionsInput{} + } + + output = &ModifyVpcEndpointServicePermissionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyVpcEndpointServicePermissions API operation for Amazon Elastic Compute Cloud. +// +// Modifies the permissions for your VPC endpoint service. You can add or remove +// permissions for service consumers (IAM users, IAM roles, and AWS accounts) +// to discover your endpoint service. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyVpcEndpointServicePermissions for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServicePermissions +func (c *EC2) ModifyVpcEndpointServicePermissions(input *ModifyVpcEndpointServicePermissionsInput) (*ModifyVpcEndpointServicePermissionsOutput, error) { + req, out := c.ModifyVpcEndpointServicePermissionsRequest(input) + return out, req.Send() +} + +// ModifyVpcEndpointServicePermissionsWithContext is the same as ModifyVpcEndpointServicePermissions with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyVpcEndpointServicePermissions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyVpcEndpointServicePermissionsWithContext(ctx aws.Context, input *ModifyVpcEndpointServicePermissionsInput, opts ...request.Option) (*ModifyVpcEndpointServicePermissionsOutput, error) { + req, out := c.ModifyVpcEndpointServicePermissionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opModifyVpcPeeringConnectionOptions = "ModifyVpcPeeringConnectionOptions" // ModifyVpcPeeringConnectionOptionsRequest generates a "aws/request.Request" representing the @@ -16878,7 +18990,7 @@ const opModifyVpcPeeringConnectionOptions = "ModifyVpcPeeringConnectionOptions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptions func (c *EC2) ModifyVpcPeeringConnectionOptionsRequest(input *ModifyVpcPeeringConnectionOptionsInput) (req *request.Request, output *ModifyVpcPeeringConnectionOptionsOutput) { op := &request.Operation{ Name: opModifyVpcPeeringConnectionOptions, @@ -16924,7 +19036,7 @@ func (c *EC2) ModifyVpcPeeringConnectionOptionsRequest(input *ModifyVpcPeeringCo // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ModifyVpcPeeringConnectionOptions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptions func (c *EC2) ModifyVpcPeeringConnectionOptions(input *ModifyVpcPeeringConnectionOptionsInput) (*ModifyVpcPeeringConnectionOptionsOutput, error) { req, out := c.ModifyVpcPeeringConnectionOptionsRequest(input) return out, req.Send() @@ -16946,6 +19058,89 @@ func (c *EC2) ModifyVpcPeeringConnectionOptionsWithContext(ctx aws.Context, inpu return out, req.Send() } +const opModifyVpcTenancy = "ModifyVpcTenancy" + +// ModifyVpcTenancyRequest generates a "aws/request.Request" representing the +// client's request for the ModifyVpcTenancy operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ModifyVpcTenancy for more information on using the ModifyVpcTenancy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ModifyVpcTenancyRequest method. +// req, resp := client.ModifyVpcTenancyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcTenancy +func (c *EC2) ModifyVpcTenancyRequest(input *ModifyVpcTenancyInput) (req *request.Request, output *ModifyVpcTenancyOutput) { + op := &request.Operation{ + Name: opModifyVpcTenancy, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ModifyVpcTenancyInput{} + } + + output = &ModifyVpcTenancyOutput{} + req = c.newRequest(op, input, output) + return +} + +// ModifyVpcTenancy API operation for Amazon Elastic Compute Cloud. +// +// Modifies the instance tenancy attribute of the specified VPC. You can change +// the instance tenancy attribute of a VPC to default only. You cannot change +// the instance tenancy attribute to dedicated. +// +// After you modify the tenancy of the VPC, any new instances that you launch +// into the VPC have a tenancy of default, unless you specify otherwise during +// launch. The tenancy of any existing instances in the VPC is not affected. +// +// For more information about Dedicated Instances, see Dedicated Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-instance.html) +// in the Amazon Elastic Compute Cloud User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ModifyVpcTenancy for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcTenancy +func (c *EC2) ModifyVpcTenancy(input *ModifyVpcTenancyInput) (*ModifyVpcTenancyOutput, error) { + req, out := c.ModifyVpcTenancyRequest(input) + return out, req.Send() +} + +// ModifyVpcTenancyWithContext is the same as ModifyVpcTenancy with the addition of +// the ability to pass a context and additional request options. +// +// See ModifyVpcTenancy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ModifyVpcTenancyWithContext(ctx aws.Context, input *ModifyVpcTenancyInput, opts ...request.Option) (*ModifyVpcTenancyOutput, error) { + req, out := c.ModifyVpcTenancyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opMonitorInstances = "MonitorInstances" // MonitorInstancesRequest generates a "aws/request.Request" representing the @@ -16971,7 +19166,7 @@ const opMonitorInstances = "MonitorInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstances func (c *EC2) MonitorInstancesRequest(input *MonitorInstancesInput) (req *request.Request, output *MonitorInstancesOutput) { op := &request.Operation{ Name: opMonitorInstances, @@ -17003,7 +19198,7 @@ func (c *EC2) MonitorInstancesRequest(input *MonitorInstancesInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation MonitorInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstances func (c *EC2) MonitorInstances(input *MonitorInstancesInput) (*MonitorInstancesOutput, error) { req, out := c.MonitorInstancesRequest(input) return out, req.Send() @@ -17050,7 +19245,7 @@ const opMoveAddressToVpc = "MoveAddressToVpc" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpc func (c *EC2) MoveAddressToVpcRequest(input *MoveAddressToVpcInput) (req *request.Request, output *MoveAddressToVpcOutput) { op := &request.Operation{ Name: opMoveAddressToVpc, @@ -17083,7 +19278,7 @@ func (c *EC2) MoveAddressToVpcRequest(input *MoveAddressToVpcInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation MoveAddressToVpc for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpc func (c *EC2) MoveAddressToVpc(input *MoveAddressToVpcInput) (*MoveAddressToVpcOutput, error) { req, out := c.MoveAddressToVpcRequest(input) return out, req.Send() @@ -17130,7 +19325,7 @@ const opPurchaseHostReservation = "PurchaseHostReservation" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservation func (c *EC2) PurchaseHostReservationRequest(input *PurchaseHostReservationInput) (req *request.Request, output *PurchaseHostReservationOutput) { op := &request.Operation{ Name: opPurchaseHostReservation, @@ -17160,7 +19355,7 @@ func (c *EC2) PurchaseHostReservationRequest(input *PurchaseHostReservationInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation PurchaseHostReservation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservation func (c *EC2) PurchaseHostReservation(input *PurchaseHostReservationInput) (*PurchaseHostReservationOutput, error) { req, out := c.PurchaseHostReservationRequest(input) return out, req.Send() @@ -17207,7 +19402,7 @@ const opPurchaseReservedInstancesOffering = "PurchaseReservedInstancesOffering" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOffering +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOffering func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedInstancesOfferingInput) (req *request.Request, output *PurchaseReservedInstancesOfferingOutput) { op := &request.Operation{ Name: opPurchaseReservedInstancesOffering, @@ -17243,7 +19438,7 @@ func (c *EC2) PurchaseReservedInstancesOfferingRequest(input *PurchaseReservedIn // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation PurchaseReservedInstancesOffering for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOffering +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOffering func (c *EC2) PurchaseReservedInstancesOffering(input *PurchaseReservedInstancesOfferingInput) (*PurchaseReservedInstancesOfferingOutput, error) { req, out := c.PurchaseReservedInstancesOfferingRequest(input) return out, req.Send() @@ -17290,7 +19485,7 @@ const opPurchaseScheduledInstances = "PurchaseScheduledInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstances func (c *EC2) PurchaseScheduledInstancesRequest(input *PurchaseScheduledInstancesInput) (req *request.Request, output *PurchaseScheduledInstancesOutput) { op := &request.Operation{ Name: opPurchaseScheduledInstances, @@ -17326,7 +19521,7 @@ func (c *EC2) PurchaseScheduledInstancesRequest(input *PurchaseScheduledInstance // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation PurchaseScheduledInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstances func (c *EC2) PurchaseScheduledInstances(input *PurchaseScheduledInstancesInput) (*PurchaseScheduledInstancesOutput, error) { req, out := c.PurchaseScheduledInstancesRequest(input) return out, req.Send() @@ -17373,7 +19568,7 @@ const opRebootInstances = "RebootInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstances func (c *EC2) RebootInstancesRequest(input *RebootInstancesInput) (req *request.Request, output *RebootInstancesOutput) { op := &request.Operation{ Name: opRebootInstances, @@ -17412,7 +19607,7 @@ func (c *EC2) RebootInstancesRequest(input *RebootInstancesInput) (req *request. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RebootInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstances func (c *EC2) RebootInstances(input *RebootInstancesInput) (*RebootInstancesOutput, error) { req, out := c.RebootInstancesRequest(input) return out, req.Send() @@ -17459,7 +19654,7 @@ const opRegisterImage = "RegisterImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImage func (c *EC2) RegisterImageRequest(input *RegisterImageInput) (req *request.Request, output *RegisterImageOutput) { op := &request.Operation{ Name: opRegisterImage, @@ -17514,7 +19709,7 @@ func (c *EC2) RegisterImageRequest(input *RegisterImageInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RegisterImage for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImage func (c *EC2) RegisterImage(input *RegisterImageInput) (*RegisterImageOutput, error) { req, out := c.RegisterImageRequest(input) return out, req.Send() @@ -17536,6 +19731,81 @@ func (c *EC2) RegisterImageWithContext(ctx aws.Context, input *RegisterImageInpu return out, req.Send() } +const opRejectVpcEndpointConnections = "RejectVpcEndpointConnections" + +// RejectVpcEndpointConnectionsRequest generates a "aws/request.Request" representing the +// client's request for the RejectVpcEndpointConnections operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See RejectVpcEndpointConnections for more information on using the RejectVpcEndpointConnections +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the RejectVpcEndpointConnectionsRequest method. +// req, resp := client.RejectVpcEndpointConnectionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcEndpointConnections +func (c *EC2) RejectVpcEndpointConnectionsRequest(input *RejectVpcEndpointConnectionsInput) (req *request.Request, output *RejectVpcEndpointConnectionsOutput) { + op := &request.Operation{ + Name: opRejectVpcEndpointConnections, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RejectVpcEndpointConnectionsInput{} + } + + output = &RejectVpcEndpointConnectionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// RejectVpcEndpointConnections API operation for Amazon Elastic Compute Cloud. +// +// Rejects one or more VPC endpoint connection requests to your VPC endpoint +// service. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation RejectVpcEndpointConnections for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcEndpointConnections +func (c *EC2) RejectVpcEndpointConnections(input *RejectVpcEndpointConnectionsInput) (*RejectVpcEndpointConnectionsOutput, error) { + req, out := c.RejectVpcEndpointConnectionsRequest(input) + return out, req.Send() +} + +// RejectVpcEndpointConnectionsWithContext is the same as RejectVpcEndpointConnections with the addition of +// the ability to pass a context and additional request options. +// +// See RejectVpcEndpointConnections for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) RejectVpcEndpointConnectionsWithContext(ctx aws.Context, input *RejectVpcEndpointConnectionsInput, opts ...request.Option) (*RejectVpcEndpointConnectionsOutput, error) { + req, out := c.RejectVpcEndpointConnectionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opRejectVpcPeeringConnection = "RejectVpcPeeringConnection" // RejectVpcPeeringConnectionRequest generates a "aws/request.Request" representing the @@ -17561,7 +19831,7 @@ const opRejectVpcPeeringConnection = "RejectVpcPeeringConnection" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnection func (c *EC2) RejectVpcPeeringConnectionRequest(input *RejectVpcPeeringConnectionInput) (req *request.Request, output *RejectVpcPeeringConnectionOutput) { op := &request.Operation{ Name: opRejectVpcPeeringConnection, @@ -17592,7 +19862,7 @@ func (c *EC2) RejectVpcPeeringConnectionRequest(input *RejectVpcPeeringConnectio // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RejectVpcPeeringConnection for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnection func (c *EC2) RejectVpcPeeringConnection(input *RejectVpcPeeringConnectionInput) (*RejectVpcPeeringConnectionOutput, error) { req, out := c.RejectVpcPeeringConnectionRequest(input) return out, req.Send() @@ -17639,7 +19909,7 @@ const opReleaseAddress = "ReleaseAddress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddress func (c *EC2) ReleaseAddressRequest(input *ReleaseAddressInput) (req *request.Request, output *ReleaseAddressOutput) { op := &request.Operation{ Name: opReleaseAddress, @@ -17662,19 +19932,22 @@ func (c *EC2) ReleaseAddressRequest(input *ReleaseAddressInput) (req *request.Re // // Releases the specified Elastic IP address. // -// After releasing an Elastic IP address, it is released to the IP address pool -// and might be unavailable to you. Be sure to update your DNS records and any -// servers or devices that communicate with the address. If you attempt to release -// an Elastic IP address that you already released, you'll get an AuthFailure -// error if the address is already allocated to another AWS account. -// // [EC2-Classic, default VPC] Releasing an Elastic IP address automatically // disassociates it from any instance that it's associated with. To disassociate // an Elastic IP address without releasing it, use DisassociateAddress. // // [Nondefault VPC] You must use DisassociateAddress to disassociate the Elastic -// IP address before you try to release it. Otherwise, Amazon EC2 returns an -// error (InvalidIPAddress.InUse). +// IP address before you can release it. Otherwise, Amazon EC2 returns an error +// (InvalidIPAddress.InUse). +// +// After releasing an Elastic IP address, it is released to the IP address pool. +// Be sure to update your DNS records and any servers or devices that communicate +// with the address. If you attempt to release an Elastic IP address that you +// already released, you'll get an AuthFailure error if the address is already +// allocated to another AWS account. +// +// [EC2-VPC] After you release an Elastic IP address for use in a VPC, you might +// be able to recover it. For more information, see AllocateAddress. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -17682,7 +19955,7 @@ func (c *EC2) ReleaseAddressRequest(input *ReleaseAddressInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReleaseAddress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddress func (c *EC2) ReleaseAddress(input *ReleaseAddressInput) (*ReleaseAddressOutput, error) { req, out := c.ReleaseAddressRequest(input) return out, req.Send() @@ -17729,7 +20002,7 @@ const opReleaseHosts = "ReleaseHosts" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHosts func (c *EC2) ReleaseHostsRequest(input *ReleaseHostsInput) (req *request.Request, output *ReleaseHostsOutput) { op := &request.Operation{ Name: opReleaseHosts, @@ -17767,7 +20040,7 @@ func (c *EC2) ReleaseHostsRequest(input *ReleaseHostsInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReleaseHosts for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHosts +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHosts func (c *EC2) ReleaseHosts(input *ReleaseHostsInput) (*ReleaseHostsOutput, error) { req, out := c.ReleaseHostsRequest(input) return out, req.Send() @@ -17814,7 +20087,7 @@ const opReplaceIamInstanceProfileAssociation = "ReplaceIamInstanceProfileAssocia // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociation func (c *EC2) ReplaceIamInstanceProfileAssociationRequest(input *ReplaceIamInstanceProfileAssociationInput) (req *request.Request, output *ReplaceIamInstanceProfileAssociationOutput) { op := &request.Operation{ Name: opReplaceIamInstanceProfileAssociation, @@ -17846,7 +20119,7 @@ func (c *EC2) ReplaceIamInstanceProfileAssociationRequest(input *ReplaceIamInsta // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReplaceIamInstanceProfileAssociation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociation func (c *EC2) ReplaceIamInstanceProfileAssociation(input *ReplaceIamInstanceProfileAssociationInput) (*ReplaceIamInstanceProfileAssociationOutput, error) { req, out := c.ReplaceIamInstanceProfileAssociationRequest(input) return out, req.Send() @@ -17893,7 +20166,7 @@ const opReplaceNetworkAclAssociation = "ReplaceNetworkAclAssociation" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociation func (c *EC2) ReplaceNetworkAclAssociationRequest(input *ReplaceNetworkAclAssociationInput) (req *request.Request, output *ReplaceNetworkAclAssociationOutput) { op := &request.Operation{ Name: opReplaceNetworkAclAssociation, @@ -17917,13 +20190,15 @@ func (c *EC2) ReplaceNetworkAclAssociationRequest(input *ReplaceNetworkAclAssoci // For more information about network ACLs, see Network ACLs (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) // in the Amazon Virtual Private Cloud User Guide. // +// This is an idempotent operation. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReplaceNetworkAclAssociation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociation func (c *EC2) ReplaceNetworkAclAssociation(input *ReplaceNetworkAclAssociationInput) (*ReplaceNetworkAclAssociationOutput, error) { req, out := c.ReplaceNetworkAclAssociationRequest(input) return out, req.Send() @@ -17970,7 +20245,7 @@ const opReplaceNetworkAclEntry = "ReplaceNetworkAclEntry" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntry func (c *EC2) ReplaceNetworkAclEntryRequest(input *ReplaceNetworkAclEntryInput) (req *request.Request, output *ReplaceNetworkAclEntryOutput) { op := &request.Operation{ Name: opReplaceNetworkAclEntry, @@ -18001,7 +20276,7 @@ func (c *EC2) ReplaceNetworkAclEntryRequest(input *ReplaceNetworkAclEntryInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReplaceNetworkAclEntry for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntry func (c *EC2) ReplaceNetworkAclEntry(input *ReplaceNetworkAclEntryInput) (*ReplaceNetworkAclEntryOutput, error) { req, out := c.ReplaceNetworkAclEntryRequest(input) return out, req.Send() @@ -18048,7 +20323,7 @@ const opReplaceRoute = "ReplaceRoute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRoute func (c *EC2) ReplaceRouteRequest(input *ReplaceRouteInput) (req *request.Request, output *ReplaceRouteOutput) { op := &request.Operation{ Name: opReplaceRoute, @@ -18083,7 +20358,7 @@ func (c *EC2) ReplaceRouteRequest(input *ReplaceRouteInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReplaceRoute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRoute func (c *EC2) ReplaceRoute(input *ReplaceRouteInput) (*ReplaceRouteOutput, error) { req, out := c.ReplaceRouteRequest(input) return out, req.Send() @@ -18130,7 +20405,7 @@ const opReplaceRouteTableAssociation = "ReplaceRouteTableAssociation" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociation func (c *EC2) ReplaceRouteTableAssociationRequest(input *ReplaceRouteTableAssociationInput) (req *request.Request, output *ReplaceRouteTableAssociationOutput) { op := &request.Operation{ Name: opReplaceRouteTableAssociation, @@ -18165,7 +20440,7 @@ func (c *EC2) ReplaceRouteTableAssociationRequest(input *ReplaceRouteTableAssoci // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReplaceRouteTableAssociation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociation func (c *EC2) ReplaceRouteTableAssociation(input *ReplaceRouteTableAssociationInput) (*ReplaceRouteTableAssociationOutput, error) { req, out := c.ReplaceRouteTableAssociationRequest(input) return out, req.Send() @@ -18212,7 +20487,7 @@ const opReportInstanceStatus = "ReportInstanceStatus" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatus func (c *EC2) ReportInstanceStatusRequest(input *ReportInstanceStatusInput) (req *request.Request, output *ReportInstanceStatusOutput) { op := &request.Operation{ Name: opReportInstanceStatus, @@ -18247,7 +20522,7 @@ func (c *EC2) ReportInstanceStatusRequest(input *ReportInstanceStatusInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ReportInstanceStatus for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatus func (c *EC2) ReportInstanceStatus(input *ReportInstanceStatusInput) (*ReportInstanceStatusOutput, error) { req, out := c.ReportInstanceStatusRequest(input) return out, req.Send() @@ -18294,7 +20569,7 @@ const opRequestSpotFleet = "RequestSpotFleet" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleet func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *request.Request, output *RequestSpotFleetOutput) { op := &request.Operation{ Name: opRequestSpotFleet, @@ -18313,21 +20588,24 @@ func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *reques // RequestSpotFleet API operation for Amazon Elastic Compute Cloud. // -// Creates a Spot fleet request. +// Creates a Spot Fleet request. // // You can submit a single request that includes multiple launch specifications // that vary by instance type, AMI, Availability Zone, or subnet. // -// By default, the Spot fleet requests Spot instances in the Spot pool where +// By default, the Spot Fleet requests Spot Instances in the Spot pool where // the price per unit is the lowest. Each launch specification can include its // own instance weighting that reflects the value of the instance type to your // application workload. // -// Alternatively, you can specify that the Spot fleet distribute the target +// Alternatively, you can specify that the Spot Fleet distribute the target // capacity across the Spot pools included in its launch specifications. By -// ensuring that the Spot instances in your Spot fleet are in different Spot +// ensuring that the Spot Instances in your Spot Fleet are in different Spot // pools, you can improve the availability of your fleet. // +// You can specify tags for the Spot Instances. You cannot tag other resource +// types in a Spot Fleet request; only the instance resource type is supported. +// // For more information, see Spot Fleet Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet-requests.html) // in the Amazon Elastic Compute Cloud User Guide. // @@ -18337,7 +20615,7 @@ func (c *EC2) RequestSpotFleetRequest(input *RequestSpotFleetInput) (req *reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RequestSpotFleet for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleet func (c *EC2) RequestSpotFleet(input *RequestSpotFleetInput) (*RequestSpotFleetOutput, error) { req, out := c.RequestSpotFleetRequest(input) return out, req.Send() @@ -18384,7 +20662,7 @@ const opRequestSpotInstances = "RequestSpotInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstances func (c *EC2) RequestSpotInstancesRequest(input *RequestSpotInstancesInput) (req *request.Request, output *RequestSpotInstancesOutput) { op := &request.Operation{ Name: opRequestSpotInstances, @@ -18403,11 +20681,9 @@ func (c *EC2) RequestSpotInstancesRequest(input *RequestSpotInstancesInput) (req // RequestSpotInstances API operation for Amazon Elastic Compute Cloud. // -// Creates a Spot instance request. Spot instances are instances that Amazon -// EC2 launches when the bid price that you specify exceeds the current Spot -// price. Amazon EC2 periodically sets the Spot price based on available Spot -// Instance capacity and current Spot instance requests. For more information, -// see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) +// Creates a Spot Instance request. Spot Instances are instances that Amazon +// EC2 launches when the maximum price that you specify exceeds the current +// Spot price. For more information, see Spot Instance Requests (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html) // in the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -18416,7 +20692,7 @@ func (c *EC2) RequestSpotInstancesRequest(input *RequestSpotInstancesInput) (req // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RequestSpotInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstances func (c *EC2) RequestSpotInstances(input *RequestSpotInstancesInput) (*RequestSpotInstancesOutput, error) { req, out := c.RequestSpotInstancesRequest(input) return out, req.Send() @@ -18438,6 +20714,81 @@ func (c *EC2) RequestSpotInstancesWithContext(ctx aws.Context, input *RequestSpo return out, req.Send() } +const opResetFpgaImageAttribute = "ResetFpgaImageAttribute" + +// ResetFpgaImageAttributeRequest generates a "aws/request.Request" representing the +// client's request for the ResetFpgaImageAttribute operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ResetFpgaImageAttribute for more information on using the ResetFpgaImageAttribute +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ResetFpgaImageAttributeRequest method. +// req, resp := client.ResetFpgaImageAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetFpgaImageAttribute +func (c *EC2) ResetFpgaImageAttributeRequest(input *ResetFpgaImageAttributeInput) (req *request.Request, output *ResetFpgaImageAttributeOutput) { + op := &request.Operation{ + Name: opResetFpgaImageAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ResetFpgaImageAttributeInput{} + } + + output = &ResetFpgaImageAttributeOutput{} + req = c.newRequest(op, input, output) + return +} + +// ResetFpgaImageAttribute API operation for Amazon Elastic Compute Cloud. +// +// Resets the specified attribute of the specified Amazon FPGA Image (AFI) to +// its default value. You can only reset the load permission attribute. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation ResetFpgaImageAttribute for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetFpgaImageAttribute +func (c *EC2) ResetFpgaImageAttribute(input *ResetFpgaImageAttributeInput) (*ResetFpgaImageAttributeOutput, error) { + req, out := c.ResetFpgaImageAttributeRequest(input) + return out, req.Send() +} + +// ResetFpgaImageAttributeWithContext is the same as ResetFpgaImageAttribute with the addition of +// the ability to pass a context and additional request options. +// +// See ResetFpgaImageAttribute for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) ResetFpgaImageAttributeWithContext(ctx aws.Context, input *ResetFpgaImageAttributeInput, opts ...request.Option) (*ResetFpgaImageAttributeOutput, error) { + req, out := c.ResetFpgaImageAttributeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opResetImageAttribute = "ResetImageAttribute" // ResetImageAttributeRequest generates a "aws/request.Request" representing the @@ -18463,7 +20814,7 @@ const opResetImageAttribute = "ResetImageAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttribute func (c *EC2) ResetImageAttributeRequest(input *ResetImageAttributeInput) (req *request.Request, output *ResetImageAttributeOutput) { op := &request.Operation{ Name: opResetImageAttribute, @@ -18494,7 +20845,7 @@ func (c *EC2) ResetImageAttributeRequest(input *ResetImageAttributeInput) (req * // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ResetImageAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttribute func (c *EC2) ResetImageAttribute(input *ResetImageAttributeInput) (*ResetImageAttributeOutput, error) { req, out := c.ResetImageAttributeRequest(input) return out, req.Send() @@ -18541,7 +20892,7 @@ const opResetInstanceAttribute = "ResetInstanceAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttribute func (c *EC2) ResetInstanceAttributeRequest(input *ResetInstanceAttributeInput) (req *request.Request, output *ResetInstanceAttributeOutput) { op := &request.Operation{ Name: opResetInstanceAttribute, @@ -18578,7 +20929,7 @@ func (c *EC2) ResetInstanceAttributeRequest(input *ResetInstanceAttributeInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ResetInstanceAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttribute func (c *EC2) ResetInstanceAttribute(input *ResetInstanceAttributeInput) (*ResetInstanceAttributeOutput, error) { req, out := c.ResetInstanceAttributeRequest(input) return out, req.Send() @@ -18625,7 +20976,7 @@ const opResetNetworkInterfaceAttribute = "ResetNetworkInterfaceAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttribute func (c *EC2) ResetNetworkInterfaceAttributeRequest(input *ResetNetworkInterfaceAttributeInput) (req *request.Request, output *ResetNetworkInterfaceAttributeOutput) { op := &request.Operation{ Name: opResetNetworkInterfaceAttribute, @@ -18655,7 +21006,7 @@ func (c *EC2) ResetNetworkInterfaceAttributeRequest(input *ResetNetworkInterface // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ResetNetworkInterfaceAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttribute func (c *EC2) ResetNetworkInterfaceAttribute(input *ResetNetworkInterfaceAttributeInput) (*ResetNetworkInterfaceAttributeOutput, error) { req, out := c.ResetNetworkInterfaceAttributeRequest(input) return out, req.Send() @@ -18702,7 +21053,7 @@ const opResetSnapshotAttribute = "ResetSnapshotAttribute" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttribute func (c *EC2) ResetSnapshotAttributeRequest(input *ResetSnapshotAttributeInput) (req *request.Request, output *ResetSnapshotAttributeOutput) { op := &request.Operation{ Name: opResetSnapshotAttribute, @@ -18735,7 +21086,7 @@ func (c *EC2) ResetSnapshotAttributeRequest(input *ResetSnapshotAttributeInput) // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation ResetSnapshotAttribute for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttribute func (c *EC2) ResetSnapshotAttribute(input *ResetSnapshotAttributeInput) (*ResetSnapshotAttributeOutput, error) { req, out := c.ResetSnapshotAttributeRequest(input) return out, req.Send() @@ -18782,7 +21133,7 @@ const opRestoreAddressToClassic = "RestoreAddressToClassic" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassic +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassic func (c *EC2) RestoreAddressToClassicRequest(input *RestoreAddressToClassicInput) (req *request.Request, output *RestoreAddressToClassicOutput) { op := &request.Operation{ Name: opRestoreAddressToClassic, @@ -18812,7 +21163,7 @@ func (c *EC2) RestoreAddressToClassicRequest(input *RestoreAddressToClassicInput // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RestoreAddressToClassic for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassic +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassic func (c *EC2) RestoreAddressToClassic(input *RestoreAddressToClassicInput) (*RestoreAddressToClassicOutput, error) { req, out := c.RestoreAddressToClassicRequest(input) return out, req.Send() @@ -18859,7 +21210,7 @@ const opRevokeSecurityGroupEgress = "RevokeSecurityGroupEgress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgress func (c *EC2) RevokeSecurityGroupEgressRequest(input *RevokeSecurityGroupEgressInput) (req *request.Request, output *RevokeSecurityGroupEgressOutput) { op := &request.Operation{ Name: opRevokeSecurityGroupEgress, @@ -18882,13 +21233,14 @@ func (c *EC2) RevokeSecurityGroupEgressRequest(input *RevokeSecurityGroupEgressI // // [EC2-VPC only] Removes one or more egress rules from a security group for // EC2-VPC. This action doesn't apply to security groups for use in EC2-Classic. -// The values that you specify in the revoke request (for example, ports) must -// match the existing rule's values for the rule to be revoked. +// To remove a rule, the values that you specify (for example, ports) must match +// the existing rule's values exactly. // // Each rule consists of the protocol and the IPv4 or IPv6 CIDR range or source // security group. For the TCP and UDP protocols, you must also specify the // destination port or range of ports. For the ICMP protocol, you must also -// specify the ICMP type and code. +// specify the ICMP type and code. If the security group rule has a description, +// you do not have to specify the description to revoke the rule. // // Rule changes are propagated to instances within the security group as quickly // as possible. However, a small delay might occur. @@ -18899,7 +21251,7 @@ func (c *EC2) RevokeSecurityGroupEgressRequest(input *RevokeSecurityGroupEgressI // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RevokeSecurityGroupEgress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgress func (c *EC2) RevokeSecurityGroupEgress(input *RevokeSecurityGroupEgressInput) (*RevokeSecurityGroupEgressOutput, error) { req, out := c.RevokeSecurityGroupEgressRequest(input) return out, req.Send() @@ -18946,7 +21298,7 @@ const opRevokeSecurityGroupIngress = "RevokeSecurityGroupIngress" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngress func (c *EC2) RevokeSecurityGroupIngressRequest(input *RevokeSecurityGroupIngressInput) (req *request.Request, output *RevokeSecurityGroupIngressOutput) { op := &request.Operation{ Name: opRevokeSecurityGroupIngress, @@ -18967,14 +21319,19 @@ func (c *EC2) RevokeSecurityGroupIngressRequest(input *RevokeSecurityGroupIngres // RevokeSecurityGroupIngress API operation for Amazon Elastic Compute Cloud. // -// Removes one or more ingress rules from a security group. The values that -// you specify in the revoke request (for example, ports) must match the existing -// rule's values for the rule to be removed. +// Removes one or more ingress rules from a security group. To remove a rule, +// the values that you specify (for example, ports) must match the existing +// rule's values exactly. +// +// [EC2-Classic security groups only] If the values you specify do not match +// the existing rule's values, no error is returned. Use DescribeSecurityGroups +// to verify that the rule has been removed. // // Each rule consists of the protocol and the CIDR range or source security // group. For the TCP and UDP protocols, you must also specify the destination // port or range of ports. For the ICMP protocol, you must also specify the -// ICMP type and code. +// ICMP type and code. If the security group rule has a description, you do +// not have to specify the description to revoke the rule. // // Rule changes are propagated to instances within the security group as quickly // as possible. However, a small delay might occur. @@ -18985,7 +21342,7 @@ func (c *EC2) RevokeSecurityGroupIngressRequest(input *RevokeSecurityGroupIngres // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RevokeSecurityGroupIngress for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngress func (c *EC2) RevokeSecurityGroupIngress(input *RevokeSecurityGroupIngressInput) (*RevokeSecurityGroupIngressOutput, error) { req, out := c.RevokeSecurityGroupIngressRequest(input) return out, req.Send() @@ -19032,7 +21389,7 @@ const opRunInstances = "RunInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstances func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *request.Request, output *Reservation) { op := &request.Operation{ Name: opRunInstances, @@ -19081,9 +21438,14 @@ func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *request.Reques // * If any of the AMIs have a product code attached for which the user has // not subscribed, the request fails. // +// You can create a launch template (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html), +// which is a resource that contains the parameters to launch an instance. When +// you launch an instance using RunInstances, you can specify the launch template +// instead of specifying the launch parameters. +// // To ensure faster instance launches, break up large requests into smaller -// batches. For example, create 5 separate launch requests for 100 instances -// each instead of 1 launch request for 500 instances. +// batches. For example, create five separate launch requests for 100 instances +// each instead of one launch request for 500 instances. // // An instance is ready for you to use when it's in the running state. You can // check the state of your instance using DescribeInstances. You can tag instances @@ -19107,7 +21469,7 @@ func (c *EC2) RunInstancesRequest(input *RunInstancesInput) (req *request.Reques // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RunInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstances func (c *EC2) RunInstances(input *RunInstancesInput) (*Reservation, error) { req, out := c.RunInstancesRequest(input) return out, req.Send() @@ -19154,7 +21516,7 @@ const opRunScheduledInstances = "RunScheduledInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstances func (c *EC2) RunScheduledInstancesRequest(input *RunScheduledInstancesInput) (req *request.Request, output *RunScheduledInstancesOutput) { op := &request.Operation{ Name: opRunScheduledInstances, @@ -19191,7 +21553,7 @@ func (c *EC2) RunScheduledInstancesRequest(input *RunScheduledInstancesInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation RunScheduledInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstances func (c *EC2) RunScheduledInstances(input *RunScheduledInstancesInput) (*RunScheduledInstancesOutput, error) { req, out := c.RunScheduledInstancesRequest(input) return out, req.Send() @@ -19238,7 +21600,7 @@ const opStartInstances = "StartInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstances func (c *EC2) StartInstancesRequest(input *StartInstancesInput) (req *request.Request, output *StartInstancesOutput) { op := &request.Operation{ Name: opStartInstances, @@ -19257,16 +21619,20 @@ func (c *EC2) StartInstancesRequest(input *StartInstancesInput) (req *request.Re // StartInstances API operation for Amazon Elastic Compute Cloud. // -// Starts an Amazon EBS-backed AMI that you've previously stopped. +// Starts an Amazon EBS-backed instance that you've previously stopped. // // Instances that use Amazon EBS volumes as their root devices can be quickly // stopped and started. When an instance is stopped, the compute resources are -// released and you are not billed for hourly instance usage. However, your -// root partition Amazon EBS volume remains, continues to persist your data, -// and you are charged for Amazon EBS volume usage. You can restart your instance -// at any time. Each time you transition an instance from stopped to started, -// Amazon EC2 charges a full instance hour, even if transitions happen multiple -// times within a single hour. +// released and you are not billed for instance usage. However, your root partition +// Amazon EBS volume remains and continues to persist your data, and you are +// charged for Amazon EBS volume usage. You can restart your instance at any +// time. Every time you start your Windows instance, Amazon EC2 charges you +// for a full instance hour. If you stop and restart your Windows instance, +// a new instance hour begins and Amazon EC2 charges you for another full instance +// hour even if you are still within the same 60-minute period when it was stopped. +// Every time you start your Linux instance, Amazon EC2 charges a one-minute +// minimum for instance usage, and thereafter charges per second for instance +// usage. // // Before stopping an instance, make sure it is in a state from which it can // be restarted. Stopping an instance does not preserve data stored in RAM. @@ -19283,7 +21649,7 @@ func (c *EC2) StartInstancesRequest(input *StartInstancesInput) (req *request.Re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation StartInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstances func (c *EC2) StartInstances(input *StartInstancesInput) (*StartInstancesOutput, error) { req, out := c.StartInstancesRequest(input) return out, req.Send() @@ -19330,7 +21696,7 @@ const opStopInstances = "StopInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstances func (c *EC2) StopInstancesRequest(input *StopInstancesInput) (req *request.Request, output *StopInstancesOutput) { op := &request.Operation{ Name: opStopInstances, @@ -19351,14 +21717,17 @@ func (c *EC2) StopInstancesRequest(input *StopInstancesInput) (req *request.Requ // // Stops an Amazon EBS-backed instance. // -// We don't charge hourly usage for a stopped instance, or data transfer fees; -// however, your root partition Amazon EBS volume remains, continues to persist -// your data, and you are charged for Amazon EBS volume usage. Each time you -// transition an instance from stopped to started, Amazon EC2 charges a full -// instance hour, even if transitions happen multiple times within a single -// hour. +// We don't charge usage for a stopped instance, or data transfer fees; however, +// your root partition Amazon EBS volume remains and continues to persist your +// data, and you are charged for Amazon EBS volume usage. Every time you start +// your Windows instance, Amazon EC2 charges you for a full instance hour. If +// you stop and restart your Windows instance, a new instance hour begins and +// Amazon EC2 charges you for another full instance hour even if you are still +// within the same 60-minute period when it was stopped. Every time you start +// your Linux instance, Amazon EC2 charges a one-minute minimum for instance +// usage, and thereafter charges per second for instance usage. // -// You can't start or stop Spot instances, and you can't stop instance store-backed +// You can't start or stop Spot Instances, and you can't stop instance store-backed // instances. // // When you stop an instance, we shut it down. You can restart your instance @@ -19386,7 +21755,7 @@ func (c *EC2) StopInstancesRequest(input *StopInstancesInput) (req *request.Requ // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation StopInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstances func (c *EC2) StopInstances(input *StopInstancesInput) (*StopInstancesOutput, error) { req, out := c.StopInstancesRequest(input) return out, req.Send() @@ -19433,7 +21802,7 @@ const opTerminateInstances = "TerminateInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstances func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *request.Request, output *TerminateInstancesOutput) { op := &request.Operation{ Name: opTerminateInstances, @@ -19484,7 +21853,7 @@ func (c *EC2) TerminateInstancesRequest(input *TerminateInstancesInput) (req *re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation TerminateInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstances func (c *EC2) TerminateInstances(input *TerminateInstancesInput) (*TerminateInstancesOutput, error) { req, out := c.TerminateInstancesRequest(input) return out, req.Send() @@ -19531,7 +21900,7 @@ const opUnassignIpv6Addresses = "UnassignIpv6Addresses" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6Addresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6Addresses func (c *EC2) UnassignIpv6AddressesRequest(input *UnassignIpv6AddressesInput) (req *request.Request, output *UnassignIpv6AddressesOutput) { op := &request.Operation{ Name: opUnassignIpv6Addresses, @@ -19558,7 +21927,7 @@ func (c *EC2) UnassignIpv6AddressesRequest(input *UnassignIpv6AddressesInput) (r // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation UnassignIpv6Addresses for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6Addresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6Addresses func (c *EC2) UnassignIpv6Addresses(input *UnassignIpv6AddressesInput) (*UnassignIpv6AddressesOutput, error) { req, out := c.UnassignIpv6AddressesRequest(input) return out, req.Send() @@ -19605,7 +21974,7 @@ const opUnassignPrivateIpAddresses = "UnassignPrivateIpAddresses" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddresses func (c *EC2) UnassignPrivateIpAddressesRequest(input *UnassignPrivateIpAddressesInput) (req *request.Request, output *UnassignPrivateIpAddressesOutput) { op := &request.Operation{ Name: opUnassignPrivateIpAddresses, @@ -19634,7 +22003,7 @@ func (c *EC2) UnassignPrivateIpAddressesRequest(input *UnassignPrivateIpAddresse // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation UnassignPrivateIpAddresses for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddresses +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddresses func (c *EC2) UnassignPrivateIpAddresses(input *UnassignPrivateIpAddressesInput) (*UnassignPrivateIpAddressesOutput, error) { req, out := c.UnassignPrivateIpAddressesRequest(input) return out, req.Send() @@ -19681,7 +22050,7 @@ const opUnmonitorInstances = "UnmonitorInstances" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstances func (c *EC2) UnmonitorInstancesRequest(input *UnmonitorInstancesInput) (req *request.Request, output *UnmonitorInstancesOutput) { op := &request.Operation{ Name: opUnmonitorInstances, @@ -19710,7 +22079,7 @@ func (c *EC2) UnmonitorInstancesRequest(input *UnmonitorInstancesInput) (req *re // // See the AWS API reference guide for Amazon Elastic Compute Cloud's // API operation UnmonitorInstances for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstances func (c *EC2) UnmonitorInstances(input *UnmonitorInstancesInput) (*UnmonitorInstancesOutput, error) { req, out := c.UnmonitorInstancesRequest(input) return out, req.Send() @@ -19732,8 +22101,168 @@ func (c *EC2) UnmonitorInstancesWithContext(ctx aws.Context, input *UnmonitorIns return out, req.Send() } +const opUpdateSecurityGroupRuleDescriptionsEgress = "UpdateSecurityGroupRuleDescriptionsEgress" + +// UpdateSecurityGroupRuleDescriptionsEgressRequest generates a "aws/request.Request" representing the +// client's request for the UpdateSecurityGroupRuleDescriptionsEgress operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateSecurityGroupRuleDescriptionsEgress for more information on using the UpdateSecurityGroupRuleDescriptionsEgress +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateSecurityGroupRuleDescriptionsEgressRequest method. +// req, resp := client.UpdateSecurityGroupRuleDescriptionsEgressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsEgress +func (c *EC2) UpdateSecurityGroupRuleDescriptionsEgressRequest(input *UpdateSecurityGroupRuleDescriptionsEgressInput) (req *request.Request, output *UpdateSecurityGroupRuleDescriptionsEgressOutput) { + op := &request.Operation{ + Name: opUpdateSecurityGroupRuleDescriptionsEgress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateSecurityGroupRuleDescriptionsEgressInput{} + } + + output = &UpdateSecurityGroupRuleDescriptionsEgressOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateSecurityGroupRuleDescriptionsEgress API operation for Amazon Elastic Compute Cloud. +// +// [EC2-VPC only] Updates the description of an egress (outbound) security group +// rule. You can replace an existing description, or add a description to a +// rule that did not have one previously. +// +// You specify the description as part of the IP permissions structure. You +// can remove a description for a security group rule by omitting the description +// parameter in the request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation UpdateSecurityGroupRuleDescriptionsEgress for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsEgress +func (c *EC2) UpdateSecurityGroupRuleDescriptionsEgress(input *UpdateSecurityGroupRuleDescriptionsEgressInput) (*UpdateSecurityGroupRuleDescriptionsEgressOutput, error) { + req, out := c.UpdateSecurityGroupRuleDescriptionsEgressRequest(input) + return out, req.Send() +} + +// UpdateSecurityGroupRuleDescriptionsEgressWithContext is the same as UpdateSecurityGroupRuleDescriptionsEgress with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateSecurityGroupRuleDescriptionsEgress for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) UpdateSecurityGroupRuleDescriptionsEgressWithContext(ctx aws.Context, input *UpdateSecurityGroupRuleDescriptionsEgressInput, opts ...request.Option) (*UpdateSecurityGroupRuleDescriptionsEgressOutput, error) { + req, out := c.UpdateSecurityGroupRuleDescriptionsEgressRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateSecurityGroupRuleDescriptionsIngress = "UpdateSecurityGroupRuleDescriptionsIngress" + +// UpdateSecurityGroupRuleDescriptionsIngressRequest generates a "aws/request.Request" representing the +// client's request for the UpdateSecurityGroupRuleDescriptionsIngress operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateSecurityGroupRuleDescriptionsIngress for more information on using the UpdateSecurityGroupRuleDescriptionsIngress +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateSecurityGroupRuleDescriptionsIngressRequest method. +// req, resp := client.UpdateSecurityGroupRuleDescriptionsIngressRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsIngress +func (c *EC2) UpdateSecurityGroupRuleDescriptionsIngressRequest(input *UpdateSecurityGroupRuleDescriptionsIngressInput) (req *request.Request, output *UpdateSecurityGroupRuleDescriptionsIngressOutput) { + op := &request.Operation{ + Name: opUpdateSecurityGroupRuleDescriptionsIngress, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateSecurityGroupRuleDescriptionsIngressInput{} + } + + output = &UpdateSecurityGroupRuleDescriptionsIngressOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateSecurityGroupRuleDescriptionsIngress API operation for Amazon Elastic Compute Cloud. +// +// Updates the description of an ingress (inbound) security group rule. You +// can replace an existing description, or add a description to a rule that +// did not have one previously. +// +// You specify the description as part of the IP permissions structure. You +// can remove a description for a security group rule by omitting the description +// parameter in the request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Elastic Compute Cloud's +// API operation UpdateSecurityGroupRuleDescriptionsIngress for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsIngress +func (c *EC2) UpdateSecurityGroupRuleDescriptionsIngress(input *UpdateSecurityGroupRuleDescriptionsIngressInput) (*UpdateSecurityGroupRuleDescriptionsIngressOutput, error) { + req, out := c.UpdateSecurityGroupRuleDescriptionsIngressRequest(input) + return out, req.Send() +} + +// UpdateSecurityGroupRuleDescriptionsIngressWithContext is the same as UpdateSecurityGroupRuleDescriptionsIngress with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateSecurityGroupRuleDescriptionsIngress for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) UpdateSecurityGroupRuleDescriptionsIngressWithContext(ctx aws.Context, input *UpdateSecurityGroupRuleDescriptionsIngressInput, opts ...request.Option) (*UpdateSecurityGroupRuleDescriptionsIngressOutput, error) { + req, out := c.UpdateSecurityGroupRuleDescriptionsIngressRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + // Contains the parameters for accepting the quote. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuoteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuoteRequest type AcceptReservedInstancesExchangeQuoteInput struct { _ struct{} `type:"structure"` @@ -19743,14 +22272,14 @@ type AcceptReservedInstancesExchangeQuoteInput struct { // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` - // The IDs of the Convertible Reserved Instances to exchange for other Convertible - // Reserved Instances of the same or higher value. + // The IDs of the Convertible Reserved Instances to exchange for another Convertible + // Reserved Instance of the same or higher value. // // ReservedInstanceIds is a required field ReservedInstanceIds []*string `locationName:"ReservedInstanceId" locationNameList:"ReservedInstanceId" type:"list" required:"true"` - // The configurations of the Convertible Reserved Instance offerings that you - // are purchasing in this exchange. + // The configuration of the target Convertible Reserved Instance to exchange + // for your current Convertible Reserved Instances. TargetConfigurations []*TargetConfigurationRequest `locationName:"TargetConfiguration" locationNameList:"TargetConfigurationRequest" type:"list"` } @@ -19806,7 +22335,7 @@ func (s *AcceptReservedInstancesExchangeQuoteInput) SetTargetConfigurations(v [] } // The result of the exchange and whether it was successful. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuoteResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuoteResult type AcceptReservedInstancesExchangeQuoteOutput struct { _ struct{} `type:"structure"` @@ -19830,8 +22359,97 @@ func (s *AcceptReservedInstancesExchangeQuoteOutput) SetExchangeId(v string) *Ac return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcEndpointConnectionsRequest +type AcceptVpcEndpointConnectionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the endpoint service. + // + // ServiceId is a required field + ServiceId *string `type:"string" required:"true"` + + // The IDs of one or more interface VPC endpoints. + // + // VpcEndpointIds is a required field + VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s AcceptVpcEndpointConnectionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AcceptVpcEndpointConnectionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AcceptVpcEndpointConnectionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AcceptVpcEndpointConnectionsInput"} + if s.ServiceId == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceId")) + } + if s.VpcEndpointIds == nil { + invalidParams.Add(request.NewErrParamRequired("VpcEndpointIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *AcceptVpcEndpointConnectionsInput) SetDryRun(v bool) *AcceptVpcEndpointConnectionsInput { + s.DryRun = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *AcceptVpcEndpointConnectionsInput) SetServiceId(v string) *AcceptVpcEndpointConnectionsInput { + s.ServiceId = &v + return s +} + +// SetVpcEndpointIds sets the VpcEndpointIds field's value. +func (s *AcceptVpcEndpointConnectionsInput) SetVpcEndpointIds(v []*string) *AcceptVpcEndpointConnectionsInput { + s.VpcEndpointIds = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcEndpointConnectionsResult +type AcceptVpcEndpointConnectionsOutput struct { + _ struct{} `type:"structure"` + + // Information about the interface endpoints that were not accepted, if applicable. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s AcceptVpcEndpointConnectionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AcceptVpcEndpointConnectionsOutput) GoString() string { + return s.String() +} + +// SetUnsuccessful sets the Unsuccessful field's value. +func (s *AcceptVpcEndpointConnectionsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *AcceptVpcEndpointConnectionsOutput { + s.Unsuccessful = v + return s +} + // Contains the parameters for AcceptVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnectionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnectionRequest type AcceptVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -19841,7 +22459,8 @@ type AcceptVpcPeeringConnectionInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the VPC peering connection. + // The ID of the VPC peering connection. You must specify this parameter in + // the request. VpcPeeringConnectionId *string `locationName:"vpcPeeringConnectionId" type:"string"` } @@ -19868,7 +22487,7 @@ func (s *AcceptVpcPeeringConnectionInput) SetVpcPeeringConnectionId(v string) *A } // Contains the output of AcceptVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnectionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnectionResult type AcceptVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -19893,7 +22512,7 @@ func (s *AcceptVpcPeeringConnectionOutput) SetVpcPeeringConnection(v *VpcPeering } // Describes an account attribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AccountAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AccountAttribute type AccountAttribute struct { _ struct{} `type:"structure"` @@ -19927,7 +22546,7 @@ func (s *AccountAttribute) SetAttributeValues(v []*AccountAttributeValue) *Accou } // Describes a value of an account attribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AccountAttributeValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AccountAttributeValue type AccountAttributeValue struct { _ struct{} `type:"structure"` @@ -19951,8 +22570,8 @@ func (s *AccountAttributeValue) SetAttributeValue(v string) *AccountAttributeVal return s } -// Describes a running instance in a Spot fleet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ActiveInstance +// Describes a running instance in a Spot Fleet. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ActiveInstance type ActiveInstance struct { _ struct{} `type:"structure"` @@ -19967,7 +22586,7 @@ type ActiveInstance struct { // The instance type. InstanceType *string `locationName:"instanceType" type:"string"` - // The ID of the Spot instance request. + // The ID of the Spot Instance request. SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` } @@ -20006,7 +22625,7 @@ func (s *ActiveInstance) SetSpotInstanceRequestId(v string) *ActiveInstance { } // Describes an Elastic IP address. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Address +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Address type Address struct { _ struct{} `type:"structure"` @@ -20035,6 +22654,9 @@ type Address struct { // The Elastic IP address. PublicIp *string `locationName:"publicIp" type:"string"` + + // Any tags assigned to the Elastic IP address. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` } // String returns the string representation @@ -20095,11 +22717,20 @@ func (s *Address) SetPublicIp(v string) *Address { return s } +// SetTags sets the Tags field's value. +func (s *Address) SetTags(v []*Tag) *Address { + s.Tags = v + return s +} + // Contains the parameters for AllocateAddress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddressRequest type AllocateAddressInput struct { _ struct{} `type:"structure"` + // [EC2-VPC] The Elastic IP address to recover. + Address *string `type:"string"` + // Set to vpc to allocate the address for use with instances in a VPC. // // Default: The address is for use with instances in EC2-Classic. @@ -20122,6 +22753,12 @@ func (s AllocateAddressInput) GoString() string { return s.String() } +// SetAddress sets the Address field's value. +func (s *AllocateAddressInput) SetAddress(v string) *AllocateAddressInput { + s.Address = &v + return s +} + // SetDomain sets the Domain field's value. func (s *AllocateAddressInput) SetDomain(v string) *AllocateAddressInput { s.Domain = &v @@ -20135,7 +22772,7 @@ func (s *AllocateAddressInput) SetDryRun(v bool) *AllocateAddressInput { } // Contains the output of AllocateAddress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddressResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddressResult type AllocateAddressOutput struct { _ struct{} `type:"structure"` @@ -20180,7 +22817,7 @@ func (s *AllocateAddressOutput) SetPublicIp(v string) *AllocateAddressOutput { } // Contains the parameters for AllocateHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHostsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHostsRequest type AllocateHostsInput struct { _ struct{} `type:"structure"` @@ -20275,7 +22912,7 @@ func (s *AllocateHostsInput) SetQuantity(v int64) *AllocateHostsInput { } // Contains the output of AllocateHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHostsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHostsResult type AllocateHostsOutput struct { _ struct{} `type:"structure"` @@ -20300,7 +22937,41 @@ func (s *AllocateHostsOutput) SetHostIds(v []*string) *AllocateHostsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6AddressesRequest +// Describes a principal. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllowedPrincipal +type AllowedPrincipal struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the principal. + Principal *string `locationName:"principal" type:"string"` + + // The type of principal. + PrincipalType *string `locationName:"principalType" type:"string" enum:"PrincipalType"` +} + +// String returns the string representation +func (s AllowedPrincipal) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllowedPrincipal) GoString() string { + return s.String() +} + +// SetPrincipal sets the Principal field's value. +func (s *AllowedPrincipal) SetPrincipal(v string) *AllowedPrincipal { + s.Principal = &v + return s +} + +// SetPrincipalType sets the PrincipalType field's value. +func (s *AllowedPrincipal) SetPrincipalType(v string) *AllowedPrincipal { + s.PrincipalType = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6AddressesRequest type AssignIpv6AddressesInput struct { _ struct{} `type:"structure"` @@ -20360,7 +23031,7 @@ func (s *AssignIpv6AddressesInput) SetNetworkInterfaceId(v string) *AssignIpv6Ad return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6AddressesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6AddressesResult type AssignIpv6AddressesOutput struct { _ struct{} `type:"structure"` @@ -20394,7 +23065,7 @@ func (s *AssignIpv6AddressesOutput) SetNetworkInterfaceId(v string) *AssignIpv6A } // Contains the parameters for AssignPrivateIpAddresses. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddressesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddressesRequest type AssignPrivateIpAddressesInput struct { _ struct{} `type:"structure"` @@ -20467,7 +23138,7 @@ func (s *AssignPrivateIpAddressesInput) SetSecondaryPrivateIpAddressCount(v int6 return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddressesOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddressesOutput type AssignPrivateIpAddressesOutput struct { _ struct{} `type:"structure"` } @@ -20483,7 +23154,7 @@ func (s AssignPrivateIpAddressesOutput) GoString() string { } // Contains the parameters for AssociateAddress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddressRequest type AssociateAddressInput struct { _ struct{} `type:"structure"` @@ -20576,7 +23247,7 @@ func (s *AssociateAddressInput) SetPublicIp(v string) *AssociateAddressInput { } // Contains the output of AssociateAddress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddressResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddressResult type AssociateAddressOutput struct { _ struct{} `type:"structure"` @@ -20602,7 +23273,7 @@ func (s *AssociateAddressOutput) SetAssociationId(v string) *AssociateAddressOut } // Contains the parameters for AssociateDhcpOptions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptionsRequest type AssociateDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -20668,7 +23339,7 @@ func (s *AssociateDhcpOptionsInput) SetVpcId(v string) *AssociateDhcpOptionsInpu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptionsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptionsOutput type AssociateDhcpOptionsOutput struct { _ struct{} `type:"structure"` } @@ -20683,7 +23354,7 @@ func (s AssociateDhcpOptionsOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfileRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfileRequest type AssociateIamInstanceProfileInput struct { _ struct{} `type:"structure"` @@ -20736,7 +23407,7 @@ func (s *AssociateIamInstanceProfileInput) SetInstanceId(v string) *AssociateIam return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfileResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfileResult type AssociateIamInstanceProfileOutput struct { _ struct{} `type:"structure"` @@ -20761,7 +23432,7 @@ func (s *AssociateIamInstanceProfileOutput) SetIamInstanceProfileAssociation(v * } // Contains the parameters for AssociateRouteTable. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTableRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTableRequest type AssociateRouteTableInput struct { _ struct{} `type:"structure"` @@ -20827,7 +23498,7 @@ func (s *AssociateRouteTableInput) SetSubnetId(v string) *AssociateRouteTableInp } // Contains the output of AssociateRouteTable. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTableResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTableResult type AssociateRouteTableOutput struct { _ struct{} `type:"structure"` @@ -20851,7 +23522,7 @@ func (s *AssociateRouteTableOutput) SetAssociationId(v string) *AssociateRouteTa return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlockRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlockRequest type AssociateSubnetCidrBlockInput struct { _ struct{} `type:"structure"` @@ -20904,7 +23575,7 @@ func (s *AssociateSubnetCidrBlockInput) SetSubnetId(v string) *AssociateSubnetCi return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlockResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlockResult type AssociateSubnetCidrBlockOutput struct { _ struct{} `type:"structure"` @@ -20937,7 +23608,7 @@ func (s *AssociateSubnetCidrBlockOutput) SetSubnetId(v string) *AssociateSubnetC return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlockRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlockRequest type AssociateVpcCidrBlockInput struct { _ struct{} `type:"structure"` @@ -20946,6 +23617,9 @@ type AssociateVpcCidrBlockInput struct { // CIDR block. AmazonProvidedIpv6CidrBlock *bool `locationName:"amazonProvidedIpv6CidrBlock" type:"boolean"` + // An IPv4 CIDR block to associate with the VPC. + CidrBlock *string `type:"string"` + // The ID of the VPC. // // VpcId is a required field @@ -20981,16 +23655,25 @@ func (s *AssociateVpcCidrBlockInput) SetAmazonProvidedIpv6CidrBlock(v bool) *Ass return s } +// SetCidrBlock sets the CidrBlock field's value. +func (s *AssociateVpcCidrBlockInput) SetCidrBlock(v string) *AssociateVpcCidrBlockInput { + s.CidrBlock = &v + return s +} + // SetVpcId sets the VpcId field's value. func (s *AssociateVpcCidrBlockInput) SetVpcId(v string) *AssociateVpcCidrBlockInput { s.VpcId = &v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlockResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlockResult type AssociateVpcCidrBlockOutput struct { _ struct{} `type:"structure"` + // Information about the IPv4 CIDR block association. + CidrBlockAssociation *VpcCidrBlockAssociation `locationName:"cidrBlockAssociation" type:"structure"` + // Information about the IPv6 CIDR block association. Ipv6CidrBlockAssociation *VpcIpv6CidrBlockAssociation `locationName:"ipv6CidrBlockAssociation" type:"structure"` @@ -21008,6 +23691,12 @@ func (s AssociateVpcCidrBlockOutput) GoString() string { return s.String() } +// SetCidrBlockAssociation sets the CidrBlockAssociation field's value. +func (s *AssociateVpcCidrBlockOutput) SetCidrBlockAssociation(v *VpcCidrBlockAssociation) *AssociateVpcCidrBlockOutput { + s.CidrBlockAssociation = v + return s +} + // SetIpv6CidrBlockAssociation sets the Ipv6CidrBlockAssociation field's value. func (s *AssociateVpcCidrBlockOutput) SetIpv6CidrBlockAssociation(v *VpcIpv6CidrBlockAssociation) *AssociateVpcCidrBlockOutput { s.Ipv6CidrBlockAssociation = v @@ -21021,7 +23710,7 @@ func (s *AssociateVpcCidrBlockOutput) SetVpcId(v string) *AssociateVpcCidrBlockO } // Contains the parameters for AttachClassicLinkVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpcRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpcRequest type AttachClassicLinkVpcInput struct { _ struct{} `type:"structure"` @@ -21102,7 +23791,7 @@ func (s *AttachClassicLinkVpcInput) SetVpcId(v string) *AttachClassicLinkVpcInpu } // Contains the output of AttachClassicLinkVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpcResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpcResult type AttachClassicLinkVpcOutput struct { _ struct{} `type:"structure"` @@ -21127,7 +23816,7 @@ func (s *AttachClassicLinkVpcOutput) SetReturn(v bool) *AttachClassicLinkVpcOutp } // Contains the parameters for AttachInternetGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGatewayRequest type AttachInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -21192,7 +23881,7 @@ func (s *AttachInternetGatewayInput) SetVpcId(v string) *AttachInternetGatewayIn return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGatewayOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGatewayOutput type AttachInternetGatewayOutput struct { _ struct{} `type:"structure"` } @@ -21208,7 +23897,7 @@ func (s AttachInternetGatewayOutput) GoString() string { } // Contains the parameters for AttachNetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterfaceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterfaceRequest type AttachNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -21288,7 +23977,7 @@ func (s *AttachNetworkInterfaceInput) SetNetworkInterfaceId(v string) *AttachNet } // Contains the output of AttachNetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterfaceResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterfaceResult type AttachNetworkInterfaceOutput struct { _ struct{} `type:"structure"` @@ -21313,11 +24002,11 @@ func (s *AttachNetworkInterfaceOutput) SetAttachmentId(v string) *AttachNetworkI } // Contains the parameters for AttachVolume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolumeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolumeRequest type AttachVolumeInput struct { _ struct{} `type:"structure"` - // The device name to expose to the instance (for example, /dev/sdh or xvdh). + // The device name (for example, /dev/sdh or xvdh). // // Device is a required field Device *string `type:"string" required:"true"` @@ -21394,7 +24083,7 @@ func (s *AttachVolumeInput) SetVolumeId(v string) *AttachVolumeInput { } // Contains the parameters for AttachVpnGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGatewayRequest type AttachVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -21460,7 +24149,7 @@ func (s *AttachVpnGatewayInput) SetVpnGatewayId(v string) *AttachVpnGatewayInput } // Contains the output of AttachVpnGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGatewayResult type AttachVpnGatewayOutput struct { _ struct{} `type:"structure"` @@ -21485,7 +24174,7 @@ func (s *AttachVpnGatewayOutput) SetVpcAttachment(v *VpcAttachment) *AttachVpnGa } // Describes a value for a resource attribute that is a Boolean value. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttributeBooleanValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttributeBooleanValue type AttributeBooleanValue struct { _ struct{} `type:"structure"` @@ -21510,7 +24199,7 @@ func (s *AttributeBooleanValue) SetValue(v bool) *AttributeBooleanValue { } // Describes a value for a resource attribute that is a String. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttributeValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttributeValue type AttributeValue struct { _ struct{} `type:"structure"` @@ -21535,12 +24224,11 @@ func (s *AttributeValue) SetValue(v string) *AttributeValue { } // Contains the parameters for AuthorizeSecurityGroupEgress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgressRequest type AuthorizeSecurityGroupEgressInput struct { _ struct{} `type:"structure"` - // The CIDR IPv4 address range. We recommend that you specify the CIDR range - // in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the CIDR. CidrIp *string `locationName:"cidrIp" type:"string"` // Checks whether you have the required permissions for the action, without @@ -21549,8 +24237,7 @@ type AuthorizeSecurityGroupEgressInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The start of port range for the TCP and UDP protocols, or an ICMP type number. - // We recommend that you specify the port range in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the port. FromPort *int64 `locationName:"fromPort" type:"integer"` // The ID of the security group. @@ -21558,26 +24245,23 @@ type AuthorizeSecurityGroupEgressInput struct { // GroupId is a required field GroupId *string `locationName:"groupId" type:"string" required:"true"` - // A set of IP permissions. You can't specify a destination security group and - // a CIDR IP address range. + // One or more sets of IP permissions. You can't specify a destination security + // group and a CIDR IP address range in the same set of permissions. IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` - // The IP protocol name or number. We recommend that you specify the protocol - // in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the protocol name or + // number. IpProtocol *string `locationName:"ipProtocol" type:"string"` - // The name of a destination security group. To authorize outbound access to - // a destination security group, we recommend that you use a set of IP permissions - // instead. + // Not supported. Use a set of IP permissions to specify a destination security + // group. SourceSecurityGroupName *string `locationName:"sourceSecurityGroupName" type:"string"` - // The AWS account number for a destination security group. To authorize outbound - // access to a destination security group, we recommend that you use a set of - // IP permissions instead. + // Not supported. Use a set of IP permissions to specify a destination security + // group. SourceSecurityGroupOwnerId *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` - // The end of port range for the TCP and UDP protocols, or an ICMP type number. - // We recommend that you specify the port range in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the port. ToPort *int64 `locationName:"toPort" type:"integer"` } @@ -21658,7 +24342,7 @@ func (s *AuthorizeSecurityGroupEgressInput) SetToPort(v int64) *AuthorizeSecurit return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgressOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgressOutput type AuthorizeSecurityGroupEgressOutput struct { _ struct{} `type:"structure"` } @@ -21674,7 +24358,7 @@ func (s AuthorizeSecurityGroupEgressOutput) GoString() string { } // Contains the parameters for AuthorizeSecurityGroupIngress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngressRequest type AuthorizeSecurityGroupIngressInput struct { _ struct{} `type:"structure"` @@ -21690,16 +24374,20 @@ type AuthorizeSecurityGroupIngressInput struct { // The start of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 // type number. For the ICMP/ICMPv6 type number, use -1 to specify all types. + // If you specify all ICMP/ICMPv6 types, you must specify all codes. FromPort *int64 `type:"integer"` - // The ID of the security group. Required for a nondefault VPC. + // The ID of the security group. You must specify either the security group + // ID or the security group name in the request. For security groups in a nondefault + // VPC, you must specify the security group ID. GroupId *string `type:"string"` - // [EC2-Classic, default VPC] The name of the security group. + // [EC2-Classic, default VPC] The name of the security group. You must specify + // either the security group ID or the security group name in the request. GroupName *string `type:"string"` - // A set of IP permissions. Can be used to specify multiple rules in a single - // command. + // One or more sets of IP permissions. Can be used to specify multiple rules + // in a single command. IpPermissions []*IpPermission `locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). @@ -21719,8 +24407,8 @@ type AuthorizeSecurityGroupIngressInput struct { // be in the same VPC. SourceSecurityGroupName *string `type:"string"` - // [EC2-Classic] The AWS account number for the source security group, if the - // source security group is in a different account. You can't specify this parameter + // [EC2-Classic] The AWS account ID for the source security group, if the source + // security group is in a different account. You can't specify this parameter // in combination with the following parameters: the CIDR IP address range, // the IP protocol, the start of the port range, and the end of the port range. // Creates rules that grant full ICMP, UDP, and TCP access. To create a rule @@ -21728,7 +24416,8 @@ type AuthorizeSecurityGroupIngressInput struct { SourceSecurityGroupOwnerId *string `type:"string"` // The end of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 code - // number. For the ICMP/ICMPv6 code number, use -1 to specify all codes. + // number. For the ICMP/ICMPv6 code number, use -1 to specify all codes. If + // you specify all ICMP/ICMPv6 types, you must specify all codes. ToPort *int64 `type:"integer"` } @@ -21802,7 +24491,7 @@ func (s *AuthorizeSecurityGroupIngressInput) SetToPort(v int64) *AuthorizeSecuri return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngressOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngressOutput type AuthorizeSecurityGroupIngressOutput struct { _ struct{} `type:"structure"` } @@ -21818,7 +24507,7 @@ func (s AuthorizeSecurityGroupIngressOutput) GoString() string { } // Describes an Availability Zone. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailabilityZone +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailabilityZone type AvailabilityZone struct { _ struct{} `type:"structure"` @@ -21870,7 +24559,7 @@ func (s *AvailabilityZone) SetZoneName(v string) *AvailabilityZone { } // Describes a message about an Availability Zone. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailabilityZoneMessage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailabilityZoneMessage type AvailabilityZoneMessage struct { _ struct{} `type:"structure"` @@ -21895,7 +24584,7 @@ func (s *AvailabilityZoneMessage) SetMessage(v string) *AvailabilityZoneMessage } // The capacity information for instances launched onto the Dedicated Host. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailableCapacity +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailableCapacity type AvailableCapacity struct { _ struct{} `type:"structure"` @@ -21928,7 +24617,7 @@ func (s *AvailableCapacity) SetAvailableVCpus(v int64) *AvailableCapacity { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BlobAttributeValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BlobAttributeValue type BlobAttributeValue struct { _ struct{} `type:"structure"` @@ -21953,11 +24642,11 @@ func (s *BlobAttributeValue) SetValue(v []byte) *BlobAttributeValue { } // Describes a block device mapping. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BlockDeviceMapping +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BlockDeviceMapping type BlockDeviceMapping struct { _ struct{} `type:"structure"` - // The device name exposed to the instance (for example, /dev/sdh or xvdh). + // The device name (for example, /dev/sdh or xvdh). DeviceName *string `locationName:"deviceName" type:"string"` // Parameters used to automatically set up EBS volumes when the instance is @@ -22016,7 +24705,7 @@ func (s *BlockDeviceMapping) SetVirtualName(v string) *BlockDeviceMapping { } // Contains the parameters for BundleInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstanceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstanceRequest type BundleInstanceInput struct { _ struct{} `type:"structure"` @@ -22090,7 +24779,7 @@ func (s *BundleInstanceInput) SetStorage(v *Storage) *BundleInstanceInput { } // Contains the output of BundleInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstanceResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstanceResult type BundleInstanceOutput struct { _ struct{} `type:"structure"` @@ -22115,7 +24804,7 @@ func (s *BundleInstanceOutput) SetBundleTask(v *BundleTask) *BundleInstanceOutpu } // Describes a bundle task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleTask type BundleTask struct { _ struct{} `type:"structure"` @@ -22203,7 +24892,7 @@ func (s *BundleTask) SetUpdateTime(v time.Time) *BundleTask { } // Describes an error for BundleInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleTaskError +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleTaskError type BundleTaskError struct { _ struct{} `type:"structure"` @@ -22237,7 +24926,7 @@ func (s *BundleTaskError) SetMessage(v string) *BundleTaskError { } // Contains the parameters for CancelBundleTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTaskRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTaskRequest type CancelBundleTaskInput struct { _ struct{} `type:"structure"` @@ -22289,7 +24978,7 @@ func (s *CancelBundleTaskInput) SetDryRun(v bool) *CancelBundleTaskInput { } // Contains the output of CancelBundleTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTaskResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTaskResult type CancelBundleTaskOutput struct { _ struct{} `type:"structure"` @@ -22314,7 +25003,7 @@ func (s *CancelBundleTaskOutput) SetBundleTask(v *BundleTask) *CancelBundleTaskO } // Contains the parameters for CancelConversionTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionRequest type CancelConversionTaskInput struct { _ struct{} `type:"structure"` @@ -22374,7 +25063,7 @@ func (s *CancelConversionTaskInput) SetReasonMessage(v string) *CancelConversion return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTaskOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTaskOutput type CancelConversionTaskOutput struct { _ struct{} `type:"structure"` } @@ -22390,7 +25079,7 @@ func (s CancelConversionTaskOutput) GoString() string { } // Contains the parameters for CancelExportTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTaskRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTaskRequest type CancelExportTaskInput struct { _ struct{} `type:"structure"` @@ -22429,7 +25118,7 @@ func (s *CancelExportTaskInput) SetExportTaskId(v string) *CancelExportTaskInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTaskOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTaskOutput type CancelExportTaskOutput struct { _ struct{} `type:"structure"` } @@ -22445,7 +25134,7 @@ func (s CancelExportTaskOutput) GoString() string { } // Contains the parameters for CancelImportTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTaskRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTaskRequest type CancelImportTaskInput struct { _ struct{} `type:"structure"` @@ -22491,7 +25180,7 @@ func (s *CancelImportTaskInput) SetImportTaskId(v string) *CancelImportTaskInput } // Contains the output for CancelImportTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTaskResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTaskResult type CancelImportTaskOutput struct { _ struct{} `type:"structure"` @@ -22534,7 +25223,7 @@ func (s *CancelImportTaskOutput) SetState(v string) *CancelImportTaskOutput { } // Contains the parameters for CancelReservedInstancesListing. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListingRequest type CancelReservedInstancesListingInput struct { _ struct{} `type:"structure"` @@ -22574,7 +25263,7 @@ func (s *CancelReservedInstancesListingInput) SetReservedInstancesListingId(v st } // Contains the output of CancelReservedInstancesListing. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListingResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListingResult type CancelReservedInstancesListingOutput struct { _ struct{} `type:"structure"` @@ -22598,8 +25287,8 @@ func (s *CancelReservedInstancesListingOutput) SetReservedInstancesListings(v [] return s } -// Describes a Spot fleet error. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsError +// Describes a Spot Fleet error. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsError type CancelSpotFleetRequestsError struct { _ struct{} `type:"structure"` @@ -22636,8 +25325,8 @@ func (s *CancelSpotFleetRequestsError) SetMessage(v string) *CancelSpotFleetRequ return s } -// Describes a Spot fleet request that was not successfully canceled. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsErrorItem +// Describes a Spot Fleet request that was not successfully canceled. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsErrorItem type CancelSpotFleetRequestsErrorItem struct { _ struct{} `type:"structure"` @@ -22646,7 +25335,7 @@ type CancelSpotFleetRequestsErrorItem struct { // Error is a required field Error *CancelSpotFleetRequestsError `locationName:"error" type:"structure" required:"true"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -22675,7 +25364,7 @@ func (s *CancelSpotFleetRequestsErrorItem) SetSpotFleetRequestId(v string) *Canc } // Contains the parameters for CancelSpotFleetRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsRequest type CancelSpotFleetRequestsInput struct { _ struct{} `type:"structure"` @@ -22685,12 +25374,12 @@ type CancelSpotFleetRequestsInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The IDs of the Spot fleet requests. + // The IDs of the Spot Fleet requests. // // SpotFleetRequestIds is a required field SpotFleetRequestIds []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list" required:"true"` - // Indicates whether to terminate instances for a Spot fleet request if it is + // Indicates whether to terminate instances for a Spot Fleet request if it is // canceled successfully. // // TerminateInstances is a required field @@ -22742,14 +25431,14 @@ func (s *CancelSpotFleetRequestsInput) SetTerminateInstances(v bool) *CancelSpot } // Contains the output of CancelSpotFleetRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsResponse type CancelSpotFleetRequestsOutput struct { _ struct{} `type:"structure"` - // Information about the Spot fleet requests that are successfully canceled. + // Information about the Spot Fleet requests that are successfully canceled. SuccessfulFleetRequests []*CancelSpotFleetRequestsSuccessItem `locationName:"successfulFleetRequestSet" locationNameList:"item" type:"list"` - // Information about the Spot fleet requests that are not successfully canceled. + // Information about the Spot Fleet requests that are not successfully canceled. UnsuccessfulFleetRequests []*CancelSpotFleetRequestsErrorItem `locationName:"unsuccessfulFleetRequestSet" locationNameList:"item" type:"list"` } @@ -22775,22 +25464,22 @@ func (s *CancelSpotFleetRequestsOutput) SetUnsuccessfulFleetRequests(v []*Cancel return s } -// Describes a Spot fleet request that was successfully canceled. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsSuccessItem +// Describes a Spot Fleet request that was successfully canceled. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsSuccessItem type CancelSpotFleetRequestsSuccessItem struct { _ struct{} `type:"structure"` - // The current state of the Spot fleet request. + // The current state of the Spot Fleet request. // // CurrentSpotFleetRequestState is a required field CurrentSpotFleetRequestState *string `locationName:"currentSpotFleetRequestState" type:"string" required:"true" enum:"BatchState"` - // The previous state of the Spot fleet request. + // The previous state of the Spot Fleet request. // // PreviousSpotFleetRequestState is a required field PreviousSpotFleetRequestState *string `locationName:"previousSpotFleetRequestState" type:"string" required:"true" enum:"BatchState"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -22825,7 +25514,7 @@ func (s *CancelSpotFleetRequestsSuccessItem) SetSpotFleetRequestId(v string) *Ca } // Contains the parameters for CancelSpotInstanceRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequestsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequestsRequest type CancelSpotInstanceRequestsInput struct { _ struct{} `type:"structure"` @@ -22835,7 +25524,7 @@ type CancelSpotInstanceRequestsInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // One or more Spot instance request IDs. + // One or more Spot Instance request IDs. // // SpotInstanceRequestIds is a required field SpotInstanceRequestIds []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list" required:"true"` @@ -22877,11 +25566,11 @@ func (s *CancelSpotInstanceRequestsInput) SetSpotInstanceRequestIds(v []*string) } // Contains the output of CancelSpotInstanceRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequestsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequestsResult type CancelSpotInstanceRequestsOutput struct { _ struct{} `type:"structure"` - // One or more Spot instance requests. + // One or more Spot Instance requests. CancelledSpotInstanceRequests []*CancelledSpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` } @@ -22901,15 +25590,15 @@ func (s *CancelSpotInstanceRequestsOutput) SetCancelledSpotInstanceRequests(v [] return s } -// Describes a request to cancel a Spot instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelledSpotInstanceRequest +// Describes a request to cancel a Spot Instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelledSpotInstanceRequest type CancelledSpotInstanceRequest struct { _ struct{} `type:"structure"` - // The ID of the Spot instance request. + // The ID of the Spot Instance request. SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` - // The state of the Spot instance request. + // The state of the Spot Instance request. State *string `locationName:"state" type:"string" enum:"CancelSpotInstanceRequestState"` } @@ -22935,8 +25624,33 @@ func (s *CancelledSpotInstanceRequest) SetState(v string) *CancelledSpotInstance return s } +// Describes an IPv4 CIDR block. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CidrBlock +type CidrBlock struct { + _ struct{} `type:"structure"` + + // The IPv4 CIDR block. + CidrBlock *string `locationName:"cidrBlock" type:"string"` +} + +// String returns the string representation +func (s CidrBlock) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CidrBlock) GoString() string { + return s.String() +} + +// SetCidrBlock sets the CidrBlock field's value. +func (s *CidrBlock) SetCidrBlock(v string) *CidrBlock { + s.CidrBlock = &v + return s +} + // Describes the ClassicLink DNS support status of a VPC. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLinkDnsSupport +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLinkDnsSupport type ClassicLinkDnsSupport struct { _ struct{} `type:"structure"` @@ -22970,7 +25684,7 @@ func (s *ClassicLinkDnsSupport) SetVpcId(v string) *ClassicLinkDnsSupport { } // Describes a linked EC2-Classic instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLinkInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLinkInstance type ClassicLinkInstance struct { _ struct{} `type:"structure"` @@ -23021,8 +25735,102 @@ func (s *ClassicLinkInstance) SetVpcId(v string) *ClassicLinkInstance { return s } +// Describes a Classic Load Balancer. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLoadBalancer +type ClassicLoadBalancer struct { + _ struct{} `type:"structure"` + + // The name of the load balancer. + // + // Name is a required field + Name *string `locationName:"name" type:"string" required:"true"` +} + +// String returns the string representation +func (s ClassicLoadBalancer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClassicLoadBalancer) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ClassicLoadBalancer) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ClassicLoadBalancer"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *ClassicLoadBalancer) SetName(v string) *ClassicLoadBalancer { + s.Name = &v + return s +} + +// Describes the Classic Load Balancers to attach to a Spot Fleet. Spot Fleet +// registers the running Spot Instances with these Classic Load Balancers. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLoadBalancersConfig +type ClassicLoadBalancersConfig struct { + _ struct{} `type:"structure"` + + // One or more Classic Load Balancers. + // + // ClassicLoadBalancers is a required field + ClassicLoadBalancers []*ClassicLoadBalancer `locationName:"classicLoadBalancers" locationNameList:"item" min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s ClassicLoadBalancersConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ClassicLoadBalancersConfig) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ClassicLoadBalancersConfig) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ClassicLoadBalancersConfig"} + if s.ClassicLoadBalancers == nil { + invalidParams.Add(request.NewErrParamRequired("ClassicLoadBalancers")) + } + if s.ClassicLoadBalancers != nil && len(s.ClassicLoadBalancers) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ClassicLoadBalancers", 1)) + } + if s.ClassicLoadBalancers != nil { + for i, v := range s.ClassicLoadBalancers { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ClassicLoadBalancers", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClassicLoadBalancers sets the ClassicLoadBalancers field's value. +func (s *ClassicLoadBalancersConfig) SetClassicLoadBalancers(v []*ClassicLoadBalancer) *ClassicLoadBalancersConfig { + s.ClassicLoadBalancers = v + return s +} + // Describes the client-specific data. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClientData +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClientData type ClientData struct { _ struct{} `type:"structure"` @@ -23074,7 +25882,7 @@ func (s *ClientData) SetUploadStart(v time.Time) *ClientData { } // Contains the parameters for ConfirmProductInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstanceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstanceRequest type ConfirmProductInstanceInput struct { _ struct{} `type:"structure"` @@ -23140,7 +25948,7 @@ func (s *ConfirmProductInstanceInput) SetProductCode(v string) *ConfirmProductIn } // Contains the output of ConfirmProductInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstanceResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstanceResult type ConfirmProductInstanceOutput struct { _ struct{} `type:"structure"` @@ -23175,8 +25983,88 @@ func (s *ConfirmProductInstanceOutput) SetReturn(v bool) *ConfirmProductInstance return s } +// Describes a connection notification for a VPC endpoint or VPC endpoint service. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConnectionNotification +type ConnectionNotification struct { + _ struct{} `type:"structure"` + + // The events for the notification. Valid values are Accept, Connect, Delete, + // and Reject. + ConnectionEvents []*string `locationName:"connectionEvents" locationNameList:"item" type:"list"` + + // The ARN of the SNS topic for the notification. + ConnectionNotificationArn *string `locationName:"connectionNotificationArn" type:"string"` + + // The ID of the notification. + ConnectionNotificationId *string `locationName:"connectionNotificationId" type:"string"` + + // The state of the notification. + ConnectionNotificationState *string `locationName:"connectionNotificationState" type:"string" enum:"ConnectionNotificationState"` + + // The type of notification. + ConnectionNotificationType *string `locationName:"connectionNotificationType" type:"string" enum:"ConnectionNotificationType"` + + // The ID of the endpoint service. + ServiceId *string `locationName:"serviceId" type:"string"` + + // The ID of the VPC endpoint. + VpcEndpointId *string `locationName:"vpcEndpointId" type:"string"` +} + +// String returns the string representation +func (s ConnectionNotification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConnectionNotification) GoString() string { + return s.String() +} + +// SetConnectionEvents sets the ConnectionEvents field's value. +func (s *ConnectionNotification) SetConnectionEvents(v []*string) *ConnectionNotification { + s.ConnectionEvents = v + return s +} + +// SetConnectionNotificationArn sets the ConnectionNotificationArn field's value. +func (s *ConnectionNotification) SetConnectionNotificationArn(v string) *ConnectionNotification { + s.ConnectionNotificationArn = &v + return s +} + +// SetConnectionNotificationId sets the ConnectionNotificationId field's value. +func (s *ConnectionNotification) SetConnectionNotificationId(v string) *ConnectionNotification { + s.ConnectionNotificationId = &v + return s +} + +// SetConnectionNotificationState sets the ConnectionNotificationState field's value. +func (s *ConnectionNotification) SetConnectionNotificationState(v string) *ConnectionNotification { + s.ConnectionNotificationState = &v + return s +} + +// SetConnectionNotificationType sets the ConnectionNotificationType field's value. +func (s *ConnectionNotification) SetConnectionNotificationType(v string) *ConnectionNotification { + s.ConnectionNotificationType = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *ConnectionNotification) SetServiceId(v string) *ConnectionNotification { + s.ServiceId = &v + return s +} + +// SetVpcEndpointId sets the VpcEndpointId field's value. +func (s *ConnectionNotification) SetVpcEndpointId(v string) *ConnectionNotification { + s.VpcEndpointId = &v + return s +} + // Describes a conversion task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConversionTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConversionTask type ConversionTask struct { _ struct{} `type:"structure"` @@ -23261,8 +26149,125 @@ func (s *ConversionTask) SetTags(v []*Tag) *ConversionTask { return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyFpgaImageRequest +type CopyFpgaImageInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier that you provide to ensure the idempotency + // of the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // The description for the new AFI. + Description *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The name for the new AFI. The default is the name of the source AFI. + Name *string `type:"string"` + + // The ID of the source AFI. + // + // SourceFpgaImageId is a required field + SourceFpgaImageId *string `type:"string" required:"true"` + + // The region that contains the source AFI. + // + // SourceRegion is a required field + SourceRegion *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CopyFpgaImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopyFpgaImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CopyFpgaImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CopyFpgaImageInput"} + if s.SourceFpgaImageId == nil { + invalidParams.Add(request.NewErrParamRequired("SourceFpgaImageId")) + } + if s.SourceRegion == nil { + invalidParams.Add(request.NewErrParamRequired("SourceRegion")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *CopyFpgaImageInput) SetClientToken(v string) *CopyFpgaImageInput { + s.ClientToken = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *CopyFpgaImageInput) SetDescription(v string) *CopyFpgaImageInput { + s.Description = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CopyFpgaImageInput) SetDryRun(v bool) *CopyFpgaImageInput { + s.DryRun = &v + return s +} + +// SetName sets the Name field's value. +func (s *CopyFpgaImageInput) SetName(v string) *CopyFpgaImageInput { + s.Name = &v + return s +} + +// SetSourceFpgaImageId sets the SourceFpgaImageId field's value. +func (s *CopyFpgaImageInput) SetSourceFpgaImageId(v string) *CopyFpgaImageInput { + s.SourceFpgaImageId = &v + return s +} + +// SetSourceRegion sets the SourceRegion field's value. +func (s *CopyFpgaImageInput) SetSourceRegion(v string) *CopyFpgaImageInput { + s.SourceRegion = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyFpgaImageResult +type CopyFpgaImageOutput struct { + _ struct{} `type:"structure"` + + // The ID of the new AFI. + FpgaImageId *string `locationName:"fpgaImageId" type:"string"` +} + +// String returns the string representation +func (s CopyFpgaImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopyFpgaImageOutput) GoString() string { + return s.String() +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *CopyFpgaImageOutput) SetFpgaImageId(v string) *CopyFpgaImageOutput { + s.FpgaImageId = &v + return s +} + // Contains the parameters for CopyImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImageRequest type CopyImageInput struct { _ struct{} `type:"structure"` @@ -23391,7 +26396,7 @@ func (s *CopyImageInput) SetSourceRegion(v string) *CopyImageInput { } // Contains the output of CopyImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImageResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImageResult type CopyImageOutput struct { _ struct{} `type:"structure"` @@ -23416,7 +26421,7 @@ func (s *CopyImageOutput) SetImageId(v string) *CopyImageOutput { } // Contains the parameters for CopySnapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshotRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshotRequest type CopySnapshotInput struct { _ struct{} `type:"structure"` @@ -23558,7 +26563,7 @@ func (s *CopySnapshotInput) SetSourceSnapshotId(v string) *CopySnapshotInput { } // Contains the output of CopySnapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshotResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshotResult type CopySnapshotOutput struct { _ struct{} `type:"structure"` @@ -23583,7 +26588,7 @@ func (s *CopySnapshotOutput) SetSnapshotId(v string) *CopySnapshotOutput { } // Contains the parameters for CreateCustomerGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGatewayRequest type CreateCustomerGatewayInput struct { _ struct{} `type:"structure"` @@ -23666,7 +26671,7 @@ func (s *CreateCustomerGatewayInput) SetType(v string) *CreateCustomerGatewayInp } // Contains the output of CreateCustomerGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGatewayResult type CreateCustomerGatewayOutput struct { _ struct{} `type:"structure"` @@ -23690,8 +26695,83 @@ func (s *CreateCustomerGatewayOutput) SetCustomerGateway(v *CustomerGateway) *Cr return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultSubnetRequest +type CreateDefaultSubnetInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which to create the default subnet. + // + // AvailabilityZone is a required field + AvailabilityZone *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` +} + +// String returns the string representation +func (s CreateDefaultSubnetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDefaultSubnetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDefaultSubnetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDefaultSubnetInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateDefaultSubnetInput) SetAvailabilityZone(v string) *CreateDefaultSubnetInput { + s.AvailabilityZone = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateDefaultSubnetInput) SetDryRun(v bool) *CreateDefaultSubnetInput { + s.DryRun = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultSubnetResult +type CreateDefaultSubnetOutput struct { + _ struct{} `type:"structure"` + + // Information about the subnet. + Subnet *Subnet `locationName:"subnet" type:"structure"` +} + +// String returns the string representation +func (s CreateDefaultSubnetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDefaultSubnetOutput) GoString() string { + return s.String() +} + +// SetSubnet sets the Subnet field's value. +func (s *CreateDefaultSubnetOutput) SetSubnet(v *Subnet) *CreateDefaultSubnetOutput { + s.Subnet = v + return s +} + // Contains the parameters for CreateDefaultVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcRequest type CreateDefaultVpcInput struct { _ struct{} `type:"structure"` @@ -23719,7 +26799,7 @@ func (s *CreateDefaultVpcInput) SetDryRun(v bool) *CreateDefaultVpcInput { } // Contains the output of CreateDefaultVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcResult type CreateDefaultVpcOutput struct { _ struct{} `type:"structure"` @@ -23744,7 +26824,7 @@ func (s *CreateDefaultVpcOutput) SetVpc(v *Vpc) *CreateDefaultVpcOutput { } // Contains the parameters for CreateDhcpOptions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsRequest type CreateDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -23796,7 +26876,7 @@ func (s *CreateDhcpOptionsInput) SetDryRun(v bool) *CreateDhcpOptionsInput { } // Contains the output of CreateDhcpOptions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsResult type CreateDhcpOptionsOutput struct { _ struct{} `type:"structure"` @@ -23820,7 +26900,7 @@ func (s *CreateDhcpOptionsOutput) SetDhcpOptions(v *DhcpOptions) *CreateDhcpOpti return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGatewayRequest type CreateEgressOnlyInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -23881,7 +26961,7 @@ func (s *CreateEgressOnlyInternetGatewayInput) SetVpcId(v string) *CreateEgressO return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGatewayResult type CreateEgressOnlyInternetGatewayOutput struct { _ struct{} `type:"structure"` @@ -23916,7 +26996,7 @@ func (s *CreateEgressOnlyInternetGatewayOutput) SetEgressOnlyInternetGateway(v * } // Contains the parameters for CreateFlowLogs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogsRequest type CreateFlowLogsInput struct { _ struct{} `type:"structure"` @@ -24025,7 +27105,7 @@ func (s *CreateFlowLogsInput) SetTrafficType(v string) *CreateFlowLogsInput { } // Contains the output of CreateFlowLogs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogsResult type CreateFlowLogsOutput struct { _ struct{} `type:"structure"` @@ -24068,7 +27148,7 @@ func (s *CreateFlowLogsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *CreateFlo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageRequest type CreateFpgaImageInput struct { _ struct{} `type:"structure"` @@ -24157,7 +27237,7 @@ func (s *CreateFpgaImageInput) SetName(v string) *CreateFpgaImageInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageResult type CreateFpgaImageOutput struct { _ struct{} `type:"structure"` @@ -24191,7 +27271,7 @@ func (s *CreateFpgaImageOutput) SetFpgaImageId(v string) *CreateFpgaImageOutput } // Contains the parameters for CreateImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageRequest type CreateImageInput struct { _ struct{} `type:"structure"` @@ -24291,7 +27371,7 @@ func (s *CreateImageInput) SetNoReboot(v bool) *CreateImageInput { } // Contains the output of CreateImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageResult type CreateImageOutput struct { _ struct{} `type:"structure"` @@ -24316,7 +27396,7 @@ func (s *CreateImageOutput) SetImageId(v string) *CreateImageOutput { } // Contains the parameters for CreateInstanceExportTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTaskRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTaskRequest type CreateInstanceExportTaskInput struct { _ struct{} `type:"structure"` @@ -24384,7 +27464,7 @@ func (s *CreateInstanceExportTaskInput) SetTargetEnvironment(v string) *CreateIn } // Contains the output for CreateInstanceExportTask. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTaskResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTaskResult type CreateInstanceExportTaskOutput struct { _ struct{} `type:"structure"` @@ -24409,7 +27489,7 @@ func (s *CreateInstanceExportTaskOutput) SetExportTask(v *ExportTask) *CreateIns } // Contains the parameters for CreateInternetGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGatewayRequest type CreateInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -24437,7 +27517,7 @@ func (s *CreateInternetGatewayInput) SetDryRun(v bool) *CreateInternetGatewayInp } // Contains the output of CreateInternetGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGatewayResult type CreateInternetGatewayOutput struct { _ struct{} `type:"structure"` @@ -24462,7 +27542,7 @@ func (s *CreateInternetGatewayOutput) SetInternetGateway(v *InternetGateway) *Cr } // Contains the parameters for CreateKeyPair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPairRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPairRequest type CreateKeyPairInput struct { _ struct{} `type:"structure"` @@ -24516,7 +27596,7 @@ func (s *CreateKeyPairInput) SetKeyName(v string) *CreateKeyPairInput { } // Describes a key pair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/KeyPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/KeyPair type CreateKeyPairOutput struct { _ struct{} `type:"structure"` @@ -24558,8 +27638,257 @@ func (s *CreateKeyPairOutput) SetKeyName(v string) *CreateKeyPairOutput { return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateRequest +type CreateLaunchTemplateInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The information for the launch template. + // + // LaunchTemplateData is a required field + LaunchTemplateData *RequestLaunchTemplateData `type:"structure" required:"true"` + + // A name for the launch template. + // + // LaunchTemplateName is a required field + LaunchTemplateName *string `min:"3" type:"string" required:"true"` + + // A description for the first version of the launch template. + VersionDescription *string `type:"string"` +} + +// String returns the string representation +func (s CreateLaunchTemplateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLaunchTemplateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateLaunchTemplateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateLaunchTemplateInput"} + if s.LaunchTemplateData == nil { + invalidParams.Add(request.NewErrParamRequired("LaunchTemplateData")) + } + if s.LaunchTemplateName == nil { + invalidParams.Add(request.NewErrParamRequired("LaunchTemplateName")) + } + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + if s.LaunchTemplateData != nil { + if err := s.LaunchTemplateData.Validate(); err != nil { + invalidParams.AddNested("LaunchTemplateData", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateLaunchTemplateInput) SetClientToken(v string) *CreateLaunchTemplateInput { + s.ClientToken = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateLaunchTemplateInput) SetDryRun(v bool) *CreateLaunchTemplateInput { + s.DryRun = &v + return s +} + +// SetLaunchTemplateData sets the LaunchTemplateData field's value. +func (s *CreateLaunchTemplateInput) SetLaunchTemplateData(v *RequestLaunchTemplateData) *CreateLaunchTemplateInput { + s.LaunchTemplateData = v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *CreateLaunchTemplateInput) SetLaunchTemplateName(v string) *CreateLaunchTemplateInput { + s.LaunchTemplateName = &v + return s +} + +// SetVersionDescription sets the VersionDescription field's value. +func (s *CreateLaunchTemplateInput) SetVersionDescription(v string) *CreateLaunchTemplateInput { + s.VersionDescription = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateResult +type CreateLaunchTemplateOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch template. + LaunchTemplate *LaunchTemplate `locationName:"launchTemplate" type:"structure"` +} + +// String returns the string representation +func (s CreateLaunchTemplateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLaunchTemplateOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplate sets the LaunchTemplate field's value. +func (s *CreateLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *CreateLaunchTemplateOutput { + s.LaunchTemplate = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateVersionRequest +type CreateLaunchTemplateVersionInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The information for the launch template. + // + // LaunchTemplateData is a required field + LaunchTemplateData *RequestLaunchTemplateData `type:"structure" required:"true"` + + // The ID of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateId *string `type:"string"` + + // The name of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateName *string `min:"3" type:"string"` + + // The version number of the launch template version on which to base the new + // version. The new version inherits the same launch parameters as the source + // version, except for parameters that you specify in LaunchTemplateData. + SourceVersion *string `type:"string"` + + // A description for the version of the launch template. + VersionDescription *string `type:"string"` +} + +// String returns the string representation +func (s CreateLaunchTemplateVersionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLaunchTemplateVersionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateLaunchTemplateVersionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateLaunchTemplateVersionInput"} + if s.LaunchTemplateData == nil { + invalidParams.Add(request.NewErrParamRequired("LaunchTemplateData")) + } + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + if s.LaunchTemplateData != nil { + if err := s.LaunchTemplateData.Validate(); err != nil { + invalidParams.AddNested("LaunchTemplateData", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateLaunchTemplateVersionInput) SetClientToken(v string) *CreateLaunchTemplateVersionInput { + s.ClientToken = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateLaunchTemplateVersionInput) SetDryRun(v bool) *CreateLaunchTemplateVersionInput { + s.DryRun = &v + return s +} + +// SetLaunchTemplateData sets the LaunchTemplateData field's value. +func (s *CreateLaunchTemplateVersionInput) SetLaunchTemplateData(v *RequestLaunchTemplateData) *CreateLaunchTemplateVersionInput { + s.LaunchTemplateData = v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *CreateLaunchTemplateVersionInput) SetLaunchTemplateId(v string) *CreateLaunchTemplateVersionInput { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *CreateLaunchTemplateVersionInput) SetLaunchTemplateName(v string) *CreateLaunchTemplateVersionInput { + s.LaunchTemplateName = &v + return s +} + +// SetSourceVersion sets the SourceVersion field's value. +func (s *CreateLaunchTemplateVersionInput) SetSourceVersion(v string) *CreateLaunchTemplateVersionInput { + s.SourceVersion = &v + return s +} + +// SetVersionDescription sets the VersionDescription field's value. +func (s *CreateLaunchTemplateVersionInput) SetVersionDescription(v string) *CreateLaunchTemplateVersionInput { + s.VersionDescription = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateVersionResult +type CreateLaunchTemplateVersionOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch template version. + LaunchTemplateVersion *LaunchTemplateVersion `locationName:"launchTemplateVersion" type:"structure"` +} + +// String returns the string representation +func (s CreateLaunchTemplateVersionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLaunchTemplateVersionOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplateVersion sets the LaunchTemplateVersion field's value. +func (s *CreateLaunchTemplateVersionOutput) SetLaunchTemplateVersion(v *LaunchTemplateVersion) *CreateLaunchTemplateVersionOutput { + s.LaunchTemplateVersion = v + return s +} + // Contains the parameters for CreateNatGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGatewayRequest type CreateNatGatewayInput struct { _ struct{} `type:"structure"` @@ -24627,7 +27956,7 @@ func (s *CreateNatGatewayInput) SetSubnetId(v string) *CreateNatGatewayInput { } // Contains the output of CreateNatGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGatewayResult type CreateNatGatewayOutput struct { _ struct{} `type:"structure"` @@ -24662,7 +27991,7 @@ func (s *CreateNatGatewayOutput) SetNatGateway(v *NatGateway) *CreateNatGatewayO } // Contains the parameters for CreateNetworkAclEntry. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntryRequest type CreateNetworkAclEntryInput struct { _ struct{} `type:"structure"` @@ -24817,7 +28146,7 @@ func (s *CreateNetworkAclEntryInput) SetRuleNumber(v int64) *CreateNetworkAclEnt return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntryOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntryOutput type CreateNetworkAclEntryOutput struct { _ struct{} `type:"structure"` } @@ -24833,7 +28162,7 @@ func (s CreateNetworkAclEntryOutput) GoString() string { } // Contains the parameters for CreateNetworkAcl. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclRequest type CreateNetworkAclInput struct { _ struct{} `type:"structure"` @@ -24885,7 +28214,7 @@ func (s *CreateNetworkAclInput) SetVpcId(v string) *CreateNetworkAclInput { } // Contains the output of CreateNetworkAcl. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclResult type CreateNetworkAclOutput struct { _ struct{} `type:"structure"` @@ -24910,7 +28239,7 @@ func (s *CreateNetworkAclOutput) SetNetworkAcl(v *NetworkAcl) *CreateNetworkAclO } // Contains the parameters for CreateNetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfaceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfaceRequest type CreateNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -25052,7 +28381,7 @@ func (s *CreateNetworkInterfaceInput) SetSubnetId(v string) *CreateNetworkInterf } // Contains the output of CreateNetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfaceResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfaceResult type CreateNetworkInterfaceOutput struct { _ struct{} `type:"structure"` @@ -25077,7 +28406,7 @@ func (s *CreateNetworkInterfaceOutput) SetNetworkInterface(v *NetworkInterface) } // Contains the parameters for CreateNetworkInterfacePermission. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionRequest type CreateNetworkInterfacePermissionInput struct { _ struct{} `type:"structure"` @@ -25161,7 +28490,7 @@ func (s *CreateNetworkInterfacePermissionInput) SetPermission(v string) *CreateN } // Contains the output of CreateNetworkInterfacePermission. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionResult type CreateNetworkInterfacePermissionOutput struct { _ struct{} `type:"structure"` @@ -25186,7 +28515,7 @@ func (s *CreateNetworkInterfacePermissionOutput) SetInterfacePermission(v *Netwo } // Contains the parameters for CreatePlacementGroup. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupRequest type CreatePlacementGroupInput struct { _ struct{} `type:"structure"` @@ -25196,7 +28525,8 @@ type CreatePlacementGroupInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // A name for the placement group. + // A name for the placement group. Must be unique within the scope of your account + // for the region. // // Constraints: Up to 255 ASCII characters // @@ -25253,7 +28583,7 @@ func (s *CreatePlacementGroupInput) SetStrategy(v string) *CreatePlacementGroupI return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupOutput type CreatePlacementGroupOutput struct { _ struct{} `type:"structure"` } @@ -25269,7 +28599,7 @@ func (s CreatePlacementGroupOutput) GoString() string { } // Contains the parameters for CreateReservedInstancesListing. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListingRequest type CreateReservedInstancesListingInput struct { _ struct{} `type:"structure"` @@ -25357,7 +28687,7 @@ func (s *CreateReservedInstancesListingInput) SetReservedInstancesId(v string) * } // Contains the output of CreateReservedInstancesListing. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListingResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListingResult type CreateReservedInstancesListingOutput struct { _ struct{} `type:"structure"` @@ -25382,7 +28712,7 @@ func (s *CreateReservedInstancesListingOutput) SetReservedInstancesListings(v [] } // Contains the parameters for CreateRoute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteRequest type CreateRouteInput struct { _ struct{} `type:"structure"` @@ -25510,7 +28840,7 @@ func (s *CreateRouteInput) SetVpcPeeringConnectionId(v string) *CreateRouteInput } // Contains the output of CreateRoute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteResult type CreateRouteOutput struct { _ struct{} `type:"structure"` @@ -25535,7 +28865,7 @@ func (s *CreateRouteOutput) SetReturn(v bool) *CreateRouteOutput { } // Contains the parameters for CreateRouteTable. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTableRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTableRequest type CreateRouteTableInput struct { _ struct{} `type:"structure"` @@ -25587,7 +28917,7 @@ func (s *CreateRouteTableInput) SetVpcId(v string) *CreateRouteTableInput { } // Contains the output of CreateRouteTable. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTableResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTableResult type CreateRouteTableOutput struct { _ struct{} `type:"structure"` @@ -25612,7 +28942,7 @@ func (s *CreateRouteTableOutput) SetRouteTable(v *RouteTable) *CreateRouteTableO } // Contains the parameters for CreateSecurityGroup. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroupRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroupRequest type CreateSecurityGroupInput struct { _ struct{} `type:"structure"` @@ -25699,7 +29029,7 @@ func (s *CreateSecurityGroupInput) SetVpcId(v string) *CreateSecurityGroupInput } // Contains the output of CreateSecurityGroup. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroupResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroupResult type CreateSecurityGroupOutput struct { _ struct{} `type:"structure"` @@ -25724,7 +29054,7 @@ func (s *CreateSecurityGroupOutput) SetGroupId(v string) *CreateSecurityGroupOut } // Contains the parameters for CreateSnapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshotRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshotRequest type CreateSnapshotInput struct { _ struct{} `type:"structure"` @@ -25785,11 +29115,11 @@ func (s *CreateSnapshotInput) SetVolumeId(v string) *CreateSnapshotInput { } // Contains the parameters for CreateSpotDatafeedSubscription. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscriptionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscriptionRequest type CreateSpotDatafeedSubscriptionInput struct { _ struct{} `type:"structure"` - // The Amazon S3 bucket in which to store the Spot instance data feed. + // The Amazon S3 bucket in which to store the Spot Instance data feed. // // Bucket is a required field Bucket *string `locationName:"bucket" type:"string" required:"true"` @@ -25846,11 +29176,11 @@ func (s *CreateSpotDatafeedSubscriptionInput) SetPrefix(v string) *CreateSpotDat } // Contains the output of CreateSpotDatafeedSubscription. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscriptionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscriptionResult type CreateSpotDatafeedSubscriptionOutput struct { _ struct{} `type:"structure"` - // The Spot instance data feed subscription. + // The Spot Instance data feed subscription. SpotDatafeedSubscription *SpotDatafeedSubscription `locationName:"spotDatafeedSubscription" type:"structure"` } @@ -25871,7 +29201,7 @@ func (s *CreateSpotDatafeedSubscriptionOutput) SetSpotDatafeedSubscription(v *Sp } // Contains the parameters for CreateSubnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnetRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnetRequest type CreateSubnetInput struct { _ struct{} `type:"structure"` @@ -25959,7 +29289,7 @@ func (s *CreateSubnetInput) SetVpcId(v string) *CreateSubnetInput { } // Contains the output of CreateSubnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnetResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnetResult type CreateSubnetOutput struct { _ struct{} `type:"structure"` @@ -25984,7 +29314,7 @@ func (s *CreateSubnetOutput) SetSubnet(v *Subnet) *CreateSubnetOutput { } // Contains the parameters for CreateTags. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTagsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTagsRequest type CreateTagsInput struct { _ struct{} `type:"structure"` @@ -26051,7 +29381,7 @@ func (s *CreateTagsInput) SetTags(v []*Tag) *CreateTagsInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTagsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTagsOutput type CreateTagsOutput struct { _ struct{} `type:"structure"` } @@ -26067,7 +29397,7 @@ func (s CreateTagsOutput) GoString() string { } // Contains the parameters for CreateVolume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumeRequest type CreateVolumeInput struct { _ struct{} `type:"structure"` @@ -26211,7 +29541,7 @@ func (s *CreateVolumeInput) SetVolumeType(v string) *CreateVolumeInput { // Describes the user or group to be added or removed from the permissions for // a volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumePermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumePermission type CreateVolumePermission struct { _ struct{} `type:"structure"` @@ -26247,7 +29577,7 @@ func (s *CreateVolumePermission) SetUserId(v string) *CreateVolumePermission { } // Describes modifications to the permissions for a volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumePermissionModifications +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumePermissionModifications type CreateVolumePermissionModifications struct { _ struct{} `type:"structure"` @@ -26282,8 +29612,136 @@ func (s *CreateVolumePermissionModifications) SetRemove(v []*CreateVolumePermiss return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointConnectionNotificationRequest +type CreateVpcEndpointConnectionNotificationInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // One or more endpoint events for which to receive notifications. Valid values + // are Accept, Connect, Delete, and Reject. + // + // ConnectionEvents is a required field + ConnectionEvents []*string `locationNameList:"item" type:"list" required:"true"` + + // The ARN of the SNS topic for the notifications. + // + // ConnectionNotificationArn is a required field + ConnectionNotificationArn *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the endpoint service. + ServiceId *string `type:"string"` + + // The ID of the endpoint. + VpcEndpointId *string `type:"string"` +} + +// String returns the string representation +func (s CreateVpcEndpointConnectionNotificationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointConnectionNotificationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpcEndpointConnectionNotificationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpcEndpointConnectionNotificationInput"} + if s.ConnectionEvents == nil { + invalidParams.Add(request.NewErrParamRequired("ConnectionEvents")) + } + if s.ConnectionNotificationArn == nil { + invalidParams.Add(request.NewErrParamRequired("ConnectionNotificationArn")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateVpcEndpointConnectionNotificationInput) SetClientToken(v string) *CreateVpcEndpointConnectionNotificationInput { + s.ClientToken = &v + return s +} + +// SetConnectionEvents sets the ConnectionEvents field's value. +func (s *CreateVpcEndpointConnectionNotificationInput) SetConnectionEvents(v []*string) *CreateVpcEndpointConnectionNotificationInput { + s.ConnectionEvents = v + return s +} + +// SetConnectionNotificationArn sets the ConnectionNotificationArn field's value. +func (s *CreateVpcEndpointConnectionNotificationInput) SetConnectionNotificationArn(v string) *CreateVpcEndpointConnectionNotificationInput { + s.ConnectionNotificationArn = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateVpcEndpointConnectionNotificationInput) SetDryRun(v bool) *CreateVpcEndpointConnectionNotificationInput { + s.DryRun = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *CreateVpcEndpointConnectionNotificationInput) SetServiceId(v string) *CreateVpcEndpointConnectionNotificationInput { + s.ServiceId = &v + return s +} + +// SetVpcEndpointId sets the VpcEndpointId field's value. +func (s *CreateVpcEndpointConnectionNotificationInput) SetVpcEndpointId(v string) *CreateVpcEndpointConnectionNotificationInput { + s.VpcEndpointId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointConnectionNotificationResult +type CreateVpcEndpointConnectionNotificationOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Information about the notification. + ConnectionNotification *ConnectionNotification `locationName:"connectionNotification" type:"structure"` +} + +// String returns the string representation +func (s CreateVpcEndpointConnectionNotificationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointConnectionNotificationOutput) GoString() string { + return s.String() +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateVpcEndpointConnectionNotificationOutput) SetClientToken(v string) *CreateVpcEndpointConnectionNotificationOutput { + s.ClientToken = &v + return s +} + +// SetConnectionNotification sets the ConnectionNotification field's value. +func (s *CreateVpcEndpointConnectionNotificationOutput) SetConnectionNotification(v *ConnectionNotification) *CreateVpcEndpointConnectionNotificationOutput { + s.ConnectionNotification = v + return s +} + // Contains the parameters for CreateVpcEndpoint. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointRequest type CreateVpcEndpointInput struct { _ struct{} `type:"structure"` @@ -26297,20 +29755,49 @@ type CreateVpcEndpointInput struct { // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` - // A policy to attach to the endpoint that controls access to the service. The - // policy must be in valid JSON format. If this parameter is not specified, - // we attach a default policy that allows full access to the service. + // (Gateway endpoint) A policy to attach to the endpoint that controls access + // to the service. The policy must be in valid JSON format. If this parameter + // is not specified, we attach a default policy that allows full access to the + // service. PolicyDocument *string `type:"string"` - // One or more route table IDs. + // (Interface endpoint) Indicate whether to associate a private hosted zone + // with the specified VPC. The private hosted zone contains a record set for + // the default public DNS name for the service for the region (for example, + // kinesis.us-east-1.amazonaws.com) which resolves to the private IP addresses + // of the endpoint network interfaces in the VPC. This enables you to make requests + // to the default public DNS name for the service instead of the public DNS + // names that are automatically generated by the VPC endpoint service. + // + // To use a private hosted zone, you must set the following VPC attributes to + // true: enableDnsHostnames and enableDnsSupport. Use ModifyVpcAttribute to + // set the VPC attributes. + // + // Default: true + PrivateDnsEnabled *bool `type:"boolean"` + + // (Gateway endpoint) One or more route table IDs. RouteTableIds []*string `locationName:"RouteTableId" locationNameList:"item" type:"list"` - // The AWS service name, in the form com.amazonaws.region.service. To get a - // list of available services, use the DescribeVpcEndpointServices request. + // (Interface endpoint) The ID of one or more security groups to associate with + // the endpoint network interface. + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"item" type:"list"` + + // The service name. To get a list of available services, use the DescribeVpcEndpointServices + // request. // // ServiceName is a required field ServiceName *string `type:"string" required:"true"` + // (Interface endpoint) The ID of one or more subnets in which to create an + // endpoint network interface. + SubnetIds []*string `locationName:"SubnetId" locationNameList:"item" type:"list"` + + // The type of endpoint. + // + // Default: Gateway + VpcEndpointType *string `type:"string" enum:"VpcEndpointType"` + // The ID of the VPC in which the endpoint will be used. // // VpcId is a required field @@ -26361,18 +29848,42 @@ func (s *CreateVpcEndpointInput) SetPolicyDocument(v string) *CreateVpcEndpointI return s } +// SetPrivateDnsEnabled sets the PrivateDnsEnabled field's value. +func (s *CreateVpcEndpointInput) SetPrivateDnsEnabled(v bool) *CreateVpcEndpointInput { + s.PrivateDnsEnabled = &v + return s +} + // SetRouteTableIds sets the RouteTableIds field's value. func (s *CreateVpcEndpointInput) SetRouteTableIds(v []*string) *CreateVpcEndpointInput { s.RouteTableIds = v return s } +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *CreateVpcEndpointInput) SetSecurityGroupIds(v []*string) *CreateVpcEndpointInput { + s.SecurityGroupIds = v + return s +} + // SetServiceName sets the ServiceName field's value. func (s *CreateVpcEndpointInput) SetServiceName(v string) *CreateVpcEndpointInput { s.ServiceName = &v return s } +// SetSubnetIds sets the SubnetIds field's value. +func (s *CreateVpcEndpointInput) SetSubnetIds(v []*string) *CreateVpcEndpointInput { + s.SubnetIds = v + return s +} + +// SetVpcEndpointType sets the VpcEndpointType field's value. +func (s *CreateVpcEndpointInput) SetVpcEndpointType(v string) *CreateVpcEndpointInput { + s.VpcEndpointType = &v + return s +} + // SetVpcId sets the VpcId field's value. func (s *CreateVpcEndpointInput) SetVpcId(v string) *CreateVpcEndpointInput { s.VpcId = &v @@ -26380,7 +29891,7 @@ func (s *CreateVpcEndpointInput) SetVpcId(v string) *CreateVpcEndpointInput { } // Contains the output of CreateVpcEndpoint. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointResult type CreateVpcEndpointOutput struct { _ struct{} `type:"structure"` @@ -26414,8 +29925,114 @@ func (s *CreateVpcEndpointOutput) SetVpcEndpoint(v *VpcEndpoint) *CreateVpcEndpo return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointServiceConfigurationRequest +type CreateVpcEndpointServiceConfigurationInput struct { + _ struct{} `type:"structure"` + + // Indicate whether requests from service consumers to create an endpoint to + // your service must be accepted. To accept a request, use AcceptVpcEndpointConnections. + AcceptanceRequired *bool `type:"boolean"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see How to Ensure Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The Amazon Resource Names (ARNs) of one or more Network Load Balancers for + // your service. + // + // NetworkLoadBalancerArns is a required field + NetworkLoadBalancerArns []*string `locationName:"NetworkLoadBalancerArn" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s CreateVpcEndpointServiceConfigurationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointServiceConfigurationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVpcEndpointServiceConfigurationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVpcEndpointServiceConfigurationInput"} + if s.NetworkLoadBalancerArns == nil { + invalidParams.Add(request.NewErrParamRequired("NetworkLoadBalancerArns")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAcceptanceRequired sets the AcceptanceRequired field's value. +func (s *CreateVpcEndpointServiceConfigurationInput) SetAcceptanceRequired(v bool) *CreateVpcEndpointServiceConfigurationInput { + s.AcceptanceRequired = &v + return s +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateVpcEndpointServiceConfigurationInput) SetClientToken(v string) *CreateVpcEndpointServiceConfigurationInput { + s.ClientToken = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *CreateVpcEndpointServiceConfigurationInput) SetDryRun(v bool) *CreateVpcEndpointServiceConfigurationInput { + s.DryRun = &v + return s +} + +// SetNetworkLoadBalancerArns sets the NetworkLoadBalancerArns field's value. +func (s *CreateVpcEndpointServiceConfigurationInput) SetNetworkLoadBalancerArns(v []*string) *CreateVpcEndpointServiceConfigurationInput { + s.NetworkLoadBalancerArns = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointServiceConfigurationResult +type CreateVpcEndpointServiceConfigurationOutput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. + ClientToken *string `locationName:"clientToken" type:"string"` + + // Information about the service configuration. + ServiceConfiguration *ServiceConfiguration `locationName:"serviceConfiguration" type:"structure"` +} + +// String returns the string representation +func (s CreateVpcEndpointServiceConfigurationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVpcEndpointServiceConfigurationOutput) GoString() string { + return s.String() +} + +// SetClientToken sets the ClientToken field's value. +func (s *CreateVpcEndpointServiceConfigurationOutput) SetClientToken(v string) *CreateVpcEndpointServiceConfigurationOutput { + s.ClientToken = &v + return s +} + +// SetServiceConfiguration sets the ServiceConfiguration field's value. +func (s *CreateVpcEndpointServiceConfigurationOutput) SetServiceConfiguration(v *ServiceConfiguration) *CreateVpcEndpointServiceConfigurationOutput { + s.ServiceConfiguration = v + return s +} + // Contains the parameters for CreateVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcRequest type CreateVpcInput struct { _ struct{} `type:"structure"` @@ -26496,7 +30113,7 @@ func (s *CreateVpcInput) SetInstanceTenancy(v string) *CreateVpcInput { } // Contains the output of CreateVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcResult type CreateVpcOutput struct { _ struct{} `type:"structure"` @@ -26521,7 +30138,7 @@ func (s *CreateVpcOutput) SetVpc(v *Vpc) *CreateVpcOutput { } // Contains the parameters for CreateVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnectionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnectionRequest type CreateVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -26531,15 +30148,22 @@ type CreateVpcPeeringConnectionInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The AWS account ID of the owner of the peer VPC. + // The AWS account ID of the owner of the accepter VPC. // // Default: Your AWS account ID PeerOwnerId *string `locationName:"peerOwnerId" type:"string"` + // The region code for the accepter VPC, if the accepter VPC is located in a + // region other than the region in which you make the request. + // + // Default: The region in which you make the request. + PeerRegion *string `type:"string"` + // The ID of the VPC with which you are creating the VPC peering connection. + // You must specify this parameter in the request. PeerVpcId *string `locationName:"peerVpcId" type:"string"` - // The ID of the requester VPC. + // The ID of the requester VPC. You must specify this parameter in the request. VpcId *string `locationName:"vpcId" type:"string"` } @@ -26565,6 +30189,12 @@ func (s *CreateVpcPeeringConnectionInput) SetPeerOwnerId(v string) *CreateVpcPee return s } +// SetPeerRegion sets the PeerRegion field's value. +func (s *CreateVpcPeeringConnectionInput) SetPeerRegion(v string) *CreateVpcPeeringConnectionInput { + s.PeerRegion = &v + return s +} + // SetPeerVpcId sets the PeerVpcId field's value. func (s *CreateVpcPeeringConnectionInput) SetPeerVpcId(v string) *CreateVpcPeeringConnectionInput { s.PeerVpcId = &v @@ -26578,7 +30208,7 @@ func (s *CreateVpcPeeringConnectionInput) SetVpcId(v string) *CreateVpcPeeringCo } // Contains the output of CreateVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnectionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnectionResult type CreateVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -26603,7 +30233,7 @@ func (s *CreateVpcPeeringConnectionOutput) SetVpcPeeringConnection(v *VpcPeering } // Contains the parameters for CreateVpnConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRequest type CreateVpnConnectionInput struct { _ struct{} `type:"structure"` @@ -26618,11 +30248,7 @@ type CreateVpnConnectionInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // Indicates whether the VPN connection requires static routes. If you are creating - // a VPN connection for a device that does not support BGP, you must specify - // true. - // - // Default: false + // The options for the VPN connection. Options *VpnConnectionOptionsSpecification `locationName:"options" type:"structure"` // The type of VPN connection (ipsec.1). @@ -26696,7 +30322,7 @@ func (s *CreateVpnConnectionInput) SetVpnGatewayId(v string) *CreateVpnConnectio } // Contains the output of CreateVpnConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionResult type CreateVpnConnectionOutput struct { _ struct{} `type:"structure"` @@ -26721,7 +30347,7 @@ func (s *CreateVpnConnectionOutput) SetVpnConnection(v *VpnConnection) *CreateVp } // Contains the parameters for CreateVpnConnectionRoute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRouteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRouteRequest type CreateVpnConnectionRouteInput struct { _ struct{} `type:"structure"` @@ -26774,7 +30400,7 @@ func (s *CreateVpnConnectionRouteInput) SetVpnConnectionId(v string) *CreateVpnC return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRouteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRouteOutput type CreateVpnConnectionRouteOutput struct { _ struct{} `type:"structure"` } @@ -26790,10 +30416,17 @@ func (s CreateVpnConnectionRouteOutput) GoString() string { } // Contains the parameters for CreateVpnGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGatewayRequest type CreateVpnGatewayInput struct { _ struct{} `type:"structure"` + // A private Autonomous System Number (ASN) for the Amazon side of a BGP session. + // If you're using a 16-bit ASN, it must be in the 64512 to 65534 range. If + // you're using a 32-bit ASN, it must be in the 4200000000 to 4294967294 range. + // + // Default: 64512 + AmazonSideAsn *int64 `type:"long"` + // The Availability Zone for the virtual private gateway. AvailabilityZone *string `type:"string"` @@ -26832,6 +30465,12 @@ func (s *CreateVpnGatewayInput) Validate() error { return nil } +// SetAmazonSideAsn sets the AmazonSideAsn field's value. +func (s *CreateVpnGatewayInput) SetAmazonSideAsn(v int64) *CreateVpnGatewayInput { + s.AmazonSideAsn = &v + return s +} + // SetAvailabilityZone sets the AvailabilityZone field's value. func (s *CreateVpnGatewayInput) SetAvailabilityZone(v string) *CreateVpnGatewayInput { s.AvailabilityZone = &v @@ -26851,7 +30490,7 @@ func (s *CreateVpnGatewayInput) SetType(v string) *CreateVpnGatewayInput { } // Contains the output of CreateVpnGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGatewayResult type CreateVpnGatewayOutput struct { _ struct{} `type:"structure"` @@ -26875,8 +30514,74 @@ func (s *CreateVpnGatewayOutput) SetVpnGateway(v *VpnGateway) *CreateVpnGatewayO return s } +// Describes the credit option for CPU usage of a T2 instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreditSpecification +type CreditSpecification struct { + _ struct{} `type:"structure"` + + // The credit option for CPU usage of a T2 instance. + CpuCredits *string `locationName:"cpuCredits" type:"string"` +} + +// String returns the string representation +func (s CreditSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreditSpecification) GoString() string { + return s.String() +} + +// SetCpuCredits sets the CpuCredits field's value. +func (s *CreditSpecification) SetCpuCredits(v string) *CreditSpecification { + s.CpuCredits = &v + return s +} + +// The credit option for CPU usage of a T2 instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreditSpecificationRequest +type CreditSpecificationRequest struct { + _ struct{} `type:"structure"` + + // The credit option for CPU usage of a T2 instance. Valid values are standard + // and unlimited. + // + // CpuCredits is a required field + CpuCredits *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreditSpecificationRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreditSpecificationRequest) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreditSpecificationRequest) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreditSpecificationRequest"} + if s.CpuCredits == nil { + invalidParams.Add(request.NewErrParamRequired("CpuCredits")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCpuCredits sets the CpuCredits field's value. +func (s *CreditSpecificationRequest) SetCpuCredits(v string) *CreditSpecificationRequest { + s.CpuCredits = &v + return s +} + // Describes a customer gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CustomerGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CustomerGateway type CustomerGateway struct { _ struct{} `type:"structure"` @@ -26948,7 +30653,7 @@ func (s *CustomerGateway) SetType(v string) *CustomerGateway { } // Contains the parameters for DeleteCustomerGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGatewayRequest type DeleteCustomerGatewayInput struct { _ struct{} `type:"structure"` @@ -26999,7 +30704,7 @@ func (s *DeleteCustomerGatewayInput) SetDryRun(v bool) *DeleteCustomerGatewayInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGatewayOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGatewayOutput type DeleteCustomerGatewayOutput struct { _ struct{} `type:"structure"` } @@ -27015,7 +30720,7 @@ func (s DeleteCustomerGatewayOutput) GoString() string { } // Contains the parameters for DeleteDhcpOptions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptionsRequest type DeleteDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -27066,7 +30771,7 @@ func (s *DeleteDhcpOptionsInput) SetDryRun(v bool) *DeleteDhcpOptionsInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptionsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptionsOutput type DeleteDhcpOptionsOutput struct { _ struct{} `type:"structure"` } @@ -27081,7 +30786,7 @@ func (s DeleteDhcpOptionsOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGatewayRequest type DeleteEgressOnlyInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -27132,7 +30837,7 @@ func (s *DeleteEgressOnlyInternetGatewayInput) SetEgressOnlyInternetGatewayId(v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGatewayResult type DeleteEgressOnlyInternetGatewayOutput struct { _ struct{} `type:"structure"` @@ -27157,7 +30862,7 @@ func (s *DeleteEgressOnlyInternetGatewayOutput) SetReturnCode(v bool) *DeleteEgr } // Contains the parameters for DeleteFlowLogs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogsRequest type DeleteFlowLogsInput struct { _ struct{} `type:"structure"` @@ -27197,7 +30902,7 @@ func (s *DeleteFlowLogsInput) SetFlowLogIds(v []*string) *DeleteFlowLogsInput { } // Contains the output of DeleteFlowLogs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogsResult type DeleteFlowLogsOutput struct { _ struct{} `type:"structure"` @@ -27221,8 +30926,83 @@ func (s *DeleteFlowLogsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *DeleteFlo return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFpgaImageRequest +type DeleteFpgaImageInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the AFI. + // + // FpgaImageId is a required field + FpgaImageId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteFpgaImageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFpgaImageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteFpgaImageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteFpgaImageInput"} + if s.FpgaImageId == nil { + invalidParams.Add(request.NewErrParamRequired("FpgaImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DeleteFpgaImageInput) SetDryRun(v bool) *DeleteFpgaImageInput { + s.DryRun = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *DeleteFpgaImageInput) SetFpgaImageId(v string) *DeleteFpgaImageInput { + s.FpgaImageId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFpgaImageResult +type DeleteFpgaImageOutput struct { + _ struct{} `type:"structure"` + + // Is true if the request succeeds, and an error otherwise. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s DeleteFpgaImageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteFpgaImageOutput) GoString() string { + return s.String() +} + +// SetReturn sets the Return field's value. +func (s *DeleteFpgaImageOutput) SetReturn(v bool) *DeleteFpgaImageOutput { + s.Return = &v + return s +} + // Contains the parameters for DeleteInternetGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGatewayRequest type DeleteInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -27273,7 +31053,7 @@ func (s *DeleteInternetGatewayInput) SetInternetGatewayId(v string) *DeleteInter return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGatewayOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGatewayOutput type DeleteInternetGatewayOutput struct { _ struct{} `type:"structure"` } @@ -27289,7 +31069,7 @@ func (s DeleteInternetGatewayOutput) GoString() string { } // Contains the parameters for DeleteKeyPair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPairRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPairRequest type DeleteKeyPairInput struct { _ struct{} `type:"structure"` @@ -27340,7 +31120,7 @@ func (s *DeleteKeyPairInput) SetKeyName(v string) *DeleteKeyPairInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPairOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPairOutput type DeleteKeyPairOutput struct { _ struct{} `type:"structure"` } @@ -27355,8 +31135,294 @@ func (s DeleteKeyPairOutput) GoString() string { return s.String() } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateRequest +type DeleteLaunchTemplateInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateId *string `type:"string"` + + // The name of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateName *string `min:"3" type:"string"` +} + +// String returns the string representation +func (s DeleteLaunchTemplateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchTemplateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteLaunchTemplateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteLaunchTemplateInput"} + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DeleteLaunchTemplateInput) SetDryRun(v bool) *DeleteLaunchTemplateInput { + s.DryRun = &v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *DeleteLaunchTemplateInput) SetLaunchTemplateId(v string) *DeleteLaunchTemplateInput { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *DeleteLaunchTemplateInput) SetLaunchTemplateName(v string) *DeleteLaunchTemplateInput { + s.LaunchTemplateName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateResult +type DeleteLaunchTemplateOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch template. + LaunchTemplate *LaunchTemplate `locationName:"launchTemplate" type:"structure"` +} + +// String returns the string representation +func (s DeleteLaunchTemplateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchTemplateOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplate sets the LaunchTemplate field's value. +func (s *DeleteLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *DeleteLaunchTemplateOutput { + s.LaunchTemplate = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsRequest +type DeleteLaunchTemplateVersionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateId *string `type:"string"` + + // The name of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateName *string `min:"3" type:"string"` + + // The version numbers of one or more launch template versions to delete. + // + // Versions is a required field + Versions []*string `locationName:"LaunchTemplateVersion" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s DeleteLaunchTemplateVersionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchTemplateVersionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteLaunchTemplateVersionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteLaunchTemplateVersionsInput"} + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + if s.Versions == nil { + invalidParams.Add(request.NewErrParamRequired("Versions")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DeleteLaunchTemplateVersionsInput) SetDryRun(v bool) *DeleteLaunchTemplateVersionsInput { + s.DryRun = &v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *DeleteLaunchTemplateVersionsInput) SetLaunchTemplateId(v string) *DeleteLaunchTemplateVersionsInput { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *DeleteLaunchTemplateVersionsInput) SetLaunchTemplateName(v string) *DeleteLaunchTemplateVersionsInput { + s.LaunchTemplateName = &v + return s +} + +// SetVersions sets the Versions field's value. +func (s *DeleteLaunchTemplateVersionsInput) SetVersions(v []*string) *DeleteLaunchTemplateVersionsInput { + s.Versions = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsResult +type DeleteLaunchTemplateVersionsOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch template versions that were successfully deleted. + SuccessfullyDeletedLaunchTemplateVersions []*DeleteLaunchTemplateVersionsResponseSuccessItem `locationName:"successfullyDeletedLaunchTemplateVersionSet" locationNameList:"item" type:"list"` + + // Information about the launch template versions that could not be deleted. + UnsuccessfullyDeletedLaunchTemplateVersions []*DeleteLaunchTemplateVersionsResponseErrorItem `locationName:"unsuccessfullyDeletedLaunchTemplateVersionSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DeleteLaunchTemplateVersionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchTemplateVersionsOutput) GoString() string { + return s.String() +} + +// SetSuccessfullyDeletedLaunchTemplateVersions sets the SuccessfullyDeletedLaunchTemplateVersions field's value. +func (s *DeleteLaunchTemplateVersionsOutput) SetSuccessfullyDeletedLaunchTemplateVersions(v []*DeleteLaunchTemplateVersionsResponseSuccessItem) *DeleteLaunchTemplateVersionsOutput { + s.SuccessfullyDeletedLaunchTemplateVersions = v + return s +} + +// SetUnsuccessfullyDeletedLaunchTemplateVersions sets the UnsuccessfullyDeletedLaunchTemplateVersions field's value. +func (s *DeleteLaunchTemplateVersionsOutput) SetUnsuccessfullyDeletedLaunchTemplateVersions(v []*DeleteLaunchTemplateVersionsResponseErrorItem) *DeleteLaunchTemplateVersionsOutput { + s.UnsuccessfullyDeletedLaunchTemplateVersions = v + return s +} + +// Describes a launch template version that could not be deleted. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsResponseErrorItem +type DeleteLaunchTemplateVersionsResponseErrorItem struct { + _ struct{} `type:"structure"` + + // The ID of the launch template. + LaunchTemplateId *string `locationName:"launchTemplateId" type:"string"` + + // The name of the launch template. + LaunchTemplateName *string `locationName:"launchTemplateName" type:"string"` + + // Information about the error. + ResponseError *ResponseError `locationName:"responseError" type:"structure"` + + // The version number of the launch template. + VersionNumber *int64 `locationName:"versionNumber" type:"long"` +} + +// String returns the string representation +func (s DeleteLaunchTemplateVersionsResponseErrorItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchTemplateVersionsResponseErrorItem) GoString() string { + return s.String() +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *DeleteLaunchTemplateVersionsResponseErrorItem) SetLaunchTemplateId(v string) *DeleteLaunchTemplateVersionsResponseErrorItem { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *DeleteLaunchTemplateVersionsResponseErrorItem) SetLaunchTemplateName(v string) *DeleteLaunchTemplateVersionsResponseErrorItem { + s.LaunchTemplateName = &v + return s +} + +// SetResponseError sets the ResponseError field's value. +func (s *DeleteLaunchTemplateVersionsResponseErrorItem) SetResponseError(v *ResponseError) *DeleteLaunchTemplateVersionsResponseErrorItem { + s.ResponseError = v + return s +} + +// SetVersionNumber sets the VersionNumber field's value. +func (s *DeleteLaunchTemplateVersionsResponseErrorItem) SetVersionNumber(v int64) *DeleteLaunchTemplateVersionsResponseErrorItem { + s.VersionNumber = &v + return s +} + +// Describes a launch template version that was successfully deleted. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsResponseSuccessItem +type DeleteLaunchTemplateVersionsResponseSuccessItem struct { + _ struct{} `type:"structure"` + + // The ID of the launch template. + LaunchTemplateId *string `locationName:"launchTemplateId" type:"string"` + + // The name of the launch template. + LaunchTemplateName *string `locationName:"launchTemplateName" type:"string"` + + // The version number of the launch template. + VersionNumber *int64 `locationName:"versionNumber" type:"long"` +} + +// String returns the string representation +func (s DeleteLaunchTemplateVersionsResponseSuccessItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLaunchTemplateVersionsResponseSuccessItem) GoString() string { + return s.String() +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *DeleteLaunchTemplateVersionsResponseSuccessItem) SetLaunchTemplateId(v string) *DeleteLaunchTemplateVersionsResponseSuccessItem { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *DeleteLaunchTemplateVersionsResponseSuccessItem) SetLaunchTemplateName(v string) *DeleteLaunchTemplateVersionsResponseSuccessItem { + s.LaunchTemplateName = &v + return s +} + +// SetVersionNumber sets the VersionNumber field's value. +func (s *DeleteLaunchTemplateVersionsResponseSuccessItem) SetVersionNumber(v int64) *DeleteLaunchTemplateVersionsResponseSuccessItem { + s.VersionNumber = &v + return s +} + // Contains the parameters for DeleteNatGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGatewayRequest type DeleteNatGatewayInput struct { _ struct{} `type:"structure"` @@ -27396,7 +31462,7 @@ func (s *DeleteNatGatewayInput) SetNatGatewayId(v string) *DeleteNatGatewayInput } // Contains the output of DeleteNatGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGatewayResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGatewayResult type DeleteNatGatewayOutput struct { _ struct{} `type:"structure"` @@ -27421,7 +31487,7 @@ func (s *DeleteNatGatewayOutput) SetNatGatewayId(v string) *DeleteNatGatewayOutp } // Contains the parameters for DeleteNetworkAclEntry. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntryRequest type DeleteNetworkAclEntryInput struct { _ struct{} `type:"structure"` @@ -27500,7 +31566,7 @@ func (s *DeleteNetworkAclEntryInput) SetRuleNumber(v int64) *DeleteNetworkAclEnt return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntryOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntryOutput type DeleteNetworkAclEntryOutput struct { _ struct{} `type:"structure"` } @@ -27516,7 +31582,7 @@ func (s DeleteNetworkAclEntryOutput) GoString() string { } // Contains the parameters for DeleteNetworkAcl. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclRequest type DeleteNetworkAclInput struct { _ struct{} `type:"structure"` @@ -27567,7 +31633,7 @@ func (s *DeleteNetworkAclInput) SetNetworkAclId(v string) *DeleteNetworkAclInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclOutput type DeleteNetworkAclOutput struct { _ struct{} `type:"structure"` } @@ -27583,7 +31649,7 @@ func (s DeleteNetworkAclOutput) GoString() string { } // Contains the parameters for DeleteNetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfaceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfaceRequest type DeleteNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -27634,7 +31700,7 @@ func (s *DeleteNetworkInterfaceInput) SetNetworkInterfaceId(v string) *DeleteNet return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfaceOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfaceOutput type DeleteNetworkInterfaceOutput struct { _ struct{} `type:"structure"` } @@ -27650,7 +31716,7 @@ func (s DeleteNetworkInterfaceOutput) GoString() string { } // Contains the parameters for DeleteNetworkInterfacePermission. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionRequest type DeleteNetworkInterfacePermissionInput struct { _ struct{} `type:"structure"` @@ -27712,7 +31778,7 @@ func (s *DeleteNetworkInterfacePermissionInput) SetNetworkInterfacePermissionId( } // Contains the output for DeleteNetworkInterfacePermission. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionResult type DeleteNetworkInterfacePermissionOutput struct { _ struct{} `type:"structure"` @@ -27737,7 +31803,7 @@ func (s *DeleteNetworkInterfacePermissionOutput) SetReturn(v bool) *DeleteNetwor } // Contains the parameters for DeletePlacementGroup. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupRequest type DeletePlacementGroupInput struct { _ struct{} `type:"structure"` @@ -27788,7 +31854,7 @@ func (s *DeletePlacementGroupInput) SetGroupName(v string) *DeletePlacementGroup return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupOutput type DeletePlacementGroupOutput struct { _ struct{} `type:"structure"` } @@ -27804,7 +31870,7 @@ func (s DeletePlacementGroupOutput) GoString() string { } // Contains the parameters for DeleteRoute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteRequest type DeleteRouteInput struct { _ struct{} `type:"structure"` @@ -27875,7 +31941,7 @@ func (s *DeleteRouteInput) SetRouteTableId(v string) *DeleteRouteInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteOutput type DeleteRouteOutput struct { _ struct{} `type:"structure"` } @@ -27891,7 +31957,7 @@ func (s DeleteRouteOutput) GoString() string { } // Contains the parameters for DeleteRouteTable. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTableRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTableRequest type DeleteRouteTableInput struct { _ struct{} `type:"structure"` @@ -27942,7 +32008,7 @@ func (s *DeleteRouteTableInput) SetRouteTableId(v string) *DeleteRouteTableInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTableOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTableOutput type DeleteRouteTableOutput struct { _ struct{} `type:"structure"` } @@ -27958,7 +32024,7 @@ func (s DeleteRouteTableOutput) GoString() string { } // Contains the parameters for DeleteSecurityGroup. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroupRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroupRequest type DeleteSecurityGroupInput struct { _ struct{} `type:"structure"` @@ -28004,7 +32070,7 @@ func (s *DeleteSecurityGroupInput) SetGroupName(v string) *DeleteSecurityGroupIn return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroupOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroupOutput type DeleteSecurityGroupOutput struct { _ struct{} `type:"structure"` } @@ -28020,7 +32086,7 @@ func (s DeleteSecurityGroupOutput) GoString() string { } // Contains the parameters for DeleteSnapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshotRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshotRequest type DeleteSnapshotInput struct { _ struct{} `type:"structure"` @@ -28071,7 +32137,7 @@ func (s *DeleteSnapshotInput) SetSnapshotId(v string) *DeleteSnapshotInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshotOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshotOutput type DeleteSnapshotOutput struct { _ struct{} `type:"structure"` } @@ -28087,7 +32153,7 @@ func (s DeleteSnapshotOutput) GoString() string { } // Contains the parameters for DeleteSpotDatafeedSubscription. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscriptionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscriptionRequest type DeleteSpotDatafeedSubscriptionInput struct { _ struct{} `type:"structure"` @@ -28114,7 +32180,7 @@ func (s *DeleteSpotDatafeedSubscriptionInput) SetDryRun(v bool) *DeleteSpotDataf return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscriptionOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscriptionOutput type DeleteSpotDatafeedSubscriptionOutput struct { _ struct{} `type:"structure"` } @@ -28130,7 +32196,7 @@ func (s DeleteSpotDatafeedSubscriptionOutput) GoString() string { } // Contains the parameters for DeleteSubnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnetRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnetRequest type DeleteSubnetInput struct { _ struct{} `type:"structure"` @@ -28181,7 +32247,7 @@ func (s *DeleteSubnetInput) SetSubnetId(v string) *DeleteSubnetInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnetOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnetOutput type DeleteSubnetOutput struct { _ struct{} `type:"structure"` } @@ -28197,7 +32263,7 @@ func (s DeleteSubnetOutput) GoString() string { } // Contains the parameters for DeleteTags. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTagsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTagsRequest type DeleteTagsInput struct { _ struct{} `type:"structure"` @@ -28207,15 +32273,17 @@ type DeleteTagsInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The ID of the resource. For example, ami-1a2b3c4d. You can specify more than - // one resource ID. + // The IDs of one or more resources. // // Resources is a required field Resources []*string `locationName:"resourceId" type:"list" required:"true"` - // One or more tags to delete. If you omit the value parameter, we delete the - // tag regardless of its value. If you specify this parameter with an empty - // string as the value, we delete the key only if its value is an empty string. + // One or more tags to delete. If you omit this parameter, we delete all tags + // for the specified resources. Specify a tag key and an optional tag value + // to delete specific tags. If you specify a tag key without a tag value, we + // delete any tag with this key regardless of its value. If you specify a tag + // key with an empty string as the tag value, we delete the tag only if its + // value is an empty string. Tags []*Tag `locationName:"tag" locationNameList:"item" type:"list"` } @@ -28260,7 +32328,7 @@ func (s *DeleteTagsInput) SetTags(v []*Tag) *DeleteTagsInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTagsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTagsOutput type DeleteTagsOutput struct { _ struct{} `type:"structure"` } @@ -28276,7 +32344,7 @@ func (s DeleteTagsOutput) GoString() string { } // Contains the parameters for DeleteVolume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolumeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolumeRequest type DeleteVolumeInput struct { _ struct{} `type:"structure"` @@ -28327,7 +32395,7 @@ func (s *DeleteVolumeInput) SetVolumeId(v string) *DeleteVolumeInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolumeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolumeOutput type DeleteVolumeOutput struct { _ struct{} `type:"structure"` } @@ -28342,8 +32410,158 @@ func (s DeleteVolumeOutput) GoString() string { return s.String() } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointConnectionNotificationsRequest +type DeleteVpcEndpointConnectionNotificationsInput struct { + _ struct{} `type:"structure"` + + // One or more notification IDs. + // + // ConnectionNotificationIds is a required field + ConnectionNotificationIds []*string `locationName:"ConnectionNotificationId" locationNameList:"item" type:"list" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` +} + +// String returns the string representation +func (s DeleteVpcEndpointConnectionNotificationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointConnectionNotificationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpcEndpointConnectionNotificationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpcEndpointConnectionNotificationsInput"} + if s.ConnectionNotificationIds == nil { + invalidParams.Add(request.NewErrParamRequired("ConnectionNotificationIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConnectionNotificationIds sets the ConnectionNotificationIds field's value. +func (s *DeleteVpcEndpointConnectionNotificationsInput) SetConnectionNotificationIds(v []*string) *DeleteVpcEndpointConnectionNotificationsInput { + s.ConnectionNotificationIds = v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *DeleteVpcEndpointConnectionNotificationsInput) SetDryRun(v bool) *DeleteVpcEndpointConnectionNotificationsInput { + s.DryRun = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointConnectionNotificationsResult +type DeleteVpcEndpointConnectionNotificationsOutput struct { + _ struct{} `type:"structure"` + + // Information about the notifications that could not be deleted successfully. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DeleteVpcEndpointConnectionNotificationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointConnectionNotificationsOutput) GoString() string { + return s.String() +} + +// SetUnsuccessful sets the Unsuccessful field's value. +func (s *DeleteVpcEndpointConnectionNotificationsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *DeleteVpcEndpointConnectionNotificationsOutput { + s.Unsuccessful = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointServiceConfigurationsRequest +type DeleteVpcEndpointServiceConfigurationsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The IDs of one or more services. + // + // ServiceIds is a required field + ServiceIds []*string `locationName:"ServiceId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s DeleteVpcEndpointServiceConfigurationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointServiceConfigurationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVpcEndpointServiceConfigurationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVpcEndpointServiceConfigurationsInput"} + if s.ServiceIds == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DeleteVpcEndpointServiceConfigurationsInput) SetDryRun(v bool) *DeleteVpcEndpointServiceConfigurationsInput { + s.DryRun = &v + return s +} + +// SetServiceIds sets the ServiceIds field's value. +func (s *DeleteVpcEndpointServiceConfigurationsInput) SetServiceIds(v []*string) *DeleteVpcEndpointServiceConfigurationsInput { + s.ServiceIds = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointServiceConfigurationsResult +type DeleteVpcEndpointServiceConfigurationsOutput struct { + _ struct{} `type:"structure"` + + // Information about the service configurations that were not deleted, if applicable. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DeleteVpcEndpointServiceConfigurationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVpcEndpointServiceConfigurationsOutput) GoString() string { + return s.String() +} + +// SetUnsuccessful sets the Unsuccessful field's value. +func (s *DeleteVpcEndpointServiceConfigurationsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *DeleteVpcEndpointServiceConfigurationsOutput { + s.Unsuccessful = v + return s +} + // Contains the parameters for DeleteVpcEndpoints. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointsRequest type DeleteVpcEndpointsInput struct { _ struct{} `type:"structure"` @@ -28353,7 +32571,7 @@ type DeleteVpcEndpointsInput struct { // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` - // One or more endpoint IDs. + // One or more VPC endpoint IDs. // // VpcEndpointIds is a required field VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list" required:"true"` @@ -28395,11 +32613,11 @@ func (s *DeleteVpcEndpointsInput) SetVpcEndpointIds(v []*string) *DeleteVpcEndpo } // Contains the output of DeleteVpcEndpoints. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointsResult type DeleteVpcEndpointsOutput struct { _ struct{} `type:"structure"` - // Information about the endpoints that were not successfully deleted. + // Information about the VPC endpoints that were not successfully deleted. Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` } @@ -28420,7 +32638,7 @@ func (s *DeleteVpcEndpointsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *Delet } // Contains the parameters for DeleteVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcRequest type DeleteVpcInput struct { _ struct{} `type:"structure"` @@ -28471,7 +32689,7 @@ func (s *DeleteVpcInput) SetVpcId(v string) *DeleteVpcInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcOutput type DeleteVpcOutput struct { _ struct{} `type:"structure"` } @@ -28487,7 +32705,7 @@ func (s DeleteVpcOutput) GoString() string { } // Contains the parameters for DeleteVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnectionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnectionRequest type DeleteVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -28539,7 +32757,7 @@ func (s *DeleteVpcPeeringConnectionInput) SetVpcPeeringConnectionId(v string) *D } // Contains the output of DeleteVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnectionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnectionResult type DeleteVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -28564,7 +32782,7 @@ func (s *DeleteVpcPeeringConnectionOutput) SetReturn(v bool) *DeleteVpcPeeringCo } // Contains the parameters for DeleteVpnConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRequest type DeleteVpnConnectionInput struct { _ struct{} `type:"structure"` @@ -28615,7 +32833,7 @@ func (s *DeleteVpnConnectionInput) SetVpnConnectionId(v string) *DeleteVpnConnec return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionOutput type DeleteVpnConnectionOutput struct { _ struct{} `type:"structure"` } @@ -28631,7 +32849,7 @@ func (s DeleteVpnConnectionOutput) GoString() string { } // Contains the parameters for DeleteVpnConnectionRoute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRouteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRouteRequest type DeleteVpnConnectionRouteInput struct { _ struct{} `type:"structure"` @@ -28684,7 +32902,7 @@ func (s *DeleteVpnConnectionRouteInput) SetVpnConnectionId(v string) *DeleteVpnC return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRouteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRouteOutput type DeleteVpnConnectionRouteOutput struct { _ struct{} `type:"structure"` } @@ -28700,7 +32918,7 @@ func (s DeleteVpnConnectionRouteOutput) GoString() string { } // Contains the parameters for DeleteVpnGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGatewayRequest type DeleteVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -28751,7 +32969,7 @@ func (s *DeleteVpnGatewayInput) SetVpnGatewayId(v string) *DeleteVpnGatewayInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGatewayOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGatewayOutput type DeleteVpnGatewayOutput struct { _ struct{} `type:"structure"` } @@ -28767,7 +32985,7 @@ func (s DeleteVpnGatewayOutput) GoString() string { } // Contains the parameters for DeregisterImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImageRequest type DeregisterImageInput struct { _ struct{} `type:"structure"` @@ -28818,7 +33036,7 @@ func (s *DeregisterImageInput) SetImageId(v string) *DeregisterImageInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImageOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImageOutput type DeregisterImageOutput struct { _ struct{} `type:"structure"` } @@ -28834,7 +33052,7 @@ func (s DeregisterImageOutput) GoString() string { } // Contains the parameters for DescribeAccountAttributes. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributesRequest type DescribeAccountAttributesInput struct { _ struct{} `type:"structure"` @@ -28871,7 +33089,7 @@ func (s *DescribeAccountAttributesInput) SetDryRun(v bool) *DescribeAccountAttri } // Contains the output of DescribeAccountAttributes. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributesResult type DescribeAccountAttributesOutput struct { _ struct{} `type:"structure"` @@ -28896,7 +33114,7 @@ func (s *DescribeAccountAttributesOutput) SetAccountAttributes(v []*AccountAttri } // Contains the parameters for DescribeAddresses. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddressesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddressesRequest type DescribeAddressesInput struct { _ struct{} `type:"structure"` @@ -28975,7 +33193,7 @@ func (s *DescribeAddressesInput) SetPublicIps(v []*string) *DescribeAddressesInp } // Contains the output of DescribeAddresses. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddressesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddressesResult type DescribeAddressesOutput struct { _ struct{} `type:"structure"` @@ -29000,7 +33218,7 @@ func (s *DescribeAddressesOutput) SetAddresses(v []*Address) *DescribeAddressesO } // Contains the parameters for DescribeAvailabilityZones. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZonesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZonesRequest type DescribeAvailabilityZonesInput struct { _ struct{} `type:"structure"` @@ -29056,7 +33274,7 @@ func (s *DescribeAvailabilityZonesInput) SetZoneNames(v []*string) *DescribeAvai } // Contains the output of DescribeAvailabiltyZones. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZonesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZonesResult type DescribeAvailabilityZonesOutput struct { _ struct{} `type:"structure"` @@ -29081,7 +33299,7 @@ func (s *DescribeAvailabilityZonesOutput) SetAvailabilityZones(v []*Availability } // Contains the parameters for DescribeBundleTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasksRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasksRequest type DescribeBundleTasksInput struct { _ struct{} `type:"structure"` @@ -29151,7 +33369,7 @@ func (s *DescribeBundleTasksInput) SetFilters(v []*Filter) *DescribeBundleTasksI } // Contains the output of DescribeBundleTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasksResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasksResult type DescribeBundleTasksOutput struct { _ struct{} `type:"structure"` @@ -29176,7 +33394,7 @@ func (s *DescribeBundleTasksOutput) SetBundleTasks(v []*BundleTask) *DescribeBun } // Contains the parameters for DescribeClassicLinkInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstancesRequest type DescribeClassicLinkInstancesInput struct { _ struct{} `type:"structure"` @@ -29267,7 +33485,7 @@ func (s *DescribeClassicLinkInstancesInput) SetNextToken(v string) *DescribeClas } // Contains the output of DescribeClassicLinkInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstancesResult type DescribeClassicLinkInstancesOutput struct { _ struct{} `type:"structure"` @@ -29302,7 +33520,7 @@ func (s *DescribeClassicLinkInstancesOutput) SetNextToken(v string) *DescribeCla } // Contains the parameters for DescribeConversionTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasksRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasksRequest type DescribeConversionTasksInput struct { _ struct{} `type:"structure"` @@ -29339,7 +33557,7 @@ func (s *DescribeConversionTasksInput) SetDryRun(v bool) *DescribeConversionTask } // Contains the output for DescribeConversionTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasksResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasksResult type DescribeConversionTasksOutput struct { _ struct{} `type:"structure"` @@ -29364,7 +33582,7 @@ func (s *DescribeConversionTasksOutput) SetConversionTasks(v []*ConversionTask) } // Contains the parameters for DescribeCustomerGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGatewaysRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGatewaysRequest type DescribeCustomerGatewaysInput struct { _ struct{} `type:"structure"` @@ -29442,7 +33660,7 @@ func (s *DescribeCustomerGatewaysInput) SetFilters(v []*Filter) *DescribeCustome } // Contains the output of DescribeCustomerGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGatewaysResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGatewaysResult type DescribeCustomerGatewaysOutput struct { _ struct{} `type:"structure"` @@ -29467,7 +33685,7 @@ func (s *DescribeCustomerGatewaysOutput) SetCustomerGateways(v []*CustomerGatewa } // Contains the parameters for DescribeDhcpOptions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptionsRequest type DescribeDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -29537,7 +33755,7 @@ func (s *DescribeDhcpOptionsInput) SetFilters(v []*Filter) *DescribeDhcpOptionsI } // Contains the output of DescribeDhcpOptions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptionsResult type DescribeDhcpOptionsOutput struct { _ struct{} `type:"structure"` @@ -29561,7 +33779,7 @@ func (s *DescribeDhcpOptionsOutput) SetDhcpOptions(v []*DhcpOptions) *DescribeDh return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGatewaysRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGatewaysRequest type DescribeEgressOnlyInternetGatewaysInput struct { _ struct{} `type:"structure"` @@ -29618,7 +33836,7 @@ func (s *DescribeEgressOnlyInternetGatewaysInput) SetNextToken(v string) *Descri return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGatewaysResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGatewaysResult type DescribeEgressOnlyInternetGatewaysOutput struct { _ struct{} `type:"structure"` @@ -29651,7 +33869,7 @@ func (s *DescribeEgressOnlyInternetGatewaysOutput) SetNextToken(v string) *Descr return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusRequest type DescribeElasticGpusInput struct { _ struct{} `type:"structure"` @@ -29726,12 +33944,12 @@ func (s *DescribeElasticGpusInput) SetNextToken(v string) *DescribeElasticGpusIn return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusResult type DescribeElasticGpusOutput struct { _ struct{} `type:"structure"` // Information about the Elastic GPUs. - ElasticGpuSet []*ElasticGpus `locationName:"elasticGpuSet" type:"list"` + ElasticGpuSet []*ElasticGpus `locationName:"elasticGpuSet" locationNameList:"item" type:"list"` // The total number of items to return. If the total number of items available // is more than the value specified in max-items then a Next-Token will be provided @@ -29772,7 +33990,7 @@ func (s *DescribeElasticGpusOutput) SetNextToken(v string) *DescribeElasticGpusO } // Contains the parameters for DescribeExportTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksRequest type DescribeExportTasksInput struct { _ struct{} `type:"structure"` @@ -29797,7 +34015,7 @@ func (s *DescribeExportTasksInput) SetExportTaskIds(v []*string) *DescribeExport } // Contains the output for DescribeExportTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksResult type DescribeExportTasksOutput struct { _ struct{} `type:"structure"` @@ -29822,7 +34040,7 @@ func (s *DescribeExportTasksOutput) SetExportTasks(v []*ExportTask) *DescribeExp } // Contains the parameters for DescribeFlowLogs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogsRequest type DescribeFlowLogsInput struct { _ struct{} `type:"structure"` @@ -29888,7 +34106,7 @@ func (s *DescribeFlowLogsInput) SetNextToken(v string) *DescribeFlowLogsInput { } // Contains the output of DescribeFlowLogs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogsResult type DescribeFlowLogsOutput struct { _ struct{} `type:"structure"` @@ -29922,7 +34140,96 @@ func (s *DescribeFlowLogsOutput) SetNextToken(v string) *DescribeFlowLogsOutput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImageAttributeRequest +type DescribeFpgaImageAttributeInput struct { + _ struct{} `type:"structure"` + + // The AFI attribute. + // + // Attribute is a required field + Attribute *string `type:"string" required:"true" enum:"FpgaImageAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the AFI. + // + // FpgaImageId is a required field + FpgaImageId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeFpgaImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFpgaImageAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeFpgaImageAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeFpgaImageAttributeInput"} + if s.Attribute == nil { + invalidParams.Add(request.NewErrParamRequired("Attribute")) + } + if s.FpgaImageId == nil { + invalidParams.Add(request.NewErrParamRequired("FpgaImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttribute sets the Attribute field's value. +func (s *DescribeFpgaImageAttributeInput) SetAttribute(v string) *DescribeFpgaImageAttributeInput { + s.Attribute = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeFpgaImageAttributeInput) SetDryRun(v bool) *DescribeFpgaImageAttributeInput { + s.DryRun = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *DescribeFpgaImageAttributeInput) SetFpgaImageId(v string) *DescribeFpgaImageAttributeInput { + s.FpgaImageId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImageAttributeResult +type DescribeFpgaImageAttributeOutput struct { + _ struct{} `type:"structure"` + + // Information about the attribute. + FpgaImageAttribute *FpgaImageAttribute `locationName:"fpgaImageAttribute" type:"structure"` +} + +// String returns the string representation +func (s DescribeFpgaImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeFpgaImageAttributeOutput) GoString() string { + return s.String() +} + +// SetFpgaImageAttribute sets the FpgaImageAttribute field's value. +func (s *DescribeFpgaImageAttributeOutput) SetFpgaImageAttribute(v *FpgaImageAttribute) *DescribeFpgaImageAttributeOutput { + s.FpgaImageAttribute = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesRequest type DescribeFpgaImagesInput struct { _ struct{} `type:"structure"` @@ -30046,7 +34353,7 @@ func (s *DescribeFpgaImagesInput) SetOwners(v []*string) *DescribeFpgaImagesInpu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesResult type DescribeFpgaImagesOutput struct { _ struct{} `type:"structure"` @@ -30080,7 +34387,7 @@ func (s *DescribeFpgaImagesOutput) SetNextToken(v string) *DescribeFpgaImagesOut return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsRequest type DescribeHostReservationOfferingsInput struct { _ struct{} `type:"structure"` @@ -30164,7 +34471,7 @@ func (s *DescribeHostReservationOfferingsInput) SetOfferingId(v string) *Describ return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsResult type DescribeHostReservationOfferingsOutput struct { _ struct{} `type:"structure"` @@ -30173,7 +34480,7 @@ type DescribeHostReservationOfferingsOutput struct { NextToken *string `locationName:"nextToken" type:"string"` // Information about the offerings. - OfferingSet []*HostOffering `locationName:"offeringSet" type:"list"` + OfferingSet []*HostOffering `locationName:"offeringSet" locationNameList:"item" type:"list"` } // String returns the string representation @@ -30198,7 +34505,7 @@ func (s *DescribeHostReservationOfferingsOutput) SetOfferingSet(v []*HostOfferin return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationsRequest type DescribeHostReservationsInput struct { _ struct{} `type:"structure"` @@ -30259,12 +34566,12 @@ func (s *DescribeHostReservationsInput) SetNextToken(v string) *DescribeHostRese return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationsResult type DescribeHostReservationsOutput struct { _ struct{} `type:"structure"` // Details about the reservation's configuration. - HostReservationSet []*HostReservation `locationName:"hostReservationSet" type:"list"` + HostReservationSet []*HostReservation `locationName:"hostReservationSet" locationNameList:"item" type:"list"` // The token to use to retrieve the next page of results. This value is null // when there are no more results to return. @@ -30294,7 +34601,7 @@ func (s *DescribeHostReservationsOutput) SetNextToken(v string) *DescribeHostRes } // Contains the parameters for DescribeHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostsRequest type DescribeHostsInput struct { _ struct{} `type:"structure"` @@ -30366,7 +34673,7 @@ func (s *DescribeHostsInput) SetNextToken(v string) *DescribeHostsInput { } // Contains the output of DescribeHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostsResult type DescribeHostsOutput struct { _ struct{} `type:"structure"` @@ -30400,7 +34707,7 @@ func (s *DescribeHostsOutput) SetNextToken(v string) *DescribeHostsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociationsRequest type DescribeIamInstanceProfileAssociationsInput struct { _ struct{} `type:"structure"` @@ -30473,7 +34780,7 @@ func (s *DescribeIamInstanceProfileAssociationsInput) SetNextToken(v string) *De return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociationsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociationsResult type DescribeIamInstanceProfileAssociationsOutput struct { _ struct{} `type:"structure"` @@ -30508,7 +34815,7 @@ func (s *DescribeIamInstanceProfileAssociationsOutput) SetNextToken(v string) *D } // Contains the parameters for DescribeIdFormat. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormatRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormatRequest type DescribeIdFormatInput struct { _ struct{} `type:"structure"` @@ -30533,7 +34840,7 @@ func (s *DescribeIdFormatInput) SetResource(v string) *DescribeIdFormatInput { } // Contains the output of DescribeIdFormat. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormatResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormatResult type DescribeIdFormatOutput struct { _ struct{} `type:"structure"` @@ -30558,7 +34865,7 @@ func (s *DescribeIdFormatOutput) SetStatuses(v []*IdFormat) *DescribeIdFormatOut } // Contains the parameters for DescribeIdentityIdFormat. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormatRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormatRequest type DescribeIdentityIdFormatInput struct { _ struct{} `type:"structure"` @@ -30608,7 +34915,7 @@ func (s *DescribeIdentityIdFormatInput) SetResource(v string) *DescribeIdentityI } // Contains the output of DescribeIdentityIdFormat. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormatResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormatResult type DescribeIdentityIdFormatOutput struct { _ struct{} `type:"structure"` @@ -30633,7 +34940,7 @@ func (s *DescribeIdentityIdFormatOutput) SetStatuses(v []*IdFormat) *DescribeIde } // Contains the parameters for DescribeImageAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttributeRequest type DescribeImageAttributeInput struct { _ struct{} `type:"structure"` @@ -30703,7 +35010,7 @@ func (s *DescribeImageAttributeInput) SetImageId(v string) *DescribeImageAttribu } // Describes an image attribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImageAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImageAttribute type DescribeImageAttributeOutput struct { _ struct{} `type:"structure"` @@ -30792,7 +35099,7 @@ func (s *DescribeImageAttributeOutput) SetSriovNetSupport(v *AttributeValue) *De } // Contains the parameters for DescribeImages. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImagesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImagesRequest type DescribeImagesInput struct { _ struct{} `type:"structure"` @@ -30813,8 +35120,8 @@ type DescribeImagesInput struct { // * block-device-mapping.delete-on-termination - A Boolean value that indicates // whether the Amazon EBS volume is deleted on instance termination. // - // * block-device-mapping.device-name - The device name for the EBS volume - // (for example, /dev/sdh). + // * block-device-mapping.device-name - The device name specified in the + // block device mapping (for example, /dev/sdh or xvdh). // // * block-device-mapping.snapshot-id - The ID of the snapshot used for the // EBS volume. @@ -30858,7 +35165,7 @@ type DescribeImagesInput struct { // // * ramdisk-id - The RAM disk ID. // - // * root-device-name - The name of the root device volume (for example, + // * root-device-name - The device name of the root device volume (for example, // /dev/sda1). // // * root-device-type - The type of the root device volume (ebs | instance-store). @@ -30869,6 +35176,9 @@ type DescribeImagesInput struct { // // * state-reason-message - The message for the state change. // + // * sriov-net-support - A value of simple indicates that enhanced networking + // with the Intel 82599 VF interface is enabled. + // // * tag:key=value - The key/value combination of a tag assigned to the resource. // Specify the key of the tag in the filter name and the value of the tag // in the filter value. For example, for the tag Purpose=X, specify tag:Purpose @@ -30941,7 +35251,7 @@ func (s *DescribeImagesInput) SetOwners(v []*string) *DescribeImagesInput { } // Contains the output of DescribeImages. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImagesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImagesResult type DescribeImagesOutput struct { _ struct{} `type:"structure"` @@ -30966,7 +35276,7 @@ func (s *DescribeImagesOutput) SetImages(v []*Image) *DescribeImagesOutput { } // Contains the parameters for DescribeImportImageTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasksRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasksRequest type DescribeImportImageTasksInput struct { _ struct{} `type:"structure"` @@ -31032,7 +35342,7 @@ func (s *DescribeImportImageTasksInput) SetNextToken(v string) *DescribeImportIm } // Contains the output for DescribeImportImageTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasksResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasksResult type DescribeImportImageTasksOutput struct { _ struct{} `type:"structure"` @@ -31068,7 +35378,7 @@ func (s *DescribeImportImageTasksOutput) SetNextToken(v string) *DescribeImportI } // Contains the parameters for DescribeImportSnapshotTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasksRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasksRequest type DescribeImportSnapshotTasksInput struct { _ struct{} `type:"structure"` @@ -31133,7 +35443,7 @@ func (s *DescribeImportSnapshotTasksInput) SetNextToken(v string) *DescribeImpor } // Contains the output for DescribeImportSnapshotTasks. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasksResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasksResult type DescribeImportSnapshotTasksOutput struct { _ struct{} `type:"structure"` @@ -31169,7 +35479,7 @@ func (s *DescribeImportSnapshotTasksOutput) SetNextToken(v string) *DescribeImpo } // Contains the parameters for DescribeInstanceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttributeRequest type DescribeInstanceAttributeInput struct { _ struct{} `type:"structure"` @@ -31237,7 +35547,7 @@ func (s *DescribeInstanceAttributeInput) SetInstanceId(v string) *DescribeInstan } // Describes an instance attribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceAttribute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceAttribute type DescribeInstanceAttributeOutput struct { _ struct{} `type:"structure"` @@ -31248,7 +35558,7 @@ type DescribeInstanceAttributeOutput struct { // EC2 console, CLI, or API; otherwise, you can. DisableApiTermination *AttributeBooleanValue `locationName:"disableApiTermination" type:"structure"` - // Indicates whether the instance is optimized for EBS I/O. + // Indicates whether the instance is optimized for Amazon EBS I/O. EbsOptimized *AttributeBooleanValue `locationName:"ebsOptimized" type:"structure"` // Indicates whether enhanced networking with ENA is enabled. @@ -31276,12 +35586,12 @@ type DescribeInstanceAttributeOutput struct { // The RAM disk ID. RamdiskId *AttributeValue `locationName:"ramdisk" type:"structure"` - // The name of the root device (for example, /dev/sda1 or /dev/xvda). + // The device name of the root device volume (for example, /dev/sda1). RootDeviceName *AttributeValue `locationName:"rootDeviceName" type:"structure"` // Indicates whether source/destination checking is enabled. A value of true - // means checking is enabled, and false means checking is disabled. This value - // must be false for a NAT instance to perform NAT. + // means that checking is enabled, and false means that checking is disabled. + // This value must be false for a NAT instance to perform NAT. SourceDestCheck *AttributeBooleanValue `locationName:"sourceDestCheck" type:"structure"` // Indicates whether enhanced networking with the Intel 82599 Virtual Function @@ -31392,8 +35702,114 @@ func (s *DescribeInstanceAttributeOutput) SetUserData(v *AttributeValue) *Descri return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceCreditSpecificationsRequest +type DescribeInstanceCreditSpecificationsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * instance-id - The ID of the instance. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more instance IDs. + // + // Default: Describes all your instances. + // + // Constraints: Maximum 1000 explicitly specified instance IDs. + InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. This + // value can be between 5 and 1000. You cannot specify this parameter and the + // instance IDs parameter in the same call. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeInstanceCreditSpecificationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceCreditSpecificationsInput) GoString() string { + return s.String() +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeInstanceCreditSpecificationsInput) SetDryRun(v bool) *DescribeInstanceCreditSpecificationsInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeInstanceCreditSpecificationsInput) SetFilters(v []*Filter) *DescribeInstanceCreditSpecificationsInput { + s.Filters = v + return s +} + +// SetInstanceIds sets the InstanceIds field's value. +func (s *DescribeInstanceCreditSpecificationsInput) SetInstanceIds(v []*string) *DescribeInstanceCreditSpecificationsInput { + s.InstanceIds = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeInstanceCreditSpecificationsInput) SetMaxResults(v int64) *DescribeInstanceCreditSpecificationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeInstanceCreditSpecificationsInput) SetNextToken(v string) *DescribeInstanceCreditSpecificationsInput { + s.NextToken = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceCreditSpecificationsResult +type DescribeInstanceCreditSpecificationsOutput struct { + _ struct{} `type:"structure"` + + // Information about the credit option for CPU usage of an instance. + InstanceCreditSpecifications []*InstanceCreditSpecification `locationName:"instanceCreditSpecificationSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeInstanceCreditSpecificationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeInstanceCreditSpecificationsOutput) GoString() string { + return s.String() +} + +// SetInstanceCreditSpecifications sets the InstanceCreditSpecifications field's value. +func (s *DescribeInstanceCreditSpecificationsOutput) SetInstanceCreditSpecifications(v []*InstanceCreditSpecification) *DescribeInstanceCreditSpecificationsOutput { + s.InstanceCreditSpecifications = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeInstanceCreditSpecificationsOutput) SetNextToken(v string) *DescribeInstanceCreditSpecificationsOutput { + s.NextToken = &v + return s +} + // Contains the parameters for DescribeInstanceStatus. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatusRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatusRequest type DescribeInstanceStatusInput struct { _ struct{} `type:"structure"` @@ -31510,7 +35926,7 @@ func (s *DescribeInstanceStatusInput) SetNextToken(v string) *DescribeInstanceSt } // Contains the output of DescribeInstanceStatus. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatusResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatusResult type DescribeInstanceStatusOutput struct { _ struct{} `type:"structure"` @@ -31545,7 +35961,7 @@ func (s *DescribeInstanceStatusOutput) SetNextToken(v string) *DescribeInstanceS } // Contains the parameters for DescribeInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstancesRequest type DescribeInstancesInput struct { _ struct{} `type:"structure"` @@ -31570,8 +35986,8 @@ type DescribeInstancesInput struct { // * block-device-mapping.delete-on-termination - A Boolean that indicates // whether the EBS volume is deleted on instance termination. // - // * block-device-mapping.device-name - The device name for the EBS volume - // (for example, /dev/sdh or xvdh). + // * block-device-mapping.device-name - The device name specified in the + // block device mapping (for example, /dev/sdh or xvdh). // // * block-device-mapping.status - The status for the EBS volume (attaching // | attached | detaching | detached). @@ -31712,10 +36128,10 @@ type DescribeInstancesInput struct { // | in-use). // // * network-interface.source-dest-check - Whether the network interface - // performs source/destination checking. A value of true means checking is - // enabled, and false means checking is disabled. The value must be false - // for the network interface to perform network address translation (NAT) - // in your VPC. + // performs source/destination checking. A value of true means that checking + // is enabled, and false means that checking is disabled. The value must + // be false for the network interface to perform network address translation + // (NAT) in your VPC. // // * network-interface.subnet-id - The ID of the subnet for the network interface. // @@ -31750,22 +36166,21 @@ type DescribeInstancesInput struct { // ID is created any time you launch an instance. A reservation ID has a // one-to-one relationship with an instance launch request, but can be associated // with more than one instance if you launch multiple instances using the - // same launch request. For example, if you launch one instance, you'll get + // same launch request. For example, if you launch one instance, you get // one reservation ID. If you launch ten instances using the same launch - // request, you'll also get one reservation ID. + // request, you also get one reservation ID. // - // * root-device-name - The name of the root device for the instance (for - // example, /dev/sda1 or /dev/xvda). + // * root-device-name - The device name of the root device volume (for example, + // /dev/sda1). // - // * root-device-type - The type of root device that the instance uses (ebs - // | instance-store). + // * root-device-type - The type of the root device volume (ebs | instance-store). // // * source-dest-check - Indicates whether the instance performs source/destination // checking. A value of true means that checking is enabled, and false means - // checking is disabled. The value must be false for the instance to perform - // network address translation (NAT) in your VPC. + // that checking is disabled. The value must be false for the instance to + // perform network address translation (NAT) in your VPC. // - // * spot-instance-request-id - The ID of the Spot instance request. + // * spot-instance-request-id - The ID of the Spot Instance request. // // * state-reason-code - The reason code for the state change. // @@ -31782,9 +36197,8 @@ type DescribeInstancesInput struct { // independent of the tag-value filter. For example, if you use both the // filter "tag-key=Purpose" and the filter "tag-value=X", you get any resources // assigned both the tag key Purpose (regardless of what the tag's value - // is), and the tag value X (regardless of what the tag's key is). If you - // want to list only resources where Purpose is X, see the tag:key=value - // filter. + // is), and the tag value X (regardless of the tag's key). If you want to + // list only resources where Purpose is X, see the tag:key=value filter. // // * tag-value - The value of a tag assigned to the resource. This filter // is independent of the tag-key filter. @@ -31853,7 +36267,7 @@ func (s *DescribeInstancesInput) SetNextToken(v string) *DescribeInstancesInput } // Contains the output of DescribeInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstancesResult type DescribeInstancesOutput struct { _ struct{} `type:"structure"` @@ -31888,7 +36302,7 @@ func (s *DescribeInstancesOutput) SetReservations(v []*Reservation) *DescribeIns } // Contains the parameters for DescribeInternetGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGatewaysRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGatewaysRequest type DescribeInternetGatewaysInput struct { _ struct{} `type:"structure"` @@ -31959,7 +36373,7 @@ func (s *DescribeInternetGatewaysInput) SetInternetGatewayIds(v []*string) *Desc } // Contains the output of DescribeInternetGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGatewaysResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGatewaysResult type DescribeInternetGatewaysOutput struct { _ struct{} `type:"structure"` @@ -31984,7 +36398,7 @@ func (s *DescribeInternetGatewaysOutput) SetInternetGateways(v []*InternetGatewa } // Contains the parameters for DescribeKeyPairs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairsRequest type DescribeKeyPairsInput struct { _ struct{} `type:"structure"` @@ -32036,7 +36450,7 @@ func (s *DescribeKeyPairsInput) SetKeyNames(v []*string) *DescribeKeyPairsInput } // Contains the output of DescribeKeyPairs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairsResult type DescribeKeyPairsOutput struct { _ struct{} `type:"structure"` @@ -32060,8 +36474,288 @@ func (s *DescribeKeyPairsOutput) SetKeyPairs(v []*KeyPairInfo) *DescribeKeyPairs return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplateVersionsRequest +type DescribeLaunchTemplateVersionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * create-time - The time the launch template version was created. + // + // * ebs-optimized - A boolean that indicates whether the instance is optimized + // for Amazon EBS I/O. + // + // * iam-instance-profile - The ARN of the IAM instance profile. + // + // * image-id - The ID of the AMI. + // + // * instance-type - The instance type. + // + // * is-default-version - A boolean that indicates whether the launch template + // version is the default version. + // + // * kernel-id - The kernel ID. + // + // * ram-disk-id - The RAM disk ID. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The ID of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateId *string `type:"string"` + + // The name of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateName *string `min:"3" type:"string"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. This + // value can be between 5 and 1000. + MaxResults *int64 `type:"integer"` + + // The version number up to which to describe launch template versions. + MaxVersion *string `type:"string"` + + // The version number after which to describe launch template versions. + MinVersion *string `type:"string"` + + // The token to request the next page of results. + NextToken *string `type:"string"` + + // One or more versions of the launch template. + Versions []*string `locationName:"LaunchTemplateVersion" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeLaunchTemplateVersionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLaunchTemplateVersionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeLaunchTemplateVersionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeLaunchTemplateVersionsInput"} + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetDryRun(v bool) *DescribeLaunchTemplateVersionsInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetFilters(v []*Filter) *DescribeLaunchTemplateVersionsInput { + s.Filters = v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetLaunchTemplateId(v string) *DescribeLaunchTemplateVersionsInput { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetLaunchTemplateName(v string) *DescribeLaunchTemplateVersionsInput { + s.LaunchTemplateName = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetMaxResults(v int64) *DescribeLaunchTemplateVersionsInput { + s.MaxResults = &v + return s +} + +// SetMaxVersion sets the MaxVersion field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetMaxVersion(v string) *DescribeLaunchTemplateVersionsInput { + s.MaxVersion = &v + return s +} + +// SetMinVersion sets the MinVersion field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetMinVersion(v string) *DescribeLaunchTemplateVersionsInput { + s.MinVersion = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetNextToken(v string) *DescribeLaunchTemplateVersionsInput { + s.NextToken = &v + return s +} + +// SetVersions sets the Versions field's value. +func (s *DescribeLaunchTemplateVersionsInput) SetVersions(v []*string) *DescribeLaunchTemplateVersionsInput { + s.Versions = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplateVersionsResult +type DescribeLaunchTemplateVersionsOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch template versions. + LaunchTemplateVersions []*LaunchTemplateVersion `locationName:"launchTemplateVersionSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeLaunchTemplateVersionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLaunchTemplateVersionsOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplateVersions sets the LaunchTemplateVersions field's value. +func (s *DescribeLaunchTemplateVersionsOutput) SetLaunchTemplateVersions(v []*LaunchTemplateVersion) *DescribeLaunchTemplateVersionsOutput { + s.LaunchTemplateVersions = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeLaunchTemplateVersionsOutput) SetNextToken(v string) *DescribeLaunchTemplateVersionsOutput { + s.NextToken = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplatesRequest +type DescribeLaunchTemplatesInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * create-time - The time the launch template was created. + // + // * launch-template-name - The name of the launch template. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // One or more launch template IDs. + LaunchTemplateIds []*string `locationName:"LaunchTemplateId" locationNameList:"item" type:"list"` + + // One or more launch template names. + LaunchTemplateNames []*string `locationName:"LaunchTemplateName" locationNameList:"item" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another call with the returned NextToken value. This + // value can be between 5 and 1000. + MaxResults *int64 `type:"integer"` + + // The token to request the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeLaunchTemplatesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLaunchTemplatesInput) GoString() string { + return s.String() +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeLaunchTemplatesInput) SetDryRun(v bool) *DescribeLaunchTemplatesInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeLaunchTemplatesInput) SetFilters(v []*Filter) *DescribeLaunchTemplatesInput { + s.Filters = v + return s +} + +// SetLaunchTemplateIds sets the LaunchTemplateIds field's value. +func (s *DescribeLaunchTemplatesInput) SetLaunchTemplateIds(v []*string) *DescribeLaunchTemplatesInput { + s.LaunchTemplateIds = v + return s +} + +// SetLaunchTemplateNames sets the LaunchTemplateNames field's value. +func (s *DescribeLaunchTemplatesInput) SetLaunchTemplateNames(v []*string) *DescribeLaunchTemplatesInput { + s.LaunchTemplateNames = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeLaunchTemplatesInput) SetMaxResults(v int64) *DescribeLaunchTemplatesInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeLaunchTemplatesInput) SetNextToken(v string) *DescribeLaunchTemplatesInput { + s.NextToken = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplatesResult +type DescribeLaunchTemplatesOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch templates. + LaunchTemplates []*LaunchTemplate `locationName:"launchTemplates" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeLaunchTemplatesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeLaunchTemplatesOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplates sets the LaunchTemplates field's value. +func (s *DescribeLaunchTemplatesOutput) SetLaunchTemplates(v []*LaunchTemplate) *DescribeLaunchTemplatesOutput { + s.LaunchTemplates = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeLaunchTemplatesOutput) SetNextToken(v string) *DescribeLaunchTemplatesOutput { + s.NextToken = &v + return s +} + // Contains the parameters for DescribeMovingAddresses. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddressesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddressesRequest type DescribeMovingAddressesInput struct { _ struct{} `type:"structure"` @@ -32133,7 +36827,7 @@ func (s *DescribeMovingAddressesInput) SetPublicIps(v []*string) *DescribeMoving } // Contains the output of DescribeMovingAddresses. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddressesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddressesResult type DescribeMovingAddressesOutput struct { _ struct{} `type:"structure"` @@ -32168,7 +36862,7 @@ func (s *DescribeMovingAddressesOutput) SetNextToken(v string) *DescribeMovingAd } // Contains the parameters for DescribeNatGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGatewaysRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGatewaysRequest type DescribeNatGatewaysInput struct { _ struct{} `type:"structure"` @@ -32181,6 +36875,22 @@ type DescribeNatGatewaysInput struct { // // * subnet-id - The ID of the subnet in which the NAT gateway resides. // + // * tag:key=value - The key/value combination of a tag assigned to the resource. + // Specify the key of the tag in the filter name and the value of the tag + // in the filter value. For example, for the tag Purpose=X, specify tag:Purpose + // for the filter name and X for the filter value. + // + // * tag-key - The key of a tag assigned to the resource. This filter is + // independent of the tag-value filter. For example, if you use both the + // filter "tag-key=Purpose" and the filter "tag-value=X", you get any resources + // assigned both the tag key Purpose (regardless of what the tag's value + // is), and the tag value X (regardless of what the tag's key is). If you + // want to list only resources where Purpose is X, see the tag:key=value + // filter. + // + // * tag-value - The value of a tag assigned to the resource. This filter + // is independent of the tag-key filter. + // // * vpc-id - The ID of the VPC in which the NAT gateway resides. Filter []*Filter `locationNameList:"Filter" type:"list"` @@ -32234,7 +36944,7 @@ func (s *DescribeNatGatewaysInput) SetNextToken(v string) *DescribeNatGatewaysIn } // Contains the output of DescribeNatGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGatewaysResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGatewaysResult type DescribeNatGatewaysOutput struct { _ struct{} `type:"structure"` @@ -32269,7 +36979,7 @@ func (s *DescribeNatGatewaysOutput) SetNextToken(v string) *DescribeNatGatewaysO } // Contains the parameters for DescribeNetworkAcls. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAclsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAclsRequest type DescribeNetworkAclsInput struct { _ struct{} `type:"structure"` @@ -32371,7 +37081,7 @@ func (s *DescribeNetworkAclsInput) SetNetworkAclIds(v []*string) *DescribeNetwor } // Contains the output of DescribeNetworkAcls. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAclsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAclsResult type DescribeNetworkAclsOutput struct { _ struct{} `type:"structure"` @@ -32396,7 +37106,7 @@ func (s *DescribeNetworkAclsOutput) SetNetworkAcls(v []*NetworkAcl) *DescribeNet } // Contains the parameters for DescribeNetworkInterfaceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttributeRequest type DescribeNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` @@ -32457,7 +37167,7 @@ func (s *DescribeNetworkInterfaceAttributeInput) SetNetworkInterfaceId(v string) } // Contains the output of DescribeNetworkInterfaceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttributeResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttributeResult type DescribeNetworkInterfaceAttributeOutput struct { _ struct{} `type:"structure"` @@ -32518,7 +37228,7 @@ func (s *DescribeNetworkInterfaceAttributeOutput) SetSourceDestCheck(v *Attribut } // Contains the parameters for DescribeNetworkInterfacePermissions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsRequest type DescribeNetworkInterfacePermissionsInput struct { _ struct{} `type:"structure"` @@ -32585,7 +37295,7 @@ func (s *DescribeNetworkInterfacePermissionsInput) SetNextToken(v string) *Descr } // Contains the output for DescribeNetworkInterfacePermissions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsResult type DescribeNetworkInterfacePermissionsOutput struct { _ struct{} `type:"structure"` @@ -32619,7 +37329,7 @@ func (s *DescribeNetworkInterfacePermissionsOutput) SetNextToken(v string) *Desc } // Contains the parameters for DescribeNetworkInterfaces. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesRequest type DescribeNetworkInterfacesInput struct { _ struct{} `type:"structure"` @@ -32777,7 +37487,7 @@ func (s *DescribeNetworkInterfacesInput) SetNetworkInterfaceIds(v []*string) *De } // Contains the output of DescribeNetworkInterfaces. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesResult type DescribeNetworkInterfacesOutput struct { _ struct{} `type:"structure"` @@ -32802,7 +37512,7 @@ func (s *DescribeNetworkInterfacesOutput) SetNetworkInterfaces(v []*NetworkInter } // Contains the parameters for DescribePlacementGroups. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroupsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroupsRequest type DescribePlacementGroupsInput struct { _ struct{} `type:"structure"` @@ -32819,7 +37529,7 @@ type DescribePlacementGroupsInput struct { // * state - The state of the placement group (pending | available | deleting // | deleted). // - // * strategy - The strategy of the placement group (cluster). + // * strategy - The strategy of the placement group (cluster | spread). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // One or more placement group names. @@ -32857,7 +37567,7 @@ func (s *DescribePlacementGroupsInput) SetGroupNames(v []*string) *DescribePlace } // Contains the output of DescribePlacementGroups. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroupsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroupsResult type DescribePlacementGroupsOutput struct { _ struct{} `type:"structure"` @@ -32882,7 +37592,7 @@ func (s *DescribePlacementGroupsOutput) SetPlacementGroups(v []*PlacementGroup) } // Contains the parameters for DescribePrefixLists. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixListsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixListsRequest type DescribePrefixListsInput struct { _ struct{} `type:"structure"` @@ -32956,7 +37666,7 @@ func (s *DescribePrefixListsInput) SetPrefixListIds(v []*string) *DescribePrefix } // Contains the output of DescribePrefixLists. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixListsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixListsResult type DescribePrefixListsOutput struct { _ struct{} `type:"structure"` @@ -32991,7 +37701,7 @@ func (s *DescribePrefixListsOutput) SetPrefixLists(v []*PrefixList) *DescribePre } // Contains the parameters for DescribeRegions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegionsRequest type DescribeRegionsInput struct { _ struct{} `type:"structure"` @@ -33041,7 +37751,7 @@ func (s *DescribeRegionsInput) SetRegionNames(v []*string) *DescribeRegionsInput } // Contains the output of DescribeRegions. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegionsResult type DescribeRegionsOutput struct { _ struct{} `type:"structure"` @@ -33066,7 +37776,7 @@ func (s *DescribeRegionsOutput) SetRegions(v []*Region) *DescribeRegionsOutput { } // Contains the parameters for DescribeReservedInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesRequest type DescribeReservedInstancesInput struct { _ struct{} `type:"structure"` @@ -33186,7 +37896,7 @@ func (s *DescribeReservedInstancesInput) SetReservedInstancesIds(v []*string) *D } // Contains the parameters for DescribeReservedInstancesListings. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListingsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListingsRequest type DescribeReservedInstancesListingsInput struct { _ struct{} `type:"structure"` @@ -33238,7 +37948,7 @@ func (s *DescribeReservedInstancesListingsInput) SetReservedInstancesListingId(v } // Contains the output of DescribeReservedInstancesListings. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListingsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListingsResult type DescribeReservedInstancesListingsOutput struct { _ struct{} `type:"structure"` @@ -33263,7 +37973,7 @@ func (s *DescribeReservedInstancesListingsOutput) SetReservedInstancesListings(v } // Contains the parameters for DescribeReservedInstancesModifications. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModificationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModificationsRequest type DescribeReservedInstancesModificationsInput struct { _ struct{} `type:"structure"` @@ -33339,7 +38049,7 @@ func (s *DescribeReservedInstancesModificationsInput) SetReservedInstancesModifi } // Contains the output of DescribeReservedInstancesModifications. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModificationsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModificationsResult type DescribeReservedInstancesModificationsOutput struct { _ struct{} `type:"structure"` @@ -33374,7 +38084,7 @@ func (s *DescribeReservedInstancesModificationsOutput) SetReservedInstancesModif } // Contains the parameters for DescribeReservedInstancesOfferings. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferingsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferingsRequest type DescribeReservedInstancesOfferingsInput struct { _ struct{} `type:"structure"` @@ -33584,7 +38294,7 @@ func (s *DescribeReservedInstancesOfferingsInput) SetReservedInstancesOfferingId } // Contains the output of DescribeReservedInstancesOfferings. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferingsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferingsResult type DescribeReservedInstancesOfferingsOutput struct { _ struct{} `type:"structure"` @@ -33619,7 +38329,7 @@ func (s *DescribeReservedInstancesOfferingsOutput) SetReservedInstancesOfferings } // Contains the output for DescribeReservedInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesResult type DescribeReservedInstancesOutput struct { _ struct{} `type:"structure"` @@ -33644,7 +38354,7 @@ func (s *DescribeReservedInstancesOutput) SetReservedInstances(v []*ReservedInst } // Contains the parameters for DescribeRouteTables. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTablesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTablesRequest type DescribeRouteTablesInput struct { _ struct{} `type:"structure"` @@ -33757,7 +38467,7 @@ func (s *DescribeRouteTablesInput) SetRouteTableIds(v []*string) *DescribeRouteT } // Contains the output of DescribeRouteTables. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTablesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTablesResult type DescribeRouteTablesOutput struct { _ struct{} `type:"structure"` @@ -33782,7 +38492,7 @@ func (s *DescribeRouteTablesOutput) SetRouteTables(v []*RouteTable) *DescribeRou } // Contains the parameters for DescribeScheduledInstanceAvailability. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailabilityRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailabilityRequest type DescribeScheduledInstanceAvailabilityInput struct { _ struct{} `type:"structure"` @@ -33912,7 +38622,7 @@ func (s *DescribeScheduledInstanceAvailabilityInput) SetRecurrence(v *ScheduledI } // Contains the output of DescribeScheduledInstanceAvailability. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailabilityResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailabilityResult type DescribeScheduledInstanceAvailabilityOutput struct { _ struct{} `type:"structure"` @@ -33947,7 +38657,7 @@ func (s *DescribeScheduledInstanceAvailabilityOutput) SetScheduledInstanceAvaila } // Contains the parameters for DescribeScheduledInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstancesRequest type DescribeScheduledInstancesInput struct { _ struct{} `type:"structure"` @@ -34030,7 +38740,7 @@ func (s *DescribeScheduledInstancesInput) SetSlotStartTimeRange(v *SlotStartTime } // Contains the output of DescribeScheduledInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstancesResult type DescribeScheduledInstancesOutput struct { _ struct{} `type:"structure"` @@ -34064,7 +38774,7 @@ func (s *DescribeScheduledInstancesOutput) SetScheduledInstanceSet(v []*Schedule return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferencesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferencesRequest type DescribeSecurityGroupReferencesInput struct { _ struct{} `type:"structure"` @@ -34115,7 +38825,7 @@ func (s *DescribeSecurityGroupReferencesInput) SetGroupId(v []*string) *Describe return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferencesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferencesResult type DescribeSecurityGroupReferencesOutput struct { _ struct{} `type:"structure"` @@ -34140,7 +38850,7 @@ func (s *DescribeSecurityGroupReferencesOutput) SetSecurityGroupReferenceSet(v [ } // Contains the parameters for DescribeSecurityGroups. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupsRequest type DescribeSecurityGroupsInput struct { _ struct{} `type:"structure"` @@ -34156,36 +38866,63 @@ type DescribeSecurityGroupsInput struct { // // * description - The description of the security group. // + // * egress.ip-permission.cidr - An IPv4 CIDR block for an outbound security + // group rule. + // + // * egress.ip-permission.from-port - For an outbound rule, the start of + // port range for the TCP and UDP protocols, or an ICMP type number. + // + // * egress.ip-permission.group-id - The ID of a security group that has + // been referenced in an outbound security group rule. + // + // * egress.ip-permission.group-name - The name of a security group that + // has been referenced in an outbound security group rule. + // + // * egress.ip-permission.ipv6-cidr - An IPv6 CIDR block for an outbound + // security group rule. + // // * egress.ip-permission.prefix-list-id - The ID (prefix) of the AWS service - // to which the security group allows access. + // to which a security group rule allows outbound access. + // + // * egress.ip-permission.protocol - The IP protocol for an outbound security + // group rule (tcp | udp | icmp or a protocol number). + // + // * egress.ip-permission.to-port - For an outbound rule, the end of port + // range for the TCP and UDP protocols, or an ICMP code. + // + // * egress.ip-permission.user-id - The ID of an AWS account that has been + // referenced in an outbound security group rule. // // * group-id - The ID of the security group. // // * group-name - The name of the security group. // - // * ip-permission.cidr - An IPv4 CIDR range that has been granted permission - // in a security group rule. + // * ip-permission.cidr - An IPv4 CIDR block for an inbound security group + // rule. // - // * ip-permission.from-port - The start of port range for the TCP and UDP - // protocols, or an ICMP type number. + // * ip-permission.from-port - For an inbound rule, the start of port range + // for the TCP and UDP protocols, or an ICMP type number. // - // * ip-permission.group-id - The ID of a security group that has been granted - // permission. + // * ip-permission.group-id - The ID of a security group that has been referenced + // in an inbound security group rule. // // * ip-permission.group-name - The name of a security group that has been - // granted permission. + // referenced in an inbound security group rule. // - // * ip-permission.ipv6-cidr - An IPv6 CIDR range that has been granted permission - // in a security group rule. + // * ip-permission.ipv6-cidr - An IPv6 CIDR block for an inbound security + // group rule. // - // * ip-permission.protocol - The IP protocol for the permission (tcp | udp - // | icmp or a protocol number). + // * ip-permission.prefix-list-id - The ID (prefix) of the AWS service from + // which a security group rule allows inbound access. // - // * ip-permission.to-port - The end of port range for the TCP and UDP protocols, - // or an ICMP code. + // * ip-permission.protocol - The IP protocol for an inbound security group + // rule (tcp | udp | icmp or a protocol number). // - // * ip-permission.user-id - The ID of an AWS account that has been granted - // permission. + // * ip-permission.to-port - For an inbound rule, the end of port range for + // the TCP and UDP protocols, or an ICMP code. + // + // * ip-permission.user-id - The ID of an AWS account that has been referenced + // in an inbound security group rule. // // * owner-id - The AWS account ID of the owner of the security group. // @@ -34209,6 +38946,14 @@ type DescribeSecurityGroupsInput struct { // // Default: Describes all your security groups. GroupNames []*string `locationName:"GroupName" locationNameList:"GroupName" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another request with the returned NextToken value. + // This value can be between 5 and 1000. + MaxResults *int64 `type:"integer"` + + // The token to request the next page of results. + NextToken *string `type:"string"` } // String returns the string representation @@ -34245,11 +38990,27 @@ func (s *DescribeSecurityGroupsInput) SetGroupNames(v []*string) *DescribeSecuri return s } +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeSecurityGroupsInput) SetMaxResults(v int64) *DescribeSecurityGroupsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeSecurityGroupsInput) SetNextToken(v string) *DescribeSecurityGroupsInput { + s.NextToken = &v + return s +} + // Contains the output of DescribeSecurityGroups. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupsResult type DescribeSecurityGroupsOutput struct { _ struct{} `type:"structure"` + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + // Information about one or more security groups. SecurityGroups []*SecurityGroup `locationName:"securityGroupInfo" locationNameList:"item" type:"list"` } @@ -34264,6 +39025,12 @@ func (s DescribeSecurityGroupsOutput) GoString() string { return s.String() } +// SetNextToken sets the NextToken field's value. +func (s *DescribeSecurityGroupsOutput) SetNextToken(v string) *DescribeSecurityGroupsOutput { + s.NextToken = &v + return s +} + // SetSecurityGroups sets the SecurityGroups field's value. func (s *DescribeSecurityGroupsOutput) SetSecurityGroups(v []*SecurityGroup) *DescribeSecurityGroupsOutput { s.SecurityGroups = v @@ -34271,7 +39038,7 @@ func (s *DescribeSecurityGroupsOutput) SetSecurityGroups(v []*SecurityGroup) *De } // Contains the parameters for DescribeSnapshotAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttributeRequest type DescribeSnapshotAttributeInput struct { _ struct{} `type:"structure"` @@ -34337,7 +39104,7 @@ func (s *DescribeSnapshotAttributeInput) SetSnapshotId(v string) *DescribeSnapsh } // Contains the output of DescribeSnapshotAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttributeResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttributeResult type DescribeSnapshotAttributeOutput struct { _ struct{} `type:"structure"` @@ -34380,7 +39147,7 @@ func (s *DescribeSnapshotAttributeOutput) SetSnapshotId(v string) *DescribeSnaps } // Contains the parameters for DescribeSnapshots. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotsRequest type DescribeSnapshotsInput struct { _ struct{} `type:"structure"` @@ -34514,7 +39281,7 @@ func (s *DescribeSnapshotsInput) SetSnapshotIds(v []*string) *DescribeSnapshotsI } // Contains the output of DescribeSnapshots. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotsResult type DescribeSnapshotsOutput struct { _ struct{} `type:"structure"` @@ -34551,7 +39318,7 @@ func (s *DescribeSnapshotsOutput) SetSnapshots(v []*Snapshot) *DescribeSnapshots } // Contains the parameters for DescribeSpotDatafeedSubscription. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscriptionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscriptionRequest type DescribeSpotDatafeedSubscriptionInput struct { _ struct{} `type:"structure"` @@ -34579,11 +39346,11 @@ func (s *DescribeSpotDatafeedSubscriptionInput) SetDryRun(v bool) *DescribeSpotD } // Contains the output of DescribeSpotDatafeedSubscription. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscriptionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscriptionResult type DescribeSpotDatafeedSubscriptionOutput struct { _ struct{} `type:"structure"` - // The Spot instance data feed subscription. + // The Spot Instance data feed subscription. SpotDatafeedSubscription *SpotDatafeedSubscription `locationName:"spotDatafeedSubscription" type:"structure"` } @@ -34604,7 +39371,7 @@ func (s *DescribeSpotDatafeedSubscriptionOutput) SetSpotDatafeedSubscription(v * } // Contains the parameters for DescribeSpotFleetInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstancesRequest type DescribeSpotFleetInstancesInput struct { _ struct{} `type:"structure"` @@ -34622,7 +39389,7 @@ type DescribeSpotFleetInstancesInput struct { // The token for the next set of results. NextToken *string `locationName:"nextToken" type:"string"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -34676,7 +39443,7 @@ func (s *DescribeSpotFleetInstancesInput) SetSpotFleetRequestId(v string) *Descr } // Contains the output of DescribeSpotFleetInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstancesResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstancesResponse type DescribeSpotFleetInstancesOutput struct { _ struct{} `type:"structure"` @@ -34690,7 +39457,7 @@ type DescribeSpotFleetInstancesOutput struct { // when there are no more results to return. NextToken *string `locationName:"nextToken" type:"string"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -34725,7 +39492,7 @@ func (s *DescribeSpotFleetInstancesOutput) SetSpotFleetRequestId(v string) *Desc } // Contains the parameters for DescribeSpotFleetRequestHistory. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistoryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistoryRequest type DescribeSpotFleetRequestHistoryInput struct { _ struct{} `type:"structure"` @@ -34746,7 +39513,7 @@ type DescribeSpotFleetRequestHistoryInput struct { // The token for the next set of results. NextToken *string `locationName:"nextToken" type:"string"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -34820,11 +39587,11 @@ func (s *DescribeSpotFleetRequestHistoryInput) SetStartTime(v time.Time) *Descri } // Contains the output of DescribeSpotFleetRequestHistory. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistoryResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistoryResponse type DescribeSpotFleetRequestHistoryOutput struct { _ struct{} `type:"structure"` - // Information about the events in the history of the Spot fleet request. + // Information about the events in the history of the Spot Fleet request. // // HistoryRecords is a required field HistoryRecords []*HistoryRecord `locationName:"historyRecordSet" locationNameList:"item" type:"list" required:"true"` @@ -34841,7 +39608,7 @@ type DescribeSpotFleetRequestHistoryOutput struct { // when there are no more results to return. NextToken *string `locationName:"nextToken" type:"string"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -34893,7 +39660,7 @@ func (s *DescribeSpotFleetRequestHistoryOutput) SetStartTime(v time.Time) *Descr } // Contains the parameters for DescribeSpotFleetRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestsRequest type DescribeSpotFleetRequestsInput struct { _ struct{} `type:"structure"` @@ -34911,7 +39678,7 @@ type DescribeSpotFleetRequestsInput struct { // The token for the next set of results. NextToken *string `locationName:"nextToken" type:"string"` - // The IDs of the Spot fleet requests. + // The IDs of the Spot Fleet requests. SpotFleetRequestIds []*string `locationName:"spotFleetRequestId" locationNameList:"item" type:"list"` } @@ -34950,7 +39717,7 @@ func (s *DescribeSpotFleetRequestsInput) SetSpotFleetRequestIds(v []*string) *De } // Contains the output of DescribeSpotFleetRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestsResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestsResponse type DescribeSpotFleetRequestsOutput struct { _ struct{} `type:"structure"` @@ -34958,7 +39725,7 @@ type DescribeSpotFleetRequestsOutput struct { // when there are no more results to return. NextToken *string `locationName:"nextToken" type:"string"` - // Information about the configuration of your Spot fleet. + // Information about the configuration of your Spot Fleet. // // SpotFleetRequestConfigs is a required field SpotFleetRequestConfigs []*SpotFleetRequestConfig `locationName:"spotFleetRequestConfigSet" locationNameList:"item" type:"list" required:"true"` @@ -34987,7 +39754,7 @@ func (s *DescribeSpotFleetRequestsOutput) SetSpotFleetRequestConfigs(v []*SpotFl } // Contains the parameters for DescribeSpotInstanceRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequestsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequestsRequest type DescribeSpotInstanceRequestsInput struct { _ struct{} `type:"structure"` @@ -35001,7 +39768,7 @@ type DescribeSpotInstanceRequestsInput struct { // // * availability-zone-group - The Availability Zone group. // - // * create-time - The time stamp when the Spot instance request was created. + // * create-time - The time stamp when the Spot Instance request was created. // // * fault-code - The fault code related to the request. // @@ -35009,23 +39776,23 @@ type DescribeSpotInstanceRequestsInput struct { // // * instance-id - The ID of the instance that fulfilled the request. // - // * launch-group - The Spot instance launch group. + // * launch-group - The Spot Instance launch group. // // * launch.block-device-mapping.delete-on-termination - Indicates whether - // the Amazon EBS volume is deleted on instance termination. + // the EBS volume is deleted on instance termination. // - // * launch.block-device-mapping.device-name - The device name for the Amazon - // EBS volume (for example, /dev/sdh). + // * launch.block-device-mapping.device-name - The device name for the volume + // in the block device mapping (for example, /dev/sdh or xvdh). // - // * launch.block-device-mapping.snapshot-id - The ID of the snapshot used - // for the Amazon EBS volume. + // * launch.block-device-mapping.snapshot-id - The ID of the snapshot for + // the EBS volume. // - // * launch.block-device-mapping.volume-size - The size of the Amazon EBS - // volume, in GiB. + // * launch.block-device-mapping.volume-size - The size of the EBS volume, + // in GiB. // - // * launch.block-device-mapping.volume-type - The type of the Amazon EBS - // volume: gp2 for General Purpose SSD, io1 for Provisioned IOPS SSD, st1 - // for Throughput Optimized HDD, sc1for Cold HDD, or standard for Magnetic. + // * launch.block-device-mapping.volume-type - The type of EBS volume: gp2 + // for General Purpose SSD, io1 for Provisioned IOPS SSD, st1 for Throughput + // Optimized HDD, sc1for Cold HDD, or standard for Magnetic. // // * launch.group-id - The security group for the instance. // @@ -35037,53 +39804,53 @@ type DescribeSpotInstanceRequestsInput struct { // // * launch.key-name - The name of the key pair the instance launched with. // - // * launch.monitoring-enabled - Whether monitoring is enabled for the Spot - // instance. + // * launch.monitoring-enabled - Whether detailed monitoring is enabled for + // the Spot Instance. // // * launch.ramdisk-id - The RAM disk ID. // - // * network-interface.network-interface-id - The ID of the network interface. - // - // * network-interface.device-index - The index of the device for the network - // interface attachment on the instance. - // - // * network-interface.subnet-id - The ID of the subnet for the instance. - // - // * network-interface.description - A description of the network interface. - // - // * network-interface.private-ip-address - The primary private IP address - // of the network interface. - // - // * network-interface.delete-on-termination - Indicates whether the network - // interface is deleted when the instance is terminated. - // - // * network-interface.group-id - The ID of the security group associated - // with the network interface. - // - // * network-interface.group-name - The name of the security group associated - // with the network interface. + // * launched-availability-zone - The Availability Zone in which the request + // is launched. // // * network-interface.addresses.primary - Indicates whether the IP address // is the primary private IP address. // + // * network-interface.delete-on-termination - Indicates whether the network + // interface is deleted when the instance is terminated. + // + // * network-interface.description - A description of the network interface. + // + // * network-interface.device-index - The index of the device for the network + // interface attachment on the instance. + // + // * network-interface.group-id - The ID of the security group associated + // with the network interface. + // + // * network-interface.network-interface-id - The ID of the network interface. + // + // * network-interface.private-ip-address - The primary private IP address + // of the network interface. + // + // * network-interface.subnet-id - The ID of the subnet for the instance. + // // * product-description - The product description associated with the instance // (Linux/UNIX | Windows). // - // * spot-instance-request-id - The Spot instance request ID. + // * spot-instance-request-id - The Spot Instance request ID. // - // * spot-price - The maximum hourly price for any Spot instance launched + // * spot-price - The maximum hourly price for any Spot Instance launched // to fulfill the request. // - // * state - The state of the Spot instance request (open | active | closed - // | cancelled | failed). Spot bid status information can help you track - // your Amazon EC2 Spot instance requests. For more information, see Spot - // Bid Status (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) + // * state - The state of the Spot Instance request (open | active | closed + // | cancelled | failed). Spot request status information can help you track + // your Amazon EC2 Spot Instance requests. For more information, see Spot + // Request Status (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) // in the Amazon Elastic Compute Cloud User Guide. // // * status-code - The short code describing the most recent evaluation of - // your Spot instance request. + // your Spot Instance request. // - // * status-message - The message explaining the status of the Spot instance + // * status-message - The message explaining the status of the Spot Instance // request. // // * tag:key=value - The key/value combination of a tag assigned to the resource. @@ -35102,17 +39869,14 @@ type DescribeSpotInstanceRequestsInput struct { // * tag-value - The value of a tag assigned to the resource. This filter // is independent of the tag-key filter. // - // * type - The type of Spot instance request (one-time | persistent). - // - // * launched-availability-zone - The Availability Zone in which the bid - // is launched. + // * type - The type of Spot Instance request (one-time | persistent). // // * valid-from - The start date of the request. // // * valid-until - The end date of the request. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // One or more Spot instance request IDs. + // One or more Spot Instance request IDs. SpotInstanceRequestIds []*string `locationName:"SpotInstanceRequestId" locationNameList:"SpotInstanceRequestId" type:"list"` } @@ -35145,11 +39909,11 @@ func (s *DescribeSpotInstanceRequestsInput) SetSpotInstanceRequestIds(v []*strin } // Contains the output of DescribeSpotInstanceRequests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequestsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequestsResult type DescribeSpotInstanceRequestsOutput struct { _ struct{} `type:"structure"` - // One or more Spot instance requests. + // One or more Spot Instance requests. SpotInstanceRequests []*SpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` } @@ -35170,7 +39934,7 @@ func (s *DescribeSpotInstanceRequestsOutput) SetSpotInstanceRequests(v []*SpotIn } // Contains the parameters for DescribeSpotPriceHistory. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistoryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistoryRequest type DescribeSpotPriceHistoryInput struct { _ struct{} `type:"structure"` @@ -35206,8 +39970,7 @@ type DescribeSpotPriceHistoryInput struct { // than or less than comparison is not supported. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // Filters the results by the specified instance types. Note that T2 and HS1 - // instance types are not supported. + // Filters the results by the specified instance types. InstanceTypes []*string `locationName:"InstanceType" type:"list"` // The maximum number of results to return in a single call. Specify a value @@ -35291,7 +40054,7 @@ func (s *DescribeSpotPriceHistoryInput) SetStartTime(v time.Time) *DescribeSpotP } // Contains the output of DescribeSpotPriceHistory. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistoryResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistoryResult type DescribeSpotPriceHistoryOutput struct { _ struct{} `type:"structure"` @@ -35325,7 +40088,7 @@ func (s *DescribeSpotPriceHistoryOutput) SetSpotPriceHistory(v []*SpotPrice) *De return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroupsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroupsRequest type DescribeStaleSecurityGroupsInput struct { _ struct{} `type:"structure"` @@ -35403,7 +40166,7 @@ func (s *DescribeStaleSecurityGroupsInput) SetVpcId(v string) *DescribeStaleSecu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroupsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroupsResult type DescribeStaleSecurityGroupsOutput struct { _ struct{} `type:"structure"` @@ -35438,7 +40201,7 @@ func (s *DescribeStaleSecurityGroupsOutput) SetStaleSecurityGroupSet(v []*StaleS } // Contains the parameters for DescribeSubnets. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnetsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnetsRequest type DescribeSubnetsInput struct { _ struct{} `type:"structure"` @@ -35530,7 +40293,7 @@ func (s *DescribeSubnetsInput) SetSubnetIds(v []*string) *DescribeSubnetsInput { } // Contains the output of DescribeSubnets. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnetsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnetsResult type DescribeSubnetsOutput struct { _ struct{} `type:"structure"` @@ -35555,7 +40318,7 @@ func (s *DescribeSubnetsOutput) SetSubnets(v []*Subnet) *DescribeSubnetsOutput { } // Contains the parameters for DescribeTags. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTagsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTagsRequest type DescribeTagsInput struct { _ struct{} `type:"structure"` @@ -35623,7 +40386,7 @@ func (s *DescribeTagsInput) SetNextToken(v string) *DescribeTagsInput { } // Contains the output of DescribeTags. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTagsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTagsResult type DescribeTagsOutput struct { _ struct{} `type:"structure"` @@ -35658,7 +40421,7 @@ func (s *DescribeTagsOutput) SetTags(v []*TagDescription) *DescribeTagsOutput { } // Contains the parameters for DescribeVolumeAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttributeRequest type DescribeVolumeAttributeInput struct { _ struct{} `type:"structure"` @@ -35719,7 +40482,7 @@ func (s *DescribeVolumeAttributeInput) SetVolumeId(v string) *DescribeVolumeAttr } // Contains the output of DescribeVolumeAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttributeResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttributeResult type DescribeVolumeAttributeOutput struct { _ struct{} `type:"structure"` @@ -35762,7 +40525,7 @@ func (s *DescribeVolumeAttributeOutput) SetVolumeId(v string) *DescribeVolumeAtt } // Contains the parameters for DescribeVolumeStatus. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatusRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatusRequest type DescribeVolumeStatusInput struct { _ struct{} `type:"structure"` @@ -35868,7 +40631,7 @@ func (s *DescribeVolumeStatusInput) SetVolumeIds(v []*string) *DescribeVolumeSta } // Contains the output of DescribeVolumeStatus. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatusResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatusResult type DescribeVolumeStatusOutput struct { _ struct{} `type:"structure"` @@ -35903,7 +40666,7 @@ func (s *DescribeVolumeStatusOutput) SetVolumeStatuses(v []*VolumeStatusItem) *D } // Contains the parameters for DescribeVolumes. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesRequest type DescribeVolumesInput struct { _ struct{} `type:"structure"` @@ -35920,7 +40683,7 @@ type DescribeVolumesInput struct { // * attachment.delete-on-termination - Whether the volume is deleted on // instance termination. // - // * attachment.device - The device name that is exposed to the instance + // * attachment.device - The device name specified in the block device mapping // (for example, /dev/sda1). // // * attachment.instance-id - The ID of the instance the volume is attached @@ -36026,7 +40789,7 @@ func (s *DescribeVolumesInput) SetVolumeIds(v []*string) *DescribeVolumesInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModificationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModificationsRequest type DescribeVolumesModificationsInput struct { _ struct{} `type:"structure"` @@ -36092,7 +40855,7 @@ func (s *DescribeVolumesModificationsInput) SetVolumeIds(v []*string) *DescribeV return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModificationsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModificationsResult type DescribeVolumesModificationsOutput struct { _ struct{} `type:"structure"` @@ -36126,7 +40889,7 @@ func (s *DescribeVolumesModificationsOutput) SetVolumesModifications(v []*Volume } // Contains the output of DescribeVolumes. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesResult type DescribeVolumesOutput struct { _ struct{} `type:"structure"` @@ -36163,7 +40926,7 @@ func (s *DescribeVolumesOutput) SetVolumes(v []*Volume) *DescribeVolumesOutput { } // Contains the parameters for DescribeVpcAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttributeRequest type DescribeVpcAttributeInput struct { _ struct{} `type:"structure"` @@ -36229,7 +40992,7 @@ func (s *DescribeVpcAttributeInput) SetVpcId(v string) *DescribeVpcAttributeInpu } // Contains the output of DescribeVpcAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttributeResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttributeResult type DescribeVpcAttributeOutput struct { _ struct{} `type:"structure"` @@ -36276,7 +41039,7 @@ func (s *DescribeVpcAttributeOutput) SetVpcId(v string) *DescribeVpcAttributeOut } // Contains the parameters for DescribeVpcClassicLinkDnsSupport. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupportRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupportRequest type DescribeVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` @@ -36338,7 +41101,7 @@ func (s *DescribeVpcClassicLinkDnsSupportInput) SetVpcIds(v []*string) *Describe } // Contains the output of DescribeVpcClassicLinkDnsSupport. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupportResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupportResult type DescribeVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` @@ -36372,7 +41135,7 @@ func (s *DescribeVpcClassicLinkDnsSupportOutput) SetVpcs(v []*ClassicLinkDnsSupp } // Contains the parameters for DescribeVpcClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkRequest type DescribeVpcClassicLinkInput struct { _ struct{} `type:"structure"` @@ -36437,7 +41200,7 @@ func (s *DescribeVpcClassicLinkInput) SetVpcIds(v []*string) *DescribeVpcClassic } // Contains the output of DescribeVpcClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkResult type DescribeVpcClassicLinkOutput struct { _ struct{} `type:"structure"` @@ -36461,8 +41224,449 @@ func (s *DescribeVpcClassicLinkOutput) SetVpcs(v []*VpcClassicLink) *DescribeVpc return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionNotificationsRequest +type DescribeVpcEndpointConnectionNotificationsInput struct { + _ struct{} `type:"structure"` + + // The ID of the notification. + ConnectionNotificationId *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * connection-notification-arn - The ARN of SNS topic for the notification. + // + // * connection-notification-id - The ID of the notification. + // + // * connection-notification-state - The state of the notification (Enabled + // | Disabled). + // + // * connection-notification-type - The type of notification (Topic). + // + // * service-id - The ID of the endpoint service. + // + // * vpc-endpoint-id - The ID of the VPC endpoint. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return in a single call. To retrieve the + // remaining results, make another request with the returned NextToken value. + MaxResults *int64 `type:"integer"` + + // The token to request the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeVpcEndpointConnectionNotificationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointConnectionNotificationsInput) GoString() string { + return s.String() +} + +// SetConnectionNotificationId sets the ConnectionNotificationId field's value. +func (s *DescribeVpcEndpointConnectionNotificationsInput) SetConnectionNotificationId(v string) *DescribeVpcEndpointConnectionNotificationsInput { + s.ConnectionNotificationId = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeVpcEndpointConnectionNotificationsInput) SetDryRun(v bool) *DescribeVpcEndpointConnectionNotificationsInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeVpcEndpointConnectionNotificationsInput) SetFilters(v []*Filter) *DescribeVpcEndpointConnectionNotificationsInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeVpcEndpointConnectionNotificationsInput) SetMaxResults(v int64) *DescribeVpcEndpointConnectionNotificationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointConnectionNotificationsInput) SetNextToken(v string) *DescribeVpcEndpointConnectionNotificationsInput { + s.NextToken = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionNotificationsResult +type DescribeVpcEndpointConnectionNotificationsOutput struct { + _ struct{} `type:"structure"` + + // One or more notifications. + ConnectionNotificationSet []*ConnectionNotification `locationName:"connectionNotificationSet" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeVpcEndpointConnectionNotificationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointConnectionNotificationsOutput) GoString() string { + return s.String() +} + +// SetConnectionNotificationSet sets the ConnectionNotificationSet field's value. +func (s *DescribeVpcEndpointConnectionNotificationsOutput) SetConnectionNotificationSet(v []*ConnectionNotification) *DescribeVpcEndpointConnectionNotificationsOutput { + s.ConnectionNotificationSet = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointConnectionNotificationsOutput) SetNextToken(v string) *DescribeVpcEndpointConnectionNotificationsOutput { + s.NextToken = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionsRequest +type DescribeVpcEndpointConnectionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * service-id - The ID of the service. + // + // * vpc-endpoint-owner - The AWS account number of the owner of the endpoint. + // + // * vpc-endpoint-state - The state of the endpoint (pendingAcceptance | + // pending | available | deleting | deleted | rejected | failed). + // + // * vpc-endpoint-id - The ID of the endpoint. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results of the initial request can be seen by sending another + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeVpcEndpointConnectionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointConnectionsInput) GoString() string { + return s.String() +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeVpcEndpointConnectionsInput) SetDryRun(v bool) *DescribeVpcEndpointConnectionsInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeVpcEndpointConnectionsInput) SetFilters(v []*Filter) *DescribeVpcEndpointConnectionsInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeVpcEndpointConnectionsInput) SetMaxResults(v int64) *DescribeVpcEndpointConnectionsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointConnectionsInput) SetNextToken(v string) *DescribeVpcEndpointConnectionsInput { + s.NextToken = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionsResult +type DescribeVpcEndpointConnectionsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about one or more VPC endpoint connections. + VpcEndpointConnections []*VpcEndpointConnection `locationName:"vpcEndpointConnectionSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcEndpointConnectionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointConnectionsOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointConnectionsOutput) SetNextToken(v string) *DescribeVpcEndpointConnectionsOutput { + s.NextToken = &v + return s +} + +// SetVpcEndpointConnections sets the VpcEndpointConnections field's value. +func (s *DescribeVpcEndpointConnectionsOutput) SetVpcEndpointConnections(v []*VpcEndpointConnection) *DescribeVpcEndpointConnectionsOutput { + s.VpcEndpointConnections = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServiceConfigurationsRequest +type DescribeVpcEndpointServiceConfigurationsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * service-name - The name of the service. + // + // * service-id - The ID of the service. + // + // * service-state - The state of the service (Pending | Available | Deleting + // | Deleted | Failed). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results of the initial request can be seen by sending another + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` + + // The IDs of one or more services. + ServiceIds []*string `locationName:"ServiceId" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcEndpointServiceConfigurationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServiceConfigurationsInput) GoString() string { + return s.String() +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeVpcEndpointServiceConfigurationsInput) SetDryRun(v bool) *DescribeVpcEndpointServiceConfigurationsInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeVpcEndpointServiceConfigurationsInput) SetFilters(v []*Filter) *DescribeVpcEndpointServiceConfigurationsInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeVpcEndpointServiceConfigurationsInput) SetMaxResults(v int64) *DescribeVpcEndpointServiceConfigurationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointServiceConfigurationsInput) SetNextToken(v string) *DescribeVpcEndpointServiceConfigurationsInput { + s.NextToken = &v + return s +} + +// SetServiceIds sets the ServiceIds field's value. +func (s *DescribeVpcEndpointServiceConfigurationsInput) SetServiceIds(v []*string) *DescribeVpcEndpointServiceConfigurationsInput { + s.ServiceIds = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServiceConfigurationsResult +type DescribeVpcEndpointServiceConfigurationsOutput struct { + _ struct{} `type:"structure"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // Information about one or more services. + ServiceConfigurations []*ServiceConfiguration `locationName:"serviceConfigurationSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s DescribeVpcEndpointServiceConfigurationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServiceConfigurationsOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointServiceConfigurationsOutput) SetNextToken(v string) *DescribeVpcEndpointServiceConfigurationsOutput { + s.NextToken = &v + return s +} + +// SetServiceConfigurations sets the ServiceConfigurations field's value. +func (s *DescribeVpcEndpointServiceConfigurationsOutput) SetServiceConfigurations(v []*ServiceConfiguration) *DescribeVpcEndpointServiceConfigurationsOutput { + s.ServiceConfigurations = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicePermissionsRequest +type DescribeVpcEndpointServicePermissionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more filters. + // + // * principal - The ARN of the principal. + // + // * principal-type - The principal type (All | Service | OrganizationUnit + // | Account | User | Role). + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + + // The maximum number of results to return for the request in a single page. + // The remaining results of the initial request can be seen by sending another + // request with the returned NextToken value. This value can be between 5 and + // 1000; if MaxResults is given a value larger than 1000, only 1000 results + // are returned. + MaxResults *int64 `type:"integer"` + + // The token to retrieve the next page of results. + NextToken *string `type:"string"` + + // The ID of the service. + // + // ServiceId is a required field + ServiceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeVpcEndpointServicePermissionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServicePermissionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeVpcEndpointServicePermissionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeVpcEndpointServicePermissionsInput"} + if s.ServiceId == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *DescribeVpcEndpointServicePermissionsInput) SetDryRun(v bool) *DescribeVpcEndpointServicePermissionsInput { + s.DryRun = &v + return s +} + +// SetFilters sets the Filters field's value. +func (s *DescribeVpcEndpointServicePermissionsInput) SetFilters(v []*Filter) *DescribeVpcEndpointServicePermissionsInput { + s.Filters = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeVpcEndpointServicePermissionsInput) SetMaxResults(v int64) *DescribeVpcEndpointServicePermissionsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointServicePermissionsInput) SetNextToken(v string) *DescribeVpcEndpointServicePermissionsInput { + s.NextToken = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *DescribeVpcEndpointServicePermissionsInput) SetServiceId(v string) *DescribeVpcEndpointServicePermissionsInput { + s.ServiceId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicePermissionsResult +type DescribeVpcEndpointServicePermissionsOutput struct { + _ struct{} `type:"structure"` + + // Information about one or more allowed principals. + AllowedPrincipals []*AllowedPrincipal `locationName:"allowedPrincipals" locationNameList:"item" type:"list"` + + // The token to use to retrieve the next page of results. This value is null + // when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeVpcEndpointServicePermissionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeVpcEndpointServicePermissionsOutput) GoString() string { + return s.String() +} + +// SetAllowedPrincipals sets the AllowedPrincipals field's value. +func (s *DescribeVpcEndpointServicePermissionsOutput) SetAllowedPrincipals(v []*AllowedPrincipal) *DescribeVpcEndpointServicePermissionsOutput { + s.AllowedPrincipals = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeVpcEndpointServicePermissionsOutput) SetNextToken(v string) *DescribeVpcEndpointServicePermissionsOutput { + s.NextToken = &v + return s +} + // Contains the parameters for DescribeVpcEndpointServices. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicesRequest type DescribeVpcEndpointServicesInput struct { _ struct{} `type:"structure"` @@ -36472,6 +41676,11 @@ type DescribeVpcEndpointServicesInput struct { // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` + // One or more filters. + // + // * service-name: The name of the service. + Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` + // The maximum number of items to return for this request. The request returns // a token that you can specify in a subsequent call to get the next set of // results. @@ -36482,6 +41691,9 @@ type DescribeVpcEndpointServicesInput struct { // The token for the next set of items to return. (You received this token from // a prior call.) NextToken *string `type:"string"` + + // One or more service names. + ServiceNames []*string `locationName:"ServiceName" locationNameList:"item" type:"list"` } // String returns the string representation @@ -36500,6 +41712,12 @@ func (s *DescribeVpcEndpointServicesInput) SetDryRun(v bool) *DescribeVpcEndpoin return s } +// SetFilters sets the Filters field's value. +func (s *DescribeVpcEndpointServicesInput) SetFilters(v []*Filter) *DescribeVpcEndpointServicesInput { + s.Filters = v + return s +} + // SetMaxResults sets the MaxResults field's value. func (s *DescribeVpcEndpointServicesInput) SetMaxResults(v int64) *DescribeVpcEndpointServicesInput { s.MaxResults = &v @@ -36512,8 +41730,14 @@ func (s *DescribeVpcEndpointServicesInput) SetNextToken(v string) *DescribeVpcEn return s } +// SetServiceNames sets the ServiceNames field's value. +func (s *DescribeVpcEndpointServicesInput) SetServiceNames(v []*string) *DescribeVpcEndpointServicesInput { + s.ServiceNames = v + return s +} + // Contains the output of DescribeVpcEndpointServices. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicesResult type DescribeVpcEndpointServicesOutput struct { _ struct{} `type:"structure"` @@ -36521,7 +41745,10 @@ type DescribeVpcEndpointServicesOutput struct { // items to return, the string is empty. NextToken *string `locationName:"nextToken" type:"string"` - // A list of supported AWS services. + // Information about the service. + ServiceDetails []*ServiceDetail `locationName:"serviceDetailSet" locationNameList:"item" type:"list"` + + // A list of supported services. ServiceNames []*string `locationName:"serviceNameSet" locationNameList:"item" type:"list"` } @@ -36541,6 +41768,12 @@ func (s *DescribeVpcEndpointServicesOutput) SetNextToken(v string) *DescribeVpcE return s } +// SetServiceDetails sets the ServiceDetails field's value. +func (s *DescribeVpcEndpointServicesOutput) SetServiceDetails(v []*ServiceDetail) *DescribeVpcEndpointServicesOutput { + s.ServiceDetails = v + return s +} + // SetServiceNames sets the ServiceNames field's value. func (s *DescribeVpcEndpointServicesOutput) SetServiceNames(v []*string) *DescribeVpcEndpointServicesOutput { s.ServiceNames = v @@ -36548,7 +41781,7 @@ func (s *DescribeVpcEndpointServicesOutput) SetServiceNames(v []*string) *Descri } // Contains the parameters for DescribeVpcEndpoints. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointsRequest type DescribeVpcEndpointsInput struct { _ struct{} `type:"structure"` @@ -36560,7 +41793,7 @@ type DescribeVpcEndpointsInput struct { // One or more filters. // - // * service-name: The name of the AWS service. + // * service-name: The name of the service. // // * vpc-id: The ID of the VPC in which the endpoint resides. // @@ -36626,7 +41859,7 @@ func (s *DescribeVpcEndpointsInput) SetVpcEndpointIds(v []*string) *DescribeVpcE } // Contains the output of DescribeVpcEndpoints. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointsResult type DescribeVpcEndpointsOutput struct { _ struct{} `type:"structure"` @@ -36661,7 +41894,7 @@ func (s *DescribeVpcEndpointsOutput) SetVpcEndpoints(v []*VpcEndpoint) *Describe } // Contains the parameters for DescribeVpcPeeringConnections. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnectionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnectionsRequest type DescribeVpcPeeringConnectionsInput struct { _ struct{} `type:"structure"` @@ -36673,12 +41906,12 @@ type DescribeVpcPeeringConnectionsInput struct { // One or more filters. // - // * accepter-vpc-info.cidr-block - The IPv4 CIDR block of the peer VPC. + // * accepter-vpc-info.cidr-block - The IPv4 CIDR block of the accepter VPC. // // * accepter-vpc-info.owner-id - The AWS account ID of the owner of the - // peer VPC. + // accepter VPC. // - // * accepter-vpc-info.vpc-id - The ID of the peer VPC. + // * accepter-vpc-info.vpc-id - The ID of the accepter VPC. // // * expiration-time - The expiration date and time for the VPC peering connection. // @@ -36691,7 +41924,7 @@ type DescribeVpcPeeringConnectionsInput struct { // * requester-vpc-info.vpc-id - The ID of the requester VPC. // // * status-code - The status of the VPC peering connection (pending-acceptance - // | failed | expired | provisioning | active | deleted | rejected). + // | failed | expired | provisioning | active | deleting | deleted | rejected). // // * status-message - A message that provides more information about the // status of the VPC peering connection, if applicable. @@ -36750,7 +41983,7 @@ func (s *DescribeVpcPeeringConnectionsInput) SetVpcPeeringConnectionIds(v []*str } // Contains the output of DescribeVpcPeeringConnections. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnectionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnectionsResult type DescribeVpcPeeringConnectionsOutput struct { _ struct{} `type:"structure"` @@ -36775,7 +42008,7 @@ func (s *DescribeVpcPeeringConnectionsOutput) SetVpcPeeringConnections(v []*VpcP } // Contains the parameters for DescribeVpcs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcsRequest type DescribeVpcsInput struct { _ struct{} `type:"structure"` @@ -36787,10 +42020,19 @@ type DescribeVpcsInput struct { // One or more filters. // - // * cidr - The IPv4 CIDR block of the VPC. The CIDR block you specify must - // exactly match the VPC's CIDR block for information to be returned for - // the VPC. Must contain the slash followed by one or two digits (for example, - // /28). + // * cidr - The primary IPv4 CIDR block of the VPC. The CIDR block you specify + // must exactly match the VPC's CIDR block for information to be returned + // for the VPC. Must contain the slash followed by one or two digits (for + // example, /28). + // + // * cidr-block-association.cidr-block - An IPv4 CIDR block associated with + // the VPC. + // + // * cidr-block-association.association-id - The association ID for an IPv4 + // CIDR block associated with the VPC. + // + // * cidr-block-association.state - The state of an IPv4 CIDR block associated + // with the VPC. // // * dhcp-options-id - The ID of a set of DHCP options. // @@ -36861,7 +42103,7 @@ func (s *DescribeVpcsInput) SetVpcIds(v []*string) *DescribeVpcsInput { } // Contains the output of DescribeVpcs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcsResult type DescribeVpcsOutput struct { _ struct{} `type:"structure"` @@ -36886,7 +42128,7 @@ func (s *DescribeVpcsOutput) SetVpcs(v []*Vpc) *DescribeVpcsOutput { } // Contains the parameters for DescribeVpnConnections. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnectionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnectionsRequest type DescribeVpnConnectionsInput struct { _ struct{} `type:"structure"` @@ -36977,7 +42219,7 @@ func (s *DescribeVpnConnectionsInput) SetVpnConnectionIds(v []*string) *Describe } // Contains the output of DescribeVpnConnections. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnectionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnectionsResult type DescribeVpnConnectionsOutput struct { _ struct{} `type:"structure"` @@ -37002,7 +42244,7 @@ func (s *DescribeVpnConnectionsOutput) SetVpnConnections(v []*VpnConnection) *De } // Contains the parameters for DescribeVpnGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGatewaysRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGatewaysRequest type DescribeVpnGatewaysInput struct { _ struct{} `type:"structure"` @@ -37014,6 +42256,9 @@ type DescribeVpnGatewaysInput struct { // One or more filters. // + // * amazon-side-asn - The Autonomous System Number (ASN) for the Amazon + // side of the gateway. + // // * attachment.state - The current state of the attachment between the gateway // and the VPC (attaching | attached | detaching | detached). // @@ -37082,7 +42327,7 @@ func (s *DescribeVpnGatewaysInput) SetVpnGatewayIds(v []*string) *DescribeVpnGat } // Contains the output of DescribeVpnGateways. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGatewaysResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGatewaysResult type DescribeVpnGatewaysOutput struct { _ struct{} `type:"structure"` @@ -37107,7 +42352,7 @@ func (s *DescribeVpnGatewaysOutput) SetVpnGateways(v []*VpnGateway) *DescribeVpn } // Contains the parameters for DetachClassicLinkVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpcRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpcRequest type DetachClassicLinkVpcInput struct { _ struct{} `type:"structure"` @@ -37173,7 +42418,7 @@ func (s *DetachClassicLinkVpcInput) SetVpcId(v string) *DetachClassicLinkVpcInpu } // Contains the output of DetachClassicLinkVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpcResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpcResult type DetachClassicLinkVpcOutput struct { _ struct{} `type:"structure"` @@ -37198,7 +42443,7 @@ func (s *DetachClassicLinkVpcOutput) SetReturn(v bool) *DetachClassicLinkVpcOutp } // Contains the parameters for DetachInternetGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGatewayRequest type DetachInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -37263,7 +42508,7 @@ func (s *DetachInternetGatewayInput) SetVpcId(v string) *DetachInternetGatewayIn return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGatewayOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGatewayOutput type DetachInternetGatewayOutput struct { _ struct{} `type:"structure"` } @@ -37279,7 +42524,7 @@ func (s DetachInternetGatewayOutput) GoString() string { } // Contains the parameters for DetachNetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterfaceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterfaceRequest type DetachNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -37339,7 +42584,7 @@ func (s *DetachNetworkInterfaceInput) SetForce(v bool) *DetachNetworkInterfaceIn return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterfaceOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterfaceOutput type DetachNetworkInterfaceOutput struct { _ struct{} `type:"structure"` } @@ -37355,7 +42600,7 @@ func (s DetachNetworkInterfaceOutput) GoString() string { } // Contains the parameters for DetachVolume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolumeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolumeRequest type DetachVolumeInput struct { _ struct{} `type:"structure"` @@ -37440,7 +42685,7 @@ func (s *DetachVolumeInput) SetVolumeId(v string) *DetachVolumeInput { } // Contains the parameters for DetachVpnGateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGatewayRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGatewayRequest type DetachVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -37505,7 +42750,7 @@ func (s *DetachVpnGatewayInput) SetVpnGatewayId(v string) *DetachVpnGatewayInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGatewayOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGatewayOutput type DetachVpnGatewayOutput struct { _ struct{} `type:"structure"` } @@ -37521,7 +42766,7 @@ func (s DetachVpnGatewayOutput) GoString() string { } // Describes a DHCP configuration option. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DhcpConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DhcpConfiguration type DhcpConfiguration struct { _ struct{} `type:"structure"` @@ -37555,7 +42800,7 @@ func (s *DhcpConfiguration) SetValues(v []*AttributeValue) *DhcpConfiguration { } // Describes a set of DHCP options. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DhcpOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DhcpOptions type DhcpOptions struct { _ struct{} `type:"structure"` @@ -37598,7 +42843,7 @@ func (s *DhcpOptions) SetTags(v []*Tag) *DhcpOptions { } // Contains the parameters for DisableVgwRoutePropagation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagationRequest type DisableVgwRoutePropagationInput struct { _ struct{} `type:"structure"` @@ -37651,7 +42896,7 @@ func (s *DisableVgwRoutePropagationInput) SetRouteTableId(v string) *DisableVgwR return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagationOutput type DisableVgwRoutePropagationOutput struct { _ struct{} `type:"structure"` } @@ -37667,7 +42912,7 @@ func (s DisableVgwRoutePropagationOutput) GoString() string { } // Contains the parameters for DisableVpcClassicLinkDnsSupport. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupportRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupportRequest type DisableVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` @@ -37692,7 +42937,7 @@ func (s *DisableVpcClassicLinkDnsSupportInput) SetVpcId(v string) *DisableVpcCla } // Contains the output of DisableVpcClassicLinkDnsSupport. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupportResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupportResult type DisableVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` @@ -37717,7 +42962,7 @@ func (s *DisableVpcClassicLinkDnsSupportOutput) SetReturn(v bool) *DisableVpcCla } // Contains the parameters for DisableVpcClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkRequest type DisableVpcClassicLinkInput struct { _ struct{} `type:"structure"` @@ -37769,7 +43014,7 @@ func (s *DisableVpcClassicLinkInput) SetVpcId(v string) *DisableVpcClassicLinkIn } // Contains the output of DisableVpcClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkResult type DisableVpcClassicLinkOutput struct { _ struct{} `type:"structure"` @@ -37794,7 +43039,7 @@ func (s *DisableVpcClassicLinkOutput) SetReturn(v bool) *DisableVpcClassicLinkOu } // Contains the parameters for DisassociateAddress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddressRequest type DisassociateAddressInput struct { _ struct{} `type:"structure"` @@ -37839,7 +43084,7 @@ func (s *DisassociateAddressInput) SetPublicIp(v string) *DisassociateAddressInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddressOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddressOutput type DisassociateAddressOutput struct { _ struct{} `type:"structure"` } @@ -37854,7 +43099,7 @@ func (s DisassociateAddressOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfileRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfileRequest type DisassociateIamInstanceProfileInput struct { _ struct{} `type:"structure"` @@ -37893,7 +43138,7 @@ func (s *DisassociateIamInstanceProfileInput) SetAssociationId(v string) *Disass return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfileResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfileResult type DisassociateIamInstanceProfileOutput struct { _ struct{} `type:"structure"` @@ -37918,7 +43163,7 @@ func (s *DisassociateIamInstanceProfileOutput) SetIamInstanceProfileAssociation( } // Contains the parameters for DisassociateRouteTable. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTableRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTableRequest type DisassociateRouteTableInput struct { _ struct{} `type:"structure"` @@ -37970,7 +43215,7 @@ func (s *DisassociateRouteTableInput) SetDryRun(v bool) *DisassociateRouteTableI return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTableOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTableOutput type DisassociateRouteTableOutput struct { _ struct{} `type:"structure"` } @@ -37985,7 +43230,7 @@ func (s DisassociateRouteTableOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlockRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlockRequest type DisassociateSubnetCidrBlockInput struct { _ struct{} `type:"structure"` @@ -38024,7 +43269,7 @@ func (s *DisassociateSubnetCidrBlockInput) SetAssociationId(v string) *Disassoci return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlockResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlockResult type DisassociateSubnetCidrBlockOutput struct { _ struct{} `type:"structure"` @@ -38057,7 +43302,7 @@ func (s *DisassociateSubnetCidrBlockOutput) SetSubnetId(v string) *DisassociateS return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlockRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlockRequest type DisassociateVpcCidrBlockInput struct { _ struct{} `type:"structure"` @@ -38096,10 +43341,13 @@ func (s *DisassociateVpcCidrBlockInput) SetAssociationId(v string) *Disassociate return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlockResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlockResult type DisassociateVpcCidrBlockOutput struct { _ struct{} `type:"structure"` + // Information about the IPv4 CIDR block association. + CidrBlockAssociation *VpcCidrBlockAssociation `locationName:"cidrBlockAssociation" type:"structure"` + // Information about the IPv6 CIDR block association. Ipv6CidrBlockAssociation *VpcIpv6CidrBlockAssociation `locationName:"ipv6CidrBlockAssociation" type:"structure"` @@ -38117,6 +43365,12 @@ func (s DisassociateVpcCidrBlockOutput) GoString() string { return s.String() } +// SetCidrBlockAssociation sets the CidrBlockAssociation field's value. +func (s *DisassociateVpcCidrBlockOutput) SetCidrBlockAssociation(v *VpcCidrBlockAssociation) *DisassociateVpcCidrBlockOutput { + s.CidrBlockAssociation = v + return s +} + // SetIpv6CidrBlockAssociation sets the Ipv6CidrBlockAssociation field's value. func (s *DisassociateVpcCidrBlockOutput) SetIpv6CidrBlockAssociation(v *VpcIpv6CidrBlockAssociation) *DisassociateVpcCidrBlockOutput { s.Ipv6CidrBlockAssociation = v @@ -38130,7 +43384,7 @@ func (s *DisassociateVpcCidrBlockOutput) SetVpcId(v string) *DisassociateVpcCidr } // Describes a disk image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImage type DiskImage struct { _ struct{} `type:"structure"` @@ -38193,7 +43447,7 @@ func (s *DiskImage) SetVolume(v *VolumeDetail) *DiskImage { } // Describes a disk image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageDescription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageDescription type DiskImageDescription struct { _ struct{} `type:"structure"` @@ -38258,7 +43512,7 @@ func (s *DiskImageDescription) SetSize(v int64) *DiskImageDescription { } // Describes a disk image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageDetail +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageDetail type DiskImageDetail struct { _ struct{} `type:"structure"` @@ -38333,7 +43587,7 @@ func (s *DiskImageDetail) SetImportManifestUrl(v string) *DiskImageDetail { } // Describes a disk image volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageVolumeDescription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageVolumeDescription type DiskImageVolumeDescription struct { _ struct{} `type:"structure"` @@ -38368,16 +43622,52 @@ func (s *DiskImageVolumeDescription) SetSize(v int64) *DiskImageVolumeDescriptio return s } +// Describes a DNS entry. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DnsEntry +type DnsEntry struct { + _ struct{} `type:"structure"` + + // The DNS name. + DnsName *string `locationName:"dnsName" type:"string"` + + // The ID of the private hosted zone. + HostedZoneId *string `locationName:"hostedZoneId" type:"string"` +} + +// String returns the string representation +func (s DnsEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DnsEntry) GoString() string { + return s.String() +} + +// SetDnsName sets the DnsName field's value. +func (s *DnsEntry) SetDnsName(v string) *DnsEntry { + s.DnsName = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *DnsEntry) SetHostedZoneId(v string) *DnsEntry { + s.HostedZoneId = &v + return s +} + // Describes a block device for an EBS volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsBlockDevice +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsBlockDevice type EbsBlockDevice struct { _ struct{} `type:"structure"` // Indicates whether the EBS volume is deleted on instance termination. DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` - // Indicates whether the EBS volume is encrypted. Encrypted Amazon EBS volumes - // may only be attached to instances that support Amazon EBS encryption. + // Indicates whether the EBS volume is encrypted. Encrypted volumes can only + // be attached to instances that support Amazon EBS encryption. If you are creating + // a volume from a snapshot, you can't specify an encryption value. This is + // because only blank volumes can be encrypted on creation. Encrypted *bool `locationName:"encrypted" type:"boolean"` // The number of I/O operations per second (IOPS) that the volume supports. @@ -38395,6 +43685,14 @@ type EbsBlockDevice struct { // it is not used in requests to create gp2, st1, sc1, or standard volumes. Iops *int64 `locationName:"iops" type:"integer"` + // ID for a user-managed CMK under which the EBS volume is encrypted. + // + // Note: This parameter is only supported on BlockDeviceMapping objects called + // by RunInstances (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html), + // RequestSpotFleet (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RequestSpotFleet.html), + // and RequestSpotInstances (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RequestSpotInstances.html). + KmsKeyId *string `type:"string"` + // The ID of the snapshot. SnapshotId *string `locationName:"snapshotId" type:"string"` @@ -38444,6 +43742,12 @@ func (s *EbsBlockDevice) SetIops(v int64) *EbsBlockDevice { return s } +// SetKmsKeyId sets the KmsKeyId field's value. +func (s *EbsBlockDevice) SetKmsKeyId(v string) *EbsBlockDevice { + s.KmsKeyId = &v + return s +} + // SetSnapshotId sets the SnapshotId field's value. func (s *EbsBlockDevice) SetSnapshotId(v string) *EbsBlockDevice { s.SnapshotId = &v @@ -38463,7 +43767,7 @@ func (s *EbsBlockDevice) SetVolumeType(v string) *EbsBlockDevice { } // Describes a parameter used to set up an EBS volume in a block device mapping. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsInstanceBlockDevice +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsInstanceBlockDevice type EbsInstanceBlockDevice struct { _ struct{} `type:"structure"` @@ -38516,7 +43820,7 @@ func (s *EbsInstanceBlockDevice) SetVolumeId(v string) *EbsInstanceBlockDevice { // Describes information used to set up an EBS volume specified in a block device // mapping. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsInstanceBlockDeviceSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsInstanceBlockDeviceSpecification type EbsInstanceBlockDeviceSpecification struct { _ struct{} `type:"structure"` @@ -38550,7 +43854,7 @@ func (s *EbsInstanceBlockDeviceSpecification) SetVolumeId(v string) *EbsInstance } // Describes an egress-only Internet gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EgressOnlyInternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EgressOnlyInternetGateway type EgressOnlyInternetGateway struct { _ struct{} `type:"structure"` @@ -38584,7 +43888,7 @@ func (s *EgressOnlyInternetGateway) SetEgressOnlyInternetGatewayId(v string) *Eg } // Describes the association between an instance and an Elastic GPU. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuAssociation type ElasticGpuAssociation struct { _ struct{} `type:"structure"` @@ -38636,7 +43940,7 @@ func (s *ElasticGpuAssociation) SetElasticGpuId(v string) *ElasticGpuAssociation } // Describes the status of an Elastic GPU. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuHealth +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuHealth type ElasticGpuHealth struct { _ struct{} `type:"structure"` @@ -38661,7 +43965,7 @@ func (s *ElasticGpuHealth) SetStatus(v string) *ElasticGpuHealth { } // A specification for an Elastic GPU. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuSpecification type ElasticGpuSpecification struct { _ struct{} `type:"structure"` @@ -38700,8 +44004,33 @@ func (s *ElasticGpuSpecification) SetType(v string) *ElasticGpuSpecification { return s } +// Describes an elastic GPU. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuSpecificationResponse +type ElasticGpuSpecificationResponse struct { + _ struct{} `type:"structure"` + + // The elastic GPU type. + Type *string `locationName:"type" type:"string"` +} + +// String returns the string representation +func (s ElasticGpuSpecificationResponse) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ElasticGpuSpecificationResponse) GoString() string { + return s.String() +} + +// SetType sets the Type field's value. +func (s *ElasticGpuSpecificationResponse) SetType(v string) *ElasticGpuSpecificationResponse { + s.Type = &v + return s +} + // Describes an Elastic GPU. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpus type ElasticGpus struct { _ struct{} `type:"structure"` @@ -38771,7 +44100,7 @@ func (s *ElasticGpus) SetInstanceId(v string) *ElasticGpus { } // Contains the parameters for EnableVgwRoutePropagation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationRequest type EnableVgwRoutePropagationInput struct { _ struct{} `type:"structure"` @@ -38824,7 +44153,7 @@ func (s *EnableVgwRoutePropagationInput) SetRouteTableId(v string) *EnableVgwRou return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationOutput type EnableVgwRoutePropagationOutput struct { _ struct{} `type:"structure"` } @@ -38840,7 +44169,7 @@ func (s EnableVgwRoutePropagationOutput) GoString() string { } // Contains the parameters for EnableVolumeIO. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIORequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIORequest type EnableVolumeIOInput struct { _ struct{} `type:"structure"` @@ -38891,7 +44220,7 @@ func (s *EnableVolumeIOInput) SetVolumeId(v string) *EnableVolumeIOInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIOOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIOOutput type EnableVolumeIOOutput struct { _ struct{} `type:"structure"` } @@ -38907,7 +44236,7 @@ func (s EnableVolumeIOOutput) GoString() string { } // Contains the parameters for EnableVpcClassicLinkDnsSupport. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupportRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupportRequest type EnableVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` @@ -38932,7 +44261,7 @@ func (s *EnableVpcClassicLinkDnsSupportInput) SetVpcId(v string) *EnableVpcClass } // Contains the output of EnableVpcClassicLinkDnsSupport. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupportResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupportResult type EnableVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` @@ -38957,7 +44286,7 @@ func (s *EnableVpcClassicLinkDnsSupportOutput) SetReturn(v bool) *EnableVpcClass } // Contains the parameters for EnableVpcClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkRequest type EnableVpcClassicLinkInput struct { _ struct{} `type:"structure"` @@ -39009,7 +44338,7 @@ func (s *EnableVpcClassicLinkInput) SetVpcId(v string) *EnableVpcClassicLinkInpu } // Contains the output of EnableVpcClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkResult type EnableVpcClassicLinkOutput struct { _ struct{} `type:"structure"` @@ -39033,8 +44362,8 @@ func (s *EnableVpcClassicLinkOutput) SetReturn(v bool) *EnableVpcClassicLinkOutp return s } -// Describes a Spot fleet event. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EventInformation +// Describes a Spot Fleet event. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EventInformation type EventInformation struct { _ struct{} `type:"structure"` @@ -39043,9 +44372,9 @@ type EventInformation struct { // The event. // - // The following are the error events. + // The following are the error events: // - // * iamFleetRoleInvalid - The Spot fleet did not have the required permissions + // * iamFleetRoleInvalid - The Spot Fleet did not have the required permissions // either to launch or terminate an instance. // // * launchSpecTemporarilyBlacklisted - The configuration is not valid and @@ -39056,43 +44385,52 @@ type EventInformation struct { // For more information, see the description of the event. // // * spotInstanceCountLimitExceeded - You've reached the limit on the number - // of Spot instances that you can launch. + // of Spot Instances that you can launch. // - // The following are the fleetRequestChange events. + // The following are the fleetRequestChange events: // - // * active - The Spot fleet has been validated and Amazon EC2 is attempting - // to maintain the target number of running Spot instances. + // * active - The Spot Fleet has been validated and Amazon EC2 is attempting + // to maintain the target number of running Spot Instances. // - // * cancelled - The Spot fleet is canceled and has no running Spot instances. - // The Spot fleet will be deleted two days after its instances were terminated. + // * cancelled - The Spot Fleet is canceled and has no running Spot Instances. + // The Spot Fleet will be deleted two days after its instances were terminated. // - // * cancelled_running - The Spot fleet is canceled and will not launch additional - // Spot instances, but its existing Spot instances continue to run until + // * cancelled_running - The Spot Fleet is canceled and will not launch additional + // Spot Instances, but its existing Spot Instances continue to run until // they are interrupted or terminated. // - // * cancelled_terminating - The Spot fleet is canceled and its Spot instances + // * cancelled_terminating - The Spot Fleet is canceled and its Spot Instances // are terminating. // - // * expired - The Spot fleet request has expired. A subsequent event indicates + // * expired - The Spot Fleet request has expired. A subsequent event indicates // that the instances were terminated, if the request was created with TerminateInstancesWithExpiration // set. // - // * modify_in_progress - A request to modify the Spot fleet request was + // * modify_in_progress - A request to modify the Spot Fleet request was // accepted and is in progress. // - // * modify_successful - The Spot fleet request was modified. + // * modify_successful - The Spot Fleet request was modified. // - // * price_update - The bid price for a launch configuration was adjusted - // because it was too high. This change is permanent. + // * price_update - The price for a launch configuration was adjusted because + // it was too high. This change is permanent. // - // * submitted - The Spot fleet request is being evaluated and Amazon EC2 - // is preparing to launch the target number of Spot instances. + // * submitted - The Spot Fleet request is being evaluated and Amazon EC2 + // is preparing to launch the target number of Spot Instances. // - // The following are the instanceChange events. + // The following are the instanceChange events: // - // * launched - A bid was fulfilled and a new instance was launched. + // * launched - A request was fulfilled and a new instance was launched. // // * terminated - An instance was terminated by the user. + // + // The following are the Information events: + // + // * launchSpecUnusable - The price in a launch specification is not valid + // because it is below the Spot price or the Spot price is above the On-Demand + // price. + // + // * fleetProgressHalted - The price in every launch specification is not + // valid. A launch specification might become valid if the Spot price changes. EventSubType *string `locationName:"eventSubType" type:"string"` // The ID of the instance. This information is available only for instanceChange @@ -39129,7 +44467,7 @@ func (s *EventInformation) SetInstanceId(v string) *EventInformation { } // Describes an instance export task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportTask type ExportTask struct { _ struct{} `type:"structure"` @@ -39199,7 +44537,7 @@ func (s *ExportTask) SetStatusMessage(v string) *ExportTask { } // Describes the format and location for an instance export task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportToS3Task +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportToS3Task type ExportToS3Task struct { _ struct{} `type:"structure"` @@ -39253,7 +44591,7 @@ func (s *ExportToS3Task) SetS3Key(v string) *ExportToS3Task { } // Describes an instance export task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportToS3TaskSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportToS3TaskSpecification type ExportToS3TaskSpecification struct { _ struct{} `type:"structure"` @@ -39310,7 +44648,7 @@ func (s *ExportToS3TaskSpecification) SetS3Prefix(v string) *ExportToS3TaskSpeci // A filter name and value pair that is used to return a more specific list // of results. Filters can be used to match a set of resources by various criteria, // such as tags, attributes, or IDs. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Filter +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Filter type Filter struct { _ struct{} `type:"structure"` @@ -39343,8 +44681,67 @@ func (s *Filter) SetValues(v []*string) *Filter { return s } +// Describes a launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FleetLaunchTemplateSpecification +type FleetLaunchTemplateSpecification struct { + _ struct{} `type:"structure"` + + // The ID of the launch template. You must specify either a template ID or a + // template name. + LaunchTemplateId *string `locationName:"launchTemplateId" type:"string"` + + // The name of the launch template. You must specify either a template name + // or a template ID. + LaunchTemplateName *string `locationName:"launchTemplateName" min:"3" type:"string"` + + // The version number. By default, the default version of the launch template + // is used. + Version *string `locationName:"version" type:"string"` +} + +// String returns the string representation +func (s FleetLaunchTemplateSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FleetLaunchTemplateSpecification) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *FleetLaunchTemplateSpecification) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "FleetLaunchTemplateSpecification"} + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *FleetLaunchTemplateSpecification) SetLaunchTemplateId(v string) *FleetLaunchTemplateSpecification { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *FleetLaunchTemplateSpecification) SetLaunchTemplateName(v string) *FleetLaunchTemplateSpecification { + s.LaunchTemplateName = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *FleetLaunchTemplateSpecification) SetVersion(v string) *FleetLaunchTemplateSpecification { + s.Version = &v + return s +} + // Describes a flow log. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FlowLog +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FlowLog type FlowLog struct { _ struct{} `type:"structure"` @@ -39446,7 +44843,7 @@ func (s *FlowLog) SetTrafficType(v string) *FlowLog { } // Describes an Amazon FPGA image (AFI). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImage type FpgaImage struct { _ struct{} `type:"structure"` @@ -39477,6 +44874,9 @@ type FpgaImage struct { // The product codes for the AFI. ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` + // Indicates whether the AFI is public. + Public *bool `locationName:"public" type:"boolean"` + // The version of the AWS Shell that was used to create the bitstream. ShellVersion *string `locationName:"shellVersion" type:"string"` @@ -39554,6 +44954,12 @@ func (s *FpgaImage) SetProductCodes(v []*ProductCode) *FpgaImage { return s } +// SetPublic sets the Public field's value. +func (s *FpgaImage) SetPublic(v bool) *FpgaImage { + s.Public = &v + return s +} + // SetShellVersion sets the ShellVersion field's value. func (s *FpgaImage) SetShellVersion(v string) *FpgaImage { s.ShellVersion = &v @@ -39578,9 +44984,70 @@ func (s *FpgaImage) SetUpdateTime(v time.Time) *FpgaImage { return s } +// Describes an Amazon FPGA image (AFI) attribute. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImageAttribute +type FpgaImageAttribute struct { + _ struct{} `type:"structure"` + + // The description of the AFI. + Description *string `locationName:"description" type:"string"` + + // The ID of the AFI. + FpgaImageId *string `locationName:"fpgaImageId" type:"string"` + + // One or more load permissions. + LoadPermissions []*LoadPermission `locationName:"loadPermissions" locationNameList:"item" type:"list"` + + // The name of the AFI. + Name *string `locationName:"name" type:"string"` + + // One or more product codes. + ProductCodes []*ProductCode `locationName:"productCodes" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s FpgaImageAttribute) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FpgaImageAttribute) GoString() string { + return s.String() +} + +// SetDescription sets the Description field's value. +func (s *FpgaImageAttribute) SetDescription(v string) *FpgaImageAttribute { + s.Description = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *FpgaImageAttribute) SetFpgaImageId(v string) *FpgaImageAttribute { + s.FpgaImageId = &v + return s +} + +// SetLoadPermissions sets the LoadPermissions field's value. +func (s *FpgaImageAttribute) SetLoadPermissions(v []*LoadPermission) *FpgaImageAttribute { + s.LoadPermissions = v + return s +} + +// SetName sets the Name field's value. +func (s *FpgaImageAttribute) SetName(v string) *FpgaImageAttribute { + s.Name = &v + return s +} + +// SetProductCodes sets the ProductCodes field's value. +func (s *FpgaImageAttribute) SetProductCodes(v []*ProductCode) *FpgaImageAttribute { + s.ProductCodes = v + return s +} + // Describes the state of the bitstream generation process for an Amazon FPGA // image (AFI). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImageState +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImageState type FpgaImageState struct { _ struct{} `type:"structure"` @@ -39622,7 +45089,7 @@ func (s *FpgaImageState) SetMessage(v string) *FpgaImageState { } // Contains the parameters for GetConsoleOutput. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputRequest type GetConsoleOutputInput struct { _ struct{} `type:"structure"` @@ -39674,7 +45141,7 @@ func (s *GetConsoleOutputInput) SetInstanceId(v string) *GetConsoleOutputInput { } // Contains the output of GetConsoleOutput. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputResult type GetConsoleOutputOutput struct { _ struct{} `type:"structure"` @@ -39718,7 +45185,7 @@ func (s *GetConsoleOutputOutput) SetTimestamp(v time.Time) *GetConsoleOutputOutp } // Contains the parameters for the request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshotRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshotRequest type GetConsoleScreenshotInput struct { _ struct{} `type:"structure"` @@ -39780,7 +45247,7 @@ func (s *GetConsoleScreenshotInput) SetWakeUp(v bool) *GetConsoleScreenshotInput } // Contains the output of the request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshotResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshotResult type GetConsoleScreenshotOutput struct { _ struct{} `type:"structure"` @@ -39813,7 +45280,7 @@ func (s *GetConsoleScreenshotOutput) SetInstanceId(v string) *GetConsoleScreensh return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreviewRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreviewRequest type GetHostReservationPurchasePreviewInput struct { _ struct{} `type:"structure"` @@ -39867,7 +45334,7 @@ func (s *GetHostReservationPurchasePreviewInput) SetOfferingId(v string) *GetHos return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreviewResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreviewResult type GetHostReservationPurchasePreviewOutput struct { _ struct{} `type:"structure"` @@ -39877,7 +45344,7 @@ type GetHostReservationPurchasePreviewOutput struct { // The purchase information of the Dedicated Host Reservation and the Dedicated // Hosts associated with it. - Purchase []*Purchase `locationName:"purchase" type:"list"` + Purchase []*Purchase `locationName:"purchase" locationNameList:"item" type:"list"` // The potential total hourly price of the reservation per hour. TotalHourlyPrice *string `locationName:"totalHourlyPrice" type:"string"` @@ -39920,8 +45387,83 @@ func (s *GetHostReservationPurchasePreviewOutput) SetTotalUpfrontPrice(v string) return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetLaunchTemplateDataRequest +type GetLaunchTemplateDataInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the instance. + // + // InstanceId is a required field + InstanceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s GetLaunchTemplateDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLaunchTemplateDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLaunchTemplateDataInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLaunchTemplateDataInput"} + if s.InstanceId == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *GetLaunchTemplateDataInput) SetDryRun(v bool) *GetLaunchTemplateDataInput { + s.DryRun = &v + return s +} + +// SetInstanceId sets the InstanceId field's value. +func (s *GetLaunchTemplateDataInput) SetInstanceId(v string) *GetLaunchTemplateDataInput { + s.InstanceId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetLaunchTemplateDataResult +type GetLaunchTemplateDataOutput struct { + _ struct{} `type:"structure"` + + // The instance data. + LaunchTemplateData *ResponseLaunchTemplateData `locationName:"launchTemplateData" type:"structure"` +} + +// String returns the string representation +func (s GetLaunchTemplateDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLaunchTemplateDataOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplateData sets the LaunchTemplateData field's value. +func (s *GetLaunchTemplateDataOutput) SetLaunchTemplateData(v *ResponseLaunchTemplateData) *GetLaunchTemplateDataOutput { + s.LaunchTemplateData = v + return s +} + // Contains the parameters for GetPasswordData. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordDataRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordDataRequest type GetPasswordDataInput struct { _ struct{} `type:"structure"` @@ -39973,14 +45515,15 @@ func (s *GetPasswordDataInput) SetInstanceId(v string) *GetPasswordDataInput { } // Contains the output of GetPasswordData. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordDataResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordDataResult type GetPasswordDataOutput struct { _ struct{} `type:"structure"` // The ID of the Windows instance. InstanceId *string `locationName:"instanceId" type:"string"` - // The password of the instance. + // The password of the instance. Returns an empty string if the password is + // not available. PasswordData *string `locationName:"passwordData" type:"string"` // The time the data was last updated. @@ -40016,7 +45559,7 @@ func (s *GetPasswordDataOutput) SetTimestamp(v time.Time) *GetPasswordDataOutput } // Contains the parameters for GetReservedInstanceExchangeQuote. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuoteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuoteRequest type GetReservedInstancesExchangeQuoteInput struct { _ struct{} `type:"structure"` @@ -40031,7 +45574,7 @@ type GetReservedInstancesExchangeQuoteInput struct { // ReservedInstanceIds is a required field ReservedInstanceIds []*string `locationName:"ReservedInstanceId" locationNameList:"ReservedInstanceId" type:"list" required:"true"` - // The configuration requirements of the Convertible Reserved Instances to exchange + // The configuration of the target Convertible Reserved Instance to exchange // for your current Convertible Reserved Instances. TargetConfigurations []*TargetConfigurationRequest `locationName:"TargetConfiguration" locationNameList:"TargetConfigurationRequest" type:"list"` } @@ -40088,7 +45631,7 @@ func (s *GetReservedInstancesExchangeQuoteInput) SetTargetConfigurations(v []*Ta } // Contains the output of GetReservedInstancesExchangeQuote. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuoteResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuoteResult type GetReservedInstancesExchangeQuoteOutput struct { _ struct{} `type:"structure"` @@ -40185,7 +45728,7 @@ func (s *GetReservedInstancesExchangeQuoteOutput) SetValidationFailureReason(v s } // Describes a security group. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GroupIdentifier +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GroupIdentifier type GroupIdentifier struct { _ struct{} `type:"structure"` @@ -40218,8 +45761,8 @@ func (s *GroupIdentifier) SetGroupName(v string) *GroupIdentifier { return s } -// Describes an event in the history of the Spot fleet request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HistoryRecord +// Describes an event in the history of the Spot Fleet request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HistoryRecord type HistoryRecord struct { _ struct{} `type:"structure"` @@ -40230,12 +45773,14 @@ type HistoryRecord struct { // The event type. // - // * error - Indicates an error with the Spot fleet request. + // * error - An error with the Spot Fleet request. // - // * fleetRequestChange - Indicates a change in the status or configuration - // of the Spot fleet request. + // * fleetRequestChange - A change in the status or configuration of the + // Spot Fleet request. // - // * instanceChange - Indicates that an instance was launched or terminated. + // * instanceChange - An instance was launched or terminated. + // + // * Information - An informational event. // // EventType is a required field EventType *string `locationName:"eventType" type:"string" required:"true" enum:"EventType"` @@ -40275,7 +45820,7 @@ func (s *HistoryRecord) SetTimestamp(v time.Time) *HistoryRecord { } // Describes the properties of the Dedicated Host. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Host +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Host type Host struct { _ struct{} `type:"structure"` @@ -40375,7 +45920,7 @@ func (s *Host) SetState(v string) *Host { } // Describes an instance running on a Dedicated Host. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostInstance type HostInstance struct { _ struct{} `type:"structure"` @@ -40409,7 +45954,7 @@ func (s *HostInstance) SetInstanceType(v string) *HostInstance { } // Details about the Dedicated Host Reservation offering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostOffering +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostOffering type HostOffering struct { _ struct{} `type:"structure"` @@ -40488,7 +46033,7 @@ func (s *HostOffering) SetUpfrontPrice(v string) *HostOffering { } // Describes properties of a Dedicated Host. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostProperties +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostProperties type HostProperties struct { _ struct{} `type:"structure"` @@ -40540,7 +46085,7 @@ func (s *HostProperties) SetTotalVCpus(v int64) *HostProperties { } // Details about the Dedicated Host Reservation and associated Dedicated Hosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostReservation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostReservation type HostReservation struct { _ struct{} `type:"structure"` @@ -40678,7 +46223,7 @@ func (s *HostReservation) SetUpfrontPrice(v string) *HostReservation { } // Describes an IAM instance profile. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfile +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfile type IamInstanceProfile struct { _ struct{} `type:"structure"` @@ -40712,7 +46257,7 @@ func (s *IamInstanceProfile) SetId(v string) *IamInstanceProfile { } // Describes an association between an IAM instance profile and an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfileAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfileAssociation type IamInstanceProfileAssociation struct { _ struct{} `type:"structure"` @@ -40773,7 +46318,7 @@ func (s *IamInstanceProfileAssociation) SetTimestamp(v time.Time) *IamInstancePr } // Describes an IAM instance profile. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfileSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfileSpecification type IamInstanceProfileSpecification struct { _ struct{} `type:"structure"` @@ -40807,7 +46352,7 @@ func (s *IamInstanceProfileSpecification) SetName(v string) *IamInstanceProfileS } // Describes the ICMP type and code. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IcmpTypeCode +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IcmpTypeCode type IcmpTypeCode struct { _ struct{} `type:"structure"` @@ -40841,7 +46386,7 @@ func (s *IcmpTypeCode) SetType(v int64) *IcmpTypeCode { } // Describes the ID format for a resource. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IdFormat +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IdFormat type IdFormat struct { _ struct{} `type:"structure"` @@ -40886,7 +46431,7 @@ func (s *IdFormat) SetUseLongIds(v bool) *IdFormat { } // Describes an image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Image +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Image type Image struct { _ struct{} `type:"structure"` @@ -40946,7 +46491,7 @@ type Image struct { // images. RamdiskId *string `locationName:"ramdiskId" type:"string"` - // The device name of the root device (for example, /dev/sda1 or /dev/xvda). + // The device name of the root device volume (for example, /dev/sda1). RootDeviceName *string `locationName:"rootDeviceName" type:"string"` // The type of root device used by the AMI. The AMI can use an EBS volume or @@ -41126,7 +46671,7 @@ func (s *Image) SetVirtualizationType(v string) *Image { } // Describes the disk container object for an import image task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImageDiskContainer +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImageDiskContainer type ImageDiskContainer struct { _ struct{} `type:"structure"` @@ -41199,7 +46744,7 @@ func (s *ImageDiskContainer) SetUserBucket(v *UserBucket) *ImageDiskContainer { } // Contains the parameters for ImportImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageRequest type ImportImageInput struct { _ struct{} `type:"structure"` @@ -41321,7 +46866,7 @@ func (s *ImportImageInput) SetRoleName(v string) *ImportImageInput { } // Contains the output for ImportImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageResult type ImportImageOutput struct { _ struct{} `type:"structure"` @@ -41436,7 +46981,7 @@ func (s *ImportImageOutput) SetStatusMessage(v string) *ImportImageOutput { } // Describes an import image task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageTask type ImportImageTask struct { _ struct{} `type:"structure"` @@ -41555,7 +47100,7 @@ func (s *ImportImageTask) SetStatusMessage(v string) *ImportImageTask { } // Contains the parameters for ImportInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceRequest type ImportInstanceInput struct { _ struct{} `type:"structure"` @@ -41644,7 +47189,7 @@ func (s *ImportInstanceInput) SetPlatform(v string) *ImportInstanceInput { } // Describes the launch specification for VM import. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceLaunchSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceLaunchSpecification type ImportInstanceLaunchSpecification struct { _ struct{} `type:"structure"` @@ -41764,7 +47309,7 @@ func (s *ImportInstanceLaunchSpecification) SetUserData(v *UserData) *ImportInst } // Contains the output for ImportInstance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceResult type ImportInstanceOutput struct { _ struct{} `type:"structure"` @@ -41789,7 +47334,7 @@ func (s *ImportInstanceOutput) SetConversionTask(v *ConversionTask) *ImportInsta } // Describes an import instance task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceTaskDetails +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceTaskDetails type ImportInstanceTaskDetails struct { _ struct{} `type:"structure"` @@ -41843,7 +47388,7 @@ func (s *ImportInstanceTaskDetails) SetVolumes(v []*ImportInstanceVolumeDetailIt } // Describes an import volume task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceVolumeDetailItem +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceVolumeDetailItem type ImportInstanceVolumeDetailItem struct { _ struct{} `type:"structure"` @@ -41932,7 +47477,7 @@ func (s *ImportInstanceVolumeDetailItem) SetVolume(v *DiskImageVolumeDescription } // Contains the parameters for ImportKeyPair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPairRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPairRequest type ImportKeyPairInput struct { _ struct{} `type:"structure"` @@ -42001,7 +47546,7 @@ func (s *ImportKeyPairInput) SetPublicKeyMaterial(v []byte) *ImportKeyPairInput } // Contains the output of ImportKeyPair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPairResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPairResult type ImportKeyPairOutput struct { _ struct{} `type:"structure"` @@ -42035,7 +47580,7 @@ func (s *ImportKeyPairOutput) SetKeyName(v string) *ImportKeyPairOutput { } // Contains the parameters for ImportSnapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotRequest type ImportSnapshotInput struct { _ struct{} `type:"structure"` @@ -42108,7 +47653,7 @@ func (s *ImportSnapshotInput) SetRoleName(v string) *ImportSnapshotInput { } // Contains the output for ImportSnapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotResult type ImportSnapshotOutput struct { _ struct{} `type:"structure"` @@ -42151,7 +47696,7 @@ func (s *ImportSnapshotOutput) SetSnapshotTaskDetail(v *SnapshotTaskDetail) *Imp } // Describes an import snapshot task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotTask +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotTask type ImportSnapshotTask struct { _ struct{} `type:"structure"` @@ -42194,7 +47739,7 @@ func (s *ImportSnapshotTask) SetSnapshotTaskDetail(v *SnapshotTaskDetail) *Impor } // Contains the parameters for ImportVolume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeRequest type ImportVolumeInput struct { _ struct{} `type:"structure"` @@ -42293,7 +47838,7 @@ func (s *ImportVolumeInput) SetVolume(v *VolumeDetail) *ImportVolumeInput { } // Contains the output for ImportVolume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeResult type ImportVolumeOutput struct { _ struct{} `type:"structure"` @@ -42318,7 +47863,7 @@ func (s *ImportVolumeOutput) SetConversionTask(v *ConversionTask) *ImportVolumeO } // Describes an import volume task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeTaskDetails +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeTaskDetails type ImportVolumeTaskDetails struct { _ struct{} `type:"structure"` @@ -42387,7 +47932,7 @@ func (s *ImportVolumeTaskDetails) SetVolume(v *DiskImageVolumeDescription) *Impo } // Describes an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Instance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Instance type Instance struct { _ struct{} `type:"structure"` @@ -42404,7 +47949,7 @@ type Instance struct { // The idempotency token you provided when you launched the instance, if applicable. ClientToken *string `locationName:"clientToken" type:"string"` - // Indicates whether the instance is optimized for EBS I/O. This optimization + // Indicates whether the instance is optimized for Amazon EBS I/O. This optimization // provides dedicated throughput to Amazon EBS and an optimized configuration // stack to provide optimal I/O performance. This optimization isn't available // with all instance types. Additional usage charges apply when using an EBS @@ -42429,7 +47974,7 @@ type Instance struct { // The ID of the instance. InstanceId *string `locationName:"instanceId" type:"string"` - // Indicates whether this is a Spot instance or a Scheduled Instance. + // Indicates whether this is a Spot Instance or a Scheduled Instance. InstanceLifecycle *string `locationName:"instanceLifecycle" type:"string" enum:"InstanceLifecycleType"` // The instance type. @@ -42461,7 +48006,7 @@ type Instance struct { // DNS hostname can only be used inside the Amazon EC2 network. This name is // not available until the instance enters the running state. // - // [EC2-VPC] The Amazon-provided DNS server will resolve Amazon-provided private + // [EC2-VPC] The Amazon-provided DNS server resolves Amazon-provided private // DNS hostnames if you've enabled DNS resolution and DNS hostnames in your // VPC. If you are not using the Amazon-provided DNS server in your VPC, your // custom domain name servers must resolve the hostname as appropriate. @@ -42484,7 +48029,7 @@ type Instance struct { // The RAM disk associated with this instance, if applicable. RamdiskId *string `locationName:"ramdiskId" type:"string"` - // The root device name (for example, /dev/sda1 or /dev/xvda). + // The device name of the root device volume (for example, /dev/sda1). RootDeviceName *string `locationName:"rootDeviceName" type:"string"` // The root device type used by the AMI. The AMI can use an EBS volume or an @@ -42496,13 +48041,13 @@ type Instance struct { // Specifies whether to enable an instance launched in a VPC to perform NAT. // This controls whether source/destination checking is enabled on the instance. - // A value of true means checking is enabled, and false means checking is disabled. - // The value must be false for the instance to perform NAT. For more information, - // see NAT Instances (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html) + // A value of true means that checking is enabled, and false means that checking + // is disabled. The value must be false for the instance to perform NAT. For + // more information, see NAT Instances (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html) // in the Amazon Virtual Private Cloud User Guide. SourceDestCheck *bool `locationName:"sourceDestCheck" type:"boolean"` - // If the request is a Spot instance request, the ID of the request. + // If the request is a Spot Instance request, the ID of the request. SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` // Specifies whether enhanced networking with the Intel 82599 Virtual Function @@ -42776,11 +48321,11 @@ func (s *Instance) SetVpcId(v string) *Instance { } // Describes a block device mapping. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceBlockDeviceMapping +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceBlockDeviceMapping type InstanceBlockDeviceMapping struct { _ struct{} `type:"structure"` - // The device name exposed to the instance (for example, /dev/sdh or xvdh). + // The device name (for example, /dev/sdh or xvdh). DeviceName *string `locationName:"deviceName" type:"string"` // Parameters used to automatically set up EBS volumes when the instance is @@ -42811,11 +48356,11 @@ func (s *InstanceBlockDeviceMapping) SetEbs(v *EbsInstanceBlockDevice) *Instance } // Describes a block device mapping entry. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceBlockDeviceMappingSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceBlockDeviceMappingSpecification type InstanceBlockDeviceMappingSpecification struct { _ struct{} `type:"structure"` - // The device name exposed to the instance (for example, /dev/sdh or xvdh). + // The device name (for example, /dev/sdh or xvdh). DeviceName *string `locationName:"deviceName" type:"string"` // Parameters used to automatically set up EBS volumes when the instance is @@ -42864,7 +48409,7 @@ func (s *InstanceBlockDeviceMappingSpecification) SetVirtualName(v string) *Inst } // Information about the instance type that the Dedicated Host supports. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCapacity +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCapacity type InstanceCapacity struct { _ struct{} `type:"structure"` @@ -42907,7 +48452,7 @@ func (s *InstanceCapacity) SetTotalCapacity(v int64) *InstanceCapacity { } // Describes a Reserved Instance listing state. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCount +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCount type InstanceCount struct { _ struct{} `type:"structure"` @@ -42940,8 +48485,78 @@ func (s *InstanceCount) SetState(v string) *InstanceCount { return s } +// Describes the credit option for CPU usage of a T2 instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCreditSpecification +type InstanceCreditSpecification struct { + _ struct{} `type:"structure"` + + // The credit option for CPU usage of the instance. Valid values are standard + // and unlimited. + CpuCredits *string `locationName:"cpuCredits" type:"string"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` +} + +// String returns the string representation +func (s InstanceCreditSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceCreditSpecification) GoString() string { + return s.String() +} + +// SetCpuCredits sets the CpuCredits field's value. +func (s *InstanceCreditSpecification) SetCpuCredits(v string) *InstanceCreditSpecification { + s.CpuCredits = &v + return s +} + +// SetInstanceId sets the InstanceId field's value. +func (s *InstanceCreditSpecification) SetInstanceId(v string) *InstanceCreditSpecification { + s.InstanceId = &v + return s +} + +// Describes the credit option for CPU usage of a T2 instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCreditSpecificationRequest +type InstanceCreditSpecificationRequest struct { + _ struct{} `type:"structure"` + + // The credit option for CPU usage of the instance. Valid values are standard + // and unlimited. + CpuCredits *string `type:"string"` + + // The ID of the instance. + InstanceId *string `type:"string"` +} + +// String returns the string representation +func (s InstanceCreditSpecificationRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceCreditSpecificationRequest) GoString() string { + return s.String() +} + +// SetCpuCredits sets the CpuCredits field's value. +func (s *InstanceCreditSpecificationRequest) SetCpuCredits(v string) *InstanceCreditSpecificationRequest { + s.CpuCredits = &v + return s +} + +// SetInstanceId sets the InstanceId field's value. +func (s *InstanceCreditSpecificationRequest) SetInstanceId(v string) *InstanceCreditSpecificationRequest { + s.InstanceId = &v + return s +} + // Describes an instance to export. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceExportDetails +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceExportDetails type InstanceExportDetails struct { _ struct{} `type:"structure"` @@ -42975,7 +48590,7 @@ func (s *InstanceExportDetails) SetTargetEnvironment(v string) *InstanceExportDe } // Describes an IPv6 address. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceIpv6Address +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceIpv6Address type InstanceIpv6Address struct { _ struct{} `type:"structure"` @@ -42999,8 +48614,67 @@ func (s *InstanceIpv6Address) SetIpv6Address(v string) *InstanceIpv6Address { return s } +// Describes an IPv6 address. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceIpv6AddressRequest +type InstanceIpv6AddressRequest struct { + _ struct{} `type:"structure"` + + // The IPv6 address. + Ipv6Address *string `type:"string"` +} + +// String returns the string representation +func (s InstanceIpv6AddressRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceIpv6AddressRequest) GoString() string { + return s.String() +} + +// SetIpv6Address sets the Ipv6Address field's value. +func (s *InstanceIpv6AddressRequest) SetIpv6Address(v string) *InstanceIpv6AddressRequest { + s.Ipv6Address = &v + return s +} + +// Describes the market (purchasing) option for the instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceMarketOptionsRequest +type InstanceMarketOptionsRequest struct { + _ struct{} `type:"structure"` + + // The market type. + MarketType *string `type:"string" enum:"MarketType"` + + // The options for Spot Instances. + SpotOptions *SpotMarketOptions `type:"structure"` +} + +// String returns the string representation +func (s InstanceMarketOptionsRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceMarketOptionsRequest) GoString() string { + return s.String() +} + +// SetMarketType sets the MarketType field's value. +func (s *InstanceMarketOptionsRequest) SetMarketType(v string) *InstanceMarketOptionsRequest { + s.MarketType = &v + return s +} + +// SetSpotOptions sets the SpotOptions field's value. +func (s *InstanceMarketOptionsRequest) SetSpotOptions(v *SpotMarketOptions) *InstanceMarketOptionsRequest { + s.SpotOptions = v + return s +} + // Describes the monitoring of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceMonitoring +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceMonitoring type InstanceMonitoring struct { _ struct{} `type:"structure"` @@ -43034,7 +48708,7 @@ func (s *InstanceMonitoring) SetMonitoring(v *Monitoring) *InstanceMonitoring { } // Describes a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterface type InstanceNetworkInterface struct { _ struct{} `type:"structure"` @@ -43186,7 +48860,7 @@ func (s *InstanceNetworkInterface) SetVpcId(v string) *InstanceNetworkInterface } // Describes association information for an Elastic IP address (IPv4). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceAssociation type InstanceNetworkInterfaceAssociation struct { _ struct{} `type:"structure"` @@ -43229,7 +48903,7 @@ func (s *InstanceNetworkInterfaceAssociation) SetPublicIp(v string) *InstanceNet } // Describes a network interface attachment. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceAttachment +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceAttachment type InstanceNetworkInterfaceAttachment struct { _ struct{} `type:"structure"` @@ -43290,7 +48964,7 @@ func (s *InstanceNetworkInterfaceAttachment) SetStatus(v string) *InstanceNetwor } // Describes a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceSpecification type InstanceNetworkInterfaceSpecification struct { _ struct{} `type:"structure"` @@ -43460,7 +49134,7 @@ func (s *InstanceNetworkInterfaceSpecification) SetSubnetId(v string) *InstanceN } // Describes a private IPv4 address. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstancePrivateIpAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstancePrivateIpAddress type InstancePrivateIpAddress struct { _ struct{} `type:"structure"` @@ -43513,7 +49187,7 @@ func (s *InstancePrivateIpAddress) SetPrivateIpAddress(v string) *InstancePrivat } // Describes the current state of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceState +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceState type InstanceState struct { _ struct{} `type:"structure"` @@ -43560,7 +49234,7 @@ func (s *InstanceState) SetName(v string) *InstanceState { } // Describes an instance state change. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStateChange +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStateChange type InstanceStateChange struct { _ struct{} `type:"structure"` @@ -43603,7 +49277,7 @@ func (s *InstanceStateChange) SetPreviousState(v *InstanceState) *InstanceStateC } // Describes the status of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatus type InstanceStatus struct { _ struct{} `type:"structure"` @@ -43677,7 +49351,7 @@ func (s *InstanceStatus) SetSystemStatus(v *InstanceStatusSummary) *InstanceStat } // Describes the instance status. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusDetails +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusDetails type InstanceStatusDetails struct { _ struct{} `type:"structure"` @@ -43721,7 +49395,7 @@ func (s *InstanceStatusDetails) SetStatus(v string) *InstanceStatusDetails { } // Describes a scheduled event for an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusEvent +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusEvent type InstanceStatusEvent struct { _ struct{} `type:"structure"` @@ -43777,7 +49451,7 @@ func (s *InstanceStatusEvent) SetNotBefore(v time.Time) *InstanceStatusEvent { } // Describes the status of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusSummary +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusSummary type InstanceStatusSummary struct { _ struct{} `type:"structure"` @@ -43811,7 +49485,7 @@ func (s *InstanceStatusSummary) SetStatus(v string) *InstanceStatusSummary { } // Describes an Internet gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InternetGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InternetGateway type InternetGateway struct { _ struct{} `type:"structure"` @@ -43855,7 +49529,7 @@ func (s *InternetGateway) SetTags(v []*Tag) *InternetGateway { // Describes the attachment of a VPC to an Internet gateway or an egress-only // Internet gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InternetGatewayAttachment +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InternetGatewayAttachment type InternetGatewayAttachment struct { _ struct{} `type:"structure"` @@ -43888,13 +49562,14 @@ func (s *InternetGatewayAttachment) SetVpcId(v string) *InternetGatewayAttachmen return s } -// Describes a security group rule. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IpPermission +// Describes a set of permissions for a security group rule. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IpPermission type IpPermission struct { _ struct{} `type:"structure"` // The start of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 - // type number. A value of -1 indicates all ICMP/ICMPv6 types. + // type number. A value of -1 indicates all ICMP/ICMPv6 types. If you specify + // all ICMP/ICMPv6 types, you must specify all codes. FromPort *int64 `locationName:"fromPort" type:"integer"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). @@ -43913,14 +49588,16 @@ type IpPermission struct { // [EC2-VPC only] One or more IPv6 ranges. Ipv6Ranges []*Ipv6Range `locationName:"ipv6Ranges" locationNameList:"item" type:"list"` - // (Valid for AuthorizeSecurityGroupEgress, RevokeSecurityGroupEgress and DescribeSecurityGroups - // only) One or more prefix list IDs for an AWS service. In an AuthorizeSecurityGroupEgress - // request, this is the AWS service that you want to access through a VPC endpoint - // from instances associated with the security group. + // (EC2-VPC only; valid for AuthorizeSecurityGroupEgress, RevokeSecurityGroupEgress + // and DescribeSecurityGroups only) One or more prefix list IDs for an AWS service. + // In an AuthorizeSecurityGroupEgress request, this is the AWS service that + // you want to access through a VPC endpoint from instances associated with + // the security group. PrefixListIds []*PrefixListId `locationName:"prefixListIds" locationNameList:"item" type:"list"` // The end of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 code. // A value of -1 indicates all ICMP/ICMPv6 codes for the specified ICMP type. + // If you specify all ICMP/ICMPv6 types, you must specify all codes. ToPort *int64 `locationName:"toPort" type:"integer"` // One or more security group and AWS account ID pairs. @@ -43980,13 +49657,20 @@ func (s *IpPermission) SetUserIdGroupPairs(v []*UserIdGroupPair) *IpPermission { } // Describes an IPv4 range. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IpRange +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IpRange type IpRange struct { _ struct{} `type:"structure"` // The IPv4 CIDR range. You can either specify a CIDR range or a source security - // group, not both. To specify a single IPv4 address, use the /32 prefix. + // group, not both. To specify a single IPv4 address, use the /32 prefix length. CidrIp *string `locationName:"cidrIp" type:"string"` + + // A description for the security group rule that references this IPv4 address + // range. + // + // Constraints: Up to 255 characters in length. Allowed characters are a-z, + // A-Z, 0-9, spaces, and ._-:/()#,@[]+=;{}!$* + Description *string `locationName:"description" type:"string"` } // String returns the string representation @@ -44005,8 +49689,14 @@ func (s *IpRange) SetCidrIp(v string) *IpRange { return s } +// SetDescription sets the Description field's value. +func (s *IpRange) SetDescription(v string) *IpRange { + s.Description = &v + return s +} + // Describes an IPv6 CIDR block. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Ipv6CidrBlock +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Ipv6CidrBlock type Ipv6CidrBlock struct { _ struct{} `type:"structure"` @@ -44031,13 +49721,20 @@ func (s *Ipv6CidrBlock) SetIpv6CidrBlock(v string) *Ipv6CidrBlock { } // [EC2-VPC only] Describes an IPv6 range. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Ipv6Range +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Ipv6Range type Ipv6Range struct { _ struct{} `type:"structure"` // The IPv6 CIDR range. You can either specify a CIDR range or a source security - // group, not both. To specify a single IPv6 address, use the /128 prefix. + // group, not both. To specify a single IPv6 address, use the /128 prefix length. CidrIpv6 *string `locationName:"cidrIpv6" type:"string"` + + // A description for the security group rule that references this IPv6 address + // range. + // + // Constraints: Up to 255 characters in length. Allowed characters are a-z, + // A-Z, 0-9, spaces, and ._-:/()#,@[]+=;{}!$* + Description *string `locationName:"description" type:"string"` } // String returns the string representation @@ -44056,8 +49753,14 @@ func (s *Ipv6Range) SetCidrIpv6(v string) *Ipv6Range { return s } +// SetDescription sets the Description field's value. +func (s *Ipv6Range) SetDescription(v string) *Ipv6Range { + s.Description = &v + return s +} + // Describes a key pair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/KeyPairInfo +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/KeyPairInfo type KeyPairInfo struct { _ struct{} `type:"structure"` @@ -44094,7 +49797,7 @@ func (s *KeyPairInfo) SetKeyName(v string) *KeyPairInfo { } // Describes a launch permission. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchPermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchPermission type LaunchPermission struct { _ struct{} `type:"structure"` @@ -44128,7 +49831,7 @@ func (s *LaunchPermission) SetUserId(v string) *LaunchPermission { } // Describes a launch permission modification. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchPermissionModifications +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchPermissionModifications type LaunchPermissionModifications struct { _ struct{} `type:"structure"` @@ -44163,7 +49866,7 @@ func (s *LaunchPermissionModifications) SetRemove(v []*LaunchPermission) *Launch } // Describes the launch specification for an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchSpecification type LaunchSpecification struct { _ struct{} `type:"structure"` @@ -44171,9 +49874,6 @@ type LaunchSpecification struct { AddressingType *string `locationName:"addressingType" type:"string"` // One or more block device mapping entries. - // - // Although you can specify encrypted EBS volumes in this block device mapping - // for your Spot Instances, these volumes are not encrypted. BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` // Indicates whether the instance is optimized for EBS I/O. This optimization @@ -44327,8 +50027,1727 @@ func (s *LaunchSpecification) SetUserData(v string) *LaunchSpecification { return s } +// Describes a launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplate +type LaunchTemplate struct { + _ struct{} `type:"structure"` + + // The time launch template was created. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` + + // The principal that created the launch template. + CreatedBy *string `locationName:"createdBy" type:"string"` + + // The version number of the default version of the launch template. + DefaultVersionNumber *int64 `locationName:"defaultVersionNumber" type:"long"` + + // The version number of the latest version of the launch template. + LatestVersionNumber *int64 `locationName:"latestVersionNumber" type:"long"` + + // The ID of the launch template. + LaunchTemplateId *string `locationName:"launchTemplateId" type:"string"` + + // The name of the launch template. + LaunchTemplateName *string `locationName:"launchTemplateName" min:"3" type:"string"` + + // The tags for the launch template. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s LaunchTemplate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplate) GoString() string { + return s.String() +} + +// SetCreateTime sets the CreateTime field's value. +func (s *LaunchTemplate) SetCreateTime(v time.Time) *LaunchTemplate { + s.CreateTime = &v + return s +} + +// SetCreatedBy sets the CreatedBy field's value. +func (s *LaunchTemplate) SetCreatedBy(v string) *LaunchTemplate { + s.CreatedBy = &v + return s +} + +// SetDefaultVersionNumber sets the DefaultVersionNumber field's value. +func (s *LaunchTemplate) SetDefaultVersionNumber(v int64) *LaunchTemplate { + s.DefaultVersionNumber = &v + return s +} + +// SetLatestVersionNumber sets the LatestVersionNumber field's value. +func (s *LaunchTemplate) SetLatestVersionNumber(v int64) *LaunchTemplate { + s.LatestVersionNumber = &v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *LaunchTemplate) SetLaunchTemplateId(v string) *LaunchTemplate { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *LaunchTemplate) SetLaunchTemplateName(v string) *LaunchTemplate { + s.LaunchTemplateName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *LaunchTemplate) SetTags(v []*Tag) *LaunchTemplate { + s.Tags = v + return s +} + +// Describes a block device mapping. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateBlockDeviceMapping +type LaunchTemplateBlockDeviceMapping struct { + _ struct{} `type:"structure"` + + // The device name. + DeviceName *string `locationName:"deviceName" type:"string"` + + // Information about the block device for an EBS volume. + Ebs *LaunchTemplateEbsBlockDevice `locationName:"ebs" type:"structure"` + + // Suppresses the specified device included in the block device mapping of the + // AMI. + NoDevice *string `locationName:"noDevice" type:"string"` + + // The virtual device name (ephemeralN). + VirtualName *string `locationName:"virtualName" type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateBlockDeviceMapping) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateBlockDeviceMapping) GoString() string { + return s.String() +} + +// SetDeviceName sets the DeviceName field's value. +func (s *LaunchTemplateBlockDeviceMapping) SetDeviceName(v string) *LaunchTemplateBlockDeviceMapping { + s.DeviceName = &v + return s +} + +// SetEbs sets the Ebs field's value. +func (s *LaunchTemplateBlockDeviceMapping) SetEbs(v *LaunchTemplateEbsBlockDevice) *LaunchTemplateBlockDeviceMapping { + s.Ebs = v + return s +} + +// SetNoDevice sets the NoDevice field's value. +func (s *LaunchTemplateBlockDeviceMapping) SetNoDevice(v string) *LaunchTemplateBlockDeviceMapping { + s.NoDevice = &v + return s +} + +// SetVirtualName sets the VirtualName field's value. +func (s *LaunchTemplateBlockDeviceMapping) SetVirtualName(v string) *LaunchTemplateBlockDeviceMapping { + s.VirtualName = &v + return s +} + +// Describes a block device mapping. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateBlockDeviceMappingRequest +type LaunchTemplateBlockDeviceMappingRequest struct { + _ struct{} `type:"structure"` + + // The device name (for example, /dev/sdh or xvdh). + DeviceName *string `type:"string"` + + // Parameters used to automatically set up EBS volumes when the instance is + // launched. + Ebs *LaunchTemplateEbsBlockDeviceRequest `type:"structure"` + + // Suppresses the specified device included in the block device mapping of the + // AMI. + NoDevice *string `type:"string"` + + // The virtual device name (ephemeralN). Instance store volumes are numbered + // starting from 0. An instance type with 2 available instance store volumes + // can specify mappings for ephemeral0 and ephemeral1. The number of available + // instance store volumes depends on the instance type. After you connect to + // the instance, you must mount the volume. + VirtualName *string `type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateBlockDeviceMappingRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateBlockDeviceMappingRequest) GoString() string { + return s.String() +} + +// SetDeviceName sets the DeviceName field's value. +func (s *LaunchTemplateBlockDeviceMappingRequest) SetDeviceName(v string) *LaunchTemplateBlockDeviceMappingRequest { + s.DeviceName = &v + return s +} + +// SetEbs sets the Ebs field's value. +func (s *LaunchTemplateBlockDeviceMappingRequest) SetEbs(v *LaunchTemplateEbsBlockDeviceRequest) *LaunchTemplateBlockDeviceMappingRequest { + s.Ebs = v + return s +} + +// SetNoDevice sets the NoDevice field's value. +func (s *LaunchTemplateBlockDeviceMappingRequest) SetNoDevice(v string) *LaunchTemplateBlockDeviceMappingRequest { + s.NoDevice = &v + return s +} + +// SetVirtualName sets the VirtualName field's value. +func (s *LaunchTemplateBlockDeviceMappingRequest) SetVirtualName(v string) *LaunchTemplateBlockDeviceMappingRequest { + s.VirtualName = &v + return s +} + +// Describes a launch template and overrides. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateConfig +type LaunchTemplateConfig struct { + _ struct{} `type:"structure"` + + // The launch template. + LaunchTemplateSpecification *FleetLaunchTemplateSpecification `locationName:"launchTemplateSpecification" type:"structure"` + + // Any parameters that you specify override the same parameters in the launch + // template. + Overrides []*LaunchTemplateOverrides `locationName:"overrides" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s LaunchTemplateConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateConfig) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *LaunchTemplateConfig) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "LaunchTemplateConfig"} + if s.LaunchTemplateSpecification != nil { + if err := s.LaunchTemplateSpecification.Validate(); err != nil { + invalidParams.AddNested("LaunchTemplateSpecification", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLaunchTemplateSpecification sets the LaunchTemplateSpecification field's value. +func (s *LaunchTemplateConfig) SetLaunchTemplateSpecification(v *FleetLaunchTemplateSpecification) *LaunchTemplateConfig { + s.LaunchTemplateSpecification = v + return s +} + +// SetOverrides sets the Overrides field's value. +func (s *LaunchTemplateConfig) SetOverrides(v []*LaunchTemplateOverrides) *LaunchTemplateConfig { + s.Overrides = v + return s +} + +// Describes a block device for an EBS volume. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateEbsBlockDevice +type LaunchTemplateEbsBlockDevice struct { + _ struct{} `type:"structure"` + + // Indicates whether the EBS volume is deleted on instance termination. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // Indicates whether the EBS volume is encrypted. + Encrypted *bool `locationName:"encrypted" type:"boolean"` + + // The number of I/O operations per second (IOPS) that the volume supports. + Iops *int64 `locationName:"iops" type:"integer"` + + // The ARN of the AWS Key Management Service (AWS KMS) CMK used for encryption. + KmsKeyId *string `locationName:"kmsKeyId" type:"string"` + + // The ID of the snapshot. + SnapshotId *string `locationName:"snapshotId" type:"string"` + + // The size of the volume, in GiB. + VolumeSize *int64 `locationName:"volumeSize" type:"integer"` + + // The volume type. + VolumeType *string `locationName:"volumeType" type:"string" enum:"VolumeType"` +} + +// String returns the string representation +func (s LaunchTemplateEbsBlockDevice) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateEbsBlockDevice) GoString() string { + return s.String() +} + +// SetDeleteOnTermination sets the DeleteOnTermination field's value. +func (s *LaunchTemplateEbsBlockDevice) SetDeleteOnTermination(v bool) *LaunchTemplateEbsBlockDevice { + s.DeleteOnTermination = &v + return s +} + +// SetEncrypted sets the Encrypted field's value. +func (s *LaunchTemplateEbsBlockDevice) SetEncrypted(v bool) *LaunchTemplateEbsBlockDevice { + s.Encrypted = &v + return s +} + +// SetIops sets the Iops field's value. +func (s *LaunchTemplateEbsBlockDevice) SetIops(v int64) *LaunchTemplateEbsBlockDevice { + s.Iops = &v + return s +} + +// SetKmsKeyId sets the KmsKeyId field's value. +func (s *LaunchTemplateEbsBlockDevice) SetKmsKeyId(v string) *LaunchTemplateEbsBlockDevice { + s.KmsKeyId = &v + return s +} + +// SetSnapshotId sets the SnapshotId field's value. +func (s *LaunchTemplateEbsBlockDevice) SetSnapshotId(v string) *LaunchTemplateEbsBlockDevice { + s.SnapshotId = &v + return s +} + +// SetVolumeSize sets the VolumeSize field's value. +func (s *LaunchTemplateEbsBlockDevice) SetVolumeSize(v int64) *LaunchTemplateEbsBlockDevice { + s.VolumeSize = &v + return s +} + +// SetVolumeType sets the VolumeType field's value. +func (s *LaunchTemplateEbsBlockDevice) SetVolumeType(v string) *LaunchTemplateEbsBlockDevice { + s.VolumeType = &v + return s +} + +// The parameters for a block device for an EBS volume. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateEbsBlockDeviceRequest +type LaunchTemplateEbsBlockDeviceRequest struct { + _ struct{} `type:"structure"` + + // Indicates whether the EBS volume is deleted on instance termination. + DeleteOnTermination *bool `type:"boolean"` + + // Indicates whether the EBS volume is encrypted. Encrypted volumes can only + // be attached to instances that support Amazon EBS encryption. If you are creating + // a volume from a snapshot, you can't specify an encryption value. + Encrypted *bool `type:"boolean"` + + // The number of I/O operations per second (IOPS) that the volume supports. + // For io1, this represents the number of IOPS that are provisioned for the + // volume. For gp2, this represents the baseline performance of the volume and + // the rate at which the volume accumulates I/O credits for bursting. For more + // information about General Purpose SSD baseline performance, I/O credits, + // and bursting, see Amazon EBS Volume Types in the Amazon Elastic Compute Cloud + // User Guide. + // + // Condition: This parameter is required for requests to create io1 volumes; + // it is not used in requests to create gp2, st1, sc1, or standard volumes. + Iops *int64 `type:"integer"` + + // The ARN of the AWS Key Management Service (AWS KMS) CMK used for encryption. + KmsKeyId *string `type:"string"` + + // The ID of the snapshot. + SnapshotId *string `type:"string"` + + // The size of the volume, in GiB. + // + // Default: If you're creating the volume from a snapshot and don't specify + // a volume size, the default is the snapshot size. + VolumeSize *int64 `type:"integer"` + + // The volume type. + VolumeType *string `type:"string" enum:"VolumeType"` +} + +// String returns the string representation +func (s LaunchTemplateEbsBlockDeviceRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateEbsBlockDeviceRequest) GoString() string { + return s.String() +} + +// SetDeleteOnTermination sets the DeleteOnTermination field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetDeleteOnTermination(v bool) *LaunchTemplateEbsBlockDeviceRequest { + s.DeleteOnTermination = &v + return s +} + +// SetEncrypted sets the Encrypted field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetEncrypted(v bool) *LaunchTemplateEbsBlockDeviceRequest { + s.Encrypted = &v + return s +} + +// SetIops sets the Iops field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetIops(v int64) *LaunchTemplateEbsBlockDeviceRequest { + s.Iops = &v + return s +} + +// SetKmsKeyId sets the KmsKeyId field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetKmsKeyId(v string) *LaunchTemplateEbsBlockDeviceRequest { + s.KmsKeyId = &v + return s +} + +// SetSnapshotId sets the SnapshotId field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetSnapshotId(v string) *LaunchTemplateEbsBlockDeviceRequest { + s.SnapshotId = &v + return s +} + +// SetVolumeSize sets the VolumeSize field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetVolumeSize(v int64) *LaunchTemplateEbsBlockDeviceRequest { + s.VolumeSize = &v + return s +} + +// SetVolumeType sets the VolumeType field's value. +func (s *LaunchTemplateEbsBlockDeviceRequest) SetVolumeType(v string) *LaunchTemplateEbsBlockDeviceRequest { + s.VolumeType = &v + return s +} + +// Describes an IAM instance profile. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateIamInstanceProfileSpecification +type LaunchTemplateIamInstanceProfileSpecification struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the instance profile. + Arn *string `locationName:"arn" type:"string"` + + // The name of the instance profile. + Name *string `locationName:"name" type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateIamInstanceProfileSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateIamInstanceProfileSpecification) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *LaunchTemplateIamInstanceProfileSpecification) SetArn(v string) *LaunchTemplateIamInstanceProfileSpecification { + s.Arn = &v + return s +} + +// SetName sets the Name field's value. +func (s *LaunchTemplateIamInstanceProfileSpecification) SetName(v string) *LaunchTemplateIamInstanceProfileSpecification { + s.Name = &v + return s +} + +// An IAM instance profile. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateIamInstanceProfileSpecificationRequest +type LaunchTemplateIamInstanceProfileSpecificationRequest struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the instance profile. + Arn *string `type:"string"` + + // The name of the instance profile. + Name *string `type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateIamInstanceProfileSpecificationRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateIamInstanceProfileSpecificationRequest) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *LaunchTemplateIamInstanceProfileSpecificationRequest) SetArn(v string) *LaunchTemplateIamInstanceProfileSpecificationRequest { + s.Arn = &v + return s +} + +// SetName sets the Name field's value. +func (s *LaunchTemplateIamInstanceProfileSpecificationRequest) SetName(v string) *LaunchTemplateIamInstanceProfileSpecificationRequest { + s.Name = &v + return s +} + +// The market (purchasing) option for the instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceMarketOptions +type LaunchTemplateInstanceMarketOptions struct { + _ struct{} `type:"structure"` + + // The market type. + MarketType *string `locationName:"marketType" type:"string" enum:"MarketType"` + + // The options for Spot Instances. + SpotOptions *LaunchTemplateSpotMarketOptions `locationName:"spotOptions" type:"structure"` +} + +// String returns the string representation +func (s LaunchTemplateInstanceMarketOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateInstanceMarketOptions) GoString() string { + return s.String() +} + +// SetMarketType sets the MarketType field's value. +func (s *LaunchTemplateInstanceMarketOptions) SetMarketType(v string) *LaunchTemplateInstanceMarketOptions { + s.MarketType = &v + return s +} + +// SetSpotOptions sets the SpotOptions field's value. +func (s *LaunchTemplateInstanceMarketOptions) SetSpotOptions(v *LaunchTemplateSpotMarketOptions) *LaunchTemplateInstanceMarketOptions { + s.SpotOptions = v + return s +} + +// The market (purchasing) option for the instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceMarketOptionsRequest +type LaunchTemplateInstanceMarketOptionsRequest struct { + _ struct{} `type:"structure"` + + // The market type. + MarketType *string `type:"string" enum:"MarketType"` + + // The options for Spot Instances. + SpotOptions *LaunchTemplateSpotMarketOptionsRequest `type:"structure"` +} + +// String returns the string representation +func (s LaunchTemplateInstanceMarketOptionsRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateInstanceMarketOptionsRequest) GoString() string { + return s.String() +} + +// SetMarketType sets the MarketType field's value. +func (s *LaunchTemplateInstanceMarketOptionsRequest) SetMarketType(v string) *LaunchTemplateInstanceMarketOptionsRequest { + s.MarketType = &v + return s +} + +// SetSpotOptions sets the SpotOptions field's value. +func (s *LaunchTemplateInstanceMarketOptionsRequest) SetSpotOptions(v *LaunchTemplateSpotMarketOptionsRequest) *LaunchTemplateInstanceMarketOptionsRequest { + s.SpotOptions = v + return s +} + +// Describes a network interface. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceNetworkInterfaceSpecification +type LaunchTemplateInstanceNetworkInterfaceSpecification struct { + _ struct{} `type:"structure"` + + // Indicates whether to associate a public IPv4 address with eth0 for a new + // network interface. + AssociatePublicIpAddress *bool `locationName:"associatePublicIpAddress" type:"boolean"` + + // Indicates whether the network interface is deleted when the instance is terminated. + DeleteOnTermination *bool `locationName:"deleteOnTermination" type:"boolean"` + + // A description for the network interface. + Description *string `locationName:"description" type:"string"` + + // The device index for the network interface attachment. + DeviceIndex *int64 `locationName:"deviceIndex" type:"integer"` + + // The IDs of one or more security groups. + Groups []*string `locationName:"groupSet" locationNameList:"groupId" type:"list"` + + // The number of IPv6 addresses for the network interface. + Ipv6AddressCount *int64 `locationName:"ipv6AddressCount" type:"integer"` + + // The IPv6 addresses for the network interface. + Ipv6Addresses []*InstanceIpv6Address `locationName:"ipv6AddressesSet" locationNameList:"item" type:"list"` + + // The ID of the network interface. + NetworkInterfaceId *string `locationName:"networkInterfaceId" type:"string"` + + // The primary private IPv4 address of the network interface. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // One or more private IPv4 addresses. + PrivateIpAddresses []*PrivateIpAddressSpecification `locationName:"privateIpAddressesSet" locationNameList:"item" type:"list"` + + // The number of secondary private IPv4 addresses for the network interface. + SecondaryPrivateIpAddressCount *int64 `locationName:"secondaryPrivateIpAddressCount" type:"integer"` + + // The ID of the subnet for the network interface. + SubnetId *string `locationName:"subnetId" type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateInstanceNetworkInterfaceSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateInstanceNetworkInterfaceSpecification) GoString() string { + return s.String() +} + +// SetAssociatePublicIpAddress sets the AssociatePublicIpAddress field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetAssociatePublicIpAddress(v bool) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.AssociatePublicIpAddress = &v + return s +} + +// SetDeleteOnTermination sets the DeleteOnTermination field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetDeleteOnTermination(v bool) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.DeleteOnTermination = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetDescription(v string) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.Description = &v + return s +} + +// SetDeviceIndex sets the DeviceIndex field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetDeviceIndex(v int64) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.DeviceIndex = &v + return s +} + +// SetGroups sets the Groups field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetGroups(v []*string) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.Groups = v + return s +} + +// SetIpv6AddressCount sets the Ipv6AddressCount field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetIpv6AddressCount(v int64) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.Ipv6AddressCount = &v + return s +} + +// SetIpv6Addresses sets the Ipv6Addresses field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetIpv6Addresses(v []*InstanceIpv6Address) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.Ipv6Addresses = v + return s +} + +// SetNetworkInterfaceId sets the NetworkInterfaceId field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetNetworkInterfaceId(v string) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.NetworkInterfaceId = &v + return s +} + +// SetPrivateIpAddress sets the PrivateIpAddress field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetPrivateIpAddress(v string) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.PrivateIpAddress = &v + return s +} + +// SetPrivateIpAddresses sets the PrivateIpAddresses field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetPrivateIpAddresses(v []*PrivateIpAddressSpecification) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.PrivateIpAddresses = v + return s +} + +// SetSecondaryPrivateIpAddressCount sets the SecondaryPrivateIpAddressCount field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetSecondaryPrivateIpAddressCount(v int64) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.SecondaryPrivateIpAddressCount = &v + return s +} + +// SetSubnetId sets the SubnetId field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetSubnetId(v string) *LaunchTemplateInstanceNetworkInterfaceSpecification { + s.SubnetId = &v + return s +} + +// The parameters for a network interface. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceNetworkInterfaceSpecificationRequest +type LaunchTemplateInstanceNetworkInterfaceSpecificationRequest struct { + _ struct{} `type:"structure"` + + // Associates a public IPv4 address with eth0 for a new network interface. + AssociatePublicIpAddress *bool `type:"boolean"` + + // Indicates whether the network interface is deleted when the instance is terminated. + DeleteOnTermination *bool `type:"boolean"` + + // A description for the network interface. + Description *string `type:"string"` + + // The device index for the network interface attachment. + DeviceIndex *int64 `type:"integer"` + + // The IDs of one or more security groups. + Groups []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // The number of IPv6 addresses to assign to a network interface. Amazon EC2 + // automatically selects the IPv6 addresses from the subnet range. You can't + // use this option if specifying specific IPv6 addresses. + Ipv6AddressCount *int64 `type:"integer"` + + // One or more specific IPv6 addresses from the IPv6 CIDR block range of your + // subnet. You can't use this option if you're specifying a number of IPv6 addresses. + Ipv6Addresses []*InstanceIpv6AddressRequest `locationNameList:"InstanceIpv6Address" type:"list"` + + // The ID of the network interface. + NetworkInterfaceId *string `type:"string"` + + // The primary private IPv4 address of the network interface. + PrivateIpAddress *string `type:"string"` + + // One or more private IPv4 addresses. + PrivateIpAddresses []*PrivateIpAddressSpecification `locationNameList:"item" type:"list"` + + // The number of secondary private IPv4 addresses to assign to a network interface. + SecondaryPrivateIpAddressCount *int64 `type:"integer"` + + // The ID of the subnet for the network interface. + SubnetId *string `type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "LaunchTemplateInstanceNetworkInterfaceSpecificationRequest"} + if s.PrivateIpAddresses != nil { + for i, v := range s.PrivateIpAddresses { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PrivateIpAddresses", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAssociatePublicIpAddress sets the AssociatePublicIpAddress field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetAssociatePublicIpAddress(v bool) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.AssociatePublicIpAddress = &v + return s +} + +// SetDeleteOnTermination sets the DeleteOnTermination field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetDeleteOnTermination(v bool) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.DeleteOnTermination = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetDescription(v string) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.Description = &v + return s +} + +// SetDeviceIndex sets the DeviceIndex field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetDeviceIndex(v int64) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.DeviceIndex = &v + return s +} + +// SetGroups sets the Groups field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetGroups(v []*string) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.Groups = v + return s +} + +// SetIpv6AddressCount sets the Ipv6AddressCount field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetIpv6AddressCount(v int64) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.Ipv6AddressCount = &v + return s +} + +// SetIpv6Addresses sets the Ipv6Addresses field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetIpv6Addresses(v []*InstanceIpv6AddressRequest) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.Ipv6Addresses = v + return s +} + +// SetNetworkInterfaceId sets the NetworkInterfaceId field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetNetworkInterfaceId(v string) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.NetworkInterfaceId = &v + return s +} + +// SetPrivateIpAddress sets the PrivateIpAddress field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetPrivateIpAddress(v string) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.PrivateIpAddress = &v + return s +} + +// SetPrivateIpAddresses sets the PrivateIpAddresses field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetPrivateIpAddresses(v []*PrivateIpAddressSpecification) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.PrivateIpAddresses = v + return s +} + +// SetSecondaryPrivateIpAddressCount sets the SecondaryPrivateIpAddressCount field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetSecondaryPrivateIpAddressCount(v int64) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.SecondaryPrivateIpAddressCount = &v + return s +} + +// SetSubnetId sets the SubnetId field's value. +func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetSubnetId(v string) *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest { + s.SubnetId = &v + return s +} + +// Describes overrides for a launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateOverrides +type LaunchTemplateOverrides struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which to launch the instances. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The maximum price per unit hour that you are willing to pay for a Spot Instance. + SpotPrice *string `locationName:"spotPrice" type:"string"` + + // The ID of the subnet in which to launch the instances. + SubnetId *string `locationName:"subnetId" type:"string"` + + // The number of units provided by the specified instance type. + WeightedCapacity *float64 `locationName:"weightedCapacity" type:"double"` +} + +// String returns the string representation +func (s LaunchTemplateOverrides) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateOverrides) GoString() string { + return s.String() +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *LaunchTemplateOverrides) SetAvailabilityZone(v string) *LaunchTemplateOverrides { + s.AvailabilityZone = &v + return s +} + +// SetInstanceType sets the InstanceType field's value. +func (s *LaunchTemplateOverrides) SetInstanceType(v string) *LaunchTemplateOverrides { + s.InstanceType = &v + return s +} + +// SetSpotPrice sets the SpotPrice field's value. +func (s *LaunchTemplateOverrides) SetSpotPrice(v string) *LaunchTemplateOverrides { + s.SpotPrice = &v + return s +} + +// SetSubnetId sets the SubnetId field's value. +func (s *LaunchTemplateOverrides) SetSubnetId(v string) *LaunchTemplateOverrides { + s.SubnetId = &v + return s +} + +// SetWeightedCapacity sets the WeightedCapacity field's value. +func (s *LaunchTemplateOverrides) SetWeightedCapacity(v float64) *LaunchTemplateOverrides { + s.WeightedCapacity = &v + return s +} + +// Describes the placement of an instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatePlacement +type LaunchTemplatePlacement struct { + _ struct{} `type:"structure"` + + // The affinity setting for the instance on the Dedicated Host. + Affinity *string `locationName:"affinity" type:"string"` + + // The Availability Zone of the instance. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The name of the placement group for the instance. + GroupName *string `locationName:"groupName" type:"string"` + + // The ID of the Dedicated Host for the instance. + HostId *string `locationName:"hostId" type:"string"` + + // Reserved for future use. + SpreadDomain *string `locationName:"spreadDomain" type:"string"` + + // The tenancy of the instance (if the instance is running in a VPC). An instance + // with a tenancy of dedicated runs on single-tenant hardware. + Tenancy *string `locationName:"tenancy" type:"string" enum:"Tenancy"` +} + +// String returns the string representation +func (s LaunchTemplatePlacement) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplatePlacement) GoString() string { + return s.String() +} + +// SetAffinity sets the Affinity field's value. +func (s *LaunchTemplatePlacement) SetAffinity(v string) *LaunchTemplatePlacement { + s.Affinity = &v + return s +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *LaunchTemplatePlacement) SetAvailabilityZone(v string) *LaunchTemplatePlacement { + s.AvailabilityZone = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *LaunchTemplatePlacement) SetGroupName(v string) *LaunchTemplatePlacement { + s.GroupName = &v + return s +} + +// SetHostId sets the HostId field's value. +func (s *LaunchTemplatePlacement) SetHostId(v string) *LaunchTemplatePlacement { + s.HostId = &v + return s +} + +// SetSpreadDomain sets the SpreadDomain field's value. +func (s *LaunchTemplatePlacement) SetSpreadDomain(v string) *LaunchTemplatePlacement { + s.SpreadDomain = &v + return s +} + +// SetTenancy sets the Tenancy field's value. +func (s *LaunchTemplatePlacement) SetTenancy(v string) *LaunchTemplatePlacement { + s.Tenancy = &v + return s +} + +// The placement for the instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatePlacementRequest +type LaunchTemplatePlacementRequest struct { + _ struct{} `type:"structure"` + + // The affinity setting for an instance on a Dedicated Host. + Affinity *string `type:"string"` + + // The Availability Zone for the instance. + AvailabilityZone *string `type:"string"` + + // The name of the placement group for the instance. + GroupName *string `type:"string"` + + // The ID of the Dedicated Host for the instance. + HostId *string `type:"string"` + + // Reserved for future use. + SpreadDomain *string `type:"string"` + + // The tenancy of the instance (if the instance is running in a VPC). An instance + // with a tenancy of dedicated runs on single-tenant hardware. + Tenancy *string `type:"string" enum:"Tenancy"` +} + +// String returns the string representation +func (s LaunchTemplatePlacementRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplatePlacementRequest) GoString() string { + return s.String() +} + +// SetAffinity sets the Affinity field's value. +func (s *LaunchTemplatePlacementRequest) SetAffinity(v string) *LaunchTemplatePlacementRequest { + s.Affinity = &v + return s +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *LaunchTemplatePlacementRequest) SetAvailabilityZone(v string) *LaunchTemplatePlacementRequest { + s.AvailabilityZone = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *LaunchTemplatePlacementRequest) SetGroupName(v string) *LaunchTemplatePlacementRequest { + s.GroupName = &v + return s +} + +// SetHostId sets the HostId field's value. +func (s *LaunchTemplatePlacementRequest) SetHostId(v string) *LaunchTemplatePlacementRequest { + s.HostId = &v + return s +} + +// SetSpreadDomain sets the SpreadDomain field's value. +func (s *LaunchTemplatePlacementRequest) SetSpreadDomain(v string) *LaunchTemplatePlacementRequest { + s.SpreadDomain = &v + return s +} + +// SetTenancy sets the Tenancy field's value. +func (s *LaunchTemplatePlacementRequest) SetTenancy(v string) *LaunchTemplatePlacementRequest { + s.Tenancy = &v + return s +} + +// The launch template to use. You must specify either the launch template ID +// or launch template name in the request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateSpecification +type LaunchTemplateSpecification struct { + _ struct{} `type:"structure"` + + // The ID of the launch template. + LaunchTemplateId *string `type:"string"` + + // The name of the launch template. + LaunchTemplateName *string `type:"string"` + + // The version number of the launch template. + // + // Default: The default version for the launch template. + Version *string `type:"string"` +} + +// String returns the string representation +func (s LaunchTemplateSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateSpecification) GoString() string { + return s.String() +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *LaunchTemplateSpecification) SetLaunchTemplateId(v string) *LaunchTemplateSpecification { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *LaunchTemplateSpecification) SetLaunchTemplateName(v string) *LaunchTemplateSpecification { + s.LaunchTemplateName = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *LaunchTemplateSpecification) SetVersion(v string) *LaunchTemplateSpecification { + s.Version = &v + return s +} + +// The options for Spot Instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateSpotMarketOptions +type LaunchTemplateSpotMarketOptions struct { + _ struct{} `type:"structure"` + + // The required duration for the Spot Instances (also known as Spot blocks), + // in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, + // or 360). + BlockDurationMinutes *int64 `locationName:"blockDurationMinutes" type:"integer"` + + // The behavior when a Spot Instance is interrupted. + InstanceInterruptionBehavior *string `locationName:"instanceInterruptionBehavior" type:"string" enum:"InstanceInterruptionBehavior"` + + // The maximum hourly price you're willing to pay for the Spot Instances. + MaxPrice *string `locationName:"maxPrice" type:"string"` + + // The Spot Instance request type. + SpotInstanceType *string `locationName:"spotInstanceType" type:"string" enum:"SpotInstanceType"` + + // The end date of the request. For a one-time request, the request remains + // active until all instances launch, the request is canceled, or this date + // is reached. If the request is persistent, it remains active until it is canceled + // or this date and time is reached. + ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s LaunchTemplateSpotMarketOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateSpotMarketOptions) GoString() string { + return s.String() +} + +// SetBlockDurationMinutes sets the BlockDurationMinutes field's value. +func (s *LaunchTemplateSpotMarketOptions) SetBlockDurationMinutes(v int64) *LaunchTemplateSpotMarketOptions { + s.BlockDurationMinutes = &v + return s +} + +// SetInstanceInterruptionBehavior sets the InstanceInterruptionBehavior field's value. +func (s *LaunchTemplateSpotMarketOptions) SetInstanceInterruptionBehavior(v string) *LaunchTemplateSpotMarketOptions { + s.InstanceInterruptionBehavior = &v + return s +} + +// SetMaxPrice sets the MaxPrice field's value. +func (s *LaunchTemplateSpotMarketOptions) SetMaxPrice(v string) *LaunchTemplateSpotMarketOptions { + s.MaxPrice = &v + return s +} + +// SetSpotInstanceType sets the SpotInstanceType field's value. +func (s *LaunchTemplateSpotMarketOptions) SetSpotInstanceType(v string) *LaunchTemplateSpotMarketOptions { + s.SpotInstanceType = &v + return s +} + +// SetValidUntil sets the ValidUntil field's value. +func (s *LaunchTemplateSpotMarketOptions) SetValidUntil(v time.Time) *LaunchTemplateSpotMarketOptions { + s.ValidUntil = &v + return s +} + +// The options for Spot Instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateSpotMarketOptionsRequest +type LaunchTemplateSpotMarketOptionsRequest struct { + _ struct{} `type:"structure"` + + // The required duration for the Spot Instances (also known as Spot blocks), + // in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, + // or 360). + BlockDurationMinutes *int64 `type:"integer"` + + // The behavior when a Spot Instance is interrupted. The default is terminate. + InstanceInterruptionBehavior *string `type:"string" enum:"InstanceInterruptionBehavior"` + + // The maximum hourly price you're willing to pay for the Spot Instances. + MaxPrice *string `type:"string"` + + // The Spot Instance request type. + SpotInstanceType *string `type:"string" enum:"SpotInstanceType"` + + // The end date of the request. For a one-time request, the request remains + // active until all instances launch, the request is canceled, or this date + // is reached. If the request is persistent, it remains active until it is canceled + // or this date and time is reached. The default end date is 7 days from the + // current date. + ValidUntil *time.Time `type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s LaunchTemplateSpotMarketOptionsRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateSpotMarketOptionsRequest) GoString() string { + return s.String() +} + +// SetBlockDurationMinutes sets the BlockDurationMinutes field's value. +func (s *LaunchTemplateSpotMarketOptionsRequest) SetBlockDurationMinutes(v int64) *LaunchTemplateSpotMarketOptionsRequest { + s.BlockDurationMinutes = &v + return s +} + +// SetInstanceInterruptionBehavior sets the InstanceInterruptionBehavior field's value. +func (s *LaunchTemplateSpotMarketOptionsRequest) SetInstanceInterruptionBehavior(v string) *LaunchTemplateSpotMarketOptionsRequest { + s.InstanceInterruptionBehavior = &v + return s +} + +// SetMaxPrice sets the MaxPrice field's value. +func (s *LaunchTemplateSpotMarketOptionsRequest) SetMaxPrice(v string) *LaunchTemplateSpotMarketOptionsRequest { + s.MaxPrice = &v + return s +} + +// SetSpotInstanceType sets the SpotInstanceType field's value. +func (s *LaunchTemplateSpotMarketOptionsRequest) SetSpotInstanceType(v string) *LaunchTemplateSpotMarketOptionsRequest { + s.SpotInstanceType = &v + return s +} + +// SetValidUntil sets the ValidUntil field's value. +func (s *LaunchTemplateSpotMarketOptionsRequest) SetValidUntil(v time.Time) *LaunchTemplateSpotMarketOptionsRequest { + s.ValidUntil = &v + return s +} + +// The tag specification for the launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateTagSpecification +type LaunchTemplateTagSpecification struct { + _ struct{} `type:"structure"` + + // The type of resource. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The tags for the resource. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s LaunchTemplateTagSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateTagSpecification) GoString() string { + return s.String() +} + +// SetResourceType sets the ResourceType field's value. +func (s *LaunchTemplateTagSpecification) SetResourceType(v string) *LaunchTemplateTagSpecification { + s.ResourceType = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *LaunchTemplateTagSpecification) SetTags(v []*Tag) *LaunchTemplateTagSpecification { + s.Tags = v + return s +} + +// The tags specification for the launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateTagSpecificationRequest +type LaunchTemplateTagSpecificationRequest struct { + _ struct{} `type:"structure"` + + // The type of resource to tag. Currently, the resource types that support tagging + // on creation are instance and volume. + ResourceType *string `type:"string" enum:"ResourceType"` + + // The tags to apply to the resource. + Tags []*Tag `locationName:"Tag" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s LaunchTemplateTagSpecificationRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateTagSpecificationRequest) GoString() string { + return s.String() +} + +// SetResourceType sets the ResourceType field's value. +func (s *LaunchTemplateTagSpecificationRequest) SetResourceType(v string) *LaunchTemplateTagSpecificationRequest { + s.ResourceType = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *LaunchTemplateTagSpecificationRequest) SetTags(v []*Tag) *LaunchTemplateTagSpecificationRequest { + s.Tags = v + return s +} + +// Describes a launch template version. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateVersion +type LaunchTemplateVersion struct { + _ struct{} `type:"structure"` + + // The time the version was created. + CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` + + // The principal that created the version. + CreatedBy *string `locationName:"createdBy" type:"string"` + + // Indicates whether the version is the default version. + DefaultVersion *bool `locationName:"defaultVersion" type:"boolean"` + + // Information about the launch template. + LaunchTemplateData *ResponseLaunchTemplateData `locationName:"launchTemplateData" type:"structure"` + + // The ID of the launch template. + LaunchTemplateId *string `locationName:"launchTemplateId" type:"string"` + + // The name of the launch template. + LaunchTemplateName *string `locationName:"launchTemplateName" min:"3" type:"string"` + + // The description for the version. + VersionDescription *string `locationName:"versionDescription" type:"string"` + + // The version number. + VersionNumber *int64 `locationName:"versionNumber" type:"long"` +} + +// String returns the string representation +func (s LaunchTemplateVersion) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplateVersion) GoString() string { + return s.String() +} + +// SetCreateTime sets the CreateTime field's value. +func (s *LaunchTemplateVersion) SetCreateTime(v time.Time) *LaunchTemplateVersion { + s.CreateTime = &v + return s +} + +// SetCreatedBy sets the CreatedBy field's value. +func (s *LaunchTemplateVersion) SetCreatedBy(v string) *LaunchTemplateVersion { + s.CreatedBy = &v + return s +} + +// SetDefaultVersion sets the DefaultVersion field's value. +func (s *LaunchTemplateVersion) SetDefaultVersion(v bool) *LaunchTemplateVersion { + s.DefaultVersion = &v + return s +} + +// SetLaunchTemplateData sets the LaunchTemplateData field's value. +func (s *LaunchTemplateVersion) SetLaunchTemplateData(v *ResponseLaunchTemplateData) *LaunchTemplateVersion { + s.LaunchTemplateData = v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *LaunchTemplateVersion) SetLaunchTemplateId(v string) *LaunchTemplateVersion { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *LaunchTemplateVersion) SetLaunchTemplateName(v string) *LaunchTemplateVersion { + s.LaunchTemplateName = &v + return s +} + +// SetVersionDescription sets the VersionDescription field's value. +func (s *LaunchTemplateVersion) SetVersionDescription(v string) *LaunchTemplateVersion { + s.VersionDescription = &v + return s +} + +// SetVersionNumber sets the VersionNumber field's value. +func (s *LaunchTemplateVersion) SetVersionNumber(v int64) *LaunchTemplateVersion { + s.VersionNumber = &v + return s +} + +// Describes the monitoring for the instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatesMonitoring +type LaunchTemplatesMonitoring struct { + _ struct{} `type:"structure"` + + // Indicates whether detailed monitoring is enabled. Otherwise, basic monitoring + // is enabled. + Enabled *bool `locationName:"enabled" type:"boolean"` +} + +// String returns the string representation +func (s LaunchTemplatesMonitoring) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplatesMonitoring) GoString() string { + return s.String() +} + +// SetEnabled sets the Enabled field's value. +func (s *LaunchTemplatesMonitoring) SetEnabled(v bool) *LaunchTemplatesMonitoring { + s.Enabled = &v + return s +} + +// Describes the monitoring for the instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatesMonitoringRequest +type LaunchTemplatesMonitoringRequest struct { + _ struct{} `type:"structure"` + + // Specify true to enable detailed monitoring. Otherwise, basic monitoring is + // enabled. + Enabled *bool `type:"boolean"` +} + +// String returns the string representation +func (s LaunchTemplatesMonitoringRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LaunchTemplatesMonitoringRequest) GoString() string { + return s.String() +} + +// SetEnabled sets the Enabled field's value. +func (s *LaunchTemplatesMonitoringRequest) SetEnabled(v bool) *LaunchTemplatesMonitoringRequest { + s.Enabled = &v + return s +} + +// Describes the Classic Load Balancers and target groups to attach to a Spot +// Fleet request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadBalancersConfig +type LoadBalancersConfig struct { + _ struct{} `type:"structure"` + + // The Classic Load Balancers. + ClassicLoadBalancersConfig *ClassicLoadBalancersConfig `locationName:"classicLoadBalancersConfig" type:"structure"` + + // The target groups. + TargetGroupsConfig *TargetGroupsConfig `locationName:"targetGroupsConfig" type:"structure"` +} + +// String returns the string representation +func (s LoadBalancersConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancersConfig) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *LoadBalancersConfig) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "LoadBalancersConfig"} + if s.ClassicLoadBalancersConfig != nil { + if err := s.ClassicLoadBalancersConfig.Validate(); err != nil { + invalidParams.AddNested("ClassicLoadBalancersConfig", err.(request.ErrInvalidParams)) + } + } + if s.TargetGroupsConfig != nil { + if err := s.TargetGroupsConfig.Validate(); err != nil { + invalidParams.AddNested("TargetGroupsConfig", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClassicLoadBalancersConfig sets the ClassicLoadBalancersConfig field's value. +func (s *LoadBalancersConfig) SetClassicLoadBalancersConfig(v *ClassicLoadBalancersConfig) *LoadBalancersConfig { + s.ClassicLoadBalancersConfig = v + return s +} + +// SetTargetGroupsConfig sets the TargetGroupsConfig field's value. +func (s *LoadBalancersConfig) SetTargetGroupsConfig(v *TargetGroupsConfig) *LoadBalancersConfig { + s.TargetGroupsConfig = v + return s +} + +// Describes a load permission. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadPermission +type LoadPermission struct { + _ struct{} `type:"structure"` + + // The name of the group. + Group *string `locationName:"group" type:"string" enum:"PermissionGroup"` + + // The AWS account ID. + UserId *string `locationName:"userId" type:"string"` +} + +// String returns the string representation +func (s LoadPermission) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadPermission) GoString() string { + return s.String() +} + +// SetGroup sets the Group field's value. +func (s *LoadPermission) SetGroup(v string) *LoadPermission { + s.Group = &v + return s +} + +// SetUserId sets the UserId field's value. +func (s *LoadPermission) SetUserId(v string) *LoadPermission { + s.UserId = &v + return s +} + +// Describes modifications to the load permissions of an Amazon FPGA image (AFI). +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadPermissionModifications +type LoadPermissionModifications struct { + _ struct{} `type:"structure"` + + // The load permissions to add. + Add []*LoadPermissionRequest `locationNameList:"item" type:"list"` + + // The load permissions to remove. + Remove []*LoadPermissionRequest `locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s LoadPermissionModifications) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadPermissionModifications) GoString() string { + return s.String() +} + +// SetAdd sets the Add field's value. +func (s *LoadPermissionModifications) SetAdd(v []*LoadPermissionRequest) *LoadPermissionModifications { + s.Add = v + return s +} + +// SetRemove sets the Remove field's value. +func (s *LoadPermissionModifications) SetRemove(v []*LoadPermissionRequest) *LoadPermissionModifications { + s.Remove = v + return s +} + +// Describes a load permission. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadPermissionRequest +type LoadPermissionRequest struct { + _ struct{} `type:"structure"` + + // The name of the group. + Group *string `type:"string" enum:"PermissionGroup"` + + // The AWS account ID. + UserId *string `type:"string"` +} + +// String returns the string representation +func (s LoadPermissionRequest) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadPermissionRequest) GoString() string { + return s.String() +} + +// SetGroup sets the Group field's value. +func (s *LoadPermissionRequest) SetGroup(v string) *LoadPermissionRequest { + s.Group = &v + return s +} + +// SetUserId sets the UserId field's value. +func (s *LoadPermissionRequest) SetUserId(v string) *LoadPermissionRequest { + s.UserId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyFpgaImageAttributeRequest +type ModifyFpgaImageAttributeInput struct { + _ struct{} `type:"structure"` + + // The name of the attribute. + Attribute *string `type:"string" enum:"FpgaImageAttributeName"` + + // A description for the AFI. + Description *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the AFI. + // + // FpgaImageId is a required field + FpgaImageId *string `type:"string" required:"true"` + + // The load permission for the AFI. + LoadPermission *LoadPermissionModifications `type:"structure"` + + // A name for the AFI. + Name *string `type:"string"` + + // The operation type. + OperationType *string `type:"string" enum:"OperationType"` + + // One or more product codes. After you add a product code to an AFI, it can't + // be removed. This parameter is valid only when modifying the productCodes + // attribute. + ProductCodes []*string `locationName:"ProductCode" locationNameList:"ProductCode" type:"list"` + + // One or more user groups. This parameter is valid only when modifying the + // loadPermission attribute. + UserGroups []*string `locationName:"UserGroup" locationNameList:"UserGroup" type:"list"` + + // One or more AWS account IDs. This parameter is valid only when modifying + // the loadPermission attribute. + UserIds []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` +} + +// String returns the string representation +func (s ModifyFpgaImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyFpgaImageAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyFpgaImageAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyFpgaImageAttributeInput"} + if s.FpgaImageId == nil { + invalidParams.Add(request.NewErrParamRequired("FpgaImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttribute sets the Attribute field's value. +func (s *ModifyFpgaImageAttributeInput) SetAttribute(v string) *ModifyFpgaImageAttributeInput { + s.Attribute = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *ModifyFpgaImageAttributeInput) SetDescription(v string) *ModifyFpgaImageAttributeInput { + s.Description = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyFpgaImageAttributeInput) SetDryRun(v bool) *ModifyFpgaImageAttributeInput { + s.DryRun = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *ModifyFpgaImageAttributeInput) SetFpgaImageId(v string) *ModifyFpgaImageAttributeInput { + s.FpgaImageId = &v + return s +} + +// SetLoadPermission sets the LoadPermission field's value. +func (s *ModifyFpgaImageAttributeInput) SetLoadPermission(v *LoadPermissionModifications) *ModifyFpgaImageAttributeInput { + s.LoadPermission = v + return s +} + +// SetName sets the Name field's value. +func (s *ModifyFpgaImageAttributeInput) SetName(v string) *ModifyFpgaImageAttributeInput { + s.Name = &v + return s +} + +// SetOperationType sets the OperationType field's value. +func (s *ModifyFpgaImageAttributeInput) SetOperationType(v string) *ModifyFpgaImageAttributeInput { + s.OperationType = &v + return s +} + +// SetProductCodes sets the ProductCodes field's value. +func (s *ModifyFpgaImageAttributeInput) SetProductCodes(v []*string) *ModifyFpgaImageAttributeInput { + s.ProductCodes = v + return s +} + +// SetUserGroups sets the UserGroups field's value. +func (s *ModifyFpgaImageAttributeInput) SetUserGroups(v []*string) *ModifyFpgaImageAttributeInput { + s.UserGroups = v + return s +} + +// SetUserIds sets the UserIds field's value. +func (s *ModifyFpgaImageAttributeInput) SetUserIds(v []*string) *ModifyFpgaImageAttributeInput { + s.UserIds = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyFpgaImageAttributeResult +type ModifyFpgaImageAttributeOutput struct { + _ struct{} `type:"structure"` + + // Information about the attribute. + FpgaImageAttribute *FpgaImageAttribute `locationName:"fpgaImageAttribute" type:"structure"` +} + +// String returns the string representation +func (s ModifyFpgaImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyFpgaImageAttributeOutput) GoString() string { + return s.String() +} + +// SetFpgaImageAttribute sets the FpgaImageAttribute field's value. +func (s *ModifyFpgaImageAttributeOutput) SetFpgaImageAttribute(v *FpgaImageAttribute) *ModifyFpgaImageAttributeOutput { + s.FpgaImageAttribute = v + return s +} + // Contains the parameters for ModifyHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHostsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHostsRequest type ModifyHostsInput struct { _ struct{} `type:"structure"` @@ -44382,7 +51801,7 @@ func (s *ModifyHostsInput) SetHostIds(v []*string) *ModifyHostsInput { } // Contains the output of ModifyHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHostsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHostsResult type ModifyHostsOutput struct { _ struct{} `type:"structure"` @@ -44417,7 +51836,7 @@ func (s *ModifyHostsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *ModifyHostsO } // Contains the parameters of ModifyIdFormat. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormatRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormatRequest type ModifyIdFormatInput struct { _ struct{} `type:"structure"` @@ -44470,7 +51889,7 @@ func (s *ModifyIdFormatInput) SetUseLongIds(v bool) *ModifyIdFormatInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormatOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormatOutput type ModifyIdFormatOutput struct { _ struct{} `type:"structure"` } @@ -44486,7 +51905,7 @@ func (s ModifyIdFormatOutput) GoString() string { } // Contains the parameters of ModifyIdentityIdFormat. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormatRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormatRequest type ModifyIdentityIdFormatInput struct { _ struct{} `type:"structure"` @@ -44555,7 +51974,7 @@ func (s *ModifyIdentityIdFormatInput) SetUseLongIds(v bool) *ModifyIdentityIdFor return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormatOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormatOutput type ModifyIdentityIdFormatOutput struct { _ struct{} `type:"structure"` } @@ -44571,14 +51990,15 @@ func (s ModifyIdentityIdFormatOutput) GoString() string { } // Contains the parameters for ModifyImageAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttributeRequest type ModifyImageAttributeInput struct { _ struct{} `type:"structure"` - // The name of the attribute to modify. + // The name of the attribute to modify. The valid values are description, launchPermission, + // and productCodes. Attribute *string `type:"string"` - // A description for the AMI. + // A new description for the AMI. Description *AttributeValue `type:"structure"` // Checks whether you have the required permissions for the action, without @@ -44592,26 +52012,27 @@ type ModifyImageAttributeInput struct { // ImageId is a required field ImageId *string `type:"string" required:"true"` - // A launch permission modification. + // A new launch permission for the AMI. LaunchPermission *LaunchPermissionModifications `type:"structure"` - // The operation type. + // The operation type. This parameter can be used only when the Attribute parameter + // is launchPermission. OperationType *string `type:"string" enum:"OperationType"` - // One or more product codes. After you add a product code to an AMI, it can't - // be removed. This is only valid when modifying the productCodes attribute. + // One or more DevPay product codes. After you add a product code to an AMI, + // it can't be removed. ProductCodes []*string `locationName:"ProductCode" locationNameList:"ProductCode" type:"list"` - // One or more user groups. This is only valid when modifying the launchPermission - // attribute. + // One or more user groups. This parameter can be used only when the Attribute + // parameter is launchPermission. UserGroups []*string `locationName:"UserGroup" locationNameList:"UserGroup" type:"list"` - // One or more AWS account IDs. This is only valid when modifying the launchPermission - // attribute. + // One or more AWS account IDs. This parameter can be used only when the Attribute + // parameter is launchPermission. UserIds []*string `locationName:"UserId" locationNameList:"UserId" type:"list"` - // The value of the attribute being modified. This is only valid when modifying - // the description attribute. + // The value of the attribute being modified. This parameter can be used only + // when the Attribute parameter is description or productCodes. Value *string `type:"string"` } @@ -44698,7 +52119,7 @@ func (s *ModifyImageAttributeInput) SetValue(v string) *ModifyImageAttributeInpu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttributeOutput type ModifyImageAttributeOutput struct { _ struct{} `type:"structure"` } @@ -44714,7 +52135,7 @@ func (s ModifyImageAttributeOutput) GoString() string { } // Contains the parameters for ModifyInstanceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttributeRequest type ModifyInstanceAttributeInput struct { _ struct{} `type:"structure"` @@ -44743,7 +52164,7 @@ type ModifyInstanceAttributeInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // Specifies whether the instance is optimized for EBS I/O. This optimization + // Specifies whether the instance is optimized for Amazon EBS I/O. This optimization // provides dedicated throughput to Amazon EBS and an optimized configuration // stack to provide optimal EBS I/O performance. This optimization isn't available // with all instance types. Additional usage charges apply when using an EBS @@ -44786,8 +52207,8 @@ type ModifyInstanceAttributeInput struct { Ramdisk *AttributeValue `locationName:"ramdisk" type:"structure"` // Specifies whether source/destination checking is enabled. A value of true - // means that checking is enabled, and false means checking is disabled. This - // value must be false for a NAT instance to perform NAT. + // means that checking is enabled, and false means that checking is disabled. + // This value must be false for a NAT instance to perform NAT. SourceDestCheck *AttributeBooleanValue `type:"structure"` // Set to simple to enable enhanced networking with the Intel 82599 Virtual @@ -44801,8 +52222,8 @@ type ModifyInstanceAttributeInput struct { SriovNetSupport *AttributeValue `locationName:"sriovNetSupport" type:"structure"` // Changes the instance's user data to the specified value. If you are using - // an AWS SDK or command line tool, Base64-encoding is performed for you, and - // you can load the text from a file. Otherwise, you must provide Base64-encoded + // an AWS SDK or command line tool, base64-encoding is performed for you, and + // you can load the text from a file. Otherwise, you must provide base64-encoded // text. UserData *BlobAttributeValue `locationName:"userData" type:"structure"` @@ -44930,7 +52351,7 @@ func (s *ModifyInstanceAttributeInput) SetValue(v string) *ModifyInstanceAttribu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttributeOutput type ModifyInstanceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -44945,8 +52366,105 @@ func (s ModifyInstanceAttributeOutput) GoString() string { return s.String() } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceCreditSpecificationRequest +type ModifyInstanceCreditSpecificationInput struct { + _ struct{} `type:"structure"` + + // A unique, case-sensitive token that you provide to ensure idempotency of + // your modification request. For more information, see Ensuring Idempotency + // (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // Information about the credit option for CPU usage. + // + // InstanceCreditSpecifications is a required field + InstanceCreditSpecifications []*InstanceCreditSpecificationRequest `locationName:"InstanceCreditSpecification" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s ModifyInstanceCreditSpecificationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstanceCreditSpecificationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyInstanceCreditSpecificationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyInstanceCreditSpecificationInput"} + if s.InstanceCreditSpecifications == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceCreditSpecifications")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *ModifyInstanceCreditSpecificationInput) SetClientToken(v string) *ModifyInstanceCreditSpecificationInput { + s.ClientToken = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyInstanceCreditSpecificationInput) SetDryRun(v bool) *ModifyInstanceCreditSpecificationInput { + s.DryRun = &v + return s +} + +// SetInstanceCreditSpecifications sets the InstanceCreditSpecifications field's value. +func (s *ModifyInstanceCreditSpecificationInput) SetInstanceCreditSpecifications(v []*InstanceCreditSpecificationRequest) *ModifyInstanceCreditSpecificationInput { + s.InstanceCreditSpecifications = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceCreditSpecificationResult +type ModifyInstanceCreditSpecificationOutput struct { + _ struct{} `type:"structure"` + + // Information about the instances whose credit option for CPU usage was successfully + // modified. + SuccessfulInstanceCreditSpecifications []*SuccessfulInstanceCreditSpecificationItem `locationName:"successfulInstanceCreditSpecificationSet" locationNameList:"item" type:"list"` + + // Information about the instances whose credit option for CPU usage was not + // modified. + UnsuccessfulInstanceCreditSpecifications []*UnsuccessfulInstanceCreditSpecificationItem `locationName:"unsuccessfulInstanceCreditSpecificationSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s ModifyInstanceCreditSpecificationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyInstanceCreditSpecificationOutput) GoString() string { + return s.String() +} + +// SetSuccessfulInstanceCreditSpecifications sets the SuccessfulInstanceCreditSpecifications field's value. +func (s *ModifyInstanceCreditSpecificationOutput) SetSuccessfulInstanceCreditSpecifications(v []*SuccessfulInstanceCreditSpecificationItem) *ModifyInstanceCreditSpecificationOutput { + s.SuccessfulInstanceCreditSpecifications = v + return s +} + +// SetUnsuccessfulInstanceCreditSpecifications sets the UnsuccessfulInstanceCreditSpecifications field's value. +func (s *ModifyInstanceCreditSpecificationOutput) SetUnsuccessfulInstanceCreditSpecifications(v []*UnsuccessfulInstanceCreditSpecificationItem) *ModifyInstanceCreditSpecificationOutput { + s.UnsuccessfulInstanceCreditSpecifications = v + return s +} + // Contains the parameters for ModifyInstancePlacement. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacementRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacementRequest type ModifyInstancePlacementInput struct { _ struct{} `type:"structure"` @@ -45013,7 +52531,7 @@ func (s *ModifyInstancePlacementInput) SetTenancy(v string) *ModifyInstancePlace } // Contains the output of ModifyInstancePlacement. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacementResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacementResult type ModifyInstancePlacementOutput struct { _ struct{} `type:"structure"` @@ -45037,8 +52555,111 @@ func (s *ModifyInstancePlacementOutput) SetReturn(v bool) *ModifyInstancePlaceme return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyLaunchTemplateRequest +type ModifyLaunchTemplateInput struct { + _ struct{} `type:"structure"` + + // Unique, case-sensitive identifier you provide to ensure the idempotency of + // the request. For more information, see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). + ClientToken *string `type:"string"` + + // The version number of the launch template to set as the default version. + DefaultVersion *string `locationName:"SetDefaultVersion" type:"string"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateId *string `type:"string"` + + // The name of the launch template. You must specify either the launch template + // ID or launch template name in the request. + LaunchTemplateName *string `min:"3" type:"string"` +} + +// String returns the string representation +func (s ModifyLaunchTemplateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyLaunchTemplateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyLaunchTemplateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyLaunchTemplateInput"} + if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 { + invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetClientToken sets the ClientToken field's value. +func (s *ModifyLaunchTemplateInput) SetClientToken(v string) *ModifyLaunchTemplateInput { + s.ClientToken = &v + return s +} + +// SetDefaultVersion sets the DefaultVersion field's value. +func (s *ModifyLaunchTemplateInput) SetDefaultVersion(v string) *ModifyLaunchTemplateInput { + s.DefaultVersion = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyLaunchTemplateInput) SetDryRun(v bool) *ModifyLaunchTemplateInput { + s.DryRun = &v + return s +} + +// SetLaunchTemplateId sets the LaunchTemplateId field's value. +func (s *ModifyLaunchTemplateInput) SetLaunchTemplateId(v string) *ModifyLaunchTemplateInput { + s.LaunchTemplateId = &v + return s +} + +// SetLaunchTemplateName sets the LaunchTemplateName field's value. +func (s *ModifyLaunchTemplateInput) SetLaunchTemplateName(v string) *ModifyLaunchTemplateInput { + s.LaunchTemplateName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyLaunchTemplateResult +type ModifyLaunchTemplateOutput struct { + _ struct{} `type:"structure"` + + // Information about the launch template. + LaunchTemplate *LaunchTemplate `locationName:"launchTemplate" type:"structure"` +} + +// String returns the string representation +func (s ModifyLaunchTemplateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyLaunchTemplateOutput) GoString() string { + return s.String() +} + +// SetLaunchTemplate sets the LaunchTemplate field's value. +func (s *ModifyLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *ModifyLaunchTemplateOutput { + s.LaunchTemplate = v + return s +} + // Contains the parameters for ModifyNetworkInterfaceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttributeRequest type ModifyNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` @@ -45133,7 +52754,7 @@ func (s *ModifyNetworkInterfaceAttributeInput) SetSourceDestCheck(v *AttributeBo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttributeOutput type ModifyNetworkInterfaceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -45149,7 +52770,7 @@ func (s ModifyNetworkInterfaceAttributeOutput) GoString() string { } // Contains the parameters for ModifyReservedInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstancesRequest type ModifyReservedInstancesInput struct { _ struct{} `type:"structure"` @@ -45213,7 +52834,7 @@ func (s *ModifyReservedInstancesInput) SetTargetConfigurations(v []*ReservedInst } // Contains the output of ModifyReservedInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstancesResult type ModifyReservedInstancesOutput struct { _ struct{} `type:"structure"` @@ -45238,7 +52859,7 @@ func (s *ModifyReservedInstancesOutput) SetReservedInstancesModificationId(v str } // Contains the parameters for ModifySnapshotAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttributeRequest type ModifySnapshotAttributeInput struct { _ struct{} `type:"structure"` @@ -45336,7 +52957,7 @@ func (s *ModifySnapshotAttributeInput) SetUserIds(v []*string) *ModifySnapshotAt return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttributeOutput type ModifySnapshotAttributeOutput struct { _ struct{} `type:"structure"` } @@ -45352,16 +52973,16 @@ func (s ModifySnapshotAttributeOutput) GoString() string { } // Contains the parameters for ModifySpotFleetRequest. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequestRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequestRequest type ModifySpotFleetRequestInput struct { _ struct{} `type:"structure"` - // Indicates whether running Spot instances should be terminated if the target - // capacity of the Spot fleet request is decreased below the current size of - // the Spot fleet. + // Indicates whether running Spot Instances should be terminated if the target + // capacity of the Spot Fleet request is decreased below the current size of + // the Spot Fleet. ExcessCapacityTerminationPolicy *string `locationName:"excessCapacityTerminationPolicy" type:"string" enum:"ExcessCapacityTerminationPolicy"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -45412,7 +53033,7 @@ func (s *ModifySpotFleetRequestInput) SetTargetCapacity(v int64) *ModifySpotFlee } // Contains the output of ModifySpotFleetRequest. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequestResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequestResponse type ModifySpotFleetRequestOutput struct { _ struct{} `type:"structure"` @@ -45437,7 +53058,7 @@ func (s *ModifySpotFleetRequestOutput) SetReturn(v bool) *ModifySpotFleetRequest } // Contains the parameters for ModifySubnetAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttributeRequest type ModifySubnetAttributeInput struct { _ struct{} `type:"structure"` @@ -45504,7 +53125,7 @@ func (s *ModifySubnetAttributeInput) SetSubnetId(v string) *ModifySubnetAttribut return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttributeOutput type ModifySubnetAttributeOutput struct { _ struct{} `type:"structure"` } @@ -45520,7 +53141,7 @@ func (s ModifySubnetAttributeOutput) GoString() string { } // Contains the parameters for ModifyVolumeAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttributeRequest type ModifyVolumeAttributeInput struct { _ struct{} `type:"structure"` @@ -45580,7 +53201,7 @@ func (s *ModifyVolumeAttributeInput) SetVolumeId(v string) *ModifyVolumeAttribut return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttributeOutput type ModifyVolumeAttributeOutput struct { _ struct{} `type:"structure"` } @@ -45595,7 +53216,7 @@ func (s ModifyVolumeAttributeOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeRequest type ModifyVolumeInput struct { _ struct{} `type:"structure"` @@ -45687,7 +53308,7 @@ func (s *ModifyVolumeInput) SetVolumeType(v string) *ModifyVolumeInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeResult type ModifyVolumeOutput struct { _ struct{} `type:"structure"` @@ -45712,7 +53333,7 @@ func (s *ModifyVolumeOutput) SetVolumeModification(v *VolumeModification) *Modif } // Contains the parameters for ModifyVpcAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttributeRequest type ModifyVpcAttributeInput struct { _ struct{} `type:"structure"` @@ -45781,7 +53402,7 @@ func (s *ModifyVpcAttributeInput) SetVpcId(v string) *ModifyVpcAttributeInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttributeOutput type ModifyVpcAttributeOutput struct { _ struct{} `type:"structure"` } @@ -45796,29 +53417,141 @@ func (s ModifyVpcAttributeOutput) GoString() string { return s.String() } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointConnectionNotificationRequest +type ModifyVpcEndpointConnectionNotificationInput struct { + _ struct{} `type:"structure"` + + // One or more events for the endpoint. Valid values are Accept, Connect, Delete, + // and Reject. + ConnectionEvents []*string `locationNameList:"item" type:"list"` + + // The ARN for the SNS topic for the notification. + ConnectionNotificationArn *string `type:"string"` + + // The ID of the notification. + // + // ConnectionNotificationId is a required field + ConnectionNotificationId *string `type:"string" required:"true"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` +} + +// String returns the string representation +func (s ModifyVpcEndpointConnectionNotificationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointConnectionNotificationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcEndpointConnectionNotificationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcEndpointConnectionNotificationInput"} + if s.ConnectionNotificationId == nil { + invalidParams.Add(request.NewErrParamRequired("ConnectionNotificationId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetConnectionEvents sets the ConnectionEvents field's value. +func (s *ModifyVpcEndpointConnectionNotificationInput) SetConnectionEvents(v []*string) *ModifyVpcEndpointConnectionNotificationInput { + s.ConnectionEvents = v + return s +} + +// SetConnectionNotificationArn sets the ConnectionNotificationArn field's value. +func (s *ModifyVpcEndpointConnectionNotificationInput) SetConnectionNotificationArn(v string) *ModifyVpcEndpointConnectionNotificationInput { + s.ConnectionNotificationArn = &v + return s +} + +// SetConnectionNotificationId sets the ConnectionNotificationId field's value. +func (s *ModifyVpcEndpointConnectionNotificationInput) SetConnectionNotificationId(v string) *ModifyVpcEndpointConnectionNotificationInput { + s.ConnectionNotificationId = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyVpcEndpointConnectionNotificationInput) SetDryRun(v bool) *ModifyVpcEndpointConnectionNotificationInput { + s.DryRun = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointConnectionNotificationResult +type ModifyVpcEndpointConnectionNotificationOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + ReturnValue *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifyVpcEndpointConnectionNotificationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointConnectionNotificationOutput) GoString() string { + return s.String() +} + +// SetReturnValue sets the ReturnValue field's value. +func (s *ModifyVpcEndpointConnectionNotificationOutput) SetReturnValue(v bool) *ModifyVpcEndpointConnectionNotificationOutput { + s.ReturnValue = &v + return s +} + // Contains the parameters for ModifyVpcEndpoint. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointRequest type ModifyVpcEndpointInput struct { _ struct{} `type:"structure"` - // One or more route tables IDs to associate with the endpoint. + // (Gateway endpoint) One or more route tables IDs to associate with the endpoint. AddRouteTableIds []*string `locationName:"AddRouteTableId" locationNameList:"item" type:"list"` + // (Interface endpoint) One or more security group IDs to associate with the + // network interface. + AddSecurityGroupIds []*string `locationName:"AddSecurityGroupId" locationNameList:"item" type:"list"` + + // (Interface endpoint) One or more subnet IDs in which to serve the endpoint. + AddSubnetIds []*string `locationName:"AddSubnetId" locationNameList:"item" type:"list"` + // Checks whether you have the required permissions for the action, without // actually making the request, and provides an error response. If you have // the required permissions, the error response is DryRunOperation. Otherwise, // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` - // A policy document to attach to the endpoint. The policy must be in valid - // JSON format. + // (Gateway endpoint) A policy document to attach to the endpoint. The policy + // must be in valid JSON format. PolicyDocument *string `type:"string"` - // One or more route table IDs to disassociate from the endpoint. + // (Interface endpoint) Indicate whether a private hosted zone is associated + // with the VPC. + PrivateDnsEnabled *bool `type:"boolean"` + + // (Gateway endpoint) One or more route table IDs to disassociate from the endpoint. RemoveRouteTableIds []*string `locationName:"RemoveRouteTableId" locationNameList:"item" type:"list"` - // Specify true to reset the policy document to the default policy. The default - // policy allows access to the service. + // (Interface endpoint) One or more security group IDs to disassociate from + // the network interface. + RemoveSecurityGroupIds []*string `locationName:"RemoveSecurityGroupId" locationNameList:"item" type:"list"` + + // (Interface endpoint) One or more subnets IDs in which to remove the endpoint. + RemoveSubnetIds []*string `locationName:"RemoveSubnetId" locationNameList:"item" type:"list"` + + // (Gateway endpoint) Specify true to reset the policy document to the default + // policy. The default policy allows full access to the service. ResetPolicy *bool `type:"boolean"` // The ID of the endpoint. @@ -45856,6 +53589,18 @@ func (s *ModifyVpcEndpointInput) SetAddRouteTableIds(v []*string) *ModifyVpcEndp return s } +// SetAddSecurityGroupIds sets the AddSecurityGroupIds field's value. +func (s *ModifyVpcEndpointInput) SetAddSecurityGroupIds(v []*string) *ModifyVpcEndpointInput { + s.AddSecurityGroupIds = v + return s +} + +// SetAddSubnetIds sets the AddSubnetIds field's value. +func (s *ModifyVpcEndpointInput) SetAddSubnetIds(v []*string) *ModifyVpcEndpointInput { + s.AddSubnetIds = v + return s +} + // SetDryRun sets the DryRun field's value. func (s *ModifyVpcEndpointInput) SetDryRun(v bool) *ModifyVpcEndpointInput { s.DryRun = &v @@ -45868,12 +53613,30 @@ func (s *ModifyVpcEndpointInput) SetPolicyDocument(v string) *ModifyVpcEndpointI return s } +// SetPrivateDnsEnabled sets the PrivateDnsEnabled field's value. +func (s *ModifyVpcEndpointInput) SetPrivateDnsEnabled(v bool) *ModifyVpcEndpointInput { + s.PrivateDnsEnabled = &v + return s +} + // SetRemoveRouteTableIds sets the RemoveRouteTableIds field's value. func (s *ModifyVpcEndpointInput) SetRemoveRouteTableIds(v []*string) *ModifyVpcEndpointInput { s.RemoveRouteTableIds = v return s } +// SetRemoveSecurityGroupIds sets the RemoveSecurityGroupIds field's value. +func (s *ModifyVpcEndpointInput) SetRemoveSecurityGroupIds(v []*string) *ModifyVpcEndpointInput { + s.RemoveSecurityGroupIds = v + return s +} + +// SetRemoveSubnetIds sets the RemoveSubnetIds field's value. +func (s *ModifyVpcEndpointInput) SetRemoveSubnetIds(v []*string) *ModifyVpcEndpointInput { + s.RemoveSubnetIds = v + return s +} + // SetResetPolicy sets the ResetPolicy field's value. func (s *ModifyVpcEndpointInput) SetResetPolicy(v bool) *ModifyVpcEndpointInput { s.ResetPolicy = &v @@ -45886,8 +53649,7 @@ func (s *ModifyVpcEndpointInput) SetVpcEndpointId(v string) *ModifyVpcEndpointIn return s } -// Contains the output of ModifyVpcEndpoint. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointResult type ModifyVpcEndpointOutput struct { _ struct{} `type:"structure"` @@ -45911,7 +53673,206 @@ func (s *ModifyVpcEndpointOutput) SetReturn(v bool) *ModifyVpcEndpointOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServiceConfigurationRequest +type ModifyVpcEndpointServiceConfigurationInput struct { + _ struct{} `type:"structure"` + + // Indicate whether requests to create an endpoint to your service must be accepted. + AcceptanceRequired *bool `type:"boolean"` + + // The Amazon Resource Names (ARNs) of Network Load Balancers to add to your + // service configuration. + AddNetworkLoadBalancerArns []*string `locationName:"addNetworkLoadBalancerArn" locationNameList:"item" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The Amazon Resource Names (ARNs) of Network Load Balancers to remove from + // your service configuration. + RemoveNetworkLoadBalancerArns []*string `locationName:"removeNetworkLoadBalancerArn" locationNameList:"item" type:"list"` + + // The ID of the service. + // + // ServiceId is a required field + ServiceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVpcEndpointServiceConfigurationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointServiceConfigurationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcEndpointServiceConfigurationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcEndpointServiceConfigurationInput"} + if s.ServiceId == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAcceptanceRequired sets the AcceptanceRequired field's value. +func (s *ModifyVpcEndpointServiceConfigurationInput) SetAcceptanceRequired(v bool) *ModifyVpcEndpointServiceConfigurationInput { + s.AcceptanceRequired = &v + return s +} + +// SetAddNetworkLoadBalancerArns sets the AddNetworkLoadBalancerArns field's value. +func (s *ModifyVpcEndpointServiceConfigurationInput) SetAddNetworkLoadBalancerArns(v []*string) *ModifyVpcEndpointServiceConfigurationInput { + s.AddNetworkLoadBalancerArns = v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyVpcEndpointServiceConfigurationInput) SetDryRun(v bool) *ModifyVpcEndpointServiceConfigurationInput { + s.DryRun = &v + return s +} + +// SetRemoveNetworkLoadBalancerArns sets the RemoveNetworkLoadBalancerArns field's value. +func (s *ModifyVpcEndpointServiceConfigurationInput) SetRemoveNetworkLoadBalancerArns(v []*string) *ModifyVpcEndpointServiceConfigurationInput { + s.RemoveNetworkLoadBalancerArns = v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *ModifyVpcEndpointServiceConfigurationInput) SetServiceId(v string) *ModifyVpcEndpointServiceConfigurationInput { + s.ServiceId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServiceConfigurationResult +type ModifyVpcEndpointServiceConfigurationOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifyVpcEndpointServiceConfigurationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointServiceConfigurationOutput) GoString() string { + return s.String() +} + +// SetReturn sets the Return field's value. +func (s *ModifyVpcEndpointServiceConfigurationOutput) SetReturn(v bool) *ModifyVpcEndpointServiceConfigurationOutput { + s.Return = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServicePermissionsRequest +type ModifyVpcEndpointServicePermissionsInput struct { + _ struct{} `type:"structure"` + + // One or more Amazon Resource Names (ARNs) of principals for which to allow + // permission. Specify * to allow all principals. + AddAllowedPrincipals []*string `locationNameList:"item" type:"list"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // One or more Amazon Resource Names (ARNs) of principals for which to remove + // permission. + RemoveAllowedPrincipals []*string `locationNameList:"item" type:"list"` + + // The ID of the service. + // + // ServiceId is a required field + ServiceId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVpcEndpointServicePermissionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointServicePermissionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcEndpointServicePermissionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcEndpointServicePermissionsInput"} + if s.ServiceId == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAddAllowedPrincipals sets the AddAllowedPrincipals field's value. +func (s *ModifyVpcEndpointServicePermissionsInput) SetAddAllowedPrincipals(v []*string) *ModifyVpcEndpointServicePermissionsInput { + s.AddAllowedPrincipals = v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyVpcEndpointServicePermissionsInput) SetDryRun(v bool) *ModifyVpcEndpointServicePermissionsInput { + s.DryRun = &v + return s +} + +// SetRemoveAllowedPrincipals sets the RemoveAllowedPrincipals field's value. +func (s *ModifyVpcEndpointServicePermissionsInput) SetRemoveAllowedPrincipals(v []*string) *ModifyVpcEndpointServicePermissionsInput { + s.RemoveAllowedPrincipals = v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *ModifyVpcEndpointServicePermissionsInput) SetServiceId(v string) *ModifyVpcEndpointServicePermissionsInput { + s.ServiceId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServicePermissionsResult +type ModifyVpcEndpointServicePermissionsOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, it returns an error. + ReturnValue *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifyVpcEndpointServicePermissionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcEndpointServicePermissionsOutput) GoString() string { + return s.String() +} + +// SetReturnValue sets the ReturnValue field's value. +func (s *ModifyVpcEndpointServicePermissionsOutput) SetReturnValue(v bool) *ModifyVpcEndpointServicePermissionsOutput { + s.ReturnValue = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptionsRequest type ModifyVpcPeeringConnectionOptionsInput struct { _ struct{} `type:"structure"` @@ -45980,7 +53941,7 @@ func (s *ModifyVpcPeeringConnectionOptionsInput) SetVpcPeeringConnectionId(v str return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptionsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptionsResult type ModifyVpcPeeringConnectionOptionsOutput struct { _ struct{} `type:"structure"` @@ -46013,8 +53974,99 @@ func (s *ModifyVpcPeeringConnectionOptionsOutput) SetRequesterPeeringConnectionO return s } +// Contains the parameters for ModifyVpcTenancy. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcTenancyRequest +type ModifyVpcTenancyInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the operation, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The instance tenancy attribute for the VPC. + // + // InstanceTenancy is a required field + InstanceTenancy *string `type:"string" required:"true" enum:"VpcTenancy"` + + // The ID of the VPC. + // + // VpcId is a required field + VpcId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ModifyVpcTenancyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcTenancyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ModifyVpcTenancyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ModifyVpcTenancyInput"} + if s.InstanceTenancy == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceTenancy")) + } + if s.VpcId == nil { + invalidParams.Add(request.NewErrParamRequired("VpcId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *ModifyVpcTenancyInput) SetDryRun(v bool) *ModifyVpcTenancyInput { + s.DryRun = &v + return s +} + +// SetInstanceTenancy sets the InstanceTenancy field's value. +func (s *ModifyVpcTenancyInput) SetInstanceTenancy(v string) *ModifyVpcTenancyInput { + s.InstanceTenancy = &v + return s +} + +// SetVpcId sets the VpcId field's value. +func (s *ModifyVpcTenancyInput) SetVpcId(v string) *ModifyVpcTenancyInput { + s.VpcId = &v + return s +} + +// Contains the output of ModifyVpcTenancy. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcTenancyResult +type ModifyVpcTenancyOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, returns an error. + ReturnValue *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ModifyVpcTenancyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ModifyVpcTenancyOutput) GoString() string { + return s.String() +} + +// SetReturnValue sets the ReturnValue field's value. +func (s *ModifyVpcTenancyOutput) SetReturnValue(v bool) *ModifyVpcTenancyOutput { + s.ReturnValue = &v + return s +} + // Contains the parameters for MonitorInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstancesRequest type MonitorInstancesInput struct { _ struct{} `type:"structure"` @@ -46066,7 +54118,7 @@ func (s *MonitorInstancesInput) SetInstanceIds(v []*string) *MonitorInstancesInp } // Contains the output of MonitorInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstancesResult type MonitorInstancesOutput struct { _ struct{} `type:"structure"` @@ -46091,7 +54143,7 @@ func (s *MonitorInstancesOutput) SetInstanceMonitorings(v []*InstanceMonitoring) } // Describes the monitoring of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Monitoring +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Monitoring type Monitoring struct { _ struct{} `type:"structure"` @@ -46117,7 +54169,7 @@ func (s *Monitoring) SetState(v string) *Monitoring { } // Contains the parameters for MoveAddressToVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpcRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpcRequest type MoveAddressToVpcInput struct { _ struct{} `type:"structure"` @@ -46169,7 +54221,7 @@ func (s *MoveAddressToVpcInput) SetPublicIp(v string) *MoveAddressToVpcInput { } // Contains the output of MoveAddressToVpc. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpcResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpcResult type MoveAddressToVpcOutput struct { _ struct{} `type:"structure"` @@ -46203,7 +54255,7 @@ func (s *MoveAddressToVpcOutput) SetStatus(v string) *MoveAddressToVpcOutput { } // Describes the status of a moving Elastic IP address. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MovingAddressStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MovingAddressStatus type MovingAddressStatus struct { _ struct{} `type:"structure"` @@ -46238,7 +54290,7 @@ func (s *MovingAddressStatus) SetPublicIp(v string) *MovingAddressStatus { } // Describes a NAT gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NatGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NatGateway type NatGateway struct { _ struct{} `type:"structure"` @@ -46309,6 +54361,9 @@ type NatGateway struct { // The ID of the subnet in which the NAT gateway is located. SubnetId *string `locationName:"subnetId" type:"string"` + // The tags for the NAT gateway. + Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` + // The ID of the VPC in which the NAT gateway is located. VpcId *string `locationName:"vpcId" type:"string"` } @@ -46377,6 +54432,12 @@ func (s *NatGateway) SetSubnetId(v string) *NatGateway { return s } +// SetTags sets the Tags field's value. +func (s *NatGateway) SetTags(v []*Tag) *NatGateway { + s.Tags = v + return s +} + // SetVpcId sets the VpcId field's value. func (s *NatGateway) SetVpcId(v string) *NatGateway { s.VpcId = &v @@ -46384,7 +54445,7 @@ func (s *NatGateway) SetVpcId(v string) *NatGateway { } // Describes the IP addresses and network interface associated with a NAT gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NatGatewayAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NatGatewayAddress type NatGatewayAddress struct { _ struct{} `type:"structure"` @@ -46437,7 +54498,7 @@ func (s *NatGatewayAddress) SetPublicIp(v string) *NatGatewayAddress { } // Describes a network ACL. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAcl type NetworkAcl struct { _ struct{} `type:"structure"` @@ -46507,7 +54568,7 @@ func (s *NetworkAcl) SetVpcId(v string) *NetworkAcl { } // Describes an association between a network ACL and a subnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAclAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAclAssociation type NetworkAclAssociation struct { _ struct{} `type:"structure"` @@ -46550,7 +54611,7 @@ func (s *NetworkAclAssociation) SetSubnetId(v string) *NetworkAclAssociation { } // Describes an entry in a network ACL. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAclEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAclEntry type NetworkAclEntry struct { _ struct{} `type:"structure"` @@ -46640,7 +54701,7 @@ func (s *NetworkAclEntry) SetRuleNumber(v int64) *NetworkAclEntry { } // Describes a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterface type NetworkInterface struct { _ struct{} `type:"structure"` @@ -46838,7 +54899,7 @@ func (s *NetworkInterface) SetVpcId(v string) *NetworkInterface { } // Describes association information for an Elastic IP address (IPv4 only). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAssociation type NetworkInterfaceAssociation struct { _ struct{} `type:"structure"` @@ -46899,7 +54960,7 @@ func (s *NetworkInterfaceAssociation) SetPublicIp(v string) *NetworkInterfaceAss } // Describes a network interface attachment. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAttachment +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAttachment type NetworkInterfaceAttachment struct { _ struct{} `type:"structure"` @@ -46978,7 +55039,7 @@ func (s *NetworkInterfaceAttachment) SetStatus(v string) *NetworkInterfaceAttach } // Describes an attachment change. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAttachmentChanges +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAttachmentChanges type NetworkInterfaceAttachmentChanges struct { _ struct{} `type:"structure"` @@ -47012,7 +55073,7 @@ func (s *NetworkInterfaceAttachmentChanges) SetDeleteOnTermination(v bool) *Netw } // Describes an IPv6 address associated with a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceIpv6Address +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceIpv6Address type NetworkInterfaceIpv6Address struct { _ struct{} `type:"structure"` @@ -47037,7 +55098,7 @@ func (s *NetworkInterfaceIpv6Address) SetIpv6Address(v string) *NetworkInterface } // Describes a permission for a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermission type NetworkInterfacePermission struct { _ struct{} `type:"structure"` @@ -47107,7 +55168,7 @@ func (s *NetworkInterfacePermission) SetPermissionState(v *NetworkInterfacePermi } // Describes the state of a network interface permission. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermissionState +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermissionState type NetworkInterfacePermissionState struct { _ struct{} `type:"structure"` @@ -47141,7 +55202,7 @@ func (s *NetworkInterfacePermissionState) SetStatusMessage(v string) *NetworkInt } // Describes the private IPv4 address of a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePrivateIpAddress +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePrivateIpAddress type NetworkInterfacePrivateIpAddress struct { _ struct{} `type:"structure"` @@ -47194,7 +55255,7 @@ func (s *NetworkInterfacePrivateIpAddress) SetPrivateIpAddress(v string) *Networ return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NewDhcpConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NewDhcpConfiguration type NewDhcpConfiguration struct { _ struct{} `type:"structure"` @@ -47227,7 +55288,7 @@ func (s *NewDhcpConfiguration) SetValues(v []*string) *NewDhcpConfiguration { // Describes the data that identifies an Amazon FPGA image (AFI) on the PCI // bus. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PciId +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PciId type PciId struct { _ struct{} `type:"structure"` @@ -47279,7 +55340,7 @@ func (s *PciId) SetVendorId(v string) *PciId { } // Describes the VPC peering connection options. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptions type PeeringConnectionOptions struct { _ struct{} `type:"structure"` @@ -47325,7 +55386,7 @@ func (s *PeeringConnectionOptions) SetAllowEgressFromLocalVpcToRemoteClassicLink } // The VPC peering connection options. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptionsRequest type PeeringConnectionOptionsRequest struct { _ struct{} `type:"structure"` @@ -47371,7 +55432,7 @@ func (s *PeeringConnectionOptionsRequest) SetAllowEgressFromLocalVpcToRemoteClas } // Describes the placement of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Placement +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Placement type Placement struct { _ struct{} `type:"structure"` @@ -47445,7 +55506,7 @@ func (s *Placement) SetTenancy(v string) *Placement { } // Describes a placement group. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PlacementGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PlacementGroup type PlacementGroup struct { _ struct{} `type:"structure"` @@ -47488,7 +55549,7 @@ func (s *PlacementGroup) SetStrategy(v string) *PlacementGroup { } // Describes a range of ports. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PortRange +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PortRange type PortRange struct { _ struct{} `type:"structure"` @@ -47522,7 +55583,7 @@ func (s *PortRange) SetTo(v int64) *PortRange { } // Describes prefixes for AWS services. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrefixList +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrefixList type PrefixList struct { _ struct{} `type:"structure"` @@ -47564,11 +55625,18 @@ func (s *PrefixList) SetPrefixListName(v string) *PrefixList { return s } -// The ID of the prefix. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrefixListId +// [EC2-VPC only] The ID of the prefix. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrefixListId type PrefixListId struct { _ struct{} `type:"structure"` + // A description for the security group rule that references this prefix list + // ID. + // + // Constraints: Up to 255 characters in length. Allowed characters are a-z, + // A-Z, 0-9, spaces, and ._-:/()#,@[]+=;{}!$* + Description *string `locationName:"description" type:"string"` + // The ID of the prefix. PrefixListId *string `locationName:"prefixListId" type:"string"` } @@ -47583,6 +55651,12 @@ func (s PrefixListId) GoString() string { return s.String() } +// SetDescription sets the Description field's value. +func (s *PrefixListId) SetDescription(v string) *PrefixListId { + s.Description = &v + return s +} + // SetPrefixListId sets the PrefixListId field's value. func (s *PrefixListId) SetPrefixListId(v string) *PrefixListId { s.PrefixListId = &v @@ -47590,7 +55664,7 @@ func (s *PrefixListId) SetPrefixListId(v string) *PrefixListId { } // Describes the price for a Reserved Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PriceSchedule +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PriceSchedule type PriceSchedule struct { _ struct{} `type:"structure"` @@ -47653,7 +55727,7 @@ func (s *PriceSchedule) SetTerm(v int64) *PriceSchedule { } // Describes the price for a Reserved Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PriceScheduleSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PriceScheduleSpecification type PriceScheduleSpecification struct { _ struct{} `type:"structure"` @@ -47698,7 +55772,7 @@ func (s *PriceScheduleSpecification) SetTerm(v int64) *PriceScheduleSpecificatio } // Describes a Reserved Instance offering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PricingDetail +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PricingDetail type PricingDetail struct { _ struct{} `type:"structure"` @@ -47732,7 +55806,7 @@ func (s *PricingDetail) SetPrice(v float64) *PricingDetail { } // Describes a secondary private IPv4 address for a network interface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrivateIpAddressSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrivateIpAddressSpecification type PrivateIpAddressSpecification struct { _ struct{} `type:"structure"` @@ -47782,7 +55856,7 @@ func (s *PrivateIpAddressSpecification) SetPrivateIpAddress(v string) *PrivateIp } // Describes a product code. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ProductCode +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ProductCode type ProductCode struct { _ struct{} `type:"structure"` @@ -47816,7 +55890,7 @@ func (s *ProductCode) SetProductCodeType(v string) *ProductCode { } // Describes a virtual private gateway propagating route. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PropagatingVgw +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PropagatingVgw type PropagatingVgw struct { _ struct{} `type:"structure"` @@ -47843,7 +55917,7 @@ func (s *PropagatingVgw) SetGatewayId(v string) *PropagatingVgw { // Reserved. If you need to sustain traffic greater than the documented limits // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), // contact us through the Support Center (https://console.aws.amazon.com/support/home?). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ProvisionedBandwidth +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ProvisionedBandwidth type ProvisionedBandwidth struct { _ struct{} `type:"structure"` @@ -47914,7 +55988,7 @@ func (s *ProvisionedBandwidth) SetStatus(v string) *ProvisionedBandwidth { } // Describes the result of the purchase. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Purchase +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Purchase type Purchase struct { _ struct{} `type:"structure"` @@ -48003,7 +56077,7 @@ func (s *Purchase) SetUpfrontPrice(v string) *Purchase { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservationRequest type PurchaseHostReservationInput struct { _ struct{} `type:"structure"` @@ -48093,7 +56167,7 @@ func (s *PurchaseHostReservationInput) SetOfferingId(v string) *PurchaseHostRese return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservationResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservationResult type PurchaseHostReservationOutput struct { _ struct{} `type:"structure"` @@ -48107,7 +56181,7 @@ type PurchaseHostReservationOutput struct { CurrencyCode *string `locationName:"currencyCode" type:"string" enum:"CurrencyCodeValues"` // Describes the details of the purchase. - Purchase []*Purchase `locationName:"purchase" type:"list"` + Purchase []*Purchase `locationName:"purchase" locationNameList:"item" type:"list"` // The total hourly price of the reservation calculated per hour. TotalHourlyPrice *string `locationName:"totalHourlyPrice" type:"string"` @@ -48158,7 +56232,7 @@ func (s *PurchaseHostReservationOutput) SetTotalUpfrontPrice(v string) *Purchase } // Describes a request to purchase Scheduled Instances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseRequest type PurchaseRequest struct { _ struct{} `type:"structure"` @@ -48212,7 +56286,7 @@ func (s *PurchaseRequest) SetPurchaseToken(v string) *PurchaseRequest { } // Contains the parameters for PurchaseReservedInstancesOffering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOfferingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOfferingRequest type PurchaseReservedInstancesOfferingInput struct { _ struct{} `type:"structure"` @@ -48289,7 +56363,7 @@ func (s *PurchaseReservedInstancesOfferingInput) SetReservedInstancesOfferingId( } // Contains the output of PurchaseReservedInstancesOffering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOfferingResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOfferingResult type PurchaseReservedInstancesOfferingOutput struct { _ struct{} `type:"structure"` @@ -48314,7 +56388,7 @@ func (s *PurchaseReservedInstancesOfferingOutput) SetReservedInstancesId(v strin } // Contains the parameters for PurchaseScheduledInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstancesRequest type PurchaseScheduledInstancesInput struct { _ struct{} `type:"structure"` @@ -48389,7 +56463,7 @@ func (s *PurchaseScheduledInstancesInput) SetPurchaseRequests(v []*PurchaseReque } // Contains the output of PurchaseScheduledInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstancesResult type PurchaseScheduledInstancesOutput struct { _ struct{} `type:"structure"` @@ -48414,7 +56488,7 @@ func (s *PurchaseScheduledInstancesOutput) SetScheduledInstanceSet(v []*Schedule } // Contains the parameters for RebootInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstancesRequest type RebootInstancesInput struct { _ struct{} `type:"structure"` @@ -48465,7 +56539,7 @@ func (s *RebootInstancesInput) SetInstanceIds(v []*string) *RebootInstancesInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstancesOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstancesOutput type RebootInstancesOutput struct { _ struct{} `type:"structure"` } @@ -48481,7 +56555,7 @@ func (s RebootInstancesOutput) GoString() string { } // Describes a recurring charge. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RecurringCharge +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RecurringCharge type RecurringCharge struct { _ struct{} `type:"structure"` @@ -48515,7 +56589,7 @@ func (s *RecurringCharge) SetFrequency(v string) *RecurringCharge { } // Describes a region. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Region +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Region type Region struct { _ struct{} `type:"structure"` @@ -48549,7 +56623,7 @@ func (s *Region) SetRegionName(v string) *Region { } // Contains the parameters for RegisterImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImageRequest type RegisterImageInput struct { _ struct{} `type:"structure"` @@ -48601,7 +56675,7 @@ type RegisterImageInput struct { // The ID of the RAM disk. RamdiskId *string `locationName:"ramdiskId" type:"string"` - // The name of the root device (for example, /dev/sda1, or /dev/xvda). + // The device name of the root device volume (for example, /dev/sda1). RootDeviceName *string `locationName:"rootDeviceName" type:"string"` // Set to simple to enable enhanced networking with the Intel 82599 Virtual @@ -48614,7 +56688,7 @@ type RegisterImageInput struct { // PV AMI can make instances launched from the AMI unreachable. SriovNetSupport *string `locationName:"sriovNetSupport" type:"string"` - // The type of virtualization. + // The type of virtualization (hvm | paravirtual). // // Default: paravirtual VirtualizationType *string `locationName:"virtualizationType" type:"string"` @@ -48722,7 +56796,7 @@ func (s *RegisterImageInput) SetVirtualizationType(v string) *RegisterImageInput } // Contains the output of RegisterImage. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImageResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImageResult type RegisterImageOutput struct { _ struct{} `type:"structure"` @@ -48746,8 +56820,97 @@ func (s *RegisterImageOutput) SetImageId(v string) *RegisterImageOutput { return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcEndpointConnectionsRequest +type RejectVpcEndpointConnectionsInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the service. + // + // ServiceId is a required field + ServiceId *string `type:"string" required:"true"` + + // The IDs of one or more VPC endpoints. + // + // VpcEndpointIds is a required field + VpcEndpointIds []*string `locationName:"VpcEndpointId" locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s RejectVpcEndpointConnectionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RejectVpcEndpointConnectionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RejectVpcEndpointConnectionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RejectVpcEndpointConnectionsInput"} + if s.ServiceId == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceId")) + } + if s.VpcEndpointIds == nil { + invalidParams.Add(request.NewErrParamRequired("VpcEndpointIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *RejectVpcEndpointConnectionsInput) SetDryRun(v bool) *RejectVpcEndpointConnectionsInput { + s.DryRun = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *RejectVpcEndpointConnectionsInput) SetServiceId(v string) *RejectVpcEndpointConnectionsInput { + s.ServiceId = &v + return s +} + +// SetVpcEndpointIds sets the VpcEndpointIds field's value. +func (s *RejectVpcEndpointConnectionsInput) SetVpcEndpointIds(v []*string) *RejectVpcEndpointConnectionsInput { + s.VpcEndpointIds = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcEndpointConnectionsResult +type RejectVpcEndpointConnectionsOutput struct { + _ struct{} `type:"structure"` + + // Information about the endpoints that were not rejected, if applicable. + Unsuccessful []*UnsuccessfulItem `locationName:"unsuccessful" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s RejectVpcEndpointConnectionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RejectVpcEndpointConnectionsOutput) GoString() string { + return s.String() +} + +// SetUnsuccessful sets the Unsuccessful field's value. +func (s *RejectVpcEndpointConnectionsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *RejectVpcEndpointConnectionsOutput { + s.Unsuccessful = v + return s +} + // Contains the parameters for RejectVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnectionRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnectionRequest type RejectVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -48799,7 +56962,7 @@ func (s *RejectVpcPeeringConnectionInput) SetVpcPeeringConnectionId(v string) *R } // Contains the output of RejectVpcPeeringConnection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnectionResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnectionResult type RejectVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -48824,7 +56987,7 @@ func (s *RejectVpcPeeringConnectionOutput) SetReturn(v bool) *RejectVpcPeeringCo } // Contains the parameters for ReleaseAddress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddressRequest type ReleaseAddressInput struct { _ struct{} `type:"structure"` @@ -48869,7 +57032,7 @@ func (s *ReleaseAddressInput) SetPublicIp(v string) *ReleaseAddressInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddressOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddressOutput type ReleaseAddressOutput struct { _ struct{} `type:"structure"` } @@ -48885,7 +57048,7 @@ func (s ReleaseAddressOutput) GoString() string { } // Contains the parameters for ReleaseHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHostsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHostsRequest type ReleaseHostsInput struct { _ struct{} `type:"structure"` @@ -48925,7 +57088,7 @@ func (s *ReleaseHostsInput) SetHostIds(v []*string) *ReleaseHostsInput { } // Contains the output of ReleaseHosts. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHostsResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHostsResult type ReleaseHostsOutput struct { _ struct{} `type:"structure"` @@ -48959,7 +57122,7 @@ func (s *ReleaseHostsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *ReleaseHost return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociationRequest type ReplaceIamInstanceProfileAssociationInput struct { _ struct{} `type:"structure"` @@ -49012,7 +57175,7 @@ func (s *ReplaceIamInstanceProfileAssociationInput) SetIamInstanceProfile(v *Iam return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociationResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociationResult type ReplaceIamInstanceProfileAssociationOutput struct { _ struct{} `type:"structure"` @@ -49037,7 +57200,7 @@ func (s *ReplaceIamInstanceProfileAssociationOutput) SetIamInstanceProfileAssoci } // Contains the parameters for ReplaceNetworkAclAssociation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociationRequest type ReplaceNetworkAclAssociationInput struct { _ struct{} `type:"structure"` @@ -49104,7 +57267,7 @@ func (s *ReplaceNetworkAclAssociationInput) SetNetworkAclId(v string) *ReplaceNe } // Contains the output of ReplaceNetworkAclAssociation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociationResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociationResult type ReplaceNetworkAclAssociationOutput struct { _ struct{} `type:"structure"` @@ -49129,7 +57292,7 @@ func (s *ReplaceNetworkAclAssociationOutput) SetNewAssociationId(v string) *Repl } // Contains the parameters for ReplaceNetworkAclEntry. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntryRequest type ReplaceNetworkAclEntryInput struct { _ struct{} `type:"structure"` @@ -49282,7 +57445,7 @@ func (s *ReplaceNetworkAclEntryInput) SetRuleNumber(v int64) *ReplaceNetworkAclE return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntryOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntryOutput type ReplaceNetworkAclEntryOutput struct { _ struct{} `type:"structure"` } @@ -49298,7 +57461,7 @@ func (s ReplaceNetworkAclEntryOutput) GoString() string { } // Contains the parameters for ReplaceRoute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteRequest type ReplaceRouteInput struct { _ struct{} `type:"structure"` @@ -49423,7 +57586,7 @@ func (s *ReplaceRouteInput) SetVpcPeeringConnectionId(v string) *ReplaceRouteInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteOutput type ReplaceRouteOutput struct { _ struct{} `type:"structure"` } @@ -49439,7 +57602,7 @@ func (s ReplaceRouteOutput) GoString() string { } // Contains the parameters for ReplaceRouteTableAssociation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociationRequest type ReplaceRouteTableAssociationInput struct { _ struct{} `type:"structure"` @@ -49505,7 +57668,7 @@ func (s *ReplaceRouteTableAssociationInput) SetRouteTableId(v string) *ReplaceRo } // Contains the output of ReplaceRouteTableAssociation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociationResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociationResult type ReplaceRouteTableAssociationOutput struct { _ struct{} `type:"structure"` @@ -49530,7 +57693,7 @@ func (s *ReplaceRouteTableAssociationOutput) SetNewAssociationId(v string) *Repl } // Contains the parameters for ReportInstanceStatus. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatusRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatusRequest type ReportInstanceStatusInput struct { _ struct{} `type:"structure"` @@ -49551,7 +57714,7 @@ type ReportInstanceStatusInput struct { // Instances is a required field Instances []*string `locationName:"instanceId" locationNameList:"InstanceId" type:"list" required:"true"` - // One or more reason codes that describes the health state of your instance. + // One or more reason codes that describe the health state of your instance. // // * instance-stuck-in-state: My instance is stuck in a state. // @@ -49562,13 +57725,13 @@ type ReportInstanceStatusInput struct { // * password-not-available: A password is not available for my instance. // // * performance-network: My instance is experiencing performance problems - // which I believe are network related. + // that I believe are network related. // // * performance-instance-store: My instance is experiencing performance - // problems which I believe are related to the instance stores. + // problems that I believe are related to the instance stores. // // * performance-ebs-volume: My instance is experiencing performance problems - // which I believe are related to an EBS volume. + // that I believe are related to an EBS volume. // // * performance-other: My instance is experiencing performance problems. // @@ -49657,7 +57820,7 @@ func (s *ReportInstanceStatusInput) SetStatus(v string) *ReportInstanceStatusInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatusOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatusOutput type ReportInstanceStatusOutput struct { _ struct{} `type:"structure"` } @@ -49672,8 +57835,277 @@ func (s ReportInstanceStatusOutput) GoString() string { return s.String() } +// The information to include in the launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestLaunchTemplateData +type RequestLaunchTemplateData struct { + _ struct{} `type:"structure"` + + // The block device mapping. + // + // Supplying both a snapshot ID and an encryption value as arguments for block-device + // mapping results in an error. This is because only blank volumes can be encrypted + // on start, and these are not created from a snapshot. If a snapshot is the + // basis for the volume, it contains data by definition and its encryption status + // cannot be changed using this action. + BlockDeviceMappings []*LaunchTemplateBlockDeviceMappingRequest `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` + + // The credit option for CPU usage of the instance. Valid for T2 instances only. + CreditSpecification *CreditSpecificationRequest `type:"structure"` + + // If set to true, you can't terminate the instance using the Amazon EC2 console, + // CLI, or API. To change this attribute to false after launch, use ModifyInstanceAttribute. + DisableApiTermination *bool `type:"boolean"` + + // Indicates whether the instance is optimized for Amazon EBS I/O. This optimization + // provides dedicated throughput to Amazon EBS and an optimized configuration + // stack to provide optimal Amazon EBS I/O performance. This optimization isn't + // available with all instance types. Additional usage charges apply when using + // an EBS-optimized instance. + EbsOptimized *bool `type:"boolean"` + + // An elastic GPU to associate with the instance. + ElasticGpuSpecifications []*ElasticGpuSpecification `locationName:"ElasticGpuSpecification" locationNameList:"ElasticGpuSpecification" type:"list"` + + // The IAM instance profile. + IamInstanceProfile *LaunchTemplateIamInstanceProfileSpecificationRequest `type:"structure"` + + // The ID of the AMI, which you can get by using DescribeImages. + ImageId *string `type:"string"` + + // Indicates whether an instance stops or terminates when you initiate shutdown + // from the instance (using the operating system command for system shutdown). + // + // Default: stop + InstanceInitiatedShutdownBehavior *string `type:"string" enum:"ShutdownBehavior"` + + // The market (purchasing) option for the instances. + InstanceMarketOptions *LaunchTemplateInstanceMarketOptionsRequest `type:"structure"` + + // The instance type. For more information, see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) + // in the Amazon Elastic Compute Cloud User Guide. + InstanceType *string `type:"string" enum:"InstanceType"` + + // The ID of the kernel. + // + // We recommend that you use PV-GRUB instead of kernels and RAM disks. For more + // information, see User Provided Kernels (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) + // in the Amazon Elastic Compute Cloud User Guide. + KernelId *string `type:"string"` + + // The name of the key pair. You can create a key pair using CreateKeyPair or + // ImportKeyPair. + // + // If you do not specify a key pair, you can't connect to the instance unless + // you choose an AMI that is configured to allow users another way to log in. + KeyName *string `type:"string"` + + // The monitoring for the instance. + Monitoring *LaunchTemplatesMonitoringRequest `type:"structure"` + + // One or more network interfaces. + NetworkInterfaces []*LaunchTemplateInstanceNetworkInterfaceSpecificationRequest `locationName:"NetworkInterface" locationNameList:"InstanceNetworkInterfaceSpecification" type:"list"` + + // The placement for the instance. + Placement *LaunchTemplatePlacementRequest `type:"structure"` + + // The ID of the RAM disk. + // + // We recommend that you use PV-GRUB instead of kernels and RAM disks. For more + // information, see User Provided Kernels (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) + // in the Amazon Elastic Compute Cloud User Guide. + RamDiskId *string `type:"string"` + + // One or more security group IDs. You can create a security group using CreateSecurityGroup. + // You cannot specify both a security group ID and security name in the same + // request. + SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"SecurityGroupId" type:"list"` + + // [EC2-Classic, default VPC] One or more security group names. For a nondefault + // VPC, you must use security group IDs instead. You cannot specify both a security + // group ID and security name in the same request. + SecurityGroups []*string `locationName:"SecurityGroup" locationNameList:"SecurityGroup" type:"list"` + + // The tags to apply to the resources during launch. You can tag instances and + // volumes. The specified tags are applied to all instances or volumes that + // are created during launch. + TagSpecifications []*LaunchTemplateTagSpecificationRequest `locationName:"TagSpecification" locationNameList:"LaunchTemplateTagSpecificationRequest" type:"list"` + + // The user data to make available to the instance. For more information, see + // Running Commands on Your Linux Instance at Launch (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) + // (Linux) and Adding User Data (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-instance-metadata.html#instancedata-add-user-data) + // (Windows). If you are using a command line tool, base64-encoding is performed + // for you and you can load the text from a file. Otherwise, you must provide + // base64-encoded text. + UserData *string `type:"string"` +} + +// String returns the string representation +func (s RequestLaunchTemplateData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RequestLaunchTemplateData) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RequestLaunchTemplateData) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RequestLaunchTemplateData"} + if s.CreditSpecification != nil { + if err := s.CreditSpecification.Validate(); err != nil { + invalidParams.AddNested("CreditSpecification", err.(request.ErrInvalidParams)) + } + } + if s.ElasticGpuSpecifications != nil { + for i, v := range s.ElasticGpuSpecifications { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ElasticGpuSpecifications", i), err.(request.ErrInvalidParams)) + } + } + } + if s.NetworkInterfaces != nil { + for i, v := range s.NetworkInterfaces { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "NetworkInterfaces", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBlockDeviceMappings sets the BlockDeviceMappings field's value. +func (s *RequestLaunchTemplateData) SetBlockDeviceMappings(v []*LaunchTemplateBlockDeviceMappingRequest) *RequestLaunchTemplateData { + s.BlockDeviceMappings = v + return s +} + +// SetCreditSpecification sets the CreditSpecification field's value. +func (s *RequestLaunchTemplateData) SetCreditSpecification(v *CreditSpecificationRequest) *RequestLaunchTemplateData { + s.CreditSpecification = v + return s +} + +// SetDisableApiTermination sets the DisableApiTermination field's value. +func (s *RequestLaunchTemplateData) SetDisableApiTermination(v bool) *RequestLaunchTemplateData { + s.DisableApiTermination = &v + return s +} + +// SetEbsOptimized sets the EbsOptimized field's value. +func (s *RequestLaunchTemplateData) SetEbsOptimized(v bool) *RequestLaunchTemplateData { + s.EbsOptimized = &v + return s +} + +// SetElasticGpuSpecifications sets the ElasticGpuSpecifications field's value. +func (s *RequestLaunchTemplateData) SetElasticGpuSpecifications(v []*ElasticGpuSpecification) *RequestLaunchTemplateData { + s.ElasticGpuSpecifications = v + return s +} + +// SetIamInstanceProfile sets the IamInstanceProfile field's value. +func (s *RequestLaunchTemplateData) SetIamInstanceProfile(v *LaunchTemplateIamInstanceProfileSpecificationRequest) *RequestLaunchTemplateData { + s.IamInstanceProfile = v + return s +} + +// SetImageId sets the ImageId field's value. +func (s *RequestLaunchTemplateData) SetImageId(v string) *RequestLaunchTemplateData { + s.ImageId = &v + return s +} + +// SetInstanceInitiatedShutdownBehavior sets the InstanceInitiatedShutdownBehavior field's value. +func (s *RequestLaunchTemplateData) SetInstanceInitiatedShutdownBehavior(v string) *RequestLaunchTemplateData { + s.InstanceInitiatedShutdownBehavior = &v + return s +} + +// SetInstanceMarketOptions sets the InstanceMarketOptions field's value. +func (s *RequestLaunchTemplateData) SetInstanceMarketOptions(v *LaunchTemplateInstanceMarketOptionsRequest) *RequestLaunchTemplateData { + s.InstanceMarketOptions = v + return s +} + +// SetInstanceType sets the InstanceType field's value. +func (s *RequestLaunchTemplateData) SetInstanceType(v string) *RequestLaunchTemplateData { + s.InstanceType = &v + return s +} + +// SetKernelId sets the KernelId field's value. +func (s *RequestLaunchTemplateData) SetKernelId(v string) *RequestLaunchTemplateData { + s.KernelId = &v + return s +} + +// SetKeyName sets the KeyName field's value. +func (s *RequestLaunchTemplateData) SetKeyName(v string) *RequestLaunchTemplateData { + s.KeyName = &v + return s +} + +// SetMonitoring sets the Monitoring field's value. +func (s *RequestLaunchTemplateData) SetMonitoring(v *LaunchTemplatesMonitoringRequest) *RequestLaunchTemplateData { + s.Monitoring = v + return s +} + +// SetNetworkInterfaces sets the NetworkInterfaces field's value. +func (s *RequestLaunchTemplateData) SetNetworkInterfaces(v []*LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) *RequestLaunchTemplateData { + s.NetworkInterfaces = v + return s +} + +// SetPlacement sets the Placement field's value. +func (s *RequestLaunchTemplateData) SetPlacement(v *LaunchTemplatePlacementRequest) *RequestLaunchTemplateData { + s.Placement = v + return s +} + +// SetRamDiskId sets the RamDiskId field's value. +func (s *RequestLaunchTemplateData) SetRamDiskId(v string) *RequestLaunchTemplateData { + s.RamDiskId = &v + return s +} + +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *RequestLaunchTemplateData) SetSecurityGroupIds(v []*string) *RequestLaunchTemplateData { + s.SecurityGroupIds = v + return s +} + +// SetSecurityGroups sets the SecurityGroups field's value. +func (s *RequestLaunchTemplateData) SetSecurityGroups(v []*string) *RequestLaunchTemplateData { + s.SecurityGroups = v + return s +} + +// SetTagSpecifications sets the TagSpecifications field's value. +func (s *RequestLaunchTemplateData) SetTagSpecifications(v []*LaunchTemplateTagSpecificationRequest) *RequestLaunchTemplateData { + s.TagSpecifications = v + return s +} + +// SetUserData sets the UserData field's value. +func (s *RequestLaunchTemplateData) SetUserData(v string) *RequestLaunchTemplateData { + s.UserData = &v + return s +} + // Contains the parameters for RequestSpotFleet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleetRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleetRequest type RequestSpotFleetInput struct { _ struct{} `type:"structure"` @@ -49683,7 +58115,7 @@ type RequestSpotFleetInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The configuration for the Spot fleet request. + // The configuration for the Spot Fleet request. // // SpotFleetRequestConfig is a required field SpotFleetRequestConfig *SpotFleetRequestConfigData `locationName:"spotFleetRequestConfig" type:"structure" required:"true"` @@ -49730,11 +58162,11 @@ func (s *RequestSpotFleetInput) SetSpotFleetRequestConfig(v *SpotFleetRequestCon } // Contains the output of RequestSpotFleet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleetResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleetResponse type RequestSpotFleetOutput struct { _ struct{} `type:"structure"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` @@ -49757,38 +58189,38 @@ func (s *RequestSpotFleetOutput) SetSpotFleetRequestId(v string) *RequestSpotFle } // Contains the parameters for RequestSpotInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstancesRequest type RequestSpotInstancesInput struct { _ struct{} `type:"structure"` - // The user-specified name for a logical grouping of bids. + // The user-specified name for a logical grouping of requests. // // When you specify an Availability Zone group in a Spot Instance request, all - // Spot instances in the request are launched in the same Availability Zone. + // Spot Instances in the request are launched in the same Availability Zone. // Instance proximity is maintained with this parameter, but the choice of Availability - // Zone is not. The group applies only to bids for Spot Instances of the same - // instance type. Any additional Spot instance requests that are specified with - // the same Availability Zone group name are launched in that same Availability + // Zone is not. The group applies only to requests for Spot Instances of the + // same instance type. Any additional Spot Instance requests that are specified + // with the same Availability Zone group name are launched in that same Availability // Zone, as long as at least one instance from the group is still active. // // If there is no active instance running in the Availability Zone group that - // you specify for a new Spot instance request (all instances are terminated, - // the bid is expired, or the bid falls below current market), then Amazon EC2 - // launches the instance in any Availability Zone where the constraint can be - // met. Consequently, the subsequent set of Spot instances could be placed in - // a different zone from the original request, even if you specified the same - // Availability Zone group. + // you specify for a new Spot Instance request (all instances are terminated, + // the request is expired, or the maximum price you specified falls below current + // Spot price), then Amazon EC2 launches the instance in any Availability Zone + // where the constraint can be met. Consequently, the subsequent set of Spot + // Instances could be placed in a different zone from the original request, + // even if you specified the same Availability Zone group. // // Default: Instances are launched in any available Availability Zone. AvailabilityZoneGroup *string `locationName:"availabilityZoneGroup" type:"string"` - // The required duration for the Spot instances (also known as Spot blocks), + // The required duration for the Spot Instances (also known as Spot blocks), // in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, // or 360). // - // The duration period starts as soon as your Spot instance receives its instance - // ID. At the end of the duration period, Amazon EC2 marks the Spot instance - // for termination and provides a Spot instance termination notice, which gives + // The duration period starts as soon as your Spot Instance receives its instance + // ID. At the end of the duration period, Amazon EC2 marks the Spot Instance + // for termination and provides a Spot Instance termination notice, which gives // the instance a two-minute warning before it terminates. // // Note that you can't specify an Availability Zone group or a launch group @@ -49806,12 +58238,15 @@ type RequestSpotInstancesInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The maximum number of Spot instances to launch. + // The maximum number of Spot Instances to launch. // // Default: 1 InstanceCount *int64 `locationName:"instanceCount" type:"integer"` - // The instance launch group. Launch groups are Spot instances that launch together + // The behavior when a Spot Instance is interrupted. The default is terminate. + InstanceInterruptionBehavior *string `type:"string" enum:"InstanceInterruptionBehavior"` + + // The instance launch group. Launch groups are Spot Instances that launch together // and terminate together. // // Default: Instances are launched and terminated individually @@ -49820,13 +58255,11 @@ type RequestSpotInstancesInput struct { // The launch specification. LaunchSpecification *RequestSpotLaunchSpecification `type:"structure"` - // The maximum hourly price (bid) for any Spot instance launched to fulfill - // the request. - // - // SpotPrice is a required field - SpotPrice *string `locationName:"spotPrice" type:"string" required:"true"` + // The maximum price per hour that you are willing to pay for a Spot Instance. + // The default is the On-Demand price. + SpotPrice *string `locationName:"spotPrice" type:"string"` - // The Spot instance request type. + // The Spot Instance request type. // // Default: one-time Type *string `locationName:"type" type:"string" enum:"SpotInstanceType"` @@ -49836,16 +58269,13 @@ type RequestSpotInstancesInput struct { // launch, the request expires, or the request is canceled. If the request is // persistent, the request becomes active at this date and time and remains // active until it expires or is canceled. - // - // Default: The request is effective indefinitely. ValidFrom *time.Time `locationName:"validFrom" type:"timestamp" timestampFormat:"iso8601"` // The end date of the request. If this is a one-time request, the request remains // active until all instances launch, the request is canceled, or this date // is reached. If the request is persistent, it remains active until it is canceled - // or this date and time is reached. - // - // Default: The request is effective indefinitely. + // or this date is reached. The default end date is 7 days from the current + // date. ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` } @@ -49862,9 +58292,6 @@ func (s RequestSpotInstancesInput) GoString() string { // Validate inspects the fields of the type to determine if they are valid. func (s *RequestSpotInstancesInput) Validate() error { invalidParams := request.ErrInvalidParams{Context: "RequestSpotInstancesInput"} - if s.SpotPrice == nil { - invalidParams.Add(request.NewErrParamRequired("SpotPrice")) - } if s.LaunchSpecification != nil { if err := s.LaunchSpecification.Validate(); err != nil { invalidParams.AddNested("LaunchSpecification", err.(request.ErrInvalidParams)) @@ -49907,6 +58334,12 @@ func (s *RequestSpotInstancesInput) SetInstanceCount(v int64) *RequestSpotInstan return s } +// SetInstanceInterruptionBehavior sets the InstanceInterruptionBehavior field's value. +func (s *RequestSpotInstancesInput) SetInstanceInterruptionBehavior(v string) *RequestSpotInstancesInput { + s.InstanceInterruptionBehavior = &v + return s +} + // SetLaunchGroup sets the LaunchGroup field's value. func (s *RequestSpotInstancesInput) SetLaunchGroup(v string) *RequestSpotInstancesInput { s.LaunchGroup = &v @@ -49944,11 +58377,11 @@ func (s *RequestSpotInstancesInput) SetValidUntil(v time.Time) *RequestSpotInsta } // Contains the output of RequestSpotInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstancesResult type RequestSpotInstancesOutput struct { _ struct{} `type:"structure"` - // One or more Spot instance requests. + // One or more Spot Instance requests. SpotInstanceRequests []*SpotInstanceRequest `locationName:"spotInstanceRequestSet" locationNameList:"item" type:"list"` } @@ -49969,17 +58402,17 @@ func (s *RequestSpotInstancesOutput) SetSpotInstanceRequests(v []*SpotInstanceRe } // Describes the launch specification for an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotLaunchSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotLaunchSpecification type RequestSpotLaunchSpecification struct { _ struct{} `type:"structure"` // Deprecated. AddressingType *string `locationName:"addressingType" type:"string"` - // One or more block device mapping entries. - // - // Although you can specify encrypted EBS volumes in this block device mapping - // for your Spot Instances, these volumes are not encrypted. + // One or more block device mapping entries. You can't specify both a snapshot + // ID and an encryption value. This is because only blank volumes can be encrypted + // on creation. If a snapshot is the basis for a volume, it is not blank and + // its encryption status is used for the volume encryption status. BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` // Indicates whether the instance is optimized for EBS I/O. This optimization @@ -50170,7 +58603,7 @@ func (s *RequestSpotLaunchSpecification) SetUserData(v string) *RequestSpotLaunc } // Describes a reservation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Reservation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Reservation type Reservation struct { _ struct{} `type:"structure"` @@ -50232,7 +58665,7 @@ func (s *Reservation) SetReservationId(v string) *Reservation { } // The cost associated with the Reserved Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservationValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservationValue type ReservationValue struct { _ struct{} `type:"structure"` @@ -50276,7 +58709,7 @@ func (s *ReservationValue) SetRemainingUpfrontValue(v string) *ReservationValue } // Describes the limit price of a Reserved Instance offering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstanceLimitPrice +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstanceLimitPrice type ReservedInstanceLimitPrice struct { _ struct{} `type:"structure"` @@ -50312,7 +58745,7 @@ func (s *ReservedInstanceLimitPrice) SetCurrencyCode(v string) *ReservedInstance } // The total value of the Convertible Reserved Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstanceReservationValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstanceReservationValue type ReservedInstanceReservationValue struct { _ struct{} `type:"structure"` @@ -50346,7 +58779,7 @@ func (s *ReservedInstanceReservationValue) SetReservedInstanceId(v string) *Rese } // Describes a Reserved Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstances +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstances type ReservedInstances struct { _ struct{} `type:"structure"` @@ -50525,7 +58958,7 @@ func (s *ReservedInstances) SetUsagePrice(v float64) *ReservedInstances { } // Describes the configuration settings for the modified Reserved Instances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesConfiguration type ReservedInstancesConfiguration struct { _ struct{} `type:"structure"` @@ -50588,7 +59021,7 @@ func (s *ReservedInstancesConfiguration) SetScope(v string) *ReservedInstancesCo } // Describes the ID of a Reserved Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesId +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesId type ReservedInstancesId struct { _ struct{} `type:"structure"` @@ -50613,7 +59046,7 @@ func (s *ReservedInstancesId) SetReservedInstancesId(v string) *ReservedInstance } // Describes a Reserved Instance listing. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesListing +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesListing type ReservedInstancesListing struct { _ struct{} `type:"structure"` @@ -50721,7 +59154,7 @@ func (s *ReservedInstancesListing) SetUpdateDate(v time.Time) *ReservedInstances } // Describes a Reserved Instance modification. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesModification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesModification type ReservedInstancesModification struct { _ struct{} `type:"structure"` @@ -50820,7 +59253,7 @@ func (s *ReservedInstancesModification) SetUpdateDate(v time.Time) *ReservedInst } // Describes the modification request/s. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesModificationResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesModificationResult type ReservedInstancesModificationResult struct { _ struct{} `type:"structure"` @@ -50856,7 +59289,7 @@ func (s *ReservedInstancesModificationResult) SetTargetConfiguration(v *Reserved } // Describes a Reserved Instance offering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesOffering +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesOffering type ReservedInstancesOffering struct { _ struct{} `type:"structure"` @@ -51014,8 +59447,92 @@ func (s *ReservedInstancesOffering) SetUsagePrice(v float64) *ReservedInstancesO return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetFpgaImageAttributeRequest +type ResetFpgaImageAttributeInput struct { + _ struct{} `type:"structure"` + + // The attribute. + Attribute *string `type:"string" enum:"ResetFpgaImageAttributeName"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the AFI. + // + // FpgaImageId is a required field + FpgaImageId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ResetFpgaImageAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetFpgaImageAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResetFpgaImageAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResetFpgaImageAttributeInput"} + if s.FpgaImageId == nil { + invalidParams.Add(request.NewErrParamRequired("FpgaImageId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttribute sets the Attribute field's value. +func (s *ResetFpgaImageAttributeInput) SetAttribute(v string) *ResetFpgaImageAttributeInput { + s.Attribute = &v + return s +} + +// SetDryRun sets the DryRun field's value. +func (s *ResetFpgaImageAttributeInput) SetDryRun(v bool) *ResetFpgaImageAttributeInput { + s.DryRun = &v + return s +} + +// SetFpgaImageId sets the FpgaImageId field's value. +func (s *ResetFpgaImageAttributeInput) SetFpgaImageId(v string) *ResetFpgaImageAttributeInput { + s.FpgaImageId = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetFpgaImageAttributeResult +type ResetFpgaImageAttributeOutput struct { + _ struct{} `type:"structure"` + + // Is true if the request succeeds, and an error otherwise. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s ResetFpgaImageAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResetFpgaImageAttributeOutput) GoString() string { + return s.String() +} + +// SetReturn sets the Return field's value. +func (s *ResetFpgaImageAttributeOutput) SetReturn(v bool) *ResetFpgaImageAttributeOutput { + s.Return = &v + return s +} + // Contains the parameters for ResetImageAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttributeRequest type ResetImageAttributeInput struct { _ struct{} `type:"structure"` @@ -51081,7 +59598,7 @@ func (s *ResetImageAttributeInput) SetImageId(v string) *ResetImageAttributeInpu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttributeOutput type ResetImageAttributeOutput struct { _ struct{} `type:"structure"` } @@ -51097,7 +59614,7 @@ func (s ResetImageAttributeOutput) GoString() string { } // Contains the parameters for ResetInstanceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttributeRequest type ResetInstanceAttributeInput struct { _ struct{} `type:"structure"` @@ -51165,7 +59682,7 @@ func (s *ResetInstanceAttributeInput) SetInstanceId(v string) *ResetInstanceAttr return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttributeOutput type ResetInstanceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -51181,7 +59698,7 @@ func (s ResetInstanceAttributeOutput) GoString() string { } // Contains the parameters for ResetNetworkInterfaceAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttributeRequest type ResetNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` @@ -51241,7 +59758,7 @@ func (s *ResetNetworkInterfaceAttributeInput) SetSourceDestCheck(v string) *Rese return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttributeOutput type ResetNetworkInterfaceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -51257,7 +59774,7 @@ func (s ResetNetworkInterfaceAttributeOutput) GoString() string { } // Contains the parameters for ResetSnapshotAttribute. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttributeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttributeRequest type ResetSnapshotAttributeInput struct { _ struct{} `type:"structure"` @@ -51323,7 +59840,7 @@ func (s *ResetSnapshotAttributeInput) SetSnapshotId(v string) *ResetSnapshotAttr return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttributeOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttributeOutput type ResetSnapshotAttributeOutput struct { _ struct{} `type:"structure"` } @@ -51338,8 +59855,241 @@ func (s ResetSnapshotAttributeOutput) GoString() string { return s.String() } +// Describes the error that's returned when you cannot delete a launch template +// version. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResponseError +type ResponseError struct { + _ struct{} `type:"structure"` + + // The error code. + Code *string `locationName:"code" type:"string" enum:"LaunchTemplateErrorCode"` + + // The error message, if applicable. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s ResponseError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResponseError) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *ResponseError) SetCode(v string) *ResponseError { + s.Code = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *ResponseError) SetMessage(v string) *ResponseError { + s.Message = &v + return s +} + +// The information for a launch template. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResponseLaunchTemplateData +type ResponseLaunchTemplateData struct { + _ struct{} `type:"structure"` + + // The block device mappings. + BlockDeviceMappings []*LaunchTemplateBlockDeviceMapping `locationName:"blockDeviceMappingSet" locationNameList:"item" type:"list"` + + // The credit option for CPU usage of the instance. + CreditSpecification *CreditSpecification `locationName:"creditSpecification" type:"structure"` + + // If set to true, indicates that the instance cannot be terminated using the + // Amazon EC2 console, command line tool, or API. + DisableApiTermination *bool `locationName:"disableApiTermination" type:"boolean"` + + // Indicates whether the instance is optimized for Amazon EBS I/O. + EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` + + // The elastic GPU specification. + ElasticGpuSpecifications []*ElasticGpuSpecificationResponse `locationName:"elasticGpuSpecificationSet" locationNameList:"item" type:"list"` + + // The IAM instance profile. + IamInstanceProfile *LaunchTemplateIamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` + + // The ID of the AMI that was used to launch the instance. + ImageId *string `locationName:"imageId" type:"string"` + + // Indicates whether an instance stops or terminates when you initiate shutdown + // from the instance (using the operating system command for system shutdown). + InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` + + // The market (purchasing) option for the instances. + InstanceMarketOptions *LaunchTemplateInstanceMarketOptions `locationName:"instanceMarketOptions" type:"structure"` + + // The instance type. + InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` + + // The ID of the kernel, if applicable. + KernelId *string `locationName:"kernelId" type:"string"` + + // The name of the key pair. + KeyName *string `locationName:"keyName" type:"string"` + + // The monitoring for the instance. + Monitoring *LaunchTemplatesMonitoring `locationName:"monitoring" type:"structure"` + + // The network interfaces. + NetworkInterfaces []*LaunchTemplateInstanceNetworkInterfaceSpecification `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` + + // The placement of the instance. + Placement *LaunchTemplatePlacement `locationName:"placement" type:"structure"` + + // The ID of the RAM disk, if applicable. + RamDiskId *string `locationName:"ramDiskId" type:"string"` + + // The security group IDs. + SecurityGroupIds []*string `locationName:"securityGroupIdSet" locationNameList:"item" type:"list"` + + // The security group names. + SecurityGroups []*string `locationName:"securityGroupSet" locationNameList:"item" type:"list"` + + // The tags. + TagSpecifications []*LaunchTemplateTagSpecification `locationName:"tagSpecificationSet" locationNameList:"item" type:"list"` + + // The user data for the instance. + UserData *string `locationName:"userData" type:"string"` +} + +// String returns the string representation +func (s ResponseLaunchTemplateData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResponseLaunchTemplateData) GoString() string { + return s.String() +} + +// SetBlockDeviceMappings sets the BlockDeviceMappings field's value. +func (s *ResponseLaunchTemplateData) SetBlockDeviceMappings(v []*LaunchTemplateBlockDeviceMapping) *ResponseLaunchTemplateData { + s.BlockDeviceMappings = v + return s +} + +// SetCreditSpecification sets the CreditSpecification field's value. +func (s *ResponseLaunchTemplateData) SetCreditSpecification(v *CreditSpecification) *ResponseLaunchTemplateData { + s.CreditSpecification = v + return s +} + +// SetDisableApiTermination sets the DisableApiTermination field's value. +func (s *ResponseLaunchTemplateData) SetDisableApiTermination(v bool) *ResponseLaunchTemplateData { + s.DisableApiTermination = &v + return s +} + +// SetEbsOptimized sets the EbsOptimized field's value. +func (s *ResponseLaunchTemplateData) SetEbsOptimized(v bool) *ResponseLaunchTemplateData { + s.EbsOptimized = &v + return s +} + +// SetElasticGpuSpecifications sets the ElasticGpuSpecifications field's value. +func (s *ResponseLaunchTemplateData) SetElasticGpuSpecifications(v []*ElasticGpuSpecificationResponse) *ResponseLaunchTemplateData { + s.ElasticGpuSpecifications = v + return s +} + +// SetIamInstanceProfile sets the IamInstanceProfile field's value. +func (s *ResponseLaunchTemplateData) SetIamInstanceProfile(v *LaunchTemplateIamInstanceProfileSpecification) *ResponseLaunchTemplateData { + s.IamInstanceProfile = v + return s +} + +// SetImageId sets the ImageId field's value. +func (s *ResponseLaunchTemplateData) SetImageId(v string) *ResponseLaunchTemplateData { + s.ImageId = &v + return s +} + +// SetInstanceInitiatedShutdownBehavior sets the InstanceInitiatedShutdownBehavior field's value. +func (s *ResponseLaunchTemplateData) SetInstanceInitiatedShutdownBehavior(v string) *ResponseLaunchTemplateData { + s.InstanceInitiatedShutdownBehavior = &v + return s +} + +// SetInstanceMarketOptions sets the InstanceMarketOptions field's value. +func (s *ResponseLaunchTemplateData) SetInstanceMarketOptions(v *LaunchTemplateInstanceMarketOptions) *ResponseLaunchTemplateData { + s.InstanceMarketOptions = v + return s +} + +// SetInstanceType sets the InstanceType field's value. +func (s *ResponseLaunchTemplateData) SetInstanceType(v string) *ResponseLaunchTemplateData { + s.InstanceType = &v + return s +} + +// SetKernelId sets the KernelId field's value. +func (s *ResponseLaunchTemplateData) SetKernelId(v string) *ResponseLaunchTemplateData { + s.KernelId = &v + return s +} + +// SetKeyName sets the KeyName field's value. +func (s *ResponseLaunchTemplateData) SetKeyName(v string) *ResponseLaunchTemplateData { + s.KeyName = &v + return s +} + +// SetMonitoring sets the Monitoring field's value. +func (s *ResponseLaunchTemplateData) SetMonitoring(v *LaunchTemplatesMonitoring) *ResponseLaunchTemplateData { + s.Monitoring = v + return s +} + +// SetNetworkInterfaces sets the NetworkInterfaces field's value. +func (s *ResponseLaunchTemplateData) SetNetworkInterfaces(v []*LaunchTemplateInstanceNetworkInterfaceSpecification) *ResponseLaunchTemplateData { + s.NetworkInterfaces = v + return s +} + +// SetPlacement sets the Placement field's value. +func (s *ResponseLaunchTemplateData) SetPlacement(v *LaunchTemplatePlacement) *ResponseLaunchTemplateData { + s.Placement = v + return s +} + +// SetRamDiskId sets the RamDiskId field's value. +func (s *ResponseLaunchTemplateData) SetRamDiskId(v string) *ResponseLaunchTemplateData { + s.RamDiskId = &v + return s +} + +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *ResponseLaunchTemplateData) SetSecurityGroupIds(v []*string) *ResponseLaunchTemplateData { + s.SecurityGroupIds = v + return s +} + +// SetSecurityGroups sets the SecurityGroups field's value. +func (s *ResponseLaunchTemplateData) SetSecurityGroups(v []*string) *ResponseLaunchTemplateData { + s.SecurityGroups = v + return s +} + +// SetTagSpecifications sets the TagSpecifications field's value. +func (s *ResponseLaunchTemplateData) SetTagSpecifications(v []*LaunchTemplateTagSpecification) *ResponseLaunchTemplateData { + s.TagSpecifications = v + return s +} + +// SetUserData sets the UserData field's value. +func (s *ResponseLaunchTemplateData) SetUserData(v string) *ResponseLaunchTemplateData { + s.UserData = &v + return s +} + // Contains the parameters for RestoreAddressToClassic. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassicRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassicRequest type RestoreAddressToClassicInput struct { _ struct{} `type:"structure"` @@ -51391,7 +60141,7 @@ func (s *RestoreAddressToClassicInput) SetPublicIp(v string) *RestoreAddressToCl } // Contains the output of RestoreAddressToClassic. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassicResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassicResult type RestoreAddressToClassicOutput struct { _ struct{} `type:"structure"` @@ -51425,12 +60175,11 @@ func (s *RestoreAddressToClassicOutput) SetStatus(v string) *RestoreAddressToCla } // Contains the parameters for RevokeSecurityGroupEgress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgressRequest type RevokeSecurityGroupEgressInput struct { _ struct{} `type:"structure"` - // The CIDR IP address range. We recommend that you specify the CIDR range in - // a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the CIDR. CidrIp *string `locationName:"cidrIp" type:"string"` // Checks whether you have the required permissions for the action, without @@ -51439,8 +60188,7 @@ type RevokeSecurityGroupEgressInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // The start of port range for the TCP and UDP protocols, or an ICMP type number. - // We recommend that you specify the port range in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the port. FromPort *int64 `locationName:"fromPort" type:"integer"` // The ID of the security group. @@ -51448,26 +60196,23 @@ type RevokeSecurityGroupEgressInput struct { // GroupId is a required field GroupId *string `locationName:"groupId" type:"string" required:"true"` - // A set of IP permissions. You can't specify a destination security group and - // a CIDR IP address range. + // One or more sets of IP permissions. You can't specify a destination security + // group and a CIDR IP address range in the same set of permissions. IpPermissions []*IpPermission `locationName:"ipPermissions" locationNameList:"item" type:"list"` - // The IP protocol name or number. We recommend that you specify the protocol - // in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the protocol name or + // number. IpProtocol *string `locationName:"ipProtocol" type:"string"` - // The name of a destination security group. To revoke outbound access to a - // destination security group, we recommend that you use a set of IP permissions - // instead. + // Not supported. Use a set of IP permissions to specify a destination security + // group. SourceSecurityGroupName *string `locationName:"sourceSecurityGroupName" type:"string"` - // The AWS account number for a destination security group. To revoke outbound - // access to a destination security group, we recommend that you use a set of - // IP permissions instead. + // Not supported. Use a set of IP permissions to specify a destination security + // group. SourceSecurityGroupOwnerId *string `locationName:"sourceSecurityGroupOwnerId" type:"string"` - // The end of port range for the TCP and UDP protocols, or an ICMP type number. - // We recommend that you specify the port range in a set of IP permissions instead. + // Not supported. Use a set of IP permissions to specify the port. ToPort *int64 `locationName:"toPort" type:"integer"` } @@ -51548,7 +60293,7 @@ func (s *RevokeSecurityGroupEgressInput) SetToPort(v int64) *RevokeSecurityGroup return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgressOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgressOutput type RevokeSecurityGroupEgressOutput struct { _ struct{} `type:"structure"` } @@ -51564,7 +60309,7 @@ func (s RevokeSecurityGroupEgressOutput) GoString() string { } // Contains the parameters for RevokeSecurityGroupIngress. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngressRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngressRequest type RevokeSecurityGroupIngressInput struct { _ struct{} `type:"structure"` @@ -51582,15 +60327,17 @@ type RevokeSecurityGroupIngressInput struct { // For the ICMP type number, use -1 to specify all ICMP types. FromPort *int64 `type:"integer"` - // The ID of the security group. Required for a security group in a nondefault - // VPC. + // The ID of the security group. You must specify either the security group + // ID or the security group name in the request. For security groups in a nondefault + // VPC, you must specify the security group ID. GroupId *string `type:"string"` - // [EC2-Classic, default VPC] The name of the security group. + // [EC2-Classic, default VPC] The name of the security group. You must specify + // either the security group ID or the security group name in the request. GroupName *string `type:"string"` - // A set of IP permissions. You can't specify a source security group and a - // CIDR IP address range. + // One or more sets of IP permissions. You can't specify a source security group + // and a CIDR IP address range in the same set of permissions. IpPermissions []*IpPermission `locationNameList:"item" type:"list"` // The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)). @@ -51688,7 +60435,7 @@ func (s *RevokeSecurityGroupIngressInput) SetToPort(v int64) *RevokeSecurityGrou return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngressOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngressOutput type RevokeSecurityGroupIngressOutput struct { _ struct{} `type:"structure"` } @@ -51704,7 +60451,7 @@ func (s RevokeSecurityGroupIngressOutput) GoString() string { } // Describes a route in a route table. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Route +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Route type Route struct { _ struct{} `type:"structure"` @@ -51837,7 +60584,7 @@ func (s *Route) SetVpcPeeringConnectionId(v string) *Route { } // Describes a route table. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RouteTable +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RouteTable type RouteTable struct { _ struct{} `type:"structure"` @@ -51907,7 +60654,7 @@ func (s *RouteTable) SetVpcId(v string) *RouteTable { } // Describes an association between a route table and a subnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RouteTableAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RouteTableAssociation type RouteTableAssociation struct { _ struct{} `type:"structure"` @@ -51959,20 +60706,17 @@ func (s *RouteTableAssociation) SetSubnetId(v string) *RouteTableAssociation { } // Contains the parameters for RunInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstancesRequest type RunInstancesInput struct { _ struct{} `type:"structure"` // Reserved. AdditionalInfo *string `locationName:"additionalInfo" type:"string"` - // The block device mapping. - // - // Supplying both a snapshot ID and an encryption value as arguments for block-device - // mapping results in an error. This is because only blank volumes can be encrypted - // on start, and these are not created from a snapshot. If a snapshot is the - // basis for the volume, it contains data by definition and its encryption status - // cannot be changed using this action. + // One or more block device mapping entries. You can't specify both a snapshot + // ID and an encryption value. This is because only blank volumes can be encrypted + // on creation. If a snapshot is the basis for a volume, it is not blank and + // its encryption status is used for the volume encryption status. BlockDeviceMappings []*BlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` // Unique, case-sensitive identifier you provide to ensure the idempotency of @@ -51981,6 +60725,14 @@ type RunInstancesInput struct { // Constraints: Maximum 64 ASCII characters ClientToken *string `locationName:"clientToken" type:"string"` + // The credit option for CPU usage of the instance. Valid values are standard + // and unlimited. To change this attribute after launch, use ModifyInstanceCreditSpecification. + // For more information, see T2 Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-instances.html) + // in the Amazon Elastic Compute Cloud User Guide. + // + // Default: standard + CreditSpecification *CreditSpecificationRequest `type:"structure"` + // If you set this parameter to true, you can't terminate the instance using // the Amazon EC2 console, CLI, or API; otherwise, you can. To change this attribute // to false after launch, use ModifyInstanceAttribute. Alternatively, if you @@ -51996,25 +60748,23 @@ type RunInstancesInput struct { // it is UnauthorizedOperation. DryRun *bool `locationName:"dryRun" type:"boolean"` - // Indicates whether the instance is optimized for EBS I/O. This optimization + // Indicates whether the instance is optimized for Amazon EBS I/O. This optimization // provides dedicated throughput to Amazon EBS and an optimized configuration - // stack to provide optimal EBS I/O performance. This optimization isn't available - // with all instance types. Additional usage charges apply when using an EBS-optimized - // instance. + // stack to provide optimal Amazon EBS I/O performance. This optimization isn't + // available with all instance types. Additional usage charges apply when using + // an EBS-optimized instance. // // Default: false EbsOptimized *bool `locationName:"ebsOptimized" type:"boolean"` - // An Elastic GPU to associate with the instance. + // An elastic GPU to associate with the instance. ElasticGpuSpecification []*ElasticGpuSpecification `locationNameList:"item" type:"list"` // The IAM instance profile. IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` // The ID of the AMI, which you can get by calling DescribeImages. - // - // ImageId is a required field - ImageId *string `type:"string" required:"true"` + ImageId *string `type:"string"` // Indicates whether an instance stops or terminates when you initiate shutdown // from the instance (using the operating system command for system shutdown). @@ -52022,6 +60772,9 @@ type RunInstancesInput struct { // Default: stop InstanceInitiatedShutdownBehavior *string `locationName:"instanceInitiatedShutdownBehavior" type:"string" enum:"ShutdownBehavior"` + // The market (purchasing) option for the instances. + InstanceMarketOptions *InstanceMarketOptionsRequest `type:"structure"` + // The instance type. For more information, see Instance Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) // in the Amazon Elastic Compute Cloud User Guide. // @@ -52056,6 +60809,10 @@ type RunInstancesInput struct { // you choose an AMI that is configured to allow users another way to log in. KeyName *string `type:"string"` + // The launch template to use to launch the instances. Any parameters that you + // specify in RunInstances override the same parameters in the launch template. + LaunchTemplate *LaunchTemplateSpecification `type:"structure"` + // The maximum number of instances to launch. If you specify more instances // than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches // the largest possible number of instances above MinCount. @@ -52127,9 +60884,9 @@ type RunInstancesInput struct { // The user data to make available to the instance. For more information, see // Running Commands on Your Linux Instance at Launch (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) // (Linux) and Adding User Data (http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-instance-metadata.html#instancedata-add-user-data) - // (Windows). If you are using an AWS SDK or command line tool, Base64-encoding - // is performed for you, and you can load the text from a file. Otherwise, you - // must provide Base64-encoded text. + // (Windows). If you are using a command line tool, base64-encoding is performed + // for you, and you can load the text from a file. Otherwise, you must provide + // base64-encoded text. UserData *string `type:"string"` } @@ -52146,15 +60903,17 @@ func (s RunInstancesInput) GoString() string { // Validate inspects the fields of the type to determine if they are valid. func (s *RunInstancesInput) Validate() error { invalidParams := request.ErrInvalidParams{Context: "RunInstancesInput"} - if s.ImageId == nil { - invalidParams.Add(request.NewErrParamRequired("ImageId")) - } if s.MaxCount == nil { invalidParams.Add(request.NewErrParamRequired("MaxCount")) } if s.MinCount == nil { invalidParams.Add(request.NewErrParamRequired("MinCount")) } + if s.CreditSpecification != nil { + if err := s.CreditSpecification.Validate(); err != nil { + invalidParams.AddNested("CreditSpecification", err.(request.ErrInvalidParams)) + } + } if s.ElasticGpuSpecification != nil { for i, v := range s.ElasticGpuSpecification { if v == nil { @@ -52205,6 +60964,12 @@ func (s *RunInstancesInput) SetClientToken(v string) *RunInstancesInput { return s } +// SetCreditSpecification sets the CreditSpecification field's value. +func (s *RunInstancesInput) SetCreditSpecification(v *CreditSpecificationRequest) *RunInstancesInput { + s.CreditSpecification = v + return s +} + // SetDisableApiTermination sets the DisableApiTermination field's value. func (s *RunInstancesInput) SetDisableApiTermination(v bool) *RunInstancesInput { s.DisableApiTermination = &v @@ -52247,6 +61012,12 @@ func (s *RunInstancesInput) SetInstanceInitiatedShutdownBehavior(v string) *RunI return s } +// SetInstanceMarketOptions sets the InstanceMarketOptions field's value. +func (s *RunInstancesInput) SetInstanceMarketOptions(v *InstanceMarketOptionsRequest) *RunInstancesInput { + s.InstanceMarketOptions = v + return s +} + // SetInstanceType sets the InstanceType field's value. func (s *RunInstancesInput) SetInstanceType(v string) *RunInstancesInput { s.InstanceType = &v @@ -52277,6 +61048,12 @@ func (s *RunInstancesInput) SetKeyName(v string) *RunInstancesInput { return s } +// SetLaunchTemplate sets the LaunchTemplate field's value. +func (s *RunInstancesInput) SetLaunchTemplate(v *LaunchTemplateSpecification) *RunInstancesInput { + s.LaunchTemplate = v + return s +} + // SetMaxCount sets the MaxCount field's value. func (s *RunInstancesInput) SetMaxCount(v int64) *RunInstancesInput { s.MaxCount = &v @@ -52350,7 +61127,7 @@ func (s *RunInstancesInput) SetUserData(v string) *RunInstancesInput { } // Describes the monitoring of an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstancesMonitoringEnabled +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstancesMonitoringEnabled type RunInstancesMonitoringEnabled struct { _ struct{} `type:"structure"` @@ -52391,7 +61168,7 @@ func (s *RunInstancesMonitoringEnabled) SetEnabled(v bool) *RunInstancesMonitori } // Contains the parameters for RunScheduledInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstancesRequest type RunScheduledInstancesInput struct { _ struct{} `type:"structure"` @@ -52484,7 +61261,7 @@ func (s *RunScheduledInstancesInput) SetScheduledInstanceId(v string) *RunSchedu } // Contains the output of RunScheduledInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstancesResult type RunScheduledInstancesOutput struct { _ struct{} `type:"structure"` @@ -52510,7 +61287,7 @@ func (s *RunScheduledInstancesOutput) SetInstanceIdSet(v []*string) *RunSchedule // Describes the storage parameters for S3 and S3 buckets for an instance store-backed // AMI. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/S3Storage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/S3Storage type S3Storage struct { _ struct{} `type:"structure"` @@ -52578,7 +61355,7 @@ func (s *S3Storage) SetUploadPolicySignature(v string) *S3Storage { } // Describes a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstance +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstance type ScheduledInstance struct { _ struct{} `type:"structure"` @@ -52729,7 +61506,7 @@ func (s *ScheduledInstance) SetTotalScheduledInstanceHours(v int64) *ScheduledIn } // Describes a schedule that is available for your Scheduled Instances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceAvailability +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceAvailability type ScheduledInstanceAvailability struct { _ struct{} `type:"structure"` @@ -52863,7 +61640,7 @@ func (s *ScheduledInstanceAvailability) SetTotalScheduledInstanceHours(v int64) } // Describes the recurring schedule for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceRecurrence +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceRecurrence type ScheduledInstanceRecurrence struct { _ struct{} `type:"structure"` @@ -52928,7 +61705,7 @@ func (s *ScheduledInstanceRecurrence) SetOccurrenceUnit(v string) *ScheduledInst } // Describes the recurring schedule for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceRecurrenceRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceRecurrenceRequest type ScheduledInstanceRecurrenceRequest struct { _ struct{} `type:"structure"` @@ -52996,11 +61773,11 @@ func (s *ScheduledInstanceRecurrenceRequest) SetOccurrenceUnit(v string) *Schedu } // Describes a block device mapping for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesBlockDeviceMapping +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesBlockDeviceMapping type ScheduledInstancesBlockDeviceMapping struct { _ struct{} `type:"structure"` - // The device name exposed to the instance (for example, /dev/sdh or xvdh). + // The device name (for example, /dev/sdh or xvdh). DeviceName *string `type:"string"` // Parameters used to set up EBS volumes automatically when the instance is @@ -53013,7 +61790,7 @@ type ScheduledInstancesBlockDeviceMapping struct { // The virtual device name (ephemeralN). Instance store volumes are numbered // starting from 0. An instance type with two available instance store volumes - // can specify mappings for ephemeral0 and ephemeral1.The number of available + // can specify mappings for ephemeral0 and ephemeral1. The number of available // instance store volumes depends on the instance type. After you connect to // the instance, you must mount the volume. // @@ -53059,7 +61836,7 @@ func (s *ScheduledInstancesBlockDeviceMapping) SetVirtualName(v string) *Schedul } // Describes an EBS volume for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesEbs +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesEbs type ScheduledInstancesEbs struct { _ struct{} `type:"structure"` @@ -53148,7 +61925,7 @@ func (s *ScheduledInstancesEbs) SetVolumeType(v string) *ScheduledInstancesEbs { } // Describes an IAM instance profile for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesIamInstanceProfile +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesIamInstanceProfile type ScheduledInstancesIamInstanceProfile struct { _ struct{} `type:"structure"` @@ -53182,7 +61959,7 @@ func (s *ScheduledInstancesIamInstanceProfile) SetName(v string) *ScheduledInsta } // Describes an IPv6 address. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesIpv6Address +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesIpv6Address type ScheduledInstancesIpv6Address struct { _ struct{} `type:"structure"` @@ -53211,7 +61988,7 @@ func (s *ScheduledInstancesIpv6Address) SetIpv6Address(v string) *ScheduledInsta // If you are launching the Scheduled Instance in EC2-VPC, you must specify // the ID of the subnet. You can specify the subnet using either SubnetId or // NetworkInterface. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesLaunchSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesLaunchSpecification type ScheduledInstancesLaunchSpecification struct { _ struct{} `type:"structure"` @@ -53374,7 +62151,7 @@ func (s *ScheduledInstancesLaunchSpecification) SetUserData(v string) *Scheduled } // Describes whether monitoring is enabled for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesMonitoring +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesMonitoring type ScheduledInstancesMonitoring struct { _ struct{} `type:"structure"` @@ -53399,7 +62176,7 @@ func (s *ScheduledInstancesMonitoring) SetEnabled(v bool) *ScheduledInstancesMon } // Describes a network interface for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesNetworkInterface +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesNetworkInterface type ScheduledInstancesNetworkInterface struct { _ struct{} `type:"structure"` @@ -53528,7 +62305,7 @@ func (s *ScheduledInstancesNetworkInterface) SetSubnetId(v string) *ScheduledIns } // Describes the placement for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesPlacement +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesPlacement type ScheduledInstancesPlacement struct { _ struct{} `type:"structure"` @@ -53562,7 +62339,7 @@ func (s *ScheduledInstancesPlacement) SetGroupName(v string) *ScheduledInstances } // Describes a private IPv4 address for a Scheduled Instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesPrivateIpAddressConfig +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesPrivateIpAddressConfig type ScheduledInstancesPrivateIpAddressConfig struct { _ struct{} `type:"structure"` @@ -53597,7 +62374,7 @@ func (s *ScheduledInstancesPrivateIpAddressConfig) SetPrivateIpAddress(v string) } // Describes a security group -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroup type SecurityGroup struct { _ struct{} `type:"structure"` @@ -53684,8 +62461,42 @@ func (s *SecurityGroup) SetVpcId(v string) *SecurityGroup { return s } +// Describes a security group. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroupIdentifier +type SecurityGroupIdentifier struct { + _ struct{} `type:"structure"` + + // The ID of the security group. + GroupId *string `locationName:"groupId" type:"string"` + + // The name of the security group. + GroupName *string `locationName:"groupName" type:"string"` +} + +// String returns the string representation +func (s SecurityGroupIdentifier) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SecurityGroupIdentifier) GoString() string { + return s.String() +} + +// SetGroupId sets the GroupId field's value. +func (s *SecurityGroupIdentifier) SetGroupId(v string) *SecurityGroupIdentifier { + s.GroupId = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *SecurityGroupIdentifier) SetGroupName(v string) *SecurityGroupIdentifier { + s.GroupName = &v + return s +} + // Describes a VPC with a security group that references your security group. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroupReference +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroupReference type SecurityGroupReference struct { _ struct{} `type:"structure"` @@ -53731,9 +62542,221 @@ func (s *SecurityGroupReference) SetVpcPeeringConnectionId(v string) *SecurityGr return s } +// Describes a service configuration for a VPC endpoint service. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ServiceConfiguration +type ServiceConfiguration struct { + _ struct{} `type:"structure"` + + // Indicates whether requests from other AWS accounts to create an endpoint + // to the service must first be accepted. + AcceptanceRequired *bool `locationName:"acceptanceRequired" type:"boolean"` + + // In the Availability Zones in which the service is available. + AvailabilityZones []*string `locationName:"availabilityZoneSet" locationNameList:"item" type:"list"` + + // The DNS names for the service. + BaseEndpointDnsNames []*string `locationName:"baseEndpointDnsNameSet" locationNameList:"item" type:"list"` + + // The Amazon Resource Names (ARNs) of the Network Load Balancers for the service. + NetworkLoadBalancerArns []*string `locationName:"networkLoadBalancerArnSet" locationNameList:"item" type:"list"` + + // The private DNS name for the service. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The ID of the service. + ServiceId *string `locationName:"serviceId" type:"string"` + + // The name of the service. + ServiceName *string `locationName:"serviceName" type:"string"` + + // The service state. + ServiceState *string `locationName:"serviceState" type:"string" enum:"ServiceState"` + + // The type of service. + ServiceType []*ServiceTypeDetail `locationName:"serviceType" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s ServiceConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServiceConfiguration) GoString() string { + return s.String() +} + +// SetAcceptanceRequired sets the AcceptanceRequired field's value. +func (s *ServiceConfiguration) SetAcceptanceRequired(v bool) *ServiceConfiguration { + s.AcceptanceRequired = &v + return s +} + +// SetAvailabilityZones sets the AvailabilityZones field's value. +func (s *ServiceConfiguration) SetAvailabilityZones(v []*string) *ServiceConfiguration { + s.AvailabilityZones = v + return s +} + +// SetBaseEndpointDnsNames sets the BaseEndpointDnsNames field's value. +func (s *ServiceConfiguration) SetBaseEndpointDnsNames(v []*string) *ServiceConfiguration { + s.BaseEndpointDnsNames = v + return s +} + +// SetNetworkLoadBalancerArns sets the NetworkLoadBalancerArns field's value. +func (s *ServiceConfiguration) SetNetworkLoadBalancerArns(v []*string) *ServiceConfiguration { + s.NetworkLoadBalancerArns = v + return s +} + +// SetPrivateDnsName sets the PrivateDnsName field's value. +func (s *ServiceConfiguration) SetPrivateDnsName(v string) *ServiceConfiguration { + s.PrivateDnsName = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *ServiceConfiguration) SetServiceId(v string) *ServiceConfiguration { + s.ServiceId = &v + return s +} + +// SetServiceName sets the ServiceName field's value. +func (s *ServiceConfiguration) SetServiceName(v string) *ServiceConfiguration { + s.ServiceName = &v + return s +} + +// SetServiceState sets the ServiceState field's value. +func (s *ServiceConfiguration) SetServiceState(v string) *ServiceConfiguration { + s.ServiceState = &v + return s +} + +// SetServiceType sets the ServiceType field's value. +func (s *ServiceConfiguration) SetServiceType(v []*ServiceTypeDetail) *ServiceConfiguration { + s.ServiceType = v + return s +} + +// Describes a VPC endpoint service. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ServiceDetail +type ServiceDetail struct { + _ struct{} `type:"structure"` + + // Indicates whether VPC endpoint connection requests to the service must be + // accepted by the service owner. + AcceptanceRequired *bool `locationName:"acceptanceRequired" type:"boolean"` + + // The Availability Zones in which the service is available. + AvailabilityZones []*string `locationName:"availabilityZoneSet" locationNameList:"item" type:"list"` + + // The DNS names for the service. + BaseEndpointDnsNames []*string `locationName:"baseEndpointDnsNameSet" locationNameList:"item" type:"list"` + + // The AWS account ID of the service owner. + Owner *string `locationName:"owner" type:"string"` + + // The private DNS name for the service. + PrivateDnsName *string `locationName:"privateDnsName" type:"string"` + + // The Amazon Resource Name (ARN) of the service. + ServiceName *string `locationName:"serviceName" type:"string"` + + // The type of service. + ServiceType []*ServiceTypeDetail `locationName:"serviceType" locationNameList:"item" type:"list"` + + // Indicates whether the service supports endpoint policies. + VpcEndpointPolicySupported *bool `locationName:"vpcEndpointPolicySupported" type:"boolean"` +} + +// String returns the string representation +func (s ServiceDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServiceDetail) GoString() string { + return s.String() +} + +// SetAcceptanceRequired sets the AcceptanceRequired field's value. +func (s *ServiceDetail) SetAcceptanceRequired(v bool) *ServiceDetail { + s.AcceptanceRequired = &v + return s +} + +// SetAvailabilityZones sets the AvailabilityZones field's value. +func (s *ServiceDetail) SetAvailabilityZones(v []*string) *ServiceDetail { + s.AvailabilityZones = v + return s +} + +// SetBaseEndpointDnsNames sets the BaseEndpointDnsNames field's value. +func (s *ServiceDetail) SetBaseEndpointDnsNames(v []*string) *ServiceDetail { + s.BaseEndpointDnsNames = v + return s +} + +// SetOwner sets the Owner field's value. +func (s *ServiceDetail) SetOwner(v string) *ServiceDetail { + s.Owner = &v + return s +} + +// SetPrivateDnsName sets the PrivateDnsName field's value. +func (s *ServiceDetail) SetPrivateDnsName(v string) *ServiceDetail { + s.PrivateDnsName = &v + return s +} + +// SetServiceName sets the ServiceName field's value. +func (s *ServiceDetail) SetServiceName(v string) *ServiceDetail { + s.ServiceName = &v + return s +} + +// SetServiceType sets the ServiceType field's value. +func (s *ServiceDetail) SetServiceType(v []*ServiceTypeDetail) *ServiceDetail { + s.ServiceType = v + return s +} + +// SetVpcEndpointPolicySupported sets the VpcEndpointPolicySupported field's value. +func (s *ServiceDetail) SetVpcEndpointPolicySupported(v bool) *ServiceDetail { + s.VpcEndpointPolicySupported = &v + return s +} + +// Describes the type of service for a VPC endpoint. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ServiceTypeDetail +type ServiceTypeDetail struct { + _ struct{} `type:"structure"` + + // The type of service. + ServiceType *string `locationName:"serviceType" type:"string" enum:"ServiceType"` +} + +// String returns the string representation +func (s ServiceTypeDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServiceTypeDetail) GoString() string { + return s.String() +} + +// SetServiceType sets the ServiceType field's value. +func (s *ServiceTypeDetail) SetServiceType(v string) *ServiceTypeDetail { + s.ServiceType = &v + return s +} + // Describes the time period for a Scheduled Instance to start its first schedule. // The time period must span less than one day. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SlotDateTimeRangeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SlotDateTimeRangeRequest type SlotDateTimeRangeRequest struct { _ struct{} `type:"structure"` @@ -53789,7 +62812,7 @@ func (s *SlotDateTimeRangeRequest) SetLatestTime(v time.Time) *SlotDateTimeRange } // Describes the time period for a Scheduled Instance to start its first schedule. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SlotStartTimeRangeRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SlotStartTimeRangeRequest type SlotStartTimeRangeRequest struct { _ struct{} `type:"structure"` @@ -53823,7 +62846,7 @@ func (s *SlotStartTimeRangeRequest) SetLatestTime(v time.Time) *SlotStartTimeRan } // Describes a snapshot. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Snapshot +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Snapshot type Snapshot struct { _ struct{} `type:"structure"` @@ -53981,7 +63004,7 @@ func (s *Snapshot) SetVolumeSize(v int64) *Snapshot { } // Describes the snapshot created from the imported disk. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotDetail +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotDetail type SnapshotDetail struct { _ struct{} `type:"structure"` @@ -54087,7 +63110,7 @@ func (s *SnapshotDetail) SetUserBucket(v *UserBucketDetails) *SnapshotDetail { } // The disk container object for the import snapshot request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotDiskContainer +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotDiskContainer type SnapshotDiskContainer struct { _ struct{} `type:"structure"` @@ -54142,7 +63165,7 @@ func (s *SnapshotDiskContainer) SetUserBucket(v *UserBucket) *SnapshotDiskContai } // Details about the import snapshot task. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotTaskDetail +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotTaskDetail type SnapshotTaskDetail struct { _ struct{} `type:"structure"` @@ -54238,15 +63261,15 @@ func (s *SnapshotTaskDetail) SetUserBucket(v *UserBucketDetails) *SnapshotTaskDe return s } -// Describes the data feed for a Spot instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotDatafeedSubscription +// Describes the data feed for a Spot Instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotDatafeedSubscription type SpotDatafeedSubscription struct { _ struct{} `type:"structure"` - // The Amazon S3 bucket where the Spot instance data feed is located. + // The Amazon S3 bucket where the Spot Instance data feed is located. Bucket *string `locationName:"bucket" type:"string"` - // The fault codes for the Spot instance request, if any. + // The fault codes for the Spot Instance request, if any. Fault *SpotInstanceStateFault `locationName:"fault" type:"structure"` // The AWS account ID of the account. @@ -54255,7 +63278,7 @@ type SpotDatafeedSubscription struct { // The prefix that is prepended to data feed files. Prefix *string `locationName:"prefix" type:"string"` - // The state of the Spot instance data feed subscription. + // The state of the Spot Instance data feed subscription. State *string `locationName:"state" type:"string" enum:"DatafeedSubscriptionState"` } @@ -54299,15 +63322,18 @@ func (s *SpotDatafeedSubscription) SetState(v string) *SpotDatafeedSubscription return s } -// Describes the launch specification for one or more Spot instances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetLaunchSpecification +// Describes the launch specification for one or more Spot Instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetLaunchSpecification type SpotFleetLaunchSpecification struct { _ struct{} `type:"structure"` // Deprecated. AddressingType *string `locationName:"addressingType" type:"string"` - // One or more block device mapping entries. + // One or more block device mapping entries. You can't specify both a snapshot + // ID and an encryption value. This is because only blank volumes can be encrypted + // on creation. If a snapshot is the basis for a volume, it is not blank and + // its encryption status is used for the volume encryption status. BlockDeviceMappings []*BlockDeviceMapping `locationName:"blockDeviceMapping" locationNameList:"item" type:"list"` // Indicates whether the instances are optimized for EBS I/O. This optimization @@ -54325,7 +63351,7 @@ type SpotFleetLaunchSpecification struct { // The ID of the AMI. ImageId *string `locationName:"imageId" type:"string"` - // The instance type. Note that T2 and HS1 instance types are not supported. + // The instance type. InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // The ID of the kernel. @@ -54352,10 +63378,10 @@ type SpotFleetLaunchSpecification struct { // you can specify the names or the IDs of the security groups. SecurityGroups []*GroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` - // The bid price per unit hour for the specified instance type. If this value - // is not specified, the default is the Spot bid price specified for the fleet. - // To determine the bid price per unit hour, divide the Spot bid price by the - // value of WeightedCapacity. + // The maximum price per unit hour that you are willing to pay for a Spot Instance. + // If this value is not specified, the default is the Spot price specified for + // the fleet. To determine the Spot price per unit hour, divide the Spot price + // by the value of WeightedCapacity. SpotPrice *string `locationName:"spotPrice" type:"string"` // The ID of the subnet in which to launch the instances. To specify multiple @@ -54519,7 +63545,7 @@ func (s *SpotFleetLaunchSpecification) SetWeightedCapacity(v float64) *SpotFleet } // Describes whether monitoring is enabled. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetMonitoring +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetMonitoring type SpotFleetMonitoring struct { _ struct{} `type:"structure"` @@ -54545,16 +63571,16 @@ func (s *SpotFleetMonitoring) SetEnabled(v bool) *SpotFleetMonitoring { return s } -// Describes a Spot fleet request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetRequestConfig +// Describes a Spot Fleet request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetRequestConfig type SpotFleetRequestConfig struct { _ struct{} `type:"structure"` - // The progress of the Spot fleet request. If there is an error, the status - // is error. After all bids are placed, the status is pending_fulfillment. If - // the size of the fleet is equal to or greater than its target capacity, the - // status is fulfilled. If the size of the fleet is decreased, the status is - // pending_termination while Spot instances are terminating. + // The progress of the Spot Fleet request. If there is an error, the status + // is error. After all requests are placed, the status is pending_fulfillment. + // If the size of the fleet is equal to or greater than its target capacity, + // the status is fulfilled. If the size of the fleet is decreased, the status + // is pending_termination while Spot Instances are terminating. ActivityStatus *string `locationName:"activityStatus" type:"string" enum:"ActivityStatus"` // The creation date and time of the request. @@ -54562,17 +63588,17 @@ type SpotFleetRequestConfig struct { // CreateTime is a required field CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601" required:"true"` - // Information about the configuration of the Spot fleet request. + // The configuration of the Spot Fleet request. // // SpotFleetRequestConfig is a required field SpotFleetRequestConfig *SpotFleetRequestConfigData `locationName:"spotFleetRequestConfig" type:"structure" required:"true"` - // The ID of the Spot fleet request. + // The ID of the Spot Fleet request. // // SpotFleetRequestId is a required field SpotFleetRequestId *string `locationName:"spotFleetRequestId" type:"string" required:"true"` - // The state of the Spot fleet request. + // The state of the Spot Fleet request. // // SpotFleetRequestState is a required field SpotFleetRequestState *string `locationName:"spotFleetRequestState" type:"string" required:"true" enum:"BatchState"` @@ -54618,13 +63644,13 @@ func (s *SpotFleetRequestConfig) SetSpotFleetRequestState(v string) *SpotFleetRe return s } -// Describes the configuration of a Spot fleet request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetRequestConfigData +// Describes the configuration of a Spot Fleet request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetRequestConfigData type SpotFleetRequestConfigData struct { _ struct{} `type:"structure"` // Indicates how to allocate the target capacity across the Spot pools specified - // by the Spot fleet request. The default is lowestPrice. + // by the Spot Fleet request. The default is lowestPrice. AllocationStrategy *string `locationName:"allocationStrategy" type:"string" enum:"AllocationStrategy"` // A unique, case-sensitive identifier you provide to ensure idempotency of @@ -54632,54 +63658,68 @@ type SpotFleetRequestConfigData struct { // see Ensuring Idempotency (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). ClientToken *string `locationName:"clientToken" type:"string"` - // Indicates whether running Spot instances should be terminated if the target - // capacity of the Spot fleet request is decreased below the current size of - // the Spot fleet. + // Indicates whether running Spot Instances should be terminated if the target + // capacity of the Spot Fleet request is decreased below the current size of + // the Spot Fleet. ExcessCapacityTerminationPolicy *string `locationName:"excessCapacityTerminationPolicy" type:"string" enum:"ExcessCapacityTerminationPolicy"` // The number of units fulfilled by this request compared to the set target // capacity. FulfilledCapacity *float64 `locationName:"fulfilledCapacity" type:"double"` - // Grants the Spot fleet permission to terminate Spot instances on your behalf - // when you cancel its Spot fleet request using CancelSpotFleetRequests or when - // the Spot fleet request expires, if you set terminateInstancesWithExpiration. + // Grants the Spot Fleet permission to terminate Spot Instances on your behalf + // when you cancel its Spot Fleet request using CancelSpotFleetRequests or when + // the Spot Fleet request expires, if you set terminateInstancesWithExpiration. // // IamFleetRole is a required field IamFleetRole *string `locationName:"iamFleetRole" type:"string" required:"true"` - // Information about the launch specifications for the Spot fleet request. - // - // LaunchSpecifications is a required field - LaunchSpecifications []*SpotFleetLaunchSpecification `locationName:"launchSpecifications" locationNameList:"item" min:"1" type:"list" required:"true"` + // The behavior when a Spot Instance is interrupted. The default is terminate. + InstanceInterruptionBehavior *string `locationName:"instanceInterruptionBehavior" type:"string" enum:"InstanceInterruptionBehavior"` - // Indicates whether Spot fleet should replace unhealthy instances. + // The launch specifications for the Spot Fleet request. + LaunchSpecifications []*SpotFleetLaunchSpecification `locationName:"launchSpecifications" locationNameList:"item" type:"list"` + + // The launch template and overrides. + LaunchTemplateConfigs []*LaunchTemplateConfig `locationName:"launchTemplateConfigs" locationNameList:"item" type:"list"` + + // One or more Classic Load Balancers and target groups to attach to the Spot + // Fleet request. Spot Fleet registers the running Spot Instances with the specified + // Classic Load Balancers and target groups. + // + // With Network Load Balancers, Spot Fleet cannot register instances that have + // the following instance types: C1, CC1, CC2, CG1, CG2, CR1, CS1, G1, G2, HI1, + // HS1, M1, M2, M3, and T1. + LoadBalancersConfig *LoadBalancersConfig `locationName:"loadBalancersConfig" type:"structure"` + + // Indicates whether Spot Fleet should replace unhealthy instances. ReplaceUnhealthyInstances *bool `locationName:"replaceUnhealthyInstances" type:"boolean"` - // The bid price per unit hour. - // - // SpotPrice is a required field - SpotPrice *string `locationName:"spotPrice" type:"string" required:"true"` + // The maximum price per unit hour that you are willing to pay for a Spot Instance. + // The default is the On-Demand price. + SpotPrice *string `locationName:"spotPrice" type:"string"` // The number of units to request. You can choose to set the target capacity // in terms of instances or a performance characteristic that is important to - // your application workload, such as vCPUs, memory, or I/O. + // your application workload, such as vCPUs, memory, or I/O. If the request + // type is maintain, you can specify a target capacity of 0 and add capacity + // later. // // TargetCapacity is a required field TargetCapacity *int64 `locationName:"targetCapacity" type:"integer" required:"true"` - // Indicates whether running Spot instances should be terminated when the Spot - // fleet request expires. + // Indicates whether running Spot Instances should be terminated when the Spot + // Fleet request expires. TerminateInstancesWithExpiration *bool `locationName:"terminateInstancesWithExpiration" type:"boolean"` // The type of request. Indicates whether the fleet will only request the target // capacity or also attempt to maintain it. When you request a certain target - // capacity, the fleet will only place the required bids. It will not attempt - // to replenish Spot instances if capacity is diminished, nor will it submit - // bids in alternative Spot pools if capacity is not available. When you want - // to maintain a certain target capacity, fleet will place the required bids - // to meet this target capacity. It will also automatically replenish any interrupted - // instances. Default: maintain. + // capacity, the fleet will only place the required requests. It will not attempt + // to replenish Spot Instances if capacity is diminished, nor will it submit + // requests in alternative Spot pools if capacity is not available. When you + // want to maintain a certain target capacity, fleet will place the required + // requests to meet this target capacity. It will also automatically replenish + // any interrupted instances. Default: maintain. Type *string `locationName:"type" type:"string" enum:"FleetType"` // The start date and time of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). @@ -54687,8 +63727,8 @@ type SpotFleetRequestConfigData struct { ValidFrom *time.Time `locationName:"validFrom" type:"timestamp" timestampFormat:"iso8601"` // The end date and time of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). - // At this point, no new Spot instance requests are placed or enabled to fulfill - // the request. + // At this point, no new Spot Instance requests are placed or able to fulfill + // the request. The default end date is 7 days from the current date. ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` } @@ -54708,15 +63748,6 @@ func (s *SpotFleetRequestConfigData) Validate() error { if s.IamFleetRole == nil { invalidParams.Add(request.NewErrParamRequired("IamFleetRole")) } - if s.LaunchSpecifications == nil { - invalidParams.Add(request.NewErrParamRequired("LaunchSpecifications")) - } - if s.LaunchSpecifications != nil && len(s.LaunchSpecifications) < 1 { - invalidParams.Add(request.NewErrParamMinLen("LaunchSpecifications", 1)) - } - if s.SpotPrice == nil { - invalidParams.Add(request.NewErrParamRequired("SpotPrice")) - } if s.TargetCapacity == nil { invalidParams.Add(request.NewErrParamRequired("TargetCapacity")) } @@ -54730,6 +63761,21 @@ func (s *SpotFleetRequestConfigData) Validate() error { } } } + if s.LaunchTemplateConfigs != nil { + for i, v := range s.LaunchTemplateConfigs { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LaunchTemplateConfigs", i), err.(request.ErrInvalidParams)) + } + } + } + if s.LoadBalancersConfig != nil { + if err := s.LoadBalancersConfig.Validate(); err != nil { + invalidParams.AddNested("LoadBalancersConfig", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -54767,12 +63813,30 @@ func (s *SpotFleetRequestConfigData) SetIamFleetRole(v string) *SpotFleetRequest return s } +// SetInstanceInterruptionBehavior sets the InstanceInterruptionBehavior field's value. +func (s *SpotFleetRequestConfigData) SetInstanceInterruptionBehavior(v string) *SpotFleetRequestConfigData { + s.InstanceInterruptionBehavior = &v + return s +} + // SetLaunchSpecifications sets the LaunchSpecifications field's value. func (s *SpotFleetRequestConfigData) SetLaunchSpecifications(v []*SpotFleetLaunchSpecification) *SpotFleetRequestConfigData { s.LaunchSpecifications = v return s } +// SetLaunchTemplateConfigs sets the LaunchTemplateConfigs field's value. +func (s *SpotFleetRequestConfigData) SetLaunchTemplateConfigs(v []*LaunchTemplateConfig) *SpotFleetRequestConfigData { + s.LaunchTemplateConfigs = v + return s +} + +// SetLoadBalancersConfig sets the LoadBalancersConfig field's value. +func (s *SpotFleetRequestConfigData) SetLoadBalancersConfig(v *LoadBalancersConfig) *SpotFleetRequestConfigData { + s.LoadBalancersConfig = v + return s +} + // SetReplaceUnhealthyInstances sets the ReplaceUnhealthyInstances field's value. func (s *SpotFleetRequestConfigData) SetReplaceUnhealthyInstances(v bool) *SpotFleetRequestConfigData { s.ReplaceUnhealthyInstances = &v @@ -54815,8 +63879,8 @@ func (s *SpotFleetRequestConfigData) SetValidUntil(v time.Time) *SpotFleetReques return s } -// The tags for a Spot fleet resource. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetTagSpecification +// The tags for a Spot Fleet resource. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetTagSpecification type SpotFleetTagSpecification struct { _ struct{} `type:"structure"` @@ -54850,67 +63914,69 @@ func (s *SpotFleetTagSpecification) SetTags(v []*Tag) *SpotFleetTagSpecification return s } -// Describes a Spot instance request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceRequest +// Describes a Spot Instance request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceRequest type SpotInstanceRequest struct { _ struct{} `type:"structure"` - // If you specified a duration and your Spot instance request was fulfilled, - // this is the fixed hourly price in effect for the Spot instance while it runs. + // If you specified a duration and your Spot Instance request was fulfilled, + // this is the fixed hourly price in effect for the Spot Instance while it runs. ActualBlockHourlyPrice *string `locationName:"actualBlockHourlyPrice" type:"string"` // The Availability Zone group. If you specify the same Availability Zone group - // for all Spot instance requests, all Spot instances are launched in the same + // for all Spot Instance requests, all Spot Instances are launched in the same // Availability Zone. AvailabilityZoneGroup *string `locationName:"availabilityZoneGroup" type:"string"` - // The duration for the Spot instance, in minutes. + // The duration for the Spot Instance, in minutes. BlockDurationMinutes *int64 `locationName:"blockDurationMinutes" type:"integer"` - // The date and time when the Spot instance request was created, in UTC format + // The date and time when the Spot Instance request was created, in UTC format // (for example, YYYY-MM-DDTHH:MM:SSZ). CreateTime *time.Time `locationName:"createTime" type:"timestamp" timestampFormat:"iso8601"` - // The fault codes for the Spot instance request, if any. + // The fault codes for the Spot Instance request, if any. Fault *SpotInstanceStateFault `locationName:"fault" type:"structure"` - // The instance ID, if an instance has been launched to fulfill the Spot instance + // The instance ID, if an instance has been launched to fulfill the Spot Instance // request. InstanceId *string `locationName:"instanceId" type:"string"` - // The instance launch group. Launch groups are Spot instances that launch together + // The behavior when a Spot Instance is interrupted. + InstanceInterruptionBehavior *string `locationName:"instanceInterruptionBehavior" type:"string" enum:"InstanceInterruptionBehavior"` + + // The instance launch group. Launch groups are Spot Instances that launch together // and terminate together. LaunchGroup *string `locationName:"launchGroup" type:"string"` // Additional information for launching instances. LaunchSpecification *LaunchSpecification `locationName:"launchSpecification" type:"structure"` - // The Availability Zone in which the bid is launched. + // The Availability Zone in which the request is launched. LaunchedAvailabilityZone *string `locationName:"launchedAvailabilityZone" type:"string"` - // The product description associated with the Spot instance. + // The product description associated with the Spot Instance. ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` - // The ID of the Spot instance request. + // The ID of the Spot Instance request. SpotInstanceRequestId *string `locationName:"spotInstanceRequestId" type:"string"` - // The maximum hourly price (bid) for the Spot instance launched to fulfill - // the request. + // The maximum price per hour that you are willing to pay for a Spot Instance. SpotPrice *string `locationName:"spotPrice" type:"string"` - // The state of the Spot instance request. Spot bid status information can help - // you track your Spot instance requests. For more information, see Spot Bid - // Status (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) + // The state of the Spot Instance request. Spot status information can help + // you track your Spot Instance requests. For more information, see Spot Status + // (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html) // in the Amazon Elastic Compute Cloud User Guide. State *string `locationName:"state" type:"string" enum:"SpotInstanceState"` - // The status code and status message describing the Spot instance request. + // The status code and status message describing the Spot Instance request. Status *SpotInstanceStatus `locationName:"status" type:"structure"` // Any tags assigned to the resource. Tags []*Tag `locationName:"tagSet" locationNameList:"item" type:"list"` - // The Spot instance request type. + // The Spot Instance request type. Type *string `locationName:"type" type:"string" enum:"SpotInstanceType"` // The start date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). @@ -54920,7 +63986,8 @@ type SpotInstanceRequest struct { // The end date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). // If this is a one-time request, it remains active until all instances launch, // the request is canceled, or this date is reached. If the request is persistent, - // it remains active until it is canceled or this date is reached. + // it remains active until it is canceled or this date is reached. The default + // end date is 7 days from the current date. ValidUntil *time.Time `locationName:"validUntil" type:"timestamp" timestampFormat:"iso8601"` } @@ -54970,6 +64037,12 @@ func (s *SpotInstanceRequest) SetInstanceId(v string) *SpotInstanceRequest { return s } +// SetInstanceInterruptionBehavior sets the InstanceInterruptionBehavior field's value. +func (s *SpotInstanceRequest) SetInstanceInterruptionBehavior(v string) *SpotInstanceRequest { + s.InstanceInterruptionBehavior = &v + return s +} + // SetLaunchGroup sets the LaunchGroup field's value. func (s *SpotInstanceRequest) SetLaunchGroup(v string) *SpotInstanceRequest { s.LaunchGroup = &v @@ -55042,15 +64115,15 @@ func (s *SpotInstanceRequest) SetValidUntil(v time.Time) *SpotInstanceRequest { return s } -// Describes a Spot instance state change. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceStateFault +// Describes a Spot Instance state change. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceStateFault type SpotInstanceStateFault struct { _ struct{} `type:"structure"` - // The reason code for the Spot instance state change. + // The reason code for the Spot Instance state change. Code *string `locationName:"code" type:"string"` - // The message for the Spot instance state change. + // The message for the Spot Instance state change. Message *string `locationName:"message" type:"string"` } @@ -55076,12 +64149,12 @@ func (s *SpotInstanceStateFault) SetMessage(v string) *SpotInstanceStateFault { return s } -// Describes the status of a Spot instance request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceStatus +// Describes the status of a Spot Instance request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceStatus type SpotInstanceStatus struct { _ struct{} `type:"structure"` - // The status code. For a list of status codes, see Spot Bid Status Codes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html#spot-instance-bid-status-understand) + // The status code. For a list of status codes, see Spot Status Codes (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html#spot-instance-bid-status-understand) // in the Amazon Elastic Compute Cloud User Guide. Code *string `locationName:"code" type:"string"` @@ -55121,23 +64194,91 @@ func (s *SpotInstanceStatus) SetUpdateTime(v time.Time) *SpotInstanceStatus { return s } -// Describes Spot instance placement. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotPlacement +// The options for Spot Instances. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotMarketOptions +type SpotMarketOptions struct { + _ struct{} `type:"structure"` + + // The required duration for the Spot Instances (also known as Spot blocks), + // in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, + // or 360). + BlockDurationMinutes *int64 `type:"integer"` + + // The behavior when a Spot Instance is interrupted. The default is terminate. + InstanceInterruptionBehavior *string `type:"string" enum:"InstanceInterruptionBehavior"` + + // The maximum hourly price you're willing to pay for the Spot Instances. The + // default is the On-Demand price. + MaxPrice *string `type:"string"` + + // The Spot Instance request type. + SpotInstanceType *string `type:"string" enum:"SpotInstanceType"` + + // The end date of the request. For a one-time request, the request remains + // active until all instances launch, the request is canceled, or this date + // is reached. If the request is persistent, it remains active until it is canceled + // or this date and time is reached. The default end date is 7 days from the + // current date. + ValidUntil *time.Time `type:"timestamp" timestampFormat:"iso8601"` +} + +// String returns the string representation +func (s SpotMarketOptions) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SpotMarketOptions) GoString() string { + return s.String() +} + +// SetBlockDurationMinutes sets the BlockDurationMinutes field's value. +func (s *SpotMarketOptions) SetBlockDurationMinutes(v int64) *SpotMarketOptions { + s.BlockDurationMinutes = &v + return s +} + +// SetInstanceInterruptionBehavior sets the InstanceInterruptionBehavior field's value. +func (s *SpotMarketOptions) SetInstanceInterruptionBehavior(v string) *SpotMarketOptions { + s.InstanceInterruptionBehavior = &v + return s +} + +// SetMaxPrice sets the MaxPrice field's value. +func (s *SpotMarketOptions) SetMaxPrice(v string) *SpotMarketOptions { + s.MaxPrice = &v + return s +} + +// SetSpotInstanceType sets the SpotInstanceType field's value. +func (s *SpotMarketOptions) SetSpotInstanceType(v string) *SpotMarketOptions { + s.SpotInstanceType = &v + return s +} + +// SetValidUntil sets the ValidUntil field's value. +func (s *SpotMarketOptions) SetValidUntil(v time.Time) *SpotMarketOptions { + s.ValidUntil = &v + return s +} + +// Describes Spot Instance placement. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotPlacement type SpotPlacement struct { _ struct{} `type:"structure"` // The Availability Zone. // - // [Spot fleet only] To specify multiple Availability Zones, separate them using + // [Spot Fleet only] To specify multiple Availability Zones, separate them using // commas; for example, "us-west-2a, us-west-2b". AvailabilityZone *string `locationName:"availabilityZone" type:"string"` - // The name of the placement group (for cluster instances). + // The name of the placement group. GroupName *string `locationName:"groupName" type:"string"` // The tenancy of the instance (if the instance is running in a VPC). An instance // with a tenancy of dedicated runs on single-tenant hardware. The host tenancy - // is not supported for Spot instances. + // is not supported for Spot Instances. Tenancy *string `locationName:"tenancy" type:"string" enum:"Tenancy"` } @@ -55169,22 +64310,22 @@ func (s *SpotPlacement) SetTenancy(v string) *SpotPlacement { return s } -// Describes the maximum hourly price (bid) for any Spot instance launched to -// fulfill the request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotPrice +// Describes the maximum price per hour that you are willing to pay for a Spot +// Instance. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotPrice type SpotPrice struct { _ struct{} `type:"structure"` // The Availability Zone. AvailabilityZone *string `locationName:"availabilityZone" type:"string"` - // The instance type. Note that T2 and HS1 instance types are not supported. + // The instance type. InstanceType *string `locationName:"instanceType" type:"string" enum:"InstanceType"` // A general description of the AMI. ProductDescription *string `locationName:"productDescription" type:"string" enum:"RIProductDescription"` - // The maximum price (bid) that you are willing to pay for a Spot instance. + // The maximum price per hour that you are willing to pay for a Spot Instance. SpotPrice *string `locationName:"spotPrice" type:"string"` // The date and time the request was created, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). @@ -55232,7 +64373,7 @@ func (s *SpotPrice) SetTimestamp(v time.Time) *SpotPrice { } // Describes a stale rule in a security group. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StaleIpPermission +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StaleIpPermission type StaleIpPermission struct { _ struct{} `type:"structure"` @@ -55307,7 +64448,7 @@ func (s *StaleIpPermission) SetUserIdGroupPairs(v []*UserIdGroupPair) *StaleIpPe } // Describes a stale security group (a security group that contains stale rules). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StaleSecurityGroup +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StaleSecurityGroup type StaleSecurityGroup struct { _ struct{} `type:"structure"` @@ -55379,7 +64520,7 @@ func (s *StaleSecurityGroup) SetVpcId(v string) *StaleSecurityGroup { } // Contains the parameters for StartInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstancesRequest type StartInstancesInput struct { _ struct{} `type:"structure"` @@ -55440,7 +64581,7 @@ func (s *StartInstancesInput) SetInstanceIds(v []*string) *StartInstancesInput { } // Contains the output of StartInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstancesResult type StartInstancesOutput struct { _ struct{} `type:"structure"` @@ -55465,7 +64606,7 @@ func (s *StartInstancesOutput) SetStartingInstances(v []*InstanceStateChange) *S } // Describes a state change. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StateReason +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StateReason type StateReason struct { _ struct{} `type:"structure"` @@ -55482,8 +64623,8 @@ type StateReason struct { // // * Server.ScheduledStop: The instance was stopped due to a scheduled retirement. // - // * Server.SpotInstanceTermination: A Spot instance was terminated due to - // an increase in the market price. + // * Server.SpotInstanceTermination: A Spot Instance was terminated due to + // an increase in the Spot price. // // * Client.InternalError: A client error caused the instance to terminate // on launch. @@ -55491,6 +64632,9 @@ type StateReason struct { // * Client.InstanceInitiatedShutdown: The instance was shut down using the // shutdown -h command from the instance. // + // * Client.InstanceTerminated: The instance was terminated or rebooted during + // AMI creation. + // // * Client.UserInitiatedShutdown: The instance was shut down using the Amazon // EC2 API. // @@ -55525,7 +64669,7 @@ func (s *StateReason) SetMessage(v string) *StateReason { } // Contains the parameters for StopInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstancesRequest type StopInstancesInput struct { _ struct{} `type:"structure"` @@ -55591,7 +64735,7 @@ func (s *StopInstancesInput) SetInstanceIds(v []*string) *StopInstancesInput { } // Contains the output of StopInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstancesResult type StopInstancesOutput struct { _ struct{} `type:"structure"` @@ -55616,7 +64760,7 @@ func (s *StopInstancesOutput) SetStoppingInstances(v []*InstanceStateChange) *St } // Describes the storage location for an instance store-backed AMI. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Storage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Storage type Storage struct { _ struct{} `type:"structure"` @@ -55641,7 +64785,7 @@ func (s *Storage) SetS3(v *S3Storage) *Storage { } // Describes a storage location in Amazon S3. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StorageLocation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StorageLocation type StorageLocation struct { _ struct{} `type:"structure"` @@ -55675,7 +64819,7 @@ func (s *StorageLocation) SetKey(v string) *StorageLocation { } // Describes a subnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Subnet +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Subnet type Subnet struct { _ struct{} `type:"structure"` @@ -55793,7 +64937,7 @@ func (s *Subnet) SetVpcId(v string) *Subnet { } // Describes the state of a CIDR block. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SubnetCidrBlockState +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SubnetCidrBlockState type SubnetCidrBlockState struct { _ struct{} `type:"structure"` @@ -55827,7 +64971,7 @@ func (s *SubnetCidrBlockState) SetStatusMessage(v string) *SubnetCidrBlockState } // Describes an IPv6 CIDR block associated with a subnet. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SubnetIpv6CidrBlockAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SubnetIpv6CidrBlockAssociation type SubnetIpv6CidrBlockAssociation struct { _ struct{} `type:"structure"` @@ -55869,8 +65013,34 @@ func (s *SubnetIpv6CidrBlockAssociation) SetIpv6CidrBlockState(v *SubnetCidrBloc return s } +// Describes the T2 instance whose credit option for CPU usage was successfully +// modified. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SuccessfulInstanceCreditSpecificationItem +type SuccessfulInstanceCreditSpecificationItem struct { + _ struct{} `type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` +} + +// String returns the string representation +func (s SuccessfulInstanceCreditSpecificationItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SuccessfulInstanceCreditSpecificationItem) GoString() string { + return s.String() +} + +// SetInstanceId sets the InstanceId field's value. +func (s *SuccessfulInstanceCreditSpecificationItem) SetInstanceId(v string) *SuccessfulInstanceCreditSpecificationItem { + s.InstanceId = &v + return s +} + // Describes a tag. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Tag +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Tag type Tag struct { _ struct{} `type:"structure"` @@ -55910,7 +65080,7 @@ func (s *Tag) SetValue(v string) *Tag { } // Describes a tag. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TagDescription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TagDescription type TagDescription struct { _ struct{} `type:"structure"` @@ -55962,7 +65132,7 @@ func (s *TagDescription) SetValue(v string) *TagDescription { } // The tags to apply to a resource when the resource is being created. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TagSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TagSpecification type TagSpecification struct { _ struct{} `type:"structure"` @@ -55997,7 +65167,7 @@ func (s *TagSpecification) SetTags(v []*Tag) *TagSpecification { } // Information about the Convertible Reserved Instance offering. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetConfiguration type TargetConfiguration struct { _ struct{} `type:"structure"` @@ -56032,7 +65202,7 @@ func (s *TargetConfiguration) SetOfferingId(v string) *TargetConfiguration { } // Details about the target configuration. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetConfigurationRequest type TargetConfigurationRequest struct { _ struct{} `type:"structure"` @@ -56081,8 +65251,102 @@ func (s *TargetConfigurationRequest) SetOfferingId(v string) *TargetConfiguratio return s } +// Describes a load balancer target group. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetGroup +type TargetGroup struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the target group. + // + // Arn is a required field + Arn *string `locationName:"arn" type:"string" required:"true"` +} + +// String returns the string representation +func (s TargetGroup) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TargetGroup) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TargetGroup) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TargetGroup"} + if s.Arn == nil { + invalidParams.Add(request.NewErrParamRequired("Arn")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetArn sets the Arn field's value. +func (s *TargetGroup) SetArn(v string) *TargetGroup { + s.Arn = &v + return s +} + +// Describes the target groups to attach to a Spot Fleet. Spot Fleet registers +// the running Spot Instances with these target groups. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetGroupsConfig +type TargetGroupsConfig struct { + _ struct{} `type:"structure"` + + // One or more target groups. + // + // TargetGroups is a required field + TargetGroups []*TargetGroup `locationName:"targetGroups" locationNameList:"item" min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s TargetGroupsConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TargetGroupsConfig) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TargetGroupsConfig) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TargetGroupsConfig"} + if s.TargetGroups == nil { + invalidParams.Add(request.NewErrParamRequired("TargetGroups")) + } + if s.TargetGroups != nil && len(s.TargetGroups) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TargetGroups", 1)) + } + if s.TargetGroups != nil { + for i, v := range s.TargetGroups { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TargetGroups", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTargetGroups sets the TargetGroups field's value. +func (s *TargetGroupsConfig) SetTargetGroups(v []*TargetGroup) *TargetGroupsConfig { + s.TargetGroups = v + return s +} + // The total value of the new Convertible Reserved Instances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetReservationValue +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetReservationValue type TargetReservationValue struct { _ struct{} `type:"structure"` @@ -56119,7 +65383,7 @@ func (s *TargetReservationValue) SetTargetConfiguration(v *TargetConfiguration) } // Contains the parameters for TerminateInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstancesRequest type TerminateInstancesInput struct { _ struct{} `type:"structure"` @@ -56174,7 +65438,7 @@ func (s *TerminateInstancesInput) SetInstanceIds(v []*string) *TerminateInstance } // Contains the output of TerminateInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstancesResult type TerminateInstancesOutput struct { _ struct{} `type:"structure"` @@ -56198,7 +65462,7 @@ func (s *TerminateInstancesOutput) SetTerminatingInstances(v []*InstanceStateCha return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6AddressesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6AddressesRequest type UnassignIpv6AddressesInput struct { _ struct{} `type:"structure"` @@ -56251,7 +65515,7 @@ func (s *UnassignIpv6AddressesInput) SetNetworkInterfaceId(v string) *UnassignIp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6AddressesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6AddressesResult type UnassignIpv6AddressesOutput struct { _ struct{} `type:"structure"` @@ -56285,7 +65549,7 @@ func (s *UnassignIpv6AddressesOutput) SetUnassignedIpv6Addresses(v []*string) *U } // Contains the parameters for UnassignPrivateIpAddresses. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddressesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddressesRequest type UnassignPrivateIpAddressesInput struct { _ struct{} `type:"structure"` @@ -56339,7 +65603,7 @@ func (s *UnassignPrivateIpAddressesInput) SetPrivateIpAddresses(v []*string) *Un return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddressesOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddressesOutput type UnassignPrivateIpAddressesOutput struct { _ struct{} `type:"structure"` } @@ -56355,7 +65619,7 @@ func (s UnassignPrivateIpAddressesOutput) GoString() string { } // Contains the parameters for UnmonitorInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstancesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstancesRequest type UnmonitorInstancesInput struct { _ struct{} `type:"structure"` @@ -56407,7 +65671,7 @@ func (s *UnmonitorInstancesInput) SetInstanceIds(v []*string) *UnmonitorInstance } // Contains the output of UnmonitorInstances. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstancesResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstancesResult type UnmonitorInstancesOutput struct { _ struct{} `type:"structure"` @@ -56431,8 +65695,78 @@ func (s *UnmonitorInstancesOutput) SetInstanceMonitorings(v []*InstanceMonitorin return s } +// Describes the T2 instance whose credit option for CPU usage was not modified. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulInstanceCreditSpecificationItem +type UnsuccessfulInstanceCreditSpecificationItem struct { + _ struct{} `type:"structure"` + + // The applicable error for the T2 instance whose credit option for CPU usage + // was not modified. + Error *UnsuccessfulInstanceCreditSpecificationItemError `locationName:"error" type:"structure"` + + // The ID of the instance. + InstanceId *string `locationName:"instanceId" type:"string"` +} + +// String returns the string representation +func (s UnsuccessfulInstanceCreditSpecificationItem) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnsuccessfulInstanceCreditSpecificationItem) GoString() string { + return s.String() +} + +// SetError sets the Error field's value. +func (s *UnsuccessfulInstanceCreditSpecificationItem) SetError(v *UnsuccessfulInstanceCreditSpecificationItemError) *UnsuccessfulInstanceCreditSpecificationItem { + s.Error = v + return s +} + +// SetInstanceId sets the InstanceId field's value. +func (s *UnsuccessfulInstanceCreditSpecificationItem) SetInstanceId(v string) *UnsuccessfulInstanceCreditSpecificationItem { + s.InstanceId = &v + return s +} + +// Information about the error for the T2 instance whose credit option for CPU +// usage was not modified. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulInstanceCreditSpecificationItemError +type UnsuccessfulInstanceCreditSpecificationItemError struct { + _ struct{} `type:"structure"` + + // The error code. + Code *string `locationName:"code" type:"string" enum:"UnsuccessfulInstanceCreditSpecificationErrorCode"` + + // The applicable error message. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s UnsuccessfulInstanceCreditSpecificationItemError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnsuccessfulInstanceCreditSpecificationItemError) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *UnsuccessfulInstanceCreditSpecificationItemError) SetCode(v string) *UnsuccessfulInstanceCreditSpecificationItemError { + s.Code = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *UnsuccessfulInstanceCreditSpecificationItemError) SetMessage(v string) *UnsuccessfulInstanceCreditSpecificationItemError { + s.Message = &v + return s +} + // Information about items that were not successfully processed in a batch call. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulItem +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulItem type UnsuccessfulItem struct { _ struct{} `type:"structure"` @@ -56469,7 +65803,7 @@ func (s *UnsuccessfulItem) SetResourceId(v string) *UnsuccessfulItem { // Information about the error that occurred. For more information about errors, // see Error Codes (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html). -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulItemError +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulItemError type UnsuccessfulItemError struct { _ struct{} `type:"structure"` @@ -56506,8 +65840,204 @@ func (s *UnsuccessfulItemError) SetMessage(v string) *UnsuccessfulItemError { return s } +// Contains the parameters for UpdateSecurityGroupRuleDescriptionsEgress. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsEgressRequest +type UpdateSecurityGroupRuleDescriptionsEgressInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the security group. You must specify either the security group + // ID or the security group name in the request. For security groups in a nondefault + // VPC, you must specify the security group ID. + GroupId *string `type:"string"` + + // [Default VPC] The name of the security group. You must specify either the + // security group ID or the security group name in the request. + GroupName *string `type:"string"` + + // The IP permissions for the security group rule. + // + // IpPermissions is a required field + IpPermissions []*IpPermission `locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsEgressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsEgressInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateSecurityGroupRuleDescriptionsEgressInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateSecurityGroupRuleDescriptionsEgressInput"} + if s.IpPermissions == nil { + invalidParams.Add(request.NewErrParamRequired("IpPermissions")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *UpdateSecurityGroupRuleDescriptionsEgressInput) SetDryRun(v bool) *UpdateSecurityGroupRuleDescriptionsEgressInput { + s.DryRun = &v + return s +} + +// SetGroupId sets the GroupId field's value. +func (s *UpdateSecurityGroupRuleDescriptionsEgressInput) SetGroupId(v string) *UpdateSecurityGroupRuleDescriptionsEgressInput { + s.GroupId = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *UpdateSecurityGroupRuleDescriptionsEgressInput) SetGroupName(v string) *UpdateSecurityGroupRuleDescriptionsEgressInput { + s.GroupName = &v + return s +} + +// SetIpPermissions sets the IpPermissions field's value. +func (s *UpdateSecurityGroupRuleDescriptionsEgressInput) SetIpPermissions(v []*IpPermission) *UpdateSecurityGroupRuleDescriptionsEgressInput { + s.IpPermissions = v + return s +} + +// Contains the output of UpdateSecurityGroupRuleDescriptionsEgress. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsEgressResult +type UpdateSecurityGroupRuleDescriptionsEgressOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsEgressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsEgressOutput) GoString() string { + return s.String() +} + +// SetReturn sets the Return field's value. +func (s *UpdateSecurityGroupRuleDescriptionsEgressOutput) SetReturn(v bool) *UpdateSecurityGroupRuleDescriptionsEgressOutput { + s.Return = &v + return s +} + +// Contains the parameters for UpdateSecurityGroupRuleDescriptionsIngress. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsIngressRequest +type UpdateSecurityGroupRuleDescriptionsIngressInput struct { + _ struct{} `type:"structure"` + + // Checks whether you have the required permissions for the action, without + // actually making the request, and provides an error response. If you have + // the required permissions, the error response is DryRunOperation. Otherwise, + // it is UnauthorizedOperation. + DryRun *bool `type:"boolean"` + + // The ID of the security group. You must specify either the security group + // ID or the security group name in the request. For security groups in a nondefault + // VPC, you must specify the security group ID. + GroupId *string `type:"string"` + + // [EC2-Classic, default VPC] The name of the security group. You must specify + // either the security group ID or the security group name in the request. + GroupName *string `type:"string"` + + // The IP permissions for the security group rule. + // + // IpPermissions is a required field + IpPermissions []*IpPermission `locationNameList:"item" type:"list" required:"true"` +} + +// String returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsIngressInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsIngressInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateSecurityGroupRuleDescriptionsIngressInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateSecurityGroupRuleDescriptionsIngressInput"} + if s.IpPermissions == nil { + invalidParams.Add(request.NewErrParamRequired("IpPermissions")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDryRun sets the DryRun field's value. +func (s *UpdateSecurityGroupRuleDescriptionsIngressInput) SetDryRun(v bool) *UpdateSecurityGroupRuleDescriptionsIngressInput { + s.DryRun = &v + return s +} + +// SetGroupId sets the GroupId field's value. +func (s *UpdateSecurityGroupRuleDescriptionsIngressInput) SetGroupId(v string) *UpdateSecurityGroupRuleDescriptionsIngressInput { + s.GroupId = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *UpdateSecurityGroupRuleDescriptionsIngressInput) SetGroupName(v string) *UpdateSecurityGroupRuleDescriptionsIngressInput { + s.GroupName = &v + return s +} + +// SetIpPermissions sets the IpPermissions field's value. +func (s *UpdateSecurityGroupRuleDescriptionsIngressInput) SetIpPermissions(v []*IpPermission) *UpdateSecurityGroupRuleDescriptionsIngressInput { + s.IpPermissions = v + return s +} + +// Contains the output of UpdateSecurityGroupRuleDescriptionsIngress. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsIngressResult +type UpdateSecurityGroupRuleDescriptionsIngressOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the request succeeds; otherwise, returns an error. + Return *bool `locationName:"return" type:"boolean"` +} + +// String returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsIngressOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSecurityGroupRuleDescriptionsIngressOutput) GoString() string { + return s.String() +} + +// SetReturn sets the Return field's value. +func (s *UpdateSecurityGroupRuleDescriptionsIngressOutput) SetReturn(v bool) *UpdateSecurityGroupRuleDescriptionsIngressOutput { + s.Return = &v + return s +} + // Describes the S3 bucket for the disk image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserBucket type UserBucket struct { _ struct{} `type:"structure"` @@ -56541,7 +66071,7 @@ func (s *UserBucket) SetS3Key(v string) *UserBucket { } // Describes the S3 bucket for the disk image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserBucketDetails +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserBucketDetails type UserBucketDetails struct { _ struct{} `type:"structure"` @@ -56575,7 +66105,7 @@ func (s *UserBucketDetails) SetS3Key(v string) *UserBucketDetails { } // Describes the user data for an instance. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserData +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserData type UserData struct { _ struct{} `type:"structure"` @@ -56602,10 +66132,17 @@ func (s *UserData) SetData(v string) *UserData { } // Describes a security group and AWS account ID pair. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserIdGroupPair +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserIdGroupPair type UserIdGroupPair struct { _ struct{} `type:"structure"` + // A description for the security group rule that references this user ID group + // pair. + // + // Constraints: Up to 255 characters in length. Allowed characters are a-z, + // A-Z, 0-9, spaces, and ._-:/()#,@[]+=;{}!$* + Description *string `locationName:"description" type:"string"` + // The ID of the security group. GroupId *string `locationName:"groupId" type:"string"` @@ -56641,6 +66178,12 @@ func (s UserIdGroupPair) GoString() string { return s.String() } +// SetDescription sets the Description field's value. +func (s *UserIdGroupPair) SetDescription(v string) *UserIdGroupPair { + s.Description = &v + return s +} + // SetGroupId sets the GroupId field's value. func (s *UserIdGroupPair) SetGroupId(v string) *UserIdGroupPair { s.GroupId = &v @@ -56678,7 +66221,7 @@ func (s *UserIdGroupPair) SetVpcPeeringConnectionId(v string) *UserIdGroupPair { } // Describes telemetry for a VPN tunnel. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VgwTelemetry +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VgwTelemetry type VgwTelemetry struct { _ struct{} `type:"structure"` @@ -56740,7 +66283,7 @@ func (s *VgwTelemetry) SetStatusMessage(v string) *VgwTelemetry { } // Describes a volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Volume +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Volume type Volume struct { _ struct{} `type:"structure"` @@ -56879,7 +66422,7 @@ func (s *Volume) SetVolumeType(v string) *Volume { } // Describes volume attachment details. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeAttachment +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeAttachment type VolumeAttachment struct { _ struct{} `type:"structure"` @@ -56949,7 +66492,7 @@ func (s *VolumeAttachment) SetVolumeId(v string) *VolumeAttachment { } // Describes an EBS volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeDetail +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeDetail type VolumeDetail struct { _ struct{} `type:"structure"` @@ -56991,7 +66534,7 @@ func (s *VolumeDetail) SetSize(v int64) *VolumeDetail { // Describes the modification status of an EBS volume. // // If the volume has never been modified, some element values will be null. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeModification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeModification type VolumeModification struct { _ struct{} `type:"structure"` @@ -57116,7 +66659,7 @@ func (s *VolumeModification) SetVolumeId(v string) *VolumeModification { } // Describes a volume status operation code. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusAction +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusAction type VolumeStatusAction struct { _ struct{} `type:"structure"` @@ -57168,7 +66711,7 @@ func (s *VolumeStatusAction) SetEventType(v string) *VolumeStatusAction { } // Describes a volume status. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusDetails +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusDetails type VolumeStatusDetails struct { _ struct{} `type:"structure"` @@ -57202,7 +66745,7 @@ func (s *VolumeStatusDetails) SetStatus(v string) *VolumeStatusDetails { } // Describes a volume status event. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusEvent +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusEvent type VolumeStatusEvent struct { _ struct{} `type:"structure"` @@ -57263,7 +66806,7 @@ func (s *VolumeStatusEvent) SetNotBefore(v time.Time) *VolumeStatusEvent { } // Describes the status of a volume. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusInfo +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusInfo type VolumeStatusInfo struct { _ struct{} `type:"structure"` @@ -57297,7 +66840,7 @@ func (s *VolumeStatusInfo) SetStatus(v string) *VolumeStatusInfo { } // Describes the volume status. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusItem +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusItem type VolumeStatusItem struct { _ struct{} `type:"structure"` @@ -57358,13 +66901,16 @@ func (s *VolumeStatusItem) SetVolumeStatus(v *VolumeStatusInfo) *VolumeStatusIte } // Describes a VPC. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Vpc +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Vpc type Vpc struct { _ struct{} `type:"structure"` - // The IPv4 CIDR block for the VPC. + // The primary IPv4 CIDR block for the VPC. CidrBlock *string `locationName:"cidrBlock" type:"string"` + // Information about the IPv4 CIDR blocks associated with the VPC. + CidrBlockAssociationSet []*VpcCidrBlockAssociation `locationName:"cidrBlockAssociationSet" locationNameList:"item" type:"list"` + // The ID of the set of DHCP options you've associated with the VPC (or default // if the default options are associated with the VPC). DhcpOptionsId *string `locationName:"dhcpOptionsId" type:"string"` @@ -57404,6 +66950,12 @@ func (s *Vpc) SetCidrBlock(v string) *Vpc { return s } +// SetCidrBlockAssociationSet sets the CidrBlockAssociationSet field's value. +func (s *Vpc) SetCidrBlockAssociationSet(v []*VpcCidrBlockAssociation) *Vpc { + s.CidrBlockAssociationSet = v + return s +} + // SetDhcpOptionsId sets the DhcpOptionsId field's value. func (s *Vpc) SetDhcpOptionsId(v string) *Vpc { s.DhcpOptionsId = &v @@ -57447,7 +66999,7 @@ func (s *Vpc) SetVpcId(v string) *Vpc { } // Describes an attachment between a virtual private gateway and a VPC. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcAttachment +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcAttachment type VpcAttachment struct { _ struct{} `type:"structure"` @@ -57480,8 +67032,51 @@ func (s *VpcAttachment) SetVpcId(v string) *VpcAttachment { return s } +// Describes an IPv4 CIDR block associated with a VPC. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcCidrBlockAssociation +type VpcCidrBlockAssociation struct { + _ struct{} `type:"structure"` + + // The association ID for the IPv4 CIDR block. + AssociationId *string `locationName:"associationId" type:"string"` + + // The IPv4 CIDR block. + CidrBlock *string `locationName:"cidrBlock" type:"string"` + + // Information about the state of the CIDR block. + CidrBlockState *VpcCidrBlockState `locationName:"cidrBlockState" type:"structure"` +} + +// String returns the string representation +func (s VpcCidrBlockAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcCidrBlockAssociation) GoString() string { + return s.String() +} + +// SetAssociationId sets the AssociationId field's value. +func (s *VpcCidrBlockAssociation) SetAssociationId(v string) *VpcCidrBlockAssociation { + s.AssociationId = &v + return s +} + +// SetCidrBlock sets the CidrBlock field's value. +func (s *VpcCidrBlockAssociation) SetCidrBlock(v string) *VpcCidrBlockAssociation { + s.CidrBlock = &v + return s +} + +// SetCidrBlockState sets the CidrBlockState field's value. +func (s *VpcCidrBlockAssociation) SetCidrBlockState(v *VpcCidrBlockState) *VpcCidrBlockAssociation { + s.CidrBlockState = v + return s +} + // Describes the state of a CIDR block. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcCidrBlockState +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcCidrBlockState type VpcCidrBlockState struct { _ struct{} `type:"structure"` @@ -57515,7 +67110,7 @@ func (s *VpcCidrBlockState) SetStatusMessage(v string) *VpcCidrBlockState { } // Describes whether a VPC is enabled for ClassicLink. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcClassicLink +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcClassicLink type VpcClassicLink struct { _ struct{} `type:"structure"` @@ -57558,28 +67153,48 @@ func (s *VpcClassicLink) SetVpcId(v string) *VpcClassicLink { } // Describes a VPC endpoint. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcEndpoint +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcEndpoint type VpcEndpoint struct { _ struct{} `type:"structure"` // The date and time the VPC endpoint was created. CreationTimestamp *time.Time `locationName:"creationTimestamp" type:"timestamp" timestampFormat:"iso8601"` - // The policy document associated with the endpoint. + // (Interface endpoint) The DNS entries for the endpoint. + DnsEntries []*DnsEntry `locationName:"dnsEntrySet" locationNameList:"item" type:"list"` + + // (Interface endpoint) Information about the security groups associated with + // the network interface. + Groups []*SecurityGroupIdentifier `locationName:"groupSet" locationNameList:"item" type:"list"` + + // (Interface endpoint) One or more network interfaces for the endpoint. + NetworkInterfaceIds []*string `locationName:"networkInterfaceIdSet" locationNameList:"item" type:"list"` + + // The policy document associated with the endpoint, if applicable. PolicyDocument *string `locationName:"policyDocument" type:"string"` - // One or more route tables associated with the endpoint. + // (Interface endpoint) Indicates whether the VPC is associated with a private + // hosted zone. + PrivateDnsEnabled *bool `locationName:"privateDnsEnabled" type:"boolean"` + + // (Gateway endpoint) One or more route tables associated with the endpoint. RouteTableIds []*string `locationName:"routeTableIdSet" locationNameList:"item" type:"list"` - // The name of the AWS service to which the endpoint is associated. + // The name of the service to which the endpoint is associated. ServiceName *string `locationName:"serviceName" type:"string"` // The state of the VPC endpoint. State *string `locationName:"state" type:"string" enum:"State"` + // (Interface endpoint) One or more subnets in which the endpoint is located. + SubnetIds []*string `locationName:"subnetIdSet" locationNameList:"item" type:"list"` + // The ID of the VPC endpoint. VpcEndpointId *string `locationName:"vpcEndpointId" type:"string"` + // The type of endpoint. + VpcEndpointType *string `locationName:"vpcEndpointType" type:"string" enum:"VpcEndpointType"` + // The ID of the VPC to which the endpoint is associated. VpcId *string `locationName:"vpcId" type:"string"` } @@ -57600,12 +67215,36 @@ func (s *VpcEndpoint) SetCreationTimestamp(v time.Time) *VpcEndpoint { return s } +// SetDnsEntries sets the DnsEntries field's value. +func (s *VpcEndpoint) SetDnsEntries(v []*DnsEntry) *VpcEndpoint { + s.DnsEntries = v + return s +} + +// SetGroups sets the Groups field's value. +func (s *VpcEndpoint) SetGroups(v []*SecurityGroupIdentifier) *VpcEndpoint { + s.Groups = v + return s +} + +// SetNetworkInterfaceIds sets the NetworkInterfaceIds field's value. +func (s *VpcEndpoint) SetNetworkInterfaceIds(v []*string) *VpcEndpoint { + s.NetworkInterfaceIds = v + return s +} + // SetPolicyDocument sets the PolicyDocument field's value. func (s *VpcEndpoint) SetPolicyDocument(v string) *VpcEndpoint { s.PolicyDocument = &v return s } +// SetPrivateDnsEnabled sets the PrivateDnsEnabled field's value. +func (s *VpcEndpoint) SetPrivateDnsEnabled(v bool) *VpcEndpoint { + s.PrivateDnsEnabled = &v + return s +} + // SetRouteTableIds sets the RouteTableIds field's value. func (s *VpcEndpoint) SetRouteTableIds(v []*string) *VpcEndpoint { s.RouteTableIds = v @@ -57624,20 +67263,93 @@ func (s *VpcEndpoint) SetState(v string) *VpcEndpoint { return s } +// SetSubnetIds sets the SubnetIds field's value. +func (s *VpcEndpoint) SetSubnetIds(v []*string) *VpcEndpoint { + s.SubnetIds = v + return s +} + // SetVpcEndpointId sets the VpcEndpointId field's value. func (s *VpcEndpoint) SetVpcEndpointId(v string) *VpcEndpoint { s.VpcEndpointId = &v return s } +// SetVpcEndpointType sets the VpcEndpointType field's value. +func (s *VpcEndpoint) SetVpcEndpointType(v string) *VpcEndpoint { + s.VpcEndpointType = &v + return s +} + // SetVpcId sets the VpcId field's value. func (s *VpcEndpoint) SetVpcId(v string) *VpcEndpoint { s.VpcId = &v return s } +// Describes a VPC endpoint connection to a service. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcEndpointConnection +type VpcEndpointConnection struct { + _ struct{} `type:"structure"` + + // The date and time the VPC endpoint was created. + CreationTimestamp *time.Time `locationName:"creationTimestamp" type:"timestamp" timestampFormat:"iso8601"` + + // The ID of the service to which the endpoint is connected. + ServiceId *string `locationName:"serviceId" type:"string"` + + // The ID of the VPC endpoint. + VpcEndpointId *string `locationName:"vpcEndpointId" type:"string"` + + // The AWS account ID of the owner of the VPC endpoint. + VpcEndpointOwner *string `locationName:"vpcEndpointOwner" type:"string"` + + // The state of the VPC endpoint. + VpcEndpointState *string `locationName:"vpcEndpointState" type:"string" enum:"State"` +} + +// String returns the string representation +func (s VpcEndpointConnection) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcEndpointConnection) GoString() string { + return s.String() +} + +// SetCreationTimestamp sets the CreationTimestamp field's value. +func (s *VpcEndpointConnection) SetCreationTimestamp(v time.Time) *VpcEndpointConnection { + s.CreationTimestamp = &v + return s +} + +// SetServiceId sets the ServiceId field's value. +func (s *VpcEndpointConnection) SetServiceId(v string) *VpcEndpointConnection { + s.ServiceId = &v + return s +} + +// SetVpcEndpointId sets the VpcEndpointId field's value. +func (s *VpcEndpointConnection) SetVpcEndpointId(v string) *VpcEndpointConnection { + s.VpcEndpointId = &v + return s +} + +// SetVpcEndpointOwner sets the VpcEndpointOwner field's value. +func (s *VpcEndpointConnection) SetVpcEndpointOwner(v string) *VpcEndpointConnection { + s.VpcEndpointOwner = &v + return s +} + +// SetVpcEndpointState sets the VpcEndpointState field's value. +func (s *VpcEndpointConnection) SetVpcEndpointState(v string) *VpcEndpointConnection { + s.VpcEndpointState = &v + return s +} + // Describes an IPv6 CIDR block associated with a VPC. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcIpv6CidrBlockAssociation +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcIpv6CidrBlockAssociation type VpcIpv6CidrBlockAssociation struct { _ struct{} `type:"structure"` @@ -57680,7 +67392,7 @@ func (s *VpcIpv6CidrBlockAssociation) SetIpv6CidrBlockState(v *VpcCidrBlockState } // Describes a VPC peering connection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnection type VpcPeeringConnection struct { _ struct{} `type:"structure"` @@ -57752,7 +67464,7 @@ func (s *VpcPeeringConnection) SetVpcPeeringConnectionId(v string) *VpcPeeringCo } // Describes the VPC peering connection options. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionOptionsDescription +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionOptionsDescription type VpcPeeringConnectionOptionsDescription struct { _ struct{} `type:"structure"` @@ -57798,7 +67510,7 @@ func (s *VpcPeeringConnectionOptionsDescription) SetAllowEgressFromLocalVpcToRem } // Describes the status of a VPC peering connection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionStateReason +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionStateReason type VpcPeeringConnectionStateReason struct { _ struct{} `type:"structure"` @@ -57832,13 +67544,16 @@ func (s *VpcPeeringConnectionStateReason) SetMessage(v string) *VpcPeeringConnec } // Describes a VPC in a VPC peering connection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionVpcInfo +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionVpcInfo type VpcPeeringConnectionVpcInfo struct { _ struct{} `type:"structure"` // The IPv4 CIDR block for the VPC. CidrBlock *string `locationName:"cidrBlock" type:"string"` + // Information about the IPv4 CIDR blocks for the VPC. + CidrBlockSet []*CidrBlock `locationName:"cidrBlockSet" locationNameList:"item" type:"list"` + // The IPv6 CIDR block for the VPC. Ipv6CidrBlockSet []*Ipv6CidrBlock `locationName:"ipv6CidrBlockSet" locationNameList:"item" type:"list"` @@ -57849,6 +67564,9 @@ type VpcPeeringConnectionVpcInfo struct { // requester VPC. PeeringOptions *VpcPeeringConnectionOptionsDescription `locationName:"peeringOptions" type:"structure"` + // The region in which the VPC is located. + Region *string `locationName:"region" type:"string"` + // The ID of the VPC. VpcId *string `locationName:"vpcId" type:"string"` } @@ -57869,6 +67587,12 @@ func (s *VpcPeeringConnectionVpcInfo) SetCidrBlock(v string) *VpcPeeringConnecti return s } +// SetCidrBlockSet sets the CidrBlockSet field's value. +func (s *VpcPeeringConnectionVpcInfo) SetCidrBlockSet(v []*CidrBlock) *VpcPeeringConnectionVpcInfo { + s.CidrBlockSet = v + return s +} + // SetIpv6CidrBlockSet sets the Ipv6CidrBlockSet field's value. func (s *VpcPeeringConnectionVpcInfo) SetIpv6CidrBlockSet(v []*Ipv6CidrBlock) *VpcPeeringConnectionVpcInfo { s.Ipv6CidrBlockSet = v @@ -57887,6 +67611,12 @@ func (s *VpcPeeringConnectionVpcInfo) SetPeeringOptions(v *VpcPeeringConnectionO return s } +// SetRegion sets the Region field's value. +func (s *VpcPeeringConnectionVpcInfo) SetRegion(v string) *VpcPeeringConnectionVpcInfo { + s.Region = &v + return s +} + // SetVpcId sets the VpcId field's value. func (s *VpcPeeringConnectionVpcInfo) SetVpcId(v string) *VpcPeeringConnectionVpcInfo { s.VpcId = &v @@ -57894,10 +67624,16 @@ func (s *VpcPeeringConnectionVpcInfo) SetVpcId(v string) *VpcPeeringConnectionVp } // Describes a VPN connection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnection +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnection type VpnConnection struct { _ struct{} `type:"structure"` + // The category of the VPN connection. A value of VPN indicates an AWS VPN connection. + // A value of VPN-Classic indicates an AWS Classic VPN connection. For more + // information, see AWS Managed VPN Categories (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html#vpn-categories) + // in the Amazon Virtual Private Cloud User Guide. + Category *string `locationName:"category" type:"string"` + // The configuration information for the VPN connection's customer gateway (in // the native XML format). This element is always present in the CreateVpnConnection // response; however, it's present in the DescribeVpnConnections response only @@ -57942,6 +67678,12 @@ func (s VpnConnection) GoString() string { return s.String() } +// SetCategory sets the Category field's value. +func (s *VpnConnection) SetCategory(v string) *VpnConnection { + s.Category = &v + return s +} + // SetCustomerGatewayConfiguration sets the CustomerGatewayConfiguration field's value. func (s *VpnConnection) SetCustomerGatewayConfiguration(v string) *VpnConnection { s.CustomerGatewayConfiguration = &v @@ -58003,7 +67745,7 @@ func (s *VpnConnection) SetVpnGatewayId(v string) *VpnConnection { } // Describes VPN connection options. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnectionOptions +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnectionOptions type VpnConnectionOptions struct { _ struct{} `type:"structure"` @@ -58029,13 +67771,19 @@ func (s *VpnConnectionOptions) SetStaticRoutesOnly(v bool) *VpnConnectionOptions } // Describes VPN connection options. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnectionOptionsSpecification +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnectionOptionsSpecification type VpnConnectionOptionsSpecification struct { _ struct{} `type:"structure"` - // Indicates whether the VPN connection uses static routes only. Static routes - // must be used for devices that don't support BGP. + // Indicate whether the VPN connection uses static routes only. If you are creating + // a VPN connection for a device that does not support BGP, you must specify + // true. + // + // Default: false StaticRoutesOnly *bool `locationName:"staticRoutesOnly" type:"boolean"` + + // The tunnel options for the VPN connection. + TunnelOptions []*VpnTunnelOptionsSpecification `locationNameList:"item" type:"list"` } // String returns the string representation @@ -58054,11 +67802,20 @@ func (s *VpnConnectionOptionsSpecification) SetStaticRoutesOnly(v bool) *VpnConn return s } +// SetTunnelOptions sets the TunnelOptions field's value. +func (s *VpnConnectionOptionsSpecification) SetTunnelOptions(v []*VpnTunnelOptionsSpecification) *VpnConnectionOptionsSpecification { + s.TunnelOptions = v + return s +} + // Describes a virtual private gateway. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnGateway +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnGateway type VpnGateway struct { _ struct{} `type:"structure"` + // The private Autonomous System Number (ASN) for the Amazon side of a BGP session. + AmazonSideAsn *int64 `locationName:"amazonSideAsn" type:"long"` + // The Availability Zone where the virtual private gateway was created, if applicable. // This field may be empty or not returned. AvailabilityZone *string `locationName:"availabilityZone" type:"string"` @@ -58089,6 +67846,12 @@ func (s VpnGateway) GoString() string { return s.String() } +// SetAmazonSideAsn sets the AmazonSideAsn field's value. +func (s *VpnGateway) SetAmazonSideAsn(v int64) *VpnGateway { + s.AmazonSideAsn = &v + return s +} + // SetAvailabilityZone sets the AvailabilityZone field's value. func (s *VpnGateway) SetAvailabilityZone(v string) *VpnGateway { s.AvailabilityZone = &v @@ -58126,7 +67889,7 @@ func (s *VpnGateway) SetVpnGatewayId(v string) *VpnGateway { } // Describes a static route for a VPN connection. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnStaticRoute +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnStaticRoute type VpnStaticRoute struct { _ struct{} `type:"structure"` @@ -58168,6 +67931,63 @@ func (s *VpnStaticRoute) SetState(v string) *VpnStaticRoute { return s } +// The tunnel options for a VPN connection. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnTunnelOptionsSpecification +type VpnTunnelOptionsSpecification struct { + _ struct{} `type:"structure"` + + // The pre-shared key (PSK) to establish initial authentication between the + // virtual private gateway and customer gateway. + // + // Constraints: Allowed characters are alphanumeric characters and ._. Must + // be between 8 and 64 characters in length and cannot start with zero (0). + PreSharedKey *string `type:"string"` + + // The range of inside IP addresses for the tunnel. Any specified CIDR blocks + // must be unique across all VPN connections that use the same virtual private + // gateway. + // + // Constraints: A size /30 CIDR block from the 169.254.0.0/16 range. The following + // CIDR blocks are reserved and cannot be used: + // + // * 169.254.0.0/30 + // + // * 169.254.1.0/30 + // + // * 169.254.2.0/30 + // + // * 169.254.3.0/30 + // + // * 169.254.4.0/30 + // + // * 169.254.5.0/30 + // + // * 169.254.169.252/30 + TunnelInsideCidr *string `type:"string"` +} + +// String returns the string representation +func (s VpnTunnelOptionsSpecification) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpnTunnelOptionsSpecification) GoString() string { + return s.String() +} + +// SetPreSharedKey sets the PreSharedKey field's value. +func (s *VpnTunnelOptionsSpecification) SetPreSharedKey(v string) *VpnTunnelOptionsSpecification { + s.PreSharedKey = &v + return s +} + +// SetTunnelInsideCidr sets the TunnelInsideCidr field's value. +func (s *VpnTunnelOptionsSpecification) SetTunnelInsideCidr(v string) *VpnTunnelOptionsSpecification { + s.TunnelInsideCidr = &v + return s +} + const ( // AccountAttributeNameSupportedPlatforms is a AccountAttributeName enum value AccountAttributeNameSupportedPlatforms = "supported-platforms" @@ -58344,6 +68164,19 @@ const ( CancelSpotInstanceRequestStateCompleted = "completed" ) +const ( + // ConnectionNotificationStateEnabled is a ConnectionNotificationState enum value + ConnectionNotificationStateEnabled = "Enabled" + + // ConnectionNotificationStateDisabled is a ConnectionNotificationState enum value + ConnectionNotificationStateDisabled = "Disabled" +) + +const ( + // ConnectionNotificationTypeTopic is a ConnectionNotificationType enum value + ConnectionNotificationTypeTopic = "Topic" +) + const ( // ContainerFormatOva is a ContainerFormat enum value ContainerFormatOva = "ova" @@ -58496,6 +68329,20 @@ const ( FlowLogsResourceTypeNetworkInterface = "NetworkInterface" ) +const ( + // FpgaImageAttributeNameDescription is a FpgaImageAttributeName enum value + FpgaImageAttributeNameDescription = "description" + + // FpgaImageAttributeNameName is a FpgaImageAttributeName enum value + FpgaImageAttributeNameName = "name" + + // FpgaImageAttributeNameLoadPermission is a FpgaImageAttributeName enum value + FpgaImageAttributeNameLoadPermission = "loadPermission" + + // FpgaImageAttributeNameProductCodes is a FpgaImageAttributeName enum value + FpgaImageAttributeNameProductCodes = "productCodes" +) + const ( // FpgaImageStateCodePending is a FpgaImageStateCode enum value FpgaImageStateCodePending = "pending" @@ -58654,6 +68501,17 @@ const ( InstanceHealthStatusUnhealthy = "unhealthy" ) +const ( + // InstanceInterruptionBehaviorHibernate is a InstanceInterruptionBehavior enum value + InstanceInterruptionBehaviorHibernate = "hibernate" + + // InstanceInterruptionBehaviorStop is a InstanceInterruptionBehavior enum value + InstanceInterruptionBehaviorStop = "stop" + + // InstanceInterruptionBehaviorTerminate is a InstanceInterruptionBehavior enum value + InstanceInterruptionBehaviorTerminate = "terminate" +) + const ( // InstanceLifecycleTypeSpot is a InstanceLifecycleType enum value InstanceLifecycleTypeSpot = "spot" @@ -58800,6 +68658,24 @@ const ( // InstanceTypeX132xlarge is a InstanceType enum value InstanceTypeX132xlarge = "x1.32xlarge" + // InstanceTypeX1eXlarge is a InstanceType enum value + InstanceTypeX1eXlarge = "x1e.xlarge" + + // InstanceTypeX1e2xlarge is a InstanceType enum value + InstanceTypeX1e2xlarge = "x1e.2xlarge" + + // InstanceTypeX1e4xlarge is a InstanceType enum value + InstanceTypeX1e4xlarge = "x1e.4xlarge" + + // InstanceTypeX1e8xlarge is a InstanceType enum value + InstanceTypeX1e8xlarge = "x1e.8xlarge" + + // InstanceTypeX1e16xlarge is a InstanceType enum value + InstanceTypeX1e16xlarge = "x1e.16xlarge" + + // InstanceTypeX1e32xlarge is a InstanceType enum value + InstanceTypeX1e32xlarge = "x1e.32xlarge" + // InstanceTypeI2Xlarge is a InstanceType enum value InstanceTypeI2Xlarge = "i2.xlarge" @@ -58872,6 +68748,24 @@ const ( // InstanceTypeC48xlarge is a InstanceType enum value InstanceTypeC48xlarge = "c4.8xlarge" + // InstanceTypeC5Large is a InstanceType enum value + InstanceTypeC5Large = "c5.large" + + // InstanceTypeC5Xlarge is a InstanceType enum value + InstanceTypeC5Xlarge = "c5.xlarge" + + // InstanceTypeC52xlarge is a InstanceType enum value + InstanceTypeC52xlarge = "c5.2xlarge" + + // InstanceTypeC54xlarge is a InstanceType enum value + InstanceTypeC54xlarge = "c5.4xlarge" + + // InstanceTypeC59xlarge is a InstanceType enum value + InstanceTypeC59xlarge = "c5.9xlarge" + + // InstanceTypeC518xlarge is a InstanceType enum value + InstanceTypeC518xlarge = "c5.18xlarge" + // InstanceTypeCc14xlarge is a InstanceType enum value InstanceTypeCc14xlarge = "cc1.4xlarge" @@ -58905,6 +68799,15 @@ const ( // InstanceTypeP216xlarge is a InstanceType enum value InstanceTypeP216xlarge = "p2.16xlarge" + // InstanceTypeP32xlarge is a InstanceType enum value + InstanceTypeP32xlarge = "p3.2xlarge" + + // InstanceTypeP38xlarge is a InstanceType enum value + InstanceTypeP38xlarge = "p3.8xlarge" + + // InstanceTypeP316xlarge is a InstanceType enum value + InstanceTypeP316xlarge = "p3.16xlarge" + // InstanceTypeD2Xlarge is a InstanceType enum value InstanceTypeD2Xlarge = "d2.xlarge" @@ -58922,6 +68825,36 @@ const ( // InstanceTypeF116xlarge is a InstanceType enum value InstanceTypeF116xlarge = "f1.16xlarge" + + // InstanceTypeM5Large is a InstanceType enum value + InstanceTypeM5Large = "m5.large" + + // InstanceTypeM5Xlarge is a InstanceType enum value + InstanceTypeM5Xlarge = "m5.xlarge" + + // InstanceTypeM52xlarge is a InstanceType enum value + InstanceTypeM52xlarge = "m5.2xlarge" + + // InstanceTypeM54xlarge is a InstanceType enum value + InstanceTypeM54xlarge = "m5.4xlarge" + + // InstanceTypeM512xlarge is a InstanceType enum value + InstanceTypeM512xlarge = "m5.12xlarge" + + // InstanceTypeM524xlarge is a InstanceType enum value + InstanceTypeM524xlarge = "m5.24xlarge" + + // InstanceTypeH12xlarge is a InstanceType enum value + InstanceTypeH12xlarge = "h1.2xlarge" + + // InstanceTypeH14xlarge is a InstanceType enum value + InstanceTypeH14xlarge = "h1.4xlarge" + + // InstanceTypeH18xlarge is a InstanceType enum value + InstanceTypeH18xlarge = "h1.8xlarge" + + // InstanceTypeH116xlarge is a InstanceType enum value + InstanceTypeH116xlarge = "h1.16xlarge" ) const ( @@ -58932,6 +68865,26 @@ const ( InterfacePermissionTypeEipAssociate = "EIP-ASSOCIATE" ) +const ( + // LaunchTemplateErrorCodeLaunchTemplateIdDoesNotExist is a LaunchTemplateErrorCode enum value + LaunchTemplateErrorCodeLaunchTemplateIdDoesNotExist = "launchTemplateIdDoesNotExist" + + // LaunchTemplateErrorCodeLaunchTemplateIdMalformed is a LaunchTemplateErrorCode enum value + LaunchTemplateErrorCodeLaunchTemplateIdMalformed = "launchTemplateIdMalformed" + + // LaunchTemplateErrorCodeLaunchTemplateNameDoesNotExist is a LaunchTemplateErrorCode enum value + LaunchTemplateErrorCodeLaunchTemplateNameDoesNotExist = "launchTemplateNameDoesNotExist" + + // LaunchTemplateErrorCodeLaunchTemplateNameMalformed is a LaunchTemplateErrorCode enum value + LaunchTemplateErrorCodeLaunchTemplateNameMalformed = "launchTemplateNameMalformed" + + // LaunchTemplateErrorCodeLaunchTemplateVersionDoesNotExist is a LaunchTemplateErrorCode enum value + LaunchTemplateErrorCodeLaunchTemplateVersionDoesNotExist = "launchTemplateVersionDoesNotExist" + + // LaunchTemplateErrorCodeUnexpectedError is a LaunchTemplateErrorCode enum value + LaunchTemplateErrorCodeUnexpectedError = "unexpectedError" +) + const ( // ListingStateAvailable is a ListingState enum value ListingStateAvailable = "available" @@ -58960,6 +68913,11 @@ const ( ListingStatusClosed = "closed" ) +const ( + // MarketTypeSpot is a MarketType enum value + MarketTypeSpot = "spot" +) + const ( // MonitoringStateDisabled is a MonitoringState enum value MonitoringStateDisabled = "disabled" @@ -59118,6 +69076,9 @@ const ( const ( // PlacementStrategyCluster is a PlacementStrategy enum value PlacementStrategyCluster = "cluster" + + // PlacementStrategySpread is a PlacementStrategy enum value + PlacementStrategySpread = "spread" ) const ( @@ -59125,6 +69086,26 @@ const ( PlatformValuesWindows = "Windows" ) +const ( + // PrincipalTypeAll is a PrincipalType enum value + PrincipalTypeAll = "All" + + // PrincipalTypeService is a PrincipalType enum value + PrincipalTypeService = "Service" + + // PrincipalTypeOrganizationUnit is a PrincipalType enum value + PrincipalTypeOrganizationUnit = "OrganizationUnit" + + // PrincipalTypeAccount is a PrincipalType enum value + PrincipalTypeAccount = "Account" + + // PrincipalTypeUser is a PrincipalType enum value + PrincipalTypeUser = "User" + + // PrincipalTypeRole is a PrincipalType enum value + PrincipalTypeRole = "Role" +) + const ( // ProductCodeValuesDevpay is a ProductCodeValues enum value ProductCodeValuesDevpay = "devpay" @@ -59217,6 +69198,11 @@ const ( ReservedInstanceStateRetired = "retired" ) +const ( + // ResetFpgaImageAttributeNameLoadPermission is a ResetFpgaImageAttributeName enum value + ResetFpgaImageAttributeNameLoadPermission = "loadPermission" +) + const ( // ResetImageAttributeNameLaunchPermission is a ResetImageAttributeName enum value ResetImageAttributeNameLaunchPermission = "launchPermission" @@ -59302,6 +69288,31 @@ const ( RuleActionDeny = "deny" ) +const ( + // ServiceStatePending is a ServiceState enum value + ServiceStatePending = "Pending" + + // ServiceStateAvailable is a ServiceState enum value + ServiceStateAvailable = "Available" + + // ServiceStateDeleting is a ServiceState enum value + ServiceStateDeleting = "Deleting" + + // ServiceStateDeleted is a ServiceState enum value + ServiceStateDeleted = "Deleted" + + // ServiceStateFailed is a ServiceState enum value + ServiceStateFailed = "Failed" +) + +const ( + // ServiceTypeInterface is a ServiceType enum value + ServiceTypeInterface = "Interface" + + // ServiceTypeGateway is a ServiceType enum value + ServiceTypeGateway = "Gateway" +) + const ( // ShutdownBehaviorStop is a ShutdownBehavior enum value ShutdownBehaviorStop = "stop" @@ -59355,6 +69366,9 @@ const ( ) const ( + // StatePendingAcceptance is a State enum value + StatePendingAcceptance = "PendingAcceptance" + // StatePending is a State enum value StatePending = "Pending" @@ -59366,6 +69380,15 @@ const ( // StateDeleted is a State enum value StateDeleted = "Deleted" + + // StateRejected is a State enum value + StateRejected = "Rejected" + + // StateFailed is a State enum value + StateFailed = "Failed" + + // StateExpired is a State enum value + StateExpired = "Expired" ) const ( @@ -59473,6 +69496,20 @@ const ( TrafficTypeAll = "ALL" ) +const ( + // UnsuccessfulInstanceCreditSpecificationErrorCodeInvalidInstanceIdMalformed is a UnsuccessfulInstanceCreditSpecificationErrorCode enum value + UnsuccessfulInstanceCreditSpecificationErrorCodeInvalidInstanceIdMalformed = "InvalidInstanceID.Malformed" + + // UnsuccessfulInstanceCreditSpecificationErrorCodeInvalidInstanceIdNotFound is a UnsuccessfulInstanceCreditSpecificationErrorCode enum value + UnsuccessfulInstanceCreditSpecificationErrorCodeInvalidInstanceIdNotFound = "InvalidInstanceID.NotFound" + + // UnsuccessfulInstanceCreditSpecificationErrorCodeIncorrectInstanceState is a UnsuccessfulInstanceCreditSpecificationErrorCode enum value + UnsuccessfulInstanceCreditSpecificationErrorCodeIncorrectInstanceState = "IncorrectInstanceState" + + // UnsuccessfulInstanceCreditSpecificationErrorCodeInstanceCreditSpecificationNotSupported is a UnsuccessfulInstanceCreditSpecificationErrorCode enum value + UnsuccessfulInstanceCreditSpecificationErrorCodeInstanceCreditSpecificationNotSupported = "InstanceCreditSpecification.NotSupported" +) + const ( // VirtualizationTypeHvm is a VirtualizationType enum value VirtualizationTypeHvm = "hvm" @@ -59493,6 +69530,9 @@ const ( // VolumeAttachmentStateDetached is a VolumeAttachmentState enum value VolumeAttachmentStateDetached = "detached" + + // VolumeAttachmentStateBusy is a VolumeAttachmentState enum value + VolumeAttachmentStateBusy = "busy" ) const ( @@ -59601,6 +69641,14 @@ const ( VpcCidrBlockStateCodeFailed = "failed" ) +const ( + // VpcEndpointTypeInterface is a VpcEndpointType enum value + VpcEndpointTypeInterface = "Interface" + + // VpcEndpointTypeGateway is a VpcEndpointType enum value + VpcEndpointTypeGateway = "Gateway" +) + const ( // VpcPeeringConnectionStateReasonCodeInitiatingRequest is a VpcPeeringConnectionStateReasonCode enum value VpcPeeringConnectionStateReasonCodeInitiatingRequest = "initiating-request" @@ -59638,6 +69686,11 @@ const ( VpcStateAvailable = "available" ) +const ( + // VpcTenancyDefault is a VpcTenancy enum value + VpcTenancyDefault = "default" +) + const ( // VpnStatePending is a VpnState enum value VpnStatePending = "pending" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go index 547167782..1ba51125e 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go @@ -15,7 +15,7 @@ // // Using the Client // -// To Amazon Elastic Compute Cloud with the SDK use the New function to create +// To contact Amazon Elastic Compute Cloud with the SDK use the New function to create // a new service client. With that client you can make API requests to the service. // These clients are safe to use concurrently. // diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go index 6914a666b..0469f0f01 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go @@ -1025,6 +1025,11 @@ func (c *EC2) WaitUntilSpotInstanceRequestFulfilledWithContext(ctx aws.Context, Matcher: request.PathAllWaiterMatch, Argument: "SpotInstanceRequests[].Status.Code", Expected: "fulfilled", }, + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, Argument: "SpotInstanceRequests[].Status.Code", + Expected: "request-canceled-and-instance-running", + }, { State: request.FailureWaiterState, Matcher: request.PathAnyWaiterMatch, Argument: "SpotInstanceRequests[].Status.Code", diff --git a/vendor/vendor.json b/vendor/vendor.json index 4438b367e..d4d157eb9 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -497,13 +497,13 @@ "versionExact": "v1.10.23" }, { - "checksumSHA1": "1mbCBXbu6m8bfRAq1+7Cul4VXkU=", + "checksumSHA1": "INaeHZ2L5x6RlrcQBm4q1hFqNRM=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "5177d71d80f123f6d82aaf762387e39b88c5ba23", + "revisionTime": "2018-01-09T00:04:15Z", + "version": "v1.12.57", + "versionExact": "v1.12.57" }, { "checksumSHA1": "YNq7YhasHn9ceelWX2aG0Cg0Ga0=", From 2ac59b3c2748f42985d48d758642e9739310590c Mon Sep 17 00:00:00 2001 From: Jason Wieringa <jason@wieringa.io> Date: Mon, 8 Jan 2018 20:30:29 -0800 Subject: [PATCH 0377/1007] builder/amazon: Added KmsKeyID to BlockDevice + Adds kms_key_id to list of options + Tests that configuraiton is set along with encrypted + Updates documentation on ebsvolume builder --- builder/amazon/common/block_device.go | 5 +++++ builder/amazon/common/block_device_test.go | 21 +++++++++++++++++++ .../docs/builders/amazon-ebsvolume.html.md | 1 + 3 files changed, 27 insertions(+) diff --git a/builder/amazon/common/block_device.go b/builder/amazon/common/block_device.go index 57f6a4307..cb490c3d4 100644 --- a/builder/amazon/common/block_device.go +++ b/builder/amazon/common/block_device.go @@ -19,6 +19,7 @@ type BlockDevice struct { VirtualName string `mapstructure:"virtual_name"` VolumeType string `mapstructure:"volume_type"` VolumeSize int64 `mapstructure:"volume_size"` + KmsKeyId string `mapstructure:"kms_key_id"` } type BlockDevices struct { @@ -73,6 +74,10 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping { ebsBlockDevice.Encrypted = aws.Bool(blockDevice.Encrypted) } + if blockDevice.KmsKeyId != "" { + ebsBlockDevice.KmsKeyId = aws.String(blockDevice.KmsKeyId) + } + mapping.Ebs = ebsBlockDevice } diff --git a/builder/amazon/common/block_device_test.go b/builder/amazon/common/block_device_test.go index 5fc25f243..130bbef0b 100644 --- a/builder/amazon/common/block_device_test.go +++ b/builder/amazon/common/block_device_test.go @@ -84,6 +84,27 @@ func TestBlockDevice(t *testing.T) { }, }, }, + { + Config: &BlockDevice{ + DeviceName: "/dev/sdb", + VolumeType: "gp2", + VolumeSize: 8, + DeleteOnTermination: true, + Encrypted: true, + KmsKeyId: "2Fa48a521f-3aff-4b34-a159-376ac5d37812", + }, + + Result: &ec2.BlockDeviceMapping{ + DeviceName: aws.String("/dev/sdb"), + Ebs: &ec2.EbsBlockDevice{ + VolumeType: aws.String("gp2"), + VolumeSize: aws.Int64(8), + DeleteOnTermination: aws.Bool(true), + Encrypted: aws.Bool(true), + KmsKeyId: aws.String("2Fa48a521f-3aff-4b34-a159-376ac5d37812"), + }, + }, + }, { Config: &BlockDevice{ DeviceName: "/dev/sdb", diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 319021e5e..d2f8bd440 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -67,6 +67,7 @@ builder. - `delete_on_termination` (boolean) - Indicates whether the EBS volume is deleted on instance termination - `encrypted` (boolean) - Indicates whether to encrypt the volume or not + - `kms_key_id` (string) - The ARN for the KMS encryption key. When specifying kms_key_id, encrypted needs to be set to true. - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) From f6772f06bed48fb72e297c6a8d7cea0c5e06fbb1 Mon Sep 17 00:00:00 2001 From: Jason Wieringa <jason@wieringa.io> Date: Thu, 11 Jan 2018 20:26:44 -0800 Subject: [PATCH 0378/1007] builder/amazon: Raise error when ebsvolume kms_key_id is without encrypted = true --- builder/amazon/ebsvolume/builder.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 6ce9ae58d..01b9e3b76 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -57,6 +57,14 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + // Warn that encrypted must be true when setting kms_key_id + for _, device := range b.config.VolumeMappings { + if device.KmsKeyId != "" && device.Encrypted == false { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("The device %v, must also have `encrytped: "+ + "true` when setting a kms_key_id.", device.DeviceName)) + } + } + b.config.launchBlockDevices, err = commonBlockDevices(b.config.VolumeMappings, &b.config.ctx) if err != nil { errs = packer.MultiErrorAppend(errs, err) From e968f9d6ccf706ad454b0bd7af92fe47a1ce5822 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 14:26:56 -0800 Subject: [PATCH 0379/1007] spelling/style fixes --- builder/amazon/ebsvolume/builder.go | 2 +- website/source/docs/builders/amazon-ebsvolume.html.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 01b9e3b76..d8f905f6c 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -60,7 +60,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { // Warn that encrypted must be true when setting kms_key_id for _, device := range b.config.VolumeMappings { if device.KmsKeyId != "" && device.Encrypted == false { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("The device %v, must also have `encrytped: "+ + errs = packer.MultiErrorAppend(errs, fmt.Errorf("The device %v, must also have `encrypted: "+ "true` when setting a kms_key_id.", device.DeviceName)) } } diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index d2f8bd440..5f63ac63a 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -67,7 +67,8 @@ builder. - `delete_on_termination` (boolean) - Indicates whether the EBS volume is deleted on instance termination - `encrypted` (boolean) - Indicates whether to encrypt the volume or not - - `kms_key_id` (string) - The ARN for the KMS encryption key. When specifying kms_key_id, encrypted needs to be set to true. + - `kms_key_id` (string) - The ARN for the KMS encryption key. When + specifying `kms_key_id`, `encrypted` needs to be set to `true`. - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) From 0023aa11cf9b6909c0f0c22c33e22e0a63d0d864 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 14:48:18 -0800 Subject: [PATCH 0380/1007] add kms_key_id to block device docs --- website/data/format.yml | 8 ++++++++ website/source/docs/builders/amazon-chroot.html.md | 3 +++ website/source/docs/builders/amazon-ebs.html.md | 3 +++ website/source/docs/builders/amazon-ebssurrogate.html.md | 3 +++ website/source/docs/builders/amazon-instance.html.md | 3 +++ 5 files changed, 20 insertions(+) create mode 100644 website/data/format.yml diff --git a/website/data/format.yml b/website/data/format.yml new file mode 100644 index 000000000..5a176fee2 --- /dev/null +++ b/website/data/format.yml @@ -0,0 +1,8 @@ +required: + <config parameter>: + type: <type> + docs: <doc string> +optional: + <config parameter>: + type: <type> + docs: <doc string> diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index a983305c2..1ffe84f38 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -170,6 +170,9 @@ each category, the available configuration keys are alphabetized. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not + - `kms_key_id` (string) - The ARN for the KMS encryption key. When + specifying `kms_key_id`, `encrypted` needs to be set to `true`. + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 6b48621b4..1abf3b97f 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -87,6 +87,9 @@ builder. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not + - `kms_key_id` (string) - The ARN for the KMS encryption key. When + specifying `kms_key_id`, `encrypted` needs to be set to `true`. + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 7b995fa87..7fbd3f506 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -80,6 +80,9 @@ builder. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not + - `kms_key_id` (string) - The ARN for the KMS encryption key. When + specifying `kms_key_id`, `encrypted` needs to be set to `true`. + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index f8f72708a..e9d633269 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -109,6 +109,9 @@ builder. - `encrypted` (boolean) - Indicates whether to encrypt the volume or not + - `kms_key_id` (string) - The ARN for the KMS encryption key. When + specifying `kms_key_id`, `encrypted` needs to be set to `true`. + - `iops` (number) - The number of I/O operations per second (IOPS) that the volume supports. See the documentation on [IOPs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html) From 53aaf841009836716af7c3a0abb396c392d907d6 Mon Sep 17 00:00:00 2001 From: Gennady Lipenkov <xgen@yandex-team.ru> Date: Sat, 13 Jan 2018 01:53:49 +0300 Subject: [PATCH 0381/1007] Support 'trusted_certs_dir' chef-client configuration option --- provisioner/chef-client/provisioner.go | 28 +++++++++++++------ .../docs/provisioners/chef-client.html.md | 9 ++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index c7bd865dd..7feab150c 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -63,6 +63,7 @@ type Config struct { SkipCleanNode bool `mapstructure:"skip_clean_node"` SkipInstall bool `mapstructure:"skip_install"` SslVerifyMode string `mapstructure:"ssl_verify_mode"` + TrustedCertsDir string `mapstructure:"trusted_certs_dir"` StagingDir string `mapstructure:"staging_directory"` ValidationClientName string `mapstructure:"validation_client_name"` ValidationKeyPath string `mapstructure:"validation_key_path"` @@ -83,6 +84,7 @@ type ConfigTemplate struct { NodeName string ServerUrl string SslVerifyMode string + TrustedCertsDir string ValidationClientName string ValidationKeyPath string } @@ -268,7 +270,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { remoteValidationKeyPath, p.config.ValidationClientName, p.config.ChefEnvironment, - p.config.SslVerifyMode) + p.config.SslVerifyMode, + p.config.TrustedCertsDir) if err != nil { return fmt.Errorf("Error creating Chef config file: %s", err) } @@ -283,7 +286,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { if !(p.config.SkipCleanNode && p.config.SkipCleanClient) { knifeConfigPath, knifeErr := p.createKnifeConfig( - ui, comm, nodeName, serverUrl, p.config.ClientKey, p.config.SslVerifyMode) + ui, comm, nodeName, serverUrl, p.config.ClientKey, p.config.SslVerifyMode, p.config.TrustedCertsDir) if knifeErr != nil { return fmt.Errorf("Error creating knife config on node: %s", knifeErr) @@ -341,7 +344,8 @@ func (p *Provisioner) createConfig( remoteKeyPath string, validationClientName string, chefEnvironment string, - sslVerifyMode string) (string, error) { + sslVerifyMode string, + trustedCertsDir string) (string, error) { ui.Message("Creating configuration file 'client.rb'") @@ -371,6 +375,7 @@ func (p *Provisioner) createConfig( ValidationClientName: validationClientName, ChefEnvironment: chefEnvironment, SslVerifyMode: sslVerifyMode, + TrustedCertsDir: trustedCertsDir, EncryptedDataBagSecretPath: encryptedDataBagSecretPath, } configString, err := interpolate.Render(tpl, &ctx) @@ -386,7 +391,7 @@ func (p *Provisioner) createConfig( return remotePath, nil } -func (p *Provisioner) createKnifeConfig(ui packer.Ui, comm packer.Communicator, nodeName string, serverUrl string, clientKey string, sslVerifyMode string) (string, error) { +func (p *Provisioner) createKnifeConfig(ui packer.Ui, comm packer.Communicator, nodeName string, serverUrl string, clientKey string, sslVerifyMode string, trustedCertsDir string) (string, error) { ui.Message("Creating configuration file 'knife.rb'") // Read the template @@ -394,10 +399,11 @@ func (p *Provisioner) createKnifeConfig(ui packer.Ui, comm packer.Communicator, ctx := p.config.ctx ctx.Data = &ConfigTemplate{ - NodeName: nodeName, - ServerUrl: serverUrl, - ClientKey: clientKey, - SslVerifyMode: sslVerifyMode, + NodeName: nodeName, + ServerUrl: serverUrl, + ClientKey: clientKey, + SslVerifyMode: sslVerifyMode, + TrustedCertsDir: trustedCertsDir, } configString, err := interpolate.Render(tpl, &ctx) if err != nil { @@ -685,6 +691,9 @@ environment "{{.ChefEnvironment}}" {{if ne .SslVerifyMode ""}} ssl_verify_mode :{{.SslVerifyMode}} {{end}} +{{if ne .TrustedCertsDir ""}} +trusted_certs_dir "{{.TrustedCertsDir}}" +{{end}} ` var DefaultKnifeTemplate = ` @@ -696,4 +705,7 @@ node_name "{{.NodeName}}" {{if ne .SslVerifyMode ""}} ssl_verify_mode :{{.SslVerifyMode}} {{end}} +{{if ne .TrustedCertsDir ""}} +trusted_certs_dir "{{.TrustedCertsDir}}" +{{end}} ` diff --git a/website/source/docs/provisioners/chef-client.html.md b/website/source/docs/provisioners/chef-client.html.md index 05898263e..566742490 100644 --- a/website/source/docs/provisioners/chef-client.html.md +++ b/website/source/docs/provisioners/chef-client.html.md @@ -105,6 +105,11 @@ configuration is actually required. SSL certificates. If not set, this defaults to "verify\_peer" which validates all SSL certifications. +- `trusted_certs_dir` (string) - This is a directory that contains additional + SSL certificates to trust. Any certificates in this directory will be added to + whatever CA bundle ruby is using. Use this to add self-signed certs for your + Chef Server or local HTTP file servers. + - `staging_directory` (string) - This is the directory where all the configuration of Chef by Packer will be placed. By default this is "/tmp/packer-chef-client" when guest\_os\_type unix and @@ -158,6 +163,9 @@ environment "{{.ChefEnvironment}}" {{if ne .SslVerifyMode ""}} ssl_verify_mode :{{.SslVerifyMode}} {{end}} +{{if ne .TrustedCertsDir ""}} +trusted_certs_dir :{{.TrustedCertsDir}} +{{end}} ``` This template is a [configuration @@ -170,6 +178,7 @@ variables available to use: - `NodeName` - The node name set in the configuration. - `ServerUrl` - The URL of the Chef Server set in the configuration. - `SslVerifyMode` - Whether Chef SSL verify mode is on or off. +- `TrustedCertsDir` - Path to dir with trusted certificates. - `ValidationClientName` - The name of the client used for validation. - `ValidationKeyPath` - Path to the validation key, if it is set. From cea2ab8c6d71ec93c91269610c0bd7f72de6c838 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 15:10:51 -0800 Subject: [PATCH 0382/1007] move kms/encrypted validation to block devices --- builder/amazon/common/block_device.go | 22 +++++++++++++++++++++- builder/amazon/ebsvolume/builder.go | 9 ++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/builder/amazon/common/block_device.go b/builder/amazon/common/block_device.go index cb490c3d4..c88e1cbb5 100644 --- a/builder/amazon/common/block_device.go +++ b/builder/amazon/common/block_device.go @@ -1,6 +1,7 @@ package common import ( + "fmt" "strings" "github.com/aws/aws-sdk-go/aws" @@ -86,10 +87,29 @@ func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping { return blockDevices } -func (b *BlockDevices) Prepare(ctx *interpolate.Context) []error { +func (b *BlockDevice) Prepare(ctx *interpolate.Context) error { + // Warn that encrypted must be true when setting kms_key_id + if b.KmsKeyId != "" && b.Encrypted == false { + return fmt.Errorf("The device %v, must also have `encrypted: "+ + "true` when setting a kms_key_id.", b.DeviceName) + } return nil } +func (b *BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) { + for _, d := range b.AMIMappings { + if err := d.Prepare(ctx); err != nil { + errs = append(errs, fmt.Errorf("AMIMapping: %s", err.Error())) + } + } + for _, d := range b.LaunchMappings { + if err := d.Prepare(ctx); err != nil { + errs = append(errs, fmt.Errorf("LaunchMapping: %s", err.Error())) + } + } + return errs +} + func (b *AMIBlockDevices) BuildAMIDevices() []*ec2.BlockDeviceMapping { return buildBlockDevices(b.AMIMappings) } diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index d8f905f6c..b95af11f8 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -56,12 +56,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { var errs *packer.MultiError errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.launchBlockDevices.Prepare(&b.config.ctx)...) - // Warn that encrypted must be true when setting kms_key_id - for _, device := range b.config.VolumeMappings { - if device.KmsKeyId != "" && device.Encrypted == false { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("The device %v, must also have `encrypted: "+ - "true` when setting a kms_key_id.", device.DeviceName)) + for _, d := range b.config.VolumeMappings { + if err := d.Prepare(&b.config.ctx); err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("AMIMapping: %s", err.Error())) } } From e222d60b5a41da15c8c7b4c7c23a10effb7fe5d5 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 15:11:50 -0800 Subject: [PATCH 0383/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 429a3c842..b3920501e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * post-processor/docker: Remove credentials from being shown in the log. [GH-5666] * builder/amazon: Warn during prepare if we didn't get both an access key and a secret key when we were expecting one. [GH-5762] * builder/amazon: Replace `InstanceStatusOK` check with `InstanceReady`. This reduces build times universally while still working for all instance types. [GH-5678] +* builder/amazon: Add `kms_key_id` option to block device mappings. [GH-5774] ### BUG FIXES: From 9c728750762bcb83e028188496212a63b4234bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Sun, 14 Jan 2018 16:08:06 +0900 Subject: [PATCH 0384/1007] Add tablewriter package --- vendor/github.com/mattn/go-runewidth/LICENSE | 21 + .../github.com/mattn/go-runewidth/README.mkd | 27 + .../mattn/go-runewidth/runewidth.go | 1224 +++++++++++++++++ .../mattn/go-runewidth/runewidth_js.go | 8 + .../mattn/go-runewidth/runewidth_posix.go | 77 ++ .../mattn/go-runewidth/runewidth_windows.go | 25 + .../olekukonko/tablewriter/LICENCE.md | 19 + .../olekukonko/tablewriter/README.md | 279 ++++ .../github.com/olekukonko/tablewriter/csv.go | 52 + .../olekukonko/tablewriter/table.go | 798 +++++++++++ .../tablewriter/table_with_color.go | 134 ++ .../olekukonko/tablewriter/test.csv | 4 + .../olekukonko/tablewriter/test_info.csv | 4 + .../github.com/olekukonko/tablewriter/util.go | 72 + .../github.com/olekukonko/tablewriter/wrap.go | 104 ++ vendor/vendor.json | 12 + 16 files changed, 2860 insertions(+) create mode 100644 vendor/github.com/mattn/go-runewidth/LICENSE create mode 100644 vendor/github.com/mattn/go-runewidth/README.mkd create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go create mode 100644 vendor/github.com/olekukonko/tablewriter/LICENCE.md create mode 100644 vendor/github.com/olekukonko/tablewriter/README.md create mode 100644 vendor/github.com/olekukonko/tablewriter/csv.go create mode 100644 vendor/github.com/olekukonko/tablewriter/table.go create mode 100644 vendor/github.com/olekukonko/tablewriter/table_with_color.go create mode 100644 vendor/github.com/olekukonko/tablewriter/test.csv create mode 100644 vendor/github.com/olekukonko/tablewriter/test_info.csv create mode 100644 vendor/github.com/olekukonko/tablewriter/util.go create mode 100644 vendor/github.com/olekukonko/tablewriter/wrap.go diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE new file mode 100644 index 000000000..91b5cef30 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-runewidth/README.mkd b/vendor/github.com/mattn/go-runewidth/README.mkd new file mode 100644 index 000000000..66663a94b --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/README.mkd @@ -0,0 +1,27 @@ +go-runewidth +============ + +[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) +[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) +[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) +[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) + +Provides functions to get fixed width of the character or string. + +Usage +----- + +```go +runewidth.StringWidth("つのだ☆HIRO") == 12 +``` + + +Author +------ + +Yasuhiro Matsumoto + +License +------- + +under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go new file mode 100644 index 000000000..a16f1af0e --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -0,0 +1,1224 @@ +package runewidth + +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth = IsEastAsian() + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{EastAsianWidth} +) + +type interval struct { + first rune + last rune +} + +type table []interval + +func inTables(r rune, ts ...table) bool { + for _, t := range ts { + if inTable(r, t) { + return true + } + } + return false +} + +func inTable(r rune, t table) bool { + // func (t table) IncludesRune(r rune) bool { + if r < t[0].first { + return false + } + + bot := 0 + top := len(t) - 1 + for top >= bot { + mid := (bot + top) / 2 + + switch { + case t[mid].last < r: + bot = mid + 1 + case t[mid].first > r: + top = mid - 1 + default: + return true + } + } + + return false +} + +var private = table{ + {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, +} + +var nonprint = table{ + {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, + {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, + {0x2028, 0x2029}, + {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, +} + +var combining = table{ + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, + {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, + {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, + {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, + {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, + {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, + {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, + {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, + {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, + {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, + {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, + {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, + {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, + {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, + {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, + {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, + {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, + {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, + {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, + {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, + {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, + {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, + {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, + {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, + {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, + {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, + {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, + {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, + {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, + {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, + {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, + {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, + {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, + {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, + {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, + {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, + {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, + {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, + {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, + {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, + {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, + {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, + {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, + {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, + {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, + {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, + {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, + {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, + {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, + {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, + {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, + {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, + {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, + {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, + {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, + {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, + {0xE0100, 0xE01EF}, +} + +var doublewidth = table{ + {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, + {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, + {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, + {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, + {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, + {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, + {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, + {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, + {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, + {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, + {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, + {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, + {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +} + +var ambiguous = table{ + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, + {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, + {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, + {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, + {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, + {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, + {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, + {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, + {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, + {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, + {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, + {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, + {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, + {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, + {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, + {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, + {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, + {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, + {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, + {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, + {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, + {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, + {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, + {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, + {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, + {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, + {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, + {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, + {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, + {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, + {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, + {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, +} + +var emoji = table{ + {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, + {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, + {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, + {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, + {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, + {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, + {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, + {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, + {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, + {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, + {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, + {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, + {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, +} + +var notassigned = table{ + {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, + {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, + {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, + {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, + {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, + {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, + {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, + {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, + {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, + {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, + {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, + {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, + {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, + {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, + {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, + {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, + {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, + {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, + {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, + {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, + {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, + {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, + {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, + {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, + {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, + {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, + {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, + {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, + {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, + {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, + {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, + {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, + {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, + {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, + {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, + {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, + {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, + {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, + {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, + {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, + {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, + {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, + {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, + {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, + {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, + {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, + {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, + {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, + {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, + {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, + {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, + {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, + {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, + {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, + {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, + {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, + {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, + {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, + {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, + {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, + {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, + {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, + {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, + {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, + {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, + {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, + {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, + {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, + {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, + {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, + {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, + {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, + {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, + {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, + {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, + {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, + {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, + {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, + {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, + {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, + {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, + {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, + {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, + {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, + {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, + {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, + {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, + {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, + {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, + {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, + {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, + {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, + {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, + {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, + {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, + {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, + {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, + {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, + {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, + {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, + {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, + {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, + {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, + {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, + {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, + {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, + {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, + {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, + {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, + {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, + {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, + {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, + {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, + {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, + {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, + {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, + {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, + {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, + {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, + {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, + {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, + {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, + {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, + {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, + {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, + {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, + {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, + {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, + {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, + {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, + {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, + {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, + {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, + {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, + {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, + {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, + {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, + {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, + {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, + {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, + {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, + {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, + {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, + {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, + {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, + {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, + {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, + {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, + {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, + {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, + {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, + {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, + {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, + {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, + {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, + {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, + {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, + {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, + {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, + {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, + {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, + {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, + {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, + {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, + {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, + {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, + {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, + {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, + {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, + {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, + {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, + {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, + {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, + {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, + {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, + {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, + {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, + {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, + {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, + {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, + {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, + {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, + {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, + {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, + {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, + {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, + {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, + {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, + {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, + {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, + {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, + {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, + {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, + {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, + {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, + {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, + {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, + {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, + {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, + {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, + {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, + {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, + {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, + {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, + {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, + {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, + {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, + {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, + {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, + {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, + {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, + {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, + {0xFFFFE, 0xFFFFF}, +} + +var neutral = table{ + {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, + {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, + {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, + {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, + {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, + {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, + {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, + {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, + {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, + {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, + {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, + {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, + {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, + {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, + {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, + {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, + {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, + {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, + {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, + {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, + {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, + {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, + {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, + {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, + {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, + {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, + {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, + {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, + {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, + {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, + {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, + {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, + {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, + {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, + {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, + {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, + {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, + {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, + {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, + {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, + {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, + {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, + {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, + {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, + {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, + {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, + {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, + {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, + {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, + {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, + {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, + {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, + {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, + {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, + {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, + {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, + {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, + {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, + {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, + {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, + {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, + {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, + {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, + {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, + {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, + {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, + {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, + {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, + {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, + {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, + {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, + {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, + {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, + {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, + {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, + {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, + {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, + {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, + {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, + {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, + {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, + {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, + {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, + {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, + {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, + {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, + {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, + {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, + {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, + {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, + {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, + {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, + {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, + {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, + {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, + {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, + {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, + {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, + {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, + {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, + {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, + {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, + {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, + {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, + {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, + {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, + {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, + {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, + {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, + {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, + {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, + {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, + {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, + {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, + {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, + {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, + {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, + {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, + {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, + {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, + {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, + {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, + {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, + {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, + {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, + {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, + {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, + {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, + {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, + {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, + {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, + {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, + {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, + {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, + {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, + {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, + {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, + {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, + {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, + {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, + {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, + {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, + {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, + {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, + {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, + {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, + {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, + {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, + {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, + {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, + {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, + {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, + {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, + {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, + {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, + {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, + {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, + {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, + {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, + {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, + {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, + {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, + {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, + {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, + {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, + {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, + {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, + {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, + {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, + {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, + {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, + {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, + {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, + {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, + {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, + {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, + {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, + {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, + {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, + {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, + {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, + {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, + {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, + {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, + {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, + {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, + {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, + {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, + {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, + {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, + {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, + {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, + {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, + {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, + {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, + {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, + {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, + {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, + {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, + {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, + {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, + {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, + {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, + {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, + {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, + {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, + {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, + {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, + {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, + {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, + {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, + {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, + {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, + {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, + {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, + {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, + {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, + {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, + {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, + {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, + {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, + {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, + {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, + {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, + {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, + {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, + {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, + {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, + {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, + {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, + {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, + {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, + {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, + {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, + {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, + {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, + {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, + {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, + {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, + {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, + {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, + {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, + {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, + {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, + {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, + {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, + {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, + {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, + {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, + {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, + {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, + {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, + {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, + {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, + {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, + {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, + {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, + {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, + {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, + {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, + {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, + {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, + {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, + {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, + {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, + {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, + {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, + {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, + {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, + {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, + {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, + {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, + {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, + {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, + {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, + {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, + {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, + {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, + {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, + {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, + {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, + {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, + {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, + {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, + {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, + {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, + {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, + {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, + {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, + {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, + {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, + {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, + {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, + {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, + {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, + {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, + {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, + {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, + {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, + {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, + {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, + {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, + {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, + {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, + {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, + {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, + {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, + {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, + {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, + {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, + {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, + {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, + {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, + {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, + {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, + {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, + {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, + {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, + {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, + {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, + {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, + {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, + {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, + {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, + {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, + {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, + {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, + {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, + {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, + {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, + {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, + {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, + {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, + {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, + {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, + {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, + {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, + {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, + {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, + {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, + {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, + {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, + {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, + {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, + {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, + {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, + {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, + {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, + {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, + {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, + {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, + {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, + {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, + {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, + {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, + {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, + {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, + {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, + {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, + {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, + {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, + {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, + {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, + {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, + {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, + {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, + {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, + {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, + {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, + {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, + {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, + {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, + {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, + {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, + {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, + {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, + {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, + {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, + {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, + {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, + {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, + {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, + {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, + {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, + {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, + {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, + {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, + {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, + {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, + {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, + {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, + {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, + {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, + {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, + {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, + {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, + {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, + {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, + {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, + {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, + {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, + {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, + {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, + {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, + {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, + {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, + {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, + {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, + {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, + {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, + {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, + {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, + {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, + {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, + {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, + {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, + {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, + {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, + {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, + {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, + {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, + {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, + {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, + {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, + {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, + {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, + {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, + {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, + {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, + {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, + {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, + {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, + {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, + {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, + {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, + {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, + {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, + {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, + {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, + {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, + {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, + {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, + {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, + {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, + {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, + {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, + {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, + {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, + {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, + {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, + {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, + {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, + {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, + {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, + {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, + {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, + {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, + {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, + {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, + {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, + {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, + {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, + {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, + {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, + {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, + {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, + {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, + {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, + {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, + {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, + {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, + {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, + {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, + {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, + {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, + {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, + {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, + {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, + {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, + {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, + {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, + {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, + {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, + {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, + {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, + {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, + {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, + {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, + {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, + {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, + {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, + {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, + {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, + {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, + {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, + {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, + {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, + {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, + {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, + {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, + {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, + {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, + {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, + {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, + {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, + {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, + {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, + {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, + {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, + {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, + {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, + {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, + {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, + {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, + {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, + {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, + {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, + {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, + {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, + {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, + {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, + {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, + {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, + {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, + {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, + {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, + {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, + {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, + {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, + {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, + {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, + {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, + {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, + {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, + {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, + {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, + {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, + {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, + {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, + {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, + {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, + {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, + {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, + {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, + {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, + {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, + {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, + {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, + {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, + {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, + {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, + {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, + {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, + {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, + {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, + {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, + {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, + {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, + {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, + {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, + {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, + {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, + {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, + {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, + {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, + {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, + {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, + {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, + {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, + {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, + {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, + {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, + {0xE0020, 0xE007F}, +} + +// Condition have flag EastAsianWidth whether the current locale is CJK or not. +type Condition struct { + EastAsianWidth bool +} + +// NewCondition return new instance of Condition which is current locale. +func NewCondition() *Condition { + return &Condition{EastAsianWidth} +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func (c *Condition) RuneWidth(r rune) int { + switch { + case r < 0 || r > 0x10FFFF || + inTables(r, nonprint, combining, notassigned): + return 0 + case (c.EastAsianWidth && IsAmbiguousWidth(r)) || + inTables(r, doublewidth, emoji): + return 2 + default: + return 1 + } +} + +// StringWidth return width as you can see +func (c *Condition) StringWidth(s string) (width int) { + for _, r := range []rune(s) { + width += c.RuneWidth(r) + } + return width +} + +// Truncate return string truncated with w cells +func (c *Condition) Truncate(s string, w int, tail string) string { + if c.StringWidth(s) <= w { + return s + } + r := []rune(s) + tw := c.StringWidth(tail) + w -= tw + width := 0 + i := 0 + for ; i < len(r); i++ { + cw := c.RuneWidth(r[i]) + if width+cw > w { + break + } + width += cw + } + return string(r[0:i]) + tail +} + +// Wrap return string wrapped with w cells +func (c *Condition) Wrap(s string, w int) string { + width := 0 + out := "" + for _, r := range []rune(s) { + cw := RuneWidth(r) + if r == '\n' { + out += string(r) + width = 0 + continue + } else if width+cw > w { + out += "\n" + width = 0 + out += string(r) + width += cw + continue + } + out += string(r) + width += cw + } + return out +} + +// FillLeft return string filled in left by spaces in w cells +func (c *Condition) FillLeft(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return string(b) + s + } + return s +} + +// FillRight return string filled in left by spaces in w cells +func (c *Condition) FillRight(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return s + string(b) + } + return s +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func RuneWidth(r rune) int { + return DefaultCondition.RuneWidth(r) +} + +// IsAmbiguousWidth returns whether is ambiguous width or not. +func IsAmbiguousWidth(r rune) bool { + return inTables(r, private, ambiguous) +} + +// IsNeutralWidth returns whether is neutral width or not. +func IsNeutralWidth(r rune) bool { + return inTable(r, neutral) +} + +// StringWidth return width as you can see +func StringWidth(s string) (width int) { + return DefaultCondition.StringWidth(s) +} + +// Truncate return string truncated with w cells +func Truncate(s string, w int, tail string) string { + return DefaultCondition.Truncate(s, w, tail) +} + +// Wrap return string wrapped with w cells +func Wrap(s string, w int) string { + return DefaultCondition.Wrap(s, w) +} + +// FillLeft return string filled in left by spaces in w cells +func FillLeft(s string, w int) string { + return DefaultCondition.FillLeft(s, w) +} + +// FillRight return string filled in left by spaces in w cells +func FillRight(s string, w int) string { + return DefaultCondition.FillRight(s, w) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go new file mode 100644 index 000000000..0ce32c5e7 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go @@ -0,0 +1,8 @@ +// +build js + +package runewidth + +func IsEastAsian() bool { + // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go new file mode 100644 index 000000000..c579e9a31 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go @@ -0,0 +1,77 @@ +// +build !windows,!js + +package runewidth + +import ( + "os" + "regexp" + "strings" +) + +var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) + +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} + +func isEastAsian(locale string) bool { + charset := strings.ToLower(locale) + r := reLoc.FindStringSubmatch(locale) + if len(r) == 2 { + charset = strings.ToLower(r[1]) + } + + if strings.HasSuffix(charset, "@cjk_narrow") { + return false + } + + for pos, b := range []byte(charset) { + if b == '@' { + charset = charset[:pos] + break + } + } + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m + } + if max > 1 && (charset[0] != 'u' || + strings.HasPrefix(locale, "ja") || + strings.HasPrefix(locale, "ko") || + strings.HasPrefix(locale, "zh")) { + return true + } + return false +} + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_CTYPE") + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go new file mode 100644 index 000000000..0258876b9 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go @@ -0,0 +1,25 @@ +package runewidth + +import ( + "syscall" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") +) + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + r1, _, _ := procGetConsoleOutputCP.Call() + if r1 == 0 { + return false + } + + switch int(r1) { + case 932, 51932, 936, 949, 950: + return true + } + + return false +} diff --git a/vendor/github.com/olekukonko/tablewriter/LICENCE.md b/vendor/github.com/olekukonko/tablewriter/LICENCE.md new file mode 100644 index 000000000..1fd848425 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/LICENCE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 by Oleku Konko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/olekukonko/tablewriter/README.md b/vendor/github.com/olekukonko/tablewriter/README.md new file mode 100644 index 000000000..ae12208be --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/README.md @@ -0,0 +1,279 @@ +ASCII Table Writer +========= + +[![Build Status](https://travis-ci.org/olekukonko/tablewriter.png?branch=master)](https://travis-ci.org/olekukonko/tablewriter) +[![Total views](https://img.shields.io/sourcegraph/rrc/github.com/olekukonko/tablewriter.svg)](https://sourcegraph.com/github.com/olekukonko/tablewriter) +[![Godoc](https://godoc.org/github.com/olekukonko/tablewriter?status.svg)](https://godoc.org/github.com/olekukonko/tablewriter) + +Generate ASCII table on the fly ... Installation is simple as + + go get github.com/olekukonko/tablewriter + + +#### Features +- Automatic Padding +- Support Multiple Lines +- Supports Alignment +- Support Custom Separators +- Automatic Alignment of numbers & percentage +- Write directly to http , file etc via `io.Writer` +- Read directly from CSV file +- Optional row line via `SetRowLine` +- Normalise table header +- Make CSV Headers optional +- Enable or disable table border +- Set custom footer support +- Optional identical cells merging +- Set custom caption + + +#### Example 1 - Basic +```go +data := [][]string{ + []string{"A", "The Good", "500"}, + []string{"B", "The Very very Bad Man", "288"}, + []string{"C", "The Ugly", "120"}, + []string{"D", "The Gopher", "800"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Name", "Sign", "Rating"}) + +for _, v := range data { + table.Append(v) +} +table.Render() // Send output +``` + +##### Output 1 +``` ++------+-----------------------+--------+ +| NAME | SIGN | RATING | ++------+-----------------------+--------+ +| A | The Good | 500 | +| B | The Very very Bad Man | 288 | +| C | The Ugly | 120 | +| D | The Gopher | 800 | ++------+-----------------------+--------+ +``` + +#### Example 2 - Without Border / Footer / Bulk Append +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "2233", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2233", "$54.95"}, + []string{"1/4/2014", "February Hosting", "2233", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer +table.SetBorder(false) // Set Border to false +table.AppendBulk(data) // Add Bulk Data +table.Render() +``` + +##### Output 2 +``` + + DATE | DESCRIPTION | CV2 | AMOUNT ++----------+--------------------------+-------+---------+ + 1/1/2014 | Domain name | 2233 | $10.98 + 1/1/2014 | January Hosting | 2233 | $54.95 + 1/4/2014 | February Hosting | 2233 | $51.00 + 1/4/2014 | February Extra Bandwidth | 2233 | $30.00 ++----------+--------------------------+-------+---------+ + TOTAL | $146 93 + +-------+---------+ + +``` + + +#### Example 3 - CSV +```go +table, _ := tablewriter.NewCSV(os.Stdout, "test_info.csv", true) +table.SetAlignment(tablewriter.ALIGN_LEFT) // Set Alignment +table.Render() +``` + +##### Output 3 +``` ++----------+--------------+------+-----+---------+----------------+ +| FIELD | TYPE | NULL | KEY | DEFAULT | EXTRA | ++----------+--------------+------+-----+---------+----------------+ +| user_id | smallint(5) | NO | PRI | NULL | auto_increment | +| username | varchar(10) | NO | | NULL | | +| password | varchar(100) | NO | | NULL | | ++----------+--------------+------+-----+---------+----------------+ +``` + +#### Example 4 - Custom Separator +```go +table, _ := tablewriter.NewCSV(os.Stdout, "test.csv", true) +table.SetRowLine(true) // Enable row line + +// Change table lines +table.SetCenterSeparator("*") +table.SetColumnSeparator("‡") +table.SetRowSeparator("-") + +table.SetAlignment(tablewriter.ALIGN_LEFT) +table.Render() +``` + +##### Output 4 +``` +*------------*-----------*---------* +╪ FIRST NAME ╪ LAST NAME ╪ SSN ╪ +*------------*-----------*---------* +╪ John ╪ Barry ╪ 123456 ╪ +*------------*-----------*---------* +╪ Kathy ╪ Smith ╪ 687987 ╪ +*------------*-----------*---------* +╪ Bob ╪ McCornick ╪ 3979870 ╪ +*------------*-----------*---------* +``` + +#### Example 5 - Markdown Format +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "2233", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2233", "$54.95"}, + []string{"1/4/2014", "February Hosting", "2233", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) +table.SetCenterSeparator("|") +table.AppendBulk(data) // Add Bulk Data +table.Render() +``` + +##### Output 5 +``` +| DATE | DESCRIPTION | CV2 | AMOUNT | +|----------|--------------------------|------|--------| +| 1/1/2014 | Domain name | 2233 | $10.98 | +| 1/1/2014 | January Hosting | 2233 | $54.95 | +| 1/4/2014 | February Hosting | 2233 | $51.00 | +| 1/4/2014 | February Extra Bandwidth | 2233 | $30.00 | +``` + +#### Example 6 - Identical cells merging +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "1234", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2345", "$54.95"}, + []string{"1/4/2014", "February Hosting", "3456", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "4567", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetFooter([]string{"", "", "Total", "$146.93"}) +table.SetAutoMergeCells(true) +table.SetRowLine(true) +table.AppendBulk(data) +table.Render() +``` + +##### Output 6 +``` ++----------+--------------------------+-------+---------+ +| DATE | DESCRIPTION | CV2 | AMOUNT | ++----------+--------------------------+-------+---------+ +| 1/1/2014 | Domain name | 1234 | $10.98 | ++ +--------------------------+-------+---------+ +| | January Hosting | 2345 | $54.95 | ++----------+--------------------------+-------+---------+ +| 1/4/2014 | February Hosting | 3456 | $51.00 | ++ +--------------------------+-------+---------+ +| | February Extra Bandwidth | 4567 | $30.00 | ++----------+--------------------------+-------+---------+ +| TOTAL | $146 93 | ++----------+--------------------------+-------+---------+ +``` + + +#### Table with color +```go +data := [][]string{ + []string{"1/1/2014", "Domain name", "2233", "$10.98"}, + []string{"1/1/2014", "January Hosting", "2233", "$54.95"}, + []string{"1/4/2014", "February Hosting", "2233", "$51.00"}, + []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Date", "Description", "CV2", "Amount"}) +table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer +table.SetBorder(false) // Set Border to false + +table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor}, + tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor}, + tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor}, + tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor}) + +table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor}) + +table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{}, + tablewriter.Colors{tablewriter.Bold}, + tablewriter.Colors{tablewriter.FgHiRedColor}) + +table.AppendBulk(data) +table.Render() +``` + +#### Table with color Output +![Table with Color](https://cloud.githubusercontent.com/assets/6460392/21101956/bbc7b356-c0a1-11e6-9f36-dba694746efc.png) + +#### Example 6 - Set table caption +```go +data := [][]string{ + []string{"A", "The Good", "500"}, + []string{"B", "The Very very Bad Man", "288"}, + []string{"C", "The Ugly", "120"}, + []string{"D", "The Gopher", "800"}, +} + +table := tablewriter.NewWriter(os.Stdout) +table.SetHeader([]string{"Name", "Sign", "Rating"}) +table.SetCaption(true, "Movie ratings.") + +for _, v := range data { + table.Append(v) +} +table.Render() // Send output +``` + +Note: Caption text will wrap with total width of rendered table. + +##### Output 6 +``` ++------+-----------------------+--------+ +| NAME | SIGN | RATING | ++------+-----------------------+--------+ +| A | The Good | 500 | +| B | The Very very Bad Man | 288 | +| C | The Ugly | 120 | +| D | The Gopher | 800 | ++------+-----------------------+--------+ +Movie ratings. +``` + +#### TODO +- ~~Import Directly from CSV~~ - `done` +- ~~Support for `SetFooter`~~ - `done` +- ~~Support for `SetBorder`~~ - `done` +- ~~Support table with uneven rows~~ - `done` +- Support custom alignment +- General Improvement & Optimisation +- `NewHTML` Parse table from HTML + + diff --git a/vendor/github.com/olekukonko/tablewriter/csv.go b/vendor/github.com/olekukonko/tablewriter/csv.go new file mode 100644 index 000000000..98878303b --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/csv.go @@ -0,0 +1,52 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +package tablewriter + +import ( + "encoding/csv" + "io" + "os" +) + +// Start A new table by importing from a CSV file +// Takes io.Writer and csv File name +func NewCSV(writer io.Writer, fileName string, hasHeader bool) (*Table, error) { + file, err := os.Open(fileName) + if err != nil { + return &Table{}, err + } + defer file.Close() + csvReader := csv.NewReader(file) + t, err := NewCSVReader(writer, csvReader, hasHeader) + return t, err +} + +// Start a New Table Writer with csv.Reader +// This enables customisation such as reader.Comma = ';' +// See http://golang.org/src/pkg/encoding/csv/reader.go?s=3213:3671#L94 +func NewCSVReader(writer io.Writer, csvReader *csv.Reader, hasHeader bool) (*Table, error) { + t := NewWriter(writer) + if hasHeader { + // Read the first row + headers, err := csvReader.Read() + if err != nil { + return &Table{}, err + } + t.SetHeader(headers) + } + for { + record, err := csvReader.Read() + if err == io.EOF { + break + } else if err != nil { + return &Table{}, err + } + t.Append(record) + } + return t, nil +} diff --git a/vendor/github.com/olekukonko/tablewriter/table.go b/vendor/github.com/olekukonko/tablewriter/table.go new file mode 100644 index 000000000..8b62c628c --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/table.go @@ -0,0 +1,798 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +// Create & Generate text based table +package tablewriter + +import ( + "bytes" + "fmt" + "io" + "regexp" + "strings" +) + +const ( + MAX_ROW_WIDTH = 30 +) + +const ( + CENTER = "+" + ROW = "-" + COLUMN = "|" + SPACE = " " + NEWLINE = "\n" +) + +const ( + ALIGN_DEFAULT = iota + ALIGN_CENTER + ALIGN_RIGHT + ALIGN_LEFT +) + +var ( + decimal = regexp.MustCompile(`^-*\d*\.?\d*$`) + percent = regexp.MustCompile(`^-*\d*\.?\d*$%$`) +) + +type Border struct { + Left bool + Right bool + Top bool + Bottom bool +} + +type Table struct { + out io.Writer + rows [][]string + lines [][][]string + cs map[int]int + rs map[int]int + headers []string + footers []string + caption bool + captionText string + autoFmt bool + autoWrap bool + mW int + pCenter string + pRow string + pColumn string + tColumn int + tRow int + hAlign int + fAlign int + align int + newLine string + rowLine bool + autoMergeCells bool + hdrLine bool + borders Border + colSize int + headerParams []string + columnsParams []string + footerParams []string + columnsAlign []int +} + +// Start New Table +// Take io.Writer Directly +func NewWriter(writer io.Writer) *Table { + t := &Table{ + out: writer, + rows: [][]string{}, + lines: [][][]string{}, + cs: make(map[int]int), + rs: make(map[int]int), + headers: []string{}, + footers: []string{}, + caption: false, + captionText: "Table caption.", + autoFmt: true, + autoWrap: true, + mW: MAX_ROW_WIDTH, + pCenter: CENTER, + pRow: ROW, + pColumn: COLUMN, + tColumn: -1, + tRow: -1, + hAlign: ALIGN_DEFAULT, + fAlign: ALIGN_DEFAULT, + align: ALIGN_DEFAULT, + newLine: NEWLINE, + rowLine: false, + hdrLine: true, + borders: Border{Left: true, Right: true, Bottom: true, Top: true}, + colSize: -1, + headerParams: []string{}, + columnsParams: []string{}, + footerParams: []string{}, + columnsAlign: []int{}} + return t +} + +// Render table output +func (t *Table) Render() { + if t.borders.Top { + t.printLine(true) + } + t.printHeading() + if t.autoMergeCells { + t.printRowsMergeCells() + } else { + t.printRows() + } + if !t.rowLine && t.borders.Bottom { + t.printLine(true) + } + t.printFooter() + + if t.caption { + t.printCaption() + } +} + +// Set table header +func (t *Table) SetHeader(keys []string) { + t.colSize = len(keys) + for i, v := range keys { + t.parseDimension(v, i, -1) + t.headers = append(t.headers, v) + } +} + +// Set table Footer +func (t *Table) SetFooter(keys []string) { + //t.colSize = len(keys) + for i, v := range keys { + t.parseDimension(v, i, -1) + t.footers = append(t.footers, v) + } +} + +// Set table Caption +func (t *Table) SetCaption(caption bool, captionText ...string) { + t.caption = caption + if len(captionText) == 1 { + t.captionText = captionText[0] + } +} + +// Turn header autoformatting on/off. Default is on (true). +func (t *Table) SetAutoFormatHeaders(auto bool) { + t.autoFmt = auto +} + +// Turn automatic multiline text adjustment on/off. Default is on (true). +func (t *Table) SetAutoWrapText(auto bool) { + t.autoWrap = auto +} + +// Set the Default column width +func (t *Table) SetColWidth(width int) { + t.mW = width +} + +// Set the minimal width for a column +func (t *Table) SetColMinWidth(column int, width int) { + t.cs[column] = width +} + +// Set the Column Separator +func (t *Table) SetColumnSeparator(sep string) { + t.pColumn = sep +} + +// Set the Row Separator +func (t *Table) SetRowSeparator(sep string) { + t.pRow = sep +} + +// Set the center Separator +func (t *Table) SetCenterSeparator(sep string) { + t.pCenter = sep +} + +// Set Header Alignment +func (t *Table) SetHeaderAlignment(hAlign int) { + t.hAlign = hAlign +} + +// Set Footer Alignment +func (t *Table) SetFooterAlignment(fAlign int) { + t.fAlign = fAlign +} + +// Set Table Alignment +func (t *Table) SetAlignment(align int) { + t.align = align +} + +func (t *Table) SetColumnAlignment(keys []int) { + for _, v := range keys { + switch v { + case ALIGN_CENTER: + break + case ALIGN_LEFT: + break + case ALIGN_RIGHT: + break + default: + v = ALIGN_DEFAULT + } + t.columnsAlign = append(t.columnsAlign, v) + } +} + +// Set New Line +func (t *Table) SetNewLine(nl string) { + t.newLine = nl +} + +// Set Header Line +// This would enable / disable a line after the header +func (t *Table) SetHeaderLine(line bool) { + t.hdrLine = line +} + +// Set Row Line +// This would enable / disable a line on each row of the table +func (t *Table) SetRowLine(line bool) { + t.rowLine = line +} + +// Set Auto Merge Cells +// This would enable / disable the merge of cells with identical values +func (t *Table) SetAutoMergeCells(auto bool) { + t.autoMergeCells = auto +} + +// Set Table Border +// This would enable / disable line around the table +func (t *Table) SetBorder(border bool) { + t.SetBorders(Border{border, border, border, border}) +} + +func (t *Table) SetBorders(border Border) { + t.borders = border +} + +// Append row to table +func (t *Table) Append(row []string) { + rowSize := len(t.headers) + if rowSize > t.colSize { + t.colSize = rowSize + } + + n := len(t.lines) + line := [][]string{} + for i, v := range row { + + // Detect string width + // Detect String height + // Break strings into words + out := t.parseDimension(v, i, n) + + // Append broken words + line = append(line, out) + } + t.lines = append(t.lines, line) +} + +// Allow Support for Bulk Append +// Eliminates repeated for loops +func (t *Table) AppendBulk(rows [][]string) { + for _, row := range rows { + t.Append(row) + } +} + +// NumLines to get the number of lines +func (t *Table) NumLines() int { + return len(t.lines) +} + +// Clear rows +func (t *Table) ClearRows() { + t.lines = [][][]string{} +} + +// Clear footer +func (t *Table) ClearFooter() { + t.footers = []string{} +} + +// Print line based on row width +func (t *Table) printLine(nl bool) { + fmt.Fprint(t.out, t.pCenter) + for i := 0; i < len(t.cs); i++ { + v := t.cs[i] + fmt.Fprintf(t.out, "%s%s%s%s", + t.pRow, + strings.Repeat(string(t.pRow), v), + t.pRow, + t.pCenter) + } + if nl { + fmt.Fprint(t.out, t.newLine) + } +} + +// Print line based on row width with our without cell separator +func (t *Table) printLineOptionalCellSeparators(nl bool, displayCellSeparator []bool) { + fmt.Fprint(t.out, t.pCenter) + for i := 0; i < len(t.cs); i++ { + v := t.cs[i] + if i > len(displayCellSeparator) || displayCellSeparator[i] { + // Display the cell separator + fmt.Fprintf(t.out, "%s%s%s%s", + t.pRow, + strings.Repeat(string(t.pRow), v), + t.pRow, + t.pCenter) + } else { + // Don't display the cell separator for this cell + fmt.Fprintf(t.out, "%s%s", + strings.Repeat(" ", v+2), + t.pCenter) + } + } + if nl { + fmt.Fprint(t.out, t.newLine) + } +} + +// Return the PadRight function if align is left, PadLeft if align is right, +// and Pad by default +func pad(align int) func(string, string, int) string { + padFunc := Pad + switch align { + case ALIGN_LEFT: + padFunc = PadRight + case ALIGN_RIGHT: + padFunc = PadLeft + } + return padFunc +} + +// Print heading information +func (t *Table) printHeading() { + // Check if headers is available + if len(t.headers) < 1 { + return + } + + // Check if border is set + // Replace with space if not set + fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE)) + + // Identify last column + end := len(t.cs) - 1 + + // Get pad function + padFunc := pad(t.hAlign) + + // Checking for ANSI escape sequences for header + is_esc_seq := false + if len(t.headerParams) > 0 { + is_esc_seq = true + } + + // Print Heading column + for i := 0; i <= end; i++ { + v := t.cs[i] + h := "" + if i < len(t.headers) { + h = t.headers[i] + } + if t.autoFmt { + h = Title(h) + } + pad := ConditionString((i == end && !t.borders.Left), SPACE, t.pColumn) + + if is_esc_seq { + fmt.Fprintf(t.out, " %s %s", + format(padFunc(h, SPACE, v), + t.headerParams[i]), pad) + } else { + fmt.Fprintf(t.out, " %s %s", + padFunc(h, SPACE, v), + pad) + } + + } + // Next line + fmt.Fprint(t.out, t.newLine) + if t.hdrLine { + t.printLine(true) + } +} + +// Print heading information +func (t *Table) printFooter() { + // Check if headers is available + if len(t.footers) < 1 { + return + } + + // Only print line if border is not set + if !t.borders.Bottom { + t.printLine(true) + } + // Check if border is set + // Replace with space if not set + fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE)) + + // Identify last column + end := len(t.cs) - 1 + + // Get pad function + padFunc := pad(t.fAlign) + + // Checking for ANSI escape sequences for header + is_esc_seq := false + if len(t.footerParams) > 0 { + is_esc_seq = true + } + + // Print Heading column + for i := 0; i <= end; i++ { + v := t.cs[i] + f := t.footers[i] + if t.autoFmt { + f = Title(f) + } + pad := ConditionString((i == end && !t.borders.Top), SPACE, t.pColumn) + + if len(t.footers[i]) == 0 { + pad = SPACE + } + + if is_esc_seq { + fmt.Fprintf(t.out, " %s %s", + format(padFunc(f, SPACE, v), + t.footerParams[i]), pad) + } else { + fmt.Fprintf(t.out, " %s %s", + padFunc(f, SPACE, v), + pad) + } + + //fmt.Fprintf(t.out, " %s %s", + // padFunc(f, SPACE, v), + // pad) + } + // Next line + fmt.Fprint(t.out, t.newLine) + //t.printLine(true) + + hasPrinted := false + + for i := 0; i <= end; i++ { + v := t.cs[i] + pad := t.pRow + center := t.pCenter + length := len(t.footers[i]) + + if length > 0 { + hasPrinted = true + } + + // Set center to be space if length is 0 + if length == 0 && !t.borders.Right { + center = SPACE + } + + // Print first junction + if i == 0 { + fmt.Fprint(t.out, center) + } + + // Pad With space of length is 0 + if length == 0 { + pad = SPACE + } + // Ignore left space of it has printed before + if hasPrinted || t.borders.Left { + pad = t.pRow + center = t.pCenter + } + + // Change Center start position + if center == SPACE { + if i < end && len(t.footers[i+1]) != 0 { + center = t.pCenter + } + } + + // Print the footer + fmt.Fprintf(t.out, "%s%s%s%s", + pad, + strings.Repeat(string(pad), v), + pad, + center) + + } + + fmt.Fprint(t.out, t.newLine) +} + +// Print caption text +func (t Table) printCaption() { + width := t.getTableWidth() + paragraph, _ := WrapString(t.captionText, width) + for linecount := 0; linecount < len(paragraph); linecount++ { + fmt.Fprintln(t.out, paragraph[linecount]) + } +} + +// Calculate the total number of characters in a row +func (t Table) getTableWidth() int { + var chars int + for _, v := range t.cs { + chars += v + } + + // Add chars, spaces, seperators to calculate the total width of the table. + // ncols := t.colSize + // spaces := ncols * 2 + // seps := ncols + 1 + + return (chars + (3 * t.colSize) + 2) +} + +func (t Table) printRows() { + for i, lines := range t.lines { + t.printRow(lines, i) + } +} + +func (t *Table) fillAlignment(num int) { + if len(t.columnsAlign) < num { + t.columnsAlign = make([]int, num) + for i := range t.columnsAlign { + t.columnsAlign[i] = t.align + } + } +} + +// Print Row Information +// Adjust column alignment based on type + +func (t *Table) printRow(columns [][]string, colKey int) { + // Get Maximum Height + max := t.rs[colKey] + total := len(columns) + + // TODO Fix uneven col size + // if total < t.colSize { + // for n := t.colSize - total; n < t.colSize ; n++ { + // columns = append(columns, []string{SPACE}) + // t.cs[n] = t.mW + // } + //} + + // Pad Each Height + // pads := []int{} + pads := []int{} + + // Checking for ANSI escape sequences for columns + is_esc_seq := false + if len(t.columnsParams) > 0 { + is_esc_seq = true + } + t.fillAlignment(total) + + for i, line := range columns { + length := len(line) + pad := max - length + pads = append(pads, pad) + for n := 0; n < pad; n++ { + columns[i] = append(columns[i], " ") + } + } + //fmt.Println(max, "\n") + for x := 0; x < max; x++ { + for y := 0; y < total; y++ { + + // Check if border is set + fmt.Fprint(t.out, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn)) + + fmt.Fprintf(t.out, SPACE) + str := columns[y][x] + + // Embedding escape sequence with column value + if is_esc_seq { + str = format(str, t.columnsParams[y]) + } + + // This would print alignment + // Default alignment would use multiple configuration + switch t.columnsAlign[y] { + case ALIGN_CENTER: // + fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y])) + case ALIGN_RIGHT: + fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y])) + case ALIGN_LEFT: + fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y])) + default: + if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) { + fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y])) + } else { + fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y])) + + // TODO Custom alignment per column + //if max == 1 || pads[y] > 0 { + // fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y])) + //} else { + // fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y])) + //} + + } + } + fmt.Fprintf(t.out, SPACE) + } + // Check if border is set + // Replace with space if not set + fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE)) + fmt.Fprint(t.out, t.newLine) + } + + if t.rowLine { + t.printLine(true) + } +} + +// Print the rows of the table and merge the cells that are identical +func (t *Table) printRowsMergeCells() { + var previousLine []string + var displayCellBorder []bool + var tmpWriter bytes.Buffer + for i, lines := range t.lines { + // We store the display of the current line in a tmp writer, as we need to know which border needs to be print above + previousLine, displayCellBorder = t.printRowMergeCells(&tmpWriter, lines, i, previousLine) + if i > 0 { //We don't need to print borders above first line + if t.rowLine { + t.printLineOptionalCellSeparators(true, displayCellBorder) + } + } + tmpWriter.WriteTo(t.out) + } + //Print the end of the table + if t.rowLine { + t.printLine(true) + } +} + +// Print Row Information to a writer and merge identical cells. +// Adjust column alignment based on type + +func (t *Table) printRowMergeCells(writer io.Writer, columns [][]string, colKey int, previousLine []string) ([]string, []bool) { + // Get Maximum Height + max := t.rs[colKey] + total := len(columns) + + // Pad Each Height + pads := []int{} + + for i, line := range columns { + length := len(line) + pad := max - length + pads = append(pads, pad) + for n := 0; n < pad; n++ { + columns[i] = append(columns[i], " ") + } + } + + var displayCellBorder []bool + t.fillAlignment(total) + for x := 0; x < max; x++ { + for y := 0; y < total; y++ { + + // Check if border is set + fmt.Fprint(writer, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn)) + + fmt.Fprintf(writer, SPACE) + + str := columns[y][x] + + if t.autoMergeCells { + //Store the full line to merge mutli-lines cells + fullLine := strings.Join(columns[y], " ") + if len(previousLine) > y && fullLine == previousLine[y] && fullLine != "" { + // If this cell is identical to the one above but not empty, we don't display the border and keep the cell empty. + displayCellBorder = append(displayCellBorder, false) + str = "" + } else { + // First line or different content, keep the content and print the cell border + displayCellBorder = append(displayCellBorder, true) + } + } + + // This would print alignment + // Default alignment would use multiple configuration + switch t.columnsAlign[y] { + case ALIGN_CENTER: // + fmt.Fprintf(writer, "%s", Pad(str, SPACE, t.cs[y])) + case ALIGN_RIGHT: + fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y])) + case ALIGN_LEFT: + fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y])) + default: + if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) { + fmt.Fprintf(writer, "%s", PadLeft(str, SPACE, t.cs[y])) + } else { + fmt.Fprintf(writer, "%s", PadRight(str, SPACE, t.cs[y])) + } + } + fmt.Fprintf(writer, SPACE) + } + // Check if border is set + // Replace with space if not set + fmt.Fprint(writer, ConditionString(t.borders.Left, t.pColumn, SPACE)) + fmt.Fprint(writer, t.newLine) + } + + //The new previous line is the current one + previousLine = make([]string, total) + for y := 0; y < total; y++ { + previousLine[y] = strings.Join(columns[y], " ") //Store the full line for multi-lines cells + } + //Returns the newly added line and wether or not a border should be displayed above. + return previousLine, displayCellBorder +} + +func (t *Table) parseDimension(str string, colKey, rowKey int) []string { + var ( + raw []string + max int + ) + w := DisplayWidth(str) + // Calculate Width + // Check if with is grater than maximum width + if w > t.mW { + w = t.mW + } + + // Check if width exists + v, ok := t.cs[colKey] + if !ok || v < w || v == 0 { + t.cs[colKey] = w + } + + if rowKey == -1 { + return raw + } + // Calculate Height + if t.autoWrap { + raw, _ = WrapString(str, t.cs[colKey]) + } else { + raw = getLines(str) + } + + for _, line := range raw { + if w := DisplayWidth(line); w > max { + max = w + } + } + + // Make sure the with is the same length as maximum word + // Important for cases where the width is smaller than maxu word + if max > t.cs[colKey] { + t.cs[colKey] = max + } + + h := len(raw) + v, ok = t.rs[rowKey] + + if !ok || v < h || v == 0 { + t.rs[rowKey] = h + } + //fmt.Printf("Raw %+v %d\n", raw, len(raw)) + return raw +} diff --git a/vendor/github.com/olekukonko/tablewriter/table_with_color.go b/vendor/github.com/olekukonko/tablewriter/table_with_color.go new file mode 100644 index 000000000..5a4a53ec2 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/table_with_color.go @@ -0,0 +1,134 @@ +package tablewriter + +import ( + "fmt" + "strconv" + "strings" +) + +const ESC = "\033" +const SEP = ";" + +const ( + BgBlackColor int = iota + 40 + BgRedColor + BgGreenColor + BgYellowColor + BgBlueColor + BgMagentaColor + BgCyanColor + BgWhiteColor +) + +const ( + FgBlackColor int = iota + 30 + FgRedColor + FgGreenColor + FgYellowColor + FgBlueColor + FgMagentaColor + FgCyanColor + FgWhiteColor +) + +const ( + BgHiBlackColor int = iota + 100 + BgHiRedColor + BgHiGreenColor + BgHiYellowColor + BgHiBlueColor + BgHiMagentaColor + BgHiCyanColor + BgHiWhiteColor +) + +const ( + FgHiBlackColor int = iota + 90 + FgHiRedColor + FgHiGreenColor + FgHiYellowColor + FgHiBlueColor + FgHiMagentaColor + FgHiCyanColor + FgHiWhiteColor +) + +const ( + Normal = 0 + Bold = 1 + UnderlineSingle = 4 + Italic +) + +type Colors []int + +func startFormat(seq string) string { + return fmt.Sprintf("%s[%sm", ESC, seq) +} + +func stopFormat() string { + return fmt.Sprintf("%s[%dm", ESC, Normal) +} + +// Making the SGR (Select Graphic Rendition) sequence. +func makeSequence(codes []int) string { + codesInString := []string{} + for _, code := range codes { + codesInString = append(codesInString, strconv.Itoa(code)) + } + return strings.Join(codesInString, SEP) +} + +// Adding ANSI escape sequences before and after string +func format(s string, codes interface{}) string { + var seq string + + switch v := codes.(type) { + + case string: + seq = v + case []int: + seq = makeSequence(v) + default: + return s + } + + if len(seq) == 0 { + return s + } + return startFormat(seq) + s + stopFormat() +} + +// Adding header colors (ANSI codes) +func (t *Table) SetHeaderColor(colors ...Colors) { + if t.colSize != len(colors) { + panic("Number of header colors must be equal to number of headers.") + } + for i := 0; i < len(colors); i++ { + t.headerParams = append(t.headerParams, makeSequence(colors[i])) + } +} + +// Adding column colors (ANSI codes) +func (t *Table) SetColumnColor(colors ...Colors) { + if t.colSize != len(colors) { + panic("Number of column colors must be equal to number of headers.") + } + for i := 0; i < len(colors); i++ { + t.columnsParams = append(t.columnsParams, makeSequence(colors[i])) + } +} + +// Adding column colors (ANSI codes) +func (t *Table) SetFooterColor(colors ...Colors) { + if len(t.footers) != len(colors) { + panic("Number of footer colors must be equal to number of footer.") + } + for i := 0; i < len(colors); i++ { + t.footerParams = append(t.footerParams, makeSequence(colors[i])) + } +} + +func Color(colors ...int) []int { + return colors +} diff --git a/vendor/github.com/olekukonko/tablewriter/test.csv b/vendor/github.com/olekukonko/tablewriter/test.csv new file mode 100644 index 000000000..1609327e9 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/test.csv @@ -0,0 +1,4 @@ +first_name,last_name,ssn +John,Barry,123456 +Kathy,Smith,687987 +Bob,McCornick,3979870 \ No newline at end of file diff --git a/vendor/github.com/olekukonko/tablewriter/test_info.csv b/vendor/github.com/olekukonko/tablewriter/test_info.csv new file mode 100644 index 000000000..e4c40e983 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/test_info.csv @@ -0,0 +1,4 @@ +Field,Type,Null,Key,Default,Extra +user_id,smallint(5),NO,PRI,NULL,auto_increment +username,varchar(10),NO,,NULL, +password,varchar(100),NO,,NULL, \ No newline at end of file diff --git a/vendor/github.com/olekukonko/tablewriter/util.go b/vendor/github.com/olekukonko/tablewriter/util.go new file mode 100644 index 000000000..2deefbc52 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/util.go @@ -0,0 +1,72 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +package tablewriter + +import ( + "math" + "regexp" + "strings" + + "github.com/mattn/go-runewidth" +) + +var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]") + +func DisplayWidth(str string) int { + return runewidth.StringWidth(ansi.ReplaceAllLiteralString(str, "")) +} + +// Simple Condition for string +// Returns value based on condition +func ConditionString(cond bool, valid, inValid string) string { + if cond { + return valid + } + return inValid +} + +// Format Table Header +// Replace _ , . and spaces +func Title(name string) string { + name = strings.Replace(name, "_", " ", -1) + name = strings.Replace(name, ".", " ", -1) + name = strings.TrimSpace(name) + return strings.ToUpper(name) +} + +// Pad String +// Attempts to play string in the center +func Pad(s, pad string, width int) string { + gap := width - DisplayWidth(s) + if gap > 0 { + gapLeft := int(math.Ceil(float64(gap / 2))) + gapRight := gap - gapLeft + return strings.Repeat(string(pad), gapLeft) + s + strings.Repeat(string(pad), gapRight) + } + return s +} + +// Pad String Right position +// This would pace string at the left side fo the screen +func PadRight(s, pad string, width int) string { + gap := width - DisplayWidth(s) + if gap > 0 { + return s + strings.Repeat(string(pad), gap) + } + return s +} + +// Pad String Left position +// This would pace string at the right side fo the screen +func PadLeft(s, pad string, width int) string { + gap := width - DisplayWidth(s) + if gap > 0 { + return strings.Repeat(string(pad), gap) + s + } + return s +} diff --git a/vendor/github.com/olekukonko/tablewriter/wrap.go b/vendor/github.com/olekukonko/tablewriter/wrap.go new file mode 100644 index 000000000..9ef69e904 --- /dev/null +++ b/vendor/github.com/olekukonko/tablewriter/wrap.go @@ -0,0 +1,104 @@ +// Copyright 2014 Oleku Konko All rights reserved. +// Use of this source code is governed by a MIT +// license that can be found in the LICENSE file. + +// This module is a Table Writer API for the Go Programming Language. +// The protocols were written in pure Go and works on windows and unix systems + +package tablewriter + +import ( + "math" + "strings" + + "github.com/mattn/go-runewidth" +) + +var ( + nl = "\n" + sp = " " +) + +const defaultPenalty = 1e5 + +// Wrap wraps s into a paragraph of lines of length lim, with minimal +// raggedness. +func WrapString(s string, lim int) ([]string, int) { + words := strings.Split(strings.Replace(s, nl, sp, -1), sp) + var lines []string + max := 0 + for _, v := range words { + max = runewidth.StringWidth(v) + if max > lim { + lim = max + } + } + for _, line := range WrapWords(words, 1, lim, defaultPenalty) { + lines = append(lines, strings.Join(line, sp)) + } + return lines, lim +} + +// WrapWords is the low-level line-breaking algorithm, useful if you need more +// control over the details of the text wrapping process. For most uses, +// WrapString will be sufficient and more convenient. +// +// WrapWords splits a list of words into lines with minimal "raggedness", +// treating each rune as one unit, accounting for spc units between adjacent +// words on each line, and attempting to limit lines to lim units. Raggedness +// is the total error over all lines, where error is the square of the +// difference of the length of the line and lim. Too-long lines (which only +// happen when a single word is longer than lim units) have pen penalty units +// added to the error. +func WrapWords(words []string, spc, lim, pen int) [][]string { + n := len(words) + + length := make([][]int, n) + for i := 0; i < n; i++ { + length[i] = make([]int, n) + length[i][i] = runewidth.StringWidth(words[i]) + for j := i + 1; j < n; j++ { + length[i][j] = length[i][j-1] + spc + runewidth.StringWidth(words[j]) + } + } + nbrk := make([]int, n) + cost := make([]int, n) + for i := range cost { + cost[i] = math.MaxInt32 + } + for i := n - 1; i >= 0; i-- { + if length[i][n-1] <= lim { + cost[i] = 0 + nbrk[i] = n + } else { + for j := i + 1; j < n; j++ { + d := lim - length[i][j-1] + c := d*d + cost[j] + if length[i][j-1] > lim { + c += pen // too-long lines get a worse penalty + } + if c < cost[i] { + cost[i] = c + nbrk[i] = j + } + } + } + } + var lines [][]string + i := 0 + for i < n { + lines = append(lines, words[i:nbrk[i]]) + i = nbrk[i] + } + return lines +} + +// getLines decomposes a multiline string into a slice of strings. +func getLines(s string) []string { + var lines []string + + for _, line := range strings.Split(s, nl) { + lines = append(lines, line) + } + return lines +} diff --git a/vendor/vendor.json b/vendor/vendor.json index c5714b58f..5ce94fe2c 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -941,6 +941,12 @@ "path": "github.com/mattn/go-isatty", "revision": "56b76bdf51f7708750eac80fa38b952bb9f32639" }, + { + "checksumSHA1": "cJE7dphDlam/i7PhnsyosNWtbd4=", + "path": "github.com/mattn/go-runewidth", + "revision": "97311d9f7767e3d6f422ea06661bc2c7a19e8a5d", + "revisionTime": "2017-05-10T07:48:58Z" + }, { "checksumSHA1": "UP+pXl+ic9y6qrpZA5MqDIAuGfw=", "path": "github.com/mitchellh/cli", @@ -1006,6 +1012,12 @@ "path": "github.com/nu7hatch/gouuid", "revision": "179d4d0c4d8d407a32af483c2354df1d2c91e6c3" }, + { + "checksumSHA1": "WY8p2ZNGyl69P1tcVc5HFal/Ng0=", + "path": "github.com/olekukonko/tablewriter", + "revision": "96aac992fc8b1a4c83841a6c3e7178d20d989625", + "revisionTime": "2018-01-05T11:11:33Z" + }, { "checksumSHA1": "/NoE6t3UkW4/iKAtbf59GGv6tF8=", "path": "github.com/packer-community/winrmcp/winrmcp", From 281dd1258a16e9bc8d5a765fcbe30fd433a02df9 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sun, 1 Nov 2015 21:46:14 -0600 Subject: [PATCH 0385/1007] Added proper support for downloading via a Windows UNC path or a relative uri. Added proper support for validating a downloadableURL containing a UNC or relative uri. Removed the workaround for an earlier Go issue that had remained dormant in common/download.go (issue #5927). When building a .vmx file via the vmware-iso builder, transform the path to the correct os-formatted one (using filepath.FromSlash). --- builder/vmware/iso/step_create_vmx.go | 5 ++ common/config.go | 94 ++++++++++++++++++--------- common/download.go | 49 +++++++++++++- packer/core.go | 2 +- 4 files changed, 115 insertions(+), 35 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 1f4ee812f..62546d212 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -43,6 +43,11 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction { isoPath := state.Get("iso_path").(string) ui := state.Get("ui").(packer.Ui) + // Convert the iso_path into a path relative to the .vmx file if possible + if relativeIsoPath,err := filepath.Rel(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { + isoPath = relativeIsoPath + } + ui.Say("Building and writing VMX file") vmxTemplate := DefaultVMXTemplate diff --git a/common/config.go b/common/config.go index 7bef253ee..7b01191a8 100644 --- a/common/config.go +++ b/common/config.go @@ -56,77 +56,109 @@ func DownloadableURL(original string) (string, error) { // for more info about valid windows URIs idx := strings.Index(original, ":") if idx == 1 { - original = "file:///" + original + original = "file://" + filepath.ToSlash(original) } } - u, err := url.Parse(original) + + // XXX: The validation here is later re-parsed in common/download.go and + // thus any modifications here must remain consistent over there too. + uri, err := url.Parse(original) if err != nil { return "", err } - if u.Scheme == "" { - u.Scheme = "file" + if uri.Scheme == "" { + uri.Scheme = "file" } - if u.Scheme == "file" { - // Windows file handling is all sorts of tricky... + const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) + if uri.Scheme == "file" { + var ospath string // os-formatted pathname if runtime.GOOS == "windows" { - // If the path is using Windows-style slashes, URL parses - // it into the host field. - if u.Path == "" && strings.Contains(u.Host, `\`) { - u.Path = u.Host - u.Host = "" + // Move any extra path components that were mis-parsed into the Host + // field back into the uri.Path field + if len(uri.Host) >= len(UNCPrefix) && uri.Host[:len(UNCPrefix)] == UNCPrefix { + idx := strings.Index(uri.Host[len(UNCPrefix):], string(os.PathSeparator)) + if idx > -1 { + uri.Path = filepath.ToSlash(uri.Host[idx+len(UNCPrefix):]) + uri.Path + uri.Host = uri.Host[:idx+len(UNCPrefix)] + } } + // Now all we need to do to convert the uri to a platform-specific path + // is to trade it's slashes for some os.PathSeparator ones. + ospath = uri.Host + filepath.FromSlash(uri.Path) + + } else { + // Since we're already using sane paths on a sane platform, anything in + // uri.Host can be assumed that the user is describing a relative uri. + // This means that if we concatenate it with uri.Path, the filepath + // transform will still open the file correctly. + // i.e. file://localdirectory/filename -> localdirectory/filename + ospath = uri.Host + uri.Path } // Only do the filepath transformations if the file appears - // to actually exist. - if _, err := os.Stat(u.Path); err == nil { - u.Path, err = filepath.Abs(u.Path) + // to actually exist. We don't do it on windows, because EvalSymlinks + // won't understand how to handle UNC paths and other Windows-specific minutae. + if _, err := os.Stat(ospath); err == nil && runtime.GOOS != "windows" { + ospath, err = filepath.Abs(ospath) if err != nil { return "", err } - u.Path, err = filepath.EvalSymlinks(u.Path) + ospath, err = filepath.EvalSymlinks(ospath) if err != nil { return "", err } - u.Path = filepath.Clean(u.Path) + ospath = filepath.Clean(ospath) } + // now that ospath was normalized and such.. if runtime.GOOS == "windows" { - // Also replace all backslashes with forwardslashes since Windows - // users are likely to do this but the URL should actually only - // contain forward slashes. - u.Path = strings.Replace(u.Path, `\`, `/`, -1) - // prepend absolute windows paths with "/" so that when we - // compose u.String() below the outcome will be correct - // file:///c/blah syntax; otherwise u.String() will only add - // file:// which is not technically a correct windows URI - if filepath.IsAbs(u.Path) && !strings.HasPrefix(u.Path, "/") { - u.Path = "/" + u.Path + uri.Host = "" + // Check to see if our ospath is unc-prefixed, and if it is then split + // the UNC host into uri.Host, leaving the rest in ospath. + // This way, our UNC-uri is protected from injury in the call to uri.String() + if len(ospath) >= len(UNCPrefix) && ospath[:len(UNCPrefix)] == UNCPrefix { + idx := strings.Index(ospath[len(UNCPrefix):], string(os.PathSeparator)) + if idx > -1 { + uri.Host = ospath[:len(UNCPrefix)+idx] + ospath = ospath[len(UNCPrefix)+idx:] + } } - + // Restore the uri by re-transforming our os-formatted path + uri.Path = filepath.ToSlash(ospath) + } else { + uri.Host = "" + uri.Path = filepath.ToSlash(ospath) } } // Make sure it is lowercased - u.Scheme = strings.ToLower(u.Scheme) + uri.Scheme = strings.ToLower(uri.Scheme) // Verify that the scheme is something we support in our common downloader. supported := []string{"file", "http", "https"} found := false for _, s := range supported { - if u.Scheme == s { + if uri.Scheme == s { found = true break } } if !found { - return "", fmt.Errorf("Unsupported URL scheme: %s", u.Scheme) + return "", fmt.Errorf("Unsupported URL scheme: %s", uri.Scheme) } - return u.String(), nil + + // explicit check to see if we need to manually replace the uri host with a UNC one + if runtime.GOOS == "windows" && uri.Scheme == "file" { + if len(uri.Host) >= len(UNCPrefix) && uri.Host[:len(UNCPrefix)] == UNCPrefix { + escapedHost := url.QueryEscape(uri.Host) + return strings.Replace(uri.String(), escapedHost, uri.Host, 1), nil + } + } + return uri.String(), nil } // FileExistsLocally takes the URL output from DownloadableURL, and determines diff --git a/common/download.go b/common/download.go index ada4c9756..5f9940056 100644 --- a/common/download.go +++ b/common/download.go @@ -16,6 +16,9 @@ import ( "net/url" "os" "runtime" + "path" + "path/filepath" + "strings" ) // DownloadConfig is the configuration given to instantiate a new @@ -130,9 +133,49 @@ func (d *DownloadClient) Get() (string, error) { // locally and we don't make a copy. Normally we would copy or download. log.Printf("[DEBUG] Using local file: %s", finalPath) - // Remove forward slash on absolute Windows file URLs before processing - if runtime.GOOS == "windows" && len(finalPath) > 0 && finalPath[0] == '/' { - finalPath = finalPath[1:] + // FIXME: + // cwd should point to the path relative to client.json, but + // since this isn't exposed to us anywhere, we use os.Getwd() + // to figure it out. + cwd,err := os.Getwd() + if err != nil { + return "", fmt.Errorf("Unable to get working directory") + } + + // convert the actual file uri to a windowsy path + // (this logic must correspond to the same logic in common/config.go) + if runtime.GOOS == "windows" { + const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) + + // move any extra path components that were parsed into Host due + // to UNC into the url.Path field so that it's PathSeparators get + // normalized + if len(url.Host) >= len(UNCPrefix) && url.Host[:len(UNCPrefix)] == UNCPrefix { + idx := strings.Index(url.Host[len(UNCPrefix):], string(os.PathSeparator)) + if idx > -1 { + url.Path = filepath.ToSlash(url.Host[idx+len(UNCPrefix):]) + url.Path + url.Host = url.Host[:idx+len(UNCPrefix)] + } + } + + // clean up backward-slashes since they only matter when part of a unc path + urlPath := filepath.ToSlash(url.Path) + + // semi-absolute path (current drive letter) -- file:///absolute/path + if url.Host == "" && len(urlPath) > 0 && urlPath[0] == '/' { + finalPath = path.Join(filepath.VolumeName(cwd), urlPath) + + // relative path -- file://./relative/path + // file://relative/path + } else if url.Host == "" || (len(url.Host) > 0 && url.Host[0] == '.') { + finalPath = path.Join(filepath.ToSlash(cwd), urlPath) + + // absolute path + } else { + // UNC -- file://\\host/share/whatever + // drive -- file://c:/absolute/path + finalPath = path.Join(url.Host, urlPath) + } } // Keep track of the source so we can make sure not to delete this later diff --git a/packer/core.go b/packer/core.go index 7da3e4510..c8ac2cfb7 100644 --- a/packer/core.go +++ b/packer/core.go @@ -67,7 +67,7 @@ func NewCore(c *CoreConfig) (*Core, error) { return nil, err } - // Go through and interpolate all the build names. We shuld be able + // Go through and interpolate all the build names. We should be able // to do this at this point with the variables. result.builds = make(map[string]*template.Builder) for _, b := range c.Template.Builders { From da9c94b345a5266b4534200a78a398473fa77377 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Mon, 18 Jan 2016 17:36:47 -0600 Subject: [PATCH 0386/1007] Added some testcases for the various file uri transforms to download_test.go Moved some of the code for normalizing a Windows file uri to a regular path into it's own function NormalizeWindowsURL --- common/download.go | 88 +++++++++++++++++---------------- common/download_test.go | 105 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 151 insertions(+), 42 deletions(-) diff --git a/common/download.go b/common/download.go index 5f9940056..65d72d22a 100644 --- a/common/download.go +++ b/common/download.go @@ -101,6 +101,44 @@ func (d *DownloadClient) Cancel() { // TODO(mitchellh): Implement } +// Take a uri and convert it to a path that makes sense on the Windows platform +func NormalizeWindowsURL(basepath string, url url.URL) string { + // This logic must correspond to the same logic in the NormalizeWindowsURL + // function found in common/config.go since that function _also_ checks that + // the url actually exists in file form. + + const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) + + // move any extra path components that were parsed into Host due + // to UNC into the url.Path field so that it's PathSeparators get + // normalized + if len(url.Host) >= len(UNCPrefix) && url.Host[:len(UNCPrefix)] == UNCPrefix { + idx := strings.Index(url.Host[len(UNCPrefix):], string(os.PathSeparator)) + if idx > -1 { + url.Path = filepath.ToSlash(url.Host[idx+len(UNCPrefix):]) + url.Path + url.Host = url.Host[:idx+len(UNCPrefix)] + } + } + + // clean up backward-slashes since they only matter when part of a unc path + urlPath := filepath.ToSlash(url.Path) + + // semi-absolute path (current drive letter) -- file:///absolute/path + if url.Host == "" && len(urlPath) > 0 && urlPath[0] == '/' { + return path.Join(filepath.VolumeName(basepath), urlPath) + + // relative path -- file://./relative/path + // file://relative/path + } else if url.Host == "" || (len(url.Host) > 0 && url.Host[0] == '.') { + return path.Join(filepath.ToSlash(basepath), urlPath) + } + + // absolute path + // UNC -- file://\\host/share/whatever + // drive -- file://c:/absolute/path + return path.Join(url.Host, urlPath) +} + func (d *DownloadClient) Get() (string, error) { // If we already have the file and it matches, then just return the target path. if verify, _ := d.VerifyChecksum(d.config.TargetPath); verify { @@ -133,49 +171,17 @@ func (d *DownloadClient) Get() (string, error) { // locally and we don't make a copy. Normally we would copy or download. log.Printf("[DEBUG] Using local file: %s", finalPath) - // FIXME: - // cwd should point to the path relative to client.json, but - // since this isn't exposed to us anywhere, we use os.Getwd() - // to figure it out. - cwd,err := os.Getwd() - if err != nil { - return "", fmt.Errorf("Unable to get working directory") - } - - // convert the actual file uri to a windowsy path - // (this logic must correspond to the same logic in common/config.go) + // transform the actual file uri to a windowsy path if we're being windowsy. if runtime.GOOS == "windows" { - const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) - - // move any extra path components that were parsed into Host due - // to UNC into the url.Path field so that it's PathSeparators get - // normalized - if len(url.Host) >= len(UNCPrefix) && url.Host[:len(UNCPrefix)] == UNCPrefix { - idx := strings.Index(url.Host[len(UNCPrefix):], string(os.PathSeparator)) - if idx > -1 { - url.Path = filepath.ToSlash(url.Host[idx+len(UNCPrefix):]) + url.Path - url.Host = url.Host[:idx+len(UNCPrefix)] - } - } - - // clean up backward-slashes since they only matter when part of a unc path - urlPath := filepath.ToSlash(url.Path) - - // semi-absolute path (current drive letter) -- file:///absolute/path - if url.Host == "" && len(urlPath) > 0 && urlPath[0] == '/' { - finalPath = path.Join(filepath.VolumeName(cwd), urlPath) - - // relative path -- file://./relative/path - // file://relative/path - } else if url.Host == "" || (len(url.Host) > 0 && url.Host[0] == '.') { - finalPath = path.Join(filepath.ToSlash(cwd), urlPath) - - // absolute path - } else { - // UNC -- file://\\host/share/whatever - // drive -- file://c:/absolute/path - finalPath = path.Join(url.Host, urlPath) + // FIXME: cwd should point to a path relative to the TEMPLATE path, + // but since this isn't exposed to us anywhere, we use os.Getwd() + // and assume the user ran packer in the same directory that + // any relative files are located at. + cwd,err := os.Getwd() + if err != nil { + return "", fmt.Errorf("Unable to get working directory") } + finalPath = NormalizeWindowsURL(cwd, *url) } // Keep track of the source so we can make sure not to delete this later diff --git a/common/download_test.go b/common/download_test.go index 497a05649..b46d81455 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -9,6 +9,8 @@ import ( "net/http/httptest" "os" "runtime" + "strings" + "path/filepath" "testing" ) @@ -382,5 +384,106 @@ func TestDownloadFileUrl(t *testing.T) { if _, err = os.Stat(sourcePath); err != nil { t.Errorf("Could not stat source file: %s", sourcePath) } - +} + +// SimulateFileUriDownload is a simple utility function that converts a uri +// into a testable file path whilst ignoring a correct checksum match, stripping +// UNC path info, and then calling stat to ensure the correct file exists. +// (used by TestFileUriTransforms) +func SimulateFileUriDownload(t *testing.T, uri string) (string,error) { + // source_path is a file path and source is a network path + source := fmt.Sprintf(uri) + t.Logf("Trying to download %s", source) + + config := &DownloadConfig{ + Url: source, + // This should be wrong. We want to make sure we don't delete + Checksum: []byte("nope"), + Hash: HashForType("sha256"), + CopyFile: false, + } + + // go go go + client := NewDownloadClient(config) + path, err := client.Get() + + // ignore any non-important checksum errors if it's not a unc path + if !strings.HasPrefix(path, "\\\\") && err.Error() != "checksums didn't match expected: 6e6f7065" { + t.Fatalf("Unexpected failure; expected checksum not to match") + } + + // if it's a unc path, then remove the host and share name so we don't have + // to force the user to enable ADMIN$ and Windows File Sharing + if strings.HasPrefix(path, "\\\\") { + res := strings.SplitN(path, "/", 3) + path = "/" + res[2] + } + + if _, err = os.Stat(path); err != nil { + t.Errorf("Could not stat source file: %s", path) + } + return path,err +} + +// TestFileUriTransforms tests the case where we use a local file uri +// for iso_url. There's a few different formats that a file uri can exist as +// and so we try to test the most useful and common ones. +func TestFileUriTransforms(t *testing.T) { + const testpath = /* have your */ "test-fixtures/fileurl/cake" /* and eat it too */ + const host = "localhost" + + var cwd string + var volume string + var share string + + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("Unable to detect working directory: %s", err) + return + } + cwd = filepath.ToSlash(cwd) + volume = filepath.VolumeName(cwd) + share = volume + if share[len(share)-1] == ':' { + share = share[:len(share)-1] + "$" + } + cwd = cwd[len(volume):] + + t.Logf("TestFileUriTransforms : Running with cwd : '%s'", cwd) + t.Logf("TestFileUriTransforms : Running with volume : '%s'", volume) + + // ./relative/path -> ./relative/path + // /absolute/path -> /absolute/path + // c:/windows/absolute -> c:/windows/absolute + // \\host/sharename/file -> \\host/sharename/file + testcases := []string{ + "./%s", + cwd + "/%s", + volume + cwd + "/%s", + "\\\\" + host + "/" + share + "/" + cwd[1:] + "/%s", + } + + // all regular slashed testcases + for _,testcase := range testcases { + uri := "file://" + fmt.Sprintf(testcase, testpath) + t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) + res,err := SimulateFileUriDownload(t, uri) + if err != nil { + t.Errorf("Unable to transform uri '%s' into a path : %v", uri, err) + } + t.Errorf("TestFileUriTransforms : Result Path '%s'", res) + } + + // ...and finally the oddball windows native path + // \\host\sharename\file -> \\host/sharename/file + testpath_native := filepath.FromSlash(testpath) + testcase_native := "\\\\" + host + "\\" + share + "\\" + filepath.FromSlash(cwd[1:]) + "\\%s" + uri := "file://" + fmt.Sprintf(testcase_native, testpath_native) + t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) + res,err := SimulateFileUriDownload(t, uri) + if err != nil { + t.Errorf("Unable to transform uri '%s' into a path", uri) + return + } + t.Errorf("TestFileUriTransforms : Result Path '%s'", res) } From 60831801a72d5cd1932dbac44d9a36513387866f Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 5 Apr 2016 13:11:30 -0500 Subject: [PATCH 0387/1007] Added the file, ftp, and smb downloaders to common/download.go --- common/download.go | 353 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 313 insertions(+), 40 deletions(-) diff --git a/common/download.go b/common/download.go index 65d72d22a..b0550927f 100644 --- a/common/download.go +++ b/common/download.go @@ -12,7 +12,6 @@ import ( "hash" "io" "log" - "net/http" "net/url" "os" "runtime" @@ -21,6 +20,13 @@ import ( "strings" ) +import ( + "net/http" + "github.com/jlaffeye/ftp" + "bufio" +) + + // DownloadConfig is the configuration given to instantiate a new // download instance. Once a configuration is used to instantiate // a download client, it must not be modified. @@ -78,10 +84,15 @@ func HashForType(t string) hash.Hash { // NewDownloadClient returns a new DownloadClient for the given // configuration. func NewDownloadClient(c *DownloadConfig) *DownloadClient { + const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */ + if c.DownloaderMap == nil { c.DownloaderMap = map[string]Downloader{ + "file": &FileDownloader{bufferSize: nil}, + "ftp": &FTPDownloader{userInfo: url.Userinfo{username:"anonymous", password: "anonymous@"}, mtu: mtu}, "http": &HTTPDownloader{userAgent: c.UserAgent}, "https": &HTTPDownloader{userAgent: c.UserAgent}, + "smb": &SMBDownloader{bufferSize: nil} } } @@ -101,44 +112,6 @@ func (d *DownloadClient) Cancel() { // TODO(mitchellh): Implement } -// Take a uri and convert it to a path that makes sense on the Windows platform -func NormalizeWindowsURL(basepath string, url url.URL) string { - // This logic must correspond to the same logic in the NormalizeWindowsURL - // function found in common/config.go since that function _also_ checks that - // the url actually exists in file form. - - const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) - - // move any extra path components that were parsed into Host due - // to UNC into the url.Path field so that it's PathSeparators get - // normalized - if len(url.Host) >= len(UNCPrefix) && url.Host[:len(UNCPrefix)] == UNCPrefix { - idx := strings.Index(url.Host[len(UNCPrefix):], string(os.PathSeparator)) - if idx > -1 { - url.Path = filepath.ToSlash(url.Host[idx+len(UNCPrefix):]) + url.Path - url.Host = url.Host[:idx+len(UNCPrefix)] - } - } - - // clean up backward-slashes since they only matter when part of a unc path - urlPath := filepath.ToSlash(url.Path) - - // semi-absolute path (current drive letter) -- file:///absolute/path - if url.Host == "" && len(urlPath) > 0 && urlPath[0] == '/' { - return path.Join(filepath.VolumeName(basepath), urlPath) - - // relative path -- file://./relative/path - // file://relative/path - } else if url.Host == "" || (len(url.Host) > 0 && url.Host[0] == '.') { - return path.Join(filepath.ToSlash(basepath), urlPath) - } - - // absolute path - // UNC -- file://\\host/share/whatever - // drive -- file://c:/absolute/path - return path.Join(url.Host, urlPath) -} - func (d *DownloadClient) Get() (string, error) { // If we already have the file and it matches, then just return the target path. if verify, _ := d.VerifyChecksum(d.config.TargetPath); verify { @@ -153,6 +126,11 @@ func (d *DownloadClient) Get() (string, error) { log.Printf("Parsed URL: %#v", u) + /* FIXME: + handle the special case of d.config.CopyFile which returns the path + in an os-specific format. + */ + // Files when we don't copy the file are special cased. var f *os.File var finalPath string @@ -271,7 +249,7 @@ func (*HTTPDownloader) Cancel() { } func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { - log.Printf("Starting download: %s", src.String()) + log.Printf("Starting download over HTTP: %s", src.String()) // Seek to the beginning by default if _, err := dst.Seek(0, 0); err != nil { @@ -350,3 +328,298 @@ func (d *HTTPDownloader) Progress() uint { func (d *HTTPDownloader) Total() uint { return d.total } + +// FTPDownloader is an implementation of Downloader that downloads +// files over FTP. +type FTPDownloader struct { + userInfo url.UserInfo + mtu uint + + active bool + progress uint + total uint +} + +func (*FTPDownloader) Cancel() { + d.active = false +} + +func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { + var userinfo *url.Userinfo + + userinfo = d.userInfo + d.active = false + + // check the uri is correct + uri, err := url.Parse(src) + if err != nil { return err } + + if uri.Scheme != "ftp" { + return fmt.Errorf("Unexpected uri scheme: %s", uri.Scheme) + } + + // connect to ftp server + var cli *ftp.ServerConn + + log.Printf("Starting download over FTP: %s : %s\n", uri.Host, Uri.Path) + cli,err := ftp.Dial(uri.Host) + if err != nil { return nil } + defer cli.Close() + + // handle authentication + if uri.User != nil { userinfo = uri.User } + + log.Printf("Authenticating to FTP server: %s : %s\n", uri.User.username, uri.User.password) + err = cli.Login(userinfo.username, userinfo.password) + if err != nil { return err } + + // locate specified path + path := path.Dir(uri.Path) + + log.Printf("Changing to FTP directory : %s\n", path) + err = cli.ChangeDir(path) + if err != nil { return nil } + + curpath,err := cli.CurrentDir() + if err != nil { return err } + log.Printf("Current FTP directory : %s\n", curpath) + + // collect stats about the specified file + var name string + var entry *ftp.Entry + + _,name = path.Split(uri.Path) + entry = nil + + entries,err := cli.List(curpath) + for _,e := range entries { + if e.Type == ftp.EntryTypeFile && e.Name == name { + entry = e + break + } + } + + if entry == nil { + return fmt.Errorf("Unable to find file: %s", uri.Path) + } + log.Printf("Found file : %s : %v bytes\n", entry.Name, entry.Size) + + d.progress = 0 + d.total = entry.Size + + // download specified file + d.active = true + reader,err := cli.RetrFrom(uri.Path, d.progress) + if err != nil { return nil } + + // do it in a goro so that if someone wants to cancel it, they can + errch := make(chan error) + go func(d *FTPDownloader, r *io.Reader, w *bufio.Writer, e chan error) { + defer w.Flush() + for ; d.active { + n,err := io.CopyN(writer, reader, d.mtu) + if err != nil { break } + d.progress += n + } + d.active = false + e <- err + }(d, reader, bufio.NewWriter(dst), errch) + + // spin until it's done + err = <-errch + reader.Close() + + if err == nil && d.progress != d.total { + err = fmt.Errorf("FTP total transfer size was %d when %d was expected", d.progress, d.total) + } + + // log out and quit + cli.Logout() + cli.Quit() + return err +} + +func (d *FTPDownloader) Progress() uint { + return d.progress +} + +func (d *FTPDownloader) Total() uint { + return d.total +} + +// FileDownloader is an implementation of Downloader that downloads +// files using the regular filesystem. +type FileDownloader struct { + bufferSize *uint + + active bool + progress uint + total uint +} + +func (*FileDownloader) Cancel() { + d.active = false +} + +func (d *FileDownloader) Progress() uint { + return d.progress +} + +func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { + d.active = false + + /* parse the uri using the net/url module */ + uri, err := url.Parse(src) + if uri.Scheme != "file" { + return fmt.Errorf("Unexpected uri scheme: %s", uri.Scheme) + } + + /* use the current working directory as the base for relative uri's */ + cwd,err := os.Getwd() + if err != nil { + return "", fmt.Errorf("Unable to get working directory") + } + + /* determine which uri format is being used and convert to a real path */ + var realpath string, basepath string + basepath = filepath.ToSlash(cwd) + + // absolute path -- file://c:/absolute/path + if strings.HasSuffix(uri.Host, ":") { + realpath = path.Join(uri.Host, uri.Path) + + // semi-absolute path (current drive letter) -- file:///absolute/path + } else if uri.Host == "" && strings.HasPrefix(uri.Path, "/") { + realpath = path.Join(filepath.VolumeName(basepath), uri.Path) + + // relative path -- file://./relative/path + } else if uri.Host == "." { + realpath = path.Join(basepath, uri.Path) + + // relative path -- file://relative/path + } else { + realpath = path.Join(basepath, uri.Host, uri.Path) + } + + /* download the file using the operating system's facilities */ + d.progress = 0 + d.active = true + + f, err = os.Open(realpath) + if err != nil { return err } + defer f.Close() + + // get the file size + fi, err := f.Stat() + if err != nil { return err } + d.total = fi.Size() + + // no bufferSize specified, so copy synchronously. + if d.bufferSize == nil { + n,err := io.Copy(dst, f) + d.active = false + d.progress += n + + // use a goro in case someone else wants to enable cancel/resume + } else { + errch := make(chan error) + go func(d* FileDownloader, r *bufio.Reader, w *bufio.Writer, e chan error) { + defer w.Flush() + for ; d.active { + n,err := io.CopyN(writer, reader, d.bufferSize) + if err != nil { break } + d.progress += n + } + d.active = false + e <- err + }(d, f, bufio.NewWriter(dst), errch) + + // ...and we spin until it's done + err = <-errch + } + f.Close() + return err +} + +func (d *FileDownloader) Total() uint { + return d.total +} + +// SMBDownloader is an implementation of Downloader that downloads +// files using the "\\" path format on Windows +type SMBDownloader struct { + bufferSize *uint + + active bool + progress uint + total uint +} + +func (*SMBDownloader) Cancel() { + d.active = false +} + +func (d *SMBDownloader) Progress() uint { + return d.progress +} + +func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { + const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) + d.active = false + + if runtime.GOOS != "windows" { + return fmt.Errorf("Support for SMB based uri's are not supported on %s", runtime.GOOS) + } + + /* convert the uri using the net/url module to a UNC path */ + var realpath string + uri, err := url.Parse(src) + if uri.Scheme != "smb" { + return fmt.Errorf("Unexpected uri scheme: %s", uri.Scheme) + } + + realpath = UNCPrefix + filepath.ToSlash(path.Join(uri.Host, uri.Path)) + + /* Open up the "\\"-prefixed path using the Windows filesystem */ + d.progress = 0 + d.active = true + + f, err = os.Open(realpath) + if err != nil { return err } + defer f.Close() + + // get the file size (at the risk of performance) + fi, err := f.Stat() + if err != nil { return err } + d.total = fi.Size() + + // no bufferSize specified, so copy synchronously. + if d.bufferSize == nil { + n,err := io.Copy(dst, f) + d.active = false + d.progress += n + + // use a goro in case someone else wants to enable cancel/resume + } else { + errch := make(chan error) + go func(d* SMBDownloader, r *bufio.Reader, w *bufio.Writer, e chan error) { + defer w.Flush() + for ; d.active { + n,err := io.CopyN(writer, reader, d.bufferSize) + if err != nil { break } + d.progress += n + } + d.active = false + e <- err + }(d, f, bufio.NewWriter(dst), errch) + + // ...and as usual we spin until it's done + err = <-errch + } + f.Close() + return err +} + +func (d *SMBDownloader) Total() uint { + return d.total +} From 6170e24ecbd4a60bb94b6ff3ea11661fb65f8645 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 5 Apr 2016 15:01:06 -0500 Subject: [PATCH 0388/1007] Refactored the code a bit to move the CopyFile hack out of DownloadClient and instead into each protocol. config.go: Removed all of the windows-specific net/url hackery since it's now handled mostly by download.go Removed the replacement of '\' with '/' since url.Parse does it now. Added knowledge of the other protocols implemented in download.go (ftp, smb) Removed some modules that were unused in this commit. download.go: Moved the file-path conversions for the different protocols into their own internally callable functions. Shuffled some of the functions around in case someone wants to implement the ability to resume. Modified DownloadClient.Get to remove the CopyFile special case and trust the protocol implementations if a user doesn't want to copy the file. Since all the protocols except for HTTPDownloader implement Cancel, added a Resume method as a placeholder for another developer to implement. Added a few missing names from their function definitions. Fixed the syntax in a few lines due to my suckage at go. Adjusted the types for progress and total so that they support 64-bit sizes. Removed the usage of the bufio library since it wasn't really being used. --- common/config.go | 124 +++----------- common/download.go | 391 +++++++++++++++++++++++---------------------- 2 files changed, 225 insertions(+), 290 deletions(-) diff --git a/common/config.go b/common/config.go index 7b01191a8..103c51105 100644 --- a/common/config.go +++ b/common/config.go @@ -2,10 +2,8 @@ package common import ( "fmt" - "net/url" "os" "path/filepath" - "runtime" "strings" "time" ) @@ -47,118 +45,40 @@ func ChooseString(vals ...string) string { // a completely valid URL. For example, the original URL might be "local/file.iso" // which isn't a valid URL. DownloadableURL will return "file:///local/file.iso" func DownloadableURL(original string) (string, error) { - if runtime.GOOS == "windows" { - // If the distance to the first ":" is just one character, assume - // we're dealing with a drive letter and thus a file path. - // prepend with "file:///"" now so that url.Parse won't accidentally - // parse the drive letter into the url scheme. - // See https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/ - // for more info about valid windows URIs - idx := strings.Index(original, ":") - if idx == 1 { - original = "file://" + filepath.ToSlash(original) - } - } - - // XXX: The validation here is later re-parsed in common/download.go and - // thus any modifications here must remain consistent over there too. - uri, err := url.Parse(original) - if err != nil { - return "", err - } - - if uri.Scheme == "" { - uri.Scheme = "file" - } - - const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) - if uri.Scheme == "file" { - var ospath string // os-formatted pathname - if runtime.GOOS == "windows" { - // Move any extra path components that were mis-parsed into the Host - // field back into the uri.Path field - if len(uri.Host) >= len(UNCPrefix) && uri.Host[:len(UNCPrefix)] == UNCPrefix { - idx := strings.Index(uri.Host[len(UNCPrefix):], string(os.PathSeparator)) - if idx > -1 { - uri.Path = filepath.ToSlash(uri.Host[idx+len(UNCPrefix):]) + uri.Path - uri.Host = uri.Host[:idx+len(UNCPrefix)] - } - } - // Now all we need to do to convert the uri to a platform-specific path - // is to trade it's slashes for some os.PathSeparator ones. - ospath = uri.Host + filepath.FromSlash(uri.Path) - - } else { - // Since we're already using sane paths on a sane platform, anything in - // uri.Host can be assumed that the user is describing a relative uri. - // This means that if we concatenate it with uri.Path, the filepath - // transform will still open the file correctly. - // i.e. file://localdirectory/filename -> localdirectory/filename - ospath = uri.Host + uri.Path - } - // Only do the filepath transformations if the file appears - // to actually exist. We don't do it on windows, because EvalSymlinks - // won't understand how to handle UNC paths and other Windows-specific minutae. - if _, err := os.Stat(ospath); err == nil && runtime.GOOS != "windows" { - ospath, err = filepath.Abs(ospath) - if err != nil { - return "", err - } - - ospath, err = filepath.EvalSymlinks(ospath) - if err != nil { - return "", err - } - - ospath = filepath.Clean(ospath) - } - - // now that ospath was normalized and such.. - if runtime.GOOS == "windows" { - uri.Host = "" - // Check to see if our ospath is unc-prefixed, and if it is then split - // the UNC host into uri.Host, leaving the rest in ospath. - // This way, our UNC-uri is protected from injury in the call to uri.String() - if len(ospath) >= len(UNCPrefix) && ospath[:len(UNCPrefix)] == UNCPrefix { - idx := strings.Index(ospath[len(UNCPrefix):], string(os.PathSeparator)) - if idx > -1 { - uri.Host = ospath[:len(UNCPrefix)+idx] - ospath = ospath[len(UNCPrefix)+idx:] - } - } - // Restore the uri by re-transforming our os-formatted path - uri.Path = filepath.ToSlash(ospath) - } else { - uri.Host = "" - uri.Path = filepath.ToSlash(ospath) - } - } - - // Make sure it is lowercased - uri.Scheme = strings.ToLower(uri.Scheme) // Verify that the scheme is something we support in our common downloader. - supported := []string{"file", "http", "https"} + supported := []string{"file", "http", "https", "ftp", "smb"} found := false for _, s := range supported { - if uri.Scheme == s { + if strings.HasPrefix(original, s + "://") { found = true break } } - if !found { - return "", fmt.Errorf("Unsupported URL scheme: %s", uri.Scheme) + // If it's properly prefixed with something we support, then we don't need + // to make it a uri. + if found { + return original, nil } - // explicit check to see if we need to manually replace the uri host with a UNC one - if runtime.GOOS == "windows" && uri.Scheme == "file" { - if len(uri.Host) >= len(UNCPrefix) && uri.Host[:len(UNCPrefix)] == UNCPrefix { - escapedHost := url.QueryEscape(uri.Host) - return strings.Replace(uri.String(), escapedHost, uri.Host, 1), nil - } + // If the file exists, then make it an absolute path + _,err := os.Stat(original) + if err == nil { + original, err = filepath.Abs(filepath.FromSlash(original)) + if err != nil { return "", err } + + original, err = filepath.EvalSymlinks(original) + if err != nil { return "", err } + + original = filepath.Clean(original) + original = filepath.ToSlash(original) } - return uri.String(), nil + + // Since it wasn't properly prefixed, let's make it into a well-formed + // file:// uri. + + return "file://" + original, nil } // FileExistsLocally takes the URL output from DownloadableURL, and determines diff --git a/common/download.go b/common/download.go index b0550927f..c06f385e8 100644 --- a/common/download.go +++ b/common/download.go @@ -10,20 +10,20 @@ import ( "errors" "fmt" "hash" - "io" "log" "net/url" "os" "runtime" "path" - "path/filepath" "strings" ) +// imports related to each Downloader implementation import ( + "io" + "path/filepath" "net/http" - "github.com/jlaffeye/ftp" - "bufio" + "github.com/jlaffaye/ftp" ) @@ -89,23 +89,35 @@ func NewDownloadClient(c *DownloadConfig) *DownloadClient { if c.DownloaderMap == nil { c.DownloaderMap = map[string]Downloader{ "file": &FileDownloader{bufferSize: nil}, - "ftp": &FTPDownloader{userInfo: url.Userinfo{username:"anonymous", password: "anonymous@"}, mtu: mtu}, + "ftp": &FTPDownloader{userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, "http": &HTTPDownloader{userAgent: c.UserAgent}, "https": &HTTPDownloader{userAgent: c.UserAgent}, - "smb": &SMBDownloader{bufferSize: nil} + "smb": &SMBDownloader{bufferSize: nil}, } } return &DownloadClient{config: c} } -// A downloader is responsible for actually taking a remote URL and -// downloading it. +// A downloader implements the ability to transfer a file, and cancel or resume +// it. type Downloader interface { + Resume() Cancel() + Progress() uint64 + Total() uint64 +} + +// A LocalDownloader is responsible for converting a uri to a local path +// that the platform can open directly. +type LocalDownloader interface { + toPath(string, url.URL) (string,error) +} + +// A RemoteDownloader is responsible for actually taking a remote URL and +// downloading it. +type RemoteDownloader interface { Download(*os.File, *url.URL) error - Progress() uint - Total() uint } func (d *DownloadClient) Cancel() { @@ -119,75 +131,54 @@ func (d *DownloadClient) Get() (string, error) { return d.config.TargetPath, nil } + /* parse the configuration url into a net/url object */ u, err := url.Parse(d.config.Url) - if err != nil { - return "", err - } - + if err != nil { return "", err } log.Printf("Parsed URL: %#v", u) - /* FIXME: - handle the special case of d.config.CopyFile which returns the path - in an os-specific format. - */ + /* use the current working directory as the base for relative uri's */ + cwd,err := os.Getwd() + if err != nil { return "", err } - // Files when we don't copy the file are special cased. - var f *os.File + // Determine which is the correct downloader to use var finalPath string - sourcePath := "" - if u.Scheme == "file" && !d.config.CopyFile { - // This is special case for relative path in this case user specify - // file:../ and after parse destination goes to Opaque - if u.Path != "" { - // If url.Path is set just use this - finalPath = u.Path - } else if u.Opaque != "" { - // otherwise try url.Opaque - finalPath = u.Opaque - } - // This is a special case where we use a source file that already exists - // locally and we don't make a copy. Normally we would copy or download. - log.Printf("[DEBUG] Using local file: %s", finalPath) - // transform the actual file uri to a windowsy path if we're being windowsy. - if runtime.GOOS == "windows" { - // FIXME: cwd should point to a path relative to the TEMPLATE path, - // but since this isn't exposed to us anywhere, we use os.Getwd() - // and assume the user ran packer in the same directory that - // any relative files are located at. - cwd,err := os.Getwd() - if err != nil { - return "", fmt.Errorf("Unable to get working directory") - } - finalPath = NormalizeWindowsURL(cwd, *url) - } + var ok bool + d.downloader, ok = d.config.DownloaderMap[u.Scheme] + if !ok { + return "", fmt.Errorf("No downloader for scheme: %s", u.Scheme) + } - // Keep track of the source so we can make sure not to delete this later - sourcePath = finalPath - if _, err = os.Stat(finalPath); err != nil { - return "", err - } - } else { + remote,ok := d.downloader.(RemoteDownloader) + if !ok { + return "", fmt.Errorf("Unable to treat uri scheme %s as a Downloader : %T", u.Scheme, d.downloader) + } + + local,ok := d.downloader.(LocalDownloader) + if !ok && !d.config.CopyFile{ + return "", fmt.Errorf("Not allowed to use uri scheme %s in no copy file mode : %T", u.Scheme, d.downloader) + } + + // If we're copying the file, then just use the actual downloader + if d.config.CopyFile { + var f *os.File finalPath = d.config.TargetPath - var ok bool - d.downloader, ok = d.config.DownloaderMap[u.Scheme] - if !ok { - return "", fmt.Errorf("No downloader for scheme: %s", u.Scheme) - } - - // Otherwise, download using the downloader. f, err = os.OpenFile(finalPath, os.O_RDWR|os.O_CREATE, os.FileMode(0666)) - if err != nil { - return "", err - } + if err != nil { return "", err } log.Printf("[DEBUG] Downloading: %s", u.String()) - err = d.downloader.Download(f, u) + err = remote.Download(f, u) f.Close() - if err != nil { - return "", err - } + if err != nil { return "", err } + + // Otherwise if our Downloader is a LocalDownloader we can just use the + // path after transforming it. + } else { + finalPath,err = local.toPath(cwd, *u) + if err != nil { return "", err } + + log.Printf("[DEBUG] Using local file: %s", finalPath) } if d.config.Hash != nil { @@ -195,9 +186,7 @@ func (d *DownloadClient) Get() (string, error) { verify, err = d.VerifyChecksum(finalPath) if err == nil && !verify { // Only delete the file if we made a copy or downloaded it - if sourcePath != finalPath { - os.Remove(finalPath) - } + if d.config.CopyFile { os.Remove(finalPath) } err = fmt.Errorf( "checksums didn't match expected: %s", @@ -210,10 +199,7 @@ func (d *DownloadClient) Get() (string, error) { // PercentProgress returns the download progress as a percentage. func (d *DownloadClient) PercentProgress() int { - if d.downloader == nil { - return -1 - } - + if d.downloader == nil { return -1 } return int((float64(d.downloader.Progress()) / float64(d.downloader.Total())) * 100) } @@ -239,12 +225,16 @@ func (d *DownloadClient) VerifyChecksum(path string) (bool, error) { // HTTPDownloader is an implementation of Downloader that downloads // files over HTTP. type HTTPDownloader struct { - progress uint - total uint + progress uint64 + total uint64 userAgent string } -func (*HTTPDownloader) Cancel() { +func (d *HTTPDownloader) Cancel() { + // TODO(mitchellh): Implement +} + +func (d *HTTPDownloader) Resume() { // TODO(mitchellh): Implement } @@ -285,7 +275,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { if fi, err := dst.Stat(); err == nil { if _, err = dst.Seek(0, os.SEEK_END); err == nil { req.Header.Set("Range", fmt.Sprintf("bytes=%d-", fi.Size())) - d.progress = uint(fi.Size()) + d.progress = uint64(fi.Size()) } } } @@ -299,7 +289,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { return err } - d.total = d.progress + uint(resp.ContentLength) + d.total = d.progress + uint64(resp.ContentLength) var buffer [4096]byte for { n, err := resp.Body.Read(buffer[:]) @@ -307,7 +297,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { return err } - d.progress += uint(n) + d.progress += uint64(n) if _, werr := dst.Write(buffer[:n]); werr != nil { return werr @@ -321,29 +311,41 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { return nil } -func (d *HTTPDownloader) Progress() uint { +func (d *HTTPDownloader) Progress() uint64 { return d.progress } -func (d *HTTPDownloader) Total() uint { +func (d *HTTPDownloader) Total() uint64 { return d.total } // FTPDownloader is an implementation of Downloader that downloads // files over FTP. type FTPDownloader struct { - userInfo url.UserInfo + userInfo *url.Userinfo mtu uint active bool - progress uint - total uint + progress uint64 + total uint64 } -func (*FTPDownloader) Cancel() { +func (d *FTPDownloader) Progress() uint64 { + return d.progress +} + +func (d *FTPDownloader) Total() uint64 { + return d.total +} + +func (d *FTPDownloader) Cancel() { d.active = false } +func (d *FTPDownloader) Resume() { + // TODO: Implement +} + func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { var userinfo *url.Userinfo @@ -351,33 +353,34 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { d.active = false // check the uri is correct - uri, err := url.Parse(src) - if err != nil { return err } - - if uri.Scheme != "ftp" { - return fmt.Errorf("Unexpected uri scheme: %s", uri.Scheme) + if src == nil || src.Scheme != "ftp" { + return fmt.Errorf("Unexpected uri scheme: %s", src.Scheme) } + uri := src // connect to ftp server var cli *ftp.ServerConn - log.Printf("Starting download over FTP: %s : %s\n", uri.Host, Uri.Path) + log.Printf("Starting download over FTP: %s : %s\n", uri.Host, uri.Path) cli,err := ftp.Dial(uri.Host) if err != nil { return nil } - defer cli.Close() + defer cli.Quit() // handle authentication if uri.User != nil { userinfo = uri.User } - log.Printf("Authenticating to FTP server: %s : %s\n", uri.User.username, uri.User.password) - err = cli.Login(userinfo.username, userinfo.password) + pass,ok := userinfo.Password() + if !ok { pass = "ftp@" } + + log.Printf("Authenticating to FTP server: %s : %s\n", userinfo.Username(), pass) + err = cli.Login(userinfo.Username(), pass) if err != nil { return err } // locate specified path - path := path.Dir(uri.Path) + p := path.Dir(uri.Path) - log.Printf("Changing to FTP directory : %s\n", path) - err = cli.ChangeDir(path) + log.Printf("Changing to FTP directory : %s\n", p) + err = cli.ChangeDir(p) if err != nil { return nil } curpath,err := cli.CurrentDir() @@ -393,7 +396,7 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { entries,err := cli.List(curpath) for _,e := range entries { - if e.Type == ftp.EntryTypeFile && e.Name == name { + if e.Type == ftp.EntryTypeFile && e.Name == name { entry = e break } @@ -414,16 +417,15 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { // do it in a goro so that if someone wants to cancel it, they can errch := make(chan error) - go func(d *FTPDownloader, r *io.Reader, w *bufio.Writer, e chan error) { - defer w.Flush() - for ; d.active { - n,err := io.CopyN(writer, reader, d.mtu) + go func(d *FTPDownloader, r io.Reader, w io.Writer, e chan error) { + for ; d.active; { + n,err := io.CopyN(w, r, int64(d.mtu)) if err != nil { break } - d.progress += n + d.progress += uint64(n) } d.active = false e <- err - }(d, reader, bufio.NewWriter(dst), errch) + }(d, reader, dst, errch) // spin until it's done err = <-errch @@ -433,106 +435,109 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { err = fmt.Errorf("FTP total transfer size was %d when %d was expected", d.progress, d.total) } - // log out and quit + // log out cli.Logout() - cli.Quit() return err } -func (d *FTPDownloader) Progress() uint { - return d.progress -} - -func (d *FTPDownloader) Total() uint { - return d.total -} - // FileDownloader is an implementation of Downloader that downloads // files using the regular filesystem. type FileDownloader struct { bufferSize *uint active bool - progress uint - total uint + progress uint64 + total uint64 } -func (*FileDownloader) Cancel() { +func (d *FileDownloader) Progress() uint64 { + return d.progress +} + +func (d *FileDownloader) Total() uint64 { + return d.total +} + +func (d *FileDownloader) Cancel() { d.active = false } -func (d *FileDownloader) Progress() uint { - return d.progress +func (d *FileDownloader) Resume() { + // TODO: Implement +} + +func (d *FileDownloader) toPath(base string, uri url.URL) (string,error) { + var result string + + // absolute path -- file://c:/absolute/path -> c:/absolute/path + if strings.HasSuffix(uri.Host, ":") { + result = path.Join(uri.Host, uri.Path) + + // semi-absolute path (current drive letter) + // -- file:///absolute/path -> /absolute/path + } else if uri.Host == "" && strings.HasPrefix(uri.Path, "/") { + result = path.Join(filepath.VolumeName(base), uri.Path) + + // relative path -- file://./relative/path -> ./relative/path + } else if uri.Host == "." { + result = path.Join(base, uri.Path) + + // relative path -- file://relative/path -> ./relative/path + } else { + result = path.Join(base, uri.Host, uri.Path) + } + return filepath.ToSlash(result),nil } func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { d.active = false - /* parse the uri using the net/url module */ - uri, err := url.Parse(src) - if uri.Scheme != "file" { - return fmt.Errorf("Unexpected uri scheme: %s", uri.Scheme) + /* check the uri's scheme to make sure it matches */ + if src == nil || src.Scheme != "file" { + return fmt.Errorf("Unexpected uri scheme: %s", src.Scheme) } + uri := src /* use the current working directory as the base for relative uri's */ cwd,err := os.Getwd() - if err != nil { - return "", fmt.Errorf("Unable to get working directory") - } + if err != nil { return err } /* determine which uri format is being used and convert to a real path */ - var realpath string, basepath string - basepath = filepath.ToSlash(cwd) - - // absolute path -- file://c:/absolute/path - if strings.HasSuffix(uri.Host, ":") { - realpath = path.Join(uri.Host, uri.Path) - - // semi-absolute path (current drive letter) -- file:///absolute/path - } else if uri.Host == "" && strings.HasPrefix(uri.Path, "/") { - realpath = path.Join(filepath.VolumeName(basepath), uri.Path) - - // relative path -- file://./relative/path - } else if uri.Host == "." { - realpath = path.Join(basepath, uri.Path) - - // relative path -- file://relative/path - } else { - realpath = path.Join(basepath, uri.Host, uri.Path) - } + realpath,err := d.toPath(cwd, *uri) + if err != nil { return err } /* download the file using the operating system's facilities */ d.progress = 0 d.active = true - f, err = os.Open(realpath) + f, err := os.Open(realpath) if err != nil { return err } defer f.Close() // get the file size fi, err := f.Stat() if err != nil { return err } - d.total = fi.Size() + d.total = uint64(fi.Size()) // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { - n,err := io.Copy(dst, f) + var n int64 + n,err = io.Copy(dst, f) d.active = false - d.progress += n + d.progress += uint64(n) // use a goro in case someone else wants to enable cancel/resume } else { errch := make(chan error) - go func(d* FileDownloader, r *bufio.Reader, w *bufio.Writer, e chan error) { - defer w.Flush() - for ; d.active { - n,err := io.CopyN(writer, reader, d.bufferSize) + go func(d* FileDownloader, r io.Reader, w io.Writer, e chan error) { + for ; d.active; { + n,err := io.CopyN(w, r, int64(*d.bufferSize)) if err != nil { break } - d.progress += n + d.progress += uint64(n) } d.active = false e <- err - }(d, f, bufio.NewWriter(dst), errch) + }(d, f, dst, errch) // ...and we spin until it's done err = <-errch @@ -541,77 +546,91 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { return err } -func (d *FileDownloader) Total() uint { - return d.total -} - // SMBDownloader is an implementation of Downloader that downloads // files using the "\\" path format on Windows type SMBDownloader struct { bufferSize *uint active bool - progress uint - total uint + progress uint64 + total uint64 } -func (*SMBDownloader) Cancel() { - d.active = false -} - -func (d *SMBDownloader) Progress() uint { +func (d *SMBDownloader) Progress() uint64 { return d.progress } -func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { - const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) +func (d *SMBDownloader) Total() uint64 { + return d.total +} + +func (d *SMBDownloader) Cancel() { d.active = false +} + +func (d *SMBDownloader) Resume() { + // TODO: Implement +} + +func (d *SMBDownloader) toPath(base string, uri url.URL) (string,error) { + const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) if runtime.GOOS != "windows" { - return fmt.Errorf("Support for SMB based uri's are not supported on %s", runtime.GOOS) + return "",fmt.Errorf("Support for SMB based uri's are not supported on %s", runtime.GOOS) } + return UNCPrefix + filepath.ToSlash(path.Join(uri.Host, uri.Path)), nil +} + +func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { + d.active = false + /* convert the uri using the net/url module to a UNC path */ - var realpath string - uri, err := url.Parse(src) - if uri.Scheme != "smb" { - return fmt.Errorf("Unexpected uri scheme: %s", uri.Scheme) + if src == nil || src.Scheme != "smb" { + return fmt.Errorf("Unexpected uri scheme: %s", src.Scheme) } + uri := src - realpath = UNCPrefix + filepath.ToSlash(path.Join(uri.Host, uri.Path)) + /* use the current working directory as the base for relative uri's */ + cwd,err := os.Getwd() + if err != nil { return err } + + /* convert uri to an smb-path */ + realpath,err := d.toPath(cwd, *uri) + if err != nil { return err } /* Open up the "\\"-prefixed path using the Windows filesystem */ d.progress = 0 d.active = true - f, err = os.Open(realpath) + f, err := os.Open(realpath) if err != nil { return err } defer f.Close() // get the file size (at the risk of performance) fi, err := f.Stat() if err != nil { return err } - d.total = fi.Size() + d.total = uint64(fi.Size()) // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { - n,err := io.Copy(dst, f) + var n int64 + n,err = io.Copy(dst, f) d.active = false - d.progress += n + d.progress += uint64(n) // use a goro in case someone else wants to enable cancel/resume } else { errch := make(chan error) - go func(d* SMBDownloader, r *bufio.Reader, w *bufio.Writer, e chan error) { - defer w.Flush() - for ; d.active { - n,err := io.CopyN(writer, reader, d.bufferSize) + go func(d* SMBDownloader, r io.Reader, w io.Writer, e chan error) { + for ; d.active; { + n,err := io.CopyN(w, r, int64(*d.bufferSize)) if err != nil { break } - d.progress += n + d.progress += uint64(n) } d.active = false e <- err - }(d, f, bufio.NewWriter(dst), errch) + }(d, f, dst, errch) // ...and as usual we spin until it's done err = <-errch @@ -619,7 +638,3 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { f.Close() return err } - -func (d *SMBDownloader) Total() uint { - return d.total -} From 2f1104625df488bea7d261f079bb69a3eb41d72d Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 5 Apr 2016 16:51:17 -0500 Subject: [PATCH 0389/1007] Fixed some of the unit-tests in common/ due to the changes made in {config,download}.go config.go: Fixed some issues related to the url scheme not being lowercased which broke some of the tests. config_test.go: Removed the UNC share test for \\host\share\file since SMB support has been moved to a different uri scheme. download_test.go: Explicitly set the CopyFile configuration option for all the unit-tests that test file copying capability. Removed the UNC share testcase since it's under a different uri scheme now. Modified the file:// UNC share testcase to explicitly test the smb:// uri. Changed the incorrect t.Errorf calls to t.Logf so that the tests can pass. --- common/config.go | 13 +++++++++++-- common/config_test.go | 24 ++++++++++++++++-------- common/download_test.go | 21 +++++++++++++-------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/common/config.go b/common/config.go index 103c51105..bcc0e08e8 100644 --- a/common/config.go +++ b/common/config.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" "time" + "net/url" ) // PackerKeyEnv is used to specify the key interval (delay) between keystrokes @@ -50,7 +51,7 @@ func DownloadableURL(original string) (string, error) { supported := []string{"file", "http", "https", "ftp", "smb"} found := false for _, s := range supported { - if strings.HasPrefix(original, s + "://") { + if strings.HasPrefix(strings.ToLower(original), s + "://") { found = true break } @@ -59,7 +60,15 @@ func DownloadableURL(original string) (string, error) { // If it's properly prefixed with something we support, then we don't need // to make it a uri. if found { - return original, nil + original = filepath.ToSlash(original) + + // make sure that it can be parsed though.. + uri,err := url.Parse(original) + if err != nil { return "", err } + + uri.Scheme = strings.ToLower(uri.Scheme) + + return uri.String(), nil } // If the file exists, then make it an absolute path diff --git a/common/config_test.go b/common/config_test.go index 365515109..3b1aff8cf 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -5,7 +5,6 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "strings" "testing" ) @@ -38,6 +37,21 @@ func TestChooseString(t *testing.T) { } func TestDownloadableURL(t *testing.T) { + // Invalid URL: has hex code in host + _, err := DownloadableURL("http://what%20.com") + if err == nil { + t.Fatalf("expected err : %s", err) + } + + // Valid: http + u, err := DownloadableURL("HTTP://packer.io/path") + if err != nil { + t.Fatalf("err: %s", err) + } + + if u != "http://packer.io/path" { + t.Fatalf("bad: %s", u) + } cases := []struct { InputString string @@ -154,11 +168,7 @@ func TestDownloadableURL_FilePaths(t *testing.T) { } tfPath = filepath.Clean(tfPath) - filePrefix := "file://" - if runtime.GOOS == "windows" { - filePrefix += "/" - } // Relative filepath. We run this test in a func so that // the defers run right away. @@ -180,9 +190,7 @@ func TestDownloadableURL_FilePaths(t *testing.T) { t.Fatalf("err: %s", err) } - expected := fmt.Sprintf("%s%s", - filePrefix, - strings.Replace(tfPath, `\`, `/`, -1)) + expected := "file://" + strings.Replace(tfPath, `\`, `/`, -1) if u != expected { t.Fatalf("unexpected: %#v != %#v", u, expected) } diff --git a/common/download_test.go b/common/download_test.go index b46d81455..091d9c7d7 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -58,6 +58,7 @@ func TestDownloadClient_basic(t *testing.T) { client := NewDownloadClient(&DownloadConfig{ Url: ts.URL + "/basic.txt", TargetPath: tf.Name(), + CopyFile: true, }) path, err := client.Get() @@ -93,6 +94,7 @@ func TestDownloadClient_checksumBad(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, + CopyFile: true, }) if _, err := client.Get(); err == nil { t.Fatal("should error") @@ -117,6 +119,7 @@ func TestDownloadClient_checksumGood(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, + CopyFile: true, }) path, err := client.Get() if err != nil { @@ -147,6 +150,7 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) { TargetPath: "./test-fixtures/root/another.txt", Hash: HashForType("md5"), Checksum: checksum, + CopyFile: true, }) path, err := client.Get() if err != nil { @@ -185,6 +189,7 @@ func TestDownloadClient_resume(t *testing.T) { client := NewDownloadClient(&DownloadConfig{ Url: ts.URL, TargetPath: tf.Name(), + CopyFile: true, }) path, err := client.Get() if err != nil { @@ -242,6 +247,7 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { config := &DownloadConfig{ Url: server.URL, TargetPath: tf.Name(), + CopyFile: true, } client := NewDownloadClient(config) @@ -273,6 +279,7 @@ func TestDownloadClient_setsUserAgent(t *testing.T) { Url: server.URL, TargetPath: tf.Name(), UserAgent: "fancy user agent", + CopyFile: true, } client := NewDownloadClient(config) @@ -353,6 +360,7 @@ func TestDownloadFileUrl(t *testing.T) { if err != nil { t.Fatalf("Unable to detect working directory: %s", err) } + cwd = filepath.ToSlash(cwd) // source_path is a file path and source is a network path sourcePath := fmt.Sprintf("%s/test-fixtures/fileurl/%s", cwd, "cake") @@ -455,12 +463,10 @@ func TestFileUriTransforms(t *testing.T) { // ./relative/path -> ./relative/path // /absolute/path -> /absolute/path // c:/windows/absolute -> c:/windows/absolute - // \\host/sharename/file -> \\host/sharename/file testcases := []string{ "./%s", cwd + "/%s", volume + cwd + "/%s", - "\\\\" + host + "/" + share + "/" + cwd[1:] + "/%s", } // all regular slashed testcases @@ -471,19 +477,18 @@ func TestFileUriTransforms(t *testing.T) { if err != nil { t.Errorf("Unable to transform uri '%s' into a path : %v", uri, err) } - t.Errorf("TestFileUriTransforms : Result Path '%s'", res) + t.Logf("TestFileUriTransforms : Result Path '%s'", res) } // ...and finally the oddball windows native path - // \\host\sharename\file -> \\host/sharename/file - testpath_native := filepath.FromSlash(testpath) - testcase_native := "\\\\" + host + "\\" + share + "\\" + filepath.FromSlash(cwd[1:]) + "\\%s" - uri := "file://" + fmt.Sprintf(testcase_native, testpath_native) + // smb://host/sharename/file -> \\host\sharename\file + testcase := host + "/" + share + "/" + cwd[1:] + "/%s" + uri := "smb://" + fmt.Sprintf(testcase, testpath) t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) res,err := SimulateFileUriDownload(t, uri) if err != nil { t.Errorf("Unable to transform uri '%s' into a path", uri) return } - t.Errorf("TestFileUriTransforms : Result Path '%s'", res) + t.Logf("TestFileUriTransforms : Result Path '%s'", res) } From 0fa6c3782eed3f4b24d9716903b28fc0c30323f5 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sun, 12 Feb 2017 17:00:47 -0600 Subject: [PATCH 0390/1007] Added a progressbar using gopkg.in/cheggaaa/pb.v1 as per #3578 for all the DownloadClients in common/download.go. --- common/download.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/common/download.go b/common/download.go index c06f385e8..96a40d488 100644 --- a/common/download.go +++ b/common/download.go @@ -23,6 +23,7 @@ import ( "io" "path/filepath" "net/http" + "gopkg.in/cheggaaa/pb.v1" "github.com/jlaffaye/ftp" ) @@ -157,6 +158,7 @@ func (d *DownloadClient) Get() (string, error) { local,ok := d.downloader.(LocalDownloader) if !ok && !d.config.CopyFile{ return "", fmt.Errorf("Not allowed to use uri scheme %s in no copy file mode : %T", u.Scheme, d.downloader) + d.config.CopyFile = true } // If we're copying the file, then just use the actual downloader @@ -275,7 +277,9 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { if fi, err := dst.Stat(); err == nil { if _, err = dst.Seek(0, os.SEEK_END); err == nil { req.Header.Set("Range", fmt.Sprintf("bytes=%d-", fi.Size())) + d.progress = uint64(fi.Size()) + progressBar.Set64(int64(d.Progress())) } } } @@ -290,6 +294,8 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { } d.total = d.progress + uint64(resp.ContentLength) + progressBar := pb.New64(int64(d.Total())).Start() + var buffer [4096]byte for { n, err := resp.Body.Read(buffer[:]) @@ -298,6 +304,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { } d.progress += uint64(n) + progressBar.Set64(int64(d.Progress())) if _, werr := dst.Write(buffer[:n]); werr != nil { return werr @@ -409,6 +416,7 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { d.progress = 0 d.total = entry.Size + progressBar := pb.New64(int64(d.Total())).Start() // download specified file d.active = true @@ -421,7 +429,9 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { for ; d.active; { n,err := io.CopyN(w, r, int64(d.mtu)) if err != nil { break } + d.progress += uint64(n) + progressBar.Set64(int64(d.Progress())) } d.active = false e <- err @@ -518,13 +528,16 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { fi, err := f.Stat() if err != nil { return err } d.total = uint64(fi.Size()) + progressBar := pb.New64(int64(d.Total())).Start() // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { var n int64 n,err = io.Copy(dst, f) d.active = false + d.progress += uint64(n) + progressBar.Set64(int64(d.Progress())) // use a goro in case someone else wants to enable cancel/resume } else { @@ -533,7 +546,9 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { for ; d.active; { n,err := io.CopyN(w, r, int64(*d.bufferSize)) if err != nil { break } + d.progress += uint64(n) + progressBar.Set64(int64(d.Progress())) } d.active = false e <- err @@ -611,13 +626,16 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { fi, err := f.Stat() if err != nil { return err } d.total = uint64(fi.Size()) + progressBar := pb.New64(int64(d.Total())).Start() // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { var n int64 n,err = io.Copy(dst, f) d.active = false + d.progress += uint64(n) + progressBar.Set64(int64(d.Progress())) // use a goro in case someone else wants to enable cancel/resume } else { @@ -626,7 +644,9 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { for ; d.active; { n,err := io.CopyN(w, r, int64(*d.bufferSize)) if err != nil { break } + d.progress += uint64(n) + progressBar.Set64(int64(d.Progress())) } d.active = false e <- err From 11ff4439a691671c36421bb46114386735ce735e Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 1 Mar 2017 14:35:00 -0600 Subject: [PATCH 0391/1007] Moved the setting of HTTPDownloader's current progress to after the object actually gets instantiated. ;) --- common/download.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/download.go b/common/download.go index 96a40d488..f8b273e8d 100644 --- a/common/download.go +++ b/common/download.go @@ -279,7 +279,6 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { req.Header.Set("Range", fmt.Sprintf("bytes=%d-", fi.Size())) d.progress = uint64(fi.Size()) - progressBar.Set64(int64(d.Progress())) } } } @@ -295,6 +294,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { d.total = d.progress + uint64(resp.ContentLength) progressBar := pb.New64(int64(d.Total())).Start() + progressBar.Set64(int64(d.Progress())) var buffer [4096]byte for { From b1ff14714b093bde3b14fc824fad27edcf6de751 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 1 Mar 2017 14:37:05 -0600 Subject: [PATCH 0392/1007] go fmt --- common/config.go | 22 +++-- common/download.go | 205 +++++++++++++++++++++++++--------------- common/download_test.go | 14 +-- 3 files changed, 148 insertions(+), 93 deletions(-) diff --git a/common/config.go b/common/config.go index bcc0e08e8..0e97f6a0e 100644 --- a/common/config.go +++ b/common/config.go @@ -2,11 +2,11 @@ package common import ( "fmt" + "net/url" "os" "path/filepath" "strings" "time" - "net/url" ) // PackerKeyEnv is used to specify the key interval (delay) between keystrokes @@ -51,7 +51,7 @@ func DownloadableURL(original string) (string, error) { supported := []string{"file", "http", "https", "ftp", "smb"} found := false for _, s := range supported { - if strings.HasPrefix(strings.ToLower(original), s + "://") { + if strings.HasPrefix(strings.ToLower(original), s+"://") { found = true break } @@ -63,8 +63,10 @@ func DownloadableURL(original string) (string, error) { original = filepath.ToSlash(original) // make sure that it can be parsed though.. - uri,err := url.Parse(original) - if err != nil { return "", err } + uri, err := url.Parse(original) + if err != nil { + return "", err + } uri.Scheme = strings.ToLower(uri.Scheme) @@ -72,16 +74,20 @@ func DownloadableURL(original string) (string, error) { } // If the file exists, then make it an absolute path - _,err := os.Stat(original) + _, err := os.Stat(original) if err == nil { original, err = filepath.Abs(filepath.FromSlash(original)) - if err != nil { return "", err } + if err != nil { + return "", err + } original, err = filepath.EvalSymlinks(original) - if err != nil { return "", err } + if err != nil { + return "", err + } original = filepath.Clean(original) - original = filepath.ToSlash(original) + original = filepath.ToSlash(original) } // Since it wasn't properly prefixed, let's make it into a well-formed diff --git a/common/download.go b/common/download.go index f8b273e8d..110cb1536 100644 --- a/common/download.go +++ b/common/download.go @@ -13,21 +13,20 @@ import ( "log" "net/url" "os" - "runtime" "path" + "runtime" "strings" ) // imports related to each Downloader implementation import ( - "io" - "path/filepath" - "net/http" - "gopkg.in/cheggaaa/pb.v1" "github.com/jlaffaye/ftp" + "gopkg.in/cheggaaa/pb.v1" + "io" + "net/http" + "path/filepath" ) - // DownloadConfig is the configuration given to instantiate a new // download instance. Once a configuration is used to instantiate // a download client, it must not be modified. @@ -112,7 +111,7 @@ type Downloader interface { // A LocalDownloader is responsible for converting a uri to a local path // that the platform can open directly. type LocalDownloader interface { - toPath(string, url.URL) (string,error) + toPath(string, url.URL) (string, error) } // A RemoteDownloader is responsible for actually taking a remote URL and @@ -134,12 +133,16 @@ func (d *DownloadClient) Get() (string, error) { /* parse the configuration url into a net/url object */ u, err := url.Parse(d.config.Url) - if err != nil { return "", err } + if err != nil { + return "", err + } log.Printf("Parsed URL: %#v", u) /* use the current working directory as the base for relative uri's */ - cwd,err := os.Getwd() - if err != nil { return "", err } + cwd, err := os.Getwd() + if err != nil { + return "", err + } // Determine which is the correct downloader to use var finalPath string @@ -150,13 +153,13 @@ func (d *DownloadClient) Get() (string, error) { return "", fmt.Errorf("No downloader for scheme: %s", u.Scheme) } - remote,ok := d.downloader.(RemoteDownloader) + remote, ok := d.downloader.(RemoteDownloader) if !ok { return "", fmt.Errorf("Unable to treat uri scheme %s as a Downloader : %T", u.Scheme, d.downloader) } - local,ok := d.downloader.(LocalDownloader) - if !ok && !d.config.CopyFile{ + local, ok := d.downloader.(LocalDownloader) + if !ok && !d.config.CopyFile { return "", fmt.Errorf("Not allowed to use uri scheme %s in no copy file mode : %T", u.Scheme, d.downloader) d.config.CopyFile = true } @@ -167,18 +170,24 @@ func (d *DownloadClient) Get() (string, error) { finalPath = d.config.TargetPath f, err = os.OpenFile(finalPath, os.O_RDWR|os.O_CREATE, os.FileMode(0666)) - if err != nil { return "", err } + if err != nil { + return "", err + } log.Printf("[DEBUG] Downloading: %s", u.String()) err = remote.Download(f, u) f.Close() - if err != nil { return "", err } + if err != nil { + return "", err + } - // Otherwise if our Downloader is a LocalDownloader we can just use the - // path after transforming it. + // Otherwise if our Downloader is a LocalDownloader we can just use the + // path after transforming it. } else { - finalPath,err = local.toPath(cwd, *u) - if err != nil { return "", err } + finalPath, err = local.toPath(cwd, *u) + if err != nil { + return "", err + } log.Printf("[DEBUG] Using local file: %s", finalPath) } @@ -188,7 +197,9 @@ func (d *DownloadClient) Get() (string, error) { verify, err = d.VerifyChecksum(finalPath) if err == nil && !verify { // Only delete the file if we made a copy or downloaded it - if d.config.CopyFile { os.Remove(finalPath) } + if d.config.CopyFile { + os.Remove(finalPath) + } err = fmt.Errorf( "checksums didn't match expected: %s", @@ -201,7 +212,9 @@ func (d *DownloadClient) Get() (string, error) { // PercentProgress returns the download progress as a percentage. func (d *DownloadClient) PercentProgress() int { - if d.downloader == nil { return -1 } + if d.downloader == nil { + return -1 + } return int((float64(d.downloader.Progress()) / float64(d.downloader.Total())) * 100) } @@ -330,11 +343,11 @@ func (d *HTTPDownloader) Total() uint64 { // files over FTP. type FTPDownloader struct { userInfo *url.Userinfo - mtu uint + mtu uint - active bool + active bool progress uint64 - total uint64 + total uint64 } func (d *FTPDownloader) Progress() uint64 { @@ -369,40 +382,52 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { var cli *ftp.ServerConn log.Printf("Starting download over FTP: %s : %s\n", uri.Host, uri.Path) - cli,err := ftp.Dial(uri.Host) - if err != nil { return nil } + cli, err := ftp.Dial(uri.Host) + if err != nil { + return nil + } defer cli.Quit() // handle authentication - if uri.User != nil { userinfo = uri.User } + if uri.User != nil { + userinfo = uri.User + } - pass,ok := userinfo.Password() - if !ok { pass = "ftp@" } + pass, ok := userinfo.Password() + if !ok { + pass = "ftp@" + } log.Printf("Authenticating to FTP server: %s : %s\n", userinfo.Username(), pass) err = cli.Login(userinfo.Username(), pass) - if err != nil { return err } + if err != nil { + return err + } // locate specified path p := path.Dir(uri.Path) log.Printf("Changing to FTP directory : %s\n", p) err = cli.ChangeDir(p) - if err != nil { return nil } + if err != nil { + return nil + } - curpath,err := cli.CurrentDir() - if err != nil { return err } + curpath, err := cli.CurrentDir() + if err != nil { + return err + } log.Printf("Current FTP directory : %s\n", curpath) // collect stats about the specified file var name string var entry *ftp.Entry - _,name = path.Split(uri.Path) + _, name = path.Split(uri.Path) entry = nil - entries,err := cli.List(curpath) - for _,e := range entries { + entries, err := cli.List(curpath) + for _, e := range entries { if e.Type == ftp.EntryTypeFile && e.Name == name { entry = e break @@ -420,15 +445,19 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { // download specified file d.active = true - reader,err := cli.RetrFrom(uri.Path, d.progress) - if err != nil { return nil } + reader, err := cli.RetrFrom(uri.Path, d.progress) + if err != nil { + return nil + } // do it in a goro so that if someone wants to cancel it, they can errch := make(chan error) go func(d *FTPDownloader, r io.Reader, w io.Writer, e chan error) { - for ; d.active; { - n,err := io.CopyN(w, r, int64(d.mtu)) - if err != nil { break } + for d.active { + n, err := io.CopyN(w, r, int64(d.mtu)) + if err != nil { + break + } d.progress += uint64(n) progressBar.Set64(int64(d.Progress())) @@ -455,9 +484,9 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { type FileDownloader struct { bufferSize *uint - active bool + active bool progress uint64 - total uint64 + total uint64 } func (d *FileDownloader) Progress() uint64 { @@ -476,27 +505,27 @@ func (d *FileDownloader) Resume() { // TODO: Implement } -func (d *FileDownloader) toPath(base string, uri url.URL) (string,error) { +func (d *FileDownloader) toPath(base string, uri url.URL) (string, error) { var result string // absolute path -- file://c:/absolute/path -> c:/absolute/path if strings.HasSuffix(uri.Host, ":") { result = path.Join(uri.Host, uri.Path) - // semi-absolute path (current drive letter) - // -- file:///absolute/path -> /absolute/path + // semi-absolute path (current drive letter) + // -- file:///absolute/path -> /absolute/path } else if uri.Host == "" && strings.HasPrefix(uri.Path, "/") { result = path.Join(filepath.VolumeName(base), uri.Path) - // relative path -- file://./relative/path -> ./relative/path + // relative path -- file://./relative/path -> ./relative/path } else if uri.Host == "." { result = path.Join(base, uri.Path) - // relative path -- file://relative/path -> ./relative/path + // relative path -- file://relative/path -> ./relative/path } else { result = path.Join(base, uri.Host, uri.Path) } - return filepath.ToSlash(result),nil + return filepath.ToSlash(result), nil } func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { @@ -509,43 +538,53 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { uri := src /* use the current working directory as the base for relative uri's */ - cwd,err := os.Getwd() - if err != nil { return err } + cwd, err := os.Getwd() + if err != nil { + return err + } /* determine which uri format is being used and convert to a real path */ - realpath,err := d.toPath(cwd, *uri) - if err != nil { return err } + realpath, err := d.toPath(cwd, *uri) + if err != nil { + return err + } /* download the file using the operating system's facilities */ d.progress = 0 d.active = true f, err := os.Open(realpath) - if err != nil { return err } + if err != nil { + return err + } defer f.Close() // get the file size fi, err := f.Stat() - if err != nil { return err } + if err != nil { + return err + } d.total = uint64(fi.Size()) progressBar := pb.New64(int64(d.Total())).Start() // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { var n int64 - n,err = io.Copy(dst, f) + n, err = io.Copy(dst, f) d.active = false d.progress += uint64(n) progressBar.Set64(int64(d.Progress())) - // use a goro in case someone else wants to enable cancel/resume + // use a goro in case someone else wants to enable cancel/resume } else { errch := make(chan error) - go func(d* FileDownloader, r io.Reader, w io.Writer, e chan error) { - for ; d.active; { - n,err := io.CopyN(w, r, int64(*d.bufferSize)) - if err != nil { break } + go func(d *FileDownloader, r io.Reader, w io.Writer, e chan error) { + for d.active { + n, err := io.CopyN(w, r, int64(*d.bufferSize)) + if err != nil { + break + } d.progress += uint64(n) progressBar.Set64(int64(d.Progress())) @@ -566,9 +605,9 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { type SMBDownloader struct { bufferSize *uint - active bool + active bool progress uint64 - total uint64 + total uint64 } func (d *SMBDownloader) Progress() uint64 { @@ -587,11 +626,11 @@ func (d *SMBDownloader) Resume() { // TODO: Implement } -func (d *SMBDownloader) toPath(base string, uri url.URL) (string,error) { - const UNCPrefix = string(os.PathSeparator)+string(os.PathSeparator) +func (d *SMBDownloader) toPath(base string, uri url.URL) (string, error) { + const UNCPrefix = string(os.PathSeparator) + string(os.PathSeparator) if runtime.GOOS != "windows" { - return "",fmt.Errorf("Support for SMB based uri's are not supported on %s", runtime.GOOS) + return "", fmt.Errorf("Support for SMB based uri's are not supported on %s", runtime.GOOS) } return UNCPrefix + filepath.ToSlash(path.Join(uri.Host, uri.Path)), nil @@ -607,43 +646,53 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { uri := src /* use the current working directory as the base for relative uri's */ - cwd,err := os.Getwd() - if err != nil { return err } + cwd, err := os.Getwd() + if err != nil { + return err + } /* convert uri to an smb-path */ - realpath,err := d.toPath(cwd, *uri) - if err != nil { return err } + realpath, err := d.toPath(cwd, *uri) + if err != nil { + return err + } /* Open up the "\\"-prefixed path using the Windows filesystem */ d.progress = 0 d.active = true f, err := os.Open(realpath) - if err != nil { return err } + if err != nil { + return err + } defer f.Close() // get the file size (at the risk of performance) fi, err := f.Stat() - if err != nil { return err } + if err != nil { + return err + } d.total = uint64(fi.Size()) progressBar := pb.New64(int64(d.Total())).Start() // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { var n int64 - n,err = io.Copy(dst, f) + n, err = io.Copy(dst, f) d.active = false d.progress += uint64(n) progressBar.Set64(int64(d.Progress())) - // use a goro in case someone else wants to enable cancel/resume + // use a goro in case someone else wants to enable cancel/resume } else { errch := make(chan error) - go func(d* SMBDownloader, r io.Reader, w io.Writer, e chan error) { - for ; d.active; { - n,err := io.CopyN(w, r, int64(*d.bufferSize)) - if err != nil { break } + go func(d *SMBDownloader, r io.Reader, w io.Writer, e chan error) { + for d.active { + n, err := io.CopyN(w, r, int64(*d.bufferSize)) + if err != nil { + break + } d.progress += uint64(n) progressBar.Set64(int64(d.Progress())) diff --git a/common/download_test.go b/common/download_test.go index 091d9c7d7..81cc3244f 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -8,9 +8,9 @@ import ( "net/http" "net/http/httptest" "os" + "path/filepath" "runtime" "strings" - "path/filepath" "testing" ) @@ -119,7 +119,7 @@ func TestDownloadClient_checksumGood(t *testing.T) { TargetPath: tf.Name(), Hash: HashForType("md5"), Checksum: checksum, - CopyFile: true, + CopyFile: true, }) path, err := client.Get() if err != nil { @@ -398,7 +398,7 @@ func TestDownloadFileUrl(t *testing.T) { // into a testable file path whilst ignoring a correct checksum match, stripping // UNC path info, and then calling stat to ensure the correct file exists. // (used by TestFileUriTransforms) -func SimulateFileUriDownload(t *testing.T, uri string) (string,error) { +func SimulateFileUriDownload(t *testing.T, uri string) (string, error) { // source_path is a file path and source is a network path source := fmt.Sprintf(uri) t.Logf("Trying to download %s", source) @@ -430,7 +430,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string,error) { if _, err = os.Stat(path); err != nil { t.Errorf("Could not stat source file: %s", path) } - return path,err + return path, err } // TestFileUriTransforms tests the case where we use a local file uri @@ -470,10 +470,10 @@ func TestFileUriTransforms(t *testing.T) { } // all regular slashed testcases - for _,testcase := range testcases { + for _, testcase := range testcases { uri := "file://" + fmt.Sprintf(testcase, testpath) t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) - res,err := SimulateFileUriDownload(t, uri) + res, err := SimulateFileUriDownload(t, uri) if err != nil { t.Errorf("Unable to transform uri '%s' into a path : %v", uri, err) } @@ -485,7 +485,7 @@ func TestFileUriTransforms(t *testing.T) { testcase := host + "/" + share + "/" + cwd[1:] + "/%s" uri := "smb://" + fmt.Sprintf(testcase, testpath) t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) - res,err := SimulateFileUriDownload(t, uri) + res, err := SimulateFileUriDownload(t, uri) if err != nil { t.Errorf("Unable to transform uri '%s' into a path", uri) return From c29e3915be5a95643a00a103e7d97d607834bfcd Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 1 Mar 2017 14:38:01 -0600 Subject: [PATCH 0393/1007] Added gopkg.in/cheggaaa/pb.v1 to vendor/vendor.json via govendor. --- vendor/gopkg.in/cheggaaa/pb.v1/LICENSE | 12 + vendor/gopkg.in/cheggaaa/pb.v1/README.md | 176 +++++++ vendor/gopkg.in/cheggaaa/pb.v1/format.go | 87 ++++ vendor/gopkg.in/cheggaaa/pb.v1/pb.go | 444 ++++++++++++++++++ vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go | 8 + vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go | 6 + vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go | 141 ++++++ vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go | 110 +++++ vendor/gopkg.in/cheggaaa/pb.v1/pool.go | 76 +++ vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go | 35 ++ vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go | 22 + vendor/gopkg.in/cheggaaa/pb.v1/reader.go | 25 + vendor/gopkg.in/cheggaaa/pb.v1/runecount.go | 17 + vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go | 9 + vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go | 7 + vendor/vendor.json | 16 + 16 files changed, 1191 insertions(+) create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/LICENSE create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/README.md create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/format.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pool.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/reader.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/runecount.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE b/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE new file mode 100644 index 000000000..511970333 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE @@ -0,0 +1,12 @@ +Copyright (c) 2012-2015, Sergey Cherepanov +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/README.md b/vendor/gopkg.in/cheggaaa/pb.v1/README.md new file mode 100644 index 000000000..31babb305 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/README.md @@ -0,0 +1,176 @@ +# Terminal progress bar for Go + +Simple progress bar for console programs. + + +## Installation + +``` +go get gopkg.in/cheggaaa/pb.v1 +``` + +## Usage + +```Go +package main + +import ( + "gopkg.in/cheggaaa/pb.v1" + "time" +) + +func main() { + count := 100000 + bar := pb.StartNew(count) + for i := 0; i < count; i++ { + bar.Increment() + time.Sleep(time.Millisecond) + } + bar.FinishPrint("The End!") +} + +``` + +Result will be like this: + +``` +> go run test.go +37158 / 100000 [================>_______________________________] 37.16% 1m11s +``` + +## Customization + +```Go +// create bar +bar := pb.New(count) + +// refresh info every second (default 200ms) +bar.SetRefreshRate(time.Second) + +// show percents (by default already true) +bar.ShowPercent = true + +// show bar (by default already true) +bar.ShowBar = true + +// no counters +bar.ShowCounters = false + +// show "time left" +bar.ShowTimeLeft = true + +// show average speed +bar.ShowSpeed = true + +// sets the width of the progress bar +bar.SetWidth(80) + +// sets the width of the progress bar, but if terminal size smaller will be ignored +bar.SetMaxWidth(80) + +// convert output to readable format (like KB, MB) +bar.SetUnits(pb.U_BYTES) + +// and start +bar.Start() +``` + +## Progress bar for IO Operations + +```go +// create and start bar +bar := pb.New(myDataLen).SetUnits(pb.U_BYTES) +bar.Start() + +// my io.Reader +r := myReader + +// my io.Writer +w := myWriter + +// create proxy reader +reader := bar.NewProxyReader(r) + +// and copy from pb reader +io.Copy(w, reader) + +``` + +```go +// create and start bar +bar := pb.New(myDataLen).SetUnits(pb.U_BYTES) +bar.Start() + +// my io.Reader +r := myReader + +// my io.Writer +w := myWriter + +// create multi writer +writer := io.MultiWriter(w, bar) + +// and copy +io.Copy(writer, r) + +bar.Finish() +``` + +## Custom Progress Bar Look-and-feel + +```go +bar.Format("<.- >") +``` + +## Multiple Progress Bars (experimental and unstable) + +Do not print to terminal while pool is active. + +```go +package main + +import ( + "math/rand" + "sync" + "time" + + "gopkg.in/cheggaaa/pb.v1" +) + +func main() { + // create bars + first := pb.New(200).Prefix("First ") + second := pb.New(200).Prefix("Second ") + third := pb.New(200).Prefix("Third ") + // start pool + pool, err := pb.StartPool(first, second, third) + if err != nil { + panic(err) + } + // update bars + wg := new(sync.WaitGroup) + for _, bar := range []*pb.ProgressBar{first, second, third} { + wg.Add(1) + go func(cb *pb.ProgressBar) { + for n := 0; n < 200; n++ { + cb.Increment() + time.Sleep(time.Millisecond * time.Duration(rand.Intn(100))) + } + cb.Finish() + wg.Done() + }(bar) + } + wg.Wait() + // close pool + pool.Stop() +} +``` + +The result will be as follows: + +``` +$ go run example/multiple.go +First 141 / 1000 [===============>---------------------------------------] 14.10 % 44s +Second 139 / 1000 [==============>---------------------------------------] 13.90 % 44s +Third 152 / 1000 [================>--------------------------------------] 15.20 % 40s +``` diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/format.go b/vendor/gopkg.in/cheggaaa/pb.v1/format.go new file mode 100644 index 000000000..d5aeff793 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/format.go @@ -0,0 +1,87 @@ +package pb + +import ( + "fmt" + "strings" + "time" +) + +type Units int + +const ( + // U_NO are default units, they represent a simple value and are not formatted at all. + U_NO Units = iota + // U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...) + U_BYTES + // U_DURATION units are formatted in a human readable way (3h14m15s) + U_DURATION +) + +func Format(i int64) *formatter { + return &formatter{n: i} +} + +type formatter struct { + n int64 + unit Units + width int + perSec bool +} + +func (f *formatter) Value(n int64) *formatter { + f.n = n + return f +} + +func (f *formatter) To(unit Units) *formatter { + f.unit = unit + return f +} + +func (f *formatter) Width(width int) *formatter { + f.width = width + return f +} + +func (f *formatter) PerSec() *formatter { + f.perSec = true + return f +} + +func (f *formatter) String() (out string) { + switch f.unit { + case U_BYTES: + out = formatBytes(f.n) + case U_DURATION: + d := time.Duration(f.n) + if d > time.Hour*24 { + out = fmt.Sprintf("%dd", d/24/time.Hour) + d -= (d / time.Hour / 24) * (time.Hour * 24) + } + out = fmt.Sprintf("%s%v", out, d) + default: + out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n) + } + if f.perSec { + out += "/s" + } + return +} + +// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B +func formatBytes(i int64) (result string) { + switch { + case i > (1024 * 1024 * 1024 * 1024): + result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024) + case i > (1024 * 1024 * 1024): + result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024) + case i > (1024 * 1024): + result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024) + case i > 1024: + result = fmt.Sprintf("%.02f KB", float64(i)/1024) + default: + result = fmt.Sprintf("%d B", i) + } + result = strings.Trim(result, " ") + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb.go new file mode 100644 index 000000000..f1f15bff3 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb.go @@ -0,0 +1,444 @@ +// Simple console progress bars +package pb + +import ( + "fmt" + "io" + "math" + "strings" + "sync" + "sync/atomic" + "time" + "unicode/utf8" +) + +// Current version +const Version = "1.0.6" + +const ( + // Default refresh rate - 200ms + DEFAULT_REFRESH_RATE = time.Millisecond * 200 + FORMAT = "[=>-]" +) + +// DEPRECATED +// variables for backward compatibility, from now do not work +// use pb.Format and pb.SetRefreshRate +var ( + DefaultRefreshRate = DEFAULT_REFRESH_RATE + BarStart, BarEnd, Empty, Current, CurrentN string +) + +// Create new progress bar object +func New(total int) *ProgressBar { + return New64(int64(total)) +} + +// Create new progress bar object using int64 as total +func New64(total int64) *ProgressBar { + pb := &ProgressBar{ + Total: total, + RefreshRate: DEFAULT_REFRESH_RATE, + ShowPercent: true, + ShowCounters: true, + ShowBar: true, + ShowTimeLeft: true, + ShowFinalTime: true, + Units: U_NO, + ManualUpdate: false, + finish: make(chan struct{}), + currentValue: -1, + mu: new(sync.Mutex), + } + return pb.Format(FORMAT) +} + +// Create new object and start +func StartNew(total int) *ProgressBar { + return New(total).Start() +} + +// Callback for custom output +// For example: +// bar.Callback = func(s string) { +// mySuperPrint(s) +// } +// +type Callback func(out string) + +type ProgressBar struct { + current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278) + + Total int64 + RefreshRate time.Duration + ShowPercent, ShowCounters bool + ShowSpeed, ShowTimeLeft, ShowBar bool + ShowFinalTime bool + Output io.Writer + Callback Callback + NotPrint bool + Units Units + Width int + ForceWidth bool + ManualUpdate bool + AutoStat bool + + // Default width for the time box. + UnitsWidth int + TimeBoxWidth int + + finishOnce sync.Once //Guards isFinish + finish chan struct{} + isFinish bool + + startTime time.Time + startValue int64 + currentValue int64 + + prefix, postfix string + + mu *sync.Mutex + lastPrint string + + BarStart string + BarEnd string + Empty string + Current string + CurrentN string + + AlwaysUpdate bool +} + +// Start print +func (pb *ProgressBar) Start() *ProgressBar { + pb.startTime = time.Now() + pb.startValue = pb.current + if pb.Total == 0 { + pb.ShowTimeLeft = false + pb.ShowPercent = false + pb.AutoStat = false + } + if !pb.ManualUpdate { + pb.Update() // Initial printing of the bar before running the bar refresher. + go pb.refresher() + } + return pb +} + +// Increment current value +func (pb *ProgressBar) Increment() int { + return pb.Add(1) +} + +// Get current value +func (pb *ProgressBar) Get() int64 { + c := atomic.LoadInt64(&pb.current) + return c +} + +// Set current value +func (pb *ProgressBar) Set(current int) *ProgressBar { + return pb.Set64(int64(current)) +} + +// Set64 sets the current value as int64 +func (pb *ProgressBar) Set64(current int64) *ProgressBar { + atomic.StoreInt64(&pb.current, current) + return pb +} + +// Add to current value +func (pb *ProgressBar) Add(add int) int { + return int(pb.Add64(int64(add))) +} + +func (pb *ProgressBar) Add64(add int64) int64 { + return atomic.AddInt64(&pb.current, add) +} + +// Set prefix string +func (pb *ProgressBar) Prefix(prefix string) *ProgressBar { + pb.prefix = prefix + return pb +} + +// Set postfix string +func (pb *ProgressBar) Postfix(postfix string) *ProgressBar { + pb.postfix = postfix + return pb +} + +// Set custom format for bar +// Example: bar.Format("[=>_]") +// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter +func (pb *ProgressBar) Format(format string) *ProgressBar { + var formatEntries []string + if len(format) == 5 { + formatEntries = strings.Split(format, "") + } else { + formatEntries = strings.Split(format, "\x00") + } + if len(formatEntries) == 5 { + pb.BarStart = formatEntries[0] + pb.BarEnd = formatEntries[4] + pb.Empty = formatEntries[3] + pb.Current = formatEntries[1] + pb.CurrentN = formatEntries[2] + } + return pb +} + +// Set bar refresh rate +func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar { + pb.RefreshRate = rate + return pb +} + +// Set units +// bar.SetUnits(U_NO) - by default +// bar.SetUnits(U_BYTES) - for Mb, Kb, etc +func (pb *ProgressBar) SetUnits(units Units) *ProgressBar { + pb.Units = units + return pb +} + +// Set max width, if width is bigger than terminal width, will be ignored +func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar { + pb.Width = width + pb.ForceWidth = false + return pb +} + +// Set bar width +func (pb *ProgressBar) SetWidth(width int) *ProgressBar { + pb.Width = width + pb.ForceWidth = true + return pb +} + +// End print +func (pb *ProgressBar) Finish() { + //Protect multiple calls + pb.finishOnce.Do(func() { + close(pb.finish) + pb.write(atomic.LoadInt64(&pb.current)) + switch { + case pb.Output != nil: + fmt.Fprintln(pb.Output) + case !pb.NotPrint: + fmt.Println() + } + pb.isFinish = true + }) +} + +// End print and write string 'str' +func (pb *ProgressBar) FinishPrint(str string) { + pb.Finish() + if pb.Output != nil { + fmt.Fprintln(pb.Output, str) + } else { + fmt.Println(str) + } +} + +// implement io.Writer +func (pb *ProgressBar) Write(p []byte) (n int, err error) { + n = len(p) + pb.Add(n) + return +} + +// implement io.Reader +func (pb *ProgressBar) Read(p []byte) (n int, err error) { + n = len(p) + pb.Add(n) + return +} + +// Create new proxy reader over bar +// Takes io.Reader or io.ReadCloser +func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader { + return &Reader{r, pb} +} + +func (pb *ProgressBar) write(current int64) { + width := pb.GetWidth() + + var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string + + // percents + if pb.ShowPercent { + var percent float64 + if pb.Total > 0 { + percent = float64(current) / (float64(pb.Total) / float64(100)) + } else { + percent = float64(current) / float64(100) + } + percentBox = fmt.Sprintf(" %6.02f%%", percent) + } + + // counters + if pb.ShowCounters { + current := Format(current).To(pb.Units).Width(pb.UnitsWidth) + if pb.Total > 0 { + total := Format(pb.Total).To(pb.Units).Width(pb.UnitsWidth) + countersBox = fmt.Sprintf(" %s / %s ", current, total) + } else { + countersBox = fmt.Sprintf(" %s / ? ", current) + } + } + + // time left + fromStart := time.Now().Sub(pb.startTime) + currentFromStart := current - pb.startValue + select { + case <-pb.finish: + if pb.ShowFinalTime { + var left time.Duration + left = (fromStart / time.Second) * time.Second + timeLeftBox = fmt.Sprintf(" %s", left.String()) + } + default: + if pb.ShowTimeLeft && currentFromStart > 0 { + perEntry := fromStart / time.Duration(currentFromStart) + var left time.Duration + if pb.Total > 0 { + left = time.Duration(pb.Total-currentFromStart) * perEntry + left = (left / time.Second) * time.Second + } else { + left = time.Duration(currentFromStart) * perEntry + left = (left / time.Second) * time.Second + } + timeLeft := Format(int64(left)).To(U_DURATION).String() + timeLeftBox = fmt.Sprintf(" %s", timeLeft) + } + } + + if len(timeLeftBox) < pb.TimeBoxWidth { + timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox) + } + + // speed + if pb.ShowSpeed && currentFromStart > 0 { + fromStart := time.Now().Sub(pb.startTime) + speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second)) + speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String() + } + + barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix) + // bar + if pb.ShowBar { + size := width - barWidth + if size > 0 { + if pb.Total > 0 { + curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size))) + emptCount := size - curCount + barBox = pb.BarStart + if emptCount < 0 { + emptCount = 0 + } + if curCount > size { + curCount = size + } + if emptCount <= 0 { + barBox += strings.Repeat(pb.Current, curCount) + } else if curCount > 0 { + barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN + } + barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd + } else { + barBox = pb.BarStart + pos := size - int(current)%int(size) + if pos-1 > 0 { + barBox += strings.Repeat(pb.Empty, pos-1) + } + barBox += pb.Current + if size-pos-1 > 0 { + barBox += strings.Repeat(pb.Empty, size-pos-1) + } + barBox += pb.BarEnd + } + } + } + + // check len + out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix + if escapeAwareRuneCountInString(out) < width { + end = strings.Repeat(" ", width-utf8.RuneCountInString(out)) + } + + // and print! + pb.mu.Lock() + pb.lastPrint = out + end + pb.mu.Unlock() + switch { + case pb.isFinish: + return + case pb.Output != nil: + fmt.Fprint(pb.Output, "\r"+out+end) + case pb.Callback != nil: + pb.Callback(out + end) + case !pb.NotPrint: + fmt.Print("\r" + out + end) + } +} + +// GetTerminalWidth - returns terminal width for all platforms. +func GetTerminalWidth() (int, error) { + return terminalWidth() +} + +func (pb *ProgressBar) GetWidth() int { + if pb.ForceWidth { + return pb.Width + } + + width := pb.Width + termWidth, _ := terminalWidth() + if width == 0 || termWidth <= width { + width = termWidth + } + + return width +} + +// Write the current state of the progressbar +func (pb *ProgressBar) Update() { + c := atomic.LoadInt64(&pb.current) + if pb.AlwaysUpdate || c != pb.currentValue { + pb.write(c) + pb.currentValue = c + } + if pb.AutoStat { + if c == 0 { + pb.startTime = time.Now() + pb.startValue = 0 + } else if c >= pb.Total && pb.isFinish != true { + pb.Finish() + } + } +} + +func (pb *ProgressBar) String() string { + return pb.lastPrint +} + +// Internal loop for refreshing the progressbar +func (pb *ProgressBar) refresher() { + for { + select { + case <-pb.finish: + return + case <-time.After(pb.RefreshRate): + pb.Update() + } + } +} + +type window struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go new file mode 100644 index 000000000..c06097b43 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go @@ -0,0 +1,8 @@ +// +build linux darwin freebsd netbsd openbsd dragonfly +// +build !appengine + +package pb + +import "syscall" + +const sysIoctl = syscall.SYS_IOCTL diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go new file mode 100644 index 000000000..b7d461e17 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go @@ -0,0 +1,6 @@ +// +build solaris +// +build !appengine + +package pb + +const sysIoctl = 54 diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go new file mode 100644 index 000000000..72f682835 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go @@ -0,0 +1,141 @@ +// +build windows + +package pb + +import ( + "errors" + "fmt" + "os" + "sync" + "syscall" + "unsafe" +) + +var tty = os.Stdin + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + + // GetConsoleScreenBufferInfo retrieves information about the + // specified console screen buffer. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + + // GetConsoleMode retrieves the current input mode of a console's + // input buffer or the current output mode of a console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx + getConsoleMode = kernel32.NewProc("GetConsoleMode") + + // SetConsoleMode sets the input mode of a console's input buffer + // or the output mode of a console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + setConsoleMode = kernel32.NewProc("SetConsoleMode") + + // SetConsoleCursorPosition sets the cursor position in the + // specified console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx + setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") +) + +type ( + // Defines the coordinates of the upper left and lower right corners + // of a rectangle. + // See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx + smallRect struct { + Left, Top, Right, Bottom int16 + } + + // Defines the coordinates of a character cell in a console screen + // buffer. The origin of the coordinate system (0,0) is at the top, left cell + // of the buffer. + // See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx + coordinates struct { + X, Y int16 + } + + word int16 + + // Contains information about a console screen buffer. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx + consoleScreenBufferInfo struct { + dwSize coordinates + dwCursorPosition coordinates + wAttributes word + srWindow smallRect + dwMaximumWindowSize coordinates + } +) + +// terminalWidth returns width of the terminal. +func terminalWidth() (width int, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return 0, error(e) + } + return int(info.dwSize.X) - 1, nil +} + +func getCursorPos() (pos coordinates, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return info.dwCursorPosition, error(e) + } + return info.dwCursorPosition, nil +} + +func setCursorPos(pos coordinates) error { + _, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0) + if e != 0 { + return error(e) + } + return nil +} + +var ErrPoolWasStarted = errors.New("Bar pool was started") + +var echoLocked bool +var echoLockMutex sync.Mutex + +var oldState word + +func lockEcho() (quit chan int, err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if echoLocked { + err = ErrPoolWasStarted + return + } + echoLocked = true + + if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 { + err = fmt.Errorf("Can't get terminal settings: %v", e) + return + } + + newState := oldState + const ENABLE_ECHO_INPUT = 0x0004 + const ENABLE_LINE_INPUT = 0x0002 + newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) + if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings: %v", e) + return + } + return +} + +func unlockEcho() (err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if !echoLocked { + return + } + echoLocked = false + if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings") + } + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go new file mode 100644 index 000000000..12e6fe6e2 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go @@ -0,0 +1,110 @@ +// +build linux darwin freebsd netbsd openbsd solaris dragonfly +// +build !appengine + +package pb + +import ( + "errors" + "fmt" + "os" + "os/signal" + "runtime" + "sync" + "syscall" + "unsafe" +) + +const ( + TIOCGWINSZ = 0x5413 + TIOCGWINSZ_OSX = 1074295912 +) + +var tty *os.File + +var ErrPoolWasStarted = errors.New("Bar pool was started") + +var echoLocked bool +var echoLockMutex sync.Mutex + +func init() { + var err error + tty, err = os.Open("/dev/tty") + if err != nil { + tty = os.Stdin + } +} + +// terminalWidth returns width of the terminal. +func terminalWidth() (int, error) { + w := new(window) + tio := syscall.TIOCGWINSZ + if runtime.GOOS == "darwin" { + tio = TIOCGWINSZ_OSX + } + res, _, err := syscall.Syscall(sysIoctl, + tty.Fd(), + uintptr(tio), + uintptr(unsafe.Pointer(w)), + ) + if int(res) == -1 { + return 0, err + } + return int(w.Col), nil +} + +var oldState syscall.Termios + +func lockEcho() (quit chan int, err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if echoLocked { + err = ErrPoolWasStarted + return + } + echoLocked = true + + fd := tty.Fd() + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't get terminal settings: %v", e) + return + } + + newState := oldState + newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings: %v", e) + return + } + quit = make(chan int, 1) + go catchTerminate(quit) + return +} + +func unlockEcho() (err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if !echoLocked { + return + } + echoLocked = false + fd := tty.Fd() + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings") + } + return +} + +// listen exit signals and restore terminal state +func catchTerminate(quit chan int) { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) + defer signal.Stop(sig) + select { + case <-quit: + unlockEcho() + case <-sig: + unlockEcho() + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool.go b/vendor/gopkg.in/cheggaaa/pb.v1/pool.go new file mode 100644 index 000000000..0b4a4afa8 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pool.go @@ -0,0 +1,76 @@ +// +build linux darwin freebsd netbsd openbsd solaris dragonfly windows + +package pb + +import ( + "sync" + "time" +) + +// Create and start new pool with given bars +// You need call pool.Stop() after work +func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) { + pool = new(Pool) + if err = pool.start(); err != nil { + return + } + pool.Add(pbs...) + return +} + +type Pool struct { + RefreshRate time.Duration + bars []*ProgressBar + quit chan int + finishOnce sync.Once +} + +// Add progress bars. +func (p *Pool) Add(pbs ...*ProgressBar) { + for _, bar := range pbs { + bar.ManualUpdate = true + bar.NotPrint = true + bar.Start() + p.bars = append(p.bars, bar) + } +} + +func (p *Pool) start() (err error) { + p.RefreshRate = DefaultRefreshRate + quit, err := lockEcho() + if err != nil { + return + } + p.quit = make(chan int) + go p.writer(quit) + return +} + +func (p *Pool) writer(finish chan int) { + var first = true + for { + select { + case <-time.After(p.RefreshRate): + if p.print(first) { + p.print(false) + finish <- 1 + return + } + first = false + case <-p.quit: + finish <- 1 + return + } + } +} + +// Restore terminal state and close pool +func (p *Pool) Stop() error { + // Wait until one final refresh has passed. + time.Sleep(p.RefreshRate) + + p.finishOnce.Do(func() { + close(p.quit) + }) + return unlockEcho() +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go b/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go new file mode 100644 index 000000000..d7a5ace41 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go @@ -0,0 +1,35 @@ +// +build windows + +package pb + +import ( + "fmt" + "log" +) + +func (p *Pool) print(first bool) bool { + var out string + if !first { + coords, err := getCursorPos() + if err != nil { + log.Panic(err) + } + coords.Y -= int16(len(p.bars)) + coords.X = 0 + + err = setCursorPos(coords) + if err != nil { + log.Panic(err) + } + } + isFinished := true + for _, bar := range p.bars { + if !bar.isFinish { + isFinished = false + } + bar.Update() + out += fmt.Sprintf("\r%s\n", bar.String()) + } + fmt.Print(out) + return isFinished +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go new file mode 100644 index 000000000..d95b71d87 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go @@ -0,0 +1,22 @@ +// +build linux darwin freebsd netbsd openbsd solaris dragonfly + +package pb + +import "fmt" + +func (p *Pool) print(first bool) bool { + var out string + if !first { + out = fmt.Sprintf("\033[%dA", len(p.bars)) + } + isFinished := true + for _, bar := range p.bars { + if !bar.isFinish { + isFinished = false + } + bar.Update() + out += fmt.Sprintf("\r%s\n", bar.String()) + } + fmt.Print(out) + return isFinished +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/reader.go b/vendor/gopkg.in/cheggaaa/pb.v1/reader.go new file mode 100644 index 000000000..9f3148b54 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/reader.go @@ -0,0 +1,25 @@ +package pb + +import ( + "io" +) + +// It's proxy reader, implement io.Reader +type Reader struct { + io.Reader + bar *ProgressBar +} + +func (r *Reader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) + r.bar.Add(n) + return +} + +// Close the reader when it implements io.Closer +func (r *Reader) Close() (err error) { + if closer, ok := r.Reader.(io.Closer); ok { + return closer.Close() + } + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go b/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go new file mode 100644 index 000000000..d52edd365 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go @@ -0,0 +1,17 @@ +package pb + +import ( + "github.com/mattn/go-runewidth" + "regexp" +) + +// Finds the control character sequences (like colors) +var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") + +func escapeAwareRuneCountInString(s string) int { + n := runewidth.StringWidth(s) + for _, sm := range ctrlFinder.FindAllString(s, -1) { + n -= len(sm) + } + return n +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go b/vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go new file mode 100644 index 000000000..517ea8ed7 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go @@ -0,0 +1,9 @@ +// +build darwin freebsd netbsd openbsd dragonfly +// +build !appengine + +package pb + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA +const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go b/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go new file mode 100644 index 000000000..ebb3fe87c --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go @@ -0,0 +1,7 @@ +// +build linux solaris +// +build !appengine + +package pb + +const ioctlReadTermios = 0x5401 // syscall.TCGETS +const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/vendor.json b/vendor/vendor.json index d4d157eb9..eda4727e4 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1480,6 +1480,22 @@ "checksumSHA1": "U7dGDNwEHORvJFMoNSXErKE7ITg=", "path": "google.golang.org/cloud/internal", "revision": "5a3b06f8b5da3b7c3a93da43163b872c86c509ef" + }, + { + "checksumSHA1": "w3z2xM4+RT/OWvVusDgNXZZEEkE=", + "path": "gopkg.in/cheggaaa/pb.v1", + "revision": "d7e6ca3010b6f084d8056847f55d7f572f180678", + "revisionTime": "2016-11-21T09:29:06Z" + }, + { + "checksumSHA1": "gY2M/3SCxqgrPz+P/N6JQ+m/wnA=", + "path": "gopkg.in/xmlpath.v2", + "revision": "860cbeca3ebcc600db0b213c0e83ad6ce91f5739" + }, + { + "checksumSHA1": "0dDWcU08d0FS4d99NCgCkGLjjqw=", + "path": "gopkg.in/xmlpath.v2/cmd/webpath", + "revision": "860cbeca3ebcc600db0b213c0e83ad6ce91f5739" } ], "rootPath": "github.com/hashicorp/packer" From e42a23ecb5ec15489277f8208b2b76def45a65a9 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 1 Mar 2017 14:45:49 -0600 Subject: [PATCH 0394/1007] Ugh..added dependency for gopkg.in/cheggaaa/pb.v1: github.com/matn/go-runewidth. Also added github.com/jlaffaye/ftp for ftp support. --- vendor/github.com/jlaffaye/ftp/LICENSE | 13 + vendor/github.com/jlaffaye/ftp/README.md | 17 + vendor/github.com/jlaffaye/ftp/ftp.go | 671 +++++++++ vendor/github.com/jlaffaye/ftp/status.go | 106 ++ vendor/github.com/mattn/go-runewidth/LICENSE | 21 + .../github.com/mattn/go-runewidth/README.mkd | 27 + .../mattn/go-runewidth/runewidth.go | 1223 +++++++++++++++++ .../mattn/go-runewidth/runewidth_js.go | 8 + .../mattn/go-runewidth/runewidth_posix.go | 77 ++ .../mattn/go-runewidth/runewidth_windows.go | 25 + vendor/vendor.json | 12 + 11 files changed, 2200 insertions(+) create mode 100644 vendor/github.com/jlaffaye/ftp/LICENSE create mode 100644 vendor/github.com/jlaffaye/ftp/README.md create mode 100644 vendor/github.com/jlaffaye/ftp/ftp.go create mode 100644 vendor/github.com/jlaffaye/ftp/status.go create mode 100644 vendor/github.com/mattn/go-runewidth/LICENSE create mode 100644 vendor/github.com/mattn/go-runewidth/README.mkd create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go create mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go diff --git a/vendor/github.com/jlaffaye/ftp/LICENSE b/vendor/github.com/jlaffaye/ftp/LICENSE new file mode 100644 index 000000000..9ab085c51 --- /dev/null +++ b/vendor/github.com/jlaffaye/ftp/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2011-2013, Julien Laffaye <jlaffaye@FreeBSD.org> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/jlaffaye/ftp/README.md b/vendor/github.com/jlaffaye/ftp/README.md new file mode 100644 index 000000000..b711be7ad --- /dev/null +++ b/vendor/github.com/jlaffaye/ftp/README.md @@ -0,0 +1,17 @@ +# goftp # + +[![Build Status](https://travis-ci.org/jlaffaye/ftp.svg?branch=master)](https://travis-ci.org/jlaffaye/ftp) +[![Coverage Status](https://coveralls.io/repos/jlaffaye/ftp/badge.svg?branch=master&service=github)](https://coveralls.io/github/jlaffaye/ftp?branch=master) +[![Go ReportCard](http://goreportcard.com/badge/jlaffaye/ftp)](http://goreportcard.com/report/jlaffaye/ftp) + +A FTP client package for Go + +## Install ## + +``` +go get -u github.com/jlaffaye/ftp +``` + +## Documentation ## + +http://godoc.org/github.com/jlaffaye/ftp diff --git a/vendor/github.com/jlaffaye/ftp/ftp.go b/vendor/github.com/jlaffaye/ftp/ftp.go new file mode 100644 index 000000000..db7ac9277 --- /dev/null +++ b/vendor/github.com/jlaffaye/ftp/ftp.go @@ -0,0 +1,671 @@ +// Package ftp implements a FTP client as described in RFC 959. +package ftp + +import ( + "bufio" + "errors" + "io" + "net" + "net/textproto" + "strconv" + "strings" + "time" +) + +// EntryType describes the different types of an Entry. +type EntryType int + +// The differents types of an Entry +const ( + EntryTypeFile EntryType = iota + EntryTypeFolder + EntryTypeLink +) + +// ServerConn represents the connection to a remote FTP server. +type ServerConn struct { + conn *textproto.Conn + host string + timeout time.Duration + features map[string]string +} + +// Entry describes a file and is returned by List(). +type Entry struct { + Name string + Type EntryType + Size uint64 + Time time.Time +} + +// response represent a data-connection +type response struct { + conn net.Conn + c *ServerConn +} + +// Connect is an alias to Dial, for backward compatibility +func Connect(addr string) (*ServerConn, error) { + return Dial(addr) +} + +// Dial is like DialTimeout with no timeout +func Dial(addr string) (*ServerConn, error) { + return DialTimeout(addr, 0) +} + +// DialTimeout initializes the connection to the specified ftp server address. +// +// It is generally followed by a call to Login() as most FTP commands require +// an authenticated user. +func DialTimeout(addr string, timeout time.Duration) (*ServerConn, error) { + tconn, err := net.DialTimeout("tcp", addr, timeout) + if err != nil { + return nil, err + } + + // Use the resolved IP address in case addr contains a domain name + // If we use the domain name, we might not resolve to the same IP. + remoteAddr := tconn.RemoteAddr().String() + host, _, err := net.SplitHostPort(remoteAddr) + if err != nil { + return nil, err + } + + conn := textproto.NewConn(tconn) + + c := &ServerConn{ + conn: conn, + host: host, + timeout: timeout, + features: make(map[string]string), + } + + _, _, err = c.conn.ReadResponse(StatusReady) + if err != nil { + c.Quit() + return nil, err + } + + err = c.feat() + if err != nil { + c.Quit() + return nil, err + } + + return c, nil +} + +// Login authenticates the client with specified user and password. +// +// "anonymous"/"anonymous" is a common user/password scheme for FTP servers +// that allows anonymous read-only accounts. +func (c *ServerConn) Login(user, password string) error { + code, message, err := c.cmd(-1, "USER %s", user) + if err != nil { + return err + } + + switch code { + case StatusLoggedIn: + case StatusUserOK: + _, _, err = c.cmd(StatusLoggedIn, "PASS %s", password) + if err != nil { + return err + } + default: + return errors.New(message) + } + + // Switch to binary mode + _, _, err = c.cmd(StatusCommandOK, "TYPE I") + if err != nil { + return err + } + + return nil +} + +// feat issues a FEAT FTP command to list the additional commands supported by +// the remote FTP server. +// FEAT is described in RFC 2389 +func (c *ServerConn) feat() error { + code, message, err := c.cmd(-1, "FEAT") + if err != nil { + return err + } + + if code != StatusSystem { + // The server does not support the FEAT command. This is not an + // error: we consider that there is no additional feature. + return nil + } + + lines := strings.Split(message, "\n") + for _, line := range lines { + if !strings.HasPrefix(line, " ") { + continue + } + + line = strings.TrimSpace(line) + featureElements := strings.SplitN(line, " ", 2) + + command := featureElements[0] + + var commandDesc string + if len(featureElements) == 2 { + commandDesc = featureElements[1] + } + + c.features[command] = commandDesc + } + + return nil +} + +// epsv issues an "EPSV" command to get a port number for a data connection. +func (c *ServerConn) epsv() (port int, err error) { + _, line, err := c.cmd(StatusExtendedPassiveMode, "EPSV") + if err != nil { + return + } + + start := strings.Index(line, "|||") + end := strings.LastIndex(line, "|") + if start == -1 || end == -1 { + err = errors.New("Invalid EPSV response format") + return + } + port, err = strconv.Atoi(line[start+3 : end]) + return +} + +// pasv issues a "PASV" command to get a port number for a data connection. +func (c *ServerConn) pasv() (port int, err error) { + _, line, err := c.cmd(StatusPassiveMode, "PASV") + if err != nil { + return + } + + // PASV response format : 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). + start := strings.Index(line, "(") + end := strings.LastIndex(line, ")") + if start == -1 || end == -1 { + return 0, errors.New("Invalid PASV response format") + } + + // We have to split the response string + pasvData := strings.Split(line[start+1:end], ",") + + if len(pasvData) < 6 { + return 0, errors.New("Invalid PASV response format") + } + + // Let's compute the port number + portPart1, err1 := strconv.Atoi(pasvData[4]) + if err1 != nil { + err = err1 + return + } + + portPart2, err2 := strconv.Atoi(pasvData[5]) + if err2 != nil { + err = err2 + return + } + + // Recompose port + port = portPart1*256 + portPart2 + return +} + +// openDataConn creates a new FTP data connection. +func (c *ServerConn) openDataConn() (net.Conn, error) { + var ( + port int + err error + ) + + if port, err = c.epsv(); err != nil { + if port, err = c.pasv(); err != nil { + return nil, err + } + } + + return net.DialTimeout("tcp", net.JoinHostPort(c.host, strconv.Itoa(port)), c.timeout) +} + +// cmd is a helper function to execute a command and check for the expected FTP +// return code +func (c *ServerConn) cmd(expected int, format string, args ...interface{}) (int, string, error) { + _, err := c.conn.Cmd(format, args...) + if err != nil { + return 0, "", err + } + + return c.conn.ReadResponse(expected) +} + +// cmdDataConnFrom executes a command which require a FTP data connection. +// Issues a REST FTP command to specify the number of bytes to skip for the transfer. +func (c *ServerConn) cmdDataConnFrom(offset uint64, format string, args ...interface{}) (net.Conn, error) { + conn, err := c.openDataConn() + if err != nil { + return nil, err + } + + if offset != 0 { + _, _, err := c.cmd(StatusRequestFilePending, "REST %d", offset) + if err != nil { + return nil, err + } + } + + _, err = c.conn.Cmd(format, args...) + if err != nil { + conn.Close() + return nil, err + } + + code, msg, err := c.conn.ReadResponse(-1) + if err != nil { + conn.Close() + return nil, err + } + if code != StatusAlreadyOpen && code != StatusAboutToSend { + conn.Close() + return nil, &textproto.Error{Code: code, Msg: msg} + } + + return conn, nil +} + +var errUnsupportedListLine = errors.New("Unsupported LIST line") + +// parseRFC3659ListLine parses the style of directory line defined in RFC 3659. +func parseRFC3659ListLine(line string) (*Entry, error) { + iSemicolon := strings.Index(line, ";") + iWhitespace := strings.Index(line, " ") + + if iSemicolon < 0 || iSemicolon > iWhitespace { + return nil, errUnsupportedListLine + } + + e := &Entry{ + Name: line[iWhitespace+1:], + } + + for _, field := range strings.Split(line[:iWhitespace-1], ";") { + i := strings.Index(field, "=") + if i < 1 { + return nil, errUnsupportedListLine + } + + key := field[:i] + value := field[i+1:] + + switch key { + case "modify": + var err error + e.Time, err = time.Parse("20060102150405", value) + if err != nil { + return nil, err + } + case "type": + switch value { + case "dir", "cdir", "pdir": + e.Type = EntryTypeFolder + case "file": + e.Type = EntryTypeFile + } + case "size": + e.setSize(value) + } + } + return e, nil +} + +// parseLsListLine parses a directory line in a format based on the output of +// the UNIX ls command. +func parseLsListLine(line string) (*Entry, error) { + fields := strings.Fields(line) + if len(fields) >= 7 && fields[1] == "folder" && fields[2] == "0" { + e := &Entry{ + Type: EntryTypeFolder, + Name: strings.Join(fields[6:], " "), + } + if err := e.setTime(fields[3:6]); err != nil { + return nil, err + } + + return e, nil + } + + if len(fields) < 8 { + return nil, errUnsupportedListLine + } + + if fields[1] == "0" { + e := &Entry{ + Type: EntryTypeFile, + Name: strings.Join(fields[7:], " "), + } + + if err := e.setSize(fields[2]); err != nil { + return nil, err + } + if err := e.setTime(fields[4:7]); err != nil { + return nil, err + } + + return e, nil + } + + if len(fields) < 9 { + return nil, errUnsupportedListLine + } + + e := &Entry{} + switch fields[0][0] { + case '-': + e.Type = EntryTypeFile + if err := e.setSize(fields[4]); err != nil { + return nil, err + } + case 'd': + e.Type = EntryTypeFolder + case 'l': + e.Type = EntryTypeLink + default: + return nil, errors.New("Unknown entry type") + } + + if err := e.setTime(fields[5:8]); err != nil { + return nil, err + } + + e.Name = strings.Join(fields[8:], " ") + return e, nil +} + +var dirTimeFormats = []string{ + "01-02-06 03:04PM", + "2006-01-02 15:04", +} + +// parseDirListLine parses a directory line in a format based on the output of +// the MS-DOS DIR command. +func parseDirListLine(line string) (*Entry, error) { + e := &Entry{} + var err error + + // Try various time formats that DIR might use, and stop when one works. + for _, format := range dirTimeFormats { + if len(line) > len(format) { + e.Time, err = time.Parse(format, line[:len(format)]) + if err == nil { + line = line[len(format):] + break + } + } + } + if err != nil { + // None of the time formats worked. + return nil, errUnsupportedListLine + } + + line = strings.TrimLeft(line, " ") + if strings.HasPrefix(line, "<DIR>") { + e.Type = EntryTypeFolder + line = strings.TrimPrefix(line, "<DIR>") + } else { + space := strings.Index(line, " ") + if space == -1 { + return nil, errUnsupportedListLine + } + e.Size, err = strconv.ParseUint(line[:space], 10, 64) + if err != nil { + return nil, errUnsupportedListLine + } + e.Type = EntryTypeFile + line = line[space:] + } + + e.Name = strings.TrimLeft(line, " ") + return e, nil +} + +var listLineParsers = []func(line string) (*Entry, error){ + parseRFC3659ListLine, + parseLsListLine, + parseDirListLine, +} + +// parseListLine parses the various non-standard format returned by the LIST +// FTP command. +func parseListLine(line string) (*Entry, error) { + for _, f := range listLineParsers { + e, err := f(line) + if err == errUnsupportedListLine { + // Try another format. + continue + } + return e, err + } + return nil, errUnsupportedListLine +} + +func (e *Entry) setSize(str string) (err error) { + e.Size, err = strconv.ParseUint(str, 0, 64) + return +} + +func (e *Entry) setTime(fields []string) (err error) { + var timeStr string + if strings.Contains(fields[2], ":") { // this year + thisYear, _, _ := time.Now().Date() + timeStr = fields[1] + " " + fields[0] + " " + strconv.Itoa(thisYear)[2:4] + " " + fields[2] + " GMT" + } else { // not this year + if len(fields[2]) != 4 { + return errors.New("Invalid year format in time string") + } + timeStr = fields[1] + " " + fields[0] + " " + fields[2][2:4] + " 00:00 GMT" + } + e.Time, err = time.Parse("_2 Jan 06 15:04 MST", timeStr) + return +} + +// NameList issues an NLST FTP command. +func (c *ServerConn) NameList(path string) (entries []string, err error) { + conn, err := c.cmdDataConnFrom(0, "NLST %s", path) + if err != nil { + return + } + + r := &response{conn, c} + defer r.Close() + + scanner := bufio.NewScanner(r) + for scanner.Scan() { + entries = append(entries, scanner.Text()) + } + if err = scanner.Err(); err != nil { + return entries, err + } + return +} + +// List issues a LIST FTP command. +func (c *ServerConn) List(path string) (entries []*Entry, err error) { + conn, err := c.cmdDataConnFrom(0, "LIST %s", path) + if err != nil { + return + } + + r := &response{conn, c} + defer r.Close() + + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + entry, err := parseListLine(line) + if err == nil { + entries = append(entries, entry) + } + } + if err := scanner.Err(); err != nil { + return nil, err + } + return +} + +// ChangeDir issues a CWD FTP command, which changes the current directory to +// the specified path. +func (c *ServerConn) ChangeDir(path string) error { + _, _, err := c.cmd(StatusRequestedFileActionOK, "CWD %s", path) + return err +} + +// ChangeDirToParent issues a CDUP FTP command, which changes the current +// directory to the parent directory. This is similar to a call to ChangeDir +// with a path set to "..". +func (c *ServerConn) ChangeDirToParent() error { + _, _, err := c.cmd(StatusRequestedFileActionOK, "CDUP") + return err +} + +// CurrentDir issues a PWD FTP command, which Returns the path of the current +// directory. +func (c *ServerConn) CurrentDir() (string, error) { + _, msg, err := c.cmd(StatusPathCreated, "PWD") + if err != nil { + return "", err + } + + start := strings.Index(msg, "\"") + end := strings.LastIndex(msg, "\"") + + if start == -1 || end == -1 { + return "", errors.New("Unsuported PWD response format") + } + + return msg[start+1 : end], nil +} + +// Retr issues a RETR FTP command to fetch the specified file from the remote +// FTP server. +// +// The returned ReadCloser must be closed to cleanup the FTP data connection. +func (c *ServerConn) Retr(path string) (io.ReadCloser, error) { + return c.RetrFrom(path, 0) +} + +// RetrFrom issues a RETR FTP command to fetch the specified file from the remote +// FTP server, the server will not send the offset first bytes of the file. +// +// The returned ReadCloser must be closed to cleanup the FTP data connection. +func (c *ServerConn) RetrFrom(path string, offset uint64) (io.ReadCloser, error) { + conn, err := c.cmdDataConnFrom(offset, "RETR %s", path) + if err != nil { + return nil, err + } + + return &response{conn, c}, nil +} + +// Stor issues a STOR FTP command to store a file to the remote FTP server. +// Stor creates the specified file with the content of the io.Reader. +// +// Hint: io.Pipe() can be used if an io.Writer is required. +func (c *ServerConn) Stor(path string, r io.Reader) error { + return c.StorFrom(path, r, 0) +} + +// StorFrom issues a STOR FTP command to store a file to the remote FTP server. +// Stor creates the specified file with the content of the io.Reader, writing +// on the server will start at the given file offset. +// +// Hint: io.Pipe() can be used if an io.Writer is required. +func (c *ServerConn) StorFrom(path string, r io.Reader, offset uint64) error { + conn, err := c.cmdDataConnFrom(offset, "STOR %s", path) + if err != nil { + return err + } + + _, err = io.Copy(conn, r) + conn.Close() + if err != nil { + return err + } + + _, _, err = c.conn.ReadResponse(StatusClosingDataConnection) + return err +} + +// Rename renames a file on the remote FTP server. +func (c *ServerConn) Rename(from, to string) error { + _, _, err := c.cmd(StatusRequestFilePending, "RNFR %s", from) + if err != nil { + return err + } + + _, _, err = c.cmd(StatusRequestedFileActionOK, "RNTO %s", to) + return err +} + +// Delete issues a DELE FTP command to delete the specified file from the +// remote FTP server. +func (c *ServerConn) Delete(path string) error { + _, _, err := c.cmd(StatusRequestedFileActionOK, "DELE %s", path) + return err +} + +// MakeDir issues a MKD FTP command to create the specified directory on the +// remote FTP server. +func (c *ServerConn) MakeDir(path string) error { + _, _, err := c.cmd(StatusPathCreated, "MKD %s", path) + return err +} + +// RemoveDir issues a RMD FTP command to remove the specified directory from +// the remote FTP server. +func (c *ServerConn) RemoveDir(path string) error { + _, _, err := c.cmd(StatusRequestedFileActionOK, "RMD %s", path) + return err +} + +// NoOp issues a NOOP FTP command. +// NOOP has no effects and is usually used to prevent the remote FTP server to +// close the otherwise idle connection. +func (c *ServerConn) NoOp() error { + _, _, err := c.cmd(StatusCommandOK, "NOOP") + return err +} + +// Logout issues a REIN FTP command to logout the current user. +func (c *ServerConn) Logout() error { + _, _, err := c.cmd(StatusReady, "REIN") + return err +} + +// Quit issues a QUIT FTP command to properly close the connection from the +// remote FTP server. +func (c *ServerConn) Quit() error { + c.conn.Cmd("QUIT") + return c.conn.Close() +} + +// Read implements the io.Reader interface on a FTP data connection. +func (r *response) Read(buf []byte) (int, error) { + return r.conn.Read(buf) +} + +// Close implements the io.Closer interface on a FTP data connection. +func (r *response) Close() error { + err := r.conn.Close() + _, _, err2 := r.c.conn.ReadResponse(StatusClosingDataConnection) + if err2 != nil { + err = err2 + } + return err +} diff --git a/vendor/github.com/jlaffaye/ftp/status.go b/vendor/github.com/jlaffaye/ftp/status.go new file mode 100644 index 000000000..e90ca6211 --- /dev/null +++ b/vendor/github.com/jlaffaye/ftp/status.go @@ -0,0 +1,106 @@ +package ftp + +// FTP status codes, defined in RFC 959 +const ( + StatusInitiating = 100 + StatusRestartMarker = 110 + StatusReadyMinute = 120 + StatusAlreadyOpen = 125 + StatusAboutToSend = 150 + + StatusCommandOK = 200 + StatusCommandNotImplemented = 202 + StatusSystem = 211 + StatusDirectory = 212 + StatusFile = 213 + StatusHelp = 214 + StatusName = 215 + StatusReady = 220 + StatusClosing = 221 + StatusDataConnectionOpen = 225 + StatusClosingDataConnection = 226 + StatusPassiveMode = 227 + StatusLongPassiveMode = 228 + StatusExtendedPassiveMode = 229 + StatusLoggedIn = 230 + StatusLoggedOut = 231 + StatusLogoutAck = 232 + StatusRequestedFileActionOK = 250 + StatusPathCreated = 257 + + StatusUserOK = 331 + StatusLoginNeedAccount = 332 + StatusRequestFilePending = 350 + + StatusNotAvailable = 421 + StatusCanNotOpenDataConnection = 425 + StatusTransfertAborted = 426 + StatusInvalidCredentials = 430 + StatusHostUnavailable = 434 + StatusFileActionIgnored = 450 + StatusActionAborted = 451 + Status452 = 452 + + StatusBadCommand = 500 + StatusBadArguments = 501 + StatusNotImplemented = 502 + StatusBadSequence = 503 + StatusNotImplementedParameter = 504 + StatusNotLoggedIn = 530 + StatusStorNeedAccount = 532 + StatusFileUnavailable = 550 + StatusPageTypeUnknown = 551 + StatusExceededStorage = 552 + StatusBadFileName = 553 +) + +var statusText = map[int]string{ + // 200 + StatusCommandOK: "Command okay.", + StatusCommandNotImplemented: "Command not implemented, superfluous at this site.", + StatusSystem: "System status, or system help reply.", + StatusDirectory: "Directory status.", + StatusFile: "File status.", + StatusHelp: "Help message.", + StatusName: "", + StatusReady: "Service ready for new user.", + StatusClosing: "Service closing control connection.", + StatusDataConnectionOpen: "Data connection open; no transfer in progress.", + StatusClosingDataConnection: "Closing data connection. Requested file action successful.", + StatusPassiveMode: "Entering Passive Mode.", + StatusLongPassiveMode: "Entering Long Passive Mode.", + StatusExtendedPassiveMode: "Entering Extended Passive Mode.", + StatusLoggedIn: "User logged in, proceed.", + StatusLoggedOut: "User logged out; service terminated.", + StatusLogoutAck: "Logout command noted, will complete when transfer done.", + StatusRequestedFileActionOK: "Requested file action okay, completed.", + StatusPathCreated: "Path created.", + + // 300 + StatusUserOK: "User name okay, need password.", + StatusLoginNeedAccount: "Need account for login.", + StatusRequestFilePending: "Requested file action pending further information.", + + // 400 + StatusNotAvailable: "Service not available, closing control connection.", + StatusCanNotOpenDataConnection: "Can't open data connection.", + StatusTransfertAborted: "Connection closed; transfer aborted.", + StatusInvalidCredentials: "Invalid username or password.", + StatusHostUnavailable: "Requested host unavailable.", + StatusFileActionIgnored: "Requested file action not taken.", + StatusActionAborted: "Requested action aborted. Local error in processing.", + Status452: "Insufficient storage space in system.", + + // 500 + StatusBadCommand: "Command unrecognized.", + StatusBadArguments: "Syntax error in parameters or arguments.", + StatusNotImplemented: "Command not implemented.", + StatusBadSequence: "Bad sequence of commands.", + StatusNotImplementedParameter: "Command not implemented for that parameter.", + StatusNotLoggedIn: "Not logged in.", + StatusStorNeedAccount: "Need account for storing files.", + StatusFileUnavailable: "File unavailable.", + StatusPageTypeUnknown: "Page type unknown.", + StatusExceededStorage: "Exceeded storage allocation.", + StatusBadFileName: "File name not allowed.", +} diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE new file mode 100644 index 000000000..91b5cef30 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-runewidth/README.mkd b/vendor/github.com/mattn/go-runewidth/README.mkd new file mode 100644 index 000000000..66663a94b --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/README.mkd @@ -0,0 +1,27 @@ +go-runewidth +============ + +[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) +[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) +[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) +[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) + +Provides functions to get fixed width of the character or string. + +Usage +----- + +```go +runewidth.StringWidth("つのだ☆HIRO") == 12 +``` + + +Author +------ + +Yasuhiro Matsumoto + +License +------- + +under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go new file mode 100644 index 000000000..2164497ad --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth.go @@ -0,0 +1,1223 @@ +package runewidth + +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth = IsEastAsian() + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{EastAsianWidth} +) + +type interval struct { + first rune + last rune +} + +type table []interval + +func inTables(r rune, ts ...table) bool { + for _, t := range ts { + if inTable(r, t) { + return true + } + } + return false +} + +func inTable(r rune, t table) bool { + // func (t table) IncludesRune(r rune) bool { + if r < t[0].first { + return false + } + + bot := 0 + top := len(t) - 1 + for top >= bot { + mid := (bot + top) / 2 + + switch { + case t[mid].last < r: + bot = mid + 1 + case t[mid].first > r: + top = mid - 1 + default: + return true + } + } + + return false +} + +var private = table{ + {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, +} + +var nonprint = table{ + {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, + {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, + {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, +} + +var combining = table{ + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, + {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, + {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, + {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, + {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, + {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, + {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, + {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, + {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, + {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, + {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, + {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, + {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, + {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, + {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, + {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, + {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, + {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, + {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, + {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, + {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, + {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, + {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, + {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, + {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, + {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, + {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, + {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, + {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, + {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, + {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, + {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, + {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, + {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, + {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, + {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, + {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, + {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, + {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, + {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, + {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, + {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, + {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, + {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, + {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, + {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, + {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, + {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, + {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, + {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, + {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, + {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, + {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, + {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, + {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, + {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, + {0xE0100, 0xE01EF}, +} + +var doublewidth = table{ + {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, + {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, + {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, + {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, + {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, + {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, + {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, + {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, + {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, + {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, + {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, + {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, + {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +} + +var ambiguous = table{ + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, + {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, + {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, + {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, + {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, + {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, + {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, + {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, + {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, + {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, + {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, + {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, + {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, + {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, + {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, + {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, + {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, + {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, + {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, + {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, + {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, + {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, + {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, + {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, + {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, + {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, + {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, + {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, + {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, + {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, + {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, + {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, +} + +var emoji = table{ + {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, + {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, + {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, + {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, + {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, + {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, + {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, + {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, + {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, + {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, + {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, + {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, + {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, +} + +var notassigned = table{ + {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, + {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, + {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, + {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, + {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, + {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, + {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, + {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, + {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, + {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, + {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, + {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, + {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, + {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, + {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, + {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, + {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, + {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, + {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, + {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, + {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, + {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, + {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, + {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, + {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, + {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, + {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, + {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, + {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, + {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, + {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, + {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, + {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, + {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, + {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, + {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, + {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, + {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, + {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, + {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, + {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, + {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, + {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, + {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, + {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, + {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, + {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, + {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, + {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, + {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, + {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, + {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, + {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, + {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, + {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, + {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, + {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, + {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, + {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, + {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, + {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, + {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, + {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, + {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, + {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, + {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, + {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, + {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, + {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, + {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, + {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, + {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, + {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, + {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, + {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, + {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, + {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, + {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, + {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, + {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, + {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, + {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, + {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, + {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, + {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, + {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, + {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, + {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, + {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, + {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, + {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, + {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, + {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, + {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, + {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, + {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, + {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, + {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, + {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, + {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, + {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, + {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, + {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, + {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, + {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, + {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, + {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, + {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, + {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, + {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, + {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, + {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, + {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, + {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, + {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, + {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, + {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, + {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, + {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, + {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, + {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, + {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, + {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, + {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, + {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, + {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, + {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, + {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, + {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, + {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, + {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, + {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, + {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, + {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, + {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, + {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, + {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, + {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, + {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, + {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, + {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, + {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, + {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, + {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, + {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, + {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, + {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, + {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, + {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, + {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, + {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, + {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, + {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, + {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, + {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, + {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, + {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, + {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, + {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, + {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, + {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, + {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, + {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, + {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, + {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, + {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, + {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, + {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, + {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, + {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, + {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, + {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, + {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, + {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, + {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, + {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, + {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, + {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, + {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, + {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, + {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, + {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, + {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, + {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, + {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, + {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, + {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, + {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, + {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, + {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, + {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, + {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, + {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, + {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, + {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, + {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, + {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, + {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, + {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, + {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, + {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, + {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, + {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, + {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, + {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, + {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, + {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, + {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, + {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, + {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, + {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, + {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, + {0xFFFFE, 0xFFFFF}, +} + +var neutral = table{ + {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, + {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, + {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, + {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, + {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, + {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, + {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, + {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, + {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, + {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, + {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, + {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, + {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, + {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, + {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, + {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, + {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, + {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, + {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, + {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, + {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, + {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, + {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, + {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, + {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, + {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, + {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, + {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, + {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, + {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, + {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, + {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, + {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, + {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, + {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, + {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, + {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, + {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, + {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, + {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, + {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, + {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, + {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, + {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, + {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, + {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, + {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, + {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, + {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, + {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, + {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, + {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, + {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, + {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, + {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, + {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, + {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, + {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, + {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, + {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, + {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, + {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, + {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, + {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, + {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, + {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, + {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, + {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, + {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, + {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, + {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, + {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, + {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, + {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, + {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, + {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, + {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, + {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, + {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, + {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, + {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, + {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, + {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, + {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, + {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, + {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, + {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, + {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, + {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, + {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, + {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, + {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, + {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, + {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, + {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, + {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, + {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, + {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, + {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, + {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, + {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, + {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, + {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, + {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, + {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, + {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, + {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, + {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, + {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, + {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, + {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, + {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, + {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, + {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, + {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, + {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, + {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, + {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, + {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, + {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, + {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, + {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, + {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, + {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, + {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, + {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, + {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, + {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, + {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, + {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, + {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, + {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, + {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, + {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, + {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, + {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, + {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, + {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, + {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, + {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, + {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, + {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, + {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, + {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, + {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, + {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, + {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, + {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, + {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, + {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, + {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, + {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, + {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, + {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, + {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, + {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, + {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, + {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, + {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, + {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, + {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, + {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, + {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, + {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, + {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, + {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, + {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, + {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, + {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, + {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, + {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, + {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, + {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, + {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, + {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, + {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, + {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, + {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, + {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, + {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, + {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, + {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, + {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, + {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, + {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, + {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, + {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, + {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, + {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, + {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, + {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, + {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, + {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, + {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, + {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, + {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, + {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, + {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, + {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, + {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, + {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, + {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, + {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, + {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, + {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, + {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, + {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, + {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, + {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, + {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, + {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, + {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, + {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, + {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, + {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, + {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, + {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, + {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, + {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, + {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, + {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, + {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, + {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, + {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, + {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, + {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, + {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, + {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, + {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, + {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, + {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, + {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, + {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, + {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, + {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, + {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, + {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, + {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, + {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, + {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, + {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, + {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, + {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, + {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, + {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, + {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, + {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, + {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, + {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, + {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, + {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, + {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, + {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, + {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, + {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, + {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, + {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, + {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, + {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, + {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, + {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, + {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, + {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, + {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, + {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, + {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, + {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, + {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, + {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, + {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, + {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, + {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, + {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, + {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, + {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, + {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, + {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, + {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, + {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, + {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, + {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, + {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, + {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, + {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, + {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, + {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, + {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, + {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, + {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, + {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, + {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, + {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, + {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, + {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, + {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, + {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, + {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, + {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, + {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, + {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, + {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, + {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, + {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, + {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, + {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, + {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, + {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, + {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, + {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, + {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, + {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, + {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, + {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, + {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, + {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, + {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, + {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, + {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, + {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, + {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, + {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, + {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, + {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, + {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, + {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, + {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, + {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, + {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, + {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, + {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, + {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, + {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, + {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, + {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, + {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, + {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, + {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, + {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, + {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, + {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, + {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, + {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, + {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, + {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, + {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, + {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, + {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, + {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, + {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, + {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, + {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, + {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, + {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, + {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, + {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, + {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, + {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, + {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, + {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, + {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, + {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, + {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, + {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, + {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, + {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, + {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, + {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, + {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, + {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, + {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, + {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, + {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, + {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, + {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, + {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, + {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, + {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, + {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, + {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, + {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, + {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, + {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, + {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, + {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, + {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, + {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, + {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, + {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, + {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, + {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, + {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, + {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, + {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, + {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, + {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, + {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, + {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, + {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, + {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, + {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, + {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, + {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, + {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, + {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, + {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, + {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, + {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, + {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, + {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, + {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, + {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, + {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, + {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, + {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, + {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, + {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, + {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, + {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, + {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, + {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, + {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, + {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, + {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, + {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, + {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, + {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, + {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, + {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, + {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, + {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, + {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, + {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, + {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, + {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, + {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, + {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, + {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, + {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, + {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, + {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, + {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, + {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, + {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, + {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, + {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, + {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, + {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, + {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, + {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, + {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, + {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, + {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, + {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, + {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, + {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, + {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, + {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, + {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, + {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, + {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, + {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, + {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, + {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, + {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, + {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, + {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, + {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, + {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, + {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, + {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, + {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, + {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, + {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, + {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, + {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, + {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, + {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, + {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, + {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, + {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, + {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, + {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, + {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, + {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, + {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, + {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, + {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, + {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, + {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, + {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, + {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, + {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, + {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, + {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, + {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, + {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, + {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, + {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, + {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, + {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, + {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, + {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, + {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, + {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, + {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, + {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, + {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, + {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, + {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, + {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, + {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, + {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, + {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, + {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, + {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, + {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, + {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, + {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, + {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, + {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, + {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, + {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, + {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, + {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, + {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, + {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, + {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, + {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, + {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, + {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, + {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, + {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, + {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, + {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, + {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, + {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, + {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, + {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, + {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, + {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, + {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, + {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, + {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, + {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, + {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, + {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, + {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, + {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, + {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, + {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, + {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, + {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, + {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, + {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, + {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, + {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, + {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, + {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, + {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, + {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, + {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, + {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, + {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, + {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, + {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, + {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, + {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, + {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, + {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, + {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, + {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, + {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, + {0xE0020, 0xE007F}, +} + +// Condition have flag EastAsianWidth whether the current locale is CJK or not. +type Condition struct { + EastAsianWidth bool +} + +// NewCondition return new instance of Condition which is current locale. +func NewCondition() *Condition { + return &Condition{EastAsianWidth} +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func (c *Condition) RuneWidth(r rune) int { + switch { + case r < 0 || r > 0x10FFFF || + inTables(r, nonprint, combining, notassigned): + return 0 + case (c.EastAsianWidth && IsAmbiguousWidth(r)) || + inTables(r, doublewidth, emoji): + return 2 + default: + return 1 + } +} + +// StringWidth return width as you can see +func (c *Condition) StringWidth(s string) (width int) { + for _, r := range []rune(s) { + width += c.RuneWidth(r) + } + return width +} + +// Truncate return string truncated with w cells +func (c *Condition) Truncate(s string, w int, tail string) string { + if c.StringWidth(s) <= w { + return s + } + r := []rune(s) + tw := c.StringWidth(tail) + w -= tw + width := 0 + i := 0 + for ; i < len(r); i++ { + cw := c.RuneWidth(r[i]) + if width+cw > w { + break + } + width += cw + } + return string(r[0:i]) + tail +} + +// Wrap return string wrapped with w cells +func (c *Condition) Wrap(s string, w int) string { + width := 0 + out := "" + for _, r := range []rune(s) { + cw := RuneWidth(r) + if r == '\n' { + out += string(r) + width = 0 + continue + } else if width+cw > w { + out += "\n" + width = 0 + out += string(r) + width += cw + continue + } + out += string(r) + width += cw + } + return out +} + +// FillLeft return string filled in left by spaces in w cells +func (c *Condition) FillLeft(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return string(b) + s + } + return s +} + +// FillRight return string filled in left by spaces in w cells +func (c *Condition) FillRight(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return s + string(b) + } + return s +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func RuneWidth(r rune) int { + return DefaultCondition.RuneWidth(r) +} + +// IsAmbiguousWidth returns whether is ambiguous width or not. +func IsAmbiguousWidth(r rune) bool { + return inTables(r, private, ambiguous) +} + +// IsNeutralWidth returns whether is neutral width or not. +func IsNeutralWidth(r rune) bool { + return inTable(r, neutral) +} + +// StringWidth return width as you can see +func StringWidth(s string) (width int) { + return DefaultCondition.StringWidth(s) +} + +// Truncate return string truncated with w cells +func Truncate(s string, w int, tail string) string { + return DefaultCondition.Truncate(s, w, tail) +} + +// Wrap return string wrapped with w cells +func Wrap(s string, w int) string { + return DefaultCondition.Wrap(s, w) +} + +// FillLeft return string filled in left by spaces in w cells +func FillLeft(s string, w int) string { + return DefaultCondition.FillLeft(s, w) +} + +// FillRight return string filled in left by spaces in w cells +func FillRight(s string, w int) string { + return DefaultCondition.FillRight(s, w) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go new file mode 100644 index 000000000..0ce32c5e7 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go @@ -0,0 +1,8 @@ +// +build js + +package runewidth + +func IsEastAsian() bool { + // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. + return false +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go new file mode 100644 index 000000000..c579e9a31 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go @@ -0,0 +1,77 @@ +// +build !windows,!js + +package runewidth + +import ( + "os" + "regexp" + "strings" +) + +var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) + +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} + +func isEastAsian(locale string) bool { + charset := strings.ToLower(locale) + r := reLoc.FindStringSubmatch(locale) + if len(r) == 2 { + charset = strings.ToLower(r[1]) + } + + if strings.HasSuffix(charset, "@cjk_narrow") { + return false + } + + for pos, b := range []byte(charset) { + if b == '@' { + charset = charset[:pos] + break + } + } + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m + } + if max > 1 && (charset[0] != 'u' || + strings.HasPrefix(locale, "ja") || + strings.HasPrefix(locale, "ko") || + strings.HasPrefix(locale, "zh")) { + return true + } + return false +} + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_CTYPE") + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go new file mode 100644 index 000000000..0258876b9 --- /dev/null +++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go @@ -0,0 +1,25 @@ +package runewidth + +import ( + "syscall" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") +) + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + r1, _, _ := procGetConsoleOutputCP.Call() + if r1 == 0 { + return false + } + + switch int(r1) { + case 932, 51932, 936, 949, 950: + return true + } + + return false +} diff --git a/vendor/vendor.json b/vendor/vendor.json index eda4727e4..e47378fdf 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -816,6 +816,12 @@ "path": "github.com/hashicorp/yamux", "revision": "df949784da9ed028ee76df44652e42d37a09d7e4" }, + { + "checksumSHA1": "28nznojcl6Ejtm6I1tKozgy0isg=", + "path": "github.com/jlaffaye/ftp", + "revision": "025815df64030c144b86e368fedf80ee195fe464", + "revisionTime": "2016-02-29T21:52:38Z" + }, { "checksumSHA1": "3/Bhy+ua/DCv2ElMD5GzOYSGN6g=", "comment": "0.2.2-2-gc01cf91", @@ -917,6 +923,12 @@ "path": "github.com/mattn/go-isatty", "revision": "56b76bdf51f7708750eac80fa38b952bb9f32639" }, + { + "checksumSHA1": "MNkKJyk2TazKMJYbal5wFHybpyA=", + "path": "github.com/mattn/go-runewidth", + "revision": "14207d285c6c197daabb5c9793d63e7af9ab2d50", + "revisionTime": "2017-02-01T02:35:40Z" + }, { "checksumSHA1": "UP+pXl+ic9y6qrpZA5MqDIAuGfw=", "path": "github.com/mitchellh/cli", From e940dc7e429834095abd53303fe2889ded272f71 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 1 Mar 2017 14:52:55 -0600 Subject: [PATCH 0395/1007] Fixed a config_test that should've failed but didn't because ftp:// uris work now. HeH! --- builder/virtualbox/ovf/config_test.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index 5e67b242d..e9c536e54 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -76,17 +76,6 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("Nonexistant file should throw a validation error!") } - // Bad - c = testConfig(t) - c["source_path"] = "ftp://i/dont/exist" - _, warns, err = NewConfig(c) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should error") - } - // Good tf := getTempFile(t) defer os.Remove(tf.Name()) From d275bacb0f8e9ffa45787bd954742cc9ef62c115 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 23 Mar 2017 14:51:45 -0500 Subject: [PATCH 0396/1007] go fmt builder/vmware/iso/step_create_vmx.go to calm down Travis CI. --- builder/vmware/iso/step_create_vmx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 62546d212..3f3644e70 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -44,7 +44,7 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) // Convert the iso_path into a path relative to the .vmx file if possible - if relativeIsoPath,err := filepath.Rel(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { + if relativeIsoPath, err := filepath.Rel(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { isoPath = relativeIsoPath } From 4783b6508e69d34d65dc32db30e85842ba0d4985 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 23 Mar 2017 15:12:25 -0500 Subject: [PATCH 0397/1007] Fix common/download_test.go to avoid formatting the volume name to a hidden windows share when not on windows. --- common/download_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/download_test.go b/common/download_test.go index 81cc3244f..114ca8ec3 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -452,7 +452,10 @@ func TestFileUriTransforms(t *testing.T) { cwd = filepath.ToSlash(cwd) volume = filepath.VolumeName(cwd) share = volume - if share[len(share)-1] == ':' { + + // if a volume was found (on windows), replace the ':' from + // C: to C$ to convert it into a hidden windows share. + if len(share) > 1 && share[len(share)-1] == ':' { share = share[:len(share)-1] + "$" } cwd = cwd[len(volume):] From 5a4ce2165c22edeec96f1f02b259cbe3e45b30be Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 23 Mar 2017 15:29:38 -0500 Subject: [PATCH 0398/1007] Modified common/download_test.go to not test the smb:// uri on platforms other than windows. Added an immediate platform error to SMBDownloader.Download as opposed to letting .toPath return it (which would have left the structure partially initialized). --- common/download.go | 6 ++++++ common/download_test.go | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/common/download.go b/common/download.go index 110cb1536..5d3621d1c 100644 --- a/common/download.go +++ b/common/download.go @@ -637,6 +637,12 @@ func (d *SMBDownloader) toPath(base string, uri url.URL) (string, error) { } func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { + + /* first we warn the world if we're not running windows */ + if runtime.GOOS != "windows" { + return fmt.Errorf("Support for SMB based uri's are not supported on %s", runtime.GOOS) + } + d.active = false /* convert the uri using the net/url module to a UNC path */ diff --git a/common/download_test.go b/common/download_test.go index 114ca8ec3..a62fceb96 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -483,15 +483,19 @@ func TestFileUriTransforms(t *testing.T) { t.Logf("TestFileUriTransforms : Result Path '%s'", res) } - // ...and finally the oddball windows native path - // smb://host/sharename/file -> \\host\sharename\file - testcase := host + "/" + share + "/" + cwd[1:] + "/%s" - uri := "smb://" + fmt.Sprintf(testcase, testpath) - t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) - res, err := SimulateFileUriDownload(t, uri) - if err != nil { - t.Errorf("Unable to transform uri '%s' into a path", uri) - return + // smb protocol depends on platform support which currently + // only exists on windows. + if runtime.GOOS == "windows" { + // ...and finally the oddball windows native path + // smb://host/sharename/file -> \\host\sharename\file + testcase := host + "/" + share + "/" + cwd[1:] + "/%s" + uri := "smb://" + fmt.Sprintf(testcase, testpath) + t.Logf("TestFileUriTransforms : Trying Uri '%s'", uri) + res, err := SimulateFileUriDownload(t, uri) + if err != nil { + t.Errorf("Unable to transform uri '%s' into a path", uri) + return + } + t.Logf("TestFileUriTransforms : Result Path '%s'", res) } - t.Logf("TestFileUriTransforms : Result Path '%s'", res) } From c978e27f0f7e091092fbc863665370b2c9088b32 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 23 Mar 2017 15:36:40 -0500 Subject: [PATCH 0399/1007] grr. removed an assignment that was dead in common/download.go. --- common/download.go | 1 - 1 file changed, 1 deletion(-) diff --git a/common/download.go b/common/download.go index 5d3621d1c..188a8ca07 100644 --- a/common/download.go +++ b/common/download.go @@ -161,7 +161,6 @@ func (d *DownloadClient) Get() (string, error) { local, ok := d.downloader.(LocalDownloader) if !ok && !d.config.CopyFile { return "", fmt.Errorf("Not allowed to use uri scheme %s in no copy file mode : %T", u.Scheme, d.downloader) - d.config.CopyFile = true } // If we're copying the file, then just use the actual downloader From d85883582fb363ff817ffeb9418c9de53726f7a1 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 6 Dec 2017 16:29:00 -0600 Subject: [PATCH 0400/1007] Changed a critical error to a non-critical one when dealing with the strange .CopyFile flag in common/download.go. --- common/download.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/download.go b/common/download.go index 188a8ca07..46cc1213e 100644 --- a/common/download.go +++ b/common/download.go @@ -155,12 +155,12 @@ func (d *DownloadClient) Get() (string, error) { remote, ok := d.downloader.(RemoteDownloader) if !ok { - return "", fmt.Errorf("Unable to treat uri scheme %s as a Downloader : %T", u.Scheme, d.downloader) + return "", fmt.Errorf("Unable to treat uri scheme %s as a Downloader. : %T", u.Scheme, d.downloader) } local, ok := d.downloader.(LocalDownloader) if !ok && !d.config.CopyFile { - return "", fmt.Errorf("Not allowed to use uri scheme %s in no copy file mode : %T", u.Scheme, d.downloader) + d.config.CopyFile = true } // If we're copying the file, then just use the actual downloader From 69e5eec1ce5378b887d34afb24ece895a763b495 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 6 Dec 2017 17:57:03 -0600 Subject: [PATCH 0401/1007] Consolidated the progress-bar's format into common/step_download.go. Removed DownloadClient's PercentProgress callback since cheggaaa's progress-bar already does that. --- common/download.go | 124 ++++++++++++++++++++++------------------ common/step_download.go | 33 +++++++---- 2 files changed, 91 insertions(+), 66 deletions(-) diff --git a/common/download.go b/common/download.go index 46cc1213e..be53dfed4 100644 --- a/common/download.go +++ b/common/download.go @@ -83,19 +83,19 @@ func HashForType(t string) hash.Hash { // NewDownloadClient returns a new DownloadClient for the given // configuration. -func NewDownloadClient(c *DownloadConfig) *DownloadClient { +func NewDownloadClient(c *DownloadConfig, bar *pb.ProgressBar) *DownloadClient { const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */ if c.DownloaderMap == nil { + // Create downloader map c.DownloaderMap = map[string]Downloader{ - "file": &FileDownloader{bufferSize: nil}, - "ftp": &FTPDownloader{userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, - "http": &HTTPDownloader{userAgent: c.UserAgent}, - "https": &HTTPDownloader{userAgent: c.UserAgent}, - "smb": &SMBDownloader{bufferSize: nil}, + "file": &FileDownloader{progress: bar, bufferSize: nil}, + "ftp": &FTPDownloader{progress: bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, + "http": &HTTPDownloader{progress: bar, userAgent: c.UserAgent}, + "https": &HTTPDownloader{progress: bar, userAgent: c.UserAgent}, + "smb": &SMBDownloader{progress: bar, bufferSize: nil}, } } - return &DownloadClient{config: c} } @@ -209,14 +209,6 @@ func (d *DownloadClient) Get() (string, error) { return finalPath, err } -// PercentProgress returns the download progress as a percentage. -func (d *DownloadClient) PercentProgress() int { - if d.downloader == nil { - return -1 - } - return int((float64(d.downloader.Progress()) / float64(d.downloader.Total())) * 100) -} - // VerifyChecksum tests that the path matches the checksum for the // download. func (d *DownloadClient) VerifyChecksum(path string) (bool, error) { @@ -239,9 +231,11 @@ func (d *DownloadClient) VerifyChecksum(path string) (bool, error) { // HTTPDownloader is an implementation of Downloader that downloads // files over HTTP. type HTTPDownloader struct { - progress uint64 + current uint64 total uint64 userAgent string + + progress *pb.ProgressBar } func (d *HTTPDownloader) Cancel() { @@ -261,7 +255,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { } // Reset our progress - d.progress = 0 + d.current = 0 // Make the request. We first make a HEAD request so we can check // if the server supports range queries. If the server/URL doesn't @@ -290,7 +284,7 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { if _, err = dst.Seek(0, os.SEEK_END); err == nil { req.Header.Set("Range", fmt.Sprintf("bytes=%d-", fi.Size())) - d.progress = uint64(fi.Size()) + d.current = uint64(fi.Size()) } } } @@ -304,9 +298,11 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { return err } - d.total = d.progress + uint64(resp.ContentLength) - progressBar := pb.New64(int64(d.Total())).Start() - progressBar.Set64(int64(d.Progress())) + d.total = d.current + uint64(resp.ContentLength) + + d.progress.Total = int64(d.total) + progressBar := d.progress.Start() + progressBar.Set64(int64(d.current)) var buffer [4096]byte for { @@ -315,8 +311,8 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { return err } - d.progress += uint64(n) - progressBar.Set64(int64(d.Progress())) + d.current += uint64(n) + progressBar.Set64(int64(d.current)) if _, werr := dst.Write(buffer[:n]); werr != nil { return werr @@ -326,12 +322,12 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { break } } - + progressBar.Finish() return nil } func (d *HTTPDownloader) Progress() uint64 { - return d.progress + return d.current } func (d *HTTPDownloader) Total() uint64 { @@ -344,13 +340,15 @@ type FTPDownloader struct { userInfo *url.Userinfo mtu uint - active bool - progress uint64 - total uint64 + active bool + current uint64 + total uint64 + + progress *pb.ProgressBar } func (d *FTPDownloader) Progress() uint64 { - return d.progress + return d.current } func (d *FTPDownloader) Total() uint64 { @@ -438,13 +436,15 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { } log.Printf("Found file : %s : %v bytes\n", entry.Name, entry.Size) - d.progress = 0 + d.current = 0 d.total = entry.Size - progressBar := pb.New64(int64(d.Total())).Start() + + d.progress.Total = int64(d.total) + progressBar := d.progress.Start() // download specified file d.active = true - reader, err := cli.RetrFrom(uri.Path, d.progress) + reader, err := cli.RetrFrom(uri.Path, d.current) if err != nil { return nil } @@ -458,8 +458,8 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { break } - d.progress += uint64(n) - progressBar.Set64(int64(d.Progress())) + d.current += uint64(n) + progressBar.Set64(int64(d.current)) } d.active = false e <- err @@ -467,10 +467,12 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { // spin until it's done err = <-errch + + progressBar.Finish() reader.Close() - if err == nil && d.progress != d.total { - err = fmt.Errorf("FTP total transfer size was %d when %d was expected", d.progress, d.total) + if err == nil && d.current != d.total { + err = fmt.Errorf("FTP total transfer size was %d when %d was expected", d.current, d.total) } // log out @@ -483,13 +485,15 @@ func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { type FileDownloader struct { bufferSize *uint - active bool - progress uint64 - total uint64 + active bool + current uint64 + total uint64 + + progress *pb.ProgressBar } func (d *FileDownloader) Progress() uint64 { - return d.progress + return d.current } func (d *FileDownloader) Total() uint64 { @@ -549,7 +553,7 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { } /* download the file using the operating system's facilities */ - d.progress = 0 + d.current = 0 d.active = true f, err := os.Open(realpath) @@ -564,7 +568,9 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { return err } d.total = uint64(fi.Size()) - progressBar := pb.New64(int64(d.Total())).Start() + + d.progress.Total = int64(d.total) + progressBar := d.progress.Start() // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { @@ -572,8 +578,8 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { n, err = io.Copy(dst, f) d.active = false - d.progress += uint64(n) - progressBar.Set64(int64(d.Progress())) + d.current += uint64(n) + progressBar.Set64(int64(d.current)) // use a goro in case someone else wants to enable cancel/resume } else { @@ -585,8 +591,8 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { break } - d.progress += uint64(n) - progressBar.Set64(int64(d.Progress())) + d.current += uint64(n) + progressBar.Set64(int64(d.current)) } d.active = false e <- err @@ -595,6 +601,7 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { // ...and we spin until it's done err = <-errch } + progressBar.Finish() f.Close() return err } @@ -604,13 +611,15 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { type SMBDownloader struct { bufferSize *uint - active bool - progress uint64 - total uint64 + active bool + current uint64 + total uint64 + + progress *pb.ProgressBar } func (d *SMBDownloader) Progress() uint64 { - return d.progress + return d.current } func (d *SMBDownloader) Total() uint64 { @@ -663,7 +672,7 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { } /* Open up the "\\"-prefixed path using the Windows filesystem */ - d.progress = 0 + d.current = 0 d.active = true f, err := os.Open(realpath) @@ -678,7 +687,9 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { return err } d.total = uint64(fi.Size()) - progressBar := pb.New64(int64(d.Total())).Start() + + d.progress.Total = int64(d.total) + progressBar := d.progress.Start() // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { @@ -686,8 +697,8 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { n, err = io.Copy(dst, f) d.active = false - d.progress += uint64(n) - progressBar.Set64(int64(d.Progress())) + d.current += uint64(n) + progressBar.Set64(int64(d.current)) // use a goro in case someone else wants to enable cancel/resume } else { @@ -699,8 +710,8 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { break } - d.progress += uint64(n) - progressBar.Set64(int64(d.Progress())) + d.current += uint64(n) + progressBar.Set64(int64(d.current)) } d.active = false e <- err @@ -709,6 +720,7 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { // ...and as usual we spin until it's done err = <-errch } + progressBar.Finish() f.Close() return err } diff --git a/common/step_download.go b/common/step_download.go index 765a07d23..2ce48cfff 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -9,6 +9,8 @@ import ( "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" + + "gopkg.in/cheggaaa/pb.v1" ) // StepDownload downloads a remote file using the download client within @@ -139,7 +141,23 @@ func (s *StepDownload) Cleanup(multistep.StateBag) {} func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag) (string, error, bool) { var path string ui := state.Get("ui").(packer.Ui) - download := NewDownloadClient(config) + + // design the appearance of the progress bar + bar := pb.New64(0) + bar.ShowPercent = true + bar.ShowCounters = true + bar.ShowSpeed = false + bar.ShowBar = true + bar.ShowTimeLeft = false + bar.ShowFinalTime = false + bar.SetUnits(pb.U_BYTES) + bar.Format("[=>-]") + bar.SetRefreshRate(1 * time.Second) + bar.SetWidth(25) + bar.Callback = ui.Message + + // create download client with config and progress bar + download := NewDownloadClient(config, bar) downloadCompleteCh := make(chan error, 1) go func() { @@ -148,24 +166,19 @@ func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag downloadCompleteCh <- err }() - progressTicker := time.NewTicker(5 * time.Second) - defer progressTicker.Stop() - for { select { case err := <-downloadCompleteCh: + bar.Finish() + if err != nil { return "", err, true } - return path, nil, true - case <-progressTicker.C: - progress := download.PercentProgress() - if progress >= 0 { - ui.Message(fmt.Sprintf("Download progress: %d%%", progress)) - } + case <-time.After(1 * time.Second): if _, ok := state.GetOk(multistep.StateCancelled); ok { + bar.Finish() ui.Say("Interrupt received. Cancelling download...") return "", nil, false } From 8c6efe336ce4ed5fea9fa816f9ce98d2f51a8dc4 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 7 Dec 2017 11:57:40 -0600 Subject: [PATCH 0402/1007] Added second argument for custom-formatted progress-bar to NewDownloadClient in common/download_test.go. This second parameter was added as a result of commit f0bd9018f3e318caafb1fe7d46e04c470e07c092 which lets you customize the progress-bar format. --- common/download.go | 7 ++++++- common/download_test.go | 20 ++++++++++---------- common/step_download.go | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/common/download.go b/common/download.go index be53dfed4..4826d1dd1 100644 --- a/common/download.go +++ b/common/download.go @@ -86,8 +86,13 @@ func HashForType(t string) hash.Hash { func NewDownloadClient(c *DownloadConfig, bar *pb.ProgressBar) *DownloadClient { const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */ + // If no custom progress-bar was specified, then create a default one. + if bar == nil { + bar = pb.New64(0) + } + + // Create downloader map if it hasn't been specified already. if c.DownloaderMap == nil { - // Create downloader map c.DownloaderMap = map[string]Downloader{ "file": &FileDownloader{progress: bar, bufferSize: nil}, "ftp": &FTPDownloader{progress: bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, diff --git a/common/download_test.go b/common/download_test.go index a62fceb96..50bdfa971 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -36,7 +36,7 @@ func TestDownloadClientVerifyChecksum(t *testing.T) { Checksum: checksum, } - d := NewDownloadClient(config) + d := NewDownloadClient(config, nil) result, err := d.VerifyChecksum(tf.Name()) if err != nil { t.Fatalf("Verify err: %s", err) @@ -59,7 +59,7 @@ func TestDownloadClient_basic(t *testing.T) { Url: ts.URL + "/basic.txt", TargetPath: tf.Name(), CopyFile: true, - }) + }, nil) path, err := client.Get() if err != nil { @@ -95,7 +95,7 @@ func TestDownloadClient_checksumBad(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }) + }, nil) if _, err := client.Get(); err == nil { t.Fatal("should error") } @@ -120,7 +120,7 @@ func TestDownloadClient_checksumGood(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }) + }, nil) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -151,7 +151,7 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }) + }, nil) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -190,7 +190,7 @@ func TestDownloadClient_resume(t *testing.T) { Url: ts.URL, TargetPath: tf.Name(), CopyFile: true, - }) + }, nil) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -250,7 +250,7 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { CopyFile: true, } - client := NewDownloadClient(config) + client := NewDownloadClient(config, nil) _, err = client.Get() if err != nil { t.Fatal(err) @@ -282,7 +282,7 @@ func TestDownloadClient_setsUserAgent(t *testing.T) { CopyFile: true, } - client := NewDownloadClient(config) + client := NewDownloadClient(config, nil) _, err = client.Get() if err != nil { t.Fatal(err) @@ -381,7 +381,7 @@ func TestDownloadFileUrl(t *testing.T) { CopyFile: false, } - client := NewDownloadClient(config) + client := NewDownloadClient(config, nil) // Verify that we fail to match the checksum _, err = client.Get() @@ -412,7 +412,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string, error) { } // go go go - client := NewDownloadClient(config) + client := NewDownloadClient(config, nil) path, err := client.Get() // ignore any non-important checksum errors if it's not a unc path diff --git a/common/step_download.go b/common/step_download.go index 2ce48cfff..a4f249290 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -96,7 +96,7 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { } downloadConfigs[i] = config - if match, _ := NewDownloadClient(config).VerifyChecksum(config.TargetPath); match { + if match, _ := NewDownloadClient(config, nil).VerifyChecksum(config.TargetPath); match { ui.Message(fmt.Sprintf("Found already downloaded, initial checksum matched, no download needed: %s", url)) finalPath = config.TargetPath break From ab4490b9679765d77f275eb2ac958e5ac88c8d30 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 2 Jan 2018 17:26:25 -0600 Subject: [PATCH 0403/1007] Consolidated progress bar's appearance into the GetDefaultProgressBar() function. Updated dependency for cheggaaa's progress-bar from the gopkg.in location to the better maintained one on github.com. --- common/download.go | 19 ++- common/step_download.go | 27 ++-- .../pb.v1 => github.com/cheggaaa/pb}/LICENSE | 0 .../cheggaaa/pb}/README.md | 7 +- vendor/github.com/cheggaaa/pb/format.go | 118 ++++++++++++++++++ .../pb.v1 => github.com/cheggaaa/pb}/pb.go | 103 +++++++++------ .../cheggaaa/pb}/pb_win.go | 0 vendor/github.com/cheggaaa/pb/pb_x.go | 108 ++++++++++++++++ .../pb.v1 => github.com/cheggaaa/pb}/pool.go | 14 ++- .../cheggaaa/pb}/pool_win.go | 16 ++- .../cheggaaa/pb}/pool_x.go | 13 +- .../cheggaaa/pb}/reader.go | 0 .../cheggaaa/pb}/runecount.go | 2 +- .../cheggaaa/pb}/termios_bsd.go | 0 vendor/github.com/cheggaaa/pb/termios_sysv.go | 13 ++ vendor/gopkg.in/cheggaaa/pb.v1/format.go | 87 ------------- vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go | 8 -- vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go | 6 - vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go | 110 ---------------- vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go | 7 -- vendor/vendor.json | 12 +- 21 files changed, 373 insertions(+), 297 deletions(-) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/LICENSE (100%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/README.md (89%) create mode 100644 vendor/github.com/cheggaaa/pb/format.go rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/pb.go (82%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/pb_win.go (100%) create mode 100644 vendor/github.com/cheggaaa/pb/pb_x.go rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/pool.go (84%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/pool_win.go (64%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/pool_x.go (59%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/reader.go (100%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/runecount.go (90%) rename vendor/{gopkg.in/cheggaaa/pb.v1 => github.com/cheggaaa/pb}/termios_bsd.go (100%) create mode 100644 vendor/github.com/cheggaaa/pb/termios_sysv.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/format.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go diff --git a/common/download.go b/common/download.go index 4826d1dd1..e5ebe305f 100644 --- a/common/download.go +++ b/common/download.go @@ -20,8 +20,8 @@ import ( // imports related to each Downloader implementation import ( + "github.com/cheggaaa/pb" "github.com/jlaffaye/ftp" - "gopkg.in/cheggaaa/pb.v1" "io" "net/http" "path/filepath" @@ -83,22 +83,17 @@ func HashForType(t string) hash.Hash { // NewDownloadClient returns a new DownloadClient for the given // configuration. -func NewDownloadClient(c *DownloadConfig, bar *pb.ProgressBar) *DownloadClient { +func NewDownloadClient(c *DownloadConfig, bar pb.ProgressBar) *DownloadClient { const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */ - // If no custom progress-bar was specified, then create a default one. - if bar == nil { - bar = pb.New64(0) - } - // Create downloader map if it hasn't been specified already. if c.DownloaderMap == nil { c.DownloaderMap = map[string]Downloader{ - "file": &FileDownloader{progress: bar, bufferSize: nil}, - "ftp": &FTPDownloader{progress: bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, - "http": &HTTPDownloader{progress: bar, userAgent: c.UserAgent}, - "https": &HTTPDownloader{progress: bar, userAgent: c.UserAgent}, - "smb": &SMBDownloader{progress: bar, bufferSize: nil}, + "file": &FileDownloader{progress: &bar, bufferSize: nil}, + "ftp": &FTPDownloader{progress: &bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, + "http": &HTTPDownloader{progress: &bar, userAgent: c.UserAgent}, + "https": &HTTPDownloader{progress: &bar, userAgent: c.UserAgent}, + "smb": &SMBDownloader{progress: &bar, bufferSize: nil}, } } return &DownloadClient{config: c} diff --git a/common/step_download.go b/common/step_download.go index a4f249290..f483eaba6 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -7,10 +7,9 @@ import ( "log" "time" + "github.com/cheggaaa/pb" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - - "gopkg.in/cheggaaa/pb.v1" ) // StepDownload downloads a remote file using the download client within @@ -63,6 +62,10 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) + // Get a default-looking progress bar and connect it to the ui. + bar := GetDefaultProgressBar() + bar.Callback = ui.Message + // First try to use any already downloaded file // If it fails, proceed to regualar download logic @@ -96,7 +99,7 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { } downloadConfigs[i] = config - if match, _ := NewDownloadClient(config, nil).VerifyChecksum(config.TargetPath); match { + if match, _ := NewDownloadClient(config, bar).VerifyChecksum(config.TargetPath); match { ui.Message(fmt.Sprintf("Found already downloaded, initial checksum matched, no download needed: %s", url)) finalPath = config.TargetPath break @@ -138,11 +141,7 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { func (s *StepDownload) Cleanup(multistep.StateBag) {} -func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag) (string, error, bool) { - var path string - ui := state.Get("ui").(packer.Ui) - - // design the appearance of the progress bar +func GetDefaultProgressBar() pb.ProgressBar { bar := pb.New64(0) bar.ShowPercent = true bar.ShowCounters = true @@ -154,9 +153,19 @@ func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag bar.Format("[=>-]") bar.SetRefreshRate(1 * time.Second) bar.SetWidth(25) + + return *bar +} + +func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag) (string, error, bool) { + var path string + ui := state.Get("ui").(packer.Ui) + + // Get a default looking progress bar and connect it to the ui. + bar := GetDefaultProgressBar() bar.Callback = ui.Message - // create download client with config and progress bar + // Create download client with config and progress bar download := NewDownloadClient(config, bar) downloadCompleteCh := make(chan error, 1) diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE b/vendor/github.com/cheggaaa/pb/LICENSE similarity index 100% rename from vendor/gopkg.in/cheggaaa/pb.v1/LICENSE rename to vendor/github.com/cheggaaa/pb/LICENSE diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/README.md b/vendor/github.com/cheggaaa/pb/README.md similarity index 89% rename from vendor/gopkg.in/cheggaaa/pb.v1/README.md rename to vendor/github.com/cheggaaa/pb/README.md index 31babb305..948545110 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/README.md +++ b/vendor/github.com/cheggaaa/pb/README.md @@ -1,7 +1,10 @@ # Terminal progress bar for Go -Simple progress bar for console programs. - +[![Join the chat at https://gitter.im/cheggaaa/pb](https://badges.gitter.im/cheggaaa/pb.svg)](https://gitter.im/cheggaaa/pb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +Simple progress bar for console programs. + +Please check the new version https://github.com/cheggaaa/pb/tree/v2 (currently, it's beta) ## Installation diff --git a/vendor/github.com/cheggaaa/pb/format.go b/vendor/github.com/cheggaaa/pb/format.go new file mode 100644 index 000000000..0723561c2 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/format.go @@ -0,0 +1,118 @@ +package pb + +import ( + "fmt" + "time" +) + +type Units int + +const ( + // U_NO are default units, they represent a simple value and are not formatted at all. + U_NO Units = iota + // U_BYTES units are formatted in a human readable way (B, KiB, MiB, ...) + U_BYTES + // U_BYTES_DEC units are like U_BYTES, but base 10 (B, KB, MB, ...) + U_BYTES_DEC + // U_DURATION units are formatted in a human readable way (3h14m15s) + U_DURATION +) + +const ( + KiB = 1024 + MiB = 1048576 + GiB = 1073741824 + TiB = 1099511627776 + + KB = 1e3 + MB = 1e6 + GB = 1e9 + TB = 1e12 +) + +func Format(i int64) *formatter { + return &formatter{n: i} +} + +type formatter struct { + n int64 + unit Units + width int + perSec bool +} + +func (f *formatter) To(unit Units) *formatter { + f.unit = unit + return f +} + +func (f *formatter) Width(width int) *formatter { + f.width = width + return f +} + +func (f *formatter) PerSec() *formatter { + f.perSec = true + return f +} + +func (f *formatter) String() (out string) { + switch f.unit { + case U_BYTES: + out = formatBytes(f.n) + case U_BYTES_DEC: + out = formatBytesDec(f.n) + case U_DURATION: + out = formatDuration(f.n) + default: + out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n) + } + if f.perSec { + out += "/s" + } + return +} + +// Convert bytes to human readable string. Like 2 MiB, 64.2 KiB, 52 B +func formatBytes(i int64) (result string) { + switch { + case i >= TiB: + result = fmt.Sprintf("%.02f TiB", float64(i)/TiB) + case i >= GiB: + result = fmt.Sprintf("%.02f GiB", float64(i)/GiB) + case i >= MiB: + result = fmt.Sprintf("%.02f MiB", float64(i)/MiB) + case i >= KiB: + result = fmt.Sprintf("%.02f KiB", float64(i)/KiB) + default: + result = fmt.Sprintf("%d B", i) + } + return +} + +// Convert bytes to base-10 human readable string. Like 2 MB, 64.2 KB, 52 B +func formatBytesDec(i int64) (result string) { + switch { + case i >= TB: + result = fmt.Sprintf("%.02f TB", float64(i)/TB) + case i >= GB: + result = fmt.Sprintf("%.02f GB", float64(i)/GB) + case i >= MB: + result = fmt.Sprintf("%.02f MB", float64(i)/MB) + case i >= KB: + result = fmt.Sprintf("%.02f KB", float64(i)/KB) + default: + result = fmt.Sprintf("%d B", i) + } + return +} + +func formatDuration(n int64) (result string) { + d := time.Duration(n) + if d > time.Hour*24 { + result = fmt.Sprintf("%dd", d/24/time.Hour) + d -= (d / time.Hour / 24) * (time.Hour * 24) + } + result = fmt.Sprintf("%s%v", result, d) + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb.go b/vendor/github.com/cheggaaa/pb/pb.go similarity index 82% rename from vendor/gopkg.in/cheggaaa/pb.v1/pb.go rename to vendor/github.com/cheggaaa/pb/pb.go index f1f15bff3..19eb4d1a9 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pb.go +++ b/vendor/github.com/cheggaaa/pb/pb.go @@ -13,7 +13,7 @@ import ( ) // Current version -const Version = "1.0.6" +const Version = "1.0.19" const ( // Default refresh rate - 200ms @@ -47,8 +47,6 @@ func New64(total int64) *ProgressBar { Units: U_NO, ManualUpdate: false, finish: make(chan struct{}), - currentValue: -1, - mu: new(sync.Mutex), } return pb.Format(FORMAT) } @@ -67,7 +65,8 @@ func StartNew(total int) *ProgressBar { type Callback func(out string) type ProgressBar struct { - current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278) + current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278) + previous int64 Total int64 RefreshRate time.Duration @@ -91,13 +90,14 @@ type ProgressBar struct { finish chan struct{} isFinish bool - startTime time.Time - startValue int64 - currentValue int64 + startTime time.Time + startValue int64 + + changeTime time.Time prefix, postfix string - mu *sync.Mutex + mu sync.Mutex lastPrint string BarStart string @@ -112,7 +112,7 @@ type ProgressBar struct { // Start print func (pb *ProgressBar) Start() *ProgressBar { pb.startTime = time.Now() - pb.startValue = pb.current + pb.startValue = atomic.LoadInt64(&pb.current) if pb.Total == 0 { pb.ShowTimeLeft = false pb.ShowPercent = false @@ -173,7 +173,7 @@ func (pb *ProgressBar) Postfix(postfix string) *ProgressBar { // Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter func (pb *ProgressBar) Format(format string) *ProgressBar { var formatEntries []string - if len(format) == 5 { + if utf8.RuneCountInString(format) == 5 { formatEntries = strings.Split(format, "") } else { formatEntries = strings.Split(format, "\x00") @@ -222,6 +222,8 @@ func (pb *ProgressBar) Finish() { pb.finishOnce.Do(func() { close(pb.finish) pb.write(atomic.LoadInt64(&pb.current)) + pb.mu.Lock() + defer pb.mu.Unlock() switch { case pb.Output != nil: fmt.Fprintln(pb.Output) @@ -232,6 +234,13 @@ func (pb *ProgressBar) Finish() { }) } +// IsFinished return boolean +func (pb *ProgressBar) IsFinished() bool { + pb.mu.Lock() + defer pb.mu.Unlock() + return pb.isFinish +} + // End print and write string 'str' func (pb *ProgressBar) FinishPrint(str string) { pb.Finish() @@ -290,8 +299,12 @@ func (pb *ProgressBar) write(current int64) { } // time left - fromStart := time.Now().Sub(pb.startTime) + pb.mu.Lock() currentFromStart := current - pb.startValue + fromStart := time.Now().Sub(pb.startTime) + lastChangeTime := pb.changeTime + fromChange := lastChangeTime.Sub(pb.startTime) + pb.mu.Unlock() select { case <-pb.finish: if pb.ShowFinalTime { @@ -301,17 +314,20 @@ func (pb *ProgressBar) write(current int64) { } default: if pb.ShowTimeLeft && currentFromStart > 0 { - perEntry := fromStart / time.Duration(currentFromStart) + perEntry := fromChange / time.Duration(currentFromStart) var left time.Duration if pb.Total > 0 { left = time.Duration(pb.Total-currentFromStart) * perEntry + left -= time.Since(lastChangeTime) left = (left / time.Second) * time.Second } else { left = time.Duration(currentFromStart) * perEntry left = (left / time.Second) * time.Second } - timeLeft := Format(int64(left)).To(U_DURATION).String() - timeLeftBox = fmt.Sprintf(" %s", timeLeft) + if left > 0 { + timeLeft := Format(int64(left)).To(U_DURATION).String() + timeLeftBox = fmt.Sprintf(" %s", timeLeft) + } } } @@ -332,24 +348,32 @@ func (pb *ProgressBar) write(current int64) { size := width - barWidth if size > 0 { if pb.Total > 0 { - curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size))) - emptCount := size - curCount + curSize := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size))) + emptySize := size - curSize barBox = pb.BarStart - if emptCount < 0 { - emptCount = 0 + if emptySize < 0 { + emptySize = 0 } - if curCount > size { - curCount = size + if curSize > size { + curSize = size } - if emptCount <= 0 { - barBox += strings.Repeat(pb.Current, curCount) - } else if curCount > 0 { - barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN + + cursorLen := escapeAwareRuneCountInString(pb.Current) + if emptySize <= 0 { + barBox += strings.Repeat(pb.Current, curSize/cursorLen) + } else if curSize > 0 { + cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN) + cursorRepetitions := (curSize - cursorEndLen) / cursorLen + barBox += strings.Repeat(pb.Current, cursorRepetitions) + barBox += pb.CurrentN } - barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd + + emptyLen := escapeAwareRuneCountInString(pb.Empty) + barBox += strings.Repeat(pb.Empty, emptySize/emptyLen) + barBox += pb.BarEnd } else { - barBox = pb.BarStart pos := size - int(current)%int(size) + barBox = pb.BarStart if pos-1 > 0 { barBox += strings.Repeat(pb.Empty, pos-1) } @@ -364,16 +388,17 @@ func (pb *ProgressBar) write(current int64) { // check len out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix - if escapeAwareRuneCountInString(out) < width { - end = strings.Repeat(" ", width-utf8.RuneCountInString(out)) + if cl := escapeAwareRuneCountInString(out); cl < width { + end = strings.Repeat(" ", width-cl) } // and print! pb.mu.Lock() pb.lastPrint = out + end + isFinish := pb.isFinish pb.mu.Unlock() switch { - case pb.isFinish: + case isFinish: return case pb.Output != nil: fmt.Fprint(pb.Output, "\r"+out+end) @@ -406,10 +431,14 @@ func (pb *ProgressBar) GetWidth() int { // Write the current state of the progressbar func (pb *ProgressBar) Update() { c := atomic.LoadInt64(&pb.current) - if pb.AlwaysUpdate || c != pb.currentValue { - pb.write(c) - pb.currentValue = c + p := atomic.LoadInt64(&pb.previous) + if p != c { + pb.mu.Lock() + pb.changeTime = time.Now() + pb.mu.Unlock() + atomic.StoreInt64(&pb.previous, c) } + pb.write(c) if pb.AutoStat { if c == 0 { pb.startTime = time.Now() @@ -420,7 +449,10 @@ func (pb *ProgressBar) Update() { } } +// String return the last bar print func (pb *ProgressBar) String() string { + pb.mu.Lock() + defer pb.mu.Unlock() return pb.lastPrint } @@ -435,10 +467,3 @@ func (pb *ProgressBar) refresher() { } } } - -type window struct { - Row uint16 - Col uint16 - Xpixel uint16 - Ypixel uint16 -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go b/vendor/github.com/cheggaaa/pb/pb_win.go similarity index 100% rename from vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go rename to vendor/github.com/cheggaaa/pb/pb_win.go diff --git a/vendor/github.com/cheggaaa/pb/pb_x.go b/vendor/github.com/cheggaaa/pb/pb_x.go new file mode 100644 index 000000000..bbbe7c2d6 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/pb_x.go @@ -0,0 +1,108 @@ +// +build linux darwin freebsd netbsd openbsd solaris dragonfly +// +build !appengine + +package pb + +import ( + "errors" + "fmt" + "os" + "os/signal" + "sync" + "syscall" + + "golang.org/x/sys/unix" +) + +var ErrPoolWasStarted = errors.New("Bar pool was started") + +var ( + echoLockMutex sync.Mutex + origTermStatePtr *unix.Termios + tty *os.File +) + +func init() { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + + var err error + tty, err = os.Open("/dev/tty") + if err != nil { + tty = os.Stdin + } +} + +// terminalWidth returns width of the terminal. +func terminalWidth() (int, error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + + fd := int(tty.Fd()) + + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { + return 0, err + } + + return int(ws.Col), nil +} + +func lockEcho() (quit chan int, err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if origTermStatePtr != nil { + return quit, ErrPoolWasStarted + } + + fd := int(tty.Fd()) + + oldTermStatePtr, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { + return nil, fmt.Errorf("Can't get terminal settings: %v", err) + } + + oldTermios := *oldTermStatePtr + newTermios := oldTermios + newTermios.Lflag &^= syscall.ECHO + newTermios.Lflag |= syscall.ICANON | syscall.ISIG + newTermios.Iflag |= syscall.ICRNL + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil { + return nil, fmt.Errorf("Can't set terminal settings: %v", err) + } + + quit = make(chan int, 1) + go catchTerminate(quit) + return +} + +func unlockEcho() error { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if origTermStatePtr == nil { + return nil + } + + fd := int(tty.Fd()) + + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil { + return fmt.Errorf("Can't set terminal settings: %v", err) + } + + origTermStatePtr = nil + + return nil +} + +// listen exit signals and restore terminal state +func catchTerminate(quit chan int) { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) + defer signal.Stop(sig) + select { + case <-quit: + unlockEcho() + case <-sig: + unlockEcho() + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool.go b/vendor/github.com/cheggaaa/pb/pool.go similarity index 84% rename from vendor/gopkg.in/cheggaaa/pb.v1/pool.go rename to vendor/github.com/cheggaaa/pb/pool.go index 0b4a4afa8..bc1a13886 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pool.go +++ b/vendor/github.com/cheggaaa/pb/pool.go @@ -3,6 +3,7 @@ package pb import ( + "io" "sync" "time" ) @@ -19,14 +20,19 @@ func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) { } type Pool struct { - RefreshRate time.Duration - bars []*ProgressBar - quit chan int - finishOnce sync.Once + Output io.Writer + RefreshRate time.Duration + bars []*ProgressBar + lastBarsCount int + quit chan int + m sync.Mutex + finishOnce sync.Once } // Add progress bars. func (p *Pool) Add(pbs ...*ProgressBar) { + p.m.Lock() + defer p.m.Unlock() for _, bar := range pbs { bar.ManualUpdate = true bar.NotPrint = true diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go b/vendor/github.com/cheggaaa/pb/pool_win.go similarity index 64% rename from vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go rename to vendor/github.com/cheggaaa/pb/pool_win.go index d7a5ace41..63598d378 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go +++ b/vendor/github.com/cheggaaa/pb/pool_win.go @@ -8,13 +8,18 @@ import ( ) func (p *Pool) print(first bool) bool { + p.m.Lock() + defer p.m.Unlock() var out string if !first { coords, err := getCursorPos() if err != nil { log.Panic(err) } - coords.Y -= int16(len(p.bars)) + coords.Y -= int16(p.lastBarsCount) + if coords.Y < 0 { + coords.Y = 0 + } coords.X = 0 err = setCursorPos(coords) @@ -24,12 +29,17 @@ func (p *Pool) print(first bool) bool { } isFinished := true for _, bar := range p.bars { - if !bar.isFinish { + if !bar.IsFinished() { isFinished = false } bar.Update() out += fmt.Sprintf("\r%s\n", bar.String()) } - fmt.Print(out) + if p.Output != nil { + fmt.Fprint(p.Output, out) + } else { + fmt.Print(out) + } + p.lastBarsCount = len(p.bars) return isFinished } diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go b/vendor/github.com/cheggaaa/pb/pool_x.go similarity index 59% rename from vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go rename to vendor/github.com/cheggaaa/pb/pool_x.go index d95b71d87..a8ae14d2f 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go +++ b/vendor/github.com/cheggaaa/pb/pool_x.go @@ -5,18 +5,25 @@ package pb import "fmt" func (p *Pool) print(first bool) bool { + p.m.Lock() + defer p.m.Unlock() var out string if !first { - out = fmt.Sprintf("\033[%dA", len(p.bars)) + out = fmt.Sprintf("\033[%dA", p.lastBarsCount) } isFinished := true for _, bar := range p.bars { - if !bar.isFinish { + if !bar.IsFinished() { isFinished = false } bar.Update() out += fmt.Sprintf("\r%s\n", bar.String()) } - fmt.Print(out) + if p.Output != nil { + fmt.Fprint(p.Output, out) + } else { + fmt.Print(out) + } + p.lastBarsCount = len(p.bars) return isFinished } diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/reader.go b/vendor/github.com/cheggaaa/pb/reader.go similarity index 100% rename from vendor/gopkg.in/cheggaaa/pb.v1/reader.go rename to vendor/github.com/cheggaaa/pb/reader.go diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go b/vendor/github.com/cheggaaa/pb/runecount.go similarity index 90% rename from vendor/gopkg.in/cheggaaa/pb.v1/runecount.go rename to vendor/github.com/cheggaaa/pb/runecount.go index d52edd365..c617c55ec 100644 --- a/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go +++ b/vendor/github.com/cheggaaa/pb/runecount.go @@ -11,7 +11,7 @@ var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") func escapeAwareRuneCountInString(s string) int { n := runewidth.StringWidth(s) for _, sm := range ctrlFinder.FindAllString(s, -1) { - n -= len(sm) + n -= runewidth.StringWidth(sm) } return n } diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go b/vendor/github.com/cheggaaa/pb/termios_bsd.go similarity index 100% rename from vendor/gopkg.in/cheggaaa/pb.v1/termios_bsd.go rename to vendor/github.com/cheggaaa/pb/termios_bsd.go diff --git a/vendor/github.com/cheggaaa/pb/termios_sysv.go b/vendor/github.com/cheggaaa/pb/termios_sysv.go new file mode 100644 index 000000000..b10f61859 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termios_sysv.go @@ -0,0 +1,13 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux solaris +// +build !appengine + +package pb + +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS +const ioctlWriteTermios = unix.TCSETS diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/format.go b/vendor/gopkg.in/cheggaaa/pb.v1/format.go deleted file mode 100644 index d5aeff793..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v1/format.go +++ /dev/null @@ -1,87 +0,0 @@ -package pb - -import ( - "fmt" - "strings" - "time" -) - -type Units int - -const ( - // U_NO are default units, they represent a simple value and are not formatted at all. - U_NO Units = iota - // U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...) - U_BYTES - // U_DURATION units are formatted in a human readable way (3h14m15s) - U_DURATION -) - -func Format(i int64) *formatter { - return &formatter{n: i} -} - -type formatter struct { - n int64 - unit Units - width int - perSec bool -} - -func (f *formatter) Value(n int64) *formatter { - f.n = n - return f -} - -func (f *formatter) To(unit Units) *formatter { - f.unit = unit - return f -} - -func (f *formatter) Width(width int) *formatter { - f.width = width - return f -} - -func (f *formatter) PerSec() *formatter { - f.perSec = true - return f -} - -func (f *formatter) String() (out string) { - switch f.unit { - case U_BYTES: - out = formatBytes(f.n) - case U_DURATION: - d := time.Duration(f.n) - if d > time.Hour*24 { - out = fmt.Sprintf("%dd", d/24/time.Hour) - d -= (d / time.Hour / 24) * (time.Hour * 24) - } - out = fmt.Sprintf("%s%v", out, d) - default: - out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n) - } - if f.perSec { - out += "/s" - } - return -} - -// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B -func formatBytes(i int64) (result string) { - switch { - case i > (1024 * 1024 * 1024 * 1024): - result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024) - case i > (1024 * 1024 * 1024): - result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024) - case i > (1024 * 1024): - result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024) - case i > 1024: - result = fmt.Sprintf("%.02f KB", float64(i)/1024) - default: - result = fmt.Sprintf("%d B", i) - } - result = strings.Trim(result, " ") - return -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go deleted file mode 100644 index c06097b43..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd dragonfly -// +build !appengine - -package pb - -import "syscall" - -const sysIoctl = syscall.SYS_IOCTL diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go deleted file mode 100644 index b7d461e17..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go +++ /dev/null @@ -1,6 +0,0 @@ -// +build solaris -// +build !appengine - -package pb - -const sysIoctl = 54 diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go deleted file mode 100644 index 12e6fe6e2..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go +++ /dev/null @@ -1,110 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly -// +build !appengine - -package pb - -import ( - "errors" - "fmt" - "os" - "os/signal" - "runtime" - "sync" - "syscall" - "unsafe" -) - -const ( - TIOCGWINSZ = 0x5413 - TIOCGWINSZ_OSX = 1074295912 -) - -var tty *os.File - -var ErrPoolWasStarted = errors.New("Bar pool was started") - -var echoLocked bool -var echoLockMutex sync.Mutex - -func init() { - var err error - tty, err = os.Open("/dev/tty") - if err != nil { - tty = os.Stdin - } -} - -// terminalWidth returns width of the terminal. -func terminalWidth() (int, error) { - w := new(window) - tio := syscall.TIOCGWINSZ - if runtime.GOOS == "darwin" { - tio = TIOCGWINSZ_OSX - } - res, _, err := syscall.Syscall(sysIoctl, - tty.Fd(), - uintptr(tio), - uintptr(unsafe.Pointer(w)), - ) - if int(res) == -1 { - return 0, err - } - return int(w.Col), nil -} - -var oldState syscall.Termios - -func lockEcho() (quit chan int, err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if echoLocked { - err = ErrPoolWasStarted - return - } - echoLocked = true - - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } - - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return - } - quit = make(chan int, 1) - go catchTerminate(quit) - return -} - -func unlockEcho() (err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if !echoLocked { - return - } - echoLocked = false - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") - } - return -} - -// listen exit signals and restore terminal state -func catchTerminate(quit chan int) { - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) - defer signal.Stop(sig) - select { - case <-quit: - unlockEcho() - case <-sig: - unlockEcho() - } -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go b/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go deleted file mode 100644 index ebb3fe87c..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build linux solaris -// +build !appengine - -package pb - -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/vendor.json b/vendor/vendor.json index e47378fdf..e536cbb7d 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -565,6 +565,12 @@ "path": "github.com/biogo/hts/bgzf", "revision": "50da7d4131a3b5c9d063932461cab4d1fafb20b0" }, + { + "checksumSHA1": "ymc5+iJ+1ipls3ihqPdzMjFYCqo=", + "path": "github.com/cheggaaa/pb", + "revision": "18d384da9bdc1e5a08fc2a62a494c321d9ae74ea", + "revisionTime": "2017-12-14T13:20:59Z" + }, { "checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=", "comment": "v1.0.0-3-g6d21280", @@ -1493,12 +1499,6 @@ "path": "google.golang.org/cloud/internal", "revision": "5a3b06f8b5da3b7c3a93da43163b872c86c509ef" }, - { - "checksumSHA1": "w3z2xM4+RT/OWvVusDgNXZZEEkE=", - "path": "gopkg.in/cheggaaa/pb.v1", - "revision": "d7e6ca3010b6f084d8056847f55d7f572f180678", - "revisionTime": "2016-11-21T09:29:06Z" - }, { "checksumSHA1": "gY2M/3SCxqgrPz+P/N6JQ+m/wnA=", "path": "gopkg.in/xmlpath.v2", From 5a3e98b529be462209badd511f2686fa6de8ee0f Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 3 Jan 2018 20:31:49 -0600 Subject: [PATCH 0404/1007] Updated the testcases in common/download_test.go to pass a non-nil progress-bar due to the removal of a pointer type in commit ed2e341b7d7f49a063dd5018701b4ae548b8ec14 from yesterday. --- common/download.go | 15 +++++++++++++-- common/download_test.go | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/common/download.go b/common/download.go index e5ebe305f..cfa2d8849 100644 --- a/common/download.go +++ b/common/download.go @@ -516,9 +516,20 @@ func (d *FileDownloader) toPath(base string, uri url.URL) (string, error) { result = path.Join(uri.Host, uri.Path) // semi-absolute path (current drive letter) - // -- file:///absolute/path -> /absolute/path + // -- file:///absolute/path -> drive:/absolute/path } else if uri.Host == "" && strings.HasPrefix(uri.Path, "/") { - result = path.Join(filepath.VolumeName(base), uri.Path) + apath := uri.Path + components := strings.Split(apath, "/") + volume := filepath.VolumeName(base) + + // semi-absolute absolute path (includes volume letter) + // -- file://drive:/path -> drive:/absolute/path + if len(components) > 1 && strings.HasSuffix(components[1], ":") { + volume = components[1] + apath = path.Join(components[2:]...) + } + + result = path.Join(volume, apath) // relative path -- file://./relative/path -> ./relative/path } else if uri.Host == "." { diff --git a/common/download_test.go b/common/download_test.go index 50bdfa971..db31fe152 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -12,6 +12,8 @@ import ( "runtime" "strings" "testing" + + "github.com/cheggaaa/pb" ) func TestDownloadClientVerifyChecksum(t *testing.T) { @@ -36,7 +38,7 @@ func TestDownloadClientVerifyChecksum(t *testing.T) { Checksum: checksum, } - d := NewDownloadClient(config, nil) + d := NewDownloadClient(config, *pb.New64(0)) result, err := d.VerifyChecksum(tf.Name()) if err != nil { t.Fatalf("Verify err: %s", err) @@ -59,7 +61,7 @@ func TestDownloadClient_basic(t *testing.T) { Url: ts.URL + "/basic.txt", TargetPath: tf.Name(), CopyFile: true, - }, nil) + }, *pb.New64(0)) path, err := client.Get() if err != nil { @@ -95,7 +97,7 @@ func TestDownloadClient_checksumBad(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }, nil) + }, *pb.New64(0)) if _, err := client.Get(); err == nil { t.Fatal("should error") } @@ -120,7 +122,7 @@ func TestDownloadClient_checksumGood(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }, nil) + }, *pb.New64(0)) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -151,7 +153,7 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }, nil) + }, *pb.New64(0)) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -190,7 +192,7 @@ func TestDownloadClient_resume(t *testing.T) { Url: ts.URL, TargetPath: tf.Name(), CopyFile: true, - }, nil) + }, *pb.New64(0)) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -250,7 +252,7 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { CopyFile: true, } - client := NewDownloadClient(config, nil) + client := NewDownloadClient(config, *pb.New64(0)) _, err = client.Get() if err != nil { t.Fatal(err) @@ -282,7 +284,7 @@ func TestDownloadClient_setsUserAgent(t *testing.T) { CopyFile: true, } - client := NewDownloadClient(config, nil) + client := NewDownloadClient(config, *pb.New64(0)) _, err = client.Get() if err != nil { t.Fatal(err) @@ -381,12 +383,12 @@ func TestDownloadFileUrl(t *testing.T) { CopyFile: false, } - client := NewDownloadClient(config, nil) + client := NewDownloadClient(config, *pb.New64(0)) // Verify that we fail to match the checksum _, err = client.Get() if err.Error() != "checksums didn't match expected: 6e6f7065" { - t.Fatalf("Unexpected failure; expected checksum not to match") + t.Fatalf("Unexpected failure; expected checksum not to match. Error was \"%v\"", err) } if _, err = os.Stat(sourcePath); err != nil { @@ -412,7 +414,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string, error) { } // go go go - client := NewDownloadClient(config, nil) + client := NewDownloadClient(config, *pb.New64(0)) path, err := client.Get() // ignore any non-important checksum errors if it's not a unc path From 5d97b105a8b6baf2cf3004e3765f5df66113a1a1 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sat, 6 Jan 2018 19:32:18 -0600 Subject: [PATCH 0405/1007] Removed implementation of the ftp protocol and the usage of cheggaaa's progress-bar as suggested by @SwampDragons. Replaced some of the old smoke-tests that were based on the ftp-protocol non-existing with a "non-existent://" protocol that's guaranteed to not exist. --- builder/virtualbox/ovf/config_test.go | 11 + builder/vmware/iso/step_create_vmx.go | 2 +- common/config.go | 2 +- common/config_test.go | 10 +- common/download.go | 196 +-- common/download_test.go | 22 +- common/step_download.go | 44 +- packer/core.go | 2 +- vendor/github.com/cheggaaa/pb/LICENSE | 12 - vendor/github.com/cheggaaa/pb/README.md | 179 --- vendor/github.com/cheggaaa/pb/format.go | 118 -- vendor/github.com/cheggaaa/pb/pb.go | 469 ------- vendor/github.com/cheggaaa/pb/pb_win.go | 141 -- vendor/github.com/cheggaaa/pb/pb_x.go | 108 -- vendor/github.com/cheggaaa/pb/pool.go | 82 -- vendor/github.com/cheggaaa/pb/pool_win.go | 45 - vendor/github.com/cheggaaa/pb/pool_x.go | 29 - vendor/github.com/cheggaaa/pb/reader.go | 25 - vendor/github.com/cheggaaa/pb/runecount.go | 17 - vendor/github.com/cheggaaa/pb/termios_bsd.go | 9 - vendor/github.com/cheggaaa/pb/termios_sysv.go | 13 - vendor/github.com/jlaffaye/ftp/LICENSE | 13 - vendor/github.com/jlaffaye/ftp/README.md | 17 - vendor/github.com/jlaffaye/ftp/ftp.go | 671 --------- vendor/github.com/jlaffaye/ftp/status.go | 106 -- vendor/github.com/mattn/go-runewidth/LICENSE | 21 - .../github.com/mattn/go-runewidth/README.mkd | 27 - .../mattn/go-runewidth/runewidth.go | 1223 ----------------- .../mattn/go-runewidth/runewidth_js.go | 8 - .../mattn/go-runewidth/runewidth_posix.go | 77 -- .../mattn/go-runewidth/runewidth_windows.go | 25 - vendor/vendor.json | 28 - 32 files changed, 60 insertions(+), 3692 deletions(-) delete mode 100644 vendor/github.com/cheggaaa/pb/LICENSE delete mode 100644 vendor/github.com/cheggaaa/pb/README.md delete mode 100644 vendor/github.com/cheggaaa/pb/format.go delete mode 100644 vendor/github.com/cheggaaa/pb/pb.go delete mode 100644 vendor/github.com/cheggaaa/pb/pb_win.go delete mode 100644 vendor/github.com/cheggaaa/pb/pb_x.go delete mode 100644 vendor/github.com/cheggaaa/pb/pool.go delete mode 100644 vendor/github.com/cheggaaa/pb/pool_win.go delete mode 100644 vendor/github.com/cheggaaa/pb/pool_x.go delete mode 100644 vendor/github.com/cheggaaa/pb/reader.go delete mode 100644 vendor/github.com/cheggaaa/pb/runecount.go delete mode 100644 vendor/github.com/cheggaaa/pb/termios_bsd.go delete mode 100644 vendor/github.com/cheggaaa/pb/termios_sysv.go delete mode 100644 vendor/github.com/jlaffaye/ftp/LICENSE delete mode 100644 vendor/github.com/jlaffaye/ftp/README.md delete mode 100644 vendor/github.com/jlaffaye/ftp/ftp.go delete mode 100644 vendor/github.com/jlaffaye/ftp/status.go delete mode 100644 vendor/github.com/mattn/go-runewidth/LICENSE delete mode 100644 vendor/github.com/mattn/go-runewidth/README.mkd delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index e9c536e54..baba657a8 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -76,6 +76,17 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("Nonexistant file should throw a validation error!") } + // Bad + c = testConfig(t) + c["source_path"] = "nonexistent-protocol://i/dont/exist" + _, warns, err = NewConfig(c) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatalf("should error") + } + // Good tf := getTempFile(t) defer os.Remove(tf.Name()) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 3f3644e70..292a6a6e7 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -44,7 +44,7 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) // Convert the iso_path into a path relative to the .vmx file if possible - if relativeIsoPath, err := filepath.Rel(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { + if relativeIsoPath, err := filepath.Abs(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { isoPath = relativeIsoPath } diff --git a/common/config.go b/common/config.go index 0e97f6a0e..c8c99a31e 100644 --- a/common/config.go +++ b/common/config.go @@ -48,7 +48,7 @@ func ChooseString(vals ...string) string { func DownloadableURL(original string) (string, error) { // Verify that the scheme is something we support in our common downloader. - supported := []string{"file", "http", "https", "ftp", "smb"} + supported := []string{"file", "http", "https", "smb"} found := false for _, s := range supported { if strings.HasPrefix(strings.ToLower(original), s+"://") { diff --git a/common/config_test.go b/common/config_test.go index 3b1aff8cf..f9b1748ce 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -43,6 +43,12 @@ func TestDownloadableURL(t *testing.T) { t.Fatalf("expected err : %s", err) } + // Invalid: unsupported scheme + _, err = DownloadableURL("nonexistent-protocol://host.com/path") + if err == nil { + t.Fatalf("expected err : %s", err) + } + // Valid: http u, err := DownloadableURL("HTTP://packer.io/path") if err != nil { @@ -190,7 +196,9 @@ func TestDownloadableURL_FilePaths(t *testing.T) { t.Fatalf("err: %s", err) } - expected := "file://" + strings.Replace(tfPath, `\`, `/`, -1) + expected := fmt.Sprintf("%s%s", + filePrefix, + strings.Replace(tfPath, `\`, `/`, -1)) if u != expected { t.Fatalf("unexpected: %#v != %#v", u, expected) } diff --git a/common/download.go b/common/download.go index cfa2d8849..27e9b32a8 100644 --- a/common/download.go +++ b/common/download.go @@ -20,8 +20,6 @@ import ( // imports related to each Downloader implementation import ( - "github.com/cheggaaa/pb" - "github.com/jlaffaye/ftp" "io" "net/http" "path/filepath" @@ -83,24 +81,24 @@ func HashForType(t string) hash.Hash { // NewDownloadClient returns a new DownloadClient for the given // configuration. -func NewDownloadClient(c *DownloadConfig, bar pb.ProgressBar) *DownloadClient { +func NewDownloadClient(c *DownloadConfig) *DownloadClient { const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */ // Create downloader map if it hasn't been specified already. if c.DownloaderMap == nil { + // XXX: Make sure you add any new protocols you implement + // to the DownloadableURL implementation in config.go! c.DownloaderMap = map[string]Downloader{ - "file": &FileDownloader{progress: &bar, bufferSize: nil}, - "ftp": &FTPDownloader{progress: &bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu}, - "http": &HTTPDownloader{progress: &bar, userAgent: c.UserAgent}, - "https": &HTTPDownloader{progress: &bar, userAgent: c.UserAgent}, - "smb": &SMBDownloader{progress: &bar, bufferSize: nil}, + "file": &FileDownloader{bufferSize: nil}, + "http": &HTTPDownloader{userAgent: c.UserAgent}, + "https": &HTTPDownloader{userAgent: c.UserAgent}, + "smb": &SMBDownloader{bufferSize: nil}, } } return &DownloadClient{config: c} } -// A downloader implements the ability to transfer a file, and cancel or resume -// it. +// A downloader implements the ability to transfer, cancel, or resume a file. type Downloader interface { Resume() Cancel() @@ -209,6 +207,14 @@ func (d *DownloadClient) Get() (string, error) { return finalPath, err } +func (d *DownloadClient) PercentProgress() int { + if (d.downloader == nil) { + return -1 + } + + return int((float64(d.downloader.Progress()) / float64(d.downloader.Total())) * 100) +} + // VerifyChecksum tests that the path matches the checksum for the // download. func (d *DownloadClient) VerifyChecksum(path string) (bool, error) { @@ -234,8 +240,6 @@ type HTTPDownloader struct { current uint64 total uint64 userAgent string - - progress *pb.ProgressBar } func (d *HTTPDownloader) Cancel() { @@ -300,10 +304,6 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { d.total = d.current + uint64(resp.ContentLength) - d.progress.Total = int64(d.total) - progressBar := d.progress.Start() - progressBar.Set64(int64(d.current)) - var buffer [4096]byte for { n, err := resp.Body.Read(buffer[:]) @@ -312,7 +312,6 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { } d.current += uint64(n) - progressBar.Set64(int64(d.current)) if _, werr := dst.Write(buffer[:n]); werr != nil { return werr @@ -322,7 +321,6 @@ func (d *HTTPDownloader) Download(dst *os.File, src *url.URL) error { break } } - progressBar.Finish() return nil } @@ -334,152 +332,6 @@ func (d *HTTPDownloader) Total() uint64 { return d.total } -// FTPDownloader is an implementation of Downloader that downloads -// files over FTP. -type FTPDownloader struct { - userInfo *url.Userinfo - mtu uint - - active bool - current uint64 - total uint64 - - progress *pb.ProgressBar -} - -func (d *FTPDownloader) Progress() uint64 { - return d.current -} - -func (d *FTPDownloader) Total() uint64 { - return d.total -} - -func (d *FTPDownloader) Cancel() { - d.active = false -} - -func (d *FTPDownloader) Resume() { - // TODO: Implement -} - -func (d *FTPDownloader) Download(dst *os.File, src *url.URL) error { - var userinfo *url.Userinfo - - userinfo = d.userInfo - d.active = false - - // check the uri is correct - if src == nil || src.Scheme != "ftp" { - return fmt.Errorf("Unexpected uri scheme: %s", src.Scheme) - } - uri := src - - // connect to ftp server - var cli *ftp.ServerConn - - log.Printf("Starting download over FTP: %s : %s\n", uri.Host, uri.Path) - cli, err := ftp.Dial(uri.Host) - if err != nil { - return nil - } - defer cli.Quit() - - // handle authentication - if uri.User != nil { - userinfo = uri.User - } - - pass, ok := userinfo.Password() - if !ok { - pass = "ftp@" - } - - log.Printf("Authenticating to FTP server: %s : %s\n", userinfo.Username(), pass) - err = cli.Login(userinfo.Username(), pass) - if err != nil { - return err - } - - // locate specified path - p := path.Dir(uri.Path) - - log.Printf("Changing to FTP directory : %s\n", p) - err = cli.ChangeDir(p) - if err != nil { - return nil - } - - curpath, err := cli.CurrentDir() - if err != nil { - return err - } - log.Printf("Current FTP directory : %s\n", curpath) - - // collect stats about the specified file - var name string - var entry *ftp.Entry - - _, name = path.Split(uri.Path) - entry = nil - - entries, err := cli.List(curpath) - for _, e := range entries { - if e.Type == ftp.EntryTypeFile && e.Name == name { - entry = e - break - } - } - - if entry == nil { - return fmt.Errorf("Unable to find file: %s", uri.Path) - } - log.Printf("Found file : %s : %v bytes\n", entry.Name, entry.Size) - - d.current = 0 - d.total = entry.Size - - d.progress.Total = int64(d.total) - progressBar := d.progress.Start() - - // download specified file - d.active = true - reader, err := cli.RetrFrom(uri.Path, d.current) - if err != nil { - return nil - } - - // do it in a goro so that if someone wants to cancel it, they can - errch := make(chan error) - go func(d *FTPDownloader, r io.Reader, w io.Writer, e chan error) { - for d.active { - n, err := io.CopyN(w, r, int64(d.mtu)) - if err != nil { - break - } - - d.current += uint64(n) - progressBar.Set64(int64(d.current)) - } - d.active = false - e <- err - }(d, reader, dst, errch) - - // spin until it's done - err = <-errch - - progressBar.Finish() - reader.Close() - - if err == nil && d.current != d.total { - err = fmt.Errorf("FTP total transfer size was %d when %d was expected", d.current, d.total) - } - - // log out - cli.Logout() - return err -} - // FileDownloader is an implementation of Downloader that downloads // files using the regular filesystem. type FileDownloader struct { @@ -488,8 +340,6 @@ type FileDownloader struct { active bool current uint64 total uint64 - - progress *pb.ProgressBar } func (d *FileDownloader) Progress() uint64 { @@ -580,9 +430,6 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { } d.total = uint64(fi.Size()) - d.progress.Total = int64(d.total) - progressBar := d.progress.Start() - // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { var n int64 @@ -590,7 +437,6 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { d.active = false d.current += uint64(n) - progressBar.Set64(int64(d.current)) // use a goro in case someone else wants to enable cancel/resume } else { @@ -603,7 +449,6 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { } d.current += uint64(n) - progressBar.Set64(int64(d.current)) } d.active = false e <- err @@ -612,7 +457,6 @@ func (d *FileDownloader) Download(dst *os.File, src *url.URL) error { // ...and we spin until it's done err = <-errch } - progressBar.Finish() f.Close() return err } @@ -625,8 +469,6 @@ type SMBDownloader struct { active bool current uint64 total uint64 - - progress *pb.ProgressBar } func (d *SMBDownloader) Progress() uint64 { @@ -699,9 +541,6 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { } d.total = uint64(fi.Size()) - d.progress.Total = int64(d.total) - progressBar := d.progress.Start() - // no bufferSize specified, so copy synchronously. if d.bufferSize == nil { var n int64 @@ -709,7 +548,6 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { d.active = false d.current += uint64(n) - progressBar.Set64(int64(d.current)) // use a goro in case someone else wants to enable cancel/resume } else { @@ -722,7 +560,6 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { } d.current += uint64(n) - progressBar.Set64(int64(d.current)) } d.active = false e <- err @@ -731,7 +568,6 @@ func (d *SMBDownloader) Download(dst *os.File, src *url.URL) error { // ...and as usual we spin until it's done err = <-errch } - progressBar.Finish() f.Close() return err } diff --git a/common/download_test.go b/common/download_test.go index db31fe152..beac9cbab 100644 --- a/common/download_test.go +++ b/common/download_test.go @@ -12,8 +12,6 @@ import ( "runtime" "strings" "testing" - - "github.com/cheggaaa/pb" ) func TestDownloadClientVerifyChecksum(t *testing.T) { @@ -38,7 +36,7 @@ func TestDownloadClientVerifyChecksum(t *testing.T) { Checksum: checksum, } - d := NewDownloadClient(config, *pb.New64(0)) + d := NewDownloadClient(config) result, err := d.VerifyChecksum(tf.Name()) if err != nil { t.Fatalf("Verify err: %s", err) @@ -61,7 +59,7 @@ func TestDownloadClient_basic(t *testing.T) { Url: ts.URL + "/basic.txt", TargetPath: tf.Name(), CopyFile: true, - }, *pb.New64(0)) + }) path, err := client.Get() if err != nil { @@ -97,7 +95,7 @@ func TestDownloadClient_checksumBad(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }, *pb.New64(0)) + }) if _, err := client.Get(); err == nil { t.Fatal("should error") } @@ -122,7 +120,7 @@ func TestDownloadClient_checksumGood(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }, *pb.New64(0)) + }) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -153,7 +151,7 @@ func TestDownloadClient_checksumNoDownload(t *testing.T) { Hash: HashForType("md5"), Checksum: checksum, CopyFile: true, - }, *pb.New64(0)) + }) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -192,7 +190,7 @@ func TestDownloadClient_resume(t *testing.T) { Url: ts.URL, TargetPath: tf.Name(), CopyFile: true, - }, *pb.New64(0)) + }) path, err := client.Get() if err != nil { t.Fatalf("err: %s", err) @@ -252,7 +250,7 @@ func TestDownloadClient_usesDefaultUserAgent(t *testing.T) { CopyFile: true, } - client := NewDownloadClient(config, *pb.New64(0)) + client := NewDownloadClient(config) _, err = client.Get() if err != nil { t.Fatal(err) @@ -284,7 +282,7 @@ func TestDownloadClient_setsUserAgent(t *testing.T) { CopyFile: true, } - client := NewDownloadClient(config, *pb.New64(0)) + client := NewDownloadClient(config) _, err = client.Get() if err != nil { t.Fatal(err) @@ -383,7 +381,7 @@ func TestDownloadFileUrl(t *testing.T) { CopyFile: false, } - client := NewDownloadClient(config, *pb.New64(0)) + client := NewDownloadClient(config) // Verify that we fail to match the checksum _, err = client.Get() @@ -414,7 +412,7 @@ func SimulateFileUriDownload(t *testing.T, uri string) (string, error) { } // go go go - client := NewDownloadClient(config, *pb.New64(0)) + client := NewDownloadClient(config) path, err := client.Get() // ignore any non-important checksum errors if it's not a unc path diff --git a/common/step_download.go b/common/step_download.go index f483eaba6..765a07d23 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -7,7 +7,6 @@ import ( "log" "time" - "github.com/cheggaaa/pb" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) @@ -62,10 +61,6 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) - // Get a default-looking progress bar and connect it to the ui. - bar := GetDefaultProgressBar() - bar.Callback = ui.Message - // First try to use any already downloaded file // If it fails, proceed to regualar download logic @@ -99,7 +94,7 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { } downloadConfigs[i] = config - if match, _ := NewDownloadClient(config, bar).VerifyChecksum(config.TargetPath); match { + if match, _ := NewDownloadClient(config).VerifyChecksum(config.TargetPath); match { ui.Message(fmt.Sprintf("Found already downloaded, initial checksum matched, no download needed: %s", url)) finalPath = config.TargetPath break @@ -141,32 +136,10 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { func (s *StepDownload) Cleanup(multistep.StateBag) {} -func GetDefaultProgressBar() pb.ProgressBar { - bar := pb.New64(0) - bar.ShowPercent = true - bar.ShowCounters = true - bar.ShowSpeed = false - bar.ShowBar = true - bar.ShowTimeLeft = false - bar.ShowFinalTime = false - bar.SetUnits(pb.U_BYTES) - bar.Format("[=>-]") - bar.SetRefreshRate(1 * time.Second) - bar.SetWidth(25) - - return *bar -} - func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag) (string, error, bool) { var path string ui := state.Get("ui").(packer.Ui) - - // Get a default looking progress bar and connect it to the ui. - bar := GetDefaultProgressBar() - bar.Callback = ui.Message - - // Create download client with config and progress bar - download := NewDownloadClient(config, bar) + download := NewDownloadClient(config) downloadCompleteCh := make(chan error, 1) go func() { @@ -175,19 +148,24 @@ func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag downloadCompleteCh <- err }() + progressTicker := time.NewTicker(5 * time.Second) + defer progressTicker.Stop() + for { select { case err := <-downloadCompleteCh: - bar.Finish() - if err != nil { return "", err, true } - return path, nil, true + return path, nil, true + case <-progressTicker.C: + progress := download.PercentProgress() + if progress >= 0 { + ui.Message(fmt.Sprintf("Download progress: %d%%", progress)) + } case <-time.After(1 * time.Second): if _, ok := state.GetOk(multistep.StateCancelled); ok { - bar.Finish() ui.Say("Interrupt received. Cancelling download...") return "", nil, false } diff --git a/packer/core.go b/packer/core.go index c8ac2cfb7..7da3e4510 100644 --- a/packer/core.go +++ b/packer/core.go @@ -67,7 +67,7 @@ func NewCore(c *CoreConfig) (*Core, error) { return nil, err } - // Go through and interpolate all the build names. We should be able + // Go through and interpolate all the build names. We shuld be able // to do this at this point with the variables. result.builds = make(map[string]*template.Builder) for _, b := range c.Template.Builders { diff --git a/vendor/github.com/cheggaaa/pb/LICENSE b/vendor/github.com/cheggaaa/pb/LICENSE deleted file mode 100644 index 511970333..000000000 --- a/vendor/github.com/cheggaaa/pb/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012-2015, Sergey Cherepanov -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/cheggaaa/pb/README.md b/vendor/github.com/cheggaaa/pb/README.md deleted file mode 100644 index 948545110..000000000 --- a/vendor/github.com/cheggaaa/pb/README.md +++ /dev/null @@ -1,179 +0,0 @@ -# Terminal progress bar for Go - -[![Join the chat at https://gitter.im/cheggaaa/pb](https://badges.gitter.im/cheggaaa/pb.svg)](https://gitter.im/cheggaaa/pb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -Simple progress bar for console programs. - -Please check the new version https://github.com/cheggaaa/pb/tree/v2 (currently, it's beta) - -## Installation - -``` -go get gopkg.in/cheggaaa/pb.v1 -``` - -## Usage - -```Go -package main - -import ( - "gopkg.in/cheggaaa/pb.v1" - "time" -) - -func main() { - count := 100000 - bar := pb.StartNew(count) - for i := 0; i < count; i++ { - bar.Increment() - time.Sleep(time.Millisecond) - } - bar.FinishPrint("The End!") -} - -``` - -Result will be like this: - -``` -> go run test.go -37158 / 100000 [================>_______________________________] 37.16% 1m11s -``` - -## Customization - -```Go -// create bar -bar := pb.New(count) - -// refresh info every second (default 200ms) -bar.SetRefreshRate(time.Second) - -// show percents (by default already true) -bar.ShowPercent = true - -// show bar (by default already true) -bar.ShowBar = true - -// no counters -bar.ShowCounters = false - -// show "time left" -bar.ShowTimeLeft = true - -// show average speed -bar.ShowSpeed = true - -// sets the width of the progress bar -bar.SetWidth(80) - -// sets the width of the progress bar, but if terminal size smaller will be ignored -bar.SetMaxWidth(80) - -// convert output to readable format (like KB, MB) -bar.SetUnits(pb.U_BYTES) - -// and start -bar.Start() -``` - -## Progress bar for IO Operations - -```go -// create and start bar -bar := pb.New(myDataLen).SetUnits(pb.U_BYTES) -bar.Start() - -// my io.Reader -r := myReader - -// my io.Writer -w := myWriter - -// create proxy reader -reader := bar.NewProxyReader(r) - -// and copy from pb reader -io.Copy(w, reader) - -``` - -```go -// create and start bar -bar := pb.New(myDataLen).SetUnits(pb.U_BYTES) -bar.Start() - -// my io.Reader -r := myReader - -// my io.Writer -w := myWriter - -// create multi writer -writer := io.MultiWriter(w, bar) - -// and copy -io.Copy(writer, r) - -bar.Finish() -``` - -## Custom Progress Bar Look-and-feel - -```go -bar.Format("<.- >") -``` - -## Multiple Progress Bars (experimental and unstable) - -Do not print to terminal while pool is active. - -```go -package main - -import ( - "math/rand" - "sync" - "time" - - "gopkg.in/cheggaaa/pb.v1" -) - -func main() { - // create bars - first := pb.New(200).Prefix("First ") - second := pb.New(200).Prefix("Second ") - third := pb.New(200).Prefix("Third ") - // start pool - pool, err := pb.StartPool(first, second, third) - if err != nil { - panic(err) - } - // update bars - wg := new(sync.WaitGroup) - for _, bar := range []*pb.ProgressBar{first, second, third} { - wg.Add(1) - go func(cb *pb.ProgressBar) { - for n := 0; n < 200; n++ { - cb.Increment() - time.Sleep(time.Millisecond * time.Duration(rand.Intn(100))) - } - cb.Finish() - wg.Done() - }(bar) - } - wg.Wait() - // close pool - pool.Stop() -} -``` - -The result will be as follows: - -``` -$ go run example/multiple.go -First 141 / 1000 [===============>---------------------------------------] 14.10 % 44s -Second 139 / 1000 [==============>---------------------------------------] 13.90 % 44s -Third 152 / 1000 [================>--------------------------------------] 15.20 % 40s -``` diff --git a/vendor/github.com/cheggaaa/pb/format.go b/vendor/github.com/cheggaaa/pb/format.go deleted file mode 100644 index 0723561c2..000000000 --- a/vendor/github.com/cheggaaa/pb/format.go +++ /dev/null @@ -1,118 +0,0 @@ -package pb - -import ( - "fmt" - "time" -) - -type Units int - -const ( - // U_NO are default units, they represent a simple value and are not formatted at all. - U_NO Units = iota - // U_BYTES units are formatted in a human readable way (B, KiB, MiB, ...) - U_BYTES - // U_BYTES_DEC units are like U_BYTES, but base 10 (B, KB, MB, ...) - U_BYTES_DEC - // U_DURATION units are formatted in a human readable way (3h14m15s) - U_DURATION -) - -const ( - KiB = 1024 - MiB = 1048576 - GiB = 1073741824 - TiB = 1099511627776 - - KB = 1e3 - MB = 1e6 - GB = 1e9 - TB = 1e12 -) - -func Format(i int64) *formatter { - return &formatter{n: i} -} - -type formatter struct { - n int64 - unit Units - width int - perSec bool -} - -func (f *formatter) To(unit Units) *formatter { - f.unit = unit - return f -} - -func (f *formatter) Width(width int) *formatter { - f.width = width - return f -} - -func (f *formatter) PerSec() *formatter { - f.perSec = true - return f -} - -func (f *formatter) String() (out string) { - switch f.unit { - case U_BYTES: - out = formatBytes(f.n) - case U_BYTES_DEC: - out = formatBytesDec(f.n) - case U_DURATION: - out = formatDuration(f.n) - default: - out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n) - } - if f.perSec { - out += "/s" - } - return -} - -// Convert bytes to human readable string. Like 2 MiB, 64.2 KiB, 52 B -func formatBytes(i int64) (result string) { - switch { - case i >= TiB: - result = fmt.Sprintf("%.02f TiB", float64(i)/TiB) - case i >= GiB: - result = fmt.Sprintf("%.02f GiB", float64(i)/GiB) - case i >= MiB: - result = fmt.Sprintf("%.02f MiB", float64(i)/MiB) - case i >= KiB: - result = fmt.Sprintf("%.02f KiB", float64(i)/KiB) - default: - result = fmt.Sprintf("%d B", i) - } - return -} - -// Convert bytes to base-10 human readable string. Like 2 MB, 64.2 KB, 52 B -func formatBytesDec(i int64) (result string) { - switch { - case i >= TB: - result = fmt.Sprintf("%.02f TB", float64(i)/TB) - case i >= GB: - result = fmt.Sprintf("%.02f GB", float64(i)/GB) - case i >= MB: - result = fmt.Sprintf("%.02f MB", float64(i)/MB) - case i >= KB: - result = fmt.Sprintf("%.02f KB", float64(i)/KB) - default: - result = fmt.Sprintf("%d B", i) - } - return -} - -func formatDuration(n int64) (result string) { - d := time.Duration(n) - if d > time.Hour*24 { - result = fmt.Sprintf("%dd", d/24/time.Hour) - d -= (d / time.Hour / 24) * (time.Hour * 24) - } - result = fmt.Sprintf("%s%v", result, d) - return -} diff --git a/vendor/github.com/cheggaaa/pb/pb.go b/vendor/github.com/cheggaaa/pb/pb.go deleted file mode 100644 index 19eb4d1a9..000000000 --- a/vendor/github.com/cheggaaa/pb/pb.go +++ /dev/null @@ -1,469 +0,0 @@ -// Simple console progress bars -package pb - -import ( - "fmt" - "io" - "math" - "strings" - "sync" - "sync/atomic" - "time" - "unicode/utf8" -) - -// Current version -const Version = "1.0.19" - -const ( - // Default refresh rate - 200ms - DEFAULT_REFRESH_RATE = time.Millisecond * 200 - FORMAT = "[=>-]" -) - -// DEPRECATED -// variables for backward compatibility, from now do not work -// use pb.Format and pb.SetRefreshRate -var ( - DefaultRefreshRate = DEFAULT_REFRESH_RATE - BarStart, BarEnd, Empty, Current, CurrentN string -) - -// Create new progress bar object -func New(total int) *ProgressBar { - return New64(int64(total)) -} - -// Create new progress bar object using int64 as total -func New64(total int64) *ProgressBar { - pb := &ProgressBar{ - Total: total, - RefreshRate: DEFAULT_REFRESH_RATE, - ShowPercent: true, - ShowCounters: true, - ShowBar: true, - ShowTimeLeft: true, - ShowFinalTime: true, - Units: U_NO, - ManualUpdate: false, - finish: make(chan struct{}), - } - return pb.Format(FORMAT) -} - -// Create new object and start -func StartNew(total int) *ProgressBar { - return New(total).Start() -} - -// Callback for custom output -// For example: -// bar.Callback = func(s string) { -// mySuperPrint(s) -// } -// -type Callback func(out string) - -type ProgressBar struct { - current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278) - previous int64 - - Total int64 - RefreshRate time.Duration - ShowPercent, ShowCounters bool - ShowSpeed, ShowTimeLeft, ShowBar bool - ShowFinalTime bool - Output io.Writer - Callback Callback - NotPrint bool - Units Units - Width int - ForceWidth bool - ManualUpdate bool - AutoStat bool - - // Default width for the time box. - UnitsWidth int - TimeBoxWidth int - - finishOnce sync.Once //Guards isFinish - finish chan struct{} - isFinish bool - - startTime time.Time - startValue int64 - - changeTime time.Time - - prefix, postfix string - - mu sync.Mutex - lastPrint string - - BarStart string - BarEnd string - Empty string - Current string - CurrentN string - - AlwaysUpdate bool -} - -// Start print -func (pb *ProgressBar) Start() *ProgressBar { - pb.startTime = time.Now() - pb.startValue = atomic.LoadInt64(&pb.current) - if pb.Total == 0 { - pb.ShowTimeLeft = false - pb.ShowPercent = false - pb.AutoStat = false - } - if !pb.ManualUpdate { - pb.Update() // Initial printing of the bar before running the bar refresher. - go pb.refresher() - } - return pb -} - -// Increment current value -func (pb *ProgressBar) Increment() int { - return pb.Add(1) -} - -// Get current value -func (pb *ProgressBar) Get() int64 { - c := atomic.LoadInt64(&pb.current) - return c -} - -// Set current value -func (pb *ProgressBar) Set(current int) *ProgressBar { - return pb.Set64(int64(current)) -} - -// Set64 sets the current value as int64 -func (pb *ProgressBar) Set64(current int64) *ProgressBar { - atomic.StoreInt64(&pb.current, current) - return pb -} - -// Add to current value -func (pb *ProgressBar) Add(add int) int { - return int(pb.Add64(int64(add))) -} - -func (pb *ProgressBar) Add64(add int64) int64 { - return atomic.AddInt64(&pb.current, add) -} - -// Set prefix string -func (pb *ProgressBar) Prefix(prefix string) *ProgressBar { - pb.prefix = prefix - return pb -} - -// Set postfix string -func (pb *ProgressBar) Postfix(postfix string) *ProgressBar { - pb.postfix = postfix - return pb -} - -// Set custom format for bar -// Example: bar.Format("[=>_]") -// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter -func (pb *ProgressBar) Format(format string) *ProgressBar { - var formatEntries []string - if utf8.RuneCountInString(format) == 5 { - formatEntries = strings.Split(format, "") - } else { - formatEntries = strings.Split(format, "\x00") - } - if len(formatEntries) == 5 { - pb.BarStart = formatEntries[0] - pb.BarEnd = formatEntries[4] - pb.Empty = formatEntries[3] - pb.Current = formatEntries[1] - pb.CurrentN = formatEntries[2] - } - return pb -} - -// Set bar refresh rate -func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar { - pb.RefreshRate = rate - return pb -} - -// Set units -// bar.SetUnits(U_NO) - by default -// bar.SetUnits(U_BYTES) - for Mb, Kb, etc -func (pb *ProgressBar) SetUnits(units Units) *ProgressBar { - pb.Units = units - return pb -} - -// Set max width, if width is bigger than terminal width, will be ignored -func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar { - pb.Width = width - pb.ForceWidth = false - return pb -} - -// Set bar width -func (pb *ProgressBar) SetWidth(width int) *ProgressBar { - pb.Width = width - pb.ForceWidth = true - return pb -} - -// End print -func (pb *ProgressBar) Finish() { - //Protect multiple calls - pb.finishOnce.Do(func() { - close(pb.finish) - pb.write(atomic.LoadInt64(&pb.current)) - pb.mu.Lock() - defer pb.mu.Unlock() - switch { - case pb.Output != nil: - fmt.Fprintln(pb.Output) - case !pb.NotPrint: - fmt.Println() - } - pb.isFinish = true - }) -} - -// IsFinished return boolean -func (pb *ProgressBar) IsFinished() bool { - pb.mu.Lock() - defer pb.mu.Unlock() - return pb.isFinish -} - -// End print and write string 'str' -func (pb *ProgressBar) FinishPrint(str string) { - pb.Finish() - if pb.Output != nil { - fmt.Fprintln(pb.Output, str) - } else { - fmt.Println(str) - } -} - -// implement io.Writer -func (pb *ProgressBar) Write(p []byte) (n int, err error) { - n = len(p) - pb.Add(n) - return -} - -// implement io.Reader -func (pb *ProgressBar) Read(p []byte) (n int, err error) { - n = len(p) - pb.Add(n) - return -} - -// Create new proxy reader over bar -// Takes io.Reader or io.ReadCloser -func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader { - return &Reader{r, pb} -} - -func (pb *ProgressBar) write(current int64) { - width := pb.GetWidth() - - var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string - - // percents - if pb.ShowPercent { - var percent float64 - if pb.Total > 0 { - percent = float64(current) / (float64(pb.Total) / float64(100)) - } else { - percent = float64(current) / float64(100) - } - percentBox = fmt.Sprintf(" %6.02f%%", percent) - } - - // counters - if pb.ShowCounters { - current := Format(current).To(pb.Units).Width(pb.UnitsWidth) - if pb.Total > 0 { - total := Format(pb.Total).To(pb.Units).Width(pb.UnitsWidth) - countersBox = fmt.Sprintf(" %s / %s ", current, total) - } else { - countersBox = fmt.Sprintf(" %s / ? ", current) - } - } - - // time left - pb.mu.Lock() - currentFromStart := current - pb.startValue - fromStart := time.Now().Sub(pb.startTime) - lastChangeTime := pb.changeTime - fromChange := lastChangeTime.Sub(pb.startTime) - pb.mu.Unlock() - select { - case <-pb.finish: - if pb.ShowFinalTime { - var left time.Duration - left = (fromStart / time.Second) * time.Second - timeLeftBox = fmt.Sprintf(" %s", left.String()) - } - default: - if pb.ShowTimeLeft && currentFromStart > 0 { - perEntry := fromChange / time.Duration(currentFromStart) - var left time.Duration - if pb.Total > 0 { - left = time.Duration(pb.Total-currentFromStart) * perEntry - left -= time.Since(lastChangeTime) - left = (left / time.Second) * time.Second - } else { - left = time.Duration(currentFromStart) * perEntry - left = (left / time.Second) * time.Second - } - if left > 0 { - timeLeft := Format(int64(left)).To(U_DURATION).String() - timeLeftBox = fmt.Sprintf(" %s", timeLeft) - } - } - } - - if len(timeLeftBox) < pb.TimeBoxWidth { - timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox) - } - - // speed - if pb.ShowSpeed && currentFromStart > 0 { - fromStart := time.Now().Sub(pb.startTime) - speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second)) - speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String() - } - - barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix) - // bar - if pb.ShowBar { - size := width - barWidth - if size > 0 { - if pb.Total > 0 { - curSize := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size))) - emptySize := size - curSize - barBox = pb.BarStart - if emptySize < 0 { - emptySize = 0 - } - if curSize > size { - curSize = size - } - - cursorLen := escapeAwareRuneCountInString(pb.Current) - if emptySize <= 0 { - barBox += strings.Repeat(pb.Current, curSize/cursorLen) - } else if curSize > 0 { - cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN) - cursorRepetitions := (curSize - cursorEndLen) / cursorLen - barBox += strings.Repeat(pb.Current, cursorRepetitions) - barBox += pb.CurrentN - } - - emptyLen := escapeAwareRuneCountInString(pb.Empty) - barBox += strings.Repeat(pb.Empty, emptySize/emptyLen) - barBox += pb.BarEnd - } else { - pos := size - int(current)%int(size) - barBox = pb.BarStart - if pos-1 > 0 { - barBox += strings.Repeat(pb.Empty, pos-1) - } - barBox += pb.Current - if size-pos-1 > 0 { - barBox += strings.Repeat(pb.Empty, size-pos-1) - } - barBox += pb.BarEnd - } - } - } - - // check len - out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix - if cl := escapeAwareRuneCountInString(out); cl < width { - end = strings.Repeat(" ", width-cl) - } - - // and print! - pb.mu.Lock() - pb.lastPrint = out + end - isFinish := pb.isFinish - pb.mu.Unlock() - switch { - case isFinish: - return - case pb.Output != nil: - fmt.Fprint(pb.Output, "\r"+out+end) - case pb.Callback != nil: - pb.Callback(out + end) - case !pb.NotPrint: - fmt.Print("\r" + out + end) - } -} - -// GetTerminalWidth - returns terminal width for all platforms. -func GetTerminalWidth() (int, error) { - return terminalWidth() -} - -func (pb *ProgressBar) GetWidth() int { - if pb.ForceWidth { - return pb.Width - } - - width := pb.Width - termWidth, _ := terminalWidth() - if width == 0 || termWidth <= width { - width = termWidth - } - - return width -} - -// Write the current state of the progressbar -func (pb *ProgressBar) Update() { - c := atomic.LoadInt64(&pb.current) - p := atomic.LoadInt64(&pb.previous) - if p != c { - pb.mu.Lock() - pb.changeTime = time.Now() - pb.mu.Unlock() - atomic.StoreInt64(&pb.previous, c) - } - pb.write(c) - if pb.AutoStat { - if c == 0 { - pb.startTime = time.Now() - pb.startValue = 0 - } else if c >= pb.Total && pb.isFinish != true { - pb.Finish() - } - } -} - -// String return the last bar print -func (pb *ProgressBar) String() string { - pb.mu.Lock() - defer pb.mu.Unlock() - return pb.lastPrint -} - -// Internal loop for refreshing the progressbar -func (pb *ProgressBar) refresher() { - for { - select { - case <-pb.finish: - return - case <-time.After(pb.RefreshRate): - pb.Update() - } - } -} diff --git a/vendor/github.com/cheggaaa/pb/pb_win.go b/vendor/github.com/cheggaaa/pb/pb_win.go deleted file mode 100644 index 72f682835..000000000 --- a/vendor/github.com/cheggaaa/pb/pb_win.go +++ /dev/null @@ -1,141 +0,0 @@ -// +build windows - -package pb - -import ( - "errors" - "fmt" - "os" - "sync" - "syscall" - "unsafe" -) - -var tty = os.Stdin - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - - // GetConsoleScreenBufferInfo retrieves information about the - // specified console screen buffer. - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - - // GetConsoleMode retrieves the current input mode of a console's - // input buffer or the current output mode of a console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx - getConsoleMode = kernel32.NewProc("GetConsoleMode") - - // SetConsoleMode sets the input mode of a console's input buffer - // or the output mode of a console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx - setConsoleMode = kernel32.NewProc("SetConsoleMode") - - // SetConsoleCursorPosition sets the cursor position in the - // specified console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx - setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") -) - -type ( - // Defines the coordinates of the upper left and lower right corners - // of a rectangle. - // See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx - smallRect struct { - Left, Top, Right, Bottom int16 - } - - // Defines the coordinates of a character cell in a console screen - // buffer. The origin of the coordinate system (0,0) is at the top, left cell - // of the buffer. - // See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx - coordinates struct { - X, Y int16 - } - - word int16 - - // Contains information about a console screen buffer. - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx - consoleScreenBufferInfo struct { - dwSize coordinates - dwCursorPosition coordinates - wAttributes word - srWindow smallRect - dwMaximumWindowSize coordinates - } -) - -// terminalWidth returns width of the terminal. -func terminalWidth() (width int, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return 0, error(e) - } - return int(info.dwSize.X) - 1, nil -} - -func getCursorPos() (pos coordinates, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return info.dwCursorPosition, error(e) - } - return info.dwCursorPosition, nil -} - -func setCursorPos(pos coordinates) error { - _, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0) - if e != 0 { - return error(e) - } - return nil -} - -var ErrPoolWasStarted = errors.New("Bar pool was started") - -var echoLocked bool -var echoLockMutex sync.Mutex - -var oldState word - -func lockEcho() (quit chan int, err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if echoLocked { - err = ErrPoolWasStarted - return - } - echoLocked = true - - if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } - - newState := oldState - const ENABLE_ECHO_INPUT = 0x0004 - const ENABLE_LINE_INPUT = 0x0002 - newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) - if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return - } - return -} - -func unlockEcho() (err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if !echoLocked { - return - } - echoLocked = false - if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") - } - return -} diff --git a/vendor/github.com/cheggaaa/pb/pb_x.go b/vendor/github.com/cheggaaa/pb/pb_x.go deleted file mode 100644 index bbbe7c2d6..000000000 --- a/vendor/github.com/cheggaaa/pb/pb_x.go +++ /dev/null @@ -1,108 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly -// +build !appengine - -package pb - -import ( - "errors" - "fmt" - "os" - "os/signal" - "sync" - "syscall" - - "golang.org/x/sys/unix" -) - -var ErrPoolWasStarted = errors.New("Bar pool was started") - -var ( - echoLockMutex sync.Mutex - origTermStatePtr *unix.Termios - tty *os.File -) - -func init() { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - - var err error - tty, err = os.Open("/dev/tty") - if err != nil { - tty = os.Stdin - } -} - -// terminalWidth returns width of the terminal. -func terminalWidth() (int, error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - - fd := int(tty.Fd()) - - ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) - if err != nil { - return 0, err - } - - return int(ws.Col), nil -} - -func lockEcho() (quit chan int, err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if origTermStatePtr != nil { - return quit, ErrPoolWasStarted - } - - fd := int(tty.Fd()) - - oldTermStatePtr, err := unix.IoctlGetTermios(fd, ioctlReadTermios) - if err != nil { - return nil, fmt.Errorf("Can't get terminal settings: %v", err) - } - - oldTermios := *oldTermStatePtr - newTermios := oldTermios - newTermios.Lflag &^= syscall.ECHO - newTermios.Lflag |= syscall.ICANON | syscall.ISIG - newTermios.Iflag |= syscall.ICRNL - if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil { - return nil, fmt.Errorf("Can't set terminal settings: %v", err) - } - - quit = make(chan int, 1) - go catchTerminate(quit) - return -} - -func unlockEcho() error { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if origTermStatePtr == nil { - return nil - } - - fd := int(tty.Fd()) - - if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil { - return fmt.Errorf("Can't set terminal settings: %v", err) - } - - origTermStatePtr = nil - - return nil -} - -// listen exit signals and restore terminal state -func catchTerminate(quit chan int) { - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) - defer signal.Stop(sig) - select { - case <-quit: - unlockEcho() - case <-sig: - unlockEcho() - } -} diff --git a/vendor/github.com/cheggaaa/pb/pool.go b/vendor/github.com/cheggaaa/pb/pool.go deleted file mode 100644 index bc1a13886..000000000 --- a/vendor/github.com/cheggaaa/pb/pool.go +++ /dev/null @@ -1,82 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly windows - -package pb - -import ( - "io" - "sync" - "time" -) - -// Create and start new pool with given bars -// You need call pool.Stop() after work -func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) { - pool = new(Pool) - if err = pool.start(); err != nil { - return - } - pool.Add(pbs...) - return -} - -type Pool struct { - Output io.Writer - RefreshRate time.Duration - bars []*ProgressBar - lastBarsCount int - quit chan int - m sync.Mutex - finishOnce sync.Once -} - -// Add progress bars. -func (p *Pool) Add(pbs ...*ProgressBar) { - p.m.Lock() - defer p.m.Unlock() - for _, bar := range pbs { - bar.ManualUpdate = true - bar.NotPrint = true - bar.Start() - p.bars = append(p.bars, bar) - } -} - -func (p *Pool) start() (err error) { - p.RefreshRate = DefaultRefreshRate - quit, err := lockEcho() - if err != nil { - return - } - p.quit = make(chan int) - go p.writer(quit) - return -} - -func (p *Pool) writer(finish chan int) { - var first = true - for { - select { - case <-time.After(p.RefreshRate): - if p.print(first) { - p.print(false) - finish <- 1 - return - } - first = false - case <-p.quit: - finish <- 1 - return - } - } -} - -// Restore terminal state and close pool -func (p *Pool) Stop() error { - // Wait until one final refresh has passed. - time.Sleep(p.RefreshRate) - - p.finishOnce.Do(func() { - close(p.quit) - }) - return unlockEcho() -} diff --git a/vendor/github.com/cheggaaa/pb/pool_win.go b/vendor/github.com/cheggaaa/pb/pool_win.go deleted file mode 100644 index 63598d378..000000000 --- a/vendor/github.com/cheggaaa/pb/pool_win.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build windows - -package pb - -import ( - "fmt" - "log" -) - -func (p *Pool) print(first bool) bool { - p.m.Lock() - defer p.m.Unlock() - var out string - if !first { - coords, err := getCursorPos() - if err != nil { - log.Panic(err) - } - coords.Y -= int16(p.lastBarsCount) - if coords.Y < 0 { - coords.Y = 0 - } - coords.X = 0 - - err = setCursorPos(coords) - if err != nil { - log.Panic(err) - } - } - isFinished := true - for _, bar := range p.bars { - if !bar.IsFinished() { - isFinished = false - } - bar.Update() - out += fmt.Sprintf("\r%s\n", bar.String()) - } - if p.Output != nil { - fmt.Fprint(p.Output, out) - } else { - fmt.Print(out) - } - p.lastBarsCount = len(p.bars) - return isFinished -} diff --git a/vendor/github.com/cheggaaa/pb/pool_x.go b/vendor/github.com/cheggaaa/pb/pool_x.go deleted file mode 100644 index a8ae14d2f..000000000 --- a/vendor/github.com/cheggaaa/pb/pool_x.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly - -package pb - -import "fmt" - -func (p *Pool) print(first bool) bool { - p.m.Lock() - defer p.m.Unlock() - var out string - if !first { - out = fmt.Sprintf("\033[%dA", p.lastBarsCount) - } - isFinished := true - for _, bar := range p.bars { - if !bar.IsFinished() { - isFinished = false - } - bar.Update() - out += fmt.Sprintf("\r%s\n", bar.String()) - } - if p.Output != nil { - fmt.Fprint(p.Output, out) - } else { - fmt.Print(out) - } - p.lastBarsCount = len(p.bars) - return isFinished -} diff --git a/vendor/github.com/cheggaaa/pb/reader.go b/vendor/github.com/cheggaaa/pb/reader.go deleted file mode 100644 index 9f3148b54..000000000 --- a/vendor/github.com/cheggaaa/pb/reader.go +++ /dev/null @@ -1,25 +0,0 @@ -package pb - -import ( - "io" -) - -// It's proxy reader, implement io.Reader -type Reader struct { - io.Reader - bar *ProgressBar -} - -func (r *Reader) Read(p []byte) (n int, err error) { - n, err = r.Reader.Read(p) - r.bar.Add(n) - return -} - -// Close the reader when it implements io.Closer -func (r *Reader) Close() (err error) { - if closer, ok := r.Reader.(io.Closer); ok { - return closer.Close() - } - return -} diff --git a/vendor/github.com/cheggaaa/pb/runecount.go b/vendor/github.com/cheggaaa/pb/runecount.go deleted file mode 100644 index c617c55ec..000000000 --- a/vendor/github.com/cheggaaa/pb/runecount.go +++ /dev/null @@ -1,17 +0,0 @@ -package pb - -import ( - "github.com/mattn/go-runewidth" - "regexp" -) - -// Finds the control character sequences (like colors) -var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") - -func escapeAwareRuneCountInString(s string) int { - n := runewidth.StringWidth(s) - for _, sm := range ctrlFinder.FindAllString(s, -1) { - n -= runewidth.StringWidth(sm) - } - return n -} diff --git a/vendor/github.com/cheggaaa/pb/termios_bsd.go b/vendor/github.com/cheggaaa/pb/termios_bsd.go deleted file mode 100644 index 517ea8ed7..000000000 --- a/vendor/github.com/cheggaaa/pb/termios_bsd.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build darwin freebsd netbsd openbsd dragonfly -// +build !appengine - -package pb - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/github.com/cheggaaa/pb/termios_sysv.go b/vendor/github.com/cheggaaa/pb/termios_sysv.go deleted file mode 100644 index b10f61859..000000000 --- a/vendor/github.com/cheggaaa/pb/termios_sysv.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux solaris -// +build !appengine - -package pb - -import "golang.org/x/sys/unix" - -const ioctlReadTermios = unix.TCGETS -const ioctlWriteTermios = unix.TCSETS diff --git a/vendor/github.com/jlaffaye/ftp/LICENSE b/vendor/github.com/jlaffaye/ftp/LICENSE deleted file mode 100644 index 9ab085c51..000000000 --- a/vendor/github.com/jlaffaye/ftp/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2011-2013, Julien Laffaye <jlaffaye@FreeBSD.org> - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/jlaffaye/ftp/README.md b/vendor/github.com/jlaffaye/ftp/README.md deleted file mode 100644 index b711be7ad..000000000 --- a/vendor/github.com/jlaffaye/ftp/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# goftp # - -[![Build Status](https://travis-ci.org/jlaffaye/ftp.svg?branch=master)](https://travis-ci.org/jlaffaye/ftp) -[![Coverage Status](https://coveralls.io/repos/jlaffaye/ftp/badge.svg?branch=master&service=github)](https://coveralls.io/github/jlaffaye/ftp?branch=master) -[![Go ReportCard](http://goreportcard.com/badge/jlaffaye/ftp)](http://goreportcard.com/report/jlaffaye/ftp) - -A FTP client package for Go - -## Install ## - -``` -go get -u github.com/jlaffaye/ftp -``` - -## Documentation ## - -http://godoc.org/github.com/jlaffaye/ftp diff --git a/vendor/github.com/jlaffaye/ftp/ftp.go b/vendor/github.com/jlaffaye/ftp/ftp.go deleted file mode 100644 index db7ac9277..000000000 --- a/vendor/github.com/jlaffaye/ftp/ftp.go +++ /dev/null @@ -1,671 +0,0 @@ -// Package ftp implements a FTP client as described in RFC 959. -package ftp - -import ( - "bufio" - "errors" - "io" - "net" - "net/textproto" - "strconv" - "strings" - "time" -) - -// EntryType describes the different types of an Entry. -type EntryType int - -// The differents types of an Entry -const ( - EntryTypeFile EntryType = iota - EntryTypeFolder - EntryTypeLink -) - -// ServerConn represents the connection to a remote FTP server. -type ServerConn struct { - conn *textproto.Conn - host string - timeout time.Duration - features map[string]string -} - -// Entry describes a file and is returned by List(). -type Entry struct { - Name string - Type EntryType - Size uint64 - Time time.Time -} - -// response represent a data-connection -type response struct { - conn net.Conn - c *ServerConn -} - -// Connect is an alias to Dial, for backward compatibility -func Connect(addr string) (*ServerConn, error) { - return Dial(addr) -} - -// Dial is like DialTimeout with no timeout -func Dial(addr string) (*ServerConn, error) { - return DialTimeout(addr, 0) -} - -// DialTimeout initializes the connection to the specified ftp server address. -// -// It is generally followed by a call to Login() as most FTP commands require -// an authenticated user. -func DialTimeout(addr string, timeout time.Duration) (*ServerConn, error) { - tconn, err := net.DialTimeout("tcp", addr, timeout) - if err != nil { - return nil, err - } - - // Use the resolved IP address in case addr contains a domain name - // If we use the domain name, we might not resolve to the same IP. - remoteAddr := tconn.RemoteAddr().String() - host, _, err := net.SplitHostPort(remoteAddr) - if err != nil { - return nil, err - } - - conn := textproto.NewConn(tconn) - - c := &ServerConn{ - conn: conn, - host: host, - timeout: timeout, - features: make(map[string]string), - } - - _, _, err = c.conn.ReadResponse(StatusReady) - if err != nil { - c.Quit() - return nil, err - } - - err = c.feat() - if err != nil { - c.Quit() - return nil, err - } - - return c, nil -} - -// Login authenticates the client with specified user and password. -// -// "anonymous"/"anonymous" is a common user/password scheme for FTP servers -// that allows anonymous read-only accounts. -func (c *ServerConn) Login(user, password string) error { - code, message, err := c.cmd(-1, "USER %s", user) - if err != nil { - return err - } - - switch code { - case StatusLoggedIn: - case StatusUserOK: - _, _, err = c.cmd(StatusLoggedIn, "PASS %s", password) - if err != nil { - return err - } - default: - return errors.New(message) - } - - // Switch to binary mode - _, _, err = c.cmd(StatusCommandOK, "TYPE I") - if err != nil { - return err - } - - return nil -} - -// feat issues a FEAT FTP command to list the additional commands supported by -// the remote FTP server. -// FEAT is described in RFC 2389 -func (c *ServerConn) feat() error { - code, message, err := c.cmd(-1, "FEAT") - if err != nil { - return err - } - - if code != StatusSystem { - // The server does not support the FEAT command. This is not an - // error: we consider that there is no additional feature. - return nil - } - - lines := strings.Split(message, "\n") - for _, line := range lines { - if !strings.HasPrefix(line, " ") { - continue - } - - line = strings.TrimSpace(line) - featureElements := strings.SplitN(line, " ", 2) - - command := featureElements[0] - - var commandDesc string - if len(featureElements) == 2 { - commandDesc = featureElements[1] - } - - c.features[command] = commandDesc - } - - return nil -} - -// epsv issues an "EPSV" command to get a port number for a data connection. -func (c *ServerConn) epsv() (port int, err error) { - _, line, err := c.cmd(StatusExtendedPassiveMode, "EPSV") - if err != nil { - return - } - - start := strings.Index(line, "|||") - end := strings.LastIndex(line, "|") - if start == -1 || end == -1 { - err = errors.New("Invalid EPSV response format") - return - } - port, err = strconv.Atoi(line[start+3 : end]) - return -} - -// pasv issues a "PASV" command to get a port number for a data connection. -func (c *ServerConn) pasv() (port int, err error) { - _, line, err := c.cmd(StatusPassiveMode, "PASV") - if err != nil { - return - } - - // PASV response format : 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). - start := strings.Index(line, "(") - end := strings.LastIndex(line, ")") - if start == -1 || end == -1 { - return 0, errors.New("Invalid PASV response format") - } - - // We have to split the response string - pasvData := strings.Split(line[start+1:end], ",") - - if len(pasvData) < 6 { - return 0, errors.New("Invalid PASV response format") - } - - // Let's compute the port number - portPart1, err1 := strconv.Atoi(pasvData[4]) - if err1 != nil { - err = err1 - return - } - - portPart2, err2 := strconv.Atoi(pasvData[5]) - if err2 != nil { - err = err2 - return - } - - // Recompose port - port = portPart1*256 + portPart2 - return -} - -// openDataConn creates a new FTP data connection. -func (c *ServerConn) openDataConn() (net.Conn, error) { - var ( - port int - err error - ) - - if port, err = c.epsv(); err != nil { - if port, err = c.pasv(); err != nil { - return nil, err - } - } - - return net.DialTimeout("tcp", net.JoinHostPort(c.host, strconv.Itoa(port)), c.timeout) -} - -// cmd is a helper function to execute a command and check for the expected FTP -// return code -func (c *ServerConn) cmd(expected int, format string, args ...interface{}) (int, string, error) { - _, err := c.conn.Cmd(format, args...) - if err != nil { - return 0, "", err - } - - return c.conn.ReadResponse(expected) -} - -// cmdDataConnFrom executes a command which require a FTP data connection. -// Issues a REST FTP command to specify the number of bytes to skip for the transfer. -func (c *ServerConn) cmdDataConnFrom(offset uint64, format string, args ...interface{}) (net.Conn, error) { - conn, err := c.openDataConn() - if err != nil { - return nil, err - } - - if offset != 0 { - _, _, err := c.cmd(StatusRequestFilePending, "REST %d", offset) - if err != nil { - return nil, err - } - } - - _, err = c.conn.Cmd(format, args...) - if err != nil { - conn.Close() - return nil, err - } - - code, msg, err := c.conn.ReadResponse(-1) - if err != nil { - conn.Close() - return nil, err - } - if code != StatusAlreadyOpen && code != StatusAboutToSend { - conn.Close() - return nil, &textproto.Error{Code: code, Msg: msg} - } - - return conn, nil -} - -var errUnsupportedListLine = errors.New("Unsupported LIST line") - -// parseRFC3659ListLine parses the style of directory line defined in RFC 3659. -func parseRFC3659ListLine(line string) (*Entry, error) { - iSemicolon := strings.Index(line, ";") - iWhitespace := strings.Index(line, " ") - - if iSemicolon < 0 || iSemicolon > iWhitespace { - return nil, errUnsupportedListLine - } - - e := &Entry{ - Name: line[iWhitespace+1:], - } - - for _, field := range strings.Split(line[:iWhitespace-1], ";") { - i := strings.Index(field, "=") - if i < 1 { - return nil, errUnsupportedListLine - } - - key := field[:i] - value := field[i+1:] - - switch key { - case "modify": - var err error - e.Time, err = time.Parse("20060102150405", value) - if err != nil { - return nil, err - } - case "type": - switch value { - case "dir", "cdir", "pdir": - e.Type = EntryTypeFolder - case "file": - e.Type = EntryTypeFile - } - case "size": - e.setSize(value) - } - } - return e, nil -} - -// parseLsListLine parses a directory line in a format based on the output of -// the UNIX ls command. -func parseLsListLine(line string) (*Entry, error) { - fields := strings.Fields(line) - if len(fields) >= 7 && fields[1] == "folder" && fields[2] == "0" { - e := &Entry{ - Type: EntryTypeFolder, - Name: strings.Join(fields[6:], " "), - } - if err := e.setTime(fields[3:6]); err != nil { - return nil, err - } - - return e, nil - } - - if len(fields) < 8 { - return nil, errUnsupportedListLine - } - - if fields[1] == "0" { - e := &Entry{ - Type: EntryTypeFile, - Name: strings.Join(fields[7:], " "), - } - - if err := e.setSize(fields[2]); err != nil { - return nil, err - } - if err := e.setTime(fields[4:7]); err != nil { - return nil, err - } - - return e, nil - } - - if len(fields) < 9 { - return nil, errUnsupportedListLine - } - - e := &Entry{} - switch fields[0][0] { - case '-': - e.Type = EntryTypeFile - if err := e.setSize(fields[4]); err != nil { - return nil, err - } - case 'd': - e.Type = EntryTypeFolder - case 'l': - e.Type = EntryTypeLink - default: - return nil, errors.New("Unknown entry type") - } - - if err := e.setTime(fields[5:8]); err != nil { - return nil, err - } - - e.Name = strings.Join(fields[8:], " ") - return e, nil -} - -var dirTimeFormats = []string{ - "01-02-06 03:04PM", - "2006-01-02 15:04", -} - -// parseDirListLine parses a directory line in a format based on the output of -// the MS-DOS DIR command. -func parseDirListLine(line string) (*Entry, error) { - e := &Entry{} - var err error - - // Try various time formats that DIR might use, and stop when one works. - for _, format := range dirTimeFormats { - if len(line) > len(format) { - e.Time, err = time.Parse(format, line[:len(format)]) - if err == nil { - line = line[len(format):] - break - } - } - } - if err != nil { - // None of the time formats worked. - return nil, errUnsupportedListLine - } - - line = strings.TrimLeft(line, " ") - if strings.HasPrefix(line, "<DIR>") { - e.Type = EntryTypeFolder - line = strings.TrimPrefix(line, "<DIR>") - } else { - space := strings.Index(line, " ") - if space == -1 { - return nil, errUnsupportedListLine - } - e.Size, err = strconv.ParseUint(line[:space], 10, 64) - if err != nil { - return nil, errUnsupportedListLine - } - e.Type = EntryTypeFile - line = line[space:] - } - - e.Name = strings.TrimLeft(line, " ") - return e, nil -} - -var listLineParsers = []func(line string) (*Entry, error){ - parseRFC3659ListLine, - parseLsListLine, - parseDirListLine, -} - -// parseListLine parses the various non-standard format returned by the LIST -// FTP command. -func parseListLine(line string) (*Entry, error) { - for _, f := range listLineParsers { - e, err := f(line) - if err == errUnsupportedListLine { - // Try another format. - continue - } - return e, err - } - return nil, errUnsupportedListLine -} - -func (e *Entry) setSize(str string) (err error) { - e.Size, err = strconv.ParseUint(str, 0, 64) - return -} - -func (e *Entry) setTime(fields []string) (err error) { - var timeStr string - if strings.Contains(fields[2], ":") { // this year - thisYear, _, _ := time.Now().Date() - timeStr = fields[1] + " " + fields[0] + " " + strconv.Itoa(thisYear)[2:4] + " " + fields[2] + " GMT" - } else { // not this year - if len(fields[2]) != 4 { - return errors.New("Invalid year format in time string") - } - timeStr = fields[1] + " " + fields[0] + " " + fields[2][2:4] + " 00:00 GMT" - } - e.Time, err = time.Parse("_2 Jan 06 15:04 MST", timeStr) - return -} - -// NameList issues an NLST FTP command. -func (c *ServerConn) NameList(path string) (entries []string, err error) { - conn, err := c.cmdDataConnFrom(0, "NLST %s", path) - if err != nil { - return - } - - r := &response{conn, c} - defer r.Close() - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - entries = append(entries, scanner.Text()) - } - if err = scanner.Err(); err != nil { - return entries, err - } - return -} - -// List issues a LIST FTP command. -func (c *ServerConn) List(path string) (entries []*Entry, err error) { - conn, err := c.cmdDataConnFrom(0, "LIST %s", path) - if err != nil { - return - } - - r := &response{conn, c} - defer r.Close() - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() - entry, err := parseListLine(line) - if err == nil { - entries = append(entries, entry) - } - } - if err := scanner.Err(); err != nil { - return nil, err - } - return -} - -// ChangeDir issues a CWD FTP command, which changes the current directory to -// the specified path. -func (c *ServerConn) ChangeDir(path string) error { - _, _, err := c.cmd(StatusRequestedFileActionOK, "CWD %s", path) - return err -} - -// ChangeDirToParent issues a CDUP FTP command, which changes the current -// directory to the parent directory. This is similar to a call to ChangeDir -// with a path set to "..". -func (c *ServerConn) ChangeDirToParent() error { - _, _, err := c.cmd(StatusRequestedFileActionOK, "CDUP") - return err -} - -// CurrentDir issues a PWD FTP command, which Returns the path of the current -// directory. -func (c *ServerConn) CurrentDir() (string, error) { - _, msg, err := c.cmd(StatusPathCreated, "PWD") - if err != nil { - return "", err - } - - start := strings.Index(msg, "\"") - end := strings.LastIndex(msg, "\"") - - if start == -1 || end == -1 { - return "", errors.New("Unsuported PWD response format") - } - - return msg[start+1 : end], nil -} - -// Retr issues a RETR FTP command to fetch the specified file from the remote -// FTP server. -// -// The returned ReadCloser must be closed to cleanup the FTP data connection. -func (c *ServerConn) Retr(path string) (io.ReadCloser, error) { - return c.RetrFrom(path, 0) -} - -// RetrFrom issues a RETR FTP command to fetch the specified file from the remote -// FTP server, the server will not send the offset first bytes of the file. -// -// The returned ReadCloser must be closed to cleanup the FTP data connection. -func (c *ServerConn) RetrFrom(path string, offset uint64) (io.ReadCloser, error) { - conn, err := c.cmdDataConnFrom(offset, "RETR %s", path) - if err != nil { - return nil, err - } - - return &response{conn, c}, nil -} - -// Stor issues a STOR FTP command to store a file to the remote FTP server. -// Stor creates the specified file with the content of the io.Reader. -// -// Hint: io.Pipe() can be used if an io.Writer is required. -func (c *ServerConn) Stor(path string, r io.Reader) error { - return c.StorFrom(path, r, 0) -} - -// StorFrom issues a STOR FTP command to store a file to the remote FTP server. -// Stor creates the specified file with the content of the io.Reader, writing -// on the server will start at the given file offset. -// -// Hint: io.Pipe() can be used if an io.Writer is required. -func (c *ServerConn) StorFrom(path string, r io.Reader, offset uint64) error { - conn, err := c.cmdDataConnFrom(offset, "STOR %s", path) - if err != nil { - return err - } - - _, err = io.Copy(conn, r) - conn.Close() - if err != nil { - return err - } - - _, _, err = c.conn.ReadResponse(StatusClosingDataConnection) - return err -} - -// Rename renames a file on the remote FTP server. -func (c *ServerConn) Rename(from, to string) error { - _, _, err := c.cmd(StatusRequestFilePending, "RNFR %s", from) - if err != nil { - return err - } - - _, _, err = c.cmd(StatusRequestedFileActionOK, "RNTO %s", to) - return err -} - -// Delete issues a DELE FTP command to delete the specified file from the -// remote FTP server. -func (c *ServerConn) Delete(path string) error { - _, _, err := c.cmd(StatusRequestedFileActionOK, "DELE %s", path) - return err -} - -// MakeDir issues a MKD FTP command to create the specified directory on the -// remote FTP server. -func (c *ServerConn) MakeDir(path string) error { - _, _, err := c.cmd(StatusPathCreated, "MKD %s", path) - return err -} - -// RemoveDir issues a RMD FTP command to remove the specified directory from -// the remote FTP server. -func (c *ServerConn) RemoveDir(path string) error { - _, _, err := c.cmd(StatusRequestedFileActionOK, "RMD %s", path) - return err -} - -// NoOp issues a NOOP FTP command. -// NOOP has no effects and is usually used to prevent the remote FTP server to -// close the otherwise idle connection. -func (c *ServerConn) NoOp() error { - _, _, err := c.cmd(StatusCommandOK, "NOOP") - return err -} - -// Logout issues a REIN FTP command to logout the current user. -func (c *ServerConn) Logout() error { - _, _, err := c.cmd(StatusReady, "REIN") - return err -} - -// Quit issues a QUIT FTP command to properly close the connection from the -// remote FTP server. -func (c *ServerConn) Quit() error { - c.conn.Cmd("QUIT") - return c.conn.Close() -} - -// Read implements the io.Reader interface on a FTP data connection. -func (r *response) Read(buf []byte) (int, error) { - return r.conn.Read(buf) -} - -// Close implements the io.Closer interface on a FTP data connection. -func (r *response) Close() error { - err := r.conn.Close() - _, _, err2 := r.c.conn.ReadResponse(StatusClosingDataConnection) - if err2 != nil { - err = err2 - } - return err -} diff --git a/vendor/github.com/jlaffaye/ftp/status.go b/vendor/github.com/jlaffaye/ftp/status.go deleted file mode 100644 index e90ca6211..000000000 --- a/vendor/github.com/jlaffaye/ftp/status.go +++ /dev/null @@ -1,106 +0,0 @@ -package ftp - -// FTP status codes, defined in RFC 959 -const ( - StatusInitiating = 100 - StatusRestartMarker = 110 - StatusReadyMinute = 120 - StatusAlreadyOpen = 125 - StatusAboutToSend = 150 - - StatusCommandOK = 200 - StatusCommandNotImplemented = 202 - StatusSystem = 211 - StatusDirectory = 212 - StatusFile = 213 - StatusHelp = 214 - StatusName = 215 - StatusReady = 220 - StatusClosing = 221 - StatusDataConnectionOpen = 225 - StatusClosingDataConnection = 226 - StatusPassiveMode = 227 - StatusLongPassiveMode = 228 - StatusExtendedPassiveMode = 229 - StatusLoggedIn = 230 - StatusLoggedOut = 231 - StatusLogoutAck = 232 - StatusRequestedFileActionOK = 250 - StatusPathCreated = 257 - - StatusUserOK = 331 - StatusLoginNeedAccount = 332 - StatusRequestFilePending = 350 - - StatusNotAvailable = 421 - StatusCanNotOpenDataConnection = 425 - StatusTransfertAborted = 426 - StatusInvalidCredentials = 430 - StatusHostUnavailable = 434 - StatusFileActionIgnored = 450 - StatusActionAborted = 451 - Status452 = 452 - - StatusBadCommand = 500 - StatusBadArguments = 501 - StatusNotImplemented = 502 - StatusBadSequence = 503 - StatusNotImplementedParameter = 504 - StatusNotLoggedIn = 530 - StatusStorNeedAccount = 532 - StatusFileUnavailable = 550 - StatusPageTypeUnknown = 551 - StatusExceededStorage = 552 - StatusBadFileName = 553 -) - -var statusText = map[int]string{ - // 200 - StatusCommandOK: "Command okay.", - StatusCommandNotImplemented: "Command not implemented, superfluous at this site.", - StatusSystem: "System status, or system help reply.", - StatusDirectory: "Directory status.", - StatusFile: "File status.", - StatusHelp: "Help message.", - StatusName: "", - StatusReady: "Service ready for new user.", - StatusClosing: "Service closing control connection.", - StatusDataConnectionOpen: "Data connection open; no transfer in progress.", - StatusClosingDataConnection: "Closing data connection. Requested file action successful.", - StatusPassiveMode: "Entering Passive Mode.", - StatusLongPassiveMode: "Entering Long Passive Mode.", - StatusExtendedPassiveMode: "Entering Extended Passive Mode.", - StatusLoggedIn: "User logged in, proceed.", - StatusLoggedOut: "User logged out; service terminated.", - StatusLogoutAck: "Logout command noted, will complete when transfer done.", - StatusRequestedFileActionOK: "Requested file action okay, completed.", - StatusPathCreated: "Path created.", - - // 300 - StatusUserOK: "User name okay, need password.", - StatusLoginNeedAccount: "Need account for login.", - StatusRequestFilePending: "Requested file action pending further information.", - - // 400 - StatusNotAvailable: "Service not available, closing control connection.", - StatusCanNotOpenDataConnection: "Can't open data connection.", - StatusTransfertAborted: "Connection closed; transfer aborted.", - StatusInvalidCredentials: "Invalid username or password.", - StatusHostUnavailable: "Requested host unavailable.", - StatusFileActionIgnored: "Requested file action not taken.", - StatusActionAborted: "Requested action aborted. Local error in processing.", - Status452: "Insufficient storage space in system.", - - // 500 - StatusBadCommand: "Command unrecognized.", - StatusBadArguments: "Syntax error in parameters or arguments.", - StatusNotImplemented: "Command not implemented.", - StatusBadSequence: "Bad sequence of commands.", - StatusNotImplementedParameter: "Command not implemented for that parameter.", - StatusNotLoggedIn: "Not logged in.", - StatusStorNeedAccount: "Need account for storing files.", - StatusFileUnavailable: "File unavailable.", - StatusPageTypeUnknown: "Page type unknown.", - StatusExceededStorage: "Exceeded storage allocation.", - StatusBadFileName: "File name not allowed.", -} diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE deleted file mode 100644 index 91b5cef30..000000000 --- a/vendor/github.com/mattn/go-runewidth/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-runewidth/README.mkd b/vendor/github.com/mattn/go-runewidth/README.mkd deleted file mode 100644 index 66663a94b..000000000 --- a/vendor/github.com/mattn/go-runewidth/README.mkd +++ /dev/null @@ -1,27 +0,0 @@ -go-runewidth -============ - -[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) -[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) -[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) -[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) - -Provides functions to get fixed width of the character or string. - -Usage ------ - -```go -runewidth.StringWidth("つのだ☆HIRO") == 12 -``` - - -Author ------- - -Yasuhiro Matsumoto - -License -------- - -under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go deleted file mode 100644 index 2164497ad..000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth.go +++ /dev/null @@ -1,1223 +0,0 @@ -package runewidth - -var ( - // EastAsianWidth will be set true if the current locale is CJK - EastAsianWidth = IsEastAsian() - - // DefaultCondition is a condition in current locale - DefaultCondition = &Condition{EastAsianWidth} -) - -type interval struct { - first rune - last rune -} - -type table []interval - -func inTables(r rune, ts ...table) bool { - for _, t := range ts { - if inTable(r, t) { - return true - } - } - return false -} - -func inTable(r rune, t table) bool { - // func (t table) IncludesRune(r rune) bool { - if r < t[0].first { - return false - } - - bot := 0 - top := len(t) - 1 - for top >= bot { - mid := (bot + top) / 2 - - switch { - case t[mid].last < r: - bot = mid + 1 - case t[mid].first > r: - top = mid - 1 - default: - return true - } - } - - return false -} - -var private = table{ - {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, -} - -var nonprint = table{ - {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, - {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, - {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, - {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, -} - -var combining = table{ - {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, - {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, - {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, - {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, - {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, - {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, - {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, - {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, - {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, - {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, - {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, - {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, - {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, - {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, - {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, - {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, - {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, - {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, - {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, - {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, - {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, - {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, - {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, - {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, - {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, - {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, - {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, - {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, - {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, - {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, - {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, - {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, - {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, - {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, - {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, - {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, - {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, - {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, - {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, - {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, - {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, - {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, - {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, - {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, - {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, - {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, - {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, - {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, - {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, - {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, - {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, - {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, - {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, - {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, - {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, - {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, - {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, - {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, - {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, - {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, - {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, - {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, - {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, - {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, - {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, - {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, - {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, - {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, - {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, - {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, - {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, - {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, - {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, - {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, - {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, - {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, - {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, - {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, - {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, - {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, - {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, - {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, - {0xE0100, 0xE01EF}, -} - -var doublewidth = table{ - {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, - {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, - {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, - {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, - {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, - {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, - {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, - {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, - {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, - {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, - {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, - {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, - {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, - {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, - {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, - {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, - {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, - {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, - {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, - {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, - {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, - {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, - {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, - {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, - {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, - {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, - {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, - {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, - {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, - {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, - {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, - {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, - {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, - {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, - {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, - {0x30000, 0x3FFFD}, -} - -var ambiguous = table{ - {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, - {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, - {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, - {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, - {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, - {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, - {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, - {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, - {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, - {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, - {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, - {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, - {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, - {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, - {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, - {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, - {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, - {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, - {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, - {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, - {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, - {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, - {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, - {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, - {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, - {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, - {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, - {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, - {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, - {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, - {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, - {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, - {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, - {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, - {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, - {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, - {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, - {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, - {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, - {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, - {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, - {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, - {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, - {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, - {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, - {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, - {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, - {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, - {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, - {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, - {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, - {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, - {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, - {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, - {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, - {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, - {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, - {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, - {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, - {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, -} - -var emoji = table{ - {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, - {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, - {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, - {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, - {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, - {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, - {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, - {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, - {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, - {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, - {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, - {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, - {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, -} - -var notassigned = table{ - {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, - {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, - {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, - {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, - {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, - {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, - {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, - {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, - {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, - {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, - {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, - {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, - {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, - {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, - {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, - {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, - {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, - {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, - {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, - {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, - {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, - {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, - {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, - {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, - {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, - {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, - {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, - {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, - {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, - {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, - {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, - {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, - {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, - {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, - {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, - {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, - {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, - {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, - {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, - {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, - {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, - {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, - {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, - {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, - {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, - {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, - {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, - {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, - {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, - {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, - {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, - {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, - {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, - {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, - {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, - {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, - {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, - {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, - {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, - {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, - {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, - {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, - {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, - {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, - {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, - {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, - {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, - {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, - {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, - {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, - {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, - {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, - {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, - {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, - {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, - {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, - {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, - {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, - {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, - {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, - {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, - {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, - {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, - {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, - {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, - {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, - {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, - {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, - {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, - {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, - {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, - {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, - {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, - {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, - {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, - {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, - {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, - {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, - {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, - {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, - {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, - {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, - {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, - {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, - {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, - {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, - {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, - {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, - {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, - {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, - {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, - {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, - {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, - {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, - {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, - {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, - {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, - {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, - {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, - {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, - {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, - {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, - {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, - {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, - {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, - {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, - {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, - {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, - {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, - {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, - {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, - {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, - {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, - {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, - {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, - {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, - {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, - {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, - {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, - {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, - {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, - {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, - {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, - {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, - {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, - {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, - {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, - {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, - {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, - {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, - {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, - {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, - {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, - {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, - {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, - {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, - {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, - {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, - {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, - {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, - {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, - {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, - {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, - {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, - {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, - {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, - {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, - {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, - {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, - {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, - {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, - {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, - {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, - {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, - {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, - {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, - {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, - {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, - {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, - {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, - {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, - {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, - {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, - {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, - {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, - {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, - {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, - {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, - {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, - {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, - {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, - {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, - {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, - {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, - {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, - {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, - {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, - {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, - {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, - {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, - {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, - {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, - {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, - {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, - {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, - {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, - {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, - {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, - {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, - {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, - {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, - {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, - {0xFFFFE, 0xFFFFF}, -} - -var neutral = table{ - {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, - {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, - {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, - {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, - {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, - {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, - {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, - {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, - {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, - {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, - {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, - {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, - {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, - {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, - {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, - {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, - {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, - {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, - {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, - {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, - {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, - {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, - {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, - {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, - {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, - {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, - {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, - {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, - {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, - {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, - {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, - {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, - {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, - {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, - {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, - {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, - {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, - {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, - {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, - {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, - {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, - {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, - {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, - {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, - {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, - {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, - {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, - {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, - {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, - {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, - {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, - {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, - {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, - {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, - {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, - {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, - {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, - {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, - {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, - {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, - {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, - {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, - {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, - {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, - {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, - {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, - {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, - {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, - {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, - {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, - {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, - {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, - {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, - {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, - {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, - {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, - {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, - {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, - {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, - {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, - {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, - {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, - {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, - {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, - {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, - {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, - {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, - {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, - {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, - {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, - {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, - {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, - {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, - {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, - {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, - {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, - {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, - {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, - {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, - {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, - {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, - {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, - {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, - {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, - {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, - {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, - {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, - {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, - {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, - {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, - {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, - {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, - {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, - {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, - {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, - {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, - {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, - {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, - {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, - {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, - {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, - {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, - {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, - {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, - {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, - {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, - {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, - {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, - {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, - {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, - {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, - {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, - {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, - {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, - {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, - {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, - {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, - {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, - {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, - {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, - {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, - {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, - {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, - {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, - {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, - {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, - {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, - {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, - {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, - {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, - {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, - {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, - {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, - {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, - {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, - {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, - {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, - {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, - {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, - {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, - {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, - {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, - {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, - {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, - {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, - {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, - {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, - {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, - {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, - {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, - {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, - {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, - {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, - {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, - {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, - {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, - {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, - {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, - {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, - {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, - {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, - {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, - {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, - {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, - {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, - {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, - {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, - {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, - {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, - {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, - {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, - {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, - {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, - {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, - {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, - {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, - {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, - {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, - {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, - {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, - {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, - {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, - {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, - {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, - {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, - {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, - {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, - {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, - {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, - {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, - {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, - {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, - {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, - {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, - {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, - {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, - {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, - {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, - {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, - {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, - {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, - {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, - {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, - {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, - {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, - {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, - {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, - {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, - {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, - {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, - {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, - {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, - {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, - {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, - {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, - {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, - {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, - {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, - {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, - {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, - {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, - {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, - {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, - {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, - {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, - {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, - {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, - {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, - {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, - {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, - {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, - {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, - {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, - {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, - {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, - {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, - {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, - {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, - {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, - {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, - {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, - {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, - {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, - {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, - {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, - {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, - {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, - {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, - {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, - {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, - {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, - {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, - {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, - {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, - {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, - {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, - {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, - {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, - {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, - {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, - {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, - {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, - {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, - {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, - {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, - {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, - {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, - {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, - {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, - {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, - {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, - {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, - {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, - {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, - {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, - {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, - {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, - {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, - {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, - {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, - {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, - {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, - {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, - {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, - {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, - {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, - {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, - {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, - {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, - {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, - {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, - {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, - {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, - {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, - {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, - {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, - {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, - {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, - {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, - {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, - {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, - {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, - {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, - {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, - {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, - {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, - {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, - {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, - {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, - {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, - {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, - {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, - {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, - {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, - {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, - {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, - {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, - {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, - {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, - {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, - {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, - {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, - {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, - {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, - {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, - {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, - {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, - {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, - {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, - {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, - {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, - {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, - {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, - {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, - {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, - {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, - {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, - {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, - {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, - {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, - {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, - {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, - {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, - {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, - {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, - {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, - {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, - {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, - {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, - {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, - {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, - {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, - {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, - {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, - {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, - {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, - {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, - {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, - {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, - {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, - {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, - {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, - {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, - {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, - {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, - {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, - {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, - {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, - {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, - {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, - {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, - {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, - {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, - {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, - {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, - {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, - {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, - {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, - {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, - {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, - {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, - {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, - {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, - {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, - {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, - {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, - {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, - {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, - {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, - {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, - {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, - {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, - {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, - {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, - {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, - {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, - {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, - {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, - {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, - {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, - {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, - {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, - {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, - {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, - {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, - {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, - {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, - {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, - {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, - {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, - {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, - {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, - {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, - {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, - {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, - {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, - {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, - {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, - {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, - {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, - {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, - {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, - {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, - {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, - {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, - {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, - {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, - {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, - {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, - {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, - {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, - {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, - {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, - {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, - {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, - {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, - {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, - {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, - {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, - {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, - {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, - {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, - {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, - {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, - {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, - {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, - {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, - {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, - {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, - {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, - {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, - {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, - {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, - {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, - {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, - {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, - {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, - {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, - {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, - {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, - {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, - {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, - {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, - {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, - {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, - {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, - {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, - {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, - {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, - {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, - {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, - {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, - {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, - {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, - {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, - {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, - {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, - {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, - {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, - {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, - {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, - {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, - {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, - {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, - {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, - {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, - {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, - {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, - {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, - {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, - {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, - {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, - {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, - {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, - {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, - {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, - {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, - {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, - {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, - {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, - {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, - {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, - {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, - {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, - {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, - {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, - {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, - {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, - {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, - {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, - {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, - {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, - {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, - {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, - {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, - {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, - {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, - {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, - {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, - {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, - {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, - {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, - {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, - {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, - {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, - {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, - {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, - {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, - {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, - {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, - {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, - {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, - {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, - {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, - {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, - {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, - {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, - {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, - {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, - {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, - {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, - {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, - {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, - {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, - {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, - {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, - {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, - {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, - {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, - {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, - {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, - {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, - {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, - {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, - {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, - {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, - {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, - {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, - {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, - {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, - {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, - {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, - {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, - {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, - {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, - {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, - {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, - {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, - {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, - {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, - {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, - {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, - {0xE0020, 0xE007F}, -} - -// Condition have flag EastAsianWidth whether the current locale is CJK or not. -type Condition struct { - EastAsianWidth bool -} - -// NewCondition return new instance of Condition which is current locale. -func NewCondition() *Condition { - return &Condition{EastAsianWidth} -} - -// RuneWidth returns the number of cells in r. -// See http://www.unicode.org/reports/tr11/ -func (c *Condition) RuneWidth(r rune) int { - switch { - case r < 0 || r > 0x10FFFF || - inTables(r, nonprint, combining, notassigned): - return 0 - case (c.EastAsianWidth && IsAmbiguousWidth(r)) || - inTables(r, doublewidth, emoji): - return 2 - default: - return 1 - } -} - -// StringWidth return width as you can see -func (c *Condition) StringWidth(s string) (width int) { - for _, r := range []rune(s) { - width += c.RuneWidth(r) - } - return width -} - -// Truncate return string truncated with w cells -func (c *Condition) Truncate(s string, w int, tail string) string { - if c.StringWidth(s) <= w { - return s - } - r := []rune(s) - tw := c.StringWidth(tail) - w -= tw - width := 0 - i := 0 - for ; i < len(r); i++ { - cw := c.RuneWidth(r[i]) - if width+cw > w { - break - } - width += cw - } - return string(r[0:i]) + tail -} - -// Wrap return string wrapped with w cells -func (c *Condition) Wrap(s string, w int) string { - width := 0 - out := "" - for _, r := range []rune(s) { - cw := RuneWidth(r) - if r == '\n' { - out += string(r) - width = 0 - continue - } else if width+cw > w { - out += "\n" - width = 0 - out += string(r) - width += cw - continue - } - out += string(r) - width += cw - } - return out -} - -// FillLeft return string filled in left by spaces in w cells -func (c *Condition) FillLeft(s string, w int) string { - width := c.StringWidth(s) - count := w - width - if count > 0 { - b := make([]byte, count) - for i := range b { - b[i] = ' ' - } - return string(b) + s - } - return s -} - -// FillRight return string filled in left by spaces in w cells -func (c *Condition) FillRight(s string, w int) string { - width := c.StringWidth(s) - count := w - width - if count > 0 { - b := make([]byte, count) - for i := range b { - b[i] = ' ' - } - return s + string(b) - } - return s -} - -// RuneWidth returns the number of cells in r. -// See http://www.unicode.org/reports/tr11/ -func RuneWidth(r rune) int { - return DefaultCondition.RuneWidth(r) -} - -// IsAmbiguousWidth returns whether is ambiguous width or not. -func IsAmbiguousWidth(r rune) bool { - return inTables(r, private, ambiguous) -} - -// IsNeutralWidth returns whether is neutral width or not. -func IsNeutralWidth(r rune) bool { - return inTable(r, neutral) -} - -// StringWidth return width as you can see -func StringWidth(s string) (width int) { - return DefaultCondition.StringWidth(s) -} - -// Truncate return string truncated with w cells -func Truncate(s string, w int, tail string) string { - return DefaultCondition.Truncate(s, w, tail) -} - -// Wrap return string wrapped with w cells -func Wrap(s string, w int) string { - return DefaultCondition.Wrap(s, w) -} - -// FillLeft return string filled in left by spaces in w cells -func FillLeft(s string, w int) string { - return DefaultCondition.FillLeft(s, w) -} - -// FillRight return string filled in left by spaces in w cells -func FillRight(s string, w int) string { - return DefaultCondition.FillRight(s, w) -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go deleted file mode 100644 index 0ce32c5e7..000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_js.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build js - -package runewidth - -func IsEastAsian() bool { - // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. - return false -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go deleted file mode 100644 index c579e9a31..000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build !windows,!js - -package runewidth - -import ( - "os" - "regexp" - "strings" -) - -var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) - -var mblenTable = map[string]int{ - "utf-8": 6, - "utf8": 6, - "jis": 8, - "eucjp": 3, - "euckr": 2, - "euccn": 2, - "sjis": 2, - "cp932": 2, - "cp51932": 2, - "cp936": 2, - "cp949": 2, - "cp950": 2, - "big5": 2, - "gbk": 2, - "gb2312": 2, -} - -func isEastAsian(locale string) bool { - charset := strings.ToLower(locale) - r := reLoc.FindStringSubmatch(locale) - if len(r) == 2 { - charset = strings.ToLower(r[1]) - } - - if strings.HasSuffix(charset, "@cjk_narrow") { - return false - } - - for pos, b := range []byte(charset) { - if b == '@' { - charset = charset[:pos] - break - } - } - max := 1 - if m, ok := mblenTable[charset]; ok { - max = m - } - if max > 1 && (charset[0] != 'u' || - strings.HasPrefix(locale, "ja") || - strings.HasPrefix(locale, "ko") || - strings.HasPrefix(locale, "zh")) { - return true - } - return false -} - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - locale := os.Getenv("LC_CTYPE") - if locale == "" { - locale = os.Getenv("LANG") - } - - // ignore C locale - if locale == "POSIX" || locale == "C" { - return false - } - if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { - return false - } - - return isEastAsian(locale) -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go deleted file mode 100644 index 0258876b9..000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go +++ /dev/null @@ -1,25 +0,0 @@ -package runewidth - -import ( - "syscall" -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32") - procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") -) - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - r1, _, _ := procGetConsoleOutputCP.Call() - if r1 == 0 { - return false - } - - switch int(r1) { - case 932, 51932, 936, 949, 950: - return true - } - - return false -} diff --git a/vendor/vendor.json b/vendor/vendor.json index e536cbb7d..d4d157eb9 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -565,12 +565,6 @@ "path": "github.com/biogo/hts/bgzf", "revision": "50da7d4131a3b5c9d063932461cab4d1fafb20b0" }, - { - "checksumSHA1": "ymc5+iJ+1ipls3ihqPdzMjFYCqo=", - "path": "github.com/cheggaaa/pb", - "revision": "18d384da9bdc1e5a08fc2a62a494c321d9ae74ea", - "revisionTime": "2017-12-14T13:20:59Z" - }, { "checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=", "comment": "v1.0.0-3-g6d21280", @@ -822,12 +816,6 @@ "path": "github.com/hashicorp/yamux", "revision": "df949784da9ed028ee76df44652e42d37a09d7e4" }, - { - "checksumSHA1": "28nznojcl6Ejtm6I1tKozgy0isg=", - "path": "github.com/jlaffaye/ftp", - "revision": "025815df64030c144b86e368fedf80ee195fe464", - "revisionTime": "2016-02-29T21:52:38Z" - }, { "checksumSHA1": "3/Bhy+ua/DCv2ElMD5GzOYSGN6g=", "comment": "0.2.2-2-gc01cf91", @@ -929,12 +917,6 @@ "path": "github.com/mattn/go-isatty", "revision": "56b76bdf51f7708750eac80fa38b952bb9f32639" }, - { - "checksumSHA1": "MNkKJyk2TazKMJYbal5wFHybpyA=", - "path": "github.com/mattn/go-runewidth", - "revision": "14207d285c6c197daabb5c9793d63e7af9ab2d50", - "revisionTime": "2017-02-01T02:35:40Z" - }, { "checksumSHA1": "UP+pXl+ic9y6qrpZA5MqDIAuGfw=", "path": "github.com/mitchellh/cli", @@ -1498,16 +1480,6 @@ "checksumSHA1": "U7dGDNwEHORvJFMoNSXErKE7ITg=", "path": "google.golang.org/cloud/internal", "revision": "5a3b06f8b5da3b7c3a93da43163b872c86c509ef" - }, - { - "checksumSHA1": "gY2M/3SCxqgrPz+P/N6JQ+m/wnA=", - "path": "gopkg.in/xmlpath.v2", - "revision": "860cbeca3ebcc600db0b213c0e83ad6ce91f5739" - }, - { - "checksumSHA1": "0dDWcU08d0FS4d99NCgCkGLjjqw=", - "path": "gopkg.in/xmlpath.v2/cmd/webpath", - "revision": "860cbeca3ebcc600db0b213c0e83ad6ce91f5739" } ], "rootPath": "github.com/hashicorp/packer" From 4a1fb0d26242906229a6b3ab876a1b66feee37f8 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sat, 6 Jan 2018 19:46:52 -0600 Subject: [PATCH 0406/1007] Grrr...gofmt -w common/*.go --- common/config_test.go | 4 ++-- common/download.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/config_test.go b/common/config_test.go index f9b1748ce..bb2889f33 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -197,8 +197,8 @@ func TestDownloadableURL_FilePaths(t *testing.T) { } expected := fmt.Sprintf("%s%s", - filePrefix, - strings.Replace(tfPath, `\`, `/`, -1)) + filePrefix, + strings.Replace(tfPath, `\`, `/`, -1)) if u != expected { t.Fatalf("unexpected: %#v != %#v", u, expected) } diff --git a/common/download.go b/common/download.go index 27e9b32a8..fb7ce5584 100644 --- a/common/download.go +++ b/common/download.go @@ -208,7 +208,7 @@ func (d *DownloadClient) Get() (string, error) { } func (d *DownloadClient) PercentProgress() int { - if (d.downloader == nil) { + if d.downloader == nil { return -1 } From 46a5ca30e5823e5b0c9cbdfafc9ca85da06b14d5 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sat, 6 Jan 2018 19:51:11 -0600 Subject: [PATCH 0407/1007] Removed call to filepath.Rel(...) in builder/vmware/iso/step_create_vmx.go --- builder/vmware/iso/step_create_vmx.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 292a6a6e7..1f4ee812f 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -43,11 +43,6 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction { isoPath := state.Get("iso_path").(string) ui := state.Get("ui").(packer.Ui) - // Convert the iso_path into a path relative to the .vmx file if possible - if relativeIsoPath, err := filepath.Abs(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { - isoPath = relativeIsoPath - } - ui.Say("Building and writing VMX file") vmxTemplate := DefaultVMXTemplate From 3cf448f6ec8b5339619ba6d0435e80d1eee7a8ac Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sat, 6 Jan 2018 20:02:37 -0600 Subject: [PATCH 0408/1007] Reverted previously removed additions of tests that check for ftp:// or nonexistent-protocol:// using DownloadableURL. DownloadableURL's responsibility is not to have inherent knowledge of protocols that are available, but to format an invalid url/path to a valid url/path. --- builder/virtualbox/ovf/config_test.go | 11 ----------- common/config_test.go | 6 ------ 2 files changed, 17 deletions(-) diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index baba657a8..e9c536e54 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -76,17 +76,6 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("Nonexistant file should throw a validation error!") } - // Bad - c = testConfig(t) - c["source_path"] = "nonexistent-protocol://i/dont/exist" - _, warns, err = NewConfig(c) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatalf("should error") - } - // Good tf := getTempFile(t) defer os.Remove(tf.Name()) diff --git a/common/config_test.go b/common/config_test.go index bb2889f33..da93a19ef 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -43,12 +43,6 @@ func TestDownloadableURL(t *testing.T) { t.Fatalf("expected err : %s", err) } - // Invalid: unsupported scheme - _, err = DownloadableURL("nonexistent-protocol://host.com/path") - if err == nil { - t.Fatalf("expected err : %s", err) - } - // Valid: http u, err := DownloadableURL("HTTP://packer.io/path") if err != nil { From c17f827e1d5d82c12e036552148dd70883c2aa03 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 9 Jan 2018 20:08:06 -0600 Subject: [PATCH 0409/1007] Split up DownloadableURL() into it's individual components: SupportedURL(), DownloadableURL(), and ValidatedURL(). Updated all instances of DownloadableURL() to point to ValidatedURL(). Reverted the tests that are based on un-supported protocols. --- .../common/step_download_guest_additions.go | 2 +- builder/virtualbox/ovf/config.go | 2 +- builder/virtualbox/ovf/config_test.go | 11 ++ common/config.go | 111 ++++++++++++------ common/config_test.go | 18 ++- common/download.go | 2 - common/iso_config.go | 2 +- 7 files changed, 102 insertions(+), 46 deletions(-) diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 93f3952c2..d0522e093 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -121,7 +121,7 @@ func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.Ste } // Convert the file/url to an actual URL for step_download to process. - url, err = common.DownloadableURL(url) + url, err = common.ValidatedURL(url) if err != nil { err := fmt.Errorf("Error preparing guest additions url: %s", err) state.Put("error", err) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 41a013ebd..5eef4507c 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -97,7 +97,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { if c.SourcePath == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is required")) } else { - c.SourcePath, err = common.DownloadableURL(c.SourcePath) + c.SourcePath, err = common.ValidatedURL(c.SourcePath) if err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is invalid: %s", err)) } diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index e9c536e54..51412a0c5 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -76,6 +76,17 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("Nonexistant file should throw a validation error!") } + // Bad + c = testConfig(t) + c["source_path"] = "ftp://i/dont/exist" + _, warns, err = NewConfig(c) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err == nil { + t.Fatalf("should error") + } + // Good tf := getTempFile(t) defer os.Remove(tf.Name()) diff --git a/common/config.go b/common/config.go index c8c99a31e..5631e8e5e 100644 --- a/common/config.go +++ b/common/config.go @@ -5,6 +5,7 @@ import ( "net/url" "os" "path/filepath" + "regexp" "strings" "time" ) @@ -42,58 +43,98 @@ func ChooseString(vals ...string) string { return "" } +// SupportedURL verifies that the url passed is actually supported or not +// This will also validate that the protocol is one that's actually implemented. +func SupportedURL(u *url.URL) bool { + // url.Parse shouldn't return nil except on error....but it can. + if u == nil { + return false + } + + // build a dummy NewDownloadClient since this is the only place that valid + // protocols are actually exposed. + cli := NewDownloadClient(&DownloadConfig{}) + + // Iterate through each downloader to see if a protocol was found. + ok := false + for scheme, _ := range cli.config.DownloaderMap { + if strings.ToLower(u.Scheme) == strings.ToLower(scheme) { + ok = true + } + } + return ok +} + // DownloadableURL processes a URL that may also be a file path and returns -// a completely valid URL. For example, the original URL might be "local/file.iso" -// which isn't a valid URL. DownloadableURL will return "file:///local/file.iso" +// a completely valid URL representing the requested file. For example, +// the original URL might be "local/file.iso" which isn't a valid URL, +// and so DownloadableURL will return "file://local/file.iso" +// No other transformations are done to the path. func DownloadableURL(original string) (string, error) { + var result string - // Verify that the scheme is something we support in our common downloader. - supported := []string{"file", "http", "https", "smb"} - found := false - for _, s := range supported { - if strings.HasPrefix(strings.ToLower(original), s+"://") { - found = true - break - } + // Fix the url if it's using bad characters commonly mistaken with a path. + original = filepath.ToSlash(original) + + // Check to see that this is a parseable URL with a scheme. If so, then just pass it through. + if u, err := url.Parse(original); err == nil && u.Scheme != "" && u.Host != "" { + return filepath.ToSlash(original), nil } - // If it's properly prefixed with something we support, then we don't need - // to make it a uri. - if found { - original = filepath.ToSlash(original) - - // make sure that it can be parsed though.. - uri, err := url.Parse(original) + // Since it's not a url, this might be a path. So, check that the file exists, + // then make it an absolute path so we can make a proper uri. + if _, err := os.Stat(original); err == nil { + result, err = filepath.Abs(filepath.FromSlash(original)) if err != nil { return "", err } - uri.Scheme = strings.ToLower(uri.Scheme) - - return uri.String(), nil - } - - // If the file exists, then make it an absolute path - _, err := os.Stat(original) - if err == nil { - original, err = filepath.Abs(filepath.FromSlash(original)) + result, err = filepath.EvalSymlinks(result) if err != nil { return "", err } - original, err = filepath.EvalSymlinks(original) - if err != nil { - return "", err - } + result = filepath.Clean(result) + result = filepath.ToSlash(result) - original = filepath.Clean(original) - original = filepath.ToSlash(original) + // We have no idea what this might be, so we'll leave it as is. + } else { + result = filepath.ToSlash(original) } - // Since it wasn't properly prefixed, let's make it into a well-formed - // file:// uri. + // We should have a path that can just turn into a file:// scheme'd url. + return fmt.Sprintf("file://%s", result), nil +} - return "file://" + original, nil +// Force the parameter into a url. This will transform the parameter into +// a proper url, removing slashes, adding the proper prefix, etc. +func ValidatedURL(original string) (string, error) { + + // See if the user failed to give a url + if ok, _ := regexp.MatchString("(?m)^[^[:punct:]]+://", original); !ok { + + // So since no magic was found, this must be a path. + result, err := DownloadableURL(original) + if err == nil { + return ValidatedURL(result) + } + + return "", err + } + + // Verify that the url is parseable...just in case. + u, err := url.Parse(original) + if err != nil { + return "", err + } + + // We should now have a url, so verify that it's a protocol we support. + if !SupportedURL(u) { + return "", fmt.Errorf("Unsupported protocol scheme! (%#v)", u) + } + + // We should now have a properly formatted and supported url + return u.String(), nil } // FileExistsLocally takes the URL output from DownloadableURL, and determines diff --git a/common/config_test.go b/common/config_test.go index da93a19ef..2eaa5a998 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -36,15 +36,21 @@ func TestChooseString(t *testing.T) { } } -func TestDownloadableURL(t *testing.T) { +func TestValidatedURL(t *testing.T) { // Invalid URL: has hex code in host - _, err := DownloadableURL("http://what%20.com") + _, err := ValidatedURL("http://what%20.com") + if err == nil { + t.Fatalf("expected err : %s", err) + } + + // Invalid: unsupported scheme + _, err = ValidatedURL("ftp://host.com/path") if err == nil { t.Fatalf("expected err : %s", err) } // Valid: http - u, err := DownloadableURL("HTTP://packer.io/path") + u, err := ValidatedURL("HTTP://packer.io/path") if err != nil { t.Fatalf("err: %s", err) } @@ -69,7 +75,7 @@ func TestDownloadableURL(t *testing.T) { } for _, tc := range cases { - u, err := DownloadableURL(tc.InputString) + u, err := ValidatedURL(tc.InputString) if u != tc.OutputURL { t.Fatal(fmt.Sprintf("Error with URL %s: got %s but expected %s", tc.InputString, tc.OutputURL, u)) @@ -77,11 +83,11 @@ func TestDownloadableURL(t *testing.T) { if (err != nil) != tc.ErrExpected { if tc.ErrExpected == true { t.Fatal(fmt.Sprintf("Error with URL %s: we expected "+ - "DownloadableURL to return an error but didn't get one.", + "ValidatedURL to return an error but didn't get one.", tc.InputString)) } else { t.Fatal(fmt.Sprintf("Error with URL %s: we did not expect an "+ - " error from DownloadableURL but we got: %s", + " error from ValidatedURL but we got: %s", tc.InputString, err)) } } diff --git a/common/download.go b/common/download.go index fb7ce5584..6d3d2a685 100644 --- a/common/download.go +++ b/common/download.go @@ -86,8 +86,6 @@ func NewDownloadClient(c *DownloadConfig) *DownloadClient { // Create downloader map if it hasn't been specified already. if c.DownloaderMap == nil { - // XXX: Make sure you add any new protocols you implement - // to the DownloadableURL implementation in config.go! c.DownloaderMap = map[string]Downloader{ "file": &FileDownloader{bufferSize: nil}, "http": &HTTPDownloader{userAgent: c.UserAgent}, diff --git a/common/iso_config.go b/common/iso_config.go index 5216dc458..e5a1e4e90 100644 --- a/common/iso_config.go +++ b/common/iso_config.go @@ -111,7 +111,7 @@ func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs [ c.ISOChecksum = strings.ToLower(c.ISOChecksum) for i, url := range c.ISOUrls { - url, err := DownloadableURL(url) + url, err := ValidatedURL(url) if err != nil { errs = append( errs, fmt.Errorf("Failed to parse iso_url %d: %s", i+1, err)) From 50e9cd2ca75c9387113cea136ca06b29fae098cf Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 16 Jan 2018 13:46:27 -0600 Subject: [PATCH 0410/1007] Initial fixes of common/config.go after rebase before refactoring of test-cases so that they don't require root to run. --- common/config.go | 1 + common/config_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/common/config.go b/common/config.go index 5631e8e5e..c79710221 100644 --- a/common/config.go +++ b/common/config.go @@ -8,6 +8,7 @@ import ( "regexp" "strings" "time" + "runtime" ) // PackerKeyEnv is used to specify the key interval (delay) between keystrokes diff --git a/common/config_test.go b/common/config_test.go index 2eaa5a998..af26aeefa 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -7,6 +7,7 @@ import ( "path/filepath" "strings" "testing" + "runtime" ) func TestChooseString(t *testing.T) { From 20f9ef344535e786d6eef2be462dd792f3ac8e14 Mon Sep 17 00:00:00 2001 From: stack72 <public@paulstack.co.uk> Date: Tue, 16 Jan 2018 19:48:25 +0200 Subject: [PATCH 0411/1007] builder/triton: bump triton-go dependencies This introduces a new triton-go errors package so we can error handle our code in a better way --- builder/triton/driver_triton.go | 4 +- .../github.com/joyent/triton-go/CHANGELOG.md | 6 + .../github.com/joyent/triton-go/GNUmakefile | 5 +- vendor/github.com/joyent/triton-go/Gopkg.lock | 14 +- vendor/github.com/joyent/triton-go/Gopkg.toml | 12 +- .../joyent/triton-go/authentication/dummy.go | 8 + .../authentication/ecdsa_signature.go | 12 +- .../authentication/private_key_signer.go | 19 +- .../triton-go/authentication/rsa_signature.go | 8 + .../triton-go/authentication/signature.go | 10 +- .../joyent/triton-go/authentication/signer.go | 8 + .../authentication/ssh_agent_signer.go | 33 +- .../triton-go/authentication/test_signer.go | 8 + .../joyent/triton-go/authentication/util.go | 8 + .../joyent/triton-go/client/client.go | 132 ++++---- .../joyent/triton-go/client/errors.go | 190 ----------- .../joyent/triton-go/compute/client.go | 14 + .../joyent/triton-go/compute/datacenters.go | 56 ++-- .../joyent/triton-go/compute/errors.go | 121 ------- .../joyent/triton-go/compute/images.go | 64 ++-- .../joyent/triton-go/compute/instances.go | 271 ++++++++-------- .../joyent/triton-go/compute/packages.go | 28 +- .../joyent/triton-go/compute/ping.go | 30 +- .../joyent/triton-go/compute/services.go | 20 +- .../joyent/triton-go/compute/snapshots.go | 49 +-- .../joyent/triton-go/compute/volumes.go | 217 +++++++++++++ .../joyent/triton-go/errors/errors.go | 297 ++++++++++++++++++ .../joyent/triton-go/network/client.go | 8 + .../joyent/triton-go/network/fabrics.go | 86 ++--- .../joyent/triton-go/network/firewall.go | 83 ++--- .../joyent/triton-go/network/network.go | 28 +- vendor/github.com/joyent/triton-go/triton.go | 8 + vendor/github.com/joyent/triton-go/version.go | 32 ++ vendor/github.com/pkg/errors/LICENSE | 23 ++ vendor/github.com/pkg/errors/README.md | 52 +++ vendor/github.com/pkg/errors/appveyor.yml | 32 ++ vendor/github.com/pkg/errors/errors.go | 269 ++++++++++++++++ vendor/github.com/pkg/errors/stack.go | 187 +++++++++++ vendor/vendor.json | 42 ++- 39 files changed, 1738 insertions(+), 756 deletions(-) delete mode 100644 vendor/github.com/joyent/triton-go/client/errors.go delete mode 100644 vendor/github.com/joyent/triton-go/compute/errors.go create mode 100644 vendor/github.com/joyent/triton-go/compute/volumes.go create mode 100644 vendor/github.com/joyent/triton-go/errors/errors.go create mode 100644 vendor/github.com/joyent/triton-go/version.go create mode 100644 vendor/github.com/pkg/errors/LICENSE create mode 100644 vendor/github.com/pkg/errors/README.md create mode 100644 vendor/github.com/pkg/errors/appveyor.yml create mode 100644 vendor/github.com/pkg/errors/errors.go create mode 100644 vendor/github.com/pkg/errors/stack.go diff --git a/builder/triton/driver_triton.go b/builder/triton/driver_triton.go index 5e6acffef..58d943216 100644 --- a/builder/triton/driver_triton.go +++ b/builder/triton/driver_triton.go @@ -8,8 +8,8 @@ import ( "time" "github.com/hashicorp/packer/packer" - "github.com/joyent/triton-go/client" "github.com/joyent/triton-go/compute" + terrors "github.com/joyent/triton-go/errors" ) type driverTriton struct { @@ -177,7 +177,7 @@ func (d *driverTriton) WaitForMachineDeletion(machineId string, timeout time.Dur // 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 triErr, ok := err.(*client.TritonError); ok && triErr.StatusCode == http.StatusGone { + if terrors.IsSpecificStatusCode(err, http.StatusGone) { return true, nil } } diff --git a/vendor/github.com/joyent/triton-go/CHANGELOG.md b/vendor/github.com/joyent/triton-go/CHANGELOG.md index c0d740998..7b2df2e8a 100644 --- a/vendor/github.com/joyent/triton-go/CHANGELOG.md +++ b/vendor/github.com/joyent/triton-go/CHANGELOG.md @@ -1,5 +1,11 @@ ## Unreleased +- Add support for managing columes in Triton [#100] +- identity/policies: Add support for managing policies in Triton [#86] +- addition of triton-go errors package to expose unwraping of internal errors +- Migration from hashicorp/errwrap to pkg/errors +- Using path.Join() for URL structures rather than fmt.Sprintf() + ## 0.5.2 (December 28) - Standardise the API SSH Signers input casing and naming diff --git a/vendor/github.com/joyent/triton-go/GNUmakefile b/vendor/github.com/joyent/triton-go/GNUmakefile index cca7f6759..f996b9951 100644 --- a/vendor/github.com/joyent/triton-go/GNUmakefile +++ b/vendor/github.com/joyent/triton-go/GNUmakefile @@ -12,9 +12,8 @@ tools:: ## Download and install all dev/code tools go test -i $(TEST) || exit 1 test:: ## Run unit tests - @echo "==> Running unit tests" - @echo $(TEST) | \ - xargs -t go test -v $(TESTARGS) -timeout=30s -parallel=1 | grep -Ev 'TRITON_TEST|TestAcc' + @echo "==> Running unit test with coverage" + @./scripts/go-test-with-coverage.sh testacc:: ## Run acceptance tests @echo "==> Running acceptance tests" diff --git a/vendor/github.com/joyent/triton-go/Gopkg.lock b/vendor/github.com/joyent/triton-go/Gopkg.lock index b61936ad3..858574604 100644 --- a/vendor/github.com/joyent/triton-go/Gopkg.lock +++ b/vendor/github.com/joyent/triton-go/Gopkg.lock @@ -7,17 +7,11 @@ packages = ["."] revision = "d5467c17e7afe8d8f08f556c6c811a50c3feb28d" -[[projects]] - name = "github.com/davecgh/go-spew" - packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" - [[projects]] branch = "master" - name = "github.com/hashicorp/errwrap" + name = "github.com/pkg/errors" packages = ["."] - revision = "7554cd9344cec97297fa6649b055a8c98c2a1e55" + revision = "e881fd58d78e04cf6d0de1217f8707c8cc2249bc" [[projects]] branch = "master" @@ -29,11 +23,11 @@ branch = "master" name = "golang.org/x/crypto" packages = ["curve25519","ed25519","ed25519/internal/edwards25519","ssh","ssh/agent"] - revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8" + revision = "0fcca4842a8d74bfddc2c96a073bd2a4d2a7a2e8" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "28853a8970ee33112a9e7998b18e658bed04d177537ec69db678189f0b8a9a7d" + inputs-digest = "f7efd974ae38e2ee077c4d2698df74128a04797460b5f9c833853ddfaa86a0a0" solver-name = "gps-cdcl" solver-version = 1 diff --git a/vendor/github.com/joyent/triton-go/Gopkg.toml b/vendor/github.com/joyent/triton-go/Gopkg.toml index 3b85ddf9b..3d3f322e6 100644 --- a/vendor/github.com/joyent/triton-go/Gopkg.toml +++ b/vendor/github.com/joyent/triton-go/Gopkg.toml @@ -25,14 +25,6 @@ branch = "master" name = "github.com/abdullin/seq" -[[constraint]] - name = "github.com/davecgh/go-spew" - version = "1.1.0" - -[[constraint]] - branch = "master" - name = "github.com/hashicorp/errwrap" - [[constraint]] branch = "master" name = "github.com/sean-/seed" @@ -40,3 +32,7 @@ [[constraint]] branch = "master" name = "golang.org/x/crypto" + +[[constraint]] + branch = "master" + name = "github.com/pkg/errors" diff --git a/vendor/github.com/joyent/triton-go/authentication/dummy.go b/vendor/github.com/joyent/triton-go/authentication/dummy.go index cd16273b6..797e0047b 100644 --- a/vendor/github.com/joyent/triton-go/authentication/dummy.go +++ b/vendor/github.com/joyent/triton-go/authentication/dummy.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication // DON'T USE THIS OUTSIDE TESTING ~ This key was only created to use for diff --git a/vendor/github.com/joyent/triton-go/authentication/ecdsa_signature.go b/vendor/github.com/joyent/triton-go/authentication/ecdsa_signature.go index 8aaba97a5..7fb5a5ab8 100644 --- a/vendor/github.com/joyent/triton-go/authentication/ecdsa_signature.go +++ b/vendor/github.com/joyent/triton-go/authentication/ecdsa_signature.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication import ( @@ -6,7 +14,7 @@ import ( "fmt" "math/big" - "github.com/hashicorp/errwrap" + "github.com/pkg/errors" "golang.org/x/crypto/ssh" ) @@ -44,7 +52,7 @@ func newECDSASignature(signatureBlob []byte) (*ecdsaSignature, error) { } if err := ssh.Unmarshal(signatureBlob, &ecSig); err != nil { - return nil, errwrap.Wrapf("Error unmarshaling signature: {{err}}", err) + return nil, errors.Wrap(err, "unable to unmarshall signature") } rValue := ecSig.R.Bytes() diff --git a/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go b/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go index 35abff0f6..6e5a67331 100644 --- a/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/private_key_signer.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication import ( @@ -7,12 +15,11 @@ import ( "crypto/x509" "encoding/base64" "encoding/pem" - "errors" "fmt" "path" "strings" - "github.com/hashicorp/errwrap" + "github.com/pkg/errors" "golang.org/x/crypto/ssh" ) @@ -44,12 +51,12 @@ func NewPrivateKeySigner(input PrivateKeySignerInput) (*PrivateKeySigner, error) rsakey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { - return nil, errwrap.Wrapf("Error parsing private key: {{err}}", err) + return nil, errors.Wrap(err, "unable to parse private key") } sshPublicKey, err := ssh.NewPublicKey(rsakey.Public()) if err != nil { - return nil, errwrap.Wrapf("Error parsing SSH key from private key: {{err}}", err) + return nil, errors.Wrap(err, "unable to parse SSH key from private key") } matchKeyFingerprint := formatPublicKeyFingerprint(sshPublicKey, false) @@ -89,7 +96,7 @@ func (s *PrivateKeySigner) Sign(dateHeader string) (string, error) { signed, err := rsa.SignPKCS1v15(rand.Reader, s.privateKey, s.hashFunc, digest) if err != nil { - return "", errwrap.Wrapf("Error signing date header: {{err}}", err) + return "", errors.Wrap(err, "unable to sign date header") } signedBase64 := base64.StdEncoding.EncodeToString(signed) @@ -110,7 +117,7 @@ func (s *PrivateKeySigner) SignRaw(toSign string) (string, string, error) { signed, err := rsa.SignPKCS1v15(rand.Reader, s.privateKey, s.hashFunc, digest) if err != nil { - return "", "", errwrap.Wrapf("Error signing date header: {{err}}", err) + return "", "", errors.Wrap(err, "unable to sign date header") } signedBase64 := base64.StdEncoding.EncodeToString(signed) return signedBase64, "rsa-sha1", nil diff --git a/vendor/github.com/joyent/triton-go/authentication/rsa_signature.go b/vendor/github.com/joyent/triton-go/authentication/rsa_signature.go index 8d513f6c4..81b735eb1 100644 --- a/vendor/github.com/joyent/triton-go/authentication/rsa_signature.go +++ b/vendor/github.com/joyent/triton-go/authentication/rsa_signature.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication import ( diff --git a/vendor/github.com/joyent/triton-go/authentication/signature.go b/vendor/github.com/joyent/triton-go/authentication/signature.go index e6a52df30..8cc18d964 100644 --- a/vendor/github.com/joyent/triton-go/authentication/signature.go +++ b/vendor/github.com/joyent/triton-go/authentication/signature.go @@ -1,8 +1,16 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication import ( - "regexp" "fmt" + "regexp" ) type httpAuthSignature interface { diff --git a/vendor/github.com/joyent/triton-go/authentication/signer.go b/vendor/github.com/joyent/triton-go/authentication/signer.go index 6e3d31dd7..f1e114194 100644 --- a/vendor/github.com/joyent/triton-go/authentication/signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/signer.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication const authorizationHeaderFormat = `Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"` diff --git a/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go b/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go index c068dae27..304e7fb3b 100644 --- a/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/ssh_agent_signer.go @@ -1,23 +1,30 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication import ( "crypto/md5" "crypto/sha256" "encoding/base64" - "errors" "fmt" "net" "os" "path" "strings" - "github.com/hashicorp/errwrap" + pkgerrors "github.com/pkg/errors" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) var ( - ErrUnsetEnvVar = errors.New("SSH_AUTH_SOCK is not set") + ErrUnsetEnvVar = pkgerrors.New("environment variable SSH_AUTH_SOCK not set") ) type SSHAgentSigner struct { @@ -46,7 +53,7 @@ func NewSSHAgentSigner(input SSHAgentSignerInput) (*SSHAgentSigner, error) { conn, err := net.Dial("unix", sshAgentAddress) if err != nil { - return nil, errwrap.Wrapf("Error dialing SSH agent: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to dial SSH agent") } ag := agent.NewClient(conn) @@ -82,7 +89,7 @@ func NewSSHAgentSigner(input SSHAgentSignerInput) (*SSHAgentSigner, error) { func (s *SSHAgentSigner) MatchKey() (ssh.PublicKey, error) { keys, err := s.agent.List() if err != nil { - return nil, errwrap.Wrapf("Error listing keys in SSH Agent: %s", err) + return nil, pkgerrors.Wrap(err, "unable to list keys in SSH Agent") } keyFingerprintStripped := strings.TrimPrefix(s.keyFingerprint, "MD5:") @@ -116,12 +123,12 @@ func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) { signature, err := s.agent.Sign(s.key, []byte(fmt.Sprintf("%s: %s", headerName, dateHeader))) if err != nil { - return "", errwrap.Wrapf("Error signing date header: {{err}}", err) + return "", pkgerrors.Wrap(err, "unable to sign date header") } keyFormat, err := keyFormatToKeyType(signature.Format) if err != nil { - return "", errwrap.Wrapf("Error reading signature: {{err}}", err) + return "", pkgerrors.Wrap(err, "unable to format signature") } var authSignature httpAuthSignature @@ -129,12 +136,12 @@ func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) { case "rsa": authSignature, err = newRSASignature(signature.Blob) if err != nil { - return "", errwrap.Wrapf("Error reading signature: {{err}}", err) + return "", pkgerrors.Wrap(err, "unable to read RSA signature") } case "ecdsa": authSignature, err = newECDSASignature(signature.Blob) if err != nil { - return "", errwrap.Wrapf("Error reading signature: {{err}}", err) + return "", pkgerrors.Wrap(err, "unable to read ECDSA signature") } default: return "", fmt.Errorf("Unsupported algorithm from SSH agent: %s", signature.Format) @@ -147,12 +154,12 @@ func (s *SSHAgentSigner) Sign(dateHeader string) (string, error) { func (s *SSHAgentSigner) SignRaw(toSign string) (string, string, error) { signature, err := s.agent.Sign(s.key, []byte(toSign)) if err != nil { - return "", "", errwrap.Wrapf("Error signing string: {{err}}", err) + return "", "", pkgerrors.Wrap(err, "unable to sign string") } keyFormat, err := keyFormatToKeyType(signature.Format) if err != nil { - return "", "", errwrap.Wrapf("Error reading signature: {{err}}", err) + return "", "", pkgerrors.Wrap(err, "unable to format key") } var authSignature httpAuthSignature @@ -160,12 +167,12 @@ func (s *SSHAgentSigner) SignRaw(toSign string) (string, string, error) { case "rsa": authSignature, err = newRSASignature(signature.Blob) if err != nil { - return "", "", errwrap.Wrapf("Error reading signature: {{err}}", err) + return "", "", pkgerrors.Wrap(err, "unable to read RSA signature") } case "ecdsa": authSignature, err = newECDSASignature(signature.Blob) if err != nil { - return "", "", errwrap.Wrapf("Error reading signature: {{err}}", err) + return "", "", pkgerrors.Wrap(err, "unable to read ECDSA signature") } default: return "", "", fmt.Errorf("Unsupported algorithm from SSH agent: %s", signature.Format) diff --git a/vendor/github.com/joyent/triton-go/authentication/test_signer.go b/vendor/github.com/joyent/triton-go/authentication/test_signer.go index a9c2c82d5..4ccfd3847 100644 --- a/vendor/github.com/joyent/triton-go/authentication/test_signer.go +++ b/vendor/github.com/joyent/triton-go/authentication/test_signer.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication // TestSigner represents an authentication key signer which we can use for diff --git a/vendor/github.com/joyent/triton-go/authentication/util.go b/vendor/github.com/joyent/triton-go/authentication/util.go index 7c298b68c..95918439f 100644 --- a/vendor/github.com/joyent/triton-go/authentication/util.go +++ b/vendor/github.com/joyent/triton-go/authentication/util.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package authentication import ( diff --git a/vendor/github.com/joyent/triton-go/client/client.go b/vendor/github.com/joyent/triton-go/client/client.go index cccf3a25d..0d8bc8931 100644 --- a/vendor/github.com/joyent/triton-go/client/client.go +++ b/vendor/github.com/joyent/triton-go/client/client.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package client import ( @@ -5,7 +13,6 @@ import ( "context" "crypto/tls" "encoding/json" - "errors" "fmt" "io" "net" @@ -14,19 +21,21 @@ import ( "os" "time" - "github.com/hashicorp/errwrap" + "github.com/joyent/triton-go" "github.com/joyent/triton-go/authentication" + "github.com/joyent/triton-go/errors" + pkgerrors "github.com/pkg/errors" ) const nilContext = "nil context" var ( - ErrDefaultAuth = errors.New("default SSH agent authentication requires SDC_KEY_ID / TRITON_KEY_ID and SSH_AUTH_SOCK") - ErrAccountName = errors.New("missing account name for Triton/Manta") - ErrMissingURL = errors.New("missing Triton and/or Manta URL") + ErrDefaultAuth = pkgerrors.New("default SSH agent authentication requires SDC_KEY_ID / TRITON_KEY_ID and SSH_AUTH_SOCK") + ErrAccountName = pkgerrors.New("missing account name") + ErrMissingURL = pkgerrors.New("missing API URL") - BadTritonURL = "invalid format of triton URL" - BadMantaURL = "invalid format of manta URL" + InvalidTritonURL = "invalid format of Triton URL" + InvalidMantaURL = "invalid format of Manta URL" ) // Client represents a connection to the Triton Compute or Object Storage APIs. @@ -55,12 +64,12 @@ func New(tritonURL string, mantaURL string, accountName string, signers ...authe cloudURL, err := url.Parse(tritonURL) if err != nil { - return nil, errwrap.Wrapf(BadTritonURL+": {{err}}", err) + return nil, pkgerrors.Wrapf(err, InvalidTritonURL) } storageURL, err := url.Parse(mantaURL) if err != nil { - return nil, errwrap.Wrapf(BadMantaURL+": {{err}}", err) + return nil, pkgerrors.Wrapf(err, InvalidMantaURL) } authorizers := make([]authentication.Signer, 0) @@ -124,7 +133,7 @@ func (c *Client) DefaultAuth() error { } defaultSigner, err := authentication.NewSSHAgentSigner(input) if err != nil { - return errwrap.Wrapf("problem initializing NewSSHAgentSigner: {{err}}", err) + return pkgerrors.Wrapf(err, "unable to initialize NewSSHAgentSigner") } c.Authorizers = append(c.Authorizers, defaultSigner) } @@ -164,19 +173,20 @@ func doNotFollowRedirects(*http.Request, []*http.Request) error { return http.ErrUseLastResponse } -// TODO(justinwr): Deprecated? -// func (c *Client) FormatURL(path string) string { -// return fmt.Sprintf("%s%s", c.Endpoint, path) -// } - -func (c *Client) DecodeError(statusCode int, body io.Reader) error { - err := &TritonError{ - StatusCode: statusCode, +func (c *Client) DecodeError(resp *http.Response, requestMethod string) error { + err := &errors.APIError{ + StatusCode: resp.StatusCode, } - errorDecoder := json.NewDecoder(body) - if err := errorDecoder.Decode(err); err != nil { - return errwrap.Wrapf("Error decoding error response: {{err}}", err) + if requestMethod != http.MethodHead && resp.Body != nil { + errorDecoder := json.NewDecoder(resp.Body) + if err := errorDecoder.Decode(err); err != nil { + return pkgerrors.Wrapf(err, "unable to decode error response") + } + } + + if err.Message == "" { + err.Message = fmt.Sprintf("HTTP response returned status code %d", err.StatusCode) } return err @@ -215,7 +225,7 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu req, err := http.NewRequest(method, endpoint.String(), requestBody) if err != nil { - return nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + return nil, pkgerrors.Wrapf(err, "unable to construct HTTP request") } dateHeader := time.Now().UTC().Format(time.RFC1123) @@ -225,12 +235,12 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu // outside that constructor). authHeader, err := c.Authorizers[0].Sign(dateHeader) if err != nil { - return nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + return nil, pkgerrors.Wrapf(err, "unable to sign HTTP request") } req.Header.Set("Authorization", authHeader) req.Header.Set("Accept", "application/json") - req.Header.Set("Accept-Version", "8") - req.Header.Set("User-Agent", "triton-go Client API") + req.Header.Set("Accept-Version", triton.CloudAPIMajorVersion) + req.Header.Set("User-Agent", triton.UserAgent()) if body != nil { req.Header.Set("Content-Type", "application/json") @@ -238,14 +248,16 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu resp, err := c.HTTPClient.Do(req.WithContext(ctx)) if err != nil { - return nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + return nil, pkgerrors.Wrapf(err, "unable to execute HTTP request") } + // We will only return a response from the API it is in the HTTP StatusCode 2xx range + // StatusMultipleChoices is StatusCode 300 if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { return resp.Body, nil } - return nil, c.DecodeError(resp.StatusCode, resp.Body) + return nil, c.DecodeError(resp, req.Method) } func (c *Client) ExecuteRequest(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) { @@ -271,7 +283,7 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h req, err := http.NewRequest(method, endpoint.String(), requestBody) if err != nil { - return nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + return nil, pkgerrors.Wrapf(err, "unable to construct HTTP request") } dateHeader := time.Now().UTC().Format(time.RFC1123) @@ -281,12 +293,12 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h // outside that constructor). authHeader, err := c.Authorizers[0].Sign(dateHeader) if err != nil { - return nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + return nil, pkgerrors.Wrapf(err, "unable to sign HTTP request") } req.Header.Set("Authorization", authHeader) req.Header.Set("Accept", "application/json") - req.Header.Set("Accept-Version", "8") - req.Header.Set("User-Agent", "triton-go c API") + req.Header.Set("Accept-Version", triton.CloudAPIMajorVersion) + req.Header.Set("User-Agent", triton.UserAgent()) if body != nil { req.Header.Set("Content-Type", "application/json") @@ -294,10 +306,16 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h resp, err := c.HTTPClient.Do(req.WithContext(ctx)) if err != nil { - return nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + return nil, pkgerrors.Wrapf(err, "unable to execute HTTP request") } - return resp, nil + // We will only return a response from the API it is in the HTTP StatusCode 2xx range + // StatusMultipleChoices is StatusCode 300 + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + return resp, nil + } + + return nil, c.DecodeError(resp, req.Method) } func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) (io.ReadCloser, http.Header, error) { @@ -321,7 +339,7 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) req, err := http.NewRequest(method, endpoint.String(), requestBody) if err != nil { - return nil, nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + return nil, nil, pkgerrors.Wrapf(err, "unable to construct HTTP request") } if body != nil && (headers == nil || headers.Get("Content-Type") == "") { @@ -340,11 +358,11 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) authHeader, err := c.Authorizers[0].Sign(dateHeader) if err != nil { - return nil, nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + return nil, nil, pkgerrors.Wrapf(err, "unable to sign HTTP request") } req.Header.Set("Authorization", authHeader) req.Header.Set("Accept", "*/*") - req.Header.Set("User-Agent", "manta-go client API") + req.Header.Set("User-Agent", triton.UserAgent()) if query != nil { req.URL.RawQuery = query.Encode() @@ -352,29 +370,16 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) resp, err := c.HTTPClient.Do(req.WithContext(ctx)) if err != nil { - return nil, nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + return nil, nil, pkgerrors.Wrapf(err, "unable to execute HTTP request") } + // We will only return a response from the API it is in the HTTP StatusCode 2xx range + // StatusMultipleChoices is StatusCode 300 if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { return resp.Body, resp.Header, nil } - mantaError := &MantaError{ - StatusCode: resp.StatusCode, - } - - if req.Method != http.MethodHead { - errorDecoder := json.NewDecoder(resp.Body) - if err := errorDecoder.Decode(mantaError); err != nil { - return nil, nil, errwrap.Wrapf("Error decoding error response: {{err}}", err) - } - } - - if mantaError.Message == "" { - mantaError.Message = fmt.Sprintf("HTTP response returned status code %d", resp.StatusCode) - } - - return nil, nil, mantaError + return nil, nil, c.DecodeError(resp, req.Method) } type RequestNoEncodeInput struct { @@ -397,7 +402,7 @@ func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEnc req, err := http.NewRequest(method, endpoint.String(), body) if err != nil { - return nil, nil, errwrap.Wrapf("Error constructing HTTP request: {{err}}", err) + return nil, nil, pkgerrors.Wrapf(err, "unable to construct HTTP request") } if headers != nil { @@ -413,11 +418,12 @@ func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEnc authHeader, err := c.Authorizers[0].Sign(dateHeader) if err != nil { - return nil, nil, errwrap.Wrapf("Error signing HTTP request: {{err}}", err) + return nil, nil, pkgerrors.Wrapf(err, "unable to sign HTTP request") } req.Header.Set("Authorization", authHeader) req.Header.Set("Accept", "*/*") - req.Header.Set("User-Agent", "manta-go client API") + req.Header.Set("Accept-Version", triton.CloudAPIMajorVersion) + req.Header.Set("User-Agent", triton.UserAgent()) if query != nil { req.URL.RawQuery = query.Encode() @@ -425,20 +431,14 @@ func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEnc resp, err := c.HTTPClient.Do(req.WithContext(ctx)) if err != nil { - return nil, nil, errwrap.Wrapf("Error executing HTTP request: {{err}}", err) + return nil, nil, pkgerrors.Wrapf(err, "unable to execute HTTP request") } + // We will only return a response from the API it is in the HTTP StatusCode 2xx range + // StatusMultipleChoices is StatusCode 300 if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { return resp.Body, resp.Header, nil } - mantaError := &MantaError{ - StatusCode: resp.StatusCode, - } - - errorDecoder := json.NewDecoder(resp.Body) - if err := errorDecoder.Decode(mantaError); err != nil { - return nil, nil, errwrap.Wrapf("Error decoding error response: {{err}}", err) - } - return nil, nil, mantaError + return nil, nil, c.DecodeError(resp, req.Method) } diff --git a/vendor/github.com/joyent/triton-go/client/errors.go b/vendor/github.com/joyent/triton-go/client/errors.go deleted file mode 100644 index 1fc64a095..000000000 --- a/vendor/github.com/joyent/triton-go/client/errors.go +++ /dev/null @@ -1,190 +0,0 @@ -package client - -import ( - "fmt" - - "github.com/hashicorp/errwrap" -) - -// ClientError represents an error code and message along with the status code -// of the HTTP request which resulted in the error message. -type ClientError struct { - StatusCode int - Code string - Message string -} - -// Error implements interface Error on the TritonError type. -func (e ClientError) Error() string { - return fmt.Sprintf("%s: %s", e.Code, e.Message) -} - -// MantaError represents an error code and message along with -// the status code of the HTTP request which resulted in the error -// message. Error codes used by the Manta API are listed at -// https://apidocs.joyent.com/manta/api.html#errors -type MantaError struct { - StatusCode int - Code string `json:"code"` - Message string `json:"message"` -} - -// Error implements interface Error on the MantaError type. -func (e MantaError) Error() string { - return fmt.Sprintf("%s: %s", e.Code, e.Message) -} - -// TritonError represents an error code and message along with -// the status code of the HTTP request which resulted in the error -// message. Error codes used by the Triton API are listed at -// https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses -type TritonError struct { - StatusCode int - Code string `json:"code"` - Message string `json:"message"` -} - -// Error implements interface Error on the TritonError type. -func (e TritonError) Error() string { - return fmt.Sprintf("%s: %s", e.Code, e.Message) -} - -func IsAuthSchemeError(err error) bool { - return isSpecificError(err, "AuthScheme") -} -func IsAuthorizationError(err error) bool { - return isSpecificError(err, "Authorization") -} -func IsBadRequestError(err error) bool { - return isSpecificError(err, "BadRequest") -} -func IsChecksumError(err error) bool { - return isSpecificError(err, "Checksum") -} -func IsConcurrentRequestError(err error) bool { - return isSpecificError(err, "ConcurrentRequest") -} -func IsContentLengthError(err error) bool { - return isSpecificError(err, "ContentLength") -} -func IsContentMD5MismatchError(err error) bool { - return isSpecificError(err, "ContentMD5Mismatch") -} -func IsEntityExistsError(err error) bool { - return isSpecificError(err, "EntityExists") -} -func IsInvalidArgumentError(err error) bool { - return isSpecificError(err, "InvalidArgument") -} -func IsInvalidAuthTokenError(err error) bool { - return isSpecificError(err, "InvalidAuthToken") -} -func IsInvalidCredentialsError(err error) bool { - return isSpecificError(err, "InvalidCredentials") -} -func IsInvalidDurabilityLevelError(err error) bool { - return isSpecificError(err, "InvalidDurabilityLevel") -} -func IsInvalidKeyIdError(err error) bool { - return isSpecificError(err, "InvalidKeyId") -} -func IsInvalidJobError(err error) bool { - return isSpecificError(err, "InvalidJob") -} -func IsInvalidLinkError(err error) bool { - return isSpecificError(err, "InvalidLink") -} -func IsInvalidLimitError(err error) bool { - return isSpecificError(err, "InvalidLimit") -} -func IsInvalidSignatureError(err error) bool { - return isSpecificError(err, "InvalidSignature") -} -func IsInvalidUpdateError(err error) bool { - return isSpecificError(err, "InvalidUpdate") -} -func IsDirectoryDoesNotExistError(err error) bool { - return isSpecificError(err, "DirectoryDoesNotExist") -} -func IsDirectoryExistsError(err error) bool { - return isSpecificError(err, "DirectoryExists") -} -func IsDirectoryNotEmptyError(err error) bool { - return isSpecificError(err, "DirectoryNotEmpty") -} -func IsDirectoryOperationError(err error) bool { - return isSpecificError(err, "DirectoryOperation") -} -func IsInternalError(err error) bool { - return isSpecificError(err, "Internal") -} -func IsJobNotFoundError(err error) bool { - return isSpecificError(err, "JobNotFound") -} -func IsJobStateError(err error) bool { - return isSpecificError(err, "JobState") -} -func IsKeyDoesNotExistError(err error) bool { - return isSpecificError(err, "KeyDoesNotExist") -} -func IsNotAcceptableError(err error) bool { - return isSpecificError(err, "NotAcceptable") -} -func IsNotEnoughSpaceError(err error) bool { - return isSpecificError(err, "NotEnoughSpace") -} -func IsLinkNotFoundError(err error) bool { - return isSpecificError(err, "LinkNotFound") -} -func IsLinkNotObjectError(err error) bool { - return isSpecificError(err, "LinkNotObject") -} -func IsLinkRequiredError(err error) bool { - return isSpecificError(err, "LinkRequired") -} -func IsParentNotDirectoryError(err error) bool { - return isSpecificError(err, "ParentNotDirectory") -} -func IsPreconditionFailedError(err error) bool { - return isSpecificError(err, "PreconditionFailed") -} -func IsPreSignedRequestError(err error) bool { - return isSpecificError(err, "PreSignedRequest") -} -func IsRequestEntityTooLargeError(err error) bool { - return isSpecificError(err, "RequestEntityTooLarge") -} -func IsResourceNotFoundError(err error) bool { - return isSpecificError(err, "ResourceNotFound") -} -func IsRootDirectoryError(err error) bool { - return isSpecificError(err, "RootDirectory") -} -func IsServiceUnavailableError(err error) bool { - return isSpecificError(err, "ServiceUnavailable") -} -func IsSSLRequiredError(err error) bool { - return isSpecificError(err, "SSLRequired") -} -func IsUploadTimeoutError(err error) bool { - return isSpecificError(err, "UploadTimeout") -} -func IsUserDoesNotExistError(err error) bool { - return isSpecificError(err, "UserDoesNotExist") -} - -// isSpecificError checks whether the error represented by err wraps -// an underlying MantaError with code errorCode. -func isSpecificError(err error, errorCode string) bool { - tritonErrorInterface := errwrap.GetType(err.(error), &MantaError{}) - if tritonErrorInterface == nil { - return false - } - - tritonErr := tritonErrorInterface.(*MantaError) - if tritonErr.Code == errorCode { - return true - } - - return false -} diff --git a/vendor/github.com/joyent/triton-go/compute/client.go b/vendor/github.com/joyent/triton-go/compute/client.go index 73582e2ae..c70daef8c 100644 --- a/vendor/github.com/joyent/triton-go/compute/client.go +++ b/vendor/github.com/joyent/triton-go/compute/client.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( @@ -61,3 +69,9 @@ func (c *ComputeClient) Services() *ServicesClient { func (c *ComputeClient) Snapshots() *SnapshotsClient { return &SnapshotsClient{c.Client} } + +// Snapshots returns a Compute client used for accessing functions pertaining to +// Snapshots functionality in the Triton API. +func (c *ComputeClient) Volumes() *VolumesClient { + return &VolumesClient{c.Client} +} diff --git a/vendor/github.com/joyent/triton-go/compute/datacenters.go b/vendor/github.com/joyent/triton-go/compute/datacenters.go index 365474e17..9f22cffbb 100644 --- a/vendor/github.com/joyent/triton-go/compute/datacenters.go +++ b/vendor/github.com/joyent/triton-go/compute/datacenters.go @@ -1,16 +1,24 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( + "context" "encoding/json" - "errors" "fmt" "net/http" + "path" "sort" - "context" - - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/joyent/triton-go/errors" + pkgerrors "github.com/pkg/errors" ) type DataCentersClient struct { @@ -25,23 +33,24 @@ type DataCenter struct { type ListDataCentersInput struct{} func (c *DataCentersClient) List(ctx context.Context, _ *ListDataCentersInput) ([]*DataCenter, error) { - path := fmt.Sprintf("/%s/datacenters", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "datacenters") + reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to list data centers") } var intermediate map[string]string decoder := json.NewDecoder(respReader) if err = decoder.Decode(&intermediate); err != nil { - return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode list data centers response") } keys := make([]string, len(intermediate)) @@ -70,28 +79,23 @@ type GetDataCenterInput struct { } func (c *DataCentersClient) Get(ctx context.Context, input *GetDataCenterInput) (*DataCenter, error) { - path := fmt.Sprintf("/%s/datacenters/%s", c.client.AccountName, input.Name) - reqInputs := client.RequestInput{ - Method: http.MethodGet, - Path: path, - } - resp, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + dcs, err := c.List(ctx, &ListDataCentersInput{}) if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to get data center") } - if resp.StatusCode != http.StatusFound { - return nil, fmt.Errorf("Error executing Get request: expected status code 302, got %d", - resp.StatusCode) + for _, dc := range dcs { + if dc.Name == input.Name { + return &DataCenter{ + Name: input.Name, + URL: dc.URL, + }, nil + } } - location := resp.Header.Get("Location") - if location == "" { - return nil, errors.New("Error decoding Get response: no Location header") + return nil, &errors.APIError{ + StatusCode: http.StatusNotFound, + Code: "ResourceNotFound", + Message: fmt.Sprintf("data center %q not found", input.Name), } - - return &DataCenter{ - Name: input.Name, - URL: location, - }, nil } diff --git a/vendor/github.com/joyent/triton-go/compute/errors.go b/vendor/github.com/joyent/triton-go/compute/errors.go deleted file mode 100644 index db31472ff..000000000 --- a/vendor/github.com/joyent/triton-go/compute/errors.go +++ /dev/null @@ -1,121 +0,0 @@ -package compute - -import ( - "github.com/hashicorp/errwrap" - "github.com/joyent/triton-go/client" -) - -// IsBadRequest tests whether err wraps a client.TritonError with -// code BadRequest -func IsBadRequest(err error) bool { - return isSpecificError(err, "BadRequest") -} - -// IsInternalError tests whether err wraps a client.TritonError with -// code InternalError -func IsInternalError(err error) bool { - return isSpecificError(err, "InternalError") -} - -// IsInUseError tests whether err wraps a client.TritonError with -// code InUseError -func IsInUseError(err error) bool { - return isSpecificError(err, "InUseError") -} - -// IsInvalidArgument tests whether err wraps a client.TritonError with -// code InvalidArgument -func IsInvalidArgument(err error) bool { - return isSpecificError(err, "InvalidArgument") -} - -// IsInvalidCredentials tests whether err wraps a client.TritonError with -// code InvalidCredentials -func IsInvalidCredentials(err error) bool { - return isSpecificError(err, "InvalidCredentials") -} - -// IsInvalidHeader tests whether err wraps a client.TritonError with -// code InvalidHeader -func IsInvalidHeader(err error) bool { - return isSpecificError(err, "InvalidHeader") -} - -// IsInvalidVersion tests whether err wraps a client.TritonError with -// code InvalidVersion -func IsInvalidVersion(err error) bool { - return isSpecificError(err, "InvalidVersion") -} - -// IsMissingParameter tests whether err wraps a client.TritonError with -// code MissingParameter -func IsMissingParameter(err error) bool { - return isSpecificError(err, "MissingParameter") -} - -// IsNotAuthorized tests whether err wraps a client.TritonError with -// code NotAuthorized -func IsNotAuthorized(err error) bool { - return isSpecificError(err, "NotAuthorized") -} - -// IsRequestThrottled tests whether err wraps a client.TritonError with -// code RequestThrottled -func IsRequestThrottled(err error) bool { - return isSpecificError(err, "RequestThrottled") -} - -// IsRequestTooLarge tests whether err wraps a client.TritonError with -// code RequestTooLarge -func IsRequestTooLarge(err error) bool { - return isSpecificError(err, "RequestTooLarge") -} - -// IsRequestMoved tests whether err wraps a client.TritonError with -// code RequestMoved -func IsRequestMoved(err error) bool { - return isSpecificError(err, "RequestMoved") -} - -// IsResourceFound tests whether err wraps a client.TritonError with code ResourceFound -func IsResourceFound(err error) bool { - return isSpecificError(err, "ResourceFound") -} - -// IsResourceNotFound tests whether err wraps a client.TritonError with -// code ResourceNotFound -func IsResourceNotFound(err error) bool { - return isSpecificError(err, "ResourceNotFound") -} - -// IsUnknownError tests whether err wraps a client.TritonError with -// code UnknownError -func IsUnknownError(err error) bool { - return isSpecificError(err, "UnknownError") -} - -// IsEmptyResponse tests whether err wraps a client.TritonError with code -// EmptyResponse -func IsEmptyResponse(err error) bool { - return isSpecificError(err, "EmptyResponse") -} - -// isSpecificError checks whether the error represented by err wraps -// an underlying client.TritonError with code errorCode. -func isSpecificError(err error, errorCode string) bool { - if err == nil { - return false - } - - tritonErrorInterface := errwrap.GetType(err.(error), &client.TritonError{}) - if tritonErrorInterface == nil { - return false - } - - tritonErr := tritonErrorInterface.(*client.TritonError) - if tritonErr.Code == errorCode { - return true - } - - return false -} diff --git a/vendor/github.com/joyent/triton-go/compute/images.go b/vendor/github.com/joyent/triton-go/compute/images.go index b60f05e53..8dcae0a89 100644 --- a/vendor/github.com/joyent/triton-go/compute/images.go +++ b/vendor/github.com/joyent/triton-go/compute/images.go @@ -1,15 +1,23 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( "context" "encoding/json" - "fmt" "net/http" "net/url" + "path" "time" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type ImagesClient struct { @@ -39,7 +47,6 @@ type Image struct { Tags map[string]string `json:"tags"` EULA string `json:"eula"` ACL []string `json:"acl"` - Error client.TritonError `json:"error"` } type ListImagesInput struct { @@ -53,7 +60,7 @@ type ListImagesInput struct { } func (c *ImagesClient) List(ctx context.Context, input *ListImagesInput) ([]*Image, error) { - path := fmt.Sprintf("/%s/images", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "images") query := &url.Values{} if input.Name != "" { @@ -80,7 +87,7 @@ func (c *ImagesClient) List(ctx context.Context, input *ListImagesInput) ([]*Ima reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, Query: query, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -88,13 +95,13 @@ func (c *ImagesClient) List(ctx context.Context, input *ListImagesInput) ([]*Ima defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list images") } var result []*Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list images response") } return result, nil @@ -105,23 +112,23 @@ type GetImageInput struct { } func (c *ImagesClient) Get(ctx context.Context, input *GetImageInput) (*Image, error) { - path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) + fullPath := path.Join("/", c.client.AccountName, "images", input.ImageID) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get image") } var result *Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get image response") } return result, nil @@ -132,17 +139,17 @@ type DeleteImageInput struct { } func (c *ImagesClient) Delete(ctx context.Context, input *DeleteImageInput) error { - path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) + fullPath := path.Join("/", c.client.AccountName, "images", input.ImageID) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Delete request: {{err}}", err) + return errors.Wrap(err, "unable to delete image") } return nil @@ -160,14 +167,13 @@ type MantaLocation struct { } func (c *ImagesClient) Export(ctx context.Context, input *ExportImageInput) (*MantaLocation, error) { - path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) + fullPath := path.Join("/", c.client.AccountName, "images", input.ImageID) query := &url.Values{} query.Set("action", "export") - query.Set("manta_path", input.MantaPath) reqInputs := client.RequestInput{ - Method: http.MethodGet, - Path: path, + Method: http.MethodPost, + Path: fullPath, Query: query, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -175,13 +181,13 @@ func (c *ImagesClient) Export(ctx context.Context, input *ExportImageInput) (*Ma defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + return nil, errors.Wrap(err, "unable to export image") } var result *MantaLocation decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode export image response") } return result, nil @@ -199,10 +205,10 @@ type CreateImageFromMachineInput struct { } func (c *ImagesClient) CreateFromMachine(ctx context.Context, input *CreateImageFromMachineInput) (*Image, error) { - path := fmt.Sprintf("/%s/images", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "images") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -210,13 +216,13 @@ func (c *ImagesClient) CreateFromMachine(ctx context.Context, input *CreateImage defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing CreateFromMachine request: {{err}}", err) + return nil, errors.Wrap(err, "unable to create machine from image") } var result *Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateFromMachine response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode create machine from image response") } return result, nil @@ -224,7 +230,7 @@ func (c *ImagesClient) CreateFromMachine(ctx context.Context, input *CreateImage type UpdateImageInput struct { ImageID string `json:"-"` - Name string `json:"name"` + Name string `json:"name,omitempty"` Version string `json:"version,omitempty"` Description string `json:"description,omitempty"` HomePage string `json:"homepage,omitempty"` @@ -234,13 +240,13 @@ type UpdateImageInput struct { } func (c *ImagesClient) Update(ctx context.Context, input *UpdateImageInput) (*Image, error) { - path := fmt.Sprintf("/%s/images/%s", c.client.AccountName, input.ImageID) + fullPath := path.Join("/", c.client.AccountName, "images", input.ImageID) query := &url.Values{} query.Set("action", "update") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: query, Body: input, } @@ -249,13 +255,13 @@ func (c *ImagesClient) Update(ctx context.Context, input *UpdateImageInput) (*Im defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Update request: {{err}}", err) + return nil, errors.Wrap(err, "unable to update image") } var result *Image decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Update response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode update image response") } return result, nil diff --git a/vendor/github.com/joyent/triton-go/compute/instances.go b/vendor/github.com/joyent/triton-go/compute/instances.go index 9be14bb21..eae65804e 100644 --- a/vendor/github.com/joyent/triton-go/compute/instances.go +++ b/vendor/github.com/joyent/triton-go/compute/instances.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( @@ -7,11 +15,13 @@ import ( "io/ioutil" "net/http" "net/url" + "path" "strings" "time" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/joyent/triton-go/errors" + pkgerrors "github.com/pkg/errors" ) type InstancesClient struct { @@ -33,6 +43,13 @@ type InstanceCNS struct { Services []string } +type InstanceVolume struct { + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Mode string `json:"mode,omitempty"` + Mountpoint string `json:"mountpoint,omitempty"` +} + type Instance struct { ID string `json:"id"` Name string `json:"name"` @@ -88,41 +105,40 @@ func (gmi *GetInstanceInput) Validate() error { func (c *InstancesClient) Get(ctx context.Context, input *GetInstanceInput) (*Instance, error) { if err := input.Validate(); err != nil { - return nil, errwrap.Wrapf("unable to get machine: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to get machine") } - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) if response == nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to get machine") } if response.Body != nil { defer response.Body.Close() } if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { - return nil, &client.TritonError{ + return nil, &errors.APIError{ StatusCode: response.StatusCode, Code: "ResourceNotFound", } } if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", - c.client.DecodeError(response.StatusCode, response.Body)) + return nil, pkgerrors.Wrap(err, "unable to get machine") } var result *_Instance decoder := json.NewDecoder(response.Body) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode get machine response") } native, err := result.toNative() if err != nil { - return nil, errwrap.Wrapf("unable to convert API response for instances to native type: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode get machine response") } return native, nil @@ -144,7 +160,7 @@ type ListInstancesInput struct { } func (c *InstancesClient) List(ctx context.Context, input *ListInstancesInput) ([]*Instance, error) { - path := fmt.Sprintf("/%s/machines", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "machines") query := &url.Values{} if input.Brand != "" { @@ -180,25 +196,25 @@ func (c *InstancesClient) List(ctx context.Context, input *ListInstancesInput) ( reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, Query: query, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if err != nil { - return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to list machines") } var results []*_Instance decoder := json.NewDecoder(respReader) if err = decoder.Decode(&results); err != nil { - return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode list machines response") } machines := make([]*Instance, 0, len(results)) for _, machineAPI := range results { native, err := machineAPI.toNative() if err != nil { - return nil, errwrap.Wrapf("unable to convert API response for instances to native type: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode list machines response") } machines = append(machines, native) } @@ -219,6 +235,7 @@ type CreateInstanceInput struct { Tags map[string]string FirewallEnabled bool CNS InstanceCNS + Volumes []InstanceVolume } func (input *CreateInstanceInput) toAPI() (map[string]interface{}, error) { @@ -243,6 +260,10 @@ func (input *CreateInstanceInput) toAPI() (map[string]interface{}, error) { result["networks"] = input.Networks } + if len(input.Volumes) > 0 { + result["volumes"] = input.Volumes + } + // validate that affinity and locality are not included together hasAffinity := len(input.Affinity) > 0 hasLocality := len(input.LocalityNear) > 0 || len(input.LocalityFar) > 0 @@ -286,15 +307,15 @@ func (input *CreateInstanceInput) toAPI() (map[string]interface{}, error) { } func (c *InstancesClient) Create(ctx context.Context, input *CreateInstanceInput) (*Instance, error) { - path := fmt.Sprintf("/%s/machines", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "machines") body, err := input.toAPI() if err != nil { - return nil, errwrap.Wrapf("Error preparing Create request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to prepare for machine creation") } reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: body, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -302,13 +323,13 @@ func (c *InstancesClient) Create(ctx context.Context, input *CreateInstanceInput defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Create request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to create machine") } var result *Instance decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Create response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode create machine response") } return result, nil @@ -319,14 +340,14 @@ type DeleteInstanceInput struct { } func (c *InstancesClient) Delete(ctx context.Context, input *DeleteInstanceInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) if response == nil { - return fmt.Errorf("Delete request has empty response") + return pkgerrors.Wrap(err, "unable to delete machine") } if response.Body != nil { defer response.Body.Close() @@ -335,8 +356,7 @@ func (c *InstancesClient) Delete(ctx context.Context, input *DeleteInstanceInput return nil } if err != nil { - return errwrap.Wrapf("Error executing Delete request: {{err}}", - c.client.DecodeError(response.StatusCode, response.Body)) + return pkgerrors.Wrap(err, "unable to decode delete machine response") } return nil @@ -347,12 +367,15 @@ type DeleteTagsInput struct { } func (c *InstancesClient) DeleteTags(ctx context.Context, input *DeleteTagsInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "tags") reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return pkgerrors.Wrap(err, "unable to delete tags from machine") + } if response == nil { return fmt.Errorf("DeleteTags request has empty response") } @@ -362,10 +385,6 @@ func (c *InstancesClient) DeleteTags(ctx context.Context, input *DeleteTagsInput if response.StatusCode == http.StatusNotFound { return nil } - if err != nil { - return errwrap.Wrapf("Error executing DeleteTags request: {{err}}", - c.client.DecodeError(response.StatusCode, response.Body)) - } return nil } @@ -376,12 +395,15 @@ type DeleteTagInput struct { } func (c *InstancesClient) DeleteTag(ctx context.Context, input *DeleteTagInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags/%s", c.client.AccountName, input.ID, input.Key) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "tags", input.Key) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return pkgerrors.Wrap(err, "unable to delete tag from machine") + } if response == nil { return fmt.Errorf("DeleteTag request has empty response") } @@ -391,10 +413,6 @@ func (c *InstancesClient) DeleteTag(ctx context.Context, input *DeleteTagInput) if response.StatusCode == http.StatusNotFound { return nil } - if err != nil { - return errwrap.Wrapf("Error executing DeleteTag request: {{err}}", - c.client.DecodeError(response.StatusCode, response.Body)) - } return nil } @@ -405,7 +423,7 @@ type RenameInstanceInput struct { } func (c *InstancesClient) Rename(ctx context.Context, input *RenameInstanceInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID) params := &url.Values{} params.Set("action", "rename") @@ -413,7 +431,7 @@ func (c *InstancesClient) Rename(ctx context.Context, input *RenameInstanceInput reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -421,7 +439,7 @@ func (c *InstancesClient) Rename(ctx context.Context, input *RenameInstanceInput defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Rename request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to rename machine") } return nil @@ -445,10 +463,10 @@ func (input ReplaceTagsInput) toAPI() map[string]interface{} { } func (c *InstancesClient) ReplaceTags(ctx context.Context, input *ReplaceTagsInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "tags") reqInputs := client.RequestInput{ Method: http.MethodPut, - Path: path, + Path: fullPath, Body: input.toAPI(), } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -456,7 +474,7 @@ func (c *InstancesClient) ReplaceTags(ctx context.Context, input *ReplaceTagsInp defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing ReplaceTags request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to replace machine tags") } return nil @@ -468,10 +486,10 @@ type AddTagsInput struct { } func (c *InstancesClient) AddTags(ctx context.Context, input *AddTagsInput) error { - path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "tags") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input.Tags, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -479,7 +497,7 @@ func (c *InstancesClient) AddTags(ctx context.Context, input *AddTagsInput) erro defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing AddTags request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to add tags to machine") } return nil @@ -491,23 +509,23 @@ type GetTagInput struct { } func (c *InstancesClient) GetTag(ctx context.Context, input *GetTagInput) (string, error) { - path := fmt.Sprintf("/%s/machines/%s/tags/%s", c.client.AccountName, input.ID, input.Key) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "tags", input.Key) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if err != nil { + return "", pkgerrors.Wrap(err, "unable to get tag") + } if respReader != nil { defer respReader.Close() } - if err != nil { - return "", errwrap.Wrapf("Error executing GetTag request: {{err}}", err) - } var result string decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return "", errwrap.Wrapf("Error decoding GetTag response: {{err}}", err) + return "", pkgerrors.Wrap(err, "unable to decode get tag response") } return result, nil @@ -518,23 +536,23 @@ type ListTagsInput struct { } func (c *InstancesClient) ListTags(ctx context.Context, input *ListTagsInput) (map[string]interface{}, error) { - path := fmt.Sprintf("/%s/machines/%s/tags", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "tags") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListTags request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to list machine tags") } var result map[string]interface{} decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListTags response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable decode list machine tags response") } _, tags := tagsExtractMeta(result) @@ -552,30 +570,28 @@ func (c *InstancesClient) GetMetadata(ctx context.Context, input *GetMetadataInp return "", fmt.Errorf("Missing metadata Key from input: %s", input.Key) } - path := fmt.Sprintf("/%s/machines/%s/metadata/%s", c.client.AccountName, input.ID, input.Key) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "metadata", input.Key) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return "", pkgerrors.Wrap(err, "unable to get machine metadata") + } if response != nil { defer response.Body.Close() } if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { - return "", &client.TritonError{ + return "", &errors.APIError{ StatusCode: response.StatusCode, Code: "ResourceNotFound", } } - if err != nil { - return "", errwrap.Wrapf("Error executing Get request: {{err}}", - c.client.DecodeError(response.StatusCode, response.Body)) - } body, err := ioutil.ReadAll(response.Body) if err != nil { - return "", errwrap.Wrapf("Error unwrapping request body: {{err}}", - c.client.DecodeError(response.StatusCode, response.Body)) + return "", pkgerrors.Wrap(err, "unable to decode get machine metadata response") } return fmt.Sprintf("%s", body), nil @@ -587,7 +603,7 @@ type ListMetadataInput struct { } func (c *InstancesClient) ListMetadata(ctx context.Context, input *ListMetadataInput) (map[string]string, error) { - path := fmt.Sprintf("/%s/machines/%s/metadata", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "metadata") query := &url.Values{} if input.Credentials { @@ -596,7 +612,7 @@ func (c *InstancesClient) ListMetadata(ctx context.Context, input *ListMetadataI reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, Query: query, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -604,13 +620,13 @@ func (c *InstancesClient) ListMetadata(ctx context.Context, input *ListMetadataI defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListMetadata request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to list machine metadata") } var result map[string]string decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListMetadata response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode list machine metadata response") } return result, nil @@ -622,10 +638,10 @@ type UpdateMetadataInput struct { } func (c *InstancesClient) UpdateMetadata(ctx context.Context, input *UpdateMetadataInput) (map[string]string, error) { - path := fmt.Sprintf("/%s/machines/%s/metadata", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "metadata") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input.Metadata, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -633,13 +649,13 @@ func (c *InstancesClient) UpdateMetadata(ctx context.Context, input *UpdateMetad defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateMetadata request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to update machine metadata") } var result map[string]string decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateMetadata response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode update machine metadata response") } return result, nil @@ -656,18 +672,18 @@ func (c *InstancesClient) DeleteMetadata(ctx context.Context, input *DeleteMetad return fmt.Errorf("Missing metadata Key from input: %s", input.Key) } - path := fmt.Sprintf("/%s/machines/%s/metadata/%s", c.client.AccountName, input.ID, input.Key) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "metadata", input.Key) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if err != nil { + return pkgerrors.Wrap(err, "unable to delete machine metadata") + } if respReader != nil { defer respReader.Close() } - if err != nil { - return errwrap.Wrapf("Error executing DeleteMetadata request: {{err}}", err) - } return nil } @@ -678,18 +694,18 @@ type DeleteAllMetadataInput struct { // DeleteAllMetadata deletes all metadata keys from this instance func (c *InstancesClient) DeleteAllMetadata(ctx context.Context, input *DeleteAllMetadataInput) error { - path := fmt.Sprintf("/%s/machines/%s/metadata", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID, "metadata") reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) + if err != nil { + return pkgerrors.Wrap(err, "unable to delete all machine metadata") + } if respReader != nil { defer respReader.Close() } - if err != nil { - return errwrap.Wrapf("Error executing DeleteAllMetadata request: {{err}}", err) - } return nil } @@ -700,7 +716,7 @@ type ResizeInstanceInput struct { } func (c *InstancesClient) Resize(ctx context.Context, input *ResizeInstanceInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID) params := &url.Values{} params.Set("action", "resize") @@ -708,7 +724,7 @@ func (c *InstancesClient) Resize(ctx context.Context, input *ResizeInstanceInput reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -716,7 +732,7 @@ func (c *InstancesClient) Resize(ctx context.Context, input *ResizeInstanceInput defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Resize request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to resize machine") } return nil @@ -727,14 +743,14 @@ type EnableFirewallInput struct { } func (c *InstancesClient) EnableFirewall(ctx context.Context, input *EnableFirewallInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID) params := &url.Values{} params.Set("action", "enable_firewall") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -742,7 +758,7 @@ func (c *InstancesClient) EnableFirewall(ctx context.Context, input *EnableFirew defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing EnableFirewall request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to enable machine firewall") } return nil @@ -753,14 +769,14 @@ type DisableFirewallInput struct { } func (c *InstancesClient) DisableFirewall(ctx context.Context, input *DisableFirewallInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.ID) params := &url.Values{} params.Set("action", "disable_firewall") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -768,7 +784,7 @@ func (c *InstancesClient) DisableFirewall(ctx context.Context, input *DisableFir defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing DisableFirewall request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to disable machine firewall") } return nil @@ -779,23 +795,23 @@ type ListNICsInput struct { } func (c *InstancesClient) ListNICs(ctx context.Context, input *ListNICsInput) ([]*NIC, error) { - path := fmt.Sprintf("/%s/machines/%s/nics", c.client.AccountName, input.InstanceID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID, "nics") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListNICs request: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to list machine NICs") } var result []*NIC decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListNICs response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode list machine NICs response") } return result, nil @@ -808,30 +824,30 @@ type GetNICInput struct { func (c *InstancesClient) GetNIC(ctx context.Context, input *GetNICInput) (*NIC, error) { mac := strings.Replace(input.MAC, ":", "", -1) - path := fmt.Sprintf("/%s/machines/%s/nics/%s", c.client.AccountName, input.InstanceID, mac) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID, "nics", mac) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return nil, pkgerrors.Wrap(err, "unable to get machine NIC") + } if response != nil { defer response.Body.Close() } switch response.StatusCode { case http.StatusNotFound: - return nil, &client.TritonError{ + return nil, &errors.APIError{ StatusCode: response.StatusCode, Code: "ResourceNotFound", } } - if err != nil { - return nil, errwrap.Wrapf("Error executing GetNIC request: {{err}}", err) - } var result *NIC decoder := json.NewDecoder(response.Body) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListNICs response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode get machine NIC response") } return result, nil @@ -848,32 +864,32 @@ type AddNICInput struct { // until its state is set to "running". Only one NIC per network may exist. // Warning: this operation causes the instance to restart. func (c *InstancesClient) AddNIC(ctx context.Context, input *AddNICInput) (*NIC, error) { - path := fmt.Sprintf("/%s/machines/%s/nics", c.client.AccountName, input.InstanceID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID, "nics") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return nil, pkgerrors.Wrap(err, "unable to add NIC to machine") + } if response != nil { defer response.Body.Close() } switch response.StatusCode { case http.StatusFound: - return nil, &client.TritonError{ + return nil, &errors.APIError{ StatusCode: response.StatusCode, Code: "ResourceFound", Message: response.Header.Get("Location"), } } - if err != nil { - return nil, errwrap.Wrapf("Error executing AddNIC request: {{err}}", err) - } var result *NIC decoder := json.NewDecoder(response.Body) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding AddNIC response: {{err}}", err) + return nil, pkgerrors.Wrap(err, "unable to decode add NIC to machine response") } return result, nil @@ -890,25 +906,28 @@ type RemoveNICInput struct { // machine to restart. func (c *InstancesClient) RemoveNIC(ctx context.Context, input *RemoveNICInput) error { mac := strings.Replace(input.MAC, ":", "", -1) - path := fmt.Sprintf("/%s/machines/%s/nics/%s", c.client.AccountName, input.InstanceID, mac) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID, "nics", mac) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } response, err := c.client.ExecuteRequestRaw(ctx, reqInputs) - if response != nil { + if err != nil { + return pkgerrors.Wrap(err, "unable to remove NIC from machine") + } + if response == nil { + return pkgerrors.Wrap(err, "unable to remove NIC from machine") + } + if response.Body != nil { defer response.Body.Close() } switch response.StatusCode { case http.StatusNotFound: - return &client.TritonError{ + return &errors.APIError{ StatusCode: response.StatusCode, Code: "ResourceNotFound", } } - if err != nil { - return errwrap.Wrapf("Error executing RemoveNIC request: {{err}}", err) - } return nil } @@ -918,14 +937,14 @@ type StopInstanceInput struct { } func (c *InstancesClient) Stop(ctx context.Context, input *StopInstanceInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.InstanceID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID) params := &url.Values{} params.Set("action", "stop") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -933,7 +952,7 @@ func (c *InstancesClient) Stop(ctx context.Context, input *StopInstanceInput) er defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Stop request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to stop machine") } return nil @@ -944,14 +963,14 @@ type StartInstanceInput struct { } func (c *InstancesClient) Start(ctx context.Context, input *StartInstanceInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.InstanceID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID) params := &url.Values{} params.Set("action", "start") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -959,7 +978,7 @@ func (c *InstancesClient) Start(ctx context.Context, input *StartInstanceInput) defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Start request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to start machine") } return nil @@ -970,14 +989,14 @@ type RebootInstanceInput struct { } func (c *InstancesClient) Reboot(ctx context.Context, input *RebootInstanceInput) error { - path := fmt.Sprintf("/%s/machines/%s", c.client.AccountName, input.InstanceID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.InstanceID) params := &url.Values{} params.Set("action", "reboot") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Query: params, } respReader, err := c.client.ExecuteRequestURIParams(ctx, reqInputs) @@ -985,7 +1004,7 @@ func (c *InstancesClient) Reboot(ctx context.Context, input *RebootInstanceInput defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Start request: {{err}}", err) + return pkgerrors.Wrap(err, "unable to reboot machine") } return nil diff --git a/vendor/github.com/joyent/triton-go/compute/packages.go b/vendor/github.com/joyent/triton-go/compute/packages.go index f18407e45..e3bfb3cbe 100644 --- a/vendor/github.com/joyent/triton-go/compute/packages.go +++ b/vendor/github.com/joyent/triton-go/compute/packages.go @@ -1,13 +1,21 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( "context" "encoding/json" - "fmt" "net/http" + "path" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type PackagesClient struct { @@ -40,10 +48,10 @@ type ListPackagesInput struct { } func (c *PackagesClient) List(ctx context.Context, input *ListPackagesInput) ([]*Package, error) { - path := fmt.Sprintf("/%s/packages", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "packages") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -51,13 +59,13 @@ func (c *PackagesClient) List(ctx context.Context, input *ListPackagesInput) ([] defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list packages") } var result []*Package decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list packages response") } return result, nil @@ -68,23 +76,23 @@ type GetPackageInput struct { } func (c *PackagesClient) Get(ctx context.Context, input *GetPackageInput) (*Package, error) { - path := fmt.Sprintf("/%s/packages/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "packages", input.ID) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get package") } var result *Package decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get package response") } return result, nil diff --git a/vendor/github.com/joyent/triton-go/compute/ping.go b/vendor/github.com/joyent/triton-go/compute/ping.go index c0f62dfaa..f346e5c26 100644 --- a/vendor/github.com/joyent/triton-go/compute/ping.go +++ b/vendor/github.com/joyent/triton-go/compute/ping.go @@ -1,13 +1,20 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( "context" "encoding/json" - "fmt" "net/http" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + pkgerrors "github.com/pkg/errors" ) const pingEndpoint = "/--ping" @@ -29,27 +36,22 @@ func (c *ComputeClient) Ping(ctx context.Context) (*PingOutput, error) { Path: pingEndpoint, } response, err := c.Client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return nil, pkgerrors.Wrap(err, "unable to ping") + } if response == nil { - return nil, fmt.Errorf("Ping request has empty response") + return nil, pkgerrors.Wrap(err, "unable to ping") } if response.Body != nil { defer response.Body.Close() } - if response.StatusCode == http.StatusNotFound || response.StatusCode == http.StatusGone { - return nil, &client.TritonError{ - StatusCode: response.StatusCode, - Code: "ResourceNotFound", - } - } - if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", - c.Client.DecodeError(response.StatusCode, response.Body)) - } var result *PingOutput decoder := json.NewDecoder(response.Body) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + if err != nil { + return nil, pkgerrors.Wrap(err, "unable to decode ping response") + } } return result, nil diff --git a/vendor/github.com/joyent/triton-go/compute/services.go b/vendor/github.com/joyent/triton-go/compute/services.go index af1b017e0..3597da9b1 100644 --- a/vendor/github.com/joyent/triton-go/compute/services.go +++ b/vendor/github.com/joyent/triton-go/compute/services.go @@ -1,14 +1,22 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( "context" "encoding/json" - "fmt" "net/http" + "path" "sort" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type ServicesClient struct { @@ -23,23 +31,23 @@ type Service struct { type ListServicesInput struct{} func (c *ServicesClient) List(ctx context.Context, _ *ListServicesInput) ([]*Service, error) { - path := fmt.Sprintf("/%s/services", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "services") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list services") } var intermediate map[string]string decoder := json.NewDecoder(respReader) if err = decoder.Decode(&intermediate); err != nil { - return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list services response") } keys := make([]string, len(intermediate)) diff --git a/vendor/github.com/joyent/triton-go/compute/snapshots.go b/vendor/github.com/joyent/triton-go/compute/snapshots.go index 72873ad39..f30d394ba 100644 --- a/vendor/github.com/joyent/triton-go/compute/snapshots.go +++ b/vendor/github.com/joyent/triton-go/compute/snapshots.go @@ -1,15 +1,22 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package compute import ( "context" "encoding/json" - "fmt" "net/http" - + "path" "time" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type SnapshotsClient struct { @@ -28,23 +35,23 @@ type ListSnapshotsInput struct { } func (c *SnapshotsClient) List(ctx context.Context, input *ListSnapshotsInput) ([]*Snapshot, error) { - path := fmt.Sprintf("/%s/machines/%s/snapshots", c.client.AccountName, input.MachineID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.MachineID, "snapshots") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing List request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list snapshots") } var result []*Snapshot decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding List response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list snapshots response") } return result, nil @@ -56,23 +63,23 @@ type GetSnapshotInput struct { } func (c *SnapshotsClient) Get(ctx context.Context, input *GetSnapshotInput) (*Snapshot, error) { - path := fmt.Sprintf("/%s/machines/%s/snapshots/%s", c.client.AccountName, input.MachineID, input.Name) + fullPath := path.Join("/", c.client.AccountName, "machines", input.MachineID, "snapshots", input.Name) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Get request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get snapshot") } var result *Snapshot decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Get response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get snapshot response") } return result, nil @@ -84,17 +91,17 @@ type DeleteSnapshotInput struct { } func (c *SnapshotsClient) Delete(ctx context.Context, input *DeleteSnapshotInput) error { - path := fmt.Sprintf("/%s/machines/%s/snapshots/%s", c.client.AccountName, input.MachineID, input.Name) + fullPath := path.Join("/", c.client.AccountName, "machines", input.MachineID, "snapshots", input.Name) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing Delete request: {{err}}", err) + return errors.Wrap(err, "unable to delete snapshot") } return nil @@ -106,17 +113,17 @@ type StartMachineFromSnapshotInput struct { } func (c *SnapshotsClient) StartMachine(ctx context.Context, input *StartMachineFromSnapshotInput) error { - path := fmt.Sprintf("/%s/machines/%s/snapshots/%s", c.client.AccountName, input.MachineID, input.Name) + fullPath := path.Join("/", c.client.AccountName, "machines", input.MachineID, "snapshots", input.Name) reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing StartMachine request: {{err}}", err) + return errors.Wrap(err, "unable to start machine") } return nil @@ -128,14 +135,14 @@ type CreateSnapshotInput struct { } func (c *SnapshotsClient) Create(ctx context.Context, input *CreateSnapshotInput) (*Snapshot, error) { - path := fmt.Sprintf("/%s/machines/%s/snapshots", c.client.AccountName, input.MachineID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.MachineID, "snapshots") data := make(map[string]interface{}) data["name"] = input.Name reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: data, } @@ -144,13 +151,13 @@ func (c *SnapshotsClient) Create(ctx context.Context, input *CreateSnapshotInput defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing Create request: {{err}}", err) + return nil, errors.Wrap(err, "unable to create snapshot") } var result *Snapshot decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding Create response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode create snapshot response") } return result, nil diff --git a/vendor/github.com/joyent/triton-go/compute/volumes.go b/vendor/github.com/joyent/triton-go/compute/volumes.go new file mode 100644 index 000000000..af858061f --- /dev/null +++ b/vendor/github.com/joyent/triton-go/compute/volumes.go @@ -0,0 +1,217 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + +package compute + +import ( + "context" + "encoding/json" + "net/http" + "net/url" + "path" + + "github.com/joyent/triton-go/client" + "github.com/pkg/errors" +) + +type VolumesClient struct { + client *client.Client +} + +type Volume struct { + ID string `json:"id"` + Name string `json:"name"` + Owner string `json:"owner_uuid"` + Type string `json:"type"` + FileSystemPath string `json:"filesystem_path"` + Size int64 `json:"size"` + State string `json:"state"` + Networks []string `json:"networks"` + Refs []string `json:"refs"` +} + +type ListVolumesInput struct { + Name string + Size string + State string + Type string +} + +func (c *VolumesClient) List(ctx context.Context, input *ListVolumesInput) ([]*Volume, error) { + fullPath := path.Join("/", c.client.AccountName, "volumes") + + query := &url.Values{} + if input.Name != "" { + query.Set("name", input.Name) + } + if input.Size != "" { + query.Set("size", input.Size) + } + if input.State != "" { + query.Set("state", input.State) + } + if input.Type != "" { + query.Set("type", input.Type) + } + + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: fullPath, + Query: query, + } + resp, err := c.client.ExecuteRequest(ctx, reqInputs) + if resp != nil { + defer resp.Close() + } + if err != nil { + return nil, errors.Wrap(err, "unable to list volumes") + } + + var result []*Volume + decoder := json.NewDecoder(resp) + if err = decoder.Decode(&result); err != nil { + return nil, errors.Wrap(err, "unable to decode list volumes response") + } + + return result, nil +} + +type CreateVolumeInput struct { + Name string + Size int64 + Networks []string + Type string +} + +func (input *CreateVolumeInput) toAPI() map[string]interface{} { + result := make(map[string]interface{}, 0) + + if input.Name != "" { + result["name"] = input.Name + } + + if input.Size != 0 { + result["size"] = input.Size + } + + if input.Type != "" { + result["type"] = input.Type + } + + if len(input.Networks) > 0 { + result["networks"] = input.Networks + } + + return result +} + +func (c *VolumesClient) Create(ctx context.Context, input *CreateVolumeInput) (*Volume, error) { + fullPath := path.Join("/", c.client.AccountName, "volumes") + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: fullPath, + Body: input.toAPI(), + } + resp, err := c.client.ExecuteRequest(ctx, reqInputs) + if err != nil { + return nil, errors.Wrap(err, "unable to create volume") + } + if resp != nil { + defer resp.Close() + } + + var result *Volume + decoder := json.NewDecoder(resp) + if err = decoder.Decode(&result); err != nil { + return nil, errors.Wrap(err, "unable to decode create volume response") + } + + return result, nil +} + +type DeleteVolumeInput struct { + ID string +} + +func (c *VolumesClient) Delete(ctx context.Context, input *DeleteVolumeInput) error { + fullPath := path.Join("/", c.client.AccountName, "volumes", input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodDelete, + Path: fullPath, + } + resp, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return errors.Wrap(err, "unable to delete volume") + } + if resp == nil { + return errors.Wrap(err, "unable to delete volume") + } + if resp.Body != nil { + defer resp.Body.Close() + } + if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusGone { + return nil + } + + return nil +} + +type GetVolumeInput struct { + ID string +} + +func (c *VolumesClient) Get(ctx context.Context, input *GetVolumeInput) (*Volume, error) { + fullPath := path.Join("/", c.client.AccountName, "volumes", input.ID) + reqInputs := client.RequestInput{ + Method: http.MethodGet, + Path: fullPath, + } + resp, err := c.client.ExecuteRequestRaw(ctx, reqInputs) + if err != nil { + return nil, errors.Wrap(err, "unable to get volume") + } + if resp == nil { + return nil, errors.Wrap(err, "unable to get volume") + } + if resp.Body != nil { + defer resp.Body.Close() + } + + var result *Volume + decoder := json.NewDecoder(resp.Body) + if err = decoder.Decode(&result); err != nil { + return nil, errors.Wrap(err, "unable to decode get volume volume") + } + + return result, nil +} + +type UpdateVolumeInput struct { + ID string `json:"-"` + Name string `json:"name"` +} + +func (c *VolumesClient) Update(ctx context.Context, input *UpdateVolumeInput) error { + fullPath := path.Join("/", c.client.AccountName, "volumes", input.ID) + + reqInputs := client.RequestInput{ + Method: http.MethodPost, + Path: fullPath, + Body: input, + } + resp, err := c.client.ExecuteRequest(ctx, reqInputs) + if err != nil { + return errors.Wrap(err, "unable to update volume") + } + if resp != nil { + defer resp.Close() + } + + return nil +} diff --git a/vendor/github.com/joyent/triton-go/errors/errors.go b/vendor/github.com/joyent/triton-go/errors/errors.go new file mode 100644 index 000000000..8f2719738 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/errors/errors.go @@ -0,0 +1,297 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + +package errors + +import ( + "fmt" + "net/http" + "strings" + + "github.com/pkg/errors" +) + +// APIError represents an error code and message along with +// the status code of the HTTP request which resulted in the error +// message. Error codes used by the Triton API are listed at +// https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses +// Error codes used by the Manta API are listed at +// https://apidocs.joyent.com/manta/api.html#errors +type APIError struct { + StatusCode int + Code string `json:"code"` + Message string `json:"message"` +} + +// Error implements interface Error on the APIError type. +func (e APIError) Error() string { + return strings.Trim(fmt.Sprintf("%+q", e.Code), `"`) + ": " + strings.Trim(fmt.Sprintf("%+q", e.Message), `"`) +} + +// ClientError represents an error code and message returned +// when connecting to the triton-go client +type ClientError struct { + StatusCode int + Code string `json:"code"` + Message string `json:"message"` +} + +// Error implements interface Error on the ClientError type. +func (e ClientError) Error() string { + return strings.Trim(fmt.Sprintf("%+q", e.Code), `"`) + ": " + strings.Trim(fmt.Sprintf("%+q", e.Message), `"`) +} + +func IsAuthSchemeError(err error) bool { + return IsSpecificError(err, "AuthScheme") +} + +func IsAuthorizationError(err error) bool { + return IsSpecificError(err, "Authorization") +} + +func IsBadRequestError(err error) bool { + return IsSpecificError(err, "BadRequest") +} + +func IsChecksumError(err error) bool { + return IsSpecificError(err, "Checksum") +} + +func IsConcurrentRequestError(err error) bool { + return IsSpecificError(err, "ConcurrentRequest") +} + +func IsContentLengthError(err error) bool { + return IsSpecificError(err, "ContentLength") +} + +func IsContentMD5MismatchError(err error) bool { + return IsSpecificError(err, "ContentMD5Mismatch") +} + +func IsEntityExistsError(err error) bool { + return IsSpecificError(err, "EntityExists") +} + +func IsInvalidArgumentError(err error) bool { + return IsSpecificError(err, "InvalidArgument") +} + +func IsInvalidAuthTokenError(err error) bool { + return IsSpecificError(err, "InvalidAuthToken") +} + +func IsInvalidCredentialsError(err error) bool { + return IsSpecificError(err, "InvalidCredentials") +} + +func IsInvalidDurabilityLevelError(err error) bool { + return IsSpecificError(err, "InvalidDurabilityLevel") +} + +func IsInvalidKeyIdError(err error) bool { + return IsSpecificError(err, "InvalidKeyId") +} + +func IsInvalidJobError(err error) bool { + return IsSpecificError(err, "InvalidJob") +} + +func IsInvalidLinkError(err error) bool { + return IsSpecificError(err, "InvalidLink") +} + +func IsInvalidLimitError(err error) bool { + return IsSpecificError(err, "InvalidLimit") +} + +func IsInvalidSignatureError(err error) bool { + return IsSpecificError(err, "InvalidSignature") +} + +func IsInvalidUpdateError(err error) bool { + return IsSpecificError(err, "InvalidUpdate") +} + +func IsDirectoryDoesNotExistError(err error) bool { + return IsSpecificError(err, "DirectoryDoesNotExist") +} + +func IsDirectoryExistsError(err error) bool { + return IsSpecificError(err, "DirectoryExists") +} + +func IsDirectoryNotEmptyError(err error) bool { + return IsSpecificError(err, "DirectoryNotEmpty") +} + +func IsDirectoryOperationError(err error) bool { + return IsSpecificError(err, "DirectoryOperation") +} + +func IsInternalError(err error) bool { + return IsSpecificError(err, "Internal") +} + +func IsJobNotFoundError(err error) bool { + return IsSpecificError(err, "JobNotFound") +} + +func IsJobStateError(err error) bool { + return IsSpecificError(err, "JobState") +} + +func IsKeyDoesNotExistError(err error) bool { + return IsSpecificError(err, "KeyDoesNotExist") +} + +func IsNotAcceptableError(err error) bool { + return IsSpecificError(err, "NotAcceptable") +} + +func IsNotEnoughSpaceError(err error) bool { + return IsSpecificError(err, "NotEnoughSpace") +} + +func IsLinkNotFoundError(err error) bool { + return IsSpecificError(err, "LinkNotFound") +} + +func IsLinkNotObjectError(err error) bool { + return IsSpecificError(err, "LinkNotObject") +} + +func IsLinkRequiredError(err error) bool { + return IsSpecificError(err, "LinkRequired") +} + +func IsParentNotDirectoryError(err error) bool { + return IsSpecificError(err, "ParentNotDirectory") +} + +func IsPreconditionFailedError(err error) bool { + return IsSpecificError(err, "PreconditionFailed") +} + +func IsPreSignedRequestError(err error) bool { + return IsSpecificError(err, "PreSignedRequest") +} + +func IsRequestEntityTooLargeError(err error) bool { + return IsSpecificError(err, "RequestEntityTooLarge") +} + +func IsResourceNotFoundError(err error) bool { + return IsSpecificError(err, "ResourceNotFound") +} + +func IsRootDirectoryError(err error) bool { + return IsSpecificError(err, "RootDirectory") +} + +func IsServiceUnavailableError(err error) bool { + return IsSpecificError(err, "ServiceUnavailable") +} + +func IsSSLRequiredError(err error) bool { + return IsSpecificError(err, "SSLRequired") +} + +func IsUploadTimeoutError(err error) bool { + return IsSpecificError(err, "UploadTimeout") +} + +func IsUserDoesNotExistError(err error) bool { + return IsSpecificError(err, "UserDoesNotExist") +} + +func IsBadRequest(err error) bool { + return IsSpecificError(err, "BadRequest") +} + +func IsInUseError(err error) bool { + return IsSpecificError(err, "InUseError") +} + +func IsInvalidArgument(err error) bool { + return IsSpecificError(err, "InvalidArgument") +} + +func IsInvalidCredentials(err error) bool { + return IsSpecificError(err, "InvalidCredentials") +} + +func IsInvalidHeader(err error) bool { + return IsSpecificError(err, "InvalidHeader") +} + +func IsInvalidVersion(err error) bool { + return IsSpecificError(err, "InvalidVersion") +} + +func IsMissingParameter(err error) bool { + return IsSpecificError(err, "MissingParameter") +} + +func IsNotAuthorized(err error) bool { + return IsSpecificError(err, "NotAuthorized") +} + +func IsRequestThrottled(err error) bool { + return IsSpecificError(err, "RequestThrottled") +} + +func IsRequestTooLarge(err error) bool { + return IsSpecificError(err, "RequestTooLarge") +} + +func IsRequestMoved(err error) bool { + return IsSpecificError(err, "RequestMoved") +} + +func IsResourceFound(err error) bool { + return IsSpecificError(err, "ResourceFound") +} + +func IsResourceNotFound(err error) bool { + return IsSpecificError(err, "ResourceNotFound") +} + +func IsUnknownError(err error) bool { + return IsSpecificError(err, "UnknownError") +} + +func IsEmptyResponse(err error) bool { + return IsSpecificError(err, "EmptyResponse") +} + +func IsStatusNotFoundCode(err error) bool { + return IsSpecificStatusCode(err, http.StatusNotFound) +} + +func IsSpecificError(myError error, errorCode string) bool { + switch err := errors.Cause(myError).(type) { + case *APIError: + if err.Code == errorCode { + return true + } + } + + return false +} + +func IsSpecificStatusCode(myError error, statusCode int) bool { + switch err := errors.Cause(myError).(type) { + case *APIError: + if err.StatusCode == statusCode { + return true + } + } + + return false +} diff --git a/vendor/github.com/joyent/triton-go/network/client.go b/vendor/github.com/joyent/triton-go/network/client.go index dbc25a84c..097af171c 100644 --- a/vendor/github.com/joyent/triton-go/network/client.go +++ b/vendor/github.com/joyent/triton-go/network/client.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package network import ( diff --git a/vendor/github.com/joyent/triton-go/network/fabrics.go b/vendor/github.com/joyent/triton-go/network/fabrics.go index 20f1d2fe6..ff83ee1fa 100644 --- a/vendor/github.com/joyent/triton-go/network/fabrics.go +++ b/vendor/github.com/joyent/triton-go/network/fabrics.go @@ -1,14 +1,22 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package network import ( - "encoding/json" - "fmt" - "net/http" - "context" + "encoding/json" + "net/http" + "path" + "strconv" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type FabricsClient struct { @@ -24,23 +32,23 @@ type FabricVLAN struct { type ListVLANsInput struct{} func (c *FabricsClient) ListVLANs(ctx context.Context, _ *ListVLANsInput) ([]*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListVLANs request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list VLANs") } var result []*FabricVLAN decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListVLANs response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list VLANs response") } return result, nil @@ -53,10 +61,10 @@ type CreateVLANInput struct { } func (c *FabricsClient) CreateVLAN(ctx context.Context, input *CreateVLANInput) (*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -64,13 +72,13 @@ func (c *FabricsClient) CreateVLAN(ctx context.Context, input *CreateVLANInput) defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing CreateVLAN request: {{err}}", err) + return nil, errors.Wrap(err, "unable to create VLAN") } var result *FabricVLAN decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateVLAN response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode create VLAN response") } return result, nil @@ -83,10 +91,10 @@ type UpdateVLANInput struct { } func (c *FabricsClient) UpdateVLAN(ctx context.Context, input *UpdateVLANInput) (*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.ID)) reqInputs := client.RequestInput{ Method: http.MethodPut, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -94,13 +102,13 @@ func (c *FabricsClient) UpdateVLAN(ctx context.Context, input *UpdateVLANInput) defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateVLAN request: {{err}}", err) + return nil, errors.Wrap(err, "unable to update VLAN") } var result *FabricVLAN decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateVLAN response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode update VLAN response") } return result, nil @@ -111,23 +119,23 @@ type GetVLANInput struct { } func (c *FabricsClient) GetVLAN(ctx context.Context, input *GetVLANInput) (*FabricVLAN, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.ID)) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetVLAN request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get VLAN") } var result *FabricVLAN decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetVLAN response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get VLAN response") } return result, nil @@ -138,17 +146,17 @@ type DeleteVLANInput struct { } func (c *FabricsClient) DeleteVLAN(ctx context.Context, input *DeleteVLANInput) error { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.ID)) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing DeleteVLAN request: {{err}}", err) + return errors.Wrap(err, "unable to delete VLAN") } return nil @@ -159,23 +167,23 @@ type ListFabricsInput struct { } func (c *FabricsClient) List(ctx context.Context, input *ListFabricsInput) ([]*Network, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks", c.client.AccountName, input.FabricVLANID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.FabricVLANID), "networks") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListFabrics request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list fabrics") } var result []*Network decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListFabrics response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list fabrics response") } return result, nil @@ -195,10 +203,10 @@ type CreateFabricInput struct { } func (c *FabricsClient) Create(ctx context.Context, input *CreateFabricInput) (*Network, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks", c.client.AccountName, input.FabricVLANID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.FabricVLANID), "networks") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -206,13 +214,13 @@ func (c *FabricsClient) Create(ctx context.Context, input *CreateFabricInput) (* defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing CreateFabric request: {{err}}", err) + return nil, errors.Wrap(err, "unable to create fabric") } var result *Network decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateFabric response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode create fabric response") } return result, nil @@ -224,23 +232,23 @@ type GetFabricInput struct { } func (c *FabricsClient) Get(ctx context.Context, input *GetFabricInput) (*Network, error) { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks/%s", c.client.AccountName, input.FabricVLANID, input.NetworkID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.FabricVLANID), "networks", input.NetworkID) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetFabric request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get fabric") } var result *Network decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetFabric response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get fabric response") } return result, nil @@ -252,17 +260,17 @@ type DeleteFabricInput struct { } func (c *FabricsClient) Delete(ctx context.Context, input *DeleteFabricInput) error { - path := fmt.Sprintf("/%s/fabrics/default/vlans/%d/networks/%s", c.client.AccountName, input.FabricVLANID, input.NetworkID) + fullPath := path.Join("/", c.client.AccountName, "fabrics", "default", "vlans", strconv.Itoa(input.FabricVLANID), "networks", input.NetworkID) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing DeleteFabric request: {{err}}", err) + return errors.Wrap(err, "unable to delete fabric") } return nil diff --git a/vendor/github.com/joyent/triton-go/network/firewall.go b/vendor/github.com/joyent/triton-go/network/firewall.go index 8dbd969f3..4a6565ea5 100644 --- a/vendor/github.com/joyent/triton-go/network/firewall.go +++ b/vendor/github.com/joyent/triton-go/network/firewall.go @@ -1,15 +1,22 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package network import ( "context" "encoding/json" - "fmt" "net/http" - + "path" "time" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type FirewallClient struct { @@ -37,23 +44,23 @@ type FirewallRule struct { type ListRulesInput struct{} func (c *FirewallClient) ListRules(ctx context.Context, _ *ListRulesInput) ([]*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "fwrules") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListRules request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list firewall rules") } var result []*FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListRules response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list firewall rules response") } return result, nil @@ -64,23 +71,23 @@ type GetRuleInput struct { } func (c *FirewallClient) GetRule(ctx context.Context, input *GetRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fwrules", input.ID) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetRule request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get firewall rule") } var result *FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetRule response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get firewall rule response") } return result, nil @@ -93,10 +100,10 @@ type CreateRuleInput struct { } func (c *FirewallClient) CreateRule(ctx context.Context, input *CreateRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules", c.client.AccountName) + fullPath := path.Join("/", c.client.AccountName, "fwrules") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -104,13 +111,13 @@ func (c *FirewallClient) CreateRule(ctx context.Context, input *CreateRuleInput) defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing CreateRule request: {{err}}", err) + return nil, errors.Wrap(err, "unable to create firewall rule") } var result *FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding CreateRule response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode create firewall rule response") } return result, nil @@ -124,10 +131,10 @@ type UpdateRuleInput struct { } func (c *FirewallClient) UpdateRule(ctx context.Context, input *UpdateRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fwrules", input.ID) reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -135,13 +142,13 @@ func (c *FirewallClient) UpdateRule(ctx context.Context, input *UpdateRuleInput) defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing UpdateRule request: {{err}}", err) + return nil, errors.Wrap(err, "unable to update firewall rule") } var result *FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding UpdateRule response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode update firewall rule response") } return result, nil @@ -152,10 +159,10 @@ type EnableRuleInput struct { } func (c *FirewallClient) EnableRule(ctx context.Context, input *EnableRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s/enable", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fwrules", input.ID, "enable") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -163,13 +170,13 @@ func (c *FirewallClient) EnableRule(ctx context.Context, input *EnableRuleInput) defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing EnableRule request: {{err}}", err) + return nil, errors.Wrap(err, "unable to enable firewall rule") } var result *FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding EnableRule response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode enable firewall rule response") } return result, nil @@ -180,10 +187,10 @@ type DisableRuleInput struct { } func (c *FirewallClient) DisableRule(ctx context.Context, input *DisableRuleInput) (*FirewallRule, error) { - path := fmt.Sprintf("/%s/fwrules/%s/disable", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fwrules", input.ID, "disable") reqInputs := client.RequestInput{ Method: http.MethodPost, - Path: path, + Path: fullPath, Body: input, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) @@ -191,13 +198,13 @@ func (c *FirewallClient) DisableRule(ctx context.Context, input *DisableRuleInpu defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing DisableRule request: {{err}}", err) + return nil, errors.Wrap(err, "unable to disable firewall rule") } var result *FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding DisableRule response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode disable firewall rule response") } return result, nil @@ -208,17 +215,17 @@ type DeleteRuleInput struct { } func (c *FirewallClient) DeleteRule(ctx context.Context, input *DeleteRuleInput) error { - path := fmt.Sprintf("/%s/fwrules/%s", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fwrules", input.ID) reqInputs := client.RequestInput{ Method: http.MethodDelete, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return errwrap.Wrapf("Error executing DeleteRule request: {{err}}", err) + return errors.Wrap(err, "unable to delete firewall rule") } return nil @@ -229,23 +236,23 @@ type ListMachineRulesInput struct { } func (c *FirewallClient) ListMachineRules(ctx context.Context, input *ListMachineRulesInput) ([]*FirewallRule, error) { - path := fmt.Sprintf("/%s/machines/%s/fwrules", c.client.AccountName, input.MachineID) + fullPath := path.Join("/", c.client.AccountName, "machines", input.MachineID, "fwrules") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListMachineRules request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list machine firewall rules") } var result []*FirewallRule decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListMachineRules response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list machine firewall rules response") } return result, nil @@ -278,23 +285,23 @@ type Machine struct { } func (c *FirewallClient) ListRuleMachines(ctx context.Context, input *ListRuleMachinesInput) ([]*Machine, error) { - path := fmt.Sprintf("/%s/fwrules/%s/machines", c.client.AccountName, input.ID) + fullPath := path.Join("/", c.client.AccountName, "fwrules", input.ID, "machines") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListRuleMachines request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list firewall rule machines") } var result []*Machine decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListRuleMachines response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list firewall rule machines response") } return result, nil diff --git a/vendor/github.com/joyent/triton-go/network/network.go b/vendor/github.com/joyent/triton-go/network/network.go index d853e0402..3ad43fd54 100644 --- a/vendor/github.com/joyent/triton-go/network/network.go +++ b/vendor/github.com/joyent/triton-go/network/network.go @@ -1,13 +1,21 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package network import ( "context" "encoding/json" - "fmt" "net/http" + "path" - "github.com/hashicorp/errwrap" "github.com/joyent/triton-go/client" + "github.com/pkg/errors" ) type Network struct { @@ -28,23 +36,23 @@ type Network struct { type ListInput struct{} func (c *NetworkClient) List(ctx context.Context, _ *ListInput) ([]*Network, error) { - path := fmt.Sprintf("/%s/networks", c.Client.AccountName) + fullPath := path.Join("/", c.Client.AccountName, "networks") reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.Client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing ListNetworks request: {{err}}", err) + return nil, errors.Wrap(err, "unable to list networks") } var result []*Network decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding ListNetworks response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode list networks response") } return result, nil @@ -55,23 +63,23 @@ type GetInput struct { } func (c *NetworkClient) Get(ctx context.Context, input *GetInput) (*Network, error) { - path := fmt.Sprintf("/%s/networks/%s", c.Client.AccountName, input.ID) + fullPath := path.Join("/", c.Client.AccountName, "networks", input.ID) reqInputs := client.RequestInput{ Method: http.MethodGet, - Path: path, + Path: fullPath, } respReader, err := c.Client.ExecuteRequest(ctx, reqInputs) if respReader != nil { defer respReader.Close() } if err != nil { - return nil, errwrap.Wrapf("Error executing GetNetwork request: {{err}}", err) + return nil, errors.Wrap(err, "unable to get network") } var result *Network decoder := json.NewDecoder(respReader) if err = decoder.Decode(&result); err != nil { - return nil, errwrap.Wrapf("Error decoding GetNetwork response: {{err}}", err) + return nil, errors.Wrap(err, "unable to decode get network response") } return result, nil diff --git a/vendor/github.com/joyent/triton-go/triton.go b/vendor/github.com/joyent/triton-go/triton.go index f9202984e..5d74258d4 100644 --- a/vendor/github.com/joyent/triton-go/triton.go +++ b/vendor/github.com/joyent/triton-go/triton.go @@ -1,3 +1,11 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + package triton import ( diff --git a/vendor/github.com/joyent/triton-go/version.go b/vendor/github.com/joyent/triton-go/version.go new file mode 100644 index 000000000..0c1bc8680 --- /dev/null +++ b/vendor/github.com/joyent/triton-go/version.go @@ -0,0 +1,32 @@ +// +// Copyright (c) 2018, Joyent, Inc. All rights reserved. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + +package triton + +import ( + "fmt" + "runtime" +) + +// The main version number of the current released Triton-go SDK. +const Version = "0.9.0" + +// A pre-release marker for the version. If this is "" (empty string) +// then it means that it is a final release. Otherwise, this is a pre-release +// such as "dev" (in development), "beta", "rc1", etc. +var Prerelease = "" + +func UserAgent() string { + if Prerelease != "" { + return fmt.Sprintf("triton-go/%s-%s (%s-%s; %s)", Version, Prerelease, runtime.GOARCH, runtime.GOOS, runtime.Version()) + } else { + return fmt.Sprintf("triton-go/%s (%s-%s; %s)", Version, runtime.GOARCH, runtime.GOOS, runtime.Version()) + } +} + +const CloudAPIMajorVersion = "8" diff --git a/vendor/github.com/pkg/errors/LICENSE b/vendor/github.com/pkg/errors/LICENSE new file mode 100644 index 000000000..835ba3e75 --- /dev/null +++ b/vendor/github.com/pkg/errors/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2015, Dave Cheney <dave@cheney.net> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pkg/errors/README.md b/vendor/github.com/pkg/errors/README.md new file mode 100644 index 000000000..6483ba2af --- /dev/null +++ b/vendor/github.com/pkg/errors/README.md @@ -0,0 +1,52 @@ +# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge) + +Package errors provides simple error handling primitives. + +`go get github.com/pkg/errors` + +The traditional error handling idiom in Go is roughly akin to +```go +if err != nil { + return err +} +``` +which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error. + +## Adding context to an error + +The errors.Wrap function returns a new error that adds context to the original error. For example +```go +_, err := ioutil.ReadAll(r) +if err != nil { + return errors.Wrap(err, "read failed") +} +``` +## Retrieving the cause of an error + +Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`. +```go +type causer interface { + Cause() error +} +``` +`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example: +```go +switch err := errors.Cause(err).(type) { +case *MyError: + // handle specifically +default: + // unknown error +} +``` + +[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors). + +## Contributing + +We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high. + +Before proposing a change, please discuss your change by raising an issue. + +## License + +BSD-2-Clause diff --git a/vendor/github.com/pkg/errors/appveyor.yml b/vendor/github.com/pkg/errors/appveyor.yml new file mode 100644 index 000000000..a932eade0 --- /dev/null +++ b/vendor/github.com/pkg/errors/appveyor.yml @@ -0,0 +1,32 @@ +version: build-{build}.{branch} + +clone_folder: C:\gopath\src\github.com\pkg\errors +shallow_clone: true # for startup speed + +environment: + GOPATH: C:\gopath + +platform: + - x64 + +# http://www.appveyor.com/docs/installed-software +install: + # some helpful output for debugging builds + - go version + - go env + # pre-installed MinGW at C:\MinGW is 32bit only + # but MSYS2 at C:\msys64 has mingw64 + - set PATH=C:\msys64\mingw64\bin;%PATH% + - gcc --version + - g++ --version + +build_script: + - go install -v ./... + +test_script: + - set PATH=C:\gopath\bin;%PATH% + - go test -v ./... + +#artifacts: +# - path: '%GOPATH%\bin\*.exe' +deploy: off diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go new file mode 100644 index 000000000..842ee8045 --- /dev/null +++ b/vendor/github.com/pkg/errors/errors.go @@ -0,0 +1,269 @@ +// Package errors provides simple error handling primitives. +// +// The traditional error handling idiom in Go is roughly akin to +// +// if err != nil { +// return err +// } +// +// which applied recursively up the call stack results in error reports +// without context or debugging information. The errors package allows +// programmers to add context to the failure path in their code in a way +// that does not destroy the original value of the error. +// +// Adding context to an error +// +// The errors.Wrap function returns a new error that adds context to the +// original error by recording a stack trace at the point Wrap is called, +// and the supplied message. For example +// +// _, err := ioutil.ReadAll(r) +// if err != nil { +// return errors.Wrap(err, "read failed") +// } +// +// If additional control is required the errors.WithStack and errors.WithMessage +// functions destructure errors.Wrap into its component operations of annotating +// an error with a stack trace and an a message, respectively. +// +// Retrieving the cause of an error +// +// Using errors.Wrap constructs a stack of errors, adding context to the +// preceding error. Depending on the nature of the error it may be necessary +// to reverse the operation of errors.Wrap to retrieve the original error +// for inspection. Any error value which implements this interface +// +// type causer interface { +// Cause() error +// } +// +// can be inspected by errors.Cause. errors.Cause will recursively retrieve +// the topmost error which does not implement causer, which is assumed to be +// the original cause. For example: +// +// switch err := errors.Cause(err).(type) { +// case *MyError: +// // handle specifically +// default: +// // unknown error +// } +// +// causer interface is not exported by this package, but is considered a part +// of stable public API. +// +// Formatted printing of errors +// +// All error values returned from this package implement fmt.Formatter and can +// be formatted by the fmt package. The following verbs are supported +// +// %s print the error. If the error has a Cause it will be +// printed recursively +// %v see %s +// %+v extended format. Each Frame of the error's StackTrace will +// be printed in detail. +// +// Retrieving the stack trace of an error or wrapper +// +// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are +// invoked. This information can be retrieved with the following interface. +// +// type stackTracer interface { +// StackTrace() errors.StackTrace +// } +// +// Where errors.StackTrace is defined as +// +// type StackTrace []Frame +// +// The Frame type represents a call site in the stack trace. Frame supports +// the fmt.Formatter interface that can be used for printing information about +// the stack trace of this error. For example: +// +// if err, ok := err.(stackTracer); ok { +// for _, f := range err.StackTrace() { +// fmt.Printf("%+s:%d", f) +// } +// } +// +// stackTracer interface is not exported by this package, but is considered a part +// of stable public API. +// +// See the documentation for Frame.Format for more details. +package errors + +import ( + "fmt" + "io" +) + +// New returns an error with the supplied message. +// New also records the stack trace at the point it was called. +func New(message string) error { + return &fundamental{ + msg: message, + stack: callers(), + } +} + +// Errorf formats according to a format specifier and returns the string +// as a value that satisfies error. +// Errorf also records the stack trace at the point it was called. +func Errorf(format string, args ...interface{}) error { + return &fundamental{ + msg: fmt.Sprintf(format, args...), + stack: callers(), + } +} + +// fundamental is an error that has a message and a stack, but no caller. +type fundamental struct { + msg string + *stack +} + +func (f *fundamental) Error() string { return f.msg } + +func (f *fundamental) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + io.WriteString(s, f.msg) + f.stack.Format(s, verb) + return + } + fallthrough + case 's': + io.WriteString(s, f.msg) + case 'q': + fmt.Fprintf(s, "%q", f.msg) + } +} + +// WithStack annotates err with a stack trace at the point WithStack was called. +// If err is nil, WithStack returns nil. +func WithStack(err error) error { + if err == nil { + return nil + } + return &withStack{ + err, + callers(), + } +} + +type withStack struct { + error + *stack +} + +func (w *withStack) Cause() error { return w.error } + +func (w *withStack) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + w.stack.Format(s, verb) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +// Wrap returns an error annotating err with a stack trace +// at the point Wrap is called, and the supplied message. +// If err is nil, Wrap returns nil. +func Wrap(err error, message string) error { + if err == nil { + return nil + } + err = &withMessage{ + cause: err, + msg: message, + } + return &withStack{ + err, + callers(), + } +} + +// Wrapf returns an error annotating err with a stack trace +// at the point Wrapf is call, and the format specifier. +// If err is nil, Wrapf returns nil. +func Wrapf(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + err = &withMessage{ + cause: err, + msg: fmt.Sprintf(format, args...), + } + return &withStack{ + err, + callers(), + } +} + +// WithMessage annotates err with a new message. +// If err is nil, WithMessage returns nil. +func WithMessage(err error, message string) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: message, + } +} + +type withMessage struct { + cause error + msg string +} + +func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } +func (w *withMessage) Cause() error { return w.cause } + +func (w *withMessage) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v\n", w.Cause()) + io.WriteString(s, w.msg) + return + } + fallthrough + case 's', 'q': + io.WriteString(s, w.Error()) + } +} + +// Cause returns the underlying cause of the error, if possible. +// An error value has a cause if it implements the following +// interface: +// +// type causer interface { +// Cause() error +// } +// +// If the error does not implement Cause, the original error will +// be returned. If the error is nil, nil will be returned without further +// investigation. +func Cause(err error) error { + type causer interface { + Cause() error + } + + for err != nil { + cause, ok := err.(causer) + if !ok { + break + } + err = cause.Cause() + } + return err +} diff --git a/vendor/github.com/pkg/errors/stack.go b/vendor/github.com/pkg/errors/stack.go new file mode 100644 index 000000000..b485761a7 --- /dev/null +++ b/vendor/github.com/pkg/errors/stack.go @@ -0,0 +1,187 @@ +package errors + +import ( + "fmt" + "io" + "path" + "runtime" + "strings" +) + +// Frame represents a program counter inside a stack frame. +type Frame uintptr + +// pc returns the program counter for this frame; +// multiple frames may have the same PC value. +func (f Frame) pc() uintptr { return uintptr(f) - 1 } + +// file returns the full path to the file that contains the +// function for this Frame's pc. +func (f Frame) file() string { + fn := runtime.FuncForPC(f.pc()) + if fn == nil { + return "unknown" + } + file, _ := fn.FileLine(f.pc()) + return file +} + +// line returns the line number of source code of the +// function for this Frame's pc. +func (f Frame) line() int { + fn := runtime.FuncForPC(f.pc()) + if fn == nil { + return 0 + } + _, line := fn.FileLine(f.pc()) + return line +} + +// Format formats the frame according to the fmt.Formatter interface. +// +// %s source file +// %d source line +// %n function name +// %v equivalent to %s:%d +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+s function name and path of source file relative to the compile time +// GOPATH separated by \n\t (<funcname>\n\t<path>) +// %+v equivalent to %+s:%d +func (f Frame) Format(s fmt.State, verb rune) { + switch verb { + case 's': + switch { + case s.Flag('+'): + pc := f.pc() + fn := runtime.FuncForPC(pc) + if fn == nil { + io.WriteString(s, "unknown") + } else { + file, _ := fn.FileLine(pc) + fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file) + } + default: + io.WriteString(s, path.Base(f.file())) + } + case 'd': + fmt.Fprintf(s, "%d", f.line()) + case 'n': + name := runtime.FuncForPC(f.pc()).Name() + io.WriteString(s, funcname(name)) + case 'v': + f.Format(s, 's') + io.WriteString(s, ":") + f.Format(s, 'd') + } +} + +// StackTrace is stack of Frames from innermost (newest) to outermost (oldest). +type StackTrace []Frame + +// Format formats the stack of Frames according to the fmt.Formatter interface. +// +// %s lists source files for each Frame in the stack +// %v lists the source file and line number for each Frame in the stack +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+v Prints filename, function, and line number for each Frame in the stack. +func (st StackTrace) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + switch { + case s.Flag('+'): + for _, f := range st { + fmt.Fprintf(s, "\n%+v", f) + } + case s.Flag('#'): + fmt.Fprintf(s, "%#v", []Frame(st)) + default: + fmt.Fprintf(s, "%v", []Frame(st)) + } + case 's': + fmt.Fprintf(s, "%s", []Frame(st)) + } +} + +// stack represents a stack of program counters. +type stack []uintptr + +func (s *stack) Format(st fmt.State, verb rune) { + switch verb { + case 'v': + switch { + case st.Flag('+'): + for _, pc := range *s { + f := Frame(pc) + fmt.Fprintf(st, "\n%+v", f) + } + } + } +} + +func (s *stack) StackTrace() StackTrace { + f := make([]Frame, len(*s)) + for i := 0; i < len(f); i++ { + f[i] = Frame((*s)[i]) + } + return f +} + +func callers() *stack { + const depth = 32 + var pcs [depth]uintptr + n := runtime.Callers(3, pcs[:]) + var st stack = pcs[0:n] + return &st +} + +// funcname removes the path prefix component of a function's name reported by func.Name(). +func funcname(name string) string { + i := strings.LastIndex(name, "/") + name = name[i+1:] + i = strings.Index(name, ".") + return name[i+1:] +} + +func trimGOPATH(name, file string) string { + // Here we want to get the source file path relative to the compile time + // GOPATH. As of Go 1.6.x there is no direct way to know the compiled + // GOPATH at runtime, but we can infer the number of path segments in the + // GOPATH. We note that fn.Name() returns the function name qualified by + // the import path, which does not include the GOPATH. Thus we can trim + // segments from the beginning of the file path until the number of path + // separators remaining is one more than the number of path separators in + // the function name. For example, given: + // + // GOPATH /home/user + // file /home/user/src/pkg/sub/file.go + // fn.Name() pkg/sub.Type.Method + // + // We want to produce: + // + // pkg/sub/file.go + // + // From this we can easily see that fn.Name() has one less path separator + // than our desired output. We count separators from the end of the file + // path until it finds two more than in the function name and then move + // one character forward to preserve the initial path segment without a + // leading separator. + const sep = "/" + goal := strings.Count(name, sep) + 2 + i := len(file) + for n := 0; n < goal; n++ { + i = strings.LastIndex(file[:i], sep) + if i == -1 { + // not enough separators found, set i so that the slice expression + // below leaves file unmodified + i = -len(sep) + break + } + } + // get back to 0 or trim the leading separator + file = file[i+len(sep):] + return file +} diff --git a/vendor/vendor.json b/vendor/vendor.json index d4d157eb9..1c61745f5 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -823,34 +823,40 @@ "revision": "c01cf91b011868172fdcd9f41838e80c9d716264" }, { - "checksumSHA1": "oINoQSRkPinChzwEHr3VatB9++Y=", + "checksumSHA1": "Lg8OHK87XRGCaipG+5+zFyN8OMw=", "path": "github.com/joyent/triton-go", - "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", - "revisionTime": "2017-12-28T20:20:46Z" + "revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf", + "revisionTime": "2018-01-16T16:57:42Z" }, { - "checksumSHA1": "d6pxw8DLxYehLr92fWZTLEWVws8=", + "checksumSHA1": "Y03+L+I0FVZ2bMGWt1MHTDEyWM4=", "path": "github.com/joyent/triton-go/authentication", - "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", - "revisionTime": "2017-12-28T20:20:46Z" + "revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf", + "revisionTime": "2018-01-16T16:57:42Z" }, { - "checksumSHA1": "GCHfn8d1Mhswm7n7IRnT0n/w+dw=", + "checksumSHA1": "MuJsGBr6HlXQYxZY9cM5rBk+Lns=", "path": "github.com/joyent/triton-go/client", - "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", - "revisionTime": "2017-12-28T20:20:46Z" + "revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf", + "revisionTime": "2018-01-16T16:57:42Z" }, { - "checksumSHA1": "U9D/fCNr+1uD1p/O0PW0yD/izqc=", + "checksumSHA1": "A+YGcdf/qfac1gqK8QY1F5+pYGA=", "path": "github.com/joyent/triton-go/compute", - "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", - "revisionTime": "2017-12-28T20:20:46Z" + "revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf", + "revisionTime": "2018-01-16T16:57:42Z" }, { - "checksumSHA1": "9OdR/eI3qbmADruKn6yE1Dbx3LE=", + "checksumSHA1": "d/Py6j/uMgOAFNFGpsQrNnSsO+k=", + "path": "github.com/joyent/triton-go/errors", + "revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf", + "revisionTime": "2018-01-16T16:57:42Z" + }, + { + "checksumSHA1": "MIrIeqiPmw66cko+gzk7Cht2SLE=", "path": "github.com/joyent/triton-go/network", - "revision": "86ba9699869b6cd5ea3290faad7be659efc7d6ce", - "revisionTime": "2017-12-28T20:20:46Z" + "revision": "545edbe0d564f075ac576f1ad177f4ff39c9adaf", + "revisionTime": "2018-01-16T16:57:42Z" }, { "checksumSHA1": "gEjGS03N1eysvpQ+FCHTxPcbxXc=", @@ -1003,6 +1009,12 @@ "path": "github.com/pierrec/xxHash/xxHash32", "revision": "5a004441f897722c627870a981d02b29924215fa" }, + { + "checksumSHA1": "xCv4GBFyw07vZkVtKF/XrUnkHRk=", + "path": "github.com/pkg/errors", + "revision": "e881fd58d78e04cf6d0de1217f8707c8cc2249bc", + "revisionTime": "2017-12-16T07:03:16Z" + }, { "checksumSHA1": "Mud+5WNq90BFb4gTeM5AByN8f2Y=", "path": "github.com/pkg/sftp", From 93e565ca3cc1f385fd84924b17db7b0eb70f63f6 Mon Sep 17 00:00:00 2001 From: Jesse Stuart <hi@jessestuart.com> Date: Thu, 18 Jan 2018 04:22:23 -0500 Subject: [PATCH 0412/1007] [docs] Fix typo in CONTRIBUTING.md --- CONTRIBUTING.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85c0e04dd..78f06cf84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,9 +18,9 @@ it raises the chances we can quickly merge or address your contributions. * Make sure you test against the latest released version. It is possible we already fixed the bug you're experiencing. -* Run the command with debug ouput with the environment variable +* Run the command with debug output with the environment variable `PACKER_LOG`. For example: `PACKER_LOG=1 packer build template.json`. Take - the *entire* output and create a [gist](https://gist.github.com) for linking + the _entire_ output and create a [gist](https://gist.github.com) for linking to in your issue. Packer should strip sensitive keys from the output, but take a look through just in case. @@ -59,13 +59,12 @@ following steps in order to be able to compile and test Packer. These instructio 2. Set and export the `GOPATH` environment variable and update your `PATH`. For example, you can add to your `.bash_profile`. - ``` - export GOPATH=$HOME/go - export PATH=$PATH:$GOPATH/bin - ``` + ``` + export GOPATH=$HOME/go + export PATH=$PATH:$GOPATH/bin + ``` -3. Download the Packer source (and its dependencies) by running `go get - github.com/hashicorp/packer`. This will download the Packer source to +3. Download the Packer source (and its dependencies) by running `go get github.com/hashicorp/packer`. This will download the Packer source to `$GOPATH/src/github.com/hashicorp/packer`. 4. When working on packer `cd $GOPATH/src/github.com/hashicorp/packer` so you @@ -114,7 +113,7 @@ This way you can push to your fork to create a PR, but the code on disk still li #### Govendor -If you are submitting a change that requires new or updated dependencies, please include them in `vendor/vendor.json` and in the `vendor/` folder. This helps everything get tested properly in CI. +If you are submitting a change that requires new or updated dependencies, please include them in `vendor/vendor.json` and in the `vendor/` folder. This helps everything get tested properly in CI. Note that you will need to use [govendor](https://github.com/kardianos/govendor) to do this. This step is recommended but not required; if you don't use govendor please indicate in your PR which dependencies have changed and to what versions. @@ -140,7 +139,7 @@ additional software to be installed on your computer (VirtualBox, VMware). If you're working on a new builder or builder feature and want verify it is functioning (and also hasn't broken anything else), we recommend running the acceptance tests. -**Warning:** The acceptance tests create/destroy/modify *real resources*, which +**Warning:** The acceptance tests create/destroy/modify _real resources_, which may incur costs for real money. In the presence of a bug, it is possible that resources may be left behind, which can cost money even though you were not using them. We recommend running tests in an account used only for that purpose so it is easy to see if there are any dangling resources, and so production resources are not accidentally destroyed or overwritten during testing. To run the acceptance tests, invoke `make testacc`: From 5db947d9e822b584cb2826e98c411bf1dd472502 Mon Sep 17 00:00:00 2001 From: Jesse Stuart <hi@jessestuart.com> Date: Thu, 18 Jan 2018 04:34:14 -0500 Subject: [PATCH 0413/1007] [vagrant] Remove redundant configuration block. --- Vagrantfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index 30b0437ba..dd6370f04 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -69,11 +69,6 @@ def configureProviders(vmCfg, cpus: "2", memory: "2048") end end - vmCfg.vm.provider "virtualbox" do |v| - v.memory = memory - v.cpus = cpus - end - return vmCfg end From a83a22200a940591d9a1ad626149fd8cf146e2f0 Mon Sep 17 00:00:00 2001 From: Jesse Stuart <hi@jessestuart.com> Date: Thu, 18 Jan 2018 04:32:20 -0500 Subject: [PATCH 0414/1007] [docs] More typo fixes + cleanup. --- CONTRIBUTING.md | 168 ++++++++++++++++++++++++++++-------------------- 1 file changed, 99 insertions(+), 69 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 78f06cf84..36381a833 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,46 +1,46 @@ # Contributing to Packer -**First:** if you're unsure or afraid of _anything_, just ask -or submit the issue or pull request anyways. You won't be yelled at for -giving your best effort. The worst that can happen is that you'll be -politely asked to change something. We appreciate any sort of contributions, -and don't want a wall of rules to get in the way of that. +**First:** if you're unsure or afraid of _anything_, just ask or submit the +issue or pull request anyways. You won't be yelled at for giving your best +effort. The worst that can happen is that you'll be politely asked to change +something. We appreciate any sort of contributions, and don't want a wall of +rules to get in the way of that. -However, for those individuals who want a bit more guidance on the -best way to contribute to the project, read on. This document will cover -what we're looking for. By addressing all the points we're looking for, -it raises the chances we can quickly merge or address your contributions. +However, for those individuals who want a bit more guidance on the best way to +contribute to the project, read on. This document will cover what we're looking +for. By addressing all the points we're looking for, it raises the chances we +can quickly merge or address your contributions. ## Issues ### Reporting an Issue -* Make sure you test against the latest released version. It is possible - we already fixed the bug you're experiencing. +* Make sure you test against the latest released version. It is possible we + already fixed the bug you're experiencing. -* Run the command with debug output with the environment variable - `PACKER_LOG`. For example: `PACKER_LOG=1 packer build template.json`. Take - the _entire_ output and create a [gist](https://gist.github.com) for linking - to in your issue. Packer should strip sensitive keys from the output, - but take a look through just in case. +* Run the command with debug output with the environment variable `PACKER_LOG`. + For example: `PACKER_LOG=1 packer build template.json`. Take the _entire_ + output and create a [gist](https://gist.github.com) for linking to in your + issue. Packer should strip sensitive keys from the output, but take a look + through just in case. -* Provide a reproducible test case. If a contributor can't reproduce an - issue, then it dramatically lowers the chances it'll get fixed. And in - some cases, the issue will eventually be closed. +* Provide a reproducible test case. If a contributor can't reproduce an issue, + then it dramatically lowers the chances it'll get fixed. And in some cases, + the issue will eventually be closed. -* Respond promptly to any questions made by the Packer team to your issue. - Stale issues will be closed. +* Respond promptly to any questions made by the Packer team to your issue. Stale + issues will be closed. ### Issue Lifecycle 1. The issue is reported. 2. The issue is verified and categorized by a Packer collaborator. - Categorization is done via tags. For example, bugs are marked as "bugs" - and easy fixes are marked as "easy". + Categorization is done via tags. For example, bugs are marked as "bugs" and + easy fixes are marked as "easy". -3. Unless it is critical, the issue is left for a period of time (sometimes - many weeks), giving outside contributors a chance to address the issue. +3. Unless it is critical, the issue is left for a period of time (sometimes many + weeks), giving outside contributors a chance to address the issue. 4. The issue is addressed in a pull request or commit. The issue will be referenced in the commit message so that the code that fixes it is clearly @@ -50,85 +50,108 @@ it raises the chances we can quickly merge or address your contributions. ## Setting up Go to work on Packer -If you have never worked with Go before, you will have to complete the -following steps in order to be able to compile and test Packer. These instructions target POSIX-like environments (Mac OS X, Linux, Cygwin, etc.) so you may need to adjust them for Windows or other shells. +If you have never worked with Go before, you will have to complete the following +steps in order to be able to compile and test Packer. These instructions target +POSIX-like environments (Mac OS X, Linux, Cygwin, etc.) so you may need to +adjust them for Windows or other shells. -1. [Download](https://golang.org/dl) and install Go. The instructions below - are for go 1.7. Earlier versions of Go are no longer supported. +1. [Download](https://golang.org/dl) and install Go. The instructions below are + for go 1.7. Earlier versions of Go are no longer supported. 2. Set and export the `GOPATH` environment variable and update your `PATH`. For - example, you can add to your `.bash_profile`. + example, you can add the following to your `.bash_profile` (or comparable + shell startup scripts): - ``` - export GOPATH=$HOME/go - export PATH=$PATH:$GOPATH/bin - ``` +``` +export GOPATH=$HOME/go +export PATH=$PATH:$GOPATH/bin +``` -3. Download the Packer source (and its dependencies) by running `go get github.com/hashicorp/packer`. This will download the Packer source to +3. Download the Packer source (and its dependencies) by running + `go get github.com/hashicorp/packer`. This will download the Packer source to `$GOPATH/src/github.com/hashicorp/packer`. -4. When working on packer `cd $GOPATH/src/github.com/hashicorp/packer` so you - can run `make` and easily access other files. Run `make help` to get +4. When working on Packer, first `cd` into `$GOPATH/src/github.com/hashicorp/packer` + so you can run `make` and easily access other files. Run `make help` to get information about make targets. 5. Make your changes to the Packer source. You can run `make` in - `$GOPATH/src/github.com/hashicorp/packer` to run tests and build the packer + `$GOPATH/src/github.com/hashicorp/packer` to run tests and build the Packer binary. Any compilation errors will be shown when the binaries are - rebuilding. If you don't have `make` you can simply run `go build -o bin/packer .` from the project root. + rebuilding. If you don't have `make` you can simply run + `go build -o bin/packer .` from the project root. -6. After running building packer successfully, use +6. After running building Packer successfully, use `$GOPATH/src/github.com/hashicorp/packer/bin/packer` to build a machine and - verify your changes work. For instance: `$GOPATH/src/github.com/hashicorp/packer/bin/packer build template.json`. + verify your changes work. For instance: + `$GOPATH/src/github.com/hashicorp/packer/bin/packer build template.json`. -7. If everything works well and the tests pass, run `go fmt` on your code - before submitting a pull-request. +7. If everything works well and the tests pass, run `go fmt` on your code before + submitting a pull-request. ### Opening an Pull Request -When you are ready to open a pull-request, you will need to [fork packer](https://github.com/hashicorp/packer#fork-destination-box), push your changes to your fork, and then open a pull-request. +When you are ready to open a pull-request, you will need to +[fork Packer](https://github.com/hashicorp/packer#fork-destination-box), push +your changes to your fork, and then open a pull-request. -For example, my github username is `cbednarski` so I would do the following: +For example, my github username is `cbednarski`, so I would do the following: - git checkout -b f-my-feature - // develop a patch - git push https://github.com/cbednarski/packer f-my-feature +``` +$ git checkout -b f-my-feature +# Develop a patch. +$ git push https://github.com/cbednarski/Packer f-my-feature +``` From there, open your fork in your browser to open a new pull-request. -**Note** Go infers package names from their filepaths. This means `go build` will break if you `git clone` your fork instead of using `go get` on the main packer project. +**Note:** Go infers package names from their file paths. This means `go build` +will break if you `git clone` your fork instead of using `go get` on the main +Packer project. ### Tips for Working on Packer #### Working on forks -The easiest way to work on a fork is to set it as a remote of the packer project. After following the steps in "Setting up Go to work on Packer": +The easiest way to work on a fork is to set it as a remote of the Packer +project. After following the steps in "Setting up Go to work on Packer": -1. Navigate to $GOPATH/src/github.com/hashicorp/packer -2. Add the remote `git remote add <name of remote> <github url of fork>`. For example `git remote add mwhooker https://github.com/mwhooker/packer.git`. +1. Navigate to `$GOPATH/src/github.com/hashicorp/packer` +2. Add the remote by running + `git remote add <name of remote> <github url of fork>`. For example: + `git remote add mwhooker https://github.com/mwhooker/packer.git`. 3. Checkout a feature branch: `git checkout -b new-feature` 4. Make changes -5. (Optional) Push your changes to the fork: `git push -u <name of remote> new-feature` +5. (Optional) Push your changes to the fork: + `git push -u <name of remote> new-feature` -This way you can push to your fork to create a PR, but the code on disk still lives in the spot where the go cli tools are expecting to find it. +This way you can push to your fork to create a PR, but the code on disk still +lives in the spot where the go cli tools are expecting to find it. #### Govendor -If you are submitting a change that requires new or updated dependencies, please include them in `vendor/vendor.json` and in the `vendor/` folder. This helps everything get tested properly in CI. +If you are submitting a change that requires new or updated dependencies, please +include them in `vendor/vendor.json` and in the `vendor/` folder. This helps +everything get tested properly in CI. -Note that you will need to use [govendor](https://github.com/kardianos/govendor) to do this. This step is recommended but not required; if you don't use govendor please indicate in your PR which dependencies have changed and to what versions. +Note that you will need to use [govendor](https://github.com/kardianos/govendor) +to do this. This step is recommended but not required; if you don't use govendor +please indicate in your PR which dependencies have changed and to what versions. Use `govendor fetch <project>` to add dependencies to the project. See -[govendor quick -start](https://github.com/kardianos/govendor#quick-start-also-see-the-faq) for -examples. +[govendor quick start](https://github.com/kardianos/govendor#quick-start-also-see-the-faq) +for examples. -Please only apply the minimal vendor changes to get your PR to work. Packer does not attempt to track the latest version for each dependency. +Please only apply the minimal vendor changes to get your PR to work. Packer does +not attempt to track the latest version for each dependency. #### Running Unit Tests You can run tests for individual packages using commands like this: - $ make test TEST=./builder/amazon/... +``` +$ make test TEST=./builder/amazon/... +``` #### Running Acceptance Tests @@ -136,26 +159,33 @@ Packer has [acceptance tests](https://en.wikipedia.org/wiki/Acceptance_testing) for various builders. These typically require an API key (AWS, GCE), or additional software to be installed on your computer (VirtualBox, VMware). -If you're working on a new builder or builder feature and want verify it is functioning (and also hasn't broken anything else), we recommend running the +If you're working on a new builder or builder feature and want verify it is +functioning (and also hasn't broken anything else), we recommend running the acceptance tests. **Warning:** The acceptance tests create/destroy/modify _real resources_, which -may incur costs for real money. In the presence of a bug, it is possible that resources may be left behind, which can cost money even though you were not using them. We recommend running tests in an account used only for that purpose so it is easy to see if there are any dangling resources, and so production resources are not accidentally destroyed or overwritten during testing. +may incur costs for real money. In the presence of a bug, it is possible that +resources may be left behind, which can cost money even though you were not +using them. We recommend running tests in an account used only for that purpose +so it is easy to see if there are any dangling resources, and so production +resources are not accidentally destroyed or overwritten during testing. To run the acceptance tests, invoke `make testacc`: - $ make testacc TEST=./builder/amazon/ebs - ... +``` +$ make testacc TEST=./builder/amazon/ebs +$ ... +``` The `TEST` variable lets you narrow the scope of the acceptance tests to a -specific package / folder. The `TESTARGS` variable is recommended to filter -down to a specific resource to test, since testing all of them at once can -sometimes take a very long time. +specific package / folder. The `TESTARGS` variable is recommended to filter down +to a specific resource to test, since testing all of them at once can sometimes +take a very long time. To run only a specific test, use the `-run` argument: ``` -make testacc TEST=./builder/amazon/ebs TESTARGS="-run TestBuilderAcc_forceDeleteSnapshot" +$ make testacc TEST=./builder/amazon/ebs TESTARGS="-run TestBuilderAcc_forceDeleteSnapshot" ``` Acceptance tests typically require other environment variables to be set for From 95f60f61531916832e900d4906b675d2dd3f27f5 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 22:43:08 -0600 Subject: [PATCH 0415/1007] Modified common/config.go to accommodate some of the new DownloadableURL policies made by the PR #5761 merge. common/config.go: Added the ability for DownloadableURL to promote UNC paths to the SMB uri. Modified DownloadableURL to include the "./" prefix when a relative path is passed to it. Fix-up the DownloadableURL argument if on windows and incorrectly prefixed with "/". --- common/config.go | 50 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/common/config.go b/common/config.go index c79710221..a3723b40a 100644 --- a/common/config.go +++ b/common/config.go @@ -74,18 +74,40 @@ func SupportedURL(u *url.URL) bool { func DownloadableURL(original string) (string, error) { var result string + // Check that the user specified a UNC path, and promote it to an smb:// uri. + if strings.HasPrefix(original, "\\\\") && len(original) > 2 && original[2] != '?' { + result = filepath.ToSlash(original[2:]) + return fmt.Sprintf("smb://%s", result), nil + } + // Fix the url if it's using bad characters commonly mistaken with a path. original = filepath.ToSlash(original) - // Check to see that this is a parseable URL with a scheme. If so, then just pass it through. + // Check to see that this is a parseable URL with a scheme and a host. + // If so, then just pass it through. if u, err := url.Parse(original); err == nil && u.Scheme != "" && u.Host != "" { - return filepath.ToSlash(original), nil + return original, nil } - // Since it's not a url, this might be a path. So, check that the file exists, - // then make it an absolute path so we can make a proper uri. - if _, err := os.Stat(original); err == nil { - result, err = filepath.Abs(filepath.FromSlash(original)) + // If it's a file scheme, then convert it back to a regular path so the next + // case which forces it to an absolute path, will correct it. + if u, err := url.Parse(original); err == nil && strings.ToLower(u.Scheme) == "file" { + original = u.Path + } + + // If we're on Windows and we start with a slash, then this absolute path + // is wrong. Fix it up, so the next case can figure out the absolute path. + if rpath := strings.SplitN(original, "/", 2); rpath[0] == "" && runtime.GOOS == "windows" { + result = rpath[1] + } else { + result = original + } + + // Since we should be some kind of path (relative or absolute), check + // that the file exists, then make it an absolute path so we can return an + // absolute uri. + if _, err := os.Stat(result); err == nil { + result, err = filepath.Abs(filepath.FromSlash(result)) if err != nil { return "", err } @@ -96,15 +118,17 @@ func DownloadableURL(original string) (string, error) { } result = filepath.Clean(result) - result = filepath.ToSlash(result) - - // We have no idea what this might be, so we'll leave it as is. - } else { - result = filepath.ToSlash(original) + return fmt.Sprintf("file:///%s", filepath.ToSlash(result)), nil } - // We should have a path that can just turn into a file:// scheme'd url. - return fmt.Sprintf("file://%s", result), nil + // Otherwise, check if it was originally an absolute path, and fix it if so. + if strings.HasPrefix(original, "/") { + return fmt.Sprintf("file:///%s", result), nil + } + + // Anything left should be a non-existent relative path. So fix it up here. + result = filepath.ToSlash(filepath.Clean(result)) + return fmt.Sprintf("file://./%s", result), nil } // Force the parameter into a url. This will transform the parameter into From 15079a99dc42560122e7afa592140f99ad8370e7 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 23:08:22 -0600 Subject: [PATCH 0416/1007] Fixed common/config_test.go tests for DownloadableURL to avoid writing to disk on the windows platform. Also added tests for relative paths/uris. common/config_test.go: Replaced instances of os.Mkdir and os.Create with tests that use the existing "common/test-fixtures" mechanism. Removed the runtime.GOOS test for the "FileExistsLocally" test, as the functionality should work regardless of the platform. Added some more comprehensive tests for the relative uri/pathing. Replaced the Windows Object Manager name test as the Object Manager's naming scheme is different from a UNC path. Modified the FilePaths tests to support the policy of windows absolute paths being prefixed with the `/` introduced with PR #5761. --- common/config_test.go | 196 ++++++++++++++++++++++++++---------------- 1 file changed, 120 insertions(+), 76 deletions(-) diff --git a/common/config_test.go b/common/config_test.go index af26aeefa..55fb69a85 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -95,67 +95,116 @@ func TestValidatedURL(t *testing.T) { } } +func GetNativePathToTestFixtures(t *testing.T) string { + const path = "./test-fixtures" + res, err := filepath.Abs(path) + if err != nil { + t.Fatalf("err converting test-fixtures path into an absolute path : %s", err) + } + return res +} + +func GetPortablePathToTestFixtures(t *testing.T) string { + res := GetNativePathToTestFixtures(t) + return filepath.ToSlash(res) +} + func TestDownloadableURL_WindowsFiles(t *testing.T) { if runtime.GOOS == "windows" { + portablepath := GetPortablePathToTestFixtures(t) + nativepath := GetNativePathToTestFixtures(t) + dirCases := []struct { InputString string OutputURL string ErrExpected bool }{ // TODO: add different directories { - "C:\\Temp\\SomeDir\\myfile.txt", - "file:///C:/Temp/SomeDir/myfile.txt", + fmt.Sprintf("%s\\SomeDir\\myfile.txt", nativepath), + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), false, }, - { // need windows drive - "\\Temp\\SomeDir\\myfile.txt", - "", - true, - }, - { // need windows drive - "/Temp/SomeDir/myfile.txt", - "", - true, - }, - { // UNC paths; why not? - "\\\\?\\c:\\Temp\\SomeDir\\myfile.txt", - "", - true, - }, - { - "file:///C:\\Temp\\SomeDir\\myfile.txt", - "file:///c:/Temp/SomeDir/myfile.txt", + { // without the drive makes this native path a relative file:// uri + "test-fixtures\\SomeDir\\myfile.txt", + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), false, }, - { - "file:///c:/Temp/Somedir/myfile.txt", - "file:///c:/Temp/SomeDir/myfile.txt", + { // without the drive makes this native path a relative file:// uri + "test-fixtures/SomeDir/myfile.txt", + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // UNC paths being promoted to smb:// uri scheme. + fmt.Sprintf("\\\\localhost\\C$\\%s\\SomeDir\\myfile.txt", nativepath), + fmt.Sprintf("smb://localhost/C$/%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // Absolute uri (incorrect slash type) + fmt.Sprintf("file:///%s\\SomeDir\\myfile.txt", nativepath), + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // Absolute uri (existing and mis-spelled) + fmt.Sprintf("file:///%s/Somedir/myfile.txt", nativepath), + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // Absolute path (non-existing) + "\\absolute\\path\\to\\non-existing\\file.txt", + "file:///absolute/path/to/non-existing/file.txt", + false, + }, + { // Absolute paths (existing) + fmt.Sprintf("%s/SomeDir/myfile.txt", nativepath), + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // Relative path (non-existing) + "./nonexisting/relative/path/to/file.txt", + "file://./nonexisting/relative/path/to/file.txt", + false, + }, + { // Relative path (existing) + "./test-fixtures/SomeDir/myfile.txt", + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // Absolute uri (existing and with `/` prefix) + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), + false, + }, + { // Absolute uri (non-existing and with `/` prefix) + "file:///path/to/non-existing/file.txt", + "file:///path/to/non-existing/file.txt", + false, + }, + { // Absolute uri (non-existing and missing `/` prefix) + "file://path/to/non-existing/file.txt", + "file://path/to/non-existing/file.txt", + false, + }, + { // Absolute uri and volume (non-existing and with `/` prefix) + "file:///T:/path/to/non-existing/file.txt", + "file:///T:/path/to/non-existing/file.txt", + false, + }, + { // Absolute uri and volume (non-existing and missing `/` prefix) + "file://T:/path/to/non-existing/file.txt", + "file://T:/path/to/non-existing/file.txt", false, }, } - // create absolute-pathed tempfile to play with - err := os.Mkdir("C:\\Temp\\SomeDir", 0755) - if err != nil { - t.Fatalf("err creating test dir: %s", err) - } - fi, err := os.Create("C:\\Temp\\SomeDir\\myfile.txt") - if err != nil { - t.Fatalf("err creating test file: %s", err) - } - fi.Close() - defer os.Remove("C:\\Temp\\SomeDir\\myfile.txt") - defer os.Remove("C:\\Temp\\SomeDir") - // Run through test cases to make sure they all parse correctly - for _, tc := range dirCases { + for idx, tc := range dirCases { u, err := DownloadableURL(tc.InputString) if (err != nil) != tc.ErrExpected { - t.Fatalf("Test Case failed: Expected err = %#v, err = %#v, input = %s", - tc.ErrExpected, err, tc.InputString) + t.Fatalf("Test Case %d failed: Expected err = %#v, err = %#v, input = %s", + idx, tc.ErrExpected, err, tc.InputString) } if u != tc.OutputURL { - t.Fatalf("Test Case failed: Expected %s but received %s from input %s", - tc.OutputURL, u, tc.InputString) + t.Fatalf("Test Case %d failed: Expected %s but received %s from input %s", + idx, tc.OutputURL, u, tc.InputString) } } } @@ -177,6 +226,12 @@ func TestDownloadableURL_FilePaths(t *testing.T) { tfPath = filepath.Clean(tfPath) filePrefix := "file://" + // If we're running windows, then absolute URIs are `/`-prefixed. + platformPrefix := "" + if runtime.GOOS == "windows" { + platformPrefix = "/" + } + // Relative filepath. We run this test in a func so that // the defers run right away. func() { @@ -197,8 +252,9 @@ func TestDownloadableURL_FilePaths(t *testing.T) { t.Fatalf("err: %s", err) } - expected := fmt.Sprintf("%s%s", + expected := fmt.Sprintf("%s%s%s", filePrefix, + platformPrefix, strings.Replace(tfPath, `\`, `/`, -1)) if u != expected { t.Fatalf("unexpected: %#v != %#v", u, expected) @@ -206,21 +262,22 @@ func TestDownloadableURL_FilePaths(t *testing.T) { }() // Test some cases with and without a schema prefix - for _, prefix := range []string{"", filePrefix} { + for _, prefix := range []string{"", filePrefix + platformPrefix} { // Nonexistent file _, err = DownloadableURL(prefix + "i/dont/exist") if err != nil { t.Fatalf("err: %s", err) } - // Good file + // Good file (absolute) u, err := DownloadableURL(prefix + tfPath) if err != nil { t.Fatalf("err: %s", err) } - expected := fmt.Sprintf("%s%s", + expected := fmt.Sprintf("%s%s%s", filePrefix, + platformPrefix, strings.Replace(tfPath, `\`, `/`, -1)) if u != expected { t.Fatalf("unexpected: %s != %s", u, expected) @@ -229,38 +286,25 @@ func TestDownloadableURL_FilePaths(t *testing.T) { } func test_FileExistsLocally(t *testing.T) { - if runtime.GOOS == "windows" { - dirCases := []struct { - Input string - Output bool - }{ - // file exists locally - {"file:///C:/Temp/SomeDir/myfile.txt", true}, - // file is not supposed to exist locally - {"https://myfile.iso", true}, - // file does not exist locally - {"file:///C/i/dont/exist", false}, - } - // create absolute-pathed tempfile to play with - err := os.Mkdir("C:\\Temp\\SomeDir", 0755) - if err != nil { - t.Fatalf("err creating test dir: %s", err) - } - fi, err := os.Create("C:\\Temp\\SomeDir\\myfile.txt") - if err != nil { - t.Fatalf("err creating test file: %s", err) - } - fi.Close() - defer os.Remove("C:\\Temp\\SomeDir\\myfile.txt") - defer os.Remove("C:\\Temp\\SomeDir") + portablepath := GetPortablePathToTestFixtures(t) - // Run through test cases to make sure they all parse correctly - for _, tc := range dirCases { - fileOK := FileExistsLocally(tc.Input) - if !fileOK { - t.Fatalf("Test Case failed: Expected %#v, received = %#v, input = %s", - tc.Output, fileOK, tc.Input) - } + dirCases := []struct { + Input string + Output bool + }{ + // file exists locally + {fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), true}, + // file is not supposed to exist locally + {"https://myfile.iso", true}, + // file does not exist locally + {"file:///C/i/dont/exist", false}, + } + // Run through test cases to make sure they all parse correctly + for _, tc := range dirCases { + fileOK := FileExistsLocally(tc.Input) + if !fileOK { + t.Fatalf("Test Case failed: Expected %#v, received = %#v, input = %s", + tc.Output, fileOK, tc.Input) } } } From 8a102a42a0131d8e02f35d2362f8038c101718c2 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 23:09:53 -0600 Subject: [PATCH 0417/1007] gofmt -w on common/config{,_test}.go --- common/config.go | 2 +- common/config_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config.go b/common/config.go index a3723b40a..a8ec7d16a 100644 --- a/common/config.go +++ b/common/config.go @@ -6,9 +6,9 @@ import ( "os" "path/filepath" "regexp" + "runtime" "strings" "time" - "runtime" ) // PackerKeyEnv is used to specify the key interval (delay) between keystrokes diff --git a/common/config_test.go b/common/config_test.go index 55fb69a85..35697291d 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -5,9 +5,9 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" "testing" - "runtime" ) func TestChooseString(t *testing.T) { From 7cd5d576d9ab2fa82d4144a69ae381415e87360c Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 23:18:55 -0600 Subject: [PATCH 0418/1007] Updated common/config.go's FileExistsLocally implementation to use the LocalDownloader interface for determining the real file path. --- common/config.go | 53 +++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/common/config.go b/common/config.go index a8ec7d16a..e3fd4baf8 100644 --- a/common/config.go +++ b/common/config.go @@ -177,27 +177,38 @@ func ValidatedURL(original string) (string, error) { func FileExistsLocally(original string) bool { // original should be something like file://C:/my/path.iso + u, _ := url.Parse(original) - fileURL, _ := url.Parse(original) - fileExists := false - - if fileURL.Scheme == "file" { - // on windows, correct URI is file:///c:/blah/blah.iso. - // url.Parse will pull out the scheme "file://" and leave the path as - // "/c:/blah/blah/iso". Here we remove this forward slash on absolute - // Windows file URLs before processing - // see https://blogs.msdn.microsoft.com/ie/2006/12/06/file-uris-in-windows/ - // for more info about valid windows URIs - filePath := fileURL.Path - if runtime.GOOS == "windows" && len(filePath) > 0 && filePath[0] == '/' { - filePath = filePath[1:] - } - _, err := os.Stat(filePath) - if err != nil { - return fileExists - } else { - fileExists = true - } + // First create a dummy downloader so we can figure out which + // protocol to use. + cli := NewDownloadClient(&DownloadConfig{}) + d, ok := cli.config.DownloaderMap[u.Scheme] + if !ok { + return false } - return fileExists + + // Check to see that it's got a Local way of doing things. + local, ok := d.(LocalDownloader) + if !ok { + return false + } + + // Figure out where we're at. + wd, err := os.Getwd() + if err != nil { + return false + } + + // Now figure out the real path to the file. + realpath, err := local.toPath(wd, *u) + if err != nil { + return false + } + + // Finally we can seek the truth via os.Stat. + _, err = os.Stat(realpath) + if err != nil { + return false + } + return true } From 41f4dc3f3dfe41c71578b0a2b231abe7c0ac4f38 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 23:33:44 -0600 Subject: [PATCH 0419/1007] umm...gofmt -w on common/config{,_test}.go from linux instead of windows(?) --- common/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config.go b/common/config.go index e3fd4baf8..2ad5b528e 100644 --- a/common/config.go +++ b/common/config.go @@ -58,7 +58,7 @@ func SupportedURL(u *url.URL) bool { // Iterate through each downloader to see if a protocol was found. ok := false - for scheme, _ := range cli.config.DownloaderMap { + for scheme := range cli.config.DownloaderMap { if strings.ToLower(u.Scheme) == strings.ToLower(scheme) { ok = true } From f9572cb2447a6d334cc559545d94987a8b5a26b4 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 23:48:20 -0600 Subject: [PATCH 0420/1007] Fixed a bug on linux related to forgetting to check the platform for the forward-slash prefix. --- common/config.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/config.go b/common/config.go index 2ad5b528e..fa9dba55b 100644 --- a/common/config.go +++ b/common/config.go @@ -123,7 +123,10 @@ func DownloadableURL(original string) (string, error) { // Otherwise, check if it was originally an absolute path, and fix it if so. if strings.HasPrefix(original, "/") { - return fmt.Sprintf("file:///%s", result), nil + if runtime.GOOS == "windows" { + return fmt.Sprintf("file:///%s", result), nil + } + return fmt.Sprintf("file://%s", result), nil } // Anything left should be a non-existent relative path. So fix it up here. From 97fc9c02a50bb264d1523434524f593e3d155369 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 18 Jan 2018 23:58:24 -0600 Subject: [PATCH 0421/1007] Grr...missed the case that actually mattered on linux. --- common/config.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/common/config.go b/common/config.go index fa9dba55b..6850005d7 100644 --- a/common/config.go +++ b/common/config.go @@ -72,7 +72,12 @@ func SupportedURL(u *url.URL) bool { // and so DownloadableURL will return "file://local/file.iso" // No other transformations are done to the path. func DownloadableURL(original string) (string, error) { - var result string + var absPrefix, result string + + absPrefix = "" + if runtime.GOOS == "windows" { + absPrefix = "/" + } // Check that the user specified a UNC path, and promote it to an smb:// uri. if strings.HasPrefix(original, "\\\\") && len(original) > 2 && original[2] != '?' { @@ -118,15 +123,12 @@ func DownloadableURL(original string) (string, error) { } result = filepath.Clean(result) - return fmt.Sprintf("file:///%s", filepath.ToSlash(result)), nil + return fmt.Sprintf("file://%s%s", absPrefix, filepath.ToSlash(result)), nil } // Otherwise, check if it was originally an absolute path, and fix it if so. if strings.HasPrefix(original, "/") { - if runtime.GOOS == "windows" { - return fmt.Sprintf("file:///%s", result), nil - } - return fmt.Sprintf("file://%s", result), nil + return fmt.Sprintf("file://%s%s", absPrefix, result), nil } // Anything left should be a non-existent relative path. So fix it up here. From 0e0b467da72320f0cc68c8729b9ab785760a54db Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 19 Jan 2018 13:34:01 -0600 Subject: [PATCH 0422/1007] Forgot to check some errors during the adding of files to the floppy disk. This gives users some better information in case packer is unable to add a file...like if there's not enough disk space available. --- common/step_create_floppy.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/common/step_create_floppy.go b/common/step_create_floppy.go index 5f05eea78..d37302d5c 100644 --- a/common/step_create_floppy.go +++ b/common/step_create_floppy.go @@ -155,7 +155,10 @@ func (s *StepCreateFloppy) Run(state multistep.StateBag) multistep.StepAction { } for _, crawlfilename := range crawlDirectoryFiles { - s.Add(cache, crawlfilename) + if err = s.Add(cache, crawlfilename); err != nil { + state.Put("error", fmt.Errorf("Error adding file from floppy_files : %s : %s", filename, err)) + return multistep.ActionHalt + } s.FilesAdded[crawlfilename] = true } @@ -165,7 +168,10 @@ func (s *StepCreateFloppy) Run(state multistep.StateBag) multistep.StepAction { // add just a single file ui.Message(fmt.Sprintf("Copying file: %s", filename)) - s.Add(cache, filename) + if err = s.Add(cache, filename); err != nil { + state.Put("error", fmt.Errorf("Error adding file from floppy_files : %s : %s", filename, err)) + return multistep.ActionHalt + } s.FilesAdded[filename] = true } ui.Message("Done copying files from floppy_files") From ebe995c0ff49d479f41b60f977af724eee54690e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 17:21:10 -0800 Subject: [PATCH 0423/1007] run goimports --- builder/alicloud/ecs/image_config.go | 5 +++-- builder/alicloud/ecs/step_attach_keypair.go | 3 ++- builder/amazon/chroot/communicator_test.go | 3 ++- builder/amazon/chroot/step_copy_files.go | 5 +++-- builder/amazon/chroot/step_early_cleanup.go | 3 ++- builder/amazon/chroot/step_early_unflock.go | 3 ++- builder/amazon/chroot/step_flock.go | 5 +++-- builder/amazon/chroot/step_mount_extra.go | 5 +++-- builder/amazon/ebssurrogate/root_block_device.go | 1 + builder/amazon/instance/builder_test.go | 3 ++- builder/amazon/instance/step_upload_x509_cert.go | 3 ++- builder/azure/arm/authenticate_test.go | 3 ++- builder/azure/arm/azure_error_response_test.go | 5 +++-- builder/azure/arm/inspector.go | 3 ++- builder/azure/arm/openssh_key_pair.go | 3 ++- builder/azure/arm/openssh_key_pair_test.go | 3 ++- builder/azure/arm/resource_resolver.go | 3 ++- builder/azure/arm/step_test.go | 3 ++- builder/azure/arm/template_factory.go | 1 + builder/azure/common/dump_config.go | 3 ++- builder/azure/common/lin/step_generalize_os.go | 3 ++- builder/docker/artifact_export_test.go | 3 ++- builder/docker/artifact_import_test.go | 3 ++- builder/docker/builder_test.go | 3 ++- builder/docker/exec.go | 5 +++-- builder/docker/step_commit.go | 1 + builder/docker/step_commit_test.go | 3 ++- builder/docker/step_connect_docker.go | 3 ++- builder/docker/step_export_test.go | 3 ++- builder/docker/step_pull_test.go | 3 ++- builder/docker/step_run.go | 1 + builder/docker/step_run_test.go | 3 ++- builder/docker/step_temp_dir.go | 5 +++-- builder/docker/step_test.go | 3 ++- builder/googlecompute/artifact_test.go | 3 ++- builder/googlecompute/step_check_existing_image_test.go | 3 ++- builder/googlecompute/step_instance_info_test.go | 3 ++- builder/googlecompute/step_teardown_instance_test.go | 3 ++- builder/googlecompute/step_wait_startup_script_test.go | 3 ++- builder/hyperv/common/run_config.go | 3 ++- builder/hyperv/common/step_create_switch.go | 1 + builder/hyperv/common/step_disable_vlan.go | 1 + builder/hyperv/common/step_enable_integration_service.go | 1 + builder/hyperv/common/step_mount_dvddrive.go | 5 +++-- builder/hyperv/common/step_mount_floppydrive.go | 5 +++-- builder/hyperv/common/step_mount_guest_additions.go | 3 ++- builder/hyperv/common/step_mount_secondary_dvd_images.go | 3 ++- builder/hyperv/common/step_reboot_vm.go | 3 ++- builder/hyperv/common/step_run.go | 3 ++- builder/hyperv/common/step_sleep.go | 3 ++- builder/hyperv/common/step_unmount_dvddrive.go | 1 + builder/hyperv/common/step_unmount_floppydrive.go | 1 + builder/hyperv/common/step_unmount_guest_additions.go | 1 + builder/hyperv/common/step_unmount_secondary_dvd_images.go | 1 + builder/hyperv/common/step_wait_for_install_to_complete.go | 3 ++- builder/hyperv/iso/builder_test.go | 3 ++- builder/hyperv/vmcx/builder_test.go | 5 +++-- builder/lxc/builder.go | 7 ++++--- builder/lxc/communicator.go | 3 ++- builder/lxc/communicator_test.go | 3 ++- builder/lxc/config.go | 5 +++-- builder/lxc/step_export.go | 5 +++-- builder/lxc/step_lxc_create.go | 5 +++-- builder/lxc/step_prepare_output_dir.go | 5 +++-- builder/lxc/step_provision.go | 3 ++- builder/lxc/step_wait_init.go | 5 +++-- builder/lxd/builder.go | 3 ++- builder/lxd/communicator.go | 3 ++- builder/lxd/communicator_test.go | 3 ++- builder/lxd/config.go | 3 ++- builder/lxd/step_lxd_launch.go | 3 ++- builder/lxd/step_provision.go | 3 ++- builder/lxd/step_publish.go | 3 ++- builder/null/artifact_export_test.go | 3 ++- builder/null/builder_test.go | 3 ++- builder/oneandone/builder.go | 3 ++- builder/oneandone/builder_test.go | 3 ++- builder/oneandone/config.go | 5 +++-- builder/oneandone/ssh.go | 1 + builder/oneandone/step_create_server.go | 5 +++-- builder/oneandone/step_create_sshkey.go | 3 ++- builder/openstack/artifact_test.go | 3 ++- builder/openstack/builder_test.go | 3 ++- builder/oracle/oci/artifact.go | 1 + builder/oracle/oci/client/base_client.go | 3 ++- builder/profitbricks/builder.go | 3 ++- builder/profitbricks/builder_test.go | 3 ++- builder/profitbricks/config.go | 3 ++- builder/profitbricks/ssh.go | 1 + builder/profitbricks/step_create_ssh_key.go | 3 ++- builder/qemu/step_boot_wait.go | 3 ++- builder/qemu/step_prepare_output_dir.go | 5 +++-- builder/qemu/step_type_boot_command.go | 3 ++- builder/triton/step_test.go | 3 ++- builder/virtualbox/common/output_config_test.go | 3 ++- builder/virtualbox/common/step_attach_floppy.go | 5 +++-- builder/virtualbox/common/step_attach_floppy_test.go | 3 ++- builder/virtualbox/common/step_attach_guest_additions.go | 3 ++- builder/virtualbox/common/step_export.go | 5 +++-- builder/virtualbox/common/step_export_test.go | 3 ++- builder/virtualbox/common/step_output_dir_test.go | 3 ++- builder/virtualbox/common/step_remove_devices_test.go | 3 ++- builder/virtualbox/common/step_shutdown.go | 5 +++-- builder/virtualbox/common/step_shutdown_test.go | 5 +++-- builder/virtualbox/common/step_suppress_messages.go | 3 ++- builder/virtualbox/common/step_suppress_messages_test.go | 3 ++- builder/virtualbox/common/step_test.go | 3 ++- builder/virtualbox/common/step_upload_version.go | 3 ++- builder/virtualbox/common/step_upload_version_test.go | 3 ++- builder/virtualbox/iso/step_attach_iso.go | 1 + builder/virtualbox/ovf/step_import_test.go | 3 ++- builder/virtualbox/ovf/step_test.go | 3 ++- builder/vmware/common/step_clean_files.go | 5 +++-- builder/vmware/common/step_compact_disk.go | 3 ++- builder/vmware/common/step_output_dir_test.go | 3 ++- builder/vmware/common/step_shutdown.go | 5 +++-- builder/vmware/common/step_suppress_messages.go | 3 ++- builder/vmware/common/step_test.go | 3 ++- builder/vmware/iso/artifact_test.go | 3 ++- builder/vmware/iso/step_create_disk.go | 3 ++- builder/vmware/iso/step_export_test.go | 3 ++- builder/vmware/iso/step_register_test.go | 3 ++- builder/vmware/iso/step_remote_upload.go | 3 ++- builder/vmware/iso/step_test.go | 3 ++- builder/vmware/iso/step_upload_vmx.go | 3 ++- common/multistep_debug.go | 5 +++-- common/step_create_floppy_test.go | 5 +++-- common/step_download_test.go | 3 ++- common/step_provision.go | 5 +++-- common/step_provision_test.go | 3 ++- communicator/ssh/password_test.go | 3 ++- fix/fixer_createtime.go | 3 ++- packer/plugin/builder.go | 3 ++- packer/plugin/client.go | 5 +++-- packer/plugin/hook.go | 3 ++- packer/plugin/post_processor.go | 3 ++- packer/plugin/post_processor_test.go | 3 ++- packer/plugin/provisioner.go | 3 ++- packer/plugin/server.go | 3 ++- packer/rpc/artifact.go | 3 ++- packer/rpc/artifact_test.go | 3 ++- packer/rpc/builder.go | 3 ++- packer/rpc/builder_test.go | 3 ++- packer/rpc/cache.go | 3 ++- packer/rpc/cache_test.go | 3 ++- packer/rpc/communicator_test.go | 3 ++- packer/rpc/hook.go | 3 ++- packer/rpc/hook_test.go | 3 ++- packer/rpc/post_processor_test.go | 3 ++- packer/rpc/provisioner.go | 3 ++- packer/rpc/provisioner_test.go | 3 ++- packer/rpc/ui.go | 3 ++- post-processor/compress/artifact_test.go | 3 ++- post-processor/docker-import/post-processor_test.go | 3 ++- post-processor/docker-push/post-processor_test.go | 3 ++- post-processor/docker-save/post-processor_test.go | 3 ++- post-processor/shell-local/post-processor_test.go | 3 ++- post-processor/vagrant-cloud/artifact_test.go | 3 ++- post-processor/vagrant-cloud/step_create_provider.go | 1 + post-processor/vagrant-cloud/step_create_version.go | 1 + post-processor/vagrant-cloud/step_verify_box.go | 1 + post-processor/vagrant/artifact_test.go | 3 ++- post-processor/vagrant/digitalocean.go | 3 ++- post-processor/vagrant/libvirt.go | 3 ++- post-processor/vagrant/post-processor_test.go | 3 ++- post-processor/vagrant/virtualbox.go | 3 ++- post-processor/vagrant/vmware.go | 3 ++- provisioner/chef-solo/provisioner_test.go | 3 ++- provisioner/salt-masterless/provisioner_test.go | 3 ++- 169 files changed, 350 insertions(+), 181 deletions(-) diff --git a/builder/alicloud/ecs/image_config.go b/builder/alicloud/ecs/image_config.go index c7fed2af6..b987558f9 100644 --- a/builder/alicloud/ecs/image_config.go +++ b/builder/alicloud/ecs/image_config.go @@ -3,10 +3,11 @@ package ecs import ( "fmt" - "github.com/denverdino/aliyungo/common" - "github.com/hashicorp/packer/template/interpolate" "regexp" "strings" + + "github.com/denverdino/aliyungo/common" + "github.com/hashicorp/packer/template/interpolate" ) type AlicloudDiskDevice struct { diff --git a/builder/alicloud/ecs/step_attach_keypair.go b/builder/alicloud/ecs/step_attach_keypair.go index a6cc01381..b28de52b9 100644 --- a/builder/alicloud/ecs/step_attach_keypair.go +++ b/builder/alicloud/ecs/step_attach_keypair.go @@ -3,11 +3,12 @@ package ecs import ( "fmt" + "time" + "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) type stepAttachKeyPar struct { diff --git a/builder/amazon/chroot/communicator_test.go b/builder/amazon/chroot/communicator_test.go index 7017b9e02..43995b79a 100644 --- a/builder/amazon/chroot/communicator_test.go +++ b/builder/amazon/chroot/communicator_test.go @@ -1,8 +1,9 @@ package chroot import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestCommunicator_ImplementsCommunicator(t *testing.T) { diff --git a/builder/amazon/chroot/step_copy_files.go b/builder/amazon/chroot/step_copy_files.go index 534ec268a..e5c8e2215 100644 --- a/builder/amazon/chroot/step_copy_files.go +++ b/builder/amazon/chroot/step_copy_files.go @@ -3,10 +3,11 @@ package chroot import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "path/filepath" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // StepCopyFiles copies some files from the host into the chroot environment. diff --git a/builder/amazon/chroot/step_early_cleanup.go b/builder/amazon/chroot/step_early_cleanup.go index edcef49fc..ebbf3a0ed 100644 --- a/builder/amazon/chroot/step_early_cleanup.go +++ b/builder/amazon/chroot/step_early_cleanup.go @@ -2,9 +2,10 @@ package chroot import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // StepEarlyCleanup performs some of the cleanup steps early in order to diff --git a/builder/amazon/chroot/step_early_unflock.go b/builder/amazon/chroot/step_early_unflock.go index 4b24b8581..b1399c167 100644 --- a/builder/amazon/chroot/step_early_unflock.go +++ b/builder/amazon/chroot/step_early_unflock.go @@ -2,9 +2,10 @@ package chroot import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // StepEarlyUnflock unlocks the flock. diff --git a/builder/amazon/chroot/step_flock.go b/builder/amazon/chroot/step_flock.go index 648ec2acc..711b2581e 100644 --- a/builder/amazon/chroot/step_flock.go +++ b/builder/amazon/chroot/step_flock.go @@ -2,11 +2,12 @@ package chroot import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "os" "path/filepath" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // StepFlock provisions the instance within a chroot. diff --git a/builder/amazon/chroot/step_mount_extra.go b/builder/amazon/chroot/step_mount_extra.go index 3bd8951c7..fb62467ba 100644 --- a/builder/amazon/chroot/step_mount_extra.go +++ b/builder/amazon/chroot/step_mount_extra.go @@ -3,11 +3,12 @@ package chroot import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "os" "os/exec" "syscall" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // StepMountExtra mounts the attached device. diff --git a/builder/amazon/ebssurrogate/root_block_device.go b/builder/amazon/ebssurrogate/root_block_device.go index 2c4849732..7e34b3733 100644 --- a/builder/amazon/ebssurrogate/root_block_device.go +++ b/builder/amazon/ebssurrogate/root_block_device.go @@ -2,6 +2,7 @@ package ebssurrogate import ( "errors" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/amazon/instance/builder_test.go b/builder/amazon/instance/builder_test.go index 56ba3911c..4136d57fe 100644 --- a/builder/amazon/instance/builder_test.go +++ b/builder/amazon/instance/builder_test.go @@ -1,10 +1,11 @@ package instance import ( - "github.com/hashicorp/packer/packer" "io/ioutil" "os" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/builder/amazon/instance/step_upload_x509_cert.go b/builder/amazon/instance/step_upload_x509_cert.go index 1de1aa311..dffcf4d2b 100644 --- a/builder/amazon/instance/step_upload_x509_cert.go +++ b/builder/amazon/instance/step_upload_x509_cert.go @@ -2,9 +2,10 @@ package instance import ( "fmt" + "os" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "os" ) type StepUploadX509Cert struct{} diff --git a/builder/azure/arm/authenticate_test.go b/builder/azure/arm/authenticate_test.go index 2e290bb3d..37d7b0e1b 100644 --- a/builder/azure/arm/authenticate_test.go +++ b/builder/azure/arm/authenticate_test.go @@ -1,8 +1,9 @@ package arm import ( - "github.com/Azure/go-autorest/autorest/azure" "testing" + + "github.com/Azure/go-autorest/autorest/azure" ) // Behavior is the most important thing to assert for ServicePrincipalToken, but diff --git a/builder/azure/arm/azure_error_response_test.go b/builder/azure/arm/azure_error_response_test.go index f077fa6fe..faa429ad1 100644 --- a/builder/azure/arm/azure_error_response_test.go +++ b/builder/azure/arm/azure_error_response_test.go @@ -1,10 +1,11 @@ package arm import ( - "github.com/approvals/go-approval-tests" - "github.com/hashicorp/packer/common/json" "strings" "testing" + + "github.com/approvals/go-approval-tests" + "github.com/hashicorp/packer/common/json" ) const AzureErrorSimple = `{"error":{"code":"ResourceNotFound","message":"The Resource 'Microsoft.Compute/images/PackerUbuntuImage' under resource group 'packer-test00' was not found."}}` diff --git a/builder/azure/arm/inspector.go b/builder/azure/arm/inspector.go index d3fbd4ccd..e760323d5 100644 --- a/builder/azure/arm/inspector.go +++ b/builder/azure/arm/inspector.go @@ -6,10 +6,11 @@ import ( "log" "net/http" + "io" + "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/packer/builder/azure/common/logutil" - "io" ) func chop(data []byte, maxlen int64) string { diff --git a/builder/azure/arm/openssh_key_pair.go b/builder/azure/arm/openssh_key_pair.go index e3b296f33..7b5e771ef 100644 --- a/builder/azure/arm/openssh_key_pair.go +++ b/builder/azure/arm/openssh_key_pair.go @@ -7,8 +7,9 @@ import ( "encoding/base64" "encoding/pem" "fmt" - "golang.org/x/crypto/ssh" "time" + + "golang.org/x/crypto/ssh" ) const ( diff --git a/builder/azure/arm/openssh_key_pair_test.go b/builder/azure/arm/openssh_key_pair_test.go index fae03105e..8dc9cebf2 100644 --- a/builder/azure/arm/openssh_key_pair_test.go +++ b/builder/azure/arm/openssh_key_pair_test.go @@ -1,8 +1,9 @@ package arm import ( - "golang.org/x/crypto/ssh" "testing" + + "golang.org/x/crypto/ssh" ) func TestFart(t *testing.T) { diff --git a/builder/azure/arm/resource_resolver.go b/builder/azure/arm/resource_resolver.go index 993540f13..40f3cd7ef 100644 --- a/builder/azure/arm/resource_resolver.go +++ b/builder/azure/arm/resource_resolver.go @@ -10,8 +10,9 @@ package arm import ( "fmt" - "github.com/Azure/azure-sdk-for-go/arm/compute" "strings" + + "github.com/Azure/azure-sdk-for-go/arm/compute" ) type resourceResolver struct { diff --git a/builder/azure/arm/step_test.go b/builder/azure/arm/step_test.go index 2b10c8781..cf89021c3 100644 --- a/builder/azure/arm/step_test.go +++ b/builder/azure/arm/step_test.go @@ -2,10 +2,11 @@ package arm import ( "fmt" + "testing" + "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/mitchellh/multistep" - "testing" ) func TestProcessStepResultShouldContinueForNonErrors(t *testing.T) { diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index 16fe7bf93..07f2313b5 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -7,6 +7,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/resources/resources" "fmt" + "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/builder/azure/common/template" ) diff --git a/builder/azure/common/dump_config.go b/builder/azure/common/dump_config.go index 8be2c9aa3..73e619e76 100644 --- a/builder/azure/common/dump_config.go +++ b/builder/azure/common/dump_config.go @@ -2,9 +2,10 @@ package common import ( "fmt" - "github.com/mitchellh/reflectwalk" "reflect" "strings" + + "github.com/mitchellh/reflectwalk" ) type walker struct { diff --git a/builder/azure/common/lin/step_generalize_os.go b/builder/azure/common/lin/step_generalize_os.go index c4dacc47f..ba11a9def 100644 --- a/builder/azure/common/lin/step_generalize_os.go +++ b/builder/azure/common/lin/step_generalize_os.go @@ -3,9 +3,10 @@ package lin import ( "bytes" "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) type StepGeneralizeOS struct { diff --git a/builder/docker/artifact_export_test.go b/builder/docker/artifact_export_test.go index 784535f1b..83d522090 100644 --- a/builder/docker/artifact_export_test.go +++ b/builder/docker/artifact_export_test.go @@ -1,8 +1,9 @@ package docker import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestExportArtifact_impl(t *testing.T) { diff --git a/builder/docker/artifact_import_test.go b/builder/docker/artifact_import_test.go index 0a002344c..20aac11ee 100644 --- a/builder/docker/artifact_import_test.go +++ b/builder/docker/artifact_import_test.go @@ -2,8 +2,9 @@ package docker import ( "errors" - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestImportArtifact_impl(t *testing.T) { diff --git a/builder/docker/builder_test.go b/builder/docker/builder_test.go index e196b0b30..546d30dd4 100644 --- a/builder/docker/builder_test.go +++ b/builder/docker/builder_test.go @@ -1,8 +1,9 @@ package docker import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestBuilder_implBuilder(t *testing.T) { diff --git a/builder/docker/exec.go b/builder/docker/exec.go index 95752382f..386c5aa79 100644 --- a/builder/docker/exec.go +++ b/builder/docker/exec.go @@ -2,8 +2,6 @@ package docker import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/iochan" "io" "log" "os/exec" @@ -11,6 +9,9 @@ import ( "strings" "sync" "syscall" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/iochan" ) func runAndStream(cmd *exec.Cmd, ui packer.Ui) error { diff --git a/builder/docker/step_commit.go b/builder/docker/step_commit.go index 94205bc2f..26455670c 100644 --- a/builder/docker/step_commit.go +++ b/builder/docker/step_commit.go @@ -2,6 +2,7 @@ package docker import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/docker/step_commit_test.go b/builder/docker/step_commit_test.go index 29e583f81..dce1b1208 100644 --- a/builder/docker/step_commit_test.go +++ b/builder/docker/step_commit_test.go @@ -2,8 +2,9 @@ package docker import ( "errors" - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func testStepCommitState(t *testing.T) multistep.StateBag { diff --git a/builder/docker/step_connect_docker.go b/builder/docker/step_connect_docker.go index 45cf2d25d..ecbe55c35 100644 --- a/builder/docker/step_connect_docker.go +++ b/builder/docker/step_connect_docker.go @@ -2,9 +2,10 @@ package docker import ( "fmt" - "github.com/mitchellh/multistep" "os/exec" "strings" + + "github.com/mitchellh/multistep" ) type StepConnectDocker struct{} diff --git a/builder/docker/step_export_test.go b/builder/docker/step_export_test.go index d07d547c2..f2d1a069c 100644 --- a/builder/docker/step_export_test.go +++ b/builder/docker/step_export_test.go @@ -3,10 +3,11 @@ package docker import ( "bytes" "errors" - "github.com/mitchellh/multistep" "io/ioutil" "os" "testing" + + "github.com/mitchellh/multistep" ) func testStepExportState(t *testing.T) multistep.StateBag { diff --git a/builder/docker/step_pull_test.go b/builder/docker/step_pull_test.go index 7ba5705d5..aaeff2b2a 100644 --- a/builder/docker/step_pull_test.go +++ b/builder/docker/step_pull_test.go @@ -2,8 +2,9 @@ package docker import ( "errors" - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepPull_impl(t *testing.T) { diff --git a/builder/docker/step_run.go b/builder/docker/step_run.go index 5a56d8d7d..101788682 100644 --- a/builder/docker/step_run.go +++ b/builder/docker/step_run.go @@ -2,6 +2,7 @@ package docker import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/docker/step_run_test.go b/builder/docker/step_run_test.go index 9ce556b12..8c5b08ea3 100644 --- a/builder/docker/step_run_test.go +++ b/builder/docker/step_run_test.go @@ -2,8 +2,9 @@ package docker import ( "errors" - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func testStepRunState(t *testing.T) multistep.StateBag { diff --git a/builder/docker/step_temp_dir.go b/builder/docker/step_temp_dir.go index 7e84b908f..c7312ce49 100644 --- a/builder/docker/step_temp_dir.go +++ b/builder/docker/step_temp_dir.go @@ -2,10 +2,11 @@ package docker import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "io/ioutil" "os" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // StepTempDir creates a temporary directory that we use in order to diff --git a/builder/docker/step_test.go b/builder/docker/step_test.go index 4278fb50d..9eec9a5d8 100644 --- a/builder/docker/step_test.go +++ b/builder/docker/step_test.go @@ -2,9 +2,10 @@ package docker import ( "bytes" + "testing" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/googlecompute/artifact_test.go b/builder/googlecompute/artifact_test.go index 9d028c1a3..bb803056c 100644 --- a/builder/googlecompute/artifact_test.go +++ b/builder/googlecompute/artifact_test.go @@ -1,8 +1,9 @@ package googlecompute import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_impl(t *testing.T) { diff --git a/builder/googlecompute/step_check_existing_image_test.go b/builder/googlecompute/step_check_existing_image_test.go index a7b336407..21f4ee6c2 100644 --- a/builder/googlecompute/step_check_existing_image_test.go +++ b/builder/googlecompute/step_check_existing_image_test.go @@ -1,8 +1,9 @@ package googlecompute import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepCheckExistingImage_impl(t *testing.T) { diff --git a/builder/googlecompute/step_instance_info_test.go b/builder/googlecompute/step_instance_info_test.go index 5b6c01d0a..b8547f2ff 100644 --- a/builder/googlecompute/step_instance_info_test.go +++ b/builder/googlecompute/step_instance_info_test.go @@ -2,9 +2,10 @@ package googlecompute import ( "errors" - "github.com/mitchellh/multistep" "testing" "time" + + "github.com/mitchellh/multistep" ) func TestStepInstanceInfo_impl(t *testing.T) { diff --git a/builder/googlecompute/step_teardown_instance_test.go b/builder/googlecompute/step_teardown_instance_test.go index bd32ea26d..28c6480de 100644 --- a/builder/googlecompute/step_teardown_instance_test.go +++ b/builder/googlecompute/step_teardown_instance_test.go @@ -1,8 +1,9 @@ package googlecompute import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepTeardownInstance_impl(t *testing.T) { diff --git a/builder/googlecompute/step_wait_startup_script_test.go b/builder/googlecompute/step_wait_startup_script_test.go index 93cf108b1..d157c761f 100644 --- a/builder/googlecompute/step_wait_startup_script_test.go +++ b/builder/googlecompute/step_wait_startup_script_test.go @@ -1,9 +1,10 @@ package googlecompute import ( + "testing" + "github.com/mitchellh/multistep" "github.com/stretchr/testify/assert" - "testing" ) func TestStepWaitStartupScript(t *testing.T) { diff --git a/builder/hyperv/common/run_config.go b/builder/hyperv/common/run_config.go index a189a0355..8e29511b7 100644 --- a/builder/hyperv/common/run_config.go +++ b/builder/hyperv/common/run_config.go @@ -2,8 +2,9 @@ package common import ( "fmt" - "github.com/hashicorp/packer/template/interpolate" "time" + + "github.com/hashicorp/packer/template/interpolate" ) type RunConfig struct { diff --git a/builder/hyperv/common/step_create_switch.go b/builder/hyperv/common/step_create_switch.go index 7e5ea2751..1904c9dbd 100644 --- a/builder/hyperv/common/step_create_switch.go +++ b/builder/hyperv/common/step_create_switch.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_disable_vlan.go b/builder/hyperv/common/step_disable_vlan.go index 883ff76c4..fb1454af3 100644 --- a/builder/hyperv/common/step_disable_vlan.go +++ b/builder/hyperv/common/step_disable_vlan.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_enable_integration_service.go b/builder/hyperv/common/step_enable_integration_service.go index 0889bed22..852e3d804 100644 --- a/builder/hyperv/common/step_enable_integration_service.go +++ b/builder/hyperv/common/step_enable_integration_service.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index 1535e86b4..2f800a79c 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -2,11 +2,12 @@ package common import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "path/filepath" "strings" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) type StepMountDvdDrive struct { diff --git a/builder/hyperv/common/step_mount_floppydrive.go b/builder/hyperv/common/step_mount_floppydrive.go index c787b1fe7..d49b155b5 100644 --- a/builder/hyperv/common/step_mount_floppydrive.go +++ b/builder/hyperv/common/step_mount_floppydrive.go @@ -2,13 +2,14 @@ package common import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "io" "io/ioutil" "log" "os" "path/filepath" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) const ( diff --git a/builder/hyperv/common/step_mount_guest_additions.go b/builder/hyperv/common/step_mount_guest_additions.go index 954075d08..fafa92971 100644 --- a/builder/hyperv/common/step_mount_guest_additions.go +++ b/builder/hyperv/common/step_mount_guest_additions.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) type StepMountGuestAdditions struct { diff --git a/builder/hyperv/common/step_mount_secondary_dvd_images.go b/builder/hyperv/common/step_mount_secondary_dvd_images.go index 4e7663d40..2b7934a5e 100644 --- a/builder/hyperv/common/step_mount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_mount_secondary_dvd_images.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) type StepMountSecondaryDvdImages struct { diff --git a/builder/hyperv/common/step_reboot_vm.go b/builder/hyperv/common/step_reboot_vm.go index 9446781a2..0ba777e6f 100644 --- a/builder/hyperv/common/step_reboot_vm.go +++ b/builder/hyperv/common/step_reboot_vm.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "time" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) type StepRebootVm struct { diff --git a/builder/hyperv/common/step_run.go b/builder/hyperv/common/step_run.go index 12d621e1c..050c76f50 100644 --- a/builder/hyperv/common/step_run.go +++ b/builder/hyperv/common/step_run.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "time" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) type StepRun struct { diff --git a/builder/hyperv/common/step_sleep.go b/builder/hyperv/common/step_sleep.go index 23f7e344f..ea262d010 100644 --- a/builder/hyperv/common/step_sleep.go +++ b/builder/hyperv/common/step_sleep.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "time" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) type StepSleep struct { diff --git a/builder/hyperv/common/step_unmount_dvddrive.go b/builder/hyperv/common/step_unmount_dvddrive.go index 7ba748f2f..d8ba2033b 100644 --- a/builder/hyperv/common/step_unmount_dvddrive.go +++ b/builder/hyperv/common/step_unmount_dvddrive.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_unmount_floppydrive.go b/builder/hyperv/common/step_unmount_floppydrive.go index 2d271584d..e67279a5f 100644 --- a/builder/hyperv/common/step_unmount_floppydrive.go +++ b/builder/hyperv/common/step_unmount_floppydrive.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_unmount_guest_additions.go b/builder/hyperv/common/step_unmount_guest_additions.go index b47e969d1..da35a06e2 100644 --- a/builder/hyperv/common/step_unmount_guest_additions.go +++ b/builder/hyperv/common/step_unmount_guest_additions.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_unmount_secondary_dvd_images.go b/builder/hyperv/common/step_unmount_secondary_dvd_images.go index e59ad6014..ec42923f6 100644 --- a/builder/hyperv/common/step_unmount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_unmount_secondary_dvd_images.go @@ -2,6 +2,7 @@ package common import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/builder/hyperv/common/step_wait_for_install_to_complete.go b/builder/hyperv/common/step_wait_for_install_to_complete.go index 51736ddb5..c002f57ae 100644 --- a/builder/hyperv/common/step_wait_for_install_to_complete.go +++ b/builder/hyperv/common/step_wait_for_install_to_complete.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "time" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) const ( diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 383ab5b30..7315b4950 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -6,10 +6,11 @@ import ( "strconv" "testing" + "os" + hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "os" ) func testConfig() map[string]interface{} { diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index fb7f35c52..aef12c055 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -5,11 +5,12 @@ import ( "reflect" "testing" + "io/ioutil" + "os" + hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "io/ioutil" - "os" ) func testConfig() map[string]interface{} { diff --git a/builder/lxc/builder.go b/builder/lxc/builder.go index 31770b740..b45bd3511 100644 --- a/builder/lxc/builder.go +++ b/builder/lxc/builder.go @@ -1,13 +1,14 @@ package lxc import ( + "log" + "os" + "path/filepath" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/multistep" - "log" - "os" - "path/filepath" ) // The unique ID for this builder diff --git a/builder/lxc/communicator.go b/builder/lxc/communicator.go index 6e41ace60..f213fa8a9 100644 --- a/builder/lxc/communicator.go +++ b/builder/lxc/communicator.go @@ -2,7 +2,6 @@ package lxc import ( "fmt" - "github.com/hashicorp/packer/packer" "io" "io/ioutil" "log" @@ -11,6 +10,8 @@ import ( "path/filepath" "strings" "syscall" + + "github.com/hashicorp/packer/packer" ) type LxcAttachCommunicator struct { diff --git a/builder/lxc/communicator_test.go b/builder/lxc/communicator_test.go index 854ba6680..4a81a36a7 100644 --- a/builder/lxc/communicator_test.go +++ b/builder/lxc/communicator_test.go @@ -1,8 +1,9 @@ package lxc import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestCommunicator_ImplementsCommunicator(t *testing.T) { diff --git a/builder/lxc/config.go b/builder/lxc/config.go index 5d49dbfd6..b0736a63f 100644 --- a/builder/lxc/config.go +++ b/builder/lxc/config.go @@ -2,13 +2,14 @@ package lxc import ( "fmt" + "os" + "time" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/mapstructure" - "os" - "time" ) type Config struct { diff --git a/builder/lxc/step_export.go b/builder/lxc/step_export.go index 59e4b79e9..7a0e1ec95 100644 --- a/builder/lxc/step_export.go +++ b/builder/lxc/step_export.go @@ -3,14 +3,15 @@ package lxc import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "io" "log" "os" "os/exec" "path/filepath" "strings" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) type stepExport struct{} diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index d1dbdf2d3..131fc958b 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -3,12 +3,13 @@ package lxc import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "os/exec" "path/filepath" "strings" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) type stepLxcCreate struct{} diff --git a/builder/lxc/step_prepare_output_dir.go b/builder/lxc/step_prepare_output_dir.go index 07c6f08b7..835bbf5a3 100644 --- a/builder/lxc/step_prepare_output_dir.go +++ b/builder/lxc/step_prepare_output_dir.go @@ -1,11 +1,12 @@ package lxc import ( - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "os" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) type stepPrepareOutputDir struct{} diff --git a/builder/lxc/step_provision.go b/builder/lxc/step_provision.go index 0cf2a8bdb..9c54b9603 100644 --- a/builder/lxc/step_provision.go +++ b/builder/lxc/step_provision.go @@ -1,9 +1,10 @@ package lxc import ( + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // StepProvision provisions the instance within a chroot. diff --git a/builder/lxc/step_wait_init.go b/builder/lxc/step_wait_init.go index 1ddda52b6..69ce8a5af 100644 --- a/builder/lxc/step_wait_init.go +++ b/builder/lxc/step_wait_init.go @@ -3,11 +3,12 @@ package lxc import ( "errors" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "strings" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) type StepWaitInit struct { diff --git a/builder/lxd/builder.go b/builder/lxd/builder.go index d59cf5bcf..48a879543 100644 --- a/builder/lxd/builder.go +++ b/builder/lxd/builder.go @@ -1,11 +1,12 @@ package lxd import ( + "log" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/multistep" - "log" ) // The unique ID for this builder diff --git a/builder/lxd/communicator.go b/builder/lxd/communicator.go index 8eaa47a5f..a7ff8b4af 100644 --- a/builder/lxd/communicator.go +++ b/builder/lxd/communicator.go @@ -2,13 +2,14 @@ package lxd import ( "fmt" - "github.com/hashicorp/packer/packer" "io" "log" "os" "os/exec" "path/filepath" "syscall" + + "github.com/hashicorp/packer/packer" ) type Communicator struct { diff --git a/builder/lxd/communicator_test.go b/builder/lxd/communicator_test.go index 4a70160b7..972a5dc18 100644 --- a/builder/lxd/communicator_test.go +++ b/builder/lxd/communicator_test.go @@ -1,8 +1,9 @@ package lxd import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestCommunicator_ImplementsCommunicator(t *testing.T) { diff --git a/builder/lxd/config.go b/builder/lxd/config.go index 6a4745510..ea467f09b 100644 --- a/builder/lxd/config.go +++ b/builder/lxd/config.go @@ -2,12 +2,13 @@ package lxd import ( "fmt" + "time" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/mapstructure" - "time" ) type Config struct { diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index 1ec573b18..d8ad17734 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -2,9 +2,10 @@ package lxd import ( "fmt" + "time" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) type stepLxdLaunch struct{} diff --git a/builder/lxd/step_provision.go b/builder/lxd/step_provision.go index c46b900e7..5fbc9d034 100644 --- a/builder/lxd/step_provision.go +++ b/builder/lxd/step_provision.go @@ -1,9 +1,10 @@ package lxd import ( + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // StepProvision provisions the container diff --git a/builder/lxd/step_publish.go b/builder/lxd/step_publish.go index 31e2d638b..19a8c22af 100644 --- a/builder/lxd/step_publish.go +++ b/builder/lxd/step_publish.go @@ -2,9 +2,10 @@ package lxd import ( "fmt" + "regexp" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "regexp" ) type stepPublish struct{} diff --git a/builder/null/artifact_export_test.go b/builder/null/artifact_export_test.go index aa0540851..917578eff 100644 --- a/builder/null/artifact_export_test.go +++ b/builder/null/artifact_export_test.go @@ -1,8 +1,9 @@ package null import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestNullArtifact(t *testing.T) { diff --git a/builder/null/builder_test.go b/builder/null/builder_test.go index 2f77ccb39..89cf03a24 100644 --- a/builder/null/builder_test.go +++ b/builder/null/builder_test.go @@ -1,8 +1,9 @@ package null import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestBuilder_implBuilder(t *testing.T) { diff --git a/builder/oneandone/builder.go b/builder/oneandone/builder.go index ad470c152..673e35264 100644 --- a/builder/oneandone/builder.go +++ b/builder/oneandone/builder.go @@ -3,11 +3,12 @@ package oneandone import ( "errors" "fmt" + "log" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) const BuilderId = "packer.oneandone" diff --git a/builder/oneandone/builder_test.go b/builder/oneandone/builder_test.go index ae90f72b2..daa8536e3 100644 --- a/builder/oneandone/builder_test.go +++ b/builder/oneandone/builder_test.go @@ -2,8 +2,9 @@ package oneandone import ( "fmt" - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/builder/oneandone/config.go b/builder/oneandone/config.go index e71ef2c9f..ff85bdc6d 100644 --- a/builder/oneandone/config.go +++ b/builder/oneandone/config.go @@ -2,6 +2,9 @@ package oneandone import ( "errors" + "os" + "strings" + "github.com/1and1/oneandone-cloudserver-sdk-go" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -9,8 +12,6 @@ import ( "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/mapstructure" - "os" - "strings" ) type Config struct { diff --git a/builder/oneandone/ssh.go b/builder/oneandone/ssh.go index 33fe0cc01..69fb435e1 100644 --- a/builder/oneandone/ssh.go +++ b/builder/oneandone/ssh.go @@ -2,6 +2,7 @@ package oneandone import ( "fmt" + "github.com/hashicorp/packer/communicator/ssh" "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" diff --git a/builder/oneandone/step_create_server.go b/builder/oneandone/step_create_server.go index 2ad268ff8..7f38311a6 100644 --- a/builder/oneandone/step_create_server.go +++ b/builder/oneandone/step_create_server.go @@ -2,11 +2,12 @@ package oneandone import ( "fmt" + "strings" + "time" + "github.com/1and1/oneandone-cloudserver-sdk-go" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "strings" - "time" ) type stepCreateServer struct{} diff --git a/builder/oneandone/step_create_sshkey.go b/builder/oneandone/step_create_sshkey.go index 0ad089c23..e4174ef5d 100644 --- a/builder/oneandone/step_create_sshkey.go +++ b/builder/oneandone/step_create_sshkey.go @@ -4,10 +4,11 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "io/ioutil" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" - "io/ioutil" ) type StepCreateSSHKey struct { diff --git a/builder/openstack/artifact_test.go b/builder/openstack/artifact_test.go index 20f5fe3b5..5cf2b5834 100644 --- a/builder/openstack/artifact_test.go +++ b/builder/openstack/artifact_test.go @@ -1,8 +1,9 @@ package openstack import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_Impl(t *testing.T) { diff --git a/builder/openstack/builder_test.go b/builder/openstack/builder_test.go index 14fb8f2f9..42d78ee33 100644 --- a/builder/openstack/builder_test.go +++ b/builder/openstack/builder_test.go @@ -1,8 +1,9 @@ package openstack import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/builder/oracle/oci/artifact.go b/builder/oracle/oci/artifact.go index 6684468fc..e237d48e4 100644 --- a/builder/oracle/oci/artifact.go +++ b/builder/oracle/oci/artifact.go @@ -2,6 +2,7 @@ package oci import ( "fmt" + client "github.com/hashicorp/packer/builder/oracle/oci/client" ) diff --git a/builder/oracle/oci/client/base_client.go b/builder/oracle/oci/client/base_client.go index 7270687e7..b2fd31d9b 100644 --- a/builder/oracle/oci/client/base_client.go +++ b/builder/oracle/oci/client/base_client.go @@ -3,9 +3,10 @@ package oci import ( "bytes" "encoding/json" - "github.com/google/go-querystring/query" "net/http" "net/url" + + "github.com/google/go-querystring/query" ) const ( diff --git a/builder/profitbricks/builder.go b/builder/profitbricks/builder.go index 750b843c0..42dc148d3 100644 --- a/builder/profitbricks/builder.go +++ b/builder/profitbricks/builder.go @@ -2,11 +2,12 @@ package profitbricks import ( "fmt" + "log" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) const BuilderId = "packer.profitbricks" diff --git a/builder/profitbricks/builder_test.go b/builder/profitbricks/builder_test.go index 70b73226f..98252b410 100644 --- a/builder/profitbricks/builder_test.go +++ b/builder/profitbricks/builder_test.go @@ -2,8 +2,9 @@ package profitbricks import ( "fmt" - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/builder/profitbricks/config.go b/builder/profitbricks/config.go index bb4e8d37f..b38b8583c 100644 --- a/builder/profitbricks/config.go +++ b/builder/profitbricks/config.go @@ -2,13 +2,14 @@ package profitbricks import ( "errors" + "os" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/mapstructure" - "os" ) type Config struct { diff --git a/builder/profitbricks/ssh.go b/builder/profitbricks/ssh.go index a40959cc7..3b0c93f31 100644 --- a/builder/profitbricks/ssh.go +++ b/builder/profitbricks/ssh.go @@ -2,6 +2,7 @@ package profitbricks import ( "fmt" + "github.com/hashicorp/packer/communicator/ssh" "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" diff --git a/builder/profitbricks/step_create_ssh_key.go b/builder/profitbricks/step_create_ssh_key.go index 0afccb494..963afdf8c 100644 --- a/builder/profitbricks/step_create_ssh_key.go +++ b/builder/profitbricks/step_create_ssh_key.go @@ -4,10 +4,11 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "io/ioutil" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" - "io/ioutil" ) type StepCreateSSHKey struct { diff --git a/builder/qemu/step_boot_wait.go b/builder/qemu/step_boot_wait.go index 3e4e48320..36625b8df 100644 --- a/builder/qemu/step_boot_wait.go +++ b/builder/qemu/step_boot_wait.go @@ -2,9 +2,10 @@ package qemu import ( "fmt" + "time" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "time" ) // stepBootWait waits the configured time period. diff --git a/builder/qemu/step_prepare_output_dir.go b/builder/qemu/step_prepare_output_dir.go index 7023ac9b8..b5f96c5ca 100644 --- a/builder/qemu/step_prepare_output_dir.go +++ b/builder/qemu/step_prepare_output_dir.go @@ -1,11 +1,12 @@ package qemu import ( - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "os" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) type stepPrepareOutputDir struct{} diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index 526a792e3..97e05b7ea 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -10,12 +10,13 @@ import ( "unicode" "unicode/utf8" + "os" + "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/go-vnc" "github.com/mitchellh/multistep" - "os" ) const KeyLeftShift uint32 = 0xFFE1 diff --git a/builder/triton/step_test.go b/builder/triton/step_test.go index 61580edfe..fe647b42f 100644 --- a/builder/triton/step_test.go +++ b/builder/triton/step_test.go @@ -2,9 +2,10 @@ package triton import ( "bytes" + "testing" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/virtualbox/common/output_config_test.go b/builder/virtualbox/common/output_config_test.go index 08cff37d1..3a87dc18f 100644 --- a/builder/virtualbox/common/output_config_test.go +++ b/builder/virtualbox/common/output_config_test.go @@ -1,10 +1,11 @@ package common import ( - "github.com/hashicorp/packer/common" "io/ioutil" "os" "testing" + + "github.com/hashicorp/packer/common" ) func TestOutputConfigPrepare(t *testing.T) { diff --git a/builder/virtualbox/common/step_attach_floppy.go b/builder/virtualbox/common/step_attach_floppy.go index 238619551..35c8d1822 100644 --- a/builder/virtualbox/common/step_attach_floppy.go +++ b/builder/virtualbox/common/step_attach_floppy.go @@ -2,13 +2,14 @@ package common import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "io" "io/ioutil" "log" "os" "path/filepath" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // This step attaches the ISO to the virtual machine. diff --git a/builder/virtualbox/common/step_attach_floppy_test.go b/builder/virtualbox/common/step_attach_floppy_test.go index 110ddfe74..93d62b6d8 100644 --- a/builder/virtualbox/common/step_attach_floppy_test.go +++ b/builder/virtualbox/common/step_attach_floppy_test.go @@ -1,10 +1,11 @@ package common import ( - "github.com/mitchellh/multistep" "io/ioutil" "os" "testing" + + "github.com/mitchellh/multistep" ) func TestStepAttachFloppy_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_attach_guest_additions.go b/builder/virtualbox/common/step_attach_guest_additions.go index de51237a5..0d883f817 100644 --- a/builder/virtualbox/common/step_attach_guest_additions.go +++ b/builder/virtualbox/common/step_attach_guest_additions.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // This step attaches the VirtualBox guest additions as a inserted CD onto diff --git a/builder/virtualbox/common/step_export.go b/builder/virtualbox/common/step_export.go index adc04e40f..dab7d9ac3 100644 --- a/builder/virtualbox/common/step_export.go +++ b/builder/virtualbox/common/step_export.go @@ -2,12 +2,13 @@ package common import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "path/filepath" "strings" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // This step cleans up forwarded ports and exports the VM to an OVF. diff --git a/builder/virtualbox/common/step_export_test.go b/builder/virtualbox/common/step_export_test.go index 0a939d331..30723bae7 100644 --- a/builder/virtualbox/common/step_export_test.go +++ b/builder/virtualbox/common/step_export_test.go @@ -1,8 +1,9 @@ package common import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepExport_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_output_dir_test.go b/builder/virtualbox/common/step_output_dir_test.go index 77d1f855f..c742b5ddd 100644 --- a/builder/virtualbox/common/step_output_dir_test.go +++ b/builder/virtualbox/common/step_output_dir_test.go @@ -1,10 +1,11 @@ package common import ( - "github.com/mitchellh/multistep" "io/ioutil" "os" "testing" + + "github.com/mitchellh/multistep" ) func testStepOutputDir(t *testing.T) *StepOutputDir { diff --git a/builder/virtualbox/common/step_remove_devices_test.go b/builder/virtualbox/common/step_remove_devices_test.go index 6e6e28f79..705648e33 100644 --- a/builder/virtualbox/common/step_remove_devices_test.go +++ b/builder/virtualbox/common/step_remove_devices_test.go @@ -1,8 +1,9 @@ package common import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepRemoveDevices_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_shutdown.go b/builder/virtualbox/common/step_shutdown.go index 82bcb05ab..11a7cb3ac 100644 --- a/builder/virtualbox/common/step_shutdown.go +++ b/builder/virtualbox/common/step_shutdown.go @@ -3,10 +3,11 @@ package common import ( "errors" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // This step shuts down the machine. It first attempts to do so gracefully, diff --git a/builder/virtualbox/common/step_shutdown_test.go b/builder/virtualbox/common/step_shutdown_test.go index 769ed64f0..f83c65a8d 100644 --- a/builder/virtualbox/common/step_shutdown_test.go +++ b/builder/virtualbox/common/step_shutdown_test.go @@ -1,10 +1,11 @@ package common import ( - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "testing" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) func TestStepShutdown_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_suppress_messages.go b/builder/virtualbox/common/step_suppress_messages.go index 863606526..d6b2dcbbe 100644 --- a/builder/virtualbox/common/step_suppress_messages.go +++ b/builder/virtualbox/common/step_suppress_messages.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // This step sets some variables in VirtualBox so that annoying diff --git a/builder/virtualbox/common/step_suppress_messages_test.go b/builder/virtualbox/common/step_suppress_messages_test.go index 44612ecbc..69c947835 100644 --- a/builder/virtualbox/common/step_suppress_messages_test.go +++ b/builder/virtualbox/common/step_suppress_messages_test.go @@ -2,8 +2,9 @@ package common import ( "errors" - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepSuppressMessages_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_test.go b/builder/virtualbox/common/step_test.go index c6424b692..140f6f619 100644 --- a/builder/virtualbox/common/step_test.go +++ b/builder/virtualbox/common/step_test.go @@ -2,9 +2,10 @@ package common import ( "bytes" + "testing" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/virtualbox/common/step_upload_version.go b/builder/virtualbox/common/step_upload_version.go index ab1ca6c7f..c9481c49b 100644 --- a/builder/virtualbox/common/step_upload_version.go +++ b/builder/virtualbox/common/step_upload_version.go @@ -3,9 +3,10 @@ package common import ( "bytes" "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // This step uploads a file containing the VirtualBox version, which diff --git a/builder/virtualbox/common/step_upload_version_test.go b/builder/virtualbox/common/step_upload_version_test.go index 1414a2278..8aaf9cc90 100644 --- a/builder/virtualbox/common/step_upload_version_test.go +++ b/builder/virtualbox/common/step_upload_version_test.go @@ -1,9 +1,10 @@ package common import ( + "testing" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func TestStepUploadVersion_impl(t *testing.T) { diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index a997ee823..1eb87ff92 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -2,6 +2,7 @@ package iso import ( "fmt" + vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" diff --git a/builder/virtualbox/ovf/step_import_test.go b/builder/virtualbox/ovf/step_import_test.go index fd204c042..dcaf013b5 100644 --- a/builder/virtualbox/ovf/step_import_test.go +++ b/builder/virtualbox/ovf/step_import_test.go @@ -1,9 +1,10 @@ package ovf import ( + "testing" + vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/mitchellh/multistep" - "testing" ) func TestStepImport_impl(t *testing.T) { diff --git a/builder/virtualbox/ovf/step_test.go b/builder/virtualbox/ovf/step_test.go index cbd18dbd5..805d435bc 100644 --- a/builder/virtualbox/ovf/step_test.go +++ b/builder/virtualbox/ovf/step_test.go @@ -2,10 +2,11 @@ package ovf import ( "bytes" + "testing" + vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/common/step_clean_files.go b/builder/vmware/common/step_clean_files.go index 6dc1a730c..b6d81293f 100644 --- a/builder/vmware/common/step_clean_files.go +++ b/builder/vmware/common/step_clean_files.go @@ -2,10 +2,11 @@ package common import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "os" "path/filepath" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // These are the extensions of files that are important for the function diff --git a/builder/vmware/common/step_compact_disk.go b/builder/vmware/common/step_compact_disk.go index d3eabec6f..b53dd14c3 100644 --- a/builder/vmware/common/step_compact_disk.go +++ b/builder/vmware/common/step_compact_disk.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // This step compacts the virtual disk for the VM unless the "skip_compaction" diff --git a/builder/vmware/common/step_output_dir_test.go b/builder/vmware/common/step_output_dir_test.go index fcd64ca7e..e748578bd 100644 --- a/builder/vmware/common/step_output_dir_test.go +++ b/builder/vmware/common/step_output_dir_test.go @@ -1,10 +1,11 @@ package common import ( - "github.com/mitchellh/multistep" "io/ioutil" "os" "testing" + + "github.com/mitchellh/multistep" ) func testOutputDir(t *testing.T) *LocalOutputDir { diff --git a/builder/vmware/common/step_shutdown.go b/builder/vmware/common/step_shutdown.go index babcea28c..f0cf04aaf 100644 --- a/builder/vmware/common/step_shutdown.go +++ b/builder/vmware/common/step_shutdown.go @@ -4,12 +4,13 @@ import ( "bytes" "errors" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "regexp" "strings" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // This step shuts down the machine. It first attempts to do so gracefully, diff --git a/builder/vmware/common/step_suppress_messages.go b/builder/vmware/common/step_suppress_messages.go index ca83506bf..a0a77b9ab 100644 --- a/builder/vmware/common/step_suppress_messages.go +++ b/builder/vmware/common/step_suppress_messages.go @@ -2,9 +2,10 @@ package common import ( "fmt" + "log" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // This step suppresses any messages that VMware product might show. diff --git a/builder/vmware/common/step_test.go b/builder/vmware/common/step_test.go index c6424b692..140f6f619 100644 --- a/builder/vmware/common/step_test.go +++ b/builder/vmware/common/step_test.go @@ -2,9 +2,10 @@ package common import ( "bytes" + "testing" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/iso/artifact_test.go b/builder/vmware/iso/artifact_test.go index c18e60119..ea4bab42b 100644 --- a/builder/vmware/iso/artifact_test.go +++ b/builder/vmware/iso/artifact_test.go @@ -1,8 +1,9 @@ package iso import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_Impl(t *testing.T) { diff --git a/builder/vmware/iso/step_create_disk.go b/builder/vmware/iso/step_create_disk.go index 463599780..0985b70e5 100644 --- a/builder/vmware/iso/step_create_disk.go +++ b/builder/vmware/iso/step_create_disk.go @@ -2,10 +2,11 @@ package iso import ( "fmt" + "path/filepath" + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "path/filepath" ) // This step creates the virtual disks for the VM. diff --git a/builder/vmware/iso/step_export_test.go b/builder/vmware/iso/step_export_test.go index 9ea0d64b9..1e5ba606d 100644 --- a/builder/vmware/iso/step_export_test.go +++ b/builder/vmware/iso/step_export_test.go @@ -1,8 +1,9 @@ package iso import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepExport_impl(t *testing.T) { diff --git a/builder/vmware/iso/step_register_test.go b/builder/vmware/iso/step_register_test.go index 4862cbd6d..8bfed06e8 100644 --- a/builder/vmware/iso/step_register_test.go +++ b/builder/vmware/iso/step_register_test.go @@ -1,8 +1,9 @@ package iso import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepRegister_impl(t *testing.T) { diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 6ef27bce6..76b30bfdf 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -2,10 +2,11 @@ package iso import ( "fmt" + "log" + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "log" ) // stepRemoteUpload uploads some thing from the state bag to a remote driver diff --git a/builder/vmware/iso/step_test.go b/builder/vmware/iso/step_test.go index 783d38796..6ac2ba05e 100644 --- a/builder/vmware/iso/step_test.go +++ b/builder/vmware/iso/step_test.go @@ -2,10 +2,11 @@ package iso import ( "bytes" + "testing" + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/iso/step_upload_vmx.go b/builder/vmware/iso/step_upload_vmx.go index 39532674b..0c9e17c28 100644 --- a/builder/vmware/iso/step_upload_vmx.go +++ b/builder/vmware/iso/step_upload_vmx.go @@ -2,10 +2,11 @@ package iso import ( "fmt" + "path/filepath" + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - "path/filepath" ) // This step upload the VMX to the remote host diff --git a/common/multistep_debug.go b/common/multistep_debug.go index b726ce2c3..15ebb7eb0 100644 --- a/common/multistep_debug.go +++ b/common/multistep_debug.go @@ -2,10 +2,11 @@ package common import ( "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // MultistepDebugFn will return a proper multistep.DebugPauseFn to diff --git a/common/step_create_floppy_test.go b/common/step_create_floppy_test.go index f5cc16b64..7b5145eaa 100644 --- a/common/step_create_floppy_test.go +++ b/common/step_create_floppy_test.go @@ -3,8 +3,6 @@ package common import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "io/ioutil" "log" "os" @@ -13,6 +11,9 @@ import ( "strconv" "strings" "testing" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) const TestFixtures = "test-fixtures" diff --git a/common/step_download_test.go b/common/step_download_test.go index 258beda09..de166ae55 100644 --- a/common/step_download_test.go +++ b/common/step_download_test.go @@ -1,8 +1,9 @@ package common import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepDownload_Impl(t *testing.T) { diff --git a/common/step_provision.go b/common/step_provision.go index 14074d7a1..15a6fb921 100644 --- a/common/step_provision.go +++ b/common/step_provision.go @@ -1,10 +1,11 @@ package common import ( - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "log" "time" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" ) // StepProvision runs the provisioners. diff --git a/common/step_provision_test.go b/common/step_provision_test.go index 6da846cb3..5347aaee3 100644 --- a/common/step_provision_test.go +++ b/common/step_provision_test.go @@ -1,8 +1,9 @@ package common import ( - "github.com/mitchellh/multistep" "testing" + + "github.com/mitchellh/multistep" ) func TestStepProvision_Impl(t *testing.T) { diff --git a/communicator/ssh/password_test.go b/communicator/ssh/password_test.go index 6e3e0a257..e513716d0 100644 --- a/communicator/ssh/password_test.go +++ b/communicator/ssh/password_test.go @@ -1,9 +1,10 @@ package ssh import ( - "golang.org/x/crypto/ssh" "reflect" "testing" + + "golang.org/x/crypto/ssh" ) func TestPasswordKeyboardInteractive_Impl(t *testing.T) { diff --git a/fix/fixer_createtime.go b/fix/fixer_createtime.go index 81d23bfe0..67bd12284 100644 --- a/fix/fixer_createtime.go +++ b/fix/fixer_createtime.go @@ -1,8 +1,9 @@ package fix import ( - "github.com/mitchellh/mapstructure" "regexp" + + "github.com/mitchellh/mapstructure" ) // FixerCreateTime is a Fixer that replaces the ".CreateTime" template diff --git a/packer/plugin/builder.go b/packer/plugin/builder.go index 9036cc1b1..3b2debce7 100644 --- a/packer/plugin/builder.go +++ b/packer/plugin/builder.go @@ -1,8 +1,9 @@ package plugin import ( - "github.com/hashicorp/packer/packer" "log" + + "github.com/hashicorp/packer/packer" ) type cmdBuilder struct { diff --git a/packer/plugin/client.go b/packer/plugin/client.go index 67f2ad23e..edcab1d7a 100644 --- a/packer/plugin/client.go +++ b/packer/plugin/client.go @@ -4,8 +4,6 @@ import ( "bufio" "errors" "fmt" - "github.com/hashicorp/packer/packer" - packrpc "github.com/hashicorp/packer/packer/rpc" "io" "io/ioutil" "log" @@ -17,6 +15,9 @@ import ( "sync" "time" "unicode" + + "github.com/hashicorp/packer/packer" + packrpc "github.com/hashicorp/packer/packer/rpc" ) // If this is true, then the "unexpected EOF" panic will not be diff --git a/packer/plugin/hook.go b/packer/plugin/hook.go index 7d9f8f03f..ca28ecbee 100644 --- a/packer/plugin/hook.go +++ b/packer/plugin/hook.go @@ -1,8 +1,9 @@ package plugin import ( - "github.com/hashicorp/packer/packer" "log" + + "github.com/hashicorp/packer/packer" ) type cmdHook struct { diff --git a/packer/plugin/post_processor.go b/packer/plugin/post_processor.go index bb801448a..b65c76623 100644 --- a/packer/plugin/post_processor.go +++ b/packer/plugin/post_processor.go @@ -1,8 +1,9 @@ package plugin import ( - "github.com/hashicorp/packer/packer" "log" + + "github.com/hashicorp/packer/packer" ) type cmdPostProcessor struct { diff --git a/packer/plugin/post_processor_test.go b/packer/plugin/post_processor_test.go index 4c545142d..a1e2f0f65 100644 --- a/packer/plugin/post_processor_test.go +++ b/packer/plugin/post_processor_test.go @@ -1,9 +1,10 @@ package plugin import ( - "github.com/hashicorp/packer/packer" "os/exec" "testing" + + "github.com/hashicorp/packer/packer" ) type helperPostProcessor byte diff --git a/packer/plugin/provisioner.go b/packer/plugin/provisioner.go index d71854a58..91017062b 100644 --- a/packer/plugin/provisioner.go +++ b/packer/plugin/provisioner.go @@ -1,8 +1,9 @@ package plugin import ( - "github.com/hashicorp/packer/packer" "log" + + "github.com/hashicorp/packer/packer" ) type cmdProvisioner struct { diff --git a/packer/plugin/server.go b/packer/plugin/server.go index 667907a5f..199c77218 100644 --- a/packer/plugin/server.go +++ b/packer/plugin/server.go @@ -10,7 +10,6 @@ package plugin import ( "errors" "fmt" - packrpc "github.com/hashicorp/packer/packer/rpc" "io/ioutil" "log" "math/rand" @@ -21,6 +20,8 @@ import ( "strconv" "sync/atomic" "time" + + packrpc "github.com/hashicorp/packer/packer/rpc" ) // This is a count of the number of interrupts the process has received. diff --git a/packer/rpc/artifact.go b/packer/rpc/artifact.go index 4d01bbabd..b1166afa7 100644 --- a/packer/rpc/artifact.go +++ b/packer/rpc/artifact.go @@ -1,8 +1,9 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "net/rpc" + + "github.com/hashicorp/packer/packer" ) // An implementation of packer.Artifact where the artifact is actually diff --git a/packer/rpc/artifact_test.go b/packer/rpc/artifact_test.go index 6959c3239..2a0e7dab9 100644 --- a/packer/rpc/artifact_test.go +++ b/packer/rpc/artifact_test.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "reflect" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifactRPC(t *testing.T) { diff --git a/packer/rpc/builder.go b/packer/rpc/builder.go index ed847fa91..6365b1c23 100644 --- a/packer/rpc/builder.go +++ b/packer/rpc/builder.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "log" "net/rpc" + + "github.com/hashicorp/packer/packer" ) // An implementation of packer.Builder where the builder is actually executed diff --git a/packer/rpc/builder_test.go b/packer/rpc/builder_test.go index 255877352..0165e8d57 100644 --- a/packer/rpc/builder_test.go +++ b/packer/rpc/builder_test.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "reflect" "testing" + + "github.com/hashicorp/packer/packer" ) var testBuilderArtifact = &packer.MockArtifact{} diff --git a/packer/rpc/cache.go b/packer/rpc/cache.go index ce5a231bb..57da43cf3 100644 --- a/packer/rpc/cache.go +++ b/packer/rpc/cache.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "log" "net/rpc" + + "github.com/hashicorp/packer/packer" ) // An implementation of packer.Cache where the cache is actually executed diff --git a/packer/rpc/cache_test.go b/packer/rpc/cache_test.go index 1fa76f0e4..a6a8f2ac4 100644 --- a/packer/rpc/cache_test.go +++ b/packer/rpc/cache_test.go @@ -1,8 +1,9 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) type testCache struct { diff --git a/packer/rpc/communicator_test.go b/packer/rpc/communicator_test.go index 1af9e53c8..9712960dc 100644 --- a/packer/rpc/communicator_test.go +++ b/packer/rpc/communicator_test.go @@ -2,10 +2,11 @@ package rpc import ( "bufio" - "github.com/hashicorp/packer/packer" "io" "reflect" "testing" + + "github.com/hashicorp/packer/packer" ) func TestCommunicatorRPC(t *testing.T) { diff --git a/packer/rpc/hook.go b/packer/rpc/hook.go index 590b0899a..623f86ce7 100644 --- a/packer/rpc/hook.go +++ b/packer/rpc/hook.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "log" "net/rpc" + + "github.com/hashicorp/packer/packer" ) // An implementation of packer.Hook where the hook is actually executed diff --git a/packer/rpc/hook_test.go b/packer/rpc/hook_test.go index 8043e6ad9..d1ae7ea06 100644 --- a/packer/rpc/hook_test.go +++ b/packer/rpc/hook_test.go @@ -1,11 +1,12 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "reflect" "sync" "testing" "time" + + "github.com/hashicorp/packer/packer" ) func TestHookRPC(t *testing.T) { diff --git a/packer/rpc/post_processor_test.go b/packer/rpc/post_processor_test.go index 99258c50e..683b6dc16 100644 --- a/packer/rpc/post_processor_test.go +++ b/packer/rpc/post_processor_test.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "reflect" "testing" + + "github.com/hashicorp/packer/packer" ) var testPostProcessorArtifact = new(packer.MockArtifact) diff --git a/packer/rpc/provisioner.go b/packer/rpc/provisioner.go index 80c57e264..d8b3b3f66 100644 --- a/packer/rpc/provisioner.go +++ b/packer/rpc/provisioner.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "log" "net/rpc" + + "github.com/hashicorp/packer/packer" ) // An implementation of packer.Provisioner where the provisioner is actually diff --git a/packer/rpc/provisioner_test.go b/packer/rpc/provisioner_test.go index 448946682..df310369b 100644 --- a/packer/rpc/provisioner_test.go +++ b/packer/rpc/provisioner_test.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "reflect" "testing" + + "github.com/hashicorp/packer/packer" ) func TestProvisionerRPC(t *testing.T) { diff --git a/packer/rpc/ui.go b/packer/rpc/ui.go index 1b84e5cd1..1c6356a65 100644 --- a/packer/rpc/ui.go +++ b/packer/rpc/ui.go @@ -1,9 +1,10 @@ package rpc import ( - "github.com/hashicorp/packer/packer" "log" "net/rpc" + + "github.com/hashicorp/packer/packer" ) // An implementation of packer.Ui where the Ui is actually executed diff --git a/post-processor/compress/artifact_test.go b/post-processor/compress/artifact_test.go index 2abde78d7..ed39f4a73 100644 --- a/post-processor/compress/artifact_test.go +++ b/post-processor/compress/artifact_test.go @@ -1,8 +1,9 @@ package compress import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_ImplementsArtifact(t *testing.T) { diff --git a/post-processor/docker-import/post-processor_test.go b/post-processor/docker-import/post-processor_test.go index 4df15486e..efe51c65f 100644 --- a/post-processor/docker-import/post-processor_test.go +++ b/post-processor/docker-import/post-processor_test.go @@ -2,8 +2,9 @@ package dockerimport import ( "bytes" - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/post-processor/docker-push/post-processor_test.go b/post-processor/docker-push/post-processor_test.go index a79b4dc21..d132595e5 100644 --- a/post-processor/docker-push/post-processor_test.go +++ b/post-processor/docker-push/post-processor_test.go @@ -2,10 +2,11 @@ package dockerpush import ( "bytes" + "testing" + "github.com/hashicorp/packer/builder/docker" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/post-processor/docker-import" - "testing" ) func testConfig() map[string]interface{} { diff --git a/post-processor/docker-save/post-processor_test.go b/post-processor/docker-save/post-processor_test.go index 45ef41986..3caf78c35 100644 --- a/post-processor/docker-save/post-processor_test.go +++ b/post-processor/docker-save/post-processor_test.go @@ -2,8 +2,9 @@ package dockersave import ( "bytes" - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/post-processor/shell-local/post-processor_test.go b/post-processor/shell-local/post-processor_test.go index 094b84096..7bdef1c32 100644 --- a/post-processor/shell-local/post-processor_test.go +++ b/post-processor/shell-local/post-processor_test.go @@ -1,10 +1,11 @@ package shell_local import ( - "github.com/hashicorp/packer/packer" "io/ioutil" "os" "testing" + + "github.com/hashicorp/packer/packer" ) func TestPostProcessor_ImplementsPostProcessor(t *testing.T) { diff --git a/post-processor/vagrant-cloud/artifact_test.go b/post-processor/vagrant-cloud/artifact_test.go index e22090612..6c633ea84 100644 --- a/post-processor/vagrant-cloud/artifact_test.go +++ b/post-processor/vagrant-cloud/artifact_test.go @@ -1,8 +1,9 @@ package vagrantcloud import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_ImplementsArtifact(t *testing.T) { diff --git a/post-processor/vagrant-cloud/step_create_provider.go b/post-processor/vagrant-cloud/step_create_provider.go index c3e3665c8..4cd443577 100644 --- a/post-processor/vagrant-cloud/step_create_provider.go +++ b/post-processor/vagrant-cloud/step_create_provider.go @@ -2,6 +2,7 @@ package vagrantcloud import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/post-processor/vagrant-cloud/step_create_version.go b/post-processor/vagrant-cloud/step_create_version.go index 0a544ceba..aba6da020 100644 --- a/post-processor/vagrant-cloud/step_create_version.go +++ b/post-processor/vagrant-cloud/step_create_version.go @@ -2,6 +2,7 @@ package vagrantcloud import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/post-processor/vagrant-cloud/step_verify_box.go b/post-processor/vagrant-cloud/step_verify_box.go index c3c7ef4a6..ab6ac4fe6 100644 --- a/post-processor/vagrant-cloud/step_verify_box.go +++ b/post-processor/vagrant-cloud/step_verify_box.go @@ -2,6 +2,7 @@ package vagrantcloud import ( "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) diff --git a/post-processor/vagrant/artifact_test.go b/post-processor/vagrant/artifact_test.go index 3676e1d98..7b087d963 100644 --- a/post-processor/vagrant/artifact_test.go +++ b/post-processor/vagrant/artifact_test.go @@ -1,8 +1,9 @@ package vagrant import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_ImplementsArtifact(t *testing.T) { diff --git a/post-processor/vagrant/digitalocean.go b/post-processor/vagrant/digitalocean.go index 2aaba9067..292b00600 100644 --- a/post-processor/vagrant/digitalocean.go +++ b/post-processor/vagrant/digitalocean.go @@ -3,9 +3,10 @@ package vagrant import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" "strings" "text/template" + + "github.com/hashicorp/packer/packer" ) type digitalOceanVagrantfileTemplate struct { diff --git a/post-processor/vagrant/libvirt.go b/post-processor/vagrant/libvirt.go index ece535bf0..c20e8473b 100644 --- a/post-processor/vagrant/libvirt.go +++ b/post-processor/vagrant/libvirt.go @@ -2,9 +2,10 @@ package vagrant import ( "fmt" - "github.com/hashicorp/packer/packer" "path/filepath" "strings" + + "github.com/hashicorp/packer/packer" ) type LibVirtProvider struct{} diff --git a/post-processor/vagrant/post-processor_test.go b/post-processor/vagrant/post-processor_test.go index 8b8bfe10a..8a5368737 100644 --- a/post-processor/vagrant/post-processor_test.go +++ b/post-processor/vagrant/post-processor_test.go @@ -3,11 +3,12 @@ package vagrant import ( "bytes" "compress/flate" - "github.com/hashicorp/packer/packer" "io/ioutil" "os" "strings" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/post-processor/vagrant/virtualbox.go b/post-processor/vagrant/virtualbox.go index 29201a01a..6b01a9c8c 100644 --- a/post-processor/vagrant/virtualbox.go +++ b/post-processor/vagrant/virtualbox.go @@ -4,13 +4,14 @@ import ( "archive/tar" "errors" "fmt" - "github.com/hashicorp/packer/packer" "io" "io/ioutil" "log" "os" "path/filepath" "regexp" + + "github.com/hashicorp/packer/packer" ) type VBoxProvider struct{} diff --git a/post-processor/vagrant/vmware.go b/post-processor/vagrant/vmware.go index 3fe2aed4e..66d75b1ba 100644 --- a/post-processor/vagrant/vmware.go +++ b/post-processor/vagrant/vmware.go @@ -2,8 +2,9 @@ package vagrant import ( "fmt" - "github.com/hashicorp/packer/packer" "path/filepath" + + "github.com/hashicorp/packer/packer" ) type VMwareProvider struct{} diff --git a/provisioner/chef-solo/provisioner_test.go b/provisioner/chef-solo/provisioner_test.go index 15ae499c7..01d237330 100644 --- a/provisioner/chef-solo/provisioner_test.go +++ b/provisioner/chef-solo/provisioner_test.go @@ -1,10 +1,11 @@ package chefsolo import ( - "github.com/hashicorp/packer/packer" "io/ioutil" "os" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { diff --git a/provisioner/salt-masterless/provisioner_test.go b/provisioner/salt-masterless/provisioner_test.go index 2b40887d3..bad83b3f6 100644 --- a/provisioner/salt-masterless/provisioner_test.go +++ b/provisioner/salt-masterless/provisioner_test.go @@ -1,11 +1,12 @@ package saltmasterless import ( - "github.com/hashicorp/packer/packer" "io/ioutil" "os" "strings" "testing" + + "github.com/hashicorp/packer/packer" ) func testConfig() map[string]interface{} { From 247119e1c3f6f0b26b22cb8918a1d11b1b0be68e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 23 Jan 2018 14:33:40 -0800 Subject: [PATCH 0424/1007] make examples copy/pastable --- CONTRIBUTING.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 36381a833..2ae5b39fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,7 @@ export PATH=$PATH:$GOPATH/bin `go get github.com/hashicorp/packer`. This will download the Packer source to `$GOPATH/src/github.com/hashicorp/packer`. -4. When working on Packer, first `cd` into `$GOPATH/src/github.com/hashicorp/packer` +4. When working on Packer, first `cd $GOPATH/src/github.com/hashicorp/packer` so you can run `make` and easily access other files. Run `make help` to get information about make targets. @@ -98,9 +98,9 @@ your changes to your fork, and then open a pull-request. For example, my github username is `cbednarski`, so I would do the following: ``` -$ git checkout -b f-my-feature +git checkout -b f-my-feature # Develop a patch. -$ git push https://github.com/cbednarski/Packer f-my-feature +git push https://github.com/cbednarski/Packer f-my-feature ``` From there, open your fork in your browser to open a new pull-request. @@ -150,7 +150,7 @@ not attempt to track the latest version for each dependency. You can run tests for individual packages using commands like this: ``` -$ make test TEST=./builder/amazon/... +make test TEST=./builder/amazon/... ``` #### Running Acceptance Tests @@ -173,8 +173,8 @@ resources are not accidentally destroyed or overwritten during testing. To run the acceptance tests, invoke `make testacc`: ``` -$ make testacc TEST=./builder/amazon/ebs -$ ... +make testacc TEST=./builder/amazon/ebs +... ``` The `TEST` variable lets you narrow the scope of the acceptance tests to a @@ -185,7 +185,7 @@ take a very long time. To run only a specific test, use the `-run` argument: ``` -$ make testacc TEST=./builder/amazon/ebs TESTARGS="-run TestBuilderAcc_forceDeleteSnapshot" +make testacc TEST=./builder/amazon/ebs TESTARGS="-run TestBuilderAcc_forceDeleteSnapshot" ``` Acceptance tests typically require other environment variables to be set for From ccbd8b8abf15ffdd42fbee64d3416ef3c7c26618 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 24 Jan 2018 16:59:32 -0800 Subject: [PATCH 0425/1007] update plugin documentation --- website/source/docs/extending/plugins.html.md | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/website/source/docs/extending/plugins.html.md b/website/source/docs/extending/plugins.html.md index 180a6e8ea..8d1b6b2a5 100644 --- a/website/source/docs/extending/plugins.html.md +++ b/website/source/docs/extending/plugins.html.md @@ -17,9 +17,9 @@ writing plugins that are simply distributed with Packer. For example, all the builders, provisioners, and more that ship with Packer are implemented as Plugins that are simply hardcoded to load with Packer. -This page will cover how to install and use plugins. If you're interested in -developing plugins, the documentation for that is available the [developing -plugins](/docs/extending/plugins.html) page. +This section will cover how to install and use plugins. If you're interested in +developing plugins, the documentation for that is available below, in the [developing +plugins](#developing-plugins) section. Because Packer is so young, there is no official listing of available Packer plugins. Plugins are best found via Google. Typically, searching "packer plugin @@ -32,11 +32,11 @@ Packer plugins are completely separate, standalone applications that the core of Packer starts and communicates with. These plugin applications aren't meant to be run manually. Instead, Packer core -executes these plugin applications in a certain way and communicates with them. -For example, the VMware builder is actually a standalone binary named -`packer-builder-vmware`. The next time you run a Packer build, look at your -process list and you should see a handful of `packer-` prefixed applications -running. +executes them as a sub-process, run as a sub-command (`packer plugin`) and +communicates with them. For example, the VMware builder is actually run as +`packer plugin packer-builder-vmware`. The next time you run a Packer build, +look at your process list and you should see a handful of `packer-` prefixed +applications running. ## Installing Plugins @@ -153,12 +153,10 @@ using standard installation procedures. The specifics of how to implement each type of interface are covered in the relevant subsections available in the navigation to the left. -~&gt; **Lock your dependencies!** Unfortunately, Go's dependency management -story is fairly sad. There are various unofficial methods out there for locking -dependencies, and using one of them is highly recommended since the Packer -codebase will continue to improve, potentially breaking APIs along the way until -there is a stable release. By locking your dependencies, your plugins will -continue to work with the version of Packer you lock to. +~&gt; **Lock your dependencies!** Using `govendor` is highly recommended since +the Packer codebase will continue to improve, potentially breaking APIs along +the way until there is a stable release. By locking your dependencies, your +plugins will continue to work with the version of Packer you lock to. ### Logging and Debugging From 4c5a7e08b55fba69e7c8b2fae53721f719866b83 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 17 Jan 2018 19:48:21 -0800 Subject: [PATCH 0426/1007] remove multistep vendor dep --- .../github.com/mitchellh/multistep/LICENSE.md | 22 ---- .../github.com/mitchellh/multistep/README.md | 59 --------- .../mitchellh/multistep/basic_runner.go | 102 --------------- .../mitchellh/multistep/debug_runner.go | 123 ------------------ .../mitchellh/multistep/multistep.go | 48 ------- .../mitchellh/multistep/statebag.go | 47 ------- vendor/vendor.json | 6 - 7 files changed, 407 deletions(-) delete mode 100644 vendor/github.com/mitchellh/multistep/LICENSE.md delete mode 100644 vendor/github.com/mitchellh/multistep/README.md delete mode 100644 vendor/github.com/mitchellh/multistep/basic_runner.go delete mode 100644 vendor/github.com/mitchellh/multistep/debug_runner.go delete mode 100644 vendor/github.com/mitchellh/multistep/multistep.go delete mode 100644 vendor/github.com/mitchellh/multistep/statebag.go diff --git a/vendor/github.com/mitchellh/multistep/LICENSE.md b/vendor/github.com/mitchellh/multistep/LICENSE.md deleted file mode 100644 index c9d6b768c..000000000 --- a/vendor/github.com/mitchellh/multistep/LICENSE.md +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 Mitchell Hashimoto - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/multistep/README.md b/vendor/github.com/mitchellh/multistep/README.md deleted file mode 100644 index 9ceae012a..000000000 --- a/vendor/github.com/mitchellh/multistep/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# multistep - -multistep is a Go library for building up complex actions using discrete, -individual "steps." These steps are strung together and run in sequence -to achieve a more complex goal. The runner handles cleanup, cancelling, etc. -if necessary. - -## Basic Example - -Make a step to perform some action. The step can access your "state", -which is passed between steps by the runner. - -```go -type stepAdd struct{} - -func (s *stepAdd) Run(state multistep.StateBag) multistep.StepAction { - // Read our value and assert that it is they type we want - value := state.Get("value").(int) - fmt.Printf("Value is %d\n", value) - - // Store some state back - state.Put("value", value + 1) - return multistep.ActionContinue -} - -func (s *stepAdd) Cleanup(multistep.StateBag) { - // This is called after all the steps have run or if the runner is - // cancelled so that cleanup can be performed. -} -``` - -Make a runner and call your array of Steps. - -```go -func main() { - // Our "bag of state" that we read the value from - state := new(multistep.BasicStateBag) - state.Put("value", 0) - - steps := []multistep.Step{ - &stepAdd{}, - &stepAdd{}, - &stepAdd{}, - } - - runner := &multistep.BasicRunner{Steps: steps} - - // Executes the steps - runner.Run(state) -} -``` - -This will produce: - -``` -Value is 0 -Value is 1 -Value is 2 -``` diff --git a/vendor/github.com/mitchellh/multistep/basic_runner.go b/vendor/github.com/mitchellh/multistep/basic_runner.go deleted file mode 100644 index 35692a743..000000000 --- a/vendor/github.com/mitchellh/multistep/basic_runner.go +++ /dev/null @@ -1,102 +0,0 @@ -package multistep - -import ( - "sync" - "sync/atomic" -) - -type runState int32 - -const ( - stateIdle runState = iota - stateRunning - stateCancelling -) - -// BasicRunner is a Runner that just runs the given slice of steps. -type BasicRunner struct { - // Steps is a slice of steps to run. Once set, this should _not_ be - // modified. - Steps []Step - - cancelCh chan struct{} - doneCh chan struct{} - state runState - l sync.Mutex -} - -func (b *BasicRunner) Run(state StateBag) { - b.l.Lock() - if b.state != stateIdle { - panic("already running") - } - - cancelCh := make(chan struct{}) - doneCh := make(chan struct{}) - b.cancelCh = cancelCh - b.doneCh = doneCh - b.state = stateRunning - b.l.Unlock() - - defer func() { - b.l.Lock() - b.cancelCh = nil - b.doneCh = nil - b.state = stateIdle - close(doneCh) - b.l.Unlock() - }() - - // This goroutine listens for cancels and puts the StateCancelled key - // as quickly as possible into the state bag to mark it. - go func() { - select { - case <-cancelCh: - // Flag cancel and wait for finish - state.Put(StateCancelled, true) - <-doneCh - case <-doneCh: - } - }() - - for _, step := range b.Steps { - // We also check for cancellation here since we can't be sure - // the goroutine that is running to set it actually ran. - if runState(atomic.LoadInt32((*int32)(&b.state))) == stateCancelling { - state.Put(StateCancelled, true) - break - } - - action := step.Run(state) - defer step.Cleanup(state) - - if _, ok := state.GetOk(StateCancelled); ok { - break - } - - if action == ActionHalt { - state.Put(StateHalted, true) - break - } - } -} - -func (b *BasicRunner) Cancel() { - b.l.Lock() - switch b.state { - case stateIdle: - // Not running, so Cancel is... done. - b.l.Unlock() - return - case stateRunning: - // Running, so mark that we cancelled and set the state - close(b.cancelCh) - b.state = stateCancelling - fallthrough - case stateCancelling: - // Already cancelling, so just wait until we're done - ch := b.doneCh - b.l.Unlock() - <-ch - } -} diff --git a/vendor/github.com/mitchellh/multistep/debug_runner.go b/vendor/github.com/mitchellh/multistep/debug_runner.go deleted file mode 100644 index 882009494..000000000 --- a/vendor/github.com/mitchellh/multistep/debug_runner.go +++ /dev/null @@ -1,123 +0,0 @@ -package multistep - -import ( - "fmt" - "reflect" - "sync" -) - -// DebugLocation is the location where the pause is occuring when debugging -// a step sequence. "DebugLocationAfterRun" is after the run of the named -// step. "DebugLocationBeforeCleanup" is before the cleanup of the named -// step. -type DebugLocation uint - -const ( - DebugLocationAfterRun DebugLocation = iota - DebugLocationBeforeCleanup -) - -// StepWrapper is an interface that wrapped steps can implement to expose their -// inner step names to the debug runner. -type StepWrapper interface { - // InnerStepName should return the human readable name of the wrapped step. - InnerStepName() string -} - -// DebugPauseFn is the type signature for the function that is called -// whenever the DebugRunner pauses. It allows the caller time to -// inspect the state of the multi-step sequence at a given step. -type DebugPauseFn func(DebugLocation, string, StateBag) - -// DebugRunner is a Runner that runs the given set of steps in order, -// but pauses between each step until it is told to continue. -type DebugRunner struct { - // Steps is the steps to run. These will be run in order. - Steps []Step - - // PauseFn is the function that is called whenever the debug runner - // pauses. The debug runner continues when this function returns. - // The function is given the state so that the state can be inspected. - PauseFn DebugPauseFn - - l sync.Mutex - runner *BasicRunner -} - -func (r *DebugRunner) Run(state StateBag) { - r.l.Lock() - if r.runner != nil { - panic("already running") - } - r.runner = new(BasicRunner) - r.l.Unlock() - - pauseFn := r.PauseFn - - // If no PauseFn is specified, use the default - if pauseFn == nil { - pauseFn = DebugPauseDefault - } - - // Rebuild the steps so that we insert the pause step after each - steps := make([]Step, len(r.Steps)*2) - for i, step := range r.Steps { - steps[i*2] = step - name := "" - if wrapped, ok := step.(StepWrapper); ok { - name = wrapped.InnerStepName() - } else { - name = reflect.Indirect(reflect.ValueOf(step)).Type().Name() - } - steps[(i*2)+1] = &debugStepPause{ - name, - pauseFn, - } - } - - // Then just use a basic runner to run it - r.runner.Steps = steps - r.runner.Run(state) -} - -func (r *DebugRunner) Cancel() { - r.l.Lock() - defer r.l.Unlock() - - if r.runner != nil { - r.runner.Cancel() - } -} - -// DebugPauseDefault is the default pause function when using the -// DebugRunner if no PauseFn is specified. It outputs some information -// to stderr about the step and waits for keyboard input on stdin before -// continuing. -func DebugPauseDefault(loc DebugLocation, name string, state StateBag) { - var locationString string - switch loc { - case DebugLocationAfterRun: - locationString = "after run of" - case DebugLocationBeforeCleanup: - locationString = "before cleanup of" - } - - fmt.Printf("Pausing %s step '%s'. Press any key to continue.\n", locationString, name) - - var line string - fmt.Scanln(&line) -} - -type debugStepPause struct { - StepName string - PauseFn DebugPauseFn -} - -func (s *debugStepPause) Run(state StateBag) StepAction { - s.PauseFn(DebugLocationAfterRun, s.StepName, state) - return ActionContinue -} - -func (s *debugStepPause) Cleanup(state StateBag) { - s.PauseFn(DebugLocationBeforeCleanup, s.StepName, state) -} diff --git a/vendor/github.com/mitchellh/multistep/multistep.go b/vendor/github.com/mitchellh/multistep/multistep.go deleted file mode 100644 index feef1406f..000000000 --- a/vendor/github.com/mitchellh/multistep/multistep.go +++ /dev/null @@ -1,48 +0,0 @@ -// multistep is a library for bulding up complex actions using individual, -// discrete steps. -package multistep - -// A StepAction determines the next step to take regarding multi-step actions. -type StepAction uint - -const ( - ActionContinue StepAction = iota - ActionHalt -) - -// This is the key set in the state bag when using the basic runner to -// signal that the step sequence was cancelled. -const StateCancelled = "cancelled" - -// This is the key set in the state bag when a step halted the sequence. -const StateHalted = "halted" - -// Step is a single step that is part of a potentially large sequence -// of other steps, responsible for performing some specific action. -type Step interface { - // Run is called to perform the action. The parameter is a "state bag" - // of untyped things. Please be very careful about type-checking the - // items in this bag. - // - // The return value determines whether multi-step sequences continue - // or should halt. - Run(StateBag) StepAction - - // Cleanup is called in reverse order of the steps that have run - // and allow steps to clean up after themselves. Do not assume if this - // ran that the entire multi-step sequence completed successfully. This - // method can be ran in the face of errors and cancellations as well. - // - // The parameter is the same "state bag" as Run, and represents the - // state at the latest possible time prior to calling Cleanup. - Cleanup(StateBag) -} - -// Runner is a thing that runs one or more steps. -type Runner interface { - // Run runs the steps with the given initial state. - Run(StateBag) - - // Cancel cancels a potentially running stack of steps. - Cancel() -} diff --git a/vendor/github.com/mitchellh/multistep/statebag.go b/vendor/github.com/mitchellh/multistep/statebag.go deleted file mode 100644 index dab712316..000000000 --- a/vendor/github.com/mitchellh/multistep/statebag.go +++ /dev/null @@ -1,47 +0,0 @@ -package multistep - -import ( - "sync" -) - -// StateBag holds the state that is used by the Runner and Steps. The -// StateBag implementation must be safe for concurrent access. -type StateBag interface { - Get(string) interface{} - GetOk(string) (interface{}, bool) - Put(string, interface{}) -} - -// BasicStateBag implements StateBag by using a normal map underneath -// protected by a RWMutex. -type BasicStateBag struct { - data map[string]interface{} - l sync.RWMutex - once sync.Once -} - -func (b *BasicStateBag) Get(k string) interface{} { - result, _ := b.GetOk(k) - return result -} - -func (b *BasicStateBag) GetOk(k string) (interface{}, bool) { - b.l.RLock() - defer b.l.RUnlock() - - result, ok := b.data[k] - return result, ok -} - -func (b *BasicStateBag) Put(k string, v interface{}) { - b.l.Lock() - defer b.l.Unlock() - - // Make sure the map is initialized one time, on write - b.once.Do(func() { - b.data = make(map[string]interface{}) - }) - - // Write the data - b.data[k] = v -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 1c61745f5..3cf9e6714 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -961,12 +961,6 @@ "path": "github.com/mitchellh/mapstructure", "revision": "281073eb9eb092240d33ef253c404f1cca550309" }, - { - "checksumSHA1": "5x1RX5m8SCkCRLyLL8wBc0qJpV8=", - "path": "github.com/mitchellh/multistep", - "revision": "391576a156a54cfbb4cf5d5eda40cf6ffa3e3a4d", - "revisionTime": "2017-03-16T18:53:39Z" - }, { "checksumSHA1": "m2L8ohfZiFRsMW3iynaH/TWgnSY=", "path": "github.com/mitchellh/panicwrap", From 807e88245b8d2fd6aac8b72333c8fb713e51fe0b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 17 Jan 2018 22:49:03 -0800 Subject: [PATCH 0427/1007] trying to add context to state bag --- .../amazon/common/step_run_source_instance.go | 13 +- command/build.go | 3 + helper/multistep/LICENSE.md | 22 +++ helper/multistep/basic_runner.go | 105 +++++++++++ helper/multistep/basic_runner_test.go | 172 +++++++++++++++++ helper/multistep/debug_runner.go | 123 ++++++++++++ helper/multistep/debug_runner_test.go | 176 ++++++++++++++++++ helper/multistep/doc.go | 61 ++++++ helper/multistep/multistep.go | 48 +++++ helper/multistep/multistep_test.go | 75 ++++++++ helper/multistep/statebag.go | 48 +++++ helper/multistep/statebag_test.go | 30 +++ 12 files changed, 875 insertions(+), 1 deletion(-) create mode 100644 helper/multistep/LICENSE.md create mode 100644 helper/multistep/basic_runner.go create mode 100644 helper/multistep/basic_runner_test.go create mode 100644 helper/multistep/debug_runner.go create mode 100644 helper/multistep/debug_runner_test.go create mode 100644 helper/multistep/doc.go create mode 100644 helper/multistep/multistep.go create mode 100644 helper/multistep/multistep_test.go create mode 100644 helper/multistep/statebag.go create mode 100644 helper/multistep/statebag_test.go diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index aba0e9ab5..cf1557c54 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -1,6 +1,7 @@ package common import ( + "context" "encoding/base64" "fmt" "io/ioutil" @@ -178,7 +179,17 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - if err := ec2conn.WaitUntilInstanceRunning(describeInstance); err != nil { + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + for { + if _, ok := state.GetOk(multistep.StateCancelled); ok { + cancel() + } + } + }() + + if err := ec2conn.WaitUntilInstanceRunningWithContext(ctx, describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) diff --git a/command/build.go b/command/build.go index de9da51ee..6f7659821 100644 --- a/command/build.go +++ b/command/build.go @@ -138,9 +138,11 @@ func (c BuildCommand) Run(args []string) int { m map[string][]packer.Artifact }{m: make(map[string][]packer.Artifact)} errors := make(map[string]error) + // ctx := context.Background() for _, b := range builds { // Increment the waitgroup so we wait for this item to finish properly wg.Add(1) + // buildCtx, cancelCtx := ctx.WithCancel() // Handle interrupts for this build sigCh := make(chan os.Signal, 1) @@ -154,6 +156,7 @@ func (c BuildCommand) Run(args []string) int { log.Printf("Stopping build: %s", b.Name()) b.Cancel() + //cancelCtx() log.Printf("Build cancelled: %s", b.Name()) }(b) diff --git a/helper/multistep/LICENSE.md b/helper/multistep/LICENSE.md new file mode 100644 index 000000000..c9d6b768c --- /dev/null +++ b/helper/multistep/LICENSE.md @@ -0,0 +1,22 @@ +Copyright (c) 2013 Mitchell Hashimoto + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go new file mode 100644 index 000000000..305b801dd --- /dev/null +++ b/helper/multistep/basic_runner.go @@ -0,0 +1,105 @@ +package multistep + +import ( + "sync" + "sync/atomic" + + "golang.org/x/net/context" +) + +type runState int32 + +const ( + stateIdle runState = iota + stateRunning + stateCancelling +) + +// BasicRunner is a Runner that just runs the given slice of steps. +type BasicRunner struct { + // Steps is a slice of steps to run. Once set, this should _not_ be + // modified. + Steps []Step + + cancel context.CancelFunc + doneCh chan struct{} + state runState + l sync.Mutex +} + +func (b *BasicRunner) Run(state StateBag) { + ctx, cancel := context.WithCancel(state.Context()) + + b.l.Lock() + if b.state != stateIdle { + panic("already running") + } + + doneCh := make(chan struct{}) + b.cancel = cancel + b.doneCh = doneCh + b.state = stateRunning + b.l.Unlock() + + defer func() { + b.l.Lock() + b.cancel = nil + b.doneCh = nil + b.state = stateIdle + close(doneCh) + b.l.Unlock() + }() + + // This goroutine listens for cancels and puts the StateCancelled key + // as quickly as possible into the state bag to mark it. + go func() { + select { + case <-ctx.Done(): + // Flag cancel and wait for finish + state.Put(StateCancelled, true) + <-doneCh + case <-doneCh: + } + }() + + for _, step := range b.Steps { + // We also check for cancellation here since we can't be sure + // the goroutine that is running to set it actually ran. + if runState(atomic.LoadInt32((*int32)(&b.state))) == stateCancelling { + state.Put(StateCancelled, true) + break + } + + action := step.Run(state) + defer step.Cleanup(state) + + if _, ok := state.GetOk(StateCancelled); ok { + break + } + + if action == ActionHalt { + state.Put(StateHalted, true) + break + } + } +} + +func (b *BasicRunner) Cancel() { + b.l.Lock() + switch b.state { + case stateIdle: + // Not running, so Cancel is... done. + b.l.Unlock() + return + case stateRunning: + // Running, so mark that we cancelled and set the state + b.cancel() + b.state = stateCancelling + fallthrough + case stateCancelling: + // Already cancelling, so just wait until we're done + ch := b.doneCh + b.l.Unlock() + <-ch + } +} diff --git a/helper/multistep/basic_runner_test.go b/helper/multistep/basic_runner_test.go new file mode 100644 index 000000000..d13ccedf0 --- /dev/null +++ b/helper/multistep/basic_runner_test.go @@ -0,0 +1,172 @@ +package multistep + +import ( + "reflect" + "testing" + "time" + + "golang.org/x/net/context" +) + +func TestBasicRunner_ImplRunner(t *testing.T) { + var raw interface{} + raw = &BasicRunner{} + if _, ok := raw.(Runner); !ok { + t.Fatalf("BasicRunner must be a Runner") + } +} + +func TestBasicRunner_Run(t *testing.T) { + data := new(BasicStateBag) + stepA := &TestStepAcc{Data: "a"} + stepB := &TestStepAcc{Data: "b"} + + r := &BasicRunner{Steps: []Step{stepA, stepB}} + r.Run(context.Background(), data) + + // Test run data + expected := []string{"a", "b"} + results := data.Get("data").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test cleanup data + expected = []string{"b", "a"} + results = data.Get("cleanup").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test no halted or cancelled + if _, ok := data.GetOk(StateCancelled); ok { + t.Errorf("cancelled should not be in state bag") + } + + if _, ok := data.GetOk(StateHalted); ok { + t.Errorf("halted should not be in state bag") + } +} + +func TestBasicRunner_Run_Halt(t *testing.T) { + data := new(BasicStateBag) + stepA := &TestStepAcc{Data: "a"} + stepB := &TestStepAcc{Data: "b", Halt: true} + stepC := &TestStepAcc{Data: "c"} + + r := &BasicRunner{Steps: []Step{stepA, stepB, stepC}} + r.Run(context.Background(), data) + + // Test run data + expected := []string{"a", "b"} + results := data.Get("data").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test cleanup data + expected = []string{"b", "a"} + results = data.Get("cleanup").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test that it says it is halted + halted := data.Get(StateHalted).(bool) + if !halted { + t.Errorf("not halted") + } +} + +// confirm that can't run twice +func TestBasicRunner_Run_Run(t *testing.T) { + defer func() { + recover() + }() + ch := make(chan chan bool) + stepInt := &TestStepSync{ch} + stepWait := &TestStepWaitForever{} + r := &BasicRunner{Steps: []Step{stepInt, stepWait}} + + go r.Run(context.Background(), new(BasicStateBag)) + // wait until really running + <-ch + + // now try to run aain + r.Run(context.Background(), new(BasicStateBag)) + + // should not get here in nominal codepath + t.Errorf("Was able to run an already running BasicRunner") +} + +func TestBasicRunner_Cancel(t *testing.T) { + ch := make(chan chan bool) + data := new(BasicStateBag) + stepA := &TestStepAcc{Data: "a"} + stepB := &TestStepAcc{Data: "b"} + stepInt := &TestStepSync{ch} + stepC := &TestStepAcc{Data: "c"} + + r := &BasicRunner{Steps: []Step{stepA, stepB, stepInt, stepC}} + + // cancelling an idle Runner is a no-op + r.Cancel() + + go r.Run(context.Background(), data) + + // Wait until we reach the sync point + responseCh := <-ch + + // Cancel then continue chain + cancelCh := make(chan bool) + go func() { + r.Cancel() + cancelCh <- true + }() + + for { + if _, ok := data.GetOk(StateCancelled); ok { + responseCh <- true + break + } + + time.Sleep(10 * time.Millisecond) + } + + <-cancelCh + + // Test run data + expected := []string{"a", "b"} + results := data.Get("data").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test cleanup data + expected = []string{"b", "a"} + results = data.Get("cleanup").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test that it says it is cancelled + cancelled := data.Get(StateCancelled).(bool) + if !cancelled { + t.Errorf("not cancelled") + } +} + +func TestBasicRunner_Cancel_Special(t *testing.T) { + stepOne := &TestStepInjectCancel{} + stepTwo := &TestStepInjectCancel{} + r := &BasicRunner{Steps: []Step{stepOne, stepTwo}} + + state := new(BasicStateBag) + state.Put("runner", r) + r.Run(context.Background(), state) + + // test that state contains cancelled + if _, ok := state.GetOk(StateCancelled); !ok { + t.Errorf("cancelled should be in state bag") + } +} diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go new file mode 100644 index 000000000..882009494 --- /dev/null +++ b/helper/multistep/debug_runner.go @@ -0,0 +1,123 @@ +package multistep + +import ( + "fmt" + "reflect" + "sync" +) + +// DebugLocation is the location where the pause is occuring when debugging +// a step sequence. "DebugLocationAfterRun" is after the run of the named +// step. "DebugLocationBeforeCleanup" is before the cleanup of the named +// step. +type DebugLocation uint + +const ( + DebugLocationAfterRun DebugLocation = iota + DebugLocationBeforeCleanup +) + +// StepWrapper is an interface that wrapped steps can implement to expose their +// inner step names to the debug runner. +type StepWrapper interface { + // InnerStepName should return the human readable name of the wrapped step. + InnerStepName() string +} + +// DebugPauseFn is the type signature for the function that is called +// whenever the DebugRunner pauses. It allows the caller time to +// inspect the state of the multi-step sequence at a given step. +type DebugPauseFn func(DebugLocation, string, StateBag) + +// DebugRunner is a Runner that runs the given set of steps in order, +// but pauses between each step until it is told to continue. +type DebugRunner struct { + // Steps is the steps to run. These will be run in order. + Steps []Step + + // PauseFn is the function that is called whenever the debug runner + // pauses. The debug runner continues when this function returns. + // The function is given the state so that the state can be inspected. + PauseFn DebugPauseFn + + l sync.Mutex + runner *BasicRunner +} + +func (r *DebugRunner) Run(state StateBag) { + r.l.Lock() + if r.runner != nil { + panic("already running") + } + r.runner = new(BasicRunner) + r.l.Unlock() + + pauseFn := r.PauseFn + + // If no PauseFn is specified, use the default + if pauseFn == nil { + pauseFn = DebugPauseDefault + } + + // Rebuild the steps so that we insert the pause step after each + steps := make([]Step, len(r.Steps)*2) + for i, step := range r.Steps { + steps[i*2] = step + name := "" + if wrapped, ok := step.(StepWrapper); ok { + name = wrapped.InnerStepName() + } else { + name = reflect.Indirect(reflect.ValueOf(step)).Type().Name() + } + steps[(i*2)+1] = &debugStepPause{ + name, + pauseFn, + } + } + + // Then just use a basic runner to run it + r.runner.Steps = steps + r.runner.Run(state) +} + +func (r *DebugRunner) Cancel() { + r.l.Lock() + defer r.l.Unlock() + + if r.runner != nil { + r.runner.Cancel() + } +} + +// DebugPauseDefault is the default pause function when using the +// DebugRunner if no PauseFn is specified. It outputs some information +// to stderr about the step and waits for keyboard input on stdin before +// continuing. +func DebugPauseDefault(loc DebugLocation, name string, state StateBag) { + var locationString string + switch loc { + case DebugLocationAfterRun: + locationString = "after run of" + case DebugLocationBeforeCleanup: + locationString = "before cleanup of" + } + + fmt.Printf("Pausing %s step '%s'. Press any key to continue.\n", locationString, name) + + var line string + fmt.Scanln(&line) +} + +type debugStepPause struct { + StepName string + PauseFn DebugPauseFn +} + +func (s *debugStepPause) Run(state StateBag) StepAction { + s.PauseFn(DebugLocationAfterRun, s.StepName, state) + return ActionContinue +} + +func (s *debugStepPause) Cleanup(state StateBag) { + s.PauseFn(DebugLocationBeforeCleanup, s.StepName, state) +} diff --git a/helper/multistep/debug_runner_test.go b/helper/multistep/debug_runner_test.go new file mode 100644 index 000000000..78ce70a88 --- /dev/null +++ b/helper/multistep/debug_runner_test.go @@ -0,0 +1,176 @@ +package multistep + +import ( + "os" + "reflect" + "testing" + "time" + + "golang.org/x/net/context" +) + +func TestDebugRunner_Impl(t *testing.T) { + var raw interface{} + raw = &DebugRunner{} + if _, ok := raw.(Runner); !ok { + t.Fatal("DebugRunner must be a runner.") + } +} + +func TestDebugRunner_Run(t *testing.T) { + data := new(BasicStateBag) + stepA := &TestStepAcc{Data: "a"} + stepB := &TestStepAcc{Data: "b"} + + pauseFn := func(loc DebugLocation, name string, state StateBag) { + key := "data" + if loc == DebugLocationBeforeCleanup { + key = "cleanup" + } + + if _, ok := state.GetOk(key); !ok { + state.Put(key, make([]string, 0, 5)) + } + + data := state.Get(key).([]string) + state.Put(key, append(data, name)) + } + + r := &DebugRunner{ + Steps: []Step{stepA, stepB}, + PauseFn: pauseFn, + } + + r.Run(context.Background(), data) + + // Test data + expected := []string{"a", "TestStepAcc", "b", "TestStepAcc"} + results := data.Get("data").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected results: %#v", results) + } + + // Test cleanup + expected = []string{"TestStepAcc", "b", "TestStepAcc", "a"} + results = data.Get("cleanup").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected results: %#v", results) + } +} + +// confirm that can't run twice +func TestDebugRunner_Run_Run(t *testing.T) { + defer func() { + recover() + }() + ch := make(chan chan bool) + stepInt := &TestStepSync{ch} + stepWait := &TestStepWaitForever{} + r := &DebugRunner{Steps: []Step{stepInt, stepWait}} + + go r.Run(context.Background(), new(BasicStateBag)) + // wait until really running + <-ch + + // now try to run aain + r.Run(context.Background(), new(BasicStateBag)) + + // should not get here in nominal codepath + t.Errorf("Was able to run an already running DebugRunner") +} + +func TestDebugRunner_Cancel(t *testing.T) { + ch := make(chan chan bool) + data := new(BasicStateBag) + stepA := &TestStepAcc{Data: "a"} + stepB := &TestStepAcc{Data: "b"} + stepInt := &TestStepSync{ch} + stepC := &TestStepAcc{Data: "c"} + + r := &DebugRunner{} + r.Steps = []Step{stepA, stepB, stepInt, stepC} + + // cancelling an idle Runner is a no-op + r.Cancel() + + go r.Run(context.Background(), data) + + // Wait until we reach the sync point + responseCh := <-ch + + // Cancel then continue chain + cancelCh := make(chan bool) + go func() { + r.Cancel() + cancelCh <- true + }() + + for { + if _, ok := data.GetOk(StateCancelled); ok { + responseCh <- true + break + } + + time.Sleep(10 * time.Millisecond) + } + + <-cancelCh + + // Test run data + expected := []string{"a", "b"} + results := data.Get("data").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test cleanup data + expected = []string{"b", "a"} + results = data.Get("cleanup").([]string) + if !reflect.DeepEqual(results, expected) { + t.Errorf("unexpected result: %#v", results) + } + + // Test that it says it is cancelled + cancelled := data.Get(StateCancelled).(bool) + if !cancelled { + t.Errorf("not cancelled") + } +} + +func TestDebugPauseDefault(t *testing.T) { + + // Create a pipe pair so that writes/reads are blocked until we do it + r, w, err := os.Pipe() + if err != nil { + t.Fatalf("err: %s", err) + } + + // Set stdin so we can control it + oldStdin := os.Stdin + os.Stdin = r + defer func() { os.Stdin = oldStdin }() + + // Start pausing + complete := make(chan bool, 1) + go func() { + dr := &DebugRunner{Steps: []Step{ + &TestStepAcc{Data: "a"}, + }} + dr.Run(context.Background(), new(BasicStateBag)) + complete <- true + }() + + select { + case <-complete: + t.Fatal("shouldn't have completed") + case <-time.After(100 * time.Millisecond): + } + + w.Write([]byte("\n\n")) + + select { + case <-complete: + case <-time.After(100 * time.Millisecond): + t.Fatal("didn't complete") + } +} diff --git a/helper/multistep/doc.go b/helper/multistep/doc.go new file mode 100644 index 000000000..17570cda9 --- /dev/null +++ b/helper/multistep/doc.go @@ -0,0 +1,61 @@ +/* +multistep is a Go library for building up complex actions using discrete, +individual "steps." These steps are strung together and run in sequence +to achieve a more complex goal. The runner handles cleanup, cancelling, etc. +if necessary. + +## Basic Example + +Make a step to perform some action. The step can access your "state", +which is passed between steps by the runner. + +```go +type stepAdd struct{} + +func (s *stepAdd) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + // Read our value and assert that it is they type we want + value := state.Get("value").(int) + fmt.Printf("Value is %d\n", value) + + // Store some state back + state.Put("value", value + 1) + return multistep.ActionContinue +} + +func (s *stepAdd) Cleanup(multistep.StateBag) { + // This is called after all the steps have run or if the runner is + // cancelled so that cleanup can be performed. +} +``` + +Make a runner and call your array of Steps. + +```go +func main() { + // Our "bag of state" that we read the value from + state := new(multistep.BasicStateBag) + state.Put("value", 0) + + steps := []multistep.Step{ + &stepAdd{}, + &stepAdd{}, + &stepAdd{}, + } + + runner := &multistep.BasicRunner{Steps: steps} + + // Executes the steps + runner.Run(context.Background(), state) +} +``` + +This will produce: + +``` +Value is 0 +Value is 1 +Value is 2 +``` +*/ + +package multistep diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go new file mode 100644 index 000000000..4e3478dac --- /dev/null +++ b/helper/multistep/multistep.go @@ -0,0 +1,48 @@ +// multistep is a library for building up complex actions using individual, +// discrete steps. +package multistep + +// A StepAction determines the next step to take regarding multi-step actions. +type StepAction uint + +const ( + ActionContinue StepAction = iota + ActionHalt +) + +// This is the key set in the state bag when using the basic runner to +// signal that the step sequence was cancelled. +const StateCancelled = "cancelled" + +// This is the key set in the state bag when a step halted the sequence. +const StateHalted = "halted" + +// Step is a single step that is part of a potentially large sequence +// of other steps, responsible for performing some specific action. +type Step interface { + // Run is called to perform the action. The parameter is a "state bag" + // of untyped things. Please be very careful about type-checking the + // items in this bag. + // + // The return value determines whether multi-step sequences continue + // or should halt. + Run(StateBag) StepAction + + // Cleanup is called in reverse order of the steps that have run + // and allow steps to clean up after themselves. Do not assume if this + // ran that the entire multi-step sequence completed successfully. This + // method can be ran in the face of errors and cancellations as well. + // + // The parameter is the same "state bag" as Run, and represents the + // state at the latest possible time prior to calling Cleanup. + Cleanup(StateBag) +} + +// Runner is a thing that runs one or more steps. +type Runner interface { + // Run runs the steps with the given initial state. + Run(StateBag) + + // Cancel cancels a potentially running stack of steps. + Cancel() +} diff --git a/helper/multistep/multistep_test.go b/helper/multistep/multistep_test.go new file mode 100644 index 000000000..b8e4a0f9e --- /dev/null +++ b/helper/multistep/multistep_test.go @@ -0,0 +1,75 @@ +package multistep + +import "golang.org/x/net/context" + +// A step for testing that accumuluates data into a string slice in the +// the state bag. It always uses the "data" key in the state bag, and will +// initialize it. +type TestStepAcc struct { + // The data inserted into the state bag. + Data string + + // If true, it will halt at the step when it is run + Halt bool +} + +// A step that syncs by sending a channel and expecting a response. +type TestStepSync struct { + Ch chan chan bool +} + +// A step that sleeps forever +type TestStepWaitForever struct { +} + +// A step that manually flips state to cancelling in run +type TestStepInjectCancel struct { +} + +func (s TestStepAcc) Run(_ context.Context, state StateBag) StepAction { + s.insertData(state, "data") + + if s.Halt { + return ActionHalt + } + + return ActionContinue +} + +func (s TestStepAcc) Cleanup(state StateBag) { + s.insertData(state, "cleanup") +} + +func (s TestStepAcc) insertData(state StateBag, key string) { + if _, ok := state.GetOk(key); !ok { + state.Put(key, make([]string, 0, 5)) + } + + data := state.Get(key).([]string) + data = append(data, s.Data) + state.Put(key, data) +} + +func (s TestStepSync) Run(context.Context, StateBag) StepAction { + ch := make(chan bool) + s.Ch <- ch + <-ch + + return ActionContinue +} + +func (s TestStepSync) Cleanup(StateBag) {} + +func (s TestStepWaitForever) Run(context.Context, StateBag) StepAction { + select {} +} + +func (s TestStepWaitForever) Cleanup(StateBag) {} + +func (s TestStepInjectCancel) Run(_ context.Context, state StateBag) StepAction { + r := state.Get("runner").(*BasicRunner) + r.state = stateCancelling + return ActionContinue +} + +func (s TestStepInjectCancel) Cleanup(StateBag) {} diff --git a/helper/multistep/statebag.go b/helper/multistep/statebag.go new file mode 100644 index 000000000..d9f121561 --- /dev/null +++ b/helper/multistep/statebag.go @@ -0,0 +1,48 @@ +package multistep + +import ( + "context" + "sync" +) + +// StateBag implements StateBag by using a normal map underneath +// protected by a RWMutex. +type StateBag struct { + data map[string]interface{} + l sync.RWMutex + once sync.Once + ctx context.Context +} + +func (b *StateBag) Context() context.Context { + if b.ctx != nil { + return b.ctx + } + return context.Background() +} + +func (b *StateBag) Get(k string) interface{} { + result, _ := b.GetOk(k) + return result +} + +func (b *StateBag) GetOk(k string) (interface{}, bool) { + b.l.RLock() + defer b.l.RUnlock() + + result, ok := b.data[k] + return result, ok +} + +func (b *StateBag) Put(k string, v interface{}) { + b.l.Lock() + defer b.l.Unlock() + + // Make sure the map is initialized one time, on write + b.once.Do(func() { + b.data = make(map[string]interface{}) + }) + + // Write the data + b.data[k] = v +} diff --git a/helper/multistep/statebag_test.go b/helper/multistep/statebag_test.go new file mode 100644 index 000000000..1793ee6e2 --- /dev/null +++ b/helper/multistep/statebag_test.go @@ -0,0 +1,30 @@ +package multistep + +import ( + "testing" +) + +func TestBasicStateBag_ImplRunner(t *testing.T) { + var raw interface{} + raw = &BasicStateBag{} + if _, ok := raw.(StateBag); !ok { + t.Fatalf("must be a StateBag") + } +} + +func TestBasicStateBag(t *testing.T) { + b := new(BasicStateBag) + if b.Get("foo") != nil { + t.Fatalf("bad: %#v", b.Get("foo")) + } + + if _, ok := b.GetOk("foo"); ok { + t.Fatal("should not have foo") + } + + b.Put("foo", "bar") + + if b.Get("foo").(string) != "bar" { + t.Fatalf("bad") + } +} From 89d43256bb28fc91c2154e95330a8ac3207ee9f9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 19 Jan 2018 15:59:33 -0800 Subject: [PATCH 0428/1007] pass context into step.run --- helper/multistep/basic_runner.go | 4 ++-- helper/multistep/debug_runner.go | 3 ++- helper/multistep/multistep.go | 4 +++- helper/multistep/statebag.go | 27 +++++++++++++-------------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go index 305b801dd..eb5018d36 100644 --- a/helper/multistep/basic_runner.go +++ b/helper/multistep/basic_runner.go @@ -28,7 +28,7 @@ type BasicRunner struct { } func (b *BasicRunner) Run(state StateBag) { - ctx, cancel := context.WithCancel(state.Context()) + ctx, cancel := context.WithCancel(context.Background()) b.l.Lock() if b.state != stateIdle { @@ -70,7 +70,7 @@ func (b *BasicRunner) Run(state StateBag) { break } - action := step.Run(state) + action := step.Run(ctx, state) defer step.Cleanup(state) if _, ok := state.GetOk(StateCancelled); ok { diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 882009494..88af01c54 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,6 +1,7 @@ package multistep import ( + "context" "fmt" "reflect" "sync" @@ -113,7 +114,7 @@ type debugStepPause struct { PauseFn DebugPauseFn } -func (s *debugStepPause) Run(state StateBag) StepAction { +func (s *debugStepPause) Run(_ context.Context, state StateBag) StepAction { s.PauseFn(DebugLocationAfterRun, s.StepName, state) return ActionContinue } diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go index 4e3478dac..7b4e0801f 100644 --- a/helper/multistep/multistep.go +++ b/helper/multistep/multistep.go @@ -2,6 +2,8 @@ // discrete steps. package multistep +import "context" + // A StepAction determines the next step to take regarding multi-step actions. type StepAction uint @@ -26,7 +28,7 @@ type Step interface { // // The return value determines whether multi-step sequences continue // or should halt. - Run(StateBag) StepAction + Run(context.Context, StateBag) StepAction // Cleanup is called in reverse order of the steps that have run // and allow steps to clean up after themselves. Do not assume if this diff --git a/helper/multistep/statebag.go b/helper/multistep/statebag.go index d9f121561..dab712316 100644 --- a/helper/multistep/statebag.go +++ b/helper/multistep/statebag.go @@ -1,32 +1,31 @@ package multistep import ( - "context" "sync" ) -// StateBag implements StateBag by using a normal map underneath +// StateBag holds the state that is used by the Runner and Steps. The +// StateBag implementation must be safe for concurrent access. +type StateBag interface { + Get(string) interface{} + GetOk(string) (interface{}, bool) + Put(string, interface{}) +} + +// BasicStateBag implements StateBag by using a normal map underneath // protected by a RWMutex. -type StateBag struct { +type BasicStateBag struct { data map[string]interface{} l sync.RWMutex once sync.Once - ctx context.Context } -func (b *StateBag) Context() context.Context { - if b.ctx != nil { - return b.ctx - } - return context.Background() -} - -func (b *StateBag) Get(k string) interface{} { +func (b *BasicStateBag) Get(k string) interface{} { result, _ := b.GetOk(k) return result } -func (b *StateBag) GetOk(k string) (interface{}, bool) { +func (b *BasicStateBag) GetOk(k string) (interface{}, bool) { b.l.RLock() defer b.l.RUnlock() @@ -34,7 +33,7 @@ func (b *StateBag) GetOk(k string) (interface{}, bool) { return result, ok } -func (b *StateBag) Put(k string, v interface{}) { +func (b *BasicStateBag) Put(k string, v interface{}) { b.l.Lock() defer b.l.Unlock() From 366dc3da0a63b87c7b9a0e56d9c80ef2a25e782e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 19 Jan 2018 16:18:44 -0800 Subject: [PATCH 0429/1007] move multistep imports to helper. gomvpkg -from "github.com/mitchellh/multistep" -to "github.com/hashicorp/packer/helper/multistep" --- builder/alicloud/ecs/builder.go | 2 +- builder/alicloud/ecs/packer_helper.go | 2 +- builder/alicloud/ecs/ssh_helper.go | 2 +- builder/alicloud/ecs/step_attach_keypair.go | 3 ++- builder/alicloud/ecs/step_check_source_image.go | 2 +- builder/alicloud/ecs/step_config_eip.go | 2 +- builder/alicloud/ecs/step_config_key_pair.go | 2 +- builder/alicloud/ecs/step_config_public_ip.go | 2 +- builder/alicloud/ecs/step_config_security_group.go | 2 +- builder/alicloud/ecs/step_config_vpc.go | 2 +- builder/alicloud/ecs/step_config_vswitch.go | 2 +- builder/alicloud/ecs/step_create_image.go | 2 +- builder/alicloud/ecs/step_create_instance.go | 2 +- builder/alicloud/ecs/step_delete_images_snapshots.go | 2 +- builder/alicloud/ecs/step_mount_disk.go | 2 +- builder/alicloud/ecs/step_pre_validate.go | 2 +- builder/alicloud/ecs/step_region_copy_image.go | 2 +- builder/alicloud/ecs/step_run_instance.go | 2 +- builder/alicloud/ecs/step_share_image.go | 2 +- builder/alicloud/ecs/step_stop_instance.go | 2 +- builder/amazon/chroot/builder.go | 2 +- builder/amazon/chroot/cleanup.go | 2 +- builder/amazon/chroot/step_attach_volume.go | 2 +- builder/amazon/chroot/step_check_root_device.go | 2 +- builder/amazon/chroot/step_chroot_provision.go | 2 +- builder/amazon/chroot/step_copy_files.go | 2 ++ builder/amazon/chroot/step_create_volume.go | 2 +- builder/amazon/chroot/step_early_cleanup.go | 5 ++--- builder/amazon/chroot/step_early_unflock.go | 5 ++--- builder/amazon/chroot/step_flock.go | 2 ++ builder/amazon/chroot/step_instance_info.go | 2 +- builder/amazon/chroot/step_mount_device.go | 2 +- builder/amazon/chroot/step_mount_extra.go | 2 ++ builder/amazon/chroot/step_post_mount_commands.go | 2 +- builder/amazon/chroot/step_pre_mount_commands.go | 2 +- builder/amazon/chroot/step_prepare_device.go | 2 +- builder/amazon/chroot/step_register_ami.go | 2 +- builder/amazon/chroot/step_snapshot.go | 2 +- builder/amazon/common/ssh.go | 2 +- builder/amazon/common/ssh_test.go | 2 +- builder/amazon/common/state.go | 2 +- builder/amazon/common/step_ami_region_copy.go | 2 +- builder/amazon/common/step_create_tags.go | 2 +- builder/amazon/common/step_deregister_ami.go | 2 +- builder/amazon/common/step_encrypted_ami.go | 2 +- builder/amazon/common/step_get_password.go | 2 +- builder/amazon/common/step_key_pair.go | 2 +- builder/amazon/common/step_modify_ami_attributes.go | 2 +- builder/amazon/common/step_modify_ebs_instance.go | 2 +- builder/amazon/common/step_pre_validate.go | 2 +- builder/amazon/common/step_run_source_instance.go | 2 +- builder/amazon/common/step_run_spot_instance.go | 2 +- builder/amazon/common/step_security_group.go | 2 +- builder/amazon/common/step_source_ami_info.go | 2 +- builder/amazon/common/step_stop_ebs_instance.go | 2 +- builder/amazon/ebs/builder.go | 2 +- builder/amazon/ebs/step_cleanup_volumes.go | 2 +- builder/amazon/ebs/step_create_ami.go | 2 +- builder/amazon/ebssurrogate/builder.go | 2 +- builder/amazon/ebssurrogate/step_register_ami.go | 2 +- builder/amazon/ebssurrogate/step_snapshot_new_root.go | 2 +- builder/amazon/ebsvolume/builder.go | 2 +- builder/amazon/ebsvolume/step_tag_ebs_volumes.go | 2 +- builder/amazon/instance/builder.go | 2 +- builder/amazon/instance/step_bundle_volume.go | 2 +- builder/amazon/instance/step_register_ami.go | 2 +- builder/amazon/instance/step_upload_bundle.go | 2 +- builder/amazon/instance/step_upload_x509_cert.go | 5 ++--- builder/azure/arm/builder.go | 2 +- builder/azure/arm/step.go | 2 +- builder/azure/arm/step_capture_image.go | 2 +- builder/azure/arm/step_capture_image_test.go | 2 +- builder/azure/arm/step_create_resource_group.go | 2 +- builder/azure/arm/step_create_resource_group_test.go | 2 +- builder/azure/arm/step_delete_os_disk.go | 2 +- builder/azure/arm/step_delete_os_disk_test.go | 2 +- builder/azure/arm/step_delete_resource_group.go | 2 +- builder/azure/arm/step_delete_resource_group_test.go | 2 +- builder/azure/arm/step_deploy_template.go | 2 +- builder/azure/arm/step_deploy_template_test.go | 2 +- builder/azure/arm/step_get_certificate.go | 2 +- builder/azure/arm/step_get_certificate_test.go | 2 +- builder/azure/arm/step_get_ip_address.go | 2 +- builder/azure/arm/step_get_ip_address_test.go | 2 +- builder/azure/arm/step_get_os_disk.go | 2 +- builder/azure/arm/step_get_os_disk_test.go | 2 +- builder/azure/arm/step_power_off_compute.go | 2 +- builder/azure/arm/step_power_off_compute_test.go | 2 +- builder/azure/arm/step_set_certificate.go | 2 +- builder/azure/arm/step_set_certificate_test.go | 2 +- builder/azure/arm/step_test.go | 3 ++- builder/azure/arm/step_validate_template.go | 2 +- builder/azure/arm/step_validate_template_test.go | 2 +- builder/azure/common/lin/ssh.go | 2 +- builder/azure/common/lin/step_create_cert.go | 2 +- builder/azure/common/lin/step_generalize_os.go | 5 ++--- builder/azure/common/state_bag.go | 2 +- builder/cloudstack/builder.go | 2 +- builder/cloudstack/ssh.go | 2 +- builder/cloudstack/step_configure_networking.go | 2 +- builder/cloudstack/step_create_instance.go | 2 +- builder/cloudstack/step_create_security_group.go | 2 +- builder/cloudstack/step_create_template.go | 2 +- builder/cloudstack/step_keypair.go | 2 +- builder/cloudstack/step_prepare_config.go | 2 +- builder/cloudstack/step_shutdown_instance.go | 2 +- builder/digitalocean/builder.go | 2 +- builder/digitalocean/ssh.go | 2 +- builder/digitalocean/step_create_droplet.go | 2 +- builder/digitalocean/step_create_ssh_key.go | 2 +- builder/digitalocean/step_droplet_info.go | 2 +- builder/digitalocean/step_power_off.go | 2 +- builder/digitalocean/step_shutdown.go | 2 +- builder/digitalocean/step_snapshot.go | 2 +- builder/docker/builder.go | 2 +- builder/docker/comm.go | 2 +- builder/docker/step_commit.go | 3 +-- builder/docker/step_commit_test.go | 1 + builder/docker/step_connect_docker.go | 1 + builder/docker/step_export.go | 2 +- builder/docker/step_export_test.go | 1 + builder/docker/step_pull.go | 2 +- builder/docker/step_pull_test.go | 1 + builder/docker/step_run.go | 3 +-- builder/docker/step_run_test.go | 1 + builder/docker/step_temp_dir.go | 2 ++ builder/docker/step_temp_dir_test.go | 2 +- builder/docker/step_test.go | 5 ++--- builder/file/builder.go | 2 +- builder/googlecompute/builder.go | 2 +- builder/googlecompute/ssh.go | 2 +- builder/googlecompute/step_check_existing_image.go | 2 +- builder/googlecompute/step_check_existing_image_test.go | 1 + builder/googlecompute/step_create_image.go | 2 +- builder/googlecompute/step_create_image_test.go | 2 +- builder/googlecompute/step_create_instance.go | 2 +- builder/googlecompute/step_create_instance_test.go | 2 +- builder/googlecompute/step_create_ssh_key.go | 2 +- builder/googlecompute/step_create_ssh_key_test.go | 2 +- builder/googlecompute/step_create_windows_password.go | 2 +- builder/googlecompute/step_create_windows_password_test.go | 2 +- builder/googlecompute/step_instance_info.go | 2 +- builder/googlecompute/step_instance_info_test.go | 1 + builder/googlecompute/step_teardown_instance.go | 2 +- builder/googlecompute/step_teardown_instance_test.go | 1 + builder/googlecompute/step_test.go | 2 +- builder/googlecompute/step_wait_startup_script.go | 2 +- builder/googlecompute/step_wait_startup_script_test.go | 4 +--- builder/googlecompute/winrm.go | 2 +- builder/hyperv/common/ssh.go | 2 +- builder/hyperv/common/step_clone_vm.go | 2 +- builder/hyperv/common/step_configure_ip.go | 2 +- builder/hyperv/common/step_configure_vlan.go | 2 +- builder/hyperv/common/step_create_external_switch.go | 2 +- builder/hyperv/common/step_create_switch.go | 3 +-- builder/hyperv/common/step_create_tempdir.go | 2 +- builder/hyperv/common/step_create_vm.go | 2 +- builder/hyperv/common/step_disable_vlan.go | 3 +-- builder/hyperv/common/step_enable_integration_service.go | 3 +-- builder/hyperv/common/step_export_vm.go | 2 +- builder/hyperv/common/step_mount_dvddrive.go | 2 ++ builder/hyperv/common/step_mount_floppydrive.go | 2 ++ builder/hyperv/common/step_mount_guest_additions.go | 5 ++--- builder/hyperv/common/step_mount_secondary_dvd_images.go | 5 ++--- builder/hyperv/common/step_output_dir.go | 2 +- builder/hyperv/common/step_polling_installation.go | 2 +- builder/hyperv/common/step_reboot_vm.go | 5 ++--- builder/hyperv/common/step_run.go | 5 ++--- builder/hyperv/common/step_shutdown.go | 2 +- builder/hyperv/common/step_sleep.go | 5 ++--- builder/hyperv/common/step_type_boot_command.go | 2 +- builder/hyperv/common/step_unmount_dvddrive.go | 3 +-- builder/hyperv/common/step_unmount_floppydrive.go | 3 +-- builder/hyperv/common/step_unmount_guest_additions.go | 3 +-- builder/hyperv/common/step_unmount_secondary_dvd_images.go | 3 +-- builder/hyperv/common/step_wait_for_install_to_complete.go | 5 ++--- builder/hyperv/iso/builder.go | 2 +- builder/hyperv/iso/builder_test.go | 3 ++- builder/hyperv/vmcx/builder.go | 2 +- builder/hyperv/vmcx/builder_test.go | 4 +++- builder/lxc/builder.go | 5 ++++- builder/lxc/step_export.go | 2 ++ builder/lxc/step_lxc_create.go | 2 ++ builder/lxc/step_prepare_output_dir.go | 2 ++ builder/lxc/step_provision.go | 5 ++--- builder/lxc/step_wait_init.go | 2 ++ builder/lxd/builder.go | 3 ++- builder/lxd/step_lxd_launch.go | 5 ++--- builder/lxd/step_provision.go | 5 ++--- builder/lxd/step_publish.go | 5 ++--- builder/null/builder.go | 2 +- builder/null/ssh.go | 2 +- builder/oneandone/builder.go | 3 ++- builder/oneandone/ssh.go | 2 +- builder/oneandone/step_create_server.go | 4 +++- builder/oneandone/step_create_sshkey.go | 4 +--- builder/oneandone/step_take_snapshot.go | 2 +- builder/openstack/builder.go | 2 +- builder/openstack/server.go | 2 +- builder/openstack/ssh.go | 2 +- builder/openstack/step_add_image_members.go | 2 +- builder/openstack/step_allocate_ip.go | 2 +- builder/openstack/step_create_image.go | 2 +- builder/openstack/step_get_password.go | 2 +- builder/openstack/step_key_pair.go | 2 +- builder/openstack/step_load_extensions.go | 2 +- builder/openstack/step_load_flavor.go | 2 +- builder/openstack/step_run_source_server.go | 2 +- builder/openstack/step_stop_server.go | 2 +- builder/openstack/step_update_image_visibility.go | 2 +- builder/openstack/step_wait_for_rackconnect.go | 2 +- builder/oracle/oci/builder.go | 2 +- builder/oracle/oci/ssh.go | 2 +- builder/oracle/oci/step_create_instance.go | 2 +- builder/oracle/oci/step_create_instance_test.go | 2 +- builder/oracle/oci/step_image.go | 2 +- builder/oracle/oci/step_image_test.go | 2 +- builder/oracle/oci/step_instance_info.go | 2 +- builder/oracle/oci/step_instance_info_test.go | 2 +- builder/oracle/oci/step_ssh_key_pair.go | 2 +- builder/oracle/oci/step_test.go | 2 +- builder/parallels/common/ssh.go | 2 +- builder/parallels/common/step_attach_floppy.go | 2 +- builder/parallels/common/step_attach_floppy_test.go | 2 +- builder/parallels/common/step_attach_parallels_tools.go | 2 +- builder/parallels/common/step_compact_disk.go | 2 +- builder/parallels/common/step_compact_disk_test.go | 2 +- builder/parallels/common/step_output_dir.go | 2 +- builder/parallels/common/step_output_dir_test.go | 2 +- builder/parallels/common/step_prepare_parallels_tools.go | 2 +- .../parallels/common/step_prepare_parallels_tools_test.go | 2 +- builder/parallels/common/step_prlctl.go | 2 +- builder/parallels/common/step_run.go | 2 +- builder/parallels/common/step_shutdown.go | 2 +- builder/parallels/common/step_shutdown_test.go | 2 +- builder/parallels/common/step_test.go | 2 +- builder/parallels/common/step_type_boot_command.go | 2 +- builder/parallels/common/step_type_boot_command_test.go | 2 +- builder/parallels/common/step_upload_parallels_tools.go | 2 +- builder/parallels/common/step_upload_parallels_tools_test.go | 2 +- builder/parallels/common/step_upload_version.go | 2 +- builder/parallels/common/step_upload_version_test.go | 2 +- builder/parallels/iso/builder.go | 2 +- builder/parallels/iso/step_attach_iso.go | 2 +- builder/parallels/iso/step_create_disk.go | 2 +- builder/parallels/iso/step_create_vm.go | 2 +- builder/parallels/iso/step_set_boot_order.go | 2 +- builder/parallels/pvm/builder.go | 2 +- builder/parallels/pvm/step_import.go | 2 +- builder/parallels/pvm/step_test.go | 2 +- builder/profitbricks/builder.go | 3 ++- builder/profitbricks/ssh.go | 2 +- builder/profitbricks/step_create_server.go | 2 +- builder/profitbricks/step_create_ssh_key.go | 4 +--- builder/profitbricks/step_take_snapshot.go | 2 +- builder/qemu/builder.go | 2 +- builder/qemu/driver.go | 2 +- builder/qemu/ssh.go | 2 +- builder/qemu/step_boot_wait.go | 5 ++--- builder/qemu/step_configure_vnc.go | 2 +- builder/qemu/step_convert_disk.go | 2 +- builder/qemu/step_copy_disk.go | 2 +- builder/qemu/step_create_disk.go | 2 +- builder/qemu/step_forward_ssh.go | 2 +- builder/qemu/step_prepare_output_dir.go | 2 ++ builder/qemu/step_resize_disk.go | 2 +- builder/qemu/step_run.go | 2 +- builder/qemu/step_set_iso.go | 2 +- builder/qemu/step_shutdown.go | 2 +- builder/qemu/step_type_boot_command.go | 3 ++- builder/triton/builder.go | 2 +- builder/triton/ssh.go | 2 +- builder/triton/step_create_image_from_machine.go | 2 +- builder/triton/step_create_image_from_machine_test.go | 2 +- builder/triton/step_create_source_machine.go | 2 +- builder/triton/step_create_source_machine_test.go | 2 +- builder/triton/step_delete_machine.go | 2 +- builder/triton/step_delete_machine_test.go | 2 +- builder/triton/step_stop_machine.go | 2 +- builder/triton/step_stop_machine_test.go | 2 +- builder/triton/step_test.go | 5 ++--- builder/triton/step_wait_for_stop_to_not_fail.go | 2 +- builder/virtualbox/common/ssh.go | 2 +- builder/virtualbox/common/step_attach_floppy.go | 2 ++ builder/virtualbox/common/step_attach_floppy_test.go | 1 + builder/virtualbox/common/step_attach_guest_additions.go | 5 ++--- builder/virtualbox/common/step_configure_vrdp.go | 2 +- builder/virtualbox/common/step_download_guest_additions.go | 2 +- builder/virtualbox/common/step_export.go | 2 ++ builder/virtualbox/common/step_export_test.go | 1 + builder/virtualbox/common/step_forward_ssh.go | 2 +- builder/virtualbox/common/step_output_dir.go | 2 +- builder/virtualbox/common/step_output_dir_test.go | 1 + builder/virtualbox/common/step_remove_devices.go | 2 +- builder/virtualbox/common/step_remove_devices_test.go | 1 + builder/virtualbox/common/step_run.go | 2 +- builder/virtualbox/common/step_shutdown.go | 2 ++ builder/virtualbox/common/step_shutdown_test.go | 2 ++ builder/virtualbox/common/step_suppress_messages.go | 5 ++--- builder/virtualbox/common/step_suppress_messages_test.go | 1 + builder/virtualbox/common/step_test.go | 5 ++--- builder/virtualbox/common/step_type_boot_command.go | 2 +- builder/virtualbox/common/step_upload_guest_additions.go | 2 +- builder/virtualbox/common/step_upload_version.go | 5 ++--- builder/virtualbox/common/step_upload_version_test.go | 5 ++--- builder/virtualbox/common/step_vboxmanage.go | 2 +- builder/virtualbox/iso/builder.go | 2 +- builder/virtualbox/iso/step_attach_iso.go | 2 +- builder/virtualbox/iso/step_create_disk.go | 2 +- builder/virtualbox/iso/step_create_vm.go | 2 +- builder/virtualbox/ovf/builder.go | 2 +- builder/virtualbox/ovf/step_import.go | 2 +- builder/virtualbox/ovf/step_import_test.go | 3 ++- builder/virtualbox/ovf/step_test.go | 3 ++- builder/vmware/common/driver.go | 2 +- builder/vmware/common/driver_fusion5.go | 2 +- builder/vmware/common/driver_mock.go | 2 +- builder/vmware/common/driver_player5.go | 2 +- builder/vmware/common/driver_workstation9.go | 2 +- builder/vmware/common/ssh.go | 2 +- builder/vmware/common/step_clean_files.go | 2 ++ builder/vmware/common/step_clean_vmx.go | 2 +- builder/vmware/common/step_clean_vmx_test.go | 2 +- builder/vmware/common/step_compact_disk.go | 5 ++--- builder/vmware/common/step_compact_disk_test.go | 2 +- builder/vmware/common/step_configure_vmx.go | 2 +- builder/vmware/common/step_configure_vmx_test.go | 2 +- builder/vmware/common/step_configure_vnc.go | 2 +- builder/vmware/common/step_output_dir.go | 2 +- builder/vmware/common/step_output_dir_test.go | 1 + builder/vmware/common/step_prepare_tools.go | 2 +- builder/vmware/common/step_prepare_tools_test.go | 2 +- builder/vmware/common/step_run.go | 2 +- builder/vmware/common/step_run_test.go | 2 +- builder/vmware/common/step_shutdown.go | 2 ++ builder/vmware/common/step_shutdown_test.go | 2 +- builder/vmware/common/step_suppress_messages.go | 5 ++--- builder/vmware/common/step_suppress_messages_test.go | 2 +- builder/vmware/common/step_test.go | 5 ++--- builder/vmware/common/step_type_boot_command.go | 2 +- builder/vmware/common/step_upload_tools.go | 2 +- builder/vmware/iso/builder.go | 2 +- builder/vmware/iso/driver_esx5.go | 2 +- builder/vmware/iso/driver_esx5_test.go | 2 +- builder/vmware/iso/step_create_disk.go | 3 ++- builder/vmware/iso/step_create_vmx.go | 2 +- builder/vmware/iso/step_export.go | 2 +- builder/vmware/iso/step_export_test.go | 1 + builder/vmware/iso/step_register.go | 2 +- builder/vmware/iso/step_register_test.go | 1 + builder/vmware/iso/step_remote_upload.go | 3 ++- builder/vmware/iso/step_test.go | 3 ++- builder/vmware/iso/step_upload_vmx.go | 3 ++- builder/vmware/vmx/builder.go | 2 +- builder/vmware/vmx/step_clone_vmx.go | 2 +- builder/vmware/vmx/step_clone_vmx_test.go | 2 +- builder/vmware/vmx/step_test.go | 2 +- common/multistep_debug.go | 2 ++ common/multistep_runner.go | 2 +- common/step_create_floppy.go | 2 +- common/step_create_floppy_test.go | 2 ++ common/step_download.go | 2 +- common/step_download_test.go | 1 + common/step_http_server.go | 2 +- common/step_provision.go | 2 ++ common/step_provision_test.go | 1 + helper/communicator/step_connect.go | 2 +- helper/communicator/step_connect_ssh.go | 2 +- helper/communicator/step_connect_test.go | 2 +- helper/communicator/step_connect_winrm.go | 2 +- post-processor/googlecompute-export/post-processor.go | 2 +- post-processor/vagrant-cloud/post-processor.go | 2 +- post-processor/vagrant-cloud/step_create_provider.go | 3 +-- post-processor/vagrant-cloud/step_create_version.go | 3 +-- post-processor/vagrant-cloud/step_prepare_upload.go | 2 +- post-processor/vagrant-cloud/step_release_version.go | 2 +- post-processor/vagrant-cloud/step_upload.go | 2 +- post-processor/vagrant-cloud/step_verify_box.go | 3 +-- post-processor/vsphere-template/post-processor.go | 2 +- post-processor/vsphere-template/step_choose_datacenter.go | 2 +- post-processor/vsphere-template/step_create_folder.go | 2 +- post-processor/vsphere-template/step_mark_as_template.go | 2 +- 382 files changed, 447 insertions(+), 412 deletions(-) diff --git a/builder/alicloud/ecs/builder.go b/builder/alicloud/ecs/builder.go index 5f7973723..08a7dad08 100644 --- a/builder/alicloud/ecs/builder.go +++ b/builder/alicloud/ecs/builder.go @@ -10,9 +10,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // The unique ID for this builder diff --git a/builder/alicloud/ecs/packer_helper.go b/builder/alicloud/ecs/packer_helper.go index 2486b81cf..15f257381 100644 --- a/builder/alicloud/ecs/packer_helper.go +++ b/builder/alicloud/ecs/packer_helper.go @@ -3,8 +3,8 @@ package ecs import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func message(state multistep.StateBag, module string) { diff --git a/builder/alicloud/ecs/ssh_helper.go b/builder/alicloud/ecs/ssh_helper.go index e08b3afff..aac733ece 100644 --- a/builder/alicloud/ecs/ssh_helper.go +++ b/builder/alicloud/ecs/ssh_helper.go @@ -7,7 +7,7 @@ import ( "time" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/alicloud/ecs/step_attach_keypair.go b/builder/alicloud/ecs/step_attach_keypair.go index b28de52b9..012efd2b1 100644 --- a/builder/alicloud/ecs/step_attach_keypair.go +++ b/builder/alicloud/ecs/step_attach_keypair.go @@ -7,8 +7,9 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) type stepAttachKeyPar struct { diff --git a/builder/alicloud/ecs/step_check_source_image.go b/builder/alicloud/ecs/step_check_source_image.go index 4990f99d5..3f3ee87d0 100644 --- a/builder/alicloud/ecs/step_check_source_image.go +++ b/builder/alicloud/ecs/step_check_source_image.go @@ -5,8 +5,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCheckAlicloudSourceImage struct { diff --git a/builder/alicloud/ecs/step_config_eip.go b/builder/alicloud/ecs/step_config_eip.go index b0845ba2a..2d626bf62 100644 --- a/builder/alicloud/ecs/step_config_eip.go +++ b/builder/alicloud/ecs/step_config_eip.go @@ -5,8 +5,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type setpConfigAlicloudEIP struct { diff --git a/builder/alicloud/ecs/step_config_key_pair.go b/builder/alicloud/ecs/step_config_key_pair.go index 22ccd28b6..62fb41a9d 100644 --- a/builder/alicloud/ecs/step_config_key_pair.go +++ b/builder/alicloud/ecs/step_config_key_pair.go @@ -8,8 +8,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepConfigAlicloudKeyPair struct { diff --git a/builder/alicloud/ecs/step_config_public_ip.go b/builder/alicloud/ecs/step_config_public_ip.go index 65b7f3fe2..c8859afa3 100644 --- a/builder/alicloud/ecs/step_config_public_ip.go +++ b/builder/alicloud/ecs/step_config_public_ip.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepConfigAlicloudPublicIP struct { diff --git a/builder/alicloud/ecs/step_config_security_group.go b/builder/alicloud/ecs/step_config_security_group.go index dc8c083b2..8a20915d4 100644 --- a/builder/alicloud/ecs/step_config_security_group.go +++ b/builder/alicloud/ecs/step_config_security_group.go @@ -7,8 +7,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepConfigAlicloudSecurityGroup struct { diff --git a/builder/alicloud/ecs/step_config_vpc.go b/builder/alicloud/ecs/step_config_vpc.go index c4bdd59a3..c03ed3944 100644 --- a/builder/alicloud/ecs/step_config_vpc.go +++ b/builder/alicloud/ecs/step_config_vpc.go @@ -7,8 +7,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepConfigAlicloudVPC struct { diff --git a/builder/alicloud/ecs/step_config_vswitch.go b/builder/alicloud/ecs/step_config_vswitch.go index dfa858d0b..357e40624 100644 --- a/builder/alicloud/ecs/step_config_vswitch.go +++ b/builder/alicloud/ecs/step_config_vswitch.go @@ -7,8 +7,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepConfigAlicloudVSwitch struct { diff --git a/builder/alicloud/ecs/step_create_image.go b/builder/alicloud/ecs/step_create_image.go index 5060c78ca..852376250 100644 --- a/builder/alicloud/ecs/step_create_image.go +++ b/builder/alicloud/ecs/step_create_image.go @@ -5,8 +5,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateAlicloudImage struct { diff --git a/builder/alicloud/ecs/step_create_instance.go b/builder/alicloud/ecs/step_create_instance.go index c4f33f19c..b2019ade6 100644 --- a/builder/alicloud/ecs/step_create_instance.go +++ b/builder/alicloud/ecs/step_create_instance.go @@ -7,8 +7,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateAlicloudInstance struct { diff --git a/builder/alicloud/ecs/step_delete_images_snapshots.go b/builder/alicloud/ecs/step_delete_images_snapshots.go index 24104fef0..841190934 100644 --- a/builder/alicloud/ecs/step_delete_images_snapshots.go +++ b/builder/alicloud/ecs/step_delete_images_snapshots.go @@ -6,8 +6,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepDeleteAlicloudImageSnapshots struct { diff --git a/builder/alicloud/ecs/step_mount_disk.go b/builder/alicloud/ecs/step_mount_disk.go index 222b27f08..8ec517ece 100644 --- a/builder/alicloud/ecs/step_mount_disk.go +++ b/builder/alicloud/ecs/step_mount_disk.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepMountAlicloudDisk struct { diff --git a/builder/alicloud/ecs/step_pre_validate.go b/builder/alicloud/ecs/step_pre_validate.go index 527d84fbf..fb4a663f5 100644 --- a/builder/alicloud/ecs/step_pre_validate.go +++ b/builder/alicloud/ecs/step_pre_validate.go @@ -5,8 +5,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepPreValidate struct { diff --git a/builder/alicloud/ecs/step_region_copy_image.go b/builder/alicloud/ecs/step_region_copy_image.go index f92878712..c7b68f697 100644 --- a/builder/alicloud/ecs/step_region_copy_image.go +++ b/builder/alicloud/ecs/step_region_copy_image.go @@ -5,8 +5,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type setpRegionCopyAlicloudImage struct { diff --git a/builder/alicloud/ecs/step_run_instance.go b/builder/alicloud/ecs/step_run_instance.go index a92637648..f8e0f6b68 100644 --- a/builder/alicloud/ecs/step_run_instance.go +++ b/builder/alicloud/ecs/step_run_instance.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepRunAlicloudInstance struct { diff --git a/builder/alicloud/ecs/step_share_image.go b/builder/alicloud/ecs/step_share_image.go index 50e5a640f..7a95fdfd6 100644 --- a/builder/alicloud/ecs/step_share_image.go +++ b/builder/alicloud/ecs/step_share_image.go @@ -5,8 +5,8 @@ import ( "github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type setpShareAlicloudImage struct { diff --git a/builder/alicloud/ecs/step_stop_instance.go b/builder/alicloud/ecs/step_stop_instance.go index b12a74c63..4a55c3aba 100644 --- a/builder/alicloud/ecs/step_stop_instance.go +++ b/builder/alicloud/ecs/step_stop_instance.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/denverdino/aliyungo/ecs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepStopAlicloudInstance struct { diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 80d6ae1b9..607ad06a9 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -13,9 +13,9 @@ import ( awscommon "github.com/hashicorp/packer/builder/amazon/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // The unique ID for this builder diff --git a/builder/amazon/chroot/cleanup.go b/builder/amazon/chroot/cleanup.go index 0be3bef3f..0befac174 100644 --- a/builder/amazon/chroot/cleanup.go +++ b/builder/amazon/chroot/cleanup.go @@ -1,7 +1,7 @@ package chroot import ( - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // Cleanup is an interface that some steps implement for early cleanup. diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index 6b83f440b..47fac4d57 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -8,8 +8,8 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepAttachVolume attaches the previously created volume to an diff --git a/builder/amazon/chroot/step_check_root_device.go b/builder/amazon/chroot/step_check_root_device.go index fa0097aa4..241a46cc1 100644 --- a/builder/amazon/chroot/step_check_root_device.go +++ b/builder/amazon/chroot/step_check_root_device.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCheckRootDevice makes sure the root device on the AMI is EBS-backed. diff --git a/builder/amazon/chroot/step_chroot_provision.go b/builder/amazon/chroot/step_chroot_provision.go index 941e071b1..eb651d78c 100644 --- a/builder/amazon/chroot/step_chroot_provision.go +++ b/builder/amazon/chroot/step_chroot_provision.go @@ -3,8 +3,8 @@ package chroot import ( "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepChrootProvision provisions the instance within a chroot. diff --git a/builder/amazon/chroot/step_copy_files.go b/builder/amazon/chroot/step_copy_files.go index e5c8e2215..d608141da 100644 --- a/builder/amazon/chroot/step_copy_files.go +++ b/builder/amazon/chroot/step_copy_files.go @@ -3,6 +3,8 @@ package chroot import ( "bytes" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "path/filepath" diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index c1ecbf1a9..ce4b01e64 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -7,8 +7,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateVolume creates a new volume from the snapshot of the root diff --git a/builder/amazon/chroot/step_early_cleanup.go b/builder/amazon/chroot/step_early_cleanup.go index ebbf3a0ed..c3aecc85c 100644 --- a/builder/amazon/chroot/step_early_cleanup.go +++ b/builder/amazon/chroot/step_early_cleanup.go @@ -2,10 +2,9 @@ package chroot import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // StepEarlyCleanup performs some of the cleanup steps early in order to diff --git a/builder/amazon/chroot/step_early_unflock.go b/builder/amazon/chroot/step_early_unflock.go index b1399c167..92eff391c 100644 --- a/builder/amazon/chroot/step_early_unflock.go +++ b/builder/amazon/chroot/step_early_unflock.go @@ -2,10 +2,9 @@ package chroot import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // StepEarlyUnflock unlocks the flock. diff --git a/builder/amazon/chroot/step_flock.go b/builder/amazon/chroot/step_flock.go index 711b2581e..4b6dd284e 100644 --- a/builder/amazon/chroot/step_flock.go +++ b/builder/amazon/chroot/step_flock.go @@ -2,6 +2,8 @@ package chroot import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "os" "path/filepath" diff --git a/builder/amazon/chroot/step_instance_info.go b/builder/amazon/chroot/step_instance_info.go index 652808952..307e24aa8 100644 --- a/builder/amazon/chroot/step_instance_info.go +++ b/builder/amazon/chroot/step_instance_info.go @@ -7,8 +7,8 @@ import ( "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepInstanceInfo verifies that this builder is running on an EC2 instance. diff --git a/builder/amazon/chroot/step_mount_device.go b/builder/amazon/chroot/step_mount_device.go index 8f740bd6e..07757dba2 100644 --- a/builder/amazon/chroot/step_mount_device.go +++ b/builder/amazon/chroot/step_mount_device.go @@ -9,9 +9,9 @@ import ( "strings" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type mountPathData struct { diff --git a/builder/amazon/chroot/step_mount_extra.go b/builder/amazon/chroot/step_mount_extra.go index fb62467ba..074f40199 100644 --- a/builder/amazon/chroot/step_mount_extra.go +++ b/builder/amazon/chroot/step_mount_extra.go @@ -3,6 +3,8 @@ package chroot import ( "bytes" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "os" "os/exec" "syscall" diff --git a/builder/amazon/chroot/step_post_mount_commands.go b/builder/amazon/chroot/step_post_mount_commands.go index de927f9aa..0ebd68d60 100644 --- a/builder/amazon/chroot/step_post_mount_commands.go +++ b/builder/amazon/chroot/step_post_mount_commands.go @@ -1,8 +1,8 @@ package chroot import ( + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type postMountCommandsData struct { diff --git a/builder/amazon/chroot/step_pre_mount_commands.go b/builder/amazon/chroot/step_pre_mount_commands.go index 63aa6d15a..9a9bf69ac 100644 --- a/builder/amazon/chroot/step_pre_mount_commands.go +++ b/builder/amazon/chroot/step_pre_mount_commands.go @@ -1,8 +1,8 @@ package chroot import ( + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type preMountCommandsData struct { diff --git a/builder/amazon/chroot/step_prepare_device.go b/builder/amazon/chroot/step_prepare_device.go index 6cbefb2cc..18036f0a2 100644 --- a/builder/amazon/chroot/step_prepare_device.go +++ b/builder/amazon/chroot/step_prepare_device.go @@ -5,8 +5,8 @@ import ( "log" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepPrepareDevice finds an available device and sets it. diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index a19266f57..c37892723 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -6,8 +6,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepRegisterAMI creates the AMI. diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index 5cd646662..78c7a9a21 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -7,8 +7,8 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepSnapshot creates a snapshot of the created volume. diff --git a/builder/amazon/common/ssh.go b/builder/amazon/common/ssh.go index be414a8a0..086bc12ee 100644 --- a/builder/amazon/common/ssh.go +++ b/builder/amazon/common/ssh.go @@ -9,7 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/amazon/common/ssh_test.go b/builder/amazon/common/ssh_test.go index e39088e67..02823d1d9 100644 --- a/builder/amazon/common/ssh_test.go +++ b/builder/amazon/common/ssh_test.go @@ -5,7 +5,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) const ( diff --git a/builder/amazon/common/state.go b/builder/amazon/common/state.go index 42beb0e00..4b5fe0d46 100644 --- a/builder/amazon/common/state.go +++ b/builder/amazon/common/state.go @@ -12,7 +12,7 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // StateRefreshFunc is a function type used for StateChangeConf that is diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index f98dcbb92..3d9e4f1b6 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -7,8 +7,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepAMIRegionCopy struct { diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index d3183c7a7..b0170f850 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -8,9 +8,9 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" retry "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type StepCreateTags struct { diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index 188a40808..c8c18aca5 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -5,8 +5,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepDeregisterAMI struct { diff --git a/builder/amazon/common/step_encrypted_ami.go b/builder/amazon/common/step_encrypted_ami.go index 16c4ce7a8..f47f1a19c 100644 --- a/builder/amazon/common/step_encrypted_ami.go +++ b/builder/amazon/common/step_encrypted_ami.go @@ -6,8 +6,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreateEncryptedAMICopy struct { diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index b457658b9..50a720ef7 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -12,8 +12,8 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepGetPassword reads the password from a Windows server and sets it diff --git a/builder/amazon/common/step_key_pair.go b/builder/amazon/common/step_key_pair.go index 68ce5af2d..cc01949c6 100644 --- a/builder/amazon/common/step_key_pair.go +++ b/builder/amazon/common/step_key_pair.go @@ -7,8 +7,8 @@ import ( "runtime" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepKeyPair struct { diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index 295d98ce9..dc024d8bb 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -6,9 +6,9 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type StepModifyAMIAttributes struct { diff --git a/builder/amazon/common/step_modify_ebs_instance.go b/builder/amazon/common/step_modify_ebs_instance.go index 12c2367aa..0f9da523f 100644 --- a/builder/amazon/common/step_modify_ebs_instance.go +++ b/builder/amazon/common/step_modify_ebs_instance.go @@ -5,8 +5,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepModifyEBSBackedInstance struct { diff --git a/builder/amazon/common/step_pre_validate.go b/builder/amazon/common/step_pre_validate.go index 4c57cce0b..1e4a2b2a5 100644 --- a/builder/amazon/common/step_pre_validate.go +++ b/builder/amazon/common/step_pre_validate.go @@ -5,8 +5,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepPreValidate provides an opportunity to pre-validate any configuration for diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index cf1557c54..9186c868c 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -10,9 +10,9 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type StepRunSourceInstance struct { diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 27938ece6..9968ed962 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -13,9 +13,9 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" retry "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type StepRunSpotInstance struct { diff --git a/builder/amazon/common/step_security_group.go b/builder/amazon/common/step_security_group.go index 8027903f5..a03f496e6 100644 --- a/builder/amazon/common/step_security_group.go +++ b/builder/amazon/common/step_security_group.go @@ -10,8 +10,8 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepSecurityGroup struct { diff --git a/builder/amazon/common/step_source_ami_info.go b/builder/amazon/common/step_source_ami_info.go index c7e9f733e..16e49c546 100644 --- a/builder/amazon/common/step_source_ami_info.go +++ b/builder/amazon/common/step_source_ami_info.go @@ -7,8 +7,8 @@ import ( "time" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepSourceAMIInfo extracts critical information from the source AMI diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index 7d6b2e943..6f5be17ce 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -6,8 +6,8 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepStopEBSBackedInstance struct { diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index e22901a74..44e14b695 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -14,9 +14,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // The unique ID for this builder diff --git a/builder/amazon/ebs/step_cleanup_volumes.go b/builder/amazon/ebs/step_cleanup_volumes.go index d056f5457..2b4484f3b 100644 --- a/builder/amazon/ebs/step_cleanup_volumes.go +++ b/builder/amazon/ebs/step_cleanup_volumes.go @@ -6,8 +6,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // stepCleanupVolumes cleans up any orphaned volumes that were not designated to diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index 9cb4bcee2..2729cc64f 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -5,8 +5,8 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateAMI struct { diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index c622a4b73..6dba669d8 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -12,9 +12,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const BuilderId = "mitchellh.amazon.ebssurrogate" diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index f0d145f35..d5c7924db 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -6,8 +6,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepRegisterAMI creates the AMI. diff --git a/builder/amazon/ebssurrogate/step_snapshot_new_root.go b/builder/amazon/ebssurrogate/step_snapshot_new_root.go index e00a75cdb..3b46ca601 100644 --- a/builder/amazon/ebssurrogate/step_snapshot_new_root.go +++ b/builder/amazon/ebssurrogate/step_snapshot_new_root.go @@ -7,8 +7,8 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepSnapshotNewRootVolume creates a snapshot of the created volume. diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index b95af11f8..83fc271fb 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const BuilderId = "mitchellh.amazon.ebsvolume" diff --git a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go index 992459560..d99636b57 100644 --- a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go +++ b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go @@ -5,9 +5,9 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type stepTagEBSVolumes struct { diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 776f4fc67..828733a9f 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -14,9 +14,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // The unique ID for this builder diff --git a/builder/amazon/instance/step_bundle_volume.go b/builder/amazon/instance/step_bundle_volume.go index a8e27d635..dbce14109 100644 --- a/builder/amazon/instance/step_bundle_volume.go +++ b/builder/amazon/instance/step_bundle_volume.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type bundleCmdData struct { diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index d363bdfdd..348e7b86f 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -6,8 +6,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepRegisterAMI struct { diff --git a/builder/amazon/instance/step_upload_bundle.go b/builder/amazon/instance/step_upload_bundle.go index a38a77c93..3a314527e 100644 --- a/builder/amazon/instance/step_upload_bundle.go +++ b/builder/amazon/instance/step_upload_bundle.go @@ -3,9 +3,9 @@ package instance import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type uploadCmdData struct { diff --git a/builder/amazon/instance/step_upload_x509_cert.go b/builder/amazon/instance/step_upload_x509_cert.go index dffcf4d2b..44cd58099 100644 --- a/builder/amazon/instance/step_upload_x509_cert.go +++ b/builder/amazon/instance/step_upload_x509_cert.go @@ -2,10 +2,9 @@ package instance import ( "fmt" - "os" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "os" ) type StepUploadX509Cert struct{} diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index d1f98bbd2..62afe6fa5 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -18,8 +18,8 @@ import ( "github.com/Azure/go-autorest/autorest/adal" packerCommon "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type Builder struct { diff --git a/builder/azure/arm/step.go b/builder/azure/arm/step.go index 707a1a07e..4ac33d1b5 100644 --- a/builder/azure/arm/step.go +++ b/builder/azure/arm/step.go @@ -3,7 +3,7 @@ package arm import ( "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func processInterruptibleResult( diff --git a/builder/azure/arm/step_capture_image.go b/builder/azure/arm/step_capture_image.go index 10d29069e..944f75f3b 100644 --- a/builder/azure/arm/step_capture_image.go +++ b/builder/azure/arm/step_capture_image.go @@ -6,8 +6,8 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCaptureImage struct { diff --git a/builder/azure/arm/step_capture_image_test.go b/builder/azure/arm/step_capture_image_test.go index 4527627a3..2d005d32b 100644 --- a/builder/azure/arm/step_capture_image_test.go +++ b/builder/azure/arm/step_capture_image_test.go @@ -6,7 +6,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCaptureImageShouldFailIfCaptureFails(t *testing.T) { diff --git a/builder/azure/arm/step_create_resource_group.go b/builder/azure/arm/step_create_resource_group.go index 934cb3225..b9b7662df 100644 --- a/builder/azure/arm/step_create_resource_group.go +++ b/builder/azure/arm/step_create_resource_group.go @@ -6,8 +6,8 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/resources/resources" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreateResourceGroup struct { diff --git a/builder/azure/arm/step_create_resource_group_test.go b/builder/azure/arm/step_create_resource_group_test.go index afd47cfef..07ffb78ab 100644 --- a/builder/azure/arm/step_create_resource_group_test.go +++ b/builder/azure/arm/step_create_resource_group_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateResourceGroupShouldFailIfBothGroupNames(t *testing.T) { diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index 878c45cc6..59c644901 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -8,8 +8,8 @@ import ( "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepDeleteOSDisk struct { diff --git a/builder/azure/arm/step_delete_os_disk_test.go b/builder/azure/arm/step_delete_os_disk_test.go index 5a962dd8a..fea47e766 100644 --- a/builder/azure/arm/step_delete_os_disk_test.go +++ b/builder/azure/arm/step_delete_os_disk_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepDeleteOSDiskShouldFailIfGetFails(t *testing.T) { diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index c3db6de0a..300b8f9e0 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -6,8 +6,8 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/azure/arm/step_delete_resource_group_test.go b/builder/azure/arm/step_delete_resource_group_test.go index c9d6e22da..8b5e3590b 100644 --- a/builder/azure/arm/step_delete_resource_group_test.go +++ b/builder/azure/arm/step_delete_resource_group_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepDeleteResourceGroupShouldFailIfDeleteFails(t *testing.T) { diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index 5978a8811..d6c08f7ed 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -9,8 +9,8 @@ import ( "github.com/Azure/go-autorest/autorest" "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepDeployTemplate struct { diff --git a/builder/azure/arm/step_deploy_template_test.go b/builder/azure/arm/step_deploy_template_test.go index 4250e9e0b..16bb52692 100644 --- a/builder/azure/arm/step_deploy_template_test.go +++ b/builder/azure/arm/step_deploy_template_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepDeployTemplateShouldFailIfDeployFails(t *testing.T) { diff --git a/builder/azure/arm/step_get_certificate.go b/builder/azure/arm/step_get_certificate.go index b9126da36..80b623f38 100644 --- a/builder/azure/arm/step_get_certificate.go +++ b/builder/azure/arm/step_get_certificate.go @@ -5,8 +5,8 @@ import ( "time" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepGetCertificate struct { diff --git a/builder/azure/arm/step_get_certificate_test.go b/builder/azure/arm/step_get_certificate_test.go index 553806c5e..6823ca1f1 100644 --- a/builder/azure/arm/step_get_certificate_test.go +++ b/builder/azure/arm/step_get_certificate_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepGetCertificateShouldFailIfGetFails(t *testing.T) { diff --git a/builder/azure/arm/step_get_ip_address.go b/builder/azure/arm/step_get_ip_address.go index 2c8165b0b..b6b96addf 100644 --- a/builder/azure/arm/step_get_ip_address.go +++ b/builder/azure/arm/step_get_ip_address.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type EndpointType int diff --git a/builder/azure/arm/step_get_ip_address_test.go b/builder/azure/arm/step_get_ip_address_test.go index 1403e9a51..508aa2b08 100644 --- a/builder/azure/arm/step_get_ip_address_test.go +++ b/builder/azure/arm/step_get_ip_address_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepGetIPAddressShouldFailIfGetFails(t *testing.T) { diff --git a/builder/azure/arm/step_get_os_disk.go b/builder/azure/arm/step_get_os_disk.go index 511ab5c51..314fc8375 100644 --- a/builder/azure/arm/step_get_os_disk.go +++ b/builder/azure/arm/step_get_os_disk.go @@ -7,8 +7,8 @@ import ( "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepGetOSDisk struct { diff --git a/builder/azure/arm/step_get_os_disk_test.go b/builder/azure/arm/step_get_os_disk_test.go index 2b3a4d5d6..614684db7 100644 --- a/builder/azure/arm/step_get_os_disk_test.go +++ b/builder/azure/arm/step_get_os_disk_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepGetOSDiskShouldFailIfGetFails(t *testing.T) { diff --git a/builder/azure/arm/step_power_off_compute.go b/builder/azure/arm/step_power_off_compute.go index 931050e04..a1401faed 100644 --- a/builder/azure/arm/step_power_off_compute.go +++ b/builder/azure/arm/step_power_off_compute.go @@ -5,8 +5,8 @@ import ( "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepPowerOffCompute struct { diff --git a/builder/azure/arm/step_power_off_compute_test.go b/builder/azure/arm/step_power_off_compute_test.go index 2dcdac7f6..e1d6c6b7d 100644 --- a/builder/azure/arm/step_power_off_compute_test.go +++ b/builder/azure/arm/step_power_off_compute_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepPowerOffComputeShouldFailIfPowerOffFails(t *testing.T) { diff --git a/builder/azure/arm/step_set_certificate.go b/builder/azure/arm/step_set_certificate.go index 5e865b882..34e308263 100644 --- a/builder/azure/arm/step_set_certificate.go +++ b/builder/azure/arm/step_set_certificate.go @@ -2,8 +2,8 @@ package arm import ( "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepSetCertificate struct { diff --git a/builder/azure/arm/step_set_certificate_test.go b/builder/azure/arm/step_set_certificate_test.go index 1ad9b7dbe..8adc6f19e 100644 --- a/builder/azure/arm/step_set_certificate_test.go +++ b/builder/azure/arm/step_set_certificate_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepSetCertificateShouldPassIfGetPasses(t *testing.T) { diff --git a/builder/azure/arm/step_test.go b/builder/azure/arm/step_test.go index cf89021c3..c0115b003 100644 --- a/builder/azure/arm/step_test.go +++ b/builder/azure/arm/step_test.go @@ -6,7 +6,8 @@ import ( "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" + "testing" ) func TestProcessStepResultShouldContinueForNonErrors(t *testing.T) { diff --git a/builder/azure/arm/step_validate_template.go b/builder/azure/arm/step_validate_template.go index d2b98638b..3c7f98a8a 100644 --- a/builder/azure/arm/step_validate_template.go +++ b/builder/azure/arm/step_validate_template.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepValidateTemplate struct { diff --git a/builder/azure/arm/step_validate_template_test.go b/builder/azure/arm/step_validate_template_test.go index a56030787..310c6b49c 100644 --- a/builder/azure/arm/step_validate_template_test.go +++ b/builder/azure/arm/step_validate_template_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepValidateTemplateShouldFailIfValidateFails(t *testing.T) { diff --git a/builder/azure/common/lin/ssh.go b/builder/azure/common/lin/ssh.go index 1600c2f4f..0987a04ea 100644 --- a/builder/azure/common/lin/ssh.go +++ b/builder/azure/common/lin/ssh.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/hashicorp/packer/builder/azure/common/constants" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/azure/common/lin/step_create_cert.go b/builder/azure/common/lin/step_create_cert.go index 6f6a685d3..809bdd964 100644 --- a/builder/azure/common/lin/step_create_cert.go +++ b/builder/azure/common/lin/step_create_cert.go @@ -14,8 +14,8 @@ import ( "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreateCert struct { diff --git a/builder/azure/common/lin/step_generalize_os.go b/builder/azure/common/lin/step_generalize_os.go index ba11a9def..bd55365a2 100644 --- a/builder/azure/common/lin/step_generalize_os.go +++ b/builder/azure/common/lin/step_generalize_os.go @@ -3,10 +3,9 @@ package lin import ( "bytes" "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) type StepGeneralizeOS struct { diff --git a/builder/azure/common/state_bag.go b/builder/azure/common/state_bag.go index a402518a1..57889c03f 100644 --- a/builder/azure/common/state_bag.go +++ b/builder/azure/common/state_bag.go @@ -1,6 +1,6 @@ package common -import "github.com/mitchellh/multistep" +import "github.com/hashicorp/packer/helper/multistep" func IsStateCancelled(stateBag multistep.StateBag) bool { _, ok := stateBag.GetOk(multistep.StateCancelled) diff --git a/builder/cloudstack/builder.go b/builder/cloudstack/builder.go index 27af37d17..6726b29f9 100644 --- a/builder/cloudstack/builder.go +++ b/builder/cloudstack/builder.go @@ -5,8 +5,8 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/ssh.go b/builder/cloudstack/ssh.go index 7a4c2fcba..e1c2ef846 100644 --- a/builder/cloudstack/ssh.go +++ b/builder/cloudstack/ssh.go @@ -6,7 +6,7 @@ import ( "os" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index d9a6a365c..ff80583e9 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -6,8 +6,8 @@ import ( "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 3e37fad14..578adb898 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -8,9 +8,9 @@ import ( "strings" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/step_create_security_group.go b/builder/cloudstack/step_create_security_group.go index 1bf23100b..372df29f7 100644 --- a/builder/cloudstack/step_create_security_group.go +++ b/builder/cloudstack/step_create_security_group.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/step_create_template.go b/builder/cloudstack/step_create_template.go index 18d6c1fb0..54345fb25 100644 --- a/builder/cloudstack/step_create_template.go +++ b/builder/cloudstack/step_create_template.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/step_keypair.go b/builder/cloudstack/step_keypair.go index 675994fc1..8ecd2d1b5 100644 --- a/builder/cloudstack/step_keypair.go +++ b/builder/cloudstack/step_keypair.go @@ -6,8 +6,8 @@ import ( "os" "runtime" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/step_prepare_config.go b/builder/cloudstack/step_prepare_config.go index 4d6353c6a..12c1c44fe 100644 --- a/builder/cloudstack/step_prepare_config.go +++ b/builder/cloudstack/step_prepare_config.go @@ -5,8 +5,8 @@ import ( "io/ioutil" "regexp" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/cloudstack/step_shutdown_instance.go b/builder/cloudstack/step_shutdown_instance.go index b090a5836..fce1fa8bc 100644 --- a/builder/cloudstack/step_shutdown_instance.go +++ b/builder/cloudstack/step_shutdown_instance.go @@ -3,8 +3,8 @@ package cloudstack import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/xanzy/go-cloudstack/cloudstack" ) diff --git a/builder/digitalocean/builder.go b/builder/digitalocean/builder.go index 16d11ba29..d5e674d63 100644 --- a/builder/digitalocean/builder.go +++ b/builder/digitalocean/builder.go @@ -12,8 +12,8 @@ import ( "github.com/digitalocean/godo" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/oauth2" ) diff --git a/builder/digitalocean/ssh.go b/builder/digitalocean/ssh.go index ebccb938a..2b5c4ef8d 100644 --- a/builder/digitalocean/ssh.go +++ b/builder/digitalocean/ssh.go @@ -5,7 +5,7 @@ import ( "golang.org/x/crypto/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func commHost(state multistep.StateBag) (string, error) { diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index ed2c7390d..d64224a0a 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -7,8 +7,8 @@ import ( "io/ioutil" "github.com/digitalocean/godo" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateDroplet struct { diff --git a/builder/digitalocean/step_create_ssh_key.go b/builder/digitalocean/step_create_ssh_key.go index d255ffde0..cd8f68cc0 100644 --- a/builder/digitalocean/step_create_ssh_key.go +++ b/builder/digitalocean/step_create_ssh_key.go @@ -13,8 +13,8 @@ import ( "github.com/digitalocean/godo" "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/digitalocean/step_droplet_info.go b/builder/digitalocean/step_droplet_info.go index 4d24bb899..8cb0f6112 100644 --- a/builder/digitalocean/step_droplet_info.go +++ b/builder/digitalocean/step_droplet_info.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/digitalocean/godo" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepDropletInfo struct{} diff --git a/builder/digitalocean/step_power_off.go b/builder/digitalocean/step_power_off.go index aeded228a..a5ed96199 100644 --- a/builder/digitalocean/step_power_off.go +++ b/builder/digitalocean/step_power_off.go @@ -6,8 +6,8 @@ import ( "log" "github.com/digitalocean/godo" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepPowerOff struct{} diff --git a/builder/digitalocean/step_shutdown.go b/builder/digitalocean/step_shutdown.go index dfa47dc4a..d45f03628 100644 --- a/builder/digitalocean/step_shutdown.go +++ b/builder/digitalocean/step_shutdown.go @@ -7,8 +7,8 @@ import ( "time" "github.com/digitalocean/godo" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepShutdown struct{} diff --git a/builder/digitalocean/step_snapshot.go b/builder/digitalocean/step_snapshot.go index eb91fdead..46eb75a0e 100644 --- a/builder/digitalocean/step_snapshot.go +++ b/builder/digitalocean/step_snapshot.go @@ -8,8 +8,8 @@ import ( "time" "github.com/digitalocean/godo" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepSnapshot struct{} diff --git a/builder/docker/builder.go b/builder/docker/builder.go index c59456e80..ba58f61bb 100644 --- a/builder/docker/builder.go +++ b/builder/docker/builder.go @@ -5,8 +5,8 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/docker/comm.go b/builder/docker/comm.go index 8af3d57ca..bda53e0a1 100644 --- a/builder/docker/comm.go +++ b/builder/docker/comm.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/packer/communicator/ssh" "github.com/hashicorp/packer/helper/communicator" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/docker/step_commit.go b/builder/docker/step_commit.go index 26455670c..167f68621 100644 --- a/builder/docker/step_commit.go +++ b/builder/docker/step_commit.go @@ -2,9 +2,8 @@ package docker import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCommit commits the container to a image. diff --git a/builder/docker/step_commit_test.go b/builder/docker/step_commit_test.go index dce1b1208..b828aa3e2 100644 --- a/builder/docker/step_commit_test.go +++ b/builder/docker/step_commit_test.go @@ -2,6 +2,7 @@ package docker import ( "errors" + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/docker/step_connect_docker.go b/builder/docker/step_connect_docker.go index ecbe55c35..ed64091e7 100644 --- a/builder/docker/step_connect_docker.go +++ b/builder/docker/step_connect_docker.go @@ -2,6 +2,7 @@ package docker import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "os/exec" "strings" diff --git a/builder/docker/step_export.go b/builder/docker/step_export.go index 428055a48..7af86de0e 100644 --- a/builder/docker/step_export.go +++ b/builder/docker/step_export.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepExport exports the container to a flat tar file. diff --git a/builder/docker/step_export_test.go b/builder/docker/step_export_test.go index f2d1a069c..622d0ee5a 100644 --- a/builder/docker/step_export_test.go +++ b/builder/docker/step_export_test.go @@ -3,6 +3,7 @@ package docker import ( "bytes" "errors" + "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" diff --git a/builder/docker/step_pull.go b/builder/docker/step_pull.go index 6b1ac8935..8704de3d1 100644 --- a/builder/docker/step_pull.go +++ b/builder/docker/step_pull.go @@ -4,8 +4,8 @@ import ( "fmt" "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepPull struct{} diff --git a/builder/docker/step_pull_test.go b/builder/docker/step_pull_test.go index aaeff2b2a..6bd3d5e84 100644 --- a/builder/docker/step_pull_test.go +++ b/builder/docker/step_pull_test.go @@ -2,6 +2,7 @@ package docker import ( "errors" + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/docker/step_run.go b/builder/docker/step_run.go index 101788682..2ac471562 100644 --- a/builder/docker/step_run.go +++ b/builder/docker/step_run.go @@ -2,9 +2,8 @@ package docker import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepRun struct { diff --git a/builder/docker/step_run_test.go b/builder/docker/step_run_test.go index 8c5b08ea3..e301a11c5 100644 --- a/builder/docker/step_run_test.go +++ b/builder/docker/step_run_test.go @@ -2,6 +2,7 @@ package docker import ( "errors" + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/docker/step_temp_dir.go b/builder/docker/step_temp_dir.go index c7312ce49..e9af747e7 100644 --- a/builder/docker/step_temp_dir.go +++ b/builder/docker/step_temp_dir.go @@ -2,6 +2,8 @@ package docker import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "io/ioutil" "os" diff --git a/builder/docker/step_temp_dir_test.go b/builder/docker/step_temp_dir_test.go index cc12932f3..68c8d0455 100644 --- a/builder/docker/step_temp_dir_test.go +++ b/builder/docker/step_temp_dir_test.go @@ -5,8 +5,8 @@ import ( "path/filepath" "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepTempDir_impl(t *testing.T) { diff --git a/builder/docker/step_test.go b/builder/docker/step_test.go index 9eec9a5d8..fa0702612 100644 --- a/builder/docker/step_test.go +++ b/builder/docker/step_test.go @@ -2,10 +2,9 @@ package docker import ( "bytes" - "testing" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/file/builder.go b/builder/file/builder.go index 1ac87331c..f8b52e609 100644 --- a/builder/file/builder.go +++ b/builder/file/builder.go @@ -11,8 +11,8 @@ import ( "io/ioutil" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const BuilderId = "packer.file" diff --git a/builder/googlecompute/builder.go b/builder/googlecompute/builder.go index 589108348..c60117075 100644 --- a/builder/googlecompute/builder.go +++ b/builder/googlecompute/builder.go @@ -8,8 +8,8 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // The unique ID for this builder. diff --git a/builder/googlecompute/ssh.go b/builder/googlecompute/ssh.go index 5c224f0c6..bf704b13e 100644 --- a/builder/googlecompute/ssh.go +++ b/builder/googlecompute/ssh.go @@ -3,7 +3,7 @@ package googlecompute import ( "fmt" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/googlecompute/step_check_existing_image.go b/builder/googlecompute/step_check_existing_image.go index d5f2f5e73..b2da36973 100644 --- a/builder/googlecompute/step_check_existing_image.go +++ b/builder/googlecompute/step_check_existing_image.go @@ -3,8 +3,8 @@ package googlecompute import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCheckExistingImage represents a Packer build step that checks if the diff --git a/builder/googlecompute/step_check_existing_image_test.go b/builder/googlecompute/step_check_existing_image_test.go index 21f4ee6c2..36f9e110a 100644 --- a/builder/googlecompute/step_check_existing_image_test.go +++ b/builder/googlecompute/step_check_existing_image_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/googlecompute/step_create_image.go b/builder/googlecompute/step_create_image.go index bcb840e78..7948c0188 100644 --- a/builder/googlecompute/step_create_image.go +++ b/builder/googlecompute/step_create_image.go @@ -5,8 +5,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateImage represents a Packer build step that creates GCE machine diff --git a/builder/googlecompute/step_create_image_test.go b/builder/googlecompute/step_create_image_test.go index 639b25255..e920e03f2 100644 --- a/builder/googlecompute/step_create_image_test.go +++ b/builder/googlecompute/step_create_image_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "github.com/stretchr/testify/assert" ) diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index a4509354e..054d169ae 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -6,8 +6,8 @@ import ( "io/ioutil" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateInstance represents a Packer build step that creates GCE instances. diff --git a/builder/googlecompute/step_create_instance_test.go b/builder/googlecompute/step_create_instance_test.go index a9a91d692..5a497a78e 100644 --- a/builder/googlecompute/step_create_instance_test.go +++ b/builder/googlecompute/step_create_instance_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "github.com/stretchr/testify/assert" ) diff --git a/builder/googlecompute/step_create_ssh_key.go b/builder/googlecompute/step_create_ssh_key.go index fd6d7f55a..9c0ad5513 100644 --- a/builder/googlecompute/step_create_ssh_key.go +++ b/builder/googlecompute/step_create_ssh_key.go @@ -9,8 +9,8 @@ import ( "io/ioutil" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/googlecompute/step_create_ssh_key_test.go b/builder/googlecompute/step_create_ssh_key_test.go index 94504ac7f..31481e8b6 100644 --- a/builder/googlecompute/step_create_ssh_key_test.go +++ b/builder/googlecompute/step_create_ssh_key_test.go @@ -1,7 +1,7 @@ package googlecompute import ( - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" diff --git a/builder/googlecompute/step_create_windows_password.go b/builder/googlecompute/step_create_windows_password.go index 312e54512..3adeac11d 100644 --- a/builder/googlecompute/step_create_windows_password.go +++ b/builder/googlecompute/step_create_windows_password.go @@ -12,8 +12,8 @@ import ( "os" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateWindowsPassword represents a Packer build step that sets the windows password on a Windows GCE instance. diff --git a/builder/googlecompute/step_create_windows_password_test.go b/builder/googlecompute/step_create_windows_password_test.go index 58fc8ee83..2b0050b1d 100644 --- a/builder/googlecompute/step_create_windows_password_test.go +++ b/builder/googlecompute/step_create_windows_password_test.go @@ -5,7 +5,7 @@ import ( "io/ioutil" "os" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "testing" ) diff --git a/builder/googlecompute/step_instance_info.go b/builder/googlecompute/step_instance_info.go index d5ece22e7..8706489c9 100644 --- a/builder/googlecompute/step_instance_info.go +++ b/builder/googlecompute/step_instance_info.go @@ -5,8 +5,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // stepInstanceInfo represents a Packer build step that gathers GCE instance info. diff --git a/builder/googlecompute/step_instance_info_test.go b/builder/googlecompute/step_instance_info_test.go index b8547f2ff..8ced83c5d 100644 --- a/builder/googlecompute/step_instance_info_test.go +++ b/builder/googlecompute/step_instance_info_test.go @@ -2,6 +2,7 @@ package googlecompute import ( "errors" + "github.com/hashicorp/packer/helper/multistep" "testing" "time" diff --git a/builder/googlecompute/step_teardown_instance.go b/builder/googlecompute/step_teardown_instance.go index 58585d78f..317507d82 100644 --- a/builder/googlecompute/step_teardown_instance.go +++ b/builder/googlecompute/step_teardown_instance.go @@ -5,8 +5,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepTeardownInstance represents a Packer build step that tears down GCE diff --git a/builder/googlecompute/step_teardown_instance_test.go b/builder/googlecompute/step_teardown_instance_test.go index 28c6480de..295230e01 100644 --- a/builder/googlecompute/step_teardown_instance_test.go +++ b/builder/googlecompute/step_teardown_instance_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/googlecompute/step_test.go b/builder/googlecompute/step_test.go index 3e9b843f4..a50bde49f 100644 --- a/builder/googlecompute/step_test.go +++ b/builder/googlecompute/step_test.go @@ -4,8 +4,8 @@ import ( "bytes" "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/googlecompute/step_wait_startup_script.go b/builder/googlecompute/step_wait_startup_script.go index f2e1e523f..94b1b07ce 100644 --- a/builder/googlecompute/step_wait_startup_script.go +++ b/builder/googlecompute/step_wait_startup_script.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepWaitStartupScript int diff --git a/builder/googlecompute/step_wait_startup_script_test.go b/builder/googlecompute/step_wait_startup_script_test.go index d157c761f..a48176a61 100644 --- a/builder/googlecompute/step_wait_startup_script_test.go +++ b/builder/googlecompute/step_wait_startup_script_test.go @@ -1,9 +1,7 @@ package googlecompute import ( - "testing" - - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "github.com/stretchr/testify/assert" ) diff --git a/builder/googlecompute/winrm.go b/builder/googlecompute/winrm.go index ec617cba5..767787401 100644 --- a/builder/googlecompute/winrm.go +++ b/builder/googlecompute/winrm.go @@ -2,7 +2,7 @@ package googlecompute import ( "github.com/hashicorp/packer/helper/communicator" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // winrmConfig returns the WinRM configuration. diff --git a/builder/hyperv/common/ssh.go b/builder/hyperv/common/ssh.go index 182d154ff..f8a059bb0 100644 --- a/builder/hyperv/common/ssh.go +++ b/builder/hyperv/common/ssh.go @@ -3,7 +3,7 @@ package common import ( commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index 4a5b55566..733b6df1a 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -6,8 +6,8 @@ import ( "path/filepath" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step clones an existing virtual machine. diff --git a/builder/hyperv/common/step_configure_ip.go b/builder/hyperv/common/step_configure_ip.go index deac917f8..8670f5a41 100644 --- a/builder/hyperv/common/step_configure_ip.go +++ b/builder/hyperv/common/step_configure_ip.go @@ -6,8 +6,8 @@ import ( "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepConfigureIp struct { diff --git a/builder/hyperv/common/step_configure_vlan.go b/builder/hyperv/common/step_configure_vlan.go index 5d713ac99..acfe26422 100644 --- a/builder/hyperv/common/step_configure_vlan.go +++ b/builder/hyperv/common/step_configure_vlan.go @@ -3,8 +3,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepConfigureVlan struct { diff --git a/builder/hyperv/common/step_create_external_switch.go b/builder/hyperv/common/step_create_external_switch.go index 8443202b3..1bbfd40b7 100644 --- a/builder/hyperv/common/step_create_external_switch.go +++ b/builder/hyperv/common/step_create_external_switch.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates switch for VM. diff --git a/builder/hyperv/common/step_create_switch.go b/builder/hyperv/common/step_create_switch.go index 1904c9dbd..7d6db4c3d 100644 --- a/builder/hyperv/common/step_create_switch.go +++ b/builder/hyperv/common/step_create_switch.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/hyperv/common/step_create_tempdir.go b/builder/hyperv/common/step_create_tempdir.go index c2ac9f719..425235258 100644 --- a/builder/hyperv/common/step_create_tempdir.go +++ b/builder/hyperv/common/step_create_tempdir.go @@ -5,8 +5,8 @@ import ( "io/ioutil" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreateTempDir struct { diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 02171d9c6..6f850a044 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -6,8 +6,8 @@ import ( "path/filepath" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates the actual virtual machine. diff --git a/builder/hyperv/common/step_disable_vlan.go b/builder/hyperv/common/step_disable_vlan.go index fb1454af3..6c6a034da 100644 --- a/builder/hyperv/common/step_disable_vlan.go +++ b/builder/hyperv/common/step_disable_vlan.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepDisableVlan struct { diff --git a/builder/hyperv/common/step_enable_integration_service.go b/builder/hyperv/common/step_enable_integration_service.go index 852e3d804..98e8eedb2 100644 --- a/builder/hyperv/common/step_enable_integration_service.go +++ b/builder/hyperv/common/step_enable_integration_service.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepEnableIntegrationService struct { diff --git a/builder/hyperv/common/step_export_vm.go b/builder/hyperv/common/step_export_vm.go index 8c32052a3..3c33475c1 100644 --- a/builder/hyperv/common/step_export_vm.go +++ b/builder/hyperv/common/step_export_vm.go @@ -5,8 +5,8 @@ import ( "io/ioutil" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index 2f800a79c..97d3ff0e0 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "path/filepath" "strings" diff --git a/builder/hyperv/common/step_mount_floppydrive.go b/builder/hyperv/common/step_mount_floppydrive.go index d49b155b5..749cf5ae1 100644 --- a/builder/hyperv/common/step_mount_floppydrive.go +++ b/builder/hyperv/common/step_mount_floppydrive.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "io" "io/ioutil" "log" diff --git a/builder/hyperv/common/step_mount_guest_additions.go b/builder/hyperv/common/step_mount_guest_additions.go index fafa92971..1cf549735 100644 --- a/builder/hyperv/common/step_mount_guest_additions.go +++ b/builder/hyperv/common/step_mount_guest_additions.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) type StepMountGuestAdditions struct { diff --git a/builder/hyperv/common/step_mount_secondary_dvd_images.go b/builder/hyperv/common/step_mount_secondary_dvd_images.go index 2b7934a5e..c5be1a03b 100644 --- a/builder/hyperv/common/step_mount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_mount_secondary_dvd_images.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) type StepMountSecondaryDvdImages struct { diff --git a/builder/hyperv/common/step_output_dir.go b/builder/hyperv/common/step_output_dir.go index 0054d1994..acb905e9a 100644 --- a/builder/hyperv/common/step_output_dir.go +++ b/builder/hyperv/common/step_output_dir.go @@ -7,8 +7,8 @@ import ( "path/filepath" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepOutputDir sets up the output directory by creating it if it does diff --git a/builder/hyperv/common/step_polling_installation.go b/builder/hyperv/common/step_polling_installation.go index 8586940b1..114684f59 100644 --- a/builder/hyperv/common/step_polling_installation.go +++ b/builder/hyperv/common/step_polling_installation.go @@ -8,8 +8,8 @@ import ( "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const port string = "13000" diff --git a/builder/hyperv/common/step_reboot_vm.go b/builder/hyperv/common/step_reboot_vm.go index 0ba777e6f..3708f97cb 100644 --- a/builder/hyperv/common/step_reboot_vm.go +++ b/builder/hyperv/common/step_reboot_vm.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "time" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) type StepRebootVm struct { diff --git a/builder/hyperv/common/step_run.go b/builder/hyperv/common/step_run.go index 050c76f50..168f29520 100644 --- a/builder/hyperv/common/step_run.go +++ b/builder/hyperv/common/step_run.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "time" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) type StepRun struct { diff --git a/builder/hyperv/common/step_shutdown.go b/builder/hyperv/common/step_shutdown.go index 9b341b395..42e408799 100644 --- a/builder/hyperv/common/step_shutdown.go +++ b/builder/hyperv/common/step_shutdown.go @@ -7,8 +7,8 @@ import ( "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step shuts down the machine. It first attempts to do so gracefully, diff --git a/builder/hyperv/common/step_sleep.go b/builder/hyperv/common/step_sleep.go index ea262d010..19b4c2c1f 100644 --- a/builder/hyperv/common/step_sleep.go +++ b/builder/hyperv/common/step_sleep.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "time" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) type StepSleep struct { diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index dfeca6196..d38c53166 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -8,9 +8,9 @@ import ( "unicode/utf8" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type bootCommandTemplateData struct { diff --git a/builder/hyperv/common/step_unmount_dvddrive.go b/builder/hyperv/common/step_unmount_dvddrive.go index d8ba2033b..810e055ce 100644 --- a/builder/hyperv/common/step_unmount_dvddrive.go +++ b/builder/hyperv/common/step_unmount_dvddrive.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepUnmountDvdDrive struct { diff --git a/builder/hyperv/common/step_unmount_floppydrive.go b/builder/hyperv/common/step_unmount_floppydrive.go index e67279a5f..be71861c2 100644 --- a/builder/hyperv/common/step_unmount_floppydrive.go +++ b/builder/hyperv/common/step_unmount_floppydrive.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepUnmountFloppyDrive struct { diff --git a/builder/hyperv/common/step_unmount_guest_additions.go b/builder/hyperv/common/step_unmount_guest_additions.go index da35a06e2..44b9b5acb 100644 --- a/builder/hyperv/common/step_unmount_guest_additions.go +++ b/builder/hyperv/common/step_unmount_guest_additions.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepUnmountGuestAdditions struct { diff --git a/builder/hyperv/common/step_unmount_secondary_dvd_images.go b/builder/hyperv/common/step_unmount_secondary_dvd_images.go index ec42923f6..9e3ccbfc9 100644 --- a/builder/hyperv/common/step_unmount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_unmount_secondary_dvd_images.go @@ -2,9 +2,8 @@ package common import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepUnmountSecondaryDvdImages struct { diff --git a/builder/hyperv/common/step_wait_for_install_to_complete.go b/builder/hyperv/common/step_wait_for_install_to_complete.go index c002f57ae..a147d6963 100644 --- a/builder/hyperv/common/step_wait_for_install_to_complete.go +++ b/builder/hyperv/common/step_wait_for_install_to_complete.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "time" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) const ( diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 849cbcacf..c905d21e6 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -14,9 +14,9 @@ import ( "github.com/hashicorp/packer/common/powershell/hyperv" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 7315b4950..74c8de44e 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -9,8 +9,9 @@ import ( "os" hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "os" ) func testConfig() map[string]interface{} { diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 6a976b3df..a0238ede1 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -13,9 +13,9 @@ import ( "github.com/hashicorp/packer/common/powershell/hyperv" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index aef12c055..7792a365c 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -9,8 +9,10 @@ import ( "os" hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "io/ioutil" + "os" ) func testConfig() map[string]interface{} { diff --git a/builder/lxc/builder.go b/builder/lxc/builder.go index b45bd3511..82683b890 100644 --- a/builder/lxc/builder.go +++ b/builder/lxc/builder.go @@ -6,9 +6,12 @@ import ( "path/filepath" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" + "log" + "os" + "path/filepath" ) // The unique ID for this builder diff --git a/builder/lxc/step_export.go b/builder/lxc/step_export.go index 7a0e1ec95..632891a36 100644 --- a/builder/lxc/step_export.go +++ b/builder/lxc/step_export.go @@ -3,6 +3,8 @@ package lxc import ( "bytes" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "io" "log" "os" diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index 131fc958b..4d46a0f5c 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -3,6 +3,8 @@ package lxc import ( "bytes" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "os/exec" "path/filepath" diff --git a/builder/lxc/step_prepare_output_dir.go b/builder/lxc/step_prepare_output_dir.go index 835bbf5a3..ed79ac75e 100644 --- a/builder/lxc/step_prepare_output_dir.go +++ b/builder/lxc/step_prepare_output_dir.go @@ -1,6 +1,8 @@ package lxc import ( + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "os" "time" diff --git a/builder/lxc/step_provision.go b/builder/lxc/step_provision.go index 9c54b9603..c6d7f305e 100644 --- a/builder/lxc/step_provision.go +++ b/builder/lxc/step_provision.go @@ -1,10 +1,9 @@ package lxc import ( - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // StepProvision provisions the instance within a chroot. diff --git a/builder/lxc/step_wait_init.go b/builder/lxc/step_wait_init.go index 69ce8a5af..1c850a90b 100644 --- a/builder/lxc/step_wait_init.go +++ b/builder/lxc/step_wait_init.go @@ -3,6 +3,8 @@ package lxc import ( "errors" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "strings" "time" diff --git a/builder/lxd/builder.go b/builder/lxd/builder.go index 48a879543..d1b040853 100644 --- a/builder/lxd/builder.go +++ b/builder/lxd/builder.go @@ -4,9 +4,10 @@ import ( "log" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" + "log" ) // The unique ID for this builder diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index d8ad17734..491a880a9 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -2,10 +2,9 @@ package lxd import ( "fmt" - "time" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) type stepLxdLaunch struct{} diff --git a/builder/lxd/step_provision.go b/builder/lxd/step_provision.go index 5fbc9d034..6bd7d617c 100644 --- a/builder/lxd/step_provision.go +++ b/builder/lxd/step_provision.go @@ -1,10 +1,9 @@ package lxd import ( - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // StepProvision provisions the container diff --git a/builder/lxd/step_publish.go b/builder/lxd/step_publish.go index 19a8c22af..280dfe1cf 100644 --- a/builder/lxd/step_publish.go +++ b/builder/lxd/step_publish.go @@ -2,10 +2,9 @@ package lxd import ( "fmt" - "regexp" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "regexp" ) type stepPublish struct{} diff --git a/builder/null/builder.go b/builder/null/builder.go index 3e587ebd0..f4d4764d6 100644 --- a/builder/null/builder.go +++ b/builder/null/builder.go @@ -5,8 +5,8 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const BuilderId = "fnoeding.null" diff --git a/builder/null/ssh.go b/builder/null/ssh.go index b8dea896e..8e18bb6ac 100644 --- a/builder/null/ssh.go +++ b/builder/null/ssh.go @@ -7,7 +7,7 @@ import ( "os" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/oneandone/builder.go b/builder/oneandone/builder.go index 673e35264..7b7be84aa 100644 --- a/builder/oneandone/builder.go +++ b/builder/oneandone/builder.go @@ -7,8 +7,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) const BuilderId = "packer.oneandone" diff --git a/builder/oneandone/ssh.go b/builder/oneandone/ssh.go index 69fb435e1..9fdb128a9 100644 --- a/builder/oneandone/ssh.go +++ b/builder/oneandone/ssh.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/oneandone/step_create_server.go b/builder/oneandone/step_create_server.go index 7f38311a6..505a80242 100644 --- a/builder/oneandone/step_create_server.go +++ b/builder/oneandone/step_create_server.go @@ -6,8 +6,10 @@ import ( "time" "github.com/1and1/oneandone-cloudserver-sdk-go" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "strings" + "time" ) type stepCreateServer struct{} diff --git a/builder/oneandone/step_create_sshkey.go b/builder/oneandone/step_create_sshkey.go index e4174ef5d..e365a1362 100644 --- a/builder/oneandone/step_create_sshkey.go +++ b/builder/oneandone/step_create_sshkey.go @@ -4,10 +4,8 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "io/ioutil" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/oneandone/step_take_snapshot.go b/builder/oneandone/step_take_snapshot.go index b19790c7d..2e6192d13 100644 --- a/builder/oneandone/step_take_snapshot.go +++ b/builder/oneandone/step_take_snapshot.go @@ -2,8 +2,8 @@ package oneandone import ( "github.com/1and1/oneandone-cloudserver-sdk-go" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepTakeSnapshot struct{} diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 46d0e4e67..f3c6fd13b 100644 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -10,9 +10,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // The unique ID for this builder diff --git a/builder/openstack/server.go b/builder/openstack/server.go index 2c2dd8f2a..f509452d6 100644 --- a/builder/openstack/server.go +++ b/builder/openstack/server.go @@ -8,7 +8,7 @@ import ( "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // StateRefreshFunc is a function type used for StateChangeConf that is diff --git a/builder/openstack/ssh.go b/builder/openstack/ssh.go index 9957c6163..1dd6672c4 100644 --- a/builder/openstack/ssh.go +++ b/builder/openstack/ssh.go @@ -12,7 +12,7 @@ import ( "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/openstack/step_add_image_members.go b/builder/openstack/step_add_image_members.go index 642ed3d46..3160a0e46 100644 --- a/builder/openstack/step_add_image_members.go +++ b/builder/openstack/step_add_image_members.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/gophercloud/gophercloud/openstack/imageservice/v2/members" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepAddImageMembers struct{} diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index 521e42634..2de35b8ee 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -6,8 +6,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "github.com/gophercloud/gophercloud/pagination" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepAllocateIp struct { diff --git a/builder/openstack/step_create_image.go b/builder/openstack/step_create_image.go index 126bd4971..35fbd371a 100644 --- a/builder/openstack/step_create_image.go +++ b/builder/openstack/step_create_image.go @@ -8,8 +8,8 @@ import ( "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack/compute/v2/images" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateImage struct{} diff --git a/builder/openstack/step_get_password.go b/builder/openstack/step_get_password.go index 10800d5be..9a5d8c95d 100644 --- a/builder/openstack/step_get_password.go +++ b/builder/openstack/step_get_password.go @@ -8,8 +8,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/openstack/step_key_pair.go b/builder/openstack/step_key_pair.go index 2d1500a5c..b6b072216 100644 --- a/builder/openstack/step_key_pair.go +++ b/builder/openstack/step_key_pair.go @@ -9,8 +9,8 @@ import ( "runtime" "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/openstack/step_load_extensions.go b/builder/openstack/step_load_extensions.go index 84ab0c8d2..a7feec875 100644 --- a/builder/openstack/step_load_extensions.go +++ b/builder/openstack/step_load_extensions.go @@ -6,8 +6,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions" "github.com/gophercloud/gophercloud/pagination" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepLoadExtensions gets the FlavorRef from a Flavor. It first assumes diff --git a/builder/openstack/step_load_flavor.go b/builder/openstack/step_load_flavor.go index 816e0d8f4..ddc456681 100644 --- a/builder/openstack/step_load_flavor.go +++ b/builder/openstack/step_load_flavor.go @@ -5,8 +5,8 @@ import ( "log" "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepLoadFlavor gets the FlavorRef from a Flavor. It first assumes diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 427f507dc..8b29357bb 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -7,8 +7,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepRunSourceServer struct { diff --git a/builder/openstack/step_stop_server.go b/builder/openstack/step_stop_server.go index e0f240fbd..48d1eb4d7 100644 --- a/builder/openstack/step_stop_server.go +++ b/builder/openstack/step_stop_server.go @@ -5,8 +5,8 @@ import ( "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepStopServer struct{} diff --git a/builder/openstack/step_update_image_visibility.go b/builder/openstack/step_update_image_visibility.go index fb83134bd..d003f2894 100644 --- a/builder/openstack/step_update_image_visibility.go +++ b/builder/openstack/step_update_image_visibility.go @@ -4,8 +4,8 @@ import ( "fmt" imageservice "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepUpdateImageVisibility struct{} diff --git a/builder/openstack/step_wait_for_rackconnect.go b/builder/openstack/step_wait_for_rackconnect.go index d791e9db0..1b17a9d27 100644 --- a/builder/openstack/step_wait_for_rackconnect.go +++ b/builder/openstack/step_wait_for_rackconnect.go @@ -5,8 +5,8 @@ import ( "time" "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepWaitForRackConnect struct { diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index 5eedaa0b1..6a2f6efef 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -9,8 +9,8 @@ import ( client "github.com/hashicorp/packer/builder/oracle/oci/client" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // BuilderId uniquely identifies the builder diff --git a/builder/oracle/oci/ssh.go b/builder/oracle/oci/ssh.go index a9d62f4a4..5424b94b4 100644 --- a/builder/oracle/oci/ssh.go +++ b/builder/oracle/oci/ssh.go @@ -4,7 +4,7 @@ import ( "fmt" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/oracle/oci/step_create_instance.go b/builder/oracle/oci/step_create_instance.go index 8650f7314..ad18a7e81 100644 --- a/builder/oracle/oci/step_create_instance.go +++ b/builder/oracle/oci/step_create_instance.go @@ -3,8 +3,8 @@ package oci import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateInstance struct{} diff --git a/builder/oracle/oci/step_create_instance_test.go b/builder/oracle/oci/step_create_instance_test.go index 558a17cb6..3594281b6 100644 --- a/builder/oracle/oci/step_create_instance_test.go +++ b/builder/oracle/oci/step_create_instance_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateInstance(t *testing.T) { diff --git a/builder/oracle/oci/step_image.go b/builder/oracle/oci/step_image.go index 07c9ddb4b..b7ce54057 100644 --- a/builder/oracle/oci/step_image.go +++ b/builder/oracle/oci/step_image.go @@ -3,8 +3,8 @@ package oci import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepImage struct{} diff --git a/builder/oracle/oci/step_image_test.go b/builder/oracle/oci/step_image_test.go index 72399278c..e3e0e353c 100644 --- a/builder/oracle/oci/step_image_test.go +++ b/builder/oracle/oci/step_image_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepImage(t *testing.T) { diff --git a/builder/oracle/oci/step_instance_info.go b/builder/oracle/oci/step_instance_info.go index 310d8699c..df70434b0 100644 --- a/builder/oracle/oci/step_instance_info.go +++ b/builder/oracle/oci/step_instance_info.go @@ -3,8 +3,8 @@ package oci import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepInstanceInfo struct{} diff --git a/builder/oracle/oci/step_instance_info_test.go b/builder/oracle/oci/step_instance_info_test.go index fdae8a0ef..6280e3e6f 100644 --- a/builder/oracle/oci/step_instance_info_test.go +++ b/builder/oracle/oci/step_instance_info_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestInstanceInfo(t *testing.T) { diff --git a/builder/oracle/oci/step_ssh_key_pair.go b/builder/oracle/oci/step_ssh_key_pair.go index cc9d0358f..b7a89ae63 100644 --- a/builder/oracle/oci/step_ssh_key_pair.go +++ b/builder/oracle/oci/step_ssh_key_pair.go @@ -10,8 +10,8 @@ import ( "os" "runtime" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/oracle/oci/step_test.go b/builder/oracle/oci/step_test.go index d4436e304..f46ffa1e4 100644 --- a/builder/oracle/oci/step_test.go +++ b/builder/oracle/oci/step_test.go @@ -4,8 +4,8 @@ import ( "bytes" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" client "github.com/hashicorp/packer/builder/oracle/oci/client" ) diff --git a/builder/parallels/common/ssh.go b/builder/parallels/common/ssh.go index 8c2c8706f..6673698b5 100644 --- a/builder/parallels/common/ssh.go +++ b/builder/parallels/common/ssh.go @@ -3,7 +3,7 @@ package common import ( commonssh "github.com/hashicorp/packer/common/ssh" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/parallels/common/step_attach_floppy.go b/builder/parallels/common/step_attach_floppy.go index 8b970fef2..ec8a0663d 100644 --- a/builder/parallels/common/step_attach_floppy.go +++ b/builder/parallels/common/step_attach_floppy.go @@ -4,8 +4,8 @@ import ( "fmt" "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepAttachFloppy is a step that attaches a floppy to the virtual machine. diff --git a/builder/parallels/common/step_attach_floppy_test.go b/builder/parallels/common/step_attach_floppy_test.go index f854fd23c..7df1c4569 100644 --- a/builder/parallels/common/step_attach_floppy_test.go +++ b/builder/parallels/common/step_attach_floppy_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepAttachFloppy_impl(t *testing.T) { diff --git a/builder/parallels/common/step_attach_parallels_tools.go b/builder/parallels/common/step_attach_parallels_tools.go index 87d602df7..3d7534960 100644 --- a/builder/parallels/common/step_attach_parallels_tools.go +++ b/builder/parallels/common/step_attach_parallels_tools.go @@ -4,8 +4,8 @@ import ( "fmt" "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepAttachParallelsTools is a step that attaches Parallels Tools ISO image diff --git a/builder/parallels/common/step_compact_disk.go b/builder/parallels/common/step_compact_disk.go index 2e88e7bd5..a79cf9f7b 100644 --- a/builder/parallels/common/step_compact_disk.go +++ b/builder/parallels/common/step_compact_disk.go @@ -3,8 +3,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCompactDisk is a step that removes all empty blocks from expanding diff --git a/builder/parallels/common/step_compact_disk_test.go b/builder/parallels/common/step_compact_disk_test.go index ace932a2d..4b41c5f41 100644 --- a/builder/parallels/common/step_compact_disk_test.go +++ b/builder/parallels/common/step_compact_disk_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCompactDisk_impl(t *testing.T) { diff --git a/builder/parallels/common/step_output_dir.go b/builder/parallels/common/step_output_dir.go index 3accd2cbb..a3cb8db5a 100644 --- a/builder/parallels/common/step_output_dir.go +++ b/builder/parallels/common/step_output_dir.go @@ -7,8 +7,8 @@ import ( "path/filepath" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepOutputDir sets up the output directory by creating it if it does diff --git a/builder/parallels/common/step_output_dir_test.go b/builder/parallels/common/step_output_dir_test.go index 04f5a7339..3f6d83436 100644 --- a/builder/parallels/common/step_output_dir_test.go +++ b/builder/parallels/common/step_output_dir_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testStepOutputDir(t *testing.T) *StepOutputDir { diff --git a/builder/parallels/common/step_prepare_parallels_tools.go b/builder/parallels/common/step_prepare_parallels_tools.go index 99e8722dc..174274b3d 100644 --- a/builder/parallels/common/step_prepare_parallels_tools.go +++ b/builder/parallels/common/step_prepare_parallels_tools.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // StepPrepareParallelsTools is a step that prepares parameters related diff --git a/builder/parallels/common/step_prepare_parallels_tools_test.go b/builder/parallels/common/step_prepare_parallels_tools_test.go index 0647149e5..f0542c41d 100644 --- a/builder/parallels/common/step_prepare_parallels_tools_test.go +++ b/builder/parallels/common/step_prepare_parallels_tools_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepPrepareParallelsTools_impl(t *testing.T) { diff --git a/builder/parallels/common/step_prlctl.go b/builder/parallels/common/step_prlctl.go index a38d8b7fe..b93b396f0 100644 --- a/builder/parallels/common/step_prlctl.go +++ b/builder/parallels/common/step_prlctl.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type commandTemplate struct { diff --git a/builder/parallels/common/step_run.go b/builder/parallels/common/step_run.go index 8f86e089b..38ca6269b 100644 --- a/builder/parallels/common/step_run.go +++ b/builder/parallels/common/step_run.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepRun is a step that starts the virtual machine. diff --git a/builder/parallels/common/step_shutdown.go b/builder/parallels/common/step_shutdown.go index f8ec90009..0eaaff454 100644 --- a/builder/parallels/common/step_shutdown.go +++ b/builder/parallels/common/step_shutdown.go @@ -7,8 +7,8 @@ import ( "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepShutdown is a step that shuts down the machine. It first attempts to do diff --git a/builder/parallels/common/step_shutdown_test.go b/builder/parallels/common/step_shutdown_test.go index de3baabda..ef8dea7e0 100644 --- a/builder/parallels/common/step_shutdown_test.go +++ b/builder/parallels/common/step_shutdown_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepShutdown_impl(t *testing.T) { diff --git a/builder/parallels/common/step_test.go b/builder/parallels/common/step_test.go index cdaab7922..0964784f7 100644 --- a/builder/parallels/common/step_test.go +++ b/builder/parallels/common/step_test.go @@ -4,8 +4,8 @@ import ( "bytes" "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index c3076b82c..454b726db 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -9,9 +9,9 @@ import ( "unicode/utf8" packer_common "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type bootCommandTemplateData struct { diff --git a/builder/parallels/common/step_type_boot_command_test.go b/builder/parallels/common/step_type_boot_command_test.go index ea33b9369..559241c60 100644 --- a/builder/parallels/common/step_type_boot_command_test.go +++ b/builder/parallels/common/step_type_boot_command_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepTypeBootCommand(t *testing.T) { diff --git a/builder/parallels/common/step_upload_parallels_tools.go b/builder/parallels/common/step_upload_parallels_tools.go index 5769f1be5..f40a601b6 100644 --- a/builder/parallels/common/step_upload_parallels_tools.go +++ b/builder/parallels/common/step_upload_parallels_tools.go @@ -5,9 +5,9 @@ import ( "log" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // This step uploads the Parallels Tools ISO to the virtual machine. diff --git a/builder/parallels/common/step_upload_parallels_tools_test.go b/builder/parallels/common/step_upload_parallels_tools_test.go index 263571ff6..7e2f92110 100644 --- a/builder/parallels/common/step_upload_parallels_tools_test.go +++ b/builder/parallels/common/step_upload_parallels_tools_test.go @@ -3,8 +3,8 @@ package common import ( "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepUploadParallelsTools_impl(t *testing.T) { diff --git a/builder/parallels/common/step_upload_version.go b/builder/parallels/common/step_upload_version.go index 6824b035e..871f98400 100644 --- a/builder/parallels/common/step_upload_version.go +++ b/builder/parallels/common/step_upload_version.go @@ -5,8 +5,8 @@ import ( "fmt" "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepUploadVersion is a step that uploads a file containing the version of diff --git a/builder/parallels/common/step_upload_version_test.go b/builder/parallels/common/step_upload_version_test.go index 8aaf9cc90..17609b9aa 100644 --- a/builder/parallels/common/step_upload_version_test.go +++ b/builder/parallels/common/step_upload_version_test.go @@ -3,8 +3,8 @@ package common import ( "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepUploadVersion_impl(t *testing.T) { diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index 14ae2991d..cf8159f6b 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -9,9 +9,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const BuilderId = "rickard-von-essen.parallels" diff --git a/builder/parallels/iso/step_attach_iso.go b/builder/parallels/iso/step_attach_iso.go index 4dead4705..2ce5c7387 100644 --- a/builder/parallels/iso/step_attach_iso.go +++ b/builder/parallels/iso/step_attach_iso.go @@ -5,8 +5,8 @@ import ( "log" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step attaches the ISO to the virtual machine. diff --git a/builder/parallels/iso/step_create_disk.go b/builder/parallels/iso/step_create_disk.go index 0333472be..e7814507e 100644 --- a/builder/parallels/iso/step_create_disk.go +++ b/builder/parallels/iso/step_create_disk.go @@ -5,8 +5,8 @@ import ( "strconv" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates the virtual disk that will be used as the diff --git a/builder/parallels/iso/step_create_vm.go b/builder/parallels/iso/step_create_vm.go index b085e4485..0349931fa 100644 --- a/builder/parallels/iso/step_create_vm.go +++ b/builder/parallels/iso/step_create_vm.go @@ -4,8 +4,8 @@ import ( "fmt" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates the actual virtual machine. diff --git a/builder/parallels/iso/step_set_boot_order.go b/builder/parallels/iso/step_set_boot_order.go index a32249173..5b6837919 100644 --- a/builder/parallels/iso/step_set_boot_order.go +++ b/builder/parallels/iso/step_set_boot_order.go @@ -4,8 +4,8 @@ import ( "fmt" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step sets the device boot order for the virtual machine. diff --git a/builder/parallels/pvm/builder.go b/builder/parallels/pvm/builder.go index 5db72bbaa..1e0d3c49a 100644 --- a/builder/parallels/pvm/builder.go +++ b/builder/parallels/pvm/builder.go @@ -8,8 +8,8 @@ import ( parallelscommon "github.com/hashicorp/packer/builder/parallels/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // Builder implements packer.Builder and builds the actual Parallels diff --git a/builder/parallels/pvm/step_import.go b/builder/parallels/pvm/step_import.go index 91b8878af..d2b49f136 100644 --- a/builder/parallels/pvm/step_import.go +++ b/builder/parallels/pvm/step_import.go @@ -4,8 +4,8 @@ import ( "fmt" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step imports an PVM VM into Parallels. diff --git a/builder/parallels/pvm/step_test.go b/builder/parallels/pvm/step_test.go index 827850a35..9d891c637 100644 --- a/builder/parallels/pvm/step_test.go +++ b/builder/parallels/pvm/step_test.go @@ -5,8 +5,8 @@ import ( "testing" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/profitbricks/builder.go b/builder/profitbricks/builder.go index 42dc148d3..fc7734a07 100644 --- a/builder/profitbricks/builder.go +++ b/builder/profitbricks/builder.go @@ -6,8 +6,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) const BuilderId = "packer.profitbricks" diff --git a/builder/profitbricks/ssh.go b/builder/profitbricks/ssh.go index 3b0c93f31..d56696330 100644 --- a/builder/profitbricks/ssh.go +++ b/builder/profitbricks/ssh.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/profitbricks/step_create_server.go b/builder/profitbricks/step_create_server.go index a4de3cb19..3d2145e27 100644 --- a/builder/profitbricks/step_create_server.go +++ b/builder/profitbricks/step_create_server.go @@ -8,8 +8,8 @@ import ( "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/profitbricks/profitbricks-sdk-go" ) diff --git a/builder/profitbricks/step_create_ssh_key.go b/builder/profitbricks/step_create_ssh_key.go index 963afdf8c..26343d8a1 100644 --- a/builder/profitbricks/step_create_ssh_key.go +++ b/builder/profitbricks/step_create_ssh_key.go @@ -4,10 +4,8 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "io/ioutil" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/profitbricks/step_take_snapshot.go b/builder/profitbricks/step_take_snapshot.go index 822ea8699..31e22a379 100644 --- a/builder/profitbricks/step_take_snapshot.go +++ b/builder/profitbricks/step_take_snapshot.go @@ -4,8 +4,8 @@ import ( "encoding/json" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/profitbricks/profitbricks-sdk-go" ) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 43ec6b4c3..e926e3a17 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -13,9 +13,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const BuilderId = "transcend.qemu" diff --git a/builder/qemu/driver.go b/builder/qemu/driver.go index 632490114..eb1992ba6 100644 --- a/builder/qemu/driver.go +++ b/builder/qemu/driver.go @@ -14,7 +14,7 @@ import ( "time" "unicode" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) type DriverCancelCallback func(state multistep.StateBag) bool diff --git a/builder/qemu/ssh.go b/builder/qemu/ssh.go index 1881613fd..9c565eb32 100644 --- a/builder/qemu/ssh.go +++ b/builder/qemu/ssh.go @@ -3,7 +3,7 @@ package qemu import ( commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/qemu/step_boot_wait.go b/builder/qemu/step_boot_wait.go index 36625b8df..71d166689 100644 --- a/builder/qemu/step_boot_wait.go +++ b/builder/qemu/step_boot_wait.go @@ -2,10 +2,9 @@ package qemu import ( "fmt" - "time" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "time" ) // stepBootWait waits the configured time period. diff --git a/builder/qemu/step_configure_vnc.go b/builder/qemu/step_configure_vnc.go index 2cbfd6820..4224e2f33 100644 --- a/builder/qemu/step_configure_vnc.go +++ b/builder/qemu/step_configure_vnc.go @@ -6,8 +6,8 @@ import ( "math/rand" "net" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step configures the VM to enable the VNC server. diff --git a/builder/qemu/step_convert_disk.go b/builder/qemu/step_convert_disk.go index db7fe52c3..f74dc75d4 100644 --- a/builder/qemu/step_convert_disk.go +++ b/builder/qemu/step_convert_disk.go @@ -4,8 +4,8 @@ import ( "fmt" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "os" ) diff --git a/builder/qemu/step_copy_disk.go b/builder/qemu/step_copy_disk.go index 633d8d6b8..d60c10dec 100644 --- a/builder/qemu/step_copy_disk.go +++ b/builder/qemu/step_copy_disk.go @@ -4,8 +4,8 @@ import ( "fmt" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step copies the virtual disk that will be used as the diff --git a/builder/qemu/step_create_disk.go b/builder/qemu/step_create_disk.go index 5d844e2a0..ab0250e9b 100644 --- a/builder/qemu/step_create_disk.go +++ b/builder/qemu/step_create_disk.go @@ -4,8 +4,8 @@ import ( "fmt" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates the virtual disk that will be used as the diff --git a/builder/qemu/step_forward_ssh.go b/builder/qemu/step_forward_ssh.go index 7737fcbd8..ec1e9e18b 100644 --- a/builder/qemu/step_forward_ssh.go +++ b/builder/qemu/step_forward_ssh.go @@ -6,8 +6,8 @@ import ( "math/rand" "net" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step adds a NAT port forwarding definition so that SSH is available diff --git a/builder/qemu/step_prepare_output_dir.go b/builder/qemu/step_prepare_output_dir.go index b5f96c5ca..019e99bec 100644 --- a/builder/qemu/step_prepare_output_dir.go +++ b/builder/qemu/step_prepare_output_dir.go @@ -1,6 +1,8 @@ package qemu import ( + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "os" "time" diff --git a/builder/qemu/step_resize_disk.go b/builder/qemu/step_resize_disk.go index fbbd8d572..a6bc96487 100644 --- a/builder/qemu/step_resize_disk.go +++ b/builder/qemu/step_resize_disk.go @@ -4,8 +4,8 @@ import ( "fmt" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step resizes the virtual disk that will be used as the diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index dc9dd2faa..a9b00798e 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -7,9 +7,9 @@ import ( "strconv" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) // stepRun runs the virtual machine diff --git a/builder/qemu/step_set_iso.go b/builder/qemu/step_set_iso.go index f32a2687b..ff0f03b5b 100644 --- a/builder/qemu/step_set_iso.go +++ b/builder/qemu/step_set_iso.go @@ -4,8 +4,8 @@ import ( "fmt" "net/http" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step set iso_patch to available url diff --git a/builder/qemu/step_shutdown.go b/builder/qemu/step_shutdown.go index 88fa42c34..4efd85892 100644 --- a/builder/qemu/step_shutdown.go +++ b/builder/qemu/step_shutdown.go @@ -6,8 +6,8 @@ import ( "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step shuts down the machine. It first attempts to do so gracefully, diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index 97e05b7ea..fb0985d13 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -13,10 +13,11 @@ import ( "os" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/go-vnc" - "github.com/mitchellh/multistep" + "os" ) const KeyLeftShift uint32 = 0xFFE1 diff --git a/builder/triton/builder.go b/builder/triton/builder.go index 3e572e0a4..f2937a702 100644 --- a/builder/triton/builder.go +++ b/builder/triton/builder.go @@ -7,8 +7,8 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/triton/ssh.go b/builder/triton/ssh.go index 14fd26e31..179b94215 100644 --- a/builder/triton/ssh.go +++ b/builder/triton/ssh.go @@ -9,7 +9,7 @@ import ( "os" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/triton/step_create_image_from_machine.go b/builder/triton/step_create_image_from_machine.go index 76c46a768..cbda57e0b 100644 --- a/builder/triton/step_create_image_from_machine.go +++ b/builder/triton/step_create_image_from_machine.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateImageFromMachine creates an image with the specified attributes diff --git a/builder/triton/step_create_image_from_machine_test.go b/builder/triton/step_create_image_from_machine_test.go index 36ee43f82..9af18e44f 100644 --- a/builder/triton/step_create_image_from_machine_test.go +++ b/builder/triton/step_create_image_from_machine_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateImageFromMachine(t *testing.T) { diff --git a/builder/triton/step_create_source_machine.go b/builder/triton/step_create_source_machine.go index ae51fc60e..a52d35e50 100644 --- a/builder/triton/step_create_source_machine.go +++ b/builder/triton/step_create_source_machine.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateSourceMachine creates an machine with the specified attributes diff --git a/builder/triton/step_create_source_machine_test.go b/builder/triton/step_create_source_machine_test.go index 56f5d5940..f7101564a 100644 --- a/builder/triton/step_create_source_machine_test.go +++ b/builder/triton/step_create_source_machine_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateSourceMachine(t *testing.T) { diff --git a/builder/triton/step_delete_machine.go b/builder/triton/step_delete_machine.go index d766f9833..bccb791df 100644 --- a/builder/triton/step_delete_machine.go +++ b/builder/triton/step_delete_machine.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepDeleteMachine deletes the machine with the ID specified in state["machine"] diff --git a/builder/triton/step_delete_machine_test.go b/builder/triton/step_delete_machine_test.go index bca82b89a..a2177ca36 100644 --- a/builder/triton/step_delete_machine_test.go +++ b/builder/triton/step_delete_machine_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepDeleteMachine(t *testing.T) { diff --git a/builder/triton/step_stop_machine.go b/builder/triton/step_stop_machine.go index 00eb75958..4c2ab0d63 100644 --- a/builder/triton/step_stop_machine.go +++ b/builder/triton/step_stop_machine.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepStopMachine stops the machine with the given Machine ID, and waits diff --git a/builder/triton/step_stop_machine_test.go b/builder/triton/step_stop_machine_test.go index 4609343e0..9604c2216 100644 --- a/builder/triton/step_stop_machine_test.go +++ b/builder/triton/step_stop_machine_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepStopMachine(t *testing.T) { diff --git a/builder/triton/step_test.go b/builder/triton/step_test.go index fe647b42f..00fef044a 100644 --- a/builder/triton/step_test.go +++ b/builder/triton/step_test.go @@ -2,10 +2,9 @@ package triton import ( "bytes" - "testing" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/triton/step_wait_for_stop_to_not_fail.go b/builder/triton/step_wait_for_stop_to_not_fail.go index cd4df4704..d5479c803 100644 --- a/builder/triton/step_wait_for_stop_to_not_fail.go +++ b/builder/triton/step_wait_for_stop_to_not_fail.go @@ -3,8 +3,8 @@ package triton import ( "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepWaitForStopNotToFail waits for 10 seconds before returning with continue diff --git a/builder/virtualbox/common/ssh.go b/builder/virtualbox/common/ssh.go index b09c0cc47..45a99fb29 100644 --- a/builder/virtualbox/common/ssh.go +++ b/builder/virtualbox/common/ssh.go @@ -3,7 +3,7 @@ package common import ( commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/virtualbox/common/step_attach_floppy.go b/builder/virtualbox/common/step_attach_floppy.go index 35c8d1822..068f7814c 100644 --- a/builder/virtualbox/common/step_attach_floppy.go +++ b/builder/virtualbox/common/step_attach_floppy.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "io" "io/ioutil" "log" diff --git a/builder/virtualbox/common/step_attach_floppy_test.go b/builder/virtualbox/common/step_attach_floppy_test.go index 93d62b6d8..85f8ca0c2 100644 --- a/builder/virtualbox/common/step_attach_floppy_test.go +++ b/builder/virtualbox/common/step_attach_floppy_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" diff --git a/builder/virtualbox/common/step_attach_guest_additions.go b/builder/virtualbox/common/step_attach_guest_additions.go index 0d883f817..d9e43e820 100644 --- a/builder/virtualbox/common/step_attach_guest_additions.go +++ b/builder/virtualbox/common/step_attach_guest_additions.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // This step attaches the VirtualBox guest additions as a inserted CD onto diff --git a/builder/virtualbox/common/step_configure_vrdp.go b/builder/virtualbox/common/step_configure_vrdp.go index 9a966c508..aa47d586d 100644 --- a/builder/virtualbox/common/step_configure_vrdp.go +++ b/builder/virtualbox/common/step_configure_vrdp.go @@ -6,8 +6,8 @@ import ( "math/rand" "net" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step configures the VM to enable the VRDP server diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 93f3952c2..498d2e71e 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -10,9 +10,9 @@ import ( "strings" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) var additionsVersionMap = map[string]string{ diff --git a/builder/virtualbox/common/step_export.go b/builder/virtualbox/common/step_export.go index dab7d9ac3..268634132 100644 --- a/builder/virtualbox/common/step_export.go +++ b/builder/virtualbox/common/step_export.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "path/filepath" "strings" diff --git a/builder/virtualbox/common/step_export_test.go b/builder/virtualbox/common/step_export_test.go index 30723bae7..fee2cafdb 100644 --- a/builder/virtualbox/common/step_export_test.go +++ b/builder/virtualbox/common/step_export_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/virtualbox/common/step_forward_ssh.go b/builder/virtualbox/common/step_forward_ssh.go index 391573ced..7b0a6f903 100644 --- a/builder/virtualbox/common/step_forward_ssh.go +++ b/builder/virtualbox/common/step_forward_ssh.go @@ -7,8 +7,8 @@ import ( "net" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step adds a NAT port forwarding definition so that SSH is available diff --git a/builder/virtualbox/common/step_output_dir.go b/builder/virtualbox/common/step_output_dir.go index 0054d1994..acb905e9a 100644 --- a/builder/virtualbox/common/step_output_dir.go +++ b/builder/virtualbox/common/step_output_dir.go @@ -7,8 +7,8 @@ import ( "path/filepath" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepOutputDir sets up the output directory by creating it if it does diff --git a/builder/virtualbox/common/step_output_dir_test.go b/builder/virtualbox/common/step_output_dir_test.go index c742b5ddd..48f4634f4 100644 --- a/builder/virtualbox/common/step_output_dir_test.go +++ b/builder/virtualbox/common/step_output_dir_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" diff --git a/builder/virtualbox/common/step_remove_devices.go b/builder/virtualbox/common/step_remove_devices.go index 7860d53e9..0cdde2f23 100644 --- a/builder/virtualbox/common/step_remove_devices.go +++ b/builder/virtualbox/common/step_remove_devices.go @@ -5,8 +5,8 @@ import ( "log" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step removes any devices (floppy disks, ISOs, etc.) from the diff --git a/builder/virtualbox/common/step_remove_devices_test.go b/builder/virtualbox/common/step_remove_devices_test.go index 705648e33..9a2e8ee3a 100644 --- a/builder/virtualbox/common/step_remove_devices_test.go +++ b/builder/virtualbox/common/step_remove_devices_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/virtualbox/common/step_run.go b/builder/virtualbox/common/step_run.go index 3019c57d6..fc9ee9359 100644 --- a/builder/virtualbox/common/step_run.go +++ b/builder/virtualbox/common/step_run.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step starts the virtual machine. diff --git a/builder/virtualbox/common/step_shutdown.go b/builder/virtualbox/common/step_shutdown.go index 11a7cb3ac..51c435853 100644 --- a/builder/virtualbox/common/step_shutdown.go +++ b/builder/virtualbox/common/step_shutdown.go @@ -3,6 +3,8 @@ package common import ( "errors" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "time" diff --git a/builder/virtualbox/common/step_shutdown_test.go b/builder/virtualbox/common/step_shutdown_test.go index f83c65a8d..aa36a6c91 100644 --- a/builder/virtualbox/common/step_shutdown_test.go +++ b/builder/virtualbox/common/step_shutdown_test.go @@ -1,6 +1,8 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "testing" "time" diff --git a/builder/virtualbox/common/step_suppress_messages.go b/builder/virtualbox/common/step_suppress_messages.go index d6b2dcbbe..6ccbe0434 100644 --- a/builder/virtualbox/common/step_suppress_messages.go +++ b/builder/virtualbox/common/step_suppress_messages.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // This step sets some variables in VirtualBox so that annoying diff --git a/builder/virtualbox/common/step_suppress_messages_test.go b/builder/virtualbox/common/step_suppress_messages_test.go index 69c947835..d5609d456 100644 --- a/builder/virtualbox/common/step_suppress_messages_test.go +++ b/builder/virtualbox/common/step_suppress_messages_test.go @@ -2,6 +2,7 @@ package common import ( "errors" + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/virtualbox/common/step_test.go b/builder/virtualbox/common/step_test.go index 140f6f619..ec0854415 100644 --- a/builder/virtualbox/common/step_test.go +++ b/builder/virtualbox/common/step_test.go @@ -2,10 +2,9 @@ package common import ( "bytes" - "testing" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 3220ca8b8..ba008a5a3 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -9,9 +9,9 @@ import ( "unicode/utf8" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const KeyLeftShift uint32 = 0xFFE1 diff --git a/builder/virtualbox/common/step_upload_guest_additions.go b/builder/virtualbox/common/step_upload_guest_additions.go index a98676555..12b646e7e 100644 --- a/builder/virtualbox/common/step_upload_guest_additions.go +++ b/builder/virtualbox/common/step_upload_guest_additions.go @@ -5,9 +5,9 @@ import ( "log" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type guestAdditionsPathTemplate struct { diff --git a/builder/virtualbox/common/step_upload_version.go b/builder/virtualbox/common/step_upload_version.go index c9481c49b..262b6bfad 100644 --- a/builder/virtualbox/common/step_upload_version.go +++ b/builder/virtualbox/common/step_upload_version.go @@ -3,10 +3,9 @@ package common import ( "bytes" "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // This step uploads a file containing the VirtualBox version, which diff --git a/builder/virtualbox/common/step_upload_version_test.go b/builder/virtualbox/common/step_upload_version_test.go index 8aaf9cc90..cfd940a4b 100644 --- a/builder/virtualbox/common/step_upload_version_test.go +++ b/builder/virtualbox/common/step_upload_version_test.go @@ -1,10 +1,9 @@ package common import ( - "testing" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func TestStepUploadVersion_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_vboxmanage.go b/builder/virtualbox/common/step_vboxmanage.go index 7544dbbce..2366cc6ef 100644 --- a/builder/virtualbox/common/step_vboxmanage.go +++ b/builder/virtualbox/common/step_vboxmanage.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type commandTemplate struct { diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 82cf36409..0d1be21dd 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -10,9 +10,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const BuilderId = "mitchellh.virtualbox" diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index 1eb87ff92..088241e58 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -4,8 +4,8 @@ import ( "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step attaches the ISO to the virtual machine. diff --git a/builder/virtualbox/iso/step_create_disk.go b/builder/virtualbox/iso/step_create_disk.go index 6051768af..c5eb71302 100644 --- a/builder/virtualbox/iso/step_create_disk.go +++ b/builder/virtualbox/iso/step_create_disk.go @@ -4,8 +4,8 @@ import ( "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "path/filepath" "strconv" diff --git a/builder/virtualbox/iso/step_create_vm.go b/builder/virtualbox/iso/step_create_vm.go index ad1f72eaf..1f14d5b1a 100644 --- a/builder/virtualbox/iso/step_create_vm.go +++ b/builder/virtualbox/iso/step_create_vm.go @@ -4,8 +4,8 @@ import ( "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates the actual virtual machine. diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index 475bbebcf..d9783244f 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -8,8 +8,8 @@ import ( vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // Builder implements packer.Builder and builds the actual VirtualBox diff --git a/builder/virtualbox/ovf/step_import.go b/builder/virtualbox/ovf/step_import.go index 33e71fc24..ca52ef9fc 100644 --- a/builder/virtualbox/ovf/step_import.go +++ b/builder/virtualbox/ovf/step_import.go @@ -4,8 +4,8 @@ import ( "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step imports an OVF VM into VirtualBox. diff --git a/builder/virtualbox/ovf/step_import_test.go b/builder/virtualbox/ovf/step_import_test.go index dcaf013b5..aec090980 100644 --- a/builder/virtualbox/ovf/step_import_test.go +++ b/builder/virtualbox/ovf/step_import_test.go @@ -4,7 +4,8 @@ import ( "testing" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" + "testing" ) func TestStepImport_impl(t *testing.T) { diff --git a/builder/virtualbox/ovf/step_test.go b/builder/virtualbox/ovf/step_test.go index 805d435bc..eb6522ef6 100644 --- a/builder/virtualbox/ovf/step_test.go +++ b/builder/virtualbox/ovf/step_test.go @@ -5,8 +5,9 @@ import ( "testing" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 4e4f38e02..99c9f686c 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // A driver is able to talk to VMware, control virtual machines, etc. diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index a10f11902..9545d3e81 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -9,7 +9,7 @@ import ( "path/filepath" "strings" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // Fusion5Driver is a driver that can run VMware Fusion 5. diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index fcd80a51b..9291be976 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -3,7 +3,7 @@ package common import ( "sync" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) type DriverMock struct { diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 1552e92ea..311e5019c 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -9,7 +9,7 @@ import ( "path/filepath" "strings" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // Player5Driver is a driver that can run VMware Player 5 on Linux. diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index debcefcbc..d870a4cda 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -9,7 +9,7 @@ import ( "path/filepath" "strings" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // Workstation9Driver is a driver that can run VMware Workstation 9 diff --git a/builder/vmware/common/ssh.go b/builder/vmware/common/ssh.go index 0d94599f8..871ba8df9 100644 --- a/builder/vmware/common/ssh.go +++ b/builder/vmware/common/ssh.go @@ -9,7 +9,7 @@ import ( commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/vmware/common/step_clean_files.go b/builder/vmware/common/step_clean_files.go index b6d81293f..d1a970f36 100644 --- a/builder/vmware/common/step_clean_files.go +++ b/builder/vmware/common/step_clean_files.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "os" "path/filepath" diff --git a/builder/vmware/common/step_clean_vmx.go b/builder/vmware/common/step_clean_vmx.go index 853233e89..af29ae970 100644 --- a/builder/vmware/common/step_clean_vmx.go +++ b/builder/vmware/common/step_clean_vmx.go @@ -6,8 +6,8 @@ import ( "regexp" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step cleans up the VMX by removing or changing this prior to diff --git a/builder/vmware/common/step_clean_vmx_test.go b/builder/vmware/common/step_clean_vmx_test.go index aad39e8b0..04b2da1f5 100644 --- a/builder/vmware/common/step_clean_vmx_test.go +++ b/builder/vmware/common/step_clean_vmx_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCleanVMX_impl(t *testing.T) { diff --git a/builder/vmware/common/step_compact_disk.go b/builder/vmware/common/step_compact_disk.go index b53dd14c3..9292c46cf 100644 --- a/builder/vmware/common/step_compact_disk.go +++ b/builder/vmware/common/step_compact_disk.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // This step compacts the virtual disk for the VM unless the "skip_compaction" diff --git a/builder/vmware/common/step_compact_disk_test.go b/builder/vmware/common/step_compact_disk_test.go index e59a99a90..982191a4d 100644 --- a/builder/vmware/common/step_compact_disk_test.go +++ b/builder/vmware/common/step_compact_disk_test.go @@ -3,7 +3,7 @@ package common import ( "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCompactDisk_impl(t *testing.T) { diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 854922a2c..2b3f605f8 100644 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -7,8 +7,8 @@ import ( "regexp" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step configures a VMX by setting some default settings as well diff --git a/builder/vmware/common/step_configure_vmx_test.go b/builder/vmware/common/step_configure_vmx_test.go index 293269e3f..6bd692caa 100644 --- a/builder/vmware/common/step_configure_vmx_test.go +++ b/builder/vmware/common/step_configure_vmx_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testVMXFile(t *testing.T) string { diff --git a/builder/vmware/common/step_configure_vnc.go b/builder/vmware/common/step_configure_vnc.go index 4e4798862..e8b9f9a9f 100644 --- a/builder/vmware/common/step_configure_vnc.go +++ b/builder/vmware/common/step_configure_vnc.go @@ -8,8 +8,8 @@ import ( "net" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step configures the VM to enable the VNC server. diff --git a/builder/vmware/common/step_output_dir.go b/builder/vmware/common/step_output_dir.go index 2b679f1fc..ed180ed11 100644 --- a/builder/vmware/common/step_output_dir.go +++ b/builder/vmware/common/step_output_dir.go @@ -5,8 +5,8 @@ import ( "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepOutputDir sets up the output directory by creating it if it does diff --git a/builder/vmware/common/step_output_dir_test.go b/builder/vmware/common/step_output_dir_test.go index e748578bd..cdfba2a2e 100644 --- a/builder/vmware/common/step_output_dir_test.go +++ b/builder/vmware/common/step_output_dir_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" diff --git a/builder/vmware/common/step_prepare_tools.go b/builder/vmware/common/step_prepare_tools.go index f0566d91e..6dfabc663 100644 --- a/builder/vmware/common/step_prepare_tools.go +++ b/builder/vmware/common/step_prepare_tools.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) type StepPrepareTools struct { diff --git a/builder/vmware/common/step_prepare_tools_test.go b/builder/vmware/common/step_prepare_tools_test.go index 0326ea0d2..3ef593e5f 100644 --- a/builder/vmware/common/step_prepare_tools_test.go +++ b/builder/vmware/common/step_prepare_tools_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepPrepareTools_impl(t *testing.T) { diff --git a/builder/vmware/common/step_run.go b/builder/vmware/common/step_run.go index 2ea61f899..0324937fb 100644 --- a/builder/vmware/common/step_run.go +++ b/builder/vmware/common/step_run.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step runs the created virtual machine. diff --git a/builder/vmware/common/step_run_test.go b/builder/vmware/common/step_run_test.go index 9888cdf10..961363a04 100644 --- a/builder/vmware/common/step_run_test.go +++ b/builder/vmware/common/step_run_test.go @@ -3,7 +3,7 @@ package common import ( "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepRun_impl(t *testing.T) { diff --git a/builder/vmware/common/step_shutdown.go b/builder/vmware/common/step_shutdown.go index f0cf04aaf..2938eabe4 100644 --- a/builder/vmware/common/step_shutdown.go +++ b/builder/vmware/common/step_shutdown.go @@ -4,6 +4,8 @@ import ( "bytes" "errors" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "regexp" "strings" diff --git a/builder/vmware/common/step_shutdown_test.go b/builder/vmware/common/step_shutdown_test.go index b693527da..dd4693348 100644 --- a/builder/vmware/common/step_shutdown_test.go +++ b/builder/vmware/common/step_shutdown_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func testStepShutdownState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/common/step_suppress_messages.go b/builder/vmware/common/step_suppress_messages.go index a0a77b9ab..425da1398 100644 --- a/builder/vmware/common/step_suppress_messages.go +++ b/builder/vmware/common/step_suppress_messages.go @@ -2,10 +2,9 @@ package common import ( "fmt" - "log" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // This step suppresses any messages that VMware product might show. diff --git a/builder/vmware/common/step_suppress_messages_test.go b/builder/vmware/common/step_suppress_messages_test.go index 998cfdb24..a76b365a3 100644 --- a/builder/vmware/common/step_suppress_messages_test.go +++ b/builder/vmware/common/step_suppress_messages_test.go @@ -3,7 +3,7 @@ package common import ( "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepSuppressMessages_impl(t *testing.T) { diff --git a/builder/vmware/common/step_test.go b/builder/vmware/common/step_test.go index 140f6f619..ec0854415 100644 --- a/builder/vmware/common/step_test.go +++ b/builder/vmware/common/step_test.go @@ -2,10 +2,9 @@ package common import ( "bytes" - "testing" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 28db3c72e..84b47045e 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -12,10 +12,10 @@ import ( "unicode/utf8" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/go-vnc" - "github.com/mitchellh/multistep" ) const KeyLeftShift uint32 = 0xFFE1 diff --git a/builder/vmware/common/step_upload_tools.go b/builder/vmware/common/step_upload_tools.go index dfa8fcb88..c3642a1e6 100644 --- a/builder/vmware/common/step_upload_tools.go +++ b/builder/vmware/common/step_upload_tools.go @@ -4,9 +4,9 @@ import ( "fmt" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type toolsUploadPathTemplate struct { diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 5fa15317f..1d2a29ac5 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -13,9 +13,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const BuilderIdESX = "mitchellh.vmware-esx" diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 8da66f0d2..f30451c65 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -16,8 +16,8 @@ import ( commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/vmware/iso/driver_esx5_test.go b/builder/vmware/iso/driver_esx5_test.go index 6ce714ff1..0c0ef757e 100644 --- a/builder/vmware/iso/driver_esx5_test.go +++ b/builder/vmware/iso/driver_esx5_test.go @@ -6,7 +6,7 @@ import ( "testing" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestESX5Driver_implDriver(t *testing.T) { diff --git a/builder/vmware/iso/step_create_disk.go b/builder/vmware/iso/step_create_disk.go index 0985b70e5..1d76e68f5 100644 --- a/builder/vmware/iso/step_create_disk.go +++ b/builder/vmware/iso/step_create_disk.go @@ -5,8 +5,9 @@ import ( "path/filepath" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "path/filepath" ) // This step creates the virtual disks for the VM. diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 1f4ee812f..3a8985394 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -7,9 +7,9 @@ import ( "path/filepath" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type vmxTemplateData struct { diff --git a/builder/vmware/iso/step_export.go b/builder/vmware/iso/step_export.go index 91a2ce486..3fa71d8d8 100644 --- a/builder/vmware/iso/step_export.go +++ b/builder/vmware/iso/step_export.go @@ -9,8 +9,8 @@ import ( "runtime" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepExport struct { diff --git a/builder/vmware/iso/step_export_test.go b/builder/vmware/iso/step_export_test.go index 1e5ba606d..a713620e6 100644 --- a/builder/vmware/iso/step_export_test.go +++ b/builder/vmware/iso/step_export_test.go @@ -1,6 +1,7 @@ package iso import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/vmware/iso/step_register.go b/builder/vmware/iso/step_register.go index 509b6e017..a11ef17b5 100644 --- a/builder/vmware/iso/step_register.go +++ b/builder/vmware/iso/step_register.go @@ -5,8 +5,8 @@ import ( "time" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepRegister struct { diff --git a/builder/vmware/iso/step_register_test.go b/builder/vmware/iso/step_register_test.go index 8bfed06e8..6199696f0 100644 --- a/builder/vmware/iso/step_register_test.go +++ b/builder/vmware/iso/step_register_test.go @@ -1,6 +1,7 @@ package iso import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 76b30bfdf..48deabaab 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -5,8 +5,9 @@ import ( "log" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "log" ) // stepRemoteUpload uploads some thing from the state bag to a remote driver diff --git a/builder/vmware/iso/step_test.go b/builder/vmware/iso/step_test.go index 6ac2ba05e..66fc38d36 100644 --- a/builder/vmware/iso/step_test.go +++ b/builder/vmware/iso/step_test.go @@ -5,8 +5,9 @@ import ( "testing" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/iso/step_upload_vmx.go b/builder/vmware/iso/step_upload_vmx.go index 0c9e17c28..2fc65daaf 100644 --- a/builder/vmware/iso/step_upload_vmx.go +++ b/builder/vmware/iso/step_upload_vmx.go @@ -5,8 +5,9 @@ import ( "path/filepath" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "path/filepath" ) // This step upload the VMX to the remote host diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index b7c70d548..97852b534 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -9,8 +9,8 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // Builder implements packer.Builder and builds the actual VMware diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index eaa6607c5..76318b2ef 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -6,8 +6,8 @@ import ( "path/filepath" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCloneVMX takes a VMX file and clones the VM into the output directory. diff --git a/builder/vmware/vmx/step_clone_vmx_test.go b/builder/vmware/vmx/step_clone_vmx_test.go index 3b4cea1d5..0fedd84c8 100644 --- a/builder/vmware/vmx/step_clone_vmx_test.go +++ b/builder/vmware/vmx/step_clone_vmx_test.go @@ -7,7 +7,7 @@ import ( "testing" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCloneVMX_impl(t *testing.T) { diff --git a/builder/vmware/vmx/step_test.go b/builder/vmware/vmx/step_test.go index 60e2f890c..81439b3c4 100644 --- a/builder/vmware/vmx/step_test.go +++ b/builder/vmware/vmx/step_test.go @@ -5,8 +5,8 @@ import ( "testing" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func testState(t *testing.T) multistep.StateBag { diff --git a/common/multistep_debug.go b/common/multistep_debug.go index 15ebb7eb0..1a5fc9f10 100644 --- a/common/multistep_debug.go +++ b/common/multistep_debug.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "time" diff --git a/common/multistep_runner.go b/common/multistep_runner.go index 6f7c0a7cb..c10c0879e 100644 --- a/common/multistep_runner.go +++ b/common/multistep_runner.go @@ -8,8 +8,8 @@ import ( "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func newRunner(steps []multistep.Step, config PackerConfig, ui packer.Ui) (multistep.Runner, multistep.DebugPauseFn) { diff --git a/common/step_create_floppy.go b/common/step_create_floppy.go index d37302d5c..fdcc29f64 100644 --- a/common/step_create_floppy.go +++ b/common/step_create_floppy.go @@ -10,10 +10,10 @@ import ( "path/filepath" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/mitchellh/go-fs" "github.com/mitchellh/go-fs/fat" - "github.com/mitchellh/multistep" ) // StepCreateFloppy will create a floppy disk with the given files. diff --git a/common/step_create_floppy_test.go b/common/step_create_floppy_test.go index 7b5145eaa..a84c64677 100644 --- a/common/step_create_floppy_test.go +++ b/common/step_create_floppy_test.go @@ -3,6 +3,8 @@ package common import ( "bytes" "fmt" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "io/ioutil" "log" "os" diff --git a/common/step_download.go b/common/step_download.go index 765a07d23..d0250ec34 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -7,8 +7,8 @@ import ( "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepDownload downloads a remote file using the download client within diff --git a/common/step_download_test.go b/common/step_download_test.go index de166ae55..86d632867 100644 --- a/common/step_download_test.go +++ b/common/step_download_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/common/step_http_server.go b/common/step_http_server.go index 3752b51c6..b7fd3dcfd 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -10,8 +10,8 @@ import ( "os" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step creates and runs the HTTP server that is serving files from the diff --git a/common/step_provision.go b/common/step_provision.go index 15a6fb921..a859fea7d 100644 --- a/common/step_provision.go +++ b/common/step_provision.go @@ -1,6 +1,8 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" "log" "time" diff --git a/common/step_provision_test.go b/common/step_provision_test.go index 5347aaee3..f7c40b51d 100644 --- a/common/step_provision_test.go +++ b/common/step_provision_test.go @@ -1,6 +1,7 @@ package common import ( + "github.com/hashicorp/packer/helper/multistep" "testing" "github.com/mitchellh/multistep" diff --git a/helper/communicator/step_connect.go b/helper/communicator/step_connect.go index 7d738e4cc..5f27b0765 100644 --- a/helper/communicator/step_connect.go +++ b/helper/communicator/step_connect.go @@ -5,8 +5,8 @@ import ( "log" "github.com/hashicorp/packer/communicator/none" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" ) diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 9179f57e8..842e5e611 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -11,8 +11,8 @@ import ( commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" "golang.org/x/net/proxy" diff --git a/helper/communicator/step_connect_test.go b/helper/communicator/step_connect_test.go index d83625dd2..aa51e1782 100644 --- a/helper/communicator/step_connect_test.go +++ b/helper/communicator/step_connect_test.go @@ -4,8 +4,8 @@ import ( "bytes" "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepConnect_impl(t *testing.T) { diff --git a/helper/communicator/step_connect_winrm.go b/helper/communicator/step_connect_winrm.go index 14f5cfc91..b1182f7d6 100644 --- a/helper/communicator/step_connect_winrm.go +++ b/helper/communicator/step_connect_winrm.go @@ -10,9 +10,9 @@ import ( "time" "github.com/hashicorp/packer/communicator/winrm" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" winrmcmd "github.com/masterzen/winrm" - "github.com/mitchellh/multistep" ) // StepConnectWinRM is a multistep Step implementation that waits for WinRM diff --git a/post-processor/googlecompute-export/post-processor.go b/post-processor/googlecompute-export/post-processor.go index 8a5befbc8..e96bbb5f8 100644 --- a/post-processor/googlecompute-export/post-processor.go +++ b/post-processor/googlecompute-export/post-processor.go @@ -8,9 +8,9 @@ import ( "github.com/hashicorp/packer/builder/googlecompute" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) type Config struct { diff --git a/post-processor/vagrant-cloud/post-processor.go b/post-processor/vagrant-cloud/post-processor.go index b8eeb7105..f6c7f19d6 100644 --- a/post-processor/vagrant-cloud/post-processor.go +++ b/post-processor/vagrant-cloud/post-processor.go @@ -12,9 +12,9 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" ) const VAGRANT_CLOUD_URL = "https://vagrantcloud.com/api/v1" diff --git a/post-processor/vagrant-cloud/step_create_provider.go b/post-processor/vagrant-cloud/step_create_provider.go index 4cd443577..3e43bf451 100644 --- a/post-processor/vagrant-cloud/step_create_provider.go +++ b/post-processor/vagrant-cloud/step_create_provider.go @@ -2,9 +2,8 @@ package vagrantcloud import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type Provider struct { diff --git a/post-processor/vagrant-cloud/step_create_version.go b/post-processor/vagrant-cloud/step_create_version.go index aba6da020..6a7ef9fa7 100644 --- a/post-processor/vagrant-cloud/step_create_version.go +++ b/post-processor/vagrant-cloud/step_create_version.go @@ -2,9 +2,8 @@ package vagrantcloud import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type Version struct { diff --git a/post-processor/vagrant-cloud/step_prepare_upload.go b/post-processor/vagrant-cloud/step_prepare_upload.go index 0723520b9..88fa1eb05 100644 --- a/post-processor/vagrant-cloud/step_prepare_upload.go +++ b/post-processor/vagrant-cloud/step_prepare_upload.go @@ -3,8 +3,8 @@ package vagrantcloud import ( "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type Upload struct { diff --git a/post-processor/vagrant-cloud/step_release_version.go b/post-processor/vagrant-cloud/step_release_version.go index cc4db611f..328819570 100644 --- a/post-processor/vagrant-cloud/step_release_version.go +++ b/post-processor/vagrant-cloud/step_release_version.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepReleaseVersion struct { diff --git a/post-processor/vagrant-cloud/step_upload.go b/post-processor/vagrant-cloud/step_upload.go index 7004177fd..78d3bac0a 100644 --- a/post-processor/vagrant-cloud/step_upload.go +++ b/post-processor/vagrant-cloud/step_upload.go @@ -5,8 +5,8 @@ import ( "log" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepUpload struct { diff --git a/post-processor/vagrant-cloud/step_verify_box.go b/post-processor/vagrant-cloud/step_verify_box.go index ab6ac4fe6..84f12b6fe 100644 --- a/post-processor/vagrant-cloud/step_verify_box.go +++ b/post-processor/vagrant-cloud/step_verify_box.go @@ -2,9 +2,8 @@ package vagrantcloud import ( "fmt" - + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type Box struct { diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index f5fba9c4e..49be4ed7c 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/packer/builder/vmware/iso" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "github.com/mitchellh/multistep" "github.com/vmware/govmomi" ) diff --git a/post-processor/vsphere-template/step_choose_datacenter.go b/post-processor/vsphere-template/step_choose_datacenter.go index 51959b6d7..f66d99d9f 100644 --- a/post-processor/vsphere-template/step_choose_datacenter.go +++ b/post-processor/vsphere-template/step_choose_datacenter.go @@ -3,8 +3,8 @@ package vsphere_template import ( "context" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/vmware/govmomi" "github.com/vmware/govmomi/find" ) diff --git a/post-processor/vsphere-template/step_create_folder.go b/post-processor/vsphere-template/step_create_folder.go index a0e648275..cf5b8a847 100644 --- a/post-processor/vsphere-template/step_create_folder.go +++ b/post-processor/vsphere-template/step_create_folder.go @@ -5,8 +5,8 @@ import ( "fmt" "path" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/vmware/govmomi" "github.com/vmware/govmomi/object" ) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index dffc871ca..a8a116028 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -7,8 +7,8 @@ import ( "regexp" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/vmware/govmomi" "github.com/vmware/govmomi/object" "github.com/vmware/govmomi/vim25/types" From 07a5af66f86045cc65abbdcd445cd6ee5eecd173 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 19 Jan 2018 16:20:16 -0800 Subject: [PATCH 0430/1007] remove ctx arg from step.run --- helper/multistep/basic_runner.go | 2 +- helper/multistep/debug_runner.go | 3 +-- helper/multistep/multistep.go | 4 +--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go index eb5018d36..0c928321e 100644 --- a/helper/multistep/basic_runner.go +++ b/helper/multistep/basic_runner.go @@ -70,7 +70,7 @@ func (b *BasicRunner) Run(state StateBag) { break } - action := step.Run(ctx, state) + action := step.Run(state) defer step.Cleanup(state) if _, ok := state.GetOk(StateCancelled); ok { diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 88af01c54..882009494 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,7 +1,6 @@ package multistep import ( - "context" "fmt" "reflect" "sync" @@ -114,7 +113,7 @@ type debugStepPause struct { PauseFn DebugPauseFn } -func (s *debugStepPause) Run(_ context.Context, state StateBag) StepAction { +func (s *debugStepPause) Run(state StateBag) StepAction { s.PauseFn(DebugLocationAfterRun, s.StepName, state) return ActionContinue } diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go index 7b4e0801f..4e3478dac 100644 --- a/helper/multistep/multistep.go +++ b/helper/multistep/multistep.go @@ -2,8 +2,6 @@ // discrete steps. package multistep -import "context" - // A StepAction determines the next step to take regarding multi-step actions. type StepAction uint @@ -28,7 +26,7 @@ type Step interface { // // The return value determines whether multi-step sequences continue // or should halt. - Run(context.Context, StateBag) StepAction + Run(StateBag) StepAction // Cleanup is called in reverse order of the steps that have run // and allow steps to clean up after themselves. Do not assume if this From 030b5fd4f07f73d1d8420de9021f2aae3a0ddf83 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 19 Jan 2018 19:44:01 -0800 Subject: [PATCH 0431/1007] WIP add context to state bag --- helper/multistep/statebag.go | 44 +++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/helper/multistep/statebag.go b/helper/multistep/statebag.go index dab712316..c2f1e8a84 100644 --- a/helper/multistep/statebag.go +++ b/helper/multistep/statebag.go @@ -1,15 +1,20 @@ package multistep import ( + "context" "sync" ) +// Add context to state bag to prevent changing step signature + // StateBag holds the state that is used by the Runner and Steps. The // StateBag implementation must be safe for concurrent access. type StateBag interface { Get(string) interface{} GetOk(string) (interface{}, bool) Put(string, interface{}) + Context() context.Context + WithContext(context.Context) StateBag } // BasicStateBag implements StateBag by using a normal map underneath @@ -17,7 +22,13 @@ type StateBag interface { type BasicStateBag struct { data map[string]interface{} l sync.RWMutex - once sync.Once + ctx context.Context +} + +func NewBasicStateBag() *BasicStateBag { + b := new(BasicStateBag) + b.data = make(map[string]interface{}) + return b } func (b *BasicStateBag) Get(k string) interface{} { @@ -37,11 +48,32 @@ func (b *BasicStateBag) Put(k string, v interface{}) { b.l.Lock() defer b.l.Unlock() - // Make sure the map is initialized one time, on write - b.once.Do(func() { - b.data = make(map[string]interface{}) - }) - // Write the data b.data[k] = v } + +func (b *BasicStateBag) Context() context.Context { + if b.ctx != nil { + return b.ctx + } + return context.Background() +} + +// WithContext returns a copy of BasicStateBag with the provided context +// We copy the state bag +func (b *BasicStateBag) WithContext(ctx context.Context) *BasicStateBag { + if ctx == nil { + panic("nil context") + } + // read lock because copying is a read operation + b.l.RLock() + defer b.l.RUnlock() + + b2 := NewBasicStateBag() + + for k, v := range b.data { + b2.data[k] = v + } + b2.ctx = ctx + return b2 +} From 62e3d1362fd26e48c8b525fdc1b78e2691fd13a8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 19 Jan 2018 19:55:27 -0800 Subject: [PATCH 0432/1007] pass context through step.run again --- helper/multistep/basic_runner.go | 2 +- helper/multistep/debug_runner.go | 3 ++- helper/multistep/multistep.go | 4 ++- helper/multistep/statebag.go | 46 +++++--------------------------- 4 files changed, 13 insertions(+), 42 deletions(-) diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go index 0c928321e..eb5018d36 100644 --- a/helper/multistep/basic_runner.go +++ b/helper/multistep/basic_runner.go @@ -70,7 +70,7 @@ func (b *BasicRunner) Run(state StateBag) { break } - action := step.Run(state) + action := step.Run(ctx, state) defer step.Cleanup(state) if _, ok := state.GetOk(StateCancelled); ok { diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 882009494..88af01c54 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,6 +1,7 @@ package multistep import ( + "context" "fmt" "reflect" "sync" @@ -113,7 +114,7 @@ type debugStepPause struct { PauseFn DebugPauseFn } -func (s *debugStepPause) Run(state StateBag) StepAction { +func (s *debugStepPause) Run(_ context.Context, state StateBag) StepAction { s.PauseFn(DebugLocationAfterRun, s.StepName, state) return ActionContinue } diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go index 4e3478dac..7b4e0801f 100644 --- a/helper/multistep/multistep.go +++ b/helper/multistep/multistep.go @@ -2,6 +2,8 @@ // discrete steps. package multistep +import "context" + // A StepAction determines the next step to take regarding multi-step actions. type StepAction uint @@ -26,7 +28,7 @@ type Step interface { // // The return value determines whether multi-step sequences continue // or should halt. - Run(StateBag) StepAction + Run(context.Context, StateBag) StepAction // Cleanup is called in reverse order of the steps that have run // and allow steps to clean up after themselves. Do not assume if this diff --git a/helper/multistep/statebag.go b/helper/multistep/statebag.go index c2f1e8a84..9efb6d998 100644 --- a/helper/multistep/statebag.go +++ b/helper/multistep/statebag.go @@ -1,9 +1,6 @@ package multistep -import ( - "context" - "sync" -) +import "sync" // Add context to state bag to prevent changing step signature @@ -13,8 +10,6 @@ type StateBag interface { Get(string) interface{} GetOk(string) (interface{}, bool) Put(string, interface{}) - Context() context.Context - WithContext(context.Context) StateBag } // BasicStateBag implements StateBag by using a normal map underneath @@ -22,13 +17,7 @@ type StateBag interface { type BasicStateBag struct { data map[string]interface{} l sync.RWMutex - ctx context.Context -} - -func NewBasicStateBag() *BasicStateBag { - b := new(BasicStateBag) - b.data = make(map[string]interface{}) - return b + once sync.Once } func (b *BasicStateBag) Get(k string) interface{} { @@ -48,32 +37,11 @@ func (b *BasicStateBag) Put(k string, v interface{}) { b.l.Lock() defer b.l.Unlock() + // Make sure the map is initialized one time, on write + b.once.Do(func() { + b.data = make(map[string]interface{}) + }) + // Write the data b.data[k] = v } - -func (b *BasicStateBag) Context() context.Context { - if b.ctx != nil { - return b.ctx - } - return context.Background() -} - -// WithContext returns a copy of BasicStateBag with the provided context -// We copy the state bag -func (b *BasicStateBag) WithContext(ctx context.Context) *BasicStateBag { - if ctx == nil { - panic("nil context") - } - // read lock because copying is a read operation - b.l.RLock() - defer b.l.RUnlock() - - b2 := NewBasicStateBag() - - for k, v := range b.data { - b2.data[k] = v - } - b2.ctx = ctx - return b2 -} From e98f2016027578887926762377da8ad9a9fc8288 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 19 Jan 2018 20:09:05 -0800 Subject: [PATCH 0433/1007] working with opt-in --- builder/amazon/common/step_run_source_instance.go | 13 ++++--------- helper/multistep/basic_runner.go | 8 +++++++- helper/multistep/debug_runner.go | 3 +-- helper/multistep/multistep.go | 6 +++++- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 9186c868c..dcf6fea70 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -37,6 +37,10 @@ type StepRunSourceInstance struct { } func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepAction { + return s.RunWithContext(context.Background(), state) +} + +func (s *StepRunSourceInstance) RunWithContext(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) var keyName string if name, ok := state.GetOk("keyPair"); ok { @@ -179,15 +183,6 @@ func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepActi describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - ctx, cancel := context.WithCancel(context.Background()) - - go func() { - for { - if _, ok := state.GetOk(multistep.StateCancelled); ok { - cancel() - } - } - }() if err := ec2conn.WaitUntilInstanceRunningWithContext(ctx, describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go index eb5018d36..f152178bc 100644 --- a/helper/multistep/basic_runner.go +++ b/helper/multistep/basic_runner.go @@ -70,7 +70,13 @@ func (b *BasicRunner) Run(state StateBag) { break } - action := step.Run(ctx, state) + var action StepAction + + if stepCtx, ok := step.(StepRunnableWithContext); ok { + action = stepCtx.RunWithContext(ctx, state) + } else { + action = step.Run(state) + } defer step.Cleanup(state) if _, ok := state.GetOk(StateCancelled); ok { diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 88af01c54..882009494 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,7 +1,6 @@ package multistep import ( - "context" "fmt" "reflect" "sync" @@ -114,7 +113,7 @@ type debugStepPause struct { PauseFn DebugPauseFn } -func (s *debugStepPause) Run(_ context.Context, state StateBag) StepAction { +func (s *debugStepPause) Run(state StateBag) StepAction { s.PauseFn(DebugLocationAfterRun, s.StepName, state) return ActionContinue } diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go index 7b4e0801f..9b8a40b6d 100644 --- a/helper/multistep/multistep.go +++ b/helper/multistep/multistep.go @@ -19,6 +19,10 @@ const StateCancelled = "cancelled" // This is the key set in the state bag when a step halted the sequence. const StateHalted = "halted" +type StepRunnableWithContext interface { + RunWithContext(context.Context, StateBag) StepAction +} + // Step is a single step that is part of a potentially large sequence // of other steps, responsible for performing some specific action. type Step interface { @@ -28,7 +32,7 @@ type Step interface { // // The return value determines whether multi-step sequences continue // or should halt. - Run(context.Context, StateBag) StepAction + Run(StateBag) StepAction // Cleanup is called in reverse order of the steps that have run // and allow steps to clean up after themselves. Do not assume if this From a0c625ea4446ddcf58a616fcd2cc537440468a86 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 15:08:10 -0800 Subject: [PATCH 0434/1007] Revert "working with opt-in" This reverts commit 4068ffdaf541354e75507add7ca0b193993fcd52. --- builder/amazon/common/step_run_source_instance.go | 13 +++++++++---- helper/multistep/basic_runner.go | 8 +------- helper/multistep/debug_runner.go | 3 ++- helper/multistep/multistep.go | 6 +----- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index dcf6fea70..9186c868c 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -37,10 +37,6 @@ type StepRunSourceInstance struct { } func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepAction { - return s.RunWithContext(context.Background(), state) -} - -func (s *StepRunSourceInstance) RunWithContext(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) var keyName string if name, ok := state.GetOk("keyPair"); ok { @@ -183,6 +179,15 @@ func (s *StepRunSourceInstance) RunWithContext(ctx context.Context, state multis describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + for { + if _, ok := state.GetOk(multistep.StateCancelled); ok { + cancel() + } + } + }() if err := ec2conn.WaitUntilInstanceRunningWithContext(ctx, describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go index f152178bc..eb5018d36 100644 --- a/helper/multistep/basic_runner.go +++ b/helper/multistep/basic_runner.go @@ -70,13 +70,7 @@ func (b *BasicRunner) Run(state StateBag) { break } - var action StepAction - - if stepCtx, ok := step.(StepRunnableWithContext); ok { - action = stepCtx.RunWithContext(ctx, state) - } else { - action = step.Run(state) - } + action := step.Run(ctx, state) defer step.Cleanup(state) if _, ok := state.GetOk(StateCancelled); ok { diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 882009494..88af01c54 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,6 +1,7 @@ package multistep import ( + "context" "fmt" "reflect" "sync" @@ -113,7 +114,7 @@ type debugStepPause struct { PauseFn DebugPauseFn } -func (s *debugStepPause) Run(state StateBag) StepAction { +func (s *debugStepPause) Run(_ context.Context, state StateBag) StepAction { s.PauseFn(DebugLocationAfterRun, s.StepName, state) return ActionContinue } diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go index 9b8a40b6d..7b4e0801f 100644 --- a/helper/multistep/multistep.go +++ b/helper/multistep/multistep.go @@ -19,10 +19,6 @@ const StateCancelled = "cancelled" // This is the key set in the state bag when a step halted the sequence. const StateHalted = "halted" -type StepRunnableWithContext interface { - RunWithContext(context.Context, StateBag) StepAction -} - // Step is a single step that is part of a potentially large sequence // of other steps, responsible for performing some specific action. type Step interface { @@ -32,7 +28,7 @@ type Step interface { // // The return value determines whether multi-step sequences continue // or should halt. - Run(StateBag) StepAction + Run(context.Context, StateBag) StepAction // Cleanup is called in reverse order of the steps that have run // and allow steps to clean up after themselves. Do not assume if this From a831d522bec0ffa5fb8002f2b1c63ad69879ccc6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 15:31:41 -0800 Subject: [PATCH 0435/1007] change run signatures Run now takes a context as well as a statebag. We'll assign the context to the blank identifier to prevent namespace collisions. We'll let the step authors opt-in to using the context. `find . -iname "step_*.go" -exec gsed -i'' 's/func \(.*\)Run(/func \1Run(_ context.Context, /' {} \;` --- builder/alicloud/ecs/step_attach_keypair.go | 2 +- builder/alicloud/ecs/step_check_source_image.go | 2 +- builder/alicloud/ecs/step_config_eip.go | 2 +- builder/alicloud/ecs/step_config_key_pair.go | 2 +- builder/alicloud/ecs/step_config_public_ip.go | 2 +- builder/alicloud/ecs/step_config_security_group.go | 2 +- builder/alicloud/ecs/step_config_vpc.go | 2 +- builder/alicloud/ecs/step_config_vswitch.go | 2 +- builder/alicloud/ecs/step_create_image.go | 2 +- builder/alicloud/ecs/step_create_instance.go | 2 +- builder/alicloud/ecs/step_delete_images_snapshots.go | 2 +- builder/alicloud/ecs/step_mount_disk.go | 2 +- builder/alicloud/ecs/step_pre_validate.go | 2 +- builder/alicloud/ecs/step_region_copy_image.go | 2 +- builder/alicloud/ecs/step_run_instance.go | 2 +- builder/alicloud/ecs/step_share_image.go | 2 +- builder/alicloud/ecs/step_stop_instance.go | 2 +- builder/amazon/chroot/step_attach_volume.go | 2 +- builder/amazon/chroot/step_check_root_device.go | 2 +- builder/amazon/chroot/step_chroot_provision.go | 2 +- builder/amazon/chroot/step_copy_files.go | 2 +- builder/amazon/chroot/step_create_volume.go | 2 +- builder/amazon/chroot/step_early_cleanup.go | 2 +- builder/amazon/chroot/step_early_unflock.go | 2 +- builder/amazon/chroot/step_flock.go | 2 +- builder/amazon/chroot/step_instance_info.go | 2 +- builder/amazon/chroot/step_mount_device.go | 2 +- builder/amazon/chroot/step_mount_extra.go | 2 +- builder/amazon/chroot/step_post_mount_commands.go | 2 +- builder/amazon/chroot/step_pre_mount_commands.go | 2 +- builder/amazon/chroot/step_prepare_device.go | 2 +- builder/amazon/chroot/step_register_ami.go | 2 +- builder/amazon/chroot/step_snapshot.go | 2 +- builder/amazon/common/step_ami_region_copy.go | 2 +- builder/amazon/common/step_create_tags.go | 2 +- builder/amazon/common/step_deregister_ami.go | 2 +- builder/amazon/common/step_encrypted_ami.go | 2 +- builder/amazon/common/step_get_password.go | 2 +- builder/amazon/common/step_key_pair.go | 2 +- builder/amazon/common/step_modify_ami_attributes.go | 2 +- builder/amazon/common/step_modify_ebs_instance.go | 2 +- builder/amazon/common/step_pre_validate.go | 2 +- builder/amazon/common/step_run_source_instance.go | 2 +- builder/amazon/common/step_run_spot_instance.go | 2 +- builder/amazon/common/step_security_group.go | 2 +- builder/amazon/common/step_source_ami_info.go | 2 +- builder/amazon/common/step_stop_ebs_instance.go | 2 +- builder/amazon/ebs/step_cleanup_volumes.go | 2 +- builder/amazon/ebs/step_create_ami.go | 2 +- builder/amazon/ebssurrogate/step_register_ami.go | 2 +- builder/amazon/ebssurrogate/step_snapshot_new_root.go | 2 +- builder/amazon/ebsvolume/step_tag_ebs_volumes.go | 2 +- builder/amazon/instance/step_bundle_volume.go | 2 +- builder/amazon/instance/step_register_ami.go | 2 +- builder/amazon/instance/step_upload_bundle.go | 2 +- builder/amazon/instance/step_upload_x509_cert.go | 2 +- builder/azure/arm/step_capture_image.go | 2 +- builder/azure/arm/step_create_resource_group.go | 2 +- builder/azure/arm/step_delete_os_disk.go | 2 +- builder/azure/arm/step_delete_resource_group.go | 2 +- builder/azure/arm/step_deploy_template.go | 2 +- builder/azure/arm/step_get_certificate.go | 2 +- builder/azure/arm/step_get_ip_address.go | 2 +- builder/azure/arm/step_get_os_disk.go | 2 +- builder/azure/arm/step_power_off_compute.go | 2 +- builder/azure/arm/step_set_certificate.go | 2 +- builder/azure/arm/step_validate_template.go | 2 +- builder/azure/common/lin/step_create_cert.go | 2 +- builder/azure/common/lin/step_generalize_os.go | 2 +- builder/cloudstack/step_configure_networking.go | 2 +- builder/cloudstack/step_create_instance.go | 2 +- builder/cloudstack/step_create_security_group.go | 2 +- builder/cloudstack/step_create_template.go | 2 +- builder/cloudstack/step_keypair.go | 2 +- builder/cloudstack/step_prepare_config.go | 2 +- builder/cloudstack/step_shutdown_instance.go | 2 +- builder/digitalocean/step_create_droplet.go | 2 +- builder/digitalocean/step_create_ssh_key.go | 2 +- builder/digitalocean/step_droplet_info.go | 2 +- builder/digitalocean/step_power_off.go | 2 +- builder/digitalocean/step_shutdown.go | 2 +- builder/digitalocean/step_snapshot.go | 2 +- builder/docker/step_commit.go | 2 +- builder/docker/step_connect_docker.go | 2 +- builder/docker/step_export.go | 2 +- builder/docker/step_pull.go | 2 +- builder/docker/step_run.go | 2 +- builder/docker/step_run_test.go | 2 +- builder/docker/step_temp_dir.go | 2 +- builder/googlecompute/step_check_existing_image.go | 2 +- builder/googlecompute/step_create_image.go | 2 +- builder/googlecompute/step_create_instance.go | 2 +- builder/googlecompute/step_create_ssh_key.go | 2 +- builder/googlecompute/step_create_windows_password.go | 2 +- builder/googlecompute/step_instance_info.go | 2 +- builder/googlecompute/step_teardown_instance.go | 2 +- builder/googlecompute/step_wait_startup_script.go | 2 +- builder/hyperv/common/step_clone_vm.go | 2 +- builder/hyperv/common/step_configure_ip.go | 2 +- builder/hyperv/common/step_configure_vlan.go | 2 +- builder/hyperv/common/step_create_external_switch.go | 2 +- builder/hyperv/common/step_create_switch.go | 2 +- builder/hyperv/common/step_create_tempdir.go | 2 +- builder/hyperv/common/step_create_vm.go | 2 +- builder/hyperv/common/step_disable_vlan.go | 2 +- builder/hyperv/common/step_enable_integration_service.go | 2 +- builder/hyperv/common/step_export_vm.go | 2 +- builder/hyperv/common/step_mount_dvddrive.go | 2 +- builder/hyperv/common/step_mount_floppydrive.go | 2 +- builder/hyperv/common/step_mount_guest_additions.go | 2 +- builder/hyperv/common/step_mount_secondary_dvd_images.go | 2 +- builder/hyperv/common/step_output_dir.go | 2 +- builder/hyperv/common/step_polling_installation.go | 2 +- builder/hyperv/common/step_reboot_vm.go | 2 +- builder/hyperv/common/step_run.go | 2 +- builder/hyperv/common/step_shutdown.go | 2 +- builder/hyperv/common/step_sleep.go | 2 +- builder/hyperv/common/step_type_boot_command.go | 2 +- builder/hyperv/common/step_unmount_dvddrive.go | 2 +- builder/hyperv/common/step_unmount_floppydrive.go | 2 +- builder/hyperv/common/step_unmount_guest_additions.go | 2 +- builder/hyperv/common/step_unmount_secondary_dvd_images.go | 2 +- builder/hyperv/common/step_wait_for_install_to_complete.go | 4 ++-- builder/lxc/step_export.go | 2 +- builder/lxc/step_lxc_create.go | 2 +- builder/lxc/step_prepare_output_dir.go | 2 +- builder/lxc/step_provision.go | 2 +- builder/lxc/step_wait_init.go | 2 +- builder/lxd/step_lxd_launch.go | 2 +- builder/lxd/step_provision.go | 2 +- builder/lxd/step_publish.go | 2 +- builder/oneandone/step_create_server.go | 2 +- builder/oneandone/step_create_sshkey.go | 2 +- builder/oneandone/step_take_snapshot.go | 2 +- builder/openstack/step_add_image_members.go | 2 +- builder/openstack/step_allocate_ip.go | 2 +- builder/openstack/step_create_image.go | 2 +- builder/openstack/step_get_password.go | 2 +- builder/openstack/step_key_pair.go | 2 +- builder/openstack/step_load_extensions.go | 2 +- builder/openstack/step_load_flavor.go | 2 +- builder/openstack/step_run_source_server.go | 2 +- builder/openstack/step_stop_server.go | 2 +- builder/openstack/step_update_image_visibility.go | 2 +- builder/openstack/step_wait_for_rackconnect.go | 2 +- builder/oracle/oci/step_create_instance.go | 2 +- builder/oracle/oci/step_image.go | 2 +- builder/oracle/oci/step_instance_info.go | 2 +- builder/oracle/oci/step_ssh_key_pair.go | 2 +- builder/parallels/common/step_attach_floppy.go | 2 +- builder/parallels/common/step_attach_parallels_tools.go | 2 +- builder/parallels/common/step_compact_disk.go | 2 +- builder/parallels/common/step_output_dir.go | 2 +- builder/parallels/common/step_prepare_parallels_tools.go | 2 +- builder/parallels/common/step_prlctl.go | 2 +- builder/parallels/common/step_run.go | 2 +- builder/parallels/common/step_shutdown.go | 2 +- builder/parallels/common/step_type_boot_command.go | 2 +- builder/parallels/common/step_upload_parallels_tools.go | 2 +- builder/parallels/common/step_upload_version.go | 2 +- builder/parallels/iso/step_attach_iso.go | 2 +- builder/parallels/iso/step_create_disk.go | 2 +- builder/parallels/iso/step_create_vm.go | 2 +- builder/parallels/iso/step_set_boot_order.go | 2 +- builder/parallels/pvm/step_import.go | 2 +- builder/profitbricks/step_create_server.go | 2 +- builder/profitbricks/step_create_ssh_key.go | 2 +- builder/profitbricks/step_take_snapshot.go | 2 +- builder/qemu/step_boot_wait.go | 2 +- builder/qemu/step_configure_vnc.go | 2 +- builder/qemu/step_convert_disk.go | 2 +- builder/qemu/step_copy_disk.go | 2 +- builder/qemu/step_create_disk.go | 2 +- builder/qemu/step_forward_ssh.go | 2 +- builder/qemu/step_prepare_output_dir.go | 2 +- builder/qemu/step_resize_disk.go | 2 +- builder/qemu/step_run.go | 2 +- builder/qemu/step_set_iso.go | 2 +- builder/qemu/step_shutdown.go | 2 +- builder/qemu/step_type_boot_command.go | 2 +- builder/triton/step_create_image_from_machine.go | 2 +- builder/triton/step_create_source_machine.go | 2 +- builder/triton/step_delete_machine.go | 2 +- builder/triton/step_stop_machine.go | 2 +- builder/triton/step_wait_for_stop_to_not_fail.go | 2 +- builder/virtualbox/common/step_attach_floppy.go | 2 +- builder/virtualbox/common/step_attach_guest_additions.go | 2 +- builder/virtualbox/common/step_configure_vrdp.go | 2 +- builder/virtualbox/common/step_download_guest_additions.go | 2 +- builder/virtualbox/common/step_export.go | 2 +- builder/virtualbox/common/step_forward_ssh.go | 2 +- builder/virtualbox/common/step_output_dir.go | 2 +- builder/virtualbox/common/step_remove_devices.go | 2 +- builder/virtualbox/common/step_run.go | 2 +- builder/virtualbox/common/step_shutdown.go | 2 +- builder/virtualbox/common/step_suppress_messages.go | 2 +- builder/virtualbox/common/step_type_boot_command.go | 2 +- builder/virtualbox/common/step_upload_guest_additions.go | 2 +- builder/virtualbox/common/step_upload_version.go | 2 +- builder/virtualbox/common/step_vboxmanage.go | 2 +- builder/virtualbox/iso/step_attach_iso.go | 2 +- builder/virtualbox/iso/step_create_disk.go | 2 +- builder/virtualbox/iso/step_create_vm.go | 2 +- builder/virtualbox/ovf/step_import.go | 2 +- builder/vmware/common/step_clean_files.go | 2 +- builder/vmware/common/step_clean_vmx.go | 2 +- builder/vmware/common/step_compact_disk.go | 2 +- builder/vmware/common/step_configure_vmx.go | 2 +- builder/vmware/common/step_configure_vnc.go | 2 +- builder/vmware/common/step_output_dir.go | 2 +- builder/vmware/common/step_prepare_tools.go | 2 +- builder/vmware/common/step_run.go | 2 +- builder/vmware/common/step_run_test.go | 2 +- builder/vmware/common/step_shutdown.go | 2 +- builder/vmware/common/step_suppress_messages.go | 2 +- builder/vmware/common/step_type_boot_command.go | 2 +- builder/vmware/common/step_upload_tools.go | 2 +- builder/vmware/iso/step_create_disk.go | 2 +- builder/vmware/iso/step_create_vmx.go | 2 +- builder/vmware/iso/step_export.go | 2 +- builder/vmware/iso/step_register.go | 2 +- builder/vmware/iso/step_remote_upload.go | 2 +- builder/vmware/iso/step_upload_vmx.go | 2 +- builder/vmware/vmx/step_clone_vmx.go | 2 +- common/step_create_floppy.go | 2 +- common/step_download.go | 2 +- common/step_http_server.go | 2 +- common/step_provision.go | 2 +- helper/communicator/step_connect.go | 2 +- helper/communicator/step_connect_ssh.go | 2 +- helper/communicator/step_connect_winrm.go | 2 +- post-processor/vagrant-cloud/step_create_provider.go | 2 +- post-processor/vagrant-cloud/step_create_version.go | 2 +- post-processor/vagrant-cloud/step_prepare_upload.go | 2 +- post-processor/vagrant-cloud/step_release_version.go | 2 +- post-processor/vagrant-cloud/step_upload.go | 2 +- post-processor/vagrant-cloud/step_verify_box.go | 2 +- post-processor/vsphere-template/step_choose_datacenter.go | 2 +- post-processor/vsphere-template/step_create_folder.go | 2 +- post-processor/vsphere-template/step_mark_as_template.go | 2 +- 240 files changed, 241 insertions(+), 241 deletions(-) diff --git a/builder/alicloud/ecs/step_attach_keypair.go b/builder/alicloud/ecs/step_attach_keypair.go index 012efd2b1..1bb901f98 100644 --- a/builder/alicloud/ecs/step_attach_keypair.go +++ b/builder/alicloud/ecs/step_attach_keypair.go @@ -15,7 +15,7 @@ import ( type stepAttachKeyPar struct { } -func (s *stepAttachKeyPar) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepAttachKeyPar) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { keyPairName := state.Get("keyPair").(string) if keyPairName == "" { return multistep.ActionContinue diff --git a/builder/alicloud/ecs/step_check_source_image.go b/builder/alicloud/ecs/step_check_source_image.go index 3f3ee87d0..b9dc58f69 100644 --- a/builder/alicloud/ecs/step_check_source_image.go +++ b/builder/alicloud/ecs/step_check_source_image.go @@ -13,7 +13,7 @@ type stepCheckAlicloudSourceImage struct { SourceECSImageId string } -func (s *stepCheckAlicloudSourceImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCheckAlicloudSourceImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/alicloud/ecs/step_config_eip.go b/builder/alicloud/ecs/step_config_eip.go index 2d626bf62..edf0b2748 100644 --- a/builder/alicloud/ecs/step_config_eip.go +++ b/builder/alicloud/ecs/step_config_eip.go @@ -16,7 +16,7 @@ type setpConfigAlicloudEIP struct { allocatedId string } -func (s *setpConfigAlicloudEIP) Run(state multistep.StateBag) multistep.StepAction { +func (s *setpConfigAlicloudEIP) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) instance := state.Get("instance").(*ecs.InstanceAttributesType) diff --git a/builder/alicloud/ecs/step_config_key_pair.go b/builder/alicloud/ecs/step_config_key_pair.go index 62fb41a9d..9c68ce92e 100644 --- a/builder/alicloud/ecs/step_config_key_pair.go +++ b/builder/alicloud/ecs/step_config_key_pair.go @@ -24,7 +24,7 @@ type StepConfigAlicloudKeyPair struct { keyName string } -func (s *StepConfigAlicloudKeyPair) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigAlicloudKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/alicloud/ecs/step_config_public_ip.go b/builder/alicloud/ecs/step_config_public_ip.go index c8859afa3..e87a20079 100644 --- a/builder/alicloud/ecs/step_config_public_ip.go +++ b/builder/alicloud/ecs/step_config_public_ip.go @@ -13,7 +13,7 @@ type stepConfigAlicloudPublicIP struct { RegionId string } -func (s *stepConfigAlicloudPublicIP) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepConfigAlicloudPublicIP) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) instance := state.Get("instance").(*ecs.InstanceAttributesType) diff --git a/builder/alicloud/ecs/step_config_security_group.go b/builder/alicloud/ecs/step_config_security_group.go index 8a20915d4..4414eefe6 100644 --- a/builder/alicloud/ecs/step_config_security_group.go +++ b/builder/alicloud/ecs/step_config_security_group.go @@ -20,7 +20,7 @@ type stepConfigAlicloudSecurityGroup struct { isCreate bool } -func (s *stepConfigAlicloudSecurityGroup) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepConfigAlicloudSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) networkType := state.Get("networktype").(InstanceNetWork) diff --git a/builder/alicloud/ecs/step_config_vpc.go b/builder/alicloud/ecs/step_config_vpc.go index c03ed3944..618b4a3da 100644 --- a/builder/alicloud/ecs/step_config_vpc.go +++ b/builder/alicloud/ecs/step_config_vpc.go @@ -18,7 +18,7 @@ type stepConfigAlicloudVPC struct { isCreate bool } -func (s *stepConfigAlicloudVPC) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepConfigAlicloudVPC) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) diff --git a/builder/alicloud/ecs/step_config_vswitch.go b/builder/alicloud/ecs/step_config_vswitch.go index 357e40624..5510acb3b 100644 --- a/builder/alicloud/ecs/step_config_vswitch.go +++ b/builder/alicloud/ecs/step_config_vswitch.go @@ -19,7 +19,7 @@ type stepConfigAlicloudVSwitch struct { VSwitchName string } -func (s *stepConfigAlicloudVSwitch) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepConfigAlicloudVSwitch) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) vpcId := state.Get("vpcid").(string) diff --git a/builder/alicloud/ecs/step_create_image.go b/builder/alicloud/ecs/step_create_image.go index 852376250..098323307 100644 --- a/builder/alicloud/ecs/step_create_image.go +++ b/builder/alicloud/ecs/step_create_image.go @@ -13,7 +13,7 @@ type stepCreateAlicloudImage struct { image *ecs.ImageType } -func (s *stepCreateAlicloudImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateAlicloudImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) diff --git a/builder/alicloud/ecs/step_create_instance.go b/builder/alicloud/ecs/step_create_instance.go index b2019ade6..694ee0046 100644 --- a/builder/alicloud/ecs/step_create_instance.go +++ b/builder/alicloud/ecs/step_create_instance.go @@ -25,7 +25,7 @@ type stepCreateAlicloudInstance struct { instance *ecs.InstanceAttributesType } -func (s *stepCreateAlicloudInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateAlicloudInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/alicloud/ecs/step_delete_images_snapshots.go b/builder/alicloud/ecs/step_delete_images_snapshots.go index 841190934..39e56e7bd 100644 --- a/builder/alicloud/ecs/step_delete_images_snapshots.go +++ b/builder/alicloud/ecs/step_delete_images_snapshots.go @@ -16,7 +16,7 @@ type stepDeleteAlicloudImageSnapshots struct { AlicloudImageName string } -func (s *stepDeleteAlicloudImageSnapshots) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepDeleteAlicloudImageSnapshots) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) diff --git a/builder/alicloud/ecs/step_mount_disk.go b/builder/alicloud/ecs/step_mount_disk.go index 8ec517ece..509d06615 100644 --- a/builder/alicloud/ecs/step_mount_disk.go +++ b/builder/alicloud/ecs/step_mount_disk.go @@ -11,7 +11,7 @@ import ( type stepMountAlicloudDisk struct { } -func (s *stepMountAlicloudDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepMountAlicloudDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/alicloud/ecs/step_pre_validate.go b/builder/alicloud/ecs/step_pre_validate.go index fb4a663f5..bdcad2756 100644 --- a/builder/alicloud/ecs/step_pre_validate.go +++ b/builder/alicloud/ecs/step_pre_validate.go @@ -14,7 +14,7 @@ type stepPreValidate struct { ForceDelete bool } -func (s *stepPreValidate) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepPreValidate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.ForceDelete { ui.Say("Force delete flag found, skipping prevalidating image name.") diff --git a/builder/alicloud/ecs/step_region_copy_image.go b/builder/alicloud/ecs/step_region_copy_image.go index c7b68f697..e50398539 100644 --- a/builder/alicloud/ecs/step_region_copy_image.go +++ b/builder/alicloud/ecs/step_region_copy_image.go @@ -15,7 +15,7 @@ type setpRegionCopyAlicloudImage struct { RegionId string } -func (s *setpRegionCopyAlicloudImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *setpRegionCopyAlicloudImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if len(s.AlicloudImageDestinationRegions) == 0 { return multistep.ActionContinue } diff --git a/builder/alicloud/ecs/step_run_instance.go b/builder/alicloud/ecs/step_run_instance.go index f8e0f6b68..2bac6dc91 100644 --- a/builder/alicloud/ecs/step_run_instance.go +++ b/builder/alicloud/ecs/step_run_instance.go @@ -11,7 +11,7 @@ import ( type stepRunAlicloudInstance struct { } -func (s *stepRunAlicloudInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepRunAlicloudInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) instance := state.Get("instance").(*ecs.InstanceAttributesType) diff --git a/builder/alicloud/ecs/step_share_image.go b/builder/alicloud/ecs/step_share_image.go index 7a95fdfd6..2f6fbf06f 100644 --- a/builder/alicloud/ecs/step_share_image.go +++ b/builder/alicloud/ecs/step_share_image.go @@ -15,7 +15,7 @@ type setpShareAlicloudImage struct { RegionId string } -func (s *setpShareAlicloudImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *setpShareAlicloudImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) ui := state.Get("ui").(packer.Ui) alicloudImages := state.Get("alicloudimages").(map[string]string) diff --git a/builder/alicloud/ecs/step_stop_instance.go b/builder/alicloud/ecs/step_stop_instance.go index 4a55c3aba..055f0d5d9 100644 --- a/builder/alicloud/ecs/step_stop_instance.go +++ b/builder/alicloud/ecs/step_stop_instance.go @@ -12,7 +12,7 @@ type stepStopAlicloudInstance struct { ForceStop bool } -func (s *stepStopAlicloudInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepStopAlicloudInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*ecs.Client) instance := state.Get("instance").(*ecs.InstanceAttributesType) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index 47fac4d57..f386a031b 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -23,7 +23,7 @@ type StepAttachVolume struct { volumeId string } -func (s *StepAttachVolume) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAttachVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) device := state.Get("device").(string) instance := state.Get("instance").(*ec2.Instance) diff --git a/builder/amazon/chroot/step_check_root_device.go b/builder/amazon/chroot/step_check_root_device.go index 241a46cc1..582a76b8d 100644 --- a/builder/amazon/chroot/step_check_root_device.go +++ b/builder/amazon/chroot/step_check_root_device.go @@ -11,7 +11,7 @@ import ( // StepCheckRootDevice makes sure the root device on the AMI is EBS-backed. type StepCheckRootDevice struct{} -func (s *StepCheckRootDevice) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCheckRootDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { image := state.Get("source_image").(*ec2.Image) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_chroot_provision.go b/builder/amazon/chroot/step_chroot_provision.go index eb651d78c..6eb4226c5 100644 --- a/builder/amazon/chroot/step_chroot_provision.go +++ b/builder/amazon/chroot/step_chroot_provision.go @@ -11,7 +11,7 @@ import ( type StepChrootProvision struct { } -func (s *StepChrootProvision) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepChrootProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { hook := state.Get("hook").(packer.Hook) mountPath := state.Get("mount_path").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_copy_files.go b/builder/amazon/chroot/step_copy_files.go index d608141da..d1bdb32b4 100644 --- a/builder/amazon/chroot/step_copy_files.go +++ b/builder/amazon/chroot/step_copy_files.go @@ -21,7 +21,7 @@ type StepCopyFiles struct { files []string } -func (s *StepCopyFiles) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCopyFiles) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) mountPath := state.Get("mount_path").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index ce4b01e64..10f49b0df 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -21,7 +21,7 @@ type StepCreateVolume struct { RootVolumeSize int64 } -func (s *StepCreateVolume) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) diff --git a/builder/amazon/chroot/step_early_cleanup.go b/builder/amazon/chroot/step_early_cleanup.go index c3aecc85c..449cb2a89 100644 --- a/builder/amazon/chroot/step_early_cleanup.go +++ b/builder/amazon/chroot/step_early_cleanup.go @@ -11,7 +11,7 @@ import ( // prepare for snapshotting and creating an AMI. type StepEarlyCleanup struct{} -func (s *StepEarlyCleanup) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepEarlyCleanup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) cleanupKeys := []string{ "copy_files_cleanup", diff --git a/builder/amazon/chroot/step_early_unflock.go b/builder/amazon/chroot/step_early_unflock.go index 92eff391c..8c15713f8 100644 --- a/builder/amazon/chroot/step_early_unflock.go +++ b/builder/amazon/chroot/step_early_unflock.go @@ -10,7 +10,7 @@ import ( // StepEarlyUnflock unlocks the flock. type StepEarlyUnflock struct{} -func (s *StepEarlyUnflock) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepEarlyUnflock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { cleanup := state.Get("flock_cleanup").(Cleanup) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_flock.go b/builder/amazon/chroot/step_flock.go index 4b6dd284e..d7ef614ff 100644 --- a/builder/amazon/chroot/step_flock.go +++ b/builder/amazon/chroot/step_flock.go @@ -20,7 +20,7 @@ type StepFlock struct { fh *os.File } -func (s *StepFlock) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepFlock) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) lockfile := "/var/lock/packer-chroot/lock" diff --git a/builder/amazon/chroot/step_instance_info.go b/builder/amazon/chroot/step_instance_info.go index 307e24aa8..8811a49ff 100644 --- a/builder/amazon/chroot/step_instance_info.go +++ b/builder/amazon/chroot/step_instance_info.go @@ -14,7 +14,7 @@ import ( // StepInstanceInfo verifies that this builder is running on an EC2 instance. type StepInstanceInfo struct{} -func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepInstanceInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_mount_device.go b/builder/amazon/chroot/step_mount_device.go index 07757dba2..06fae4210 100644 --- a/builder/amazon/chroot/step_mount_device.go +++ b/builder/amazon/chroot/step_mount_device.go @@ -30,7 +30,7 @@ type StepMountDevice struct { mountPath string } -func (s *StepMountDevice) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) device := state.Get("device").(string) diff --git a/builder/amazon/chroot/step_mount_extra.go b/builder/amazon/chroot/step_mount_extra.go index 074f40199..7ebbb650a 100644 --- a/builder/amazon/chroot/step_mount_extra.go +++ b/builder/amazon/chroot/step_mount_extra.go @@ -21,7 +21,7 @@ type StepMountExtra struct { mounts []string } -func (s *StepMountExtra) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepMountExtra) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) mountPath := state.Get("mount_path").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_post_mount_commands.go b/builder/amazon/chroot/step_post_mount_commands.go index 0ebd68d60..220e32a07 100644 --- a/builder/amazon/chroot/step_post_mount_commands.go +++ b/builder/amazon/chroot/step_post_mount_commands.go @@ -16,7 +16,7 @@ type StepPostMountCommands struct { Commands []string } -func (s *StepPostMountCommands) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPostMountCommands) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) device := state.Get("device").(string) mountPath := state.Get("mount_path").(string) diff --git a/builder/amazon/chroot/step_pre_mount_commands.go b/builder/amazon/chroot/step_pre_mount_commands.go index 9a9bf69ac..b3a8aae6b 100644 --- a/builder/amazon/chroot/step_pre_mount_commands.go +++ b/builder/amazon/chroot/step_pre_mount_commands.go @@ -14,7 +14,7 @@ type StepPreMountCommands struct { Commands []string } -func (s *StepPreMountCommands) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPreMountCommands) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) device := state.Get("device").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_prepare_device.go b/builder/amazon/chroot/step_prepare_device.go index 18036f0a2..4724457e5 100644 --- a/builder/amazon/chroot/step_prepare_device.go +++ b/builder/amazon/chroot/step_prepare_device.go @@ -13,7 +13,7 @@ import ( type StepPrepareDevice struct { } -func (s *StepPrepareDevice) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPrepareDevice) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index c37892723..d73ea8b21 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -17,7 +17,7 @@ type StepRegisterAMI struct { EnableAMISriovNetSupport bool } -func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) snapshotId := state.Get("snapshot_id").(string) diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index 78c7a9a21..68a7bce2c 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -19,7 +19,7 @@ type StepSnapshot struct { snapshotId string } -func (s *StepSnapshot) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) volumeId := state.Get("volume_id").(string) diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index 3d9e4f1b6..9125453ea 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -19,7 +19,7 @@ type StepAMIRegionCopy struct { Name string } -func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAMIRegionCopy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index b0170f850..903aea91a 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -19,7 +19,7 @@ type StepCreateTags struct { Ctx interpolate.Context } -func (s *StepCreateTags) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index c8c18aca5..549987b6b 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -17,7 +17,7 @@ type StepDeregisterAMI struct { Regions []string } -func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDeregisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // Check for force deregister if !s.ForceDeregister { return multistep.ActionContinue diff --git a/builder/amazon/common/step_encrypted_ami.go b/builder/amazon/common/step_encrypted_ami.go index f47f1a19c..66174bea0 100644 --- a/builder/amazon/common/step_encrypted_ami.go +++ b/builder/amazon/common/step_encrypted_ami.go @@ -18,7 +18,7 @@ type StepCreateEncryptedAMICopy struct { AMIMappings []BlockDevice } -func (s *StepCreateEncryptedAMICopy) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateEncryptedAMICopy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) kmsKeyId := s.KeyID diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index 50a720ef7..28847003d 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -24,7 +24,7 @@ type StepGetPassword struct { Timeout time.Duration } -func (s *StepGetPassword) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGetPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) // Skip if we're not using winrm diff --git a/builder/amazon/common/step_key_pair.go b/builder/amazon/common/step_key_pair.go index cc01949c6..3558b1df2 100644 --- a/builder/amazon/common/step_key_pair.go +++ b/builder/amazon/common/step_key_pair.go @@ -22,7 +22,7 @@ type StepKeyPair struct { doCleanup bool } -func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index dc024d8bb..7ba1deb6f 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -21,7 +21,7 @@ type StepModifyAMIAttributes struct { Ctx interpolate.Context } -func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepModifyAMIAttributes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/common/step_modify_ebs_instance.go b/builder/amazon/common/step_modify_ebs_instance.go index 0f9da523f..4145bc669 100644 --- a/builder/amazon/common/step_modify_ebs_instance.go +++ b/builder/amazon/common/step_modify_ebs_instance.go @@ -14,7 +14,7 @@ type StepModifyEBSBackedInstance struct { EnableAMISriovNetSupport bool } -func (s *StepModifyEBSBackedInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepModifyEBSBackedInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/common/step_pre_validate.go b/builder/amazon/common/step_pre_validate.go index 1e4a2b2a5..57fca3fad 100644 --- a/builder/amazon/common/step_pre_validate.go +++ b/builder/amazon/common/step_pre_validate.go @@ -17,7 +17,7 @@ type StepPreValidate struct { ForceDeregister bool } -func (s *StepPreValidate) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPreValidate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.ForceDeregister { ui.Say("Force Deregister flag found, skipping prevalidating AMI Name") diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 9186c868c..a5acf0e25 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -36,7 +36,7 @@ type StepRunSourceInstance struct { instanceId string } -func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) var keyName string if name, ok := state.GetOk("keyPair"); ok { diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 9968ed962..6029ac617 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -42,7 +42,7 @@ type StepRunSpotInstance struct { spotRequest *ec2.SpotInstanceRequest } -func (s *StepRunSpotInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) var keyName string if name, ok := state.GetOk("keyPair"); ok { diff --git a/builder/amazon/common/step_security_group.go b/builder/amazon/common/step_security_group.go index a03f496e6..3d3ff8f35 100644 --- a/builder/amazon/common/step_security_group.go +++ b/builder/amazon/common/step_security_group.go @@ -23,7 +23,7 @@ type StepSecurityGroup struct { createdGroupId string } -func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/common/step_source_ami_info.go b/builder/amazon/common/step_source_ami_info.go index 16e49c546..bc3b9dd17 100644 --- a/builder/amazon/common/step_source_ami_info.go +++ b/builder/amazon/common/step_source_ami_info.go @@ -52,7 +52,7 @@ func mostRecentAmi(images []*ec2.Image) *ec2.Image { return sortedImages[len(sortedImages)-1] } -func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSourceAMIInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index 6f5be17ce..efef99b8a 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -15,7 +15,7 @@ type StepStopEBSBackedInstance struct { DisableStopInstance bool } -func (s *StepStopEBSBackedInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepStopEBSBackedInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) ui := state.Get("ui").(packer.Ui) diff --git a/builder/amazon/ebs/step_cleanup_volumes.go b/builder/amazon/ebs/step_cleanup_volumes.go index 2b4484f3b..158f970e0 100644 --- a/builder/amazon/ebs/step_cleanup_volumes.go +++ b/builder/amazon/ebs/step_cleanup_volumes.go @@ -17,7 +17,7 @@ type stepCleanupVolumes struct { BlockDevices common.BlockDevices } -func (s *stepCleanupVolumes) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCleanupVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // stepCleanupVolumes is for Cleanup only return multistep.ActionContinue } diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index 2729cc64f..1ee7319bd 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -13,7 +13,7 @@ type stepCreateAMI struct { image *ec2.Image } -func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index d5c7924db..28c01f52d 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -19,7 +19,7 @@ type StepRegisterAMI struct { image *ec2.Image } -func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) snapshotId := state.Get("snapshot_id").(string) diff --git a/builder/amazon/ebssurrogate/step_snapshot_new_root.go b/builder/amazon/ebssurrogate/step_snapshot_new_root.go index 3b46ca601..111f20268 100644 --- a/builder/amazon/ebssurrogate/step_snapshot_new_root.go +++ b/builder/amazon/ebssurrogate/step_snapshot_new_root.go @@ -20,7 +20,7 @@ type StepSnapshotNewRootVolume struct { snapshotId string } -func (s *StepSnapshotNewRootVolume) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSnapshotNewRootVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) ui := state.Get("ui").(packer.Ui) instance := state.Get("instance").(*ec2.Instance) diff --git a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go index d99636b57..42076dec2 100644 --- a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go +++ b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go @@ -15,7 +15,7 @@ type stepTagEBSVolumes struct { Ctx interpolate.Context } -func (s *stepTagEBSVolumes) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepTagEBSVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) sourceAMI := state.Get("source_image").(*ec2.Image) diff --git a/builder/amazon/instance/step_bundle_volume.go b/builder/amazon/instance/step_bundle_volume.go index dbce14109..61c2f5aad 100644 --- a/builder/amazon/instance/step_bundle_volume.go +++ b/builder/amazon/instance/step_bundle_volume.go @@ -23,7 +23,7 @@ type StepBundleVolume struct { Debug bool } -func (s *StepBundleVolume) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepBundleVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) config := state.Get("config").(*Config) instance := state.Get("instance").(*ec2.Instance) diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index 348e7b86f..9fb41d441 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -15,7 +15,7 @@ type StepRegisterAMI struct { EnableAMISriovNetSupport bool } -func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) manifestPath := state.Get("remote_manifest_path").(string) diff --git a/builder/amazon/instance/step_upload_bundle.go b/builder/amazon/instance/step_upload_bundle.go index 3a314527e..80ba9e88b 100644 --- a/builder/amazon/instance/step_upload_bundle.go +++ b/builder/amazon/instance/step_upload_bundle.go @@ -22,7 +22,7 @@ type StepUploadBundle struct { Debug bool } -func (s *StepUploadBundle) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUploadBundle) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) config := state.Get("config").(*Config) manifestName := state.Get("manifest_name").(string) diff --git a/builder/amazon/instance/step_upload_x509_cert.go b/builder/amazon/instance/step_upload_x509_cert.go index 44cd58099..3853a53c1 100644 --- a/builder/amazon/instance/step_upload_x509_cert.go +++ b/builder/amazon/instance/step_upload_x509_cert.go @@ -9,7 +9,7 @@ import ( type StepUploadX509Cert struct{} -func (s *StepUploadX509Cert) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUploadX509Cert) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/azure/arm/step_capture_image.go b/builder/azure/arm/step_capture_image.go index 944f75f3b..2da5bedc4 100644 --- a/builder/azure/arm/step_capture_image.go +++ b/builder/azure/arm/step_capture_image.go @@ -67,7 +67,7 @@ func (s *StepCaptureImage) captureImage(resourceGroupName string, computeName st return <-errChan } -func (s *StepCaptureImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCaptureImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Capturing image ...") var computeName = state.Get(constants.ArmComputeName).(string) diff --git a/builder/azure/arm/step_create_resource_group.go b/builder/azure/arm/step_create_resource_group.go index b9b7662df..787aad132 100644 --- a/builder/azure/arm/step_create_resource_group.go +++ b/builder/azure/arm/step_create_resource_group.go @@ -51,7 +51,7 @@ func (s *StepCreateResourceGroup) doesResourceGroupExist(resourceGroupName strin return exists.Response.StatusCode != 404, err } -func (s *StepCreateResourceGroup) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateResourceGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { var doubleResource, ok = state.GetOk(constants.ArmDoubleResourceGroupNameSet) if ok && doubleResource.(bool) { err := errors.New("You have filled in both temp_resource_group_name and build_resource_group_name. Please choose one.") diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index 59c644901..92e9f9757 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -50,7 +50,7 @@ func (s *StepDeleteOSDisk) deleteManagedDisk(resourceGroupName string, imageName return err } -func (s *StepDeleteOSDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDeleteOSDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Deleting the temporary OS disk ...") var osDisk = state.Get(constants.ArmOSDiskVhd).(string) diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index 300b8f9e0..a3bc2073b 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -117,7 +117,7 @@ func (s *StepDeleteResourceGroup) reportIfError(err error, resourceName string) } } -func (s *StepDeleteResourceGroup) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDeleteResourceGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Deleting resource group ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index d6c08f7ed..06baddb24 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -58,7 +58,7 @@ func (s *StepDeployTemplate) deployTemplate(resourceGroupName string, deployment return err } -func (s *StepDeployTemplate) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDeployTemplate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Deploying deployment template ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) diff --git a/builder/azure/arm/step_get_certificate.go b/builder/azure/arm/step_get_certificate.go index 80b623f38..df347e468 100644 --- a/builder/azure/arm/step_get_certificate.go +++ b/builder/azure/arm/step_get_certificate.go @@ -39,7 +39,7 @@ func (s *StepGetCertificate) getCertificateUrl(keyVaultName string, secretName s return *secret.ID, err } -func (s *StepGetCertificate) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGetCertificate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Getting the certificate's URL ...") var keyVaultName = state.Get(constants.ArmKeyVaultName).(string) diff --git a/builder/azure/arm/step_get_ip_address.go b/builder/azure/arm/step_get_ip_address.go index b6b96addf..f6ef7dc1b 100644 --- a/builder/azure/arm/step_get_ip_address.go +++ b/builder/azure/arm/step_get_ip_address.go @@ -76,7 +76,7 @@ func (s *StepGetIPAddress) getPublicIPInPrivateNetwork(resourceGroupName string, return s.getPublicIP(resourceGroupName, ipAddressName, interfaceName) } -func (s *StepGetIPAddress) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGetIPAddress) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Getting the VM's IP address ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) diff --git a/builder/azure/arm/step_get_os_disk.go b/builder/azure/arm/step_get_os_disk.go index 314fc8375..706f37a54 100644 --- a/builder/azure/arm/step_get_os_disk.go +++ b/builder/azure/arm/step_get_os_disk.go @@ -37,7 +37,7 @@ func (s *StepGetOSDisk) queryCompute(resourceGroupName string, computeName strin return vm, err } -func (s *StepGetOSDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGetOSDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Querying the machine's properties ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) diff --git a/builder/azure/arm/step_power_off_compute.go b/builder/azure/arm/step_power_off_compute.go index a1401faed..e44b13c97 100644 --- a/builder/azure/arm/step_power_off_compute.go +++ b/builder/azure/arm/step_power_off_compute.go @@ -37,7 +37,7 @@ func (s *StepPowerOffCompute) powerOffCompute(resourceGroupName string, computeN return err } -func (s *StepPowerOffCompute) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPowerOffCompute) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Powering off machine ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) diff --git a/builder/azure/arm/step_set_certificate.go b/builder/azure/arm/step_set_certificate.go index 34e308263..4729af0c0 100644 --- a/builder/azure/arm/step_set_certificate.go +++ b/builder/azure/arm/step_set_certificate.go @@ -22,7 +22,7 @@ func NewStepSetCertificate(config *Config, ui packer.Ui) *StepSetCertificate { return step } -func (s *StepSetCertificate) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSetCertificate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Setting the certificate's URL ...") var winRMCertificateUrl = state.Get(constants.ArmCertificateUrl).(string) diff --git a/builder/azure/arm/step_validate_template.go b/builder/azure/arm/step_validate_template.go index 3c7f98a8a..bdf92e652 100644 --- a/builder/azure/arm/step_validate_template.go +++ b/builder/azure/arm/step_validate_template.go @@ -43,7 +43,7 @@ func (s *StepValidateTemplate) validateTemplate(resourceGroupName string, deploy return err } -func (s *StepValidateTemplate) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepValidateTemplate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.say("Validating deployment template ...") var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) diff --git a/builder/azure/common/lin/step_create_cert.go b/builder/azure/common/lin/step_create_cert.go index 809bdd964..66dda1a3c 100644 --- a/builder/azure/common/lin/step_create_cert.go +++ b/builder/azure/common/lin/step_create_cert.go @@ -22,7 +22,7 @@ type StepCreateCert struct { TmpServiceName string } -func (s *StepCreateCert) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateCert) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating temporary certificate...") diff --git a/builder/azure/common/lin/step_generalize_os.go b/builder/azure/common/lin/step_generalize_os.go index bd55365a2..d7836d22c 100644 --- a/builder/azure/common/lin/step_generalize_os.go +++ b/builder/azure/common/lin/step_generalize_os.go @@ -12,7 +12,7 @@ type StepGeneralizeOS struct { Command string } -func (s *StepGeneralizeOS) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGeneralizeOS) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) comm := state.Get("communicator").(packer.Communicator) diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index ff80583e9..1e2e322b0 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -16,7 +16,7 @@ type stepSetupNetworking struct { publicPort int } -func (s *stepSetupNetworking) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSetupNetworking) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*cloudstack.CloudStackClient) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 578adb898..1ca0a4f70 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -27,7 +27,7 @@ type stepCreateInstance struct { } // Run executes the Packer build step that creates a CloudStack instance. -func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*cloudstack.CloudStackClient) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/cloudstack/step_create_security_group.go b/builder/cloudstack/step_create_security_group.go index 372df29f7..fb5f24a4a 100644 --- a/builder/cloudstack/step_create_security_group.go +++ b/builder/cloudstack/step_create_security_group.go @@ -13,7 +13,7 @@ type stepCreateSecurityGroup struct { tempSG string } -func (s *stepCreateSecurityGroup) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateSecurityGroup) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*cloudstack.CloudStackClient) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/cloudstack/step_create_template.go b/builder/cloudstack/step_create_template.go index 54345fb25..928e231d1 100644 --- a/builder/cloudstack/step_create_template.go +++ b/builder/cloudstack/step_create_template.go @@ -11,7 +11,7 @@ import ( type stepCreateTemplate struct{} -func (s *stepCreateTemplate) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateTemplate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*cloudstack.CloudStackClient) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/cloudstack/step_keypair.go b/builder/cloudstack/step_keypair.go index 8ecd2d1b5..7334da372 100644 --- a/builder/cloudstack/step_keypair.go +++ b/builder/cloudstack/step_keypair.go @@ -20,7 +20,7 @@ type stepKeypair struct { TemporaryKeyPairName string } -func (s *stepKeypair) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepKeypair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/cloudstack/step_prepare_config.go b/builder/cloudstack/step_prepare_config.go index 12c1c44fe..3c2944c7d 100644 --- a/builder/cloudstack/step_prepare_config.go +++ b/builder/cloudstack/step_prepare_config.go @@ -12,7 +12,7 @@ import ( type stepPrepareConfig struct{} -func (s *stepPrepareConfig) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepPrepareConfig) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*cloudstack.CloudStackClient) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/cloudstack/step_shutdown_instance.go b/builder/cloudstack/step_shutdown_instance.go index fce1fa8bc..10a4acbdd 100644 --- a/builder/cloudstack/step_shutdown_instance.go +++ b/builder/cloudstack/step_shutdown_instance.go @@ -10,7 +10,7 @@ import ( type stepShutdownInstance struct{} -func (s *stepShutdownInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepShutdownInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*cloudstack.CloudStackClient) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/digitalocean/step_create_droplet.go b/builder/digitalocean/step_create_droplet.go index d64224a0a..d9c8976bf 100644 --- a/builder/digitalocean/step_create_droplet.go +++ b/builder/digitalocean/step_create_droplet.go @@ -15,7 +15,7 @@ type stepCreateDroplet struct { dropletId int } -func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateDroplet) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) diff --git a/builder/digitalocean/step_create_ssh_key.go b/builder/digitalocean/step_create_ssh_key.go index cd8f68cc0..c03809ba2 100644 --- a/builder/digitalocean/step_create_ssh_key.go +++ b/builder/digitalocean/step_create_ssh_key.go @@ -25,7 +25,7 @@ type stepCreateSSHKey struct { keyId int } -func (s *stepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) ui := state.Get("ui").(packer.Ui) diff --git a/builder/digitalocean/step_droplet_info.go b/builder/digitalocean/step_droplet_info.go index 8cb0f6112..5c4439749 100644 --- a/builder/digitalocean/step_droplet_info.go +++ b/builder/digitalocean/step_droplet_info.go @@ -11,7 +11,7 @@ import ( type stepDropletInfo struct{} -func (s *stepDropletInfo) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepDropletInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) diff --git a/builder/digitalocean/step_power_off.go b/builder/digitalocean/step_power_off.go index a5ed96199..3b7e8bdd0 100644 --- a/builder/digitalocean/step_power_off.go +++ b/builder/digitalocean/step_power_off.go @@ -12,7 +12,7 @@ import ( type stepPowerOff struct{} -func (s *stepPowerOff) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepPowerOff) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) c := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/digitalocean/step_shutdown.go b/builder/digitalocean/step_shutdown.go index d45f03628..98d6c0c75 100644 --- a/builder/digitalocean/step_shutdown.go +++ b/builder/digitalocean/step_shutdown.go @@ -13,7 +13,7 @@ import ( type stepShutdown struct{} -func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) c := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/digitalocean/step_snapshot.go b/builder/digitalocean/step_snapshot.go index 46eb75a0e..ec978c8bc 100644 --- a/builder/digitalocean/step_snapshot.go +++ b/builder/digitalocean/step_snapshot.go @@ -14,7 +14,7 @@ import ( type stepSnapshot struct{} -func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) diff --git a/builder/docker/step_commit.go b/builder/docker/step_commit.go index 167f68621..d32f5f888 100644 --- a/builder/docker/step_commit.go +++ b/builder/docker/step_commit.go @@ -11,7 +11,7 @@ type StepCommit struct { imageId string } -func (s *StepCommit) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCommit) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) containerId := state.Get("container_id").(string) config := state.Get("config").(*Config) diff --git a/builder/docker/step_connect_docker.go b/builder/docker/step_connect_docker.go index ed64091e7..2e3a3270a 100644 --- a/builder/docker/step_connect_docker.go +++ b/builder/docker/step_connect_docker.go @@ -11,7 +11,7 @@ import ( type StepConnectDocker struct{} -func (s *StepConnectDocker) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConnectDocker) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) containerId := state.Get("container_id").(string) driver := state.Get("driver").(Driver) diff --git a/builder/docker/step_export.go b/builder/docker/step_export.go index 7af86de0e..b11319f81 100644 --- a/builder/docker/step_export.go +++ b/builder/docker/step_export.go @@ -12,7 +12,7 @@ import ( // StepExport exports the container to a flat tar file. type StepExport struct{} -func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepExport) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) diff --git a/builder/docker/step_pull.go b/builder/docker/step_pull.go index 8704de3d1..946029943 100644 --- a/builder/docker/step_pull.go +++ b/builder/docker/step_pull.go @@ -10,7 +10,7 @@ import ( type StepPull struct{} -func (s *StepPull) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPull) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/docker/step_run.go b/builder/docker/step_run.go index 2ac471562..c5b8fc525 100644 --- a/builder/docker/step_run.go +++ b/builder/docker/step_run.go @@ -10,7 +10,7 @@ type StepRun struct { containerId string } -func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) tempDir := state.Get("temp_dir").(string) diff --git a/builder/docker/step_run_test.go b/builder/docker/step_run_test.go index e301a11c5..66bd02baf 100644 --- a/builder/docker/step_run_test.go +++ b/builder/docker/step_run_test.go @@ -18,7 +18,7 @@ func TestStepRun_impl(t *testing.T) { var _ multistep.Step = new(StepRun) } -func TestStepRun(t *testing.T) { +func TestStepRun(_ context.Context, t *testing.T) { state := testStepRunState(t) step := new(StepRun) defer step.Cleanup(state) diff --git a/builder/docker/step_temp_dir.go b/builder/docker/step_temp_dir.go index e9af747e7..d3c1502ff 100644 --- a/builder/docker/step_temp_dir.go +++ b/builder/docker/step_temp_dir.go @@ -17,7 +17,7 @@ type StepTempDir struct { tempDir string } -func (s *StepTempDir) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTempDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating a temporary directory for sharing data...") diff --git a/builder/googlecompute/step_check_existing_image.go b/builder/googlecompute/step_check_existing_image.go index b2da36973..92a79f3fa 100644 --- a/builder/googlecompute/step_check_existing_image.go +++ b/builder/googlecompute/step_check_existing_image.go @@ -12,7 +12,7 @@ import ( type StepCheckExistingImage int // Run executes the Packer build step that checks if the image already exists. -func (s *StepCheckExistingImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCheckExistingImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { c := state.Get("config").(*Config) d := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/googlecompute/step_create_image.go b/builder/googlecompute/step_create_image.go index 7948c0188..16434f6c7 100644 --- a/builder/googlecompute/step_create_image.go +++ b/builder/googlecompute/step_create_image.go @@ -17,7 +17,7 @@ type StepCreateImage int // // The image is created from the persistent disk used by the instance. The // instance must be deleted and the disk retained before doing this step. -func (s *StepCreateImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index 054d169ae..1a713f123 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -72,7 +72,7 @@ func getImage(c *Config, d Driver) (*Image, error) { } // Run executes the Packer build step that creates a GCE instance. -func (s *StepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { c := state.Get("config").(*Config) d := state.Get("driver").(Driver) sshPublicKey := state.Get("ssh_public_key").(string) diff --git a/builder/googlecompute/step_create_ssh_key.go b/builder/googlecompute/step_create_ssh_key.go index 9c0ad5513..f121e3dae 100644 --- a/builder/googlecompute/step_create_ssh_key.go +++ b/builder/googlecompute/step_create_ssh_key.go @@ -24,7 +24,7 @@ type StepCreateSSHKey struct { // Run executes the Packer build step that generates SSH key pairs. // The key pairs are added to the multistep state as "ssh_private_key" and // "ssh_public_key". -func (s *StepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/googlecompute/step_create_windows_password.go b/builder/googlecompute/step_create_windows_password.go index 3adeac11d..b7d09e10d 100644 --- a/builder/googlecompute/step_create_windows_password.go +++ b/builder/googlecompute/step_create_windows_password.go @@ -23,7 +23,7 @@ type StepCreateWindowsPassword struct { } // Run executes the Packer build step that sets the windows password on a Windows GCE instance. -func (s *StepCreateWindowsPassword) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) d := state.Get("driver").(Driver) c := state.Get("config").(*Config) diff --git a/builder/googlecompute/step_instance_info.go b/builder/googlecompute/step_instance_info.go index 8706489c9..5604b3e9b 100644 --- a/builder/googlecompute/step_instance_info.go +++ b/builder/googlecompute/step_instance_info.go @@ -16,7 +16,7 @@ type StepInstanceInfo struct { // Run executes the Packer build step that gathers GCE instance info. // This adds "instance_ip" to the multistep state. -func (s *StepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepInstanceInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/googlecompute/step_teardown_instance.go b/builder/googlecompute/step_teardown_instance.go index 317507d82..e40e2fc7b 100644 --- a/builder/googlecompute/step_teardown_instance.go +++ b/builder/googlecompute/step_teardown_instance.go @@ -16,7 +16,7 @@ type StepTeardownInstance struct { } // Run executes the Packer build step that tears down a GCE instance. -func (s *StepTeardownInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTeardownInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/googlecompute/step_wait_startup_script.go b/builder/googlecompute/step_wait_startup_script.go index 94b1b07ce..9770d7cb3 100644 --- a/builder/googlecompute/step_wait_startup_script.go +++ b/builder/googlecompute/step_wait_startup_script.go @@ -13,7 +13,7 @@ type StepWaitStartupScript int // Run reads the instance metadata and looks for the log entry // indicating the startup script finished. -func (s *StepWaitStartupScript) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepWaitStartupScript) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index 733b6df1a..cda0c5da5 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -29,7 +29,7 @@ type StepCloneVM struct { EnableVirtualizationExtensions bool } -func (s *StepCloneVM) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCloneVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) ui.Say("Cloning virtual machine...") diff --git a/builder/hyperv/common/step_configure_ip.go b/builder/hyperv/common/step_configure_ip.go index 8670f5a41..d9ca74344 100644 --- a/builder/hyperv/common/step_configure_ip.go +++ b/builder/hyperv/common/step_configure_ip.go @@ -13,7 +13,7 @@ import ( type StepConfigureIp struct { } -func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureIp) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_configure_vlan.go b/builder/hyperv/common/step_configure_vlan.go index acfe26422..ea26af22e 100644 --- a/builder/hyperv/common/step_configure_vlan.go +++ b/builder/hyperv/common/step_configure_vlan.go @@ -12,7 +12,7 @@ type StepConfigureVlan struct { SwitchVlanId string } -func (s *StepConfigureVlan) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureVlan) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_create_external_switch.go b/builder/hyperv/common/step_create_external_switch.go index 1bbfd40b7..1e0ea6976 100644 --- a/builder/hyperv/common/step_create_external_switch.go +++ b/builder/hyperv/common/step_create_external_switch.go @@ -17,7 +17,7 @@ type StepCreateExternalSwitch struct { oldSwitchName string } -func (s *StepCreateExternalSwitch) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateExternalSwitch) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_create_switch.go b/builder/hyperv/common/step_create_switch.go index 7d6db4c3d..0b1df3342 100644 --- a/builder/hyperv/common/step_create_switch.go +++ b/builder/hyperv/common/step_create_switch.go @@ -31,7 +31,7 @@ type StepCreateSwitch struct { createdSwitch bool } -func (s *StepCreateSwitch) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateSwitch) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_create_tempdir.go b/builder/hyperv/common/step_create_tempdir.go index 425235258..a9829608c 100644 --- a/builder/hyperv/common/step_create_tempdir.go +++ b/builder/hyperv/common/step_create_tempdir.go @@ -18,7 +18,7 @@ type StepCreateTempDir struct { vhdDirPath string } -func (s *StepCreateTempDir) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateTempDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating temporary directory...") diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 6f850a044..1e28889c7 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -30,7 +30,7 @@ type StepCreateVM struct { DifferencingDisk bool } -func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) ui.Say("Creating virtual machine...") diff --git a/builder/hyperv/common/step_disable_vlan.go b/builder/hyperv/common/step_disable_vlan.go index 6c6a034da..acd0d323d 100644 --- a/builder/hyperv/common/step_disable_vlan.go +++ b/builder/hyperv/common/step_disable_vlan.go @@ -9,7 +9,7 @@ import ( type StepDisableVlan struct { } -func (s *StepDisableVlan) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDisableVlan) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_enable_integration_service.go b/builder/hyperv/common/step_enable_integration_service.go index 98e8eedb2..ddb74c41d 100644 --- a/builder/hyperv/common/step_enable_integration_service.go +++ b/builder/hyperv/common/step_enable_integration_service.go @@ -10,7 +10,7 @@ type StepEnableIntegrationService struct { name string } -func (s *StepEnableIntegrationService) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepEnableIntegrationService) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) ui.Say("Enabling Integration Service...") diff --git a/builder/hyperv/common/step_export_vm.go b/builder/hyperv/common/step_export_vm.go index 3c33475c1..f5ff4cf93 100644 --- a/builder/hyperv/common/step_export_vm.go +++ b/builder/hyperv/common/step_export_vm.go @@ -19,7 +19,7 @@ type StepExportVm struct { SkipCompaction bool } -func (s *StepExportVm) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepExportVm) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index 97d3ff0e0..8957fe6c2 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -16,7 +16,7 @@ type StepMountDvdDrive struct { Generation uint } -func (s *StepMountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepMountDvdDrive) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_mount_floppydrive.go b/builder/hyperv/common/step_mount_floppydrive.go index 749cf5ae1..ecf9b0194 100644 --- a/builder/hyperv/common/step_mount_floppydrive.go +++ b/builder/hyperv/common/step_mount_floppydrive.go @@ -23,7 +23,7 @@ type StepMountFloppydrive struct { floppyPath string } -func (s *StepMountFloppydrive) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepMountFloppydrive) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if s.Generation > 1 { return multistep.ActionContinue } diff --git a/builder/hyperv/common/step_mount_guest_additions.go b/builder/hyperv/common/step_mount_guest_additions.go index 1cf549735..f20e070d3 100644 --- a/builder/hyperv/common/step_mount_guest_additions.go +++ b/builder/hyperv/common/step_mount_guest_additions.go @@ -13,7 +13,7 @@ type StepMountGuestAdditions struct { Generation uint } -func (s *StepMountGuestAdditions) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepMountGuestAdditions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.GuestAdditionsMode != "attach" { diff --git a/builder/hyperv/common/step_mount_secondary_dvd_images.go b/builder/hyperv/common/step_mount_secondary_dvd_images.go index c5be1a03b..9b29a84a0 100644 --- a/builder/hyperv/common/step_mount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_mount_secondary_dvd_images.go @@ -18,7 +18,7 @@ type DvdControllerProperties struct { Existing bool } -func (s *StepMountSecondaryDvdImages) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepMountSecondaryDvdImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) ui.Say("Mounting secondary DVD images...") diff --git a/builder/hyperv/common/step_output_dir.go b/builder/hyperv/common/step_output_dir.go index acb905e9a..cad96b98e 100644 --- a/builder/hyperv/common/step_output_dir.go +++ b/builder/hyperv/common/step_output_dir.go @@ -21,7 +21,7 @@ type StepOutputDir struct { cleanup bool } -func (s *StepOutputDir) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if _, err := os.Stat(s.Path); err == nil { diff --git a/builder/hyperv/common/step_polling_installation.go b/builder/hyperv/common/step_polling_installation.go index 114684f59..092c01b17 100644 --- a/builder/hyperv/common/step_polling_installation.go +++ b/builder/hyperv/common/step_polling_installation.go @@ -17,7 +17,7 @@ const port string = "13000" type StepPollingInstalation struct { } -func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPollingInstalation) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) errorMsg := "Error polling VM: %s" diff --git a/builder/hyperv/common/step_reboot_vm.go b/builder/hyperv/common/step_reboot_vm.go index 3708f97cb..850c6aac9 100644 --- a/builder/hyperv/common/step_reboot_vm.go +++ b/builder/hyperv/common/step_reboot_vm.go @@ -10,7 +10,7 @@ import ( type StepRebootVm struct { } -func (s *StepRebootVm) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRebootVm) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_run.go b/builder/hyperv/common/step_run.go index 168f29520..ead739667 100644 --- a/builder/hyperv/common/step_run.go +++ b/builder/hyperv/common/step_run.go @@ -13,7 +13,7 @@ type StepRun struct { vmName string } -func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/hyperv/common/step_shutdown.go b/builder/hyperv/common/step_shutdown.go index 42e408799..ddced9619 100644 --- a/builder/hyperv/common/step_shutdown.go +++ b/builder/hyperv/common/step_shutdown.go @@ -28,7 +28,7 @@ type StepShutdown struct { Timeout time.Duration } -func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) driver := state.Get("driver").(Driver) diff --git a/builder/hyperv/common/step_sleep.go b/builder/hyperv/common/step_sleep.go index 19b4c2c1f..fbf671cdf 100644 --- a/builder/hyperv/common/step_sleep.go +++ b/builder/hyperv/common/step_sleep.go @@ -12,7 +12,7 @@ type StepSleep struct { ActionName string } -func (s *StepSleep) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSleep) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if len(s.ActionName) > 0 { diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index d38c53166..515c30907 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -26,7 +26,7 @@ type StepTypeBootCommand struct { Ctx interpolate.Context } -func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) driver := state.Get("driver").(Driver) diff --git a/builder/hyperv/common/step_unmount_dvddrive.go b/builder/hyperv/common/step_unmount_dvddrive.go index 810e055ce..cb62bc131 100644 --- a/builder/hyperv/common/step_unmount_dvddrive.go +++ b/builder/hyperv/common/step_unmount_dvddrive.go @@ -9,7 +9,7 @@ import ( type StepUnmountDvdDrive struct { } -func (s *StepUnmountDvdDrive) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUnmountDvdDrive) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) vmName := state.Get("vmName").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_unmount_floppydrive.go b/builder/hyperv/common/step_unmount_floppydrive.go index be71861c2..07dff3b70 100644 --- a/builder/hyperv/common/step_unmount_floppydrive.go +++ b/builder/hyperv/common/step_unmount_floppydrive.go @@ -10,7 +10,7 @@ type StepUnmountFloppyDrive struct { Generation uint } -func (s *StepUnmountFloppyDrive) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUnmountFloppyDrive) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_unmount_guest_additions.go b/builder/hyperv/common/step_unmount_guest_additions.go index 44b9b5acb..112c9c825 100644 --- a/builder/hyperv/common/step_unmount_guest_additions.go +++ b/builder/hyperv/common/step_unmount_guest_additions.go @@ -9,7 +9,7 @@ import ( type StepUnmountGuestAdditions struct { } -func (s *StepUnmountGuestAdditions) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUnmountGuestAdditions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) vmName := state.Get("vmName").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/hyperv/common/step_unmount_secondary_dvd_images.go b/builder/hyperv/common/step_unmount_secondary_dvd_images.go index 9e3ccbfc9..3de0f7ac6 100644 --- a/builder/hyperv/common/step_unmount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_unmount_secondary_dvd_images.go @@ -9,7 +9,7 @@ import ( type StepUnmountSecondaryDvdImages struct { } -func (s *StepUnmountSecondaryDvdImages) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUnmountSecondaryDvdImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/hyperv/common/step_wait_for_install_to_complete.go b/builder/hyperv/common/step_wait_for_install_to_complete.go index a147d6963..ee7d11beb 100644 --- a/builder/hyperv/common/step_wait_for_install_to_complete.go +++ b/builder/hyperv/common/step_wait_for_install_to_complete.go @@ -14,7 +14,7 @@ const ( type StepWaitForPowerOff struct { } -func (s *StepWaitForPowerOff) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepWaitForPowerOff) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) @@ -48,7 +48,7 @@ type StepWaitForInstallToComplete struct { ActionName string } -func (s *StepWaitForInstallToComplete) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepWaitForInstallToComplete) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/lxc/step_export.go b/builder/lxc/step_export.go index 632891a36..2bafdeb41 100644 --- a/builder/lxc/step_export.go +++ b/builder/lxc/step_export.go @@ -18,7 +18,7 @@ import ( type stepExport struct{} -func (s *stepExport) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepExport) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index 4d46a0f5c..9efb7bc87 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -16,7 +16,7 @@ import ( type stepLxcCreate struct{} -func (s *stepLxcCreate) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepLxcCreate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/lxc/step_prepare_output_dir.go b/builder/lxc/step_prepare_output_dir.go index ed79ac75e..1dd082580 100644 --- a/builder/lxc/step_prepare_output_dir.go +++ b/builder/lxc/step_prepare_output_dir.go @@ -13,7 +13,7 @@ import ( type stepPrepareOutputDir struct{} -func (stepPrepareOutputDir) Run(state multistep.StateBag) multistep.StepAction { +func (stepPrepareOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/lxc/step_provision.go b/builder/lxc/step_provision.go index c6d7f305e..937435d85 100644 --- a/builder/lxc/step_provision.go +++ b/builder/lxc/step_provision.go @@ -9,7 +9,7 @@ import ( // StepProvision provisions the instance within a chroot. type StepProvision struct{} -func (s *StepProvision) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { hook := state.Get("hook").(packer.Hook) config := state.Get("config").(*Config) mountPath := state.Get("mount_path").(string) diff --git a/builder/lxc/step_wait_init.go b/builder/lxc/step_wait_init.go index 1c850a90b..19383fb62 100644 --- a/builder/lxc/step_wait_init.go +++ b/builder/lxc/step_wait_init.go @@ -17,7 +17,7 @@ type StepWaitInit struct { WaitTimeout time.Duration } -func (s *StepWaitInit) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepWaitInit) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) var err error diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index 491a880a9..f1a6f6b45 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -9,7 +9,7 @@ import ( type stepLxdLaunch struct{} -func (s *stepLxdLaunch) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepLxdLaunch) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/lxd/step_provision.go b/builder/lxd/step_provision.go index 6bd7d617c..dedd1a2ae 100644 --- a/builder/lxd/step_provision.go +++ b/builder/lxd/step_provision.go @@ -9,7 +9,7 @@ import ( // StepProvision provisions the container type StepProvision struct{} -func (s *StepProvision) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { hook := state.Get("hook").(packer.Hook) config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/lxd/step_publish.go b/builder/lxd/step_publish.go index 280dfe1cf..4a6c206fe 100644 --- a/builder/lxd/step_publish.go +++ b/builder/lxd/step_publish.go @@ -9,7 +9,7 @@ import ( type stepPublish struct{} -func (s *stepPublish) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepPublish) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/oneandone/step_create_server.go b/builder/oneandone/step_create_server.go index 505a80242..8aa05fb48 100644 --- a/builder/oneandone/step_create_server.go +++ b/builder/oneandone/step_create_server.go @@ -14,7 +14,7 @@ import ( type stepCreateServer struct{} -func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) diff --git a/builder/oneandone/step_create_sshkey.go b/builder/oneandone/step_create_sshkey.go index e365a1362..9a1a58528 100644 --- a/builder/oneandone/step_create_sshkey.go +++ b/builder/oneandone/step_create_sshkey.go @@ -14,7 +14,7 @@ type StepCreateSSHKey struct { DebugKeyPath string } -func (s *StepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) diff --git a/builder/oneandone/step_take_snapshot.go b/builder/oneandone/step_take_snapshot.go index 2e6192d13..cedfb604a 100644 --- a/builder/oneandone/step_take_snapshot.go +++ b/builder/oneandone/step_take_snapshot.go @@ -8,7 +8,7 @@ import ( type stepTakeSnapshot struct{} -func (s *stepTakeSnapshot) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepTakeSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) diff --git a/builder/openstack/step_add_image_members.go b/builder/openstack/step_add_image_members.go index 3160a0e46..eda4122ce 100644 --- a/builder/openstack/step_add_image_members.go +++ b/builder/openstack/step_add_image_members.go @@ -10,7 +10,7 @@ import ( type stepAddImageMembers struct{} -func (s *stepAddImageMembers) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepAddImageMembers) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { imageId := state.Get("image").(string) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index 2de35b8ee..15f214d17 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -16,7 +16,7 @@ type StepAllocateIp struct { ReuseIps bool } -func (s *StepAllocateIp) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAllocateIp) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) server := state.Get("server").(*servers.Server) diff --git a/builder/openstack/step_create_image.go b/builder/openstack/step_create_image.go index 35fbd371a..777a3cb6a 100644 --- a/builder/openstack/step_create_image.go +++ b/builder/openstack/step_create_image.go @@ -14,7 +14,7 @@ import ( type stepCreateImage struct{} -func (s *stepCreateImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) server := state.Get("server").(*servers.Server) ui := state.Get("ui").(packer.Ui) diff --git a/builder/openstack/step_get_password.go b/builder/openstack/step_get_password.go index 9a5d8c95d..95f52e194 100644 --- a/builder/openstack/step_get_password.go +++ b/builder/openstack/step_get_password.go @@ -20,7 +20,7 @@ type StepGetPassword struct { Comm *communicator.Config } -func (s *StepGetPassword) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGetPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/openstack/step_key_pair.go b/builder/openstack/step_key_pair.go index b6b072216..fb46c1392 100644 --- a/builder/openstack/step_key_pair.go +++ b/builder/openstack/step_key_pair.go @@ -25,7 +25,7 @@ type StepKeyPair struct { doCleanup bool } -func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/openstack/step_load_extensions.go b/builder/openstack/step_load_extensions.go index a7feec875..a5ffe8145 100644 --- a/builder/openstack/step_load_extensions.go +++ b/builder/openstack/step_load_extensions.go @@ -15,7 +15,7 @@ import ( // the flavor by name. type StepLoadExtensions struct{} -func (s *StepLoadExtensions) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepLoadExtensions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/openstack/step_load_flavor.go b/builder/openstack/step_load_flavor.go index ddc456681..00f1b7092 100644 --- a/builder/openstack/step_load_flavor.go +++ b/builder/openstack/step_load_flavor.go @@ -16,7 +16,7 @@ type StepLoadFlavor struct { Flavor string } -func (s *StepLoadFlavor) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepLoadFlavor) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 8b29357bb..ebbc45773 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -25,7 +25,7 @@ type StepRunSourceServer struct { server *servers.Server } -func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) flavor := state.Get("flavor_id").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/openstack/step_stop_server.go b/builder/openstack/step_stop_server.go index 48d1eb4d7..bc651b7ce 100644 --- a/builder/openstack/step_stop_server.go +++ b/builder/openstack/step_stop_server.go @@ -11,7 +11,7 @@ import ( type StepStopServer struct{} -func (s *StepStopServer) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepStopServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) extensions := state.Get("extensions").(map[string]struct{}) diff --git a/builder/openstack/step_update_image_visibility.go b/builder/openstack/step_update_image_visibility.go index d003f2894..bd814638b 100644 --- a/builder/openstack/step_update_image_visibility.go +++ b/builder/openstack/step_update_image_visibility.go @@ -10,7 +10,7 @@ import ( type stepUpdateImageVisibility struct{} -func (s *stepUpdateImageVisibility) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepUpdateImageVisibility) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { imageId := state.Get("image").(string) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) diff --git a/builder/openstack/step_wait_for_rackconnect.go b/builder/openstack/step_wait_for_rackconnect.go index 1b17a9d27..f214e0894 100644 --- a/builder/openstack/step_wait_for_rackconnect.go +++ b/builder/openstack/step_wait_for_rackconnect.go @@ -13,7 +13,7 @@ type StepWaitForRackConnect struct { Wait bool } -func (s *StepWaitForRackConnect) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepWaitForRackConnect) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if !s.Wait { return multistep.ActionContinue } diff --git a/builder/oracle/oci/step_create_instance.go b/builder/oracle/oci/step_create_instance.go index ad18a7e81..cb1ce6642 100644 --- a/builder/oracle/oci/step_create_instance.go +++ b/builder/oracle/oci/step_create_instance.go @@ -9,7 +9,7 @@ import ( type stepCreateInstance struct{} -func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(Driver) ui = state.Get("ui").(packer.Ui) diff --git a/builder/oracle/oci/step_image.go b/builder/oracle/oci/step_image.go index b7ce54057..46c7ed8ba 100644 --- a/builder/oracle/oci/step_image.go +++ b/builder/oracle/oci/step_image.go @@ -9,7 +9,7 @@ import ( type stepImage struct{} -func (s *stepImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(Driver) ui = state.Get("ui").(packer.Ui) diff --git a/builder/oracle/oci/step_instance_info.go b/builder/oracle/oci/step_instance_info.go index df70434b0..9b79529cc 100644 --- a/builder/oracle/oci/step_instance_info.go +++ b/builder/oracle/oci/step_instance_info.go @@ -9,7 +9,7 @@ import ( type stepInstanceInfo struct{} -func (s *stepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepInstanceInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { var ( driver = state.Get("driver").(Driver) ui = state.Get("ui").(packer.Ui) diff --git a/builder/oracle/oci/step_ssh_key_pair.go b/builder/oracle/oci/step_ssh_key_pair.go index b7a89ae63..c9e80e54b 100644 --- a/builder/oracle/oci/step_ssh_key_pair.go +++ b/builder/oracle/oci/step_ssh_key_pair.go @@ -21,7 +21,7 @@ type stepKeyPair struct { PrivateKeyFile string } -func (s *stepKeyPair) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/parallels/common/step_attach_floppy.go b/builder/parallels/common/step_attach_floppy.go index ec8a0663d..bd8116597 100644 --- a/builder/parallels/common/step_attach_floppy.go +++ b/builder/parallels/common/step_attach_floppy.go @@ -22,7 +22,7 @@ type StepAttachFloppy struct { // Run adds a virtual FDD device to the VM and attaches the image. // If the image is not specified, then this step will be skipped. -func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAttachFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // Determine if we even have a floppy disk to attach var floppyPath string if floppyPathRaw, ok := state.GetOk("floppy_path"); ok { diff --git a/builder/parallels/common/step_attach_parallels_tools.go b/builder/parallels/common/step_attach_parallels_tools.go index 3d7534960..645cec0d7 100644 --- a/builder/parallels/common/step_attach_parallels_tools.go +++ b/builder/parallels/common/step_attach_parallels_tools.go @@ -25,7 +25,7 @@ type StepAttachParallelsTools struct { // Run adds a virtual CD-ROM device to the VM and attaches Parallels Tools ISO image. // If ISO image is not specified, then this step will be skipped. -func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAttachParallelsTools) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/parallels/common/step_compact_disk.go b/builder/parallels/common/step_compact_disk.go index a79cf9f7b..90f05b7f9 100644 --- a/builder/parallels/common/step_compact_disk.go +++ b/builder/parallels/common/step_compact_disk.go @@ -22,7 +22,7 @@ type StepCompactDisk struct { } // Run runs the compaction of the virtual disk attached to the VM. -func (s *StepCompactDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCompactDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) vmName := state.Get("vmName").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/common/step_output_dir.go b/builder/parallels/common/step_output_dir.go index a3cb8db5a..c94ab3928 100644 --- a/builder/parallels/common/step_output_dir.go +++ b/builder/parallels/common/step_output_dir.go @@ -21,7 +21,7 @@ type StepOutputDir struct { } // Run sets up the output directory. -func (s *StepOutputDir) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if _, err := os.Stat(s.Path); err == nil && s.Force { diff --git a/builder/parallels/common/step_prepare_parallels_tools.go b/builder/parallels/common/step_prepare_parallels_tools.go index 174274b3d..c64fd395b 100644 --- a/builder/parallels/common/step_prepare_parallels_tools.go +++ b/builder/parallels/common/step_prepare_parallels_tools.go @@ -21,7 +21,7 @@ type StepPrepareParallelsTools struct { } // Run sets the value of "parallels_tools_path". -func (s *StepPrepareParallelsTools) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPrepareParallelsTools) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) if s.ParallelsToolsMode == ParallelsToolsModeDisable { diff --git a/builder/parallels/common/step_prlctl.go b/builder/parallels/common/step_prlctl.go index b93b396f0..eea179a70 100644 --- a/builder/parallels/common/step_prlctl.go +++ b/builder/parallels/common/step_prlctl.go @@ -28,7 +28,7 @@ type StepPrlctl struct { } // Run executes `prlctl` commands. -func (s *StepPrlctl) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepPrlctl) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/parallels/common/step_run.go b/builder/parallels/common/step_run.go index 38ca6269b..b37e536d5 100644 --- a/builder/parallels/common/step_run.go +++ b/builder/parallels/common/step_run.go @@ -23,7 +23,7 @@ type StepRun struct { } // Run starts the VM. -func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/parallels/common/step_shutdown.go b/builder/parallels/common/step_shutdown.go index 0eaaff454..10a4c5a3f 100644 --- a/builder/parallels/common/step_shutdown.go +++ b/builder/parallels/common/step_shutdown.go @@ -28,7 +28,7 @@ type StepShutdown struct { } // Run shuts down the VM. -func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index 454b726db..bd6adbfd8 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -39,7 +39,7 @@ type StepTypeBootCommand struct { } // Run types the boot command by sending key scancodes into the VM. -func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { debug := state.Get("debug").(bool) httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/common/step_upload_parallels_tools.go b/builder/parallels/common/step_upload_parallels_tools.go index f40a601b6..86bd5171b 100644 --- a/builder/parallels/common/step_upload_parallels_tools.go +++ b/builder/parallels/common/step_upload_parallels_tools.go @@ -37,7 +37,7 @@ type StepUploadParallelsTools struct { } // Run uploads the Parallels Tools ISO to the VM. -func (s *StepUploadParallelsTools) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUploadParallelsTools) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/common/step_upload_version.go b/builder/parallels/common/step_upload_version.go index 871f98400..982f38f9f 100644 --- a/builder/parallels/common/step_upload_version.go +++ b/builder/parallels/common/step_upload_version.go @@ -21,7 +21,7 @@ type StepUploadVersion struct { } // Run uploads a file containing the version of Parallels Desktop. -func (s *StepUploadVersion) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUploadVersion) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/iso/step_attach_iso.go b/builder/parallels/iso/step_attach_iso.go index 2ce5c7387..bfb7bacf9 100644 --- a/builder/parallels/iso/step_attach_iso.go +++ b/builder/parallels/iso/step_attach_iso.go @@ -21,7 +21,7 @@ import ( // attachedIso bool type stepAttachISO struct{} -func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepAttachISO) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(parallelscommon.Driver) isoPath := state.Get("iso_path").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/iso/step_create_disk.go b/builder/parallels/iso/step_create_disk.go index e7814507e..d98f8c5b4 100644 --- a/builder/parallels/iso/step_create_disk.go +++ b/builder/parallels/iso/step_create_disk.go @@ -13,7 +13,7 @@ import ( // hard drive for the virtual machine. type stepCreateDisk struct{} -func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(parallelscommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/parallels/iso/step_create_vm.go b/builder/parallels/iso/step_create_vm.go index 0349931fa..255bafaaa 100644 --- a/builder/parallels/iso/step_create_vm.go +++ b/builder/parallels/iso/step_create_vm.go @@ -16,7 +16,7 @@ type stepCreateVM struct { vmName string } -func (s *stepCreateVM) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(parallelscommon.Driver) diff --git a/builder/parallels/iso/step_set_boot_order.go b/builder/parallels/iso/step_set_boot_order.go index 5b6837919..5b44d98af 100644 --- a/builder/parallels/iso/step_set_boot_order.go +++ b/builder/parallels/iso/step_set_boot_order.go @@ -18,7 +18,7 @@ import ( // Produces: type stepSetBootOrder struct{} -func (s *stepSetBootOrder) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSetBootOrder) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(parallelscommon.Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/parallels/pvm/step_import.go b/builder/parallels/pvm/step_import.go index d2b49f136..c8b97dd54 100644 --- a/builder/parallels/pvm/step_import.go +++ b/builder/parallels/pvm/step_import.go @@ -15,7 +15,7 @@ type StepImport struct { vmName string } -func (s *StepImport) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepImport) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(parallelscommon.Driver) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(*Config) diff --git a/builder/profitbricks/step_create_server.go b/builder/profitbricks/step_create_server.go index 3d2145e27..926864118 100644 --- a/builder/profitbricks/step_create_server.go +++ b/builder/profitbricks/step_create_server.go @@ -15,7 +15,7 @@ import ( type stepCreateServer struct{} -func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) diff --git a/builder/profitbricks/step_create_ssh_key.go b/builder/profitbricks/step_create_ssh_key.go index 26343d8a1..4c1a75d18 100644 --- a/builder/profitbricks/step_create_ssh_key.go +++ b/builder/profitbricks/step_create_ssh_key.go @@ -14,7 +14,7 @@ type StepCreateSSHKey struct { DebugKeyPath string } -func (s *StepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) diff --git a/builder/profitbricks/step_take_snapshot.go b/builder/profitbricks/step_take_snapshot.go index 31e22a379..8cbc208b8 100644 --- a/builder/profitbricks/step_take_snapshot.go +++ b/builder/profitbricks/step_take_snapshot.go @@ -11,7 +11,7 @@ import ( type stepTakeSnapshot struct{} -func (s *stepTakeSnapshot) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepTakeSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(*Config) diff --git a/builder/qemu/step_boot_wait.go b/builder/qemu/step_boot_wait.go index 71d166689..fe7025b84 100644 --- a/builder/qemu/step_boot_wait.go +++ b/builder/qemu/step_boot_wait.go @@ -10,7 +10,7 @@ import ( // stepBootWait waits the configured time period. type stepBootWait struct{} -func (s *stepBootWait) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepBootWait) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_configure_vnc.go b/builder/qemu/step_configure_vnc.go index 4224e2f33..5d412b811 100644 --- a/builder/qemu/step_configure_vnc.go +++ b/builder/qemu/step_configure_vnc.go @@ -20,7 +20,7 @@ import ( // vnc_port uint - The port that VNC is configured to listen on. type stepConfigureVNC struct{} -func (stepConfigureVNC) Run(state multistep.StateBag) multistep.StepAction { +func (stepConfigureVNC) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_convert_disk.go b/builder/qemu/step_convert_disk.go index f74dc75d4..209361f5d 100644 --- a/builder/qemu/step_convert_disk.go +++ b/builder/qemu/step_convert_disk.go @@ -14,7 +14,7 @@ import ( // hard drive for the virtual machine. type stepConvertDisk struct{} -func (s *stepConvertDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepConvertDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) diskName := state.Get("disk_filename").(string) diff --git a/builder/qemu/step_copy_disk.go b/builder/qemu/step_copy_disk.go index d60c10dec..a6a2e8ca1 100644 --- a/builder/qemu/step_copy_disk.go +++ b/builder/qemu/step_copy_disk.go @@ -12,7 +12,7 @@ import ( // hard drive for the virtual machine. type stepCopyDisk struct{} -func (s *stepCopyDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCopyDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) isoPath := state.Get("iso_path").(string) diff --git a/builder/qemu/step_create_disk.go b/builder/qemu/step_create_disk.go index ab0250e9b..05b5d0833 100644 --- a/builder/qemu/step_create_disk.go +++ b/builder/qemu/step_create_disk.go @@ -12,7 +12,7 @@ import ( // hard drive for the virtual machine. type stepCreateDisk struct{} -func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_forward_ssh.go b/builder/qemu/step_forward_ssh.go index ec1e9e18b..296c94d19 100644 --- a/builder/qemu/step_forward_ssh.go +++ b/builder/qemu/step_forward_ssh.go @@ -18,7 +18,7 @@ import ( // Produces: type stepForwardSSH struct{} -func (s *stepForwardSSH) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepForwardSSH) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_prepare_output_dir.go b/builder/qemu/step_prepare_output_dir.go index 019e99bec..f24138c4c 100644 --- a/builder/qemu/step_prepare_output_dir.go +++ b/builder/qemu/step_prepare_output_dir.go @@ -13,7 +13,7 @@ import ( type stepPrepareOutputDir struct{} -func (stepPrepareOutputDir) Run(state multistep.StateBag) multistep.StepAction { +func (stepPrepareOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_resize_disk.go b/builder/qemu/step_resize_disk.go index a6bc96487..63b430187 100644 --- a/builder/qemu/step_resize_disk.go +++ b/builder/qemu/step_resize_disk.go @@ -12,7 +12,7 @@ import ( // hard drive for the virtual machine. type stepResizeDisk struct{} -func (s *stepResizeDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepResizeDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index a9b00798e..463c8bf07 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -27,7 +27,7 @@ type qemuArgsTemplateData struct { SSHHostPort uint } -func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_set_iso.go b/builder/qemu/step_set_iso.go index ff0f03b5b..e17bbd254 100644 --- a/builder/qemu/step_set_iso.go +++ b/builder/qemu/step_set_iso.go @@ -14,7 +14,7 @@ type stepSetISO struct { Url []string } -func (s *stepSetISO) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSetISO) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) iso_path := "" diff --git a/builder/qemu/step_shutdown.go b/builder/qemu/step_shutdown.go index 4efd85892..394fc16fa 100644 --- a/builder/qemu/step_shutdown.go +++ b/builder/qemu/step_shutdown.go @@ -23,7 +23,7 @@ import ( // <nothing> type stepShutdown struct{} -func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index fb0985d13..dbc896a48 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -40,7 +40,7 @@ type bootCommandTemplateData struct { // <nothing> type stepTypeBootCommand struct{} -func (s *stepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) debug := state.Get("debug").(bool) httpPort := state.Get("http_port").(uint) diff --git a/builder/triton/step_create_image_from_machine.go b/builder/triton/step_create_image_from_machine.go index cbda57e0b..df83e5205 100644 --- a/builder/triton/step_create_image_from_machine.go +++ b/builder/triton/step_create_image_from_machine.go @@ -13,7 +13,7 @@ import ( // The machine must be in the "stopped" state prior to this step being run. type StepCreateImageFromMachine struct{} -func (s *StepCreateImageFromMachine) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateImageFromMachine) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/triton/step_create_source_machine.go b/builder/triton/step_create_source_machine.go index a52d35e50..bca123508 100644 --- a/builder/triton/step_create_source_machine.go +++ b/builder/triton/step_create_source_machine.go @@ -12,7 +12,7 @@ import ( // and waits for it to become available for provisioners. type StepCreateSourceMachine struct{} -func (s *StepCreateSourceMachine) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateSourceMachine) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(Config) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/triton/step_delete_machine.go b/builder/triton/step_delete_machine.go index bccb791df..28d27f268 100644 --- a/builder/triton/step_delete_machine.go +++ b/builder/triton/step_delete_machine.go @@ -11,7 +11,7 @@ import ( // StepDeleteMachine deletes the machine with the ID specified in state["machine"] type StepDeleteMachine struct{} -func (s *StepDeleteMachine) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDeleteMachine) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/triton/step_stop_machine.go b/builder/triton/step_stop_machine.go index 4c2ab0d63..6c01805a5 100644 --- a/builder/triton/step_stop_machine.go +++ b/builder/triton/step_stop_machine.go @@ -12,7 +12,7 @@ import ( // for it to reach the stopped state. type StepStopMachine struct{} -func (s *StepStopMachine) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepStopMachine) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/triton/step_wait_for_stop_to_not_fail.go b/builder/triton/step_wait_for_stop_to_not_fail.go index d5479c803..ff777d890 100644 --- a/builder/triton/step_wait_for_stop_to_not_fail.go +++ b/builder/triton/step_wait_for_stop_to_not_fail.go @@ -12,7 +12,7 @@ import ( // they are started never actually stop. type StepWaitForStopNotToFail struct{} -func (s *StepWaitForStopNotToFail) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepWaitForStopNotToFail) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Waiting 10 seconds to avoid potential SDC bug...") time.Sleep(10 * time.Second) diff --git a/builder/virtualbox/common/step_attach_floppy.go b/builder/virtualbox/common/step_attach_floppy.go index 068f7814c..f8c20f3f5 100644 --- a/builder/virtualbox/common/step_attach_floppy.go +++ b/builder/virtualbox/common/step_attach_floppy.go @@ -26,7 +26,7 @@ type StepAttachFloppy struct { floppyPath string } -func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAttachFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // Determine if we even have a floppy disk to attach var floppyPath string if floppyPathRaw, ok := state.GetOk("floppy_path"); ok { diff --git a/builder/virtualbox/common/step_attach_guest_additions.go b/builder/virtualbox/common/step_attach_guest_additions.go index d9e43e820..c6b88d1c8 100644 --- a/builder/virtualbox/common/step_attach_guest_additions.go +++ b/builder/virtualbox/common/step_attach_guest_additions.go @@ -23,7 +23,7 @@ type StepAttachGuestAdditions struct { GuestAdditionsMode string } -func (s *StepAttachGuestAdditions) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepAttachGuestAdditions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/common/step_configure_vrdp.go b/builder/virtualbox/common/step_configure_vrdp.go index aa47d586d..2cf2659d8 100644 --- a/builder/virtualbox/common/step_configure_vrdp.go +++ b/builder/virtualbox/common/step_configure_vrdp.go @@ -26,7 +26,7 @@ type StepConfigureVRDP struct { VRDPPortMax uint } -func (s *StepConfigureVRDP) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureVRDP) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 498d2e71e..750f825e5 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -36,7 +36,7 @@ type StepDownloadGuestAdditions struct { Ctx interpolate.Context } -func (s *StepDownloadGuestAdditions) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDownloadGuestAdditions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { var action multistep.StepAction driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/common/step_export.go b/builder/virtualbox/common/step_export.go index 268634132..a09b5c01c 100644 --- a/builder/virtualbox/common/step_export.go +++ b/builder/virtualbox/common/step_export.go @@ -27,7 +27,7 @@ type StepExport struct { SkipExport bool } -func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepExport) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/common/step_forward_ssh.go b/builder/virtualbox/common/step_forward_ssh.go index 7b0a6f903..4bcd2dc66 100644 --- a/builder/virtualbox/common/step_forward_ssh.go +++ b/builder/virtualbox/common/step_forward_ssh.go @@ -27,7 +27,7 @@ type StepForwardSSH struct { SkipNatMapping bool } -func (s *StepForwardSSH) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepForwardSSH) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/common/step_output_dir.go b/builder/virtualbox/common/step_output_dir.go index acb905e9a..cad96b98e 100644 --- a/builder/virtualbox/common/step_output_dir.go +++ b/builder/virtualbox/common/step_output_dir.go @@ -21,7 +21,7 @@ type StepOutputDir struct { cleanup bool } -func (s *StepOutputDir) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if _, err := os.Stat(s.Path); err == nil { diff --git a/builder/virtualbox/common/step_remove_devices.go b/builder/virtualbox/common/step_remove_devices.go index 0cdde2f23..4a4a24a9e 100644 --- a/builder/virtualbox/common/step_remove_devices.go +++ b/builder/virtualbox/common/step_remove_devices.go @@ -20,7 +20,7 @@ import ( // Produces: type StepRemoveDevices struct{} -func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRemoveDevices) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/common/step_run.go b/builder/virtualbox/common/step_run.go index fc9ee9359..391d8c25e 100644 --- a/builder/virtualbox/common/step_run.go +++ b/builder/virtualbox/common/step_run.go @@ -23,7 +23,7 @@ type StepRun struct { vmName string } -func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/common/step_shutdown.go b/builder/virtualbox/common/step_shutdown.go index 51c435853..7acf97683 100644 --- a/builder/virtualbox/common/step_shutdown.go +++ b/builder/virtualbox/common/step_shutdown.go @@ -29,7 +29,7 @@ type StepShutdown struct { Delay time.Duration } -func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/common/step_suppress_messages.go b/builder/virtualbox/common/step_suppress_messages.go index 6ccbe0434..1805a0535 100644 --- a/builder/virtualbox/common/step_suppress_messages.go +++ b/builder/virtualbox/common/step_suppress_messages.go @@ -11,7 +11,7 @@ import ( // pop-up messages don't exist. type StepSuppressMessages struct{} -func (StepSuppressMessages) Run(state multistep.StateBag) multistep.StepAction { +func (StepSuppressMessages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index ba008a5a3..997805732 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -38,7 +38,7 @@ type StepTypeBootCommand struct { Ctx interpolate.Context } -func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { debug := state.Get("debug").(bool) driver := state.Get("driver").(Driver) httpPort := state.Get("http_port").(uint) diff --git a/builder/virtualbox/common/step_upload_guest_additions.go b/builder/virtualbox/common/step_upload_guest_additions.go index 12b646e7e..6de891ffd 100644 --- a/builder/virtualbox/common/step_upload_guest_additions.go +++ b/builder/virtualbox/common/step_upload_guest_additions.go @@ -21,7 +21,7 @@ type StepUploadGuestAdditions struct { Ctx interpolate.Context } -func (s *StepUploadGuestAdditions) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUploadGuestAdditions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/common/step_upload_version.go b/builder/virtualbox/common/step_upload_version.go index 262b6bfad..fa154c7ae 100644 --- a/builder/virtualbox/common/step_upload_version.go +++ b/builder/virtualbox/common/step_upload_version.go @@ -14,7 +14,7 @@ type StepUploadVersion struct { Path string } -func (s *StepUploadVersion) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepUploadVersion) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/common/step_vboxmanage.go b/builder/virtualbox/common/step_vboxmanage.go index 2366cc6ef..54ef96e0f 100644 --- a/builder/virtualbox/common/step_vboxmanage.go +++ b/builder/virtualbox/common/step_vboxmanage.go @@ -27,7 +27,7 @@ type StepVBoxManage struct { Ctx interpolate.Context } -func (s *StepVBoxManage) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepVBoxManage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index 088241e58..3c9fcc55e 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -17,7 +17,7 @@ type stepAttachISO struct { diskPath string } -func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepAttachISO) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(vboxcommon.Driver) isoPath := state.Get("iso_path").(string) diff --git a/builder/virtualbox/iso/step_create_disk.go b/builder/virtualbox/iso/step_create_disk.go index c5eb71302..cb67af807 100644 --- a/builder/virtualbox/iso/step_create_disk.go +++ b/builder/virtualbox/iso/step_create_disk.go @@ -16,7 +16,7 @@ import ( // hard drive for the virtual machine. type stepCreateDisk struct{} -func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(vboxcommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/iso/step_create_vm.go b/builder/virtualbox/iso/step_create_vm.go index 1f14d5b1a..81a8a0304 100644 --- a/builder/virtualbox/iso/step_create_vm.go +++ b/builder/virtualbox/iso/step_create_vm.go @@ -16,7 +16,7 @@ type stepCreateVM struct { vmName string } -func (s *stepCreateVM) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateVM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(vboxcommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/virtualbox/ovf/step_import.go b/builder/virtualbox/ovf/step_import.go index ca52ef9fc..8ebf5fe4b 100644 --- a/builder/virtualbox/ovf/step_import.go +++ b/builder/virtualbox/ovf/step_import.go @@ -16,7 +16,7 @@ type StepImport struct { vmName string } -func (s *StepImport) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepImport) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vboxcommon.Driver) ui := state.Get("ui").(packer.Ui) vmPath := state.Get("vm_path").(string) diff --git a/builder/vmware/common/step_clean_files.go b/builder/vmware/common/step_clean_files.go index d1a970f36..676e08f2f 100644 --- a/builder/vmware/common/step_clean_files.go +++ b/builder/vmware/common/step_clean_files.go @@ -26,7 +26,7 @@ var KeepFileExtensions = []string{".nvram", ".vmdk", ".vmsd", ".vmx", ".vmxf"} // <nothing> type StepCleanFiles struct{} -func (StepCleanFiles) Run(state multistep.StateBag) multistep.StepAction { +func (StepCleanFiles) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { dir := state.Get("dir").(OutputDir) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/common/step_clean_vmx.go b/builder/vmware/common/step_clean_vmx.go index af29ae970..12cc6b223 100644 --- a/builder/vmware/common/step_clean_vmx.go +++ b/builder/vmware/common/step_clean_vmx.go @@ -24,7 +24,7 @@ type StepCleanVMX struct { VNCEnabled bool } -func (s StepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { +func (s StepCleanVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) diff --git a/builder/vmware/common/step_compact_disk.go b/builder/vmware/common/step_compact_disk.go index 9292c46cf..cf0c4cf19 100644 --- a/builder/vmware/common/step_compact_disk.go +++ b/builder/vmware/common/step_compact_disk.go @@ -21,7 +21,7 @@ type StepCompactDisk struct { Skip bool } -func (s StepCompactDisk) Run(state multistep.StateBag) multistep.StepAction { +func (s StepCompactDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) full_disk_path := state.Get("full_disk_path").(string) diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 2b3f605f8..369712b6e 100644 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -21,7 +21,7 @@ type StepConfigureVMX struct { SkipFloppy bool } -func (s *StepConfigureVMX) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) diff --git a/builder/vmware/common/step_configure_vnc.go b/builder/vmware/common/step_configure_vnc.go index e8b9f9a9f..1f18ce5bf 100644 --- a/builder/vmware/common/step_configure_vnc.go +++ b/builder/vmware/common/step_configure_vnc.go @@ -76,7 +76,7 @@ func VNCPassword(skipPassword bool) string { return string(password) } -func (s *StepConfigureVNC) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureVNC) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if !s.Enabled { log.Println("Skipping VNC configuration step...") return multistep.ActionContinue diff --git a/builder/vmware/common/step_output_dir.go b/builder/vmware/common/step_output_dir.go index ed180ed11..35effe138 100644 --- a/builder/vmware/common/step_output_dir.go +++ b/builder/vmware/common/step_output_dir.go @@ -18,7 +18,7 @@ type StepOutputDir struct { success bool } -func (s *StepOutputDir) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepOutputDir) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { dir := state.Get("dir").(OutputDir) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/common/step_prepare_tools.go b/builder/vmware/common/step_prepare_tools.go index 6dfabc663..3ce771387 100644 --- a/builder/vmware/common/step_prepare_tools.go +++ b/builder/vmware/common/step_prepare_tools.go @@ -12,7 +12,7 @@ type StepPrepareTools struct { ToolsUploadFlavor string } -func (c *StepPrepareTools) Run(state multistep.StateBag) multistep.StepAction { +func (c *StepPrepareTools) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) if c.RemoteType == "esx5" { diff --git a/builder/vmware/common/step_run.go b/builder/vmware/common/step_run.go index 0324937fb..14334e779 100644 --- a/builder/vmware/common/step_run.go +++ b/builder/vmware/common/step_run.go @@ -26,7 +26,7 @@ type StepRun struct { vmxPath string } -func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) diff --git a/builder/vmware/common/step_run_test.go b/builder/vmware/common/step_run_test.go index 961363a04..395575231 100644 --- a/builder/vmware/common/step_run_test.go +++ b/builder/vmware/common/step_run_test.go @@ -10,7 +10,7 @@ func TestStepRun_impl(t *testing.T) { var _ multistep.Step = new(StepRun) } -func TestStepRun(t *testing.T) { +func TestStepRun(_ context.Context, t *testing.T) { state := testState(t) step := new(StepRun) diff --git a/builder/vmware/common/step_shutdown.go b/builder/vmware/common/step_shutdown.go index 2938eabe4..5067ebbb2 100644 --- a/builder/vmware/common/step_shutdown.go +++ b/builder/vmware/common/step_shutdown.go @@ -35,7 +35,7 @@ type StepShutdown struct { Testing bool } -func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := state.Get("communicator").(packer.Communicator) dir := state.Get("dir").(OutputDir) driver := state.Get("driver").(Driver) diff --git a/builder/vmware/common/step_suppress_messages.go b/builder/vmware/common/step_suppress_messages.go index 425da1398..3e8721dec 100644 --- a/builder/vmware/common/step_suppress_messages.go +++ b/builder/vmware/common/step_suppress_messages.go @@ -10,7 +10,7 @@ import ( // This step suppresses any messages that VMware product might show. type StepSuppressMessages struct{} -func (s *StepSuppressMessages) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepSuppressMessages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 84b47045e..8e6a66366 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -42,7 +42,7 @@ type StepTypeBootCommand struct { Ctx interpolate.Context } -func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if !s.VNCEnabled { log.Println("Skipping boot command step...") return multistep.ActionContinue diff --git a/builder/vmware/common/step_upload_tools.go b/builder/vmware/common/step_upload_tools.go index c3642a1e6..4dff6496e 100644 --- a/builder/vmware/common/step_upload_tools.go +++ b/builder/vmware/common/step_upload_tools.go @@ -20,7 +20,7 @@ type StepUploadTools struct { Ctx interpolate.Context } -func (c *StepUploadTools) Run(state multistep.StateBag) multistep.StepAction { +func (c *StepUploadTools) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) if c.ToolsUploadFlavor == "" { diff --git a/builder/vmware/iso/step_create_disk.go b/builder/vmware/iso/step_create_disk.go index 1d76e68f5..457236034 100644 --- a/builder/vmware/iso/step_create_disk.go +++ b/builder/vmware/iso/step_create_disk.go @@ -21,7 +21,7 @@ import ( // full_disk_path (string) - The full path to the created disk. type stepCreateDisk struct{} -func (stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { +func (stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 3a8985394..a071ed0f1 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -38,7 +38,7 @@ type stepCreateVMX struct { tempDir string } -func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) isoPath := state.Get("iso_path").(string) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/iso/step_export.go b/builder/vmware/iso/step_export.go index 3fa71d8d8..4d08af159 100644 --- a/builder/vmware/iso/step_export.go +++ b/builder/vmware/iso/step_export.go @@ -34,7 +34,7 @@ func (s *StepExport) generateArgs(c *Config, hidePassword bool) []string { return append(c.OVFToolOptions, args...) } -func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepExport) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { c := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/iso/step_register.go b/builder/vmware/iso/step_register.go index a11ef17b5..e1d396ab1 100644 --- a/builder/vmware/iso/step_register.go +++ b/builder/vmware/iso/step_register.go @@ -14,7 +14,7 @@ type StepRegister struct { Format string } -func (s *StepRegister) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepRegister) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 48deabaab..427ba28c6 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -17,7 +17,7 @@ type stepRemoteUpload struct { Message string } -func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepRemoteUpload) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/iso/step_upload_vmx.go b/builder/vmware/iso/step_upload_vmx.go index 2fc65daaf..360372765 100644 --- a/builder/vmware/iso/step_upload_vmx.go +++ b/builder/vmware/iso/step_upload_vmx.go @@ -23,7 +23,7 @@ type StepUploadVMX struct { RemoteType string } -func (c *StepUploadVMX) Run(state multistep.StateBag) multistep.StepAction { +func (c *StepUploadVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index 76318b2ef..e65ea0dca 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -17,7 +17,7 @@ type StepCloneVMX struct { VMName string } -func (s *StepCloneVMX) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) diff --git a/common/step_create_floppy.go b/common/step_create_floppy.go index fdcc29f64..8b0ef8b83 100644 --- a/common/step_create_floppy.go +++ b/common/step_create_floppy.go @@ -26,7 +26,7 @@ type StepCreateFloppy struct { FilesAdded map[string]bool } -func (s *StepCreateFloppy) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateFloppy) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if len(s.Files) == 0 && len(s.Directories) == 0 { log.Println("No floppy files specified. Floppy disk will not be made.") return multistep.ActionContinue diff --git a/common/step_download.go b/common/step_download.go index d0250ec34..bdcd7ac65 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -45,7 +45,7 @@ type StepDownload struct { Extension string } -func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { cache := state.Get("cache").(packer.Cache) ui := state.Get("ui").(packer.Ui) diff --git a/common/step_http_server.go b/common/step_http_server.go index b7fd3dcfd..70b1e1460 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -31,7 +31,7 @@ type StepHTTPServer struct { l net.Listener } -func (s *StepHTTPServer) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) var httpPort uint = 0 diff --git a/common/step_provision.go b/common/step_provision.go index a859fea7d..971ef97fb 100644 --- a/common/step_provision.go +++ b/common/step_provision.go @@ -23,7 +23,7 @@ type StepProvision struct { Comm packer.Communicator } -func (s *StepProvision) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepProvision) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { comm := s.Comm if comm == nil { raw, ok := state.Get("communicator").(packer.Communicator) diff --git a/helper/communicator/step_connect.go b/helper/communicator/step_connect.go index 5f27b0765..67a5eebbe 100644 --- a/helper/communicator/step_connect.go +++ b/helper/communicator/step_connect.go @@ -43,7 +43,7 @@ type StepConnect struct { substep multistep.Step } -func (s *StepConnect) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConnect) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { typeMap := map[string]multistep.Step{ "none": nil, "ssh": &StepConnectSSH{ diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 842e5e611..2f3ae3666 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -29,7 +29,7 @@ type StepConnectSSH struct { SSHPort func(multistep.StateBag) (int, error) } -func (s *StepConnectSSH) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConnectSSH) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) var comm packer.Communicator diff --git a/helper/communicator/step_connect_winrm.go b/helper/communicator/step_connect_winrm.go index b1182f7d6..97e7805d6 100644 --- a/helper/communicator/step_connect_winrm.go +++ b/helper/communicator/step_connect_winrm.go @@ -32,7 +32,7 @@ type StepConnectWinRM struct { WinRMPort func(multistep.StateBag) (int, error) } -func (s *StepConnectWinRM) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConnectWinRM) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) var comm packer.Communicator diff --git a/post-processor/vagrant-cloud/step_create_provider.go b/post-processor/vagrant-cloud/step_create_provider.go index 3e43bf451..028e5c6c7 100644 --- a/post-processor/vagrant-cloud/step_create_provider.go +++ b/post-processor/vagrant-cloud/step_create_provider.go @@ -17,7 +17,7 @@ type stepCreateProvider struct { name string // the name of the provider } -func (s *stepCreateProvider) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateProvider) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*VagrantCloudClient) ui := state.Get("ui").(packer.Ui) box := state.Get("box").(*Box) diff --git a/post-processor/vagrant-cloud/step_create_version.go b/post-processor/vagrant-cloud/step_create_version.go index 6a7ef9fa7..d8e6b9df8 100644 --- a/post-processor/vagrant-cloud/step_create_version.go +++ b/post-processor/vagrant-cloud/step_create_version.go @@ -14,7 +14,7 @@ type Version struct { type stepCreateVersion struct { } -func (s *stepCreateVersion) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateVersion) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*VagrantCloudClient) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) diff --git a/post-processor/vagrant-cloud/step_prepare_upload.go b/post-processor/vagrant-cloud/step_prepare_upload.go index 88fa1eb05..1bcc05885 100644 --- a/post-processor/vagrant-cloud/step_prepare_upload.go +++ b/post-processor/vagrant-cloud/step_prepare_upload.go @@ -14,7 +14,7 @@ type Upload struct { type stepPrepareUpload struct { } -func (s *stepPrepareUpload) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepPrepareUpload) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*VagrantCloudClient) ui := state.Get("ui").(packer.Ui) box := state.Get("box").(*Box) diff --git a/post-processor/vagrant-cloud/step_release_version.go b/post-processor/vagrant-cloud/step_release_version.go index 328819570..5f7fbb0f0 100644 --- a/post-processor/vagrant-cloud/step_release_version.go +++ b/post-processor/vagrant-cloud/step_release_version.go @@ -11,7 +11,7 @@ import ( type stepReleaseVersion struct { } -func (s *stepReleaseVersion) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepReleaseVersion) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*VagrantCloudClient) ui := state.Get("ui").(packer.Ui) box := state.Get("box").(*Box) diff --git a/post-processor/vagrant-cloud/step_upload.go b/post-processor/vagrant-cloud/step_upload.go index 78d3bac0a..576558b24 100644 --- a/post-processor/vagrant-cloud/step_upload.go +++ b/post-processor/vagrant-cloud/step_upload.go @@ -12,7 +12,7 @@ import ( type stepUpload struct { } -func (s *stepUpload) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepUpload) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*VagrantCloudClient) ui := state.Get("ui").(packer.Ui) upload := state.Get("upload").(*Upload) diff --git a/post-processor/vagrant-cloud/step_verify_box.go b/post-processor/vagrant-cloud/step_verify_box.go index 84f12b6fe..baee6222a 100644 --- a/post-processor/vagrant-cloud/step_verify_box.go +++ b/post-processor/vagrant-cloud/step_verify_box.go @@ -23,7 +23,7 @@ func (b *Box) HasVersion(version string) (bool, *Version) { type stepVerifyBox struct { } -func (s *stepVerifyBox) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepVerifyBox) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*VagrantCloudClient) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) diff --git a/post-processor/vsphere-template/step_choose_datacenter.go b/post-processor/vsphere-template/step_choose_datacenter.go index f66d99d9f..450f2b946 100644 --- a/post-processor/vsphere-template/step_choose_datacenter.go +++ b/post-processor/vsphere-template/step_choose_datacenter.go @@ -13,7 +13,7 @@ type stepChooseDatacenter struct { Datacenter string } -func (s *stepChooseDatacenter) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepChooseDatacenter) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) cli := state.Get("client").(*govmomi.Client) finder := find.NewFinder(cli.Client, false) diff --git a/post-processor/vsphere-template/step_create_folder.go b/post-processor/vsphere-template/step_create_folder.go index cf5b8a847..49232c2f2 100644 --- a/post-processor/vsphere-template/step_create_folder.go +++ b/post-processor/vsphere-template/step_create_folder.go @@ -15,7 +15,7 @@ type stepCreateFolder struct { Folder string } -func (s *stepCreateFolder) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateFolder) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) cli := state.Get("client").(*govmomi.Client) dcPath := state.Get("dcPath").(string) diff --git a/post-processor/vsphere-template/step_mark_as_template.go b/post-processor/vsphere-template/step_mark_as_template.go index a8a116028..8117a4940 100644 --- a/post-processor/vsphere-template/step_mark_as_template.go +++ b/post-processor/vsphere-template/step_mark_as_template.go @@ -18,7 +18,7 @@ type stepMarkAsTemplate struct { VMName string } -func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepMarkAsTemplate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) cli := state.Get("client").(*govmomi.Client) folder := state.Get("folder").(*object.Folder) From 7a189a83a19c1acabbcdb505120653e0aa77ea46 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 15:32:33 -0800 Subject: [PATCH 0436/1007] fix imports `find . -type f -name '*.go' -not -path "./vendor/*" -exec goimports -w {} \;` --- builder/alicloud/ecs/step_attach_keypair.go | 2 +- builder/alicloud/ecs/step_check_source_image.go | 1 + builder/alicloud/ecs/step_config_eip.go | 1 + builder/alicloud/ecs/step_config_key_pair.go | 1 + builder/alicloud/ecs/step_config_public_ip.go | 1 + builder/alicloud/ecs/step_config_security_group.go | 1 + builder/alicloud/ecs/step_config_vpc.go | 1 + builder/alicloud/ecs/step_config_vswitch.go | 1 + builder/alicloud/ecs/step_create_image.go | 1 + builder/alicloud/ecs/step_create_instance.go | 1 + builder/alicloud/ecs/step_delete_images_snapshots.go | 1 + builder/alicloud/ecs/step_mount_disk.go | 1 + builder/alicloud/ecs/step_pre_validate.go | 1 + builder/alicloud/ecs/step_region_copy_image.go | 1 + builder/alicloud/ecs/step_run_instance.go | 1 + builder/alicloud/ecs/step_share_image.go | 1 + builder/alicloud/ecs/step_stop_instance.go | 1 + builder/amazon/chroot/step_attach_volume.go | 1 + builder/amazon/chroot/step_check_root_device.go | 1 + builder/amazon/chroot/step_chroot_provision.go | 1 + builder/amazon/chroot/step_copy_files.go | 5 ++--- builder/amazon/chroot/step_create_volume.go | 1 + builder/amazon/chroot/step_early_cleanup.go | 4 +++- builder/amazon/chroot/step_early_unflock.go | 4 +++- builder/amazon/chroot/step_flock.go | 5 ++--- builder/amazon/chroot/step_instance_info.go | 1 + builder/amazon/chroot/step_mount_device.go | 1 + builder/amazon/chroot/step_mount_extra.go | 5 ++--- builder/amazon/chroot/step_post_mount_commands.go | 2 ++ builder/amazon/chroot/step_pre_mount_commands.go | 2 ++ builder/amazon/chroot/step_prepare_device.go | 1 + builder/amazon/chroot/step_register_ami.go | 1 + builder/amazon/chroot/step_snapshot.go | 1 + builder/amazon/common/step_ami_region_copy.go | 1 + builder/amazon/common/step_create_tags.go | 1 + builder/amazon/common/step_deregister_ami.go | 1 + builder/amazon/common/step_encrypted_ami.go | 1 + builder/amazon/common/step_get_password.go | 1 + builder/amazon/common/step_key_pair.go | 1 + builder/amazon/common/step_modify_ami_attributes.go | 1 + builder/amazon/common/step_modify_ebs_instance.go | 1 + builder/amazon/common/step_pre_validate.go | 1 + builder/amazon/common/step_run_spot_instance.go | 1 + builder/amazon/common/step_security_group.go | 1 + builder/amazon/common/step_source_ami_info.go | 1 + builder/amazon/common/step_stop_ebs_instance.go | 1 + builder/amazon/ebs/step_cleanup_volumes.go | 1 + builder/amazon/ebs/step_create_ami.go | 1 + builder/amazon/ebssurrogate/step_register_ami.go | 1 + builder/amazon/ebssurrogate/step_snapshot_new_root.go | 1 + builder/amazon/ebsvolume/step_tag_ebs_volumes.go | 1 + builder/amazon/instance/step_bundle_volume.go | 1 + builder/amazon/instance/step_register_ami.go | 1 + builder/amazon/instance/step_upload_bundle.go | 1 + builder/amazon/instance/step_upload_x509_cert.go | 4 +++- builder/azure/arm/step_capture_image.go | 1 + builder/azure/arm/step_create_resource_group.go | 1 + builder/azure/arm/step_delete_os_disk.go | 1 + builder/azure/arm/step_delete_resource_group.go | 1 + builder/azure/arm/step_deploy_template.go | 1 + builder/azure/arm/step_get_certificate.go | 1 + builder/azure/arm/step_get_ip_address.go | 1 + builder/azure/arm/step_get_os_disk.go | 1 + builder/azure/arm/step_power_off_compute.go | 1 + builder/azure/arm/step_set_certificate.go | 2 ++ builder/azure/arm/step_test.go | 1 - builder/azure/arm/step_validate_template.go | 1 + builder/azure/common/lin/step_create_cert.go | 1 + builder/azure/common/lin/step_generalize_os.go | 4 +++- builder/cloudstack/step_configure_networking.go | 1 + builder/cloudstack/step_create_instance.go | 1 + builder/cloudstack/step_create_security_group.go | 1 + builder/cloudstack/step_create_template.go | 1 + builder/cloudstack/step_keypair.go | 1 + builder/cloudstack/step_prepare_config.go | 1 + builder/cloudstack/step_shutdown_instance.go | 1 + builder/docker/step_commit.go | 2 ++ builder/docker/step_commit_test.go | 3 +-- builder/docker/step_connect_docker.go | 4 ++-- builder/docker/step_export.go | 1 + builder/docker/step_export_test.go | 3 +-- builder/docker/step_pull.go | 1 + builder/docker/step_pull_test.go | 3 +-- builder/docker/step_run.go | 2 ++ builder/docker/step_run_test.go | 4 ++-- builder/docker/step_temp_dir.go | 5 ++--- builder/docker/step_test.go | 3 ++- builder/googlecompute/step_check_existing_image.go | 1 + builder/googlecompute/step_check_existing_image_test.go | 3 +-- builder/googlecompute/step_create_image.go | 1 + builder/googlecompute/step_create_instance.go | 1 + builder/googlecompute/step_create_ssh_key.go | 1 + builder/googlecompute/step_create_windows_password.go | 1 + builder/googlecompute/step_instance_info.go | 1 + builder/googlecompute/step_instance_info_test.go | 3 +-- builder/googlecompute/step_teardown_instance.go | 1 + builder/googlecompute/step_teardown_instance_test.go | 3 +-- builder/googlecompute/step_wait_startup_script.go | 1 + builder/googlecompute/step_wait_startup_script_test.go | 2 ++ builder/hyperv/common/step_clone_vm.go | 1 + builder/hyperv/common/step_configure_ip.go | 1 + builder/hyperv/common/step_configure_vlan.go | 1 + builder/hyperv/common/step_create_external_switch.go | 1 + builder/hyperv/common/step_create_switch.go | 2 ++ builder/hyperv/common/step_create_tempdir.go | 1 + builder/hyperv/common/step_create_vm.go | 1 + builder/hyperv/common/step_disable_vlan.go | 2 ++ builder/hyperv/common/step_enable_integration_service.go | 2 ++ builder/hyperv/common/step_export_vm.go | 1 + builder/hyperv/common/step_mount_dvddrive.go | 5 ++--- builder/hyperv/common/step_mount_floppydrive.go | 5 ++--- builder/hyperv/common/step_mount_guest_additions.go | 4 +++- builder/hyperv/common/step_mount_secondary_dvd_images.go | 4 +++- builder/hyperv/common/step_output_dir.go | 1 + builder/hyperv/common/step_polling_installation.go | 1 + builder/hyperv/common/step_reboot_vm.go | 4 +++- builder/hyperv/common/step_run.go | 4 +++- builder/hyperv/common/step_shutdown.go | 1 + builder/hyperv/common/step_sleep.go | 4 +++- builder/hyperv/common/step_type_boot_command.go | 1 + builder/hyperv/common/step_unmount_dvddrive.go | 2 ++ builder/hyperv/common/step_unmount_floppydrive.go | 2 ++ builder/hyperv/common/step_unmount_guest_additions.go | 2 ++ builder/hyperv/common/step_unmount_secondary_dvd_images.go | 2 ++ builder/hyperv/common/step_wait_for_install_to_complete.go | 4 +++- builder/hyperv/iso/builder_test.go | 1 - builder/hyperv/vmcx/builder_test.go | 2 -- builder/lxc/builder.go | 3 --- builder/lxc/step_export.go | 5 ++--- builder/lxc/step_lxc_create.go | 5 ++--- builder/lxc/step_prepare_output_dir.go | 5 ++--- builder/lxc/step_provision.go | 4 +++- builder/lxc/step_wait_init.go | 5 ++--- builder/lxd/builder.go | 1 - builder/lxd/step_lxd_launch.go | 4 +++- builder/lxd/step_provision.go | 4 +++- builder/lxd/step_publish.go | 4 +++- builder/oneandone/builder.go | 1 - builder/oneandone/step_create_server.go | 3 +-- builder/oneandone/step_create_sshkey.go | 3 +++ builder/oneandone/step_take_snapshot.go | 2 ++ builder/openstack/step_add_image_members.go | 1 + builder/openstack/step_allocate_ip.go | 1 + builder/openstack/step_create_image.go | 1 + builder/openstack/step_get_password.go | 1 + builder/openstack/step_key_pair.go | 1 + builder/openstack/step_load_extensions.go | 1 + builder/openstack/step_load_flavor.go | 1 + builder/openstack/step_run_source_server.go | 1 + builder/openstack/step_stop_server.go | 1 + builder/openstack/step_update_image_visibility.go | 1 + builder/openstack/step_wait_for_rackconnect.go | 1 + builder/oracle/oci/step_create_instance.go | 1 + builder/oracle/oci/step_image.go | 1 + builder/oracle/oci/step_instance_info.go | 1 + builder/oracle/oci/step_ssh_key_pair.go | 1 + builder/parallels/common/step_attach_floppy.go | 1 + builder/parallels/common/step_attach_parallels_tools.go | 1 + builder/parallels/common/step_compact_disk.go | 1 + builder/parallels/common/step_output_dir.go | 1 + builder/parallels/common/step_prepare_parallels_tools.go | 1 + builder/parallels/common/step_prlctl.go | 1 + builder/parallels/common/step_run.go | 1 + builder/parallels/common/step_shutdown.go | 1 + builder/parallels/common/step_type_boot_command.go | 1 + builder/parallels/common/step_upload_parallels_tools.go | 1 + builder/parallels/common/step_upload_version.go | 1 + builder/parallels/iso/step_attach_iso.go | 1 + builder/parallels/iso/step_create_disk.go | 1 + builder/parallels/iso/step_create_vm.go | 1 + builder/parallels/iso/step_set_boot_order.go | 1 + builder/parallels/pvm/step_import.go | 1 + builder/profitbricks/builder.go | 1 - builder/profitbricks/step_create_server.go | 1 + builder/profitbricks/step_create_ssh_key.go | 3 +++ builder/profitbricks/step_take_snapshot.go | 1 + builder/qemu/step_boot_wait.go | 4 +++- builder/qemu/step_configure_vnc.go | 1 + builder/qemu/step_convert_disk.go | 1 + builder/qemu/step_copy_disk.go | 1 + builder/qemu/step_create_disk.go | 1 + builder/qemu/step_forward_ssh.go | 1 + builder/qemu/step_prepare_output_dir.go | 5 ++--- builder/qemu/step_resize_disk.go | 1 + builder/qemu/step_run.go | 1 + builder/qemu/step_set_iso.go | 1 + builder/qemu/step_shutdown.go | 1 + builder/qemu/step_type_boot_command.go | 2 +- builder/triton/step_create_image_from_machine.go | 1 + builder/triton/step_create_source_machine.go | 1 + builder/triton/step_delete_machine.go | 1 + builder/triton/step_stop_machine.go | 1 + builder/triton/step_test.go | 3 ++- builder/triton/step_wait_for_stop_to_not_fail.go | 1 + builder/virtualbox/common/step_attach_floppy.go | 5 ++--- builder/virtualbox/common/step_attach_floppy_test.go | 3 +-- builder/virtualbox/common/step_attach_guest_additions.go | 4 +++- builder/virtualbox/common/step_configure_vrdp.go | 1 + builder/virtualbox/common/step_download_guest_additions.go | 1 + builder/virtualbox/common/step_export.go | 5 ++--- builder/virtualbox/common/step_export_test.go | 3 +-- builder/virtualbox/common/step_forward_ssh.go | 1 + builder/virtualbox/common/step_output_dir.go | 1 + builder/virtualbox/common/step_output_dir_test.go | 3 +-- builder/virtualbox/common/step_remove_devices.go | 1 + builder/virtualbox/common/step_remove_devices_test.go | 3 +-- builder/virtualbox/common/step_run.go | 1 + builder/virtualbox/common/step_shutdown.go | 5 ++--- builder/virtualbox/common/step_shutdown_test.go | 4 +--- builder/virtualbox/common/step_suppress_messages.go | 4 +++- builder/virtualbox/common/step_suppress_messages_test.go | 3 +-- builder/virtualbox/common/step_test.go | 3 ++- builder/virtualbox/common/step_type_boot_command.go | 1 + builder/virtualbox/common/step_upload_guest_additions.go | 1 + builder/virtualbox/common/step_upload_version.go | 4 +++- builder/virtualbox/common/step_upload_version_test.go | 3 ++- builder/virtualbox/common/step_vboxmanage.go | 1 + builder/virtualbox/iso/step_attach_iso.go | 1 + builder/virtualbox/iso/step_create_disk.go | 1 + builder/virtualbox/iso/step_create_vm.go | 1 + builder/virtualbox/ovf/step_import.go | 1 + builder/virtualbox/ovf/step_import_test.go | 1 - builder/virtualbox/ovf/step_test.go | 1 - builder/vmware/common/step_clean_files.go | 5 ++--- builder/vmware/common/step_clean_vmx.go | 1 + builder/vmware/common/step_compact_disk.go | 4 +++- builder/vmware/common/step_configure_vmx.go | 1 + builder/vmware/common/step_configure_vnc.go | 1 + builder/vmware/common/step_output_dir.go | 1 + builder/vmware/common/step_output_dir_test.go | 3 +-- builder/vmware/common/step_prepare_tools.go | 1 + builder/vmware/common/step_run.go | 1 + builder/vmware/common/step_run_test.go | 1 + builder/vmware/common/step_shutdown.go | 5 ++--- builder/vmware/common/step_suppress_messages.go | 4 +++- builder/vmware/common/step_test.go | 3 ++- builder/vmware/common/step_type_boot_command.go | 1 + builder/vmware/common/step_upload_tools.go | 1 + builder/vmware/iso/step_create_disk.go | 2 +- builder/vmware/iso/step_create_vmx.go | 1 + builder/vmware/iso/step_export.go | 1 + builder/vmware/iso/step_export_test.go | 3 +-- builder/vmware/iso/step_register.go | 1 + builder/vmware/iso/step_register_test.go | 3 +-- builder/vmware/iso/step_remote_upload.go | 2 +- builder/vmware/iso/step_test.go | 1 - builder/vmware/iso/step_upload_vmx.go | 2 +- builder/vmware/vmx/step_clone_vmx.go | 1 + common/multistep_debug.go | 4 +--- common/step_create_floppy.go | 1 + common/step_create_floppy_test.go | 4 +--- common/step_download.go | 1 + common/step_download_test.go | 3 +-- common/step_http_server.go | 1 + common/step_provision.go | 5 ++--- common/step_provision_test.go | 3 +-- helper/communicator/step_connect.go | 1 + helper/communicator/step_connect_ssh.go | 1 + helper/communicator/step_connect_winrm.go | 1 + post-processor/vagrant-cloud/step_create_provider.go | 2 ++ post-processor/vagrant-cloud/step_create_version.go | 2 ++ post-processor/vagrant-cloud/step_prepare_upload.go | 1 + post-processor/vagrant-cloud/step_release_version.go | 1 + post-processor/vagrant-cloud/step_upload.go | 1 + post-processor/vagrant-cloud/step_verify_box.go | 2 ++ 265 files changed, 340 insertions(+), 141 deletions(-) diff --git a/builder/alicloud/ecs/step_attach_keypair.go b/builder/alicloud/ecs/step_attach_keypair.go index 1bb901f98..8fa2eedfb 100644 --- a/builder/alicloud/ecs/step_attach_keypair.go +++ b/builder/alicloud/ecs/step_attach_keypair.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "time" @@ -9,7 +10,6 @@ import ( "github.com/denverdino/aliyungo/ecs" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) type stepAttachKeyPar struct { diff --git a/builder/alicloud/ecs/step_check_source_image.go b/builder/alicloud/ecs/step_check_source_image.go index b9dc58f69..6090d8868 100644 --- a/builder/alicloud/ecs/step_check_source_image.go +++ b/builder/alicloud/ecs/step_check_source_image.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/common" diff --git a/builder/alicloud/ecs/step_config_eip.go b/builder/alicloud/ecs/step_config_eip.go index edf0b2748..c9446bc47 100644 --- a/builder/alicloud/ecs/step_config_eip.go +++ b/builder/alicloud/ecs/step_config_eip.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/common" diff --git a/builder/alicloud/ecs/step_config_key_pair.go b/builder/alicloud/ecs/step_config_key_pair.go index 9c68ce92e..e49ae65fb 100644 --- a/builder/alicloud/ecs/step_config_key_pair.go +++ b/builder/alicloud/ecs/step_config_key_pair.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "io/ioutil" "os" diff --git a/builder/alicloud/ecs/step_config_public_ip.go b/builder/alicloud/ecs/step_config_public_ip.go index e87a20079..7e0a246e0 100644 --- a/builder/alicloud/ecs/step_config_public_ip.go +++ b/builder/alicloud/ecs/step_config_public_ip.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/ecs" diff --git a/builder/alicloud/ecs/step_config_security_group.go b/builder/alicloud/ecs/step_config_security_group.go index 4414eefe6..951f6e6fe 100644 --- a/builder/alicloud/ecs/step_config_security_group.go +++ b/builder/alicloud/ecs/step_config_security_group.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "errors" "fmt" "time" diff --git a/builder/alicloud/ecs/step_config_vpc.go b/builder/alicloud/ecs/step_config_vpc.go index 618b4a3da..36d52838f 100644 --- a/builder/alicloud/ecs/step_config_vpc.go +++ b/builder/alicloud/ecs/step_config_vpc.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "errors" "fmt" "time" diff --git a/builder/alicloud/ecs/step_config_vswitch.go b/builder/alicloud/ecs/step_config_vswitch.go index 5510acb3b..c1494e9d0 100644 --- a/builder/alicloud/ecs/step_config_vswitch.go +++ b/builder/alicloud/ecs/step_config_vswitch.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "errors" "fmt" "time" diff --git a/builder/alicloud/ecs/step_create_image.go b/builder/alicloud/ecs/step_create_image.go index 098323307..ae5840c09 100644 --- a/builder/alicloud/ecs/step_create_image.go +++ b/builder/alicloud/ecs/step_create_image.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/common" diff --git a/builder/alicloud/ecs/step_create_instance.go b/builder/alicloud/ecs/step_create_instance.go index 694ee0046..5001fe4df 100644 --- a/builder/alicloud/ecs/step_create_instance.go +++ b/builder/alicloud/ecs/step_create_instance.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "io/ioutil" "log" diff --git a/builder/alicloud/ecs/step_delete_images_snapshots.go b/builder/alicloud/ecs/step_delete_images_snapshots.go index 39e56e7bd..d3f6139f0 100644 --- a/builder/alicloud/ecs/step_delete_images_snapshots.go +++ b/builder/alicloud/ecs/step_delete_images_snapshots.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "log" diff --git a/builder/alicloud/ecs/step_mount_disk.go b/builder/alicloud/ecs/step_mount_disk.go index 509d06615..642605bee 100644 --- a/builder/alicloud/ecs/step_mount_disk.go +++ b/builder/alicloud/ecs/step_mount_disk.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/ecs" diff --git a/builder/alicloud/ecs/step_pre_validate.go b/builder/alicloud/ecs/step_pre_validate.go index bdcad2756..6bc3b1060 100644 --- a/builder/alicloud/ecs/step_pre_validate.go +++ b/builder/alicloud/ecs/step_pre_validate.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/common" diff --git a/builder/alicloud/ecs/step_region_copy_image.go b/builder/alicloud/ecs/step_region_copy_image.go index e50398539..dddf08488 100644 --- a/builder/alicloud/ecs/step_region_copy_image.go +++ b/builder/alicloud/ecs/step_region_copy_image.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/common" diff --git a/builder/alicloud/ecs/step_run_instance.go b/builder/alicloud/ecs/step_run_instance.go index 2bac6dc91..72491dd1d 100644 --- a/builder/alicloud/ecs/step_run_instance.go +++ b/builder/alicloud/ecs/step_run_instance.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/ecs" diff --git a/builder/alicloud/ecs/step_share_image.go b/builder/alicloud/ecs/step_share_image.go index 2f6fbf06f..f954eb421 100644 --- a/builder/alicloud/ecs/step_share_image.go +++ b/builder/alicloud/ecs/step_share_image.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/common" diff --git a/builder/alicloud/ecs/step_stop_instance.go b/builder/alicloud/ecs/step_stop_instance.go index 055f0d5d9..d57a52c12 100644 --- a/builder/alicloud/ecs/step_stop_instance.go +++ b/builder/alicloud/ecs/step_stop_instance.go @@ -1,6 +1,7 @@ package ecs import ( + "context" "fmt" "github.com/denverdino/aliyungo/ecs" diff --git a/builder/amazon/chroot/step_attach_volume.go b/builder/amazon/chroot/step_attach_volume.go index f386a031b..01ab32464 100644 --- a/builder/amazon/chroot/step_attach_volume.go +++ b/builder/amazon/chroot/step_attach_volume.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "errors" "fmt" "strings" diff --git a/builder/amazon/chroot/step_check_root_device.go b/builder/amazon/chroot/step_check_root_device.go index 582a76b8d..5ff66d055 100644 --- a/builder/amazon/chroot/step_check_root_device.go +++ b/builder/amazon/chroot/step_check_root_device.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "fmt" "github.com/aws/aws-sdk-go/service/ec2" diff --git a/builder/amazon/chroot/step_chroot_provision.go b/builder/amazon/chroot/step_chroot_provision.go index 6eb4226c5..be8667077 100644 --- a/builder/amazon/chroot/step_chroot_provision.go +++ b/builder/amazon/chroot/step_chroot_provision.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "log" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/amazon/chroot/step_copy_files.go b/builder/amazon/chroot/step_copy_files.go index d1bdb32b4..a973a5d81 100644 --- a/builder/amazon/chroot/step_copy_files.go +++ b/builder/amazon/chroot/step_copy_files.go @@ -2,14 +2,13 @@ package chroot import ( "bytes" + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCopyFiles copies some files from the host into the chroot environment. diff --git a/builder/amazon/chroot/step_create_volume.go b/builder/amazon/chroot/step_create_volume.go index 10f49b0df..b3c205b26 100644 --- a/builder/amazon/chroot/step_create_volume.go +++ b/builder/amazon/chroot/step_create_volume.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "fmt" "log" diff --git a/builder/amazon/chroot/step_early_cleanup.go b/builder/amazon/chroot/step_early_cleanup.go index 449cb2a89..34e7817df 100644 --- a/builder/amazon/chroot/step_early_cleanup.go +++ b/builder/amazon/chroot/step_early_cleanup.go @@ -1,10 +1,12 @@ package chroot import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // StepEarlyCleanup performs some of the cleanup steps early in order to diff --git a/builder/amazon/chroot/step_early_unflock.go b/builder/amazon/chroot/step_early_unflock.go index 8c15713f8..225e91fb9 100644 --- a/builder/amazon/chroot/step_early_unflock.go +++ b/builder/amazon/chroot/step_early_unflock.go @@ -1,10 +1,12 @@ package chroot import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // StepEarlyUnflock unlocks the flock. diff --git a/builder/amazon/chroot/step_flock.go b/builder/amazon/chroot/step_flock.go index d7ef614ff..d75adc7f0 100644 --- a/builder/amazon/chroot/step_flock.go +++ b/builder/amazon/chroot/step_flock.go @@ -1,15 +1,14 @@ package chroot import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "os" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepFlock provisions the instance within a chroot. diff --git a/builder/amazon/chroot/step_instance_info.go b/builder/amazon/chroot/step_instance_info.go index 8811a49ff..558e28a8d 100644 --- a/builder/amazon/chroot/step_instance_info.go +++ b/builder/amazon/chroot/step_instance_info.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "fmt" "log" diff --git a/builder/amazon/chroot/step_mount_device.go b/builder/amazon/chroot/step_mount_device.go index 06fae4210..f9fc7b0a8 100644 --- a/builder/amazon/chroot/step_mount_device.go +++ b/builder/amazon/chroot/step_mount_device.go @@ -2,6 +2,7 @@ package chroot import ( "bytes" + "context" "fmt" "log" "os" diff --git a/builder/amazon/chroot/step_mount_extra.go b/builder/amazon/chroot/step_mount_extra.go index 7ebbb650a..ffd8ac027 100644 --- a/builder/amazon/chroot/step_mount_extra.go +++ b/builder/amazon/chroot/step_mount_extra.go @@ -2,15 +2,14 @@ package chroot import ( "bytes" + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "os" "os/exec" "syscall" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepMountExtra mounts the attached device. diff --git a/builder/amazon/chroot/step_post_mount_commands.go b/builder/amazon/chroot/step_post_mount_commands.go index 220e32a07..a00e8e1bf 100644 --- a/builder/amazon/chroot/step_post_mount_commands.go +++ b/builder/amazon/chroot/step_post_mount_commands.go @@ -1,6 +1,8 @@ package chroot import ( + "context" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/amazon/chroot/step_pre_mount_commands.go b/builder/amazon/chroot/step_pre_mount_commands.go index b3a8aae6b..ce3c26e02 100644 --- a/builder/amazon/chroot/step_pre_mount_commands.go +++ b/builder/amazon/chroot/step_pre_mount_commands.go @@ -1,6 +1,8 @@ package chroot import ( + "context" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/amazon/chroot/step_prepare_device.go b/builder/amazon/chroot/step_prepare_device.go index 4724457e5..0939d33cd 100644 --- a/builder/amazon/chroot/step_prepare_device.go +++ b/builder/amazon/chroot/step_prepare_device.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "fmt" "log" "os" diff --git a/builder/amazon/chroot/step_register_ami.go b/builder/amazon/chroot/step_register_ami.go index d73ea8b21..6fa9838b0 100644 --- a/builder/amazon/chroot/step_register_ami.go +++ b/builder/amazon/chroot/step_register_ami.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/chroot/step_snapshot.go b/builder/amazon/chroot/step_snapshot.go index 68a7bce2c..3fb3ff701 100644 --- a/builder/amazon/chroot/step_snapshot.go +++ b/builder/amazon/chroot/step_snapshot.go @@ -1,6 +1,7 @@ package chroot import ( + "context" "errors" "fmt" "time" diff --git a/builder/amazon/common/step_ami_region_copy.go b/builder/amazon/common/step_ami_region_copy.go index 9125453ea..a3d92b467 100644 --- a/builder/amazon/common/step_ami_region_copy.go +++ b/builder/amazon/common/step_ami_region_copy.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "sync" diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 903aea91a..47078b6ac 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index 549987b6b..9c176d3c7 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/common/step_encrypted_ami.go b/builder/amazon/common/step_encrypted_ami.go index 66174bea0..a07c0ee25 100644 --- a/builder/amazon/common/step_encrypted_ami.go +++ b/builder/amazon/common/step_encrypted_ami.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index 28847003d..5e2a236c2 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -1,6 +1,7 @@ package common import ( + "context" "crypto/rsa" "crypto/x509" "encoding/base64" diff --git a/builder/amazon/common/step_key_pair.go b/builder/amazon/common/step_key_pair.go index 3558b1df2..927101fcf 100644 --- a/builder/amazon/common/step_key_pair.go +++ b/builder/amazon/common/step_key_pair.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io/ioutil" "os" diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index 7ba1deb6f..26ab31986 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/common/step_modify_ebs_instance.go b/builder/amazon/common/step_modify_ebs_instance.go index 4145bc669..c2c454e06 100644 --- a/builder/amazon/common/step_modify_ebs_instance.go +++ b/builder/amazon/common/step_modify_ebs_instance.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/common/step_pre_validate.go b/builder/amazon/common/step_pre_validate.go index 57fca3fad..73b4022b7 100644 --- a/builder/amazon/common/step_pre_validate.go +++ b/builder/amazon/common/step_pre_validate.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 6029ac617..c5e3382ec 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -1,6 +1,7 @@ package common import ( + "context" "encoding/base64" "fmt" "io/ioutil" diff --git a/builder/amazon/common/step_security_group.go b/builder/amazon/common/step_security_group.go index 3d3ff8f35..031842cd3 100644 --- a/builder/amazon/common/step_security_group.go +++ b/builder/amazon/common/step_security_group.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "time" diff --git a/builder/amazon/common/step_source_ami_info.go b/builder/amazon/common/step_source_ami_info.go index bc3b9dd17..5e57c2fbf 100644 --- a/builder/amazon/common/step_source_ami_info.go +++ b/builder/amazon/common/step_source_ami_info.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "sort" diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index efef99b8a..10a2f5a45 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws/awserr" diff --git a/builder/amazon/ebs/step_cleanup_volumes.go b/builder/amazon/ebs/step_cleanup_volumes.go index 158f970e0..3fd0de64f 100644 --- a/builder/amazon/ebs/step_cleanup_volumes.go +++ b/builder/amazon/ebs/step_cleanup_volumes.go @@ -1,6 +1,7 @@ package ebs import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/ebs/step_create_ami.go b/builder/amazon/ebs/step_create_ami.go index 1ee7319bd..0dde4fc30 100644 --- a/builder/amazon/ebs/step_create_ami.go +++ b/builder/amazon/ebs/step_create_ami.go @@ -1,6 +1,7 @@ package ebs import ( + "context" "fmt" "github.com/aws/aws-sdk-go/service/ec2" diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index 28c01f52d..002ed00af 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -1,6 +1,7 @@ package ebssurrogate import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/ebssurrogate/step_snapshot_new_root.go b/builder/amazon/ebssurrogate/step_snapshot_new_root.go index 111f20268..3b607fbd0 100644 --- a/builder/amazon/ebssurrogate/step_snapshot_new_root.go +++ b/builder/amazon/ebssurrogate/step_snapshot_new_root.go @@ -1,6 +1,7 @@ package ebssurrogate import ( + "context" "errors" "fmt" "time" diff --git a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go index 42076dec2..a638ec439 100644 --- a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go +++ b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go @@ -1,6 +1,7 @@ package ebsvolume import ( + "context" "fmt" "github.com/aws/aws-sdk-go/service/ec2" diff --git a/builder/amazon/instance/step_bundle_volume.go b/builder/amazon/instance/step_bundle_volume.go index 61c2f5aad..1c8b006b8 100644 --- a/builder/amazon/instance/step_bundle_volume.go +++ b/builder/amazon/instance/step_bundle_volume.go @@ -1,6 +1,7 @@ package instance import ( + "context" "fmt" "github.com/aws/aws-sdk-go/service/ec2" diff --git a/builder/amazon/instance/step_register_ami.go b/builder/amazon/instance/step_register_ami.go index 9fb41d441..c46ff8ae4 100644 --- a/builder/amazon/instance/step_register_ami.go +++ b/builder/amazon/instance/step_register_ami.go @@ -1,6 +1,7 @@ package instance import ( + "context" "fmt" "github.com/aws/aws-sdk-go/aws" diff --git a/builder/amazon/instance/step_upload_bundle.go b/builder/amazon/instance/step_upload_bundle.go index 80ba9e88b..1e7711d42 100644 --- a/builder/amazon/instance/step_upload_bundle.go +++ b/builder/amazon/instance/step_upload_bundle.go @@ -1,6 +1,7 @@ package instance import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/amazon/instance/step_upload_x509_cert.go b/builder/amazon/instance/step_upload_x509_cert.go index 3853a53c1..14ea955e5 100644 --- a/builder/amazon/instance/step_upload_x509_cert.go +++ b/builder/amazon/instance/step_upload_x509_cert.go @@ -1,10 +1,12 @@ package instance import ( + "context" "fmt" + "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "os" ) type StepUploadX509Cert struct{} diff --git a/builder/azure/arm/step_capture_image.go b/builder/azure/arm/step_capture_image.go index 2da5bedc4..9e640a891 100644 --- a/builder/azure/arm/step_capture_image.go +++ b/builder/azure/arm/step_capture_image.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "github.com/Azure/azure-sdk-for-go/arm/compute" diff --git a/builder/azure/arm/step_create_resource_group.go b/builder/azure/arm/step_create_resource_group.go index 787aad132..e0535adf6 100644 --- a/builder/azure/arm/step_create_resource_group.go +++ b/builder/azure/arm/step_create_resource_group.go @@ -1,6 +1,7 @@ package arm import ( + "context" "errors" "fmt" diff --git a/builder/azure/arm/step_delete_os_disk.go b/builder/azure/arm/step_delete_os_disk.go index 92e9f9757..723c87db0 100644 --- a/builder/azure/arm/step_delete_os_disk.go +++ b/builder/azure/arm/step_delete_os_disk.go @@ -1,6 +1,7 @@ package arm import ( + "context" "errors" "fmt" "net/url" diff --git a/builder/azure/arm/step_delete_resource_group.go b/builder/azure/arm/step_delete_resource_group.go index a3bc2073b..a16ebf8f2 100644 --- a/builder/azure/arm/step_delete_resource_group.go +++ b/builder/azure/arm/step_delete_resource_group.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "github.com/Azure/go-autorest/autorest" diff --git a/builder/azure/arm/step_deploy_template.go b/builder/azure/arm/step_deploy_template.go index 06baddb24..af838c301 100644 --- a/builder/azure/arm/step_deploy_template.go +++ b/builder/azure/arm/step_deploy_template.go @@ -1,6 +1,7 @@ package arm import ( + "context" "errors" "fmt" "net/url" diff --git a/builder/azure/arm/step_get_certificate.go b/builder/azure/arm/step_get_certificate.go index df347e468..784826771 100644 --- a/builder/azure/arm/step_get_certificate.go +++ b/builder/azure/arm/step_get_certificate.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "time" diff --git a/builder/azure/arm/step_get_ip_address.go b/builder/azure/arm/step_get_ip_address.go index f6ef7dc1b..ee28f3054 100644 --- a/builder/azure/arm/step_get_ip_address.go +++ b/builder/azure/arm/step_get_ip_address.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "github.com/hashicorp/packer/builder/azure/common/constants" diff --git a/builder/azure/arm/step_get_os_disk.go b/builder/azure/arm/step_get_os_disk.go index 706f37a54..5e32e0eea 100644 --- a/builder/azure/arm/step_get_os_disk.go +++ b/builder/azure/arm/step_get_os_disk.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "github.com/Azure/azure-sdk-for-go/arm/compute" diff --git a/builder/azure/arm/step_power_off_compute.go b/builder/azure/arm/step_power_off_compute.go index e44b13c97..693348325 100644 --- a/builder/azure/arm/step_power_off_compute.go +++ b/builder/azure/arm/step_power_off_compute.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "github.com/hashicorp/packer/builder/azure/common" diff --git a/builder/azure/arm/step_set_certificate.go b/builder/azure/arm/step_set_certificate.go index 4729af0c0..ef8832074 100644 --- a/builder/azure/arm/step_set_certificate.go +++ b/builder/azure/arm/step_set_certificate.go @@ -1,6 +1,8 @@ package arm import ( + "context" + "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" diff --git a/builder/azure/arm/step_test.go b/builder/azure/arm/step_test.go index c0115b003..aa46455e0 100644 --- a/builder/azure/arm/step_test.go +++ b/builder/azure/arm/step_test.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/packer/builder/azure/common" "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/helper/multistep" - "testing" ) func TestProcessStepResultShouldContinueForNonErrors(t *testing.T) { diff --git a/builder/azure/arm/step_validate_template.go b/builder/azure/arm/step_validate_template.go index bdf92e652..92927de5a 100644 --- a/builder/azure/arm/step_validate_template.go +++ b/builder/azure/arm/step_validate_template.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "github.com/hashicorp/packer/builder/azure/common/constants" diff --git a/builder/azure/common/lin/step_create_cert.go b/builder/azure/common/lin/step_create_cert.go index 66dda1a3c..da2cb5bf5 100644 --- a/builder/azure/common/lin/step_create_cert.go +++ b/builder/azure/common/lin/step_create_cert.go @@ -1,6 +1,7 @@ package lin import ( + "context" "crypto/rand" "crypto/rsa" "crypto/sha1" diff --git a/builder/azure/common/lin/step_generalize_os.go b/builder/azure/common/lin/step_generalize_os.go index d7836d22c..cc62f4eec 100644 --- a/builder/azure/common/lin/step_generalize_os.go +++ b/builder/azure/common/lin/step_generalize_os.go @@ -2,10 +2,12 @@ package lin import ( "bytes" + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) type StepGeneralizeOS struct { diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index 1e2e322b0..ff37a540a 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "fmt" "math/rand" "strings" diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 1ca0a4f70..19f6a3c28 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "encoding/base64" "errors" "fmt" diff --git a/builder/cloudstack/step_create_security_group.go b/builder/cloudstack/step_create_security_group.go index fb5f24a4a..c42eec5d5 100644 --- a/builder/cloudstack/step_create_security_group.go +++ b/builder/cloudstack/step_create_security_group.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "fmt" "github.com/hashicorp/packer/common/uuid" diff --git a/builder/cloudstack/step_create_template.go b/builder/cloudstack/step_create_template.go index 928e231d1..4afba8699 100644 --- a/builder/cloudstack/step_create_template.go +++ b/builder/cloudstack/step_create_template.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "fmt" "time" diff --git a/builder/cloudstack/step_keypair.go b/builder/cloudstack/step_keypair.go index 7334da372..e1f002b76 100644 --- a/builder/cloudstack/step_keypair.go +++ b/builder/cloudstack/step_keypair.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "fmt" "io/ioutil" "os" diff --git a/builder/cloudstack/step_prepare_config.go b/builder/cloudstack/step_prepare_config.go index 3c2944c7d..644547018 100644 --- a/builder/cloudstack/step_prepare_config.go +++ b/builder/cloudstack/step_prepare_config.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "fmt" "io/ioutil" "regexp" diff --git a/builder/cloudstack/step_shutdown_instance.go b/builder/cloudstack/step_shutdown_instance.go index 10a4acbdd..a7f07e8b2 100644 --- a/builder/cloudstack/step_shutdown_instance.go +++ b/builder/cloudstack/step_shutdown_instance.go @@ -1,6 +1,7 @@ package cloudstack import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/docker/step_commit.go b/builder/docker/step_commit.go index d32f5f888..d248ee64c 100644 --- a/builder/docker/step_commit.go +++ b/builder/docker/step_commit.go @@ -1,7 +1,9 @@ package docker import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/docker/step_commit_test.go b/builder/docker/step_commit_test.go index b828aa3e2..ff2db0ad7 100644 --- a/builder/docker/step_commit_test.go +++ b/builder/docker/step_commit_test.go @@ -2,10 +2,9 @@ package docker import ( "errors" - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testStepCommitState(t *testing.T) multistep.StateBag { diff --git a/builder/docker/step_connect_docker.go b/builder/docker/step_connect_docker.go index 2e3a3270a..ef0222a91 100644 --- a/builder/docker/step_connect_docker.go +++ b/builder/docker/step_connect_docker.go @@ -1,12 +1,12 @@ package docker import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" "os/exec" "strings" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) type StepConnectDocker struct{} diff --git a/builder/docker/step_export.go b/builder/docker/step_export.go index b11319f81..138e0f00c 100644 --- a/builder/docker/step_export.go +++ b/builder/docker/step_export.go @@ -1,6 +1,7 @@ package docker import ( + "context" "fmt" "os" "path/filepath" diff --git a/builder/docker/step_export_test.go b/builder/docker/step_export_test.go index 622d0ee5a..1b1221e62 100644 --- a/builder/docker/step_export_test.go +++ b/builder/docker/step_export_test.go @@ -3,12 +3,11 @@ package docker import ( "bytes" "errors" - "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testStepExportState(t *testing.T) multistep.StateBag { diff --git a/builder/docker/step_pull.go b/builder/docker/step_pull.go index 946029943..fd011680e 100644 --- a/builder/docker/step_pull.go +++ b/builder/docker/step_pull.go @@ -1,6 +1,7 @@ package docker import ( + "context" "fmt" "log" diff --git a/builder/docker/step_pull_test.go b/builder/docker/step_pull_test.go index 6bd3d5e84..9b8ed1d1b 100644 --- a/builder/docker/step_pull_test.go +++ b/builder/docker/step_pull_test.go @@ -2,10 +2,9 @@ package docker import ( "errors" - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepPull_impl(t *testing.T) { diff --git a/builder/docker/step_run.go b/builder/docker/step_run.go index c5b8fc525..1d2ba6862 100644 --- a/builder/docker/step_run.go +++ b/builder/docker/step_run.go @@ -1,7 +1,9 @@ package docker import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/docker/step_run_test.go b/builder/docker/step_run_test.go index 66bd02baf..9993cb357 100644 --- a/builder/docker/step_run_test.go +++ b/builder/docker/step_run_test.go @@ -1,11 +1,11 @@ package docker import ( + "context" "errors" - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testStepRunState(t *testing.T) multistep.StateBag { diff --git a/builder/docker/step_temp_dir.go b/builder/docker/step_temp_dir.go index d3c1502ff..a5b1d6ade 100644 --- a/builder/docker/step_temp_dir.go +++ b/builder/docker/step_temp_dir.go @@ -1,14 +1,13 @@ package docker import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "io/ioutil" "os" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepTempDir creates a temporary directory that we use in order to diff --git a/builder/docker/step_test.go b/builder/docker/step_test.go index fa0702612..0c7d56649 100644 --- a/builder/docker/step_test.go +++ b/builder/docker/step_test.go @@ -2,9 +2,10 @@ package docker import ( "bytes" + "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/googlecompute/step_check_existing_image.go b/builder/googlecompute/step_check_existing_image.go index 92a79f3fa..ac11600e1 100644 --- a/builder/googlecompute/step_check_existing_image.go +++ b/builder/googlecompute/step_check_existing_image.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/googlecompute/step_check_existing_image_test.go b/builder/googlecompute/step_check_existing_image_test.go index 36f9e110a..1c499e743 100644 --- a/builder/googlecompute/step_check_existing_image_test.go +++ b/builder/googlecompute/step_check_existing_image_test.go @@ -1,10 +1,9 @@ package googlecompute import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCheckExistingImage_impl(t *testing.T) { diff --git a/builder/googlecompute/step_create_image.go b/builder/googlecompute/step_create_image.go index 16434f6c7..72e6a06eb 100644 --- a/builder/googlecompute/step_create_image.go +++ b/builder/googlecompute/step_create_image.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "fmt" "time" diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index 1a713f123..ee3b6643b 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "fmt" "io/ioutil" diff --git a/builder/googlecompute/step_create_ssh_key.go b/builder/googlecompute/step_create_ssh_key.go index f121e3dae..7d5a24555 100644 --- a/builder/googlecompute/step_create_ssh_key.go +++ b/builder/googlecompute/step_create_ssh_key.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "crypto/rand" "crypto/rsa" "crypto/x509" diff --git a/builder/googlecompute/step_create_windows_password.go b/builder/googlecompute/step_create_windows_password.go index b7d09e10d..3386f6fbc 100644 --- a/builder/googlecompute/step_create_windows_password.go +++ b/builder/googlecompute/step_create_windows_password.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "crypto/rand" "crypto/rsa" "crypto/x509" diff --git a/builder/googlecompute/step_instance_info.go b/builder/googlecompute/step_instance_info.go index 5604b3e9b..d67984b75 100644 --- a/builder/googlecompute/step_instance_info.go +++ b/builder/googlecompute/step_instance_info.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "fmt" "time" diff --git a/builder/googlecompute/step_instance_info_test.go b/builder/googlecompute/step_instance_info_test.go index 8ced83c5d..3918a009e 100644 --- a/builder/googlecompute/step_instance_info_test.go +++ b/builder/googlecompute/step_instance_info_test.go @@ -2,11 +2,10 @@ package googlecompute import ( "errors" - "github.com/hashicorp/packer/helper/multistep" "testing" "time" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepInstanceInfo_impl(t *testing.T) { diff --git a/builder/googlecompute/step_teardown_instance.go b/builder/googlecompute/step_teardown_instance.go index e40e2fc7b..27f9fee35 100644 --- a/builder/googlecompute/step_teardown_instance.go +++ b/builder/googlecompute/step_teardown_instance.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "fmt" "time" diff --git a/builder/googlecompute/step_teardown_instance_test.go b/builder/googlecompute/step_teardown_instance_test.go index 295230e01..f19dac960 100644 --- a/builder/googlecompute/step_teardown_instance_test.go +++ b/builder/googlecompute/step_teardown_instance_test.go @@ -1,10 +1,9 @@ package googlecompute import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepTeardownInstance_impl(t *testing.T) { diff --git a/builder/googlecompute/step_wait_startup_script.go b/builder/googlecompute/step_wait_startup_script.go index 9770d7cb3..efc2a78f7 100644 --- a/builder/googlecompute/step_wait_startup_script.go +++ b/builder/googlecompute/step_wait_startup_script.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "fmt" diff --git a/builder/googlecompute/step_wait_startup_script_test.go b/builder/googlecompute/step_wait_startup_script_test.go index a48176a61..51643eb2d 100644 --- a/builder/googlecompute/step_wait_startup_script_test.go +++ b/builder/googlecompute/step_wait_startup_script_test.go @@ -1,6 +1,8 @@ package googlecompute import ( + "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/stretchr/testify/assert" ) diff --git a/builder/hyperv/common/step_clone_vm.go b/builder/hyperv/common/step_clone_vm.go index cda0c5da5..f6dc9e390 100644 --- a/builder/hyperv/common/step_clone_vm.go +++ b/builder/hyperv/common/step_clone_vm.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "path/filepath" diff --git a/builder/hyperv/common/step_configure_ip.go b/builder/hyperv/common/step_configure_ip.go index d9ca74344..41d945a0d 100644 --- a/builder/hyperv/common/step_configure_ip.go +++ b/builder/hyperv/common/step_configure_ip.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "strings" diff --git a/builder/hyperv/common/step_configure_vlan.go b/builder/hyperv/common/step_configure_vlan.go index ea26af22e..a167b9ed1 100644 --- a/builder/hyperv/common/step_configure_vlan.go +++ b/builder/hyperv/common/step_configure_vlan.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/hyperv/common/step_create_external_switch.go b/builder/hyperv/common/step_create_external_switch.go index 1e0ea6976..56e6fa6e8 100644 --- a/builder/hyperv/common/step_create_external_switch.go +++ b/builder/hyperv/common/step_create_external_switch.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/hashicorp/packer/common/uuid" diff --git a/builder/hyperv/common/step_create_switch.go b/builder/hyperv/common/step_create_switch.go index 0b1df3342..4b5ef48e2 100644 --- a/builder/hyperv/common/step_create_switch.go +++ b/builder/hyperv/common/step_create_switch.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_create_tempdir.go b/builder/hyperv/common/step_create_tempdir.go index a9829608c..1a9767fe5 100644 --- a/builder/hyperv/common/step_create_tempdir.go +++ b/builder/hyperv/common/step_create_tempdir.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io/ioutil" "os" diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index 1e28889c7..291fdc5dc 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "path/filepath" diff --git a/builder/hyperv/common/step_disable_vlan.go b/builder/hyperv/common/step_disable_vlan.go index acd0d323d..0d4882ec1 100644 --- a/builder/hyperv/common/step_disable_vlan.go +++ b/builder/hyperv/common/step_disable_vlan.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_enable_integration_service.go b/builder/hyperv/common/step_enable_integration_service.go index ddb74c41d..e3f8fd70a 100644 --- a/builder/hyperv/common/step_enable_integration_service.go +++ b/builder/hyperv/common/step_enable_integration_service.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_export_vm.go b/builder/hyperv/common/step_export_vm.go index f5ff4cf93..6de5dbb70 100644 --- a/builder/hyperv/common/step_export_vm.go +++ b/builder/hyperv/common/step_export_vm.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io/ioutil" "path/filepath" diff --git a/builder/hyperv/common/step_mount_dvddrive.go b/builder/hyperv/common/step_mount_dvddrive.go index 8957fe6c2..945c6a86d 100644 --- a/builder/hyperv/common/step_mount_dvddrive.go +++ b/builder/hyperv/common/step_mount_dvddrive.go @@ -1,15 +1,14 @@ package common import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "path/filepath" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepMountDvdDrive struct { diff --git a/builder/hyperv/common/step_mount_floppydrive.go b/builder/hyperv/common/step_mount_floppydrive.go index ecf9b0194..1ae03d1db 100644 --- a/builder/hyperv/common/step_mount_floppydrive.go +++ b/builder/hyperv/common/step_mount_floppydrive.go @@ -1,17 +1,16 @@ package common import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "io" "io/ioutil" "log" "os" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const ( diff --git a/builder/hyperv/common/step_mount_guest_additions.go b/builder/hyperv/common/step_mount_guest_additions.go index f20e070d3..71b6c3eec 100644 --- a/builder/hyperv/common/step_mount_guest_additions.go +++ b/builder/hyperv/common/step_mount_guest_additions.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) type StepMountGuestAdditions struct { diff --git a/builder/hyperv/common/step_mount_secondary_dvd_images.go b/builder/hyperv/common/step_mount_secondary_dvd_images.go index 9b29a84a0..c23e39fac 100644 --- a/builder/hyperv/common/step_mount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_mount_secondary_dvd_images.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) type StepMountSecondaryDvdImages struct { diff --git a/builder/hyperv/common/step_output_dir.go b/builder/hyperv/common/step_output_dir.go index cad96b98e..fc39d08b2 100644 --- a/builder/hyperv/common/step_output_dir.go +++ b/builder/hyperv/common/step_output_dir.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "os" diff --git a/builder/hyperv/common/step_polling_installation.go b/builder/hyperv/common/step_polling_installation.go index 092c01b17..b9d2984f6 100644 --- a/builder/hyperv/common/step_polling_installation.go +++ b/builder/hyperv/common/step_polling_installation.go @@ -2,6 +2,7 @@ package common import ( "bytes" + "context" "fmt" "log" "os/exec" diff --git a/builder/hyperv/common/step_reboot_vm.go b/builder/hyperv/common/step_reboot_vm.go index 850c6aac9..8e2bec1b8 100644 --- a/builder/hyperv/common/step_reboot_vm.go +++ b/builder/hyperv/common/step_reboot_vm.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) type StepRebootVm struct { diff --git a/builder/hyperv/common/step_run.go b/builder/hyperv/common/step_run.go index ead739667..cd8213c5e 100644 --- a/builder/hyperv/common/step_run.go +++ b/builder/hyperv/common/step_run.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) type StepRun struct { diff --git a/builder/hyperv/common/step_shutdown.go b/builder/hyperv/common/step_shutdown.go index ddced9619..b37716f60 100644 --- a/builder/hyperv/common/step_shutdown.go +++ b/builder/hyperv/common/step_shutdown.go @@ -2,6 +2,7 @@ package common import ( "bytes" + "context" "errors" "fmt" "log" diff --git a/builder/hyperv/common/step_sleep.go b/builder/hyperv/common/step_sleep.go index fbf671cdf..e65bcf0b1 100644 --- a/builder/hyperv/common/step_sleep.go +++ b/builder/hyperv/common/step_sleep.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) type StepSleep struct { diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index 515c30907..43deee1fd 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "strings" diff --git a/builder/hyperv/common/step_unmount_dvddrive.go b/builder/hyperv/common/step_unmount_dvddrive.go index cb62bc131..010e8b067 100644 --- a/builder/hyperv/common/step_unmount_dvddrive.go +++ b/builder/hyperv/common/step_unmount_dvddrive.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_unmount_floppydrive.go b/builder/hyperv/common/step_unmount_floppydrive.go index 07dff3b70..34f09aaa0 100644 --- a/builder/hyperv/common/step_unmount_floppydrive.go +++ b/builder/hyperv/common/step_unmount_floppydrive.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_unmount_guest_additions.go b/builder/hyperv/common/step_unmount_guest_additions.go index 112c9c825..06600ddaa 100644 --- a/builder/hyperv/common/step_unmount_guest_additions.go +++ b/builder/hyperv/common/step_unmount_guest_additions.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_unmount_secondary_dvd_images.go b/builder/hyperv/common/step_unmount_secondary_dvd_images.go index 3de0f7ac6..0f74d2789 100644 --- a/builder/hyperv/common/step_unmount_secondary_dvd_images.go +++ b/builder/hyperv/common/step_unmount_secondary_dvd_images.go @@ -1,7 +1,9 @@ package common import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/builder/hyperv/common/step_wait_for_install_to_complete.go b/builder/hyperv/common/step_wait_for_install_to_complete.go index ee7d11beb..0a40730b3 100644 --- a/builder/hyperv/common/step_wait_for_install_to_complete.go +++ b/builder/hyperv/common/step_wait_for_install_to_complete.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) const ( diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 74c8de44e..fa164d85f 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -11,7 +11,6 @@ import ( hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "os" ) func testConfig() map[string]interface{} { diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 7792a365c..e428672c6 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -11,8 +11,6 @@ import ( hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "io/ioutil" - "os" ) func testConfig() map[string]interface{} { diff --git a/builder/lxc/builder.go b/builder/lxc/builder.go index 82683b890..8c239cd9b 100644 --- a/builder/lxc/builder.go +++ b/builder/lxc/builder.go @@ -9,9 +9,6 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "log" - "os" - "path/filepath" ) // The unique ID for this builder diff --git a/builder/lxc/step_export.go b/builder/lxc/step_export.go index 2bafdeb41..f01b30074 100644 --- a/builder/lxc/step_export.go +++ b/builder/lxc/step_export.go @@ -2,9 +2,8 @@ package lxc import ( "bytes" + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "io" "log" "os" @@ -12,8 +11,8 @@ import ( "path/filepath" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepExport struct{} diff --git a/builder/lxc/step_lxc_create.go b/builder/lxc/step_lxc_create.go index 9efb7bc87..98dce3a7c 100644 --- a/builder/lxc/step_lxc_create.go +++ b/builder/lxc/step_lxc_create.go @@ -2,16 +2,15 @@ package lxc import ( "bytes" + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "os/exec" "path/filepath" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepLxcCreate struct{} diff --git a/builder/lxc/step_prepare_output_dir.go b/builder/lxc/step_prepare_output_dir.go index 1dd082580..25479fd8a 100644 --- a/builder/lxc/step_prepare_output_dir.go +++ b/builder/lxc/step_prepare_output_dir.go @@ -1,14 +1,13 @@ package lxc import ( - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" + "context" "log" "os" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepPrepareOutputDir struct{} diff --git a/builder/lxc/step_provision.go b/builder/lxc/step_provision.go index 937435d85..ac33eb301 100644 --- a/builder/lxc/step_provision.go +++ b/builder/lxc/step_provision.go @@ -1,9 +1,11 @@ package lxc import ( + "context" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // StepProvision provisions the instance within a chroot. diff --git a/builder/lxc/step_wait_init.go b/builder/lxc/step_wait_init.go index 19383fb62..4e055a690 100644 --- a/builder/lxc/step_wait_init.go +++ b/builder/lxc/step_wait_init.go @@ -1,16 +1,15 @@ package lxc import ( + "context" "errors" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepWaitInit struct { diff --git a/builder/lxd/builder.go b/builder/lxd/builder.go index d1b040853..290b8a631 100644 --- a/builder/lxd/builder.go +++ b/builder/lxd/builder.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "log" ) // The unique ID for this builder diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index f1a6f6b45..de34a5cb4 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -1,10 +1,12 @@ package lxd import ( + "context" "fmt" + "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) type stepLxdLaunch struct{} diff --git a/builder/lxd/step_provision.go b/builder/lxd/step_provision.go index dedd1a2ae..509006d77 100644 --- a/builder/lxd/step_provision.go +++ b/builder/lxd/step_provision.go @@ -1,9 +1,11 @@ package lxd import ( + "context" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // StepProvision provisions the container diff --git a/builder/lxd/step_publish.go b/builder/lxd/step_publish.go index 4a6c206fe..4dc21880f 100644 --- a/builder/lxd/step_publish.go +++ b/builder/lxd/step_publish.go @@ -1,10 +1,12 @@ package lxd import ( + "context" "fmt" + "regexp" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "regexp" ) type stepPublish struct{} diff --git a/builder/oneandone/builder.go b/builder/oneandone/builder.go index 7b7be84aa..4b84b3938 100644 --- a/builder/oneandone/builder.go +++ b/builder/oneandone/builder.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) const BuilderId = "packer.oneandone" diff --git a/builder/oneandone/step_create_server.go b/builder/oneandone/step_create_server.go index 8aa05fb48..cffd8c440 100644 --- a/builder/oneandone/step_create_server.go +++ b/builder/oneandone/step_create_server.go @@ -1,6 +1,7 @@ package oneandone import ( + "context" "fmt" "strings" "time" @@ -8,8 +9,6 @@ import ( "github.com/1and1/oneandone-cloudserver-sdk-go" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "strings" - "time" ) type stepCreateServer struct{} diff --git a/builder/oneandone/step_create_sshkey.go b/builder/oneandone/step_create_sshkey.go index 9a1a58528..a27561c1f 100644 --- a/builder/oneandone/step_create_sshkey.go +++ b/builder/oneandone/step_create_sshkey.go @@ -1,9 +1,12 @@ package oneandone import ( + "context" "crypto/x509" "encoding/pem" "fmt" + "io/ioutil" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "golang.org/x/crypto/ssh" diff --git a/builder/oneandone/step_take_snapshot.go b/builder/oneandone/step_take_snapshot.go index cedfb604a..65a3f7156 100644 --- a/builder/oneandone/step_take_snapshot.go +++ b/builder/oneandone/step_take_snapshot.go @@ -1,6 +1,8 @@ package oneandone import ( + "context" + "github.com/1and1/oneandone-cloudserver-sdk-go" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" diff --git a/builder/openstack/step_add_image_members.go b/builder/openstack/step_add_image_members.go index eda4122ce..e23e54588 100644 --- a/builder/openstack/step_add_image_members.go +++ b/builder/openstack/step_add_image_members.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "github.com/gophercloud/gophercloud/openstack/imageservice/v2/members" diff --git a/builder/openstack/step_allocate_ip.go b/builder/openstack/step_allocate_ip.go index 15f214d17..fb53ce434 100644 --- a/builder/openstack/step_allocate_ip.go +++ b/builder/openstack/step_allocate_ip.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" diff --git a/builder/openstack/step_create_image.go b/builder/openstack/step_create_image.go index 777a3cb6a..de8a6f4f6 100644 --- a/builder/openstack/step_create_image.go +++ b/builder/openstack/step_create_image.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "log" "time" diff --git a/builder/openstack/step_get_password.go b/builder/openstack/step_get_password.go index 95f52e194..4b962db4b 100644 --- a/builder/openstack/step_get_password.go +++ b/builder/openstack/step_get_password.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "crypto/rsa" "fmt" "log" diff --git a/builder/openstack/step_key_pair.go b/builder/openstack/step_key_pair.go index fb46c1392..c4eba5804 100644 --- a/builder/openstack/step_key_pair.go +++ b/builder/openstack/step_key_pair.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "io/ioutil" "log" diff --git a/builder/openstack/step_load_extensions.go b/builder/openstack/step_load_extensions.go index a5ffe8145..b11cf5527 100644 --- a/builder/openstack/step_load_extensions.go +++ b/builder/openstack/step_load_extensions.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "log" diff --git a/builder/openstack/step_load_flavor.go b/builder/openstack/step_load_flavor.go index 00f1b7092..8c331aa6a 100644 --- a/builder/openstack/step_load_flavor.go +++ b/builder/openstack/step_load_flavor.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "log" diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index ebbc45773..bb09f85b7 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "io/ioutil" "log" diff --git a/builder/openstack/step_stop_server.go b/builder/openstack/step_stop_server.go index bc651b7ce..1c864eef0 100644 --- a/builder/openstack/step_stop_server.go +++ b/builder/openstack/step_stop_server.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/startstop" diff --git a/builder/openstack/step_update_image_visibility.go b/builder/openstack/step_update_image_visibility.go index bd814638b..8d9a3bc7c 100644 --- a/builder/openstack/step_update_image_visibility.go +++ b/builder/openstack/step_update_image_visibility.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" imageservice "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" diff --git a/builder/openstack/step_wait_for_rackconnect.go b/builder/openstack/step_wait_for_rackconnect.go index f214e0894..6cbe2ed0e 100644 --- a/builder/openstack/step_wait_for_rackconnect.go +++ b/builder/openstack/step_wait_for_rackconnect.go @@ -1,6 +1,7 @@ package openstack import ( + "context" "fmt" "time" diff --git a/builder/oracle/oci/step_create_instance.go b/builder/oracle/oci/step_create_instance.go index cb1ce6642..375b92b1b 100644 --- a/builder/oracle/oci/step_create_instance.go +++ b/builder/oracle/oci/step_create_instance.go @@ -1,6 +1,7 @@ package oci import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/oracle/oci/step_image.go b/builder/oracle/oci/step_image.go index 46c7ed8ba..ff767f709 100644 --- a/builder/oracle/oci/step_image.go +++ b/builder/oracle/oci/step_image.go @@ -1,6 +1,7 @@ package oci import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/oracle/oci/step_instance_info.go b/builder/oracle/oci/step_instance_info.go index 9b79529cc..d3e024978 100644 --- a/builder/oracle/oci/step_instance_info.go +++ b/builder/oracle/oci/step_instance_info.go @@ -1,6 +1,7 @@ package oci import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/oracle/oci/step_ssh_key_pair.go b/builder/oracle/oci/step_ssh_key_pair.go index c9e80e54b..9fa83c17d 100644 --- a/builder/oracle/oci/step_ssh_key_pair.go +++ b/builder/oracle/oci/step_ssh_key_pair.go @@ -1,6 +1,7 @@ package oci import ( + "context" "crypto/rand" "crypto/rsa" "crypto/x509" diff --git a/builder/parallels/common/step_attach_floppy.go b/builder/parallels/common/step_attach_floppy.go index bd8116597..fa9566011 100644 --- a/builder/parallels/common/step_attach_floppy.go +++ b/builder/parallels/common/step_attach_floppy.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" diff --git a/builder/parallels/common/step_attach_parallels_tools.go b/builder/parallels/common/step_attach_parallels_tools.go index 645cec0d7..1c1ea31b4 100644 --- a/builder/parallels/common/step_attach_parallels_tools.go +++ b/builder/parallels/common/step_attach_parallels_tools.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" diff --git a/builder/parallels/common/step_compact_disk.go b/builder/parallels/common/step_compact_disk.go index 90f05b7f9..85688de51 100644 --- a/builder/parallels/common/step_compact_disk.go +++ b/builder/parallels/common/step_compact_disk.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/parallels/common/step_output_dir.go b/builder/parallels/common/step_output_dir.go index c94ab3928..f6f092c4a 100644 --- a/builder/parallels/common/step_output_dir.go +++ b/builder/parallels/common/step_output_dir.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "os" diff --git a/builder/parallels/common/step_prepare_parallels_tools.go b/builder/parallels/common/step_prepare_parallels_tools.go index c64fd395b..5da892782 100644 --- a/builder/parallels/common/step_prepare_parallels_tools.go +++ b/builder/parallels/common/step_prepare_parallels_tools.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "os" diff --git a/builder/parallels/common/step_prlctl.go b/builder/parallels/common/step_prlctl.go index eea179a70..9ae6ec7e9 100644 --- a/builder/parallels/common/step_prlctl.go +++ b/builder/parallels/common/step_prlctl.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "strings" diff --git a/builder/parallels/common/step_run.go b/builder/parallels/common/step_run.go index b37e536d5..073ad0550 100644 --- a/builder/parallels/common/step_run.go +++ b/builder/parallels/common/step_run.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "time" diff --git a/builder/parallels/common/step_shutdown.go b/builder/parallels/common/step_shutdown.go index 10a4c5a3f..7f9d3b663 100644 --- a/builder/parallels/common/step_shutdown.go +++ b/builder/parallels/common/step_shutdown.go @@ -2,6 +2,7 @@ package common import ( "bytes" + "context" "errors" "fmt" "log" diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index bd6adbfd8..e39a90b6c 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "strings" diff --git a/builder/parallels/common/step_upload_parallels_tools.go b/builder/parallels/common/step_upload_parallels_tools.go index 86bd5171b..0da0b26e0 100644 --- a/builder/parallels/common/step_upload_parallels_tools.go +++ b/builder/parallels/common/step_upload_parallels_tools.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "os" diff --git a/builder/parallels/common/step_upload_version.go b/builder/parallels/common/step_upload_version.go index 982f38f9f..1a1bfcf0c 100644 --- a/builder/parallels/common/step_upload_version.go +++ b/builder/parallels/common/step_upload_version.go @@ -2,6 +2,7 @@ package common import ( "bytes" + "context" "fmt" "log" diff --git a/builder/parallels/iso/step_attach_iso.go b/builder/parallels/iso/step_attach_iso.go index bfb7bacf9..a4cf634a8 100644 --- a/builder/parallels/iso/step_attach_iso.go +++ b/builder/parallels/iso/step_attach_iso.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" "log" diff --git a/builder/parallels/iso/step_create_disk.go b/builder/parallels/iso/step_create_disk.go index d98f8c5b4..42640f5a8 100644 --- a/builder/parallels/iso/step_create_disk.go +++ b/builder/parallels/iso/step_create_disk.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" "strconv" diff --git a/builder/parallels/iso/step_create_vm.go b/builder/parallels/iso/step_create_vm.go index 255bafaaa..8a4e22517 100644 --- a/builder/parallels/iso/step_create_vm.go +++ b/builder/parallels/iso/step_create_vm.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" diff --git a/builder/parallels/iso/step_set_boot_order.go b/builder/parallels/iso/step_set_boot_order.go index 5b44d98af..cfcda6080 100644 --- a/builder/parallels/iso/step_set_boot_order.go +++ b/builder/parallels/iso/step_set_boot_order.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" diff --git a/builder/parallels/pvm/step_import.go b/builder/parallels/pvm/step_import.go index c8b97dd54..0907c6b44 100644 --- a/builder/parallels/pvm/step_import.go +++ b/builder/parallels/pvm/step_import.go @@ -1,6 +1,7 @@ package pvm import ( + "context" "fmt" parallelscommon "github.com/hashicorp/packer/builder/parallels/common" diff --git a/builder/profitbricks/builder.go b/builder/profitbricks/builder.go index fc7734a07..6a1428075 100644 --- a/builder/profitbricks/builder.go +++ b/builder/profitbricks/builder.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) const BuilderId = "packer.profitbricks" diff --git a/builder/profitbricks/step_create_server.go b/builder/profitbricks/step_create_server.go index 926864118..00742762a 100644 --- a/builder/profitbricks/step_create_server.go +++ b/builder/profitbricks/step_create_server.go @@ -1,6 +1,7 @@ package profitbricks import ( + "context" "encoding/json" "errors" "fmt" diff --git a/builder/profitbricks/step_create_ssh_key.go b/builder/profitbricks/step_create_ssh_key.go index 4c1a75d18..be0b973a8 100644 --- a/builder/profitbricks/step_create_ssh_key.go +++ b/builder/profitbricks/step_create_ssh_key.go @@ -1,9 +1,12 @@ package profitbricks import ( + "context" "crypto/x509" "encoding/pem" "fmt" + "io/ioutil" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "golang.org/x/crypto/ssh" diff --git a/builder/profitbricks/step_take_snapshot.go b/builder/profitbricks/step_take_snapshot.go index 8cbc208b8..a3bfe2d7d 100644 --- a/builder/profitbricks/step_take_snapshot.go +++ b/builder/profitbricks/step_take_snapshot.go @@ -1,6 +1,7 @@ package profitbricks import ( + "context" "encoding/json" "time" diff --git a/builder/qemu/step_boot_wait.go b/builder/qemu/step_boot_wait.go index fe7025b84..0c3935004 100644 --- a/builder/qemu/step_boot_wait.go +++ b/builder/qemu/step_boot_wait.go @@ -1,10 +1,12 @@ package qemu import ( + "context" "fmt" + "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "time" ) // stepBootWait waits the configured time period. diff --git a/builder/qemu/step_configure_vnc.go b/builder/qemu/step_configure_vnc.go index 5d412b811..1f1cd088d 100644 --- a/builder/qemu/step_configure_vnc.go +++ b/builder/qemu/step_configure_vnc.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "log" "math/rand" diff --git a/builder/qemu/step_convert_disk.go b/builder/qemu/step_convert_disk.go index 209361f5d..bc5c3f3b1 100644 --- a/builder/qemu/step_convert_disk.go +++ b/builder/qemu/step_convert_disk.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "path/filepath" diff --git a/builder/qemu/step_copy_disk.go b/builder/qemu/step_copy_disk.go index a6a2e8ca1..51ca47a1d 100644 --- a/builder/qemu/step_copy_disk.go +++ b/builder/qemu/step_copy_disk.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "path/filepath" diff --git a/builder/qemu/step_create_disk.go b/builder/qemu/step_create_disk.go index 05b5d0833..4472903f1 100644 --- a/builder/qemu/step_create_disk.go +++ b/builder/qemu/step_create_disk.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "path/filepath" diff --git a/builder/qemu/step_forward_ssh.go b/builder/qemu/step_forward_ssh.go index 296c94d19..6e9efaca1 100644 --- a/builder/qemu/step_forward_ssh.go +++ b/builder/qemu/step_forward_ssh.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "log" "math/rand" diff --git a/builder/qemu/step_prepare_output_dir.go b/builder/qemu/step_prepare_output_dir.go index f24138c4c..8eeebb4e1 100644 --- a/builder/qemu/step_prepare_output_dir.go +++ b/builder/qemu/step_prepare_output_dir.go @@ -1,14 +1,13 @@ package qemu import ( - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" + "context" "log" "os" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepPrepareOutputDir struct{} diff --git a/builder/qemu/step_resize_disk.go b/builder/qemu/step_resize_disk.go index 63b430187..8ffab5931 100644 --- a/builder/qemu/step_resize_disk.go +++ b/builder/qemu/step_resize_disk.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "path/filepath" diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index 463c8bf07..c524d5514 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "log" "path/filepath" diff --git a/builder/qemu/step_set_iso.go b/builder/qemu/step_set_iso.go index e17bbd254..dba34777f 100644 --- a/builder/qemu/step_set_iso.go +++ b/builder/qemu/step_set_iso.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "net/http" diff --git a/builder/qemu/step_shutdown.go b/builder/qemu/step_shutdown.go index 394fc16fa..9c5f89f6c 100644 --- a/builder/qemu/step_shutdown.go +++ b/builder/qemu/step_shutdown.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "errors" "fmt" "log" diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index dbc896a48..f1dc895e9 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -1,6 +1,7 @@ package qemu import ( + "context" "fmt" "log" "net" @@ -17,7 +18,6 @@ import ( "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/go-vnc" - "os" ) const KeyLeftShift uint32 = 0xFFE1 diff --git a/builder/triton/step_create_image_from_machine.go b/builder/triton/step_create_image_from_machine.go index df83e5205..425a6690b 100644 --- a/builder/triton/step_create_image_from_machine.go +++ b/builder/triton/step_create_image_from_machine.go @@ -1,6 +1,7 @@ package triton import ( + "context" "fmt" "time" diff --git a/builder/triton/step_create_source_machine.go b/builder/triton/step_create_source_machine.go index bca123508..c3097fae2 100644 --- a/builder/triton/step_create_source_machine.go +++ b/builder/triton/step_create_source_machine.go @@ -1,6 +1,7 @@ package triton import ( + "context" "fmt" "time" diff --git a/builder/triton/step_delete_machine.go b/builder/triton/step_delete_machine.go index 28d27f268..8f9e1bc1f 100644 --- a/builder/triton/step_delete_machine.go +++ b/builder/triton/step_delete_machine.go @@ -1,6 +1,7 @@ package triton import ( + "context" "fmt" "time" diff --git a/builder/triton/step_stop_machine.go b/builder/triton/step_stop_machine.go index 6c01805a5..73fa3f4d6 100644 --- a/builder/triton/step_stop_machine.go +++ b/builder/triton/step_stop_machine.go @@ -1,6 +1,7 @@ package triton import ( + "context" "fmt" "time" diff --git a/builder/triton/step_test.go b/builder/triton/step_test.go index 00fef044a..bccc398c7 100644 --- a/builder/triton/step_test.go +++ b/builder/triton/step_test.go @@ -2,9 +2,10 @@ package triton import ( "bytes" + "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/triton/step_wait_for_stop_to_not_fail.go b/builder/triton/step_wait_for_stop_to_not_fail.go index ff777d890..de0a7cc84 100644 --- a/builder/triton/step_wait_for_stop_to_not_fail.go +++ b/builder/triton/step_wait_for_stop_to_not_fail.go @@ -1,6 +1,7 @@ package triton import ( + "context" "time" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/virtualbox/common/step_attach_floppy.go b/builder/virtualbox/common/step_attach_floppy.go index f8c20f3f5..6c73aa4b4 100644 --- a/builder/virtualbox/common/step_attach_floppy.go +++ b/builder/virtualbox/common/step_attach_floppy.go @@ -1,17 +1,16 @@ package common import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "io" "io/ioutil" "log" "os" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step attaches the ISO to the virtual machine. diff --git a/builder/virtualbox/common/step_attach_floppy_test.go b/builder/virtualbox/common/step_attach_floppy_test.go index 85f8ca0c2..9dba8adf1 100644 --- a/builder/virtualbox/common/step_attach_floppy_test.go +++ b/builder/virtualbox/common/step_attach_floppy_test.go @@ -1,12 +1,11 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepAttachFloppy_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_attach_guest_additions.go b/builder/virtualbox/common/step_attach_guest_additions.go index c6b88d1c8..d5698c372 100644 --- a/builder/virtualbox/common/step_attach_guest_additions.go +++ b/builder/virtualbox/common/step_attach_guest_additions.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // This step attaches the VirtualBox guest additions as a inserted CD onto diff --git a/builder/virtualbox/common/step_configure_vrdp.go b/builder/virtualbox/common/step_configure_vrdp.go index 2cf2659d8..6cc960ad3 100644 --- a/builder/virtualbox/common/step_configure_vrdp.go +++ b/builder/virtualbox/common/step_configure_vrdp.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "math/rand" diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 750f825e5..1aebca144 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -2,6 +2,7 @@ package common import ( "bytes" + "context" "fmt" "io" "io/ioutil" diff --git a/builder/virtualbox/common/step_export.go b/builder/virtualbox/common/step_export.go index a09b5c01c..03b02e8e4 100644 --- a/builder/virtualbox/common/step_export.go +++ b/builder/virtualbox/common/step_export.go @@ -1,16 +1,15 @@ package common import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "path/filepath" "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step cleans up forwarded ports and exports the VM to an OVF. diff --git a/builder/virtualbox/common/step_export_test.go b/builder/virtualbox/common/step_export_test.go index fee2cafdb..1bea8df57 100644 --- a/builder/virtualbox/common/step_export_test.go +++ b/builder/virtualbox/common/step_export_test.go @@ -1,10 +1,9 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepExport_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_forward_ssh.go b/builder/virtualbox/common/step_forward_ssh.go index 4bcd2dc66..b4e3b2f25 100644 --- a/builder/virtualbox/common/step_forward_ssh.go +++ b/builder/virtualbox/common/step_forward_ssh.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "math/rand" diff --git a/builder/virtualbox/common/step_output_dir.go b/builder/virtualbox/common/step_output_dir.go index cad96b98e..fc39d08b2 100644 --- a/builder/virtualbox/common/step_output_dir.go +++ b/builder/virtualbox/common/step_output_dir.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "os" diff --git a/builder/virtualbox/common/step_output_dir_test.go b/builder/virtualbox/common/step_output_dir_test.go index 48f4634f4..5066e0e56 100644 --- a/builder/virtualbox/common/step_output_dir_test.go +++ b/builder/virtualbox/common/step_output_dir_test.go @@ -1,12 +1,11 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testStepOutputDir(t *testing.T) *StepOutputDir { diff --git a/builder/virtualbox/common/step_remove_devices.go b/builder/virtualbox/common/step_remove_devices.go index 4a4a24a9e..835fd5af8 100644 --- a/builder/virtualbox/common/step_remove_devices.go +++ b/builder/virtualbox/common/step_remove_devices.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" diff --git a/builder/virtualbox/common/step_remove_devices_test.go b/builder/virtualbox/common/step_remove_devices_test.go index 9a2e8ee3a..0d9f6bbe9 100644 --- a/builder/virtualbox/common/step_remove_devices_test.go +++ b/builder/virtualbox/common/step_remove_devices_test.go @@ -1,10 +1,9 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepRemoveDevices_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_run.go b/builder/virtualbox/common/step_run.go index 391d8c25e..62d98d894 100644 --- a/builder/virtualbox/common/step_run.go +++ b/builder/virtualbox/common/step_run.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "time" diff --git a/builder/virtualbox/common/step_shutdown.go b/builder/virtualbox/common/step_shutdown.go index 7acf97683..af2539cac 100644 --- a/builder/virtualbox/common/step_shutdown.go +++ b/builder/virtualbox/common/step_shutdown.go @@ -1,15 +1,14 @@ package common import ( + "context" "errors" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step shuts down the machine. It first attempts to do so gracefully, diff --git a/builder/virtualbox/common/step_shutdown_test.go b/builder/virtualbox/common/step_shutdown_test.go index aa36a6c91..d38b3378c 100644 --- a/builder/virtualbox/common/step_shutdown_test.go +++ b/builder/virtualbox/common/step_shutdown_test.go @@ -1,13 +1,11 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "testing" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) func TestStepShutdown_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_suppress_messages.go b/builder/virtualbox/common/step_suppress_messages.go index 1805a0535..369911bdb 100644 --- a/builder/virtualbox/common/step_suppress_messages.go +++ b/builder/virtualbox/common/step_suppress_messages.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // This step sets some variables in VirtualBox so that annoying diff --git a/builder/virtualbox/common/step_suppress_messages_test.go b/builder/virtualbox/common/step_suppress_messages_test.go index d5609d456..ad3a59fd7 100644 --- a/builder/virtualbox/common/step_suppress_messages_test.go +++ b/builder/virtualbox/common/step_suppress_messages_test.go @@ -2,10 +2,9 @@ package common import ( "errors" - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepSuppressMessages_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_test.go b/builder/virtualbox/common/step_test.go index ec0854415..c8a12abb6 100644 --- a/builder/virtualbox/common/step_test.go +++ b/builder/virtualbox/common/step_test.go @@ -2,9 +2,10 @@ package common import ( "bytes" + "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 997805732..cb5b43648 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "strings" diff --git a/builder/virtualbox/common/step_upload_guest_additions.go b/builder/virtualbox/common/step_upload_guest_additions.go index 6de891ffd..c77ef7d22 100644 --- a/builder/virtualbox/common/step_upload_guest_additions.go +++ b/builder/virtualbox/common/step_upload_guest_additions.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "os" diff --git a/builder/virtualbox/common/step_upload_version.go b/builder/virtualbox/common/step_upload_version.go index fa154c7ae..deaf8824d 100644 --- a/builder/virtualbox/common/step_upload_version.go +++ b/builder/virtualbox/common/step_upload_version.go @@ -2,10 +2,12 @@ package common import ( "bytes" + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // This step uploads a file containing the VirtualBox version, which diff --git a/builder/virtualbox/common/step_upload_version_test.go b/builder/virtualbox/common/step_upload_version_test.go index cfd940a4b..17609b9aa 100644 --- a/builder/virtualbox/common/step_upload_version_test.go +++ b/builder/virtualbox/common/step_upload_version_test.go @@ -1,9 +1,10 @@ package common import ( + "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func TestStepUploadVersion_impl(t *testing.T) { diff --git a/builder/virtualbox/common/step_vboxmanage.go b/builder/virtualbox/common/step_vboxmanage.go index 54ef96e0f..948cae884 100644 --- a/builder/virtualbox/common/step_vboxmanage.go +++ b/builder/virtualbox/common/step_vboxmanage.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "strings" diff --git a/builder/virtualbox/iso/step_attach_iso.go b/builder/virtualbox/iso/step_attach_iso.go index 3c9fcc55e..619d61afd 100644 --- a/builder/virtualbox/iso/step_attach_iso.go +++ b/builder/virtualbox/iso/step_attach_iso.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" diff --git a/builder/virtualbox/iso/step_create_disk.go b/builder/virtualbox/iso/step_create_disk.go index cb67af807..7c5b03e4f 100644 --- a/builder/virtualbox/iso/step_create_disk.go +++ b/builder/virtualbox/iso/step_create_disk.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" diff --git a/builder/virtualbox/iso/step_create_vm.go b/builder/virtualbox/iso/step_create_vm.go index 81a8a0304..72a556737 100644 --- a/builder/virtualbox/iso/step_create_vm.go +++ b/builder/virtualbox/iso/step_create_vm.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" diff --git a/builder/virtualbox/ovf/step_import.go b/builder/virtualbox/ovf/step_import.go index 8ebf5fe4b..5e066d83a 100644 --- a/builder/virtualbox/ovf/step_import.go +++ b/builder/virtualbox/ovf/step_import.go @@ -1,6 +1,7 @@ package ovf import ( + "context" "fmt" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" diff --git a/builder/virtualbox/ovf/step_import_test.go b/builder/virtualbox/ovf/step_import_test.go index aec090980..45054585c 100644 --- a/builder/virtualbox/ovf/step_import_test.go +++ b/builder/virtualbox/ovf/step_import_test.go @@ -5,7 +5,6 @@ import ( vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/helper/multistep" - "testing" ) func TestStepImport_impl(t *testing.T) { diff --git a/builder/virtualbox/ovf/step_test.go b/builder/virtualbox/ovf/step_test.go index eb6522ef6..4f9a0f9d8 100644 --- a/builder/virtualbox/ovf/step_test.go +++ b/builder/virtualbox/ovf/step_test.go @@ -7,7 +7,6 @@ import ( vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/common/step_clean_files.go b/builder/vmware/common/step_clean_files.go index 676e08f2f..08d14cf63 100644 --- a/builder/vmware/common/step_clean_files.go +++ b/builder/vmware/common/step_clean_files.go @@ -1,14 +1,13 @@ package common import ( + "context" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "os" "path/filepath" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // These are the extensions of files that are important for the function diff --git a/builder/vmware/common/step_clean_vmx.go b/builder/vmware/common/step_clean_vmx.go index 12cc6b223..f112227f8 100644 --- a/builder/vmware/common/step_clean_vmx.go +++ b/builder/vmware/common/step_clean_vmx.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "regexp" diff --git a/builder/vmware/common/step_compact_disk.go b/builder/vmware/common/step_compact_disk.go index cf0c4cf19..e7823e3ba 100644 --- a/builder/vmware/common/step_compact_disk.go +++ b/builder/vmware/common/step_compact_disk.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // This step compacts the virtual disk for the VM unless the "skip_compaction" diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 369712b6e..155234ac4 100644 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io/ioutil" "log" diff --git a/builder/vmware/common/step_configure_vnc.go b/builder/vmware/common/step_configure_vnc.go index 1f18ce5bf..90aa4a998 100644 --- a/builder/vmware/common/step_configure_vnc.go +++ b/builder/vmware/common/step_configure_vnc.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io/ioutil" "log" diff --git a/builder/vmware/common/step_output_dir.go b/builder/vmware/common/step_output_dir.go index 35effe138..90c71e18a 100644 --- a/builder/vmware/common/step_output_dir.go +++ b/builder/vmware/common/step_output_dir.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "time" diff --git a/builder/vmware/common/step_output_dir_test.go b/builder/vmware/common/step_output_dir_test.go index cdfba2a2e..dd1326387 100644 --- a/builder/vmware/common/step_output_dir_test.go +++ b/builder/vmware/common/step_output_dir_test.go @@ -1,12 +1,11 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "io/ioutil" "os" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func testOutputDir(t *testing.T) *LocalOutputDir { diff --git a/builder/vmware/common/step_prepare_tools.go b/builder/vmware/common/step_prepare_tools.go index 3ce771387..72f8f1488 100644 --- a/builder/vmware/common/step_prepare_tools.go +++ b/builder/vmware/common/step_prepare_tools.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "os" diff --git a/builder/vmware/common/step_run.go b/builder/vmware/common/step_run.go index 14334e779..f85d5948f 100644 --- a/builder/vmware/common/step_run.go +++ b/builder/vmware/common/step_run.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "time" diff --git a/builder/vmware/common/step_run_test.go b/builder/vmware/common/step_run_test.go index 395575231..b884351dd 100644 --- a/builder/vmware/common/step_run_test.go +++ b/builder/vmware/common/step_run_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/vmware/common/step_shutdown.go b/builder/vmware/common/step_shutdown.go index 5067ebbb2..bc8490ff3 100644 --- a/builder/vmware/common/step_shutdown.go +++ b/builder/vmware/common/step_shutdown.go @@ -2,17 +2,16 @@ package common import ( "bytes" + "context" "errors" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "regexp" "strings" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // This step shuts down the machine. It first attempts to do so gracefully, diff --git a/builder/vmware/common/step_suppress_messages.go b/builder/vmware/common/step_suppress_messages.go index 3e8721dec..02928123a 100644 --- a/builder/vmware/common/step_suppress_messages.go +++ b/builder/vmware/common/step_suppress_messages.go @@ -1,10 +1,12 @@ package common import ( + "context" "fmt" + "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // This step suppresses any messages that VMware product might show. diff --git a/builder/vmware/common/step_test.go b/builder/vmware/common/step_test.go index ec0854415..c8a12abb6 100644 --- a/builder/vmware/common/step_test.go +++ b/builder/vmware/common/step_test.go @@ -2,9 +2,10 @@ package common import ( "bytes" + "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 8e6a66366..05c66de16 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "net" diff --git a/builder/vmware/common/step_upload_tools.go b/builder/vmware/common/step_upload_tools.go index 4dff6496e..eed55ab0b 100644 --- a/builder/vmware/common/step_upload_tools.go +++ b/builder/vmware/common/step_upload_tools.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "os" diff --git a/builder/vmware/iso/step_create_disk.go b/builder/vmware/iso/step_create_disk.go index 457236034..ddee55c7f 100644 --- a/builder/vmware/iso/step_create_disk.go +++ b/builder/vmware/iso/step_create_disk.go @@ -1,13 +1,13 @@ package iso import ( + "context" "fmt" "path/filepath" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "path/filepath" ) // This step creates the virtual disks for the VM. diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index a071ed0f1..029f2a31e 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" "io/ioutil" "os" diff --git a/builder/vmware/iso/step_export.go b/builder/vmware/iso/step_export.go index 4d08af159..4f6df9ed4 100644 --- a/builder/vmware/iso/step_export.go +++ b/builder/vmware/iso/step_export.go @@ -2,6 +2,7 @@ package iso import ( "bytes" + "context" "fmt" "net/url" "os" diff --git a/builder/vmware/iso/step_export_test.go b/builder/vmware/iso/step_export_test.go index a713620e6..c41b2550b 100644 --- a/builder/vmware/iso/step_export_test.go +++ b/builder/vmware/iso/step_export_test.go @@ -1,10 +1,9 @@ package iso import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepExport_impl(t *testing.T) { diff --git a/builder/vmware/iso/step_register.go b/builder/vmware/iso/step_register.go index e1d396ab1..c97800910 100644 --- a/builder/vmware/iso/step_register.go +++ b/builder/vmware/iso/step_register.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" "time" diff --git a/builder/vmware/iso/step_register_test.go b/builder/vmware/iso/step_register_test.go index 6199696f0..0d2aaaa97 100644 --- a/builder/vmware/iso/step_register_test.go +++ b/builder/vmware/iso/step_register_test.go @@ -1,10 +1,9 @@ package iso import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepRegister_impl(t *testing.T) { diff --git a/builder/vmware/iso/step_remote_upload.go b/builder/vmware/iso/step_remote_upload.go index 427ba28c6..c4dfda8e5 100644 --- a/builder/vmware/iso/step_remote_upload.go +++ b/builder/vmware/iso/step_remote_upload.go @@ -1,13 +1,13 @@ package iso import ( + "context" "fmt" "log" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "log" ) // stepRemoteUpload uploads some thing from the state bag to a remote driver diff --git a/builder/vmware/iso/step_test.go b/builder/vmware/iso/step_test.go index 66fc38d36..958ab4734 100644 --- a/builder/vmware/iso/step_test.go +++ b/builder/vmware/iso/step_test.go @@ -7,7 +7,6 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "testing" ) func testState(t *testing.T) multistep.StateBag { diff --git a/builder/vmware/iso/step_upload_vmx.go b/builder/vmware/iso/step_upload_vmx.go index 360372765..f0fec436c 100644 --- a/builder/vmware/iso/step_upload_vmx.go +++ b/builder/vmware/iso/step_upload_vmx.go @@ -1,13 +1,13 @@ package iso import ( + "context" "fmt" "path/filepath" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "path/filepath" ) // This step upload the VMX to the remote host diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index e65ea0dca..f7874067c 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -1,6 +1,7 @@ package vmx import ( + "context" "fmt" "log" "path/filepath" diff --git a/common/multistep_debug.go b/common/multistep_debug.go index 1a5fc9f10..2d1a58291 100644 --- a/common/multistep_debug.go +++ b/common/multistep_debug.go @@ -2,13 +2,11 @@ package common import ( "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // MultistepDebugFn will return a proper multistep.DebugPauseFn to diff --git a/common/step_create_floppy.go b/common/step_create_floppy.go index 8b0ef8b83..dd4ead840 100644 --- a/common/step_create_floppy.go +++ b/common/step_create_floppy.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io" "io/ioutil" diff --git a/common/step_create_floppy_test.go b/common/step_create_floppy_test.go index a84c64677..2128e4dd7 100644 --- a/common/step_create_floppy_test.go +++ b/common/step_create_floppy_test.go @@ -3,8 +3,6 @@ package common import ( "bytes" "fmt" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" "io/ioutil" "log" "os" @@ -14,8 +12,8 @@ import ( "strings" "testing" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) const TestFixtures = "test-fixtures" diff --git a/common/step_download.go b/common/step_download.go index bdcd7ac65..ac62fa698 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -1,6 +1,7 @@ package common import ( + "context" "crypto/sha1" "encoding/hex" "fmt" diff --git a/common/step_download_test.go b/common/step_download_test.go index 86d632867..2b6476614 100644 --- a/common/step_download_test.go +++ b/common/step_download_test.go @@ -1,10 +1,9 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepDownload_Impl(t *testing.T) { diff --git a/common/step_http_server.go b/common/step_http_server.go index 70b1e1460..e90c6ef60 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io/ioutil" "log" diff --git a/common/step_provision.go b/common/step_provision.go index 971ef97fb..9c842044b 100644 --- a/common/step_provision.go +++ b/common/step_provision.go @@ -1,13 +1,12 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" + "context" "log" "time" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepProvision runs the provisioners. diff --git a/common/step_provision_test.go b/common/step_provision_test.go index f7c40b51d..a37d7681b 100644 --- a/common/step_provision_test.go +++ b/common/step_provision_test.go @@ -1,10 +1,9 @@ package common import ( - "github.com/hashicorp/packer/helper/multistep" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepProvision_Impl(t *testing.T) { diff --git a/helper/communicator/step_connect.go b/helper/communicator/step_connect.go index 67a5eebbe..541f88fe1 100644 --- a/helper/communicator/step_connect.go +++ b/helper/communicator/step_connect.go @@ -1,6 +1,7 @@ package communicator import ( + "context" "fmt" "log" diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 2f3ae3666..680b88a02 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -1,6 +1,7 @@ package communicator import ( + "context" "errors" "fmt" "log" diff --git a/helper/communicator/step_connect_winrm.go b/helper/communicator/step_connect_winrm.go index 97e7805d6..06e6236f8 100644 --- a/helper/communicator/step_connect_winrm.go +++ b/helper/communicator/step_connect_winrm.go @@ -2,6 +2,7 @@ package communicator import ( "bytes" + "context" "errors" "fmt" "io" diff --git a/post-processor/vagrant-cloud/step_create_provider.go b/post-processor/vagrant-cloud/step_create_provider.go index 028e5c6c7..e664b8b19 100644 --- a/post-processor/vagrant-cloud/step_create_provider.go +++ b/post-processor/vagrant-cloud/step_create_provider.go @@ -1,7 +1,9 @@ package vagrantcloud import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/post-processor/vagrant-cloud/step_create_version.go b/post-processor/vagrant-cloud/step_create_version.go index d8e6b9df8..feb247f0a 100644 --- a/post-processor/vagrant-cloud/step_create_version.go +++ b/post-processor/vagrant-cloud/step_create_version.go @@ -1,7 +1,9 @@ package vagrantcloud import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) diff --git a/post-processor/vagrant-cloud/step_prepare_upload.go b/post-processor/vagrant-cloud/step_prepare_upload.go index 1bcc05885..bdab16d10 100644 --- a/post-processor/vagrant-cloud/step_prepare_upload.go +++ b/post-processor/vagrant-cloud/step_prepare_upload.go @@ -1,6 +1,7 @@ package vagrantcloud import ( + "context" "fmt" "github.com/hashicorp/packer/helper/multistep" diff --git a/post-processor/vagrant-cloud/step_release_version.go b/post-processor/vagrant-cloud/step_release_version.go index 5f7fbb0f0..94e4b90da 100644 --- a/post-processor/vagrant-cloud/step_release_version.go +++ b/post-processor/vagrant-cloud/step_release_version.go @@ -1,6 +1,7 @@ package vagrantcloud import ( + "context" "fmt" "strings" diff --git a/post-processor/vagrant-cloud/step_upload.go b/post-processor/vagrant-cloud/step_upload.go index 576558b24..cce1e9de2 100644 --- a/post-processor/vagrant-cloud/step_upload.go +++ b/post-processor/vagrant-cloud/step_upload.go @@ -1,6 +1,7 @@ package vagrantcloud import ( + "context" "fmt" "log" diff --git a/post-processor/vagrant-cloud/step_verify_box.go b/post-processor/vagrant-cloud/step_verify_box.go index baee6222a..f1dafc991 100644 --- a/post-processor/vagrant-cloud/step_verify_box.go +++ b/post-processor/vagrant-cloud/step_verify_box.go @@ -1,7 +1,9 @@ package vagrantcloud import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) From 5d48d658b477c303ba65595e40cd2aca121534c4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 15:29:42 -0800 Subject: [PATCH 0437/1007] Wire context through misc steps Some steps actually need to pass the context around, so let's create a ctx variable and pass it. --- .../virtualbox/common/step_download_guest_additions.go | 10 +++++----- common/multistep_runner.go | 9 +++++---- helper/communicator/step_connect.go | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/builder/virtualbox/common/step_download_guest_additions.go b/builder/virtualbox/common/step_download_guest_additions.go index 1aebca144..facc60b6a 100644 --- a/builder/virtualbox/common/step_download_guest_additions.go +++ b/builder/virtualbox/common/step_download_guest_additions.go @@ -37,7 +37,7 @@ type StepDownloadGuestAdditions struct { Ctx interpolate.Context } -func (s *StepDownloadGuestAdditions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepDownloadGuestAdditions) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { var action multistep.StepAction driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) @@ -114,7 +114,7 @@ func (s *StepDownloadGuestAdditions) Run(_ context.Context, state multistep.Stat if s.GuestAdditionsSHA256 != "" { checksum = s.GuestAdditionsSHA256 } else { - checksum, action = s.downloadAdditionsSHA256(state, version, additionsName) + checksum, action = s.downloadAdditionsSHA256(ctx, state, version, additionsName) if action != multistep.ActionContinue { return action } @@ -141,12 +141,12 @@ func (s *StepDownloadGuestAdditions) Run(_ context.Context, state multistep.Stat Url: []string{url}, } - return downStep.Run(state) + return downStep.Run(ctx, state) } func (s *StepDownloadGuestAdditions) Cleanup(state multistep.StateBag) {} -func (s *StepDownloadGuestAdditions) downloadAdditionsSHA256(state multistep.StateBag, additionsVersion string, additionsName string) (string, multistep.StepAction) { +func (s *StepDownloadGuestAdditions) downloadAdditionsSHA256(ctx context.Context, state multistep.StateBag, additionsVersion string, additionsName string) (string, multistep.StepAction) { // First things first, we get the list of checksums for the files available // for this version. checksumsUrl := fmt.Sprintf( @@ -170,7 +170,7 @@ func (s *StepDownloadGuestAdditions) downloadAdditionsSHA256(state multistep.Sta Url: []string{checksumsUrl}, } - action := downStep.Run(state) + action := downStep.Run(ctx, state) if action == multistep.ActionHalt { return "", action } diff --git a/common/multistep_runner.go b/common/multistep_runner.go index c10c0879e..e3c16e7cf 100644 --- a/common/multistep_runner.go +++ b/common/multistep_runner.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "log" "os" @@ -65,8 +66,8 @@ func (s abortStep) InnerStepName() string { return typeName(s.step) } -func (s abortStep) Run(state multistep.StateBag) multistep.StepAction { - return s.step.Run(state) +func (s abortStep) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { + return s.step.Run(ctx, state) } func (s abortStep) Cleanup(state multistep.StateBag) { @@ -90,9 +91,9 @@ func (s askStep) InnerStepName() string { return typeName(s.step) } -func (s askStep) Run(state multistep.StateBag) (action multistep.StepAction) { +func (s askStep) Run(ctx context.Context, state multistep.StateBag) (action multistep.StepAction) { for { - action = s.step.Run(state) + action = s.step.Run(ctx, state) if action != multistep.ActionHalt { return diff --git a/helper/communicator/step_connect.go b/helper/communicator/step_connect.go index 541f88fe1..273935710 100644 --- a/helper/communicator/step_connect.go +++ b/helper/communicator/step_connect.go @@ -44,7 +44,7 @@ type StepConnect struct { substep multistep.Step } -func (s *StepConnect) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepConnect) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { typeMap := map[string]multistep.Step{ "none": nil, "ssh": &StepConnectSSH{ @@ -85,7 +85,7 @@ func (s *StepConnect) Run(_ context.Context, state multistep.StateBag) multistep } s.substep = step - return s.substep.Run(state) + return s.substep.Run(ctx, state) } func (s *StepConnect) Cleanup(state multistep.StateBag) { From 8cd403425e821c6413e3e172d84b14c9cb87c6e9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 16:03:49 -0800 Subject: [PATCH 0438/1007] test fixes WIP --- builder/azure/arm/step_capture_image_test.go | 7 ++++--- .../arm/step_create_resource_group_test.go | 15 ++++++++------- builder/azure/arm/step_delete_os_disk_test.go | 19 ++++++++++--------- .../arm/step_delete_resource_group_test.go | 7 ++++--- .../azure/arm/step_deploy_template_test.go | 7 ++++--- .../azure/arm/step_get_certificate_test.go | 7 ++++--- builder/azure/arm/step_get_ip_address_test.go | 7 ++++--- builder/azure/arm/step_get_os_disk_test.go | 7 ++++--- .../azure/arm/step_power_off_compute_test.go | 7 ++++--- .../azure/arm/step_set_certificate_test.go | 5 +++-- .../azure/arm/step_validate_template_test.go | 7 ++++--- builder/docker/step_commit_test.go | 5 +++-- builder/docker/step_export_test.go | 5 +++-- builder/docker/step_pull_test.go | 9 +++++---- builder/docker/step_run_test.go | 6 +++--- builder/docker/step_temp_dir_test.go | 3 ++- .../step_check_existing_image_test.go | 3 ++- .../googlecompute/step_create_image_test.go | 5 +++-- .../step_create_instance_test.go | 15 ++++++++------- .../googlecompute/step_create_ssh_key_test.go | 8 +++++--- .../step_create_windows_password_test.go | 13 +++++++------ .../googlecompute/step_instance_info_test.go | 11 ++++++----- .../step_teardown_instance_test.go | 3 ++- .../step_wait_startup_script_test.go | 3 ++- builder/hyperv/iso/builder_test.go | 3 ++- builder/hyperv/vmcx/builder_test.go | 3 ++- .../oracle/oci/step_create_instance_test.go | 11 ++++++----- builder/oracle/oci/step_image_test.go | 7 ++++--- builder/oracle/oci/step_instance_info_test.go | 5 +++-- .../common/step_attach_floppy_test.go | 5 +++-- .../common/step_compact_disk_test.go | 5 +++-- .../parallels/common/step_output_dir_test.go | 7 ++++--- .../step_prepare_parallels_tools_test.go | 7 ++++--- .../parallels/common/step_shutdown_test.go | 7 ++++--- .../common/step_type_boot_command_test.go | 3 ++- .../step_upload_parallels_tools_test.go | 7 ++++--- .../common/step_upload_version_test.go | 5 +++-- .../step_create_image_from_machine_test.go | 7 ++++--- .../triton/step_create_source_machine_test.go | 13 +++++++------ builder/triton/step_delete_machine_test.go | 7 ++++--- builder/triton/step_stop_machine_test.go | 7 ++++--- .../common/step_attach_floppy_test.go | 5 +++-- builder/virtualbox/common/step_export_test.go | 3 ++- .../virtualbox/common/step_output_dir_test.go | 9 +++++---- .../common/step_remove_devices_test.go | 9 +++++---- .../virtualbox/common/step_shutdown_test.go | 11 ++++++----- .../common/step_suppress_messages_test.go | 5 +++-- .../common/step_upload_version_test.go | 5 +++-- builder/virtualbox/ovf/step_import_test.go | 3 ++- builder/vmware/common/step_clean_vmx_test.go | 9 +++++---- .../vmware/common/step_compact_disk_test.go | 5 +++-- .../vmware/common/step_configure_vmx_test.go | 7 ++++--- builder/vmware/common/step_output_dir_test.go | 11 ++++++----- .../vmware/common/step_prepare_tools_test.go | 7 ++++--- builder/vmware/common/step_run_test.go | 6 +++--- builder/vmware/common/step_shutdown_test.go | 7 ++++--- .../common/step_suppress_messages_test.go | 3 ++- builder/vmware/iso/step_export_test.go | 3 ++- builder/vmware/iso/step_register_test.go | 7 ++++--- builder/vmware/vmx/step_clone_vmx_test.go | 3 ++- common/step_create_floppy_test.go | 9 +++++---- helper/communicator/step_connect_test.go | 3 ++- 62 files changed, 242 insertions(+), 181 deletions(-) diff --git a/builder/azure/arm/step_capture_image_test.go b/builder/azure/arm/step_capture_image_test.go index 2d005d32b..52bcbd1b7 100644 --- a/builder/azure/arm/step_capture_image_test.go +++ b/builder/azure/arm/step_capture_image_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -26,7 +27,7 @@ func TestStepCaptureImageShouldFailIfCaptureFails(t *testing.T) { stateBag := createTestStateBagStepCaptureImage() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -51,7 +52,7 @@ func TestStepCaptureImageShouldPassIfCapturePasses(t *testing.T) { stateBag := createTestStateBagStepCaptureImage() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -91,7 +92,7 @@ func TestStepCaptureImageShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepCaptureImage() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_create_resource_group_test.go b/builder/azure/arm/step_create_resource_group_test.go index 07ffb78ab..3c4deeb03 100644 --- a/builder/azure/arm/step_create_resource_group_test.go +++ b/builder/azure/arm/step_create_resource_group_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "errors" "fmt" "testing" @@ -26,7 +27,7 @@ func TestStepCreateResourceGroupShouldFailIfBothGroupNames(t *testing.T) { error: func(e error) {}, exists: func(string) (bool, error) { return false, nil }, } - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -46,7 +47,7 @@ func TestStepCreateResourceGroupShouldFailIfCreateFails(t *testing.T) { stateBag := createTestStateBagStepCreateResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -66,7 +67,7 @@ func TestStepCreateResourceGroupShouldFailIfExistsFails(t *testing.T) { stateBag := createTestStateBagStepCreateResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -86,7 +87,7 @@ func TestStepCreateResourceGroupShouldPassIfCreatePasses(t *testing.T) { stateBag := createTestStateBagStepCreateResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -114,7 +115,7 @@ func TestStepCreateResourceGroupShouldTakeStepArgumentsFromStateBag(t *testing.T } stateBag := createTestStateBagStepCreateResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) @@ -152,7 +153,7 @@ func TestStepCreateResourceGroupMarkShouldFailIfTryingExistingButDoesntExist(t * stateBag := createTestExistingStateBagStepCreateResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -172,7 +173,7 @@ func TestStepCreateResourceGroupMarkShouldFailIfTryingTempButExist(t *testing.T) stateBag := createTestStateBagStepCreateResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } diff --git a/builder/azure/arm/step_delete_os_disk_test.go b/builder/azure/arm/step_delete_os_disk_test.go index fea47e766..6c8b12550 100644 --- a/builder/azure/arm/step_delete_os_disk_test.go +++ b/builder/azure/arm/step_delete_os_disk_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "errors" "fmt" "testing" @@ -19,7 +20,7 @@ func TestStepDeleteOSDiskShouldFailIfGetFails(t *testing.T) { stateBag := DeleteTestStateBagStepDeleteOSDisk("http://storage.blob.core.windows.net/images/pkrvm_os.vhd") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -38,7 +39,7 @@ func TestStepDeleteOSDiskShouldPassIfGetPasses(t *testing.T) { stateBag := DeleteTestStateBagStepDeleteOSDisk("http://storage.blob.core.windows.net/images/pkrvm_os.vhd") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -63,7 +64,7 @@ func TestStepDeleteOSDiskShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := DeleteTestStateBagStepDeleteOSDisk("http://storage.blob.core.windows.net/images/pkrvm_os.vhd") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) @@ -93,7 +94,7 @@ func TestStepDeleteOSDiskShouldHandleComplexStorageContainerNames(t *testing.T) } stateBag := DeleteTestStateBagStepDeleteOSDisk("http://storage.blob.core.windows.net/abc/def/pkrvm_os.vhd") - testSubject.Run(stateBag) + testSubject.Run(context.Background(), stateBag) if actualStorageContainerName != "abc" { t.Fatalf("Expected the storage container name to be 'abc/def', but found '%s'.", actualStorageContainerName) @@ -115,7 +116,7 @@ func TestStepDeleteOSDiskShouldFailIfVHDNameCannotBeURLParsed(t *testing.T) { // Invalid URL per https://golang.org/src/net/url/url_test.go stateBag := DeleteTestStateBagStepDeleteOSDisk("http://[fe80::1%en0]/") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%v'.", result) } @@ -134,7 +135,7 @@ func TestStepDeleteOSDiskShouldFailIfVHDNameIsTooShort(t *testing.T) { stateBag := DeleteTestStateBagStepDeleteOSDisk("storage.blob.core.windows.net/abc") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -157,7 +158,7 @@ func TestStepDeleteOSDiskShouldPassIfManagedDiskInTempResourceGroup(t *testing.T stateBag.Put(constants.ArmIsExistingResourceGroup, false) stateBag.Put(constants.ArmResourceGroupName, "testgroup") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -181,7 +182,7 @@ func TestStepDeleteOSDiskShouldFailIfManagedDiskInExistingResourceGroupFailsToDe stateBag.Put(constants.ArmIsExistingResourceGroup, true) stateBag.Put(constants.ArmResourceGroupName, "testgroup") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -205,7 +206,7 @@ func TestStepDeleteOSDiskShouldFailIfManagedDiskInExistingResourceGroupIsDeleted stateBag.Put(constants.ArmIsExistingResourceGroup, true) stateBag.Put(constants.ArmResourceGroupName, "testgroup") - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } diff --git a/builder/azure/arm/step_delete_resource_group_test.go b/builder/azure/arm/step_delete_resource_group_test.go index 8b5e3590b..823f1f6ac 100644 --- a/builder/azure/arm/step_delete_resource_group_test.go +++ b/builder/azure/arm/step_delete_resource_group_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -17,7 +18,7 @@ func TestStepDeleteResourceGroupShouldFailIfDeleteFails(t *testing.T) { stateBag := DeleteTestStateBagStepDeleteResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -36,7 +37,7 @@ func TestStepDeleteResourceGroupShouldPassIfDeletePasses(t *testing.T) { stateBag := DeleteTestStateBagStepDeleteResourceGroup() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -56,7 +57,7 @@ func TestStepDeleteResourceGroupShouldDeleteStateBagArmResourceGroupCreated(t *t } stateBag := DeleteTestStateBagStepDeleteResourceGroup() - testSubject.Run(stateBag) + testSubject.Run(context.Background(), stateBag) value, ok := stateBag.GetOk(constants.ArmIsResourceGroupCreated) if !ok { diff --git a/builder/azure/arm/step_deploy_template_test.go b/builder/azure/arm/step_deploy_template_test.go index 16bb52692..be60433f3 100644 --- a/builder/azure/arm/step_deploy_template_test.go +++ b/builder/azure/arm/step_deploy_template_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -19,7 +20,7 @@ func TestStepDeployTemplateShouldFailIfDeployFails(t *testing.T) { stateBag := createTestStateBagStepDeployTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -38,7 +39,7 @@ func TestStepDeployTemplateShouldPassIfDeployPasses(t *testing.T) { stateBag := createTestStateBagStepDeployTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -65,7 +66,7 @@ func TestStepDeployTemplateShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepValidateTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_get_certificate_test.go b/builder/azure/arm/step_get_certificate_test.go index 6823ca1f1..5ce807afe 100644 --- a/builder/azure/arm/step_get_certificate_test.go +++ b/builder/azure/arm/step_get_certificate_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -18,7 +19,7 @@ func TestStepGetCertificateShouldFailIfGetFails(t *testing.T) { stateBag := createTestStateBagStepGetCertificate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -38,7 +39,7 @@ func TestStepGetCertificateShouldPassIfGetPasses(t *testing.T) { stateBag := createTestStateBagStepGetCertificate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -65,7 +66,7 @@ func TestStepGetCertificateShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepGetCertificate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_get_ip_address_test.go b/builder/azure/arm/step_get_ip_address_test.go index 508aa2b08..e91678c3b 100644 --- a/builder/azure/arm/step_get_ip_address_test.go +++ b/builder/azure/arm/step_get_ip_address_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -21,7 +22,7 @@ func TestStepGetIPAddressShouldFailIfGetFails(t *testing.T) { stateBag := createTestStateBagStepGetIPAddress() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -45,7 +46,7 @@ func TestStepGetIPAddressShouldPassIfGetPasses(t *testing.T) { stateBag := createTestStateBagStepGetIPAddress() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -77,7 +78,7 @@ func TestStepGetIPAddressShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepGetIPAddress() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_get_os_disk_test.go b/builder/azure/arm/step_get_os_disk_test.go index 614684db7..070a3ec0a 100644 --- a/builder/azure/arm/step_get_os_disk_test.go +++ b/builder/azure/arm/step_get_os_disk_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -22,7 +23,7 @@ func TestStepGetOSDiskShouldFailIfGetFails(t *testing.T) { stateBag := createTestStateBagStepGetOSDisk() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -43,7 +44,7 @@ func TestStepGetOSDiskShouldPassIfGetPasses(t *testing.T) { stateBag := createTestStateBagStepGetOSDisk() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -69,7 +70,7 @@ func TestStepGetOSDiskShouldTakeValidateArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepGetOSDisk() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_power_off_compute_test.go b/builder/azure/arm/step_power_off_compute_test.go index e1d6c6b7d..45c7a1729 100644 --- a/builder/azure/arm/step_power_off_compute_test.go +++ b/builder/azure/arm/step_power_off_compute_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -17,7 +18,7 @@ func TestStepPowerOffComputeShouldFailIfPowerOffFails(t *testing.T) { stateBag := createTestStateBagStepPowerOffCompute() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -36,7 +37,7 @@ func TestStepPowerOffComputeShouldPassIfPowerOffPasses(t *testing.T) { stateBag := createTestStateBagStepPowerOffCompute() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -62,7 +63,7 @@ func TestStepPowerOffComputeShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepPowerOffCompute() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_set_certificate_test.go b/builder/azure/arm/step_set_certificate_test.go index 8adc6f19e..387d620a9 100644 --- a/builder/azure/arm/step_set_certificate_test.go +++ b/builder/azure/arm/step_set_certificate_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "testing" "github.com/hashicorp/packer/builder/azure/common/constants" @@ -16,7 +17,7 @@ func TestStepSetCertificateShouldPassIfGetPasses(t *testing.T) { stateBag := createTestStateBagStepSetCertificate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -35,7 +36,7 @@ func TestStepSetCertificateShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepSetCertificate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/azure/arm/step_validate_template_test.go b/builder/azure/arm/step_validate_template_test.go index 310c6b49c..7e32625d1 100644 --- a/builder/azure/arm/step_validate_template_test.go +++ b/builder/azure/arm/step_validate_template_test.go @@ -1,6 +1,7 @@ package arm import ( + "context" "fmt" "testing" @@ -17,7 +18,7 @@ func TestStepValidateTemplateShouldFailIfValidateFails(t *testing.T) { stateBag := createTestStateBagStepValidateTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) } @@ -36,7 +37,7 @@ func TestStepValidateTemplateShouldPassIfValidatePasses(t *testing.T) { stateBag := createTestStateBagStepValidateTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) } @@ -62,7 +63,7 @@ func TestStepValidateTemplateShouldTakeStepArgumentsFromStateBag(t *testing.T) { } stateBag := createTestStateBagStepValidateTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/docker/step_commit_test.go b/builder/docker/step_commit_test.go index ff2db0ad7..16548b069 100644 --- a/builder/docker/step_commit_test.go +++ b/builder/docker/step_commit_test.go @@ -1,6 +1,7 @@ package docker import ( + "context" "errors" "testing" @@ -26,7 +27,7 @@ func TestStepCommit(t *testing.T) { driver.CommitImageId = "bar" // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -56,7 +57,7 @@ func TestStepCommit_error(t *testing.T) { driver.CommitErr = errors.New("foo") // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/docker/step_export_test.go b/builder/docker/step_export_test.go index 1b1221e62..aa3fd124b 100644 --- a/builder/docker/step_export_test.go +++ b/builder/docker/step_export_test.go @@ -2,6 +2,7 @@ package docker import ( "bytes" + "context" "errors" "io/ioutil" "os" @@ -39,7 +40,7 @@ func TestStepExport(t *testing.T) { driver.ExportReader = bytes.NewReader([]byte("data!")) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -84,7 +85,7 @@ func TestStepExport_error(t *testing.T) { driver.ExportError = errors.New("foo") // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/docker/step_pull_test.go b/builder/docker/step_pull_test.go index 9b8ed1d1b..b01b42107 100644 --- a/builder/docker/step_pull_test.go +++ b/builder/docker/step_pull_test.go @@ -1,6 +1,7 @@ package docker import ( + "context" "errors" "testing" @@ -20,7 +21,7 @@ func TestStepPull(t *testing.T) { driver := state.Get("driver").(*MockDriver) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -42,7 +43,7 @@ func TestStepPull_error(t *testing.T) { driver.PullError = errors.New("foo") // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -63,7 +64,7 @@ func TestStepPull_login(t *testing.T) { config.Login = true // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -92,7 +93,7 @@ func TestStepPull_noPull(t *testing.T) { driver := state.Get("driver").(*MockDriver) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } diff --git a/builder/docker/step_run_test.go b/builder/docker/step_run_test.go index 9993cb357..bc6639319 100644 --- a/builder/docker/step_run_test.go +++ b/builder/docker/step_run_test.go @@ -18,7 +18,7 @@ func TestStepRun_impl(t *testing.T) { var _ multistep.Step = new(StepRun) } -func TestStepRun(_ context.Context, t *testing.T) { +func TestStepRun(t *testing.T) { state := testStepRunState(t) step := new(StepRun) defer step.Cleanup(state) @@ -28,7 +28,7 @@ func TestStepRun(_ context.Context, t *testing.T) { driver.StartID = "foo" // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -75,7 +75,7 @@ func TestStepRun_error(t *testing.T) { driver.StartError = errors.New("foo") // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/docker/step_temp_dir_test.go b/builder/docker/step_temp_dir_test.go index 68c8d0455..e36d4fcff 100644 --- a/builder/docker/step_temp_dir_test.go +++ b/builder/docker/step_temp_dir_test.go @@ -1,6 +1,7 @@ package docker import ( + "context" "os" "path/filepath" "testing" @@ -24,7 +25,7 @@ func testStepTempDir_impl(t *testing.T) string { } // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } diff --git a/builder/googlecompute/step_check_existing_image_test.go b/builder/googlecompute/step_check_existing_image_test.go index 1c499e743..d4b9a9541 100644 --- a/builder/googlecompute/step_check_existing_image_test.go +++ b/builder/googlecompute/step_check_existing_image_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -22,7 +23,7 @@ func TestStepCheckExistingImage(t *testing.T) { driver.ImageExistsResult = true // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/googlecompute/step_create_image_test.go b/builder/googlecompute/step_create_image_test.go index e920e03f2..6f1121a9f 100644 --- a/builder/googlecompute/step_create_image_test.go +++ b/builder/googlecompute/step_create_image_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "testing" @@ -26,7 +27,7 @@ func TestStepCreateImage(t *testing.T) { d.CreateImageResultSizeGb = 100 // run the step - action := step.Run(state) + action := step.Run(context.Background(), state) assert.Equal(t, action, multistep.ActionContinue, "Step did not pass.") uncastImage, ok := state.GetOk("image") @@ -61,7 +62,7 @@ func TestStepCreateImage_errorOnChannel(t *testing.T) { driver.CreateImageErrCh = errCh // run the step - action := step.Run(state) + action := step.Run(context.Background(), state) assert.Equal(t, action, multistep.ActionHalt, "Step should not have passed.") _, ok := state.GetOk("error") assert.True(t, ok, "State should have an error.") diff --git a/builder/googlecompute/step_create_instance_test.go b/builder/googlecompute/step_create_instance_test.go index 5a497a78e..f8196e3d0 100644 --- a/builder/googlecompute/step_create_instance_test.go +++ b/builder/googlecompute/step_create_instance_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "strings" "testing" @@ -26,7 +27,7 @@ func TestStepCreateInstance(t *testing.T) { d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) // run the step - assert.Equal(t, step.Run(state), multistep.ActionContinue, "Step should have passed and continued.") + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") // Verify state nameRaw, ok := state.GetOk("instance_name") @@ -67,7 +68,7 @@ func TestStepCreateInstance_fromFamily(t *testing.T) { d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) // run the step - assert.Equal(t, step.Run(state), multistep.ActionContinue, "Step should have passed and continued.") + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") // cleanup step.Cleanup(state) @@ -93,7 +94,7 @@ func TestStepCreateInstance_windowsNeedsPassword(t *testing.T) { d.GetImageResult = StubImage("test-image", "test-project", []string{"windows"}, 100) c.Comm.Type = "winrm" // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -142,7 +143,7 @@ func TestStepCreateInstance_windowsPasswordSet(t *testing.T) { config.Comm.WinRMPassword = "password" // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -188,7 +189,7 @@ func TestStepCreateInstance_error(t *testing.T) { d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) // run the step - assert.Equal(t, step.Run(state), multistep.ActionHalt, "Step should have failed and halted.") + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionHalt, "Step should have failed and halted.") // Verify state _, ok := state.GetOk("error") @@ -212,7 +213,7 @@ func TestStepCreateInstance_errorOnChannel(t *testing.T) { d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) // run the step - assert.Equal(t, step.Run(state), multistep.ActionHalt, "Step should have failed and halted.") + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionHalt, "Step should have failed and halted.") // Verify state _, ok := state.GetOk("error") @@ -238,7 +239,7 @@ func TestStepCreateInstance_errorTimeout(t *testing.T) { d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) // run the step - assert.Equal(t, step.Run(state), multistep.ActionHalt, "Step should have failed and halted.") + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionHalt, "Step should have failed and halted.") // Verify state _, ok := state.GetOk("error") diff --git a/builder/googlecompute/step_create_ssh_key_test.go b/builder/googlecompute/step_create_ssh_key_test.go index 31481e8b6..bc1b2e6b5 100644 --- a/builder/googlecompute/step_create_ssh_key_test.go +++ b/builder/googlecompute/step_create_ssh_key_test.go @@ -1,6 +1,8 @@ package googlecompute import ( + "context" + "github.com/hashicorp/packer/helper/multistep" "io/ioutil" @@ -19,7 +21,7 @@ func TestStepCreateSSHKey_privateKey(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -35,7 +37,7 @@ func TestStepCreateSSHKey(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -63,7 +65,7 @@ func TestStepCreateSSHKey_debug(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } diff --git a/builder/googlecompute/step_create_windows_password_test.go b/builder/googlecompute/step_create_windows_password_test.go index 2b0050b1d..3a58d4816 100644 --- a/builder/googlecompute/step_create_windows_password_test.go +++ b/builder/googlecompute/step_create_windows_password_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "io/ioutil" "os" @@ -21,7 +22,7 @@ func TestStepCreateOrResetWindowsPassword(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -44,7 +45,7 @@ func TestStepCreateOrResetWindowsPassword_passwordSet(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -63,7 +64,7 @@ func TestStepCreateOrResetWindowsPassword_dontNeedPassword(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -89,7 +90,7 @@ func TestStepCreateOrResetWindowsPassword_debug(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -116,7 +117,7 @@ func TestStepCreateOrResetWindowsPassword_error(t *testing.T) { driver.CreateOrResetWindowsPasswordErr = errors.New("error") // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -148,7 +149,7 @@ func TestStepCreateOrResetWindowsPassword_errorOnChannel(t *testing.T) { driver.CreateOrResetWindowsPasswordErrCh = errCh // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/googlecompute/step_instance_info_test.go b/builder/googlecompute/step_instance_info_test.go index 3918a009e..86f718369 100644 --- a/builder/googlecompute/step_instance_info_test.go +++ b/builder/googlecompute/step_instance_info_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "errors" "testing" "time" @@ -24,7 +25,7 @@ func TestStepInstanceInfo(t *testing.T) { driver.GetNatIPResult = "1.2.3.4" // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -64,7 +65,7 @@ func TestStepInstanceInfo_InternalIP(t *testing.T) { driver.GetInternalIPResult = "5.6.7.8" // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -101,7 +102,7 @@ func TestStepInstanceInfo_getNatIPError(t *testing.T) { driver.GetNatIPErr = errors.New("error") // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -128,7 +129,7 @@ func TestStepInstanceInfo_waitError(t *testing.T) { driver.WaitForInstanceErrCh = errCh // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -161,7 +162,7 @@ func TestStepInstanceInfo_errorTimeout(t *testing.T) { driver.WaitForInstanceErrCh = errCh // run the step - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/googlecompute/step_teardown_instance_test.go b/builder/googlecompute/step_teardown_instance_test.go index f19dac960..129c4e596 100644 --- a/builder/googlecompute/step_teardown_instance_test.go +++ b/builder/googlecompute/step_teardown_instance_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -19,7 +20,7 @@ func TestStepTeardownInstance(t *testing.T) { driver := state.Get("driver").(*DriverMock) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } diff --git a/builder/googlecompute/step_wait_startup_script_test.go b/builder/googlecompute/step_wait_startup_script_test.go index 51643eb2d..a970dc48d 100644 --- a/builder/googlecompute/step_wait_startup_script_test.go +++ b/builder/googlecompute/step_wait_startup_script_test.go @@ -1,6 +1,7 @@ package googlecompute import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -23,7 +24,7 @@ func TestStepWaitStartupScript(t *testing.T) { d.GetInstanceMetadataResult = StartupScriptStatusDone // Run the step. - assert.Equal(t, step.Run(state), multistep.ActionContinue, "Step should have passed and continued.") + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") // Check that GetInstanceMetadata was called properly. assert.Equal(t, d.GetInstanceMetadataZone, testZone, "Incorrect zone passed to GetInstanceMetadata.") diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index fa164d85f..b08a683f9 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -1,6 +1,7 @@ package iso import ( + "context" "fmt" "reflect" "strconv" @@ -513,7 +514,7 @@ func TestUserVariablesInBootCommand(t *testing.T) { Ctx: b.config.ctx, } - ret := step.Run(state) + ret := step.Run(context.Background(), state) if ret != multistep.ActionContinue { t.Fatalf("should not have error: %#v", ret) } diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index e428672c6..08444c26d 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -1,6 +1,7 @@ package vmcx import ( + "context" "fmt" "reflect" "testing" @@ -534,7 +535,7 @@ func TestUserVariablesInBootCommand(t *testing.T) { Ctx: b.config.ctx, } - ret := step.Run(state) + ret := step.Run(context.Background(), state) if ret != multistep.ActionContinue { t.Fatalf("should not have error: %#v", ret) } diff --git a/builder/oracle/oci/step_create_instance_test.go b/builder/oracle/oci/step_create_instance_test.go index 3594281b6..6ab2ceb67 100644 --- a/builder/oracle/oci/step_create_instance_test.go +++ b/builder/oracle/oci/step_create_instance_test.go @@ -1,6 +1,7 @@ package oci import ( + "context" "errors" "testing" @@ -16,7 +17,7 @@ func TestStepCreateInstance(t *testing.T) { driver := state.Get("driver").(*driverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -44,7 +45,7 @@ func TestStepCreateInstance_CreateInstanceErr(t *testing.T) { driver := state.Get("driver").(*driverMock) driver.CreateInstanceErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -73,7 +74,7 @@ func TestStepCreateInstance_WaitForInstanceStateErr(t *testing.T) { driver := state.Get("driver").(*driverMock) driver.WaitForInstanceStateErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -91,7 +92,7 @@ func TestStepCreateInstance_TerminateInstanceErr(t *testing.T) { driver := state.Get("driver").(*driverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -117,7 +118,7 @@ func TestStepCreateInstanceCleanup_WaitForInstanceStateErr(t *testing.T) { driver := state.Get("driver").(*driverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } diff --git a/builder/oracle/oci/step_image_test.go b/builder/oracle/oci/step_image_test.go index e3e0e353c..955d557a9 100644 --- a/builder/oracle/oci/step_image_test.go +++ b/builder/oracle/oci/step_image_test.go @@ -1,6 +1,7 @@ package oci import ( + "context" "errors" "testing" @@ -14,7 +15,7 @@ func TestStepImage(t *testing.T) { step := new(stepImage) defer step.Cleanup(state) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -33,7 +34,7 @@ func TestStepImage_CreateImageErr(t *testing.T) { driver := state.Get("driver").(*driverMock) driver.CreateImageErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -56,7 +57,7 @@ func TestStepImage_WaitForImageCreationErr(t *testing.T) { driver := state.Get("driver").(*driverMock) driver.WaitForImageCreationErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/oracle/oci/step_instance_info_test.go b/builder/oracle/oci/step_instance_info_test.go index 6280e3e6f..7117ec44a 100644 --- a/builder/oracle/oci/step_instance_info_test.go +++ b/builder/oracle/oci/step_instance_info_test.go @@ -1,6 +1,7 @@ package oci import ( + "context" "errors" "testing" @@ -14,7 +15,7 @@ func TestInstanceInfo(t *testing.T) { step := new(stepInstanceInfo) defer step.Cleanup(state) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -38,7 +39,7 @@ func TestInstanceInfo_GetInstanceIPErr(t *testing.T) { driver := state.Get("driver").(*driverMock) driver.GetInstanceIPErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/parallels/common/step_attach_floppy_test.go b/builder/parallels/common/step_attach_floppy_test.go index 7df1c4569..2d951cf05 100644 --- a/builder/parallels/common/step_attach_floppy_test.go +++ b/builder/parallels/common/step_attach_floppy_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -30,7 +31,7 @@ func TestStepAttachFloppy(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -72,7 +73,7 @@ func TestStepAttachFloppy_noFloppy(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/parallels/common/step_compact_disk_test.go b/builder/parallels/common/step_compact_disk_test.go index 4b41c5f41..e32ef217b 100644 --- a/builder/parallels/common/step_compact_disk_test.go +++ b/builder/parallels/common/step_compact_disk_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -31,7 +32,7 @@ func TestStepCompactDisk(t *testing.T) { driver.DiskPathResult = tf.Name() // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -59,7 +60,7 @@ func TestStepCompactDisk_skip(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/parallels/common/step_output_dir_test.go b/builder/parallels/common/step_output_dir_test.go index 3f6d83436..17d441457 100644 --- a/builder/parallels/common/step_output_dir_test.go +++ b/builder/parallels/common/step_output_dir_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -29,7 +30,7 @@ func TestStepOutputDir(t *testing.T) { step := testStepOutputDir(t) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -51,7 +52,7 @@ func TestStepOutputDir_cancelled(t *testing.T) { step := testStepOutputDir(t) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -76,7 +77,7 @@ func TestStepOutputDir_halted(t *testing.T) { step := testStepOutputDir(t) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/parallels/common/step_prepare_parallels_tools_test.go b/builder/parallels/common/step_prepare_parallels_tools_test.go index f0542c41d..4f46fc642 100644 --- a/builder/parallels/common/step_prepare_parallels_tools_test.go +++ b/builder/parallels/common/step_prepare_parallels_tools_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -32,7 +33,7 @@ func TestStepPrepareParallelsTools(t *testing.T) { driver.ToolsISOPathResult = tf.Name() // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -67,7 +68,7 @@ func TestStepPrepareParallelsTools_disabled(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -93,7 +94,7 @@ func TestStepPrepareParallelsTools_nonExist(t *testing.T) { driver.ToolsISOPathResult = "foo" // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { diff --git a/builder/parallels/common/step_shutdown_test.go b/builder/parallels/common/step_shutdown_test.go index ef8dea7e0..0d137431f 100644 --- a/builder/parallels/common/step_shutdown_test.go +++ b/builder/parallels/common/step_shutdown_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "time" @@ -23,7 +24,7 @@ func TestStepShutdown_noShutdownCommand(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -60,7 +61,7 @@ func TestStepShutdown_shutdownCommand(t *testing.T) { }() // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -97,7 +98,7 @@ func TestStepShutdown_shutdownTimeout(t *testing.T) { }() // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { diff --git a/builder/parallels/common/step_type_boot_command_test.go b/builder/parallels/common/step_type_boot_command_test.go index 559241c60..72b5056b4 100644 --- a/builder/parallels/common/step_type_boot_command_test.go +++ b/builder/parallels/common/step_type_boot_command_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "strings" "testing" @@ -38,7 +39,7 @@ func TestStepTypeBootCommand(t *testing.T) { state.Put("http_port", uint(0)) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/parallels/common/step_upload_parallels_tools_test.go b/builder/parallels/common/step_upload_parallels_tools_test.go index 7e2f92110..aeff516d3 100644 --- a/builder/parallels/common/step_upload_parallels_tools_test.go +++ b/builder/parallels/common/step_upload_parallels_tools_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -23,7 +24,7 @@ func TestStepUploadParallelsTools(t *testing.T) { state.Put("communicator", comm) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -48,7 +49,7 @@ func TestStepUploadParallelsTools_interpolate(t *testing.T) { state.Put("communicator", comm) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -73,7 +74,7 @@ func TestStepUploadParallelsTools_attach(t *testing.T) { state.Put("communicator", comm) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/parallels/common/step_upload_version_test.go b/builder/parallels/common/step_upload_version_test.go index 17609b9aa..998d35f0e 100644 --- a/builder/parallels/common/step_upload_version_test.go +++ b/builder/parallels/common/step_upload_version_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -23,7 +24,7 @@ func TestStepUploadVersion(t *testing.T) { driver.VersionResult = "foo" // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -48,7 +49,7 @@ func TestStepUploadVersion_noPath(t *testing.T) { state.Put("communicator", comm) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/triton/step_create_image_from_machine_test.go b/builder/triton/step_create_image_from_machine_test.go index 9af18e44f..34eb95c8c 100644 --- a/builder/triton/step_create_image_from_machine_test.go +++ b/builder/triton/step_create_image_from_machine_test.go @@ -1,6 +1,7 @@ package triton import ( + "context" "errors" "testing" @@ -14,7 +15,7 @@ func TestStepCreateImageFromMachine(t *testing.T) { state.Put("machine", "test-machine-id") - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -36,7 +37,7 @@ func TestStepCreateImageFromMachine_CreateImageFromMachineError(t *testing.T) { driver.CreateImageFromMachineErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -59,7 +60,7 @@ func TestStepCreateImageFromMachine_WaitForImageCreationError(t *testing.T) { driver.WaitForImageCreationErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/triton/step_create_source_machine_test.go b/builder/triton/step_create_source_machine_test.go index f7101564a..78d97ad5e 100644 --- a/builder/triton/step_create_source_machine_test.go +++ b/builder/triton/step_create_source_machine_test.go @@ -1,6 +1,7 @@ package triton import ( + "context" "errors" "testing" @@ -14,7 +15,7 @@ func TestStepCreateSourceMachine(t *testing.T) { driver := state.Get("driver").(*DriverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -39,7 +40,7 @@ func TestStepCreateSourceMachine_CreateMachineError(t *testing.T) { driver.CreateMachineErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -61,7 +62,7 @@ func TestStepCreateSourceMachine_WaitForMachineStateError(t *testing.T) { driver.WaitForMachineStateErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -81,7 +82,7 @@ func TestStepCreateSourceMachine_StopMachineError(t *testing.T) { driver := state.Get("driver").(*DriverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -109,7 +110,7 @@ func TestStepCreateSourceMachine_WaitForMachineStoppedError(t *testing.T) { driver := state.Get("driver").(*DriverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -137,7 +138,7 @@ func TestStepCreateSourceMachine_DeleteMachineError(t *testing.T) { driver := state.Get("driver").(*DriverMock) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } diff --git a/builder/triton/step_delete_machine_test.go b/builder/triton/step_delete_machine_test.go index a2177ca36..421024d58 100644 --- a/builder/triton/step_delete_machine_test.go +++ b/builder/triton/step_delete_machine_test.go @@ -1,6 +1,7 @@ package triton import ( + "context" "errors" "testing" @@ -17,7 +18,7 @@ func TestStepDeleteMachine(t *testing.T) { machineId := "test-machine-id" state.Put("machine", machineId) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -40,7 +41,7 @@ func TestStepDeleteMachine_DeleteMachineError(t *testing.T) { driver.DeleteMachineErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -65,7 +66,7 @@ func TestStepDeleteMachine_WaitForMachineDeletionError(t *testing.T) { driver.WaitForMachineDeletionErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/triton/step_stop_machine_test.go b/builder/triton/step_stop_machine_test.go index 9604c2216..8f0f39d2d 100644 --- a/builder/triton/step_stop_machine_test.go +++ b/builder/triton/step_stop_machine_test.go @@ -1,6 +1,7 @@ package triton import ( + "context" "errors" "testing" @@ -17,7 +18,7 @@ func TestStepStopMachine(t *testing.T) { machineId := "test-machine-id" state.Put("machine", machineId) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } @@ -40,7 +41,7 @@ func TestStepStopMachine_StopMachineError(t *testing.T) { driver.StopMachineErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } @@ -61,7 +62,7 @@ func TestStepStopMachine_WaitForMachineStoppedError(t *testing.T) { driver.WaitForMachineStateErr = errors.New("error") - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } diff --git a/builder/virtualbox/common/step_attach_floppy_test.go b/builder/virtualbox/common/step_attach_floppy_test.go index 9dba8adf1..32ad4a962 100644 --- a/builder/virtualbox/common/step_attach_floppy_test.go +++ b/builder/virtualbox/common/step_attach_floppy_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -30,7 +31,7 @@ func TestStepAttachFloppy(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -61,7 +62,7 @@ func TestStepAttachFloppy_noFloppy(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/virtualbox/common/step_export_test.go b/builder/virtualbox/common/step_export_test.go index 1bea8df57..6d37b3150 100644 --- a/builder/virtualbox/common/step_export_test.go +++ b/builder/virtualbox/common/step_export_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -19,7 +20,7 @@ func TestStepExport(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/virtualbox/common/step_output_dir_test.go b/builder/virtualbox/common/step_output_dir_test.go index 5066e0e56..1e2f05c84 100644 --- a/builder/virtualbox/common/step_output_dir_test.go +++ b/builder/virtualbox/common/step_output_dir_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -29,7 +30,7 @@ func TestStepOutputDir(t *testing.T) { step := testStepOutputDir(t) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -56,7 +57,7 @@ func TestStepOutputDir_exists(t *testing.T) { } // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { @@ -75,7 +76,7 @@ func TestStepOutputDir_cancelled(t *testing.T) { step := testStepOutputDir(t) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -100,7 +101,7 @@ func TestStepOutputDir_halted(t *testing.T) { step := testStepOutputDir(t) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/virtualbox/common/step_remove_devices_test.go b/builder/virtualbox/common/step_remove_devices_test.go index 0d9f6bbe9..0a548bbd2 100644 --- a/builder/virtualbox/common/step_remove_devices_test.go +++ b/builder/virtualbox/common/step_remove_devices_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -19,7 +20,7 @@ func TestStepRemoveDevices(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -42,7 +43,7 @@ func TestStepRemoveDevices_attachedIso(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -69,7 +70,7 @@ func TestStepRemoveDevices_attachedIsoOnSata(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -95,7 +96,7 @@ func TestStepRemoveDevices_floppyPath(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/virtualbox/common/step_shutdown_test.go b/builder/virtualbox/common/step_shutdown_test.go index d38b3378c..44bd1d927 100644 --- a/builder/virtualbox/common/step_shutdown_test.go +++ b/builder/virtualbox/common/step_shutdown_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "time" @@ -23,7 +24,7 @@ func TestStepShutdown_noShutdownCommand(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -60,7 +61,7 @@ func TestStepShutdown_shutdownCommand(t *testing.T) { }() // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -97,7 +98,7 @@ func TestStepShutdown_shutdownTimeout(t *testing.T) { }() // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { @@ -129,7 +130,7 @@ func TestStepShutdown_shutdownDelay(t *testing.T) { // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } testDuration := time.Since(start).Seconds() @@ -154,7 +155,7 @@ func TestStepShutdown_shutdownDelay(t *testing.T) { }() // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } testDuration = time.Since(start).Seconds() diff --git a/builder/virtualbox/common/step_suppress_messages_test.go b/builder/virtualbox/common/step_suppress_messages_test.go index ad3a59fd7..c37af7826 100644 --- a/builder/virtualbox/common/step_suppress_messages_test.go +++ b/builder/virtualbox/common/step_suppress_messages_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "errors" "testing" @@ -18,7 +19,7 @@ func TestStepSuppressMessages(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -38,7 +39,7 @@ func TestStepSuppressMessages_error(t *testing.T) { driver.SuppressMessagesErr = errors.New("foo") // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { diff --git a/builder/virtualbox/common/step_upload_version_test.go b/builder/virtualbox/common/step_upload_version_test.go index 17609b9aa..998d35f0e 100644 --- a/builder/virtualbox/common/step_upload_version_test.go +++ b/builder/virtualbox/common/step_upload_version_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -23,7 +24,7 @@ func TestStepUploadVersion(t *testing.T) { driver.VersionResult = "foo" // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -48,7 +49,7 @@ func TestStepUploadVersion_noPath(t *testing.T) { state.Put("communicator", comm) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/virtualbox/ovf/step_import_test.go b/builder/virtualbox/ovf/step_import_test.go index 45054585c..ffaecc0ba 100644 --- a/builder/virtualbox/ovf/step_import_test.go +++ b/builder/virtualbox/ovf/step_import_test.go @@ -1,6 +1,7 @@ package ovf import ( + "context" "testing" vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" @@ -23,7 +24,7 @@ func TestStepImport(t *testing.T) { driver := state.Get("driver").(*vboxcommon.DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/common/step_clean_vmx_test.go b/builder/vmware/common/step_clean_vmx_test.go index 04b2da1f5..0f4df3df2 100644 --- a/builder/vmware/common/step_clean_vmx_test.go +++ b/builder/vmware/common/step_clean_vmx_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -21,7 +22,7 @@ func TestStepCleanVMX(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -42,7 +43,7 @@ func TestStepCleanVMX_floppyPath(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -91,7 +92,7 @@ func TestStepCleanVMX_isoPath(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -143,7 +144,7 @@ func TestStepCleanVMX_ethernet(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/common/step_compact_disk_test.go b/builder/vmware/common/step_compact_disk_test.go index 982191a4d..365e9ccb2 100644 --- a/builder/vmware/common/step_compact_disk_test.go +++ b/builder/vmware/common/step_compact_disk_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -19,7 +20,7 @@ func TestStepCompactDisk(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -45,7 +46,7 @@ func TestStepCompactDisk_skip(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/common/step_configure_vmx_test.go b/builder/vmware/common/step_configure_vmx_test.go index 6bd692caa..c5e242a51 100644 --- a/builder/vmware/common/step_configure_vmx_test.go +++ b/builder/vmware/common/step_configure_vmx_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -34,7 +35,7 @@ func TestStepConfigureVMX(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -87,7 +88,7 @@ func TestStepConfigureVMX_floppyPath(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -144,7 +145,7 @@ func TestStepConfigureVMX_generatedAddresses(t *testing.T) { state.Put("vmx_path", vmxPath) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/common/step_output_dir_test.go b/builder/vmware/common/step_output_dir_test.go index dd1326387..fe71bbea8 100644 --- a/builder/vmware/common/step_output_dir_test.go +++ b/builder/vmware/common/step_output_dir_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -32,7 +33,7 @@ func TestStepOutputDir(t *testing.T) { state.Put("dir", dir) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -62,7 +63,7 @@ func TestStepOutputDir_existsNoForce(t *testing.T) { } // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { @@ -90,7 +91,7 @@ func TestStepOutputDir_existsForce(t *testing.T) { } // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -109,7 +110,7 @@ func TestStepOutputDir_cancel(t *testing.T) { state.Put("dir", dir) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -135,7 +136,7 @@ func TestStepOutputDir_halt(t *testing.T) { state.Put("dir", dir) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/common/step_prepare_tools_test.go b/builder/vmware/common/step_prepare_tools_test.go index 3ef593e5f..cddf0ffba 100644 --- a/builder/vmware/common/step_prepare_tools_test.go +++ b/builder/vmware/common/step_prepare_tools_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "testing" @@ -32,7 +33,7 @@ func TestStepPrepareTools(t *testing.T) { driver.ToolsIsoPathResult = tf.Name() // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -67,7 +68,7 @@ func TestStepPrepareTools_esx5(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -93,7 +94,7 @@ func TestStepPrepareTools_nonExist(t *testing.T) { driver.ToolsIsoPathResult = "foo" // Test the run - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { diff --git a/builder/vmware/common/step_run_test.go b/builder/vmware/common/step_run_test.go index b884351dd..e89dcb1cf 100644 --- a/builder/vmware/common/step_run_test.go +++ b/builder/vmware/common/step_run_test.go @@ -11,7 +11,7 @@ func TestStepRun_impl(t *testing.T) { var _ multistep.Step = new(StepRun) } -func TestStepRun(_ context.Context, t *testing.T) { +func TestStepRun(t *testing.T) { state := testState(t) step := new(StepRun) @@ -20,7 +20,7 @@ func TestStepRun(_ context.Context, t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -54,7 +54,7 @@ func TestStepRun_cleanupRunning(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/common/step_shutdown_test.go b/builder/vmware/common/step_shutdown_test.go index dd4693348..ed0eae486 100644 --- a/builder/vmware/common/step_shutdown_test.go +++ b/builder/vmware/common/step_shutdown_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "io/ioutil" "os" "path/filepath" @@ -49,7 +50,7 @@ func TestStepShutdown_command(t *testing.T) { resultCh := make(chan multistep.StepAction, 1) go func() { - resultCh <- step.Run(state) + resultCh <- step.Run(context.Background(), state) }() select { @@ -94,7 +95,7 @@ func TestStepShutdown_noCommand(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -138,7 +139,7 @@ func TestStepShutdown_locks(t *testing.T) { resultCh := make(chan multistep.StepAction, 1) go func() { - resultCh <- step.Run(state) + resultCh <- step.Run(context.Background(), state) }() select { diff --git a/builder/vmware/common/step_suppress_messages_test.go b/builder/vmware/common/step_suppress_messages_test.go index a76b365a3..24044d470 100644 --- a/builder/vmware/common/step_suppress_messages_test.go +++ b/builder/vmware/common/step_suppress_messages_test.go @@ -1,6 +1,7 @@ package common import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -19,7 +20,7 @@ func TestStepSuppressMessages(t *testing.T) { driver := state.Get("driver").(*DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/iso/step_export_test.go b/builder/vmware/iso/step_export_test.go index c41b2550b..27c2a0c36 100644 --- a/builder/vmware/iso/step_export_test.go +++ b/builder/vmware/iso/step_export_test.go @@ -1,6 +1,7 @@ package iso import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -18,7 +19,7 @@ func testStepExport_wrongtype_impl(t *testing.T, remoteType string) { config.RemoteType = "foo" state.Put("config", &config) - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/iso/step_register_test.go b/builder/vmware/iso/step_register_test.go index 0d2aaaa97..099e067ab 100644 --- a/builder/vmware/iso/step_register_test.go +++ b/builder/vmware/iso/step_register_test.go @@ -1,6 +1,7 @@ package iso import ( + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -17,7 +18,7 @@ func TestStepRegister_regularDriver(t *testing.T) { state.Put("vmx_path", "foo") // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -41,7 +42,7 @@ func TestStepRegister_remoteDriver(t *testing.T) { state.Put("vmx_path", "foo") // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { @@ -81,7 +82,7 @@ func TestStepRegister_WithoutUnregister_remoteDriver(t *testing.T) { state.Put("vmx_path", "foo") // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/builder/vmware/vmx/step_clone_vmx_test.go b/builder/vmware/vmx/step_clone_vmx_test.go index 0fedd84c8..e086f0ce5 100644 --- a/builder/vmware/vmx/step_clone_vmx_test.go +++ b/builder/vmware/vmx/step_clone_vmx_test.go @@ -1,6 +1,7 @@ package vmx import ( + "context" "io/ioutil" "os" "path/filepath" @@ -43,7 +44,7 @@ func TestStepCloneVMX(t *testing.T) { driver := state.Get("driver").(*vmwcommon.DriverMock) // Test the run - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); ok { diff --git a/common/step_create_floppy_test.go b/common/step_create_floppy_test.go index 2128e4dd7..4c43a6839 100644 --- a/common/step_create_floppy_test.go +++ b/common/step_create_floppy_test.go @@ -2,6 +2,7 @@ package common import ( "bytes" + "context" "fmt" "io/ioutil" "log" @@ -89,7 +90,7 @@ func TestStepCreateFloppy(t *testing.T) { } for _, step.Files = range lists { - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v for %v", action, step.Files) } @@ -140,7 +141,7 @@ func xxxTestStepCreateFloppy_missing(t *testing.T) { } for _, step.Files = range lists { - if action := step.Run(state); action != multistep.ActionHalt { + if action := step.Run(context.Background(), state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v for %v", action, step.Files) } @@ -190,7 +191,7 @@ func xxxTestStepCreateFloppy_notfound(t *testing.T) { } for _, step.Files = range lists { - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v for %v", action, step.Files) } @@ -265,7 +266,7 @@ func TestStepCreateFloppyDirectories(t *testing.T) { log.Println(fmt.Sprintf("Trying against floppy_dirs : %v", step.Directories)) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v for %v : %v", action, step.Directories, state.Get("error")) } diff --git a/helper/communicator/step_connect_test.go b/helper/communicator/step_connect_test.go index aa51e1782..fb61f6463 100644 --- a/helper/communicator/step_connect_test.go +++ b/helper/communicator/step_connect_test.go @@ -2,6 +2,7 @@ package communicator import ( "bytes" + "context" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -23,7 +24,7 @@ func TestStepConnect_none(t *testing.T) { defer step.Cleanup(state) // run the step - if action := step.Run(state); action != multistep.ActionContinue { + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { t.Fatalf("bad action: %#v", action) } } From ce4f30c5ae36013d797f5b18a6b3e03f01931f26 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 16:50:14 -0800 Subject: [PATCH 0439/1007] fix tests --- helper/multistep/basic_runner_test.go | 14 ++++++-------- helper/multistep/debug_runner.go | 2 +- helper/multistep/debug_runner_test.go | 12 +++++------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/helper/multistep/basic_runner_test.go b/helper/multistep/basic_runner_test.go index d13ccedf0..433f288d2 100644 --- a/helper/multistep/basic_runner_test.go +++ b/helper/multistep/basic_runner_test.go @@ -4,8 +4,6 @@ import ( "reflect" "testing" "time" - - "golang.org/x/net/context" ) func TestBasicRunner_ImplRunner(t *testing.T) { @@ -22,7 +20,7 @@ func TestBasicRunner_Run(t *testing.T) { stepB := &TestStepAcc{Data: "b"} r := &BasicRunner{Steps: []Step{stepA, stepB}} - r.Run(context.Background(), data) + r.Run(data) // Test run data expected := []string{"a", "b"} @@ -55,7 +53,7 @@ func TestBasicRunner_Run_Halt(t *testing.T) { stepC := &TestStepAcc{Data: "c"} r := &BasicRunner{Steps: []Step{stepA, stepB, stepC}} - r.Run(context.Background(), data) + r.Run(data) // Test run data expected := []string{"a", "b"} @@ -88,12 +86,12 @@ func TestBasicRunner_Run_Run(t *testing.T) { stepWait := &TestStepWaitForever{} r := &BasicRunner{Steps: []Step{stepInt, stepWait}} - go r.Run(context.Background(), new(BasicStateBag)) + go r.Run(new(BasicStateBag)) // wait until really running <-ch // now try to run aain - r.Run(context.Background(), new(BasicStateBag)) + r.Run(new(BasicStateBag)) // should not get here in nominal codepath t.Errorf("Was able to run an already running BasicRunner") @@ -112,7 +110,7 @@ func TestBasicRunner_Cancel(t *testing.T) { // cancelling an idle Runner is a no-op r.Cancel() - go r.Run(context.Background(), data) + go r.Run(data) // Wait until we reach the sync point responseCh := <-ch @@ -163,7 +161,7 @@ func TestBasicRunner_Cancel_Special(t *testing.T) { state := new(BasicStateBag) state.Put("runner", r) - r.Run(context.Background(), state) + r.Run(state) // test that state contains cancelled if _, ok := state.GetOk(StateCancelled); !ok { diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 88af01c54..83dbe57e2 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,8 +1,8 @@ package multistep import ( - "context" "fmt" + "golang.org/x/net/context" "reflect" "sync" ) diff --git a/helper/multistep/debug_runner_test.go b/helper/multistep/debug_runner_test.go index 78ce70a88..aae905d43 100644 --- a/helper/multistep/debug_runner_test.go +++ b/helper/multistep/debug_runner_test.go @@ -5,8 +5,6 @@ import ( "reflect" "testing" "time" - - "golang.org/x/net/context" ) func TestDebugRunner_Impl(t *testing.T) { @@ -41,7 +39,7 @@ func TestDebugRunner_Run(t *testing.T) { PauseFn: pauseFn, } - r.Run(context.Background(), data) + r.Run(data) // Test data expected := []string{"a", "TestStepAcc", "b", "TestStepAcc"} @@ -68,12 +66,12 @@ func TestDebugRunner_Run_Run(t *testing.T) { stepWait := &TestStepWaitForever{} r := &DebugRunner{Steps: []Step{stepInt, stepWait}} - go r.Run(context.Background(), new(BasicStateBag)) + go r.Run(new(BasicStateBag)) // wait until really running <-ch // now try to run aain - r.Run(context.Background(), new(BasicStateBag)) + r.Run(new(BasicStateBag)) // should not get here in nominal codepath t.Errorf("Was able to run an already running DebugRunner") @@ -93,7 +91,7 @@ func TestDebugRunner_Cancel(t *testing.T) { // cancelling an idle Runner is a no-op r.Cancel() - go r.Run(context.Background(), data) + go r.Run(data) // Wait until we reach the sync point responseCh := <-ch @@ -156,7 +154,7 @@ func TestDebugPauseDefault(t *testing.T) { dr := &DebugRunner{Steps: []Step{ &TestStepAcc{Data: "a"}, }} - dr.Run(context.Background(), new(BasicStateBag)) + dr.Run(new(BasicStateBag)) complete <- true }() From 2afd81741c0a532fa34b87e39bae5358c0509c05 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 16:55:12 -0800 Subject: [PATCH 0440/1007] use correct context --- helper/multistep/basic_runner.go | 3 +- helper/multistep/debug_runner.go | 2 +- helper/multistep/multistep_test.go | 2 +- vendor/golang.org/x/net/context/context.go | 447 ------------------ .../x/net/context/ctxhttp/cancelreq.go | 19 - .../x/net/context/ctxhttp/cancelreq_go14.go | 23 - .../x/net/context/ctxhttp/ctxhttp.go | 140 ------ vendor/vendor.json | 10 - 8 files changed, 3 insertions(+), 643 deletions(-) delete mode 100644 vendor/golang.org/x/net/context/context.go delete mode 100644 vendor/golang.org/x/net/context/ctxhttp/cancelreq.go delete mode 100644 vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go delete mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go diff --git a/helper/multistep/basic_runner.go b/helper/multistep/basic_runner.go index eb5018d36..00723725d 100644 --- a/helper/multistep/basic_runner.go +++ b/helper/multistep/basic_runner.go @@ -1,10 +1,9 @@ package multistep import ( + "context" "sync" "sync/atomic" - - "golang.org/x/net/context" ) type runState int32 diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 83dbe57e2..88af01c54 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -1,8 +1,8 @@ package multistep import ( + "context" "fmt" - "golang.org/x/net/context" "reflect" "sync" ) diff --git a/helper/multistep/multistep_test.go b/helper/multistep/multistep_test.go index b8e4a0f9e..25bbeef9b 100644 --- a/helper/multistep/multistep_test.go +++ b/helper/multistep/multistep_test.go @@ -1,6 +1,6 @@ package multistep -import "golang.org/x/net/context" +import "context" // A step for testing that accumuluates data into a string slice in the // the state bag. It always uses the "data" key in the state bag, and will diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go deleted file mode 100644 index 77b64d0c6..000000000 --- a/vendor/golang.org/x/net/context/context.go +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package context defines the Context type, which carries deadlines, -// cancelation signals, and other request-scoped values across API boundaries -// and between processes. -// -// Incoming requests to a server should create a Context, and outgoing calls to -// servers should accept a Context. The chain of function calls between must -// propagate the Context, optionally replacing it with a modified copy created -// using WithDeadline, WithTimeout, WithCancel, or WithValue. -// -// Programs that use Contexts should follow these rules to keep interfaces -// consistent across packages and enable static analysis tools to check context -// propagation: -// -// Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. The Context should be the first -// parameter, typically named ctx: -// -// func DoSomething(ctx context.Context, arg Arg) error { -// // ... use ctx ... -// } -// -// Do not pass a nil Context, even if a function permits it. Pass context.TODO -// if you are unsure about which Context to use. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -// -// The same Context may be passed to functions running in different goroutines; -// Contexts are safe for simultaneous use by multiple goroutines. -// -// See http://blog.golang.org/context for example code for a server that uses -// Contexts. -package context // import "golang.org/x/net/context" - -import ( - "errors" - "fmt" - "sync" - "time" -) - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context interface { - // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. - Deadline() (deadline time.Time, ok bool) - - // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. - // - // WithCancel arranges for Done to be closed when cancel is called; - // WithDeadline arranges for Done to be closed when the deadline - // expires; WithTimeout arranges for Done to be closed when the timeout - // elapses. - // - // Done is provided for use in select statements: - // - // // Stream generates values with DoSomething and sends them to out - // // until DoSomething returns an error or ctx.Done is closed. - // func Stream(ctx context.Context, out <-chan Value) error { - // for { - // v, err := DoSomething(ctx) - // if err != nil { - // return err - // } - // select { - // case <-ctx.Done(): - // return ctx.Err() - // case out <- v: - // } - // } - // } - // - // See http://blog.golang.org/pipelines for more examples of how to use - // a Done channel for cancelation. - Done() <-chan struct{} - - // Err returns a non-nil error value after Done is closed. Err returns - // Canceled if the context was canceled or DeadlineExceeded if the - // context's deadline passed. No other values for Err are defined. - // After Done is closed, successive calls to Err return the same value. - Err() error - - // Value returns the value associated with this context for key, or nil - // if no value is associated with key. Successive calls to Value with - // the same key returns the same result. - // - // Use context values only for request-scoped data that transits - // processes and API boundaries, not for passing optional parameters to - // functions. - // - // A key identifies a specific value in a Context. Functions that wish - // to store values in Context typically allocate a key in a global - // variable then use that key as the argument to context.WithValue and - // Context.Value. A key can be any type that supports equality; - // packages should define keys as an unexported type to avoid - // collisions. - // - // Packages that define a Context key should provide type-safe accessors - // for the values stores using that key: - // - // // Package user defines a User type that's stored in Contexts. - // package user - // - // import "golang.org/x/net/context" - // - // // User is the type of value stored in the Contexts. - // type User struct {...} - // - // // key is an unexported type for keys defined in this package. - // // This prevents collisions with keys defined in other packages. - // type key int - // - // // userKey is the key for user.User values in Contexts. It is - // // unexported; clients use user.NewContext and user.FromContext - // // instead of using this key directly. - // var userKey key = 0 - // - // // NewContext returns a new Context that carries value u. - // func NewContext(ctx context.Context, u *User) context.Context { - // return context.WithValue(ctx, userKey, u) - // } - // - // // FromContext returns the User value stored in ctx, if any. - // func FromContext(ctx context.Context) (*User, bool) { - // u, ok := ctx.Value(userKey).(*User) - // return u, ok - // } - Value(key interface{}) interface{} -} - -// Canceled is the error returned by Context.Err when the context is canceled. -var Canceled = errors.New("context canceled") - -// DeadlineExceeded is the error returned by Context.Err when the context's -// deadline passes. -var DeadlineExceeded = errors.New("context deadline exceeded") - -// An emptyCtx is never canceled, has no values, and has no deadline. It is not -// struct{}, since vars of this type must have distinct addresses. -type emptyCtx int - -func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { - return -} - -func (*emptyCtx) Done() <-chan struct{} { - return nil -} - -func (*emptyCtx) Err() error { - return nil -} - -func (*emptyCtx) Value(key interface{}) interface{} { - return nil -} - -func (e *emptyCtx) String() string { - switch e { - case background: - return "context.Background" - case todo: - return "context.TODO" - } - return "unknown empty Context" -} - -var ( - background = new(emptyCtx) - todo = new(emptyCtx) -) - -// Background returns a non-nil, empty Context. It is never canceled, has no -// values, and has no deadline. It is typically used by the main function, -// initialization, and tests, and as the top-level Context for incoming -// requests. -func Background() Context { - return background -} - -// TODO returns a non-nil, empty Context. Code should use context.TODO when -// it's unclear which Context to use or it is not yet available (because the -// surrounding function has not yet been extended to accept a Context -// parameter). TODO is recognized by static analysis tools that determine -// whether Contexts are propagated correctly in a program. -func TODO() Context { - return todo -} - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc func() - -// WithCancel returns a copy of parent with a new Done channel. The returned -// context's Done channel is closed when the returned cancel function is called -// or when the parent context's Done channel is closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { - c := newCancelCtx(parent) - propagateCancel(parent, &c) - return &c, func() { c.cancel(true, Canceled) } -} - -// newCancelCtx returns an initialized cancelCtx. -func newCancelCtx(parent Context) cancelCtx { - return cancelCtx{ - Context: parent, - done: make(chan struct{}), - } -} - -// propagateCancel arranges for child to be canceled when parent is. -func propagateCancel(parent Context, child canceler) { - if parent.Done() == nil { - return // parent is never canceled - } - if p, ok := parentCancelCtx(parent); ok { - p.mu.Lock() - if p.err != nil { - // parent has already been canceled - child.cancel(false, p.err) - } else { - if p.children == nil { - p.children = make(map[canceler]bool) - } - p.children[child] = true - } - p.mu.Unlock() - } else { - go func() { - select { - case <-parent.Done(): - child.cancel(false, parent.Err()) - case <-child.Done(): - } - }() - } -} - -// parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this -// package represents its parent. -func parentCancelCtx(parent Context) (*cancelCtx, bool) { - for { - switch c := parent.(type) { - case *cancelCtx: - return c, true - case *timerCtx: - return &c.cancelCtx, true - case *valueCtx: - parent = c.Context - default: - return nil, false - } - } -} - -// removeChild removes a context from its parent. -func removeChild(parent Context, child canceler) { - p, ok := parentCancelCtx(parent) - if !ok { - return - } - p.mu.Lock() - if p.children != nil { - delete(p.children, child) - } - p.mu.Unlock() -} - -// A canceler is a context type that can be canceled directly. The -// implementations are *cancelCtx and *timerCtx. -type canceler interface { - cancel(removeFromParent bool, err error) - Done() <-chan struct{} -} - -// A cancelCtx can be canceled. When canceled, it also cancels any children -// that implement canceler. -type cancelCtx struct { - Context - - done chan struct{} // closed by the first cancel call. - - mu sync.Mutex - children map[canceler]bool // set to nil by the first cancel call - err error // set to non-nil by the first cancel call -} - -func (c *cancelCtx) Done() <-chan struct{} { - return c.done -} - -func (c *cancelCtx) Err() error { - c.mu.Lock() - defer c.mu.Unlock() - return c.err -} - -func (c *cancelCtx) String() string { - return fmt.Sprintf("%v.WithCancel", c.Context) -} - -// cancel closes c.done, cancels each of c's children, and, if -// removeFromParent is true, removes c from its parent's children. -func (c *cancelCtx) cancel(removeFromParent bool, err error) { - if err == nil { - panic("context: internal error: missing cancel error") - } - c.mu.Lock() - if c.err != nil { - c.mu.Unlock() - return // already canceled - } - c.err = err - close(c.done) - for child := range c.children { - // NOTE: acquiring the child's lock while holding parent's lock. - child.cancel(false, err) - } - c.children = nil - c.mu.Unlock() - - if removeFromParent { - removeChild(c.Context, c) - } -} - -// WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned -// context's Done channel is closed when the deadline expires, when the returned -// cancel function is called, or when the parent context's Done channel is -// closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { - if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { - // The current deadline is already sooner than the new one. - return WithCancel(parent) - } - c := &timerCtx{ - cancelCtx: newCancelCtx(parent), - deadline: deadline, - } - propagateCancel(parent, c) - d := deadline.Sub(time.Now()) - if d <= 0 { - c.cancel(true, DeadlineExceeded) // deadline has already passed - return c, func() { c.cancel(true, Canceled) } - } - c.mu.Lock() - defer c.mu.Unlock() - if c.err == nil { - c.timer = time.AfterFunc(d, func() { - c.cancel(true, DeadlineExceeded) - }) - } - return c, func() { c.cancel(true, Canceled) } -} - -// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to -// implement Done and Err. It implements cancel by stopping its timer then -// delegating to cancelCtx.cancel. -type timerCtx struct { - cancelCtx - timer *time.Timer // Under cancelCtx.mu. - - deadline time.Time -} - -func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { - return c.deadline, true -} - -func (c *timerCtx) String() string { - return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) -} - -func (c *timerCtx) cancel(removeFromParent bool, err error) { - c.cancelCtx.cancel(false, err) - if removeFromParent { - // Remove this timerCtx from its parent cancelCtx's children. - removeChild(c.cancelCtx.Context, c) - } - c.mu.Lock() - if c.timer != nil { - c.timer.Stop() - c.timer = nil - } - c.mu.Unlock() -} - -// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete: -// -// func slowOperationWithTimeout(ctx context.Context) (Result, error) { -// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) -// defer cancel() // releases resources if slowOperation completes before timeout elapses -// return slowOperation(ctx) -// } -func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { - return WithDeadline(parent, time.Now().Add(timeout)) -} - -// WithValue returns a copy of parent in which the value associated with key is -// val. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -func WithValue(parent Context, key interface{}, val interface{}) Context { - return &valueCtx{parent, key, val} -} - -// A valueCtx carries a key-value pair. It implements Value for that key and -// delegates all other calls to the embedded Context. -type valueCtx struct { - Context - key, val interface{} -} - -func (c *valueCtx) String() string { - return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) -} - -func (c *valueCtx) Value(key interface{}) interface{} { - if c.key == key { - return c.val - } - return c.Context.Value(key) -} diff --git a/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go b/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go deleted file mode 100644 index e3170e333..000000000 --- a/vendor/golang.org/x/net/context/ctxhttp/cancelreq.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.5 - -package ctxhttp - -import "net/http" - -func canceler(client *http.Client, req *http.Request) func() { - // TODO(djd): Respect any existing value of req.Cancel. - ch := make(chan struct{}) - req.Cancel = ch - - return func() { - close(ch) - } -} diff --git a/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go b/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go deleted file mode 100644 index 56bcbadb8..000000000 --- a/vendor/golang.org/x/net/context/ctxhttp/cancelreq_go14.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.5 - -package ctxhttp - -import "net/http" - -type requestCanceler interface { - CancelRequest(*http.Request) -} - -func canceler(client *http.Client, req *http.Request) func() { - rc, ok := client.Transport.(requestCanceler) - if !ok { - return func() {} - } - return func() { - rc.CancelRequest(req) - } -} diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go deleted file mode 100644 index 62620d4eb..000000000 --- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ctxhttp provides helper functions for performing context-aware HTTP requests. -package ctxhttp // import "golang.org/x/net/context/ctxhttp" - -import ( - "io" - "net/http" - "net/url" - "strings" - - "golang.org/x/net/context" -) - -func nop() {} - -var ( - testHookContextDoneBeforeHeaders = nop - testHookDoReturned = nop - testHookDidBodyClose = nop -) - -// Do sends an HTTP request with the provided http.Client and returns an HTTP response. -// If the client is nil, http.DefaultClient is used. -// If the context is canceled or times out, ctx.Err() will be returned. -func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { - if client == nil { - client = http.DefaultClient - } - - // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. - cancel := canceler(client, req) - - type responseAndError struct { - resp *http.Response - err error - } - result := make(chan responseAndError, 1) - - go func() { - resp, err := client.Do(req) - testHookDoReturned() - result <- responseAndError{resp, err} - }() - - var resp *http.Response - - select { - case <-ctx.Done(): - testHookContextDoneBeforeHeaders() - cancel() - // Clean up after the goroutine calling client.Do: - go func() { - if r := <-result; r.resp != nil { - testHookDidBodyClose() - r.resp.Body.Close() - } - }() - return nil, ctx.Err() - case r := <-result: - var err error - resp, err = r.resp, r.err - if err != nil { - return resp, err - } - } - - c := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - cancel() - case <-c: - // The response's Body is closed. - } - }() - resp.Body = &notifyingReader{resp.Body, c} - - return resp, nil -} - -// Get issues a GET request via the Do function. -func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Head issues a HEAD request via the Do function. -func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("HEAD", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Post issues a POST request via the Do function. -func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { - req, err := http.NewRequest("POST", url, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", bodyType) - return Do(ctx, client, req) -} - -// PostForm issues a POST request via the Do function. -func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { - return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} - -// notifyingReader is an io.ReadCloser that closes the notify channel after -// Close is called or a Read fails on the underlying ReadCloser. -type notifyingReader struct { - io.ReadCloser - notify chan<- struct{} -} - -func (r *notifyingReader) Read(p []byte) (int, error) { - n, err := r.ReadCloser.Read(p) - if err != nil && r.notify != nil { - close(r.notify) - r.notify = nil - } - return n, err -} - -func (r *notifyingReader) Close() error { - err := r.ReadCloser.Close() - if r.notify != nil { - close(r.notify) - r.notify = nil - } - return err -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 3cf9e6714..1abbbe7b7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1220,16 +1220,6 @@ "revision": "453249f01cfeb54c3d549ddb75ff152ca243f9d8", "revisionTime": "2017-02-08T20:51:15Z" }, - { - "checksumSHA1": "5ARrN3Zq+E9zazFb/N+b08Serys=", - "path": "golang.org/x/net/context", - "revision": "6ccd6698c634f5d835c40c1c31848729e0cecda1" - }, - { - "checksumSHA1": "tHFno3QaRarH85A4DV1FYuWATQI=", - "path": "golang.org/x/net/context/ctxhttp", - "revision": "6ccd6698c634f5d835c40c1c31848729e0cecda1" - }, { "checksumSHA1": "vqc3a+oTUGX8PmD0TS+qQ7gmN8I=", "path": "golang.org/x/net/html", From aa667577a57de90f8cb44a337cf5b065423438a2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 16:59:34 -0800 Subject: [PATCH 0441/1007] update context library --- vendor/golang.org/x/net/context/context.go | 56 ++++ .../x/net/context/ctxhttp/ctxhttp.go | 74 +++++ .../x/net/context/ctxhttp/ctxhttp_pre17.go | 147 +++++++++ vendor/golang.org/x/net/context/go17.go | 72 +++++ vendor/golang.org/x/net/context/go19.go | 20 ++ vendor/golang.org/x/net/context/pre_go17.go | 300 ++++++++++++++++++ vendor/golang.org/x/net/context/pre_go19.go | 109 +++++++ vendor/vendor.json | 12 + 8 files changed, 790 insertions(+) create mode 100644 vendor/golang.org/x/net/context/context.go create mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go create mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go create mode 100644 vendor/golang.org/x/net/context/go17.go create mode 100644 vendor/golang.org/x/net/context/go19.go create mode 100644 vendor/golang.org/x/net/context/pre_go17.go create mode 100644 vendor/golang.org/x/net/context/pre_go19.go diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go new file mode 100644 index 000000000..a3c021d3f --- /dev/null +++ b/vendor/golang.org/x/net/context/context.go @@ -0,0 +1,56 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package context defines the Context type, which carries deadlines, +// cancelation signals, and other request-scoped values across API boundaries +// and between processes. +// As of Go 1.7 this package is available in the standard library under the +// name context. https://golang.org/pkg/context. +// +// Incoming requests to a server should create a Context, and outgoing calls to +// servers should accept a Context. The chain of function calls between must +// propagate the Context, optionally replacing it with a modified copy created +// using WithDeadline, WithTimeout, WithCancel, or WithValue. +// +// Programs that use Contexts should follow these rules to keep interfaces +// consistent across packages and enable static analysis tools to check context +// propagation: +// +// Do not store Contexts inside a struct type; instead, pass a Context +// explicitly to each function that needs it. The Context should be the first +// parameter, typically named ctx: +// +// func DoSomething(ctx context.Context, arg Arg) error { +// // ... use ctx ... +// } +// +// Do not pass a nil Context, even if a function permits it. Pass context.TODO +// if you are unsure about which Context to use. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +// +// The same Context may be passed to functions running in different goroutines; +// Contexts are safe for simultaneous use by multiple goroutines. +// +// See http://blog.golang.org/context for example code for a server that uses +// Contexts. +package context // import "golang.org/x/net/context" + +// Background returns a non-nil, empty Context. It is never canceled, has no +// values, and has no deadline. It is typically used by the main function, +// initialization, and tests, and as the top-level Context for incoming +// requests. +func Background() Context { + return background +} + +// TODO returns a non-nil, empty Context. Code should use context.TODO when +// it's unclear which Context to use or it is not yet available (because the +// surrounding function has not yet been extended to accept a Context +// parameter). TODO is recognized by static analysis tools that determine +// whether Contexts are propagated correctly in a program. +func TODO() Context { + return todo +} diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go new file mode 100644 index 000000000..606cf1f97 --- /dev/null +++ b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go @@ -0,0 +1,74 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +// Package ctxhttp provides helper functions for performing context-aware HTTP requests. +package ctxhttp // import "golang.org/x/net/context/ctxhttp" + +import ( + "io" + "net/http" + "net/url" + "strings" + + "golang.org/x/net/context" +) + +// Do sends an HTTP request with the provided http.Client and returns +// an HTTP response. +// +// If the client is nil, http.DefaultClient is used. +// +// The provided ctx must be non-nil. If it is canceled or times out, +// ctx.Err() will be returned. +func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + resp, err := client.Do(req.WithContext(ctx)) + // If we got an error, and the context has been canceled, + // the context's error is probably more useful. + if err != nil { + select { + case <-ctx.Done(): + err = ctx.Err() + default: + } + } + return resp, err +} + +// Get issues a GET request via the Do function. +func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Head issues a HEAD request via the Do function. +func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Post issues a POST request via the Do function. +func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequest("POST", url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", bodyType) + return Do(ctx, client, req) +} + +// PostForm issues a POST request via the Do function. +func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { + return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +} diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go new file mode 100644 index 000000000..926870cc2 --- /dev/null +++ b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go @@ -0,0 +1,147 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.7 + +package ctxhttp // import "golang.org/x/net/context/ctxhttp" + +import ( + "io" + "net/http" + "net/url" + "strings" + + "golang.org/x/net/context" +) + +func nop() {} + +var ( + testHookContextDoneBeforeHeaders = nop + testHookDoReturned = nop + testHookDidBodyClose = nop +) + +// Do sends an HTTP request with the provided http.Client and returns an HTTP response. +// If the client is nil, http.DefaultClient is used. +// If the context is canceled or times out, ctx.Err() will be returned. +func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + + // TODO(djd): Respect any existing value of req.Cancel. + cancel := make(chan struct{}) + req.Cancel = cancel + + type responseAndError struct { + resp *http.Response + err error + } + result := make(chan responseAndError, 1) + + // Make local copies of test hooks closed over by goroutines below. + // Prevents data races in tests. + testHookDoReturned := testHookDoReturned + testHookDidBodyClose := testHookDidBodyClose + + go func() { + resp, err := client.Do(req) + testHookDoReturned() + result <- responseAndError{resp, err} + }() + + var resp *http.Response + + select { + case <-ctx.Done(): + testHookContextDoneBeforeHeaders() + close(cancel) + // Clean up after the goroutine calling client.Do: + go func() { + if r := <-result; r.resp != nil { + testHookDidBodyClose() + r.resp.Body.Close() + } + }() + return nil, ctx.Err() + case r := <-result: + var err error + resp, err = r.resp, r.err + if err != nil { + return resp, err + } + } + + c := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + close(cancel) + case <-c: + // The response's Body is closed. + } + }() + resp.Body = &notifyingReader{resp.Body, c} + + return resp, nil +} + +// Get issues a GET request via the Do function. +func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Head issues a HEAD request via the Do function. +func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Post issues a POST request via the Do function. +func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequest("POST", url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", bodyType) + return Do(ctx, client, req) +} + +// PostForm issues a POST request via the Do function. +func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { + return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +} + +// notifyingReader is an io.ReadCloser that closes the notify channel after +// Close is called or a Read fails on the underlying ReadCloser. +type notifyingReader struct { + io.ReadCloser + notify chan<- struct{} +} + +func (r *notifyingReader) Read(p []byte) (int, error) { + n, err := r.ReadCloser.Read(p) + if err != nil && r.notify != nil { + close(r.notify) + r.notify = nil + } + return n, err +} + +func (r *notifyingReader) Close() error { + err := r.ReadCloser.Close() + if r.notify != nil { + close(r.notify) + r.notify = nil + } + return err +} diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go new file mode 100644 index 000000000..d20f52b7d --- /dev/null +++ b/vendor/golang.org/x/net/context/go17.go @@ -0,0 +1,72 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package context + +import ( + "context" // standard library's context, as of Go 1.7 + "time" +) + +var ( + todo = context.TODO() + background = context.Background() +) + +// Canceled is the error returned by Context.Err when the context is canceled. +var Canceled = context.Canceled + +// DeadlineExceeded is the error returned by Context.Err when the context's +// deadline passes. +var DeadlineExceeded = context.DeadlineExceeded + +// WithCancel returns a copy of parent with a new Done channel. The returned +// context's Done channel is closed when the returned cancel function is called +// or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + ctx, f := context.WithCancel(parent) + return ctx, CancelFunc(f) +} + +// WithDeadline returns a copy of the parent context with the deadline adjusted +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// context's Done channel is closed when the deadline expires, when the returned +// cancel function is called, or when the parent context's Done channel is +// closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { + ctx, f := context.WithDeadline(parent, deadline) + return ctx, CancelFunc(f) +} + +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: +// +// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +// defer cancel() // releases resources if slowOperation completes before timeout elapses +// return slowOperation(ctx) +// } +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { + return WithDeadline(parent, time.Now().Add(timeout)) +} + +// WithValue returns a copy of parent in which the value associated with key is +// val. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +func WithValue(parent Context, key interface{}, val interface{}) Context { + return context.WithValue(parent, key, val) +} diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go new file mode 100644 index 000000000..d88bd1db1 --- /dev/null +++ b/vendor/golang.org/x/net/context/go19.go @@ -0,0 +1,20 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.9 + +package context + +import "context" // standard library's context, as of Go 1.7 + +// A Context carries a deadline, a cancelation signal, and other values across +// API boundaries. +// +// Context's methods may be called by multiple goroutines simultaneously. +type Context = context.Context + +// A CancelFunc tells an operation to abandon its work. +// A CancelFunc does not wait for the work to stop. +// After the first call, subsequent calls to a CancelFunc do nothing. +type CancelFunc = context.CancelFunc diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go new file mode 100644 index 000000000..0f35592df --- /dev/null +++ b/vendor/golang.org/x/net/context/pre_go17.go @@ -0,0 +1,300 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.7 + +package context + +import ( + "errors" + "fmt" + "sync" + "time" +) + +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case background: + return "context.Background" + case todo: + return "context.TODO" + } + return "unknown empty Context" +} + +var ( + background = new(emptyCtx) + todo = new(emptyCtx) +) + +// Canceled is the error returned by Context.Err when the context is canceled. +var Canceled = errors.New("context canceled") + +// DeadlineExceeded is the error returned by Context.Err when the context's +// deadline passes. +var DeadlineExceeded = errors.New("context deadline exceeded") + +// WithCancel returns a copy of parent with a new Done channel. The returned +// context's Done channel is closed when the returned cancel function is called +// or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + c := newCancelCtx(parent) + propagateCancel(parent, c) + return c, func() { c.cancel(true, Canceled) } +} + +// newCancelCtx returns an initialized cancelCtx. +func newCancelCtx(parent Context) *cancelCtx { + return &cancelCtx{ + Context: parent, + done: make(chan struct{}), + } +} + +// propagateCancel arranges for child to be canceled when parent is. +func propagateCancel(parent Context, child canceler) { + if parent.Done() == nil { + return // parent is never canceled + } + if p, ok := parentCancelCtx(parent); ok { + p.mu.Lock() + if p.err != nil { + // parent has already been canceled + child.cancel(false, p.err) + } else { + if p.children == nil { + p.children = make(map[canceler]bool) + } + p.children[child] = true + } + p.mu.Unlock() + } else { + go func() { + select { + case <-parent.Done(): + child.cancel(false, parent.Err()) + case <-child.Done(): + } + }() + } +} + +// parentCancelCtx follows a chain of parent references until it finds a +// *cancelCtx. This function understands how each of the concrete types in this +// package represents its parent. +func parentCancelCtx(parent Context) (*cancelCtx, bool) { + for { + switch c := parent.(type) { + case *cancelCtx: + return c, true + case *timerCtx: + return c.cancelCtx, true + case *valueCtx: + parent = c.Context + default: + return nil, false + } + } +} + +// removeChild removes a context from its parent. +func removeChild(parent Context, child canceler) { + p, ok := parentCancelCtx(parent) + if !ok { + return + } + p.mu.Lock() + if p.children != nil { + delete(p.children, child) + } + p.mu.Unlock() +} + +// A canceler is a context type that can be canceled directly. The +// implementations are *cancelCtx and *timerCtx. +type canceler interface { + cancel(removeFromParent bool, err error) + Done() <-chan struct{} +} + +// A cancelCtx can be canceled. When canceled, it also cancels any children +// that implement canceler. +type cancelCtx struct { + Context + + done chan struct{} // closed by the first cancel call. + + mu sync.Mutex + children map[canceler]bool // set to nil by the first cancel call + err error // set to non-nil by the first cancel call +} + +func (c *cancelCtx) Done() <-chan struct{} { + return c.done +} + +func (c *cancelCtx) Err() error { + c.mu.Lock() + defer c.mu.Unlock() + return c.err +} + +func (c *cancelCtx) String() string { + return fmt.Sprintf("%v.WithCancel", c.Context) +} + +// cancel closes c.done, cancels each of c's children, and, if +// removeFromParent is true, removes c from its parent's children. +func (c *cancelCtx) cancel(removeFromParent bool, err error) { + if err == nil { + panic("context: internal error: missing cancel error") + } + c.mu.Lock() + if c.err != nil { + c.mu.Unlock() + return // already canceled + } + c.err = err + close(c.done) + for child := range c.children { + // NOTE: acquiring the child's lock while holding parent's lock. + child.cancel(false, err) + } + c.children = nil + c.mu.Unlock() + + if removeFromParent { + removeChild(c.Context, c) + } +} + +// WithDeadline returns a copy of the parent context with the deadline adjusted +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// context's Done channel is closed when the deadline expires, when the returned +// cancel function is called, or when the parent context's Done channel is +// closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { + if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { + // The current deadline is already sooner than the new one. + return WithCancel(parent) + } + c := &timerCtx{ + cancelCtx: newCancelCtx(parent), + deadline: deadline, + } + propagateCancel(parent, c) + d := deadline.Sub(time.Now()) + if d <= 0 { + c.cancel(true, DeadlineExceeded) // deadline has already passed + return c, func() { c.cancel(true, Canceled) } + } + c.mu.Lock() + defer c.mu.Unlock() + if c.err == nil { + c.timer = time.AfterFunc(d, func() { + c.cancel(true, DeadlineExceeded) + }) + } + return c, func() { c.cancel(true, Canceled) } +} + +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +// implement Done and Err. It implements cancel by stopping its timer then +// delegating to cancelCtx.cancel. +type timerCtx struct { + *cancelCtx + timer *time.Timer // Under cancelCtx.mu. + + deadline time.Time +} + +func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { + return c.deadline, true +} + +func (c *timerCtx) String() string { + return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) +} + +func (c *timerCtx) cancel(removeFromParent bool, err error) { + c.cancelCtx.cancel(false, err) + if removeFromParent { + // Remove this timerCtx from its parent cancelCtx's children. + removeChild(c.cancelCtx.Context, c) + } + c.mu.Lock() + if c.timer != nil { + c.timer.Stop() + c.timer = nil + } + c.mu.Unlock() +} + +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: +// +// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +// defer cancel() // releases resources if slowOperation completes before timeout elapses +// return slowOperation(ctx) +// } +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { + return WithDeadline(parent, time.Now().Add(timeout)) +} + +// WithValue returns a copy of parent in which the value associated with key is +// val. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +func WithValue(parent Context, key interface{}, val interface{}) Context { + return &valueCtx{parent, key, val} +} + +// A valueCtx carries a key-value pair. It implements Value for that key and +// delegates all other calls to the embedded Context. +type valueCtx struct { + Context + key, val interface{} +} + +func (c *valueCtx) String() string { + return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) +} + +func (c *valueCtx) Value(key interface{}) interface{} { + if c.key == key { + return c.val + } + return c.Context.Value(key) +} diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go new file mode 100644 index 000000000..b105f80be --- /dev/null +++ b/vendor/golang.org/x/net/context/pre_go19.go @@ -0,0 +1,109 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.9 + +package context + +import "time" + +// A Context carries a deadline, a cancelation signal, and other values across +// API boundaries. +// +// Context's methods may be called by multiple goroutines simultaneously. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + // + // WithCancel arranges for Done to be closed when cancel is called; + // WithDeadline arranges for Done to be closed when the deadline + // expires; WithTimeout arranges for Done to be closed when the timeout + // elapses. + // + // Done is provided for use in select statements: + // + // // Stream generates values with DoSomething and sends them to out + // // until DoSomething returns an error or ctx.Done is closed. + // func Stream(ctx context.Context, out chan<- Value) error { + // for { + // v, err := DoSomething(ctx) + // if err != nil { + // return err + // } + // select { + // case <-ctx.Done(): + // return ctx.Err() + // case out <- v: + // } + // } + // } + // + // See http://blog.golang.org/pipelines for more examples of how to use + // a Done channel for cancelation. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + // + // A key identifies a specific value in a Context. Functions that wish + // to store values in Context typically allocate a key in a global + // variable then use that key as the argument to context.WithValue and + // Context.Value. A key can be any type that supports equality; + // packages should define keys as an unexported type to avoid + // collisions. + // + // Packages that define a Context key should provide type-safe accessors + // for the values stores using that key: + // + // // Package user defines a User type that's stored in Contexts. + // package user + // + // import "golang.org/x/net/context" + // + // // User is the type of value stored in the Contexts. + // type User struct {...} + // + // // key is an unexported type for keys defined in this package. + // // This prevents collisions with keys defined in other packages. + // type key int + // + // // userKey is the key for user.User values in Contexts. It is + // // unexported; clients use user.NewContext and user.FromContext + // // instead of using this key directly. + // var userKey key = 0 + // + // // NewContext returns a new Context that carries value u. + // func NewContext(ctx context.Context, u *User) context.Context { + // return context.WithValue(ctx, userKey, u) + // } + // + // // FromContext returns the User value stored in ctx, if any. + // func FromContext(ctx context.Context) (*User, bool) { + // u, ok := ctx.Value(userKey).(*User) + // return u, ok + // } + Value(key interface{}) interface{} +} + +// A CancelFunc tells an operation to abandon its work. +// A CancelFunc does not wait for the work to stop. +// After the first call, subsequent calls to a CancelFunc do nothing. +type CancelFunc func() diff --git a/vendor/vendor.json b/vendor/vendor.json index 1abbbe7b7..e8c3fb6f1 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1220,6 +1220,18 @@ "revision": "453249f01cfeb54c3d549ddb75ff152ca243f9d8", "revisionTime": "2017-02-08T20:51:15Z" }, + { + "checksumSHA1": "GtamqiJoL7PGHsN454AoffBFMa8=", + "path": "golang.org/x/net/context", + "revision": "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec", + "revisionTime": "2018-01-12T01:53:59Z" + }, + { + "checksumSHA1": "WHc3uByvGaMcnSoI21fhzYgbOgg=", + "path": "golang.org/x/net/context/ctxhttp", + "revision": "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec", + "revisionTime": "2018-01-12T01:53:59Z" + }, { "checksumSHA1": "vqc3a+oTUGX8PmD0TS+qQ7gmN8I=", "path": "golang.org/x/net/html", From eafda52411adaabc69c6920a1fffa50ae315105f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 22 Jan 2018 17:50:40 -0800 Subject: [PATCH 0442/1007] use amazon steps from master --- builder/amazon/common/step_run_source_instance.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index a5acf0e25..cc343961d 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -179,17 +179,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - ctx, cancel := context.WithCancel(context.Background()) - - go func() { - for { - if _, ok := state.GetOk(multistep.StateCancelled); ok { - cancel() - } - } - }() - - if err := ec2conn.WaitUntilInstanceRunningWithContext(ctx, describeInstance); err != nil { + if err := ec2conn.WaitUntilInstanceRunning(describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) From 3e2895afecb12053d1d0df59cac925005a97726c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 23 Jan 2018 09:50:06 -0800 Subject: [PATCH 0443/1007] comments --- helper/multistep/multistep.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/helper/multistep/multistep.go b/helper/multistep/multistep.go index 7b4e0801f..39c44ed0a 100644 --- a/helper/multistep/multistep.go +++ b/helper/multistep/multistep.go @@ -22,8 +22,9 @@ const StateHalted = "halted" // Step is a single step that is part of a potentially large sequence // of other steps, responsible for performing some specific action. type Step interface { - // Run is called to perform the action. The parameter is a "state bag" - // of untyped things. Please be very careful about type-checking the + // Run is called to perform the action. The passed through context will be + // cancelled when the runner is cancelled. The second parameter is a "state + // bag" of untyped things. Please be very careful about type-checking the // items in this bag. // // The return value determines whether multi-step sequences continue From 5e444ff7ab3b5b10916000e6fce32fa80a000241 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 24 Jan 2018 17:27:08 -0800 Subject: [PATCH 0444/1007] update multistep documentation --- website/source/docs/extending/custom-builders.html.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/source/docs/extending/custom-builders.html.md b/website/source/docs/extending/custom-builders.html.md index 7cd31b161..3d421f35d 100644 --- a/website/source/docs/extending/custom-builders.html.md +++ b/website/source/docs/extending/custom-builders.html.md @@ -82,11 +82,11 @@ And `packer.Cache` is used to store files between multiple Packer runs, and is covered in more detail in the cache section below. Because builder runs are typically a complex set of many steps, the -[multistep](https://github.com/mitchellh/multistep) library is recommended to -bring order to the complexity. Multistep is a library which allows you to -separate your logic into multiple distinct "steps" and string them together. It -fully supports cancellation mid-step and so on. Please check it out, it is how -the built-in builders are all implemented. +[multistep](https://github.com/hashicorp/packer/blob/master/helper/multistep) +helper is recommended to bring order to the complexity. Multistep is a library +which allows you to separate your logic into multiple distinct "steps" and +string them together. It fully supports cancellation mid-step and so on. Please +check it out, it is how the built-in builders are all implemented. Finally, as a result of `Run`, an implementation of `packer.Artifact` should be returned. More details on creating a `packer.Artifact` are covered in the From 380147200c2a3e9177bf0e868342f89cef672ffa Mon Sep 17 00:00:00 2001 From: Brian Terry <bterry4@my.westga.edu> Date: Thu, 25 Jan 2018 10:56:30 -0500 Subject: [PATCH 0445/1007] Added role in amazon-import --- post-processor/amazon-import/post-processor.go | 6 ++++++ website/source/docs/post-processors/amazon-import.html.md | 2 ++ 2 files changed, 8 insertions(+) diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 90e87d6c7..2a5a0c785 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -34,6 +34,7 @@ type Config struct { Users []string `mapstructure:"ami_users"` Groups []string `mapstructure:"ami_groups"` LicenseType string `mapstructure:"license_type"` + RoleName string `mapstructure:"role_name"` ctx interpolate.Context } @@ -63,6 +64,10 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { p.config.S3Key = "packer-import-{{timestamp}}.ova" } + if p.config.RoleName == "" { + p.config.RoleName = "vmimport" + } + errs := new(packer.MultiError) // Check and render s3_key_name @@ -164,6 +169,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac }, }, }, + RoleName: &p.config.RoleName, } if p.config.LicenseType != "" { diff --git a/website/source/docs/post-processors/amazon-import.html.md b/website/source/docs/post-processors/amazon-import.html.md index 85d139093..766bda48b 100644 --- a/website/source/docs/post-processors/amazon-import.html.md +++ b/website/source/docs/post-processors/amazon-import.html.md @@ -70,6 +70,8 @@ Optional: - `mfa_code` (string) - The MFA [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) code. This should probably be a user variable since it changes all the time. +- `role_name` (string) - The name of the role to use when not using the default role, 'vmimport' + - `s3_key_name` (string) - The name of the key in `s3_bucket_name` where the OVA file will be copied to for import. If not specified, this will default to "packer-import-{{timestamp}}.ova". This key (ie, the uploaded OVA) will From 48e12b6beef5d06129ec3acfc58d0e3eacd4cc0f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 10:37:34 -0800 Subject: [PATCH 0446/1007] only set role name if it's set. --- post-processor/amazon-import/post-processor.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 2a5a0c785..5be505b0e 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -64,10 +64,6 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { p.config.S3Key = "packer-import-{{timestamp}}.ova" } - if p.config.RoleName == "" { - p.config.RoleName = "vmimport" - } - errs := new(packer.MultiError) // Check and render s3_key_name @@ -169,7 +165,10 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac }, }, }, - RoleName: &p.config.RoleName, + } + + if p.config.RoleName != "" { + params.SetRoleName(p.config.RoleName) } if p.config.LicenseType != "" { From 543caf3ec575621dd9210a6bd33116193d9da934 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 14:12:15 -0800 Subject: [PATCH 0447/1007] WIP OCI Classic builder --- builder/oracle/classic/access_config.go | 4 + builder/oracle/classic/artifact.go | 34 ++++++++ builder/oracle/classic/builder.go | 87 +++++++++++++++++++ builder/oracle/classic/config.go | 44 ++++++++++ .../{oci => common}/step_ssh_key_pair.go | 8 +- builder/oracle/oci/builder.go | 3 +- 6 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 builder/oracle/classic/access_config.go create mode 100644 builder/oracle/classic/artifact.go create mode 100644 builder/oracle/classic/builder.go create mode 100644 builder/oracle/classic/config.go rename builder/oracle/{oci => common}/step_ssh_key_pair.go (94%) diff --git a/builder/oracle/classic/access_config.go b/builder/oracle/classic/access_config.go new file mode 100644 index 000000000..99483ceec --- /dev/null +++ b/builder/oracle/classic/access_config.go @@ -0,0 +1,4 @@ +package classic + +type AccessConfig struct { +} diff --git a/builder/oracle/classic/artifact.go b/builder/oracle/classic/artifact.go new file mode 100644 index 000000000..ff01b186f --- /dev/null +++ b/builder/oracle/classic/artifact.go @@ -0,0 +1,34 @@ +package classic + +// Artifact is an artifact implementation that contains a built Custom Image. +type Artifact struct { +} + +// BuilderId uniquely identifies the builder. +func (a *Artifact) BuilderId() string { + return BuilderId +} + +// Files lists the files associated with an artifact. We don't have any files +// as the custom image is stored server side. +func (a *Artifact) Files() []string { + return nil +} + +// Id returns the OCID of the associated Image. +func (a *Artifact) Id() string { + return "" +} + +func (a *Artifact) String() string { + return "" +} + +func (a *Artifact) State(name string) interface{} { + return nil +} + +// Destroy deletes the custom image associated with the artifact. +func (a *Artifact) Destroy() error { + return nil +} diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go new file mode 100644 index 000000000..4b86c449c --- /dev/null +++ b/builder/oracle/classic/builder.go @@ -0,0 +1,87 @@ +package classic + +import ( + "fmt" + "log" + + ocommon "github.com/hashicorp/packer/builder/oracle/common" + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +// BuilderId uniquely identifies the builder +const BuilderId = "packer.oracle.classic" + +// Builder is a builder implementation that creates Oracle OCI custom images. +type Builder struct { + config *Config + runner multistep.Runner +} + +func (b *Builder) Prepare(rawConfig ...interface{}) ([]string, error) { + config, err := NewConfig(rawConfig...) + if err != nil { + return nil, err + } + b.config = config + + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + // Populate the state bag + state := new(multistep.BasicStateBag) + state.Put("config", b.config) + state.Put("hook", hook) + state.Put("ui", ui) + + // Build the steps + steps := []multistep.Step{ + &ocommon.StepKeyPair{ + Debug: b.config.PackerDebug, + DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), + PrivateKeyFile: b.config.Comm.SSHPrivateKey, + }, + &stepCreateInstance{}, + &communicator.StepConnect{ + Config: &b.config.Comm, + Host: commHost, + SSHConfig: SSHConfig( + b.config.Comm.SSHUsername, + b.config.Comm.SSHPassword), + }, + &common.StepProvision{}, + &stepSnapshot{}, + } + + // Run the steps + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + + // If there was an error, return that + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + /* + // Build the artifact and return it + artifact := &Artifact{ + Image: state.Get("image").(client.Image), + Region: b.config.AccessCfg.Region, + driver: driver, + } + + return artifact, nil + */ + return nil, nil +} + +// Cancel terminates a running build. +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go new file mode 100644 index 000000000..6a3c05fc8 --- /dev/null +++ b/builder/oracle/classic/config.go @@ -0,0 +1,44 @@ +package classic + +import ( + "fmt" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/template/interpolate" +) + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + Comm communicator.Config `mapstructure:",squash"` + + Access *AccessConfig + + // Access config overrides + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` + IdentityDomain string `mapstructure:"identity_domain"` + APIEndpoint string `mapstructure:"api_endpoint"` + + // Image + Shape string `mapstructure:"shape"` + ImageList string `json:"image_list"` + + ctx interpolate.Context +} + +func NewConfig(raws ...interface{}) (*Config, error) { + c := &Config{} + + // Decode from template + err := config.Decode(c, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &c.ctx, + }, raws...) + if err != nil { + return nil, fmt.Errorf("Failed to mapstructure Config: %+v", err) + } + + return c, nil +} diff --git a/builder/oracle/oci/step_ssh_key_pair.go b/builder/oracle/common/step_ssh_key_pair.go similarity index 94% rename from builder/oracle/oci/step_ssh_key_pair.go rename to builder/oracle/common/step_ssh_key_pair.go index 9fa83c17d..c545a09e2 100644 --- a/builder/oracle/oci/step_ssh_key_pair.go +++ b/builder/oracle/common/step_ssh_key_pair.go @@ -1,4 +1,4 @@ -package oci +package common import ( "context" @@ -16,13 +16,13 @@ import ( "golang.org/x/crypto/ssh" ) -type stepKeyPair struct { +type StepKeyPair struct { Debug bool DebugKeyPath string PrivateKeyFile string } -func (s *stepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { @@ -112,6 +112,6 @@ func (s *stepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep return multistep.ActionContinue } -func (s *stepKeyPair) Cleanup(state multistep.StateBag) { +func (s *StepKeyPair) Cleanup(state multistep.StateBag) { // Nothing to do } diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index 6a2f6efef..07d41b756 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -6,6 +6,7 @@ import ( "fmt" "log" + ocommon "github.com/hashicorp/packer/builder/oracle/common" client "github.com/hashicorp/packer/builder/oracle/oci/client" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -50,7 +51,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the steps steps := []multistep.Step{ - &stepKeyPair{ + &ocommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("oci_%s.pem", b.config.PackerBuildName), PrivateKeyFile: b.config.Comm.SSHPrivateKey, From 9e8d845c03e7539c18bb8ad3d2ce357cd565382c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 14:19:13 -0800 Subject: [PATCH 0448/1007] create instance reservation --- builder/oracle/classic/builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 4b86c449c..5fe719567 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -44,6 +44,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), PrivateKeyFile: b.config.Comm.SSHPrivateKey, }, + &stepCreateIPReservation{}, &stepCreateInstance{}, &communicator.StepConnect{ Config: &b.config.Comm, From 3bf431a4238b8c1f38679214acc0f6a5e9881bc1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 15:44:40 -0800 Subject: [PATCH 0449/1007] construct OCI client --- builder/oracle/classic/builder.go | 25 +- builder/oracle/classic/config.go | 7 + .../go-oracle-terraform/CHANGELOG.md | 134 +++++++ .../hashicorp/go-oracle-terraform/GNUmakefile | 41 ++ .../hashicorp/go-oracle-terraform/LICENSE | 373 ++++++++++++++++++ .../hashicorp/go-oracle-terraform/README.md | 108 +++++ vendor/vendor.json | 6 + 7 files changed, 692 insertions(+), 2 deletions(-) create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/CHANGELOG.md create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/GNUmakefile create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/LICENSE create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/README.md diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 5fe719567..b8af96345 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -4,9 +4,10 @@ import ( "fmt" "log" - ocommon "github.com/hashicorp/packer/builder/oracle/common" + "github.com/hashicorp/go-cleanhttp" + "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/go-oracle-terraform/opc" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) @@ -31,14 +32,33 @@ func (b *Builder) Prepare(rawConfig ...interface{}) ([]string, error) { } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + + httpClient := cleanhttp.DefaultClient() + config := &opc.Config{ + Username: opc.String(b.config.Username), + Password: opc.String(b.config.Password), + IdentityDomain: opc.String(b.config.IdentityDomain), + APIEndpoint: b.config.apiEndpointURL, + LogLevel: opc.LogDebug, + // Logger: # Leave blank to use the default logger, or provide your own + HTTPClient: httpClient, + } + // Create the Compute Client + client, err := compute.NewComputeClient(config) + if err != nil { + return nil, fmt.Errorf("Error creating OPC Compute Client: %s", err) + } + // Populate the state bag state := new(multistep.BasicStateBag) state.Put("config", b.config) state.Put("hook", hook) state.Put("ui", ui) + state.Put("client", client) // Build the steps steps := []multistep.Step{ + /* &ocommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), @@ -55,6 +75,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &stepSnapshot{}, + */ } // Run the steps diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 6a3c05fc8..050f78d91 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -2,6 +2,7 @@ package classic import ( "fmt" + "net/url" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -20,6 +21,7 @@ type Config struct { Password string `mapstructure:"password"` IdentityDomain string `mapstructure:"identity_domain"` APIEndpoint string `mapstructure:"api_endpoint"` + apiEndpointURL *url.URL // Image Shape string `mapstructure:"shape"` @@ -40,5 +42,10 @@ func NewConfig(raws ...interface{}) (*Config, error) { return nil, fmt.Errorf("Failed to mapstructure Config: %+v", err) } + c.apiEndpointURL, err = url.Parse(c.APIEndpoint) + if err != nil { + return nil, fmt.Errorf("Error parsing API Endpoint: %s", err) + } + return c, nil } diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/CHANGELOG.md b/vendor/github.com/hashicorp/go-oracle-terraform/CHANGELOG.md new file mode 100644 index 000000000..70e5b3c31 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/CHANGELOG.md @@ -0,0 +1,134 @@ +## 0.6.6 (January 11, 2018) + +* compute: Create and delete machine images [GH-101] + +## 0.6.5 (January 8, 2018) + +* compute: Orchestration failures should explicitly tell the user why it failed [GH-100] + +## 0.6.4 (Decemeber 20, 2017) + +* compute: Added suspend functionality to orchestrated instances [GH-99] + +## 0.6.3 (December 13, 2017) + +* storage: Added remove header option to storage objects and containers [GH-96] + +## 0.6.2 (November 28, 2017) + +* client: Added a UserAgent to the Client [GH-98] + +## 0.6.1 (Novemeber 26, 2017) + +* compute: Added is_default_gateway to network attributes for instances [GH-97] + + +## 0.6.0 (November 10, 2017) + +* compute: Added is_default_gateway to network attributes for instances [GH-90] + +* compute: Added the orchestration resource, specifically for instance creation [GH-91] + +## 0.5.1 (October 5, 2017) + +* java: Fixed subscription_type field + +## 0.5.0 (October 5, 2017) + +* java: Added more fields to java service instance [GH-89] + +## 0.4.0 (September 14, 2017) + +* database: Add utility resources [GH-87] + +* compute: Increase storage volume snapshot create timeout [GH-88] + +## 0.3.4 (August 16, 2017) + +* storage_volumes: Actually capture errors during a storage volume create ([#86](https://github.com/hashicorp/go-oracle-terraform/issues/86)) + +## 0.3.3 (August 10, 2017) + +* Add `ExposedHeaders` to storage containers ([#85](https://github.com/hashicorp/go-oracle-terraform/issues/85)) + +* Fixed `AllowedOrigins` in storage containers ([#85](https://github.com/hashicorp/go-oracle-terraform/issues/85)) + +## 0.3.2 (August 7, 2017) + +* Add `id` for storage objects ([#84](https://github.com/hashicorp/go-oracle-terraform/issues/84)) + +## 0.3.1 (August 7, 2017) + +* Update tests for Database parameter changes ([#83](https://github.com/hashicorp/go-oracle-terraform/issues/83)) + +## 0.3.0 (August 7, 2017) + + * Add JaaS Service Instances ([#82](https://github.com/hashicorp/go-oracle-terraform/issues/82)) + + * Add storage objects ([#81](https://github.com/hashicorp/go-oracle-terraform/issues/81)) + +## 0.2.0 (July 27, 2017) + + * service_instance: Switches yes/no strings to bool in input struct and then converts back to strings for ease of use on user end ([#80](https://github.com/hashicorp/go-oracle-terraform/issues/80)) + +## 0.1.9 (July 20, 2017) + + * service_instance: Update delete retry count ([#79](https://github.com/hashicorp/go-oracle-terraform/issues/79)) + + * service_instance: Add additional fields ([#79](https://github.com/hashicorp/go-oracle-terraform/issues/79)) + +## 0.1.8 (July 19, 2017) + + * storage_volumes: Add SSD support ([#78](https://github.com/hashicorp/go-oracle-terraform/issues/78)) + +## 0.1.7 (July 19, 2017) + + * database: Adds the Oracle Database Cloud to the available sdks. ([#77](https://github.com/hashicorp/go-oracle-terraform/issues/77)) + + * database: Adds Service Instances to the database sdk ([#77](https://github.com/hashicorp/go-oracle-terraform/issues/77)) + +## 0.1.6 (July 18, 2017) + + * opc: Add timeouts to instance and storage inputs ([#75](https://github.com/hashicorp/go-oracle-terraform/issues/75)) + +## 0.1.5 (July 5, 2017) + + * storage: User must pass in Storage URL to CRUD resources ([#74](https://github.com/hashicorp/go-oracle-terraform/issues/74)) + +## 0.1.4 (June 30, 2017) + + * opc: Fix infinite loop around auth token exceeding it's 25 minute duration. ([#73](https://github.com/hashicorp/go-oracle-terraform/issues/73)) + +## 0.1.3 (June 30, 2017) + + * opc: Add additional logs instance logs ([#72](https://github.com/hashicorp/go-oracle-terraform/issues/72)) + + * opc: Increase instance creation and deletion timeout ([#72](https://github.com/hashicorp/go-oracle-terraform/issues/72)) + +## 0.1.2 (June 30, 2017) + + +FEATURES: + + * opc: Add image snapshots ([#67](https://github.com/hashicorp/go-oracle-terraform/issues/67)) + + * storage: Storage containers have been added ([#70](https://github.com/hashicorp/go-oracle-terraform/issues/70)) + + +IMPROVEMENTS: + + * opc: Refactored client to be generic for multiple Oracle api endpoints ([#68](https://github.com/hashicorp/go-oracle-terraform/issues/68)) + + * opc: Instance creation retries when an instance enters a deleted state ([#71](https://github.com/hashicorp/go-oracle-terraform/issues/71)) + +## 0.1.1 (May 31, 2017) + +IMPROVEMENTS: + + * opc: Add max_retries capabilities ([#66](https://github.com/hashicorp/go-oracle-terraform/issues/66)) + +## 0.1.0 (May 25, 2017) + +BACKWARDS INCOMPATIBILITIES / NOTES: + + * Initial Release of OPC SDK diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/GNUmakefile b/vendor/github.com/hashicorp/go-oracle-terraform/GNUmakefile new file mode 100644 index 000000000..9c5a0e2f2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/GNUmakefile @@ -0,0 +1,41 @@ +TEST?=$$(go list ./... |grep -v 'vendor') +GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) + +test: fmtcheck errcheck + go test -i $(TEST) || exit 1 + echo $(TEST) | \ + xargs -t -n4 go test $(TESTARGS) -timeout=60m -parallel=4 + +testacc: fmtcheck + ORACLE_ACC=1 go test -v $(TEST) $(TESTARGS) -timeout 120m + +testrace: fmtcheck + ORACLE_ACC= go test -race $(TEST) $(TESTARGS) + +cover: + @go tool cover 2>/dev/null; if [ $$? -eq 3 ]; then \ + go get -u golang.org/x/tools/cmd/cover; \ + fi + go test $(TEST) -coverprofile=coverage.out + go tool cover -html=coverage.out + rm coverage.out + +vet: + @echo "go vet ." + @go vet $$(go list ./... | grep -v vendor/) ; if [ $$? -eq 1 ]; then \ + echo ""; \ + echo "Vet found suspicious constructs. Please check the reported constructs"; \ + echo "and fix them if necessary before submitting the code for review."; \ + exit 1; \ + fi + +fmt: + gofmt -w $(GOFMT_FILES) + +fmtcheck: + @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" + +errcheck: + @sh -c "'$(CURDIR)/scripts/errcheck.sh'" + +.PHONY: tools build test testacc testrace cover vet fmt fmtcheck errcheck diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/LICENSE b/vendor/github.com/hashicorp/go-oracle-terraform/LICENSE new file mode 100644 index 000000000..a612ad981 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/README.md b/vendor/github.com/hashicorp/go-oracle-terraform/README.md new file mode 100644 index 000000000..0accc2c32 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/README.md @@ -0,0 +1,108 @@ +Oracle SDK for Terraform +=========================================== + +**Note:** This SDK is _not_ meant to be a comprehensive SDK for Oracle Cloud. This is meant to be used solely with Terraform. + +OPC Config +---------- + +To create the Oracle clients, a populated configuration struct is required. +The config struct holds the following fields: + +* `Username` - (`*string`) The Username used to authenticate to Oracle Public Cloud. +* `Password` - (`*string`) The Password used to authenticate to Oracle Public Cloud. +* `IdentityDomain` - (`*string`) The identity domain for Oracle Public Cloud. +* `APIEndpoint` - (`*url.URL`) The API Endpoint provided by Oracle Public Cloud. +* `LogLevel` - (`LogLevelType`) Defaults to `opc.LogOff`, can be either `opc.LogOff` or `opc.LogDebug`. +* `Logger` - (`Logger`) Must satisfy the generic `Logger` interface. Defaults to `ioutil.Discard` for the `LogOff` loglevel, and `os.Stderr` for the `LogDebug` loglevel. +* `HTTPClient` - (`*http.Client`) Defaults to generic HTTP Client if unspecified. + +Oracle Compute Client +---------------------- +The Oracle Compute Client requires an OPC Config object to be populated in order to create the client. + +Full example to create an OPC Compute instance: +```go +package main + +import ( + "fmt" + "net/url" + "github.com/hashicorp/go-oracle-terraform/opc" + "github.com/hashicorp/go-oracle-terraform/compute" +) + +func main() { + apiEndpoint, err := url.Parse("myAPIEndpoint") + if err != nil { + fmt.Errorf("Error parsing API Endpoint: %s", err) + } + + config := &opc.Config{ + Username: opc.String("myusername"), + Password: opc.String("mypassword"), + IdentityDomain: opc.String("myidentitydomain"), + APIEndpoint: apiEndpoint, + LogLevel: opc.LogDebug, + // Logger: # Leave blank to use the default logger, or provide your own + // HTTPClient: # Leave blank to use default HTTP Client, or provider your own + } + // Create the Compute Client + client, err := compute.NewComputeClient(config) + if err != nil { + fmt.Errorf("Error creating OPC Compute Client: %s", err) + } + // Create instances client + instanceClient := client.Instances() + + // Instances Input + input := &compute.CreateInstanceInput{ + Name: "test-instance", + Label: "test", + Shape: "oc3", + ImageList: "/oracle/public/oel_6.7_apaas_16.4.5_1610211300", + Storage: nil, + BootOrder: nil, + SSHKeys: []string{}, + Attributes: map[string]interface{}{}, + } + + // Create the instance + instance, err := instanceClient.CreateInstance(input) + if err != nil { + fmt.Errorf("Error creating instance: %s", err) + } + fmt.Printf("Instance Created: %#v", instance) +} +``` + +Please refer to inline documentation for each resource that the compute client provides. + +Running the SDK Integration Tests +----------------------------- + +To authenticate with the Oracle Compute Cloud the following credentails must be set in the following environment variables: + +- `OPC_ENDPOINT` - Endpoint provided by Oracle Public Cloud (e.g. https://api-z13.compute.em2.oraclecloud.com/\) +- `OPC_USERNAME` - Username for Oracle Public Cloud +- `OPC_PASSWORD` - Password for Oracle Public Cloud +- `OPC_IDENTITY_DOMAIN` - Identity domain for Oracle Public Cloud + + +The Integration tests can be ran with the following command: +```sh +$ make testacc +``` + +Isolating a single SDK package can be done via the `TEST` environment variable +```sh +$ make testacc TEST=./compute +``` + +Isolating a single test within a package can be done via the `TESTARGS` environment variable +```sh +$ make testacc TEST=./compute TESTARGS='-run=TestAccIPAssociationLifeCycle' +``` + +Tests are ran with logs being sent to `ioutil.Discard` by default. +Display debug logs inside of tests by setting the `ORACLE_LOG` environment variable to any value. diff --git a/vendor/vendor.json b/vendor/vendor.json index e8c3fb6f1..2f8f8307d 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -790,6 +790,12 @@ "path": "github.com/hashicorp/go-multierror", "revision": "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5" }, + { + "checksumSHA1": "Nf2Gdn9M1KlUS3sovKfymO1VJF4=", + "path": "github.com/hashicorp/go-oracle-terraform", + "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", + "revisionTime": "2018-01-11T20:31:13Z" + }, { "checksumSHA1": "ErJHGU6AVPZM9yoY/xV11TwSjQs=", "path": "github.com/hashicorp/go-retryablehttp", From 967b858fc3262b00ab95433ce1bf2f598991b68d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 12 Jan 2018 15:46:34 -0800 Subject: [PATCH 0450/1007] add go-oracle client --- .../go-oracle-terraform/client/client.go | 245 ++++++ .../go-oracle-terraform/client/logging.go | 28 + .../go-oracle-terraform/client/version.go | 35 + .../go-oracle-terraform/compute/acl.go | 138 +++ .../compute/authentication.go | 34 + .../compute/compute_client.go | 167 ++++ .../compute/compute_resource_client.go | 113 +++ .../go-oracle-terraform/compute/image_list.go | 154 ++++ .../compute/image_list_entries.go | 122 +++ .../go-oracle-terraform/compute/instances.go | 788 ++++++++++++++++++ .../compute/ip_address_associations.go | 152 ++++ .../compute/ip_address_prefix_set.go | 135 +++ .../compute/ip_address_reservations.go | 190 +++++ .../compute/ip_associations.go | 118 +++ .../compute/ip_network_exchange.go | 99 +++ .../compute/ip_networks.go | 186 +++++ .../compute/ip_reservations.go | 147 ++++ .../compute/machine_images.go | 143 ++++ .../compute/orchestration.go | 451 ++++++++++ .../go-oracle-terraform/compute/routes.go | 153 ++++ .../go-oracle-terraform/compute/sec_rules.go | 193 +++++ .../compute/security_applications.go | 150 ++++ .../compute/security_associations.go | 95 +++ .../compute/security_ip_lists.go | 113 +++ .../compute/security_lists.go | 131 +++ .../compute/security_protocols.go | 187 +++++ .../compute/security_rules.go | 266 ++++++ .../go-oracle-terraform/compute/snapshots.go | 217 +++++ .../go-oracle-terraform/compute/ssh_keys.go | 124 +++ .../compute/storage_volume_attachments.go | 178 ++++ .../compute/storage_volume_snapshots.go | 251 ++++++ .../compute/storage_volumes.go | 389 +++++++++ .../go-oracle-terraform/compute/test_utils.go | 119 +++ .../compute/virtual_nic.go | 52 ++ .../compute/virtual_nic_sets.go | 154 ++++ .../go-oracle-terraform/opc/config.go | 22 + .../go-oracle-terraform/opc/convert.go | 9 + .../go-oracle-terraform/opc/errors.go | 12 + .../go-oracle-terraform/opc/logger.go | 70 ++ vendor/vendor.json | 18 + 40 files changed, 6348 insertions(+) create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/client/client.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/client/logging.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/client/version.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/acl.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/authentication.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_client.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_resource_client.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list_entries.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_associations.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_prefix_set.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_reservations.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_associations.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_network_exchange.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_networks.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_reservations.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/routes.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/sec_rules.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/security_applications.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/security_associations.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/security_ip_lists.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/security_protocols.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/security_rules.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_snapshots.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volumes.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/test_utils.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic_sets.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/opc/config.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/opc/convert.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/opc/errors.go create mode 100644 vendor/github.com/hashicorp/go-oracle-terraform/opc/logger.go diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/client/client.go b/vendor/github.com/hashicorp/go-oracle-terraform/client/client.go new file mode 100644 index 000000000..4188d111b --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/client/client.go @@ -0,0 +1,245 @@ +package client + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "runtime" + "time" + + "github.com/hashicorp/go-oracle-terraform/opc" +) + +const DEFAULT_MAX_RETRIES = 1 +const USER_AGENT_HEADER = "User-Agent" + +var ( + // defaultUserAgent builds a string containing the Go version, system archityecture and OS, + // and the go-autorest version. + defaultUserAgent = fmt.Sprintf("Go/%s (%s-%s) go-oracle-terraform/%s", + runtime.Version(), + runtime.GOARCH, + runtime.GOOS, + Version(), + ) +) + +// Client represents an authenticated compute client, with compute credentials and an api client. +type Client struct { + IdentityDomain *string + UserName *string + Password *string + APIEndpoint *url.URL + httpClient *http.Client + MaxRetries *int + UserAgent *string + logger opc.Logger + loglevel opc.LogLevelType +} + +func NewClient(c *opc.Config) (*Client, error) { + // First create a client + client := &Client{ + IdentityDomain: c.IdentityDomain, + UserName: c.Username, + Password: c.Password, + APIEndpoint: c.APIEndpoint, + UserAgent: &defaultUserAgent, + httpClient: c.HTTPClient, + MaxRetries: c.MaxRetries, + loglevel: c.LogLevel, + } + if c.UserAgent != nil { + client.UserAgent = c.UserAgent + } + + // Setup logger; defaults to stdout + if c.Logger == nil { + client.logger = opc.NewDefaultLogger() + } else { + client.logger = c.Logger + } + + // If LogLevel was not set to something different, + // double check for env var + if c.LogLevel == 0 { + client.loglevel = opc.LogLevel() + } + + // Default max retries if unset + if c.MaxRetries == nil { + client.MaxRetries = opc.Int(DEFAULT_MAX_RETRIES) + } + + // Protect against any nil http client + if c.HTTPClient == nil { + return nil, fmt.Errorf("No HTTP client specified in config") + } + + return client, nil +} + +// Marshalls the request body and returns the resulting byte slice +// This is split out of the BuildRequestBody method so as to allow +// the developer to print a debug string of the request body if they +// should so choose. +func (c *Client) MarshallRequestBody(body interface{}) ([]byte, error) { + // Verify interface isnt' nil + if body == nil { + return nil, nil + } + + return json.Marshal(body) +} + +// Builds an HTTP Request that accepts a pre-marshaled body parameter as a raw byte array +// Returns the raw HTTP Request and any error occured +func (c *Client) BuildRequestBody(method, path string, body []byte) (*http.Request, error) { + // Parse URL Path + urlPath, err := url.Parse(path) + if err != nil { + return nil, err + } + + var requestBody io.ReadSeeker + if len(body) != 0 { + requestBody = bytes.NewReader(body) + } + + // Create Request + req, err := http.NewRequest(method, c.formatURL(urlPath), requestBody) + if err != nil { + return nil, err + } + // Adding UserAgent Header + req.Header.Add(USER_AGENT_HEADER, *c.UserAgent) + + return req, nil +} + +// Build a new HTTP request that doesn't marshall the request body +func (c *Client) BuildNonJSONRequest(method, path string, body io.ReadSeeker) (*http.Request, error) { + // Parse URL Path + urlPath, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Create request + req, err := http.NewRequest(method, c.formatURL(urlPath), body) + if err != nil { + return nil, err + } + // Adding UserAgentHeader + req.Header.Add(USER_AGENT_HEADER, *c.UserAgent) + + return req, nil +} + +// This method executes the http.Request from the BuildRequest method. +// It is split up to add additional authentication that is Oracle API dependent. +func (c *Client) ExecuteRequest(req *http.Request) (*http.Response, error) { + // Execute request with supplied client + resp, err := c.retryRequest(req) + if err != nil { + return resp, err + } + + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + return resp, nil + } + + oracleErr := &opc.OracleError{ + StatusCode: resp.StatusCode, + } + + // Even though the returned body will be in json form, it's undocumented what + // fields are actually returned. Once we get documentation of the actual + // error fields that are possible to be returned we can have stricter error types. + if resp.Body != nil { + buf := new(bytes.Buffer) + buf.ReadFrom(resp.Body) + oracleErr.Message = buf.String() + } + + // Should return the response object regardless of error, + // some resources need to verify and check status code on errors to + // determine if an error actually occurs or not. + return resp, oracleErr +} + +// Allow retrying the request until it either returns no error, +// or we exceed the number of max retries +func (c *Client) retryRequest(req *http.Request) (*http.Response, error) { + // Double check maxRetries is not nil + var retries int + if c.MaxRetries == nil { + retries = DEFAULT_MAX_RETRIES + } else { + retries = *c.MaxRetries + } + + var statusCode int + var errMessage string + + for i := 0; i < retries; i++ { + resp, err := c.httpClient.Do(req) + if err != nil { + return resp, err + } + + if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices { + return resp, nil + } + + buf := new(bytes.Buffer) + buf.ReadFrom(resp.Body) + errMessage = buf.String() + statusCode = resp.StatusCode + c.DebugLogString(fmt.Sprintf("Encountered HTTP (%d) Error: %s", statusCode, errMessage)) + c.DebugLogString(fmt.Sprintf("%d/%d retries left", i+1, retries)) + } + + oracleErr := &opc.OracleError{ + StatusCode: statusCode, + Message: errMessage, + } + + // We ran out of retries to make, return the error and response + return nil, oracleErr +} + +func (c *Client) formatURL(path *url.URL) string { + return c.APIEndpoint.ResolveReference(path).String() +} + +// Retry function +func (c *Client) WaitFor(description string, timeout time.Duration, test func() (bool, error)) error { + tick := time.Tick(1 * time.Second) + + timeoutSeconds := int(timeout.Seconds()) + + for i := 0; i < timeoutSeconds; i++ { + select { + case <-tick: + completed, err := test() + c.DebugLogString(fmt.Sprintf("Waiting for %s (%d/%ds)", description, i, timeoutSeconds)) + if err != nil || completed { + return err + } + } + } + return fmt.Errorf("Timeout waiting for %s", description) +} + +// Used to determine if the checked resource was found or not. +func WasNotFoundError(e error) bool { + err, ok := e.(*opc.OracleError) + if ok { + return err.StatusCode == 404 + } + return false +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/client/logging.go b/vendor/github.com/hashicorp/go-oracle-terraform/client/logging.go new file mode 100644 index 000000000..893997486 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/client/logging.go @@ -0,0 +1,28 @@ +package client + +import ( + "bytes" + "fmt" + "net/http" + + "github.com/hashicorp/go-oracle-terraform/opc" +) + +// Log a string if debug logs are on +func (c *Client) DebugLogString(str string) { + if c.loglevel != opc.LogDebug { + return + } + c.logger.Log(str) +} + +func (c *Client) DebugLogReq(req *http.Request) { + // Don't need to log this if not debugging + if c.loglevel != opc.LogDebug { + return + } + buf := new(bytes.Buffer) + buf.ReadFrom(req.Body) + c.logger.Log(fmt.Sprintf("DEBUG: HTTP %s Req %s: %s", + req.Method, req.URL.String(), buf.String())) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/client/version.go b/vendor/github.com/hashicorp/go-oracle-terraform/client/version.go new file mode 100644 index 000000000..3538fd181 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/client/version.go @@ -0,0 +1,35 @@ +package client + +import ( + "bytes" + "fmt" + "strings" + "sync" +) + +const ( + major = 0 + minor = 6 + patch = 2 + tag = "" +) + +var once sync.Once +var version string + +// Version returns the semantic version (see http://semver.org). +func Version() string { + once.Do(func() { + semver := fmt.Sprintf("%d.%d.%d", major, minor, patch) + verBuilder := bytes.NewBufferString(semver) + if tag != "" && tag != "-" { + updated := strings.TrimPrefix(tag, "-") + _, err := verBuilder.WriteString("-" + updated) + if err == nil { + verBuilder = bytes.NewBufferString(semver) + } + } + version = verBuilder.String() + }) + return version +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/acl.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/acl.go new file mode 100644 index 000000000..877f51c28 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/acl.go @@ -0,0 +1,138 @@ +package compute + +// ACLsClient is a client for the ACLs functions of the Compute API. +type ACLsClient struct { + ResourceClient +} + +const ( + ACLDescription = "acl" + ACLContainerPath = "/network/v1/acl/" + ACLResourcePath = "/network/v1/acl" +) + +// ACLs obtains a ACLsClient which can be used to access to the +// ACLs functions of the Compute API +func (c *ComputeClient) ACLs() *ACLsClient { + return &ACLsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: ACLDescription, + ContainerPath: ACLContainerPath, + ResourceRootPath: ACLResourcePath, + }} +} + +// ACLInfo describes an existing ACL. +type ACLInfo struct { + // Description of the ACL + Description string `json:"description"` + // Indicates whether the ACL is enabled + Enabled bool `json:"enabledFlag"` + // The name of the ACL + Name string `json:"name"` + // Tags associated with the ACL + Tags []string `json:"tags"` + // Uniform Resource Identifier for the ACL + URI string `json:"uri"` +} + +// CreateACLInput defines a ACL to be created. +type CreateACLInput struct { + // Description of the ACL + // Optional + Description string `json:"description"` + + // Enables or disables the ACL. Set to true by default. + //Set this to false to disable the ACL. + // Optional + Enabled bool `json:"enabledFlag"` + + // The name of the ACL to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Strings that you can use to tag the ACL. + // Optional + Tags []string `json:"tags"` +} + +// CreateACL creates a new ACL. +func (c *ACLsClient) CreateACL(createInput *CreateACLInput) (*ACLInfo, error) { + createInput.Name = c.getQualifiedName(createInput.Name) + + var aclInfo ACLInfo + if err := c.createResource(createInput, &aclInfo); err != nil { + return nil, err + } + + return c.success(&aclInfo) +} + +// GetACLInput describes the ACL to get +type GetACLInput struct { + // The name of the ACL to query for + // Required + Name string `json:"name"` +} + +// GetACL retrieves the ACL with the given name. +func (c *ACLsClient) GetACL(getInput *GetACLInput) (*ACLInfo, error) { + var aclInfo ACLInfo + if err := c.getResource(getInput.Name, &aclInfo); err != nil { + return nil, err + } + + return c.success(&aclInfo) +} + +// UpdateACLInput describes a secruity rule to update +type UpdateACLInput struct { + // Description of the ACL + // Optional + Description string `json:"description"` + + // Enables or disables the ACL. Set to true by default. + //Set this to false to disable the ACL. + // Optional + Enabled bool `json:"enabledFlag"` + + // The name of the ACL to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Strings that you can use to tag the ACL. + // Optional + Tags []string `json:"tags"` +} + +// UpdateACL modifies the properties of the ACL with the given name. +func (c *ACLsClient) UpdateACL(updateInput *UpdateACLInput) (*ACLInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + + var aclInfo ACLInfo + if err := c.updateResource(updateInput.Name, updateInput, &aclInfo); err != nil { + return nil, err + } + + return c.success(&aclInfo) +} + +// DeleteACLInput describes the ACL to delete +type DeleteACLInput struct { + // The name of the ACL to delete. + // Required + Name string `json:"name"` +} + +// DeleteACL deletes the ACL with the given name. +func (c *ACLsClient) DeleteACL(deleteInput *DeleteACLInput) error { + return c.deleteResource(deleteInput.Name) +} + +func (c *ACLsClient) success(aclInfo *ACLInfo) (*ACLInfo, error) { + aclInfo.Name = c.getUnqualifiedName(aclInfo.Name) + return aclInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/authentication.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/authentication.go new file mode 100644 index 000000000..6c62d7ddd --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/authentication.go @@ -0,0 +1,34 @@ +package compute + +import ( + "fmt" + "time" +) + +// AuthenticationReq represents the body of an authentication request. +type AuthenticationReq struct { + User string `json:"user"` + Password string `json:"password"` +} + +// Get a new auth cookie for the compute client +func (c *ComputeClient) getAuthenticationCookie() error { + req := AuthenticationReq{ + User: c.getUserName(), + Password: *c.client.Password, + } + + rsp, err := c.executeRequest("POST", "/authenticate/", req) + if err != nil { + return err + } + + if len(rsp.Cookies()) == 0 { + return fmt.Errorf("No authentication cookie found in response %#v", rsp) + } + + c.client.DebugLogString("Successfully authenticated to OPC") + c.authCookie = rsp.Cookies()[0] + c.cookieIssued = time.Now() + return nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_client.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_client.go new file mode 100644 index 000000000..3719dbb15 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_client.go @@ -0,0 +1,167 @@ +package compute + +import ( + "fmt" + "net/http" + "regexp" + "strings" + "time" + + "github.com/hashicorp/go-oracle-terraform/client" + "github.com/hashicorp/go-oracle-terraform/opc" +) + +const CMP_ACME = "/Compute-%s" +const CMP_USERNAME = "/Compute-%s/%s" +const CMP_QUALIFIED_NAME = "%s/%s" + +// Client represents an authenticated compute client, with compute credentials and an api client. +type ComputeClient struct { + client *client.Client + authCookie *http.Cookie + cookieIssued time.Time +} + +func NewComputeClient(c *opc.Config) (*ComputeClient, error) { + computeClient := &ComputeClient{} + client, err := client.NewClient(c) + if err != nil { + return nil, err + } + computeClient.client = client + + if err := computeClient.getAuthenticationCookie(); err != nil { + return nil, err + } + + return computeClient, nil +} + +func (c *ComputeClient) executeRequest(method, path string, body interface{}) (*http.Response, error) { + reqBody, err := c.client.MarshallRequestBody(body) + if err != nil { + return nil, err + } + + req, err := c.client.BuildRequestBody(method, path, reqBody) + if err != nil { + return nil, err + } + + debugReqString := fmt.Sprintf("HTTP %s Req (%s)", method, path) + if body != nil { + req.Header.Set("Content-Type", "application/oracle-compute-v3+json") + // Don't leak credentials in STDERR + if path != "/authenticate/" { + debugReqString = fmt.Sprintf("%s:\n %+v", debugReqString, string(reqBody)) + } + } + // Log the request before the authentication cookie, so as not to leak credentials + c.client.DebugLogString(debugReqString) + // If we have an authentication cookie, let's authenticate, refreshing cookie if need be + if c.authCookie != nil { + if time.Since(c.cookieIssued).Minutes() > 25 { + c.authCookie = nil + if err := c.getAuthenticationCookie(); err != nil { + return nil, err + } + } + req.AddCookie(c.authCookie) + } + + resp, err := c.client.ExecuteRequest(req) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *ComputeClient) getACME() string { + return fmt.Sprintf(CMP_ACME, *c.client.IdentityDomain) +} + +func (c *ComputeClient) getUserName() string { + return fmt.Sprintf(CMP_USERNAME, *c.client.IdentityDomain, *c.client.UserName) +} + +func (c *ComputeClient) getQualifiedACMEName(name string) string { + if name == "" { + return "" + } + if strings.HasPrefix(name, "/Compute-") && len(strings.Split(name, "/")) == 1 { + return name + } + return fmt.Sprintf(CMP_QUALIFIED_NAME, c.getACME(), name) +} + +// From compute_client +// GetObjectName returns the fully-qualified name of an OPC object, e.g. /identity-domain/user@email/{name} +func (c *ComputeClient) getQualifiedName(name string) string { + if name == "" { + return "" + } + if strings.HasPrefix(name, "/oracle") || strings.HasPrefix(name, "/Compute-") { + return name + } + return fmt.Sprintf(CMP_QUALIFIED_NAME, c.getUserName(), name) +} + +func (c *ComputeClient) getObjectPath(root, name string) string { + return fmt.Sprintf("%s%s", root, c.getQualifiedName(name)) +} + +// GetUnqualifiedName returns the unqualified name of an OPC object, e.g. the {name} part of /identity-domain/user@email/{name} +func (c *ComputeClient) getUnqualifiedName(name string) string { + if name == "" { + return name + } + if strings.HasPrefix(name, "/oracle") { + return name + } + if !strings.Contains(name, "/") { + return name + } + + nameParts := strings.Split(name, "/") + return strings.Join(nameParts[3:], "/") +} + +func (c *ComputeClient) unqualify(names ...*string) { + for _, name := range names { + *name = c.getUnqualifiedName(*name) + } +} + +func (c *ComputeClient) unqualifyUrl(url *string) { + var validID = regexp.MustCompile(`(\/(Compute[^\/\s]+))(\/[^\/\s]+)(\/[^\/\s]+)`) + name := validID.FindString(*url) + *url = c.getUnqualifiedName(name) +} + +func (c *ComputeClient) getQualifiedList(list []string) []string { + for i, name := range list { + list[i] = c.getQualifiedName(name) + } + return list +} + +func (c *ComputeClient) getUnqualifiedList(list []string) []string { + for i, name := range list { + list[i] = c.getUnqualifiedName(name) + } + return list +} + +func (c *ComputeClient) getQualifiedListName(name string) string { + nameParts := strings.Split(name, ":") + listType := nameParts[0] + listName := nameParts[1] + return fmt.Sprintf("%s:%s", listType, c.getQualifiedName(listName)) +} + +func (c *ComputeClient) unqualifyListName(qualifiedName string) string { + nameParts := strings.Split(qualifiedName, ":") + listType := nameParts[0] + listName := nameParts[1] + return fmt.Sprintf("%s:%s", listType, c.getUnqualifiedName(listName)) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_resource_client.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_resource_client.go new file mode 100644 index 000000000..2c3e1dc9e --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/compute_resource_client.go @@ -0,0 +1,113 @@ +package compute + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + "github.com/mitchellh/mapstructure" +) + +// ResourceClient is an AuthenticatedClient with some additional information about the resources to be addressed. +type ResourceClient struct { + *ComputeClient + ResourceDescription string + ContainerPath string + ResourceRootPath string +} + +func (c *ResourceClient) createResource(requestBody interface{}, responseBody interface{}) error { + resp, err := c.executeRequest("POST", c.ContainerPath, requestBody) + if err != nil { + return err + } + + return c.unmarshalResponseBody(resp, responseBody) +} + +func (c *ResourceClient) updateResource(name string, requestBody interface{}, responseBody interface{}) error { + resp, err := c.executeRequest("PUT", c.getObjectPath(c.ResourceRootPath, name), requestBody) + if err != nil { + return err + } + + return c.unmarshalResponseBody(resp, responseBody) +} + +func (c *ResourceClient) getResource(name string, responseBody interface{}) error { + var objectPath string + if name != "" { + objectPath = c.getObjectPath(c.ResourceRootPath, name) + } else { + objectPath = c.ResourceRootPath + } + resp, err := c.executeRequest("GET", objectPath, nil) + if err != nil { + return err + } + + return c.unmarshalResponseBody(resp, responseBody) +} + +func (c *ResourceClient) deleteResource(name string) error { + var objectPath string + if name != "" { + objectPath = c.getObjectPath(c.ResourceRootPath, name) + } else { + objectPath = c.ResourceRootPath + } + _, err := c.executeRequest("DELETE", objectPath, nil) + if err != nil { + return err + } + + // No errors and no response body to write + return nil +} + +func (c *ResourceClient) deleteOrchestration(name string) error { + var objectPath string + if name != "" { + objectPath = c.getObjectPath(c.ResourceRootPath, name) + } else { + objectPath = c.ResourceRootPath + } + // Set terminate to true as we always want to delete an orchestration + objectPath = fmt.Sprintf("%s?terminate=True", objectPath) + + _, err := c.executeRequest("DELETE", objectPath, nil) + if err != nil { + return err + } + + // No errors and no response body to write + return nil +} + +func (c *ResourceClient) unmarshalResponseBody(resp *http.Response, iface interface{}) error { + buf := new(bytes.Buffer) + buf.ReadFrom(resp.Body) + c.client.DebugLogString(fmt.Sprintf("HTTP Resp (%d): %s", resp.StatusCode, buf.String())) + // JSON decode response into interface + var tmp interface{} + dcd := json.NewDecoder(buf) + if err := dcd.Decode(&tmp); err != nil { + return err + } + + // Use mapstructure to weakly decode into the resulting interface + msdcd, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + WeaklyTypedInput: true, + Result: iface, + TagName: "json", + }) + if err != nil { + return err + } + + if err := msdcd.Decode(tmp); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go new file mode 100644 index 000000000..0d4ca06ba --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list.go @@ -0,0 +1,154 @@ +package compute + +const ( + ImageListDescription = "Image List" + ImageListContainerPath = "/imagelist/" + ImageListResourcePath = "/imagelist" +) + +// ImageListClient is a client for the Image List functions of the Compute API. +type ImageListClient struct { + ResourceClient +} + +// ImageList obtains an ImageListClient which can be used to access to the +// Image List functions of the Compute API +func (c *ComputeClient) ImageList() *ImageListClient { + return &ImageListClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: ImageListDescription, + ContainerPath: ImageListContainerPath, + ResourceRootPath: ImageListResourcePath, + }} +} + +type ImageListEntry struct { + // User-defined parameters, in JSON format, that can be passed to an instance of this machine image when it is launched. + Attributes map[string]interface{} `json:"attributes"` + + // Name of the Image List. + ImageList string `json:"imagelist"` + + // A list of machine images. + MachineImages []string `json:"machineimages"` + + // Uniform Resource Identifier. + URI string `json:"uri"` + + // Version number of these Machine Images in the Image List. + Version int `json:"version"` +} + +// ImageList describes an existing Image List. +type ImageList struct { + // The image list entry to be used, by default, when launching instances using this image list + Default int `json:"default"` + + // A description of this image list. + Description string `json:"description"` + + // Each machine image in an image list is identified by an image list entry. + Entries []ImageListEntry `json:"entries"` + + // The name of the Image List + Name string `json:"name"` + + // Uniform Resource Identifier + URI string `json:"uri"` +} + +// CreateImageListInput defines an Image List to be created. +type CreateImageListInput struct { + // The image list entry to be used, by default, when launching instances using this image list. + // If you don't specify this value, it is set to 1. + // Optional + Default int `json:"default"` + + // A description of this image list. + // Required + Description string `json:"description"` + + // The name of the Image List + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` +} + +// CreateImageList creates a new Image List with the given name, key and enabled flag. +func (c *ImageListClient) CreateImageList(createInput *CreateImageListInput) (*ImageList, error) { + var imageList ImageList + createInput.Name = c.getQualifiedName(createInput.Name) + if err := c.createResource(&createInput, &imageList); err != nil { + return nil, err + } + + return c.success(&imageList) +} + +// DeleteKeyInput describes the image list to delete +type DeleteImageListInput struct { + // The name of the Image List + Name string `json:name` +} + +// DeleteImageList deletes the Image List with the given name. +func (c *ImageListClient) DeleteImageList(deleteInput *DeleteImageListInput) error { + deleteInput.Name = c.getQualifiedName(deleteInput.Name) + return c.deleteResource(deleteInput.Name) +} + +// GetImageListInput describes the image list to get +type GetImageListInput struct { + // The name of the Image List + Name string `json:name` +} + +// GetImageList retrieves the Image List with the given name. +func (c *ImageListClient) GetImageList(getInput *GetImageListInput) (*ImageList, error) { + getInput.Name = c.getQualifiedName(getInput.Name) + + var imageList ImageList + if err := c.getResource(getInput.Name, &imageList); err != nil { + return nil, err + } + + return c.success(&imageList) +} + +// UpdateImageListInput defines an Image List to be updated +type UpdateImageListInput struct { + // The image list entry to be used, by default, when launching instances using this image list. + // If you don't specify this value, it is set to 1. + // Optional + Default int `json:"default"` + + // A description of this image list. + // Required + Description string `json:"description"` + + // The name of the Image List + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` +} + +// UpdateImageList updates the key and enabled flag of the Image List with the given name. +func (c *ImageListClient) UpdateImageList(updateInput *UpdateImageListInput) (*ImageList, error) { + var imageList ImageList + updateInput.Name = c.getQualifiedName(updateInput.Name) + if err := c.updateResource(updateInput.Name, updateInput, &imageList); err != nil { + return nil, err + } + return c.success(&imageList) +} + +func (c *ImageListClient) success(imageList *ImageList) (*ImageList, error) { + c.unqualify(&imageList.Name) + + for _, v := range imageList.Entries { + v.MachineImages = c.getUnqualifiedList(v.MachineImages) + } + + return imageList, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list_entries.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list_entries.go new file mode 100644 index 000000000..ac72ef45a --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/image_list_entries.go @@ -0,0 +1,122 @@ +package compute + +import "fmt" + +const ( + ImageListEntryDescription = "image list entry" + ImageListEntryContainerPath = "/imagelist" + ImageListEntryResourcePath = "/imagelist" +) + +type ImageListEntriesClient struct { + ResourceClient +} + +// ImageListEntries() returns an ImageListEntriesClient that can be used to access the +// necessary CRUD functions for Image List Entry's. +func (c *ComputeClient) ImageListEntries() *ImageListEntriesClient { + return &ImageListEntriesClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: ImageListEntryDescription, + ContainerPath: ImageListEntryContainerPath, + ResourceRootPath: ImageListEntryResourcePath, + }, + } +} + +// ImageListEntryInfo contains the exported fields necessary to hold all the information about an +// Image List Entry +type ImageListEntryInfo struct { + // User-defined parameters, in JSON format, that can be passed to an instance of this machine + // image when it is launched. This field can be used, for example, to specify the location of + // a database server and login details. Instance metadata, including user-defined data is available + // at http://192.0.0.192/ within an instance. See Retrieving User-Defined Instance Attributes in Using + // Oracle Compute Cloud Service (IaaS). + Attributes map[string]interface{} `json:"attributes"` + // Name of the imagelist. + Name string `json:"imagelist"` + // A list of machine images. + MachineImages []string `json:"machineimages"` + // Uniform Resource Identifier for the Image List Entry + Uri string `json:"uri"` + // Version number of these machineImages in the imagelist. + Version int `json:"version"` +} + +type CreateImageListEntryInput struct { + // The name of the Image List + Name string + // User-defined parameters, in JSON format, that can be passed to an instance of this machine + // image when it is launched. This field can be used, for example, to specify the location of + // a database server and login details. Instance metadata, including user-defined data is + //available at http://192.0.0.192/ within an instance. See Retrieving User-Defined Instance + //Attributes in Using Oracle Compute Cloud Service (IaaS). + // Optional + Attributes map[string]interface{} `json:"attributes"` + // A list of machine images. + // Required + MachineImages []string `json:"machineimages"` + // The unique version of the entry in the image list. + // Required + Version int `json:"version"` +} + +// Create a new Image List Entry from an ImageListEntriesClient and an input struct. +// Returns a populated Info struct for the Image List Entry, and any errors +func (c *ImageListEntriesClient) CreateImageListEntry(input *CreateImageListEntryInput) (*ImageListEntryInfo, error) { + c.updateClientPaths(input.Name, -1) + var imageListEntryInfo ImageListEntryInfo + if err := c.createResource(&input, &imageListEntryInfo); err != nil { + return nil, err + } + return c.success(&imageListEntryInfo) +} + +type GetImageListEntryInput struct { + // The name of the Image List + Name string + // Version number of these machineImages in the imagelist. + Version int +} + +// Returns a populated ImageListEntryInfo struct from an input struct +func (c *ImageListEntriesClient) GetImageListEntry(input *GetImageListEntryInput) (*ImageListEntryInfo, error) { + c.updateClientPaths(input.Name, input.Version) + var imageListEntryInfo ImageListEntryInfo + if err := c.getResource("", &imageListEntryInfo); err != nil { + return nil, err + } + return c.success(&imageListEntryInfo) +} + +type DeleteImageListEntryInput struct { + // The name of the Image List + Name string + // Version number of these machineImages in the imagelist. + Version int +} + +func (c *ImageListEntriesClient) DeleteImageListEntry(input *DeleteImageListEntryInput) error { + c.updateClientPaths(input.Name, input.Version) + return c.deleteResource("") +} + +func (c *ImageListEntriesClient) updateClientPaths(name string, version int) { + var containerPath, resourcePath string + name = c.getQualifiedName(name) + containerPath = ImageListEntryContainerPath + name + "/entry/" + resourcePath = ImageListEntryContainerPath + name + "/entry" + if version != -1 { + containerPath = fmt.Sprintf("%s%d", containerPath, version) + resourcePath = fmt.Sprintf("%s/%d", resourcePath, version) + } + c.ContainerPath = containerPath + c.ResourceRootPath = resourcePath +} + +// Unqualifies any qualified fields in the IPNetworkInfo struct +func (c *ImageListEntriesClient) success(info *ImageListEntryInfo) (*ImageListEntryInfo, error) { + c.unqualifyUrl(&info.Uri) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go new file mode 100644 index 000000000..ddfa8d6ec --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go @@ -0,0 +1,788 @@ +package compute + +import ( + "errors" + "fmt" + "strings" + "time" + + "github.com/hashicorp/go-oracle-terraform/client" +) + +const WaitForInstanceReadyTimeout = time.Duration(3600 * time.Second) +const WaitForInstanceDeleteTimeout = time.Duration(3600 * time.Second) + +// InstancesClient is a client for the Instance functions of the Compute API. +type InstancesClient struct { + ResourceClient +} + +// Instances obtains an InstancesClient which can be used to access to the +// Instance functions of the Compute API +func (c *ComputeClient) Instances() *InstancesClient { + return &InstancesClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "instance", + ContainerPath: "/launchplan/", + ResourceRootPath: "/instance", + }} +} + +type InstanceState string + +const ( + InstanceRunning InstanceState = "running" + InstanceInitializing InstanceState = "initializing" + InstancePreparing InstanceState = "preparing" + InstanceStarting InstanceState = "starting" + InstanceStopping InstanceState = "stopping" + InstanceShutdown InstanceState = "shutdown" + InstanceQueued InstanceState = "queued" + InstanceError InstanceState = "error" +) + +type InstanceDesiredState string + +const ( + InstanceDesiredRunning InstanceDesiredState = "running" + InstanceDesiredShutdown InstanceDesiredState = "shutdown" +) + +// InstanceInfo represents the Compute API's view of the state of an instance. +type InstanceInfo struct { + // The ID for the instance. Set by the SDK based on the request - not the API. + ID string + + // A dictionary of attributes to be made available to the instance. + // A value with the key "userdata" will be made available in an EC2-compatible manner. + Attributes map[string]interface{} `json:"attributes"` + + // The availability domain for the instance + AvailabilityDomain string `json:"availability_domain"` + + // Boot order list. + BootOrder []int `json:"boot_order"` + + // The default domain to use for the hostname and DNS lookups + Domain string `json:"domain"` + + // The desired state of an instance + DesiredState InstanceDesiredState `json:"desired_state"` + + // Optional ImageListEntry number. Default will be used if not specified + Entry int `json:"entry"` + + // The reason for the instance going to error state, if available. + ErrorReason string `json:"error_reason"` + + // SSH Server Fingerprint presented by the instance + Fingerprint string `json:"fingerprint"` + + // The hostname for the instance + Hostname string `json:"hostname"` + + // The format of the image + ImageFormat string `json:"image_format"` + + // Name of imagelist to be launched. + ImageList string `json:"imagelist"` + + // IP address of the instance. + IPAddress string `json:"ip"` + + // A label assigned by the user, specifically for defining inter-instance relationships. + Label string `json:"label"` + + // Name of this instance, generated by the server. + Name string `json:"name"` + + // Mapping of to network specifiers for virtual NICs to be attached to this instance. + Networking map[string]NetworkingInfo `json:"networking"` + + // A list of strings specifying arbitrary tags on nodes to be matched on placement. + PlacementRequirements []string `json:"placement_requirements"` + + // The OS platform for the instance. + Platform string `json:"platform"` + + // The priority at which this instance will be run + Priority string `json:"priority"` + + // Reference to the QuotaReservation, to be destroyed with the instance + QuotaReservation string `json:"quota_reservation"` + + // Array of relationship specifications to be satisfied on this instance's placement + Relationships []string `json:"relationships"` + + // Resolvers to use instead of the default resolvers + Resolvers []string `json:"resolvers"` + + // Add PTR records for the hostname + ReverseDNS bool `json:"reverse_dns"` + + // Type of instance, as defined on site configuration. + Shape string `json:"shape"` + + // Site to run on + Site string `json:"site"` + + // ID's of SSH keys that will be exposed to the instance. + SSHKeys []string `json:"sshkeys"` + + // The start time of the instance + StartTime string `json:"start_time"` + + // State of the instance. + State InstanceState `json:"state"` + + // The Storage Attachment information. + Storage []StorageAttachment `json:"storage_attachments"` + + // Array of tags associated with the instance. + Tags []string `json:"tags"` + + // vCable for this instance. + VCableID string `json:"vcable_id"` + + // Specify if the devices created for the instance are virtio devices. If not specified, the default + // will come from the cluster configuration file + Virtio bool `json:"virtio,omitempty"` + + // IP Address and port of the VNC console for the instance + VNC string `json:"vnc"` +} + +type StorageAttachment struct { + // The index number for the volume. + Index int `json:"index"` + + // The three-part name (/Compute-identity_domain/user/object) of the storage attachment. + Name string `json:"name"` + + // The three-part name (/Compute-identity_domain/user/object) of the storage volume attached to the instance. + StorageVolumeName string `json:"storage_volume_name"` +} + +func (i *InstanceInfo) getInstanceName() string { + return fmt.Sprintf(CMP_QUALIFIED_NAME, i.Name, i.ID) +} + +type CreateInstanceInput struct { + // A dictionary of user-defined attributes to be made available to the instance. + // Optional + Attributes map[string]interface{} `json:"attributes"` + // Boot order list + // Optional + BootOrder []int `json:"boot_order,omitempty"` + // The desired state of the opc instance. Can only be `running` or `shutdown` + // Omits if empty. + // Optional + DesiredState InstanceDesiredState `json:"desired_state,omitempty"` + // The host name assigned to the instance. On an Oracle Linux instance, + // this host name is displayed in response to the hostname command. + // Only relative DNS is supported. The domain name is suffixed to the host name + // that you specify. The host name must not end with a period. If you don't specify a + // host name, then a name is generated automatically. + // Optional + Hostname string `json:"hostname"` + // Name of imagelist to be launched. + // Optional + ImageList string `json:"imagelist"` + // A label assigned by the user, specifically for defining inter-instance relationships. + // Optional + Label string `json:"label"` + // Name of this instance, generated by the server. + // Optional + Name string `json:"name"` + // Networking information. + // Optional + Networking map[string]NetworkingInfo `json:"networking"` + // If set to true (default), then reverse DNS records are created. + // If set to false, no reverse DNS records are created. + // Optional + ReverseDNS bool `json:"reverse_dns,omitempty"` + // Type of instance, as defined on site configuration. + // Required + Shape string `json:"shape"` + // A list of the Storage Attachments you want to associate with the instance. + // Optional + Storage []StorageAttachmentInput `json:"storage_attachments,omitempty"` + // A list of the SSH public keys that you want to associate with the instance. + // Optional + SSHKeys []string `json:"sshkeys"` + // A list of tags to be supplied to the instance + // Optional + Tags []string `json:"tags"` + // Time to wait for an instance to be ready + Timeout time.Duration `json:"-"` +} + +type StorageAttachmentInput struct { + // The index number for the volume. The allowed range is 1 to 10. + // If you want to use a storage volume as the boot disk for an instance, you must specify the index number for that volume as 1. + // The index determines the device name by which the volume is exposed to the instance. + Index int `json:"index"` + // The three-part name (/Compute-identity_domain/user/object) of the storage volume that you want to attach to the instance. + // Note that volumes attached to an instance at launch time can't be detached. + Volume string `json:"volume"` +} + +const ReservationPrefix = "ipreservation" +const ReservationIPPrefix = "network/v1/ipreservation" + +type NICModel string + +const ( + NICDefaultModel NICModel = "e1000" +) + +// Struct of Networking info from a populated instance, or to be used as input to create an instance +type NetworkingInfo struct { + // The DNS name for the Shared network (Required) + // DNS A Record for an IP Network (Optional) + DNS []string `json:"dns,omitempty"` + // IP Network only. + // If you want to associate a static private IP Address, + // specify that here within the range of the supplied IPNetwork attribute. + // Optional + IPAddress string `json:"ip,omitempty"` + // IP Network only. + // The name of the IP Network you want to add the instance to. + // Required + IPNetwork string `json:"ipnetwork,omitempty"` + // IP Network only. + // Set interface as default gateway for all traffic + // Optional + IsDefaultGateway bool `json:"is_default_gateway,omitempty"` + // IP Network only. + // The hexadecimal MAC Address of the interface + // Optional + MACAddress string `json:"address,omitempty"` + // Shared Network only. + // The type of NIC used. Must be set to 'e1000' + // Required + Model NICModel `json:"model,omitempty"` + // IP Network and Shared Network + // The name servers that are sent through DHCP as option 6. + // You can specify a maximum of eight name server IP addresses per interface. + // Optional + NameServers []string `json:"name_servers,omitempty"` + // The names of an IP Reservation to associate in an IP Network (Optional) + // Indicates whether a temporary or permanent public IP Address should be assigned + // in a Shared Network (Required) + Nat []string `json:"nat,omitempty"` + // IP Network and Shared Network + // The search domains that should be sent through DHCP as option 119. + // You can enter a maximum of eight search domain zones per interface. + // Optional + SearchDomains []string `json:"search_domains,omitempty"` + // Shared Network only. + // The security lists that you want to add the instance to + // Required + SecLists []string `json:"seclists,omitempty"` + // IP Network Only + // The name of the vNIC + // Optional + Vnic string `json:"vnic,omitempty"` + // IP Network only. + // The names of the vNICSets you want to add the interface to. + // Optional + VnicSets []string `json:"vnicsets,omitempty"` +} + +// LaunchPlan defines a launch plan, used to launch instances with the supplied InstanceSpec(s) +type LaunchPlanInput struct { + // Describes an array of instances which should be launched + Instances []CreateInstanceInput `json:"instances"` + // Time to wait for instance boot + Timeout time.Duration `json:"-"` +} + +type LaunchPlanResponse struct { + // An array of instances which have been launched + Instances []InstanceInfo `json:"instances"` +} + +// LaunchInstance creates and submits a LaunchPlan to launch a new instance. +func (c *InstancesClient) CreateInstance(input *CreateInstanceInput) (*InstanceInfo, error) { + qualifiedSSHKeys := []string{} + for _, key := range input.SSHKeys { + qualifiedSSHKeys = append(qualifiedSSHKeys, c.getQualifiedName(key)) + } + + input.SSHKeys = qualifiedSSHKeys + + qualifiedStorageAttachments := []StorageAttachmentInput{} + for _, attachment := range input.Storage { + qualifiedStorageAttachments = append(qualifiedStorageAttachments, StorageAttachmentInput{ + Index: attachment.Index, + Volume: c.getQualifiedName(attachment.Volume), + }) + } + input.Storage = qualifiedStorageAttachments + + input.Networking = c.qualifyNetworking(input.Networking) + + input.Name = fmt.Sprintf(CMP_QUALIFIED_NAME, c.getUserName(), input.Name) + + plan := LaunchPlanInput{ + Instances: []CreateInstanceInput{*input}, + Timeout: input.Timeout, + } + + var ( + instanceInfo *InstanceInfo + instanceError error + ) + for i := 0; i < *c.ComputeClient.client.MaxRetries; i++ { + c.client.DebugLogString(fmt.Sprintf("(Iteration: %d of %d) Creating instance with name %s\n Plan: %+v", i, *c.ComputeClient.client.MaxRetries, input.Name, plan)) + + instanceInfo, instanceError = c.startInstance(input.Name, plan) + if instanceError == nil { + c.client.DebugLogString(fmt.Sprintf("(Iteration: %d of %d) Finished creating instance with name %s\n Info: %+v", i, *c.ComputeClient.client.MaxRetries, input.Name, instanceInfo)) + return instanceInfo, nil + } + } + return nil, instanceError +} + +func (c *InstancesClient) startInstance(name string, plan LaunchPlanInput) (*InstanceInfo, error) { + var responseBody LaunchPlanResponse + + if err := c.createResource(&plan, &responseBody); err != nil { + return nil, err + } + + if len(responseBody.Instances) == 0 { + return nil, fmt.Errorf("No instance information returned: %#v", responseBody) + } + + // Call wait for instance ready now, as creating the instance is an eventually consistent operation + getInput := &GetInstanceInput{ + Name: name, + ID: responseBody.Instances[0].ID, + } + + //timeout := WaitForInstanceReadyTimeout + if plan.Timeout == 0 { + plan.Timeout = WaitForInstanceReadyTimeout + } + + // Wait for instance to be ready and return the result + // Don't have to unqualify any objects, as the GetInstance method will handle that + instanceInfo, instanceError := c.WaitForInstanceRunning(getInput, plan.Timeout) + // If the instance enters an error state we need to delete the instance and retry + if instanceError != nil { + deleteInput := &DeleteInstanceInput{ + Name: name, + ID: responseBody.Instances[0].ID, + } + err := c.DeleteInstance(deleteInput) + if err != nil { + return nil, fmt.Errorf("Error deleting instance %s: %s", name, err) + } + return nil, instanceError + } + return instanceInfo, nil +} + +// Both of these fields are required. If they're not provided, things go wrong in +// incredibly amazing ways. +type GetInstanceInput struct { + // The Unqualified Name of this Instance + Name string + // The Unqualified ID of this Instance + ID string +} + +func (g *GetInstanceInput) String() string { + return fmt.Sprintf(CMP_QUALIFIED_NAME, g.Name, g.ID) +} + +// GetInstance retrieves information about an instance. +func (c *InstancesClient) GetInstance(input *GetInstanceInput) (*InstanceInfo, error) { + if input.ID == "" || input.Name == "" { + return nil, errors.New("Both instance name and ID need to be specified") + } + + var responseBody InstanceInfo + if err := c.getResource(input.String(), &responseBody); err != nil { + return nil, err + } + + if responseBody.Name == "" { + return nil, fmt.Errorf("Empty response body when requesting instance %s", input.Name) + } + + // The returned 'Name' attribute is the fully qualified instance name + "/" + ID + // Split these out to accurately populate the fields + nID := strings.Split(c.getUnqualifiedName(responseBody.Name), "/") + responseBody.Name = nID[0] + responseBody.ID = nID[1] + + c.unqualify(&responseBody.VCableID) + + // Unqualify SSH Key names + sshKeyNames := []string{} + for _, sshKeyRef := range responseBody.SSHKeys { + sshKeyNames = append(sshKeyNames, c.getUnqualifiedName(sshKeyRef)) + } + responseBody.SSHKeys = sshKeyNames + + var networkingErr error + responseBody.Networking, networkingErr = c.unqualifyNetworking(responseBody.Networking) + if networkingErr != nil { + return nil, networkingErr + } + responseBody.Storage = c.unqualifyStorage(responseBody.Storage) + + return &responseBody, nil +} + +type InstancesInfo struct { + Instances []InstanceInfo `json:"result"` +} + +type GetInstanceIdInput struct { + // Name of the instance you want to get + Name string +} + +// GetInstanceFromName loops through all the instances and finds the instance for the given name +// This is needed for orchestration since it doesn't return the id for the instance it creates. +func (c *InstancesClient) GetInstanceFromName(input *GetInstanceIdInput) (*InstanceInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var instancesInfo InstancesInfo + if err := c.getResource(fmt.Sprintf("%s/", c.getUserName()), &instancesInfo); err != nil { + return nil, err + } + + for _, i := range instancesInfo.Instances { + if strings.Contains(i.Name, input.Name) { + if i.Name == "" { + return nil, fmt.Errorf("Empty response body when requesting instance %s", input.Name) + } + + // The returned 'Name' attribute is the fully qualified instance name + "/" + ID + // Split these out to accurately populate the fields + nID := strings.Split(c.getUnqualifiedName(i.Name), "/") + i.Name = nID[0] + i.ID = nID[1] + + c.unqualify(&i.VCableID) + + // Unqualify SSH Key names + sshKeyNames := []string{} + for _, sshKeyRef := range i.SSHKeys { + sshKeyNames = append(sshKeyNames, c.getUnqualifiedName(sshKeyRef)) + } + i.SSHKeys = sshKeyNames + + var networkingErr error + i.Networking, networkingErr = c.unqualifyNetworking(i.Networking) + if networkingErr != nil { + return nil, networkingErr + } + i.Storage = c.unqualifyStorage(i.Storage) + + return &i, nil + } + } + + return nil, fmt.Errorf("Unable to find instance: %q", input.Name) +} + +type UpdateInstanceInput struct { + // Name of this instance, generated by the server. + // Required + Name string `json:"name"` + // The desired state of the opc instance. Can only be `running` or `shutdown` + // Omits if empty. + // Optional + DesiredState InstanceDesiredState `json:"desired_state,omitempty"` + // The ID of the instance + // Required + ID string `json:"-"` + // A list of tags to be supplied to the instance + // Optional + Tags []string `json:"tags,omitempty"` + // Time to wait for instance to be ready, or shutdown depending on desired state + Timeout time.Duration `json:"-"` +} + +func (g *UpdateInstanceInput) String() string { + return fmt.Sprintf(CMP_QUALIFIED_NAME, g.Name, g.ID) +} + +func (c *InstancesClient) UpdateInstance(input *UpdateInstanceInput) (*InstanceInfo, error) { + if input.Name == "" || input.ID == "" { + return nil, errors.New("Both instance name and ID need to be specified") + } + + input.Name = fmt.Sprintf(CMP_QUALIFIED_NAME, c.getUserName(), input.Name) + + var responseBody InstanceInfo + if err := c.updateResource(input.String(), input, &responseBody); err != nil { + return nil, err + } + + getInput := &GetInstanceInput{ + Name: input.Name, + ID: input.ID, + } + + if input.Timeout == 0 { + input.Timeout = WaitForInstanceReadyTimeout + } + + // Wait for the correct instance action depending on the current desired state. + // If the instance is already running, and the desired state is to be "running", the + // wait loop will only execute a single time to verify the instance state. Otherwise + // we wait until the correct action has finalized, either a shutdown or restart, catching + // any intermittent errors during the process. + if responseBody.DesiredState == InstanceDesiredRunning { + return c.WaitForInstanceRunning(getInput, input.Timeout) + } else { + return c.WaitForInstanceShutdown(getInput, input.Timeout) + } +} + +type DeleteInstanceInput struct { + // The Unqualified Name of this Instance + Name string + // The Unqualified ID of this Instance + ID string + // Time to wait for instance to be deleted + Timeout time.Duration +} + +func (d *DeleteInstanceInput) String() string { + return fmt.Sprintf(CMP_QUALIFIED_NAME, d.Name, d.ID) +} + +// DeleteInstance deletes an instance. +func (c *InstancesClient) DeleteInstance(input *DeleteInstanceInput) error { + // Call to delete the instance + if err := c.deleteResource(input.String()); err != nil { + return err + } + + if input.Timeout == 0 { + input.Timeout = WaitForInstanceDeleteTimeout + } + + // Wait for instance to be deleted + return c.WaitForInstanceDeleted(input, input.Timeout) +} + +// WaitForInstanceRunning waits for an instance to be completely initialized and available. +func (c *InstancesClient) WaitForInstanceRunning(input *GetInstanceInput, timeout time.Duration) (*InstanceInfo, error) { + var info *InstanceInfo + var getErr error + err := c.client.WaitFor("instance to be ready", timeout, func() (bool, error) { + info, getErr = c.GetInstance(input) + if getErr != nil { + return false, getErr + } + c.client.DebugLogString(fmt.Sprintf("Instance name is %v, Instance info is %+v", info.Name, info)) + switch s := info.State; s { + case InstanceError: + return false, fmt.Errorf("Error initializing instance: %s", info.ErrorReason) + case InstanceRunning: // Target State + c.client.DebugLogString("Instance Running") + return true, nil + case InstanceQueued: + c.client.DebugLogString("Instance Queuing") + return false, nil + case InstanceInitializing: + c.client.DebugLogString("Instance Initializing") + return false, nil + case InstancePreparing: + c.client.DebugLogString("Instance Preparing") + return false, nil + case InstanceStarting: + c.client.DebugLogString("Instance Starting") + return false, nil + default: + c.client.DebugLogString(fmt.Sprintf("Unknown instance state: %s, waiting", s)) + return false, nil + } + }) + return info, err +} + +// WaitForInstanceShutdown waits for an instance to be shutdown +func (c *InstancesClient) WaitForInstanceShutdown(input *GetInstanceInput, timeout time.Duration) (*InstanceInfo, error) { + var info *InstanceInfo + var getErr error + err := c.client.WaitFor("instance to be shutdown", timeout, func() (bool, error) { + info, getErr = c.GetInstance(input) + if getErr != nil { + return false, getErr + } + switch s := info.State; s { + case InstanceError: + return false, fmt.Errorf("Error initializing instance: %s", info.ErrorReason) + case InstanceRunning: + c.client.DebugLogString("Instance Running") + return false, nil + case InstanceQueued: + c.client.DebugLogString("Instance Queuing") + return false, nil + case InstanceInitializing: + c.client.DebugLogString("Instance Initializing") + return false, nil + case InstancePreparing: + c.client.DebugLogString("Instance Preparing") + return false, nil + case InstanceStarting: + c.client.DebugLogString("Instance Starting") + return false, nil + case InstanceShutdown: // Target State + c.client.DebugLogString("Instance Shutdown") + return true, nil + default: + c.client.DebugLogString(fmt.Sprintf("Unknown instance state: %s, waiting", s)) + return false, nil + } + }) + return info, err +} + +// WaitForInstanceDeleted waits for an instance to be fully deleted. +func (c *InstancesClient) WaitForInstanceDeleted(input *DeleteInstanceInput, timeout time.Duration) error { + return c.client.WaitFor("instance to be deleted", timeout, func() (bool, error) { + var info InstanceInfo + if err := c.getResource(input.String(), &info); err != nil { + if client.WasNotFoundError(err) { + // Instance could not be found, thus deleted + return true, nil + } + // Some other error occurred trying to get instance, exit + return false, err + } + switch s := info.State; s { + case InstanceError: + return false, fmt.Errorf("Error stopping instance: %s", info.ErrorReason) + case InstanceStopping: + c.client.DebugLogString("Instance stopping") + return false, nil + default: + c.client.DebugLogString(fmt.Sprintf("Unknown instance state: %s, waiting", s)) + return false, nil + } + }) +} + +func (c *InstancesClient) qualifyNetworking(info map[string]NetworkingInfo) map[string]NetworkingInfo { + qualifiedNetworks := map[string]NetworkingInfo{} + for k, v := range info { + qfd := v + sharedNetwork := false + if v.IPNetwork != "" { + // Network interface is for an IP Network + qfd.IPNetwork = c.getQualifiedName(v.IPNetwork) + sharedNetwork = true + } + if v.Vnic != "" { + qfd.Vnic = c.getQualifiedName(v.Vnic) + } + if v.Nat != nil { + qfd.Nat = c.qualifyNat(v.Nat, sharedNetwork) + } + if v.VnicSets != nil { + qfd.VnicSets = c.getQualifiedList(v.VnicSets) + } + if v.SecLists != nil { + // Network interface is for the shared network + secLists := []string{} + for _, v := range v.SecLists { + secLists = append(secLists, c.getQualifiedName(v)) + } + qfd.SecLists = secLists + } + + qualifiedNetworks[k] = qfd + } + return qualifiedNetworks +} + +func (c *InstancesClient) unqualifyNetworking(info map[string]NetworkingInfo) (map[string]NetworkingInfo, error) { + // Unqualify ip network + var err error + unqualifiedNetworks := map[string]NetworkingInfo{} + for k, v := range info { + unq := v + if v.IPNetwork != "" { + unq.IPNetwork = c.getUnqualifiedName(v.IPNetwork) + } + if v.Vnic != "" { + unq.Vnic = c.getUnqualifiedName(v.Vnic) + } + if v.Nat != nil { + unq.Nat, err = c.unqualifyNat(v.Nat) + if err != nil { + return nil, err + } + } + if v.VnicSets != nil { + unq.VnicSets = c.getUnqualifiedList(v.VnicSets) + } + if v.SecLists != nil { + secLists := []string{} + for _, v := range v.SecLists { + secLists = append(secLists, c.getUnqualifiedName(v)) + } + v.SecLists = secLists + } + unqualifiedNetworks[k] = unq + } + return unqualifiedNetworks, nil +} + +func (c *InstancesClient) qualifyNat(nat []string, shared bool) []string { + qualifiedNats := []string{} + for _, v := range nat { + if strings.HasPrefix(v, "ippool:/oracle") { + qualifiedNats = append(qualifiedNats, v) + continue + } + prefix := ReservationPrefix + if shared { + prefix = ReservationIPPrefix + } + qualifiedNats = append(qualifiedNats, fmt.Sprintf("%s:%s", prefix, c.getQualifiedName(v))) + } + return qualifiedNats +} + +func (c *InstancesClient) unqualifyNat(nat []string) ([]string, error) { + unQualifiedNats := []string{} + for _, v := range nat { + if strings.HasPrefix(v, "ippool:/oracle") { + unQualifiedNats = append(unQualifiedNats, v) + continue + } + n := strings.Split(v, ":") + if len(n) < 1 { + return nil, fmt.Errorf("Error unqualifying NAT: %s", v) + } + u := n[1] + unQualifiedNats = append(unQualifiedNats, c.getUnqualifiedName(u)) + } + return unQualifiedNats, nil +} + +func (c *InstancesClient) unqualifyStorage(attachments []StorageAttachment) []StorageAttachment { + unqAttachments := []StorageAttachment{} + for _, v := range attachments { + if v.StorageVolumeName != "" { + v.StorageVolumeName = c.getUnqualifiedName(v.StorageVolumeName) + } + unqAttachments = append(unqAttachments, v) + } + + return unqAttachments +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_associations.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_associations.go new file mode 100644 index 000000000..6c1167f12 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_associations.go @@ -0,0 +1,152 @@ +package compute + +const ( + IPAddressAssociationDescription = "ip address association" + IPAddressAssociationContainerPath = "/network/v1/ipassociation/" + IPAddressAssociationResourcePath = "/network/v1/ipassociation" +) + +type IPAddressAssociationsClient struct { + ResourceClient +} + +// IPAddressAssociations() returns an IPAddressAssociationsClient that can be used to access the +// necessary CRUD functions for IP Address Associations. +func (c *ComputeClient) IPAddressAssociations() *IPAddressAssociationsClient { + return &IPAddressAssociationsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: IPAddressAssociationDescription, + ContainerPath: IPAddressAssociationContainerPath, + ResourceRootPath: IPAddressAssociationResourcePath, + }, + } +} + +// IPAddressAssociationInfo contains the exported fields necessary to hold all the information about an +// IP Address Association +type IPAddressAssociationInfo struct { + // The name of the NAT IP address reservation. + IPAddressReservation string `json:"ipAddressReservation"` + // Name of the virtual NIC associated with this NAT IP reservation. + Vnic string `json:"vnic"` + // The name of the IP Address Association + Name string `json:"name"` + // Description of the IP Address Association + Description string `json:"description"` + // Slice of tags associated with the IP Address Association + Tags []string `json:"tags"` + // Uniform Resource Identifier for the IP Address Association + Uri string `json:"uri"` +} + +type CreateIPAddressAssociationInput struct { + // The name of the IP Address Association to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // The name of the NAT IP address reservation. + // Optional + IPAddressReservation string `json:"ipAddressReservation,omitempty"` + + // Name of the virtual NIC associated with this NAT IP reservation. + // Optional + Vnic string `json:"vnic,omitempty"` + + // Description of the IPAddressAssociation + // Optional + Description string `json:"description"` + + // String slice of tags to apply to the IP Address Association object + // Optional + Tags []string `json:"tags"` +} + +// Create a new IP Address Association from an IPAddressAssociationsClient and an input struct. +// Returns a populated Info struct for the IP Address Association, and any errors +func (c *IPAddressAssociationsClient) CreateIPAddressAssociation(input *CreateIPAddressAssociationInput) (*IPAddressAssociationInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.IPAddressReservation = c.getQualifiedName(input.IPAddressReservation) + input.Vnic = c.getQualifiedName(input.Vnic) + + var ipInfo IPAddressAssociationInfo + if err := c.createResource(&input, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type GetIPAddressAssociationInput struct { + // The name of the IP Address Association to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +// Returns a populated IPAddressAssociationInfo struct from an input struct +func (c *IPAddressAssociationsClient) GetIPAddressAssociation(input *GetIPAddressAssociationInput) (*IPAddressAssociationInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo IPAddressAssociationInfo + if err := c.getResource(input.Name, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +// UpdateIPAddressAssociationInput defines what to update in a ip address association +type UpdateIPAddressAssociationInput struct { + // The name of the IP Address Association to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // The name of the NAT IP address reservation. + // Optional + IPAddressReservation string `json:"ipAddressReservation,omitempty"` + + // Name of the virtual NIC associated with this NAT IP reservation. + // Optional + Vnic string `json:"vnic,omitempty"` + + // Description of the IPAddressAssociation + // Optional + Description string `json:"description"` + + // String slice of tags to apply to the IP Address Association object + // Optional + Tags []string `json:"tags"` +} + +// UpdateIPAddressAssociation update the ip address association +func (c *IPAddressAssociationsClient) UpdateIPAddressAssociation(updateInput *UpdateIPAddressAssociationInput) (*IPAddressAssociationInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + updateInput.IPAddressReservation = c.getQualifiedName(updateInput.IPAddressReservation) + updateInput.Vnic = c.getQualifiedName(updateInput.Vnic) + var ipInfo IPAddressAssociationInfo + if err := c.updateResource(updateInput.Name, updateInput, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type DeleteIPAddressAssociationInput struct { + // The name of the IP Address Association to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *IPAddressAssociationsClient) DeleteIPAddressAssociation(input *DeleteIPAddressAssociationInput) error { + return c.deleteResource(input.Name) +} + +// Unqualifies any qualified fields in the IPAddressAssociationInfo struct +func (c *IPAddressAssociationsClient) success(info *IPAddressAssociationInfo) (*IPAddressAssociationInfo, error) { + c.unqualify(&info.Name) + c.unqualify(&info.Vnic) + c.unqualify(&info.IPAddressReservation) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_prefix_set.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_prefix_set.go new file mode 100644 index 000000000..3f1503c08 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_prefix_set.go @@ -0,0 +1,135 @@ +package compute + +const ( + IPAddressPrefixSetDescription = "ip address prefix set" + IPAddressPrefixSetContainerPath = "/network/v1/ipaddressprefixset/" + IPAddressPrefixSetResourcePath = "/network/v1/ipaddressprefixset" +) + +type IPAddressPrefixSetsClient struct { + ResourceClient +} + +// IPAddressPrefixSets() returns an IPAddressPrefixSetsClient that can be used to access the +// necessary CRUD functions for IP Address Prefix Sets. +func (c *ComputeClient) IPAddressPrefixSets() *IPAddressPrefixSetsClient { + return &IPAddressPrefixSetsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: IPAddressPrefixSetDescription, + ContainerPath: IPAddressPrefixSetContainerPath, + ResourceRootPath: IPAddressPrefixSetResourcePath, + }, + } +} + +// IPAddressPrefixSetInfo contains the exported fields necessary to hold all the information about an +// IP Address Prefix Set +type IPAddressPrefixSetInfo struct { + // The name of the IP Address Prefix Set + Name string `json:"name"` + // Description of the IP Address Prefix Set + Description string `json:"description"` + // List of CIDR IPv4 prefixes assigned in the virtual network. + IPAddressPrefixes []string `json:"ipAddressPrefixes"` + // Slice of tags associated with the IP Address Prefix Set + Tags []string `json:"tags"` + // Uniform Resource Identifier for the IP Address Prefix Set + Uri string `json:"uri"` +} + +type CreateIPAddressPrefixSetInput struct { + // The name of the IP Address Prefix Set to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Description of the IPAddressPrefixSet + // Optional + Description string `json:"description"` + + // List of CIDR IPv4 prefixes assigned in the virtual network. + // Optional + IPAddressPrefixes []string `json:"ipAddressPrefixes"` + + // String slice of tags to apply to the IP Address Prefix Set object + // Optional + Tags []string `json:"tags"` +} + +// Create a new IP Address Prefix Set from an IPAddressPrefixSetsClient and an input struct. +// Returns a populated Info struct for the IP Address Prefix Set, and any errors +func (c *IPAddressPrefixSetsClient) CreateIPAddressPrefixSet(input *CreateIPAddressPrefixSetInput) (*IPAddressPrefixSetInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo IPAddressPrefixSetInfo + if err := c.createResource(&input, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type GetIPAddressPrefixSetInput struct { + // The name of the IP Address Prefix Set to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +// Returns a populated IPAddressPrefixSetInfo struct from an input struct +func (c *IPAddressPrefixSetsClient) GetIPAddressPrefixSet(input *GetIPAddressPrefixSetInput) (*IPAddressPrefixSetInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo IPAddressPrefixSetInfo + if err := c.getResource(input.Name, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +// UpdateIPAddressPrefixSetInput defines what to update in a ip address prefix set +type UpdateIPAddressPrefixSetInput struct { + // The name of the IP Address Prefix Set to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Description of the IPAddressPrefixSet + // Optional + Description string `json:"description"` + + // List of CIDR IPv4 prefixes assigned in the virtual network. + IPAddressPrefixes []string `json:"ipAddressPrefixes"` + + // String slice of tags to apply to the IP Address Prefix Set object + // Optional + Tags []string `json:"tags"` +} + +// UpdateIPAddressPrefixSet update the ip address prefix set +func (c *IPAddressPrefixSetsClient) UpdateIPAddressPrefixSet(updateInput *UpdateIPAddressPrefixSetInput) (*IPAddressPrefixSetInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + var ipInfo IPAddressPrefixSetInfo + if err := c.updateResource(updateInput.Name, updateInput, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type DeleteIPAddressPrefixSetInput struct { + // The name of the IP Address Prefix Set to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *IPAddressPrefixSetsClient) DeleteIPAddressPrefixSet(input *DeleteIPAddressPrefixSetInput) error { + return c.deleteResource(input.Name) +} + +// Unqualifies any qualified fields in the IPAddressPrefixSetInfo struct +func (c *IPAddressPrefixSetsClient) success(info *IPAddressPrefixSetInfo) (*IPAddressPrefixSetInfo, error) { + c.unqualify(&info.Name) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_reservations.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_reservations.go new file mode 100644 index 000000000..a1175711e --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_address_reservations.go @@ -0,0 +1,190 @@ +package compute + +import ( + "fmt" + "path/filepath" +) + +// IPAddressReservationsClient is a client to manage ip address reservation resources +type IPAddressReservationsClient struct { + *ResourceClient +} + +const ( + IPAddressReservationDescription = "IP Address Reservation" + IPAddressReservationContainerPath = "/network/v1/ipreservation/" + IPAddressReservationResourcePath = "/network/v1/ipreservation" + IPAddressReservationQualifier = "/oracle/public" +) + +// IPAddressReservations returns an IPAddressReservationsClient to manage IP address reservation +// resources +func (c *ComputeClient) IPAddressReservations() *IPAddressReservationsClient { + return &IPAddressReservationsClient{ + ResourceClient: &ResourceClient{ + ComputeClient: c, + ResourceDescription: IPAddressReservationDescription, + ContainerPath: IPAddressReservationContainerPath, + ResourceRootPath: IPAddressReservationResourcePath, + }, + } +} + +// IPAddressReservation describes an IP Address reservation +type IPAddressReservation struct { + // Description of the IP Address Reservation + Description string `json:"description"` + + // Reserved NAT IPv4 address from the IP Address Pool + IPAddress string `json:"ipAddress"` + + // Name of the IP Address pool to reserve the NAT IP from + IPAddressPool string `json:"ipAddressPool"` + + // Name of the reservation + Name string `json:"name"` + + // Tags associated with the object + Tags []string `json:"tags"` + + // Uniform Resource Identified for the reservation + Uri string `json:"uri"` +} + +const ( + PublicIPAddressPool = "public-ippool" + PrivateIPAddressPool = "cloud-ippool" +) + +// CreateIPAddressReservationInput defines input parameters to create an ip address reservation +type CreateIPAddressReservationInput struct { + // Description of the IP Address Reservation + // Optional + Description string `json:"description"` + + // IP Address pool from which to reserve an IP Address. + // Can be one of the following: + // + // 'public-ippool' - When you attach an IP Address from this pool to an instance, you enable + // access between the public Internet and the instance + // 'cloud-ippool' - When you attach an IP Address from this pool to an instance, the instance + // can communicate privately with other Oracle Cloud Services + // Optional + IPAddressPool string `json:"ipAddressPool"` + + // The name of the reservation to create + // Required + Name string `json:"name"` + + // Tags to associate with the IP Reservation + // Optional + Tags []string `json:"tags"` +} + +// Takes an input struct, creates an IP Address reservation, and returns the info struct and any errors +func (c *IPAddressReservationsClient) CreateIPAddressReservation(input *CreateIPAddressReservationInput) (*IPAddressReservation, error) { + var ipAddrRes IPAddressReservation + // Qualify supplied name + input.Name = c.getQualifiedName(input.Name) + // Qualify supplied address pool if not nil + if input.IPAddressPool != "" { + input.IPAddressPool = c.qualifyIPAddressPool(input.IPAddressPool) + } + + if err := c.createResource(input, &ipAddrRes); err != nil { + return nil, err + } + + return c.success(&ipAddrRes) +} + +// Parameters to retrieve information on an ip address reservation +type GetIPAddressReservationInput struct { + // Name of the IP Reservation + // Required + Name string `json:"name"` +} + +// Returns an IP Address Reservation and any errors +func (c *IPAddressReservationsClient) GetIPAddressReservation(input *GetIPAddressReservationInput) (*IPAddressReservation, error) { + var ipAddrRes IPAddressReservation + + input.Name = c.getQualifiedName(input.Name) + if err := c.getResource(input.Name, &ipAddrRes); err != nil { + return nil, err + } + + return c.success(&ipAddrRes) +} + +// Parameters to update an IP Address reservation +type UpdateIPAddressReservationInput struct { + // Description of the IP Address Reservation + // Optional + Description string `json:"description"` + + // IP Address pool from which to reserve an IP Address. + // Can be one of the following: + // + // 'public-ippool' - When you attach an IP Address from this pool to an instance, you enable + // access between the public Internet and the instance + // 'cloud-ippool' - When you attach an IP Address from this pool to an instance, the instance + // can communicate privately with other Oracle Cloud Services + // Optional + IPAddressPool string `json:"ipAddressPool"` + + // The name of the reservation to create + // Required + Name string `json:"name"` + + // Tags to associate with the IP Reservation + // Optional + Tags []string `json:"tags"` +} + +func (c *IPAddressReservationsClient) UpdateIPAddressReservation(input *UpdateIPAddressReservationInput) (*IPAddressReservation, error) { + var ipAddrRes IPAddressReservation + + // Qualify supplied name + input.Name = c.getQualifiedName(input.Name) + // Qualify supplied address pool if not nil + if input.IPAddressPool != "" { + input.IPAddressPool = c.qualifyIPAddressPool(input.IPAddressPool) + } + + if err := c.updateResource(input.Name, input, &ipAddrRes); err != nil { + return nil, err + } + + return c.success(&ipAddrRes) +} + +// Parameters to delete an IP Address Reservation +type DeleteIPAddressReservationInput struct { + // The name of the reservation to delete + Name string `json:"name"` +} + +func (c *IPAddressReservationsClient) DeleteIPAddressReservation(input *DeleteIPAddressReservationInput) error { + input.Name = c.getQualifiedName(input.Name) + return c.deleteResource(input.Name) +} + +func (c *IPAddressReservationsClient) success(result *IPAddressReservation) (*IPAddressReservation, error) { + c.unqualify(&result.Name) + if result.IPAddressPool != "" { + result.IPAddressPool = c.unqualifyIPAddressPool(result.IPAddressPool) + } + + return result, nil +} + +func (c *IPAddressReservationsClient) qualifyIPAddressPool(input string) string { + // Add '/oracle/public/' + return fmt.Sprintf("%s/%s", IPAddressReservationQualifier, input) +} + +func (c *IPAddressReservationsClient) unqualifyIPAddressPool(input string) string { + // Remove '/oracle/public/' + return filepath.Base(input) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_associations.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_associations.go new file mode 100644 index 000000000..09e194985 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_associations.go @@ -0,0 +1,118 @@ +package compute + +import ( + "fmt" + "strings" +) + +// IPAssociationsClient is a client for the IP Association functions of the Compute API. +type IPAssociationsClient struct { + *ResourceClient +} + +// IPAssociations obtains a IPAssociationsClient which can be used to access to the +// IP Association functions of the Compute API +func (c *ComputeClient) IPAssociations() *IPAssociationsClient { + return &IPAssociationsClient{ + ResourceClient: &ResourceClient{ + ComputeClient: c, + ResourceDescription: "ip association", + ContainerPath: "/ip/association/", + ResourceRootPath: "/ip/association", + }} +} + +// IPAssociationInfo describes an existing IP association. +type IPAssociationInfo struct { + // TODO: it'd probably make sense to expose the `ip` field here too? + + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + + // The three-part name of the IP reservation object in the format (/Compute-identity_domain/user/object). + // An IP reservation is a public IP address which is attached to an Oracle Compute Cloud Service instance that requires access to or from the Internet. + Reservation string `json:"reservation"` + + // The type of IP Address to associate with this instance + // for a Dynamic IP address specify `ippool:/oracle/public/ippool`. + // for a Static IP address specify the three part name of the existing IP reservation + ParentPool string `json:"parentpool"` + + // Uniform Resource Identifier for the IP Association + URI string `json:"uri"` + + // The three-part name of a vcable ID of an instance that is associated with the IP reservation. + VCable string `json:"vcable"` +} + +type CreateIPAssociationInput struct { + // The type of IP Address to associate with this instance + // for a Dynamic IP address specify `ippool:/oracle/public/ippool`. + // for a Static IP address specify the three part name of the existing IP reservation + // Required + ParentPool string `json:"parentpool"` + + // The three-part name of the vcable ID of the instance that you want to associate with an IP address. The three-part name is in the format: /Compute-identity_domain/user/object. + // Required + VCable string `json:"vcable"` +} + +// CreateIPAssociation creates a new IP association with the supplied vcable and parentpool. +func (c *IPAssociationsClient) CreateIPAssociation(input *CreateIPAssociationInput) (*IPAssociationInfo, error) { + input.VCable = c.getQualifiedName(input.VCable) + input.ParentPool = c.getQualifiedParentPoolName(input.ParentPool) + var assocInfo IPAssociationInfo + if err := c.createResource(input, &assocInfo); err != nil { + return nil, err + } + + return c.success(&assocInfo) +} + +type GetIPAssociationInput struct { + // The three-part name of the IP Association + // Required. + Name string `json:"name"` +} + +// GetIPAssociation retrieves the IP association with the given name. +func (c *IPAssociationsClient) GetIPAssociation(input *GetIPAssociationInput) (*IPAssociationInfo, error) { + var assocInfo IPAssociationInfo + if err := c.getResource(input.Name, &assocInfo); err != nil { + return nil, err + } + + return c.success(&assocInfo) +} + +type DeleteIPAssociationInput struct { + // The three-part name of the IP Association + // Required. + Name string `json:"name"` +} + +// DeleteIPAssociation deletes the IP association with the given name. +func (c *IPAssociationsClient) DeleteIPAssociation(input *DeleteIPAssociationInput) error { + return c.deleteResource(input.Name) +} + +func (c *IPAssociationsClient) getQualifiedParentPoolName(parentpool string) string { + parts := strings.Split(parentpool, ":") + pooltype := parts[0] + name := parts[1] + return fmt.Sprintf("%s:%s", pooltype, c.getQualifiedName(name)) +} + +func (c *IPAssociationsClient) unqualifyParentPoolName(parentpool *string) { + parts := strings.Split(*parentpool, ":") + pooltype := parts[0] + name := parts[1] + *parentpool = fmt.Sprintf("%s:%s", pooltype, c.getUnqualifiedName(name)) +} + +// Unqualifies identifiers +func (c *IPAssociationsClient) success(assocInfo *IPAssociationInfo) (*IPAssociationInfo, error) { + c.unqualify(&assocInfo.Name, &assocInfo.VCable) + c.unqualifyParentPoolName(&assocInfo.ParentPool) + return assocInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_network_exchange.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_network_exchange.go new file mode 100644 index 000000000..1df33f296 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_network_exchange.go @@ -0,0 +1,99 @@ +package compute + +const ( + IPNetworkExchangeDescription = "ip network exchange" + IPNetworkExchangeContainerPath = "/network/v1/ipnetworkexchange/" + IPNetworkExchangeResourcePath = "/network/v1/ipnetworkexchange" +) + +type IPNetworkExchangesClient struct { + ResourceClient +} + +// IPNetworkExchanges() returns an IPNetworkExchangesClient that can be used to access the +// necessary CRUD functions for IP Network Exchanges. +func (c *ComputeClient) IPNetworkExchanges() *IPNetworkExchangesClient { + return &IPNetworkExchangesClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: IPNetworkExchangeDescription, + ContainerPath: IPNetworkExchangeContainerPath, + ResourceRootPath: IPNetworkExchangeResourcePath, + }, + } +} + +// IPNetworkExchangeInfo contains the exported fields necessary to hold all the information about an +// IP Network Exchange +type IPNetworkExchangeInfo struct { + // The name of the IP Network Exchange + Name string `json:"name"` + // Description of the IP Network Exchange + Description string `json:"description"` + // Slice of tags associated with the IP Network Exchange + Tags []string `json:"tags"` + // Uniform Resource Identifier for the IP Network Exchange + Uri string `json:"uri"` +} + +type CreateIPNetworkExchangeInput struct { + // The name of the IP Network Exchange to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Description of the IPNetworkExchange + // Optional + Description string `json:"description"` + + // String slice of tags to apply to the IP Network Exchange object + // Optional + Tags []string `json:"tags"` +} + +// Create a new IP Network Exchange from an IPNetworkExchangesClient and an input struct. +// Returns a populated Info struct for the IP Network Exchange, and any errors +func (c *IPNetworkExchangesClient) CreateIPNetworkExchange(input *CreateIPNetworkExchangeInput) (*IPNetworkExchangeInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo IPNetworkExchangeInfo + if err := c.createResource(&input, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type GetIPNetworkExchangeInput struct { + // The name of the IP Network Exchange to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +// Returns a populated IPNetworkExchangeInfo struct from an input struct +func (c *IPNetworkExchangesClient) GetIPNetworkExchange(input *GetIPNetworkExchangeInput) (*IPNetworkExchangeInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo IPNetworkExchangeInfo + if err := c.getResource(input.Name, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type DeleteIPNetworkExchangeInput struct { + // The name of the IP Network Exchange to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *IPNetworkExchangesClient) DeleteIPNetworkExchange(input *DeleteIPNetworkExchangeInput) error { + return c.deleteResource(input.Name) +} + +// Unqualifies any qualified fields in the IPNetworkExchangeInfo struct +func (c *IPNetworkExchangesClient) success(info *IPNetworkExchangeInfo) (*IPNetworkExchangeInfo, error) { + c.unqualify(&info.Name) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_networks.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_networks.go new file mode 100644 index 000000000..bfc324845 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_networks.go @@ -0,0 +1,186 @@ +package compute + +const ( + IPNetworkDescription = "ip network" + IPNetworkContainerPath = "/network/v1/ipnetwork/" + IPNetworkResourcePath = "/network/v1/ipnetwork" +) + +type IPNetworksClient struct { + ResourceClient +} + +// IPNetworks() returns an IPNetworksClient that can be used to access the +// necessary CRUD functions for IP Networks. +func (c *ComputeClient) IPNetworks() *IPNetworksClient { + return &IPNetworksClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: IPNetworkDescription, + ContainerPath: IPNetworkContainerPath, + ResourceRootPath: IPNetworkResourcePath, + }, + } +} + +// IPNetworkInfo contains the exported fields necessary to hold all the information about an +// IP Network +type IPNetworkInfo struct { + // The name of the IP Network + Name string `json:"name"` + // The CIDR IPv4 prefix associated with the IP Network + IPAddressPrefix string `json:"ipAddressPrefix"` + // Name of the IP Network Exchange associated with the IP Network + IPNetworkExchange string `json:"ipNetworkExchange,omitempty"` + // Description of the IP Network + Description string `json:"description"` + // Whether public internet access was enabled using NAPT for VNICs without any public IP reservation + PublicNaptEnabled bool `json:"publicNaptEnabledFlag"` + // Slice of tags associated with the IP Network + Tags []string `json:"tags"` + // Uniform Resource Identifier for the IP Network + Uri string `json:"uri"` +} + +type CreateIPNetworkInput struct { + // The name of the IP Network to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Specify the size of the IP Subnet. It is a range of IPv4 addresses assigned in the virtual + // network, in CIDR address prefix format. + // While specifying the IP address prefix take care of the following points: + // + //* These IP addresses aren't part of the common pool of Oracle-provided IP addresses used by the shared network. + // + //* There's no conflict with the range of IP addresses used in another IP network, the IP addresses used your on-premises network, or with the range of private IP addresses used in the shared network. If IP networks with overlapping IP subnets are linked to an IP exchange, packets going to and from those IP networks are dropped. + // + //* The upper limit of the CIDR block size for an IP network is /16. + // + //Note: The first IP address of any IP network is reserved for the default gateway, the DHCP server, and the DNS server of that IP network. + // Required + IPAddressPrefix string `json:"ipAddressPrefix"` + + //Specify the IP network exchange to which the IP network belongs. + //You can add an IP network to only one IP network exchange, but an IP network exchange + //can include multiple IP networks. An IP network exchange enables access between IP networks + //that have non-overlapping addresses, so that instances on these networks can exchange packets + //with each other without NAT. + // Optional + IPNetworkExchange string `json:"ipNetworkExchange,omitempty"` + + // Description of the IPNetwork + // Optional + Description string `json:"description"` + + // Enable public internet access using NAPT for VNICs without any public IP reservation + // Optional + PublicNaptEnabled bool `json:"publicNaptEnabledFlag"` + + // String slice of tags to apply to the IP Network object + // Optional + Tags []string `json:"tags"` +} + +// Create a new IP Network from an IPNetworksClient and an input struct. +// Returns a populated Info struct for the IP Network, and any errors +func (c *IPNetworksClient) CreateIPNetwork(input *CreateIPNetworkInput) (*IPNetworkInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.IPNetworkExchange = c.getQualifiedName(input.IPNetworkExchange) + + var ipInfo IPNetworkInfo + if err := c.createResource(&input, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type GetIPNetworkInput struct { + // The name of the IP Network to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +// Returns a populated IPNetworkInfo struct from an input struct +func (c *IPNetworksClient) GetIPNetwork(input *GetIPNetworkInput) (*IPNetworkInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo IPNetworkInfo + if err := c.getResource(input.Name, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type UpdateIPNetworkInput struct { + // The name of the IP Network to update. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Specify the size of the IP Subnet. It is a range of IPv4 addresses assigned in the virtual + // network, in CIDR address prefix format. + // While specifying the IP address prefix take care of the following points: + // + //* These IP addresses aren't part of the common pool of Oracle-provided IP addresses used by the shared network. + // + //* There's no conflict with the range of IP addresses used in another IP network, the IP addresses used your on-premises network, or with the range of private IP addresses used in the shared network. If IP networks with overlapping IP subnets are linked to an IP exchange, packets going to and from those IP networks are dropped. + // + //* The upper limit of the CIDR block size for an IP network is /16. + // + //Note: The first IP address of any IP network is reserved for the default gateway, the DHCP server, and the DNS server of that IP network. + // Required + IPAddressPrefix string `json:"ipAddressPrefix"` + + //Specify the IP network exchange to which the IP network belongs. + //You can add an IP network to only one IP network exchange, but an IP network exchange + //can include multiple IP networks. An IP network exchange enables access between IP networks + //that have non-overlapping addresses, so that instances on these networks can exchange packets + //with each other without NAT. + // Optional + IPNetworkExchange string `json:"ipNetworkExchange,omitempty"` + + // Description of the IPNetwork + // Optional + Description string `json:"description"` + + // Enable public internet access using NAPT for VNICs without any public IP reservation + // Optional + PublicNaptEnabled bool `json:"publicNaptEnabledFlag"` + + // String slice of tags to apply to the IP Network object + // Optional + Tags []string `json:"tags"` +} + +func (c *IPNetworksClient) UpdateIPNetwork(input *UpdateIPNetworkInput) (*IPNetworkInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.IPNetworkExchange = c.getQualifiedName(input.IPNetworkExchange) + + var ipInfo IPNetworkInfo + if err := c.updateResource(input.Name, &input, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type DeleteIPNetworkInput struct { + // The name of the IP Network to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *IPNetworksClient) DeleteIPNetwork(input *DeleteIPNetworkInput) error { + return c.deleteResource(input.Name) +} + +// Unqualifies any qualified fields in the IPNetworkInfo struct +func (c *IPNetworksClient) success(info *IPNetworkInfo) (*IPNetworkInfo, error) { + c.unqualify(&info.Name) + c.unqualify(&info.IPNetworkExchange) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_reservations.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_reservations.go new file mode 100644 index 000000000..42f9f1741 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ip_reservations.go @@ -0,0 +1,147 @@ +package compute + +// IPReservationsClient is a client for the IP Reservations functions of the Compute API. +type IPReservationsClient struct { + *ResourceClient +} + +const ( + IPReservationDesc = "ip reservation" + IPReservationContainerPath = "/ip/reservation/" + IPReservataionResourcePath = "/ip/reservation" +) + +// IPReservations obtains an IPReservationsClient which can be used to access to the +// IP Reservations functions of the Compute API +func (c *ComputeClient) IPReservations() *IPReservationsClient { + return &IPReservationsClient{ + ResourceClient: &ResourceClient{ + ComputeClient: c, + ResourceDescription: IPReservationDesc, + ContainerPath: IPReservationContainerPath, + ResourceRootPath: IPReservataionResourcePath, + }} +} + +type IPReservationPool string + +const ( + PublicReservationPool IPReservationPool = "/oracle/public/ippool" +) + +// IPReservationInput describes an existing IP reservation. +type IPReservation struct { + // Shows the default account for your identity domain. + Account string `json:"account"` + // Public IP address. + IP string `json:"ip"` + // The three-part name of the IP Reservation (/Compute-identity_domain/user/object). + Name string `json:"name"` + // Pool of public IP addresses + ParentPool IPReservationPool `json:"parentpool"` + // Is the IP Reservation Persistent (i.e. static) or not (i.e. Dynamic)? + Permanent bool `json:"permanent"` + // A comma-separated list of strings which helps you to identify IP reservation. + Tags []string `json:"tags"` + // Uniform Resource Identifier + Uri string `json:"uri"` + // Is the IP reservation associated with an instance? + Used bool `json:"used"` +} + +// CreateIPReservationInput defines an IP reservation to be created. +type CreateIPReservationInput struct { + // The name of the object + // If you don't specify a name for this object, then the name is generated automatically. + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. + // Object names are case-sensitive. + // Optional + Name string `json:"name"` + // Pool of public IP addresses. This must be set to `ippool` + // Required + ParentPool IPReservationPool `json:"parentpool"` + // Is the IP Reservation Persistent (i.e. static) or not (i.e. Dynamic)? + // Required + Permanent bool `json:"permanent"` + // A comma-separated list of strings which helps you to identify IP reservations. + // Optional + Tags []string `json:"tags"` +} + +// CreateIPReservation creates a new IP reservation with the given parentpool, tags and permanent flag. +func (c *IPReservationsClient) CreateIPReservation(input *CreateIPReservationInput) (*IPReservation, error) { + var ipInput IPReservation + + input.Name = c.getQualifiedName(input.Name) + if err := c.createResource(input, &ipInput); err != nil { + return nil, err + } + + return c.success(&ipInput) +} + +// GetIPReservationInput defines an IP Reservation to get +type GetIPReservationInput struct { + // The name of the IP Reservation + // Required + Name string +} + +// GetIPReservation retrieves the IP reservation with the given name. +func (c *IPReservationsClient) GetIPReservation(input *GetIPReservationInput) (*IPReservation, error) { + var ipInput IPReservation + + input.Name = c.getQualifiedName(input.Name) + if err := c.getResource(input.Name, &ipInput); err != nil { + return nil, err + } + + return c.success(&ipInput) +} + +// UpdateIPReservationInput defines an IP Reservation to be updated +type UpdateIPReservationInput struct { + // The name of the object + // If you don't specify a name for this object, then the name is generated automatically. + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. + // Object names are case-sensitive. + // Required + Name string `json:"name"` + // Pool of public IP addresses. + // Required + ParentPool IPReservationPool `json:"parentpool"` + // Is the IP Reservation Persistent (i.e. static) or not (i.e. Dynamic)? + // Required + Permanent bool `json:"permanent"` + // A comma-separated list of strings which helps you to identify IP reservations. + // Optional + Tags []string `json:"tags"` +} + +// UpdateIPReservation updates the IP reservation. +func (c *IPReservationsClient) UpdateIPReservation(input *UpdateIPReservationInput) (*IPReservation, error) { + var updateOutput IPReservation + input.Name = c.getQualifiedName(input.Name) + if err := c.updateResource(input.Name, input, &updateOutput); err != nil { + return nil, err + } + return c.success(&updateOutput) +} + +// DeleteIPReservationInput defines an IP Reservation to delete +type DeleteIPReservationInput struct { + // The name of the IP Reservation + // Required + Name string +} + +// DeleteIPReservation deletes the IP reservation with the given name. +func (c *IPReservationsClient) DeleteIPReservation(input *DeleteIPReservationInput) error { + input.Name = c.getQualifiedName(input.Name) + return c.deleteResource(input.Name) +} + +func (c *IPReservationsClient) success(result *IPReservation) (*IPReservation, error) { + c.unqualify(&result.Name) + return result, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go new file mode 100644 index 000000000..bf7736a63 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/machine_images.go @@ -0,0 +1,143 @@ +package compute + +// MachineImagesClient is a client for the MachineImage functions of the Compute API. +type MachineImagesClient struct { + ResourceClient +} + +// MachineImages obtains an MachineImagesClient which can be used to access to the +// MachineImage functions of the Compute API +func (c *ComputeClient) MachineImages() *MachineImagesClient { + return &MachineImagesClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "MachineImage", + ContainerPath: "/machineimage/", + ResourceRootPath: "/machineimage", + }} +} + +// MahineImage describes an existing Machine Image. +type MachineImage struct { + // account of the associated Object Storage Classic instance + Account string `json:"account"` + + // Dictionary of attributes to be made available to the instance + Attributes map[string]interface{} `json:"attributes"` + + // Last time when this image was audited + Audited string `json:"audited"` + + // Describing the image + Description string `json:"description"` + + // Description of the state of the machine image if there is an error + ErrorReason string `json:"error_reason"` + + // dictionary of hypervisor-specific attributes + Hypervisor map[string]interface{} `json:"hypervisor"` + + // The format of the image + ImageFormat string `json:"image_format"` + + // name of the machine image file uploaded to Object Storage Classic + File string `json:"file"` + + // name of the machine image + Name string `json:"name"` + + // Indicates that the image file is available in Object Storage Classic + NoUpload bool `json:"no_upload"` + + // The OS platform of the image + Platform string `json:"platform"` + + // Size values of the image file + Sizes map[string]interface{} `json:"sizes"` + + // The state of the uploaded machine image + State string `json:"state"` + + // Uniform Resource Identifier + URI string `json:"uri"` +} + +// CreateMachineImageInput defines an Image List to be created. +type CreateMachineImageInput struct { + // account of the associated Object Storage Classic instance + Account string `json:"account"` + + // Dictionary of attributes to be made available to the instance + Attributes map[string]interface{} `json:"attributes,omitempty"` + + // Describing the image + Description string `json:"description,omitempty"` + + // name of the machine image file uploaded to Object Storage Classic + File string `json:"file,omitempty"` + + // name of the machine image + Name string `json:"name"` + + // Indicates that the image file is available in Object Storage Classic + NoUpload bool `json:"no_upload"` + + // Size values of the image file + Sizes map[string]interface{} `json:"sizes"` +} + +// CreateMachineImage creates a new Machine Image with the given parameters. +func (c *MachineImagesClient) CreateMachineImage(createInput *CreateMachineImageInput) (*MachineImage, error) { + var machineImage MachineImage + + // If `sizes` is not set then is mst be defaulted to {"total": 0} + if createInput.Sizes == nil { + createInput.Sizes = map[string]interface{}{"total": 0} + } + + // `no_upload` must always be true + createInput.NoUpload = true + + createInput.Name = c.getQualifiedName(createInput.Name) + if err := c.createResource(createInput, &machineImage); err != nil { + return nil, err + } + + return c.success(&machineImage) +} + +// DeleteMachineImageInput describes the MachineImage to delete +type DeleteMachineImageInput struct { + // The name of the MachineImage + Name string `json:name` +} + +// DeleteMachineImage deletes the MachineImage with the given name. +func (c *MachineImagesClient) DeleteMachineImage(deleteInput *DeleteMachineImageInput) error { + return c.deleteResource(deleteInput.Name) +} + +// GetMachineList describes the MachineImage to get +type GetMachineImageInput struct { + // account of the associated Object Storage Classic instance + Account string `json:"account"` + // The name of the Machine Image + Name string `json:name` +} + +// GetMachineImage retrieves the MachineImage with the given name. +func (c *MachineImagesClient) GetMachineImage(getInput *GetMachineImageInput) (*MachineImage, error) { + getInput.Name = c.getQualifiedName(getInput.Name) + + var machineImage MachineImage + if err := c.getResource(getInput.Name, &machineImage); err != nil { + return nil, err + } + + return c.success(&machineImage) +} + +func (c *MachineImagesClient) success(result *MachineImage) (*MachineImage, error) { + c.unqualify(&result.Name) + return result, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go new file mode 100644 index 000000000..684e0d45f --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/orchestration.go @@ -0,0 +1,451 @@ +package compute + +import ( + "fmt" + "time" + + "github.com/hashicorp/go-oracle-terraform/client" +) + +const WaitForOrchestrationActiveTimeout = time.Duration(3600 * time.Second) +const WaitForOrchestrationDeleteTimeout = time.Duration(3600 * time.Second) + +// OrchestrationsClient is a client for the Orchestration functions of the Compute API. +type OrchestrationsClient struct { + ResourceClient +} + +// Orchestrations obtains an OrchestrationsClient which can be used to access to the +// Orchestration functions of the Compute API +func (c *ComputeClient) Orchestrations() *OrchestrationsClient { + return &OrchestrationsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "Orchestration", + ContainerPath: "/platform/v1/orchestration/", + ResourceRootPath: "/platform/v1/orchestration", + }} +} + +type OrchestrationDesiredState string + +const ( + // * active: Creates all the orchestration objects defined in the orchestration. + OrchestrationDesiredStateActive OrchestrationDesiredState = "active" + // * inactive: Adds the orchestration to Oracle Compute Cloud Service, but does not create any of the orchestration + OrchestrationDesiredStateInactive OrchestrationDesiredState = "inactive" + // * suspended: Suspends all orchestration objects defined in the orchestration + OrchestrationDesiredStateSuspend OrchestrationDesiredState = "suspend" +) + +type OrchestrationStatus string + +const ( + OrchestrationStatusActive OrchestrationStatus = "active" + OrchestrationStatusInactive OrchestrationStatus = "inactive" + OrchestrationStatusSuspend OrchestrationStatus = "suspend" + OrchestrationStatusActivating OrchestrationStatus = "activating" + OrchestrationStatusDeleting OrchestrationStatus = "deleting" + OrchestrationStatusError OrchestrationStatus = "terminal_error" + OrchestrationStatusStopping OrchestrationStatus = "stopping" + OrchestrationStatusSuspending OrchestrationStatus = "suspending" + OrchestrationStatusStarting OrchestrationStatus = "starting" + OrchestrationStatusDeactivating OrchestrationStatus = "deactivating" + OrchestrationStatusSuspended OrchestrationStatus = "suspended" +) + +type OrchestrationType string + +const ( + OrchestrationTypeInstance OrchestrationType = "Instance" +) + +// OrchestrationInfo describes an existing Orchestration. +type Orchestration struct { + // The default Oracle Compute Cloud Service account, such as /Compute-acme/default. + Account string `json:"account"` + // Description of this orchestration + Description string `json:"description"` + // The desired_state specified in the orchestration JSON file. A unique identifier for this orchestration. + DesiredState OrchestrationDesiredState `json:"desired_state"` + // Unique identifier of this orchestration + ID string `json:"id"` + // The three-part name of the Orchestration (/Compute-identity_domain/user/object). + Name string `json:"name"` + // List of orchestration objects + Objects []Object `json:"objects"` + // Current status of this orchestration + Status OrchestrationStatus `json:"status"` + // Strings that describe the orchestration and help you identify it. + Tags []string `json:"tags"` + // Time the orchestration was last audited + TimeAudited string `json:"time_audited"` + // The time when the orchestration was added to Oracle Compute Cloud Service. + TimeCreated string `json:"time_created"` + // The time when the orchestration was last updated in Oracle Compute Cloud Service. + TimeUpdated string `json:"time_updated"` + // Unique Resource Identifier + URI string `json:"uri"` + // Name of the user who added this orchestration or made the most recent update to this orchestration. + User string `json:"user"` + // Version of this orchestration. It is automatically generated by the server. + Version int `json:"version"` +} + +// CreateOrchestrationInput defines an Orchestration to be created. +type CreateOrchestrationInput struct { + // The default Oracle Compute Cloud Service account, such as /Compute-acme/default. + // Optional + Account string `json:"account,omitempty"` + // Description of this orchestration + // Optional + Description string `json:"description,omitempty"` + // Specify the desired state of this orchestration: active, inactive, or suspend. + // You can manage the state of the orchestration objects by changing the desired state of the orchestration. + // * active: Creates all the orchestration objects defined in the orchestration. + // * inactive: Adds the orchestration to Oracle Compute Cloud Service, but does not create any of the orchestration + // objects defined in the orchestration. + // Required + DesiredState OrchestrationDesiredState `json:"desired_state"` + // The three-part name of the Orchestration (/Compute-identity_domain/user/object). + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` + // The list of objects in the orchestration. An object is the primary building block of an orchestration. + // An orchestration can contain up to 100 objects. + // Required + Objects []Object `json:"objects"` + // Strings that describe the orchestration and help you identify it. + Tags []string `json:"tags,omitempty"` + // Version of this orchestration. It is automatically generated by the server. + Version int `json:"version,omitempty"` + // Time to wait for an orchestration to be ready + Timeout time.Duration `json:"-"` +} + +type Object struct { + // The default Oracle Compute Cloud Service account, such as /Compute-acme/default. + // Optional + Account string `json:"account,omitempty"` + // Description of this orchestration + // Optional + Description string `json:"description,omitempty"` + // The desired state of the object + // Optional + DesiredState OrchestrationDesiredState `json:"desired_state,omitempty"` + // Dictionary containing the current state of the object + Health Health `json:"health,omitempty"` + // A text string describing the object. Labels can't include spaces. In an orchestration, the label for + // each object must be unique. Maximum length is 256 characters. + // Required + Label string `json:"label"` + // The four-part name of the object (/Compute-identity_domain/user/orchestration/object). If you don't specify a name + // for this object, the name is generated automatically. Object names can contain only alphanumeric characters, hyphens, + // underscores, and periods. Object names are case-sensitive. When you specify the object name, ensure that an object of + // the same type and with the same name doesn't already exist. If such a object already exists, then another + // object of the same type and with the same name won't be created and the existing object won't be updated. + // Optional + Name string `json:"name,omitempty"` + // The three-part name (/Compute-identity_domain/user/object) of the orchestration to which the object belongs. + // Required + Orchestration string `json:"orchestration"` + // Specifies whether the object should persist when the orchestration is suspended. Specify one of the following: + // * true: The object persists when the orchestration is suspended. + // * false: The object is deleted when the orchestration is suspended. + // By default, persistent is set to false. It is recommended that you specify true for storage + // volumes and other critical objects. Persistence applies only when you're suspending an orchestration. + // When you terminate an orchestration, all the objects defined in it are deleted. + // Optional + Persistent bool `json:"persistent,omitempty"` + // The relationship between the objects that are created by this orchestration. The + // only supported relationship is depends, indicating that the specified target objects must be created first. + // Note that when recovering from a failure, the orchestration doesn't consider object relationships. + // Orchestrations v2 use object references to recover interdependent objects to a healthy state. SeeObject + // References and Relationships in Using Oracle Compute Cloud Service (IaaS). + Relationship []Object `json:"relationships,omitempty"` + // The template attribute defines the properties or characteristics of the Oracle Compute Cloud Service object + // that you want to create, as specified by the type attribute. + // The fields in the template section vary depending on the specified type. See Orchestration v2 Attributes + // Specific to Each Object Type in Using Oracle Compute Cloud Service (IaaS) to determine the parameters that are + // specific to each object type that you want to create. + // For example, if you want to create a storage volume, the type would be StorageVolume, and the template would include + // size and bootable. If you want to create an instance, the type would be Instance, and the template would include + // instance-specific attributes, such as imagelist and shape. + // Required + Template interface{} `json:"template"` + // Specify one of the following object types that you want to create. + // The only allowed type is Instance + // Required + Type OrchestrationType `json:"type"` + // Version of this object, generated by the server + // Optional + Version int `json:"version,omitempty"` +} + +type Health struct { + // The status of the object + Status OrchestrationStatus `json:"status,omitempty"` + // What caused the status of the object + Cause string `json:"cause,omitempty"` + // The specific details for what happened to the object + Detail string `json:"detail,omitempty"` + // Any errors associated with creation of the object + Error string `json:"error,omitempty"` +} + +// CreateOrchestration creates a new Orchestration with the given name, key and enabled flag. +func (c *OrchestrationsClient) CreateOrchestration(input *CreateOrchestrationInput) (*Orchestration, error) { + var createdOrchestration Orchestration + + input.Name = c.getQualifiedName(input.Name) + for _, i := range input.Objects { + i.Orchestration = c.getQualifiedName(i.Orchestration) + if i.Type == OrchestrationTypeInstance { + instanceClient := c.ComputeClient.Instances() + instanceInput := i.Template.(*CreateInstanceInput) + instanceInput.Name = c.getQualifiedName(instanceInput.Name) + + qualifiedSSHKeys := []string{} + for _, key := range instanceInput.SSHKeys { + qualifiedSSHKeys = append(qualifiedSSHKeys, c.getQualifiedName(key)) + } + + instanceInput.SSHKeys = qualifiedSSHKeys + + qualifiedStorageAttachments := []StorageAttachmentInput{} + for _, attachment := range instanceInput.Storage { + qualifiedStorageAttachments = append(qualifiedStorageAttachments, StorageAttachmentInput{ + Index: attachment.Index, + Volume: c.getQualifiedName(attachment.Volume), + }) + } + instanceInput.Storage = qualifiedStorageAttachments + + instanceInput.Networking = instanceClient.qualifyNetworking(instanceInput.Networking) + } + } + + if err := c.createResource(&input, &createdOrchestration); err != nil { + return nil, err + } + + // Call wait for orchestration ready now, as creating the orchestration is an eventually consistent operation + getInput := &GetOrchestrationInput{ + Name: createdOrchestration.Name, + } + + if input.Timeout == 0 { + input.Timeout = WaitForOrchestrationActiveTimeout + } + + // Wait for orchestration to be ready and return the result + // Don't have to unqualify any objects, as the GetOrchestration method will handle that + orchestrationInfo, orchestrationError := c.WaitForOrchestrationState(getInput, input.Timeout) + if orchestrationError != nil { + deleteInput := &DeleteOrchestrationInput{ + Name: createdOrchestration.Name, + } + err := c.DeleteOrchestration(deleteInput) + if err != nil { + return nil, fmt.Errorf("Error deleting orchestration %s: %s", getInput.Name, err) + } + return nil, fmt.Errorf("Error creating orchestration %s: %s", getInput.Name, orchestrationError) + } + + return &orchestrationInfo, nil +} + +// GetOrchestrationInput describes the Orchestration to get +type GetOrchestrationInput struct { + // The three-part name of the Orchestration (/Compute-identity_domain/user/object). + Name string `json:name` +} + +// GetOrchestration retrieves the Orchestration with the given name. +func (c *OrchestrationsClient) GetOrchestration(input *GetOrchestrationInput) (*Orchestration, error) { + var orchestrationInfo Orchestration + if err := c.getResource(input.Name, &orchestrationInfo); err != nil { + return nil, err + } + + return c.success(&orchestrationInfo) +} + +// UpdateOrchestrationInput defines an Orchestration to be updated +type UpdateOrchestrationInput struct { + // The default Oracle Compute Cloud Service account, such as /Compute-acme/default. + // Optional + Account string `json:"account,omitempty"` + // Description of this orchestration + // Optional + Description string `json:"description,omitempty"` + // Specify the desired state of this orchestration: active, inactive, or suspend. + // You can manage the state of the orchestration objects by changing the desired state of the orchestration. + // * active: Creates all the orchestration objects defined in the orchestration. + // * inactive: Adds the orchestration to Oracle Compute Cloud Service, but does not create any of the orchestration + // objects defined in the orchestration. + // Required + DesiredState OrchestrationDesiredState `json:"desired_state"` + // The three-part name of the Orchestration (/Compute-identity_domain/user/object). + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` + // The list of objects in the orchestration. An object is the primary building block of an orchestration. + // An orchestration can contain up to 100 objects. + // Required + Objects []Object `json:"objects"` + // Strings that describe the orchestration and help you identify it. + Tags []string `json:"tags,omitempty"` + // Version of this orchestration. It is automatically generated by the server. + Version int `json:"version,omitempty"` + // Time to wait for an orchestration to be ready + Timeout time.Duration `json:"-"` +} + +// UpdateOrchestration updates the orchestration. +func (c *OrchestrationsClient) UpdateOrchestration(input *UpdateOrchestrationInput) (*Orchestration, error) { + var updatedOrchestration Orchestration + input.Name = c.getQualifiedName(input.Name) + for _, i := range input.Objects { + i.Orchestration = c.getQualifiedName(i.Orchestration) + if i.Type == OrchestrationTypeInstance { + instanceInput := i.Template.(map[string]interface{}) + instanceInput["name"] = c.getQualifiedName(instanceInput["name"].(string)) + } + } + + if err := c.updateResource(input.Name, input, &updatedOrchestration); err != nil { + return nil, err + } + + // Call wait for orchestration ready now, as creating the orchestration is an eventually consistent operation + getInput := &GetOrchestrationInput{ + Name: updatedOrchestration.Name, + } + + if input.Timeout == 0 { + input.Timeout = WaitForOrchestrationActiveTimeout + } + + // Wait for orchestration to be ready and return the result + // Don't have to unqualify any objects, as the GetOrchestration method will handle that + orchestrationInfo, orchestrationError := c.WaitForOrchestrationState(getInput, input.Timeout) + if orchestrationError != nil { + return nil, orchestrationError + } + + return &orchestrationInfo, nil +} + +// DeleteOrchestrationInput describes the Orchestration to delete +type DeleteOrchestrationInput struct { + // The three-part name of the Orchestration (/Compute-identity_domain/user/object). + // Required + Name string `json:name` + // Timeout for delete request + Timeout time.Duration `json:"-"` +} + +// DeleteOrchestration deletes the Orchestration with the given name. +func (c *OrchestrationsClient) DeleteOrchestration(input *DeleteOrchestrationInput) error { + if err := c.deleteOrchestration(input.Name); err != nil { + return err + } + + if input.Timeout == 0 { + input.Timeout = WaitForOrchestrationDeleteTimeout + } + + return c.WaitForOrchestrationDeleted(input, input.Timeout) +} + +func (c *OrchestrationsClient) success(info *Orchestration) (*Orchestration, error) { + c.unqualify(&info.Name) + for _, i := range info.Objects { + c.unqualify(&i.Orchestration) + if OrchestrationType(i.Type) == OrchestrationTypeInstance { + instanceInput := i.Template.(map[string]interface{}) + instanceInput["name"] = c.getUnqualifiedName(instanceInput["name"].(string)) + } + } + + return info, nil +} + +// WaitForOrchestrationActive waits for an orchestration to be completely initialized and available. +func (c *OrchestrationsClient) WaitForOrchestrationState(input *GetOrchestrationInput, timeout time.Duration) (Orchestration, error) { + var info *Orchestration + var getErr error + err := c.client.WaitFor("orchestration to be ready", timeout, func() (bool, error) { + info, getErr = c.GetOrchestration(input) + if getErr != nil { + return false, getErr + } + c.client.DebugLogString(fmt.Sprintf("Orchestration name is %v, Orchestration info is %+v", info.Name, info)) + switch s := info.Status; s { + case OrchestrationStatusError: + // We need to check and see if an object the orchestration is trying to create is giving us an error instead of just the orchestration as a whole. + for _, object := range info.Objects { + if object.Health.Status == OrchestrationStatusError { + return false, fmt.Errorf("Error creating instance %s: %+v", object.Name, object.Health) + } + } + return false, fmt.Errorf("Error initializing orchestration: %+v", info) + case OrchestrationStatus(info.DesiredState): + c.client.DebugLogString(fmt.Sprintf("Orchestration %s", info.DesiredState)) + return true, nil + case OrchestrationStatusActivating: + c.client.DebugLogString("Orchestration activating") + return false, nil + case OrchestrationStatusStopping: + c.client.DebugLogString("Orchestration stopping") + return false, nil + case OrchestrationStatusSuspending: + c.client.DebugLogString("Orchestration suspending") + return false, nil + case OrchestrationStatusDeactivating: + c.client.DebugLogString("Orchestration deactivating") + return false, nil + case OrchestrationStatusSuspended: + c.client.DebugLogString("Orchestration suspended") + if info.DesiredState == OrchestrationDesiredStateSuspend { + return true, nil + } else { + return false, nil + } + default: + return false, fmt.Errorf("Unknown orchestration state: %s, erroring", s) + } + }) + return *info, err +} + +// WaitForOrchestrationDeleted waits for an orchestration to be fully deleted. +func (c *OrchestrationsClient) WaitForOrchestrationDeleted(input *DeleteOrchestrationInput, timeout time.Duration) error { + return c.client.WaitFor("orchestration to be deleted", timeout, func() (bool, error) { + var info Orchestration + if err := c.getResource(input.Name, &info); err != nil { + if client.WasNotFoundError(err) { + // Orchestration could not be found, thus deleted + return true, nil + } + // Some other error occurred trying to get Orchestration, exit + return false, err + } + switch s := info.Status; s { + case OrchestrationStatusError: + return false, fmt.Errorf("Error stopping orchestration: %+v", info) + case OrchestrationStatusStopping: + c.client.DebugLogString("Orchestration stopping") + return false, nil + case OrchestrationStatusDeleting: + c.client.DebugLogString("Orchestration deleting") + return false, nil + case OrchestrationStatusActive: + c.client.DebugLogString("Orchestration active") + return false, nil + default: + return false, fmt.Errorf("Unknown orchestration state: %s, erroring", s) + } + }) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/routes.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/routes.go new file mode 100644 index 000000000..f46beaecf --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/routes.go @@ -0,0 +1,153 @@ +package compute + +const ( + RoutesDescription = "IP Network Route" + RoutesContainerPath = "/network/v1/route/" + RoutesResourcePath = "/network/v1/route" +) + +type RoutesClient struct { + ResourceClient +} + +func (c *ComputeClient) Routes() *RoutesClient { + return &RoutesClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: RoutesDescription, + ContainerPath: RoutesContainerPath, + ResourceRootPath: RoutesResourcePath, + }, + } +} + +type RouteInfo struct { + // Admin distance associated with this route + AdminDistance int `json:"adminDistance"` + // Description of the route + Description string `json:"description"` + // CIDR IPv4 Prefix associated with this route + IPAddressPrefix string `json:"ipAddressPrefix"` + // Name of the route + Name string `json:"name"` + // Name of the VNIC set associated with the route + NextHopVnicSet string `json:"nextHopVnicSet"` + // Slice of Tags associated with the route + Tags []string `json:"tags,omitempty"` + // Uniform resource identifier associated with the route + Uri string `json:"uri"` +} + +type CreateRouteInput struct { + // Specify 0,1, or 2 as the route's administrative distance. + // If you do not specify a value, the default value is 0. + // The same prefix can be used in multiple routes. In this case, packets are routed over all the matching + // routes with the lowest administrative distance. + // In the case multiple routes with the same lowest administrative distance match, + // routing occurs over all these routes using ECMP. + // Optional + AdminDistance int `json:"adminDistance"` + // Description of the route + // Optional + Description string `json:"description"` + // The IPv4 address prefix in CIDR format, of the external network (external to the vNIC set) + // from which you want to route traffic + // Required + IPAddressPrefix string `json:"ipAddressPrefix"` + // Name of the route. + // Names can only contain alphanumeric, underscore, dash, and period characters. Case-sensitive + // Required + Name string `json:"name"` + // Name of the virtual NIC set to route matching packets to. + // Routed flows are load-balanced among all the virtual NICs in the virtual NIC set + // Required + NextHopVnicSet string `json:"nextHopVnicSet"` + // Slice of tags to be associated with the route + // Optional + Tags []string `json:"tags,omitempty"` +} + +func (c *RoutesClient) CreateRoute(input *CreateRouteInput) (*RouteInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.NextHopVnicSet = c.getQualifiedName(input.NextHopVnicSet) + + var routeInfo RouteInfo + if err := c.createResource(&input, &routeInfo); err != nil { + return nil, err + } + + return c.success(&routeInfo) +} + +type GetRouteInput struct { + // Name of the Route to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *RoutesClient) GetRoute(input *GetRouteInput) (*RouteInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var routeInfo RouteInfo + if err := c.getResource(input.Name, &routeInfo); err != nil { + return nil, err + } + return c.success(&routeInfo) +} + +type UpdateRouteInput struct { + // Specify 0,1, or 2 as the route's administrative distance. + // If you do not specify a value, the default value is 0. + // The same prefix can be used in multiple routes. In this case, packets are routed over all the matching + // routes with the lowest administrative distance. + // In the case multiple routes with the same lowest administrative distance match, + // routing occurs over all these routes using ECMP. + // Optional + AdminDistance int `json:"adminDistance"` + // Description of the route + // Optional + Description string `json:"description"` + // The IPv4 address prefix in CIDR format, of the external network (external to the vNIC set) + // from which you want to route traffic + // Required + IPAddressPrefix string `json:"ipAddressPrefix"` + // Name of the route. + // Names can only contain alphanumeric, underscore, dash, and period characters. Case-sensitive + // Required + Name string `json:"name"` + // Name of the virtual NIC set to route matching packets to. + // Routed flows are load-balanced among all the virtual NICs in the virtual NIC set + // Required + NextHopVnicSet string `json:"nextHopVnicSet"` + // Slice of tags to be associated with the route + // Optional + Tags []string `json:"tags"` +} + +func (c *RoutesClient) UpdateRoute(input *UpdateRouteInput) (*RouteInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.NextHopVnicSet = c.getQualifiedName(input.NextHopVnicSet) + + var routeInfo RouteInfo + if err := c.updateResource(input.Name, &input, &routeInfo); err != nil { + return nil, err + } + + return c.success(&routeInfo) +} + +type DeleteRouteInput struct { + // Name of the Route to delete. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *RoutesClient) DeleteRoute(input *DeleteRouteInput) error { + return c.deleteResource(input.Name) +} + +func (c *RoutesClient) success(info *RouteInfo) (*RouteInfo, error) { + c.unqualify(&info.Name) + c.unqualify(&info.NextHopVnicSet) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/sec_rules.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/sec_rules.go new file mode 100644 index 000000000..b45df047d --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/sec_rules.go @@ -0,0 +1,193 @@ +package compute + +// SecRulesClient is a client for the Sec Rules functions of the Compute API. +type SecRulesClient struct { + ResourceClient +} + +// SecRules obtains a SecRulesClient which can be used to access to the +// Sec Rules functions of the Compute API +func (c *ComputeClient) SecRules() *SecRulesClient { + return &SecRulesClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "security ip list", + ContainerPath: "/secrule/", + ResourceRootPath: "/secrule", + }} +} + +// SecRuleInfo describes an existing sec rule. +type SecRuleInfo struct { + // Set this parameter to PERMIT. + Action string `json:"action"` + // The name of the security application + Application string `json:"application"` + // A description of the sec rule + Description string `json:"description"` + // Indicates whether the security rule is enabled + Disabled bool `json:"disabled"` + // The name of the destination security list or security IP list. + DestinationList string `json:"dst_list"` + // The name of the sec rule + Name string `json:"name"` + // The name of the source security list or security IP list. + SourceList string `json:"src_list"` + // Uniform Resource Identifier for the sec rule + URI string `json:"uri"` +} + +// CreateSecRuleInput defines a sec rule to be created. +type CreateSecRuleInput struct { + // Set this parameter to PERMIT. + // Required + Action string `json:"action"` + + // The name of the security application for user-defined or predefined security applications. + // Required + Application string `json:"application"` + + // Description of the IP Network + // Optional + Description string `json:"description"` + + // Indicates whether the sec rule is enabled (set to false) or disabled (true). + // The default setting is false. + // Optional + Disabled bool `json:"disabled"` + + // The name of the destination security list or security IP list. + // + // You must use the prefix seclist: or seciplist: to identify the list type. + // + // You can specify a security IP list as the destination in a secrule, + // provided src_list is a security list that has DENY as its outbound policy. + // + // You cannot specify any of the security IP lists in the /oracle/public container + // as a destination in a secrule. + // Required + DestinationList string `json:"dst_list"` + + // The name of the Sec Rule to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // The name of the source security list or security IP list. + // + // You must use the prefix seclist: or seciplist: to identify the list type. + // + // Required + SourceList string `json:"src_list"` +} + +// CreateSecRule creates a new sec rule. +func (c *SecRulesClient) CreateSecRule(createInput *CreateSecRuleInput) (*SecRuleInfo, error) { + createInput.Name = c.getQualifiedName(createInput.Name) + createInput.SourceList = c.getQualifiedListName(createInput.SourceList) + createInput.DestinationList = c.getQualifiedListName(createInput.DestinationList) + createInput.Application = c.getQualifiedName(createInput.Application) + + var ruleInfo SecRuleInfo + if err := c.createResource(createInput, &ruleInfo); err != nil { + return nil, err + } + + return c.success(&ruleInfo) +} + +// GetSecRuleInput describes the Sec Rule to get +type GetSecRuleInput struct { + // The name of the Sec Rule to query for + // Required + Name string `json:"name"` +} + +// GetSecRule retrieves the sec rule with the given name. +func (c *SecRulesClient) GetSecRule(getInput *GetSecRuleInput) (*SecRuleInfo, error) { + var ruleInfo SecRuleInfo + if err := c.getResource(getInput.Name, &ruleInfo); err != nil { + return nil, err + } + + return c.success(&ruleInfo) +} + +// UpdateSecRuleInput describes a secruity rule to update +type UpdateSecRuleInput struct { + // Set this parameter to PERMIT. + // Required + Action string `json:"action"` + + // The name of the security application for user-defined or predefined security applications. + // Required + Application string `json:"application"` + + // Description of the IP Network + // Optional + Description string `json:"description"` + + // Indicates whether the sec rule is enabled (set to false) or disabled (true). + // The default setting is false. + // Optional + Disabled bool `json:"disabled"` + + // The name of the destination security list or security IP list. + // + // You must use the prefix seclist: or seciplist: to identify the list type. + // + // You can specify a security IP list as the destination in a secrule, + // provided src_list is a security list that has DENY as its outbound policy. + // + // You cannot specify any of the security IP lists in the /oracle/public container + // as a destination in a secrule. + // Required + DestinationList string `json:"dst_list"` + + // The name of the Sec Rule to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // The name of the source security list or security IP list. + // + // You must use the prefix seclist: or seciplist: to identify the list type. + // + // Required + SourceList string `json:"src_list"` +} + +// UpdateSecRule modifies the properties of the sec rule with the given name. +func (c *SecRulesClient) UpdateSecRule(updateInput *UpdateSecRuleInput) (*SecRuleInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + updateInput.SourceList = c.getQualifiedListName(updateInput.SourceList) + updateInput.DestinationList = c.getQualifiedListName(updateInput.DestinationList) + updateInput.Application = c.getQualifiedName(updateInput.Application) + + var ruleInfo SecRuleInfo + if err := c.updateResource(updateInput.Name, updateInput, &ruleInfo); err != nil { + return nil, err + } + + return c.success(&ruleInfo) +} + +// DeleteSecRuleInput describes the sec rule to delete +type DeleteSecRuleInput struct { + // The name of the Sec Rule to delete. + // Required + Name string `json:"name"` +} + +// DeleteSecRule deletes the sec rule with the given name. +func (c *SecRulesClient) DeleteSecRule(deleteInput *DeleteSecRuleInput) error { + return c.deleteResource(deleteInput.Name) +} + +func (c *SecRulesClient) success(ruleInfo *SecRuleInfo) (*SecRuleInfo, error) { + ruleInfo.Name = c.getUnqualifiedName(ruleInfo.Name) + ruleInfo.SourceList = c.unqualifyListName(ruleInfo.SourceList) + ruleInfo.DestinationList = c.unqualifyListName(ruleInfo.DestinationList) + ruleInfo.Application = c.getUnqualifiedName(ruleInfo.Application) + return ruleInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_applications.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_applications.go new file mode 100644 index 000000000..c473ecb83 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_applications.go @@ -0,0 +1,150 @@ +package compute + +// SecurityApplicationsClient is a client for the Security Application functions of the Compute API. +type SecurityApplicationsClient struct { + ResourceClient +} + +// SecurityApplications obtains a SecurityApplicationsClient which can be used to access to the +// Security Application functions of the Compute API +func (c *ComputeClient) SecurityApplications() *SecurityApplicationsClient { + return &SecurityApplicationsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "security application", + ContainerPath: "/secapplication/", + ResourceRootPath: "/secapplication", + }} +} + +// SecurityApplicationInfo describes an existing security application. +type SecurityApplicationInfo struct { + // A description of the security application. + Description string `json:"description"` + // The TCP or UDP destination port number. This can be a port range, such as 5900-5999 for TCP. + DPort string `json:"dport"` + // The ICMP code. + ICMPCode SecurityApplicationICMPCode `json:"icmpcode"` + // The ICMP type. + ICMPType SecurityApplicationICMPType `json:"icmptype"` + // The three-part name of the Security Application (/Compute-identity_domain/user/object). + Name string `json:"name"` + // The protocol to use. + Protocol SecurityApplicationProtocol `json:"protocol"` + // The Uniform Resource Identifier + URI string `json:"uri"` +} + +type SecurityApplicationProtocol string + +const ( + All SecurityApplicationProtocol = "all" + AH SecurityApplicationProtocol = "ah" + ESP SecurityApplicationProtocol = "esp" + ICMP SecurityApplicationProtocol = "icmp" + ICMPV6 SecurityApplicationProtocol = "icmpv6" + IGMP SecurityApplicationProtocol = "igmp" + IPIP SecurityApplicationProtocol = "ipip" + GRE SecurityApplicationProtocol = "gre" + MPLSIP SecurityApplicationProtocol = "mplsip" + OSPF SecurityApplicationProtocol = "ospf" + PIM SecurityApplicationProtocol = "pim" + RDP SecurityApplicationProtocol = "rdp" + SCTP SecurityApplicationProtocol = "sctp" + TCP SecurityApplicationProtocol = "tcp" + UDP SecurityApplicationProtocol = "udp" +) + +type SecurityApplicationICMPCode string + +const ( + Admin SecurityApplicationICMPCode = "admin" + Df SecurityApplicationICMPCode = "df" + Host SecurityApplicationICMPCode = "host" + Network SecurityApplicationICMPCode = "network" + Port SecurityApplicationICMPCode = "port" + Protocol SecurityApplicationICMPCode = "protocol" +) + +type SecurityApplicationICMPType string + +const ( + Echo SecurityApplicationICMPType = "echo" + Reply SecurityApplicationICMPType = "reply" + TTL SecurityApplicationICMPType = "ttl" + TraceRoute SecurityApplicationICMPType = "traceroute" + Unreachable SecurityApplicationICMPType = "unreachable" +) + +func (c *SecurityApplicationsClient) success(result *SecurityApplicationInfo) (*SecurityApplicationInfo, error) { + c.unqualify(&result.Name) + return result, nil +} + +// CreateSecurityApplicationInput describes the Security Application to create +type CreateSecurityApplicationInput struct { + // A description of the security application. + // Optional + Description string `json:"description"` + // The TCP or UDP destination port number. + // You can also specify a port range, such as 5900-5999 for TCP. + // This parameter isn't relevant to the icmp protocol. + // Required if the Protocol is TCP or UDP + DPort string `json:"dport"` + // The ICMP code. This parameter is relevant only if you specify ICMP as the protocol. + // If you specify icmp as the protocol and don't specify icmptype or icmpcode, then all ICMP packets are matched. + // Optional + ICMPCode SecurityApplicationICMPCode `json:"icmpcode,omitempty"` + // This parameter is relevant only if you specify ICMP as the protocol. + // If you specify icmp as the protocol and don't specify icmptype or icmpcode, then all ICMP packets are matched. + // Optional + ICMPType SecurityApplicationICMPType `json:"icmptype,omitempty"` + // The three-part name of the Security Application (/Compute-identity_domain/user/object). + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` + // The protocol to use. + // Required + Protocol SecurityApplicationProtocol `json:"protocol"` +} + +// CreateSecurityApplication creates a new security application. +func (c *SecurityApplicationsClient) CreateSecurityApplication(input *CreateSecurityApplicationInput) (*SecurityApplicationInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var appInfo SecurityApplicationInfo + if err := c.createResource(&input, &appInfo); err != nil { + return nil, err + } + + return c.success(&appInfo) +} + +// GetSecurityApplicationInput describes the Security Application to obtain +type GetSecurityApplicationInput struct { + // The three-part name of the Security Application (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// GetSecurityApplication retrieves the security application with the given name. +func (c *SecurityApplicationsClient) GetSecurityApplication(input *GetSecurityApplicationInput) (*SecurityApplicationInfo, error) { + var appInfo SecurityApplicationInfo + if err := c.getResource(input.Name, &appInfo); err != nil { + return nil, err + } + + return c.success(&appInfo) +} + +// DeleteSecurityApplicationInput describes the Security Application to delete +type DeleteSecurityApplicationInput struct { + // The three-part name of the Security Application (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// DeleteSecurityApplication deletes the security application with the given name. +func (c *SecurityApplicationsClient) DeleteSecurityApplication(input *DeleteSecurityApplicationInput) error { + return c.deleteResource(input.Name) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_associations.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_associations.go new file mode 100644 index 000000000..0b806f029 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_associations.go @@ -0,0 +1,95 @@ +package compute + +// SecurityAssociationsClient is a client for the Security Association functions of the Compute API. +type SecurityAssociationsClient struct { + ResourceClient +} + +// SecurityAssociations obtains a SecurityAssociationsClient which can be used to access to the +// Security Association functions of the Compute API +func (c *ComputeClient) SecurityAssociations() *SecurityAssociationsClient { + return &SecurityAssociationsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "security association", + ContainerPath: "/secassociation/", + ResourceRootPath: "/secassociation", + }} +} + +// SecurityAssociationInfo describes an existing security association. +type SecurityAssociationInfo struct { + // The three-part name of the Security Association (/Compute-identity_domain/user/object). + Name string `json:"name"` + // The name of the Security List that you want to associate with the instance. + SecList string `json:"seclist"` + // vCable of the instance that you want to associate with the security list. + VCable string `json:"vcable"` + // Uniform Resource Identifier + URI string `json:"uri"` +} + +// CreateSecurityAssociationInput defines a security association to be created. +type CreateSecurityAssociationInput struct { + // The three-part name of the Security Association (/Compute-identity_domain/user/object). + // If you don't specify a name for this object, then the name is generated automatically. + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Optional + Name string `json:"name"` + // The name of the Security list that you want to associate with the instance. + // Required + SecList string `json:"seclist"` + // The name of the vCable of the instance that you want to associate with the security list. + // Required + VCable string `json:"vcable"` +} + +// CreateSecurityAssociation creates a security association between the given VCable and security list. +func (c *SecurityAssociationsClient) CreateSecurityAssociation(createInput *CreateSecurityAssociationInput) (*SecurityAssociationInfo, error) { + if createInput.Name != "" { + createInput.Name = c.getQualifiedName(createInput.Name) + } + createInput.VCable = c.getQualifiedName(createInput.VCable) + createInput.SecList = c.getQualifiedName(createInput.SecList) + + var assocInfo SecurityAssociationInfo + if err := c.createResource(&createInput, &assocInfo); err != nil { + return nil, err + } + + return c.success(&assocInfo) +} + +// GetSecurityAssociationInput describes the security association to get +type GetSecurityAssociationInput struct { + // The three-part name of the Security Association (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// GetSecurityAssociation retrieves the security association with the given name. +func (c *SecurityAssociationsClient) GetSecurityAssociation(getInput *GetSecurityAssociationInput) (*SecurityAssociationInfo, error) { + var assocInfo SecurityAssociationInfo + if err := c.getResource(getInput.Name, &assocInfo); err != nil { + return nil, err + } + + return c.success(&assocInfo) +} + +// DeleteSecurityAssociationInput describes the security association to delete +type DeleteSecurityAssociationInput struct { + // The three-part name of the Security Association (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// DeleteSecurityAssociation deletes the security association with the given name. +func (c *SecurityAssociationsClient) DeleteSecurityAssociation(deleteInput *DeleteSecurityAssociationInput) error { + return c.deleteResource(deleteInput.Name) +} + +func (c *SecurityAssociationsClient) success(assocInfo *SecurityAssociationInfo) (*SecurityAssociationInfo, error) { + c.unqualify(&assocInfo.Name, &assocInfo.SecList, &assocInfo.VCable) + return assocInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_ip_lists.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_ip_lists.go new file mode 100644 index 000000000..28b313374 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_ip_lists.go @@ -0,0 +1,113 @@ +package compute + +// SecurityIPListsClient is a client for the Security IP List functions of the Compute API. +type SecurityIPListsClient struct { + ResourceClient +} + +// SecurityIPLists obtains a SecurityIPListsClient which can be used to access to the +// Security IP List functions of the Compute API +func (c *ComputeClient) SecurityIPLists() *SecurityIPListsClient { + return &SecurityIPListsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "security ip list", + ContainerPath: "/seciplist/", + ResourceRootPath: "/seciplist", + }} +} + +// SecurityIPListInfo describes an existing security IP list. +type SecurityIPListInfo struct { + // A description of the security IP list. + Description string `json:"description"` + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + // A comma-separated list of the subnets (in CIDR format) or IPv4 addresses for which you want to create this security IP list. + SecIPEntries []string `json:"secipentries"` + // Uniform Resource Identifier + URI string `json:"uri"` +} + +// CreateSecurityIPListInput defines a security IP list to be created. +type CreateSecurityIPListInput struct { + // A description of the security IP list. + // Optional + Description string `json:"description"` + // The three-part name of the object (/Compute-identity_domain/user/object). + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` + // A comma-separated list of the subnets (in CIDR format) or IPv4 addresses for which you want to create this security IP list. + // Required + SecIPEntries []string `json:"secipentries"` +} + +// CreateSecurityIPList creates a security IP list with the given name and entries. +func (c *SecurityIPListsClient) CreateSecurityIPList(createInput *CreateSecurityIPListInput) (*SecurityIPListInfo, error) { + createInput.Name = c.getQualifiedName(createInput.Name) + var listInfo SecurityIPListInfo + if err := c.createResource(createInput, &listInfo); err != nil { + return nil, err + } + + return c.success(&listInfo) +} + +// GetSecurityIPListInput describes the Security IP List to obtain +type GetSecurityIPListInput struct { + // The three-part name of the object (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// GetSecurityIPList gets the security IP list with the given name. +func (c *SecurityIPListsClient) GetSecurityIPList(getInput *GetSecurityIPListInput) (*SecurityIPListInfo, error) { + var listInfo SecurityIPListInfo + if err := c.getResource(getInput.Name, &listInfo); err != nil { + return nil, err + } + + return c.success(&listInfo) +} + +// UpdateSecurityIPListInput describes the security ip list to update +type UpdateSecurityIPListInput struct { + // A description of the security IP list. + // Optional + Description string `json:"description"` + // The three-part name of the object (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` + // A comma-separated list of the subnets (in CIDR format) or IPv4 addresses for which you want to create this security IP list. + // Required + SecIPEntries []string `json:"secipentries"` +} + +// UpdateSecurityIPList modifies the entries in the security IP list with the given name. +func (c *SecurityIPListsClient) UpdateSecurityIPList(updateInput *UpdateSecurityIPListInput) (*SecurityIPListInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + var listInfo SecurityIPListInfo + if err := c.updateResource(updateInput.Name, updateInput, &listInfo); err != nil { + return nil, err + } + + return c.success(&listInfo) +} + +// DeleteSecurityIPListInput describes the security ip list to delete. +type DeleteSecurityIPListInput struct { + // The three-part name of the object (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// DeleteSecurityIPList deletes the security IP list with the given name. +func (c *SecurityIPListsClient) DeleteSecurityIPList(deleteInput *DeleteSecurityIPListInput) error { + return c.deleteResource(deleteInput.Name) +} + +func (c *SecurityIPListsClient) success(listInfo *SecurityIPListInfo) (*SecurityIPListInfo, error) { + c.unqualify(&listInfo.Name) + return listInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go new file mode 100644 index 000000000..3c6d87364 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_lists.go @@ -0,0 +1,131 @@ +package compute + +// SecurityListsClient is a client for the Security List functions of the Compute API. +type SecurityListsClient struct { + ResourceClient +} + +// SecurityLists obtains a SecurityListsClient which can be used to access to the +// Security List functions of the Compute API +func (c *ComputeClient) SecurityLists() *SecurityListsClient { + return &SecurityListsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "security list", + ContainerPath: "/seclist/", + ResourceRootPath: "/seclist", + }} +} + +type SecurityListPolicy string + +const ( + SecurityListPolicyDeny SecurityListPolicy = "deny" + SecurityListPolicyReject SecurityListPolicy = "reject" + SecurityListPolicyPermit SecurityListPolicy = "permit" +) + +// SecurityListInfo describes an existing security list. +type SecurityListInfo struct { + // Shows the default account for your identity domain. + Account string `json:"account"` + // A description of the security list. + Description string `json:description` + // The three-part name of the security list (/Compute-identity_domain/user/object). + Name string `json:"name"` + // The policy for outbound traffic from the security list. + OutboundCIDRPolicy SecurityListPolicy `json:"outbound_cidr_policy"` + // The policy for inbound traffic to the security list + Policy SecurityListPolicy `json:"policy"` + // Uniform Resource Identifier + URI string `json:"uri"` +} + +// CreateSecurityListInput defines a security list to be created. +type CreateSecurityListInput struct { + // A description of the security list. + // Optional + Description string `json:"description"` + // The three-part name of the Security List (/Compute-identity_domain/user/object). + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` + // The policy for outbound traffic from the security list. + // Optional (defaults to `permit`) + OutboundCIDRPolicy SecurityListPolicy `json:"outbound_cidr_policy"` + // The policy for inbound traffic to the security list. + // Optional (defaults to `deny`) + Policy SecurityListPolicy `json:"policy"` +} + +// CreateSecurityList creates a new security list with the given name, policy and outbound CIDR policy. +func (c *SecurityListsClient) CreateSecurityList(createInput *CreateSecurityListInput) (*SecurityListInfo, error) { + createInput.Name = c.getQualifiedName(createInput.Name) + var listInfo SecurityListInfo + if err := c.createResource(createInput, &listInfo); err != nil { + return nil, err + } + + return c.success(&listInfo) +} + +// GetSecurityListInput describes the security list you want to get +type GetSecurityListInput struct { + // The three-part name of the Security List (/Compute-identity_domain/user/object). + // Required + Name string `json:name` +} + +// GetSecurityList retrieves the security list with the given name. +func (c *SecurityListsClient) GetSecurityList(getInput *GetSecurityListInput) (*SecurityListInfo, error) { + var listInfo SecurityListInfo + if err := c.getResource(getInput.Name, &listInfo); err != nil { + return nil, err + } + + return c.success(&listInfo) +} + +// UpdateSecurityListInput defines what to update in a security list +type UpdateSecurityListInput struct { + // A description of the security list. + // Optional + Description string `json:description` + // The three-part name of the Security List (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` + // The policy for outbound traffic from the security list. + // Optional (defaults to `permit`) + OutboundCIDRPolicy SecurityListPolicy `json:"outbound_cidr_policy"` + // The policy for inbound traffic to the security list. + // Optional (defaults to `deny`) + Policy SecurityListPolicy `json:"policy"` +} + +// UpdateSecurityList updates the policy and outbound CIDR pol +func (c *SecurityListsClient) UpdateSecurityList(updateInput *UpdateSecurityListInput) (*SecurityListInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + var listInfo SecurityListInfo + if err := c.updateResource(updateInput.Name, updateInput, &listInfo); err != nil { + return nil, err + } + + return c.success(&listInfo) +} + +// DeleteSecurityListInput describes the security list to destroy +type DeleteSecurityListInput struct { + // The three-part name of the Security List (/Compute-identity_domain/user/object). + // Required + Name string `json:name` +} + +// DeleteSecurityList deletes the security list with the given name. +func (c *SecurityListsClient) DeleteSecurityList(deleteInput *DeleteSecurityListInput) error { + return c.deleteResource(deleteInput.Name) +} + +func (c *SecurityListsClient) success(listInfo *SecurityListInfo) (*SecurityListInfo, error) { + c.unqualify(&listInfo.Name) + return listInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_protocols.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_protocols.go new file mode 100644 index 000000000..406be9cad --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_protocols.go @@ -0,0 +1,187 @@ +package compute + +const ( + SecurityProtocolDescription = "security protocol" + SecurityProtocolContainerPath = "/network/v1/secprotocol/" + SecurityProtocolResourcePath = "/network/v1/secprotocol" +) + +type SecurityProtocolsClient struct { + ResourceClient +} + +// SecurityProtocols() returns an SecurityProtocolsClient that can be used to access the +// necessary CRUD functions for Security Protocols. +func (c *ComputeClient) SecurityProtocols() *SecurityProtocolsClient { + return &SecurityProtocolsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: SecurityProtocolDescription, + ContainerPath: SecurityProtocolContainerPath, + ResourceRootPath: SecurityProtocolResourcePath, + }, + } +} + +// SecurityProtocolInfo contains the exported fields necessary to hold all the information about an +// Security Protocol +type SecurityProtocolInfo struct { + // List of port numbers or port range strings to match the packet's destination port. + DstPortSet []string `json:"dstPortSet"` + // Protocol used in the data portion of the IP datagram. + IPProtocol string `json:"ipProtocol"` + // List of port numbers or port range strings to match the packet's source port. + SrcPortSet []string `json:"srcPortSet"` + // The name of the Security Protocol + Name string `json:"name"` + // Description of the Security Protocol + Description string `json:"description"` + // Slice of tags associated with the Security Protocol + Tags []string `json:"tags"` + // Uniform Resource Identifier for the Security Protocol + Uri string `json:"uri"` +} + +type CreateSecurityProtocolInput struct { + // The name of the Security Protocol to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Description of the SecurityProtocol + // Optional + Description string `json:"description"` + + // Enter a list of port numbers or port range strings. + //Traffic is enabled by a security rule when a packet's destination port matches the + // ports specified here. + // For TCP, SCTP, and UDP, each port is a destination transport port, between 0 and 65535, + // inclusive. For ICMP, each port is an ICMP type, between 0 and 255, inclusive. + // If no destination ports are specified, all destination ports or ICMP types are allowed. + // Optional + DstPortSet []string `json:"dstPortSet"` + + // The protocol used in the data portion of the IP datagram. + // Specify one of the permitted values or enter a number in the range 0–254 to + // represent the protocol that you want to specify. See Assigned Internet Protocol Numbers. + // Permitted values are: tcp, udp, icmp, igmp, ipip, rdp, esp, ah, gre, icmpv6, ospf, pim, sctp, + // mplsip, all. + // Traffic is enabled by a security rule when the protocol in the packet matches the + // protocol specified here. If no protocol is specified, all protocols are allowed. + // Optional + IPProtocol string `json:"ipProtocol"` + + // Enter a list of port numbers or port range strings. + // Traffic is enabled by a security rule when a packet's source port matches the + // ports specified here. + // For TCP, SCTP, and UDP, each port is a source transport port, + // between 0 and 65535, inclusive. + // For ICMP, each port is an ICMP type, between 0 and 255, inclusive. + // If no source ports are specified, all source ports or ICMP types are allowed. + // Optional + SrcPortSet []string `json:"srcPortSet"` + + // String slice of tags to apply to the Security Protocol object + // Optional + Tags []string `json:"tags"` +} + +// Create a new Security Protocol from an SecurityProtocolsClient and an input struct. +// Returns a populated Info struct for the Security Protocol, and any errors +func (c *SecurityProtocolsClient) CreateSecurityProtocol(input *CreateSecurityProtocolInput) (*SecurityProtocolInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo SecurityProtocolInfo + if err := c.createResource(&input, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type GetSecurityProtocolInput struct { + // The name of the Security Protocol to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +// Returns a populated SecurityProtocolInfo struct from an input struct +func (c *SecurityProtocolsClient) GetSecurityProtocol(input *GetSecurityProtocolInput) (*SecurityProtocolInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var ipInfo SecurityProtocolInfo + if err := c.getResource(input.Name, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +// UpdateSecurityProtocolInput defines what to update in a security protocol +type UpdateSecurityProtocolInput struct { + // The name of the Security Protocol to create. Object names can only contain alphanumeric, + // underscore, dash, and period characters. Names are case-sensitive. + // Required + Name string `json:"name"` + + // Description of the SecurityProtocol + // Optional + Description string `json:"description"` + + // Enter a list of port numbers or port range strings. + //Traffic is enabled by a security rule when a packet's destination port matches the + // ports specified here. + // For TCP, SCTP, and UDP, each port is a destination transport port, between 0 and 65535, + // inclusive. For ICMP, each port is an ICMP type, between 0 and 255, inclusive. + // If no destination ports are specified, all destination ports or ICMP types are allowed. + DstPortSet []string `json:"dstPortSet"` + + // The protocol used in the data portion of the IP datagram. + // Specify one of the permitted values or enter a number in the range 0–254 to + // represent the protocol that you want to specify. See Assigned Internet Protocol Numbers. + // Permitted values are: tcp, udp, icmp, igmp, ipip, rdp, esp, ah, gre, icmpv6, ospf, pim, sctp, + // mplsip, all. + // Traffic is enabled by a security rule when the protocol in the packet matches the + // protocol specified here. If no protocol is specified, all protocols are allowed. + IPProtocol string `json:"ipProtocol"` + + // Enter a list of port numbers or port range strings. + // Traffic is enabled by a security rule when a packet's source port matches the + // ports specified here. + // For TCP, SCTP, and UDP, each port is a source transport port, + // between 0 and 65535, inclusive. + // For ICMP, each port is an ICMP type, between 0 and 255, inclusive. + // If no source ports are specified, all source ports or ICMP types are allowed. + SrcPortSet []string `json:"srcPortSet"` + + // String slice of tags to apply to the Security Protocol object + // Optional + Tags []string `json:"tags"` +} + +// UpdateSecurityProtocol update the security protocol +func (c *SecurityProtocolsClient) UpdateSecurityProtocol(updateInput *UpdateSecurityProtocolInput) (*SecurityProtocolInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + var ipInfo SecurityProtocolInfo + if err := c.updateResource(updateInput.Name, updateInput, &ipInfo); err != nil { + return nil, err + } + + return c.success(&ipInfo) +} + +type DeleteSecurityProtocolInput struct { + // The name of the Security Protocol to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *SecurityProtocolsClient) DeleteSecurityProtocol(input *DeleteSecurityProtocolInput) error { + return c.deleteResource(input.Name) +} + +// Unqualifies any qualified fields in the SecurityProtocolInfo struct +func (c *SecurityProtocolsClient) success(info *SecurityProtocolInfo) (*SecurityProtocolInfo, error) { + c.unqualify(&info.Name) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_rules.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_rules.go new file mode 100644 index 000000000..1773ea8b5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/security_rules.go @@ -0,0 +1,266 @@ +package compute + +const ( + SecurityRuleDescription = "security rules" + SecurityRuleContainerPath = "/network/v1/secrule/" + SecurityRuleResourcePath = "/network/v1/secrule" +) + +type SecurityRuleClient struct { + ResourceClient +} + +// SecurityRules() returns an SecurityRulesClient that can be used to access the +// necessary CRUD functions for Security Rules. +func (c *ComputeClient) SecurityRules() *SecurityRuleClient { + return &SecurityRuleClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: SecurityRuleDescription, + ContainerPath: SecurityRuleContainerPath, + ResourceRootPath: SecurityRuleResourcePath, + }, + } +} + +// SecurityRuleInfo contains the exported fields necessary to hold all the information about a +// Security Rule +type SecurityRuleInfo struct { + // Name of the ACL that contains this rule. + ACL string `json:"acl"` + // Description of the Security Rule + Description string `json:"description"` + // List of IP address prefix set names to match the packet's destination IP address. + DstIpAddressPrefixSets []string `json:"dstIpAddressPrefixSets"` + // Name of virtual NIC set containing the packet's destination virtual NIC. + DstVnicSet string `json:"dstVnicSet"` + // Allows the security rule to be disabled. + Enabled bool `json:"enabledFlag"` + // Direction of the flow; Can be "egress" or "ingress". + FlowDirection string `json:"FlowDirection"` + // The name of the Security Rule + Name string `json:"name"` + // List of security protocol names to match the packet's protocol and port. + SecProtocols []string `json:"secProtocols"` + // List of multipart names of IP address prefix set to match the packet's source IP address. + SrcIpAddressPrefixSets []string `json:"srcIpAddressPrefixSets"` + // Name of virtual NIC set containing the packet's source virtual NIC. + SrcVnicSet string `json:"srcVnicSet"` + // Slice of tags associated with the Security Rule + Tags []string `json:"tags"` + // Uniform Resource Identifier for the Security Rule + Uri string `json:"uri"` +} + +type CreateSecurityRuleInput struct { + //Select the name of the access control list (ACL) that you want to add this + // security rule to. Security rules are applied to vNIC sets by using ACLs. + // Optional + ACL string `json:"acl,omitempty"` + + // Description of the Security Rule + // Optional + Description string `json:"description"` + + // A list of IP address prefix sets to which you want to permit traffic. + // Only packets to IP addresses in the specified IP address prefix sets are permitted. + // When no destination IP address prefix sets are specified, traffic to any + // IP address is permitted. + // Optional + DstIpAddressPrefixSets []string `json:"dstIpAddressPrefixSets"` + + // The vNICset to which you want to permit traffic. Only packets to vNICs in the + // specified vNICset are permitted. When no destination vNICset is specified, traffic + // to any vNIC is permitted. + // Optional + DstVnicSet string `json:"dstVnicSet,omitempty"` + + // Allows the security rule to be enabled or disabled. This parameter is set to + // true by default. Specify false to disable the security rule. + // Optional + Enabled bool `json:"enabledFlag"` + + // Specify the direction of flow of traffic, which is relative to the instances, + // for this security rule. Allowed values are ingress or egress. + // An ingress packet is a packet received by a virtual NIC, for example from + // another virtual NIC or from the public Internet. + // An egress packet is a packet sent by a virtual NIC, for example to another + // virtual NIC or to the public Internet. + // Required + FlowDirection string `json:"flowDirection"` + + // The name of the Security Rule + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. + // Object names are case-sensitive. When you specify the object name, ensure that an object + // of the same type and with the same name doesn't already exist. + // If such an object already exists, another object of the same type and with the same name won't + // be created and the existing object won't be updated. + // Required + Name string `json:"name"` + + // A list of security protocols for which you want to permit traffic. Only packets that + // match the specified protocols and ports are permitted. When no security protocols are + // specified, traffic using any protocol over any port is permitted. + // Optional + SecProtocols []string `json:"secProtocols"` + + // A list of IP address prefix sets from which you want to permit traffic. Only packets + // from IP addresses in the specified IP address prefix sets are permitted. When no source + // IP address prefix sets are specified, traffic from any IP address is permitted. + // Optional + SrcIpAddressPrefixSets []string `json:"srcIpAddressPrefixSets"` + + // The vNICset from which you want to permit traffic. Only packets from vNICs in the + // specified vNICset are permitted. When no source vNICset is specified, traffic from any + // vNIC is permitted. + // Optional + SrcVnicSet string `json:"srcVnicSet,omitempty"` + + // Strings that you can use to tag the security rule. + // Optional + Tags []string `json:"tags"` +} + +// Create a new Security Rule from an SecurityRuleClient and an input struct. +// Returns a populated Info struct for the Security Rule, and any errors +func (c *SecurityRuleClient) CreateSecurityRule(input *CreateSecurityRuleInput) (*SecurityRuleInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.ACL = c.getQualifiedName(input.ACL) + input.SrcVnicSet = c.getQualifiedName(input.SrcVnicSet) + input.DstVnicSet = c.getQualifiedName(input.DstVnicSet) + input.SrcIpAddressPrefixSets = c.getQualifiedList(input.SrcIpAddressPrefixSets) + input.DstIpAddressPrefixSets = c.getQualifiedList(input.DstIpAddressPrefixSets) + input.SecProtocols = c.getQualifiedList(input.SecProtocols) + + var securityRuleInfo SecurityRuleInfo + if err := c.createResource(&input, &securityRuleInfo); err != nil { + return nil, err + } + + return c.success(&securityRuleInfo) +} + +type GetSecurityRuleInput struct { + // The name of the Security Rule to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +// Returns a populated SecurityRuleInfo struct from an input struct +func (c *SecurityRuleClient) GetSecurityRule(input *GetSecurityRuleInput) (*SecurityRuleInfo, error) { + input.Name = c.getQualifiedName(input.Name) + + var securityRuleInfo SecurityRuleInfo + if err := c.getResource(input.Name, &securityRuleInfo); err != nil { + return nil, err + } + + return c.success(&securityRuleInfo) +} + +// UpdateSecurityRuleInput describes a secruity rule to update +type UpdateSecurityRuleInput struct { + //Select the name of the access control list (ACL) that you want to add this + // security rule to. Security rules are applied to vNIC sets by using ACLs. + // Optional + ACL string `json:"acl,omitempty"` + + // Description of the Security Rule + // Optional + Description string `json:"description"` + + // A list of IP address prefix sets to which you want to permit traffic. + // Only packets to IP addresses in the specified IP address prefix sets are permitted. + // When no destination IP address prefix sets are specified, traffic to any + // IP address is permitted. + // Optional + DstIpAddressPrefixSets []string `json:"dstIpAddressPrefixSets"` + + // The vNICset to which you want to permit traffic. Only packets to vNICs in the + // specified vNICset are permitted. When no destination vNICset is specified, traffic + // to any vNIC is permitted. + // Optional + DstVnicSet string `json:"dstVnicSet,omitempty"` + + // Allows the security rule to be enabled or disabled. This parameter is set to + // true by default. Specify false to disable the security rule. + // Optional + Enabled bool `json:"enabledFlag"` + + // Specify the direction of flow of traffic, which is relative to the instances, + // for this security rule. Allowed values are ingress or egress. + // An ingress packet is a packet received by a virtual NIC, for example from + // another virtual NIC or from the public Internet. + // An egress packet is a packet sent by a virtual NIC, for example to another + // virtual NIC or to the public Internet. + // Required + FlowDirection string `json:"flowDirection"` + + // The name of the Security Rule + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. + // Object names are case-sensitive. When you specify the object name, ensure that an object + // of the same type and with the same name doesn't already exist. + // If such an object already exists, another object of the same type and with the same name won't + // be created and the existing object won't be updated. + // Required + Name string `json:"name"` + + // A list of security protocols for which you want to permit traffic. Only packets that + // match the specified protocols and ports are permitted. When no security protocols are + // specified, traffic using any protocol over any port is permitted. + // Optional + SecProtocols []string `json:"secProtocols"` + + // A list of IP address prefix sets from which you want to permit traffic. Only packets + // from IP addresses in the specified IP address prefix sets are permitted. When no source + // IP address prefix sets are specified, traffic from any IP address is permitted. + // Optional + SrcIpAddressPrefixSets []string `json:"srcIpAddressPrefixSets"` + + // The vNICset from which you want to permit traffic. Only packets from vNICs in the + // specified vNICset are permitted. When no source vNICset is specified, traffic from any + // vNIC is permitted. + // Optional + SrcVnicSet string `json:"srcVnicSet,omitempty"` + + // Strings that you can use to tag the security rule. + // Optional + Tags []string `json:"tags"` +} + +// UpdateSecRule modifies the properties of the sec rule with the given name. +func (c *SecurityRuleClient) UpdateSecurityRule(updateInput *UpdateSecurityRuleInput) (*SecurityRuleInfo, error) { + updateInput.Name = c.getQualifiedName(updateInput.Name) + updateInput.ACL = c.getQualifiedName(updateInput.ACL) + updateInput.SrcVnicSet = c.getQualifiedName(updateInput.SrcVnicSet) + updateInput.DstVnicSet = c.getQualifiedName(updateInput.DstVnicSet) + updateInput.SrcIpAddressPrefixSets = c.getQualifiedList(updateInput.SrcIpAddressPrefixSets) + updateInput.DstIpAddressPrefixSets = c.getQualifiedList(updateInput.DstIpAddressPrefixSets) + updateInput.SecProtocols = c.getQualifiedList(updateInput.SecProtocols) + + var securityRuleInfo SecurityRuleInfo + if err := c.updateResource(updateInput.Name, updateInput, &securityRuleInfo); err != nil { + return nil, err + } + + return c.success(&securityRuleInfo) +} + +type DeleteSecurityRuleInput struct { + // The name of the Security Rule to query for. Case-sensitive + // Required + Name string `json:"name"` +} + +func (c *SecurityRuleClient) DeleteSecurityRule(input *DeleteSecurityRuleInput) error { + return c.deleteResource(input.Name) +} + +// Unqualifies any qualified fields in the IPNetworkExchangeInfo struct +func (c *SecurityRuleClient) success(info *SecurityRuleInfo) (*SecurityRuleInfo, error) { + c.unqualify(&info.Name, &info.ACL, &info.SrcVnicSet, &info.DstVnicSet) + info.SrcIpAddressPrefixSets = c.getUnqualifiedList(info.SrcIpAddressPrefixSets) + info.DstIpAddressPrefixSets = c.getUnqualifiedList(info.DstIpAddressPrefixSets) + info.SecProtocols = c.getUnqualifiedList(info.SecProtocols) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go new file mode 100644 index 000000000..d2a9616e9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go @@ -0,0 +1,217 @@ +package compute + +import ( + "fmt" + "time" +) + +const WaitForSnapshotCompleteTimeout = time.Duration(600 * time.Second) + +// SnapshotsClient is a client for the Snapshot functions of the Compute API. +type SnapshotsClient struct { + ResourceClient +} + +// Snapshots obtains an SnapshotsClient which can be used to access to the +// Snapshot functions of the Compute API +func (c *ComputeClient) Snapshots() *SnapshotsClient { + return &SnapshotsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "Snapshot", + ContainerPath: "/snapshot/", + ResourceRootPath: "/snapshot", + }} +} + +type SnapshotState string + +const ( + SnapshotActive SnapshotState = "active" + SnapshotComplete SnapshotState = "complete" + SnapshotQueued SnapshotState = "queued" + SnapshotError SnapshotState = "error" +) + +type SnapshotDelay string + +const ( + SnapshotDelayShutdown SnapshotDelay = "shutdown" +) + +// SnapshotInfo describes an existing Snapshot. +type Snapshot struct { + // Shows the default account for your identity domain. + Account string `json:"account"` + // Timestamp when this request was created. + CreationTime string `json:"creation_time"` + // Snapshot of the instance is not taken immediately. + Delay SnapshotDelay `json:"delay"` + // A description of the reason this request entered "error" state. + ErrorReason string `json:"error_reason"` + // Name of the instance + Instance string `json:"instance"` + // Name of the machine image generated from the instance snapshot request. + MachineImage string `json:"machineimage"` + // Name of the instance snapshot request. + Name string `json:"name"` + // Not used + Quota string `json:"quota"` + // The state of the request. + State SnapshotState `json:"state"` + // Uniform Resource Identifier + URI string `json:"uri"` +} + +// CreateSnapshotInput defines an Snapshot to be created. +type CreateSnapshotInput struct { + // The name of the account that contains the credentials and access details of + // Oracle Storage Cloud Service. The machine image file is uploaded to the Oracle + // Storage Cloud Service account that you specify. + // Optional + Account string `json:"account,omitempty"` + // Use this option when you want to preserve the custom changes you have made + // to an instance before deleting the instance. The only permitted value is shutdown. + // Snapshot of the instance is not taken immediately. It creates a machine image which + // preserves the changes you have made to the instance, and then the instance is deleted. + // Note: This option has no effect if you shutdown the instance from inside it. Any pending + // snapshot request on that instance goes into error state. You must delete the instance + // (DELETE /instance/{name}). + // Optional + Delay SnapshotDelay `json:"delay,omitempty"` + // Name of the instance that you want to clone. + // Required + Instance string `json:"instance"` + // Specify the name of the machine image created by the snapshot request. + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. + // Object names are case-sensitive. + // If you don't specify a name for this object, then the name is generated automatically. + // Optional + MachineImage string `json:"machineimage,omitempty"` + // Time to wait for snapshot to be completed + Timeout time.Duration `json:"-"` +} + +// CreateSnapshot creates a new Snapshot +func (c *SnapshotsClient) CreateSnapshot(input *CreateSnapshotInput) (*Snapshot, error) { + input.Account = c.getQualifiedACMEName(input.Account) + input.Instance = c.getQualifiedName(input.Instance) + input.MachineImage = c.getQualifiedName(input.MachineImage) + + var snapshotInfo Snapshot + if err := c.createResource(&input, &snapshotInfo); err != nil { + return nil, err + } + + // Call wait for snapshot complete now, as creating the snashot is an eventually consistent operation + getInput := &GetSnapshotInput{ + Name: snapshotInfo.Name, + } + + if input.Timeout == 0 { + input.Timeout = WaitForSnapshotCompleteTimeout + } + + // Wait for snapshot to be complete and return the result + return c.WaitForSnapshotComplete(getInput, input.Timeout) +} + +// GetSnapshotInput describes the snapshot to get +type GetSnapshotInput struct { + // The name of the Snapshot + // Required + Name string `json:name` +} + +// GetSnapshot retrieves the Snapshot with the given name. +func (c *SnapshotsClient) GetSnapshot(getInput *GetSnapshotInput) (*Snapshot, error) { + getInput.Name = c.getQualifiedName(getInput.Name) + var snapshotInfo Snapshot + if err := c.getResource(getInput.Name, &snapshotInfo); err != nil { + return nil, err + } + + return c.success(&snapshotInfo) +} + +// DeleteSnapshotInput describes the snapshot to delete +type DeleteSnapshotInput struct { + // The name of the Snapshot + // Required + Snapshot string + // The name of the machine image + // Required + MachineImage string + // Time to wait for snapshot to be deleted + Timeout time.Duration +} + +// DeleteSnapshot deletes the Snapshot with the given name. +// A machine image gets created with the associated snapshot and needs to be deleted as well. +func (c *SnapshotsClient) DeleteSnapshot(machineImagesClient *MachineImagesClient, input *DeleteSnapshotInput) error { + // Wait for snapshot complete in case delay is active and the corresponding instance needs to be deleted first + getInput := &GetSnapshotInput{ + Name: input.Snapshot, + } + + if input.Timeout == 0 { + input.Timeout = WaitForSnapshotCompleteTimeout + } + + if _, err := c.WaitForSnapshotComplete(getInput, input.Timeout); err != nil { + return fmt.Errorf("Could not delete snapshot: %s", err) + } + + if err := c.deleteResource(input.Snapshot); err != nil { + return fmt.Errorf("Could not delete snapshot: %s", err) + } + + deleteMachineImageRequest := &DeleteMachineImageInput{ + Name: input.MachineImage, + } + if err := machineImagesClient.DeleteMachineImage(deleteMachineImageRequest); err != nil { + return fmt.Errorf("Could not delete machine image associated with snapshot: %s", err) + } + + return nil +} + +// WaitForSnapshotComplete waits for an snapshot to be completely initialized and available. +func (c *SnapshotsClient) WaitForSnapshotComplete(input *GetSnapshotInput, timeout time.Duration) (*Snapshot, error) { + var info *Snapshot + var getErr error + err := c.client.WaitFor("snapshot to be complete", timeout, func() (bool, error) { + info, getErr = c.GetSnapshot(input) + if getErr != nil { + return false, getErr + } + switch s := info.State; s { + case SnapshotError: + return false, fmt.Errorf("Error initializing snapshot: %s", info.ErrorReason) + case SnapshotComplete: + c.client.DebugLogString("Snapshot Complete") + return true, nil + case SnapshotQueued: + c.client.DebugLogString("Snapshot Queuing") + return false, nil + case SnapshotActive: + c.client.DebugLogString("Snapshot Active") + if info.Delay == SnapshotDelayShutdown { + return true, nil + } + return false, nil + default: + c.client.DebugLogString(fmt.Sprintf("Unknown snapshot state: %s, waiting", s)) + return false, nil + } + }) + return info, err +} + +func (c *SnapshotsClient) success(snapshotInfo *Snapshot) (*Snapshot, error) { + c.unqualify(&snapshotInfo.Account) + c.unqualify(&snapshotInfo.Instance) + c.unqualify(&snapshotInfo.MachineImage) + c.unqualify(&snapshotInfo.Name) + return snapshotInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go new file mode 100644 index 000000000..7e8be20ed --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/ssh_keys.go @@ -0,0 +1,124 @@ +package compute + +// SSHKeysClient is a client for the SSH key functions of the Compute API. +type SSHKeysClient struct { + ResourceClient +} + +// SSHKeys obtains an SSHKeysClient which can be used to access to the +// SSH key functions of the Compute API +func (c *ComputeClient) SSHKeys() *SSHKeysClient { + return &SSHKeysClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "SSH key", + ContainerPath: "/sshkey/", + ResourceRootPath: "/sshkey", + }} +} + +// SSHKeyInfo describes an existing SSH key. +type SSHKey struct { + // Indicates whether the key is enabled (true) or disabled. + Enabled bool `json:"enabled"` + // The SSH public key value. + Key string `json:"key"` + // The three-part name of the SSH Key (/Compute-identity_domain/user/object). + Name string `json:"name"` + // Unique Resource Identifier + URI string `json:"uri"` +} + +// CreateSSHKeyInput defines an SSH key to be created. +type CreateSSHKeyInput struct { + // The three-part name of the SSH Key (/Compute-identity_domain/user/object). + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods. Object names are case-sensitive. + // Required + Name string `json:"name"` + // The SSH public key value. + // Required + Key string `json:"key"` + // Indicates whether the key must be enabled (default) or disabled. Note that disabled keys cannot be associated with instances. + // To explicitly enable the key, specify true. To disable the key, specify false. + // Optional + Enabled bool `json:"enabled"` +} + +// CreateSSHKey creates a new SSH key with the given name, key and enabled flag. +func (c *SSHKeysClient) CreateSSHKey(createInput *CreateSSHKeyInput) (*SSHKey, error) { + var keyInfo SSHKey + // We have to update after create to get the full ssh key into opc + updateSSHKeyInput := UpdateSSHKeyInput{ + Name: createInput.Name, + Key: createInput.Key, + Enabled: createInput.Enabled, + } + + createInput.Name = c.getQualifiedName(createInput.Name) + if err := c.createResource(&createInput, &keyInfo); err != nil { + return nil, err + } + + _, err := c.UpdateSSHKey(&updateSSHKeyInput) + if err != nil { + return nil, err + } + + return c.success(&keyInfo) +} + +// GetSSHKeyInput describes the ssh key to get +type GetSSHKeyInput struct { + // The three-part name of the SSH Key (/Compute-identity_domain/user/object). + Name string `json:name` +} + +// GetSSHKey retrieves the SSH key with the given name. +func (c *SSHKeysClient) GetSSHKey(getInput *GetSSHKeyInput) (*SSHKey, error) { + var keyInfo SSHKey + if err := c.getResource(getInput.Name, &keyInfo); err != nil { + return nil, err + } + + return c.success(&keyInfo) +} + +// UpdateSSHKeyInput defines an SSH key to be updated +type UpdateSSHKeyInput struct { + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + // The SSH public key value. + // Required + Key string `json:"key"` + // Indicates whether the key must be enabled (default) or disabled. Note that disabled keys cannot be associated with instances. + // To explicitly enable the key, specify true. To disable the key, specify false. + // Optional + // TODO/NOTE: isn't this required? + Enabled bool `json:"enabled"` +} + +// UpdateSSHKey updates the key and enabled flag of the SSH key with the given name. +func (c *SSHKeysClient) UpdateSSHKey(updateInput *UpdateSSHKeyInput) (*SSHKey, error) { + var keyInfo SSHKey + updateInput.Name = c.getQualifiedName(updateInput.Name) + if err := c.updateResource(updateInput.Name, updateInput, &keyInfo); err != nil { + return nil, err + } + return c.success(&keyInfo) +} + +// DeleteKeyInput describes the ssh key to delete +type DeleteSSHKeyInput struct { + // The three-part name of the SSH Key (/Compute-identity_domain/user/object). + Name string `json:name` +} + +// DeleteSSHKey deletes the SSH key with the given name. +func (c *SSHKeysClient) DeleteSSHKey(deleteInput *DeleteSSHKeyInput) error { + return c.deleteResource(deleteInput.Name) +} + +func (c *SSHKeysClient) success(keyInfo *SSHKey) (*SSHKey, error) { + c.unqualify(&keyInfo.Name) + return keyInfo, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go new file mode 100644 index 000000000..51e18af47 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_attachments.go @@ -0,0 +1,178 @@ +package compute + +import ( + "time" + + "github.com/hashicorp/go-oracle-terraform/client" +) + +const WaitForVolumeAttachmentDeleteTimeout = time.Duration(30 * time.Second) +const WaitForVolumeAttachmentReadyTimeout = time.Duration(30 * time.Second) + +// StorageAttachmentsClient is a client for the Storage Attachment functions of the Compute API. +type StorageAttachmentsClient struct { + ResourceClient +} + +// StorageAttachments obtains a StorageAttachmentsClient which can be used to access to the +// Storage Attachment functions of the Compute API +func (c *ComputeClient) StorageAttachments() *StorageAttachmentsClient { + return &StorageAttachmentsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "storage volume attachment", + ContainerPath: "/storage/attachment/", + ResourceRootPath: "/storage/attachment", + }} +} + +type StorageAttachmentState string + +const ( + Attaching StorageAttachmentState = "attaching" + Attached StorageAttachmentState = "attached" + Detaching StorageAttachmentState = "detaching" + Unavailable StorageAttachmentState = "unavailable" + Unknown StorageAttachmentState = "unknown" +) + +// StorageAttachmentInfo describes an existing storage attachment. +type StorageAttachmentInfo struct { + // Name of this attachment, generated by the server. + Name string `json:"name"` + + // Index number for the volume. The allowed range is 1-10 + // An attachment with index 1 is exposed to the instance as /dev/xvdb, an attachment with index 2 is exposed as /dev/xvdc, and so on. + Index int `json:"index"` + + // Multipart name of the instance attached to the storage volume. + InstanceName string `json:"instance_name"` + + // Multipart name of the volume attached to the instance. + StorageVolumeName string `json:"storage_volume_name"` + + // The State of the Storage Attachment + State StorageAttachmentState `json:"state"` +} + +func (c *StorageAttachmentsClient) success(attachmentInfo *StorageAttachmentInfo) (*StorageAttachmentInfo, error) { + c.unqualify(&attachmentInfo.Name, &attachmentInfo.InstanceName, &attachmentInfo.StorageVolumeName) + return attachmentInfo, nil +} + +type CreateStorageAttachmentInput struct { + // Index number for the volume. The allowed range is 1-10 + // An attachment with index 1 is exposed to the instance as /dev/xvdb, an attachment with index 2 is exposed as /dev/xvdc, and so on. + // Required. + Index int `json:"index"` + + // Multipart name of the instance to which you want to attach the volume. + // Required. + InstanceName string `json:"instance_name"` + + // Multipart name of the volume that you want to attach. + // Required. + StorageVolumeName string `json:"storage_volume_name"` + + // Time to wait for storage volume attachment + Timeout time.Duration `json:"-"` +} + +// CreateStorageAttachment creates a storage attachment attaching the given volume to the given instance at the given index. +func (c *StorageAttachmentsClient) CreateStorageAttachment(input *CreateStorageAttachmentInput) (*StorageAttachmentInfo, error) { + input.InstanceName = c.getQualifiedName(input.InstanceName) + + var attachmentInfo *StorageAttachmentInfo + if err := c.createResource(&input, &attachmentInfo); err != nil { + return nil, err + } + + if input.Timeout == 0 { + input.Timeout = WaitForVolumeAttachmentReadyTimeout + } + + return c.waitForStorageAttachmentToFullyAttach(attachmentInfo.Name, input.Timeout) +} + +// DeleteStorageAttachmentInput represents the body of an API request to delete a Storage Attachment. +type DeleteStorageAttachmentInput struct { + // The three-part name of the Storage Attachment (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` + + // Time to wait for storage volume snapshot + Timeout time.Duration `json:"-"` +} + +// DeleteStorageAttachment deletes the storage attachment with the given name. +func (c *StorageAttachmentsClient) DeleteStorageAttachment(input *DeleteStorageAttachmentInput) error { + if err := c.deleteResource(input.Name); err != nil { + return err + } + + if input.Timeout == 0 { + input.Timeout = WaitForVolumeAttachmentDeleteTimeout + } + + return c.waitForStorageAttachmentToBeDeleted(input.Name, input.Timeout) +} + +// GetStorageAttachmentInput represents the body of an API request to obtain a Storage Attachment. +type GetStorageAttachmentInput struct { + // The three-part name of the Storage Attachment (/Compute-identity_domain/user/object). + // Required + Name string `json:"name"` +} + +// GetStorageAttachment retrieves the storage attachment with the given name. +func (c *StorageAttachmentsClient) GetStorageAttachment(input *GetStorageAttachmentInput) (*StorageAttachmentInfo, error) { + var attachmentInfo *StorageAttachmentInfo + if err := c.getResource(input.Name, &attachmentInfo); err != nil { + return nil, err + } + + return c.success(attachmentInfo) +} + +// waitForStorageAttachmentToFullyAttach waits for the storage attachment with the given name to be fully attached, or times out. +func (c *StorageAttachmentsClient) waitForStorageAttachmentToFullyAttach(name string, timeout time.Duration) (*StorageAttachmentInfo, error) { + var waitResult *StorageAttachmentInfo + + err := c.client.WaitFor("storage attachment to be attached", timeout, func() (bool, error) { + input := &GetStorageAttachmentInput{ + Name: name, + } + info, err := c.GetStorageAttachment(input) + if err != nil { + return false, err + } + + if info != nil { + if info.State == Attached { + waitResult = info + return true, nil + } + } + + return false, nil + }) + + return waitResult, err +} + +// waitForStorageAttachmentToBeDeleted waits for the storage attachment with the given name to be fully deleted, or times out. +func (c *StorageAttachmentsClient) waitForStorageAttachmentToBeDeleted(name string, timeout time.Duration) error { + return c.client.WaitFor("storage attachment to be deleted", timeout, func() (bool, error) { + input := &GetStorageAttachmentInput{ + Name: name, + } + _, err := c.GetStorageAttachment(input) + if err != nil { + if client.WasNotFoundError(err) { + return true, nil + } + return false, err + } + return false, nil + }) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_snapshots.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_snapshots.go new file mode 100644 index 000000000..aa7c4a7a2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volume_snapshots.go @@ -0,0 +1,251 @@ +package compute + +import ( + "fmt" + "strings" + "time" + + "github.com/hashicorp/go-oracle-terraform/client" +) + +const ( + StorageVolumeSnapshotDescription = "storage volume snapshot" + StorageVolumeSnapshotContainerPath = "/storage/snapshot/" + StorageVolumeSnapshotResourcePath = "/storage/snapshot" + + WaitForSnapshotCreateTimeout = time.Duration(2400 * time.Second) + WaitForSnapshotDeleteTimeout = time.Duration(1500 * time.Second) + + // Collocated Snapshot Property + SnapshotPropertyCollocated = "/oracle/private/storage/snapshot/collocated" +) + +// StorageVolumeSnapshotClient is a client for the Storage Volume Snapshot functions of the Compute API. +type StorageVolumeSnapshotClient struct { + ResourceClient +} + +func (c *ComputeClient) StorageVolumeSnapshots() *StorageVolumeSnapshotClient { + return &StorageVolumeSnapshotClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: StorageVolumeSnapshotDescription, + ContainerPath: StorageVolumeSnapshotContainerPath, + ResourceRootPath: StorageVolumeSnapshotResourcePath, + }, + } +} + +// StorageVolumeSnapshotInfo represents the information retrieved from the service about a storage volume snapshot +type StorageVolumeSnapshotInfo struct { + // Account to use for snapshots + Account string `json:"account"` + + // Description of the snapshot + Description string `json:"description"` + + // The name of the machine image that's used in the boot volume from which this snapshot is taken + MachineImageName string `json:"machineimage_name"` + + // Name of the snapshot + Name string `json:"name"` + + // String indicating whether the parent volume is bootable or not + ParentVolumeBootable string `json:"parent_volume_bootable"` + + // Platform the snapshot is compatible with + Platform string `json:"platform"` + + // String determining whether the snapshot is remote or collocated + Property string `json:"property"` + + // The size of the snapshot in GB + Size string `json:"size"` + + // The ID of the snapshot. Generated by the server + SnapshotID string `json:"snapshot_id"` + + // The timestamp of the storage snapshot + SnapshotTimestamp string `json:"snapshot_timestamp"` + + // Timestamp for when the operation started + StartTimestamp string `json:"start_timestamp"` + + // Status of the snapshot + Status string `json:"status"` + + // Status Detail of the storage snapshot + StatusDetail string `json:"status_detail"` + + // Indicates the time that the current view of the storage volume snapshot was generated. + StatusTimestamp string `json:"status_timestamp"` + + // Array of tags for the snapshot + Tags []string `json:"tags,omitempty"` + + // Uniform Resource Identifier + URI string `json:"uri"` + + // Name of the parent storage volume for the snapshot + Volume string `json:"volume"` +} + +// CreateStorageVolumeSnapshotInput represents the body of an API request to create a new storage volume snapshot +type CreateStorageVolumeSnapshotInput struct { + // Description of the snapshot + // Optional + Description string `json:"description,omitempty"` + + // Name of the snapshot + // Optional, will be generated if not specified + Name string `json:"name,omitempty"` + + // Whether or not the parent volume is bootable + // Optional + ParentVolumeBootable string `json:"parent_volume_bootable,omitempty"` + + // Whether collocated or remote + // Optional, will be remote if unspecified + Property string `json:"property,omitempty"` + + // Array of tags for the snapshot + // Optional + Tags []string `json:"tags,omitempty"` + + // Name of the volume to create the snapshot from + // Required + Volume string `json:"volume"` + + // Timeout to wait for snapshot to be completed. Will use default if unspecified + Timeout time.Duration `json:"-"` +} + +// CreateStorageVolumeSnapshot creates a snapshot based on the supplied information struct +func (c *StorageVolumeSnapshotClient) CreateStorageVolumeSnapshot(input *CreateStorageVolumeSnapshotInput) (*StorageVolumeSnapshotInfo, error) { + if input.Name != "" { + input.Name = c.getQualifiedName(input.Name) + } + input.Volume = c.getQualifiedName(input.Volume) + + var storageSnapshotInfo StorageVolumeSnapshotInfo + if err := c.createResource(&input, &storageSnapshotInfo); err != nil { + return nil, err + } + + if input.Timeout == 0 { + input.Timeout = WaitForSnapshotCreateTimeout + } + + // The name of the snapshot could have been generated. Use the response name as input + return c.waitForStorageSnapshotAvailable(storageSnapshotInfo.Name, input.Timeout) +} + +// GetStorageVolumeSnapshotInput represents the body of an API request to get information on a storage volume snapshot +type GetStorageVolumeSnapshotInput struct { + // Name of the snapshot + Name string `json:"name"` +} + +// GetStorageVolumeSnapshot makes an API request to populate information on a storage volume snapshot +func (c *StorageVolumeSnapshotClient) GetStorageVolumeSnapshot(input *GetStorageVolumeSnapshotInput) (*StorageVolumeSnapshotInfo, error) { + var storageSnapshot StorageVolumeSnapshotInfo + input.Name = c.getQualifiedName(input.Name) + if err := c.getResource(input.Name, &storageSnapshot); err != nil { + if client.WasNotFoundError(err) { + return nil, nil + } + + return nil, err + } + return c.success(&storageSnapshot) +} + +// DeleteStorageVolumeSnapshotInput represents the body of an API request to delete a storage volume snapshot +type DeleteStorageVolumeSnapshotInput struct { + // Name of the snapshot to delete + Name string `json:"name"` + + // Timeout to wait for deletion, will use default if unspecified + Timeout time.Duration `json:"-"` +} + +// DeleteStoragevolumeSnapshot makes an API request to delete a storage volume snapshot +func (c *StorageVolumeSnapshotClient) DeleteStorageVolumeSnapshot(input *DeleteStorageVolumeSnapshotInput) error { + input.Name = c.getQualifiedName(input.Name) + + if err := c.deleteResource(input.Name); err != nil { + return err + } + + if input.Timeout == 0 { + input.Timeout = WaitForSnapshotDeleteTimeout + } + + return c.waitForStorageSnapshotDeleted(input.Name, input.Timeout) +} + +func (c *StorageVolumeSnapshotClient) success(result *StorageVolumeSnapshotInfo) (*StorageVolumeSnapshotInfo, error) { + c.unqualify(&result.Name) + c.unqualify(&result.Volume) + + sizeInGigaBytes, err := sizeInGigaBytes(result.Size) + if err != nil { + return nil, err + } + result.Size = sizeInGigaBytes + + return result, nil +} + +// Waits for a storage snapshot to become available +func (c *StorageVolumeSnapshotClient) waitForStorageSnapshotAvailable(name string, timeout time.Duration) (*StorageVolumeSnapshotInfo, error) { + var result *StorageVolumeSnapshotInfo + + err := c.client.WaitFor( + fmt.Sprintf("storage volume snapshot %s to become available", c.getQualifiedName(name)), + timeout, + func() (bool, error) { + req := &GetStorageVolumeSnapshotInput{ + Name: name, + } + res, err := c.GetStorageVolumeSnapshot(req) + if err != nil { + return false, err + } + + if res != nil { + result = res + if strings.ToLower(result.Status) == "completed" { + return true, nil + } else if strings.ToLower(result.Status) == "error" { + return false, fmt.Errorf("Snapshot '%s' failed to create successfully. Status: %s Status Detail: %s", result.Name, result.Status, result.StatusDetail) + } + } + + return false, nil + }) + + return result, err +} + +// Waits for a storage snapshot to be deleted +func (c *StorageVolumeSnapshotClient) waitForStorageSnapshotDeleted(name string, timeout time.Duration) error { + return c.client.WaitFor( + fmt.Sprintf("storage volume snapshot %s to be deleted", c.getQualifiedName(name)), + timeout, + func() (bool, error) { + req := &GetStorageVolumeSnapshotInput{ + Name: name, + } + res, err := c.GetStorageVolumeSnapshot(req) + if res == nil { + return true, nil + } + + if err != nil { + return false, err + } + + return res == nil, nil + }) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volumes.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volumes.go new file mode 100644 index 000000000..c479638de --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/storage_volumes.go @@ -0,0 +1,389 @@ +package compute + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/go-oracle-terraform/client" +) + +const WaitForVolumeReadyTimeout = time.Duration(600 * time.Second) +const WaitForVolumeDeleteTimeout = time.Duration(600 * time.Second) + +// StorageVolumeClient is a client for the Storage Volume functions of the Compute API. +type StorageVolumeClient struct { + ResourceClient +} + +// StorageVolumes obtains a StorageVolumeClient which can be used to access to the +// Storage Volume functions of the Compute API +func (c *ComputeClient) StorageVolumes() *StorageVolumeClient { + return &StorageVolumeClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "storage volume", + ContainerPath: "/storage/volume/", + ResourceRootPath: "/storage/volume", + }} + +} + +type StorageVolumeKind string + +const ( + StorageVolumeKindDefault StorageVolumeKind = "/oracle/public/storage/default" + StorageVolumeKindLatency StorageVolumeKind = "/oracle/public/storage/latency" + StorageVolumeKindSSD StorageVolumeKind = "/oracle/public/storage/ssd/gpl" +) + +// StorageVolumeInfo represents information retrieved from the service about a Storage Volume. +type StorageVolumeInfo struct { + // Shows the default account for your identity domain. + Account string `json:"account,omitempty"` + + // true indicates that the storage volume can also be used as a boot disk for an instance. + // If you set the value to true, then you must specify values for the `ImageList` and `ImageListEntry` fields. + Bootable bool `json:"bootable,omitempty"` + + // The description of the storage volume. + Description string `json:"description,omitempty"` + + // The hypervisor that this volume is compatible with. + Hypervisor string `json:"hypervisor,omitempty"` + + // Name of machine image to extract onto this volume when created. This information is provided only for bootable storage volumes. + ImageList string `json:"imagelist,omitempty"` + + // Specific imagelist entry version to extract. + ImageListEntry int `json:"imagelist_entry,omitempty"` + + // Three-part name of the machine image. This information is available if the volume is a bootable storage volume. + MachineImage string `json:"machineimage_name,omitempty"` + + // All volumes are managed volumes. Default value is true. + Managed bool `json:"managed,omitempty"` + + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + + // The OS platform this volume is compatible with. + Platform string `json:"platform,omitempty"` + + // The storage-pool property: /oracle/public/storage/latency or /oracle/public/storage/default. + Properties []string `json:"properties,omitempty"` + + // Boolean field indicating whether this volume can be attached as readonly. If set to False the volume will be attached as read-write. + ReadOnly bool `json:"readonly,omitempty"` + + // The size of this storage volume in GB. + Size string `json:"size"` + + // Name of the parent snapshot from which the storage volume is restored or cloned. + Snapshot string `json:"snapshot,omitempty"` + + // Account of the parent snapshot from which the storage volume is restored. + SnapshotAccount string `json:"snapshot_account,omitempty"` + + // Id of the parent snapshot from which the storage volume is restored or cloned. + SnapshotID string `json:"snapshot_id,omitempty"` + + // TODO: this should become a Constant, if/when we have the values + // The current state of the storage volume. + Status string `json:"status,omitempty"` + + // Details about the latest state of the storage volume. + StatusDetail string `json:"status_detail,omitempty"` + + // It indicates the time that the current view of the storage volume was generated. + StatusTimestamp string `json:"status_timestamp,omitempty"` + + // The storage pool from which this volume is allocated. + StoragePool string `json:"storage_pool,omitempty"` + + // Comma-separated strings that tag the storage volume. + Tags []string `json:"tags,omitempty"` + + // Uniform Resource Identifier + URI string `json:"uri,omitempty"` +} + +func (c *StorageVolumeClient) getStorageVolumePath(name string) string { + return c.getObjectPath("/storage/volume", name) +} + +// CreateStorageVolumeInput represents the body of an API request to create a new Storage Volume. +type CreateStorageVolumeInput struct { + // true indicates that the storage volume can also be used as a boot disk for an instance. + // If you set the value to true, then you must specify values for the `ImageList` and `ImageListEntry` fields. + Bootable bool `json:"bootable,omitempty"` + + // The description of the storage volume. + Description string `json:"description,omitempty"` + + // Name of machine image to extract onto this volume when created. This information is provided only for bootable storage volumes. + ImageList string `json:"imagelist,omitempty"` + + // Specific imagelist entry version to extract. + ImageListEntry int `json:"imagelist_entry,omitempty"` + + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + + // The storage-pool property: /oracle/public/storage/latency or /oracle/public/storage/default. + Properties []string `json:"properties,omitempty"` + + // The size of this storage volume in GB. + Size string `json:"size"` + + // Name of the parent snapshot from which the storage volume is restored or cloned. + Snapshot string `json:"snapshot,omitempty"` + + // Account of the parent snapshot from which the storage volume is restored. + SnapshotAccount string `json:"snapshot_account,omitempty"` + + // Id of the parent snapshot from which the storage volume is restored or cloned. + SnapshotID string `json:"snapshot_id,omitempty"` + + // Comma-separated strings that tag the storage volume. + Tags []string `json:"tags,omitempty"` + + // Timeout to wait for storage volume creation. + Timeout time.Duration `json:"-"` +} + +// CreateStorageVolume uses the given CreateStorageVolumeInput to create a new Storage Volume. +func (c *StorageVolumeClient) CreateStorageVolume(input *CreateStorageVolumeInput) (*StorageVolumeInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.ImageList = c.getQualifiedName(input.ImageList) + + sizeInBytes, err := sizeInBytes(input.Size) + if err != nil { + return nil, err + } + input.Size = sizeInBytes + + var storageInfo StorageVolumeInfo + if err := c.createResource(&input, &storageInfo); err != nil { + return nil, err + } + + // Should never be nil, as we set this in the provider; but protect against it anyways. + if input.Timeout == 0 { + input.Timeout = WaitForVolumeReadyTimeout + } + + volume, err := c.waitForStorageVolumeToBecomeAvailable(input.Name, input.Timeout) + if err != nil { + if volume != nil { + deleteInput := &DeleteStorageVolumeInput{ + Name: volume.Name, + } + + if err := c.DeleteStorageVolume(deleteInput); err != nil { + return nil, err + } + } + } + return volume, err +} + +// DeleteStorageVolumeInput represents the body of an API request to delete a Storage Volume. +type DeleteStorageVolumeInput struct { + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + + // Timeout to wait for storage volume deletion + Timeout time.Duration `json:"-"` +} + +// DeleteStorageVolume deletes the specified storage volume. +func (c *StorageVolumeClient) DeleteStorageVolume(input *DeleteStorageVolumeInput) error { + if err := c.deleteResource(input.Name); err != nil { + return err + } + + // Should never be nil, but protect against it anyways + if input.Timeout == 0 { + input.Timeout = WaitForVolumeDeleteTimeout + } + + return c.waitForStorageVolumeToBeDeleted(input.Name, input.Timeout) +} + +// GetStorageVolumeInput represents the body of an API request to obtain a Storage Volume. +type GetStorageVolumeInput struct { + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` +} + +func (c *StorageVolumeClient) success(result *StorageVolumeInfo) (*StorageVolumeInfo, error) { + c.unqualify(&result.ImageList) + c.unqualify(&result.Name) + c.unqualify(&result.Snapshot) + + sizeInMegaBytes, err := sizeInGigaBytes(result.Size) + if err != nil { + return nil, err + } + result.Size = sizeInMegaBytes + + return result, nil +} + +// GetStorageVolume gets Storage Volume information for the specified storage volume. +func (c *StorageVolumeClient) GetStorageVolume(input *GetStorageVolumeInput) (*StorageVolumeInfo, error) { + var storageVolume StorageVolumeInfo + if err := c.getResource(input.Name, &storageVolume); err != nil { + if client.WasNotFoundError(err) { + return nil, nil + } + + return nil, err + } + + return c.success(&storageVolume) +} + +// UpdateStorageVolumeInput represents the body of an API request to update a Storage Volume. +type UpdateStorageVolumeInput struct { + // The description of the storage volume. + Description string `json:"description,omitempty"` + + // Name of machine image to extract onto this volume when created. This information is provided only for bootable storage volumes. + ImageList string `json:"imagelist,omitempty"` + + // Specific imagelist entry version to extract. + ImageListEntry int `json:"imagelist_entry,omitempty"` + + // The three-part name of the object (/Compute-identity_domain/user/object). + Name string `json:"name"` + + // The storage-pool property: /oracle/public/storage/latency or /oracle/public/storage/default. + Properties []string `json:"properties,omitempty"` + + // The size of this storage volume in GB. + Size string `json:"size"` + + // Name of the parent snapshot from which the storage volume is restored or cloned. + Snapshot string `json:"snapshot,omitempty"` + + // Account of the parent snapshot from which the storage volume is restored. + SnapshotAccount string `json:"snapshot_account,omitempty"` + + // Id of the parent snapshot from which the storage volume is restored or cloned. + SnapshotID string `json:"snapshot_id,omitempty"` + + // Comma-separated strings that tag the storage volume. + Tags []string `json:"tags,omitempty"` + + // Time to wait for storage volume ready + Timeout time.Duration `json:"-"` +} + +// UpdateStorageVolume updates the specified storage volume, optionally modifying size, description and tags. +func (c *StorageVolumeClient) UpdateStorageVolume(input *UpdateStorageVolumeInput) (*StorageVolumeInfo, error) { + input.Name = c.getQualifiedName(input.Name) + input.ImageList = c.getQualifiedName(input.ImageList) + + sizeInBytes, err := sizeInBytes(input.Size) + if err != nil { + return nil, err + } + input.Size = sizeInBytes + + path := c.getStorageVolumePath(input.Name) + _, err = c.executeRequest("PUT", path, input) + if err != nil { + return nil, err + } + + if input.Timeout == 0 { + input.Timeout = WaitForVolumeReadyTimeout + } + + volumeInfo, err := c.waitForStorageVolumeToBecomeAvailable(input.Name, input.Timeout) + if err != nil { + return nil, err + } + + return volumeInfo, nil +} + +// waitForStorageVolumeToBecomeAvailable waits until a new Storage Volume is available (i.e. has finished initialising or updating). +func (c *StorageVolumeClient) waitForStorageVolumeToBecomeAvailable(name string, timeout time.Duration) (*StorageVolumeInfo, error) { + var waitResult *StorageVolumeInfo + + err := c.client.WaitFor( + fmt.Sprintf("storage volume %s to become available", c.getQualifiedName(name)), + timeout, + func() (bool, error) { + getRequest := &GetStorageVolumeInput{ + Name: name, + } + result, err := c.GetStorageVolume(getRequest) + + if err != nil { + return false, err + } + + if result != nil { + waitResult = result + if strings.ToLower(waitResult.Status) == "online" { + return true, nil + } + if strings.ToLower(waitResult.Status) == "error" { + return false, fmt.Errorf("Error Creating Storage Volume: %s", waitResult.StatusDetail) + } + } + + return false, nil + }) + + return waitResult, err +} + +// waitForStorageVolumeToBeDeleted waits until the specified storage volume has been deleted. +func (c *StorageVolumeClient) waitForStorageVolumeToBeDeleted(name string, timeout time.Duration) error { + return c.client.WaitFor( + fmt.Sprintf("storage volume %s to be deleted", c.getQualifiedName(name)), + timeout, + func() (bool, error) { + getRequest := &GetStorageVolumeInput{ + Name: name, + } + result, err := c.GetStorageVolume(getRequest) + if result == nil { + return true, nil + } + + if err != nil { + return false, err + } + + return result == nil, nil + }) +} + +func sizeInGigaBytes(input string) (string, error) { + sizeInBytes, err := strconv.Atoi(input) + if err != nil { + return "", err + } + sizeInKB := sizeInBytes / 1024 + sizeInMB := sizeInKB / 1024 + sizeInGb := sizeInMB / 1024 + return strconv.Itoa(sizeInGb), nil +} + +func sizeInBytes(input string) (string, error) { + sizeInGB, err := strconv.Atoi(input) + if err != nil { + return "", err + } + sizeInMB := sizeInGB * 1024 + sizeInKB := sizeInMB * 1024 + sizeInBytes := sizeInKB * 1024 + return strconv.Itoa(sizeInBytes), nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/test_utils.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/test_utils.go new file mode 100644 index 000000000..5667e097e --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/test_utils.go @@ -0,0 +1,119 @@ +package compute + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + "net/http/httptest" + "net/url" + "os" + "testing" + "time" + + "github.com/hashicorp/go-oracle-terraform/opc" +) + +const ( + _ClientTestUser = "test-user" + _ClientTestDomain = "test-domain" +) + +func newAuthenticatingServer(handler func(w http.ResponseWriter, r *http.Request)) *httptest.Server { + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if os.Getenv("ORACLE_LOG") != "" { + log.Printf("[DEBUG] Received request: %s, %s\n", r.Method, r.URL) + } + + if r.URL.Path == "/authenticate/" { + http.SetCookie(w, &http.Cookie{Name: "testAuthCookie", Value: "cookie value"}) + // w.WriteHeader(200) + } else { + handler(w, r) + } + })) +} + +func getTestClient(c *opc.Config) (*ComputeClient, error) { + // Build up config with default values if omitted + if c.APIEndpoint == nil { + if os.Getenv("OPC_ENDPOINT") == "" { + panic("OPC_ENDPOINT not set in environment") + } + endpoint, err := url.Parse(os.Getenv("OPC_ENDPOINT")) + if err != nil { + return nil, err + } + c.APIEndpoint = endpoint + } + + if c.IdentityDomain == nil { + domain := os.Getenv("OPC_IDENTITY_DOMAIN") + c.IdentityDomain = &domain + } + + if c.Username == nil { + username := os.Getenv("OPC_USERNAME") + c.Username = &username + } + + if c.Password == nil { + password := os.Getenv("OPC_PASSWORD") + c.Password = &password + } + + if c.HTTPClient == nil { + c.HTTPClient = &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSHandshakeTimeout: 120 * time.Second}, + } + } + + return NewComputeClient(c) +} + +func getBlankTestClient() (*ComputeClient, *httptest.Server, error) { + server := newAuthenticatingServer(func(w http.ResponseWriter, r *http.Request) { + }) + + endpoint, err := url.Parse(server.URL) + if err != nil { + server.Close() + return nil, nil, err + } + + client, err := getTestClient(&opc.Config{ + IdentityDomain: opc.String(_ClientTestDomain), + Username: opc.String(_ClientTestUser), + APIEndpoint: endpoint, + }) + if err != nil { + server.Close() + return nil, nil, err + } + return client, server, nil +} + +// Returns a stub client with default values, and a custom API Endpoint +func getStubClient(endpoint *url.URL) (*ComputeClient, error) { + domain := "test" + username := "test" + password := "test" + config := &opc.Config{ + IdentityDomain: &domain, + Username: &username, + Password: &password, + APIEndpoint: endpoint, + } + return getTestClient(config) +} + +func unmarshalRequestBody(t *testing.T, r *http.Request, target interface{}) { + buf := new(bytes.Buffer) + buf.ReadFrom(r.Body) + err := json.Unmarshal(buf.Bytes(), target) + if err != nil { + t.Fatalf("Error marshalling request: %s", err) + } +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic.go new file mode 100644 index 000000000..44509d7c9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic.go @@ -0,0 +1,52 @@ +package compute + +type VirtNICsClient struct { + ResourceClient +} + +func (c *ComputeClient) VirtNICs() *VirtNICsClient { + return &VirtNICsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "Virtual NIC", + ContainerPath: "/network/v1/vnic/", + ResourceRootPath: "/network/v1/vnic", + }, + } +} + +type VirtualNIC struct { + // Description of the object. + Description string `json:"description"` + // MAC address of this VNIC. + MACAddress string `json:"macAddress"` + // The three-part name (/Compute-identity_domain/user/object) of the Virtual NIC. + Name string `json:"name"` + // Tags associated with the object. + Tags []string `json:"tags"` + // True if the VNIC is of type "transit". + TransitFlag bool `json:"transitFlag"` + // Uniform Resource Identifier + Uri string `json:"uri"` +} + +// Can only GET a virtual NIC, not update, create, or delete +type GetVirtualNICInput struct { + // The three-part name (/Compute-identity_domain/user/object) of the Virtual NIC. + // Required + Name string `json:"name"` +} + +func (c *VirtNICsClient) GetVirtualNIC(input *GetVirtualNICInput) (*VirtualNIC, error) { + var virtNIC VirtualNIC + input.Name = c.getQualifiedName(input.Name) + if err := c.getResource(input.Name, &virtNIC); err != nil { + return nil, err + } + return c.success(&virtNIC) +} + +func (c *VirtNICsClient) success(info *VirtualNIC) (*VirtualNIC, error) { + c.unqualify(&info.Name) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic_sets.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic_sets.go new file mode 100644 index 000000000..85762e52f --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/virtual_nic_sets.go @@ -0,0 +1,154 @@ +package compute + +type VirtNICSetsClient struct { + ResourceClient +} + +func (c *ComputeClient) VirtNICSets() *VirtNICSetsClient { + return &VirtNICSetsClient{ + ResourceClient: ResourceClient{ + ComputeClient: c, + ResourceDescription: "Virtual NIC Set", + ContainerPath: "/network/v1/vnicset/", + ResourceRootPath: "/network/v1/vnicset", + }, + } +} + +// Describes an existing virtual nic set +type VirtualNICSet struct { + // List of ACLs applied to the VNICs in the set. + AppliedACLs []string `json:"appliedAcls"` + // Description of the VNIC Set. + Description string `json:"description"` + // Name of the VNIC set. + Name string `json:"name"` + // The three-part name (/Compute-identity_domain/user/object) of the virtual NIC set. + Tags []string `json:"tags"` + // Uniform Resource Identifier + Uri string `json:"uri"` + // List of VNICs associated with this VNIC set. + VirtualNICs []string `json:"vnics"` +} + +type CreateVirtualNICSetInput struct { + // List of ACLs applied to the VNICs in the set. + // Optional + AppliedACLs []string `json:"appliedAcls"` + // Description of the object. + // Optional + Description string `json:"description"` + // The three-part name (/Compute-identity_domain/user/object) of the virtual NIC set. + // Object names can contain only alphanumeric, underscore (_), dash (-), and period (.) characters. Object names are case-sensitive. + // Required + Name string `json:"name"` + // Tags associated with this VNIC set. + // Optional + Tags []string `json:"tags"` + // List of VNICs associated with this VNIC set. + // Optional + VirtualNICs []string `json:"vnics"` +} + +func (c *VirtNICSetsClient) CreateVirtualNICSet(input *CreateVirtualNICSetInput) (*VirtualNICSet, error) { + input.Name = c.getQualifiedName(input.Name) + input.AppliedACLs = c.getQualifiedAcls(input.AppliedACLs) + qualifiedNics := c.getQualifiedList(input.VirtualNICs) + if len(qualifiedNics) != 0 { + input.VirtualNICs = qualifiedNics + } + + var virtNicSet VirtualNICSet + if err := c.createResource(input, &virtNicSet); err != nil { + return nil, err + } + + return c.success(&virtNicSet) +} + +type GetVirtualNICSetInput struct { + // The three-part name (/Compute-identity_domain/user/object) of the virtual NIC set. + // Required + Name string `json:"name"` +} + +func (c *VirtNICSetsClient) GetVirtualNICSet(input *GetVirtualNICSetInput) (*VirtualNICSet, error) { + var virtNicSet VirtualNICSet + // Qualify Name + input.Name = c.getQualifiedName(input.Name) + if err := c.getResource(input.Name, &virtNicSet); err != nil { + return nil, err + } + + return c.success(&virtNicSet) +} + +type UpdateVirtualNICSetInput struct { + // List of ACLs applied to the VNICs in the set. + // Optional + AppliedACLs []string `json:"appliedAcls"` + // Description of the object. + // Optional + Description string `json:"description"` + // The three-part name (/Compute-identity_domain/user/object) of the virtual NIC set. + // Object names can contain only alphanumeric, underscore (_), dash (-), and period (.) characters. Object names are case-sensitive. + // Required + Name string `json:"name"` + // Tags associated with this VNIC set. + // Optional + Tags []string `json:"tags"` + // List of VNICs associated with this VNIC set. + // Optional + VirtualNICs []string `json:"vnics"` +} + +func (c *VirtNICSetsClient) UpdateVirtualNICSet(input *UpdateVirtualNICSetInput) (*VirtualNICSet, error) { + input.Name = c.getQualifiedName(input.Name) + input.AppliedACLs = c.getQualifiedAcls(input.AppliedACLs) + // Qualify VirtualNICs + qualifiedVNICs := c.getQualifiedList(input.VirtualNICs) + if len(qualifiedVNICs) != 0 { + input.VirtualNICs = qualifiedVNICs + } + + var virtNICSet VirtualNICSet + if err := c.updateResource(input.Name, input, &virtNICSet); err != nil { + return nil, err + } + + return c.success(&virtNICSet) +} + +type DeleteVirtualNICSetInput struct { + // The name of the virtual NIC set. + // Required + Name string `json:"name"` +} + +func (c *VirtNICSetsClient) DeleteVirtualNICSet(input *DeleteVirtualNICSetInput) error { + input.Name = c.getQualifiedName(input.Name) + return c.deleteResource(input.Name) +} + +func (c *VirtNICSetsClient) getQualifiedAcls(acls []string) []string { + qualifiedAcls := []string{} + for _, acl := range acls { + qualifiedAcls = append(qualifiedAcls, c.getQualifiedName(acl)) + } + return qualifiedAcls +} + +func (c *VirtNICSetsClient) unqualifyAcls(acls []string) []string { + unqualifiedAcls := []string{} + for _, acl := range acls { + unqualifiedAcls = append(unqualifiedAcls, c.getUnqualifiedName(acl)) + } + return unqualifiedAcls +} + +func (c *VirtNICSetsClient) success(info *VirtualNICSet) (*VirtualNICSet, error) { + c.unqualify(&info.Name) + info.AppliedACLs = c.unqualifyAcls(info.AppliedACLs) + info.VirtualNICs = c.getUnqualifiedList(info.VirtualNICs) + return info, nil +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/opc/config.go b/vendor/github.com/hashicorp/go-oracle-terraform/opc/config.go new file mode 100644 index 000000000..5c144a66d --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/opc/config.go @@ -0,0 +1,22 @@ +package opc + +import ( + "net/http" + "net/url" +) + +type Config struct { + Username *string + Password *string + IdentityDomain *string + APIEndpoint *url.URL + MaxRetries *int + LogLevel LogLevelType + Logger Logger + HTTPClient *http.Client + UserAgent *string +} + +func NewConfig() *Config { + return &Config{} +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/opc/convert.go b/vendor/github.com/hashicorp/go-oracle-terraform/opc/convert.go new file mode 100644 index 000000000..52fa08902 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/opc/convert.go @@ -0,0 +1,9 @@ +package opc + +func String(v string) *string { + return &v +} + +func Int(v int) *int { + return &v +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/opc/errors.go b/vendor/github.com/hashicorp/go-oracle-terraform/opc/errors.go new file mode 100644 index 000000000..6b12c10d9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/opc/errors.go @@ -0,0 +1,12 @@ +package opc + +import "fmt" + +type OracleError struct { + StatusCode int + Message string +} + +func (e OracleError) Error() string { + return fmt.Sprintf("%d: %s", e.StatusCode, e.Message) +} diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/opc/logger.go b/vendor/github.com/hashicorp/go-oracle-terraform/opc/logger.go new file mode 100644 index 000000000..f9714a7a8 --- /dev/null +++ b/vendor/github.com/hashicorp/go-oracle-terraform/opc/logger.go @@ -0,0 +1,70 @@ +package opc + +import ( + "io" + "io/ioutil" + "log" + "os" +) + +const ( + LogOff LogLevelType = 0 + LogDebug LogLevelType = 1 +) + +type LogLevelType uint + +// Logger interface. Should be satisfied by Terraform's logger as well as the Default logger +type Logger interface { + Log(...interface{}) +} + +type LoggerFunc func(...interface{}) + +func (f LoggerFunc) Log(args ...interface{}) { + f(args...) +} + +// Returns a default logger if one isn't specified during configuration +func NewDefaultLogger() Logger { + logWriter, err := LogOutput() + if err != nil { + log.Fatalf("Error setting up log writer: %s", err) + } + return &defaultLogger{ + logger: log.New(logWriter, "", log.LstdFlags), + } +} + +// Default logger to satisfy the logger interface +type defaultLogger struct { + logger *log.Logger +} + +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} + +func LogOutput() (logOutput io.Writer, err error) { + // Default to nil + logOutput = ioutil.Discard + + logLevel := LogLevel() + if logLevel == LogOff { + return + } + + // Logging is on, set output to STDERR + logOutput = os.Stderr + return +} + +// Gets current Log Level from the ORACLE_LOG env var +func LogLevel() LogLevelType { + envLevel := os.Getenv("ORACLE_LOG") + if envLevel == "" { + return LogOff + } else { + return LogDebug + } +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 2f8f8307d..fe36fe283 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -796,6 +796,24 @@ "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", "revisionTime": "2018-01-11T20:31:13Z" }, + { + "checksumSHA1": "hjQfXn32Tvuu6IJACOTsMzm+AbA=", + "path": "github.com/hashicorp/go-oracle-terraform/client", + "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", + "revisionTime": "2018-01-11T20:31:13Z" + }, + { + "checksumSHA1": "RhoE7zmHsn5zoXbx5AsAUUQI72E=", + "path": "github.com/hashicorp/go-oracle-terraform/compute", + "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", + "revisionTime": "2018-01-11T20:31:13Z" + }, + { + "checksumSHA1": "NuObCk0/ybL3w++EnltgrB1GQRc=", + "path": "github.com/hashicorp/go-oracle-terraform/opc", + "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", + "revisionTime": "2018-01-11T20:31:13Z" + }, { "checksumSHA1": "ErJHGU6AVPZM9yoY/xV11TwSjQs=", "path": "github.com/hashicorp/go-retryablehttp", From 75ee66f934aa5aff050628a22802c28979617c5a Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 12 Jan 2018 16:06:03 -0800 Subject: [PATCH 0451/1007] add stubbed out steps --- .../classic/step_create_IP_reservation.go | 24 +++++++++++++ .../oracle/classic/step_create_instance.go | 34 +++++++++++++++++++ builder/oracle/classic/step_instance_info.go | 24 +++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 builder/oracle/classic/step_create_IP_reservation.go create mode 100644 builder/oracle/classic/step_create_instance.go create mode 100644 builder/oracle/classic/step_instance_info.go diff --git a/builder/oracle/classic/step_create_IP_reservation.go b/builder/oracle/classic/step_create_IP_reservation.go new file mode 100644 index 000000000..a719999dd --- /dev/null +++ b/builder/oracle/classic/step_create_IP_reservation.go @@ -0,0 +1,24 @@ +package classic + +import ( + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type stepCreateIPReservation struct{} + +func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + ui.Say("Creating IP reservation...") + const endpoint_path = "/ip/reservation/" // POST + + // $ opc compute ip-reservations add \ + // /Compute-mydomain/user@example.com/master-instance-ip \ + // /oracle/public/ippool + + // account /Compute-mydomain/default + // ip 129.144.27.172 + // name /Compute-mydomain/user@example.com/master-instance-ip + // ... + +} diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go new file mode 100644 index 000000000..6678979bf --- /dev/null +++ b/builder/oracle/classic/step_create_instance.go @@ -0,0 +1,34 @@ +package classic + +import ( + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type stepCreateIPReservation struct{} + +func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + ui.Say("Creating Instance...") + const endpoint_path = "/launchplan/" // POST + // master-instance.json + + // { + // "instances": [{ + // "shape": "oc3", + // "sshkeys": ["/Compute-mydomain/user@example.com/my_sshkey"], + // "name": "Compute-mydomain/user@example.com/master-instance", + // "label": "master-instance", + // "imagelist": "/Compute-mydomain/user@example.com/Ubuntu.16.04-LTS.amd64.20170330", + // "networking": { + // "eth0": { + // "nat": "ipreservation:/Compute-mydomain/user@example.com/master-instance-ip" + // } + // } + // }] + // } + // command line call + // $ opc compute launch-plans add --request-body=./master-instance.json + // ... + +} diff --git a/builder/oracle/classic/step_instance_info.go b/builder/oracle/classic/step_instance_info.go new file mode 100644 index 000000000..a2f935a99 --- /dev/null +++ b/builder/oracle/classic/step_instance_info.go @@ -0,0 +1,24 @@ +package classic + +import ( + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type stepCreateIPReservation struct{} + +func (s *stepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + ui.Say("Getting Instance Info...") + endpoint_path := "/instance/%s", instanceName // GET + + // $ opc compute ip-reservations add \ + // /Compute-mydomain/user@example.com/master-instance-ip \ + // /oracle/public/ippool + + // account /Compute-mydomain/default + // ip 129.144.27.172 + // name /Compute-mydomain/user@example.com/master-instance-ip + // ... + +} From 4fe89be32ad368915570edd2e5cdc09b4feef406 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 12 Jan 2018 16:18:55 -0800 Subject: [PATCH 0452/1007] fleshing out steps --- .../oracle/classic/step_create_instance.go | 46 ++++++++++++------- builder/oracle/classic/step_instance_info.go | 16 ++----- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 6678979bf..4b9d33c0a 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -1,34 +1,48 @@ package classic import ( + "fmt" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) -type stepCreateIPReservation struct{} +type stepCreateInstance struct{} func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating Instance...") const endpoint_path = "/launchplan/" // POST // master-instance.json - - // { - // "instances": [{ - // "shape": "oc3", - // "sshkeys": ["/Compute-mydomain/user@example.com/my_sshkey"], - // "name": "Compute-mydomain/user@example.com/master-instance", - // "label": "master-instance", - // "imagelist": "/Compute-mydomain/user@example.com/Ubuntu.16.04-LTS.amd64.20170330", - // "networking": { - // "eth0": { - // "nat": "ipreservation:/Compute-mydomain/user@example.com/master-instance-ip" - // } - // } - // }] - // } + ` + { + "instances": [{ + "shape": "oc3", + "sshkeys": ["/Compute-mydomain/user@example.com/my_sshkey"], + "name": "Compute-mydomain/user@example.com/master-instance", + "label": "master-instance", + "imagelist": "/Compute-mydomain/user@example.com/Ubuntu.16.04-LTS.amd64.20170330", + "networking": { + "eth0": { + "nat": "ipreservation:/Compute-mydomain/user@example.com/master-instance-ip" + } + } + }] + } + ` // command line call // $ opc compute launch-plans add --request-body=./master-instance.json // ... + instanceID, err := client.CreateInstance(publicKey) + if err != nil { + err = fmt.Errorf("Problem creating instance: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + state.Put("instance_id", instanceID) + + ui.Say(fmt.Sprintf("Created instance (%s).", instanceID)) } diff --git a/builder/oracle/classic/step_instance_info.go b/builder/oracle/classic/step_instance_info.go index a2f935a99..9ec01cdbc 100644 --- a/builder/oracle/classic/step_instance_info.go +++ b/builder/oracle/classic/step_instance_info.go @@ -5,20 +5,14 @@ import ( "github.com/mitchellh/multistep" ) -type stepCreateIPReservation struct{} +type stepInstanceInfo struct{} func (s *stepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) ui.Say("Getting Instance Info...") - endpoint_path := "/instance/%s", instanceName // GET + ui := state.Get("ui").(packer.Ui) + instanceID := state.Get("instance_id").(string) + endpoint_path := "/instance/%s", instanceID // GET - // $ opc compute ip-reservations add \ - // /Compute-mydomain/user@example.com/master-instance-ip \ - // /oracle/public/ippool - - // account /Compute-mydomain/default - // ip 129.144.27.172 - // name /Compute-mydomain/user@example.com/master-instance-ip - // ... + // https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/op-instance-%7Bname%7D-get.html } From a66dfe19721f31a55c7767911cc2ff8e0ae1d8ed Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 12 Jan 2018 16:48:35 -0800 Subject: [PATCH 0453/1007] fleshing out step_create_instance --- .../oracle/classic/step_create_instance.go | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 4b9d33c0a..dce6b0d78 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -2,34 +2,55 @@ package classic import ( "fmt" + "text/template" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) +type instanceOptions struct { + Username string + IdentityDomain string + SshKey string + Shape string + ImageList string + InstanceIP string +} + +var instanceTemplate = template.Must(template.New("instanceRequestBody").Parse(` +{ + "instances": [{ + "shape": "{{.Shape}}", + "sshkeys": ["/Compute-{{.IdentityDomain}}/{{Username}}/{{.SshKey}}"], + "name": "Compute-{{.IdentityDomain}}/{{Username}}/packer-instance", + "label": "packer-instance", + "imagelist": "/Compute-{{.IdentityDomain}}/{{Username}}/{{.ImageList}}", + "networking": { + "eth0": { + "nat": "ipreservation:/Compute-{{.IdentityDomain}}/{{Username}}/{{.InstanceIP}}" + } + } + }] +} +`)) + type stepCreateInstance struct{} func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) - ui.Say("Creating Instance...") + config := state.Get("config").(Config) const endpoint_path = "/launchplan/" // POST - // master-instance.json - ` - { - "instances": [{ - "shape": "oc3", - "sshkeys": ["/Compute-mydomain/user@example.com/my_sshkey"], - "name": "Compute-mydomain/user@example.com/master-instance", - "label": "master-instance", - "imagelist": "/Compute-mydomain/user@example.com/Ubuntu.16.04-LTS.amd64.20170330", - "networking": { - "eth0": { - "nat": "ipreservation:/Compute-mydomain/user@example.com/master-instance-ip" - } - } - }] - } - ` + + ui.Say("Creating Instance...") + + // generate launch plan definition for this instance + err = instanceTemplate.Execute(&buffer, instanceOptions{ + Username: config.Username, + IdentityDomain: config.IdentityDomain, + SshKey: config.SshKey, + Shape: config.Shape, + ImageList: config.ImageList, + }) // command line call // $ opc compute launch-plans add --request-body=./master-instance.json // ... From 0117f537211d1c8716e9515f6a49770ed5eca1f1 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 12 Jan 2018 16:51:59 -0800 Subject: [PATCH 0454/1007] add error message --- builder/oracle/classic/step_create_instance.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index dce6b0d78..e6fbb8798 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -51,6 +51,10 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc Shape: config.Shape, ImageList: config.ImageList, }) + if err != nil { + fmt.Printf("Error creating launch plan definition: %s", err) + return "", err + } // command line call // $ opc compute launch-plans add --request-body=./master-instance.json // ... From 7d72870179895a397acc3c5bff7ba355909ff8f1 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 16 Jan 2018 12:09:42 -0800 Subject: [PATCH 0455/1007] add buffer to read template into --- builder/oracle/classic/step_create_instance.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index e6fbb8798..e461dd5ab 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -1,6 +1,7 @@ package classic import ( + "bytes" "fmt" "text/template" @@ -44,6 +45,7 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc ui.Say("Creating Instance...") // generate launch plan definition for this instance + var buffer bytes.Buffer err = instanceTemplate.Execute(&buffer, instanceOptions{ Username: config.Username, IdentityDomain: config.IdentityDomain, @@ -55,10 +57,8 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc fmt.Printf("Error creating launch plan definition: %s", err) return "", err } - // command line call - // $ opc compute launch-plans add --request-body=./master-instance.json - // ... - + // for API docs see + // https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/op-launchplan--post.html instanceID, err := client.CreateInstance(publicKey) if err != nil { err = fmt.Errorf("Problem creating instance: %s", err) From 007e8f7c14203ef81b23e82f0ead74e4f185a187 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 16 Jan 2018 14:28:24 -0800 Subject: [PATCH 0456/1007] finish stubbing out step_create_IP_reservation --- builder/oracle/classic/builder.go | 3 +- .../classic/step_create_IP_reservation.go | 32 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index b8af96345..4867ff34e 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/go-oracle-terraform/opc" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) @@ -58,7 +59,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the steps steps := []multistep.Step{ - /* &ocommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), @@ -75,7 +75,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &stepSnapshot{}, - */ } // Run the steps diff --git a/builder/oracle/classic/step_create_IP_reservation.go b/builder/oracle/classic/step_create_IP_reservation.go index a719999dd..415b3ddac 100644 --- a/builder/oracle/classic/step_create_IP_reservation.go +++ b/builder/oracle/classic/step_create_IP_reservation.go @@ -1,6 +1,9 @@ package classic import ( + "log" + + "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) @@ -10,15 +13,22 @@ type stepCreateIPReservation struct{} func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating IP reservation...") - const endpoint_path = "/ip/reservation/" // POST - - // $ opc compute ip-reservations add \ - // /Compute-mydomain/user@example.com/master-instance-ip \ - // /oracle/public/ippool - - // account /Compute-mydomain/default - // ip 129.144.27.172 - // name /Compute-mydomain/user@example.com/master-instance-ip - // ... - + client := state.Get("client", client).(*compute.ComputeClient) + iprClient := client.IPReservations() + if err != nil { + log.Printf("Error getting IPReservations Client: %s", err) + return multistep.ActionHalt + } + // TODO: add optional Name and Tags + IPInput := &iprClient.CreateIPReservationInput{ + ParentPool: compute.PublicReservationPool, + Permanent: true, + } + ipRes, err := iprClient.CreateIPReservation(createIPReservation) + if err != nil { + log.Printf("Error creating IP Reservation: %s", err) + return multistep.ActionHalt + } + log.Printf("debug: ipRes is %#v", ipRes) + return multistep.ActionContinue } From 8aa716cd4cb559dd0ec26a8f1a3be37ba3b7eaee Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 16 Jan 2018 16:55:39 -0800 Subject: [PATCH 0457/1007] stub out step_snapshot --- .../classic/step_create_IP_reservation.go | 1 + .../oracle/classic/step_create_instance.go | 70 ++++++------------- builder/oracle/classic/step_snapshot.go | 39 +++++++++++ 3 files changed, 61 insertions(+), 49 deletions(-) create mode 100644 builder/oracle/classic/step_snapshot.go diff --git a/builder/oracle/classic/step_create_IP_reservation.go b/builder/oracle/classic/step_create_IP_reservation.go index 415b3ddac..797063b1c 100644 --- a/builder/oracle/classic/step_create_IP_reservation.go +++ b/builder/oracle/classic/step_create_IP_reservation.go @@ -29,6 +29,7 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc log.Printf("Error creating IP Reservation: %s", err) return multistep.ActionHalt } + state.Put("instance_ip", ipRes.IP) log.Printf("debug: ipRes is %#v", ipRes) return multistep.ActionContinue } diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index e461dd5ab..f94d6d0b7 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -1,65 +1,37 @@ package classic import ( - "bytes" "fmt" - "text/template" + "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" ) -type instanceOptions struct { - Username string - IdentityDomain string - SshKey string - Shape string - ImageList string - InstanceIP string -} - -var instanceTemplate = template.Must(template.New("instanceRequestBody").Parse(` -{ - "instances": [{ - "shape": "{{.Shape}}", - "sshkeys": ["/Compute-{{.IdentityDomain}}/{{Username}}/{{.SshKey}}"], - "name": "Compute-{{.IdentityDomain}}/{{Username}}/packer-instance", - "label": "packer-instance", - "imagelist": "/Compute-{{.IdentityDomain}}/{{Username}}/{{.ImageList}}", - "networking": { - "eth0": { - "nat": "ipreservation:/Compute-{{.IdentityDomain}}/{{Username}}/{{.InstanceIP}}" - } - } - }] -} -`)) - type stepCreateInstance struct{} -func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - config := state.Get("config").(Config) - const endpoint_path = "/launchplan/" // POST - +func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Creating Instance...") - // generate launch plan definition for this instance - var buffer bytes.Buffer - err = instanceTemplate.Execute(&buffer, instanceOptions{ - Username: config.Username, - IdentityDomain: config.IdentityDomain, - SshKey: config.SshKey, - Shape: config.Shape, - ImageList: config.ImageList, - }) - if err != nil { - fmt.Printf("Error creating launch plan definition: %s", err) - return "", err + // get variables from state + ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(Config) + client := state.Get("client").(*compute.ComputeClient) + sshPublicKey := state.Get("publicKey").(string) + + // get instances client + instanceClient := client.Instances() + + // Instances Input + input := &compute.CreateInstanceInput{ + Name: config.ImageName, + Shape: config.Shape, + ImageList: config.ImageList, + SSHKeys: []string{}, + Attributes: map[string]interface{}{}, } - // for API docs see - // https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/op-launchplan--post.html - instanceID, err := client.CreateInstance(publicKey) + + instanceInfo, err := instanceClient.CreateInstance(input) if err != nil { err = fmt.Errorf("Problem creating instance: %s", err) ui.Error(err.Error()) @@ -67,7 +39,7 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc return multistep.ActionHalt } - state.Put("instance_id", instanceID) + state.Put("instance_id", instanceInfo.ID) ui.Say(fmt.Sprintf("Created instance (%s).", instanceID)) } diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go new file mode 100644 index 000000000..582966a83 --- /dev/null +++ b/builder/oracle/classic/step_snapshot.go @@ -0,0 +1,39 @@ +package classic + +import ( + "fmt" + + "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type stepSnapshot struct{} + +func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { + // get variables from state + ui := state.Get("ui").(packer.Ui) + ui.Say("Creating Snapshot...") + config := state.Get("config").(Config) + client := state.Get("client").(*compute.ComputeClient) + instanceID := state.Get("instance_id").(string) + + // get instances client + snapshotClient := client.SnapshotsClient() + + // Instances Input + createSnapshotInput := &CreateSnapshotInput{ + Instance: instanceID, + MachineImage: config.ImageName, + } + + snap, err := snapshotClient.CreateSnapshot(input) + if err != nil { + err = fmt.Errorf("Problem creating snapshot: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + ui.Say(fmt.Sprintf("Created snapshot (%s).", snap.Name)) +} From 46c3113613355d7f9ba928014eaa1dc66d5c7014 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 17 Jan 2018 13:07:41 -0800 Subject: [PATCH 0458/1007] it compiles :) --- builder/oracle/classic/builder.go | 5 +- builder/oracle/classic/config.go | 1 + .../classic/step_create_IP_reservation.go | 14 +- .../oracle/classic/step_create_instance.go | 13 +- builder/oracle/classic/step_instance_info.go | 18 -- builder/oracle/classic/step_snapshot.go | 11 +- builder/oracle/oci/builder.go | 4 +- builder/oracle/oci/ssh.go | 45 ---- command/plugin.go | 198 +++++++++--------- 9 files changed, 131 insertions(+), 178 deletions(-) delete mode 100644 builder/oracle/classic/step_instance_info.go delete mode 100644 builder/oracle/oci/ssh.go diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 4867ff34e..4501456d2 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/go-oracle-terraform/opc" + ocommon "github.com/hashicorp/packer/builder/oracle/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" @@ -68,8 +69,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepCreateInstance{}, &communicator.StepConnect{ Config: &b.config.Comm, - Host: commHost, - SSHConfig: SSHConfig( + Host: ocommon.CommHost, + SSHConfig: ocommon.SSHConfig( b.config.Comm.SSHUsername, b.config.Comm.SSHPassword), }, diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 050f78d91..10ec44c54 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -24,6 +24,7 @@ type Config struct { apiEndpointURL *url.URL // Image + ImageName string `mapstructure:"image_name"` Shape string `mapstructure:"shape"` ImageList string `json:"image_list"` diff --git a/builder/oracle/classic/step_create_IP_reservation.go b/builder/oracle/classic/step_create_IP_reservation.go index 797063b1c..f3f898eaa 100644 --- a/builder/oracle/classic/step_create_IP_reservation.go +++ b/builder/oracle/classic/step_create_IP_reservation.go @@ -13,18 +13,14 @@ type stepCreateIPReservation struct{} func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating IP reservation...") - client := state.Get("client", client).(*compute.ComputeClient) + client := state.Get("client").(*compute.ComputeClient) iprClient := client.IPReservations() - if err != nil { - log.Printf("Error getting IPReservations Client: %s", err) - return multistep.ActionHalt - } // TODO: add optional Name and Tags - IPInput := &iprClient.CreateIPReservationInput{ + IPInput := &compute.CreateIPReservationInput{ ParentPool: compute.PublicReservationPool, Permanent: true, } - ipRes, err := iprClient.CreateIPReservation(createIPReservation) + ipRes, err := iprClient.CreateIPReservation(IPInput) if err != nil { log.Printf("Error creating IP Reservation: %s", err) return multistep.ActionHalt @@ -33,3 +29,7 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc log.Printf("debug: ipRes is %#v", ipRes) return multistep.ActionContinue } + +func (s *stepCreateIPReservation) Cleanup(state multistep.StateBag) { + // Nothing to do +} diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index f94d6d0b7..7de599190 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -11,10 +11,9 @@ import ( type stepCreateInstance struct{} func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { - ui.Say("Creating Instance...") - // get variables from state ui := state.Get("ui").(packer.Ui) + ui.Say("Creating Instance...") config := state.Get("config").(Config) client := state.Get("client").(*compute.ComputeClient) sshPublicKey := state.Get("publicKey").(string) @@ -27,7 +26,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction Name: config.ImageName, Shape: config.Shape, ImageList: config.ImageList, - SSHKeys: []string{}, + SSHKeys: []string{sshPublicKey}, Attributes: map[string]interface{}{}, } @@ -40,6 +39,10 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction } state.Put("instance_id", instanceInfo.ID) - - ui.Say(fmt.Sprintf("Created instance (%s).", instanceID)) + ui.Say(fmt.Sprintf("Created instance (%s).", instanceInfo.ID)) + return multistep.ActionContinue +} + +func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { + // Nothing to do } diff --git a/builder/oracle/classic/step_instance_info.go b/builder/oracle/classic/step_instance_info.go deleted file mode 100644 index 9ec01cdbc..000000000 --- a/builder/oracle/classic/step_instance_info.go +++ /dev/null @@ -1,18 +0,0 @@ -package classic - -import ( - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" -) - -type stepInstanceInfo struct{} - -func (s *stepInstanceInfo) Run(state multistep.StateBag) multistep.StepAction { - ui.Say("Getting Instance Info...") - ui := state.Get("ui").(packer.Ui) - instanceID := state.Get("instance_id").(string) - endpoint_path := "/instance/%s", instanceID // GET - - // https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/op-instance-%7Bname%7D-get.html - -} diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 582966a83..2df8976a1 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -19,15 +19,15 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { instanceID := state.Get("instance_id").(string) // get instances client - snapshotClient := client.SnapshotsClient() + snapshotClient := client.Snapshots() // Instances Input - createSnapshotInput := &CreateSnapshotInput{ + snapshotInput := &compute.CreateSnapshotInput{ Instance: instanceID, MachineImage: config.ImageName, } - snap, err := snapshotClient.CreateSnapshot(input) + snap, err := snapshotClient.CreateSnapshot(snapshotInput) if err != nil { err = fmt.Errorf("Problem creating snapshot: %s", err) ui.Error(err.Error()) @@ -36,4 +36,9 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { } ui.Say(fmt.Sprintf("Created snapshot (%s).", snap.Name)) + return multistep.ActionContinue +} + +func (s *stepSnapshot) Cleanup(state multistep.StateBag) { + // Nothing to do } diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index 07d41b756..612fdf4f6 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -60,8 +60,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &stepInstanceInfo{}, &communicator.StepConnect{ Config: &b.config.Comm, - Host: commHost, - SSHConfig: SSHConfig( + Host: ocommon.CommHost, + SSHConfig: ocommon.SSHConfig( b.config.Comm.SSHUsername, b.config.Comm.SSHPassword), }, diff --git a/builder/oracle/oci/ssh.go b/builder/oracle/oci/ssh.go deleted file mode 100644 index 5424b94b4..000000000 --- a/builder/oracle/oci/ssh.go +++ /dev/null @@ -1,45 +0,0 @@ -package oci - -import ( - "fmt" - - packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/hashicorp/packer/helper/multistep" - "golang.org/x/crypto/ssh" -) - -func commHost(state multistep.StateBag) (string, error) { - ipAddress := state.Get("instance_ip").(string) - return ipAddress, nil -} - -// SSHConfig returns a function that can be used for the SSH communicator -// config for connecting to the instance created over SSH using the private key -// or password. -func SSHConfig(username, password string) func(state multistep.StateBag) (*ssh.ClientConfig, error) { - return func(state multistep.StateBag) (*ssh.ClientConfig, error) { - privateKey, hasKey := state.GetOk("privateKey") - if hasKey { - - signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string))) - if err != nil { - return nil, fmt.Errorf("Error setting up SSH config: %s", err) - } - return &ssh.ClientConfig{ - User: username, - Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), - }, nil - - } - - return &ssh.ClientConfig{ - User: username, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), - Auth: []ssh.AuthMethod{ - ssh.Password(password), - ssh.KeyboardInteractive(packerssh.PasswordKeyboardInteractive(password)), - }, - }, nil - } -} diff --git a/command/plugin.go b/command/plugin.go index d9e7ea577..4f4228fc3 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -14,65 +14,67 @@ import ( "github.com/hashicorp/packer/packer/plugin" alicloudecsbuilder "github.com/hashicorp/packer/builder/alicloud/ecs" + alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" amazonchrootbuilder "github.com/hashicorp/packer/builder/amazon/chroot" amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" amazonebssurrogatebuilder "github.com/hashicorp/packer/builder/amazon/ebssurrogate" amazonebsvolumebuilder "github.com/hashicorp/packer/builder/amazon/ebsvolume" - amazoninstancebuilder "github.com/hashicorp/packer/builder/amazon/instance" - azurearmbuilder "github.com/hashicorp/packer/builder/azure/arm" - cloudstackbuilder "github.com/hashicorp/packer/builder/cloudstack" - digitaloceanbuilder "github.com/hashicorp/packer/builder/digitalocean" - dockerbuilder "github.com/hashicorp/packer/builder/docker" - filebuilder "github.com/hashicorp/packer/builder/file" - googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" - hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" - hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" - lxcbuilder "github.com/hashicorp/packer/builder/lxc" - lxdbuilder "github.com/hashicorp/packer/builder/lxd" - nullbuilder "github.com/hashicorp/packer/builder/null" - oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" - openstackbuilder "github.com/hashicorp/packer/builder/openstack" - oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" - parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" - parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" - profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" - qemubuilder "github.com/hashicorp/packer/builder/qemu" - tritonbuilder "github.com/hashicorp/packer/builder/triton" - virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" - virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" - vmwareisobuilder "github.com/hashicorp/packer/builder/vmware/iso" - vmwarevmxbuilder "github.com/hashicorp/packer/builder/vmware/vmx" - alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" + amazoninstancebuilder "github.com/hashicorp/packer/builder/amazon/instance" + ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" + ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" atlaspostprocessor "github.com/hashicorp/packer/post-processor/atlas" + azurearmbuilder "github.com/hashicorp/packer/builder/azure/arm" checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" + chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" + chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" + cloudstackbuilder "github.com/hashicorp/packer/builder/cloudstack" compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" + convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" + digitaloceanbuilder "github.com/hashicorp/packer/builder/digitalocean" + dockerbuilder "github.com/hashicorp/packer/builder/docker" dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" dockersavepostprocessor "github.com/hashicorp/packer/post-processor/docker-save" dockertagpostprocessor "github.com/hashicorp/packer/post-processor/docker-tag" - googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" - manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" - shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" - vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" - vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" - vspherepostprocessor "github.com/hashicorp/packer/post-processor/vsphere" - vspheretemplatepostprocessor "github.com/hashicorp/packer/post-processor/vsphere-template" - ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" - ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" - chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" - chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" - convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" + filebuilder "github.com/hashicorp/packer/builder/file" fileprovisioner "github.com/hashicorp/packer/provisioner/file" + googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" + googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" + hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" + hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" + lxcbuilder "github.com/hashicorp/packer/builder/lxc" + lxdbuilder "github.com/hashicorp/packer/builder/lxd" + manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" + nullbuilder "github.com/hashicorp/packer/builder/null" + oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" + openstackbuilder "github.com/hashicorp/packer/builder/openstack" + oracleclassicbuilder "github.com/hashicorp/packer/builder/oracle/classic" + oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" + parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" + parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" + profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" + qemubuilder "github.com/hashicorp/packer/builder/qemu" saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" - shellprovisioner "github.com/hashicorp/packer/provisioner/shell" + shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" + shellprovisioner "github.com/hashicorp/packer/provisioner/shell" + tritonbuilder "github.com/hashicorp/packer/builder/triton" + vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" + vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" + virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" + virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" + vmwareisobuilder "github.com/hashicorp/packer/builder/vmware/iso" + vmwarevmxbuilder "github.com/hashicorp/packer/builder/vmware/vmx" + vspherepostprocessor "github.com/hashicorp/packer/post-processor/vsphere" + vspheretemplatepostprocessor "github.com/hashicorp/packer/post-processor/vsphere-template" windowsrestartprovisioner "github.com/hashicorp/packer/provisioner/windows-restart" windowsshellprovisioner "github.com/hashicorp/packer/provisioner/windows-shell" + ) type PluginCommand struct { @@ -80,74 +82,78 @@ type PluginCommand struct { } var Builders = map[string]packer.Builder{ - "alicloud-ecs": new(alicloudecsbuilder.Builder), - "amazon-chroot": new(amazonchrootbuilder.Builder), - "amazon-ebs": new(amazonebsbuilder.Builder), - "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), - "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), - "amazon-instance": new(amazoninstancebuilder.Builder), - "azure-arm": new(azurearmbuilder.Builder), - "cloudstack": new(cloudstackbuilder.Builder), - "digitalocean": new(digitaloceanbuilder.Builder), - "docker": new(dockerbuilder.Builder), - "file": new(filebuilder.Builder), - "googlecompute": new(googlecomputebuilder.Builder), - "hyperv-iso": new(hypervisobuilder.Builder), - "hyperv-vmcx": new(hypervvmcxbuilder.Builder), - "lxc": new(lxcbuilder.Builder), - "lxd": new(lxdbuilder.Builder), - "null": new(nullbuilder.Builder), - "oneandone": new(oneandonebuilder.Builder), - "openstack": new(openstackbuilder.Builder), - "oracle-oci": new(oracleocibuilder.Builder), - "parallels-iso": new(parallelsisobuilder.Builder), - "parallels-pvm": new(parallelspvmbuilder.Builder), - "profitbricks": new(profitbricksbuilder.Builder), - "qemu": new(qemubuilder.Builder), - "triton": new(tritonbuilder.Builder), - "virtualbox-iso": new(virtualboxisobuilder.Builder), - "virtualbox-ovf": new(virtualboxovfbuilder.Builder), - "vmware-iso": new(vmwareisobuilder.Builder), - "vmware-vmx": new(vmwarevmxbuilder.Builder), + "alicloud-ecs": new(alicloudecsbuilder.Builder), + "amazon-chroot": new(amazonchrootbuilder.Builder), + "amazon-ebs": new(amazonebsbuilder.Builder), + "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), + "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), + "amazon-instance": new(amazoninstancebuilder.Builder), + "azure-arm": new(azurearmbuilder.Builder), + "cloudstack": new(cloudstackbuilder.Builder), + "digitalocean": new(digitaloceanbuilder.Builder), + "docker": new(dockerbuilder.Builder), + "file": new(filebuilder.Builder), + "googlecompute": new(googlecomputebuilder.Builder), + "hyperv-iso": new(hypervisobuilder.Builder), + "hyperv-vmcx": new(hypervvmcxbuilder.Builder), + "lxc": new(lxcbuilder.Builder), + "lxd": new(lxdbuilder.Builder), + "null": new(nullbuilder.Builder), + "oneandone": new(oneandonebuilder.Builder), + "openstack": new(openstackbuilder.Builder), + "oracle-classic": new(oracleclassicbuilder.Builder), + "oracle-oci": new(oracleocibuilder.Builder), + "parallels-iso": new(parallelsisobuilder.Builder), + "parallels-pvm": new(parallelspvmbuilder.Builder), + "profitbricks": new(profitbricksbuilder.Builder), + "qemu": new(qemubuilder.Builder), + "triton": new(tritonbuilder.Builder), + "virtualbox-iso": new(virtualboxisobuilder.Builder), + "virtualbox-ovf": new(virtualboxovfbuilder.Builder), + "vmware-iso": new(vmwareisobuilder.Builder), + "vmware-vmx": new(vmwarevmxbuilder.Builder), } + var Provisioners = map[string]packer.Provisioner{ - "ansible": new(ansibleprovisioner.Provisioner), - "ansible-local": new(ansiblelocalprovisioner.Provisioner), - "chef-client": new(chefclientprovisioner.Provisioner), - "chef-solo": new(chefsoloprovisioner.Provisioner), - "converge": new(convergeprovisioner.Provisioner), - "file": new(fileprovisioner.Provisioner), - "powershell": new(powershellprovisioner.Provisioner), - "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), - "puppet-server": new(puppetserverprovisioner.Provisioner), + "ansible": new(ansibleprovisioner.Provisioner), + "ansible-local": new(ansiblelocalprovisioner.Provisioner), + "chef-client": new(chefclientprovisioner.Provisioner), + "chef-solo": new(chefsoloprovisioner.Provisioner), + "converge": new(convergeprovisioner.Provisioner), + "file": new(fileprovisioner.Provisioner), + "powershell": new(powershellprovisioner.Provisioner), + "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), + "puppet-server": new(puppetserverprovisioner.Provisioner), "salt-masterless": new(saltmasterlessprovisioner.Provisioner), - "shell": new(shellprovisioner.Provisioner), - "shell-local": new(shelllocalprovisioner.Provisioner), + "shell": new(shellprovisioner.Provisioner), + "shell-local": new(shelllocalprovisioner.Provisioner), "windows-restart": new(windowsrestartprovisioner.Provisioner), - "windows-shell": new(windowsshellprovisioner.Provisioner), + "windows-shell": new(windowsshellprovisioner.Provisioner), } + var PostProcessors = map[string]packer.PostProcessor{ - "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), - "amazon-import": new(amazonimportpostprocessor.PostProcessor), - "artifice": new(artificepostprocessor.PostProcessor), - "atlas": new(atlaspostprocessor.PostProcessor), - "checksum": new(checksumpostprocessor.PostProcessor), - "compress": new(compresspostprocessor.PostProcessor), - "docker-import": new(dockerimportpostprocessor.PostProcessor), - "docker-push": new(dockerpushpostprocessor.PostProcessor), - "docker-save": new(dockersavepostprocessor.PostProcessor), - "docker-tag": new(dockertagpostprocessor.PostProcessor), - "googlecompute-export": new(googlecomputeexportpostprocessor.PostProcessor), - "manifest": new(manifestpostprocessor.PostProcessor), - "shell-local": new(shelllocalpostprocessor.PostProcessor), - "vagrant": new(vagrantpostprocessor.PostProcessor), - "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), - "vsphere": new(vspherepostprocessor.PostProcessor), - "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), + "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), + "amazon-import": new(amazonimportpostprocessor.PostProcessor), + "artifice": new(artificepostprocessor.PostProcessor), + "atlas": new(atlaspostprocessor.PostProcessor), + "checksum": new(checksumpostprocessor.PostProcessor), + "compress": new(compresspostprocessor.PostProcessor), + "docker-import": new(dockerimportpostprocessor.PostProcessor), + "docker-push": new(dockerpushpostprocessor.PostProcessor), + "docker-save": new(dockersavepostprocessor.PostProcessor), + "docker-tag": new(dockertagpostprocessor.PostProcessor), + "googlecompute-export": new(googlecomputeexportpostprocessor.PostProcessor), + "manifest": new(manifestpostprocessor.PostProcessor), + "shell-local": new(shelllocalpostprocessor.PostProcessor), + "vagrant": new(vagrantpostprocessor.PostProcessor), + "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), + "vsphere": new(vspherepostprocessor.PostProcessor), + "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), } + var pluginRegexp = regexp.MustCompile("packer-(builder|post-processor|provisioner)-(.+)") func (c *PluginCommand) Run(args []string) int { From 8b420944c5cd86b224c4ef9041560370c15c45c9 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 17 Jan 2018 16:25:38 -0800 Subject: [PATCH 0459/1007] debugs --- builder/oracle/classic/config.go | 2 +- builder/oracle/classic/step_create_instance.go | 2 +- builder/oracle/classic/step_snapshot.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 10ec44c54..8cdd9aff6 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -26,7 +26,7 @@ type Config struct { // Image ImageName string `mapstructure:"image_name"` Shape string `mapstructure:"shape"` - ImageList string `json:"image_list"` + ImageList string `mapstructure:"image_list"` ctx interpolate.Context } diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 7de599190..c13338928 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -14,7 +14,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction // get variables from state ui := state.Get("ui").(packer.Ui) ui.Say("Creating Instance...") - config := state.Get("config").(Config) + config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) sshPublicKey := state.Get("publicKey").(string) diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 2df8976a1..e83df4394 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -14,7 +14,7 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { // get variables from state ui := state.Get("ui").(packer.Ui) ui.Say("Creating Snapshot...") - config := state.Get("config").(Config) + config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) instanceID := state.Get("instance_id").(string) From a8a0072049fb46b2e676e9e3d87471a53ab37fe0 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 17 Jan 2018 16:33:35 -0800 Subject: [PATCH 0460/1007] oops need to add this moved file to git --- builder/oracle/common/ssh.go | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 builder/oracle/common/ssh.go diff --git a/builder/oracle/common/ssh.go b/builder/oracle/common/ssh.go new file mode 100644 index 000000000..aa2780128 --- /dev/null +++ b/builder/oracle/common/ssh.go @@ -0,0 +1,45 @@ +package common + +import ( + "fmt" + + packerssh "github.com/hashicorp/packer/communicator/ssh" + "github.com/mitchellh/multistep" + "golang.org/x/crypto/ssh" +) + +func CommHost(state multistep.StateBag) (string, error) { + ipAddress := state.Get("instance_ip").(string) + return ipAddress, nil +} + +// SSHConfig returns a function that can be used for the SSH communicator +// config for connecting to the instance created over SSH using the private key +// or password. +func SSHConfig(username, password string) func(state multistep.StateBag) (*ssh.ClientConfig, error) { + return func(state multistep.StateBag) (*ssh.ClientConfig, error) { + privateKey, hasKey := state.GetOk("privateKey") + if hasKey { + + signer, err := ssh.ParsePrivateKey([]byte(privateKey.(string))) + if err != nil { + return nil, fmt.Errorf("Error setting up SSH config: %s", err) + } + return &ssh.ClientConfig{ + User: username, + Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + }, nil + + } + + return &ssh.ClientConfig{ + User: username, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + Auth: []ssh.AuthMethod{ + ssh.Password(password), + ssh.KeyboardInteractive(packerssh.PasswordKeyboardInteractive(password)), + }, + }, nil + } +} From 6556a851dcce4f5e494dfaaa7588ea0d5ee696a5 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 18 Jan 2018 13:44:00 -0800 Subject: [PATCH 0461/1007] fix ssh key handling --- builder/amazon/common/step_key_pair.go | 3 +- builder/oracle/classic/builder.go | 3 +- .../oracle/classic/step_create_instance.go | 39 ++++++++++++++++--- vendor/vendor.json | 6 +++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/step_key_pair.go b/builder/amazon/common/step_key_pair.go index 927101fcf..55f5aace7 100644 --- a/builder/amazon/common/step_key_pair.go +++ b/builder/amazon/common/step_key_pair.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "runtime" + "strings" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/helper/multistep" @@ -36,7 +37,7 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep } state.Put("keyPair", s.KeyPairName) - state.Put("privateKey", string(privateKeyBytes)) + state.Put("privateKey", strings.TrimSpace(string(privateKeyBytes))) return multistep.ActionContinue } diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 4501456d2..b7773ee19 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -3,6 +3,7 @@ package classic import ( "fmt" "log" + "strings" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-oracle-terraform/compute" @@ -63,7 +64,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &ocommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), - PrivateKeyFile: b.config.Comm.SSHPrivateKey, + PrivateKeyFile: strings.TrimSpace(b.config.Comm.SSHPrivateKey), }, &stepCreateIPReservation{}, &stepCreateInstance{}, diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index c13338928..fd91ea930 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -2,6 +2,7 @@ package classic import ( "fmt" + "strings" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/packer" @@ -16,18 +17,44 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction ui.Say("Creating Instance...") config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) - sshPublicKey := state.Get("publicKey").(string) + sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) + + // Load the dynamically-generated SSH key into the Oracle Compute cloud. + sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_dynamic_key", config.IdentityDomain, config.Username) + + sshKeysClient := client.SSHKeys() + sshKeysInput := compute.CreateSSHKeyInput{ + Name: sshKeyName, + Key: sshPublicKey, + Enabled: true, + } + keyInfo, err := sshKeysClient.CreateSSHKey(&sshKeysInput) + if err != nil { + // Key already exists; update key instead + if strings.Contains(err.Error(), "packer_dynamic_key already exists") { + updateKeysInput := compute.UpdateSSHKeyInput{ + Name: sshKeyName, + Key: sshPublicKey, + Enabled: true, + } + keyInfo, err = sshKeysClient.UpdateSSHKey(&updateKeysInput) + } else { + err = fmt.Errorf("Problem adding Public SSH key through Oracle's API: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + } // get instances client instanceClient := client.Instances() // Instances Input input := &compute.CreateInstanceInput{ - Name: config.ImageName, - Shape: config.Shape, - ImageList: config.ImageList, - SSHKeys: []string{sshPublicKey}, - Attributes: map[string]interface{}{}, + Name: config.ImageName, + Shape: config.Shape, + ImageList: config.ImageList, + SSHKeys: []string{keyInfo.Name}, } instanceInfo, err := instanceClient.CreateInstance(input) diff --git a/vendor/vendor.json b/vendor/vendor.json index fe36fe283..256c2e1d2 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -785,6 +785,12 @@ "path": "github.com/hashicorp/go-cleanhttp", "revision": "875fb671b3ddc66f8e2f0acc33829c8cb989a38d" }, + { + "checksumSHA1": "1hPCerVn1bWA+9vaAGqnIkRtSFc=", + "path": "github.com/hashicorp/go-getter", + "revision": "cb2c2774e9771bd9568d843be4e59298786550fd", + "revisionTime": "2017-12-20T21:10:09Z" + }, { "checksumSHA1": "lrSl49G23l6NhfilxPM0XFs5rZo=", "path": "github.com/hashicorp/go-multierror", From f208a071a4d4ce941b0fde6a2bea3b5c8d994276 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 18 Jan 2018 15:52:31 -0800 Subject: [PATCH 0462/1007] fix communicator --- builder/oracle/classic/config.go | 6 ++++++ builder/oracle/classic/step_create_instance.go | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 8cdd9aff6..733d2252c 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" ) @@ -48,5 +49,10 @@ func NewConfig(raws ...interface{}) (*Config, error) { return nil, fmt.Errorf("Error parsing API Endpoint: %s", err) } + var errs *packer.MultiError + if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { + errs = packer.MultiErrorAppend(errs, es...) + } + return c, nil } diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index fd91ea930..1456da99e 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -20,7 +20,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) // Load the dynamically-generated SSH key into the Oracle Compute cloud. - sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_dynamic_key", config.IdentityDomain, config.Username) + sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key", config.IdentityDomain, config.Username) sshKeysClient := client.SSHKeys() sshKeysInput := compute.CreateSSHKeyInput{ @@ -31,7 +31,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction keyInfo, err := sshKeysClient.CreateSSHKey(&sshKeysInput) if err != nil { // Key already exists; update key instead - if strings.Contains(err.Error(), "packer_dynamic_key already exists") { + if strings.Contains(err.Error(), "packer_generated_key already exists") { updateKeysInput := compute.UpdateSSHKeyInput{ Name: sshKeyName, Key: sshPublicKey, From 69ba710c2a1661eab9f26239d445b2666864dfb0 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 19 Jan 2018 15:37:06 -0800 Subject: [PATCH 0463/1007] PROGRESS! Now it only fails on the snapshot step --- builder/oracle/classic/builder.go | 3 +- .../classic/step_create_IP_reservation.go | 3 ++ .../oracle/classic/step_create_instance.go | 33 +++++++++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index b7773ee19..4501456d2 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -3,7 +3,6 @@ package classic import ( "fmt" "log" - "strings" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-oracle-terraform/compute" @@ -64,7 +63,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &ocommon.StepKeyPair{ Debug: b.config.PackerDebug, DebugKeyPath: fmt.Sprintf("oci_classic_%s.pem", b.config.PackerBuildName), - PrivateKeyFile: strings.TrimSpace(b.config.Comm.SSHPrivateKey), + PrivateKeyFile: b.config.Comm.SSHPrivateKey, }, &stepCreateIPReservation{}, &stepCreateInstance{}, diff --git a/builder/oracle/classic/step_create_IP_reservation.go b/builder/oracle/classic/step_create_IP_reservation.go index f3f898eaa..f74dd6bb1 100644 --- a/builder/oracle/classic/step_create_IP_reservation.go +++ b/builder/oracle/classic/step_create_IP_reservation.go @@ -1,6 +1,7 @@ package classic import ( + "fmt" "log" "github.com/hashicorp/go-oracle-terraform/compute" @@ -13,12 +14,14 @@ type stepCreateIPReservation struct{} func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating IP reservation...") + config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) iprClient := client.IPReservations() // TODO: add optional Name and Tags IPInput := &compute.CreateIPReservationInput{ ParentPool: compute.PublicReservationPool, Permanent: true, + Name: fmt.Sprintf("ipres_%s", config.ImageName), } ipRes, err := iprClient.CreateIPReservation(IPInput) if err != nil { diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 1456da99e..1cbfcbcc6 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -2,6 +2,7 @@ package classic import ( "fmt" + "log" "strings" "github.com/hashicorp/go-oracle-terraform/compute" @@ -17,9 +18,13 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction ui.Say("Creating Instance...") config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) + + // SSH KEY CONFIGURATION + + // grab packer-generated key from statebag context. sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) - // Load the dynamically-generated SSH key into the Oracle Compute cloud. + // form API call to add key to compute cloud sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key", config.IdentityDomain, config.Username) sshKeysClient := client.SSHKeys() @@ -28,9 +33,11 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction Key: sshPublicKey, Enabled: true, } + + // Load the packer-generated SSH key into the Oracle Compute cloud. keyInfo, err := sshKeysClient.CreateSSHKey(&sshKeysInput) if err != nil { - // Key already exists; update key instead + // Key already exists; update key instead of creating it if strings.Contains(err.Error(), "packer_generated_key already exists") { updateKeysInput := compute.UpdateSSHKeyInput{ Name: sshKeyName, @@ -46,15 +53,29 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction } } + // NETWORKING INFO CONFIGURATION + ipAddName := fmt.Sprintf("ipres_%s", config.ImageName) + log.Printf("MEGAN ipADDName is %s", ipAddName) + secListName := "Megan_packer_test" + + netInfo := compute.NetworkingInfo{ + Nat: []string{ipAddName}, + SecLists: []string{secListName}, + } + fmt.Sprintf("Megan netInfo is %#v", netInfo) + + // INSTANCE LAUNCH + // get instances client instanceClient := client.Instances() // Instances Input input := &compute.CreateInstanceInput{ - Name: config.ImageName, - Shape: config.Shape, - ImageList: config.ImageList, - SSHKeys: []string{keyInfo.Name}, + Name: config.ImageName, + Shape: config.Shape, + ImageList: config.ImageList, + SSHKeys: []string{keyInfo.Name}, + Networking: map[string]compute.NetworkingInfo{"eth0": netInfo}, } instanceInfo, err := instanceClient.CreateInstance(input) From 256382547b0f708a6bb0769d783085d4d253d1db Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 19 Jan 2018 16:00:12 -0800 Subject: [PATCH 0464/1007] snapshot step works --- builder/oracle/classic/step_snapshot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index e83df4394..52c2557c6 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -23,7 +23,7 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { // Instances Input snapshotInput := &compute.CreateSnapshotInput{ - Instance: instanceID, + Instance: fmt.Sprintf("%s/%s", config.ImageName, instanceID), MachineImage: config.ImageName, } From f6c60aac787b54441053fcda79f47ca73cc31c9d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 19 Jan 2018 16:08:42 -0800 Subject: [PATCH 0465/1007] clean up instance --- .../oracle/classic/step_create_instance.go | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 1cbfcbcc6..8c3edf3a3 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -92,5 +92,30 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction } func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { - // Nothing to do + // terminate instance + ui := state.Get("ui").(packer.Ui) + client := state.Get("client").(*compute.ComputeClient) + imID := state.Get("instance_id").(string) + + ui.Say(fmt.Sprintf("Terminating instance (%s)...", id)) + + instanceClient := client.Instances() + // Instances Input + input := &compute.DeleteInstanceInput{ + Name: config.ImageName, + ID: imID, + } + + instanceInfo, err := instanceClient.DeleteInstance(input) + if err != nil { + err = fmt.Errorf("Problem destroying instance: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return + } + + // TODO wait for instance state to change to deleted? + + ui.Say("Terminated instance.") + return } From 89159f3a87a8c7b00dd9c13f0a713b186fc71cd0 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 19 Jan 2018 16:13:36 -0800 Subject: [PATCH 0466/1007] fix bugs in cleanup --- builder/oracle/classic/step_create_instance.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 8c3edf3a3..f33e5d0e5 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -95,9 +95,10 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { // terminate instance ui := state.Get("ui").(packer.Ui) client := state.Get("client").(*compute.ComputeClient) + config := state.Get("config").(*Config) imID := state.Get("instance_id").(string) - ui.Say(fmt.Sprintf("Terminating instance (%s)...", id)) + ui.Say(fmt.Sprintf("Terminating instance (%s)...", imID)) instanceClient := client.Instances() // Instances Input @@ -106,7 +107,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { ID: imID, } - instanceInfo, err := instanceClient.DeleteInstance(input) + err := instanceClient.DeleteInstance(input) if err != nil { err = fmt.Errorf("Problem destroying instance: %s", err) ui.Error(err.Error()) From 53ff257cf0d20f57937d546e988504017e60a58d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 22 Jan 2018 16:54:09 -0800 Subject: [PATCH 0467/1007] it LLIIIIIIIIIVES --- builder/oracle/classic/builder.go | 2 + .../oracle/classic/step_create_instance.go | 49 ++----------------- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 4501456d2..7e8c07f53 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -66,6 +66,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe PrivateKeyFile: b.config.Comm.SSHPrivateKey, }, &stepCreateIPReservation{}, + &stepAddKeysToAPI{}, + &stepSecurity{}, &stepCreateInstance{}, &communicator.StepConnect{ Config: &b.config.Comm, diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index f33e5d0e5..bf89a51e3 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -3,7 +3,6 @@ package classic import ( "fmt" "log" - "strings" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/packer" @@ -18,53 +17,16 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction ui.Say("Creating Instance...") config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) + keyName := state.Get("key_name").(string) - // SSH KEY CONFIGURATION - - // grab packer-generated key from statebag context. - sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) - - // form API call to add key to compute cloud - sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key", config.IdentityDomain, config.Username) - - sshKeysClient := client.SSHKeys() - sshKeysInput := compute.CreateSSHKeyInput{ - Name: sshKeyName, - Key: sshPublicKey, - Enabled: true, - } - - // Load the packer-generated SSH key into the Oracle Compute cloud. - keyInfo, err := sshKeysClient.CreateSSHKey(&sshKeysInput) - if err != nil { - // Key already exists; update key instead of creating it - if strings.Contains(err.Error(), "packer_generated_key already exists") { - updateKeysInput := compute.UpdateSSHKeyInput{ - Name: sshKeyName, - Key: sshPublicKey, - Enabled: true, - } - keyInfo, err = sshKeysClient.UpdateSSHKey(&updateKeysInput) - } else { - err = fmt.Errorf("Problem adding Public SSH key through Oracle's API: %s", err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt - } - } - - // NETWORKING INFO CONFIGURATION ipAddName := fmt.Sprintf("ipres_%s", config.ImageName) - log.Printf("MEGAN ipADDName is %s", ipAddName) - secListName := "Megan_packer_test" + // secListName := "Megan_packer_test" // hack to get working; fix b4 release + secListName := state.Get("security_list").(string) netInfo := compute.NetworkingInfo{ Nat: []string{ipAddName}, SecLists: []string{secListName}, } - fmt.Sprintf("Megan netInfo is %#v", netInfo) - - // INSTANCE LAUNCH // get instances client instanceClient := client.Instances() @@ -74,7 +36,7 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction Name: config.ImageName, Shape: config.Shape, ImageList: config.ImageList, - SSHKeys: []string{keyInfo.Name}, + SSHKeys: []string{keyName}, Networking: map[string]compute.NetworkingInfo{"eth0": netInfo}, } @@ -106,6 +68,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { Name: config.ImageName, ID: imID, } + log.Printf("instance destroy input is %#v", input) err := instanceClient.DeleteInstance(input) if err != nil { @@ -114,9 +77,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { state.Put("error", err) return } - // TODO wait for instance state to change to deleted? - ui.Say("Terminated instance.") return } From 531cb2244d8749c80b1ee07fad2595b175b01133 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 22 Jan 2018 16:54:49 -0800 Subject: [PATCH 0468/1007] add separated out steps --- .../oracle/classic/step_add_keys_to_api.go | 58 +++++++++++++++ builder/oracle/classic/step_security.go | 70 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 builder/oracle/classic/step_add_keys_to_api.go create mode 100644 builder/oracle/classic/step_security.go diff --git a/builder/oracle/classic/step_add_keys_to_api.go b/builder/oracle/classic/step_add_keys_to_api.go new file mode 100644 index 000000000..f28a9bce9 --- /dev/null +++ b/builder/oracle/classic/step_add_keys_to_api.go @@ -0,0 +1,58 @@ +package classic + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type stepAddKeysToAPI struct{} + +func (s *stepAddKeysToAPI) Run(state multistep.StateBag) multistep.StepAction { + // get variables from state + ui := state.Get("ui").(packer.Ui) + ui.Say("Adding SSH keys to API...") + config := state.Get("config").(*Config) + client := state.Get("client").(*compute.ComputeClient) + + // grab packer-generated key from statebag context. + sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) + + // form API call to add key to compute cloud + sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key", config.IdentityDomain, config.Username) + + sshKeysClient := client.SSHKeys() + sshKeysInput := compute.CreateSSHKeyInput{ + Name: sshKeyName, + Key: sshPublicKey, + Enabled: true, + } + + // Load the packer-generated SSH key into the Oracle Compute cloud. + keyInfo, err := sshKeysClient.CreateSSHKey(&sshKeysInput) + if err != nil { + // Key already exists; update key instead of creating it + if strings.Contains(err.Error(), "packer_generated_key already exists") { + updateKeysInput := compute.UpdateSSHKeyInput{ + Name: sshKeyName, + Key: sshPublicKey, + Enabled: true, + } + keyInfo, err = sshKeysClient.UpdateSSHKey(&updateKeysInput) + } else { + err = fmt.Errorf("Problem adding Public SSH key through Oracle's API: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + } + state.Put("key_name", keyInfo.Name) + return multistep.ActionContinue +} + +func (s *stepAddKeysToAPI) Cleanup(state multistep.StateBag) { + // Nothing to do +} diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go new file mode 100644 index 000000000..c907ceb7f --- /dev/null +++ b/builder/oracle/classic/step_security.go @@ -0,0 +1,70 @@ +package classic + +import ( + "fmt" + "log" + "strings" + + "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" +) + +type stepSecurity struct{} + +func (s *stepSecurity) Run(state multistep.StateBag) multistep.StepAction { + // TODO create overrides that allow savvy users to add the image to their + // own security lists instead of ours + ui := state.Get("ui").(packer.Ui) + ui.Say("Configuring security lists and rules...") + config := state.Get("config").(*Config) + client := state.Get("client").(*compute.ComputeClient) + + secListName := fmt.Sprintf("/Compute-%s/%s/Packer_SSH_Allow", + config.IdentityDomain, config.Username) + secListClient := client.SecurityLists() + secListInput := compute.CreateSecurityListInput{ + Description: "Packer-generated security list to give packer ssh access", + Name: secListName, + } + _, err := secListClient.CreateSecurityList(&secListInput) + if err != nil { + if !strings.Contains(err.Error(), "already exists") { + err = fmt.Errorf("Error creating security security IP List to"+ + " allow Packer to connect to Oracle instance via SSH: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + } + secListURI := fmt.Sprintf("%s/seclist/Compute-%s/%s/Packer_SSH_Allow", + config.APIEndpoint, config.IdentityDomain, config.Username) + log.Printf("Megan secListURI is %s", secListURI) + // DOCS NOTE: user must have Compute_Operations role + // Create security rule that allows Packer to connect via SSH + + secRulesClient := client.SecRules() + secRulesInput := compute.CreateSecRuleInput{ + Action: "PERMIT", + Application: "/oracle/public/ssh", + Description: "Packer-generated security rule to allow ssh", + DestinationList: fmt.Sprintf("seclist:%s", secListName), + Name: "Packer-allow-SSH-Rule", + SourceList: "seciplist:/oracle/public/public-internet", + } + + _, err = secRulesClient.CreateSecRule(&secRulesInput) + if err != nil { + err = fmt.Errorf("Error creating security rule to allow Packer to connect to Oracle instance via SSH: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + + state.Put("security_list", secListName) + return multistep.ActionContinue +} + +func (s *stepSecurity) Cleanup(state multistep.StateBag) { + // Nothing to do +} From 7d23cfae0af760cbe6f1a4481387d81216c0a38e Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 23 Jan 2018 11:07:04 -0800 Subject: [PATCH 0469/1007] allow user to add a security list for SSH access; add cleanup for packer-generated rules and lists --- builder/oracle/classic/config.go | 9 ++++ builder/oracle/classic/step_security.go | 59 +++++++++++++++++-------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 733d2252c..eb3fd6876 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -28,6 +28,11 @@ type Config struct { ImageName string `mapstructure:"image_name"` Shape string `mapstructure:"shape"` ImageList string `mapstructure:"image_list"` + // Optional. Describes what computers are allowed to reach your instance + // via SSH. This whitelist must contain the computer you're running Packer + // from. It defaults to public-internet, meaning that you can SSH into your + // instance from anywhere as long as you have the right keys + SSHSourceList string `mapstructure:"ssh_source_list"` ctx interpolate.Context } @@ -48,6 +53,10 @@ func NewConfig(raws ...interface{}) (*Config, error) { if err != nil { return nil, fmt.Errorf("Error parsing API Endpoint: %s", err) } + // set default source list + if c.SSHSourceList == "" { + c.SSHSourceList = "seciplist:/oracle/public/public-internet" + } var errs *packer.MultiError if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index c907ceb7f..d82f2bc41 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -13,15 +13,15 @@ import ( type stepSecurity struct{} func (s *stepSecurity) Run(state multistep.StateBag) multistep.StepAction { - // TODO create overrides that allow savvy users to add the image to their - // own security lists instead of ours ui := state.Get("ui").(packer.Ui) - ui.Say("Configuring security lists and rules...") + + ui.Say("Configuring security lists and rules to enable SSH access...") + config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) - secListName := fmt.Sprintf("/Compute-%s/%s/Packer_SSH_Allow", - config.IdentityDomain, config.Username) + secListName := fmt.Sprintf("/Compute-%s/%s/Packer_SSH_Allow_%s", + config.IdentityDomain, config.Username, config.ImageName) secListClient := client.SecurityLists() secListInput := compute.CreateSecurityListInput{ Description: "Packer-generated security list to give packer ssh access", @@ -30,41 +30,64 @@ func (s *stepSecurity) Run(state multistep.StateBag) multistep.StepAction { _, err := secListClient.CreateSecurityList(&secListInput) if err != nil { if !strings.Contains(err.Error(), "already exists") { - err = fmt.Errorf("Error creating security security IP List to"+ + err = fmt.Errorf("Error creating security List to"+ " allow Packer to connect to Oracle instance via SSH: %s", err) ui.Error(err.Error()) state.Put("error", err) return multistep.ActionHalt } } - secListURI := fmt.Sprintf("%s/seclist/Compute-%s/%s/Packer_SSH_Allow", - config.APIEndpoint, config.IdentityDomain, config.Username) - log.Printf("Megan secListURI is %s", secListURI) // DOCS NOTE: user must have Compute_Operations role // Create security rule that allows Packer to connect via SSH - secRulesClient := client.SecRules() secRulesInput := compute.CreateSecRuleInput{ Action: "PERMIT", Application: "/oracle/public/ssh", Description: "Packer-generated security rule to allow ssh", DestinationList: fmt.Sprintf("seclist:%s", secListName), - Name: "Packer-allow-SSH-Rule", - SourceList: "seciplist:/oracle/public/public-internet", + Name: fmt.Sprintf("Packer-allow-SSH-Rule_%s", config.ImageName), + SourceList: config.SSHSourceList, } + secRuleName := fmt.Sprintf("/Compute-%s/%s/Packer-allow-SSH-Rule_%s", + config.IdentityDomain, config.Username, config.ImageName) _, err = secRulesClient.CreateSecRule(&secRulesInput) if err != nil { - err = fmt.Errorf("Error creating security rule to allow Packer to connect to Oracle instance via SSH: %s", err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt + log.Printf(err.Error()) + if !strings.Contains(err.Error(), "already exists") { + err = fmt.Errorf("Error creating security rule to"+ + " allow Packer to connect to Oracle instance via SSH: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } } - + state.Put("security_rule_name", secRuleName) state.Put("security_list", secListName) return multistep.ActionContinue } func (s *stepSecurity) Cleanup(state multistep.StateBag) { - // Nothing to do + client := state.Get("client").(*compute.ComputeClient) + ui := state.Get("ui").(packer.Ui) + ui.Say("Deleting the packer-generated security rules and lists...") + // delete security list that Packer generated + secListName := state.Get("security_list").(string) + secListClient := client.SecurityLists() + input := compute.DeleteSecurityListInput{Name: secListName} + err := secListClient.DeleteSecurityList(&input) + if err != nil { + ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+ + "please delete manually. (error : %s)", secListName, err.Error())) + } + // delete security rules that Packer generated + secRuleName := state.Get("security_rule_name").(string) + secRulesClient := client.SecRules() + ruleInput := compute.DeleteSecRuleInput{Name: secRuleName} + err = secRulesClient.DeleteSecRule(&ruleInput) + if err != nil { + ui.Say(fmt.Sprintf("Error deleting the packer-generated security rule %s; "+ + "please delete manually. (error: %s)", secRuleName, err.Error())) + } + return } From b9a90b9261708d66ca974ab60596435c093190f7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 23 Jan 2018 14:16:51 -0800 Subject: [PATCH 0470/1007] Check for error when creating ip reso --- ...ate_IP_reservation.go => step_create_ip_reservation.go} | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) rename builder/oracle/classic/{step_create_IP_reservation.go => step_create_ip_reservation.go} (87%) diff --git a/builder/oracle/classic/step_create_IP_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go similarity index 87% rename from builder/oracle/classic/step_create_IP_reservation.go rename to builder/oracle/classic/step_create_ip_reservation.go index f74dd6bb1..733c07e70 100644 --- a/builder/oracle/classic/step_create_IP_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -24,8 +24,11 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc Name: fmt.Sprintf("ipres_%s", config.ImageName), } ipRes, err := iprClient.CreateIPReservation(IPInput) + if err != nil { - log.Printf("Error creating IP Reservation: %s", err) + err := fmt.Errorf("Error creating IP Reservation: %s", err) + state.Put("error", err) + ui.Error(err.Error()) return multistep.ActionHalt } state.Put("instance_ip", ipRes.IP) @@ -34,5 +37,5 @@ func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAc } func (s *stepCreateIPReservation) Cleanup(state multistep.StateBag) { - // Nothing to do + // TODO: delete ip reservation } From 44befb08576804e64a768bcb69aca1694bb668d4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 23 Jan 2018 17:33:03 -0800 Subject: [PATCH 0471/1007] rename --- .../oracle/classic/{step_add_keys_to_api.go => step_add_keys.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename builder/oracle/classic/{step_add_keys_to_api.go => step_add_keys.go} (100%) diff --git a/builder/oracle/classic/step_add_keys_to_api.go b/builder/oracle/classic/step_add_keys.go similarity index 100% rename from builder/oracle/classic/step_add_keys_to_api.go rename to builder/oracle/classic/step_add_keys.go From 603881d9902e105d14a90565cedceb18b734de0e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 23 Jan 2018 18:13:51 -0800 Subject: [PATCH 0472/1007] add oci/classic artifact --- builder/oracle/classic/artifact.go | 28 ++++++++++++++++++++----- builder/oracle/classic/builder.go | 16 ++++++-------- builder/oracle/classic/step_snapshot.go | 1 + 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/builder/oracle/classic/artifact.go b/builder/oracle/classic/artifact.go index ff01b186f..bf1fed0ba 100644 --- a/builder/oracle/classic/artifact.go +++ b/builder/oracle/classic/artifact.go @@ -1,7 +1,15 @@ package classic -// Artifact is an artifact implementation that contains a built Custom Image. +import ( + "fmt" + + "github.com/hashicorp/go-oracle-terraform/compute" +) + +// Artifact is an artifact implementation that contains a Snapshot. type Artifact struct { + Snapshot *compute.Snapshot + driver *compute.ComputeClient } // BuilderId uniquely identifies the builder. @@ -15,13 +23,17 @@ func (a *Artifact) Files() []string { return nil } -// Id returns the OCID of the associated Image. func (a *Artifact) Id() string { - return "" + return a.Snapshot.Name } func (a *Artifact) String() string { - return "" + return fmt.Sprintf("A Snapshot was created: \n"+ + "Name: %s\n"+ + "Instance: %s\n"+ + "MachineImage: %s\n"+ + "URI: %s", + a.Snapshot.Name, a.Snapshot.Instance, a.Snapshot.MachineImage, a.Snapshot.URI) } func (a *Artifact) State(name string) interface{} { @@ -30,5 +42,11 @@ func (a *Artifact) State(name string) interface{} { // Destroy deletes the custom image associated with the artifact. func (a *Artifact) Destroy() error { - return nil + client := a.driver.Snapshots() + mic := a.driver.MachineImages() + input := &compute.DeleteSnapshotInput{ + Snapshot: a.Snapshot.Name, + MachineImage: a.Snapshot.MachineImage, + } + return client.DeleteSnapshot(mic, input) } diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 7e8c07f53..7847ef179 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -89,17 +89,13 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, rawErr.(error) } - /* - // Build the artifact and return it - artifact := &Artifact{ - Image: state.Get("image").(client.Image), - Region: b.config.AccessCfg.Region, - driver: driver, - } + // Build the artifact and return it + artifact := &Artifact{ + Snapshot: state.Get("snapshot").(*compute.Snapshot), + driver: client, + } - return artifact, nil - */ - return nil, nil + return artifact, nil } // Cancel terminates a running build. diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 52c2557c6..2e4e9d7a3 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -35,6 +35,7 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } + state.Put("snapshot", snap) ui.Say(fmt.Sprintf("Created snapshot (%s).", snap.Name)) return multistep.ActionContinue } From 76ea73c5b208fd37d809782d5c12b5f44abb793d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 23 Jan 2018 18:14:10 -0800 Subject: [PATCH 0473/1007] I don't think we need to delete this artifact right now --- builder/oracle/classic/artifact.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/builder/oracle/classic/artifact.go b/builder/oracle/classic/artifact.go index bf1fed0ba..fb7861b04 100644 --- a/builder/oracle/classic/artifact.go +++ b/builder/oracle/classic/artifact.go @@ -42,11 +42,5 @@ func (a *Artifact) State(name string) interface{} { // Destroy deletes the custom image associated with the artifact. func (a *Artifact) Destroy() error { - client := a.driver.Snapshots() - mic := a.driver.MachineImages() - input := &compute.DeleteSnapshotInput{ - Snapshot: a.Snapshot.Name, - MachineImage: a.Snapshot.MachineImage, - } - return client.DeleteSnapshot(mic, input) + return nil } From 1fffbacdd3197b17aac4ebed79ebc53b18847b88 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 25 Jan 2018 09:17:30 -0800 Subject: [PATCH 0474/1007] fix ordering of deleting security rules and lists --- .../oracle/classic/step_create_instance.go | 1 - builder/oracle/classic/step_security.go | 23 +++++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index bf89a51e3..88c108466 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -20,7 +20,6 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction keyName := state.Get("key_name").(string) ipAddName := fmt.Sprintf("ipres_%s", config.ImageName) - // secListName := "Megan_packer_test" // hack to get working; fix b4 release secListName := state.Get("security_list").(string) netInfo := compute.NetworkingInfo{ diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index d82f2bc41..cc965caeb 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -71,23 +71,26 @@ func (s *stepSecurity) Cleanup(state multistep.StateBag) { client := state.Get("client").(*compute.ComputeClient) ui := state.Get("ui").(packer.Ui) ui.Say("Deleting the packer-generated security rules and lists...") - // delete security list that Packer generated - secListName := state.Get("security_list").(string) - secListClient := client.SecurityLists() - input := compute.DeleteSecurityListInput{Name: secListName} - err := secListClient.DeleteSecurityList(&input) - if err != nil { - ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+ - "please delete manually. (error : %s)", secListName, err.Error())) - } + // delete security rules that Packer generated secRuleName := state.Get("security_rule_name").(string) secRulesClient := client.SecRules() ruleInput := compute.DeleteSecRuleInput{Name: secRuleName} - err = secRulesClient.DeleteSecRule(&ruleInput) + err := secRulesClient.DeleteSecRule(&ruleInput) if err != nil { ui.Say(fmt.Sprintf("Error deleting the packer-generated security rule %s; "+ "please delete manually. (error: %s)", secRuleName, err.Error())) } + + // delete security list that Packer generated + secListName := state.Get("security_list").(string) + secListClient := client.SecurityLists() + input := compute.DeleteSecurityListInput{Name: secListName} + err = secListClient.DeleteSecurityList(&input) + if err != nil { + ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+ + "please delete manually. (error : %s)", secListName, err.Error())) + } + return } From 00db189c9c4b6872d7a0baf3031fbc9f2a3d1555 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 25 Jan 2018 14:00:26 -0800 Subject: [PATCH 0475/1007] add docs page --- .../oracle/classic/step_create_instance.go | 1 - .../docs/builders/oracle-classic.html.md | 98 +++++++++++++++++++ website/source/layouts/docs.erb | 3 + 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 website/source/docs/builders/oracle-classic.html.md diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 88c108466..8a96823aa 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -62,7 +62,6 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { ui.Say(fmt.Sprintf("Terminating instance (%s)...", imID)) instanceClient := client.Instances() - // Instances Input input := &compute.DeleteInstanceInput{ Name: config.ImageName, ID: imID, diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md new file mode 100644 index 000000000..08d3d10b1 --- /dev/null +++ b/website/source/docs/builders/oracle-classic.html.md @@ -0,0 +1,98 @@ +--- +description: + The oracle-classic builder is able to create new custom images for use with Oracle + Compute Cloud. +layout: docs +page_title: 'Oracle Classic - Builders' +sidebar_current: 'docs-builders-oracle-classic' +--- + +# Oracle Compute Cloud (Classic) Builder + +Type: `oracle-classic` + +The `oracle-classic` Packer builder is able to create custom images for use +with [Oracle Compute Cloud](https://cloud.oracle.com/compute-classic). The builder +takes a base image, runs any provisioning necessary on the base image after +launching it, and finally snapshots it creating a reusable custom image. + +It is recommended that you familiarise yourself with the +[Key Concepts and Terminology](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/terminology.html) +prior to using this builder if you have not done so already. + +The builder _does not_ manage images. Once it creates an image, it is up to you +to use it or delete it. + +## Authorization + +This builder authenticates API calls to Compute Classic using basic +authentication (user name and password). +To read more, see the [authentication documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/Authentication.html) + +## Configuration Reference + +There are many configuration options available for the `oracle-classic` builder. +This builder currently only works with the SSH communicator. + +### Required + + - `api_endpoint` (string) - This is your custom API endpoint for sending + requests. Instructions for determining your API endpoint can be found + [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/SendRequests.html) + + - `identity_domain` (string) - This is your customer-specific identity domain + as generated by Oracle. If you don't know what your identity domain is, ask + your account administrator. For a little more information, see the Oracle + [documentation](https://docs.oracle.com/en/cloud/get-started/subscriptions-cloud/ocuid/identity-domain-overview.html#GUID-7969F881-5F4D-443E-B86C-9044C8085B8A). + + - `image_list` (string) - This is what image you want to use as your base image. + See the [documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/listing-machine-images.html) + for more details. To see what public image lists are available, you can use + the CLI, as described [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stopc/image-lists-stclr-and-nmcli.html#GUID-DB7E75FE-F752-4FF7-AB70-3C8DCDFCA0FA) + + - `password` (string) - Your account password. + + - `shape` (string) - The template that determines the number of + CPUs, amount of memory, and other resources allocated to a newly created + instance. For more information about shapes, see the documentation [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/machine-images-and-shapes.html). + + - `username` (string) - Your account username. + +### Optional + + - `ssh_username` (string) - The username that Packer will use to SSH into the + instance; defaults to `opc`, the default oracle user, which has sudo + priveliges. If you have already configured users on your machine, you may + prompt Packer to use one of those instead. For more detail, see the + [documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/accessing-oracle-linux-instance-using-ssh.html). + + - `image_name` (string) - The name to assign to the resulting custom image. + +## Basic Example + +Here is a basic example. Note that account specific configuration has been +obfuscated; you will need to add a working `username`, `password`, +`identity_domain`, and `api_endpoint` in order for the example to work. + +``` {.json} +{ + "builders": [ + { + "type": "oracle-classic", + "username": "myuser@myaccount.com", + "password": "supersecretpasswordhere", + "identity_domain": "#######", + "api_endpoint": "https://api-###.compute.###.oraclecloud.com/", + "image_list": "/oracle/public/OL_7.2_UEKR4_x86_64", + "shape": "oc3", + "image_name": "Packer_Builder_Test_{{timestamp}}" + } + ], + "provisioners": [ + { + "type": "shell", + "inline": ["echo hello"] + } + ] +} +``` diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 9aa17ccc4..739b33733 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -131,6 +131,9 @@ <li<%= sidebar_current("docs-builders-openstack") %>> <a href="/docs/builders/openstack.html">OpenStack</a> </li> + <li<%= sidebar_current("docs-builders-oracle-classic") %>> + <a href="/docs/builders/oracle-classic.html">Oracle Classic</a> + </li> <li<%= sidebar_current("docs-builders-oracle-oci") %>> <a href="/docs/builders/oracle-oci.html">Oracle OCI</a> </li> From 7d85b31b29fc116cc5c0945b11b568f3865efad2 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 25 Jan 2018 14:01:34 -0800 Subject: [PATCH 0476/1007] make fmt --- command/plugin.go | 176 ++++++++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 90 deletions(-) diff --git a/command/plugin.go b/command/plugin.go index 4f4228fc3..91b052340 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -14,39 +14,21 @@ import ( "github.com/hashicorp/packer/packer/plugin" alicloudecsbuilder "github.com/hashicorp/packer/builder/alicloud/ecs" - alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" amazonchrootbuilder "github.com/hashicorp/packer/builder/amazon/chroot" amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" amazonebssurrogatebuilder "github.com/hashicorp/packer/builder/amazon/ebssurrogate" amazonebsvolumebuilder "github.com/hashicorp/packer/builder/amazon/ebsvolume" - amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" amazoninstancebuilder "github.com/hashicorp/packer/builder/amazon/instance" - ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" - ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" - artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" - atlaspostprocessor "github.com/hashicorp/packer/post-processor/atlas" azurearmbuilder "github.com/hashicorp/packer/builder/azure/arm" - checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" - chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" - chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" cloudstackbuilder "github.com/hashicorp/packer/builder/cloudstack" - compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" - convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" digitaloceanbuilder "github.com/hashicorp/packer/builder/digitalocean" dockerbuilder "github.com/hashicorp/packer/builder/docker" - dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" - dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" - dockersavepostprocessor "github.com/hashicorp/packer/post-processor/docker-save" - dockertagpostprocessor "github.com/hashicorp/packer/post-processor/docker-tag" filebuilder "github.com/hashicorp/packer/builder/file" - fileprovisioner "github.com/hashicorp/packer/provisioner/file" googlecomputebuilder "github.com/hashicorp/packer/builder/googlecompute" - googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" hypervisobuilder "github.com/hashicorp/packer/builder/hyperv/iso" hypervvmcxbuilder "github.com/hashicorp/packer/builder/hyperv/vmcx" lxcbuilder "github.com/hashicorp/packer/builder/lxc" lxdbuilder "github.com/hashicorp/packer/builder/lxd" - manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" nullbuilder "github.com/hashicorp/packer/builder/null" oneandonebuilder "github.com/hashicorp/packer/builder/oneandone" openstackbuilder "github.com/hashicorp/packer/builder/openstack" @@ -54,27 +36,44 @@ import ( oracleocibuilder "github.com/hashicorp/packer/builder/oracle/oci" parallelsisobuilder "github.com/hashicorp/packer/builder/parallels/iso" parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" - powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" - puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" - puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" qemubuilder "github.com/hashicorp/packer/builder/qemu" - saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" - shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" - shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" - shellprovisioner "github.com/hashicorp/packer/provisioner/shell" tritonbuilder "github.com/hashicorp/packer/builder/triton" - vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" - vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" vmwareisobuilder "github.com/hashicorp/packer/builder/vmware/iso" vmwarevmxbuilder "github.com/hashicorp/packer/builder/vmware/vmx" + alicloudimportpostprocessor "github.com/hashicorp/packer/post-processor/alicloud-import" + amazonimportpostprocessor "github.com/hashicorp/packer/post-processor/amazon-import" + artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice" + atlaspostprocessor "github.com/hashicorp/packer/post-processor/atlas" + checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum" + compresspostprocessor "github.com/hashicorp/packer/post-processor/compress" + dockerimportpostprocessor "github.com/hashicorp/packer/post-processor/docker-import" + dockerpushpostprocessor "github.com/hashicorp/packer/post-processor/docker-push" + dockersavepostprocessor "github.com/hashicorp/packer/post-processor/docker-save" + dockertagpostprocessor "github.com/hashicorp/packer/post-processor/docker-tag" + googlecomputeexportpostprocessor "github.com/hashicorp/packer/post-processor/googlecompute-export" + manifestpostprocessor "github.com/hashicorp/packer/post-processor/manifest" + shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local" + vagrantpostprocessor "github.com/hashicorp/packer/post-processor/vagrant" + vagrantcloudpostprocessor "github.com/hashicorp/packer/post-processor/vagrant-cloud" vspherepostprocessor "github.com/hashicorp/packer/post-processor/vsphere" vspheretemplatepostprocessor "github.com/hashicorp/packer/post-processor/vsphere-template" + ansibleprovisioner "github.com/hashicorp/packer/provisioner/ansible" + ansiblelocalprovisioner "github.com/hashicorp/packer/provisioner/ansible-local" + chefclientprovisioner "github.com/hashicorp/packer/provisioner/chef-client" + chefsoloprovisioner "github.com/hashicorp/packer/provisioner/chef-solo" + convergeprovisioner "github.com/hashicorp/packer/provisioner/converge" + fileprovisioner "github.com/hashicorp/packer/provisioner/file" + powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell" + puppetmasterlessprovisioner "github.com/hashicorp/packer/provisioner/puppet-masterless" + puppetserverprovisioner "github.com/hashicorp/packer/provisioner/puppet-server" + saltmasterlessprovisioner "github.com/hashicorp/packer/provisioner/salt-masterless" + shellprovisioner "github.com/hashicorp/packer/provisioner/shell" + shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local" windowsrestartprovisioner "github.com/hashicorp/packer/provisioner/windows-restart" windowsshellprovisioner "github.com/hashicorp/packer/provisioner/windows-shell" - ) type PluginCommand struct { @@ -82,78 +81,75 @@ type PluginCommand struct { } var Builders = map[string]packer.Builder{ - "alicloud-ecs": new(alicloudecsbuilder.Builder), - "amazon-chroot": new(amazonchrootbuilder.Builder), - "amazon-ebs": new(amazonebsbuilder.Builder), - "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), - "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), - "amazon-instance": new(amazoninstancebuilder.Builder), - "azure-arm": new(azurearmbuilder.Builder), - "cloudstack": new(cloudstackbuilder.Builder), - "digitalocean": new(digitaloceanbuilder.Builder), - "docker": new(dockerbuilder.Builder), - "file": new(filebuilder.Builder), - "googlecompute": new(googlecomputebuilder.Builder), - "hyperv-iso": new(hypervisobuilder.Builder), - "hyperv-vmcx": new(hypervvmcxbuilder.Builder), - "lxc": new(lxcbuilder.Builder), - "lxd": new(lxdbuilder.Builder), - "null": new(nullbuilder.Builder), - "oneandone": new(oneandonebuilder.Builder), - "openstack": new(openstackbuilder.Builder), - "oracle-classic": new(oracleclassicbuilder.Builder), - "oracle-oci": new(oracleocibuilder.Builder), - "parallels-iso": new(parallelsisobuilder.Builder), - "parallels-pvm": new(parallelspvmbuilder.Builder), - "profitbricks": new(profitbricksbuilder.Builder), - "qemu": new(qemubuilder.Builder), - "triton": new(tritonbuilder.Builder), - "virtualbox-iso": new(virtualboxisobuilder.Builder), - "virtualbox-ovf": new(virtualboxovfbuilder.Builder), - "vmware-iso": new(vmwareisobuilder.Builder), - "vmware-vmx": new(vmwarevmxbuilder.Builder), + "alicloud-ecs": new(alicloudecsbuilder.Builder), + "amazon-chroot": new(amazonchrootbuilder.Builder), + "amazon-ebs": new(amazonebsbuilder.Builder), + "amazon-ebssurrogate": new(amazonebssurrogatebuilder.Builder), + "amazon-ebsvolume": new(amazonebsvolumebuilder.Builder), + "amazon-instance": new(amazoninstancebuilder.Builder), + "azure-arm": new(azurearmbuilder.Builder), + "cloudstack": new(cloudstackbuilder.Builder), + "digitalocean": new(digitaloceanbuilder.Builder), + "docker": new(dockerbuilder.Builder), + "file": new(filebuilder.Builder), + "googlecompute": new(googlecomputebuilder.Builder), + "hyperv-iso": new(hypervisobuilder.Builder), + "hyperv-vmcx": new(hypervvmcxbuilder.Builder), + "lxc": new(lxcbuilder.Builder), + "lxd": new(lxdbuilder.Builder), + "null": new(nullbuilder.Builder), + "oneandone": new(oneandonebuilder.Builder), + "openstack": new(openstackbuilder.Builder), + "oracle-classic": new(oracleclassicbuilder.Builder), + "oracle-oci": new(oracleocibuilder.Builder), + "parallels-iso": new(parallelsisobuilder.Builder), + "parallels-pvm": new(parallelspvmbuilder.Builder), + "profitbricks": new(profitbricksbuilder.Builder), + "qemu": new(qemubuilder.Builder), + "triton": new(tritonbuilder.Builder), + "virtualbox-iso": new(virtualboxisobuilder.Builder), + "virtualbox-ovf": new(virtualboxovfbuilder.Builder), + "vmware-iso": new(vmwareisobuilder.Builder), + "vmware-vmx": new(vmwarevmxbuilder.Builder), } - var Provisioners = map[string]packer.Provisioner{ - "ansible": new(ansibleprovisioner.Provisioner), - "ansible-local": new(ansiblelocalprovisioner.Provisioner), - "chef-client": new(chefclientprovisioner.Provisioner), - "chef-solo": new(chefsoloprovisioner.Provisioner), - "converge": new(convergeprovisioner.Provisioner), - "file": new(fileprovisioner.Provisioner), - "powershell": new(powershellprovisioner.Provisioner), - "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), - "puppet-server": new(puppetserverprovisioner.Provisioner), + "ansible": new(ansibleprovisioner.Provisioner), + "ansible-local": new(ansiblelocalprovisioner.Provisioner), + "chef-client": new(chefclientprovisioner.Provisioner), + "chef-solo": new(chefsoloprovisioner.Provisioner), + "converge": new(convergeprovisioner.Provisioner), + "file": new(fileprovisioner.Provisioner), + "powershell": new(powershellprovisioner.Provisioner), + "puppet-masterless": new(puppetmasterlessprovisioner.Provisioner), + "puppet-server": new(puppetserverprovisioner.Provisioner), "salt-masterless": new(saltmasterlessprovisioner.Provisioner), - "shell": new(shellprovisioner.Provisioner), - "shell-local": new(shelllocalprovisioner.Provisioner), + "shell": new(shellprovisioner.Provisioner), + "shell-local": new(shelllocalprovisioner.Provisioner), "windows-restart": new(windowsrestartprovisioner.Provisioner), - "windows-shell": new(windowsshellprovisioner.Provisioner), + "windows-shell": new(windowsshellprovisioner.Provisioner), } - var PostProcessors = map[string]packer.PostProcessor{ - "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), - "amazon-import": new(amazonimportpostprocessor.PostProcessor), - "artifice": new(artificepostprocessor.PostProcessor), - "atlas": new(atlaspostprocessor.PostProcessor), - "checksum": new(checksumpostprocessor.PostProcessor), - "compress": new(compresspostprocessor.PostProcessor), - "docker-import": new(dockerimportpostprocessor.PostProcessor), - "docker-push": new(dockerpushpostprocessor.PostProcessor), - "docker-save": new(dockersavepostprocessor.PostProcessor), - "docker-tag": new(dockertagpostprocessor.PostProcessor), - "googlecompute-export": new(googlecomputeexportpostprocessor.PostProcessor), - "manifest": new(manifestpostprocessor.PostProcessor), - "shell-local": new(shelllocalpostprocessor.PostProcessor), - "vagrant": new(vagrantpostprocessor.PostProcessor), - "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), - "vsphere": new(vspherepostprocessor.PostProcessor), - "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), + "alicloud-import": new(alicloudimportpostprocessor.PostProcessor), + "amazon-import": new(amazonimportpostprocessor.PostProcessor), + "artifice": new(artificepostprocessor.PostProcessor), + "atlas": new(atlaspostprocessor.PostProcessor), + "checksum": new(checksumpostprocessor.PostProcessor), + "compress": new(compresspostprocessor.PostProcessor), + "docker-import": new(dockerimportpostprocessor.PostProcessor), + "docker-push": new(dockerpushpostprocessor.PostProcessor), + "docker-save": new(dockersavepostprocessor.PostProcessor), + "docker-tag": new(dockertagpostprocessor.PostProcessor), + "googlecompute-export": new(googlecomputeexportpostprocessor.PostProcessor), + "manifest": new(manifestpostprocessor.PostProcessor), + "shell-local": new(shelllocalpostprocessor.PostProcessor), + "vagrant": new(vagrantpostprocessor.PostProcessor), + "vagrant-cloud": new(vagrantcloudpostprocessor.PostProcessor), + "vsphere": new(vspherepostprocessor.PostProcessor), + "vsphere-template": new(vspheretemplatepostprocessor.PostProcessor), } - var pluginRegexp = regexp.MustCompile("packer-(builder|post-processor|provisioner)-(.+)") func (c *PluginCommand) Run(args []string) int { From dd2384483bb37fcb51e15b0ffb16cfe7bf844811 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 14:42:39 -0800 Subject: [PATCH 0477/1007] add context to steps --- builder/oracle/classic/step_add_keys.go | 2 +- builder/oracle/classic/step_create_instance.go | 2 +- builder/oracle/classic/step_create_ip_reservation.go | 2 +- builder/oracle/classic/step_security.go | 2 +- builder/oracle/classic/step_snapshot.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index f28a9bce9..accb613de 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -11,7 +11,7 @@ import ( type stepAddKeysToAPI struct{} -func (s *stepAddKeysToAPI) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state ui := state.Get("ui").(packer.Ui) ui.Say("Adding SSH keys to API...") diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 8a96823aa..65b7d8736 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -11,7 +11,7 @@ import ( type stepCreateInstance struct{} -func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state ui := state.Get("ui").(packer.Ui) ui.Say("Creating Instance...") diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index 733c07e70..d57aa41ea 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -11,7 +11,7 @@ import ( type stepCreateIPReservation struct{} -func (s *stepCreateIPReservation) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Creating IP reservation...") config := state.Get("config").(*Config) diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index cc965caeb..c3184f36d 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -12,7 +12,7 @@ import ( type stepSecurity struct{} -func (s *stepSecurity) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) ui.Say("Configuring security lists and rules to enable SSH access...") diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 2e4e9d7a3..5fa838e0e 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -10,7 +10,7 @@ import ( type stepSnapshot struct{} -func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state ui := state.Get("ui").(packer.Ui) ui.Say("Creating Snapshot...") From 6dc0bd759ad1eae8ffeec67a3fe916d7f1cf9ae6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 14:43:55 -0800 Subject: [PATCH 0478/1007] import context --- builder/oracle/classic/step_add_keys.go | 1 + builder/oracle/classic/step_create_instance.go | 1 + builder/oracle/classic/step_create_ip_reservation.go | 1 + builder/oracle/classic/step_security.go | 1 + builder/oracle/classic/step_snapshot.go | 1 + 5 files changed, 5 insertions(+) diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index accb613de..4e9c46d61 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -1,6 +1,7 @@ package classic import ( + "context" "fmt" "strings" diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 65b7d8736..a0183832d 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -1,6 +1,7 @@ package classic import ( + "context" "fmt" "log" diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index d57aa41ea..034cf5925 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -1,6 +1,7 @@ package classic import ( + "context" "fmt" "log" diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index c3184f36d..5cfc0e0d5 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -1,6 +1,7 @@ package classic import ( + "context" "fmt" "log" "strings" diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 5fa838e0e..4d1c531a7 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -1,6 +1,7 @@ package classic import ( + "context" "fmt" "github.com/hashicorp/go-oracle-terraform/compute" From 4dc42942f5597a2155ac221b9c59fe7f53285ccd Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 14:45:09 -0800 Subject: [PATCH 0479/1007] fix multistep path --- builder/oracle/classic/builder.go | 2 +- builder/oracle/classic/step_add_keys.go | 2 +- builder/oracle/classic/step_create_instance.go | 2 +- builder/oracle/classic/step_create_ip_reservation.go | 2 +- builder/oracle/classic/step_security.go | 2 +- builder/oracle/classic/step_snapshot.go | 2 +- builder/oracle/common/ssh.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 7847ef179..fd084b366 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -10,8 +10,8 @@ import ( ocommon "github.com/hashicorp/packer/builder/oracle/common" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // BuilderId uniquely identifies the builder diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index 4e9c46d61..e8013cf88 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepAddKeysToAPI struct{} diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index a0183832d..9438431bb 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -6,8 +6,8 @@ import ( "log" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateInstance struct{} diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index 034cf5925..f24de7766 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -6,8 +6,8 @@ import ( "log" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepCreateIPReservation struct{} diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 5cfc0e0d5..1e00b2c7b 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepSecurity struct{} diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 4d1c531a7..30a7d32c8 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type stepSnapshot struct{} diff --git a/builder/oracle/common/ssh.go b/builder/oracle/common/ssh.go index aa2780128..8e448e592 100644 --- a/builder/oracle/common/ssh.go +++ b/builder/oracle/common/ssh.go @@ -4,7 +4,7 @@ import ( "fmt" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" ) From 7f21ca546ddc0198af14738c46ac7c2e95b92a43 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 14:47:30 -0800 Subject: [PATCH 0480/1007] we're not using go-getter --- vendor/vendor.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/vendor/vendor.json b/vendor/vendor.json index 256c2e1d2..fe36fe283 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -785,12 +785,6 @@ "path": "github.com/hashicorp/go-cleanhttp", "revision": "875fb671b3ddc66f8e2f0acc33829c8cb989a38d" }, - { - "checksumSHA1": "1hPCerVn1bWA+9vaAGqnIkRtSFc=", - "path": "github.com/hashicorp/go-getter", - "revision": "cb2c2774e9771bd9568d843be4e59298786550fd", - "revisionTime": "2017-12-20T21:10:09Z" - }, { "checksumSHA1": "lrSl49G23l6NhfilxPM0XFs5rZo=", "path": "github.com/hashicorp/go-multierror", From 48105e74bd4c570194eea0736196935684122729 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 14:52:40 -0800 Subject: [PATCH 0481/1007] add note about upload-bundle iam perms --- website/source/docs/builders/amazon-instance.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index e9d633269..9e8ca833a 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -484,3 +484,6 @@ parameters they're used to satisfy the `ec2-upload-bundle` command. Additionally, `{{.Token}}` is available when overriding this command. You must create your own bundle command with the addition of `-t {{.Token}} ` if you are assuming a role. + +~&gt; **Note:** If using IAM roles to run `ec2-upload-bundle`, make sure the +role has the `s3:GetBucketLocation` and `s3:PutObjectAcl` permissions. From 0fad49e897ea9446cacffb0d2c80a27ec8acd495 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 15:05:36 -0800 Subject: [PATCH 0482/1007] simplify --- builder/oracle/classic/step_create_instance.go | 1 - builder/oracle/classic/step_security.go | 2 -- 2 files changed, 3 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 9438431bb..2f8493fd1 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -78,5 +78,4 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { } // TODO wait for instance state to change to deleted? ui.Say("Terminated instance.") - return } diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 1e00b2c7b..8b1c48a4c 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -92,6 +92,4 @@ func (s *stepSecurity) Cleanup(state multistep.StateBag) { ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+ "please delete manually. (error : %s)", secListName, err.Error())) } - - return } From a4518f8ac837ab28dd69f8fe471feaee57c2ba17 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 15:22:34 -0800 Subject: [PATCH 0483/1007] show a policy doc for `ec2-upload-bundle` --- .../docs/builders/amazon-instance.html.md | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 9e8ca833a..f9732908c 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -485,5 +485,27 @@ Additionally, `{{.Token}}` is available when overriding this command. You must create your own bundle command with the addition of `-t {{.Token}} ` if you are assuming a role. -~&gt; **Note:** If using IAM roles to run `ec2-upload-bundle`, make sure the -role has the `s3:GetBucketLocation` and `s3:PutObjectAcl` permissions. +#### Bundle Upload Permissions + +The `ec2-upload-bundle` requires a policy document that looks something like this: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucket", + "s3:GetBucketLocation", + "s3:PutObjectAcl" + ], + "Resource": "*" + } + ] +} +``` + +You may wish to constrain the resource to a specific bucket. From 77277ebc98d0337d4c9507d957eda925c0e9a20b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 16:12:03 -0800 Subject: [PATCH 0484/1007] add logging behind "PACKER_OCI_CLASSIC_LOGGING" env var --- builder/oracle/classic/builder.go | 3 +++ builder/oracle/classic/log.go | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 builder/oracle/classic/log.go diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index fd084b366..7c682b875 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -3,6 +3,7 @@ package classic import ( "fmt" "log" + "os" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-oracle-terraform/compute" @@ -35,6 +36,7 @@ func (b *Builder) Prepare(rawConfig ...interface{}) ([]string, error) { func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + loggingEnabled := os.Getenv("PACKER_OCI_CLASSIC_LOGGING")) != "" httpClient := cleanhttp.DefaultClient() config := &opc.Config{ Username: opc.String(b.config.Username), @@ -42,6 +44,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe IdentityDomain: opc.String(b.config.IdentityDomain), APIEndpoint: b.config.apiEndpointURL, LogLevel: opc.LogDebug, + Logger: &Logger{loggingEnabled}, // Logger: # Leave blank to use the default logger, or provide your own HTTPClient: httpClient, } diff --git a/builder/oracle/classic/log.go b/builder/oracle/classic/log.go new file mode 100644 index 000000000..7389dc057 --- /dev/null +++ b/builder/oracle/classic/log.go @@ -0,0 +1,14 @@ +package classic + +import "log" + +type Logger struct { + Enabled bool +} + +func (l *Logger) Log(input ...interface{}) { + if !l.Enabled { + return + } + log.Println(input...) +} From dbf5d52c43bfe83bbd3a6fc05b4e41032d407cf1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 16:20:14 -0800 Subject: [PATCH 0485/1007] update mapstructure library --- .../mitchellh/mapstructure/README.md | 2 +- .../mitchellh/mapstructure/decode_hooks.go | 19 +- .../mitchellh/mapstructure/mapstructure.go | 266 ++++++++++++++---- vendor/vendor.json | 5 +- 4 files changed, 231 insertions(+), 61 deletions(-) diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md index 659d6885f..7ecc785e4 100644 --- a/vendor/github.com/mitchellh/mapstructure/README.md +++ b/vendor/github.com/mitchellh/mapstructure/README.md @@ -1,4 +1,4 @@ -# mapstructure +# mapstructure [![Godoc](https://godoc.org/github.com/mitchell/mapstructure?status.svg)](https://godoc.org/github.com/mitchell/mapstructure) mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go index aa91f76ce..afcfd5eed 100644 --- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go @@ -38,12 +38,6 @@ func DecodeHookExec( raw DecodeHookFunc, from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) { - // Build our arguments that reflect expects - argVals := make([]reflect.Value, 3) - argVals[0] = reflect.ValueOf(from) - argVals[1] = reflect.ValueOf(to) - argVals[2] = reflect.ValueOf(data) - switch f := typedDecodeHook(raw).(type) { case DecodeHookFuncType: return f(from, to, data) @@ -72,7 +66,10 @@ func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { } // Modify the from kind to be correct with the new data - f = reflect.ValueOf(data).Type() + f = nil + if val := reflect.ValueOf(data); val.IsValid() { + f = val.Type() + } } return data, nil @@ -118,6 +115,11 @@ func StringToTimeDurationHookFunc() DecodeHookFunc { } } +// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to +// the decoder. +// +// Note that this is significantly different from the WeaklyTypedInput option +// of the DecoderConfig. func WeaklyTypedHook( f reflect.Kind, t reflect.Kind, @@ -129,9 +131,8 @@ func WeaklyTypedHook( case reflect.Bool: if dataVal.Bool() { return "1", nil - } else { - return "0", nil } + return "0", nil case reflect.Float32: return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil case reflect.Int: diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go index 40be5116d..39ec1e943 100644 --- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -1,5 +1,5 @@ -// The mapstructure package exposes functionality to convert an -// abitrary map[string]interface{} into a native Go structure. +// Package mapstructure exposes functionality to convert an arbitrary +// map[string]interface{} into a native Go structure. // // The Go structure can be arbitrarily complex, containing slices, // other structs, etc. and the decoder will properly decode nested @@ -8,6 +8,7 @@ package mapstructure import ( + "encoding/json" "errors" "fmt" "reflect" @@ -31,7 +32,12 @@ import ( // both. type DecodeHookFunc interface{} +// DecodeHookFuncType is a DecodeHookFunc which has complete information about +// the source and target types. type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error) + +// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the +// source and target types. type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) // DecoderConfig is the configuration that is used to create a new decoder @@ -67,6 +73,10 @@ type DecoderConfig struct { // FALSE, false, False. Anything else is an error) // - empty array = empty map and vice versa // - negative numbers to overflowed uint values (base 10) + // - slice of maps to a merged map + // - single values are converted to slices if required. Each + // element is weakly decoded. For example: "4" can become []int{4} + // if the target type is an int slice. // WeaklyTypedInput bool @@ -200,7 +210,7 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error d.config.DecodeHook, dataVal.Type(), val.Type(), data) if err != nil { - return err + return fmt.Errorf("error decoding '%s': %s", name, err) } } @@ -227,6 +237,10 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error err = d.decodePtr(name, data, val) case reflect.Slice: err = d.decodeSlice(name, data, val) + case reflect.Array: + err = d.decodeArray(name, data, val) + case reflect.Func: + err = d.decodeFunc(name, data, val) default: // If we reached this point then we weren't able to decode it return fmt.Errorf("%s: unsupported type: %s", name, dataKind) @@ -245,6 +259,10 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error // value to "data" of that type. func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error { dataVal := reflect.ValueOf(data) + if !dataVal.IsValid() { + dataVal = reflect.Zero(val.Type()) + } + dataValType := dataVal.Type() if !dataValType.AssignableTo(val.Type()) { return fmt.Errorf( @@ -276,12 +294,22 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) - case dataKind == reflect.Slice && d.config.WeaklyTypedInput: + case dataKind == reflect.Slice && d.config.WeaklyTypedInput, + dataKind == reflect.Array && d.config.WeaklyTypedInput: dataType := dataVal.Type() elemKind := dataType.Elem().Kind() - switch { - case elemKind == reflect.Uint8: - val.SetString(string(dataVal.Interface().([]uint8))) + switch elemKind { + case reflect.Uint8: + var uints []uint8 + if dataKind == reflect.Array { + uints = make([]uint8, dataVal.Len(), dataVal.Len()) + for i := range uints { + uints[i] = dataVal.Index(i).Interface().(uint8) + } + } else { + uints = dataVal.Interface().([]uint8) + } + val.SetString(string(uints)) default: converted = false } @@ -301,6 +329,7 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error { dataVal := reflect.ValueOf(data) dataKind := getKind(dataVal) + dataType := dataVal.Type() switch { case dataKind == reflect.Int: @@ -322,6 +351,14 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er } else { return fmt.Errorf("cannot parse '%s' as int: %s", name, err) } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Int64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetInt(i) default: return fmt.Errorf( "'%s' expected type '%s', got unconvertible type '%s'", @@ -408,6 +445,7 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error { dataVal := reflect.ValueOf(data) dataKind := getKind(dataVal) + dataType := dataVal.Type() switch { case dataKind == reflect.Int: @@ -415,7 +453,7 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) case dataKind == reflect.Uint: val.SetFloat(float64(dataVal.Uint())) case dataKind == reflect.Float32: - val.SetFloat(float64(dataVal.Float())) + val.SetFloat(dataVal.Float()) case dataKind == reflect.Bool && d.config.WeaklyTypedInput: if dataVal.Bool() { val.SetFloat(1) @@ -429,6 +467,14 @@ func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) } else { return fmt.Errorf("cannot parse '%s' as float: %s", name, err) } + case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": + jn := data.(json.Number) + i, err := jn.Float64() + if err != nil { + return fmt.Errorf( + "error decoding json.Number into %s: %s", name, err) + } + val.SetFloat(i) default: return fmt.Errorf( "'%s' expected type '%s', got unconvertible type '%s'", @@ -456,15 +502,30 @@ func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) er // Check input type dataVal := reflect.Indirect(reflect.ValueOf(data)) if dataVal.Kind() != reflect.Map { - // Accept empty array/slice instead of an empty map in weakly typed mode - if d.config.WeaklyTypedInput && - (dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) && - dataVal.Len() == 0 { - val.Set(valMap) - return nil - } else { - return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) + // In weak mode, we accept a slice of maps as an input... + if d.config.WeaklyTypedInput { + switch dataVal.Kind() { + case reflect.Array, reflect.Slice: + // Special case for BC reasons (covered by tests) + if dataVal.Len() == 0 { + val.Set(valMap) + return nil + } + + for i := 0; i < dataVal.Len(); i++ { + err := d.decode( + fmt.Sprintf("%s[%d]", name, i), + dataVal.Index(i).Interface(), val) + if err != nil { + return err + } + } + + return nil + } } + + return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) } // Accumulate errors @@ -507,7 +568,12 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er // into that. Then set the value of the pointer to this type. valType := val.Type() valElemType := valType.Elem() - realVal := reflect.New(valElemType) + + realVal := val + if realVal.IsNil() || d.config.ZeroFields { + realVal = reflect.New(valElemType) + } + if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { return err } @@ -516,6 +582,19 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er return nil } +func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error { + // Create an element of the concrete (non pointer) type and decode + // into that. Then set the value of the pointer to this type. + dataVal := reflect.Indirect(reflect.ValueOf(data)) + if val.Type() != dataVal.Type() { + return fmt.Errorf( + "'%s' expected type '%s', got unconvertible type '%s'", + name, val.Type(), dataVal.Type()) + } + val.Set(dataVal) + return nil +} + func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { dataVal := reflect.Indirect(reflect.ValueOf(data)) dataValKind := dataVal.Kind() @@ -523,26 +602,44 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) valElemType := valType.Elem() sliceType := reflect.SliceOf(valElemType) - // Check input type - if dataValKind != reflect.Array && dataValKind != reflect.Slice { - // Accept empty map instead of array/slice in weakly typed mode - if d.config.WeaklyTypedInput && dataVal.Kind() == reflect.Map && dataVal.Len() == 0 { - val.Set(reflect.MakeSlice(sliceType, 0, 0)) - return nil - } else { + valSlice := val + if valSlice.IsNil() || d.config.ZeroFields { + // Check input type + if dataValKind != reflect.Array && dataValKind != reflect.Slice { + if d.config.WeaklyTypedInput { + switch { + // Empty maps turn into empty slices + case dataValKind == reflect.Map: + if dataVal.Len() == 0 { + val.Set(reflect.MakeSlice(sliceType, 0, 0)) + return nil + } + + // All other types we try to convert to the slice type + // and "lift" it into it. i.e. a string becomes a string slice. + default: + // Just re-try this function with data as a slice. + return d.decodeSlice(name, []interface{}{data}, val) + } + } + return fmt.Errorf( "'%s': source data must be an array or slice, got %s", name, dataValKind) - } - } - // Make a new slice to hold our result, same size as the original data. - valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) + } + + // Make a new slice to hold our result, same size as the original data. + valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) + } // Accumulate any errors errors := make([]string, 0) for i := 0; i < dataVal.Len(); i++ { currentData := dataVal.Index(i).Interface() + for valSlice.Len() <= i { + valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) + } currentField := valSlice.Index(i) fieldName := fmt.Sprintf("%s[%d]", name, i) @@ -562,6 +659,73 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) return nil } +func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + dataValKind := dataVal.Kind() + valType := val.Type() + valElemType := valType.Elem() + arrayType := reflect.ArrayOf(valType.Len(), valElemType) + + valArray := val + + if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { + // Check input type + if dataValKind != reflect.Array && dataValKind != reflect.Slice { + if d.config.WeaklyTypedInput { + switch { + // Empty maps turn into empty arrays + case dataValKind == reflect.Map: + if dataVal.Len() == 0 { + val.Set(reflect.Zero(arrayType)) + return nil + } + + // All other types we try to convert to the array type + // and "lift" it into it. i.e. a string becomes a string array. + default: + // Just re-try this function with data as a slice. + return d.decodeArray(name, []interface{}{data}, val) + } + } + + return fmt.Errorf( + "'%s': source data must be an array or slice, got %s", name, dataValKind) + + } + if dataVal.Len() > arrayType.Len() { + return fmt.Errorf( + "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len()) + + } + + // Make a new array to hold our result, same size as the original data. + valArray = reflect.New(arrayType).Elem() + } + + // Accumulate any errors + errors := make([]string, 0) + + for i := 0; i < dataVal.Len(); i++ { + currentData := dataVal.Index(i).Interface() + currentField := valArray.Index(i) + + fieldName := fmt.Sprintf("%s[%d]", name, i) + if err := d.decode(fieldName, currentData, currentField); err != nil { + errors = appendErrors(errors, err) + } + } + + // Finally, set the value to the array we built up + val.Set(valArray) + + // If there were errors, we return those + if len(errors) > 0 { + return &Error{errors} + } + + return nil +} + func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error { dataVal := reflect.Indirect(reflect.ValueOf(data)) @@ -601,23 +765,20 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) // Compile the list of all the fields that we're going to be decoding // from all the structs. - fields := make(map[*reflect.StructField]reflect.Value) + type field struct { + field reflect.StructField + val reflect.Value + } + fields := []field{} for len(structs) > 0 { structVal := structs[0] structs = structs[1:] structType := structVal.Type() + for i := 0; i < structType.NumField(); i++ { fieldType := structType.Field(i) - - if fieldType.Anonymous { - fieldKind := fieldType.Type.Kind() - if fieldKind != reflect.Struct { - errors = appendErrors(errors, - fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind)) - continue - } - } + fieldKind := fieldType.Type.Kind() // If "squash" is specified in the tag, we squash the field down. squash := false @@ -630,19 +791,26 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) } if squash { - structs = append(structs, val.FieldByName(fieldType.Name)) + if fieldKind != reflect.Struct { + errors = appendErrors(errors, + fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind)) + } else { + structs = append(structs, structVal.FieldByName(fieldType.Name)) + } continue } // Normal struct field, store it away - fields[&fieldType] = structVal.Field(i) + fields = append(fields, field{fieldType, structVal.Field(i)}) } } - for fieldType, field := range fields { - fieldName := fieldType.Name + // for fieldType, field := range fields { + for _, f := range fields { + field, fieldValue := f.field, f.val + fieldName := field.Name - tagValue := fieldType.Tag.Get(d.config.TagName) + tagValue := field.Tag.Get(d.config.TagName) tagValue = strings.SplitN(tagValue, ",", 2)[0] if tagValue != "" { fieldName = tagValue @@ -653,7 +821,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) if !rawMapVal.IsValid() { // Do a slower search by iterating over each key and // doing case-insensitive search. - for dataValKey, _ := range dataValKeys { + for dataValKey := range dataValKeys { mK, ok := dataValKey.Interface().(string) if !ok { // Not a string key @@ -677,14 +845,14 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) // Delete the key we're using from the unused map so we stop tracking delete(dataValKeysUnused, rawMapKey.Interface()) - if !field.IsValid() { + if !fieldValue.IsValid() { // This should never happen panic("field is not valid") } // If we can't set the field, then it is unexported or something, // and we just continue onwards. - if !field.CanSet() { + if !fieldValue.CanSet() { continue } @@ -694,14 +862,14 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) fieldName = fmt.Sprintf("%s.%s", name, fieldName) } - if err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil { + if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { errors = appendErrors(errors, err) } } if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { keys := make([]string, 0, len(dataValKeysUnused)) - for rawKey, _ := range dataValKeysUnused { + for rawKey := range dataValKeysUnused { keys = append(keys, rawKey.(string)) } sort.Strings(keys) @@ -716,7 +884,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) // Add the unused keys to the list of unused keys if we're tracking metadata if d.config.Metadata != nil { - for rawKey, _ := range dataValKeysUnused { + for rawKey := range dataValKeysUnused { key := rawKey.(string) if name != "" { key = fmt.Sprintf("%s.%s", name, key) diff --git a/vendor/vendor.json b/vendor/vendor.json index fe36fe283..6172b8c33 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -981,9 +981,10 @@ "revision": "87b45ffd0e9581375c491fef3d32130bb15c5bd7" }, { - "checksumSHA1": "4Js6Jlu93Wa0o6Kjt393L9Z7diE=", + "checksumSHA1": "1JtAhgmRN0x794LRNhs0DJ5t8io=", "path": "github.com/mitchellh/mapstructure", - "revision": "281073eb9eb092240d33ef253c404f1cca550309" + "revision": "b4575eea38cca1123ec2dc90c26529b5c5acfcff", + "revisionTime": "2018-01-11T00:07:20Z" }, { "checksumSHA1": "m2L8ohfZiFRsMW3iynaH/TWgnSY=", From 4622bb4585994ae4a3bfbefc69ebfb0a8b929c06 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 25 Jan 2018 16:29:24 -0800 Subject: [PATCH 0486/1007] return no artifact if no snapshot was created --- builder/oracle/classic/builder.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 7c682b875..9264e6466 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -92,6 +92,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, rawErr.(error) } + // If there is no snapshot, then just return + if _, ok := state.GetOk("snapshot"); !ok { + return nil, nil + } + // Build the artifact and return it artifact := &Artifact{ Snapshot: state.Get("snapshot").(*compute.Snapshot), From de2e5edf2ee57bd0dda934d23d9fc9d2aa96e822 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 08:43:51 -0800 Subject: [PATCH 0487/1007] remove errant change in amazon builder --- builder/amazon/common/step_key_pair.go | 3 +-- builder/oracle/classic/builder.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/builder/amazon/common/step_key_pair.go b/builder/amazon/common/step_key_pair.go index 55f5aace7..927101fcf 100644 --- a/builder/amazon/common/step_key_pair.go +++ b/builder/amazon/common/step_key_pair.go @@ -6,7 +6,6 @@ import ( "io/ioutil" "os" "runtime" - "strings" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/helper/multistep" @@ -37,7 +36,7 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep } state.Put("keyPair", s.KeyPairName) - state.Put("privateKey", strings.TrimSpace(string(privateKeyBytes))) + state.Put("privateKey", string(privateKeyBytes)) return multistep.ActionContinue } diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 9264e6466..8537289cf 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -35,8 +35,7 @@ func (b *Builder) Prepare(rawConfig ...interface{}) ([]string, error) { } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { - - loggingEnabled := os.Getenv("PACKER_OCI_CLASSIC_LOGGING")) != "" + loggingEnabled := os.Getenv("PACKER_OCI_CLASSIC_LOGGING") != "" httpClient := cleanhttp.DefaultClient() config := &opc.Config{ Username: opc.String(b.config.Username), From 25bc1da8fee6f2314777bd47346e7151e7c6d65f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 08:48:23 -0800 Subject: [PATCH 0488/1007] remove unsused access config --- builder/oracle/classic/config.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index eb3fd6876..409118dd5 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -15,8 +15,6 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` - Access *AccessConfig - // Access config overrides Username string `mapstructure:"username"` Password string `mapstructure:"password"` From b6d21ecd63fc17650d32efadeaa2ffc85b1793f6 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 08:53:24 -0800 Subject: [PATCH 0489/1007] validate that required fields are present --- builder/oracle/classic/config.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 409118dd5..178bb2d4b 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -56,7 +56,26 @@ func NewConfig(raws ...interface{}) (*Config, error) { c.SSHSourceList = "seciplist:/oracle/public/public-internet" } + // Validate that all required fields are present var errs *packer.MultiError + required := map[string]string{ + "username": c.Username, + "password": c.Password, + "api_endpoint": c.APIEndpoint, + "identity_domain": c.IdentityDomain, + "image_list": c.ImageList, + "shape": c.Shape, + } + for k, v := range required { + if v == "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("You must specify a %s.", k)) + } + } + + if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { + errs = packer.MultiErrorAppend(errs, es...) + } + if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { errs = packer.MultiErrorAppend(errs, es...) } From ff9fef5ed2db3b2be53c4074ed08393d24895491 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 09:51:16 -0800 Subject: [PATCH 0490/1007] switch to using a UUID for packer-generated keys, and clean them up at end of build --- builder/oracle/classic/step_add_keys.go | 40 +++++++++++++++---------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index e8013cf88..8a6025977 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/hashicorp/go-oracle-terraform/compute" + uuid "github.com/hashicorp/go-uuid" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -23,7 +24,13 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) // form API call to add key to compute cloud - sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key", config.IdentityDomain, config.Username) + uuid_string, err := uuid.GenerateUUID() + if err != nil { + ui.Error(fmt.Sprintf("Error creating unique SSH key name: %s", err.Error())) + return multistep.ActionHalt + } + sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key_%s", + config.IdentityDomain, config.Username, uuid_string) sshKeysClient := client.SSHKeys() sshKeysInput := compute.CreateSSHKeyInput{ @@ -35,25 +42,26 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult // Load the packer-generated SSH key into the Oracle Compute cloud. keyInfo, err := sshKeysClient.CreateSSHKey(&sshKeysInput) if err != nil { - // Key already exists; update key instead of creating it - if strings.Contains(err.Error(), "packer_generated_key already exists") { - updateKeysInput := compute.UpdateSSHKeyInput{ - Name: sshKeyName, - Key: sshPublicKey, - Enabled: true, - } - keyInfo, err = sshKeysClient.UpdateSSHKey(&updateKeysInput) - } else { - err = fmt.Errorf("Problem adding Public SSH key through Oracle's API: %s", err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt - } + err = fmt.Errorf("Problem adding Public SSH key through Oracle's API: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt } state.Put("key_name", keyInfo.Name) return multistep.ActionContinue } func (s *stepAddKeysToAPI) Cleanup(state multistep.StateBag) { - // Nothing to do + // Delete the keys we created during this run + keyName := state.Get("key_name").(string) + ui := state.Get("ui").(packer.Ui) + ui.Say("Deleting SSH keys...") + deleteInput := compute.DeleteSSHKeyInput{Name: keyName} + client := state.Get("client").(*compute.ComputeClient) + deleteClient := client.SSHKeys() + err := deleteClient.DeleteSSHKey(&deleteInput) + if err != nil { + ui.Error(fmt.Sprintf("Error deleting SSH keys: %s", err.Error())) + } + return } From 0e5be59947ba353a09cd0c2a24e057b459937a51 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 09:55:31 -0800 Subject: [PATCH 0491/1007] wrap error message for clarity --- builder/oracle/classic/step_create_ip_reservation.go | 2 -- builder/oracle/classic/step_security.go | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index f24de7766..84154631b 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -3,7 +3,6 @@ package classic import ( "context" "fmt" - "log" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/helper/multistep" @@ -33,7 +32,6 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa return multistep.ActionHalt } state.Put("instance_ip", ipRes.IP) - log.Printf("debug: ipRes is %#v", ipRes) return multistep.ActionContinue } diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 8b1c48a4c..dae341ba6 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -54,7 +54,7 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste config.IdentityDomain, config.Username, config.ImageName) _, err = secRulesClient.CreateSecRule(&secRulesInput) if err != nil { - log.Printf(err.Error()) + log.Printf("Error creating security rule to allow SSH: %s", err.Error()) if !strings.Contains(err.Error(), "already exists") { err = fmt.Errorf("Error creating security rule to"+ " allow Packer to connect to Oracle instance via SSH: %s", err) From fad4d5c27248ea350d4321e80462f4739057cf68 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 12:40:34 -0800 Subject: [PATCH 0492/1007] update tests for mapstructure behavior changes --- builder/amazon/chroot/builder_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/builder/amazon/chroot/builder_test.go b/builder/amazon/chroot/builder_test.go index c13658286..c0e52a2f6 100644 --- a/builder/amazon/chroot/builder_test.go +++ b/builder/amazon/chroot/builder_test.go @@ -71,11 +71,16 @@ func TestBuilderPrepare_ChrootMounts(t *testing.T) { if err != nil { t.Errorf("err: %s", err) } +} + +func TestBuilderPrepare_ChrootMountsBadDefaults(t *testing.T) { + b := &Builder{} + config := testConfig() config["chroot_mounts"] = [][]string{ {"bad"}, } - warnings, err = b.Prepare(config) + warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } @@ -135,9 +140,14 @@ func TestBuilderPrepare_CopyFiles(t *testing.T) { if len(b.config.CopyFiles) != 1 && b.config.CopyFiles[0] != "/etc/resolv.conf" { t.Errorf("Was expecting default value for copy_files.") } +} + +func TestBuilderPrepare_CopyFilesNoDefault(t *testing.T) { + b := &Builder{} + config := testConfig() config["copy_files"] = []string{} - warnings, err = b.Prepare(config) + warnings, err := b.Prepare(config) if len(warnings) > 0 { t.Fatalf("bad: %#v", warnings) } From 18ffde4ecfa39402af0c9ddef12138222e51c8e4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 12:59:46 -0800 Subject: [PATCH 0493/1007] remove unused file --- builder/oracle/classic/access_config.go | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 builder/oracle/classic/access_config.go diff --git a/builder/oracle/classic/access_config.go b/builder/oracle/classic/access_config.go deleted file mode 100644 index 99483ceec..000000000 --- a/builder/oracle/classic/access_config.go +++ /dev/null @@ -1,4 +0,0 @@ -package classic - -type AccessConfig struct { -} From 71acccc1ed4afa077d0a1d65c8efba628f7077f2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 13:12:35 -0800 Subject: [PATCH 0494/1007] add UI output with resource names --- builder/oracle/classic/step_add_keys.go | 3 ++- builder/oracle/classic/step_create_instance.go | 4 ++-- builder/oracle/classic/step_create_ip_reservation.go | 9 +++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index 8a6025977..b8331eb94 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -16,7 +16,6 @@ type stepAddKeysToAPI struct{} func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state ui := state.Get("ui").(packer.Ui) - ui.Say("Adding SSH keys to API...") config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) @@ -32,6 +31,8 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key_%s", config.IdentityDomain, config.Username, uuid_string) + ui.Say(fmt.Sprintf("Creating temporary key: %s", sshKeyName)) + sshKeysClient := client.SSHKeys() sshKeysInput := compute.CreateSSHKeyInput{ Name: sshKeyName, diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 2f8493fd1..fd70c6afa 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -16,11 +16,11 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu // get variables from state ui := state.Get("ui").(packer.Ui) ui.Say("Creating Instance...") + config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) keyName := state.Get("key_name").(string) - - ipAddName := fmt.Sprintf("ipres_%s", config.ImageName) + ipAddName := state.Get("ipres_name").(string) secListName := state.Get("security_list").(string) netInfo := compute.NetworkingInfo{ diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index 84154631b..8e23be785 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -13,15 +13,19 @@ type stepCreateIPReservation struct{} func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) - ui.Say("Creating IP reservation...") + config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) iprClient := client.IPReservations() // TODO: add optional Name and Tags + + ipresName := fmt.Sprintf("ipres_%s", config.ImageName) + ui.Say(fmt.Sprintf("Creating IP reservation: %s", ipresName)) + IPInput := &compute.CreateIPReservationInput{ ParentPool: compute.PublicReservationPool, Permanent: true, - Name: fmt.Sprintf("ipres_%s", config.ImageName), + Name: ipresName, } ipRes, err := iprClient.CreateIPReservation(IPInput) @@ -32,6 +36,7 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa return multistep.ActionHalt } state.Put("instance_ip", ipRes.IP) + state.Put("ipres_name", ipresName) return multistep.ActionContinue } From c6b43ce6e9f645258f6898e0d4bf1646882865a0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 13:13:13 -0800 Subject: [PATCH 0495/1007] remove errouneous double prep --- builder/oracle/classic/config.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 178bb2d4b..540f24503 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -76,9 +76,5 @@ func NewConfig(raws ...interface{}) (*Config, error) { errs = packer.MultiErrorAppend(errs, es...) } - if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { - errs = packer.MultiErrorAppend(errs, es...) - } - return c, nil } From 9edd98f7b0fda9d791e9944c6a06dd0a896f70e7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 13:43:19 -0800 Subject: [PATCH 0496/1007] Use more uuids and make messaging consistent. --- builder/oracle/classic/step_add_keys.go | 9 ++------- builder/oracle/classic/step_create_instance.go | 4 ++-- builder/oracle/classic/step_create_ip_reservation.go | 5 +++-- builder/oracle/classic/step_security.go | 2 +- builder/oracle/classic/step_snapshot.go | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index b8331eb94..544c35bf2 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-oracle-terraform/compute" - uuid "github.com/hashicorp/go-uuid" + "github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -23,13 +23,8 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) // form API call to add key to compute cloud - uuid_string, err := uuid.GenerateUUID() - if err != nil { - ui.Error(fmt.Sprintf("Error creating unique SSH key name: %s", err.Error())) - return multistep.ActionHalt - } sshKeyName := fmt.Sprintf("/Compute-%s/%s/packer_generated_key_%s", - config.IdentityDomain, config.Username, uuid_string) + config.IdentityDomain, config.Username, uuid.TimeOrderedUUID()) ui.Say(fmt.Sprintf("Creating temporary key: %s", sshKeyName)) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index fd70c6afa..ea840cb22 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -49,7 +49,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu } state.Put("instance_id", instanceInfo.ID) - ui.Say(fmt.Sprintf("Created instance (%s).", instanceInfo.ID)) + ui.Message(fmt.Sprintf("Created instance: %s.", instanceInfo.ID)) return multistep.ActionContinue } @@ -60,7 +60,7 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { config := state.Get("config").(*Config) imID := state.Get("instance_id").(string) - ui.Say(fmt.Sprintf("Terminating instance (%s)...", imID)) + ui.Say("Terminating source instance...") instanceClient := client.Instances() input := &compute.DeleteInstanceInput{ diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index 8e23be785..cee4a62e8 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -19,8 +20,8 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa iprClient := client.IPReservations() // TODO: add optional Name and Tags - ipresName := fmt.Sprintf("ipres_%s", config.ImageName) - ui.Say(fmt.Sprintf("Creating IP reservation: %s", ipresName)) + ipresName := fmt.Sprintf("ipres_%s_%s", config.ImageName, uuid.TimeOrderedUUID()) + ui.Say(fmt.Sprintf("Creating temporary IP reservation: %s", ipresName)) IPInput := &compute.CreateIPReservationInput{ ParentPool: compute.PublicReservationPool, diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index dae341ba6..22d74de08 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -71,7 +71,7 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste func (s *stepSecurity) Cleanup(state multistep.StateBag) { client := state.Get("client").(*compute.ComputeClient) ui := state.Get("ui").(packer.Ui) - ui.Say("Deleting the packer-generated security rules and lists...") + ui.Say("Deleting temporary rules and lists...") // delete security rules that Packer generated secRuleName := state.Get("security_rule_name").(string) diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 30a7d32c8..602ebd1ad 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -37,7 +37,7 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste } state.Put("snapshot", snap) - ui.Say(fmt.Sprintf("Created snapshot (%s).", snap.Name)) + ui.Message(fmt.Sprintf("Created snapshot: %s.", snap.Name)) return multistep.ActionContinue } From 98857c42cfe1c0ba7484804fdd4af543a3a6a7ec Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 14:27:18 -0800 Subject: [PATCH 0497/1007] add tests; fix a couple issues caught by said tests --- builder/oracle/classic/config.go | 8 ++++ builder/oracle/classic/config_test.go | 59 +++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 builder/oracle/classic/config_test.go diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 540f24503..695307338 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -56,6 +56,10 @@ func NewConfig(raws ...interface{}) (*Config, error) { c.SSHSourceList = "seciplist:/oracle/public/public-internet" } + if c.Comm.SSHUsername == "" { + c.Comm.SSHUsername = "opc" + } + // Validate that all required fields are present var errs *packer.MultiError required := map[string]string{ @@ -76,5 +80,9 @@ func NewConfig(raws ...interface{}) (*Config, error) { errs = packer.MultiErrorAppend(errs, es...) } + if errs != nil && len(errs.Errors) > 0 { + return nil, errs + } + return c, nil } diff --git a/builder/oracle/classic/config_test.go b/builder/oracle/classic/config_test.go new file mode 100644 index 000000000..195e104a8 --- /dev/null +++ b/builder/oracle/classic/config_test.go @@ -0,0 +1,59 @@ +package classic + +import ( + "testing" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "identity_domain": "abc12345", + "username": "test@hashicorp.com", + "password": "testpassword123", + "api_endpoint": "https://api-test.compute.test.oraclecloud.com/", + "image_list": "/oracle/public/myimage", + "shape": "oc3", + "image_name": "TestImageName", + "ssh_username": "opc", + } +} + +func TestConfigAutoFillsSourceList(t *testing.T) { + tc := testConfig() + conf, err := NewConfig(tc) + if err != nil { + t.Fatalf("Should not have error: %s", err.Error()) + } + if conf.SSHSourceList != "seciplist:/oracle/public/public-internet" { + t.Fatalf("conf.SSHSourceList should have been "+ + "\"seciplist:/oracle/public/public-internet\" but is \"%s\"", + conf.SSHSourceList) + } +} + +func TestConfigValidationCatchesMissing(t *testing.T) { + required := []string{ + "username", + "password", + "api_endpoint", + "identity_domain", + "image_list", + "shape", + } + for _, key := range required { + tc := testConfig() + delete(tc, key) + _, err := NewConfig(tc) + if err == nil { + t.Fatalf("Test should have failed when config lacked %s!", key) + } + } +} + +func TestValidationsIgnoresOptional(t *testing.T) { + tc := testConfig() + delete(tc, "ssh_username") + _, err := NewConfig(tc) + if err != nil { + t.Fatalf("Test shouldn't care if ssh_username is missing: err: %#v", err.Error()) + } +} From 565b660b19d03c61b2dcbad244cbf323f27b8855 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 14:28:27 -0800 Subject: [PATCH 0498/1007] comments --- builder/oracle/classic/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 695307338..7b2f7dfb2 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -51,11 +51,11 @@ func NewConfig(raws ...interface{}) (*Config, error) { if err != nil { return nil, fmt.Errorf("Error parsing API Endpoint: %s", err) } - // set default source list + // Set default source list if c.SSHSourceList == "" { c.SSHSourceList = "seciplist:/oracle/public/public-internet" } - + // Use default oracle username with sudo privileges if c.Comm.SSHUsername == "" { c.Comm.SSHUsername = "opc" } From 3ee1aa3ed62ce8082a5e2b92aa7258ab5d21ef35 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 15:18:33 -0800 Subject: [PATCH 0499/1007] clean up ip reservations --- builder/oracle/classic/config_test.go | 2 +- .../oracle/classic/step_create_ip_reservation.go | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/config_test.go b/builder/oracle/classic/config_test.go index 195e104a8..81b8f0344 100644 --- a/builder/oracle/classic/config_test.go +++ b/builder/oracle/classic/config_test.go @@ -54,6 +54,6 @@ func TestValidationsIgnoresOptional(t *testing.T) { delete(tc, "ssh_username") _, err := NewConfig(tc) if err != nil { - t.Fatalf("Test shouldn't care if ssh_username is missing: err: %#v", err.Error()) + t.Fatalf("Shouldn't care if ssh_username is missing: err: %#v", err.Error()) } } diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index cee4a62e8..ca324b7e0 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -42,5 +42,16 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa } func (s *stepCreateIPReservation) Cleanup(state multistep.StateBag) { - // TODO: delete ip reservation + ui := state.Get("ui").(packer.Ui) + ui.Message("Cleaning up IP reservations...") + client := state.Get("client").(*compute.ComputeClient) + + ipResName := state.Get("ipres_name").(string) + input := compute.DeleteIPReservationInput{Name: ipResName} + ipClient := client.IPReservations() + err := ipClient.DeleteIPReservation(&input) + if err != nil { + fmt.Printf("error deleting IP reservation: %s", err.Error()) + } + } From 56c6fed42a3b1ae5683a1d0c2e113ba9d1c4f037 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 26 Jan 2018 15:20:12 -0800 Subject: [PATCH 0500/1007] ui.say vs ui.message --- builder/oracle/classic/step_create_ip_reservation.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index ca324b7e0..74466a39f 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -21,7 +21,7 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa // TODO: add optional Name and Tags ipresName := fmt.Sprintf("ipres_%s_%s", config.ImageName, uuid.TimeOrderedUUID()) - ui.Say(fmt.Sprintf("Creating temporary IP reservation: %s", ipresName)) + ui.Message(fmt.Sprintf("Creating temporary IP reservation: %s", ipresName)) IPInput := &compute.CreateIPReservationInput{ ParentPool: compute.PublicReservationPool, @@ -43,7 +43,7 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa func (s *stepCreateIPReservation) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) - ui.Message("Cleaning up IP reservations...") + ui.Say("Cleaning up IP reservations...") client := state.Get("client").(*compute.ComputeClient) ipResName := state.Get("ipres_name").(string) From 07421b44338e09dd7376a4ac30a480929c9e9d3a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 15:58:17 -0800 Subject: [PATCH 0501/1007] test vmware workstation version checking --- builder/vmware/common/driver_workstation_unix.go | 9 ++++++--- .../vmware/common/driver_workstation_unix_test.go | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 builder/vmware/common/driver_workstation_unix_test.go diff --git a/builder/vmware/common/driver_workstation_unix.go b/builder/vmware/common/driver_workstation_unix.go index c4217d9be..2931396a4 100644 --- a/builder/vmware/common/driver_workstation_unix.go +++ b/builder/vmware/common/driver_workstation_unix.go @@ -66,14 +66,17 @@ func workstationVerifyVersion(version string) error { if err := cmd.Run(); err != nil { return err } + return workstationTestVersion(version, stderr.String()) +} +func workstationTestVersion(wanted, versionOutput string) error { versionRe := regexp.MustCompile(`(?i)VMware Workstation (\d+)\.`) - matches := versionRe.FindStringSubmatch(stderr.String()) + matches := versionRe.FindStringSubmatch(versionOutput) if matches == nil { return fmt.Errorf( - "Could not find VMware WS version in output: %s", stderr.String()) + "Could not find VMware WS version in output: %s", wanted) } log.Printf("Detected VMware WS version: %s", matches[1]) - return compareVersions(matches[1], version, "Workstation") + return compareVersions(matches[1], wanted, "Workstation") } diff --git a/builder/vmware/common/driver_workstation_unix_test.go b/builder/vmware/common/driver_workstation_unix_test.go new file mode 100644 index 000000000..e0e3e6ecf --- /dev/null +++ b/builder/vmware/common/driver_workstation_unix_test.go @@ -0,0 +1,15 @@ +// +build !windows + +package common + +import ( + "testing" +) + +func TestWorkstationVersion_ws14(t *testing.T) { + input := `VMware Workstation Information: +VMware Workstation 14.1.1 build-7528167 Release` + if err := workstationTestVersion("10", input); err != nil { + t.Fatal(err) + } +} From 76b2ce8604618262d14e42257eee0a66d66bac75 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 26 Jan 2018 16:12:43 -0800 Subject: [PATCH 0502/1007] log which vmware driver we decide on --- builder/vmware/common/driver.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 99c9f686c..d5f8b44f4 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -106,6 +106,9 @@ func NewDriver(dconfig *DriverConfig, config *SSHConfig) (Driver, error) { errs := "" for _, driver := range drivers { err := driver.Verify() + log.Printf("Testing vmware driver %T. Success: %t", + driver, err == nil) + if err == nil { return driver, nil } From 0868c21d13da62ddf32ac47342360f530f41793b Mon Sep 17 00:00:00 2001 From: SharePointOscar <me@sharepointoscar.com> Date: Sat, 27 Jan 2018 12:49:41 -0800 Subject: [PATCH 0503/1007] updated to use new Azure CLI 'az' and respective commands --- contrib/azure-setup.sh | 66 +++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index b5f6de220..4c4d6ee6b 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -15,9 +15,9 @@ azureversion= create_sleep=10 showhelp() { - echo "azure-setup" + echo "az-setup" echo "" - echo " azure-setup helps you generate packer credentials for Azure" + echo " az-setup helps you generate packer credentials for az" echo "" echo " The script creates a resource group, storage account, application" echo " (client), service principal, and permissions and displays a snippet" @@ -25,37 +25,37 @@ showhelp() { echo "" echo " For simplicity we make a lot of assumptions and choose reasonable" echo " defaults. If you want more control over what happens, please use" - echo " the azure-cli directly." + echo " the az-cli directly." echo "" - echo " Note that you must already have an Azure account, username," + echo " Note that you must already have an az account, username," echo " password, and subscription. You can create those here:" echo "" echo " - https://account.windowsazure.com/" echo "" echo "REQUIREMENTS" echo "" - echo " - azure-cli" + echo " - az-cli" echo " - jq" echo "" echo " Use the requirements command (below) for more info." echo "" echo "USAGE" echo "" - echo " ./azure-setup.sh requirements" - echo " ./azure-setup.sh setup" + echo " ./az-setup.sh requirements" + echo " ./az-setup.sh setup" echo "" } requirements() { found=0 - azureversion=$(azure -v) + azureversion=$(az -v) if [ $? -eq 0 ]; then found=$((found + 1)) - echo "Found azure-cli version: $azureversion" + echo "Found az-cli version: $azureversion" else - echo "azure-cli is missing. Please install azure-cli from" - echo "https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/" + echo "az cli is missing. Please install az cli from" + echo "https://az.microsoft.com/en-us/documentation/articles/xplat-cli-install/" fi jqversion=$(jq --version) @@ -73,19 +73,20 @@ requirements() { } askSubscription() { - azure account list + az account list echo "" echo "Please enter the Id of the account you wish to use. If you do not see" echo "a valid account in the list press Ctrl+C to abort and create one." echo "If you leave this blank we will use the Current account." echo -n "> " read azure_subscription_id + if [ "$azure_subscription_id" != "" ]; then - azure account set $azure_subscription_id + az account set --subscription $azure_subscription_id else - azure_subscription_id=$(azure account show --json | jq -r .[].id) + azure_subscription_id=$(az account list | jq -r .[].id) fi - azure_tenant_id=$(azure account show --json | jq -r .[].tenantId) + azure_tenant_id=$(az account list | jq -r '.[] | select(.tenantId) | .tenantId') echo "Using subscription_id: $azure_subscription_id" echo "Using tenant_id: $azure_tenant_id" } @@ -118,16 +119,16 @@ askSecret() { } askLocation() { - azure location list + az account list-locations echo "" - echo "Choose which region your resource group and storage account will be created." + echo "Choose which region your resource group and storage account will be created. example: westus" echo -n "> " read location } createResourceGroup() { echo "==> Creating resource group" - azure group create -n $meta_name -l $location + az group create -n $meta_name -l $location if [ $? -eq 0 ]; then azure_group_name=$meta_name else @@ -138,7 +139,7 @@ createResourceGroup() { createStorageAccount() { echo "==> Creating storage account" - azure storage account create -g $meta_name -l $location --sku-name LRS --kind Storage $meta_name + az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage if [ $? -eq 0 ]; then azure_storage_name=$meta_name else @@ -149,7 +150,17 @@ createStorageAccount() { createApplication() { echo "==> Creating application" - azure_client_id=$(azure ad app create -n $meta_name -i http://$meta_name --home-page http://$meta_name -p $azure_client_secret --json | jq -r .appId) + echo "==> Does application exist?" + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') + + if [ "$azure_client_id" != "" ]; then + echo "==> application already exist, grab appId" + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("spfarmpacker")) .appId') + else + echo "==> application does not exist" + azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) + fi + if [ $? -ne 0 ]; then echo "Error creating application: $meta_name @ http://$meta_name" return 1 @@ -158,7 +169,7 @@ createApplication() { createServicePrincipal() { echo "==> Creating service principal" - # Azure CLI 0.10.2 introduced a breaking change, where appId must be supplied with the -a switch + # az CLI 0.10.2 introduced a breaking change, where appId must be supplied with the -a switch # prior version accepted appId as the only parameter without a switch newer_syntax=false IFS='.' read -ra azureversionsemver <<< "$azureversion" @@ -167,9 +178,11 @@ createServicePrincipal() { fi if [ "${newer_syntax}" = true ]; then - azure_object_id=$(azure ad sp create -a $azure_client_id --json | jq -r .objectId) + azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) + echo $azure_object_id "was selected." else - azure_object_id=$(azure ad sp create $azure_client_id --json | jq -r .objectId) + azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) + echo $azure_object_id "was selected." fi if [ $? -ne 0 ]; then @@ -180,10 +193,10 @@ createServicePrincipal() { createPermissions() { echo "==> Creating permissions" - azure role assignment create --objectId $azure_object_id -o "Owner" -c /subscriptions/$azure_subscription_id + az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id # We want to use this more conservative scope but it does not work with the # current implementation which uses temporary resource groups - # azure role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" + # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" if [ $? -ne 0 ]; then echo "Error creating permissions for: http://$meta_name" return 1 @@ -234,8 +247,7 @@ retryable() { setup() { requirements - azure config mode arm - azure login + #az login askSubscription askName From 6770bb8091241e7ae54c43f74ff7fdc922ebb273 Mon Sep 17 00:00:00 2001 From: SharePointOscar <me@sharepointoscar.com> Date: Sat, 27 Jan 2018 12:55:16 -0800 Subject: [PATCH 0504/1007] changed verbiage on cli name --- contrib/azure-setup.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 4c4d6ee6b..ec5f1b896 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -15,9 +15,9 @@ azureversion= create_sleep=10 showhelp() { - echo "az-setup" + echo "azure-setup" echo "" - echo " az-setup helps you generate packer credentials for az" + echo " azure-setup helps you generate packer credentials for azure" echo "" echo " The script creates a resource group, storage account, application" echo " (client), service principal, and permissions and displays a snippet" @@ -25,7 +25,7 @@ showhelp() { echo "" echo " For simplicity we make a lot of assumptions and choose reasonable" echo " defaults. If you want more control over what happens, please use" - echo " the az-cli directly." + echo " the azure cli directly." echo "" echo " Note that you must already have an az account, username," echo " password, and subscription. You can create those here:" @@ -34,15 +34,15 @@ showhelp() { echo "" echo "REQUIREMENTS" echo "" - echo " - az-cli" + echo " - azure-cli" echo " - jq" echo "" echo " Use the requirements command (below) for more info." echo "" echo "USAGE" echo "" - echo " ./az-setup.sh requirements" - echo " ./az-setup.sh setup" + echo " ./azure-setup.sh requirements" + echo " ./azure-setup.sh setup" echo "" } @@ -52,9 +52,9 @@ requirements() { azureversion=$(az -v) if [ $? -eq 0 ]; then found=$((found + 1)) - echo "Found az-cli version: $azureversion" + echo "Found azure-cli version: $azureversion" else - echo "az cli is missing. Please install az cli from" + echo "azure cli is missing. Please install azure cli from" echo "https://az.microsoft.com/en-us/documentation/articles/xplat-cli-install/" fi From 6327ab6f3d7fe0a335e41d501420c01febebc54c Mon Sep 17 00:00:00 2001 From: SharePointOscar <me@sharepointoscar.com> Date: Sat, 27 Jan 2018 12:56:43 -0800 Subject: [PATCH 0505/1007] changed verbiage on cli name --- contrib/azure-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index ec5f1b896..7e6817e74 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -247,7 +247,7 @@ retryable() { setup() { requirements - #az login + az login askSubscription askName From 361a175fc9c8ff80016bae86c3a437554d1f797c Mon Sep 17 00:00:00 2001 From: Oscar Medina <oscar@sharepointace.com> Date: Sun, 28 Jan 2018 07:49:58 -0800 Subject: [PATCH 0506/1007] Removed static value from code The parameter within the contains() should not be hard-coded, using $meta_name variable value. --- contrib/azure-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 7e6817e74..f30da9693 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -155,7 +155,7 @@ createApplication() { if [ "$azure_client_id" != "" ]; then echo "==> application already exist, grab appId" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("spfarmpacker")) .appId') + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') else echo "==> application does not exist" azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) From 32e9ff84c5efd937036a4fccb35931e214bc5b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 17:16:28 +0900 Subject: [PATCH 0507/1007] Add ncloud doc html --- website/source/docs/builders/ncloud.html.md | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 website/source/docs/builders/ncloud.html.md diff --git a/website/source/docs/builders/ncloud.html.md b/website/source/docs/builders/ncloud.html.md new file mode 100644 index 000000000..ce38a9c71 --- /dev/null +++ b/website/source/docs/builders/ncloud.html.md @@ -0,0 +1,88 @@ +--- +description: | + As Packer allows users to develop a custom builder as a plugin, NAVER CLOUD PLATFORM provides its own Packer builder for your convenience. +You can use NAVER CLOUD PLATFORM's Packer builder to easily create your server images. +layout: docs +page_title: 'Naver Cloud Platform - Builders' +sidebar_current: 'docs-builders-ncloud' +--- + +# NAVER CLOUD PLATFORM Builder + +As Packer allows users to develop a custom builder as a plugin, NAVER CLOUD PLATFORM provides its own Packer builder for your convenience. +You can use NAVER CLOUD PLATFORM's Packer builder to easily create your server images. + +#### Sample code of template.json + +``` +{ + "variables": { + "ncloud_access_key": "FRxhOQRNjKVMqIz3sRLY", + "ncloud_secret_key": "xd6kTO5iNcLookBx0D8TDKmpLj2ikxqEhc06MQD2" + }, + "builders": [ + { + "type": "ncloud", + "access_key": "{{user `ncloud_access_key`}}", + "secret_key": "{{user `ncloud_secret_key`}}", + + "server_image_product_code": "SPSW0WINNT000016", + "server_product_code": "SPSVRSSD00000011", + "member_server_image_no": "4223", + "server_image_name": "packer-test {{timestamp}}", + "server_description": "server description", + "user_data": "CreateObject(\"WScript.Shell\").run(\"cmd.exe /c powershell Set-ExecutionPolicy RemoteSigned & winrm quickconfig -q & sc config WinRM start= auto & winrm set winrm/config/service/auth @{Basic=\"\"true\"\"} & winrm set winrm/config/service @{AllowUnencrypted=\"\"true\"\"} & winrm get winrm/config/service\")", + "region": "US-West" + } + ] +} +``` + +#### Description + +* type(required): "ncloud" +* ncloud_access_key (required): User's access key. Go to [[Account Management > Authentication Key]](https://www.ncloud.com/mypage/manage/authkey) to create and view your authentication key. +* ncloud_secret_key (required): User's secret key paired with the access key. Go to [[Account Management > Authentication Key]](https://www.ncloud.com/mypage/manage/authkey) to create and view your authentication key. +* server_image_product_code: Product code of an image to create. (member_server_image_no is required if not specified) +* server_product_code (required): Product (spec) code to create. +* member_server_image_no: Previous image code. If there is an image previously created, it can be used to create a new image. (server_image_product_code is required if not specified) +* server_image_name (option): Name of an image to create. +* server_image_description (option): Description of an image to create. +* block_storage_size (option): You can add block storage ranging from 10 GB to 2000 GB, in increments of 10 GB. +* access_control_group_configuration_no: This is used to allow winrm access when you create a Windows server. An ACG that specifies an access source ("0.0.0.0/0") and allowed port (5985) must be created in advance. +* user_data (option): Init script to run when an instance is created. + * For Linux servers, Python, Perl, and Shell scripts can be used. The path of the script to run should be included at the beginning of the script, like #!/usr/bin/env python, #!/bin/perl, or #!/bin/bash. + * For Windows servers, only Visual Basic scripts can be used. + * All scripts must be written in English. +* region (option): Name of the region where you want to create an image. (default: Korea) + * values: Korea / US-West / HongKong / Singapore / Japan / Germany + +### Requirements for creating Windows images + +You should include the following code in the packer configuration file for provision when creating a Windows server. + +``` + "builders": [ + { + "type": "ncloud", + ... + "user_data": + "CreateObject(\"WScript.Shell\").run(\"cmd.exe /c powershell Set-ExecutionPolicy RemoteSigned & winrm set winrm/config/service/auth @{Basic=\"\"true\"\"} & winrm set winrm/config/service @{AllowUnencrypted=\"\"true\"\"} & winrm quickconfig -q & sc config WinRM start= auto & winrm get winrm/config/service\")", + "communicator": "winrm", + "winrm_username": "Administrator" + } + ], + "provisioners": [ + { + "type": "powershell", + "inline": [ + "$Env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /shutdown /quiet \"/unattend:C:\\Program Files (x86)\\NBP\\nserver64.xml\" " + ] + } + ] +``` + +### Note + +* You can only create as many public IP addresses as the number of server instances you own. Before running Packer, please make sure that the number of public IP addresses previously created is not larger than the number of server instances (including those to be used to create server images). +* When you forcibly terminate the packer process or close the terminal (command) window where the process is running, the resources may not be cleaned up as the packer process no longer runs. In this case, you should manually clean up the resources associated with the process. From da78ebbf837db0aa37a77e8989d91693feebddcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 17:29:26 +0900 Subject: [PATCH 0508/1007] - Remove plugin version - remove `os_type`. use `communicator` instead of this. --- builder/ncloud/builder.go | 10 +++------- builder/ncloud/config.go | 10 +++------- builder/ncloud/config_test.go | 3 --- builder/ncloud/step_create_public_ip_instance.go | 6 +++--- builder/ncloud/step_create_public_ip_instance_test.go | 6 +++++- 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index 580514d53..24ec670d3 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -8,8 +8,6 @@ import ( "github.com/mitchellh/multistep" ) -const version = "1.0.0" - // Builder assume this implements packer.Builder type Builder struct { config *Config @@ -30,8 +28,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { - ui.Say("Running builder for Naver Cloud Platform (version: " + version + ") ...") - ui.Message("Creating Naver Cloud Platform Connection ...") conn := ncloud.NewConnection(b.config.AccessKey, b.config.SecretKey) @@ -42,7 +38,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps = []multistep.Step{} - if b.config.OSType == "Linux" { + if b.config.Comm.Type == "ssh" { steps = []multistep.Step{ NewStepValidateTemplate(conn, ui, b.config), NewStepCreateLoginKey(conn, ui), @@ -63,7 +59,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepDeleteLoginKey(conn, ui), NewStepDeletePublicIPInstance(conn, ui), } - } else if b.config.OSType == "Windows" { + } else if b.config.Comm.Type == "Windows" { steps = []multistep.Step{ NewStepValidateTemplate(conn, ui, b.config), NewStepCreateLoginKey(conn, ui), @@ -94,7 +90,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } // Run! - b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner = common.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, b.stateBag) b.runner.Run(b.stateBag) // If there was an error, return that diff --git a/builder/ncloud/config.go b/builder/ncloud/config.go index e18ab822d..abaca35c3 100644 --- a/builder/ncloud/config.go +++ b/builder/ncloud/config.go @@ -16,13 +16,13 @@ type Config struct { AccessKey string `mapstructure:"access_key"` SecretKey string `mapstructure:"secret_key"` - OSType string `mapstructure:"os_type"` ServerImageProductCode string `mapstructure:"server_image_product_code"` ServerProductCode string `mapstructure:"server_product_code"` MemberServerImageNo string `mapstructure:"member_server_image_no"` ServerImageName string `mapstructure:"server_image_name"` ServerImageDescription string `mapstructure:"server_image_description"` UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` BlockStorageSize int `mapstructure:"block_storage_size"` Region string `mapstructure:"region"` AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no"` @@ -60,10 +60,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, errors.New("secret_key is required")) } - if c.OSType != "Linux" && c.OSType != "Windows" { - errs = packer.MultiErrorAppend(errs, errors.New("os_type is required. ('Linux' or 'Windows')")) - } - if c.MemberServerImageNo == "" && c.ServerImageProductCode == "" { errs = packer.MultiErrorAppend(errs, errors.New("server_image_product_code or member_server_image_no is required")) } @@ -100,8 +96,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, errors.New("If user_data field is set, length of UserData should be max 21847")) } - if c.OSType == "Windows" && c.AccessControlGroupConfigurationNo == "" { - errs = packer.MultiErrorAppend(errs, errors.New("If os_type is Windows, access_control_group_configuration_no is required")) + if c.Comm.Type == "wrinrm" && c.AccessControlGroupConfigurationNo == "" { + errs = packer.MultiErrorAppend(errs, errors.New("If Communicator is winrm, access_control_group_configuration_no is required")) } c.FeeSystemTypeCode = "MTRAT" diff --git a/builder/ncloud/config_test.go b/builder/ncloud/config_test.go index 7907c7ee1..7e2591594 100644 --- a/builder/ncloud/config_test.go +++ b/builder/ncloud/config_test.go @@ -9,7 +9,6 @@ func testConfig() map[string]interface{} { return map[string]interface{}{ "access_key": "access_key", "secret_key": "secret_key", - "os_type": "Windows", "server_image_product_code": "SPSW0WINNT000016", "server_product_code": "SPSVRSSD00000011", "server_image_name": "packer-test {{timestamp}}", @@ -27,7 +26,6 @@ func testConfigForMemberServerImage() map[string]interface{} { return map[string]interface{}{ "access_key": "access_key", "secret_key": "secret_key", - "os_type": "Windows", "server_product_code": "SPSVRSSD00000011", "member_server_image_no": "2440", "server_image_name": "packer-test {{timestamp}}", @@ -135,7 +133,6 @@ func TestExistsBothServerImageProductCodeAndMemberServerImageNoConfig(t *testing raw := map[string]interface{}{ "access_key": "access_key", "secret_key": "secret_key", - "os_type": "Windows", "server_image_product_code": "SPSW0WINNT000016", "server_product_code": "SPSVRSSD00000011", "member_server_image_no": "2440", diff --git a/builder/ncloud/step_create_public_ip_instance.go b/builder/ncloud/step_create_public_ip_instance.go index 1ea1517c5..897ff1504 100644 --- a/builder/ncloud/step_create_public_ip_instance.go +++ b/builder/ncloud/step_create_public_ip_instance.go @@ -91,10 +91,10 @@ func (s *StepCreatePublicIPInstance) Run(state multistep.StateBag) multistep.Ste publicIPInstance, err := s.CreatePublicIPInstance(serverInstanceNo) if err == nil { - switch s.Config.OSType { - case "Linux": + switch s.Config.Comm.Type { + case "ssh": state.Put("SSHHost", publicIPInstance.PublicIP) - case "Windows": + case "winrm": state.Put("WinRMHost", publicIPInstance.PublicIP) } diff --git a/builder/ncloud/step_create_public_ip_instance_test.go b/builder/ncloud/step_create_public_ip_instance_test.go index 30eaca017..0f44f4a33 100644 --- a/builder/ncloud/step_create_public_ip_instance_test.go +++ b/builder/ncloud/step_create_public_ip_instance_test.go @@ -31,13 +31,17 @@ func TestStepCreatePublicIPInstanceShouldFailIfOperationCreatePublicIPInstanceFa } func TestStepCreatePublicIPInstanceShouldPassIfOperationCreatePublicIPInstancePasses(t *testing.T) { + c := new(Config) + c.Comm.Prepare(nil) + c.Comm.Type = "ssh" + var testSubject = &StepCreatePublicIPInstance{ CreatePublicIPInstance: func(serverInstanceNo string) (*ncloud.PublicIPInstance, error) { return &ncloud.PublicIPInstance{PublicIPInstanceNo: "a", PublicIP: "b"}, nil }, Say: func(message string) {}, Error: func(e error) {}, - Config: &Config{OSType: "Windows"}, + Config: c, } stateBag := createTestStateBagStepCreatePublicIPInstance() From 2152ad76093bbd29f16075598e97fb473257be8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 18:09:14 +0900 Subject: [PATCH 0509/1007] Add UserDataFile --- builder/ncloud/config.go | 10 +++++++++- builder/ncloud/step_create_server_instance.go | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/builder/ncloud/config.go b/builder/ncloud/config.go index abaca35c3..5e713d44d 100644 --- a/builder/ncloud/config.go +++ b/builder/ncloud/config.go @@ -22,7 +22,7 @@ type Config struct { ServerImageName string `mapstructure:"server_image_name"` ServerImageDescription string `mapstructure:"server_image_description"` UserData string `mapstructure:"user_data"` - UserDataFile string `mapstructure:"user_data_file"` + UserDataFile string `mapstructure:"user_data_file"` BlockStorageSize int `mapstructure:"block_storage_size"` Region string `mapstructure:"region"` AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no"` @@ -92,6 +92,14 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { } } + if c.UserData != "" && c.UserDataFile != "" { + errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) + } else if c.UserDataFile != "" { + if _, err := os.Stat(c.UserDataFile); err != nil { + errs = append(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) + } + } + if c.UserData != "" && len(c.UserData) > 21847 { errs = packer.MultiErrorAppend(errs, errors.New("If user_data field is set, length of UserData should be max 21847")) } diff --git a/builder/ncloud/step_create_server_instance.go b/builder/ncloud/step_create_server_instance.go index d7decd4d8..3a842f899 100644 --- a/builder/ncloud/step_create_server_instance.go +++ b/builder/ncloud/step_create_server_instance.go @@ -3,6 +3,7 @@ package ncloud import ( "errors" "fmt" + "io/ioutil" "log" "time" @@ -49,6 +50,15 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon reqParams.UserData = s.Config.UserData } + if s.Config.UserDataFile != "" { + contents, err := ioutil.ReadFile(s.Config.UserDataFile) + if err != nil { + return "", fmt.Errorf("Problem reading user data file: %s", err) + } + + reqParams.UserData = string(contents) + } + if s.Config.AccessControlGroupConfigurationNo != "" { reqParams.AccessControlGroupConfigurationNoList = []string{s.Config.AccessControlGroupConfigurationNo} } From 3820f97a0b4b6b93e091d9ec78ecb0cc1da4bc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 18:35:43 +0900 Subject: [PATCH 0510/1007] use state storage to save `feeSystemTypeCode` --- builder/ncloud/config.go | 9 ++++---- builder/ncloud/step_create_server_instance.go | 13 +++++++---- .../step_create_server_instance_test.go | 4 ++-- builder/ncloud/step_validate_template.go | 23 +++++++++++-------- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/builder/ncloud/config.go b/builder/ncloud/config.go index 5e713d44d..c8c1374bb 100644 --- a/builder/ncloud/config.go +++ b/builder/ncloud/config.go @@ -2,6 +2,8 @@ package ncloud import ( "errors" + "fmt" + "os" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -26,7 +28,6 @@ type Config struct { BlockStorageSize int `mapstructure:"block_storage_size"` Region string `mapstructure:"region"` AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no"` - FeeSystemTypeCode string `mapstructure:"-"` Comm communicator.Config `mapstructure:",squash"` ctx *interpolate.Context @@ -93,10 +94,10 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { } if c.UserData != "" && c.UserDataFile != "" { - errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) + errs = packer.MultiErrorAppend(errs, errors.New("Only one of user_data or user_data_file can be specified.")) } else if c.UserDataFile != "" { if _, err := os.Stat(c.UserDataFile); err != nil { - errs = append(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) + errs = packer.MultiErrorAppend(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) } } @@ -108,8 +109,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, errors.New("If Communicator is winrm, access_control_group_configuration_no is required")) } - c.FeeSystemTypeCode = "MTRAT" - if errs != nil && len(errs.Errors) > 0 { return nil, warnings, errs } diff --git a/builder/ncloud/step_create_server_instance.go b/builder/ncloud/step_create_server_instance.go index 3a842f899..346ce3a1c 100644 --- a/builder/ncloud/step_create_server_instance.go +++ b/builder/ncloud/step_create_server_instance.go @@ -14,7 +14,7 @@ import ( type StepCreateServerInstance struct { Conn *ncloud.Conn - CreateServerInstance func(loginKeyName string, zoneNo string) (string, error) + CreateServerInstance func(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) CheckServerInstanceStatusIsRunning func(serverInstanceNo string) error Say func(message string) Error func(e error) @@ -35,7 +35,7 @@ func NewStepCreateServerInstance(conn *ncloud.Conn, ui packer.Ui, config *Config return step } -func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zoneNo string) (string, error) { +func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) { reqParams := new(ncloud.RequestCreateServerInstance) reqParams.ServerProductCode = s.Config.ServerProductCode reqParams.MemberServerImageNo = s.Config.MemberServerImageNo @@ -44,7 +44,7 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon } reqParams.LoginKeyName = loginKeyName reqParams.ZoneNo = zoneNo - reqParams.FeeSystemTypeCode = s.Config.FeeSystemTypeCode + reqParams.FeeSystemTypeCode = feeSystemTypeCode if s.Config.UserData != "" { reqParams.UserData = s.Config.UserData @@ -87,7 +87,12 @@ func (s *StepCreateServerInstance) Run(state multistep.StateBag) multistep.StepA var loginKey = state.Get("LoginKey").(*LoginKey) var zoneNo = state.Get("ZoneNo").(string) - serverInstanceNo, err := s.CreateServerInstance(loginKey.KeyName, zoneNo) + feeSystemTypeCode := "MTRAT" + if _, ok := state.GetOk("FeeSystemTypeCode"); ok { + feeSystemTypeCode = state.Get("FeeSystemTypeCode").(string) + } + + serverInstanceNo, err := s.CreateServerInstance(loginKey.KeyName, zoneNo, feeSystemTypeCode) if err == nil { state.Put("InstanceNo", serverInstanceNo) } diff --git a/builder/ncloud/step_create_server_instance_test.go b/builder/ncloud/step_create_server_instance_test.go index 327228b75..ddaa34157 100644 --- a/builder/ncloud/step_create_server_instance_test.go +++ b/builder/ncloud/step_create_server_instance_test.go @@ -8,7 +8,7 @@ import ( func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T) { var testSubject = &StepCreateServerInstance{ - CreateServerInstance: func(loginKeyName string, zoneNo string) (string, error) { + CreateServerInstance: func(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") }, Say: func(message string) {}, @@ -30,7 +30,7 @@ func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T) func TestStepCreateServerInstanceShouldPassIfOperationCreatePasses(t *testing.T) { var testSubject = &StepCreateServerInstance{ - CreateServerInstance: func(loginKeyName string, zoneNo string) (string, error) { return "", nil }, + CreateServerInstance: func(loginKeyName string, zoneNo string, feeSystemTypeCode string) (string, error) { return "", nil }, Say: func(message string) {}, Error: func(e error) {}, } diff --git a/builder/ncloud/step_validate_template.go b/builder/ncloud/step_validate_template.go index d645111c4..d4c576946 100644 --- a/builder/ncloud/step_validate_template.go +++ b/builder/ncloud/step_validate_template.go @@ -14,13 +14,14 @@ import ( //StepValidateTemplate : struct for Validation a tempalte type StepValidateTemplate struct { - Conn *ncloud.Conn - Validate func() error - Say func(message string) - Error func(e error) - Config *Config - zoneNo string - regionNo string + Conn *ncloud.Conn + Validate func() error + Say func(message string) + Error func(e error) + Config *Config + zoneNo string + regionNo string + FeeSystemTypeCode string } // NewStepValidateTemplate : funciton for Validation a tempalte @@ -168,7 +169,7 @@ func (s *StepValidateTemplate) validateServerImageProduct() error { } if strings.Contains(productName, "mssql") { - s.Config.FeeSystemTypeCode = "FXSUM" + s.FeeSystemTypeCode = "FXSUM" } return nil @@ -193,7 +194,7 @@ func (s *StepValidateTemplate) validateServerProductCode() error { if product.ProductCode == productCode { isExistProductCode = true if strings.Contains(product.ProductName, "mssql") { - s.Config.FeeSystemTypeCode = "FXSUM" + s.FeeSystemTypeCode = "FXSUM" } if product.ProductType.Code == "VDS" { @@ -255,6 +256,10 @@ func (s *StepValidateTemplate) Run(state multistep.StateBag) multistep.StepActio state.Put("ZoneNo", s.zoneNo) + if s.FeeSystemTypeCode != "" { + state.Put("FeeSystemTypeCode", s.FeeSystemTypeCode) + } + return processStepResult(err, s.Error, state) } From 30f8fee40259c2daa0e4d872683d31ee212fbc6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 19:08:53 +0900 Subject: [PATCH 0511/1007] use comment with english --- builder/ncloud/step_create_server_image.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/ncloud/step_create_server_image.go b/builder/ncloud/step_create_server_image.go index ea0784058..8bec7f11f 100644 --- a/builder/ncloud/step_create_server_image.go +++ b/builder/ncloud/step_create_server_image.go @@ -32,7 +32,7 @@ func NewStepCreateServerImage(conn *ncloud.Conn, ui packer.Ui, config *Config) * } func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*ncloud.ServerImage, error) { - // 서버 인스턴스 상태가 정지 중일 경우에는 서버 이미지 생성할 수 없음. + // Can't create server image when status of server instance is stopping (not stopped) if err := waiterServerInstanceStatus(s.Conn, serverInstanceNo, "NSTOP", 1*time.Minute); err != nil { return nil, err } From 2a3a35334a9237d521f3e644e204c454ae1f595a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 20:42:22 +0900 Subject: [PATCH 0512/1007] Logging root password --- builder/ncloud/step_get_rootpassword.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go index b696e594d..9ec0feae2 100644 --- a/builder/ncloud/step_get_rootpassword.go +++ b/builder/ncloud/step_get_rootpassword.go @@ -35,6 +35,8 @@ func (s *StepGetRootPassword) getRootPassword(serverInstanceNo string, privateKe return "", err } + s.Say(fmt.Sprintf("Root password is %s", rootPassword.RootPassword)) + return rootPassword.RootPassword, nil } From e57a8161e06d7fd24904b23e474c40b063a78b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 21:47:58 +0900 Subject: [PATCH 0513/1007] remove delete step of `login key` and `public ip instance`. --- builder/ncloud/builder.go | 4 - builder/ncloud/step_create_login_key.go | 7 -- .../ncloud/step_create_public_ip_instance.go | 12 ++- builder/ncloud/step_delete_login_key.go | 51 ------------ builder/ncloud/step_delete_login_key_test.go | 55 ------------- .../ncloud/step_delete_public_ip_instance.go | 78 ------------------- .../step_delete_public_ip_instance_test.go | 57 -------------- builder/ncloud/step_get_rootpassword.go | 2 + 8 files changed, 7 insertions(+), 259 deletions(-) delete mode 100644 builder/ncloud/step_delete_login_key.go delete mode 100644 builder/ncloud/step_delete_login_key_test.go delete mode 100644 builder/ncloud/step_delete_public_ip_instance.go delete mode 100644 builder/ncloud/step_delete_public_ip_instance_test.go diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index 24ec670d3..21435e6d0 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -56,8 +56,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepCreateServerImage(conn, ui, b.config), NewStepDeleteBlockStorageInstance(conn, ui, b.config), NewStepTerminateServerInstance(conn, ui), - NewStepDeleteLoginKey(conn, ui), - NewStepDeletePublicIPInstance(conn, ui), } } else if b.config.Comm.Type == "Windows" { steps = []multistep.Step{ @@ -84,8 +82,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepCreateServerImage(conn, ui, b.config), NewStepDeleteBlockStorageInstance(conn, ui, b.config), NewStepTerminateServerInstance(conn, ui), - NewStepDeleteLoginKey(conn, ui), - NewStepDeletePublicIPInstance(conn, ui), } } diff --git a/builder/ncloud/step_create_login_key.go b/builder/ncloud/step_create_login_key.go index d200c3106..f79c4decf 100644 --- a/builder/ncloud/step_create_login_key.go +++ b/builder/ncloud/step_create_login_key.go @@ -57,13 +57,6 @@ func (s *StepCreateLoginKey) Run(state multistep.StateBag) multistep.StepAction } func (s *StepCreateLoginKey) Cleanup(state multistep.StateBag) { - _, cancelled := state.GetOk(multistep.StateCancelled) - _, halted := state.GetOk(multistep.StateHalted) - - if !cancelled && !halted { - return - } - if loginKey, ok := state.GetOk("LoginKey"); ok { s.Say("Clean up login key") s.Conn.DeleteLoginKey(loginKey.(*LoginKey).KeyName) diff --git a/builder/ncloud/step_create_public_ip_instance.go b/builder/ncloud/step_create_public_ip_instance.go index 897ff1504..d15fd9f54 100644 --- a/builder/ncloud/step_create_public_ip_instance.go +++ b/builder/ncloud/step_create_public_ip_instance.go @@ -105,13 +105,6 @@ func (s *StepCreatePublicIPInstance) Run(state multistep.StateBag) multistep.Ste } func (s *StepCreatePublicIPInstance) Cleanup(state multistep.StateBag) { - _, cancelled := state.GetOk(multistep.StateCancelled) - _, halted := state.GetOk(multistep.StateHalted) - - if !cancelled && !halted { - return - } - publicIPInstance, ok := state.GetOk("PublicIPInstance") if !ok { return @@ -148,6 +141,11 @@ func (s *StepCreatePublicIPInstance) waitPublicIPInstanceStatus(publicIPInstance return } + if resp.TotalRows == 0 { + c1 <- nil + return + } + instance := resp.PublicIPInstanceList[0] if instance.PublicIPInstanceStatus.Code == status && instance.PublicIPInstanceOperation.Code == "NULL" { c1 <- nil diff --git a/builder/ncloud/step_delete_login_key.go b/builder/ncloud/step_delete_login_key.go deleted file mode 100644 index 18256c7d8..000000000 --- a/builder/ncloud/step_delete_login_key.go +++ /dev/null @@ -1,51 +0,0 @@ -package ncloud - -import ( - "fmt" - - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" -) - -type StepDeleteLoginKey struct { - Conn *ncloud.Conn - DeleteLoginKey func(keyName string) error - Say func(message string) - Error func(e error) -} - -func NewStepDeleteLoginKey(conn *ncloud.Conn, ui packer.Ui) *StepDeleteLoginKey { - var step = &StepDeleteLoginKey{ - Conn: conn, - Say: func(message string) { ui.Say(message) }, - Error: func(e error) { ui.Error(e.Error()) }, - } - - step.DeleteLoginKey = step.deleteLoginKey - - return step -} - -func (s *StepDeleteLoginKey) deleteLoginKey(keyName string) error { - _, err := s.Conn.DeleteLoginKey(keyName) - if err != nil { - return err - } - - return nil -} - -func (s *StepDeleteLoginKey) Run(state multistep.StateBag) multistep.StepAction { - var loginKey = state.Get("LoginKey").(*LoginKey) - - err := s.DeleteLoginKey(loginKey.KeyName) - if err == nil { - s.Say(fmt.Sprintf("Login Key[%s] is deleted", loginKey.KeyName)) - } - - return processStepResult(err, s.Error, state) -} - -func (*StepDeleteLoginKey) Cleanup(multistep.StateBag) { -} diff --git a/builder/ncloud/step_delete_login_key_test.go b/builder/ncloud/step_delete_login_key_test.go deleted file mode 100644 index 38ce1e22c..000000000 --- a/builder/ncloud/step_delete_login_key_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package ncloud - -import ( - "fmt" - "github.com/mitchellh/multistep" - "testing" -) - -func TestStepDeleteLoginKeyShouldFailIfOperationDeleteLoginKeyFails(t *testing.T) { - var testSubject = &StepDeleteLoginKey{ - DeleteLoginKey: func(keyName string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, - Say: func(message string) {}, - Error: func(e error) {}, - } - - stateBag := DeleteTestStateBagStepDeleteLoginKey() - - var result = testSubject.Run(stateBag) - - if result != multistep.ActionHalt { - t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) - } - - if _, ok := stateBag.GetOk("Error"); ok == false { - t.Fatal("Expected the step to set stateBag['Error'], but it was not.") - } -} - -func TestStepDeleteLoginKeyShouldPassIfOperationDeleteLoginKeyPasses(t *testing.T) { - var testSubject = &StepDeleteLoginKey{ - DeleteLoginKey: func(keyName string) error { return nil }, - Say: func(message string) {}, - Error: func(e error) {}, - } - - stateBag := DeleteTestStateBagStepDeleteLoginKey() - - var result = testSubject.Run(stateBag) - - if result != multistep.ActionContinue { - t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) - } - - if _, ok := stateBag.GetOk("Error"); ok == true { - t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") - } -} - -func DeleteTestStateBagStepDeleteLoginKey() multistep.StateBag { - stateBag := new(multistep.BasicStateBag) - - stateBag.Put("LoginKey", &LoginKey{"a", "b"}) - - return stateBag -} diff --git a/builder/ncloud/step_delete_public_ip_instance.go b/builder/ncloud/step_delete_public_ip_instance.go deleted file mode 100644 index 4a1401984..000000000 --- a/builder/ncloud/step_delete_public_ip_instance.go +++ /dev/null @@ -1,78 +0,0 @@ -package ncloud - -import ( - "errors" - "fmt" - "log" - "time" - - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" -) - -type StepDeletePublicIPInstance struct { - Conn *ncloud.Conn - DeletePublicIPInstance func(publicIPInstanceNo string) error - Say func(message string) - Error func(e error) -} - -func NewStepDeletePublicIPInstance(conn *ncloud.Conn, ui packer.Ui) *StepDeletePublicIPInstance { - var step = &StepDeletePublicIPInstance{ - Conn: conn, - Say: func(message string) { ui.Say(message) }, - Error: func(e error) { ui.Error(e.Error()) }, - } - - step.DeletePublicIPInstance = step.deletePublicIPInstance - - return step -} - -func (s *StepDeletePublicIPInstance) deletePublicIPInstance(publicIPInstanceNo string) error { - reqParams := new(ncloud.RequestDeletePublicIPInstances) - reqParams.PublicIPInstanceNoList = []string{publicIPInstanceNo} - - c1 := make(chan error, 1) - - go func() { - for { - resp, err := s.Conn.DeletePublicIPInstances(reqParams) - if err != nil && (resp.ReturnCode == 24073 || resp.ReturnCode == 25032) { - // error code : 24073 : Unable to destroy the server since a public IP is associated with the server. First, please disassociate a public IP from the server. - // error code : 25032 : You may not delete sk since (other) user is changing the target official IP settings. - log.Println(resp.ReturnCode, resp.ReturnMessage) - } else if err != nil { - c1 <- fmt.Errorf("error code: %d, error message: %s", resp.ReturnCode, resp.ReturnMessage) - return - } else if err == nil { - s.Say(fmt.Sprintf("Public IP Instance [%s] is deleted.", publicIPInstanceNo)) - c1 <- nil - return - } - - time.Sleep(time.Second * 5) - } - }() - - select { - case res := <-c1: - return res - case <-time.After(time.Second * 60): - return errors.New("TIMEOUT : Can't delete server instance") - } -} - -func (s *StepDeletePublicIPInstance) Run(state multistep.StateBag) multistep.StepAction { - s.Say("Delete Public IP Instance") - - publicIPInstance := state.Get("PublicIPInstance").(*ncloud.PublicIPInstance) - - err := s.DeletePublicIPInstance(publicIPInstance.PublicIPInstanceNo) - - return processStepResult(err, s.Error, state) -} - -func (*StepDeletePublicIPInstance) Cleanup(multistep.StateBag) { -} diff --git a/builder/ncloud/step_delete_public_ip_instance_test.go b/builder/ncloud/step_delete_public_ip_instance_test.go deleted file mode 100644 index b9fa04ec8..000000000 --- a/builder/ncloud/step_delete_public_ip_instance_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package ncloud - -import ( - "fmt" - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" - "testing" - - "github.com/mitchellh/multistep" -) - -func TestStepDeletePublicIPInstanceShouldFailIfOperationDeletePublicIPInstanceFails(t *testing.T) { - var testSubject = &StepDeletePublicIPInstance{ - DeletePublicIPInstance: func(publicIPInstanceNo string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, - Say: func(message string) {}, - Error: func(e error) {}, - } - - stateBag := createTestStateBagStepDeletePublicIPInstance() - - var result = testSubject.Run(stateBag) - - if result != multistep.ActionHalt { - t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) - } - - if _, ok := stateBag.GetOk("Error"); ok == false { - t.Fatal("Expected the step to set stateBag['Error'], but it was not.") - } -} - -func TestStepDeletePublicIPInstanceShouldPassIfOperationDeletePublicIPInstancePasses(t *testing.T) { - var testSubject = &StepDeletePublicIPInstance{ - DeletePublicIPInstance: func(publicIPInstanceNo string) error { return nil }, - Say: func(message string) {}, - Error: func(e error) {}, - } - - stateBag := createTestStateBagStepDeletePublicIPInstance() - - var result = testSubject.Run(stateBag) - - if result != multistep.ActionContinue { - t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) - } - - if _, ok := stateBag.GetOk("Error"); ok == true { - t.Fatalf("Expected the step to not set stateBag['Error'], but it was.") - } -} - -func createTestStateBagStepDeletePublicIPInstance() multistep.StateBag { - stateBag := new(multistep.BasicStateBag) - - stateBag.Put("PublicIPInstance", &ncloud.PublicIPInstance{PublicIPInstanceNo: "22"}) - - return stateBag -} diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go index 9ec0feae2..d9eda578a 100644 --- a/builder/ncloud/step_get_rootpassword.go +++ b/builder/ncloud/step_get_rootpassword.go @@ -1,6 +1,8 @@ package ncloud import ( + "fmt" + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" From 6b40c726e0f742c73964f3150e9aec9f91c6f3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 22:07:32 +0900 Subject: [PATCH 0514/1007] Use `PublicIp` for communicator --- builder/ncloud/builder.go | 8 +++++--- builder/ncloud/ssh.go | 5 ----- builder/ncloud/step_create_public_ip_instance.go | 8 +------- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index 21435e6d0..e493661be 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -47,8 +47,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepGetRootPassword(conn, ui), NewStepCreatePublicIPInstance(conn, ui, b.config), &communicator.StepConnectSSH{ - Config: &b.config.Comm, - Host: SSHHost, + Config: &b.config.Comm, + Host: func(stateBag multistep.StateBag) (string, error) { + return stateBag.Get("PublicIP").(string), nil + }, SSHConfig: SSHConfig(b.config.Comm.SSHUsername), }, &common.StepProvision{}, @@ -68,7 +70,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &communicator.StepConnectWinRM{ Config: &b.config.Comm, Host: func(stateBag multistep.StateBag) (string, error) { - return stateBag.Get("WinRMHost").(string), nil + return stateBag.Get("PublicIP").(string), nil }, WinRMConfig: func(state multistep.StateBag) (*communicator.WinRMConfig, error) { return &communicator.WinRMConfig{ diff --git a/builder/ncloud/ssh.go b/builder/ncloud/ssh.go index ee7d99226..5e7d31748 100644 --- a/builder/ncloud/ssh.go +++ b/builder/ncloud/ssh.go @@ -6,11 +6,6 @@ import ( "golang.org/x/crypto/ssh" ) -func SSHHost(state multistep.StateBag) (string, error) { - host := state.Get("SSHHost").(string) - return host, nil -} - // SSHConfig returns a function that can be used for the SSH communicator // config for connecting to the specified host via SSH func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) { diff --git a/builder/ncloud/step_create_public_ip_instance.go b/builder/ncloud/step_create_public_ip_instance.go index d15fd9f54..e9c4a8e37 100644 --- a/builder/ncloud/step_create_public_ip_instance.go +++ b/builder/ncloud/step_create_public_ip_instance.go @@ -91,13 +91,7 @@ func (s *StepCreatePublicIPInstance) Run(state multistep.StateBag) multistep.Ste publicIPInstance, err := s.CreatePublicIPInstance(serverInstanceNo) if err == nil { - switch s.Config.Comm.Type { - case "ssh": - state.Put("SSHHost", publicIPInstance.PublicIP) - case "winrm": - state.Put("WinRMHost", publicIPInstance.PublicIP) - } - + state.Put("PublicIP", publicIPInstance.PublicIP) state.Put("PublicIPInstance", publicIPInstance) } From 175dd2730f3465c12f0a7a95440df35643384eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 22:41:22 +0900 Subject: [PATCH 0515/1007] Use 'github.com/hashicorp/packer/helper/multistep' --- builder/ncloud/builder.go | 2 +- builder/ncloud/ssh.go | 2 +- builder/ncloud/step.go | 2 +- builder/ncloud/step_create_block_storage_instance.go | 5 +++-- builder/ncloud/step_create_block_storage_instance_test.go | 3 ++- builder/ncloud/step_create_login_key.go | 5 +++-- builder/ncloud/step_create_login_key_test.go | 3 ++- builder/ncloud/step_create_public_ip_instance.go | 5 +++-- builder/ncloud/step_create_public_ip_instance_test.go | 5 +++-- builder/ncloud/step_create_server_image.go | 5 +++-- builder/ncloud/step_create_server_image_test.go | 5 +++-- builder/ncloud/step_create_server_instance.go | 5 +++-- builder/ncloud/step_create_server_instance_test.go | 3 ++- builder/ncloud/step_delete_block_storage_instance.go | 5 +++-- builder/ncloud/step_delete_block_storage_instance_test.go | 3 ++- builder/ncloud/step_get_rootpassword.go | 5 +++-- builder/ncloud/step_get_rootpassword_test.go | 3 ++- builder/ncloud/step_stop_server_instance.go | 5 +++-- builder/ncloud/step_stop_server_instance_test.go | 2 +- builder/ncloud/step_terminate_server_instance.go | 5 +++-- builder/ncloud/step_terminate_server_instance_test.go | 3 ++- builder/ncloud/step_validate_template.go | 5 +++-- builder/ncloud/step_validate_template_test.go | 2 +- 23 files changed, 53 insertions(+), 35 deletions(-) diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index e493661be..18f45b53c 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -5,7 +5,7 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) // Builder assume this implements packer.Builder diff --git a/builder/ncloud/ssh.go b/builder/ncloud/ssh.go index 5e7d31748..08764aee6 100644 --- a/builder/ncloud/ssh.go +++ b/builder/ncloud/ssh.go @@ -2,7 +2,7 @@ package ncloud import ( packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" ) diff --git a/builder/ncloud/step.go b/builder/ncloud/step.go index ba71efbee..8b312fae7 100644 --- a/builder/ncloud/step.go +++ b/builder/ncloud/step.go @@ -1,7 +1,7 @@ package ncloud import ( - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func processStepResult(err error, sayError func(error), state multistep.StateBag) multistep.StepAction { diff --git a/builder/ncloud/step_create_block_storage_instance.go b/builder/ncloud/step_create_block_storage_instance.go index 7e4d4b54a..b135a15e7 100644 --- a/builder/ncloud/step_create_block_storage_instance.go +++ b/builder/ncloud/step_create_block_storage_instance.go @@ -1,14 +1,15 @@ package ncloud import ( + "context" "errors" "fmt" "log" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) // StepCreateBlockStorageInstance struct is for making extra block storage @@ -54,7 +55,7 @@ func (s *StepCreateBlockStorageInstance) createBlockStorageInstance(serverInstan return blockStorageInstanceList.BlockStorageInstance[0].BlockStorageInstanceNo, nil } -func (s *StepCreateBlockStorageInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateBlockStorageInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if s.Config.BlockStorageSize == 0 { return processStepResult(nil, s.Error, state) } diff --git a/builder/ncloud/step_create_block_storage_instance_test.go b/builder/ncloud/step_create_block_storage_instance_test.go index 101e94658..feae195d1 100644 --- a/builder/ncloud/step_create_block_storage_instance_test.go +++ b/builder/ncloud/step_create_block_storage_instance_test.go @@ -2,8 +2,9 @@ package ncloud import ( "fmt" - "github.com/mitchellh/multistep" "testing" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateBlockStorageInstanceShouldFailIfOperationCreateBlockStorageInstanceFails(t *testing.T) { diff --git a/builder/ncloud/step_create_login_key.go b/builder/ncloud/step_create_login_key.go index f79c4decf..05ef97739 100644 --- a/builder/ncloud/step_create_login_key.go +++ b/builder/ncloud/step_create_login_key.go @@ -1,12 +1,13 @@ package ncloud import ( + "context" "fmt" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type LoginKey struct { @@ -44,7 +45,7 @@ func (s *StepCreateLoginKey) createLoginKey() (*LoginKey, error) { return &LoginKey{KeyName, privateKey.PrivateKey}, nil } -func (s *StepCreateLoginKey) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateLoginKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Create Login Key") loginKey, err := s.CreateLoginKey() diff --git a/builder/ncloud/step_create_login_key_test.go b/builder/ncloud/step_create_login_key_test.go index 374d10330..6f0d7af8f 100644 --- a/builder/ncloud/step_create_login_key_test.go +++ b/builder/ncloud/step_create_login_key_test.go @@ -2,8 +2,9 @@ package ncloud import ( "fmt" - "github.com/mitchellh/multistep" "testing" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateLoginKeyShouldFailIfOperationCreateLoginKeyFails(t *testing.T) { diff --git a/builder/ncloud/step_create_public_ip_instance.go b/builder/ncloud/step_create_public_ip_instance.go index e9c4a8e37..d4cd72b6d 100644 --- a/builder/ncloud/step_create_public_ip_instance.go +++ b/builder/ncloud/step_create_public_ip_instance.go @@ -1,13 +1,14 @@ package ncloud import ( + "context" "fmt" "log" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreatePublicIPInstance struct { @@ -84,7 +85,7 @@ func (s *StepCreatePublicIPInstance) createPublicIPInstance(serverInstanceNo str return &publicIPInstance, nil } -func (s *StepCreatePublicIPInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreatePublicIPInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Create Public IP Instance") serverInstanceNo := state.Get("InstanceNo").(string) diff --git a/builder/ncloud/step_create_public_ip_instance_test.go b/builder/ncloud/step_create_public_ip_instance_test.go index 0f44f4a33..7269e3af5 100644 --- a/builder/ncloud/step_create_public_ip_instance_test.go +++ b/builder/ncloud/step_create_public_ip_instance_test.go @@ -2,10 +2,11 @@ package ncloud import ( "fmt" - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" "testing" - "github.com/mitchellh/multistep" + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreatePublicIPInstanceShouldFailIfOperationCreatePublicIPInstanceFails(t *testing.T) { diff --git a/builder/ncloud/step_create_server_image.go b/builder/ncloud/step_create_server_image.go index 8bec7f11f..447485641 100644 --- a/builder/ncloud/step_create_server_image.go +++ b/builder/ncloud/step_create_server_image.go @@ -1,13 +1,14 @@ package ncloud import ( + "context" "errors" "fmt" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreateServerImage struct { @@ -60,7 +61,7 @@ func (s *StepCreateServerImage) createServerImage(serverInstanceNo string) (*ncl return &serverImage, nil } -func (s *StepCreateServerImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateServerImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Create Server Image") serverInstanceNo := state.Get("InstanceNo").(string) diff --git a/builder/ncloud/step_create_server_image_test.go b/builder/ncloud/step_create_server_image_test.go index 41a40971a..fa7745135 100644 --- a/builder/ncloud/step_create_server_image_test.go +++ b/builder/ncloud/step_create_server_image_test.go @@ -2,10 +2,11 @@ package ncloud import ( "fmt" - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" "testing" - "github.com/mitchellh/multistep" + ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateServerImageShouldFailIfOperationCreateServerImageFails(t *testing.T) { diff --git a/builder/ncloud/step_create_server_instance.go b/builder/ncloud/step_create_server_instance.go index 346ce3a1c..a8a72586d 100644 --- a/builder/ncloud/step_create_server_instance.go +++ b/builder/ncloud/step_create_server_instance.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "errors" "fmt" "io/ioutil" @@ -8,8 +9,8 @@ import ( "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepCreateServerInstance struct { @@ -81,7 +82,7 @@ func (s *StepCreateServerInstance) createServerInstance(loginKeyName string, zon return s.serverInstanceNo, nil } -func (s *StepCreateServerInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepCreateServerInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Create Server Instance") var loginKey = state.Get("LoginKey").(*LoginKey) diff --git a/builder/ncloud/step_create_server_instance_test.go b/builder/ncloud/step_create_server_instance_test.go index ddaa34157..db337c41b 100644 --- a/builder/ncloud/step_create_server_instance_test.go +++ b/builder/ncloud/step_create_server_instance_test.go @@ -2,8 +2,9 @@ package ncloud import ( "fmt" - "github.com/mitchellh/multistep" "testing" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T) { diff --git a/builder/ncloud/step_delete_block_storage_instance.go b/builder/ncloud/step_delete_block_storage_instance.go index 61f8b7c3c..d43edf1c9 100644 --- a/builder/ncloud/step_delete_block_storage_instance.go +++ b/builder/ncloud/step_delete_block_storage_instance.go @@ -1,14 +1,15 @@ package ncloud import ( + "context" "errors" "fmt" "log" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepDeleteBlockStorageInstance struct { @@ -77,7 +78,7 @@ func (s *StepDeleteBlockStorageInstance) deleteBlockStorageInstance(serverInstan return nil } -func (s *StepDeleteBlockStorageInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepDeleteBlockStorageInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { if s.Config.BlockStorageSize == 0 { return processStepResult(nil, s.Error, state) } diff --git a/builder/ncloud/step_delete_block_storage_instance_test.go b/builder/ncloud/step_delete_block_storage_instance_test.go index ce0f0cb09..c5fc4566e 100644 --- a/builder/ncloud/step_delete_block_storage_instance_test.go +++ b/builder/ncloud/step_delete_block_storage_instance_test.go @@ -2,8 +2,9 @@ package ncloud import ( "fmt" - "github.com/mitchellh/multistep" "testing" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepDeleteBlockStorageInstanceShouldFailIfOperationDeleteBlockStorageInstanceFails(t *testing.T) { diff --git a/builder/ncloud/step_get_rootpassword.go b/builder/ncloud/step_get_rootpassword.go index d9eda578a..051eb386b 100644 --- a/builder/ncloud/step_get_rootpassword.go +++ b/builder/ncloud/step_get_rootpassword.go @@ -1,11 +1,12 @@ package ncloud import ( + "context" "fmt" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepGetRootPassword struct { @@ -42,7 +43,7 @@ func (s *StepGetRootPassword) getRootPassword(serverInstanceNo string, privateKe return rootPassword.RootPassword, nil } -func (s *StepGetRootPassword) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepGetRootPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Get Root Password") serverInstanceNo := state.Get("InstanceNo").(string) diff --git a/builder/ncloud/step_get_rootpassword_test.go b/builder/ncloud/step_get_rootpassword_test.go index b9ed6aa56..1717b5753 100644 --- a/builder/ncloud/step_get_rootpassword_test.go +++ b/builder/ncloud/step_get_rootpassword_test.go @@ -2,8 +2,9 @@ package ncloud import ( "fmt" - "github.com/mitchellh/multistep" "testing" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepGetRootPasswordShouldFailIfOperationGetRootPasswordFails(t *testing.T) { diff --git a/builder/ncloud/step_stop_server_instance.go b/builder/ncloud/step_stop_server_instance.go index f9cce7d9f..293c8e55d 100644 --- a/builder/ncloud/step_stop_server_instance.go +++ b/builder/ncloud/step_stop_server_instance.go @@ -1,13 +1,14 @@ package ncloud import ( + "context" "fmt" "log" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepStopServerInstance struct { @@ -50,7 +51,7 @@ func (s *StepStopServerInstance) stopServerInstance(serverInstanceNo string) err return nil } -func (s *StepStopServerInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepStopServerInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Stop Server Instance") var serverInstanceNo = state.Get("InstanceNo").(string) diff --git a/builder/ncloud/step_stop_server_instance_test.go b/builder/ncloud/step_stop_server_instance_test.go index d90bc6953..04c39d313 100644 --- a/builder/ncloud/step_stop_server_instance_test.go +++ b/builder/ncloud/step_stop_server_instance_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepStopServerInstanceShouldFailIfOperationStopFails(t *testing.T) { diff --git a/builder/ncloud/step_terminate_server_instance.go b/builder/ncloud/step_terminate_server_instance.go index aa154812b..f6c8d281a 100644 --- a/builder/ncloud/step_terminate_server_instance.go +++ b/builder/ncloud/step_terminate_server_instance.go @@ -1,12 +1,13 @@ package ncloud import ( + "context" "errors" "time" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" ) type StepTerminateServerInstance struct { @@ -66,7 +67,7 @@ func (s *StepTerminateServerInstance) terminateServerInstance(serverInstanceNo s } } -func (s *StepTerminateServerInstance) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepTerminateServerInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Terminate Server Instance") var serverInstanceNo = state.Get("InstanceNo").(string) diff --git a/builder/ncloud/step_terminate_server_instance_test.go b/builder/ncloud/step_terminate_server_instance_test.go index b5967fc65..9256b85b9 100644 --- a/builder/ncloud/step_terminate_server_instance_test.go +++ b/builder/ncloud/step_terminate_server_instance_test.go @@ -2,8 +2,9 @@ package ncloud import ( "fmt" - "github.com/mitchellh/multistep" "testing" + + "github.com/hashicorp/packer/helper/multistep" ) func TestStepTerminateServerInstanceShouldFailIfOperationTerminationFails(t *testing.T) { diff --git a/builder/ncloud/step_validate_template.go b/builder/ncloud/step_validate_template.go index d4c576946..c63c5f04b 100644 --- a/builder/ncloud/step_validate_template.go +++ b/builder/ncloud/step_validate_template.go @@ -2,13 +2,14 @@ package ncloud import ( "bytes" + "context" "errors" "fmt" "strings" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/olekukonko/tablewriter" ) @@ -249,7 +250,7 @@ func (s *StepValidateTemplate) validateTemplate() error { } // Run : main funciton for validation a template -func (s *StepValidateTemplate) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepValidateTemplate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Validating deployment template ...") err := s.Validate() diff --git a/builder/ncloud/step_validate_template_test.go b/builder/ncloud/step_validate_template_test.go index 98f45b4a0..6836f8446 100644 --- a/builder/ncloud/step_validate_template_test.go +++ b/builder/ncloud/step_validate_template_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" ) func TestStepValidateTemplateShouldFailIfValidateFails(t *testing.T) { From e68a742bca2b91488eadcc3c3cf0ad336912e059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Mon, 29 Jan 2018 22:44:24 +0900 Subject: [PATCH 0516/1007] make fmt --- builder/ncloud/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index 18f45b53c..b1aaef790 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -4,8 +4,8 @@ import ( ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" - "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" ) // Builder assume this implements packer.Builder From 705459c26060e98691db345a83ec9dc5e7f03e4f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 29 Jan 2018 16:50:53 -0800 Subject: [PATCH 0517/1007] add snapshotted machine image to image lists, then delete the snapshot. --- builder/oracle/classic/builder.go | 1 + builder/oracle/classic/config.go | 22 +++--- .../oracle/classic/step_create_instance.go | 2 +- builder/oracle/classic/step_list_images.go | 70 +++++++++++++++++++ builder/oracle/classic/step_snapshot.go | 19 ++++- 5 files changed, 103 insertions(+), 11 deletions(-) create mode 100644 builder/oracle/classic/step_list_images.go diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 8537289cf..088ff4dbc 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -80,6 +80,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &common.StepProvision{}, &stepSnapshot{}, + &stepListImages{}, } // Run the steps diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 7b2f7dfb2..e0c82beb2 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -23,9 +23,13 @@ type Config struct { apiEndpointURL *url.URL // Image - ImageName string `mapstructure:"image_name"` - Shape string `mapstructure:"shape"` - ImageList string `mapstructure:"image_list"` + ImageName string `mapstructure:"image_name"` + Shape string `mapstructure:"shape"` + SourceImageList string `mapstructure:"source_image_list"` + DestImageList string `mapstructure:"dest_image_list"` + // Optional; if you don't enter anything, the image list description + // will read "Packer-built image list" + DestImageListDescription string `mapstructure:"dest_image_list_description` // Optional. Describes what computers are allowed to reach your instance // via SSH. This whitelist must contain the computer you're running Packer // from. It defaults to public-internet, meaning that you can SSH into your @@ -63,12 +67,12 @@ func NewConfig(raws ...interface{}) (*Config, error) { // Validate that all required fields are present var errs *packer.MultiError required := map[string]string{ - "username": c.Username, - "password": c.Password, - "api_endpoint": c.APIEndpoint, - "identity_domain": c.IdentityDomain, - "image_list": c.ImageList, - "shape": c.Shape, + "username": c.Username, + "password": c.Password, + "api_endpoint": c.APIEndpoint, + "identity_domain": c.IdentityDomain, + "source_image_list": c.SourceImageList, + "shape": c.Shape, } for k, v := range required { if v == "" { diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index ea840cb22..891fda33e 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -35,7 +35,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu input := &compute.CreateInstanceInput{ Name: config.ImageName, Shape: config.Shape, - ImageList: config.ImageList, + ImageList: config.SourceImageList, SSHKeys: []string{keyName}, Networking: map[string]compute.NetworkingInfo{"eth0": netInfo}, } diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go new file mode 100644 index 000000000..8d0c5ee12 --- /dev/null +++ b/builder/oracle/classic/step_list_images.go @@ -0,0 +1,70 @@ +package classic + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type stepListImages struct{} + +func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // get variables from state + ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) + client := state.Get("client").(*compute.ComputeClient) + ui.Say("Adding image to image list...") + + // TODO: Try to get image list + imageListClient := client.ImageList() + getInput := compute.GetImageListInput{ + Name: config.DestImageList, + } + imList, err := imageListClient.GetImageList(&getInput) + if err != nil { + ui.Say(fmt.Sprintf(err.Error())) + // If the list didn't exist, create it. + ui.Say(fmt.Sprintf("Creating image list: %s", config.DestImageList)) + + ilInput := compute.CreateImageListInput{ + Name: config.DestImageList, + Description: "Packer-built image list", + } + + // Load the packer-generated SSH key into the Oracle Compute cloud. + imList, err = imageListClient.CreateImageList(&ilInput) + if err != nil { + err = fmt.Errorf("Problem creating an image list through Oracle's API: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + ui.Message(fmt.Sprintf("Image list %s created!", imList.URI)) + } + + // Now create and image list entry for the image into that list. + snap := state.Get("snapshot").(*compute.Snapshot) + entriesClient := client.ImageListEntries() + entriesInput := compute.CreateImageListEntryInput{ + Name: config.DestImageList, + MachineImages: []string{fmt.Sprintf("Compute-%s/%s/%s", config.IdentityDomain, config.Username, snap.MachineImage)}, + Version: 1, + } + entryInfo, err := entriesClient.CreateImageListEntry(&entriesInput) + if err != nil { + err = fmt.Errorf("Problem creating an image list entry: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + ui.Message(fmt.Sprintf("created image list entry %s", entryInfo.Name)) + return multistep.ActionContinue +} + +func (s *stepListImages) Cleanup(state multistep.StateBag) { + // Nothing to do + return +} diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 602ebd1ad..b98530691 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -42,5 +42,22 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste } func (s *stepSnapshot) Cleanup(state multistep.StateBag) { - // Nothing to do + // Delete the snapshot + ui := state.Get("ui").(packer.Ui) + ui.Say("Creating Snapshot...") + client := state.Get("client").(*compute.ComputeClient) + snap := state.Get("snapshot").(*compute.Snapshot) + snapClient := client.Snapshots() + snapInput := compute.DeleteSnapshotInput{ + Snapshot: snap.Name, + MachineImage: snap.MachineImage, + } + machineClient := client.MachineImages() + err := snapClient.DeleteSnapshot(machineClient, &snapInput) + if err != nil { + err = fmt.Errorf("Problem deleting snapshot: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + } + return } From f39c3458f71b98101903e932720a9a0e2c9d24b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Tue, 30 Jan 2018 10:20:02 +0900 Subject: [PATCH 0518/1007] fix Run method arguments for testing --- builder/ncloud/step_create_block_storage_instance_test.go | 5 +++-- builder/ncloud/step_create_login_key_test.go | 5 +++-- builder/ncloud/step_create_public_ip_instance_test.go | 5 +++-- builder/ncloud/step_create_server_image_test.go | 5 +++-- builder/ncloud/step_create_server_instance_test.go | 5 +++-- builder/ncloud/step_delete_block_storage_instance_test.go | 5 +++-- builder/ncloud/step_get_rootpassword_test.go | 5 +++-- builder/ncloud/step_stop_server_instance_test.go | 5 +++-- builder/ncloud/step_terminate_server_instance_test.go | 5 +++-- builder/ncloud/step_validate_template_test.go | 5 +++-- 10 files changed, 30 insertions(+), 20 deletions(-) diff --git a/builder/ncloud/step_create_block_storage_instance_test.go b/builder/ncloud/step_create_block_storage_instance_test.go index feae195d1..6f4a9e4e2 100644 --- a/builder/ncloud/step_create_block_storage_instance_test.go +++ b/builder/ncloud/step_create_block_storage_instance_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -20,7 +21,7 @@ func TestStepCreateBlockStorageInstanceShouldFailIfOperationCreateBlockStorageIn stateBag := createTestStateBagStepCreateBlockStorageInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -43,7 +44,7 @@ func TestStepCreateBlockStorageInstanceShouldPassIfOperationCreateBlockStorageIn stateBag := createTestStateBagStepCreateBlockStorageInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_create_login_key_test.go b/builder/ncloud/step_create_login_key_test.go index 6f0d7af8f..3583f47a5 100644 --- a/builder/ncloud/step_create_login_key_test.go +++ b/builder/ncloud/step_create_login_key_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -16,7 +17,7 @@ func TestStepCreateLoginKeyShouldFailIfOperationCreateLoginKeyFails(t *testing.T stateBag := createTestStateBagStepCreateLoginKey() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -36,7 +37,7 @@ func TestStepCreateLoginKeyShouldPassIfOperationCreateLoginKeyPasses(t *testing. stateBag := createTestStateBagStepCreateLoginKey() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_create_public_ip_instance_test.go b/builder/ncloud/step_create_public_ip_instance_test.go index 7269e3af5..e28a19d48 100644 --- a/builder/ncloud/step_create_public_ip_instance_test.go +++ b/builder/ncloud/step_create_public_ip_instance_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -20,7 +21,7 @@ func TestStepCreatePublicIPInstanceShouldFailIfOperationCreatePublicIPInstanceFa stateBag := createTestStateBagStepCreateServerImage() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -47,7 +48,7 @@ func TestStepCreatePublicIPInstanceShouldPassIfOperationCreatePublicIPInstancePa stateBag := createTestStateBagStepCreatePublicIPInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_create_server_image_test.go b/builder/ncloud/step_create_server_image_test.go index fa7745135..49915ced2 100644 --- a/builder/ncloud/step_create_server_image_test.go +++ b/builder/ncloud/step_create_server_image_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -20,7 +21,7 @@ func TestStepCreateServerImageShouldFailIfOperationCreateServerImageFails(t *tes stateBag := createTestStateBagStepCreateServerImage() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -39,7 +40,7 @@ func TestStepCreateServerImageShouldPassIfOperationCreateServerImagePasses(t *te stateBag := createTestStateBagStepCreateServerImage() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_create_server_instance_test.go b/builder/ncloud/step_create_server_instance_test.go index db337c41b..676c3fa3f 100644 --- a/builder/ncloud/step_create_server_instance_test.go +++ b/builder/ncloud/step_create_server_instance_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -18,7 +19,7 @@ func TestStepCreateServerInstanceShouldFailIfOperationCreateFails(t *testing.T) stateBag := createTestStateBagStepCreateServerInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -38,7 +39,7 @@ func TestStepCreateServerInstanceShouldPassIfOperationCreatePasses(t *testing.T) stateBag := createTestStateBagStepCreateServerInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_delete_block_storage_instance_test.go b/builder/ncloud/step_delete_block_storage_instance_test.go index c5fc4566e..024ed332e 100644 --- a/builder/ncloud/step_delete_block_storage_instance_test.go +++ b/builder/ncloud/step_delete_block_storage_instance_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -17,7 +18,7 @@ func TestStepDeleteBlockStorageInstanceShouldFailIfOperationDeleteBlockStorageIn stateBag := createTestStateBagStepDeleteBlockStorageInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -38,7 +39,7 @@ func TestStepDeleteBlockStorageInstanceShouldPassIfOperationDeleteBlockStorageIn stateBag := createTestStateBagStepDeleteBlockStorageInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_get_rootpassword_test.go b/builder/ncloud/step_get_rootpassword_test.go index 1717b5753..0c93229bd 100644 --- a/builder/ncloud/step_get_rootpassword_test.go +++ b/builder/ncloud/step_get_rootpassword_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -16,7 +17,7 @@ func TestStepGetRootPasswordShouldFailIfOperationGetRootPasswordFails(t *testing stateBag := DeleteTestStateBagStepGetRootPassword() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -36,7 +37,7 @@ func TestStepGetRootPasswordShouldPassIfOperationGetRootPasswordPasses(t *testin stateBag := DeleteTestStateBagStepGetRootPassword() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_stop_server_instance_test.go b/builder/ncloud/step_stop_server_instance_test.go index 04c39d313..4b5afe605 100644 --- a/builder/ncloud/step_stop_server_instance_test.go +++ b/builder/ncloud/step_stop_server_instance_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -16,7 +17,7 @@ func TestStepStopServerInstanceShouldFailIfOperationStopFails(t *testing.T) { stateBag := createTestStateBagStepStopServerInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -36,7 +37,7 @@ func TestStepStopServerInstanceShouldPassIfOperationStopPasses(t *testing.T) { stateBag := createTestStateBagStepStopServerInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_terminate_server_instance_test.go b/builder/ncloud/step_terminate_server_instance_test.go index 9256b85b9..54a00748a 100644 --- a/builder/ncloud/step_terminate_server_instance_test.go +++ b/builder/ncloud/step_terminate_server_instance_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -16,7 +17,7 @@ func TestStepTerminateServerInstanceShouldFailIfOperationTerminationFails(t *tes stateBag := createTestStateBagStepTerminateServerInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -36,7 +37,7 @@ func TestStepTerminateServerInstanceShouldPassIfOperationTerminationPasses(t *te stateBag := createTestStateBagStepTerminateServerInstance() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) diff --git a/builder/ncloud/step_validate_template_test.go b/builder/ncloud/step_validate_template_test.go index 6836f8446..7e9212c7f 100644 --- a/builder/ncloud/step_validate_template_test.go +++ b/builder/ncloud/step_validate_template_test.go @@ -1,6 +1,7 @@ package ncloud import ( + "context" "fmt" "testing" @@ -16,7 +17,7 @@ func TestStepValidateTemplateShouldFailIfValidateFails(t *testing.T) { stateBag := createTestStateBagStepValidateTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionHalt { t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) @@ -36,7 +37,7 @@ func TestStepValidateTemplateShouldPassIfValidatePasses(t *testing.T) { stateBag := createTestStateBagStepValidateTemplate() - var result = testSubject.Run(stateBag) + var result = testSubject.Run(context.Background(), stateBag) if result != multistep.ActionContinue { t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) From cab52872f499289d9c5883b322f9a77dbee0bb61 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 30 Jan 2018 22:00:37 -0800 Subject: [PATCH 0519/1007] add session level keep-alives for ssh communicator --- communicator/ssh/communicator.go | 18 ++++++++++++++++++ helper/communicator/config.go | 5 +++++ helper/communicator/step_connect_ssh.go | 1 + .../source/docs/templates/communicator.html.md | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index c10e97dcc..eabf32aea 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -55,6 +55,10 @@ type Config struct { // UseSftp, if true, sftp will be used instead of scp for file transfers UseSftp bool + + // KeepAliveInterval sets how often we send a channel request to the + // server. A value < 0 disables. + KeepAliveInterval time.Duration } // Creates a new packer.Communicator implementation over SSH. This takes @@ -104,6 +108,20 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) { return } + go func() { + if c.config.KeepAliveInterval < 0 { + return + } + c := time.NewTicker(c.config.KeepAliveInterval) + defer c.Stop() + for range c.C { + _, err := session.SendRequest("keepalive@packer.io", true, nil) + if err != nil { + return + } + } + }() + // Start a goroutine to wait for the session to end and set the // exit boolean and status. go func() { diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 5ecbdfc65..8fe1032cb 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -37,6 +37,7 @@ type Config struct { SSHProxyPort int `mapstructure:"ssh_proxy_port"` SSHProxyUsername string `mapstructure:"ssh_proxy_username"` SSHProxyPassword string `mapstructure:"ssh_proxy_password"` + SSHKeepAliveInterval time.Duration `mapstructure:"ssh_keep_alive_interval"` // WinRM WinRMUser string `mapstructure:"winrm_username"` @@ -131,6 +132,10 @@ func (c *Config) prepareSSH(ctx *interpolate.Context) []error { c.SSHTimeout = 5 * time.Minute } + if c.SSHKeepAliveInterval == 0 { + c.SSHKeepAliveInterval = 5 * time.Second + } + if c.SSHHandshakeAttempts == 0 { c.SSHHandshakeAttempts = 10 } diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 680b88a02..192dba739 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -182,6 +182,7 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru Pty: s.Config.SSHPty, DisableAgentForwarding: s.Config.SSHDisableAgentForwarding, UseSftp: s.Config.SSHFileTransferMethod == "sftp", + KeepAliveInterval: s.Config.SSHKeepAliveInterval, } log.Println("[INFO] Attempting SSH connection...") diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 6bb5150b9..e8a5d56fc 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -91,6 +91,10 @@ The SSH communicator has the following options: - `ssh_host` (string) - The address to SSH to. This usually is automatically configured by the builder. +* `ssh_keep_alive_interval` (string) - How often to send "keep alive" + messages to the server. Set to a negative value (`-1`) to disable. Example value: + "10s". Defaults to "5s". + - `ssh_password` (string) - A plaintext password to use to authenticate with SSH. From 55977be8f37427b4ff1fb1ab3084e601f76ead92 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 30 Jan 2018 23:26:26 -0800 Subject: [PATCH 0520/1007] Update communicator.html.md --- website/source/docs/templates/communicator.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index e8a5d56fc..5fbb8a3d5 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -92,7 +92,7 @@ The SSH communicator has the following options: configured by the builder. * `ssh_keep_alive_interval` (string) - How often to send "keep alive" - messages to the server. Set to a negative value (`-1`) to disable. Example value: + messages to the server. Set to a negative value (`-1s`) to disable. Example value: "10s". Defaults to "5s". - `ssh_password` (string) - A plaintext password to use to authenticate From 2452f0788bc841aef284660ea917acc8d300bdaa Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 30 Jan 2018 23:30:25 -0800 Subject: [PATCH 0521/1007] remove obsolete ssh_wait_timeout from examples --- examples/alicloud/local/centos.json | 2 +- website/source/docs/builders/parallels-iso.html.md | 2 +- website/source/docs/builders/parallels-pvm.html.md | 2 +- website/source/docs/builders/qemu.html.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/alicloud/local/centos.json b/examples/alicloud/local/centos.json index 45c19b3dc..07b2f2578 100644 --- a/examples/alicloud/local/centos.json +++ b/examples/alicloud/local/centos.json @@ -37,7 +37,7 @@ "ssh_password": "vagrant", "ssh_port": 22, "ssh_username": "root", - "ssh_wait_timeout": "10000s", + "ssh_timeout": "10000s", "type": "qemu", "vm_name": "{{ user `template` }}.raw", "net_device": "virtio-net", diff --git a/website/source/docs/builders/parallels-iso.html.md b/website/source/docs/builders/parallels-iso.html.md index c9c23d919..e7f0dd4a4 100644 --- a/website/source/docs/builders/parallels-iso.html.md +++ b/website/source/docs/builders/parallels-iso.html.md @@ -37,7 +37,7 @@ self-install. Still, the example serves to show the basic configuration: "parallels_tools_flavor": "lin", "ssh_username": "packer", "ssh_password": "packer", - "ssh_wait_timeout": "30s", + "ssh_timeout": "30s", "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" } ``` diff --git a/website/source/docs/builders/parallels-pvm.html.md b/website/source/docs/builders/parallels-pvm.html.md index ba3d9c1a9..59accdcd1 100644 --- a/website/source/docs/builders/parallels-pvm.html.md +++ b/website/source/docs/builders/parallels-pvm.html.md @@ -33,7 +33,7 @@ the settings here. "source_path": "source.pvm", "ssh_username": "packer", "ssh_password": "packer", - "ssh_wait_timeout": "30s", + "ssh_timeout": "30s", "shutdown_command": "echo 'packer' | sudo -S shutdown -P now" } ``` diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index f3de7cf9c..b8f0ab368 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -47,7 +47,7 @@ to files, URLS for ISOs and checksums. "ssh_username": "root", "ssh_password": "s0m3password", "ssh_port": 22, - "ssh_wait_timeout": "30s", + "ssh_timeout": "30s", "vm_name": "tdhtest", "net_device": "virtio-net", "disk_interface": "virtio", From 1f92aa2c0a8ded78488c33853477923023387bd4 Mon Sep 17 00:00:00 2001 From: Evan Machnic <emachnic@gmail.com> Date: Wed, 31 Jan 2018 10:49:04 -0600 Subject: [PATCH 0522/1007] Added Policyfile support to chef-client provisioner --- provisioner/chef-client/provisioner.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 7feab150c..51c315ca1 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -56,6 +56,8 @@ type Config struct { InstallCommand string `mapstructure:"install_command"` KnifeCommand string `mapstructure:"knife_command"` NodeName string `mapstructure:"node_name"` + PolicyGroup string `mapstructure:"policy_group"` + PolicyName string `mapstructure:"policy_name"` PreventSudo bool `mapstructure:"prevent_sudo"` RunList []string `mapstructure:"run_list"` ServerUrl string `mapstructure:"server_url"` @@ -82,6 +84,8 @@ type ConfigTemplate struct { ClientKey string EncryptedDataBagSecretPath string NodeName string + PolicyGroup string + PolicyName string ServerUrl string SslVerifyMode string TrustedCertsDir string @@ -270,6 +274,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { remoteValidationKeyPath, p.config.ValidationClientName, p.config.ChefEnvironment, + p.config.PolicyGroup, + p.config.PolicyName, p.config.SslVerifyMode, p.config.TrustedCertsDir) if err != nil { @@ -374,6 +380,8 @@ func (p *Provisioner) createConfig( ValidationKeyPath: remoteKeyPath, ValidationClientName: validationClientName, ChefEnvironment: chefEnvironment, + PolicyGroup: policyGroup, + PolicyName: policyName, SslVerifyMode: sslVerifyMode, TrustedCertsDir: trustedCertsDir, EncryptedDataBagSecretPath: encryptedDataBagSecretPath, @@ -688,6 +696,12 @@ node_name "{{.NodeName}}" {{if ne .ChefEnvironment ""}} environment "{{.ChefEnvironment}}" {{end}} +{{if ne .PolicyGroup ""}} +policy_group "{{.PolicyGroup}}" +{{end}} +{{if ne .PolicyName ""}} +policy_name "{{.PolicyName}}" +{{end}} {{if ne .SslVerifyMode ""}} ssl_verify_mode :{{.SslVerifyMode}} {{end}} From fe90f797041b7fe555bdbccc63818288b6a080c5 Mon Sep 17 00:00:00 2001 From: Evan Machnic <emachnic@gmail.com> Date: Wed, 31 Jan 2018 10:54:40 -0600 Subject: [PATCH 0523/1007] Changed new code to use tabs instead of spaces --- provisioner/chef-client/provisioner.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 51c315ca1..950bf7ea5 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -56,8 +56,8 @@ type Config struct { InstallCommand string `mapstructure:"install_command"` KnifeCommand string `mapstructure:"knife_command"` NodeName string `mapstructure:"node_name"` - PolicyGroup string `mapstructure:"policy_group"` - PolicyName string `mapstructure:"policy_name"` + PolicyGroup string `mapstructure:"policy_group"` + PolicyName string `mapstructure:"policy_name"` PreventSudo bool `mapstructure:"prevent_sudo"` RunList []string `mapstructure:"run_list"` ServerUrl string `mapstructure:"server_url"` @@ -84,8 +84,8 @@ type ConfigTemplate struct { ClientKey string EncryptedDataBagSecretPath string NodeName string - PolicyGroup string - PolicyName string + PolicyGroup string + PolicyName string ServerUrl string SslVerifyMode string TrustedCertsDir string @@ -274,8 +274,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { remoteValidationKeyPath, p.config.ValidationClientName, p.config.ChefEnvironment, - p.config.PolicyGroup, - p.config.PolicyName, + p.config.PolicyGroup, + p.config.PolicyName, p.config.SslVerifyMode, p.config.TrustedCertsDir) if err != nil { @@ -380,8 +380,8 @@ func (p *Provisioner) createConfig( ValidationKeyPath: remoteKeyPath, ValidationClientName: validationClientName, ChefEnvironment: chefEnvironment, - PolicyGroup: policyGroup, - PolicyName: policyName, + PolicyGroup: policyGroup, + PolicyName: policyName, SslVerifyMode: sslVerifyMode, TrustedCertsDir: trustedCertsDir, EncryptedDataBagSecretPath: encryptedDataBagSecretPath, From 735424793398d8c865459207426613087be21a05 Mon Sep 17 00:00:00 2001 From: Evan Machnic <emachnic@gmail.com> Date: Wed, 31 Jan 2018 11:01:08 -0600 Subject: [PATCH 0524/1007] Added policyGroup and policyName to Packer Communicator --- provisioner/chef-client/provisioner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 950bf7ea5..b82bb939b 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -350,6 +350,8 @@ func (p *Provisioner) createConfig( remoteKeyPath string, validationClientName string, chefEnvironment string, + policyGroup string, + policyName string, sslVerifyMode string, trustedCertsDir string) (string, error) { From 5cedfc4557acea8043578ff3d6c8fba97cdbc575 Mon Sep 17 00:00:00 2001 From: Evan Machnic <emachnic@gmail.com> Date: Wed, 31 Jan 2018 11:06:31 -0600 Subject: [PATCH 0525/1007] Fixed go format errors --- provisioner/chef-client/provisioner.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index b82bb939b..27d94c6c3 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -350,8 +350,8 @@ func (p *Provisioner) createConfig( remoteKeyPath string, validationClientName string, chefEnvironment string, - policyGroup string, - policyName string, + policyGroup string, + policyName string, sslVerifyMode string, trustedCertsDir string) (string, error) { From 871ead371a67446aa0b62d7e8f213cdedd1c927b Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 10:47:19 -0800 Subject: [PATCH 0526/1007] Clean up based on Oracle comments --- builder/oracle/classic/artifact.go | 20 +++++++------ builder/oracle/classic/builder.go | 6 ++-- builder/oracle/classic/config.go | 3 +- builder/oracle/classic/config_test.go | 20 +++++++------ .../oracle/classic/step_create_instance.go | 2 -- builder/oracle/classic/step_list_images.go | 30 ++++++++++++++++--- builder/oracle/classic/step_snapshot.go | 4 +-- .../go-oracle-terraform/compute/snapshots.go | 25 ++++++++++++++++ vendor/vendor.json | 2 +- .../docs/builders/oracle-classic.html.md | 10 +++++-- 10 files changed, 90 insertions(+), 32 deletions(-) diff --git a/builder/oracle/classic/artifact.go b/builder/oracle/classic/artifact.go index fb7861b04..82987be1a 100644 --- a/builder/oracle/classic/artifact.go +++ b/builder/oracle/classic/artifact.go @@ -6,10 +6,13 @@ import ( "github.com/hashicorp/go-oracle-terraform/compute" ) -// Artifact is an artifact implementation that contains a Snapshot. +// Artifact is an artifact implementation that contains Image List +// and Machine Image info. type Artifact struct { - Snapshot *compute.Snapshot - driver *compute.ComputeClient + MachineImageName string + MachineImageFile string + ImageListVersion int + driver *compute.ComputeClient } // BuilderId uniquely identifies the builder. @@ -24,16 +27,15 @@ func (a *Artifact) Files() []string { } func (a *Artifact) Id() string { - return a.Snapshot.Name + return a.MachineImageName } func (a *Artifact) String() string { - return fmt.Sprintf("A Snapshot was created: \n"+ + return fmt.Sprintf("An image list entry was created: \n"+ "Name: %s\n"+ - "Instance: %s\n"+ - "MachineImage: %s\n"+ - "URI: %s", - a.Snapshot.Name, a.Snapshot.Instance, a.Snapshot.MachineImage, a.Snapshot.URI) + "File: %s\n"+ + "Version: %d", + a.MachineImageName, a.MachineImageFile, a.ImageListVersion) } func (a *Artifact) State(name string) interface{} { diff --git a/builder/oracle/classic/builder.go b/builder/oracle/classic/builder.go index 088ff4dbc..1e90439be 100644 --- a/builder/oracle/classic/builder.go +++ b/builder/oracle/classic/builder.go @@ -99,8 +99,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the artifact and return it artifact := &Artifact{ - Snapshot: state.Get("snapshot").(*compute.Snapshot), - driver: client, + ImageListVersion: state.Get("image_list_version").(int), + MachineImageName: state.Get("machine_image_name").(string), + MachineImageFile: state.Get("machine_image_file").(string), + driver: client, } return artifact, nil diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index e0c82beb2..c04235da9 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -29,7 +29,7 @@ type Config struct { DestImageList string `mapstructure:"dest_image_list"` // Optional; if you don't enter anything, the image list description // will read "Packer-built image list" - DestImageListDescription string `mapstructure:"dest_image_list_description` + DestImageListDescription string `mapstructure:"dest_image_list_description"` // Optional. Describes what computers are allowed to reach your instance // via SSH. This whitelist must contain the computer you're running Packer // from. It defaults to public-internet, meaning that you can SSH into your @@ -72,6 +72,7 @@ func NewConfig(raws ...interface{}) (*Config, error) { "api_endpoint": c.APIEndpoint, "identity_domain": c.IdentityDomain, "source_image_list": c.SourceImageList, + "dest_image_list": c.DestImageList, "shape": c.Shape, } for k, v := range required { diff --git a/builder/oracle/classic/config_test.go b/builder/oracle/classic/config_test.go index 81b8f0344..214365731 100644 --- a/builder/oracle/classic/config_test.go +++ b/builder/oracle/classic/config_test.go @@ -6,14 +6,15 @@ import ( func testConfig() map[string]interface{} { return map[string]interface{}{ - "identity_domain": "abc12345", - "username": "test@hashicorp.com", - "password": "testpassword123", - "api_endpoint": "https://api-test.compute.test.oraclecloud.com/", - "image_list": "/oracle/public/myimage", - "shape": "oc3", - "image_name": "TestImageName", - "ssh_username": "opc", + "identity_domain": "abc12345", + "username": "test@hashicorp.com", + "password": "testpassword123", + "api_endpoint": "https://api-test.compute.test.oraclecloud.com/", + "dest_image_list": "/Config-thing/myuser/myimage", + "source_image_list": "/oracle/public/whatever", + "shape": "oc3", + "image_name": "TestImageName", + "ssh_username": "opc", } } @@ -36,7 +37,8 @@ func TestConfigValidationCatchesMissing(t *testing.T) { "password", "api_endpoint", "identity_domain", - "image_list", + "dest_image_list", + "source_image_list", "shape", } for _, key := range required { diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 891fda33e..041889ab1 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -3,7 +3,6 @@ package classic import ( "context" "fmt" - "log" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/helper/multistep" @@ -67,7 +66,6 @@ func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { Name: config.ImageName, ID: imID, } - log.Printf("instance destroy input is %#v", input) err := instanceClient.DeleteInstance(input) if err != nil { diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go index 8d0c5ee12..a32355e79 100644 --- a/builder/oracle/classic/step_list_images.go +++ b/builder/oracle/classic/step_list_images.go @@ -18,7 +18,6 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis client := state.Get("client").(*compute.ComputeClient) ui.Say("Adding image to image list...") - // TODO: Try to get image list imageListClient := client.ImageList() getInput := compute.GetImageListInput{ Name: config.DestImageList, @@ -27,7 +26,8 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis if err != nil { ui.Say(fmt.Sprintf(err.Error())) // If the list didn't exist, create it. - ui.Say(fmt.Sprintf("Creating image list: %s", config.DestImageList)) + ui.Say(fmt.Sprintf("Destination image list %s does not exist; Creating it...", + config.DestImageList)) ilInput := compute.CreateImageListInput{ Name: config.DestImageList, @@ -37,7 +37,7 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis // Load the packer-generated SSH key into the Oracle Compute cloud. imList, err = imageListClient.CreateImageList(&ilInput) if err != nil { - err = fmt.Errorf("Problem creating an image list through Oracle's API: %s", err) + err = fmt.Errorf("Problem creating image list: %s", err) ui.Error(err.Error()) state.Put("error", err) return multistep.ActionHalt @@ -47,11 +47,12 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis // Now create and image list entry for the image into that list. snap := state.Get("snapshot").(*compute.Snapshot) + version := len(imList.Entries) + 1 entriesClient := client.ImageListEntries() entriesInput := compute.CreateImageListEntryInput{ Name: config.DestImageList, MachineImages: []string{fmt.Sprintf("Compute-%s/%s/%s", config.IdentityDomain, config.Username, snap.MachineImage)}, - Version: 1, + Version: version, } entryInfo, err := entriesClient.CreateImageListEntry(&entriesInput) if err != nil { @@ -60,7 +61,28 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis state.Put("error", err) return multistep.ActionHalt } + state.Put("image_list_entry", entryInfo) ui.Message(fmt.Sprintf("created image list entry %s", entryInfo.Name)) + + imList, err = imageListClient.GetImageList(&getInput) + + machineImagesClient := client.MachineImages() + getImagesInput := compute.GetMachineImageInput{ + Name: config.ImageName, + } + + // Grab info about the machine image to return with the artifact + imInfo, err := machineImagesClient.GetMachineImage(&getImagesInput) + if err != nil { + err = fmt.Errorf("Problem getting machine image info: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + state.Put("machine_image_file", imInfo.File) + state.Put("machine_image_name", imInfo.Name) + state.Put("image_list_version", version) + return multistep.ActionContinue } diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index b98530691..452fb56eb 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -52,8 +52,8 @@ func (s *stepSnapshot) Cleanup(state multistep.StateBag) { Snapshot: snap.Name, MachineImage: snap.MachineImage, } - machineClient := client.MachineImages() - err := snapClient.DeleteSnapshot(machineClient, &snapInput) + + err := snapClient.DeleteSnapshotResourceOnly(&snapInput) if err != nil { err = fmt.Errorf("Problem deleting snapshot: %s", err) ui.Error(err.Error()) diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go index d2a9616e9..370fd0c97 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/snapshots.go @@ -176,6 +176,31 @@ func (c *SnapshotsClient) DeleteSnapshot(machineImagesClient *MachineImagesClien return nil } +// DeleteSnapshot deletes the Snapshot with the given name. +// A machine image gets created with the associated snapshot is not deleted +// by this method. +func (c *SnapshotsClient) DeleteSnapshotResourceOnly(input *DeleteSnapshotInput) error { + // Wait for snapshot complete in case delay is active and the corresponding + // instance needs to be deleted first + getInput := &GetSnapshotInput{ + Name: input.Snapshot, + } + + if input.Timeout == 0 { + input.Timeout = WaitForSnapshotCompleteTimeout + } + + if _, err := c.WaitForSnapshotComplete(getInput, input.Timeout); err != nil { + return fmt.Errorf("Could not delete snapshot: %s", err) + } + + if err := c.deleteResource(input.Snapshot); err != nil { + return fmt.Errorf("Could not delete snapshot: %s", err) + } + + return nil +} + // WaitForSnapshotComplete waits for an snapshot to be completely initialized and available. func (c *SnapshotsClient) WaitForSnapshotComplete(input *GetSnapshotInput, timeout time.Duration) (*Snapshot, error) { var info *Snapshot diff --git a/vendor/vendor.json b/vendor/vendor.json index 6172b8c33..421c8710a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -803,7 +803,7 @@ "revisionTime": "2018-01-11T20:31:13Z" }, { - "checksumSHA1": "RhoE7zmHsn5zoXbx5AsAUUQI72E=", + "checksumSHA1": "wce86V0j11J6xRSvJEanprjK7so=", "path": "github.com/hashicorp/go-oracle-terraform/compute", "revision": "5a9a298c54339d2296d2f1135eae55a3a8f5e8c2", "revisionTime": "2018-01-11T20:31:13Z" diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 08d3d10b1..83169fcee 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -40,14 +40,17 @@ This builder currently only works with the SSH communicator. requests. Instructions for determining your API endpoint can be found [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/SendRequests.html) + - `dest_image_list` (string) - Where to save the machine image to once you've + provisioned it. If the provided image list does not exist, Packer will create it. + - `identity_domain` (string) - This is your customer-specific identity domain as generated by Oracle. If you don't know what your identity domain is, ask your account administrator. For a little more information, see the Oracle [documentation](https://docs.oracle.com/en/cloud/get-started/subscriptions-cloud/ocuid/identity-domain-overview.html#GUID-7969F881-5F4D-443E-B86C-9044C8085B8A). - - `image_list` (string) - This is what image you want to use as your base image. + - `source_image_list` (string) - This is what image you want to use as your base image. See the [documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/listing-machine-images.html) - for more details. To see what public image lists are available, you can use + for more details. You may use either a public image list, or a private image list. To see what public image lists are available, you can use the CLI, as described [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stopc/image-lists-stclr-and-nmcli.html#GUID-DB7E75FE-F752-4FF7-AB70-3C8DCDFCA0FA) - `password` (string) - Your account password. @@ -60,6 +63,9 @@ This builder currently only works with the SSH communicator. ### Optional + - `dest_image_list_description` (string) - a description for your destination + image list. If you don't provide one, Packer will provide a generic description. + - `ssh_username` (string) - The username that Packer will use to SSH into the instance; defaults to `opc`, the default oracle user, which has sudo priveliges. If you have already configured users on your machine, you may From af26b312cdbcf5b3b0b0ed2fa0d3f34f5a5bd4eb Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 11:35:34 -0800 Subject: [PATCH 0527/1007] fix logline --- builder/oracle/classic/step_snapshot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 452fb56eb..b7cbbf008 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -44,7 +44,7 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste func (s *stepSnapshot) Cleanup(state multistep.StateBag) { // Delete the snapshot ui := state.Get("ui").(packer.Ui) - ui.Say("Creating Snapshot...") + ui.Say("Deleting Snapshot...") client := state.Get("client").(*compute.ComputeClient) snap := state.Get("snapshot").(*compute.Snapshot) snapClient := client.Snapshots() From 64e26d6fa253cb838ce69cbdd55cd6a290893206 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 12:23:25 -0800 Subject: [PATCH 0528/1007] update example file in the oracle-classic docs --- website/source/docs/builders/oracle-classic.html.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 83169fcee..ac539b255 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -89,9 +89,10 @@ obfuscated; you will need to add a working `username`, `password`, "password": "supersecretpasswordhere", "identity_domain": "#######", "api_endpoint": "https://api-###.compute.###.oraclecloud.com/", - "image_list": "/oracle/public/OL_7.2_UEKR4_x86_64", + "source_image_list": "/oracle/public/OL_7.2_UEKR4_x86_64", "shape": "oc3", "image_name": "Packer_Builder_Test_{{timestamp}}" + "dest_image_list": "Packer_Builder_Test_List" } ], "provisioners": [ From 63f1673909e7aad4822a80ecdd243a8c6babb488 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 30 Jan 2018 23:09:12 -0800 Subject: [PATCH 0529/1007] ssh deadlines --- communicator/ssh/communicator.go | 7 +++++ communicator/ssh/connection.go | 30 +++++++++++++++++++ helper/communicator/config.go | 1 + helper/communicator/step_connect_ssh.go | 1 + .../docs/templates/communicator.html.md | 3 ++ 5 files changed, 42 insertions(+) create mode 100644 communicator/ssh/connection.go diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index eabf32aea..17d7cb6b8 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -59,6 +59,9 @@ type Config struct { // KeepAliveInterval sets how often we send a channel request to the // server. A value < 0 disables. KeepAliveInterval time.Duration + + // Timeout is how long to wait for a read or write to succeed. + Timeout time.Duration } // Creates a new packer.Communicator implementation over SSH. This takes @@ -291,6 +294,10 @@ func (c *comm) reconnect() (err error) { return } + if c.config.Timeout > 0 { + c.conn = &timeoutConn{c.conn, c.config.Timeout, c.config.Timeout} + } + log.Printf("handshaking with SSH") // Default timeout to 1 minute if it wasn't specified (zero value). For diff --git a/communicator/ssh/connection.go b/communicator/ssh/connection.go new file mode 100644 index 000000000..c3df04543 --- /dev/null +++ b/communicator/ssh/connection.go @@ -0,0 +1,30 @@ +package ssh + +import ( + "net" + "time" +) + +// timeoutConn wraps a net.Conn, and sets a deadline for every read +// and write operation. +type timeoutConn struct { + net.Conn + ReadTimeout time.Duration + WriteTimeout time.Duration +} + +func (c *timeoutConn) Read(b []byte) (int, error) { + err := c.Conn.SetReadDeadline(time.Now().Add(c.ReadTimeout)) + if err != nil { + return 0, err + } + return c.Conn.Read(b) +} + +func (c *timeoutConn) Write(b []byte) (int, error) { + err := c.Conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout)) + if err != nil { + return 0, err + } + return c.Conn.Write(b) +} diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 8fe1032cb..f2664b192 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -38,6 +38,7 @@ type Config struct { SSHProxyUsername string `mapstructure:"ssh_proxy_username"` SSHProxyPassword string `mapstructure:"ssh_proxy_password"` SSHKeepAliveInterval time.Duration `mapstructure:"ssh_keep_alive_interval"` + SSHReadWriteTimeout time.Duration `mapstructure:"ssh_read_write_timeout"` // WinRM WinRMUser string `mapstructure:"winrm_username"` diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 192dba739..18fd699c7 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -183,6 +183,7 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru DisableAgentForwarding: s.Config.SSHDisableAgentForwarding, UseSftp: s.Config.SSHFileTransferMethod == "sftp", KeepAliveInterval: s.Config.SSHKeepAliveInterval, + Timeout: s.Config.SSHReadWriteTimeout, } log.Println("[INFO] Attempting SSH connection...") diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 5fbb8a3d5..7b35370b4 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -106,6 +106,9 @@ The SSH communicator has the following options: - `ssh_pty` (boolean) - If true, a PTY will be requested for the SSH connection. This defaults to false. +* `ssh_read_write_timeout` (string) - The amount of time to wait for a remote + command to end. Example: "1h". Disabled by default. + - `ssh_timeout` (string) - The time to wait for SSH to become available. Packer uses this to determine when the machine has booted so this is usually quite long. Example value: "10m" From ff6425fb22a56c7d135b82a03ba8a2a195bfff63 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 31 Jan 2018 11:48:03 -0800 Subject: [PATCH 0530/1007] better documentation --- website/source/docs/templates/communicator.html.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 7b35370b4..0165ab5a1 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -107,7 +107,8 @@ The SSH communicator has the following options: connection. This defaults to false. * `ssh_read_write_timeout` (string) - The amount of time to wait for a remote - command to end. Example: "1h". Disabled by default. + command to end. This might be useful if, for example, packer hangs on + a connection after a reboot. Example: "5m". Disabled by default. - `ssh_timeout` (string) - The time to wait for SSH to become available. Packer uses this to determine when the machine has booted so this is From 73e8be022ddb836860ba777b8bbc13cf4a904e26 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 31 Jan 2018 12:45:38 -0800 Subject: [PATCH 0531/1007] call out hax accelerator issue --- website/source/docs/builders/qemu.html.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index 4885aca1c..2d3c82d9e 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -115,6 +115,10 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). you specified. When no accelerator is specified, Packer will try to use `kvm` if it is available but will default to `tcg` otherwise. + -&gt; The `hax` accelerator has issues attaching CDROM ISOs. This is an + upstream issue which can be tracked + [here](https://github.com/intel/haxm/issues/20). + - `boot_command` (array of strings) - This is an array of commands to type when the virtual machine is first booted. The goal of these commands should be to type just enough to initialize the operating system installer. Special From 66cd85828e9e56925f95fb35266e17c089cc99f7 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 12:48:40 -0800 Subject: [PATCH 0532/1007] rename dest_image_list_description to image_description --- builder/oracle/classic/config.go | 2 +- website/source/docs/builders/oracle-classic.html.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index c04235da9..4cd7c42a7 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -29,7 +29,7 @@ type Config struct { DestImageList string `mapstructure:"dest_image_list"` // Optional; if you don't enter anything, the image list description // will read "Packer-built image list" - DestImageListDescription string `mapstructure:"dest_image_list_description"` + DestImageListDescription string `mapstructure:"image_description"` // Optional. Describes what computers are allowed to reach your instance // via SSH. This whitelist must contain the computer you're running Packer // from. It defaults to public-internet, meaning that you can SSH into your diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index ac539b255..e71cc9cc3 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -63,7 +63,7 @@ This builder currently only works with the SSH communicator. ### Optional - - `dest_image_list_description` (string) - a description for your destination + - `image_description` (string) - a description for your destination image list. If you don't provide one, Packer will provide a generic description. - `ssh_username` (string) - The username that Packer will use to SSH into the From 918a50225ba3a6e0001b8991117f4c282e3da42e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 31 Jan 2018 12:52:04 -0800 Subject: [PATCH 0533/1007] cleanup docs --- .../source/docs/builders/vmware-iso.html.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index fd56a475f..256bf63e4 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -107,10 +107,10 @@ builder. actual file representing the disk will not use the full size unless it is full. By default this is set to 40,000 (about 40 GB). -- `disk_type_id` (string) - The type of VMware virtual disk to create. The - default is "1", which corresponds to a growable virtual disk split in 2GB - files. For ESXi, this defaults to "zeroedthick". This option is for - advanced usage. For ESXi the available options are: `zeroedthick`, `eagerzeroedthick`, `thin`, `rdm:dev`, `rdmp:dev`, `2gbsparse`. For desktop VMware clients: +- `disk_type_id` (string) - The type of VMware virtual disk to create. This + option is for advanced usage. + + For desktop VMware clients: Type ID | Description --- | --- @@ -121,6 +121,16 @@ builder. `4` | Preallocated virtual disk compatible with ESX server (VMFS flat). `5` | Compressed disk optimized for streaming. + The default is "1". + + For ESXi, this defaults to "zeroedthick". The available options for ESXi + are: `zeroedthick`, `eagerzeroedthick`, `thin`, `rdm:dev`, `rdmp:dev`, + `2gbsparse`. + + For more information, please consult the [Virtual Disk Manager User's + Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) for desktop + VMware clients. For ESXi, refer to the proper ESXi documentation. + * `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. From 9f87213ba454391bfaf83e771f10a64cc741c200 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 31 Jan 2018 13:08:25 -0800 Subject: [PATCH 0534/1007] tests and docs for #5831 --- provisioner/chef-client/provisioner.go | 4 ++++ provisioner/chef-client/provisioner_test.go | 24 +++++++++++++++++++ .../docs/provisioners/chef-client.html.md | 18 +++++++++++--- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/provisioner/chef-client/provisioner.go b/provisioner/chef-client/provisioner.go index 27d94c6c3..b0af8cbea 100644 --- a/provisioner/chef-client/provisioner.go +++ b/provisioner/chef-client/provisioner.go @@ -196,6 +196,10 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } } + if (p.config.PolicyName != "") != (p.config.PolicyGroup != "") { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("If either policy_name or policy_group are set, they must both be set.")) + } + jsonValid := true for k, v := range p.config.Json { p.config.Json[k], err = p.deepJsonFix(k, v) diff --git a/provisioner/chef-client/provisioner_test.go b/provisioner/chef-client/provisioner_test.go index ac148721a..acb674b53 100644 --- a/provisioner/chef-client/provisioner_test.go +++ b/provisioner/chef-client/provisioner_test.go @@ -243,3 +243,27 @@ func TestProvisioner_removeDir(t *testing.T) { } } } + +func TestProvisionerPrepare_policy(t *testing.T) { + var p Provisioner + + var policyTests = []struct { + name string + group string + success bool + }{ + {"", "", true}, + {"a", "b", true}, + {"a", "", false}, + {"", "a", false}, + } + for _, tt := range policyTests { + config := testConfig() + config["policy_name"] = tt.name + config["policy_group"] = tt.group + err := p.Prepare(config) + if (err == nil) != tt.success { + t.Fatalf("wasn't expecting %+v to fail: %s", tt, err.Error()) + } + } +} diff --git a/website/source/docs/provisioners/chef-client.html.md b/website/source/docs/provisioners/chef-client.html.md index 566742490..c40f41034 100644 --- a/website/source/docs/provisioners/chef-client.html.md +++ b/website/source/docs/provisioners/chef-client.html.md @@ -80,6 +80,12 @@ configuration is actually required. - `node_name` (string) - The name of the node to register with the Chef Server. This is optional and by default is packer-{{uuid}}. +* `policy_group` (string) - The name of a policy group that exists on the + Chef server. `policy_name` must also be specified. + +* `policy_name` (string) - The name of a policy, as identified by the name + setting in a `Policyfile.rb` file. `policy_group` must also be specified. + - `prevent_sudo` (boolean) - By default, the configured commands that are executed to install and run Chef are executed with `sudo`. If this is true, then the sudo will be omitted. This has no effect when guest\_os\_type is @@ -105,9 +111,9 @@ configuration is actually required. SSL certificates. If not set, this defaults to "verify\_peer" which validates all SSL certifications. -- `trusted_certs_dir` (string) - This is a directory that contains additional - SSL certificates to trust. Any certificates in this directory will be added to - whatever CA bundle ruby is using. Use this to add self-signed certs for your +- `trusted_certs_dir` (string) - This is a directory that contains additional + SSL certificates to trust. Any certificates in this directory will be added to + whatever CA bundle ruby is using. Use this to add self-signed certs for your Chef Server or local HTTP file servers. - `staging_directory` (string) - This is the directory where all the @@ -160,6 +166,12 @@ node_name "{{.NodeName}}" {{if ne .ChefEnvironment ""}} environment "{{.ChefEnvironment}}" {{end}} +{{if ne .PolicyGroup ""}} +policy_group "{{.PolicyGroup}}" +{{end}} +{{if ne .PolicyName ""}} +policy_name "{{.PolicyName}}" +{{end}} {{if ne .SslVerifyMode ""}} ssl_verify_mode :{{.SslVerifyMode}} {{end}} From 8bdd3b45c7065db6b12862b3801409784d4a8805 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 31 Jan 2018 13:19:31 -0800 Subject: [PATCH 0535/1007] use helper functions for reading vmx files --- builder/vmware/common/ssh.go | 13 ++----------- builder/vmware/common/step_configure_vmx.go | 5 +---- builder/vmware/common/step_configure_vnc.go | 15 ++------------- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/builder/vmware/common/ssh.go b/builder/vmware/common/ssh.go index 871ba8df9..4e339edb9 100644 --- a/builder/vmware/common/ssh.go +++ b/builder/vmware/common/ssh.go @@ -3,9 +3,7 @@ package common import ( "errors" "fmt" - "io/ioutil" "log" - "os" commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" @@ -23,18 +21,11 @@ func CommHost(config *SSHConfig) func(multistep.StateBag) (string, error) { } log.Println("Lookup up IP information...") - f, err := os.Open(vmxPath) + + vmxData, err := ReadVMX(vmxPath) if err != nil { return "", err } - defer f.Close() - - vmxBytes, err := ioutil.ReadAll(f) - if err != nil { - return "", err - } - - vmxData := ParseVMX(string(vmxBytes)) var ok bool macAddress := "" diff --git a/builder/vmware/common/step_configure_vmx.go b/builder/vmware/common/step_configure_vmx.go index 155234ac4..102ac52ee 100644 --- a/builder/vmware/common/step_configure_vmx.go +++ b/builder/vmware/common/step_configure_vmx.go @@ -3,7 +3,6 @@ package common import ( "context" "fmt" - "io/ioutil" "log" "regexp" "strings" @@ -26,7 +25,7 @@ func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) mult ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) - vmxContents, err := ioutil.ReadFile(vmxPath) + vmxData, err := ReadVMX(vmxPath) if err != nil { err := fmt.Errorf("Error reading VMX file: %s", err) state.Put("error", err) @@ -34,8 +33,6 @@ func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) mult return multistep.ActionHalt } - vmxData := ParseVMX(string(vmxContents)) - // Set this so that no dialogs ever appear from Packer. vmxData["msg.autoanswer"] = "true" diff --git a/builder/vmware/common/step_configure_vnc.go b/builder/vmware/common/step_configure_vnc.go index 90aa4a998..54f5ac182 100644 --- a/builder/vmware/common/step_configure_vnc.go +++ b/builder/vmware/common/step_configure_vnc.go @@ -3,11 +3,9 @@ package common import ( "context" "fmt" - "io/ioutil" "log" "math/rand" "net" - "os" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -87,17 +85,9 @@ func (s *StepConfigureVNC) Run(_ context.Context, state multistep.StateBag) mult ui := state.Get("ui").(packer.Ui) vmxPath := state.Get("vmx_path").(string) - f, err := os.Open(vmxPath) + vmxData, err := ReadVMX(vmxPath) if err != nil { - err := fmt.Errorf("Error reading VMX data: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - vmxBytes, err := ioutil.ReadAll(f) - if err != nil { - err := fmt.Errorf("Error reading VMX data: %s", err) + err := fmt.Errorf("Error reading VMX file: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -121,7 +111,6 @@ func (s *StepConfigureVNC) Run(_ context.Context, state multistep.StateBag) mult log.Printf("Found available VNC port: %d", vncPort) - vmxData := ParseVMX(string(vmxBytes)) vncFinder.UpdateVMX(vncBindAddress, vncPassword, vncPort, vmxData) if err := WriteVMX(vmxPath, vmxData); err != nil { From 3180dc327c09f180ad9d6119ff504f372e028888 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 15:02:19 -0800 Subject: [PATCH 0536/1007] remove copypasta comment --- builder/oracle/classic/step_list_images.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go index a32355e79..64255b428 100644 --- a/builder/oracle/classic/step_list_images.go +++ b/builder/oracle/classic/step_list_images.go @@ -24,8 +24,8 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis } imList, err := imageListClient.GetImageList(&getInput) if err != nil { - ui.Say(fmt.Sprintf(err.Error())) // If the list didn't exist, create it. + ui.Say(fmt.Sprintf(err.Error())) ui.Say(fmt.Sprintf("Destination image list %s does not exist; Creating it...", config.DestImageList)) @@ -34,7 +34,6 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis Description: "Packer-built image list", } - // Load the packer-generated SSH key into the Oracle Compute cloud. imList, err = imageListClient.CreateImageList(&ilInput) if err != nil { err = fmt.Errorf("Problem creating image list: %s", err) From 8f7937f492de127ed72237de6b7a8df8d49c0301 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 15:22:09 -0800 Subject: [PATCH 0537/1007] fix machine image name to include prepended / --- builder/oracle/classic/step_list_images.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go index 64255b428..4125733b0 100644 --- a/builder/oracle/classic/step_list_images.go +++ b/builder/oracle/classic/step_list_images.go @@ -49,9 +49,10 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis version := len(imList.Entries) + 1 entriesClient := client.ImageListEntries() entriesInput := compute.CreateImageListEntryInput{ - Name: config.DestImageList, - MachineImages: []string{fmt.Sprintf("Compute-%s/%s/%s", config.IdentityDomain, config.Username, snap.MachineImage)}, - Version: version, + Name: config.DestImageList, + MachineImages: []string{fmt.Sprintf("/Compute-%s/%s/%s", + config.IdentityDomain, config.Username, snap.MachineImage)}, + Version: version, } entryInfo, err := entriesClient.CreateImageListEntry(&entriesInput) if err != nil { From 383ac13e2a5459d9d2d4f6d7d0101057f4c85669 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 31 Jan 2018 16:37:55 -0800 Subject: [PATCH 0538/1007] update default of image list after adding new entry. --- builder/oracle/classic/step_list_images.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go index 4125733b0..a99612c14 100644 --- a/builder/oracle/classic/step_list_images.go +++ b/builder/oracle/classic/step_list_images.go @@ -64,13 +64,25 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis state.Put("image_list_entry", entryInfo) ui.Message(fmt.Sprintf("created image list entry %s", entryInfo.Name)) - imList, err = imageListClient.GetImageList(&getInput) - machineImagesClient := client.MachineImages() getImagesInput := compute.GetMachineImageInput{ Name: config.ImageName, } + // Update image list default to use latest version + updateInput := compute.UpdateImageListInput{ + Default: version, + Description: config.DestImageListDescription, + Name: config.DestImageList, + } + _, err = imageListClient.UpdateImageList(&updateInput) + if err != nil { + err = fmt.Errorf("Problem updating default image list version: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + // Grab info about the machine image to return with the artifact imInfo, err := machineImagesClient.GetMachineImage(&getImagesInput) if err != nil { From 59ecaee2fe7db7db73baa4d5d345bb85498505c9 Mon Sep 17 00:00:00 2001 From: SharePointOscar <me@sharepointoscar.com> Date: Wed, 31 Jan 2018 18:00:13 -0800 Subject: [PATCH 0539/1007] implemented changes as per feedback for Azure CLI 2.0 --- contrib/azure-setup.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 7e6817e74..75e770055 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -25,9 +25,9 @@ showhelp() { echo "" echo " For simplicity we make a lot of assumptions and choose reasonable" echo " defaults. If you want more control over what happens, please use" - echo " the azure cli directly." + echo " the azure-cli directly." echo "" - echo " Note that you must already have an az account, username," + echo " Note that you must already have an Azure account, username," echo " password, and subscription. You can create those here:" echo "" echo " - https://account.windowsazure.com/" @@ -54,8 +54,9 @@ requirements() { found=$((found + 1)) echo "Found azure-cli version: $azureversion" else - echo "azure cli is missing. Please install azure cli from" - echo "https://az.microsoft.com/en-us/documentation/articles/xplat-cli-install/" + echo "azure-cli is missing. Please install azure-cli from" + echo "https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" + echo "Alternatively, you can use the Cloud Shell https://docs.microsoft.com/en-us/azure/cloud-shell/overview right from the Azure Portal or even VS Code." fi jqversion=$(jq --version) @@ -169,7 +170,7 @@ createApplication() { createServicePrincipal() { echo "==> Creating service principal" - # az CLI 0.10.2 introduced a breaking change, where appId must be supplied with the -a switch + # Azure CLI 0.10.2 introduced a breaking change, where appId must be supplied with the -a switch # prior version accepted appId as the only parameter without a switch newer_syntax=false IFS='.' read -ra azureversionsemver <<< "$azureversion" From f3c326bb3c47653d7f7ffa76bc02e94eec8c4b4b Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 21 Sep 2017 20:18:47 +0100 Subject: [PATCH 0540/1007] Escape chars special to PowerShell in user supplied data --- provisioner/powershell/provisioner.go | 85 ++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 3d2f16f85..cc11ebc0c 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -8,12 +8,14 @@ import ( "encoding/xml" "errors" "fmt" + "io" "io/ioutil" "log" "os" "sort" "strings" "time" + "unicode/utf8" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/uuid" @@ -345,6 +347,8 @@ func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err erro } func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { + var buf bytes.Buffer + escapedEnvVarValue := "" flattened = "" envVars := make(map[string]string) @@ -359,7 +363,16 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Split vars into key/value components for _, envVar := range p.config.Vars { keyValue := strings.SplitN(envVar, "=", 2) - envVars[keyValue[0]] = keyValue[1] + // Escape chars special to PS in each env var value + err := escapeSpecialPS(&buf, []byte(keyValue[1])) + if err != nil { + fmt.Printf("An error occured escaping chars special to PowerShell in env var value %s", keyValue[1]) + } + escapedEnvVarValue = buf.String() + buf.Reset() + + log.Printf("Env var %s converted to %s after escaping chars special to PS", keyValue[1], escapedEnvVarValue) + envVars[keyValue[0]] = escapedEnvVarValue } // Create a list of env var keys in sorted order @@ -483,10 +496,27 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin buffer.Reset() + // Escape characters special to PowerShell in the ElevatedUser string + err = escapeSpecialPS(&buffer, []byte(p.config.ElevatedUser)) + if err != nil { + fmt.Printf("Error escaping chars special to Powershell in ElevatedUser %s", p.config.ElevatedUser) + } + escapedElevatedUser := buffer.String() + log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", p.config.ElevatedUser, escapedElevatedUser) + buffer.Reset() + // Escape characters special to PowerShell in the ElevatedPassword string + err = escapeSpecialPS(&buffer, []byte(p.config.ElevatedPassword)) + if err != nil { + fmt.Printf("Error escaping chars special to Powershell in ElevatedPassword %s", p.config.ElevatedPassword) + } + escapedElevatedPassword := buffer.String() + log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", p.config.ElevatedPassword, escapedElevatedPassword) + buffer.Reset() + // Generate command err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: p.config.ElevatedUser, - Password: p.config.ElevatedPassword, + User: escapedElevatedUser, + Password: escapedElevatedPassword, TaskName: taskName, TaskDescription: "Packer elevated task", LogFile: logFile, @@ -509,3 +539,52 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin path = fmt.Sprintf("%s-%s.ps1", "%TEMP%\\packer-elevated-shell", uuid) return path, err } + +func escapeSpecialPS(w io.Writer, s []byte) error { + var esc []byte + + last := 0 + for i := 0; i < len(s); { + r, width := utf8.DecodeRune(s[i:]) + i += width + switch r { + case '"': + esc = []byte("`\"") // Double quotes + case '\'': + esc = []byte("`'") // Single quotes + case '$': + esc = []byte("`$") // Dollar sign + case '`': + esc = []byte("``") // Backticks + default: + if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) { + esc = []byte("\uFFFD") // Unicode replacement character + break + } + continue + } + if _, err := w.Write(s[last : i-width]); err != nil { + return err + } + if _, err := w.Write(esc); err != nil { + return err + } + last = i + } + if _, err := w.Write(s[last:]); err != nil { + return err + } + return nil +} + +// Decide whether the given rune is in the XML Character Range, per +// the Char production of http://www.xml.com/axml/testaxml.htm, +// Section 2.2 Characters. +func isInCharacterRange(r rune) (inrange bool) { + return r == 0x09 || + r == 0x0A || + r == 0x0D || + r >= 0x20 && r <= 0xDF77 || + r >= 0xE000 && r <= 0xFFFD || + r >= 0x10000 && r <= 0x10FFFF +} From b67c64fd66874d64dc24bd7bda26c895e877135b Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 21 Sep 2017 23:26:14 +0100 Subject: [PATCH 0541/1007] Tests for escape of chars special to PowerShell in user supplied data --- provisioner/powershell/provisioner_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 749564d4d..2791601fa 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -518,6 +518,12 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { {"FOO=bar", "BAZ=qux"}, // Multiple user env vars {"FOO=bar=baz"}, // User env var with value containing equals {"FOO==bar"}, // User env var with value starting with equals + // Test escaping of characters special to PowerShell + {"FOO=bar$baz"}, // User env var with value containing dollar + {"FOO=bar\"baz"}, // User env var with value containing a double quote + {"FOO=bar'baz"}, // User env var with value containing a single quote + {"FOO=bar`baz"}, // User env var with value containing a backtick + } expected := []string{ `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, @@ -525,6 +531,10 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", } p := new(Provisioner) @@ -553,6 +563,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { {"FOO=bar", "BAZ=qux"}, // Multiple user env vars {"FOO=bar=baz"}, // User env var with value containing equals {"FOO==bar"}, // User env var with value starting with equals + // Test escaping of characters special to PowerShell + {"FOO=bar$baz"}, // User env var with value containing dollar + {"FOO=bar\"baz"}, // User env var with value containing a double quote + {"FOO=bar'baz"}, // User env var with value containing a single quote + {"FOO=bar`baz"}, // User env var with value containing a backtick } expected := []string{ `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, @@ -560,6 +575,10 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", } p := new(Provisioner) From 68e13c90b1c7ef50a7c262a4e1341ce2dafce5bb Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sun, 15 Oct 2017 14:30:17 +0100 Subject: [PATCH 0542/1007] Revert "Escape chars special to PowerShell in user supplied data" This reverts commit 53aefe744bcd74ee6ac866f764eafe9e7f507d80. --- provisioner/powershell/provisioner.go | 85 +-------------------------- 1 file changed, 3 insertions(+), 82 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index cc11ebc0c..3d2f16f85 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -8,14 +8,12 @@ import ( "encoding/xml" "errors" "fmt" - "io" "io/ioutil" "log" "os" "sort" "strings" "time" - "unicode/utf8" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/uuid" @@ -347,8 +345,6 @@ func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err erro } func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { - var buf bytes.Buffer - escapedEnvVarValue := "" flattened = "" envVars := make(map[string]string) @@ -363,16 +359,7 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Split vars into key/value components for _, envVar := range p.config.Vars { keyValue := strings.SplitN(envVar, "=", 2) - // Escape chars special to PS in each env var value - err := escapeSpecialPS(&buf, []byte(keyValue[1])) - if err != nil { - fmt.Printf("An error occured escaping chars special to PowerShell in env var value %s", keyValue[1]) - } - escapedEnvVarValue = buf.String() - buf.Reset() - - log.Printf("Env var %s converted to %s after escaping chars special to PS", keyValue[1], escapedEnvVarValue) - envVars[keyValue[0]] = escapedEnvVarValue + envVars[keyValue[0]] = keyValue[1] } // Create a list of env var keys in sorted order @@ -496,27 +483,10 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin buffer.Reset() - // Escape characters special to PowerShell in the ElevatedUser string - err = escapeSpecialPS(&buffer, []byte(p.config.ElevatedUser)) - if err != nil { - fmt.Printf("Error escaping chars special to Powershell in ElevatedUser %s", p.config.ElevatedUser) - } - escapedElevatedUser := buffer.String() - log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", p.config.ElevatedUser, escapedElevatedUser) - buffer.Reset() - // Escape characters special to PowerShell in the ElevatedPassword string - err = escapeSpecialPS(&buffer, []byte(p.config.ElevatedPassword)) - if err != nil { - fmt.Printf("Error escaping chars special to Powershell in ElevatedPassword %s", p.config.ElevatedPassword) - } - escapedElevatedPassword := buffer.String() - log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", p.config.ElevatedPassword, escapedElevatedPassword) - buffer.Reset() - // Generate command err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: escapedElevatedUser, - Password: escapedElevatedPassword, + User: p.config.ElevatedUser, + Password: p.config.ElevatedPassword, TaskName: taskName, TaskDescription: "Packer elevated task", LogFile: logFile, @@ -539,52 +509,3 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin path = fmt.Sprintf("%s-%s.ps1", "%TEMP%\\packer-elevated-shell", uuid) return path, err } - -func escapeSpecialPS(w io.Writer, s []byte) error { - var esc []byte - - last := 0 - for i := 0; i < len(s); { - r, width := utf8.DecodeRune(s[i:]) - i += width - switch r { - case '"': - esc = []byte("`\"") // Double quotes - case '\'': - esc = []byte("`'") // Single quotes - case '$': - esc = []byte("`$") // Dollar sign - case '`': - esc = []byte("``") // Backticks - default: - if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) { - esc = []byte("\uFFFD") // Unicode replacement character - break - } - continue - } - if _, err := w.Write(s[last : i-width]); err != nil { - return err - } - if _, err := w.Write(esc); err != nil { - return err - } - last = i - } - if _, err := w.Write(s[last:]); err != nil { - return err - } - return nil -} - -// Decide whether the given rune is in the XML Character Range, per -// the Char production of http://www.xml.com/axml/testaxml.htm, -// Section 2.2 Characters. -func isInCharacterRange(r rune) (inrange bool) { - return r == 0x09 || - r == 0x0A || - r == 0x0D || - r >= 0x20 && r <= 0xDF77 || - r >= 0xE000 && r <= 0xFFFD || - r >= 0x10000 && r <= 0x10FFFF -} From 7443adf2fd3560b309e3628420dc231bc078c204 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sun, 15 Oct 2017 13:28:59 +0100 Subject: [PATCH 0543/1007] Simpler escape of chars special to PowerShell in user supplied data --- provisioner/powershell/provisioner.go | 34 +++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 3d2f16f85..41b38ed6d 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -24,6 +24,13 @@ import ( var retryableSleep = 2 * time.Second +var psEscape = strings.NewReplacer( + "$", "`$", + "\"", "`\"", + "`", "``", + "'", "`'", +) + type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -359,7 +366,13 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Split vars into key/value components for _, envVar := range p.config.Vars { keyValue := strings.SplitN(envVar, "=", 2) - envVars[keyValue[0]] = keyValue[1] + // Escape chars special to PS in each env var value + escapedEnvVarValue := psEscape.Replace(keyValue[1]) + if escapedEnvVarValue != keyValue[1] { + log.Printf("Env var %s converted to %s after escaping chars special to PS", keyValue[1], + escapedEnvVarValue) + } + envVars[keyValue[0]] = escapedEnvVarValue } // Create a list of env var keys in sorted order @@ -480,13 +493,26 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } escapedCommand := buffer.String() log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) - buffer.Reset() + // Escape chars special to PowerShell in the ElevatedUser string + escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) + if escapedElevatedUser != p.config.ElevatedUser { + log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedUser, escapedElevatedUser) + } + + // Escape chars special to PowerShell in the ElevatedPassword string + escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) + if escapedElevatedPassword != p.config.ElevatedPassword { + log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedPassword, escapedElevatedPassword) + } + // Generate command err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: p.config.ElevatedUser, - Password: p.config.ElevatedPassword, + User: escapedElevatedUser, + Password: escapedElevatedPassword, TaskName: taskName, TaskDescription: "Packer elevated task", LogFile: logFile, From 6ad4917960c251e16ac0f6d6f4e0a9dcf27e2f01 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Mon, 30 Oct 2017 00:14:06 +0000 Subject: [PATCH 0544/1007] First attempt at fixer for powershell escapes --- fix/fixer.go | 2 + fix/fixer_powershell_escapes.go | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 fix/fixer_powershell_escapes.go diff --git a/fix/fixer.go b/fix/fixer.go index 5ca0b3a18..d5622b299 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -34,6 +34,7 @@ func init() { "amazon-shutdown_behavior": new(FixerAmazonShutdownBehavior), "amazon-enhanced-networking": new(FixerAmazonEnhancedNetworking), "docker-email": new(FixerDockerEmail), + "powershell-escapes": new(FixerPowerShellEscapes), } FixerOrder = []string{ @@ -51,5 +52,6 @@ func init() { "amazon-shutdown_behavior", "amazon-enhanced-networking", "docker-email", + "powershell-escapes", } } diff --git a/fix/fixer_powershell_escapes.go b/fix/fixer_powershell_escapes.go new file mode 100644 index 000000000..9da9ae91f --- /dev/null +++ b/fix/fixer_powershell_escapes.go @@ -0,0 +1,73 @@ +package fix + +import ( + "github.com/mitchellh/mapstructure" + "strings" +) + +// FixerPowerShellEscapes removes the PowerShell escape character from user +// environment variables and elevated username and password strings +type FixerPowerShellEscapes struct{} + +func (FixerPowerShellEscapes) Fix(input map[string]interface{}) (map[string]interface{}, error) { + type template struct { + Provisioners []interface{} + } + + var psUnescape = strings.NewReplacer( + "`$", "$", + "`\"", "\"", + "``", "`", + "`'", "'", + ) + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.WeakDecode(input, &tpl); err != nil { + return nil, err + } + + for i, raw := range tpl.Provisioners { + var provisioners map[string]interface{} + if err := mapstructure.Decode(raw, &provisioners); err != nil { + // Ignore errors, could be a non-map + continue + } + + if ok := provisioners["type"] == "powershell"; !ok { + continue + } + + if _, ok := provisioners["elevated_user"]; ok { + provisioners["elevated_user"] = psUnescape.Replace(provisioners["elevated_user"].(string)) + } + if _, ok := provisioners["elevated_password"]; ok { + provisioners["elevated_password"] = psUnescape.Replace(provisioners["elevated_password"].(string)) + } + if raw, ok := provisioners["environment_vars"]; ok { + var env_vars []string + if err := mapstructure.Decode(raw, &env_vars); err != nil { + continue + } + env_vars_unescaped := make([]interface{}, len(env_vars)) + for j, env_var := range env_vars { + env_vars_unescaped[j] = psUnescape.Replace(env_var) + } + // Replace with unescaped environment variables + provisioners["environment_vars"] = env_vars_unescaped + } + + // Write all changes back to template + tpl.Provisioners[i] = provisioners + } + + if len(tpl.Provisioners) > 0 { + input["provisioners"] = tpl.Provisioners + } + + return input, nil +} + +func (FixerPowerShellEscapes) Synopsis() string { + return `Removes PowerShell escapes from user env vars and elevated username and password strings` +} From d25a26e78a6f1f729394ede86e476dc9d01f3aed Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 1 Feb 2018 14:52:22 -0800 Subject: [PATCH 0545/1007] update changelog in prep for 1.2.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3920501e..1d73eb0ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## (UNRELEASED) +### BACKWARDS INCOMPATIBILITIES: +* core: Affects Windows guests: User variables containing Powershell special characters no longer need to be escaped.[GH-5376] +* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] +* 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will break; the work to fix them is minimal and documented in GH-5810. [GH-5810] + ### IMPROVEMENTS: * builder/docker: Remove credentials from being shown in the log. [GH-5666] @@ -9,10 +14,31 @@ * builder/amazon: Warn during prepare if we didn't get both an access key and a secret key when we were expecting one. [GH-5762] * builder/amazon: Replace `InstanceStatusOK` check with `InstanceReady`. This reduces build times universally while still working for all instance types. [GH-5678] * builder/amazon: Add `kms_key_id` option to block device mappings. [GH-5774] +* builder/hyper-v: New option to use differential disks and Inline disk creation to improve build time and reduce disk usage [GH-5631] +* post-processor/vagrant: Add vagrant post-processor support for Google [GH-5732] +* provisioner/chef: Added Policyfile support to chef-client provisioner. [GH-5831] +* builder/qemu: Add Intel HAXM support to QEMU builder [GH-5738] +* communicator/ssh: Add session-level keep-alives [GH-5830] +* post-processor/amazon-import: Allow user to specify role name in amazon-import [GH-5817] +* provisioner/chef: Add support for 'trusted_certs_dir' chef-client configuration option [GH-5790] +* builder/triton: Updated triton-go dependencies, allowing better error handling. [GH-5795] +* core: Improved error logging in floppy file handling. [GH-5802] +* provisioner/amazon: Use Amazon SDK's InstanceRunning waiter instead of InstanceStatusOK waiter [GH-5773] +* builder/amazon: Add Paris region (eu-west-3) [GH-5718] +* builder/azure: Add validation for incorrect VHD URLs [GH-5695] +* builder/amazon: Remove Session Token (STS) from being shown in the log. [GH-5665] ### BUG FIXES: * builder/alicloud-ecs: Attach keypair before starting instance in alicloud builder [GH-5739] +* builder/vmware: Fixed file handle leak that may have caused race conditions in vmware builder [GH-5767] +* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] +* provisioner/ansible: The "default extra variables" feature added in Packer v1.0.1 caused the ansible-local provisioner to fail when an --extra-vars argument was specified in the extra_arguments configuration option; this has been fixed. [GH-5335] +* communicator/ssh: Add deadline to SSH connection to prevent Packer hangs after script provisioner reboots vm [GH-4684] +* builder/virtualbox: Fix regression affecting users running Packer on a Windows host that kept Packer from finding Virtualbox guest additions if Packer ran on a different drive from the one where the guest additions were stored. [GH-5761] +* builder/virtualbox: Fix interpolation ordering so that edge cases around guest_additions_url are handled correctly [GH-5757] +* builder/amazon: NewSession now inherits MaxRetries and other settings. [GH-5719] + ## 1.1.3 (December 8, 2017) From 30a4998a810fb4d2be485dde0b782e2e2129c2a6 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 1 Feb 2018 16:35:10 -0800 Subject: [PATCH 0546/1007] branding --- website/source/docs/builders/oracle-classic.html.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index e71cc9cc3..0d9dc05b7 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -3,16 +3,16 @@ description: The oracle-classic builder is able to create new custom images for use with Oracle Compute Cloud. layout: docs -page_title: 'Oracle Classic - Builders' +page_title: 'Oracle Cloud Infrastructure Classic - Builders' sidebar_current: 'docs-builders-oracle-classic' --- -# Oracle Compute Cloud (Classic) Builder +# Oracle Cloud Infrastructure Classic Compute Builder Type: `oracle-classic` The `oracle-classic` Packer builder is able to create custom images for use -with [Oracle Compute Cloud](https://cloud.oracle.com/compute-classic). The builder +with [Oracle Cloud Infrastructure Classic Compute](https://cloud.oracle.com/compute-classic). The builder takes a base image, runs any provisioning necessary on the base image after launching it, and finally snapshots it creating a reusable custom image. @@ -25,7 +25,7 @@ to use it or delete it. ## Authorization -This builder authenticates API calls to Compute Classic using basic +This builder authenticates API calls to Oracle Cloud Infrastructure Classic Compute using basic authentication (user name and password). To read more, see the [authentication documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/Authentication.html) From 79fe9003784d0bf69eaa910366c77ad94ad978fa Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 2 Feb 2018 09:57:36 -0800 Subject: [PATCH 0547/1007] Revert "Merge pull request #5376 from DanHam/ps-escapes" Revert so that we can merge a different branch that's had more recent work instead This reverts commit ba518637d49380955f4bd2f0e6009888037fa82e, reversing changes made to e56849c6056220b8dd555f841f7e0a5028b25af0. --- fix/fixer.go | 2 - fix/fixer_powershell_escapes.go | 73 ---------------------- provisioner/powershell/provisioner.go | 34 ++-------- provisioner/powershell/provisioner_test.go | 19 ------ 4 files changed, 4 insertions(+), 124 deletions(-) delete mode 100644 fix/fixer_powershell_escapes.go diff --git a/fix/fixer.go b/fix/fixer.go index d5622b299..5ca0b3a18 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -34,7 +34,6 @@ func init() { "amazon-shutdown_behavior": new(FixerAmazonShutdownBehavior), "amazon-enhanced-networking": new(FixerAmazonEnhancedNetworking), "docker-email": new(FixerDockerEmail), - "powershell-escapes": new(FixerPowerShellEscapes), } FixerOrder = []string{ @@ -52,6 +51,5 @@ func init() { "amazon-shutdown_behavior", "amazon-enhanced-networking", "docker-email", - "powershell-escapes", } } diff --git a/fix/fixer_powershell_escapes.go b/fix/fixer_powershell_escapes.go deleted file mode 100644 index 9da9ae91f..000000000 --- a/fix/fixer_powershell_escapes.go +++ /dev/null @@ -1,73 +0,0 @@ -package fix - -import ( - "github.com/mitchellh/mapstructure" - "strings" -) - -// FixerPowerShellEscapes removes the PowerShell escape character from user -// environment variables and elevated username and password strings -type FixerPowerShellEscapes struct{} - -func (FixerPowerShellEscapes) Fix(input map[string]interface{}) (map[string]interface{}, error) { - type template struct { - Provisioners []interface{} - } - - var psUnescape = strings.NewReplacer( - "`$", "$", - "`\"", "\"", - "``", "`", - "`'", "'", - ) - - // Decode the input into our structure, if we can - var tpl template - if err := mapstructure.WeakDecode(input, &tpl); err != nil { - return nil, err - } - - for i, raw := range tpl.Provisioners { - var provisioners map[string]interface{} - if err := mapstructure.Decode(raw, &provisioners); err != nil { - // Ignore errors, could be a non-map - continue - } - - if ok := provisioners["type"] == "powershell"; !ok { - continue - } - - if _, ok := provisioners["elevated_user"]; ok { - provisioners["elevated_user"] = psUnescape.Replace(provisioners["elevated_user"].(string)) - } - if _, ok := provisioners["elevated_password"]; ok { - provisioners["elevated_password"] = psUnescape.Replace(provisioners["elevated_password"].(string)) - } - if raw, ok := provisioners["environment_vars"]; ok { - var env_vars []string - if err := mapstructure.Decode(raw, &env_vars); err != nil { - continue - } - env_vars_unescaped := make([]interface{}, len(env_vars)) - for j, env_var := range env_vars { - env_vars_unescaped[j] = psUnescape.Replace(env_var) - } - // Replace with unescaped environment variables - provisioners["environment_vars"] = env_vars_unescaped - } - - // Write all changes back to template - tpl.Provisioners[i] = provisioners - } - - if len(tpl.Provisioners) > 0 { - input["provisioners"] = tpl.Provisioners - } - - return input, nil -} - -func (FixerPowerShellEscapes) Synopsis() string { - return `Removes PowerShell escapes from user env vars and elevated username and password strings` -} diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 41b38ed6d..3d2f16f85 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -24,13 +24,6 @@ import ( var retryableSleep = 2 * time.Second -var psEscape = strings.NewReplacer( - "$", "`$", - "\"", "`\"", - "`", "``", - "'", "`'", -) - type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -366,13 +359,7 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Split vars into key/value components for _, envVar := range p.config.Vars { keyValue := strings.SplitN(envVar, "=", 2) - // Escape chars special to PS in each env var value - escapedEnvVarValue := psEscape.Replace(keyValue[1]) - if escapedEnvVarValue != keyValue[1] { - log.Printf("Env var %s converted to %s after escaping chars special to PS", keyValue[1], - escapedEnvVarValue) - } - envVars[keyValue[0]] = escapedEnvVarValue + envVars[keyValue[0]] = keyValue[1] } // Create a list of env var keys in sorted order @@ -493,26 +480,13 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } escapedCommand := buffer.String() log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) + buffer.Reset() - // Escape chars special to PowerShell in the ElevatedUser string - escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) - if escapedElevatedUser != p.config.ElevatedUser { - log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", - p.config.ElevatedUser, escapedElevatedUser) - } - - // Escape chars special to PowerShell in the ElevatedPassword string - escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) - if escapedElevatedPassword != p.config.ElevatedPassword { - log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", - p.config.ElevatedPassword, escapedElevatedPassword) - } - // Generate command err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: escapedElevatedUser, - Password: escapedElevatedPassword, + User: p.config.ElevatedUser, + Password: p.config.ElevatedPassword, TaskName: taskName, TaskDescription: "Packer elevated task", LogFile: logFile, diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 2791601fa..749564d4d 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -518,12 +518,6 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { {"FOO=bar", "BAZ=qux"}, // Multiple user env vars {"FOO=bar=baz"}, // User env var with value containing equals {"FOO==bar"}, // User env var with value starting with equals - // Test escaping of characters special to PowerShell - {"FOO=bar$baz"}, // User env var with value containing dollar - {"FOO=bar\"baz"}, // User env var with value containing a double quote - {"FOO=bar'baz"}, // User env var with value containing a single quote - {"FOO=bar`baz"}, // User env var with value containing a backtick - } expected := []string{ `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, @@ -531,10 +525,6 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, - "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", - "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", - "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", - "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", } p := new(Provisioner) @@ -563,11 +553,6 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { {"FOO=bar", "BAZ=qux"}, // Multiple user env vars {"FOO=bar=baz"}, // User env var with value containing equals {"FOO==bar"}, // User env var with value starting with equals - // Test escaping of characters special to PowerShell - {"FOO=bar$baz"}, // User env var with value containing dollar - {"FOO=bar\"baz"}, // User env var with value containing a double quote - {"FOO=bar'baz"}, // User env var with value containing a single quote - {"FOO=bar`baz"}, // User env var with value containing a backtick } expected := []string{ `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, @@ -575,10 +560,6 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, - "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", - "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", - "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", - "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", } p := new(Provisioner) From addedbb680eb4d2ac4df064f712931f6b55bea4e Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 2 Feb 2018 09:58:39 -0800 Subject: [PATCH 0548/1007] Revert "Merge pull request #5515 from DanHam/dot-source-env-vars" revert so we can use a branch that's had more recent work done This reverts commit e56849c6056220b8dd555f841f7e0a5028b25af0, reversing changes made to 6d14eb6ea4ffa5cbaa0bad9d62d2dff09f946b15. --- provisioner/powershell/provisioner.go | 52 ++++-------- provisioner/powershell/provisioner_test.go | 85 ++++++------------- .../docs/provisioners/powershell.html.md | 50 +++++------ 3 files changed, 65 insertions(+), 122 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 3d2f16f85..4297acf08 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -113,7 +113,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.EnvVarFormat == "" { - p.config.EnvVarFormat = `$env:%s="%s"; ` + p.config.EnvVarFormat = `$env:%s=\"%s\"; ` } if p.config.ElevatedEnvVarFormat == "" { @@ -121,7 +121,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.ExecuteCommand == "" { - p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"` + p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` } if p.config.ElevatedExecuteCommand == "" { @@ -331,19 +331,6 @@ func (p *Provisioner) retryable(f func() error) error { } } -// Enviroment variables required within the remote environment are uploaded within a PS script and -// then enabled by 'dot sourcing' the script immediately prior to execution of the main command -func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err error) { - // Collate all required env vars into a plain string with required formatting applied - flattenedEnvVars := p.createFlattenedEnvVars(elevated) - // Create a powershell script on the target build fs containing the flattened env vars - envVarPath, err = p.uploadEnvVars(flattenedEnvVars) - if err != nil { - return "", err - } - return -} - func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { flattened = "" envVars := make(map[string]string) @@ -380,19 +367,6 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { return } -func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (envVarPath string, err error) { - // Upload all env vars to a powershell script on the target build file system - envVarReader := strings.NewReader(flattenedEnvVars) - uuid := uuid.TimeOrderedUUID() - envVarPath = fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) - log.Printf("Uploading env vars to %s", envVarPath) - err = p.communicator.Upload(envVarPath, envVarReader, nil) - if err != nil { - return "", fmt.Errorf("Error uploading ps script containing env vars: %s", err) - } - return -} - func (p *Provisioner) createCommandText() (command string, err error) { // Return the interpolated command if p.config.ElevatedUser == "" { @@ -403,15 +377,12 @@ func (p *Provisioner) createCommandText() (command string, err error) { } func (p *Provisioner) createCommandTextNonPrivileged() (command string, err error) { - // Prepare everything needed to enable the required env vars within the remote environment - envVarPath, err := p.prepareEnvVars(false) - if err != nil { - return "", err - } + // Create environment variables to set before executing the command + flattenedEnvVars := p.createFlattenedEnvVars(false) p.config.ctx.Data = &ExecuteCommandTemplate{ + Vars: flattenedEnvVars, Path: p.config.RemotePath, - Vars: envVarPath, } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -424,10 +395,17 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro } func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { - // Prepare everything needed to enable the required env vars within the remote environment - envVarPath, err := p.prepareEnvVars(false) + // Can't double escape the env vars, lets create shiny new ones + flattenedEnvVars := p.createFlattenedEnvVars(true) + // Need to create a mini ps1 script containing all of the environment variables we want; + // we'll be dot-sourcing this later + envVarReader := strings.NewReader(flattenedEnvVars) + uuid := uuid.TimeOrderedUUID() + envVarPath := fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) + log.Printf("Uploading env vars to %s", envVarPath) + err = p.communicator.Upload(envVarPath, envVarReader, nil) if err != nil { - return "", err + return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) } p.config.ctx.Data = &ExecuteCommandTemplate{ diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 749564d4d..e7e64d52e 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -79,8 +79,8 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { t.Error("expected elevated_password to be empty") } - if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"` { - t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) + if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` { + t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) } if p.config.ElevatedExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` { @@ -403,7 +403,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { ui := testUi() p := new(Provisioner) - // Defaults provided by Packer - env vars should not appear in cmd + // Defaults provided by Packer p.config.PackerBuildName = "vmware" p.config.PackerBuilderType = "iso" comm := new(packer.MockCommunicator) @@ -413,14 +413,11 @@ func TestProvisionerProvision_Inline(t *testing.T) { t.Fatal("should not have error") } - cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) - matched := re.MatchString(cmd) - if !matched { - t.Fatalf("Got unexpected command: %s", cmd) + expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` + if comm.StartCmd.Command != expectedCommand { + t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) } - // User supplied env vars should not change things envVars := make([]string, 2) envVars[0] = "FOO=BAR" envVars[1] = "BAR=BAZ" @@ -433,11 +430,9 @@ func TestProvisionerProvision_Inline(t *testing.T) { t.Fatal("should not have error") } - cmd = comm.StartCmd.Command - re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) - matched = re.MatchString(cmd) - if !matched { - t.Fatalf("Got unexpected command: %s", cmd) + expectedCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` + if comm.StartCmd.Command != expectedCommand { + t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) } } @@ -460,12 +455,11 @@ func TestProvisionerProvision_Scripts(t *testing.T) { t.Fatal("should not have error") } - cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) - matched := re.MatchString(cmd) - if !matched { - t.Fatalf("Got unexpected command: %s", cmd) + expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` + if comm.StartCmd.Command != expectedCommand { + t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) } + } func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { @@ -494,11 +488,9 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { t.Fatal("should not have error") } - cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) - matched := re.MatchString(cmd) - if !matched { - t.Fatalf("Got unexpected command: %s", cmd) + expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` + if comm.StartCmd.Command != expectedCommand { + t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) } } @@ -555,11 +547,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { {"FOO==bar"}, // User env var with value starting with equals } expected := []string{ - `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, - `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, - `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, - `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, - `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, + `$env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, + `$env:BAZ=\"qux\"; $env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, + `$env:FOO=\"bar=baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, + `$env:FOO=\"=bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, } p := new(Provisioner) @@ -579,6 +571,7 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { } func TestProvision_createCommandText(t *testing.T) { + config := testConfig() config["remote_path"] = "c:/Windows/Temp/script.ps1" p := new(Provisioner) @@ -593,46 +586,22 @@ func TestProvision_createCommandText(t *testing.T) { // Non-elevated cmd, _ := p.createCommandText() - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) - matched := re.MatchString(cmd) - if !matched { - t.Fatalf("Got unexpected command: %s", cmd) + expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` + + if cmd != expectedCommand { + t.Fatalf("Expected Non-elevated command: %s, got %s", expectedCommand, cmd) } // Elevated p.config.ElevatedUser = "vagrant" p.config.ElevatedPassword = "vagrant" cmd, _ = p.createCommandText() - re = regexp.MustCompile(`powershell -executionpolicy bypass -file "%TEMP%\\packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) - matched = re.MatchString(cmd) + matched, _ := regexp.MatchString("powershell -executionpolicy bypass -file \"%TEMP%(.{1})packer-elevated-shell.*", cmd) if !matched { t.Fatalf("Got unexpected elevated command: %s", cmd) } } -func TestProvision_uploadEnvVars(t *testing.T) { - p := new(Provisioner) - comm := new(packer.MockCommunicator) - p.communicator = comm - - flattenedEnvVars := `$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild";` - - envVarPath, err := p.uploadEnvVars(flattenedEnvVars) - if err != nil { - t.Fatalf("Did not expect error: %s", err.Error()) - } - - if comm.UploadCalled != true { - t.Fatalf("Failed to upload env var file") - } - - re := regexp.MustCompile(`\${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1`) - matched := re.MatchString(envVarPath) - if !matched { - t.Fatalf("Got unexpected path for env var file: %s", envVarPath) - } -} - func TestProvision_generateElevatedShellRunner(t *testing.T) { // Non-elevated diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index a096bf2f5..f085a6e82 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -1,8 +1,8 @@ --- description: | - The shell Packer provisioner provisions machines built by Packer using - shell scripts. Shell provisioning is the easiest way to get software - installed and configured on a machine. + The shell Packer provisioner provisions machines built by Packer using shell + scripts. Shell provisioning is the easiest way to get software installed and + configured on a machine. layout: docs page_title: 'PowerShell - Provisioners' sidebar_current: 'docs-provisioners-powershell' @@ -29,21 +29,20 @@ The example below is fully functional. ## Configuration Reference The reference of available configuration options is listed below. The only -required element is either "inline" or "script". Every other option is -optional. +required element is either "inline" or "script". Every other option is optional. Exactly *one* of the following is required: - `inline` (array of strings) - This is an array of commands to execute. The - commands are concatenated by newlines and turned into a single file, so - they are all executed within the same context. This allows you to change + commands are concatenated by newlines and turned into a single file, so they + are all executed within the same context. This allows you to change directories in one command and use something in the directory in the next and so on. Inline scripts are the easiest way to pull off simple tasks within the machine. - `script` (string) - The path to a script to upload and execute in - the machine. This path can be absolute or relative. If it is relative, it - is relative to the working directory when Packer is executed. + the machine. This path can be absolute or relative. If it is relative, it is + relative to the working directory when Packer is executed. - `scripts` (array of strings) - An array of scripts to execute. The scripts will be uploaded and executed in the order specified. Each script is @@ -52,12 +51,12 @@ Exactly *one* of the following is required: Optional parameters: -- `binary` (boolean) - If true, specifies that the script(s) are binary - files, and Packer should therefore not convert Windows line endings to Unix - line endings (if there are any). By default this is false. +- `binary` (boolean) - If true, specifies that the script(s) are binary files, + and Packer should therefore not convert Windows line endings to Unix line + endings (if there are any). By default this is false. -- `elevated_execute_command` (string) - The command to use to execute the - elevated script. By default this is as follows: +- `elevated_execute_command` (string) - The command to use to execute the elevated + script. By default this is as follows: ``` powershell powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }" @@ -66,34 +65,32 @@ Optional parameters: The value of this is treated as [configuration template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and - `Vars`, which is the location of a temp file containing the list of - `environment_vars`, if configured. + `Vars`, which is the location of a temp file containing the list of `environment_vars`, if configured. - `environment_vars` (array of strings) - An array of key/value pairs to inject prior to the execute\_command. The format should be `key=value`. - Packer injects some environmental variables by default into the - environment, as well, which are covered in the section below. + Packer injects some environmental variables by default into the environment, + as well, which are covered in the section below. - `execute_command` (string) - The command to use to execute the script. By default this is as follows: ``` powershell - powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }" + powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }" ``` The value of this is treated as [configuration template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and - `Vars`, which is the location of a temp file containing the list of - `environment_vars`, if configured. + `Vars`, which is the list of `environment_vars`, if configured. - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given Windows user. - `remote_path` (string) - The path where the script will be uploaded to in - the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must - be a writable location and any parent directories must already exist. + the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must be a + writable location and any parent directories must already exist. - `start_retry_timeout` (string) - The amount of time to attempt to *start* the remote process. By default this is "5m" or 5 minutes. This setting @@ -114,10 +111,9 @@ commonly useful environmental variables: This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. -- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create - the machine that the script is running on. This is useful if you want to - run only certain parts of the script on systems built with certain - builders. +- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the + machine that the script is running on. This is useful if you want to run + only certain parts of the script on systems built with certain builders. - `PACKER_HTTP_ADDR` If using a builder that provides an http server for file transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this From c132bd867e61e0983dbef1e9a8247991af1aa35b Mon Sep 17 00:00:00 2001 From: James Nugent <james@jen20.com> Date: Fri, 2 Feb 2018 13:14:13 -0600 Subject: [PATCH 0549/1007] vagrant: Correct name of vim package The non-X11-linked version of vim recently changed name from vim-lite to vim-console, which was preventing bootstrap. --- scripts/vagrant-freebsd-priv-config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/vagrant-freebsd-priv-config.sh b/scripts/vagrant-freebsd-priv-config.sh index 30a2e8185..e2ea148dc 100755 --- a/scripts/vagrant-freebsd-priv-config.sh +++ b/scripts/vagrant-freebsd-priv-config.sh @@ -17,7 +17,7 @@ EOT pkg update pkg install -y \ - editors/vim-lite \ + editors/vim-console \ devel/git \ devel/gmake \ lang/go \ From 399431c00b502f633f34cdb0f7a2533b0bb9c80d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 2 Feb 2018 12:19:04 -0800 Subject: [PATCH 0550/1007] group oracle builders under a single heading. --- .../docs/builders/oracle-classic.html.md | 32 +++++++++---------- .../source/docs/builders/oracle-oci.html.md | 2 +- website/source/docs/builders/oracle.html.md | 22 +++++++++++++ website/source/layouts/docs.erb | 15 ++++++--- 4 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 website/source/docs/builders/oracle.html.md diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 0d9dc05b7..f8991b968 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -1,7 +1,7 @@ --- -description: +description: | The oracle-classic builder is able to create new custom images for use with Oracle - Compute Cloud. + Cloud Infrastructure Classic Compute. layout: docs page_title: 'Oracle Cloud Infrastructure Classic - Builders' sidebar_current: 'docs-builders-oracle-classic' @@ -25,7 +25,7 @@ to use it or delete it. ## Authorization -This builder authenticates API calls to Oracle Cloud Infrastructure Classic Compute using basic +This builder authenticates API calls to Oracle Cloud Infrastructure Classic Compute using basic authentication (user name and password). To read more, see the [authentication documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/Authentication.html) @@ -36,11 +36,11 @@ This builder currently only works with the SSH communicator. ### Required - - `api_endpoint` (string) - This is your custom API endpoint for sending - requests. Instructions for determining your API endpoint can be found + - `api_endpoint` (string) - This is your custom API endpoint for sending + requests. Instructions for determining your API endpoint can be found [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsa/SendRequests.html) - - `dest_image_list` (string) - Where to save the machine image to once you've + - `dest_image_list` (string) - Where to save the machine image to once you've provisioned it. If the provided image list does not exist, Packer will create it. - `identity_domain` (string) - This is your customer-specific identity domain @@ -50,7 +50,7 @@ This builder currently only works with the SSH communicator. - `source_image_list` (string) - This is what image you want to use as your base image. See the [documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/listing-machine-images.html) - for more details. You may use either a public image list, or a private image list. To see what public image lists are available, you can use + for more details. You may use either a public image list, or a private image list. To see what public image lists are available, you can use the CLI, as described [here](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stopc/image-lists-stclr-and-nmcli.html#GUID-DB7E75FE-F752-4FF7-AB70-3C8DCDFCA0FA) - `password` (string) - Your account password. @@ -63,21 +63,21 @@ This builder currently only works with the SSH communicator. ### Optional - - `image_description` (string) - a description for your destination - image list. If you don't provide one, Packer will provide a generic description. + - `image_description` (string) - a description for your destination + image list. If you don't provide one, Packer will provide a generic description. - - `ssh_username` (string) - The username that Packer will use to SSH into the - instance; defaults to `opc`, the default oracle user, which has sudo - priveliges. If you have already configured users on your machine, you may - prompt Packer to use one of those instead. For more detail, see the + - `ssh_username` (string) - The username that Packer will use to SSH into the + instance; defaults to `opc`, the default oracle user, which has sudo + priveliges. If you have already configured users on your machine, you may + prompt Packer to use one of those instead. For more detail, see the [documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/accessing-oracle-linux-instance-using-ssh.html). - `image_name` (string) - The name to assign to the resulting custom image. ## Basic Example -Here is a basic example. Note that account specific configuration has been -obfuscated; you will need to add a working `username`, `password`, +Here is a basic example. Note that account specific configuration has been +obfuscated; you will need to add a working `username`, `password`, `identity_domain`, and `api_endpoint` in order for the example to work. ``` {.json} @@ -90,7 +90,7 @@ obfuscated; you will need to add a working `username`, `password`, "identity_domain": "#######", "api_endpoint": "https://api-###.compute.###.oraclecloud.com/", "source_image_list": "/oracle/public/OL_7.2_UEKR4_x86_64", - "shape": "oc3", + "shape": "oc3", "image_name": "Packer_Builder_Test_{{timestamp}}" "dest_image_list": "Packer_Builder_Test_List" } diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index 3503d4fca..6271c5830 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -1,5 +1,5 @@ --- -description: +description: | The oracle-oci builder is able to create new custom images for use with Oracle Cloud Infrastructure (OCI). layout: docs diff --git a/website/source/docs/builders/oracle.html.md b/website/source/docs/builders/oracle.html.md new file mode 100644 index 000000000..70a1917d0 --- /dev/null +++ b/website/source/docs/builders/oracle.html.md @@ -0,0 +1,22 @@ +--- +description: | + Packer is able to create custom images using Oracle Cloud Infrastructure. +layout: docs +page_title: 'Oracle - Builders' +sidebar_current: 'docs-builders-oracle' +--- + +# Oracle Builder + +Packer is able to create custom images on both Oracle Cloud Infrastructure and +Oracle Cloud Infrastructure Classic Compute. Packer comes with builders +designed to support both platforms. Please choose the one that's right for you: + +- [oracle-classic](/docs/builders/oracle-classic.html) - Create custom images + in Oracle Cloud Infrastructure Classic Compute by launching a source + instance and creating an image list from a snapshot of it after + provisioning. + +- [oracle-oci](/docs/builders/amazon-instance.html) - Create custom images in + Oracle Cloud Infrastructure (OCI) by launching a base instance and creating + an image from it after provisioning. diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 739b33733..8470e0d35 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -131,11 +131,16 @@ <li<%= sidebar_current("docs-builders-openstack") %>> <a href="/docs/builders/openstack.html">OpenStack</a> </li> - <li<%= sidebar_current("docs-builders-oracle-classic") %>> - <a href="/docs/builders/oracle-classic.html">Oracle Classic</a> - </li> - <li<%= sidebar_current("docs-builders-oracle-oci") %>> - <a href="/docs/builders/oracle-oci.html">Oracle OCI</a> + <li<%= sidebar_current("docs-builders-oracle") %>> + <a href="/docs/builders/oracle.html">Oracle</a> + <ul class="nav"> + <li<%= sidebar_current("docs-builders-oracle-classic") %>> + <a href="/docs/builders/oracle-classic.html">Oracle Classic</a> + </li> + <li<%= sidebar_current("docs-builders-oracle-oci") %>> + <a href="/docs/builders/oracle-oci.html">Oracle OCI</a> + </li> + </ul> </li> <li<%= sidebar_current("docs-builders-parallels") %>> <a href="/docs/builders/parallels.html">Parallels</a> From c98a074f0dd14a646a3eb919397f38b2a8269ba5 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 2 Feb 2018 18:58:42 -0600 Subject: [PATCH 0551/1007] Renamed common/config.go's SupportedURL to SupportedProtocol as suggested by @SwampDragons. --- common/config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/config.go b/common/config.go index 6850005d7..269d52dd1 100644 --- a/common/config.go +++ b/common/config.go @@ -44,9 +44,9 @@ func ChooseString(vals ...string) string { return "" } -// SupportedURL verifies that the url passed is actually supported or not +// SupportedProtocol verifies that the url passed is actually supported or not // This will also validate that the protocol is one that's actually implemented. -func SupportedURL(u *url.URL) bool { +func SupportedProtocol(u *url.URL) bool { // url.Parse shouldn't return nil except on error....but it can. if u == nil { return false @@ -159,7 +159,7 @@ func ValidatedURL(original string) (string, error) { } // We should now have a url, so verify that it's a protocol we support. - if !SupportedURL(u) { + if !SupportedProtocol(u) { return "", fmt.Errorf("Unsupported protocol scheme! (%#v)", u) } From 75d3ea7cee0ee2b7a740dcfd62f8a890a0c0dbc8 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 11 Nov 2015 06:39:06 -0600 Subject: [PATCH 0552/1007] Added support for sound, serial ports, parallel ports, usb, and specifying a default network to the vmware builder. builder/vmware/{iso,vmx}: Added the specific configuration options that get parsed. Normalize paths when pulling them from the json template so that they'll work on Windows too. Added some improved error checking when parsing these options. Stash the vm's network connection type so that other steps can figure out addressing information Modified the esx5 driver to support the new addressing logic. Modified the template in step_create_vmx to include the new options. builder/vmware/common: Implemented a parser for vmware's configuration files to the vmware builder. Modified the driver's interface to include support for resolving both guest/host hw and ip addresses Implemented a base structure with some methods that implement these features. Rewrote all ip and mac address dependent code to utilize these new methods. Removed host_ip and guest_ip due to their logic being moved directly into a base-structure used by each driver. The code was explicitly checking runtime.GOOS instead of portably using net.Interfaces() anyways. Updated driver_mock to support the new addressing methods --- builder/vmware/common/driver.go | 250 ++++- builder/vmware/common/driver_fusion5.go | 11 +- builder/vmware/common/driver_mock.go | 60 ++ builder/vmware/common/driver_parser.go | 974 ++++++++++++++++++ builder/vmware/common/driver_player5.go | 24 +- .../vmware/common/driver_player5_windows.go | 25 + builder/vmware/common/driver_workstation10.go | 1 + builder/vmware/common/driver_workstation9.go | 27 +- .../common/driver_workstation9_windows.go | 8 + .../vmware/common/driver_workstation_unix.go | 8 + builder/vmware/common/guest_ip.go | 90 -- builder/vmware/common/guest_ip_test.go | 82 -- builder/vmware/common/host_ip.go | 7 - .../vmware/common/host_ip_ifconfig_test.go | 11 - builder/vmware/common/host_ip_vmnetnatconf.go | 65 -- .../common/host_ip_vmnetnatconf_test.go | 11 - builder/vmware/common/ssh.go | 24 +- .../vmware/common/step_type_boot_command.go | 13 +- builder/vmware/iso/builder.go | 32 + builder/vmware/iso/driver_esx5.go | 11 +- builder/vmware/iso/step_create_vmx.go | 242 ++++- builder/vmware/vmx/step_clone_vmx.go | 10 + 22 files changed, 1648 insertions(+), 338 deletions(-) create mode 100644 builder/vmware/common/driver_parser.go delete mode 100644 builder/vmware/common/guest_ip.go delete mode 100644 builder/vmware/common/guest_ip_test.go delete mode 100644 builder/vmware/common/host_ip.go delete mode 100644 builder/vmware/common/host_ip_ifconfig_test.go delete mode 100644 builder/vmware/common/host_ip_vmnetnatconf.go delete mode 100644 builder/vmware/common/host_ip_vmnetnatconf_test.go diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index d5f8b44f4..1098e591f 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -1,14 +1,19 @@ package common import ( + "errors" "bytes" "fmt" "log" + "os" "os/exec" + "io/ioutil" "regexp" "runtime" "strconv" "strings" + "time" + "net" "github.com/hashicorp/packer/helper/multistep" ) @@ -29,10 +34,6 @@ type Driver interface { // Checks if the VMX file at the given path is running. IsRunning(string) (bool, error) - // CommHost returns the host address for the VM that is being - // managed by this driver. - CommHost(multistep.StateBag) (string, error) - // Start starts a VM specified by the path to the VMX given. Start(string, bool) error @@ -49,14 +50,32 @@ type Driver interface { // Attach the VMware tools ISO ToolsInstall() error - // Get the path to the DHCP leases file for the given device. - DhcpLeasesPath(string) string - // Verify checks to make sure that this driver should function // properly. This should check that all the files it will use // appear to exist and so on. If everything is okay, this doesn't - // return an error. Otherwise, this returns an error. + // return an error. Otherwise, this returns an error. Each vmware + // driver should assign the VmwareMachine callback functions for locating + // paths within this function. Verify() error + + /// This is to establish a connection to the guest + CommHost(multistep.StateBag) (string, error) + + /// These methods are generally implemented by the VmwareDriver + /// structure within this file. A driver implementation can + /// reimplement these, though, if it wants. + + // Get the guest hw address for the vm + GuestAddress(multistep.StateBag) (string, error) + + // Get the guest ip address for the vm + GuestIP(multistep.StateBag) (string, error) + + // Get the host hw address for the vm + HostAddress(multistep.StateBag) (string, error) + + // Get the host ip address for the vm + HostIP(multistep.StateBag) (string, error) } // NewDriver returns a new driver implementation for this operating @@ -192,3 +211,218 @@ func compareVersions(versionFound string, versionWanted string, product string) return nil } + +// helper functions that read configuration information from a file +func readNetmapConfig(path string) (NetworkMap,error) { + fd,err := os.Open(path) + if err != nil { return nil, err } + defer fd.Close() + return ReadNetworkMap(fd) +} + +func readDhcpConfig(path string) (DhcpConfiguration,error) { + fd,err := os.Open(path) + if err != nil { return nil, err } + defer fd.Close() + return ReadDhcpConfiguration(fd) +} + +// This VmwareDriver is a base class that contains default methods +// that a Driver can use or implement themselves. +type VmwareDriver struct { + /// These methods define paths that are utilized by the driver + /// A driver must overload these in order to point to the correct + /// files so that the address detection (ip and ethernet) machinery + /// works. + DhcpLeasesPath func(string) string + VmnetnatConfPath func() string + DhcpConfPath func() string + NetmapConfPath func() string +} + +func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string,error) { + vmxPath := state.Get("vmx_path").(string) + + log.Println("Lookup up IP information...") + f, err := os.Open(vmxPath) + if err != nil { + return "", err + } + defer f.Close() + + vmxBytes, err := ioutil.ReadAll(f) + if err != nil { + return "", err + } + vmxData := ParseVMX(string(vmxBytes)) + + var ok bool + macAddress := "" + if macAddress, ok = vmxData["ethernet0.address"]; !ok || macAddress == "" { + if macAddress, ok = vmxData["ethernet0.generatedaddress"]; !ok || macAddress == "" { + return "", errors.New("couldn't find MAC address in VMX") + } + } + + res,err := net.ParseMAC(macAddress) + if err != nil { return "", err } + + return res.String(),nil +} + +func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) { + + // read netmap config + pathNetmap := d.NetmapConfPath() + if _, err := os.Stat(pathNetmap); err != nil { + return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) + } + netmap,err := readNetmapConfig(pathNetmap) + if err != nil { return "",err } + + // convert the stashed network to a device + network := state.Get("vmnetwork").(string) + device,err := netmap.NameIntoDevice(network) + if err != nil { return "", err } + + // figure out our MAC address for looking up the guest address + MACAddress,err := d.GuestAddress(state) + if err != nil { return "", err } + + // figure out the correct dhcp leases + dhcpLeasesPath := d.DhcpLeasesPath(device) + log.Printf("DHCP leases path: %s", dhcpLeasesPath) + if dhcpLeasesPath == "" { + return "", errors.New("no DHCP leases path found.") + } + + // open up the lease and read its contents + fh, err := os.Open(dhcpLeasesPath) + if err != nil { + return "", err + } + defer fh.Close() + + dhcpBytes, err := ioutil.ReadAll(fh) + if err != nil { + return "", err + } + + // start grepping through the file looking for fields that we care about + var lastIp string + var lastLeaseEnd time.Time + + var curIp string + var curLeaseEnd time.Time + + ipLineRe := regexp.MustCompile(`^lease (.+?) {$`) + endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`) + macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) + + for _, line := range strings.Split(string(dhcpBytes), "\n") { + // Need to trim off CR character when running in windows + line = strings.TrimRight(line, "\r") + + matches := ipLineRe.FindStringSubmatch(line) + if matches != nil { + lastIp = matches[1] + continue + } + + matches = endTimeLineRe.FindStringSubmatch(line) + if matches != nil { + lastLeaseEnd, _ = time.Parse("2006/01/02 15:04:05", matches[1]) + continue + } + + // If the mac address matches and this lease ends farther in the + // future than the last match we might have, then choose it. + matches = macLineRe.FindStringSubmatch(line) + if matches != nil && strings.EqualFold(matches[1], MACAddress) && curLeaseEnd.Before(lastLeaseEnd) { + curIp = lastIp + curLeaseEnd = lastLeaseEnd + } + } + if curIp == "" { + return "", fmt.Errorf("IP not found for MAC %s in DHCP leases at %s", MACAddress, dhcpLeasesPath) + } + return curIp, nil +} + +func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { + + // parse network<->device mapping + pathNetmap := d.NetmapConfPath() + if _, err := os.Stat(pathNetmap); err != nil { + return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) + } + netmap,err := readNetmapConfig(pathNetmap) + if err != nil { return "",err } + + // parse dhcpd configuration + pathDhcpConfig := d.DhcpConfPath() + if _, err := os.Stat(pathDhcpConfig); err != nil { + return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) + } + config,err := readDhcpConfig(pathDhcpConfig) + if err != nil { return "",err } + + // convert network to name + network := state.Get("vmnetwork").(string) + device,err := netmap.NameIntoDevice(network) + if err != nil { return "", err } + + // find the entry configured in the dhcpd + interfaceConfig,err := config.HostByName(device) + if err != nil { return "", err } + + // finally grab the hardware address + address,err := interfaceConfig.Hardware() + if err == nil { return address.String(), nil } + + // we didn't find it, so search through our interfaces for the device name + interfaceList,err := net.Interfaces() + if err == nil { return "", err } + + names := make([]string, 0) + for _,intf := range interfaceList { + if strings.HasSuffix( strings.ToLower(intf.Name), device ) { + return intf.HardwareAddr.String(),nil + } + names = append(names, intf.Name) + } + return "",fmt.Errorf("Unable to find device %s : %v", device, names) +} + +func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { + + // parse network<->device mapping + pathNetmap := d.NetmapConfPath() + if _, err := os.Stat(pathNetmap); err != nil { + return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) + } + netmap,err := readNetmapConfig(pathNetmap) + if err != nil { return "",err } + + // parse dhcpd configuration + pathDhcpConfig := d.DhcpConfPath() + if _, err := os.Stat(pathDhcpConfig); err != nil { + return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) + } + config,err := readDhcpConfig(pathDhcpConfig) + if err != nil { return "",err } + + // convert network to name + network := state.Get("vmnetwork").(string) + device,err := netmap.NameIntoDevice(network) + if err != nil { return "", err } + + // find the entry configured in the dhcpd + interfaceConfig,err := config.HostByName(device) + if err != nil { return "", err } + + address,err := interfaceConfig.IP4() + if err != nil { return "", err } + + return address.String(),nil +} diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index 9545d3e81..4bc5ae301 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -14,6 +14,8 @@ import ( // Fusion5Driver is a driver that can run VMware Fusion 5. type Fusion5Driver struct { + VmwareDriver + // This is the path to the "VMware Fusion.app" AppPath string @@ -139,6 +141,11 @@ func (d *Fusion5Driver) Verify() error { return err } + // default paths + d.VmwareDriver.DhcpLeasesPath = func(device string) string { + return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases" + } + return nil } @@ -158,10 +165,6 @@ func (d *Fusion5Driver) ToolsInstall() error { return nil } -func (d *Fusion5Driver) DhcpLeasesPath(device string) string { - return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases" -} - const fusionSuppressPlist = `<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 9291be976..15e006403 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -34,6 +34,26 @@ type DriverMock struct { CommHostResult string CommHostErr error + HostAddressCalled bool + HostAddressState multistep.StateBag + HostAddressResult string + HostAddressErr error + + HostIPCalled bool + HostIPState multistep.StateBag + HostIPResult string + HostIPErr error + + GuestAddressCalled bool + GuestAddressState multistep.StateBag + GuestAddressResult string + GuestAddressErr error + + GuestIPCalled bool + GuestIPState multistep.StateBag + GuestIPResult string + GuestIPErr error + StartCalled bool StartPath string StartHeadless bool @@ -58,6 +78,12 @@ type DriverMock struct { DhcpLeasesPathDevice string DhcpLeasesPathResult string + NetmapPathCalled bool + NetmapPathResult string + + DhcpConfPathCalled bool + DhcpConfPathResult string + VerifyCalled bool VerifyErr error } @@ -98,6 +124,30 @@ func (d *DriverMock) CommHost(state multistep.StateBag) (string, error) { return d.CommHostResult, d.CommHostErr } +func (d *DriverMock) HostAddress(state multistep.StateBag) (string, error) { + d.HostAddressCalled = true + d.HostAddressState = state + return d.HostAddressResult, d.HostAddressErr +} + +func (d *DriverMock) HostIP(state multistep.StateBag) (string, error) { + d.HostIPCalled = true + d.HostIPState = state + return d.HostIPResult, d.HostIPErr +} + +func (d *DriverMock) GuestAddress(state multistep.StateBag) (string, error) { + d.GuestAddressCalled = true + d.GuestAddressState = state + return d.GuestAddressResult, d.GuestAddressErr +} + +func (d *DriverMock) GuestIP(state multistep.StateBag) (string, error) { + d.GuestIPCalled = true + d.GuestIPState = state + return d.GuestIPResult, d.GuestIPErr +} + func (d *DriverMock) Start(path string, headless bool) error { d.StartCalled = true d.StartPath = path @@ -134,6 +184,16 @@ func (d *DriverMock) DhcpLeasesPath(device string) string { return d.DhcpLeasesPathResult } +func (d *DriverMock) NetmapPath(device string) string { + d.NetmapPathCalled = true + return d.NetmapPathResult +} + +func (d *DriverMock) DhcpConfPath(device string) string { + d.DhcpConfPathCalled = true + return d.DhcpConfPathResult +} + func (d *DriverMock) Verify() error { d.VerifyCalled = true return d.VerifyErr diff --git a/builder/vmware/common/driver_parser.go b/builder/vmware/common/driver_parser.go new file mode 100644 index 000000000..38470eb5b --- /dev/null +++ b/builder/vmware/common/driver_parser.go @@ -0,0 +1,974 @@ +package common +import ( + "fmt" + "os" + "io" + "strings" + "strconv" + "net" + "sort" +) + +type sentinelSignaller chan struct{} + +/** low-level parsing */ +// strip the comments and extraneous newlines from a byte channel +func uncomment(eof sentinelSignaller, in <-chan byte) chan byte { + out := make(chan byte) + + go func(in <-chan byte, out chan byte) { + var endofline bool + for stillReading := true; stillReading; { + select { + case <-eof: + stillReading = false + case ch := <-in: + switch ch { + case '#': + endofline = true + case '\n': + if endofline { endofline = false } + } + if !endofline { out <- ch } + } + } + }(in, out) + return out +} + +// convert a byte channel into a channel of pseudo-tokens +func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) chan string { + var ch byte + var state string + var quote bool + + out := make(chan string) + go func(out chan string) { + for stillReading := true; stillReading; { + select { + case <-eof: + stillReading = false + + case ch = <-in: + if quote { + if ch == '"' { + out <- state + string(ch) + state,quote = "",false + continue + } + state += string(ch) + continue + } + + switch ch { + case '"': + quote = true + state += string(ch) + continue + + case '\r': + fallthrough + case '\n': + fallthrough + case '\t': + fallthrough + case ' ': + if len(state) == 0 { continue } + out <- state + state = "" + + case '{': fallthrough + case '}': fallthrough + case ';': + if len(state) > 0 { out <- state } + out <- string(ch) + state = "" + + default: + state += string(ch) + } + } + } + if len(state) > 0 { out <- state } + }(out) + return out +} + +/** mid-level parsing */ +type tkParameter struct { + name string + operand []string +} +func (e *tkParameter) String() string { + var values []string + for _,val := range e.operand { + values = append(values, val) + } + return fmt.Sprintf("%s [%s]", e.name, strings.Join(values, ",")) +} + +type tkGroup struct { + parent *tkGroup + id tkParameter + + groups []*tkGroup + params []tkParameter +} +func (e *tkGroup) String() string { + var id []string + + id = append(id, e.id.name) + for _,val := range e.id.operand { + id = append(id, val) + } + + var config []string + for _,val := range e.params { + config = append(config, val.String()) + } + return fmt.Sprintf("%s {\n%s\n}", strings.Join(id, " "), strings.Join(config, "\n")) +} + +// convert a channel of pseudo-tokens into an tkParameter struct +func parseTokenParameter(in chan string) tkParameter { + var result tkParameter + for { + token := <-in + if result.name == "" { + result.name = token + continue + } + switch token { + case "{": fallthrough + case "}": fallthrough + case ";": goto leave + default: + result.operand = append(result.operand, token) + } + } +leave: + return result +} + +// convert a channel of pseudo-tokens into an tkGroup tree */ +func parseDhcpConfig(eof sentinelSignaller, in chan string) (tkGroup,error) { + var tokens []string + var result tkGroup + + toParameter := func(tokens []string) tkParameter { + out := make(chan string) + go func(out chan string){ + for _,v := range tokens { out <- v } + out <- ";" + }(out) + return parseTokenParameter(out) + } + + for stillReading,currentgroup := true,&result; stillReading; { + select { + case <-eof: + stillReading = false + + case tk := <-in: + switch tk { + case "{": + grp := &tkGroup{parent:currentgroup} + grp.id = toParameter(tokens) + currentgroup.groups = append(currentgroup.groups, grp) + currentgroup = grp + case "}": + if currentgroup.parent == nil { + return tkGroup{}, fmt.Errorf("Unable to close the global declaration") + } + if len(tokens) > 0 { + return tkGroup{}, fmt.Errorf("List of tokens was left unterminated : %v", tokens) + } + currentgroup = currentgroup.parent + case ";": + arg := toParameter(tokens) + currentgroup.params = append(currentgroup.params, arg) + default: + tokens = append(tokens, tk) + continue + } + tokens = []string{} + } + } + return result,nil +} + +func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string { + var ch byte + var state string + var quote bool + var lastnewline bool + + out := make(chan string) + go func(out chan string) { + for stillReading := true; stillReading; { + select { + case <-eof: + stillReading = false + + case ch = <-in: + if quote { + if ch == '"' { + out <- state + string(ch) + state,quote = "",false + continue + } + state += string(ch) + continue + } + + switch ch { + case '"': + quote = true + state += string(ch) + continue + + case '\r': + fallthrough + case '\t': + fallthrough + case ' ': + if len(state) == 0 { continue } + out <- state + state = "" + + case '\n': + if lastnewline { continue } + if len(state) > 0 { out <- state } + out <- string(ch) + state = "" + lastnewline = true + continue + + case '.': fallthrough + case '=': + if len(state) > 0 { out <- state } + out <- string(ch) + state = "" + + default: + state += string(ch) + } + lastnewline = false + } + } + if len(state) > 0 { out <- state } + }(out) + return out +} + +func parseNetworkMapConfig(eof sentinelSignaller, in chan string) (NetworkMap,error) { + var unsorted map[string]map[string]string + var state []string + + addResult := func(network string, attribute string, value string) error { + _,ok := unsorted[network] + if !ok { unsorted[network] = make(map[string]string) } + + val,err := strconv.Unquote(value) + if err != nil { return err } + + current := unsorted[network] + current[attribute] = val + return nil + } + + stillReading := true + for unsorted = make(map[string]map[string]string); stillReading; { + select { + case <-eof: + if len(state) == 3 { + err := addResult(state[0], state[1], state[2]) + if err != nil { return nil,err } + } + stillReading = false + case tk := <-in: + switch tk { + case ".": + if len(state) != 1 { return nil,fmt.Errorf("Missing network index") } + case "=": + if len(state) != 2 { return nil,fmt.Errorf("Assignment to empty attribute") } + case "\n": + if len(state) == 0 { continue } + if len(state) != 3 { return nil,fmt.Errorf("Invalid attribute assignment : %v", state) } + err := addResult(state[0], state[1], state[2]) + if err != nil { return nil,err } + state = make([]string, 0) + default: + state = append(state, tk) + } + } + } + result := make([]map[string]string, 0) + var keys []string + for k := range unsorted { keys = append(keys, k) } + sort.Strings(keys) + for _,k := range keys { + result = append(result, unsorted[k]) + } + return result,nil +} + +/** higher-level parsing */ +/// parameters +type pParameter interface { repr() string } + +type pParameterInclude struct { + filename string +} +func (e pParameterInclude) repr() string { return fmt.Sprintf("include-file:filename=%s",e.filename) } + +type pParameterOption struct { + name string + value string +} +func (e pParameterOption) repr() string { return fmt.Sprintf("option:%s=%s",e.name,e.value) } + +// allow some-kind-of-something +type pParameterGrant struct { + verb string // allow,deny,ignore + attribute string +} +func (e pParameterGrant) repr() string { return fmt.Sprintf("grant:%s,%s",e.verb,e.attribute) } + +type pParameterAddress4 []string +func (e pParameterAddress4) repr() string { + return fmt.Sprintf("fixed-address4:%s",strings.Join(e,",")) +} + +type pParameterAddress6 []string +func (e pParameterAddress6) repr() string { + return fmt.Sprintf("fixed-address6:%s",strings.Join(e,",")) +} + +// hardware address 00:00:00:00:00:00 +type pParameterHardware struct { + class string + address []byte +} +func (e pParameterHardware) repr() string { + res := make([]string, 0) + for _,v := range e.address { + res = append(res, fmt.Sprintf("%02x",v)) + } + return fmt.Sprintf("hardware-address:%s[%s]",e.class,strings.Join(res,":")) +} + +type pParameterBoolean struct { + parameter string + truancy bool +} +func (e pParameterBoolean) repr() string { return fmt.Sprintf("boolean:%s=%s",e.parameter,e.truancy) } + +type pParameterClientMatch struct { + name string + data string +} +func (e pParameterClientMatch) repr() string { return fmt.Sprintf("match-client:%s=%s",e.name,e.data) } + +// range 127.0.0.1 127.0.0.255 +type pParameterRange4 struct { + min net.IP + max net.IP +} +func (e pParameterRange4) repr() string { return fmt.Sprintf("range4:%s-%s",e.min.String(),e.max.String()) } + +type pParameterRange6 struct { + min net.IP + max net.IP +} +func (e pParameterRange6) repr() string { return fmt.Sprintf("range6:%s-%s",e.min.String(),e.max.String()) } + +type pParameterPrefix6 struct { + min net.IP + max net.IP + bits int +} +func (e pParameterPrefix6) repr() string { return fmt.Sprintf("prefix6:/%d:%s-%s",e.bits,e.min.String(),e.max.String()) } + +// some-kind-of-parameter 1024 +type pParameterOther struct { + parameter string + value string +} +func (e pParameterOther) repr() string { return fmt.Sprintf("parameter:%s=%s",e.parameter,e.value) } + +type pParameterExpression struct { + parameter string + expression string +} +func (e pParameterExpression) repr() string { return fmt.Sprintf("parameter-expression:%s=\"%s\"",e.parameter,e.expression) } + +type pDeclarationIdentifier interface { repr() string } + +type pDeclaration struct { + id pDeclarationIdentifier + parent *pDeclaration + parameters []pParameter + declarations []pDeclaration +} + +func (e *pDeclaration) short() string { + return e.id.repr() +} + +func (e *pDeclaration) repr() string { + res := e.short() + + var parameters []string + for _,v := range e.parameters { + parameters = append(parameters, v.repr()) + } + + var groups []string + for _,v := range e.declarations { + groups = append(groups, fmt.Sprintf("-> %s",v.short())) + } + + if e.parent != nil { + res = fmt.Sprintf("%s parent:%s",res,e.parent.short()) + } + return fmt.Sprintf("%s\n%s\n%s\n", res, strings.Join(parameters,"\n"), strings.Join(groups,"\n")) +} + +type pDeclarationGlobal struct {} +func (e pDeclarationGlobal) repr() string { return fmt.Sprintf("{global}") } + +type pDeclarationShared struct { name string } +func (e pDeclarationShared) repr() string { return fmt.Sprintf("{shared-network %s}", e.name) } + +type pDeclarationSubnet4 struct { net.IPNet } +func (e pDeclarationSubnet4) repr() string { return fmt.Sprintf("{subnet4 %s}", e.String()) } + +type pDeclarationSubnet6 struct { net.IPNet } +func (e pDeclarationSubnet6) repr() string { return fmt.Sprintf("{subnet6 %s}", e.String()) } + +type pDeclarationHost struct { name string } +func (e pDeclarationHost) repr() string { return fmt.Sprintf("{host name:%s}", e.name) } + +type pDeclarationPool struct {} +func (e pDeclarationPool) repr() string { return fmt.Sprintf("{pool}") } + +type pDeclarationGroup struct {} +func (e pDeclarationGroup) repr() string { return fmt.Sprintf("{group}") } + +type pDeclarationClass struct { name string } +func (e pDeclarationClass) repr() string { return fmt.Sprintf("{class}") } + +/** parsers */ +func parseParameter(val tkParameter) (pParameter,error) { + switch val.name { + case "include": + if len(val.operand) != 2 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterInclude : %v",val.operand) + } + name := val.operand[0] + return pParameterInclude{filename: name},nil + + case "option": + if len(val.operand) != 2 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterOption : %v",val.operand) + } + name, value := val.operand[0], val.operand[1] + return pParameterOption{name: name, value: value},nil + + case "allow": fallthrough + case "deny": fallthrough + case "ignore": + if len(val.operand) < 1 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterGrant : %v",val.operand) + } + attribute := strings.Join(val.operand," ") + return pParameterGrant{verb: strings.ToLower(val.name), attribute: attribute},nil + + case "range": + if len(val.operand) < 1 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterRange4 : %v",val.operand) + } + idxAddress := map[bool]int{true:1,false:0}[strings.ToLower(val.operand[0]) == "bootp"] + if len(val.operand) > 2 + idxAddress { + return nil,fmt.Errorf("Invalid number of parameters for pParameterRange : %v",val.operand) + } + if idxAddress + 1 > len(val.operand) { + res := net.ParseIP(val.operand[idxAddress]) + return pParameterRange4{min: res, max: res},nil + } + addr1 := net.ParseIP(val.operand[idxAddress]) + addr2 := net.ParseIP(val.operand[idxAddress+1]) + return pParameterRange4{min: addr1, max: addr2},nil + + case "range6": + if len(val.operand) == 1 { + address := val.operand[0] + if (strings.Contains(address, "/")) { + cidr := strings.SplitN(address, "/", 2) + if len(cidr) != 2 { return nil,fmt.Errorf("Unknown ipv6 format : %v", address) } + address := net.ParseIP(cidr[0]) + bits,err := strconv.Atoi(cidr[1]) + if err != nil { return nil,err } + mask := net.CIDRMask(bits, net.IPv6len*8) + + // figure out the network address + network := address.Mask(mask) + + // make a broadcast address + broadcast := network + networkSize,totalSize := mask.Size() + hostSize := totalSize-networkSize + for i := networkSize / 8; i < totalSize / 8; i++ { + broadcast[i] = byte(0xff) + } + octetIndex := network[networkSize / 8] + bitsLeft := (uint32)(hostSize%8) + broadcast[octetIndex] = network[octetIndex] | ((1<<bitsLeft)-1) + + // FIXME: check that the broadcast address was made correctly + return pParameterRange6{min: network, max: broadcast},nil + } + res := net.ParseIP(address) + return pParameterRange6{min: res, max:res},nil + } + if len(val.operand) == 2 { + addr := net.ParseIP(val.operand[0]) + if strings.ToLower(val.operand[1]) == "temporary" { + return pParameterRange6{min: addr, max: addr},nil + } + other := net.ParseIP(val.operand[1]) + return pParameterRange6{min: addr, max: other},nil + } + return nil,fmt.Errorf("Invalid number of parameters for pParameterRange6 : %v",val.operand) + + case "prefix6": + if len(val.operand) != 3 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterRange6 : %v",val.operand) + } + bits,err := strconv.Atoi(val.operand[2]) + if err != nil { + return nil,fmt.Errorf("Invalid bits for pParameterPrefix6 : %v",val.operand[2]) + } + minaddr := net.ParseIP(val.operand[0]) + maxaddr := net.ParseIP(val.operand[1]) + return pParameterPrefix6{min: minaddr, max: maxaddr, bits:bits},nil + + case "hardware": + if len(val.operand) != 2 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterHardware : %v",val.operand) + } + class := val.operand[0] + octets := strings.Split(val.operand[1], ":") + address := make([]byte, 0) + for _,v := range octets { + b,err := strconv.ParseInt(v, 16, 0) + if err != nil { return nil,err } + address = append(address, byte(b)) + } + return pParameterHardware{class: class, address: address},nil + + case "fixed-address": + ip4addrs := make(pParameterAddress4,len(val.operand)) + copy(ip4addrs, val.operand) + return ip4addrs,nil + + case "fixed-address6": + ip6addrs := make(pParameterAddress6,len(val.operand)) + copy(ip6addrs, val.operand) + return ip6addrs,nil + + case "host-identifier": + if len(val.operand) != 3 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterClientMatch : %v",val.operand) + } + if val.operand[0] != "option" { + return nil,fmt.Errorf("Invalid match parameter : %v",val.operand[0]) + } + optionName := val.operand[1] + optionData := val.operand[2] + return pParameterClientMatch{name: optionName, data: optionData},nil + + default: + length := len(val.operand) + if length < 1 { + return pParameterBoolean{parameter: val.name, truancy: true},nil + } else if length > 1 { + if val.operand[0] == "=" { + return pParameterExpression{parameter: val.name, expression: strings.Join(val.operand[1:],"")},nil + } + } + if length != 1 { + return nil,fmt.Errorf("Invalid number of parameters for pParameterOther : %v",val.operand) + } + if strings.ToLower(val.name) == "not" { + return pParameterBoolean{parameter: val.operand[0], truancy: false},nil + } + return pParameterOther{parameter: val.name, value: val.operand[0]}, nil + } +} + +func parseTokenGroup(val tkGroup) (*pDeclaration,error) { + params := val.id.operand + switch val.id.name { + case "group": + return &pDeclaration{id:pDeclarationGroup{}},nil + + case "pool": + return &pDeclaration{id:pDeclarationPool{}},nil + + case "host": + if len(params) == 1 { + return &pDeclaration{id:pDeclarationHost{name: params[0]}},nil + } + + case "subnet": + if len(params) == 3 && strings.ToLower(params[1]) == "netmask" { + addr := make([]byte, 4) + for i,v := range strings.SplitN(params[2], ".", 4) { + res,err := strconv.ParseInt(v, 10, 0) + if err != nil { return nil,err } + addr[i] = byte(res) + } + oc1,oc2,oc3,oc4 := addr[0],addr[1],addr[2],addr[3] + if subnet,mask := net.ParseIP(params[0]),net.IPv4Mask(oc1,oc2,oc3,oc4); subnet != nil && mask != nil { + return &pDeclaration{id:pDeclarationSubnet4{net.IPNet{IP:subnet,Mask:mask}}},nil + } + } + case "subnet6": + if len(params) == 1 { + ip6 := strings.SplitN(params[0], "/", 2) + if len(ip6) == 2 && strings.Contains(ip6[0], ":") { + address := net.ParseIP(ip6[0]) + prefix,err := strconv.Atoi(ip6[1]) + if err != nil { return nil, err } + return &pDeclaration{id:pDeclarationSubnet6{net.IPNet{IP:address,Mask:net.CIDRMask(prefix, net.IPv6len*8)}}},nil + } + } + case "shared-network": + if len(params) == 1 { + return &pDeclaration{id:pDeclarationShared{name: params[0]}},nil + } + case "": + return &pDeclaration{id:pDeclarationGlobal{}},nil + } + return nil,fmt.Errorf("Invalid pDeclaration : %v : %v", val.id.name, params) +} + +func flattenDhcpConfig(root tkGroup) (*pDeclaration,error) { + var result *pDeclaration + result,err := parseTokenGroup(root) + if err != nil { return nil,err } + + for _,p := range root.params { + param,err := parseParameter(p) + if err != nil { return nil,err } + result.parameters = append(result.parameters, param) + } + for _,p := range root.groups { + group,err := flattenDhcpConfig(*p) + if err != nil { return nil,err } + group.parent = result + result.declarations = append(result.declarations, *group) + } + return result,nil +} + +/** reduce the tree into the things that we care about */ +type grant uint +const ( + ALLOW grant = iota + IGNORE grant = iota + DENY grant = iota +) +type configDeclaration struct { + id []pDeclarationIdentifier + composites []pDeclaration + + address []pParameter + + options map[string]string + grants map[string]grant + attributes map[string]bool + parameters map[string]string + expressions map[string]string + + hostid []pParameterClientMatch +} + +func createDeclaration(node pDeclaration) configDeclaration { + var hierarchy []pDeclaration + + for n := &node; n != nil; n = n.parent { + hierarchy = append(hierarchy, *n) + } + + var result configDeclaration + result.address = make([]pParameter, 0) + + result.options = make(map[string]string) + result.grants = make(map[string]grant) + result.attributes = make(map[string]bool) + result.parameters = make(map[string]string) + result.expressions = make(map[string]string) + + result.hostid = make([]pParameterClientMatch, 0) + + // walk from globals to pDeclaration collecting all parameters + for i := len(hierarchy)-1; i >= 0; i-- { + result.composites = append(result.composites, hierarchy[(len(hierarchy)-1) - i]) + result.id = append(result.id, hierarchy[(len(hierarchy)-1) - i].id) + + // update configDeclaration parameters + for _,p := range hierarchy[i].parameters { + switch p.(type) { + case pParameterOption: + result.options[p.(pParameterOption).name] = p.(pParameterOption).value + case pParameterGrant: + Grant := map[string]grant{"ignore":IGNORE, "allow":ALLOW, "deny":DENY} + result.grants[p.(pParameterGrant).attribute] = Grant[p.(pParameterGrant).verb] + case pParameterBoolean: + result.attributes[p.(pParameterBoolean).parameter] = p.(pParameterBoolean).truancy + case pParameterClientMatch: + result.hostid = append(result.hostid, p.(pParameterClientMatch)) + case pParameterExpression: + result.expressions[p.(pParameterExpression).parameter] = p.(pParameterExpression).expression + case pParameterOther: + result.parameters[p.(pParameterOther).parameter] = p.(pParameterOther).value + default: + result.address = append(result.address, p) + } + } + } + return result +} + +func (e *configDeclaration) repr() string { + var result []string + + var res []string + + res = make([]string, 0) + for _,v := range e.id { res = append(res, v.repr()) } + result = append(result, strings.Join(res, ",")) + + if len(e.address) > 0 { + res = make([]string, 0) + for _,v := range e.address { res = append(res, v.repr()) } + result = append(result, fmt.Sprintf("address : %v", strings.Join(res, ","))) + } + + if len(e.options) > 0 { result = append(result, fmt.Sprintf("options : %v", e.options)) } + if len(e.grants) > 0 { result = append(result, fmt.Sprintf("grants : %v", e.grants)) } + if len(e.attributes) > 0 { result = append(result, fmt.Sprintf("attributes : %v", e.attributes)) } + if len(e.parameters) > 0 { result = append(result, fmt.Sprintf("parameters : %v", e.parameters)) } + if len(e.expressions) > 0 { result = append(result, fmt.Sprintf("parameter-expressions : %v", e.expressions)) } + + if len(e.hostid) > 0 { + res = make([]string, 0) + for _,v := range e.hostid { res = append(res, v.repr()) } + result = append(result, fmt.Sprintf("hostid : %v", strings.Join(res, " "))) + } + return strings.Join(result, "\n") + "\n" +} + +func (e *configDeclaration) IP4() (net.IP,error) { + var result []string + for _,entry := range e.address { + switch entry.(type) { + case pParameterAddress4: + for _,s := range entry.(pParameterAddress4) { + result = append(result, s) + } + } + } + if len(result) > 1 { + return nil,fmt.Errorf("More than one address4 returned : %v", result) + } else if len(result) == 0 { + return nil,fmt.Errorf("No IP4 addresses found") + } + + if res := net.ParseIP(result[0]); res != nil { return res,nil } + res,err := net.ResolveIPAddr("ip4", result[0]) + if err != nil { return nil,err } + return res.IP,nil +} +func (e *configDeclaration) IP6() (net.IP,error) { + var result []string + for _,entry := range e.address { + switch entry.(type) { + case pParameterAddress6: + for _,s := range entry.(pParameterAddress6) { + result = append(result, s) + } + } + } + if len(result) > 1 { + return nil,fmt.Errorf("More than one address6 returned : %v", result) + } else if len(result) == 0 { + return nil,fmt.Errorf("No IP6 addresses found") + } + + if res := net.ParseIP(result[0]); res != nil { return res,nil } + res,err := net.ResolveIPAddr("ip6", result[0]) + if err != nil { return nil,err } + return res.IP,nil +} +func (e *configDeclaration) Hardware() (net.HardwareAddr,error) { + var result []pParameterHardware + for _,addr := range e.address { + switch addr.(type) { + case pParameterHardware: + result = append(result, addr.(pParameterHardware)) + } + } + if len(result) > 0 { + return nil,fmt.Errorf("More than one hardware address returned : %v", result) + } + res := make(net.HardwareAddr, 0) + for _,by := range result[0].address { + res = append(res, by) + } + return res,nil +} + +/*** Dhcp Configuration */ +type DhcpConfiguration []configDeclaration +func ReadDhcpConfiguration(fd *os.File) (DhcpConfiguration,error) { + fromfile,eof := consumeFile(fd) + uncommented := uncomment(eof, fromfile) + tokenized := tokenizeDhcpConfig(eof, uncommented) + parsetree,err := parseDhcpConfig(eof, tokenized) + if err != nil { return nil,err } + + global,err := flattenDhcpConfig(parsetree) + if err != nil { return nil,err } + + var walkDeclarations func(root pDeclaration, out chan*configDeclaration); + walkDeclarations = func(root pDeclaration, out chan*configDeclaration) { + res := createDeclaration(root) + out <- &res + for _,p := range root.declarations { + walkDeclarations(p, out) + } + } + + each := make(chan*configDeclaration) + go func(out chan*configDeclaration) { + walkDeclarations(*global, out) + out <- nil + }(each) + + var result DhcpConfiguration + for decl := <-each; decl != nil; decl = <-each { + result = append(result, *decl) + } + return result,nil +} + +func (e *DhcpConfiguration) Global() configDeclaration { + result := (*e)[0] + if len(result.id) != 1 { + panic(fmt.Errorf("Something that can't happen happened")) + } + return result +} + +func (e *DhcpConfiguration) SubnetByAddress(address net.IP) (configDeclaration,error) { + var result []configDeclaration + for _,entry := range *e { + switch entry.id[0].(type) { + case pDeclarationSubnet4: + id := entry.id[0].(pDeclarationSubnet4) + if id.Contains(address) { + result = append(result, entry) + } + case pDeclarationSubnet6: + id := entry.id[0].(pDeclarationSubnet6) + if id.Contains(address) { + result = append(result, entry) + } + } + } + if len(result) == 0 { + return configDeclaration{},fmt.Errorf("No network declarations containing %s found", address.String()) + } + if len(result) > 1 { + return configDeclaration{},fmt.Errorf("More than 1 network declaration found : %v", result) + } + return result[0],nil +} + +func (e *DhcpConfiguration) HostByName(host string) (configDeclaration,error) { + var result []configDeclaration + for _,entry := range *e { + switch entry.id[0].(type) { + case pDeclarationHost: + id := entry.id[0].(pDeclarationHost) + if strings.ToLower(id.name) == strings.ToLower(host) { + result = append(result, entry) + } + } + } + if len(result) == 0 { + return configDeclaration{},fmt.Errorf("No host declarations containing %s found", host) + } + if len(result) > 1 { + return configDeclaration{},fmt.Errorf("More than 1 host declaration found : %v", result) + } + return result[0],nil +} + +/*** Network Map */ +type NetworkMap []map[string]string +func ReadNetworkMap(fd *os.File) (NetworkMap,error) { + + fromfile,eof := consumeFile(fd) + uncommented := uncomment(eof,fromfile) + tokenized := tokenizeNetworkMapConfig(eof, uncommented) + + result,err := parseNetworkMapConfig(eof, tokenized) + if err != nil { return nil,err } + return result,nil +} + +func (e *NetworkMap) NameIntoDevice(name string) (string,error) { + for _,val := range *e { + if strings.ToLower(val["name"]) == strings.ToLower(name) { + return val["device"],nil + } + } + return "",fmt.Errorf("Network name not found : %v", name) +} +func (e *NetworkMap) DeviceIntoName(device string) (string,error) { + for _,val := range *e { + if strings.ToLower(val["device"]) == strings.ToLower(device) { + return val["name"],nil + } + } + return "",fmt.Errorf("Device name not found : %v", device) +} +func (e *NetworkMap) repr() string { + var result []string + for idx,val := range *e { + result = append(result, fmt.Sprintf("network%d.name = \"%s\"", idx, val["name"])) + result = append(result, fmt.Sprintf("network%d.device = \"%s\"", idx, val["device"])) + } + return strings.Join(result, "\n") +} + +/** main */ +func consumeFile(fd *os.File) (chan byte,sentinelSignaller) { + fromfile := make(chan byte) + eof := make(sentinelSignaller) + go func() { + b := make([]byte, 1) + for { + _,err := fd.Read(b) + if err == io.EOF { break } + fromfile <- b[0] + } + close(eof) + }() + return fromfile,eof +} diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 311e5019c..9dce9540c 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -14,6 +14,8 @@ import ( // Player5Driver is a driver that can run VMware Player 5 on Linux. type Player5Driver struct { + VmwareDriver + AppPath string VdiskManagerPath string QemuImgPath string @@ -181,6 +183,20 @@ func (d *Player5Driver) Verify() error { "One of these is required to configure disks for VMware Player.") } + // Assigning the path callbacks to VmwareDriver + d.VmwareDriver.DhcpLeasesPath = func(device string) string { + return playerDhcpLeasesPath(device) + } + d.VmwareDriver.VmnetnatConfPath = func() string { + return playerVmnetnatConfPath() + } + d.VmwareDriver.DhcpConfPath = func() string { + return playerVmDhcpConfPath() + } + d.VmwareDriver.NetmapConfPath = func() string { + return playerNetmapConfPath() + } + return nil } @@ -191,11 +207,3 @@ func (d *Player5Driver) ToolsIsoPath(flavor string) string { func (d *Player5Driver) ToolsInstall() error { return nil } - -func (d *Player5Driver) DhcpLeasesPath(device string) string { - return playerDhcpLeasesPath(device) -} - -func (d *Player5Driver) VmnetnatConfPath() string { - return playerVmnetnatConfPath() -} diff --git a/builder/vmware/common/driver_player5_windows.go b/builder/vmware/common/driver_player5_windows.go index e16d275db..6ca065792 100644 --- a/builder/vmware/common/driver_player5_windows.go +++ b/builder/vmware/common/driver_player5_windows.go @@ -65,6 +65,20 @@ func playerVmnetnatConfPath() string { return findFile("vmnetnat.conf", playerDataFilePaths()) } +func playerVmDhcpConfPath() string { + path, err := playerDhcpConfigPathRegistry() + if err != nil { + log.Printf("Error finding configuration in registry: %s", err) + } else if _, err := os.Stat(path); err == nil { + return path + } + return findFile("vmnetdhcp.conf", playerDataFilePaths()) +} + +func playerNetmapConfPath() string { + return findFile("netmap.conf", playerDataFilePaths()) +} + // This reads the VMware installation path from the Windows registry. func playerVMwareRoot() (s string, err error) { key := `SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\vmplayer.exe` @@ -87,7 +101,18 @@ func playerDhcpLeasesPathRegistry() (s string, err error) { log.Printf(`Unable to read registry key %s\%s`, key, subkey) return } + return normalizePath(s), nil +} +// This reads the VMware DHCP configuration path from the Windows registry. +func playerDhcpConfigPathRegistry() (s string, err error) { + key := "SYSTEM\\CurrentControlSet\\services\\VMnetDHCP\\Parameters" + subkey := "ConfFile" + s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) + if err != nil { + log.Printf(`Unable to read registry key %s\%s`, key, subkey) + return + } return normalizePath(s), nil } diff --git a/builder/vmware/common/driver_workstation10.go b/builder/vmware/common/driver_workstation10.go index 7e6ac8b8f..716717e39 100644 --- a/builder/vmware/common/driver_workstation10.go +++ b/builder/vmware/common/driver_workstation10.go @@ -33,3 +33,4 @@ func (d *Workstation10Driver) Verify() error { return workstationVerifyVersion(VMWARE_WS_VERSION) } + diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index d870a4cda..0c463a249 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -14,6 +14,8 @@ import ( // Workstation9Driver is a driver that can run VMware Workstation 9 type Workstation9Driver struct { + VmwareDriver + AppPath string VdiskManagerPath string VmrunPath string @@ -142,6 +144,23 @@ func (d *Workstation9Driver) Verify() error { return err } + // Assigning the path callbacks to VmwareDriver + d.VmwareDriver.DhcpLeasesPath = func(device string) string { + return workstationDhcpLeasesPath(device) + } + + d.VmwareDriver.VmnetnatConfPath = func() string { + return workstationVmnetnatConfPath() + } + + d.VmwareDriver.DhcpConfPath = func() string { + return workstationDhcpConfPath() + } + + d.VmwareDriver.NetmapConfPath = func() string { + return workstationNetmapConfPath() + } + return nil } @@ -152,11 +171,3 @@ func (d *Workstation9Driver) ToolsIsoPath(flavor string) string { func (d *Workstation9Driver) ToolsInstall() error { return nil } - -func (d *Workstation9Driver) DhcpLeasesPath(device string) string { - return workstationDhcpLeasesPath(device) -} - -func (d *Workstation9Driver) VmnetnatConfPath() string { - return workstationVmnetnatConfPath() -} diff --git a/builder/vmware/common/driver_workstation9_windows.go b/builder/vmware/common/driver_workstation9_windows.go index 17095badc..e69d5069f 100644 --- a/builder/vmware/common/driver_workstation9_windows.go +++ b/builder/vmware/common/driver_workstation9_windows.go @@ -63,6 +63,14 @@ func workstationVmnetnatConfPath() string { return findFile("vmnetnat.conf", workstationDataFilePaths()) } +func workstationNetmapConfPath() string { + return findFile("netmap.conf", workstationDataFilePaths()) +} + +func workstationDhcpConfPath() string { + return findFile("vmnetdhcp.conf", workstationDataFilePaths()) +} + // See http://blog.natefinch.com/2012/11/go-win-stuff.html // // This is used by workstationVMwareRoot in order to read some registry data. diff --git a/builder/vmware/common/driver_workstation_unix.go b/builder/vmware/common/driver_workstation_unix.go index 2931396a4..2ff94fd37 100644 --- a/builder/vmware/common/driver_workstation_unix.go +++ b/builder/vmware/common/driver_workstation_unix.go @@ -51,6 +51,14 @@ func workstationVmnetnatConfPath() string { return "" } +func workstationNetmapConfPath(device string) string { + return "" // FIXME +} + +func workstationDhcpConfPath(device string) string { + return "/etc/vmware/" + device + "/dhcpd/dhcpd.conf" +} + func workstationVerifyVersion(version string) error { if runtime.GOOS != "linux" { return fmt.Errorf("The VMware WS version %s driver is only supported on Linux, and Windows, at the moment. Your OS: %s", version, runtime.GOOS) diff --git a/builder/vmware/common/guest_ip.go b/builder/vmware/common/guest_ip.go deleted file mode 100644 index 25ca3b795..000000000 --- a/builder/vmware/common/guest_ip.go +++ /dev/null @@ -1,90 +0,0 @@ -package common - -import ( - "errors" - "fmt" - "io/ioutil" - "log" - "os" - "regexp" - "strings" - "time" -) - -// Interface to help find the IP address of a running virtual machine. -type GuestIPFinder interface { - GuestIP() (string, error) -} - -// DHCPLeaseGuestLookup looks up the IP address of a guest using DHCP -// lease information from the VMware network devices. -type DHCPLeaseGuestLookup struct { - // Driver that is being used (to find leases path) - Driver Driver - - // Device that the guest is connected to. - Device string - - // MAC address of the guest. - MACAddress string -} - -func (f *DHCPLeaseGuestLookup) GuestIP() (string, error) { - dhcpLeasesPath := f.Driver.DhcpLeasesPath(f.Device) - log.Printf("DHCP leases path: %s", dhcpLeasesPath) - if dhcpLeasesPath == "" { - return "", errors.New("no DHCP leases path found.") - } - - fh, err := os.Open(dhcpLeasesPath) - if err != nil { - return "", err - } - defer fh.Close() - - dhcpBytes, err := ioutil.ReadAll(fh) - if err != nil { - return "", err - } - - var lastIp string - var lastLeaseEnd time.Time - - var curIp string - var curLeaseEnd time.Time - - ipLineRe := regexp.MustCompile(`^lease (.+?) {$`) - endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`) - macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) - - for _, line := range strings.Split(string(dhcpBytes), "\n") { - // Need to trim off CR character when running in windows - line = strings.TrimRight(line, "\r") - - matches := ipLineRe.FindStringSubmatch(line) - if matches != nil { - lastIp = matches[1] - continue - } - - matches = endTimeLineRe.FindStringSubmatch(line) - if matches != nil { - lastLeaseEnd, _ = time.Parse("2006/01/02 15:04:05", matches[1]) - continue - } - - // If the mac address matches and this lease ends farther in the - // future than the last match we might have, then choose it. - matches = macLineRe.FindStringSubmatch(line) - if matches != nil && strings.EqualFold(matches[1], f.MACAddress) && curLeaseEnd.Before(lastLeaseEnd) { - curIp = lastIp - curLeaseEnd = lastLeaseEnd - } - } - - if curIp == "" { - return "", fmt.Errorf("IP not found for MAC %s in DHCP leases at %s", f.MACAddress, dhcpLeasesPath) - } - - return curIp, nil -} diff --git a/builder/vmware/common/guest_ip_test.go b/builder/vmware/common/guest_ip_test.go deleted file mode 100644 index fdd6b4c9c..000000000 --- a/builder/vmware/common/guest_ip_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package common - -import ( - "io/ioutil" - "os" - "testing" -) - -func TestDHCPLeaseGuestLookup_impl(t *testing.T) { - var _ GuestIPFinder = new(DHCPLeaseGuestLookup) -} - -func TestDHCPLeaseGuestLookup(t *testing.T) { - tf, err := ioutil.TempFile("", "packer") - if err != nil { - t.Fatalf("err: %s", err) - } - if _, err := tf.Write([]byte(testLeaseContents)); err != nil { - t.Fatalf("err: %s", err) - } - tf.Close() - defer os.Remove(tf.Name()) - - driver := new(DriverMock) - driver.DhcpLeasesPathResult = tf.Name() - - finder := &DHCPLeaseGuestLookup{ - Driver: driver, - Device: "vmnet8", - MACAddress: "00:0c:29:59:91:02", - } - - ip, err := finder.GuestIP() - if err != nil { - t.Fatalf("err: %s", err) - } - - if !driver.DhcpLeasesPathCalled { - t.Fatal("should ask for DHCP leases path") - } - if driver.DhcpLeasesPathDevice != "vmnet8" { - t.Fatal("should be vmnet8") - } - - if ip != "192.168.126.130" { - t.Fatalf("bad: %#v", ip) - } -} - -const testLeaseContents = ` -# All times in this file are in UTC (GMT), not your local timezone. This is -# not a bug, so please don't ask about it. There is no portable way to -# store leases in the local timezone, so please don't request this as a -# feature. If this is inconvenient or confusing to you, we sincerely -# apologize. Seriously, though - don't ask. -# The format of this file is documented in the dhcpd.leases(5) manual page. - -lease 192.168.126.129 { - starts 0 2013/09/15 23:58:51; - ends 1 2013/09/16 00:28:51; - hardware ethernet 00:0c:29:59:91:02; - client-hostname "precise64"; -} -lease 192.168.126.130 { - starts 2 2013/09/17 21:39:07; - ends 2 2013/09/17 22:09:07; - hardware ethernet 00:0c:29:59:91:02; - client-hostname "precise64"; -} -lease 192.168.126.128 { - starts 0 2013/09/15 20:09:59; - ends 0 2013/09/15 20:21:58; - hardware ethernet 00:0c:29:59:91:02; - client-hostname "precise64"; -} -lease 192.168.126.127 { - starts 0 2013/09/15 20:09:59; - ends 0 2013/09/15 20:21:58; - hardware ethernet 01:0c:29:59:91:02; - client-hostname "precise64"; - -` diff --git a/builder/vmware/common/host_ip.go b/builder/vmware/common/host_ip.go deleted file mode 100644 index f920043e7..000000000 --- a/builder/vmware/common/host_ip.go +++ /dev/null @@ -1,7 +0,0 @@ -package common - -// Interface to help find the host IP that is available from within -// the VMware virtual machines. -type HostIPFinder interface { - HostIP() (string, error) -} diff --git a/builder/vmware/common/host_ip_ifconfig_test.go b/builder/vmware/common/host_ip_ifconfig_test.go deleted file mode 100644 index a69104e69..000000000 --- a/builder/vmware/common/host_ip_ifconfig_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package common - -import "testing" - -func TestIfconfigIPFinder_Impl(t *testing.T) { - var raw interface{} - raw = &IfconfigIPFinder{} - if _, ok := raw.(HostIPFinder); !ok { - t.Fatalf("IfconfigIPFinder is not a host IP finder") - } -} diff --git a/builder/vmware/common/host_ip_vmnetnatconf.go b/builder/vmware/common/host_ip_vmnetnatconf.go deleted file mode 100644 index e07227a5e..000000000 --- a/builder/vmware/common/host_ip_vmnetnatconf.go +++ /dev/null @@ -1,65 +0,0 @@ -package common - -import ( - "bufio" - "errors" - "fmt" - "io" - "os" - "regexp" - "strings" -) - -// VMnetNatConfIPFinder finds the IP address of the host machine by -// retrieving the IP from the vmnetnat.conf. This isn't a full proof -// technique but so far it has not failed. -type VMnetNatConfIPFinder struct{} - -func (*VMnetNatConfIPFinder) HostIP() (string, error) { - driver := &Workstation9Driver{} - - vmnetnat := driver.VmnetnatConfPath() - if vmnetnat == "" { - return "", errors.New("Could not find NAT vmnet conf file") - } - - if _, err := os.Stat(vmnetnat); err != nil { - return "", fmt.Errorf("Could not find NAT vmnet conf file: %s", vmnetnat) - } - - f, err := os.Open(vmnetnat) - if err != nil { - return "", err - } - defer f.Close() - - ipRe := regexp.MustCompile(`^\s*ip\s*=\s*(.+?)\s*$`) - - r := bufio.NewReader(f) - for { - line, err := r.ReadString('\n') - if line != "" { - matches := ipRe.FindStringSubmatch(line) - if matches != nil { - ip := matches[1] - dotIndex := strings.LastIndex(ip, ".") - if dotIndex == -1 { - continue - } - - ip = ip[0:dotIndex] + ".1" - return ip, nil - } - } - - if err == io.EOF { - break - } - - if err != nil { - return "", err - } - } - - return "", errors.New("host IP not found in " + vmnetnat) -} diff --git a/builder/vmware/common/host_ip_vmnetnatconf_test.go b/builder/vmware/common/host_ip_vmnetnatconf_test.go deleted file mode 100644 index 9f3114a92..000000000 --- a/builder/vmware/common/host_ip_vmnetnatconf_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package common - -import "testing" - -func TestVMnetNatConfIPFinder_Impl(t *testing.T) { - var raw interface{} - raw = &VMnetNatConfIPFinder{} - if _, ok := raw.(HostIPFinder); !ok { - t.Fatalf("VMnetNatConfIPFinder is not a host IP finder") - } -} diff --git a/builder/vmware/common/ssh.go b/builder/vmware/common/ssh.go index 4e339edb9..e03f9b6bf 100644 --- a/builder/vmware/common/ssh.go +++ b/builder/vmware/common/ssh.go @@ -14,34 +14,12 @@ import ( func CommHost(config *SSHConfig) func(multistep.StateBag) (string, error) { return func(state multistep.StateBag) (string, error) { driver := state.Get("driver").(Driver) - vmxPath := state.Get("vmx_path").(string) if config.Comm.SSHHost != "" { return config.Comm.SSHHost, nil } - log.Println("Lookup up IP information...") - - vmxData, err := ReadVMX(vmxPath) - if err != nil { - return "", err - } - - var ok bool - macAddress := "" - if macAddress, ok = vmxData["ethernet0.address"]; !ok || macAddress == "" { - if macAddress, ok = vmxData["ethernet0.generatedaddress"]; !ok || macAddress == "" { - return "", errors.New("couldn't find MAC address in VMX") - } - } - - ipLookup := &DHCPLeaseGuestLookup{ - Driver: driver, - Device: "vmnet8", - MACAddress: macAddress, - } - - ipAddress, err := ipLookup.GuestIP() + ipAddress, err := driver.GuestIP(state) if err != nil { log.Printf("IP lookup failed: %s", err) return "", fmt.Errorf("IP lookup failed: %s", err) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 35e30c624..c169c59eb 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -64,7 +64,7 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m } // Connect to VNC - ui.Say("Connecting to VM via VNC") + ui.Say(fmt.Sprintf("Connecting to VM via VNC (%s:%d)", vncIp, vncPort)) nc, err := net.Dial("tcp", fmt.Sprintf("%s:%d", vncIp, vncPort)) if err != nil { err := fmt.Errorf("Error connecting to VNC: %s", err) @@ -94,16 +94,7 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m log.Printf("Connected to VNC desktop: %s", c.DesktopName) // Determine the host IP - var ipFinder HostIPFinder - if finder, ok := driver.(HostIPFinder); ok { - ipFinder = finder - } else if runtime.GOOS == "windows" { - ipFinder = new(VMnetNatConfIPFinder) - } else { - ipFinder = &IfconfigIPFinder{Device: "vmnet8"} - } - - hostIP, err := ipFinder.HostIP() + hostIP, err := driver.HostIP(state) if err != nil { err := fmt.Errorf("Error detecting host IP: %s", err) state.Put("error", err) diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 1d2a29ac5..2cce8fd3c 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -38,12 +38,31 @@ type Config struct { vmwcommon.ToolsConfig `mapstructure:",squash"` vmwcommon.VMXConfig `mapstructure:",squash"` + // disk drives AdditionalDiskSize []uint `mapstructure:"disk_additional_size"` DiskName string `mapstructure:"vmdk_name"` DiskSize uint `mapstructure:"disk_size"` DiskTypeId string `mapstructure:"disk_type_id"` Format string `mapstructure:"format"` + + // platform information GuestOSType string `mapstructure:"guest_os_type"` + Version string `mapstructure:"version"` + VMName string `mapstructure:"vm_name"` + + // Network type + Network string `mapstructure:"network"` + + // device presence + Sound bool `mapstructure:"sound"` + USB bool `mapstructure:"usb"` + + // communication ports + Serial string `mapstructure:"serial"` + Parallel string `mapstructure:"parallel"` + + // booting a guest + BootCommand []string `mapstructure:"boot_command"` KeepRegistered bool `mapstructure:"keep_registered"` OVFToolOptions []string `mapstructure:"ovftool_options"` SkipCompaction bool `mapstructure:"skip_compaction"` @@ -53,6 +72,7 @@ type Config struct { VMXTemplatePath string `mapstructure:"vmx_template_path"` Version string `mapstructure:"version"` + // remote vsphere RemoteType string `mapstructure:"remote_type"` RemoteDatastore string `mapstructure:"remote_datastore"` RemoteCacheDatastore string `mapstructure:"remote_cache_datastore"` @@ -158,6 +178,18 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } + if b.config.Network == "" { + b.config.Network = "nat" + } + + if !b.config.Sound { + b.config.Sound = false + } + + if !b.config.USB { + b.config.USB = false + } + // Remote configuration validation if b.config.RemoteType != "" { if b.config.RemoteHost == "" { diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index f30451c65..6df8271f6 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -18,12 +18,16 @@ import ( "github.com/hashicorp/packer/communicator/ssh" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + vmwcommon "github.com/mitchellh/packer/builder/vmware/common" gossh "golang.org/x/crypto/ssh" ) // ESX5 driver talks to an ESXi5 hypervisor remotely over SSH to build // virtual machines. This driver can only manage one machine at a time. type ESX5Driver struct { + vmwcommon.VmwareDriver + Host string Port uint Username string @@ -143,10 +147,6 @@ func (d *ESX5Driver) ToolsInstall() error { return d.sh("vim-cmd", "vmsvc/tools.install", d.vmId) } -func (d *ESX5Driver) DhcpLeasesPath(string) string { - return "" -} - func (d *ESX5Driver) Verify() error { checks := []func() error{ d.connect, @@ -159,11 +159,10 @@ func (d *ESX5Driver) Verify() error { return err } } - return nil } -func (d *ESX5Driver) HostIP() (string, error) { +func (d *ESX5Driver) HostIP(multistep.StateBag) (string, error) { conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", d.Host, d.Port)) if err != nil { return "", err diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 029f2a31e..8e9f6cda0 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/helper/multistep" @@ -19,6 +20,21 @@ type vmxTemplateData struct { DiskName string ISOPath string Version string + + Network string + Sound_Present string + Usb_Present string + + Serial_Present string + Serial_Type string + Serial_Endpoint string + Serial_Host string + Serial_Yield string + Serial_Filename string + + Parallel_Present string + Parallel_Bidirectional string + Parallel_Filename string } type additionalDiskTemplateData struct { @@ -39,6 +55,121 @@ type stepCreateVMX struct { tempDir string } +/* serial conversions */ +type serialConfigPipe struct { + filename string + endpoint string + host string + yield string +} + +type serialConfigFile struct { + filename string +} + +type serialConfigDevice struct { + devicename string +} + +type serialUnion struct { + serialType interface{} + pipe *serialConfigPipe + file *serialConfigFile + device *serialConfigDevice +} + +func unformat_serial(config string) (*serialUnion,error) { + comptype := strings.SplitN(config, ":", 2) + if len(comptype) < 1 { + return nil,fmt.Errorf("Unexpected format for serial port: %s", config) + } + switch strings.ToUpper(comptype[0]) { + case "PIPE": + comp := strings.Split(comptype[1], ",") + if len(comp) < 3 || len(comp) > 4 { + return nil,fmt.Errorf("Unexpected format for serial port : pipe : %s", config) + } + if res := strings.ToLower(comp[1]); res != "client" || res != "server" { + return nil,fmt.Errorf("Unexpected format for serial port : pipe : endpoint : %s : %s", res, config) + } + if res := strings.ToLower(comp[2]); res != "app" || res != "vm" { + return nil,fmt.Errorf("Unexpected format for serial port : pipe : host : %s : %s", res, config) + } + res := &serialConfigPipe{ + filename : comp[0], + endpoint : comp[1], + host : map[string]string{"app":"TRUE","vm":"FALSE"}[strings.ToLower(comp[2])], + yield : "FALSE", + } + if len(comp) == 4 { + res.yield = strings.ToUpper(comp[3]) + } + if res.yield != "TRUE" || res.yield != "FALSE" { + return nil,fmt.Errorf("Unexpected format for serial port : pipe : yield : %s : %s", res.yield, config) + } + return &serialUnion{serialType:res, pipe:res},nil + + case "FILE": + res := &serialConfigFile{ filename : comptype[1] } + return &serialUnion{serialType:res, file:res},nil + + case "DEVICE": + res := new(serialConfigDevice) + res.devicename = map[bool]string{true:strings.ToUpper(comptype[1]), false:"COM1"}[len(comptype[1]) > 0] + return &serialUnion{serialType:res, device:res},nil + + default: + return nil,fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(comptype[0]), config) + } +} + +/* parallel port */ +type parallelUnion struct { + parallelType interface{} + file *parallelPortFile + device *parallelPortDevice +} +type parallelPortFile struct { + filename string +} +type parallelPortDevice struct { + bidirectional string + devicename string +} + +func unformat_parallel(config string) (*parallelUnion,error) { + comptype := strings.SplitN(config, ":", 2) + if len(comptype) < 1 { + return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) + } + switch strings.ToUpper(comptype[0]) { + case "FILE": + res := &parallelPortFile{ filename: comptype[1] } + return &parallelUnion{ parallelType:res, file: res},nil + case "DEVICE": + comp := strings.Split(comptype[1], ",") + if len(comp) < 1 || len(comp) > 2 { + return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) + } + res := new(parallelPortDevice) + res.bidirectional = "FALSE" + res.devicename = strings.ToUpper(comp[0]) + if len(comp) > 1 { + switch strings.ToUpper(comp[1]) { + case "BI": + res.bidirectional = "TRUE" + case "UNI": + res.bidirectional = "FALSE" + default: + return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(comp[0]), config) + } + } + return &parallelUnion{ parallelType:res, device: res},nil + } + return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) +} + +/* regular steps */ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) isoPath := state.Get("iso_path").(string) @@ -111,14 +242,90 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } } - ctx.Data = &vmxTemplateData{ + templateData := vmxTemplateData{ Name: config.VMName, GuestOS: config.GuestOSType, DiskName: config.DiskName, Version: config.Version, ISOPath: isoPath, + + Network: config.Network, + Sound_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.Sound)], + Usb_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.USB)], + + Serial_Present: "FALSE", + Parallel_Present: "FALSE", } + // store the network so that we can later figure out what ip address to bind to + state.Put("vmnetwork", config.Network) + + // check if serial port has been configured + if config.Serial != "" { + serial,err := unformat_serial(config.Serial) + if err != nil { + err := fmt.Errorf("Error procesing VMX template: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + templateData.Serial_Present = "TRUE" + templateData.Serial_Filename = "" + templateData.Serial_Yield = "" + templateData.Serial_Endpoint = "" + templateData.Serial_Host = "" + + switch serial.serialType.(type) { + case *serialConfigPipe: + templateData.Serial_Type = "pipe" + templateData.Serial_Endpoint = serial.pipe.endpoint + templateData.Serial_Host = serial.pipe.host + templateData.Serial_Yield = serial.pipe.yield + templateData.Serial_Filename = filepath.FromSlash(serial.pipe.filename) + case *serialConfigFile: + templateData.Serial_Type = "file" + templateData.Serial_Filename = filepath.FromSlash(serial.file.filename) + case *serialConfigDevice: + templateData.Serial_Type = "device" + templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename) + default: + err := fmt.Errorf("Error procesing VMX template: %v", serial) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + // check if parallel port has been configured + if config.Parallel != "" { + parallel,err := unformat_parallel(config.Parallel) + if err != nil { + err := fmt.Errorf("Error procesing VMX template: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + switch parallel.parallelType.(type) { + case *parallelPortFile: + templateData.Parallel_Present = "TRUE" + templateData.Parallel_Filename = filepath.FromSlash(parallel.file.filename) + case *parallelPortDevice: + templateData.Parallel_Present = "TRUE" + templateData.Parallel_Bidirectional = parallel.device.bidirectional + templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename) + default: + err := fmt.Errorf("Error procesing VMX template: %v", parallel) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + + ctx.Data = &templateData + + // render the .vmx template vmxContents, err := interpolate.Render(vmxTemplate, &ctx) if err != nil { err := fmt.Errorf("Error procesing VMX template: %s", err) @@ -176,7 +383,7 @@ ehci.pciSlotNumber = "34" ehci.present = "TRUE" ethernet0.addressType = "generated" ethernet0.bsdName = "en0" -ethernet0.connectionType = "nat" +ethernet0.connectionType = "{{ .Network }}" ethernet0.displayName = "Ethernet" ethernet0.linkStatePropagation.enable = "FALSE" ethernet0.pciSlotNumber = "33" @@ -227,11 +434,38 @@ scsi0.virtualDev = "lsilogic" scsi0:0.fileName = "{{ .DiskName }}.vmdk" scsi0:0.present = "TRUE" scsi0:0.redo = "" -sound.startConnected = "FALSE" + +// Sound +sound.startConnected = "{{ .Sound_Present }}" +sound.present = "{{ .Sound_Present }}" +sound.fileName = "-1" +sound.autodetect = "TRUE" + tools.syncTime = "TRUE" tools.upgrade.policy = "upgradeAtPowerCycle" + +// USB usb.pciSlotNumber = "32" -usb.present = "FALSE" +usb.present = "{{ .Usb_Present }}" +usb_xhci.present = "TRUE" + +// Serial +serial0.present = "{{ .Serial_Present }}" +serial0.startConnected = "{{ .Serial_Present }}" +serial0.fileName = "{{ .Serial_Filename }}" +serial0.autodetect = "TRUE" +serial0.fileType = "{{ .Serial_Type }}" +serial0.yieldOnMsrRead = "{{ .Serial_Yield }}" +serial0.pipe.endPoint = "{{ .Serial_Endpoint }}" +serial0.tryNoRxLoss = "{{ .Serial_Host }}" + +// Parallel +parallel0.present = "{{ .Parallel_Present }}" +parallel0.startConnected = "{{ .Parallel_Present }}" +parallel0.fileName = "{{ .Parallel_Filename }}" +parallel0.autodetect = "TRUE" +parallel0.bidirectional = "{{ .Parallel_Bidirectional }}" + virtualHW.productCompatibility = "hosted" virtualHW.version = "{{ .Version }}" vmci0.id = "1861462627" diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index f7874067c..bd644ca30 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -54,6 +54,16 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste return multistep.ActionHalt } + var networkType string + if _, ok := vmxData["ethernet0.connectionType"]; ok { + networkType = vmxData["ethernet0.connectionType"] + } + if networkType == "" { + networkType = "nat" + log.Printf("Defaulting to network type : nat") + } + + state.Put("vmnetwork", networkType) state.Put("full_disk_path", filepath.Join(s.OutputDir, diskName)) state.Put("vmx_path", vmxPath) return multistep.ActionContinue From 4225b3568ee87376272dda4fdcf3325eea49cc9e Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 5 Apr 2016 18:45:36 -0500 Subject: [PATCH 0553/1007] Fixed bad ORs and a bad fmtstring. --- builder/vmware/common/driver_parser.go | 2 +- builder/vmware/iso/step_create_vmx.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/vmware/common/driver_parser.go b/builder/vmware/common/driver_parser.go index 38470eb5b..7071e424d 100644 --- a/builder/vmware/common/driver_parser.go +++ b/builder/vmware/common/driver_parser.go @@ -362,7 +362,7 @@ type pParameterBoolean struct { parameter string truancy bool } -func (e pParameterBoolean) repr() string { return fmt.Sprintf("boolean:%s=%s",e.parameter,e.truancy) } +func (e pParameterBoolean) repr() string { return fmt.Sprintf("boolean:%s=%v",e.parameter,e.truancy) } type pParameterClientMatch struct { name string diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 8e9f6cda0..c1f4ea8f3 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -89,10 +89,10 @@ func unformat_serial(config string) (*serialUnion,error) { if len(comp) < 3 || len(comp) > 4 { return nil,fmt.Errorf("Unexpected format for serial port : pipe : %s", config) } - if res := strings.ToLower(comp[1]); res != "client" || res != "server" { + if res := strings.ToLower(comp[1]); res != "client" && res != "server" { return nil,fmt.Errorf("Unexpected format for serial port : pipe : endpoint : %s : %s", res, config) } - if res := strings.ToLower(comp[2]); res != "app" || res != "vm" { + if res := strings.ToLower(comp[2]); res != "app" && res != "vm" { return nil,fmt.Errorf("Unexpected format for serial port : pipe : host : %s : %s", res, config) } res := &serialConfigPipe{ @@ -104,7 +104,7 @@ func unformat_serial(config string) (*serialUnion,error) { if len(comp) == 4 { res.yield = strings.ToUpper(comp[3]) } - if res.yield != "TRUE" || res.yield != "FALSE" { + if res.yield != "TRUE" && res.yield != "FALSE" { return nil,fmt.Errorf("Unexpected format for serial port : pipe : yield : %s : %s", res.yield, config) } return &serialUnion{serialType:res, pipe:res},nil From 9b95ce0bc6ff4da69fdf91031e2e463fb049c455 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 5 Apr 2016 20:45:58 -0500 Subject: [PATCH 0554/1007] Completely forgot to support the unix paths in each of the drivers for the VMware builder. Fixed. --- builder/vmware/common/driver.go | 33 ++++++------ builder/vmware/common/driver_mock.go | 24 ++++++--- builder/vmware/common/driver_player5.go | 12 +++-- .../vmware/common/driver_player5_windows.go | 13 ++--- builder/vmware/common/driver_player_unix.go | 46 ++++++++++++++--- builder/vmware/common/driver_workstation9.go | 9 ++-- .../common/driver_workstation9_windows.go | 12 +++-- .../vmware/common/driver_workstation_unix.go | 51 ++++++++++++++----- 8 files changed, 136 insertions(+), 64 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 1098e591f..fa2cc0c03 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -235,8 +235,8 @@ type VmwareDriver struct { /// files so that the address detection (ip and ethernet) machinery /// works. DhcpLeasesPath func(string) string - VmnetnatConfPath func() string - DhcpConfPath func() string + DhcpConfPath func(string) string + VmnetnatConfPath func(string) string NetmapConfPath func() string } @@ -359,19 +359,20 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { netmap,err := readNetmapConfig(pathNetmap) if err != nil { return "",err } - // parse dhcpd configuration - pathDhcpConfig := d.DhcpConfPath() - if _, err := os.Stat(pathDhcpConfig); err != nil { - return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) - } - config,err := readDhcpConfig(pathDhcpConfig) - if err != nil { return "",err } - // convert network to name network := state.Get("vmnetwork").(string) device,err := netmap.NameIntoDevice(network) if err != nil { return "", err } + // parse dhcpd configuration + pathDhcpConfig := d.DhcpConfPath(device) + if _, err := os.Stat(pathDhcpConfig); err != nil { + return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) + } + + config,err := readDhcpConfig(pathDhcpConfig) + if err != nil { return "",err } + // find the entry configured in the dhcpd interfaceConfig,err := config.HostByName(device) if err != nil { return "", err } @@ -404,19 +405,19 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { netmap,err := readNetmapConfig(pathNetmap) if err != nil { return "",err } + // convert network to name + network := state.Get("vmnetwork").(string) + device,err := netmap.NameIntoDevice(network) + if err != nil { return "", err } + // parse dhcpd configuration - pathDhcpConfig := d.DhcpConfPath() + pathDhcpConfig := d.DhcpConfPath(device) if _, err := os.Stat(pathDhcpConfig); err != nil { return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) } config,err := readDhcpConfig(pathDhcpConfig) if err != nil { return "",err } - // convert network to name - network := state.Get("vmnetwork").(string) - device,err := netmap.NameIntoDevice(network) - if err != nil { return "", err } - // find the entry configured in the dhcpd interfaceConfig,err := config.HostByName(device) if err != nil { return "", err } diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 15e006403..da28cd474 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -78,12 +78,15 @@ type DriverMock struct { DhcpLeasesPathDevice string DhcpLeasesPathResult string - NetmapPathCalled bool - NetmapPathResult string - DhcpConfPathCalled bool DhcpConfPathResult string + VmnetnatConfPathCalled bool + VmnetnatConfPathResult string + + NetmapConfPathCalled bool + NetmapConfPathResult string + VerifyCalled bool VerifyErr error } @@ -184,16 +187,21 @@ func (d *DriverMock) DhcpLeasesPath(device string) string { return d.DhcpLeasesPathResult } -func (d *DriverMock) NetmapPath(device string) string { - d.NetmapPathCalled = true - return d.NetmapPathResult -} - func (d *DriverMock) DhcpConfPath(device string) string { d.DhcpConfPathCalled = true return d.DhcpConfPathResult } +func (d *DriverMock) VmnetnatConfPath(device string) string { + d.VmnetnatConfPathCalled = true + return d.VmnetnatConfPathResult +} + +func (d *DriverMock) NetmapConfPath() string { + d.NetmapConfPathCalled = true + return d.NetmapConfPathResult +} + func (d *DriverMock) Verify() error { d.VerifyCalled = true return d.VerifyErr diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 9dce9540c..240b44a11 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -187,16 +187,18 @@ func (d *Player5Driver) Verify() error { d.VmwareDriver.DhcpLeasesPath = func(device string) string { return playerDhcpLeasesPath(device) } - d.VmwareDriver.VmnetnatConfPath = func() string { - return playerVmnetnatConfPath() + + d.VmwareDriver.DhcpConfPath = func(device string) string { + return playerVmDhcpConfPath(device) } - d.VmwareDriver.DhcpConfPath = func() string { - return playerVmDhcpConfPath() + + d.VmwareDriver.VmnetnatConfPath = func(device string) string { + return playerVmnetnatConfPath(device) } + d.VmwareDriver.NetmapConfPath = func() string { return playerNetmapConfPath() } - return nil } diff --git a/builder/vmware/common/driver_player5_windows.go b/builder/vmware/common/driver_player5_windows.go index 6ca065792..790a4c46c 100644 --- a/builder/vmware/common/driver_player5_windows.go +++ b/builder/vmware/common/driver_player5_windows.go @@ -57,15 +57,11 @@ func playerDhcpLeasesPath(device string) string { } else if _, err := os.Stat(path); err == nil { return path } - return findFile("vmnetdhcp.leases", playerDataFilePaths()) } -func playerVmnetnatConfPath() string { - return findFile("vmnetnat.conf", playerDataFilePaths()) -} - -func playerVmDhcpConfPath() string { +func playerVmDhcpConfPath(device string) string { + // the device isn't actually used on windows hosts path, err := playerDhcpConfigPathRegistry() if err != nil { log.Printf("Error finding configuration in registry: %s", err) @@ -75,6 +71,11 @@ func playerVmDhcpConfPath() string { return findFile("vmnetdhcp.conf", playerDataFilePaths()) } +func playerVmnetnatConfPath(device string) string { + // the device isn't actually used on windows hosts + return findFile("vmnetnat.conf", playerDataFilePaths()) +} + func playerNetmapConfPath() string { return findFile("netmap.conf", playerDataFilePaths()) } diff --git a/builder/vmware/common/driver_player_unix.go b/builder/vmware/common/driver_player_unix.go index 0c2cc8635..01b877d92 100644 --- a/builder/vmware/common/driver_player_unix.go +++ b/builder/vmware/common/driver_player_unix.go @@ -10,6 +10,7 @@ import ( "os/exec" "regexp" "runtime" + "path/filepath" ) func playerFindVdiskManager() (string, error) { @@ -28,16 +29,49 @@ func playerFindVmrun() (string, error) { return exec.LookPath("vmrun") } -func playerDhcpLeasesPath(device string) string { - return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" -} - func playerToolsIsoPath(flavor string) string { return "/usr/lib/vmware/isoimages/" + flavor + ".iso" } -func playerVmnetnatConfPath() string { - return "" +// return the base path to vmware's config on the host +func playerVMwareRoot() (s string, err error) { + return "/etc/vmware", nil +} + +func playerDhcpLeasesPath(device string) string { + base, err := playerVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, device, "dhcpd/dhcpd.leases") +} + +func playerVmDhcpConfPath(device string) string { + base, err := playerVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, device, "dhcp/dhcp.conf") +} + +func playerVmnetnatConfPath(device string) string { + base, err := playerVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, device, "nat/nat.conf") +} + +func playerNetmapConfPath() string { + base, err := playerVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, "netmap.conf") } func playerVerifyVersion(version string) error { diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index 0c463a249..8a6eb5556 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -149,18 +149,17 @@ func (d *Workstation9Driver) Verify() error { return workstationDhcpLeasesPath(device) } - d.VmwareDriver.VmnetnatConfPath = func() string { - return workstationVmnetnatConfPath() + d.VmwareDriver.DhcpConfPath = func(device string) string { + return workstationDhcpConfPath(device) } - d.VmwareDriver.DhcpConfPath = func() string { - return workstationDhcpConfPath() + d.VmwareDriver.VmnetnatConfPath = func(device string) string { + return workstationVmnetnatConfPath(device) } d.VmwareDriver.NetmapConfPath = func() string { return workstationNetmapConfPath() } - return nil } diff --git a/builder/vmware/common/driver_workstation9_windows.go b/builder/vmware/common/driver_workstation9_windows.go index e69d5069f..b8d6d2b61 100644 --- a/builder/vmware/common/driver_workstation9_windows.go +++ b/builder/vmware/common/driver_workstation9_windows.go @@ -59,7 +59,13 @@ func workstationDhcpLeasesPath(device string) string { return findFile("vmnetdhcp.leases", workstationDataFilePaths()) } -func workstationVmnetnatConfPath() string { +func workstationDhcpConfPath(device string) string { + // device isn't used on a windows host + return findFile("vmnetdhcp.conf", workstationDataFilePaths()) +} + +func workstationVmnetnatConfPath(device string) string { + // device isn't used on a windows host return findFile("vmnetnat.conf", workstationDataFilePaths()) } @@ -67,10 +73,6 @@ func workstationNetmapConfPath() string { return findFile("netmap.conf", workstationDataFilePaths()) } -func workstationDhcpConfPath() string { - return findFile("vmnetdhcp.conf", workstationDataFilePaths()) -} - // See http://blog.natefinch.com/2012/11/go-win-stuff.html // // This is used by workstationVMwareRoot in order to read some registry data. diff --git a/builder/vmware/common/driver_workstation_unix.go b/builder/vmware/common/driver_workstation_unix.go index 2ff94fd37..45e94d21e 100644 --- a/builder/vmware/common/driver_workstation_unix.go +++ b/builder/vmware/common/driver_workstation_unix.go @@ -39,26 +39,51 @@ func workstationFindVmrun() (string, error) { return exec.LookPath("vmrun") } +// return the base path to vmware's config on the host +func workstationVMwareRoot() (s string, err error) { + return "/etc/vmware", nil +} + func workstationDhcpLeasesPath(device string) string { - return "/etc/vmware/" + device + "/dhcpd/dhcpd.leases" + base, err := workstationVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, device, "dhcpd/dhcpd.leases") +} + +func workstationDhcpConfPath(device string) string { + base, err := workstationVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, device, "dhcp/dhcpd.conf") +} + +func workstationVmnetnatConfPath(device string) string { + base, err := workstationVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, device, "nat/nat.conf") +} + +func workstationNetmapConfPath() string { + base, err := workstationVMwareRoot() + if err != nil { + log.Printf("Error finding VMware root: %s", err) + return "" + } + return filepath.Join(base, "netmap.conf") } func workstationToolsIsoPath(flavor string) string { return "/usr/lib/vmware/isoimages/" + flavor + ".iso" } -func workstationVmnetnatConfPath() string { - return "" -} - -func workstationNetmapConfPath(device string) string { - return "" // FIXME -} - -func workstationDhcpConfPath(device string) string { - return "/etc/vmware/" + device + "/dhcpd/dhcpd.conf" -} - func workstationVerifyVersion(version string) error { if runtime.GOOS != "linux" { return fmt.Errorf("The VMware WS version %s driver is only supported on Linux, and Windows, at the moment. Your OS: %s", version, runtime.GOOS) From 15cb6a833a32a1f44c00625c00fe36ac52084a7d Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 5 Apr 2016 20:56:47 -0500 Subject: [PATCH 0555/1007] Ugh..missing argument in VMware builder's driver_esx5 unit-test due to api change for .HostIP(). Fixed. --- builder/vmware/iso/driver_esx5_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder/vmware/iso/driver_esx5_test.go b/builder/vmware/iso/driver_esx5_test.go index 0c0ef757e..097d6e186 100644 --- a/builder/vmware/iso/driver_esx5_test.go +++ b/builder/vmware/iso/driver_esx5_test.go @@ -50,8 +50,9 @@ func TestESX5Driver_HostIP(t *testing.T) { defer listen.Close() driver := ESX5Driver{Host: "localhost", Port: uint(port)} + state := new(multistep.BasicStateBag) - if host, _ := driver.HostIP(); host != expected_host { + if host, _ := driver.HostIP(state); host != expected_host { t.Error(fmt.Sprintf("Expected string, %s but got %s", expected_host, host)) } } From e389d30a1b15de3042f35faa70b7fc4cad7b5c06 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sun, 24 Apr 2016 22:22:13 -0500 Subject: [PATCH 0556/1007] Implemented the unit-tests for builder/vmware/iso/step_create_vmx.go --- builder/vmware/iso/step_create_vmx_test.go | 327 +++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 builder/vmware/iso/step_create_vmx_test.go diff --git a/builder/vmware/iso/step_create_vmx_test.go b/builder/vmware/iso/step_create_vmx_test.go new file mode 100644 index 000000000..e540eee8a --- /dev/null +++ b/builder/vmware/iso/step_create_vmx_test.go @@ -0,0 +1,327 @@ +package iso + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "math" + "math/rand" + "strconv" + "io/ioutil" + "bytes" + "runtime" + + "testing" + "github.com/mitchellh/packer/packer" + "github.com/mitchellh/packer/template" + "github.com/mitchellh/packer/provisioner/shell" +) + +var vmxTestBuilderConfig = map[string]string{ + "type": `"vmware-iso"`, + "iso_url": `"https://archive.org/download/ut-ttylinux-i686-12.6/ut-ttylinux-i686-12.6.iso"`, + "iso_checksum_type": `"md5"`, + "iso_checksum": `"43c1feeae55a44c6ef694b8eb18408a6"`, + "ssh_username": `"root"`, + "ssh_password": `"password"`, + "ssh_wait_timeout": `"45s"`, + "boot_command": `["<enter><wait5><wait10>","root<enter><wait>password<enter><wait>","udhcpc<enter><wait>"]`, + "shutdown_command": `"/sbin/shutdown -h; exit 0"`, +} + +var vmxTestProvisionerConfig = map[string]string{ + "type": `"shell"`, + "inline": `["echo hola mundo"]`, +} + +const vmxTestTemplate string = `{"builders":[{%s}],"provisioners":[{%s}]}` + +func tmpnam(prefix string) string { + var path string + var err error + + const length = 16 + + dir := os.TempDir() + max := int(math.Pow(2, float64(length))) + + n,err := rand.Intn(max),nil + for path = filepath.Join(dir, prefix + strconv.Itoa(n)); err == nil; _,err = os.Stat(path) { + n = rand.Intn(max) + path = filepath.Join(dir, prefix + strconv.Itoa(n)) + } + return path +} + +func createFloppyOutput(prefix string) (string,string,error) { + output := tmpnam(prefix) + f,err := os.Create(output) + if err != nil { return "","",fmt.Errorf("Unable to create empty %s: %s", output, err) } + f.Close() + + vmxData := []string{ + `"floppy0.present":"TRUE"`, + `"floppy0.fileType":"file"`, + `"floppy0.clientDevice":"FALSE"`, + `"floppy0.fileName":"%s"`, + `"floppy0.startConnected":"TRUE"`, + } + + outputFile := strings.Replace(output, "\\", "\\\\", -1) + vmxString := fmt.Sprintf("{" + strings.Join(vmxData, ",") + "}", outputFile) + return output,vmxString,nil +} + +func readFloppyOutput(path string) (string,error) { + f,err := os.Open(path) + if err != nil { return "",fmt.Errorf("Unable to open file %s", path) } + defer f.Close() + data,err := ioutil.ReadAll(f) + if err != nil { return "",fmt.Errorf("Unable to read file: %s", err) } + if len(data) == 0 { return "", nil } + return string(data[:bytes.IndexByte(data,0)]),nil +} + +func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisionerConfig map[string]string) error { + ui := packer.TestUi(t) + + // create builder config and update with user-supplied options + cfgBuilder := map[string]string{} + for k,v := range vmxTestBuilderConfig { cfgBuilder[k] = v } + for k,v := range builderConfig { cfgBuilder[k] = v } + + // convert our builder config into a single sprintfable string + builderLines := []string{} + for k,v := range cfgBuilder { + builderLines = append(builderLines, fmt.Sprintf(`"%s":%s`, k, v)) + } + + // create provisioner config and update with user-supplied options + cfgProvisioner := map[string]string{} + for k,v := range vmxTestProvisionerConfig { cfgProvisioner[k] = v } + for k,v := range provisionerConfig { cfgProvisioner[k] = v } + + // convert our provisioner config into a single sprintfable string + provisionerLines := []string{} + for k,v := range cfgProvisioner { + provisionerLines = append(provisionerLines, fmt.Sprintf(`"%s":%s`, k, v)) + } + + // and now parse them into a template + configString := fmt.Sprintf(vmxTestTemplate, strings.Join(builderLines,`,`), strings.Join(provisionerLines,`,`)) + + tpl,err := template.Parse(strings.NewReader(configString)) + if err != nil { + t.Fatalf("Unable to parse test config: %s", err) + } + + // create our config to test the vmware-iso builder + components := packer.ComponentFinder{ + Builder: func(n string) (packer.Builder,error) { + return &Builder{},nil + }, + Hook: func(n string) (packer.Hook,error) { + return &packer.DispatchHook{},nil + }, + PostProcessor: func(n string) (packer.PostProcessor,error) { + return &packer.MockPostProcessor{},nil + }, + Provisioner: func(n string) (packer.Provisioner,error) { + return &shell.Provisioner{},nil + }, + } + config := packer.CoreConfig{ + Template: tpl, + Components: components, + } + + // create a core using our template + core,err := packer.NewCore(&config) + if err != nil { t.Fatalf("Unable to create core: %s", err) } + + // now we can prepare our build + b,err := core.Build("vmware-iso") + if err != nil { t.Fatalf("Unable to create build: %s", err) } + + warn,err := b.Prepare() + if len(warn) > 0 { + for _,w := range warn { + t.Logf("Configuration warning: %s", w) + } + } + + // and then finally build it + cache := &packer.FileCache{CacheDir: os.TempDir()} + artifacts,err := b.Run(ui, cache) + if err != nil { + t.Fatalf("Failed to build artifact: %s", err) + } + + // check to see that we only got one artifact back + if len(artifacts) == 1 { + return artifacts[0].Destroy() + } + + // otherwise some number of errors happened + t.Logf("Unexpected number of artifacts returned: %d", len(artifacts)) + errors := make([]error, 0) + for _,artifact := range artifacts { + if err := artifact.Destroy(); err != nil { + errors = append(errors, err) + } + } + if len(errors) > 0 { + t.Errorf("%d Errors returned while trying to destroy artifacts", len(errors)) + return fmt.Errorf("Error while trying to destroy artifacts: %v", errors) + } + return nil +} + +func TestStepCreateVmx_SerialFile(t *testing.T) { + tmpfile := tmpnam("SerialFileInput.") + + serialConfig := map[string]string{ + "serial": fmt.Sprintf(`"file:%s"`, filepath.ToSlash(tmpfile)), + } + + error := setupVMwareBuild(t, serialConfig, map[string]string{}) + if error != nil { t.Errorf("Unable to read file: %s", error) } + + f,err := os.Stat(tmpfile) + if err != nil { + t.Errorf("VMware builder did not create a file for serial port: %s", err) + } + + if f != nil { + if err := os.Remove(tmpfile); err != nil { + t.Fatalf("Unable to remove file %s: %s", tmpfile, err) + } + } +} + +func TestStepCreateVmx_SerialPort(t *testing.T) { + var defaultSerial string + if runtime.GOOS == "windows" { + defaultSerial = "COM1" + } else { + defaultSerial = "/dev/ttyS0" + } + + config := map[string]string{ + "serial": fmt.Sprintf(`"device:%s"`, filepath.ToSlash(defaultSerial)), + } + provision := map[string]string{ + "inline": `"dmesg | egrep -o '^serial8250: ttyS1 at' > /dev/fd0"`, + } + + // where to write output + output,vmxData,err := createFloppyOutput("SerialPortOutput.") + if err != nil { t.Fatalf("Error creating output: %s", err) } + defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + config["vmx_data"] = vmxData + t.Logf("Preparing to write output to %s", output) + + // whee + err = setupVMwareBuild(t, config, provision) + if err != nil { t.Errorf("%s", err) } + + // check the output + data,err := readFloppyOutput(output) + if err != nil { t.Errorf("%s", err) } + + if data != "serial8250: ttyS1 at\n" { + t.Errorf("Serial port not detected : %v", data) + } +} + +func TestStepCreateVmx_ParallelPort(t *testing.T) { + var defaultParallel string + if runtime.GOOS == "windows" { + defaultParallel = "LPT1" + } else { + defaultParallel = "/dev/lp0" + } + + config := map[string]string{ + "parallel": fmt.Sprintf(`"device:%s,uni"`, filepath.ToSlash(defaultParallel)), + } + provision := map[string]string{ + "inline": `"cat /proc/modules | egrep -o '^parport ' > /dev/fd0"`, + } + + // where to write output + output,vmxData,err := createFloppyOutput("ParallelPortOutput.") + if err != nil { t.Fatalf("Error creating output: %s", err) } + defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + config["vmx_data"] = vmxData + t.Logf("Preparing to write output to %s", output) + + // whee + error := setupVMwareBuild(t, config, provision) + if error != nil { t.Errorf("%s", error) } + + // check the output + data,err := readFloppyOutput(output) + if err != nil { t.Errorf("%s", err) } + + if data != "parport \n" { + t.Errorf("Parallel port not detected : %v", data) + } +} + +func TestStepCreateVmx_Usb(t *testing.T) { + config := map[string]string{ + "usb": `"TRUE"`, + } + provision := map[string]string{ + "inline": `"dmesg | egrep -m1 -o 'USB hub found$' > /dev/fd0"`, + } + + // where to write output + output,vmxData,err := createFloppyOutput("UsbOutput.") + if err != nil { t.Fatalf("Error creating output: %s", err) } + defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + config["vmx_data"] = vmxData + t.Logf("Preparing to write output to %s", output) + + // whee + error := setupVMwareBuild(t, config, provision) + if error != nil { t.Errorf("%s", error) } + + // check the output + data,err := readFloppyOutput(output) + if err != nil { t.Errorf("%s", err) } + + if data != "USB hub found\n" { + t.Errorf("USB support not detected : %v", data) + } +} + +func TestStepCreateVmx_Sound(t *testing.T) { + config := map[string]string{ + "sound": `"TRUE"`, + } + provision := map[string]string { + "inline": `"cat /proc/modules | egrep -o '^soundcore' > /dev/fd0"`, + } + + // where to write output + output,vmxData,err := createFloppyOutput("SoundOutput.") + if err != nil { t.Fatalf("Error creating output: %s", err) } + defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + config["vmx_data"] = vmxData + t.Logf("Preparing to write output to %s", output) + + // whee + error := setupVMwareBuild(t, config, provision) + if error != nil { t.Errorf("Unable to read file: %s", error) } + + // check the output + data,err := readFloppyOutput(output) + if err != nil { t.Errorf("%s", err) } + + if data != "soundcore\n" { + t.Errorf("Soundcard not detected : %v", data) + } +} From b52e2d3f4575f15fec7e94d48217f55b091d92d6 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 31 May 2016 14:39:38 -0500 Subject: [PATCH 0557/1007] Added the ability for the vmware-builder to fallback and determine the network device-name using the .vmx configuration in case of a guest using the "custom" connection type. --- builder/vmware/common/driver.go | 83 +++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index fa2cc0c03..5359bf07d 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -212,7 +212,8 @@ func compareVersions(versionFound string, versionWanted string, product string) return nil } -// helper functions that read configuration information from a file +/// helper functions that read configuration information from a file +// read the network<->device configuration out of the specified path func readNetmapConfig(path string) (NetworkMap,error) { fd,err := os.Open(path) if err != nil { return nil, err } @@ -220,6 +221,7 @@ func readNetmapConfig(path string) (NetworkMap,error) { return ReadNetworkMap(fd) } +// read the dhcp configuration out of the specified path func readDhcpConfig(path string) (DhcpConfiguration,error) { fd,err := os.Open(path) if err != nil { return nil, err } @@ -227,6 +229,36 @@ func readDhcpConfig(path string) (DhcpConfiguration,error) { return ReadDhcpConfiguration(fd) } +// read the VMX configuration from the specified path +func readVMXConfig(path string) (map[string]string,error) { + f, err := os.Open(path) + if err != nil { + return map[string]string{}, err + } + defer f.Close() + + vmxBytes, err := ioutil.ReadAll(f) + if err != nil { + return map[string]string{}, err + } + return ParseVMX(string(vmxBytes)), nil +} + +// read the connection type out of a vmx configuration +func readCustomDeviceName(vmxData map[string]string) (string,error) { + + connectionType, ok := vmxData["ethernet0.connectiontype"] + if !ok || connectionType != "custom" { + return "", fmt.Errorf("Unable to determine the device name for the connection type : %s", connectionType) + } + + device, ok := vmxData["ethernet0.vnet"] + if !ok || device == "" { + return "", fmt.Errorf("Unable to determine the device name for the connection type \"%s\" : %s", connectionType, device) + } + return device, nil +} + // This VmwareDriver is a base class that contains default methods // that a Driver can use or implement themselves. type VmwareDriver struct { @@ -244,17 +276,8 @@ func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string,error) { vmxPath := state.Get("vmx_path").(string) log.Println("Lookup up IP information...") - f, err := os.Open(vmxPath) - if err != nil { - return "", err - } - defer f.Close() - - vmxBytes, err := ioutil.ReadAll(f) - if err != nil { - return "", err - } - vmxData := ParseVMX(string(vmxBytes)) + vmxData, err := readVMXConfig(vmxPath) + if err != nil { return "", err } var ok bool macAddress := "" @@ -283,7 +306,17 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) { // convert the stashed network to a device network := state.Get("vmnetwork").(string) device,err := netmap.NameIntoDevice(network) - if err != nil { return "", err } + + // we were unable to find the device, maybe it's a custom one... + // so, check to see if it's in the .vmx configuration + if err != nil || network == "custom" { + vmxPath := state.Get("vmx_path").(string) + vmxData, err := readVMXConfig(vmxPath) + if err != nil { return "", err } + + device, err = readCustomDeviceName(vmxData) + if err != nil { return "", err } + } // figure out our MAC address for looking up the guest address MACAddress,err := d.GuestAddress(state) @@ -362,7 +395,17 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { // convert network to name network := state.Get("vmnetwork").(string) device,err := netmap.NameIntoDevice(network) - if err != nil { return "", err } + + // we were unable to find the device, maybe it's a custom one... + // so, check to see if it's in the .vmx configuration + if err != nil || network == "custom" { + vmxPath := state.Get("vmx_path").(string) + vmxData, err := readVMXConfig(vmxPath) + if err != nil { return "", err } + + device, err = readCustomDeviceName(vmxData) + if err != nil { return "", err } + } // parse dhcpd configuration pathDhcpConfig := d.DhcpConfPath(device) @@ -408,7 +451,17 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { // convert network to name network := state.Get("vmnetwork").(string) device,err := netmap.NameIntoDevice(network) - if err != nil { return "", err } + + // we were unable to find the device, maybe it's a custom one... + // so, check to see if it's in the .vmx configuration + if err != nil || network == "custom" { + vmxPath := state.Get("vmx_path").(string) + vmxData, err := readVMXConfig(vmxPath) + if err != nil { return "", err } + + device, err = readCustomDeviceName(vmxData) + if err != nil { return "", err } + } // parse dhcpd configuration pathDhcpConfig := d.DhcpConfPath(device) From 0d6cf7fac44869751d31f262b2ab8ee694ed41b9 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 5 Oct 2016 21:51:42 -0500 Subject: [PATCH 0558/1007] Added support for auto-detection to the serial and parallel port types. Included the yield option to all the serial port types. Added the ability for the network type to fallback to a custom network if the specified network name is not found in netmap.conf. Promoted the scope for both Read{Dhcp,Netmap}Config inside vmwcommon.driver. Updated the documentation for the VMware builder. --- builder/vmware/common/driver.go | 14 +- builder/vmware/iso/step_create_vmx.go | 197 +++++++++++++++--- .../source/docs/builders/vmware-iso.html.md | 56 +++++ 3 files changed, 233 insertions(+), 34 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 5359bf07d..0f0bc1fe8 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -214,7 +214,7 @@ func compareVersions(versionFound string, versionWanted string, product string) /// helper functions that read configuration information from a file // read the network<->device configuration out of the specified path -func readNetmapConfig(path string) (NetworkMap,error) { +func ReadNetmapConfig(path string) (NetworkMap,error) { fd,err := os.Open(path) if err != nil { return nil, err } defer fd.Close() @@ -222,7 +222,7 @@ func readNetmapConfig(path string) (NetworkMap,error) { } // read the dhcp configuration out of the specified path -func readDhcpConfig(path string) (DhcpConfiguration,error) { +func ReadDhcpConfig(path string) (DhcpConfiguration,error) { fd,err := os.Open(path) if err != nil { return nil, err } defer fd.Close() @@ -300,7 +300,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) { if _, err := os.Stat(pathNetmap); err != nil { return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } - netmap,err := readNetmapConfig(pathNetmap) + netmap,err := ReadNetmapConfig(pathNetmap) if err != nil { return "",err } // convert the stashed network to a device @@ -389,7 +389,7 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { if _, err := os.Stat(pathNetmap); err != nil { return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } - netmap,err := readNetmapConfig(pathNetmap) + netmap,err := ReadNetmapConfig(pathNetmap) if err != nil { return "",err } // convert network to name @@ -413,7 +413,7 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) } - config,err := readDhcpConfig(pathDhcpConfig) + config,err := ReadDhcpConfig(pathDhcpConfig) if err != nil { return "",err } // find the entry configured in the dhcpd @@ -445,7 +445,7 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { if _, err := os.Stat(pathNetmap); err != nil { return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } - netmap,err := readNetmapConfig(pathNetmap) + netmap,err := ReadNetmapConfig(pathNetmap) if err != nil { return "",err } // convert network to name @@ -468,7 +468,7 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { if _, err := os.Stat(pathDhcpConfig); err != nil { return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) } - config,err := readDhcpConfig(pathDhcpConfig) + config,err := ReadDhcpConfig(pathDhcpConfig) if err != nil { return "",err } // find the entry configured in the dhcpd diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index c1f4ea8f3..d37f00969 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -21,7 +21,9 @@ type vmxTemplateData struct { ISOPath string Version string - Network string + Network_Type string + Network_Device string + Sound_Present string Usb_Present string @@ -31,10 +33,12 @@ type vmxTemplateData struct { Serial_Host string Serial_Yield string Serial_Filename string + Serial_Auto string Parallel_Present string Parallel_Bidirectional string Parallel_Filename string + Parallel_Auto string } type additionalDiskTemplateData struct { @@ -65,10 +69,17 @@ type serialConfigPipe struct { type serialConfigFile struct { filename string + yield string } type serialConfigDevice struct { devicename string + yield string +} + +type serialConfigAuto struct { + devicename string + yield string } type serialUnion struct { @@ -76,16 +87,33 @@ type serialUnion struct { pipe *serialConfigPipe file *serialConfigFile device *serialConfigDevice + auto *serialConfigAuto } func unformat_serial(config string) (*serialUnion,error) { - comptype := strings.SplitN(config, ":", 2) - if len(comptype) < 1 { + var defaultSerialPort string + if runtime.GOOS == "windows" { + defaultSerialPort = "COM1" + } else { + defaultSerialPort = "/dev/ttyS0" + } + + input := strings.SplitN(config, ":", 2) + if len(input) < 1 { return nil,fmt.Errorf("Unexpected format for serial port: %s", config) } - switch strings.ToUpper(comptype[0]) { + + var formatType, formatOptions string + formatType = input[0] + if len(input) == 2 { + formatOptions = input[1] + } else { + formatOptions = "" + } + + switch strings.ToUpper(formatType) { case "PIPE": - comp := strings.Split(comptype[1], ",") + comp := strings.Split(formatOptions, ",") if len(comp) < 3 || len(comp) > 4 { return nil,fmt.Errorf("Unexpected format for serial port : pipe : %s", config) } @@ -110,16 +138,65 @@ func unformat_serial(config string) (*serialUnion,error) { return &serialUnion{serialType:res, pipe:res},nil case "FILE": - res := &serialConfigFile{ filename : comptype[1] } + comp := strings.Split(formatOptions, ",") + if len(comp) > 2 { + return nil,fmt.Errorf("Unexpected format for serial port : file : %s", config) + } + + res := &serialConfigFile{ yield : "FALSE" } + + res.filename = filepath.FromSlash(comp[0]) + + res.yield = map[bool]string{true:strings.ToUpper(comp[0]), false:"FALSE"}[len(comp) > 1] + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil,fmt.Errorf("Unexpected format for serial port : file : yield : %s : %s", res.yield, config) + } + return &serialUnion{serialType:res, file:res},nil case "DEVICE": + comp := strings.Split(formatOptions, ",") + if len(comp) > 2 { + return nil,fmt.Errorf("Unexpected format for serial port : device : %s", config) + } + res := new(serialConfigDevice) - res.devicename = map[bool]string{true:strings.ToUpper(comptype[1]), false:"COM1"}[len(comptype[1]) > 0] + + if len(comp) == 2 { + res.devicename = map[bool]string{true:filepath.FromSlash(comp[0]), false:defaultSerialPort}[len(comp[0]) > 0] + res.yield = strings.ToUpper(comp[1]) + } else if len(comp) == 1 { + res.devicename = map[bool]string{true:filepath.FromSlash(comp[0]), false:defaultSerialPort}[len(comp[0]) > 0] + res.yield = "FALSE" + } else if len(comp) == 0 { + res.devicename = defaultSerialPort + res.yield = "FALSE" + } + + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil,fmt.Errorf("Unexpected format for serial port : device : yield : %s : %s", res.yield, config) + } + return &serialUnion{serialType:res, device:res},nil + case "AUTO": + res := new(serialConfigAuto) + res.devicename = defaultSerialPort + + if len(formatOptions) > 0 { + res.yield = strings.ToUpper(formatOptions) + } else { + res.yield = "FALSE" + } + + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil,fmt.Errorf("Unexpected format for serial port : auto : yield : %s : %s", res.yield, config) + } + + return &serialUnion{serialType:res, auto:res},nil + default: - return nil,fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(comptype[0]), config) + return nil,fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(formatType), config) } } @@ -128,6 +205,7 @@ type parallelUnion struct { parallelType interface{} file *parallelPortFile device *parallelPortDevice + auto *parallelPortAuto } type parallelPortFile struct { filename string @@ -136,18 +214,30 @@ type parallelPortDevice struct { bidirectional string devicename string } +type parallelPortAuto struct { + bidirectional string +} func unformat_parallel(config string) (*parallelUnion,error) { - comptype := strings.SplitN(config, ":", 2) - if len(comptype) < 1 { + input := strings.SplitN(config, ":", 2) + if len(input) < 1 { return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) } - switch strings.ToUpper(comptype[0]) { + + var formatType, formatOptions string + formatType = input[0] + if len(input) == 2 { + formatOptions = input[1] + } else { + formatOptions = "" + } + + switch strings.ToUpper(formatType) { case "FILE": - res := &parallelPortFile{ filename: comptype[1] } + res := &parallelPortFile{ filename: filepath.FromSlash(formatOptions) } return &parallelUnion{ parallelType:res, file: res},nil case "DEVICE": - comp := strings.Split(comptype[1], ",") + comp := strings.Split(formatOptions, ",") if len(comp) < 1 || len(comp) > 2 { return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) } @@ -156,15 +246,24 @@ func unformat_parallel(config string) (*parallelUnion,error) { res.devicename = strings.ToUpper(comp[0]) if len(comp) > 1 { switch strings.ToUpper(comp[1]) { - case "BI": - res.bidirectional = "TRUE" - case "UNI": - res.bidirectional = "FALSE" + case "BI": res.bidirectional = "TRUE" + case "UNI": res.bidirectional = "FALSE" default: return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(comp[0]), config) } } - return &parallelUnion{ parallelType:res, device: res},nil + return &parallelUnion{ parallelType:res, device:res },nil + + case "AUTO": + res := new(parallelPortAuto) + switch strings.ToUpper(formatOptions) { + case "": fallthrough + case "UNI": res.bidirectional = "FALSE" + case "BI": res.bidirectional = "TRUE" + default: + return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(formatOptions), config) + } + return &parallelUnion{ parallelType:res, auto:res },nil } return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) } @@ -249,7 +348,6 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist Version: config.Version, ISOPath: isoPath, - Network: config.Network, Sound_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.Sound)], Usb_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.USB)], @@ -257,10 +355,42 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist Parallel_Present: "FALSE", } - // store the network so that we can later figure out what ip address to bind to - state.Put("vmnetwork", config.Network) + /// Check the network type that the user specified + network := config.Network + driver := state.Get("driver").(vmwcommon.VmwareDriver) - // check if serial port has been configured + // read netmap config + pathNetmap := driver.NetmapConfPath() + if _, err := os.Stat(pathNetmap); err != nil { + err := fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + netmap,res := vmwcommon.ReadNetmapConfig(pathNetmap) + if res != nil { + err := fmt.Errorf("Unable to read netmap conf file: %s: %v", pathNetmap, res) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // try and convert the specified network to a device + device,err := netmap.NameIntoDevice(network) + + // success. so we know that it's an actual network type inside netmap.conf + if err == nil { + templateData.Network_Type = network + templateData.Network_Device = device + // we were unable to find the type, so assume it's a custom network device. + } else { + templateData.Network_Type = "custom" + templateData.Network_Device = network + } + // store the network so that we can later figure out what ip address to bind to + state.Put("vmnetwork", network) + + /// check if serial port has been configured if config.Serial != "" { serial,err := unformat_serial(config.Serial) if err != nil { @@ -275,6 +405,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Serial_Yield = "" templateData.Serial_Endpoint = "" templateData.Serial_Host = "" + templateData.Serial_Auto = "FALSE" switch serial.serialType.(type) { case *serialConfigPipe: @@ -289,6 +420,12 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist case *serialConfigDevice: templateData.Serial_Type = "device" templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename) + case *serialConfigAuto: + templateData.Serial_Type = "device" + templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename) + templateData.Serial_Yield = serial.auto.yield + templateData.Serial_Auto = "TRUE" + default: err := fmt.Errorf("Error procesing VMX template: %v", serial) state.Put("error", err) @@ -297,7 +434,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } } - // check if parallel port has been configured + /// check if parallel port has been configured if config.Parallel != "" { parallel,err := unformat_parallel(config.Parallel) if err != nil { @@ -307,6 +444,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist return multistep.ActionHalt } + templateData.Parallel_Auto = "FALSE" switch parallel.parallelType.(type) { case *parallelPortFile: templateData.Parallel_Present = "TRUE" @@ -315,6 +453,10 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Parallel_Present = "TRUE" templateData.Parallel_Bidirectional = parallel.device.bidirectional templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename) + case *parallelPortAuto: + templateData.Parallel_Present = "TRUE" + templateData.Parallel_Auto = "TRUE" + templateData.Parallel_Bidirectional = parallel.auto.bidirectional default: err := fmt.Errorf("Error procesing VMX template: %v", parallel) state.Put("error", err) @@ -325,7 +467,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist ctx.Data = &templateData - // render the .vmx template + /// render the .vmx template vmxContents, err := interpolate.Render(vmxTemplate, &ctx) if err != nil { err := fmt.Errorf("Error procesing VMX template: %s", err) @@ -383,7 +525,8 @@ ehci.pciSlotNumber = "34" ehci.present = "TRUE" ethernet0.addressType = "generated" ethernet0.bsdName = "en0" -ethernet0.connectionType = "{{ .Network }}" +ethernet0.connectionType = "{{ .Network_Type }}" +ethernet0.vnet = "{{ .Network_Device }}" ethernet0.displayName = "Ethernet" ethernet0.linkStatePropagation.enable = "FALSE" ethernet0.pciSlotNumber = "33" @@ -453,7 +596,7 @@ usb_xhci.present = "TRUE" serial0.present = "{{ .Serial_Present }}" serial0.startConnected = "{{ .Serial_Present }}" serial0.fileName = "{{ .Serial_Filename }}" -serial0.autodetect = "TRUE" +serial0.autodetect = "{{ .Serial_Auto }}" serial0.fileType = "{{ .Serial_Type }}" serial0.yieldOnMsrRead = "{{ .Serial_Yield }}" serial0.pipe.endPoint = "{{ .Serial_Endpoint }}" @@ -463,7 +606,7 @@ serial0.tryNoRxLoss = "{{ .Serial_Host }}" parallel0.present = "{{ .Parallel_Present }}" parallel0.startConnected = "{{ .Parallel_Present }}" parallel0.fileName = "{{ .Parallel_Filename }}" -parallel0.autodetect = "TRUE" +parallel0.autodetect = "{{ .Parallel_Auto }}" parallel0.bidirectional = "{{ .Parallel_Bidirectional }}" virtualHW.productCompatibility = "hosted" diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 256bf63e4..44285a850 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -193,6 +193,11 @@ builder. URLs must point to the same file (same checksum). By default this is empty and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified. +- `network` (string) - This is the network type that the virtual machine will + be created with. This can be one of the generic values that map to a device + such as "hostonly", "nat", or "bridged". If the network is not one of these + values, then it is assumed to be a VMware network device. (VMnet0..x) + - `output_directory` (string) - This is the path to the directory where the resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` @@ -200,6 +205,19 @@ builder. the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the name of the build. +- `parallel` (string) - This specifies a parallel port to add to the VM. It + has the format of `Type:option1,option2,...`. Type can be one of the + following values: "FILE", "DEVICE", or "AUTO". + + * `FILE:path` - Specifies the path to the local file to be used for the + parallel port. + * `DEVICE:path` - Specifies the path to the local device to be used for the + parallel port. + * `AUTO:direction` - Specifies to use auto-detection to determine the + parallel port. Direction can be `BI` to specify + bidirectional communication or `UNI` to specify + unidirectional communication. + - `remote_cache_datastore` (string) - The path to the datastore where supporting files will be stored during the build on the remote machine. By default this is the same as the `remote_datastore` option. This only has an @@ -234,6 +252,40 @@ builder. - `remote_username` (string) - The username for the SSH user that will access the remote machine. This is required if `remote_type` is enabled. +- `serial` (string) - This specifies a serial port to add to the VM. + It has a format of `Type:option1,option2,...`. The field `Type` can be one + of the following values: `FILE`, `DEVICE`, `PIPE`, or `AUTO`. + + * `FILE:path(,yield)` - Specifies the path to the local file to be used as the + serial port. + * `yield` (bool) - This is an optional boolean that specifies whether + the vm should yield the cpu when polling the port. + By default, the builder will assume this as `FALSE`. + * `DEVICE:path(,yield)` - Specifies the path to the local device to be used + as the serial port. If `path` is empty, then + default to the first serial port. + * `yield` (bool) - This is an optional boolean that specifies whether + the vm should yield the cpu when polling the port. + By default, the builder will assume this as `FALSE`. + * `PIPE:path,endpoint,host(,yield)` - Specifies to use the named-pipe "path" + as a serial port. This has a few + options that determine how the VM + should use the named-pipe. + * `endpoint` (string) - Chooses the type of the VM-end, which can be + either a `client` or `server`. + * `host` (string) - Chooses the type of the host-end, which can be either + an `app` (application) or `vm` (another virtual-machine). + * `yield` (bool) - This is an optional boolean that specifies whether + the vm should yield the cpu when polling the port. + By default, the builder will assume this as `FALSE`. + + * `AUTO:(yield)` - Specifies to use auto-detection to determine the serial + port to use. This has one option to determine how the VM + should support the serial port. + * `yield` (bool) - This is an optional boolean that specifies whether + the vm should yield the cpu when polling the port. + By default, the builder will assume this as `FALSE`. + - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty string, which tells Packer to just forcefully shut down the machine. @@ -264,6 +316,8 @@ builder. `--noSSLVerify`, `--skipManifestCheck`, and `--targetType` are reserved, and should not be passed to this argument. +- `sound` (boolean) - Enable VMware's virtual soundcard device for the VM. + - `tools_upload_flavor` (string) - The flavor of the VMware Tools ISO to upload into the VM. Valid values are "darwin", "linux", and "windows". By default, this is empty, which means VMware tools won't be uploaded. @@ -276,6 +330,8 @@ builder. By default the upload path is set to `{{.Flavor}}.iso`. This setting is not used when `remote_type` is "esx5". +- `usb` (boolean) - Enable VMware's USB bus for the VM. + - `version` (string) - The [vmx hardware version](http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1003746) for the new virtual machine. Only the default value has been tested, any From 884af69da14c132a378a6fb3cc10f9501fdbf03b Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Mon, 27 Feb 2017 15:34:53 -0600 Subject: [PATCH 0559/1007] go fmt on builder/vmware/* --- builder/vmware/common/driver.go | 158 ++- builder/vmware/common/driver_mock.go | 2 +- builder/vmware/common/driver_parser.go | 1122 +++++++++-------- builder/vmware/common/driver_player_unix.go | 2 +- builder/vmware/common/driver_workstation10.go | 1 - builder/vmware/iso/builder.go | 29 +- builder/vmware/iso/step_create_vmx.go | 360 +++--- builder/vmware/iso/step_create_vmx_test.go | 234 ++-- 8 files changed, 1075 insertions(+), 833 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 0f0bc1fe8..745b48d69 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -1,19 +1,19 @@ package common import ( - "errors" "bytes" + "errors" "fmt" + "io/ioutil" "log" + "net" "os" "os/exec" - "io/ioutil" "regexp" "runtime" "strconv" "strings" "time" - "net" "github.com/hashicorp/packer/helper/multistep" ) @@ -214,23 +214,27 @@ func compareVersions(versionFound string, versionWanted string, product string) /// helper functions that read configuration information from a file // read the network<->device configuration out of the specified path -func ReadNetmapConfig(path string) (NetworkMap,error) { - fd,err := os.Open(path) - if err != nil { return nil, err } +func ReadNetmapConfig(path string) (NetworkMap, error) { + fd, err := os.Open(path) + if err != nil { + return nil, err + } defer fd.Close() return ReadNetworkMap(fd) } // read the dhcp configuration out of the specified path -func ReadDhcpConfig(path string) (DhcpConfiguration,error) { - fd,err := os.Open(path) - if err != nil { return nil, err } +func ReadDhcpConfig(path string) (DhcpConfiguration, error) { + fd, err := os.Open(path) + if err != nil { + return nil, err + } defer fd.Close() return ReadDhcpConfiguration(fd) } // read the VMX configuration from the specified path -func readVMXConfig(path string) (map[string]string,error) { +func readVMXConfig(path string) (map[string]string, error) { f, err := os.Open(path) if err != nil { return map[string]string{}, err @@ -245,7 +249,7 @@ func readVMXConfig(path string) (map[string]string,error) { } // read the connection type out of a vmx configuration -func readCustomDeviceName(vmxData map[string]string) (string,error) { +func readCustomDeviceName(vmxData map[string]string) (string, error) { connectionType, ok := vmxData["ethernet0.connectiontype"] if !ok || connectionType != "custom" { @@ -266,18 +270,20 @@ type VmwareDriver struct { /// A driver must overload these in order to point to the correct /// files so that the address detection (ip and ethernet) machinery /// works. - DhcpLeasesPath func(string) string - DhcpConfPath func(string) string + DhcpLeasesPath func(string) string + DhcpConfPath func(string) string VmnetnatConfPath func(string) string - NetmapConfPath func() string + NetmapConfPath func() string } -func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string,error) { +func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string, error) { vmxPath := state.Get("vmx_path").(string) log.Println("Lookup up IP information...") vmxData, err := readVMXConfig(vmxPath) - if err != nil { return "", err } + if err != nil { + return "", err + } var ok bool macAddress := "" @@ -287,40 +293,50 @@ func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string,error) { } } - res,err := net.ParseMAC(macAddress) - if err != nil { return "", err } + res, err := net.ParseMAC(macAddress) + if err != nil { + return "", err + } - return res.String(),nil + return res.String(), nil } -func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) { +func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // read netmap config pathNetmap := d.NetmapConfPath() if _, err := os.Stat(pathNetmap); err != nil { return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } - netmap,err := ReadNetmapConfig(pathNetmap) - if err != nil { return "",err } + netmap, err := ReadNetmapConfig(pathNetmap) + if err != nil { + return "", err + } // convert the stashed network to a device network := state.Get("vmnetwork").(string) - device,err := netmap.NameIntoDevice(network) + device, err := netmap.NameIntoDevice(network) // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration if err != nil || network == "custom" { vmxPath := state.Get("vmx_path").(string) vmxData, err := readVMXConfig(vmxPath) - if err != nil { return "", err } + if err != nil { + return "", err + } device, err = readCustomDeviceName(vmxData) - if err != nil { return "", err } + if err != nil { + return "", err + } } // figure out our MAC address for looking up the guest address - MACAddress,err := d.GuestAddress(state) - if err != nil { return "", err } + MACAddress, err := d.GuestAddress(state) + if err != nil { + return "", err + } // figure out the correct dhcp leases dhcpLeasesPath := d.DhcpLeasesPath(device) @@ -382,29 +398,35 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) { return curIp, nil } -func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { +func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { // parse network<->device mapping pathNetmap := d.NetmapConfPath() if _, err := os.Stat(pathNetmap); err != nil { return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } - netmap,err := ReadNetmapConfig(pathNetmap) - if err != nil { return "",err } + netmap, err := ReadNetmapConfig(pathNetmap) + if err != nil { + return "", err + } // convert network to name network := state.Get("vmnetwork").(string) - device,err := netmap.NameIntoDevice(network) + device, err := netmap.NameIntoDevice(network) // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration if err != nil || network == "custom" { vmxPath := state.Get("vmx_path").(string) vmxData, err := readVMXConfig(vmxPath) - if err != nil { return "", err } + if err != nil { + return "", err + } device, err = readCustomDeviceName(vmxData) - if err != nil { return "", err } + if err != nil { + return "", err + } } // parse dhcpd configuration @@ -413,54 +435,68 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) { return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) } - config,err := ReadDhcpConfig(pathDhcpConfig) - if err != nil { return "",err } + config, err := ReadDhcpConfig(pathDhcpConfig) + if err != nil { + return "", err + } // find the entry configured in the dhcpd - interfaceConfig,err := config.HostByName(device) - if err != nil { return "", err } + interfaceConfig, err := config.HostByName(device) + if err != nil { + return "", err + } // finally grab the hardware address - address,err := interfaceConfig.Hardware() - if err == nil { return address.String(), nil } + address, err := interfaceConfig.Hardware() + if err == nil { + return address.String(), nil + } // we didn't find it, so search through our interfaces for the device name - interfaceList,err := net.Interfaces() - if err == nil { return "", err } + interfaceList, err := net.Interfaces() + if err == nil { + return "", err + } names := make([]string, 0) - for _,intf := range interfaceList { - if strings.HasSuffix( strings.ToLower(intf.Name), device ) { - return intf.HardwareAddr.String(),nil + for _, intf := range interfaceList { + if strings.HasSuffix(strings.ToLower(intf.Name), device) { + return intf.HardwareAddr.String(), nil } names = append(names, intf.Name) } - return "",fmt.Errorf("Unable to find device %s : %v", device, names) + return "", fmt.Errorf("Unable to find device %s : %v", device, names) } -func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { +func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { // parse network<->device mapping pathNetmap := d.NetmapConfPath() if _, err := os.Stat(pathNetmap); err != nil { return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } - netmap,err := ReadNetmapConfig(pathNetmap) - if err != nil { return "",err } + netmap, err := ReadNetmapConfig(pathNetmap) + if err != nil { + return "", err + } // convert network to name network := state.Get("vmnetwork").(string) - device,err := netmap.NameIntoDevice(network) + device, err := netmap.NameIntoDevice(network) // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration if err != nil || network == "custom" { vmxPath := state.Get("vmx_path").(string) vmxData, err := readVMXConfig(vmxPath) - if err != nil { return "", err } + if err != nil { + return "", err + } device, err = readCustomDeviceName(vmxData) - if err != nil { return "", err } + if err != nil { + return "", err + } } // parse dhcpd configuration @@ -468,15 +504,21 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) { if _, err := os.Stat(pathDhcpConfig); err != nil { return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) } - config,err := ReadDhcpConfig(pathDhcpConfig) - if err != nil { return "",err } + config, err := ReadDhcpConfig(pathDhcpConfig) + if err != nil { + return "", err + } // find the entry configured in the dhcpd - interfaceConfig,err := config.HostByName(device) - if err != nil { return "", err } + interfaceConfig, err := config.HostByName(device) + if err != nil { + return "", err + } - address,err := interfaceConfig.IP4() - if err != nil { return "", err } + address, err := interfaceConfig.IP4() + if err != nil { + return "", err + } - return address.String(),nil + return address.String(), nil } diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index da28cd474..562eab382 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -83,7 +83,7 @@ type DriverMock struct { VmnetnatConfPathCalled bool VmnetnatConfPathResult string - + NetmapConfPathCalled bool NetmapConfPathResult string diff --git a/builder/vmware/common/driver_parser.go b/builder/vmware/common/driver_parser.go index 7071e424d..dbf15b5b5 100644 --- a/builder/vmware/common/driver_parser.go +++ b/builder/vmware/common/driver_parser.go @@ -1,12 +1,13 @@ package common + import ( "fmt" - "os" "io" - "strings" - "strconv" "net" + "os" "sort" + "strconv" + "strings" ) type sentinelSignaller chan struct{} @@ -20,16 +21,20 @@ func uncomment(eof sentinelSignaller, in <-chan byte) chan byte { var endofline bool for stillReading := true; stillReading; { select { - case <-eof: - stillReading = false - case ch := <-in: - switch ch { - case '#': - endofline = true - case '\n': - if endofline { endofline = false } + case <-eof: + stillReading = false + case ch := <-in: + switch ch { + case '#': + endofline = true + case '\n': + if endofline { + endofline = false } - if !endofline { out <- ch } + } + if !endofline { + out <- ch + } } } }(in, out) @@ -46,62 +51,71 @@ func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) chan string { go func(out chan string) { for stillReading := true; stillReading; { select { - case <-eof: - stillReading = false + case <-eof: + stillReading = false - case ch = <-in: - if quote { - if ch == '"' { - out <- state + string(ch) - state,quote = "",false - continue - } - state += string(ch) + case ch = <-in: + if quote { + if ch == '"' { + out <- state + string(ch) + state, quote = "", false continue } + state += string(ch) + continue + } - switch ch { - case '"': - quote = true - state += string(ch) - continue + switch ch { + case '"': + quote = true + state += string(ch) + continue - case '\r': - fallthrough - case '\n': - fallthrough - case '\t': - fallthrough - case ' ': - if len(state) == 0 { continue } - out <- state - state = "" - - case '{': fallthrough - case '}': fallthrough - case ';': - if len(state) > 0 { out <- state } - out <- string(ch) - state = "" - - default: - state += string(ch) + case '\r': + fallthrough + case '\n': + fallthrough + case '\t': + fallthrough + case ' ': + if len(state) == 0 { + continue } + out <- state + state = "" + + case '{': + fallthrough + case '}': + fallthrough + case ';': + if len(state) > 0 { + out <- state + } + out <- string(ch) + state = "" + + default: + state += string(ch) + } } } - if len(state) > 0 { out <- state } + if len(state) > 0 { + out <- state + } }(out) return out } /** mid-level parsing */ type tkParameter struct { - name string + name string operand []string } + func (e *tkParameter) String() string { var values []string - for _,val := range e.operand { + for _, val := range e.operand { values = append(values, val) } return fmt.Sprintf("%s [%s]", e.name, strings.Join(values, ",")) @@ -109,21 +123,22 @@ func (e *tkParameter) String() string { type tkGroup struct { parent *tkGroup - id tkParameter + id tkParameter groups []*tkGroup params []tkParameter } + func (e *tkGroup) String() string { var id []string id = append(id, e.id.name) - for _,val := range e.id.operand { + for _, val := range e.id.operand { id = append(id, val) } var config []string - for _,val := range e.params { + for _, val := range e.params { config = append(config, val.String()) } return fmt.Sprintf("%s {\n%s\n}", strings.Join(id, " "), strings.Join(config, "\n")) @@ -139,11 +154,14 @@ func parseTokenParameter(in chan string) tkParameter { continue } switch token { - case "{": fallthrough - case "}": fallthrough - case ";": goto leave - default: - result.operand = append(result.operand, token) + case "{": + fallthrough + case "}": + fallthrough + case ";": + goto leave + default: + result.operand = append(result.operand, token) } } leave: @@ -151,50 +169,52 @@ leave: } // convert a channel of pseudo-tokens into an tkGroup tree */ -func parseDhcpConfig(eof sentinelSignaller, in chan string) (tkGroup,error) { +func parseDhcpConfig(eof sentinelSignaller, in chan string) (tkGroup, error) { var tokens []string var result tkGroup toParameter := func(tokens []string) tkParameter { out := make(chan string) - go func(out chan string){ - for _,v := range tokens { out <- v } + go func(out chan string) { + for _, v := range tokens { + out <- v + } out <- ";" }(out) return parseTokenParameter(out) } - for stillReading,currentgroup := true,&result; stillReading; { + for stillReading, currentgroup := true, &result; stillReading; { select { - case <-eof: - stillReading = false + case <-eof: + stillReading = false - case tk := <-in: - switch tk { - case "{": - grp := &tkGroup{parent:currentgroup} - grp.id = toParameter(tokens) - currentgroup.groups = append(currentgroup.groups, grp) - currentgroup = grp - case "}": - if currentgroup.parent == nil { - return tkGroup{}, fmt.Errorf("Unable to close the global declaration") - } - if len(tokens) > 0 { - return tkGroup{}, fmt.Errorf("List of tokens was left unterminated : %v", tokens) - } - currentgroup = currentgroup.parent - case ";": - arg := toParameter(tokens) - currentgroup.params = append(currentgroup.params, arg) - default: - tokens = append(tokens, tk) - continue + case tk := <-in: + switch tk { + case "{": + grp := &tkGroup{parent: currentgroup} + grp.id = toParameter(tokens) + currentgroup.groups = append(currentgroup.groups, grp) + currentgroup = grp + case "}": + if currentgroup.parent == nil { + return tkGroup{}, fmt.Errorf("Unable to close the global declaration") } - tokens = []string{} + if len(tokens) > 0 { + return tkGroup{}, fmt.Errorf("List of tokens was left unterminated : %v", tokens) + } + currentgroup = currentgroup.parent + case ";": + arg := toParameter(tokens) + currentgroup.params = append(currentgroup.params, arg) + default: + tokens = append(tokens, tk) + continue + } + tokens = []string{} } } - return result,nil + return result, nil } func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string { @@ -207,70 +227,85 @@ func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string { go func(out chan string) { for stillReading := true; stillReading; { select { - case <-eof: - stillReading = false + case <-eof: + stillReading = false - case ch = <-in: - if quote { - if ch == '"' { - out <- state + string(ch) - state,quote = "",false - continue - } - state += string(ch) + case ch = <-in: + if quote { + if ch == '"' { + out <- state + string(ch) + state, quote = "", false continue } + state += string(ch) + continue + } - switch ch { - case '"': - quote = true - state += string(ch) - continue + switch ch { + case '"': + quote = true + state += string(ch) + continue - case '\r': - fallthrough - case '\t': - fallthrough - case ' ': - if len(state) == 0 { continue } - out <- state - state = "" - - case '\n': - if lastnewline { continue } - if len(state) > 0 { out <- state } - out <- string(ch) - state = "" - lastnewline = true - continue - - case '.': fallthrough - case '=': - if len(state) > 0 { out <- state } - out <- string(ch) - state = "" - - default: - state += string(ch) + case '\r': + fallthrough + case '\t': + fallthrough + case ' ': + if len(state) == 0 { + continue } - lastnewline = false + out <- state + state = "" + + case '\n': + if lastnewline { + continue + } + if len(state) > 0 { + out <- state + } + out <- string(ch) + state = "" + lastnewline = true + continue + + case '.': + fallthrough + case '=': + if len(state) > 0 { + out <- state + } + out <- string(ch) + state = "" + + default: + state += string(ch) + } + lastnewline = false } } - if len(state) > 0 { out <- state } + if len(state) > 0 { + out <- state + } }(out) return out } -func parseNetworkMapConfig(eof sentinelSignaller, in chan string) (NetworkMap,error) { +func parseNetworkMapConfig(eof sentinelSignaller, in chan string) (NetworkMap, error) { var unsorted map[string]map[string]string var state []string addResult := func(network string, attribute string, value string) error { - _,ok := unsorted[network] - if !ok { unsorted[network] = make(map[string]string) } + _, ok := unsorted[network] + if !ok { + unsorted[network] = make(map[string]string) + } - val,err := strconv.Unquote(value) - if err != nil { return err } + val, err := strconv.Unquote(value) + if err != nil { + return err + } current := unsorted[network] current[attribute] = val @@ -280,135 +315,174 @@ func parseNetworkMapConfig(eof sentinelSignaller, in chan string) (NetworkMap,er stillReading := true for unsorted = make(map[string]map[string]string); stillReading; { select { - case <-eof: - if len(state) == 3 { - err := addResult(state[0], state[1], state[2]) - if err != nil { return nil,err } + case <-eof: + if len(state) == 3 { + err := addResult(state[0], state[1], state[2]) + if err != nil { + return nil, err } - stillReading = false - case tk := <-in: - switch tk { - case ".": - if len(state) != 1 { return nil,fmt.Errorf("Missing network index") } - case "=": - if len(state) != 2 { return nil,fmt.Errorf("Assignment to empty attribute") } - case "\n": - if len(state) == 0 { continue } - if len(state) != 3 { return nil,fmt.Errorf("Invalid attribute assignment : %v", state) } - err := addResult(state[0], state[1], state[2]) - if err != nil { return nil,err } - state = make([]string, 0) - default: - state = append(state, tk) + } + stillReading = false + case tk := <-in: + switch tk { + case ".": + if len(state) != 1 { + return nil, fmt.Errorf("Missing network index") } + case "=": + if len(state) != 2 { + return nil, fmt.Errorf("Assignment to empty attribute") + } + case "\n": + if len(state) == 0 { + continue + } + if len(state) != 3 { + return nil, fmt.Errorf("Invalid attribute assignment : %v", state) + } + err := addResult(state[0], state[1], state[2]) + if err != nil { + return nil, err + } + state = make([]string, 0) + default: + state = append(state, tk) + } } } result := make([]map[string]string, 0) var keys []string - for k := range unsorted { keys = append(keys, k) } + for k := range unsorted { + keys = append(keys, k) + } sort.Strings(keys) - for _,k := range keys { + for _, k := range keys { result = append(result, unsorted[k]) } - return result,nil + return result, nil } /** higher-level parsing */ /// parameters -type pParameter interface { repr() string } +type pParameter interface { + repr() string +} type pParameterInclude struct { filename string } -func (e pParameterInclude) repr() string { return fmt.Sprintf("include-file:filename=%s",e.filename) } + +func (e pParameterInclude) repr() string { return fmt.Sprintf("include-file:filename=%s", e.filename) } type pParameterOption struct { - name string + name string value string } -func (e pParameterOption) repr() string { return fmt.Sprintf("option:%s=%s",e.name,e.value) } + +func (e pParameterOption) repr() string { return fmt.Sprintf("option:%s=%s", e.name, e.value) } // allow some-kind-of-something type pParameterGrant struct { - verb string // allow,deny,ignore + verb string // allow,deny,ignore attribute string } -func (e pParameterGrant) repr() string { return fmt.Sprintf("grant:%s,%s",e.verb,e.attribute) } + +func (e pParameterGrant) repr() string { return fmt.Sprintf("grant:%s,%s", e.verb, e.attribute) } type pParameterAddress4 []string + func (e pParameterAddress4) repr() string { - return fmt.Sprintf("fixed-address4:%s",strings.Join(e,",")) + return fmt.Sprintf("fixed-address4:%s", strings.Join(e, ",")) } type pParameterAddress6 []string + func (e pParameterAddress6) repr() string { - return fmt.Sprintf("fixed-address6:%s",strings.Join(e,",")) + return fmt.Sprintf("fixed-address6:%s", strings.Join(e, ",")) } // hardware address 00:00:00:00:00:00 type pParameterHardware struct { - class string + class string address []byte } + func (e pParameterHardware) repr() string { res := make([]string, 0) - for _,v := range e.address { - res = append(res, fmt.Sprintf("%02x",v)) + for _, v := range e.address { + res = append(res, fmt.Sprintf("%02x", v)) } - return fmt.Sprintf("hardware-address:%s[%s]",e.class,strings.Join(res,":")) + return fmt.Sprintf("hardware-address:%s[%s]", e.class, strings.Join(res, ":")) } type pParameterBoolean struct { parameter string - truancy bool + truancy bool } -func (e pParameterBoolean) repr() string { return fmt.Sprintf("boolean:%s=%v",e.parameter,e.truancy) } + +func (e pParameterBoolean) repr() string { return fmt.Sprintf("boolean:%s=%v", e.parameter, e.truancy) } type pParameterClientMatch struct { name string data string } -func (e pParameterClientMatch) repr() string { return fmt.Sprintf("match-client:%s=%s",e.name,e.data) } + +func (e pParameterClientMatch) repr() string { return fmt.Sprintf("match-client:%s=%s", e.name, e.data) } // range 127.0.0.1 127.0.0.255 type pParameterRange4 struct { min net.IP max net.IP } -func (e pParameterRange4) repr() string { return fmt.Sprintf("range4:%s-%s",e.min.String(),e.max.String()) } + +func (e pParameterRange4) repr() string { + return fmt.Sprintf("range4:%s-%s", e.min.String(), e.max.String()) +} type pParameterRange6 struct { min net.IP max net.IP } -func (e pParameterRange6) repr() string { return fmt.Sprintf("range6:%s-%s",e.min.String(),e.max.String()) } + +func (e pParameterRange6) repr() string { + return fmt.Sprintf("range6:%s-%s", e.min.String(), e.max.String()) +} type pParameterPrefix6 struct { - min net.IP - max net.IP + min net.IP + max net.IP bits int } -func (e pParameterPrefix6) repr() string { return fmt.Sprintf("prefix6:/%d:%s-%s",e.bits,e.min.String(),e.max.String()) } + +func (e pParameterPrefix6) repr() string { + return fmt.Sprintf("prefix6:/%d:%s-%s", e.bits, e.min.String(), e.max.String()) +} // some-kind-of-parameter 1024 type pParameterOther struct { parameter string - value string + value string } -func (e pParameterOther) repr() string { return fmt.Sprintf("parameter:%s=%s",e.parameter,e.value) } + +func (e pParameterOther) repr() string { return fmt.Sprintf("parameter:%s=%s", e.parameter, e.value) } type pParameterExpression struct { - parameter string + parameter string expression string } -func (e pParameterExpression) repr() string { return fmt.Sprintf("parameter-expression:%s=\"%s\"",e.parameter,e.expression) } -type pDeclarationIdentifier interface { repr() string } +func (e pParameterExpression) repr() string { + return fmt.Sprintf("parameter-expression:%s=\"%s\"", e.parameter, e.expression) +} + +type pDeclarationIdentifier interface { + repr() string +} type pDeclaration struct { - id pDeclarationIdentifier - parent *pDeclaration - parameters []pParameter + id pDeclarationIdentifier + parent *pDeclaration + parameters []pParameter declarations []pDeclaration } @@ -420,277 +494,305 @@ func (e *pDeclaration) repr() string { res := e.short() var parameters []string - for _,v := range e.parameters { + for _, v := range e.parameters { parameters = append(parameters, v.repr()) } var groups []string - for _,v := range e.declarations { - groups = append(groups, fmt.Sprintf("-> %s",v.short())) + for _, v := range e.declarations { + groups = append(groups, fmt.Sprintf("-> %s", v.short())) } if e.parent != nil { - res = fmt.Sprintf("%s parent:%s",res,e.parent.short()) + res = fmt.Sprintf("%s parent:%s", res, e.parent.short()) } - return fmt.Sprintf("%s\n%s\n%s\n", res, strings.Join(parameters,"\n"), strings.Join(groups,"\n")) + return fmt.Sprintf("%s\n%s\n%s\n", res, strings.Join(parameters, "\n"), strings.Join(groups, "\n")) } -type pDeclarationGlobal struct {} +type pDeclarationGlobal struct{} + func (e pDeclarationGlobal) repr() string { return fmt.Sprintf("{global}") } -type pDeclarationShared struct { name string } +type pDeclarationShared struct{ name string } + func (e pDeclarationShared) repr() string { return fmt.Sprintf("{shared-network %s}", e.name) } -type pDeclarationSubnet4 struct { net.IPNet } +type pDeclarationSubnet4 struct{ net.IPNet } + func (e pDeclarationSubnet4) repr() string { return fmt.Sprintf("{subnet4 %s}", e.String()) } -type pDeclarationSubnet6 struct { net.IPNet } +type pDeclarationSubnet6 struct{ net.IPNet } + func (e pDeclarationSubnet6) repr() string { return fmt.Sprintf("{subnet6 %s}", e.String()) } -type pDeclarationHost struct { name string } +type pDeclarationHost struct{ name string } + func (e pDeclarationHost) repr() string { return fmt.Sprintf("{host name:%s}", e.name) } -type pDeclarationPool struct {} +type pDeclarationPool struct{} + func (e pDeclarationPool) repr() string { return fmt.Sprintf("{pool}") } -type pDeclarationGroup struct {} +type pDeclarationGroup struct{} + func (e pDeclarationGroup) repr() string { return fmt.Sprintf("{group}") } -type pDeclarationClass struct { name string } +type pDeclarationClass struct{ name string } + func (e pDeclarationClass) repr() string { return fmt.Sprintf("{class}") } /** parsers */ -func parseParameter(val tkParameter) (pParameter,error) { +func parseParameter(val tkParameter) (pParameter, error) { switch val.name { - case "include": - if len(val.operand) != 2 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterInclude : %v",val.operand) - } - name := val.operand[0] - return pParameterInclude{filename: name},nil + case "include": + if len(val.operand) != 2 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterInclude : %v", val.operand) + } + name := val.operand[0] + return pParameterInclude{filename: name}, nil - case "option": - if len(val.operand) != 2 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterOption : %v",val.operand) - } - name, value := val.operand[0], val.operand[1] - return pParameterOption{name: name, value: value},nil + case "option": + if len(val.operand) != 2 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterOption : %v", val.operand) + } + name, value := val.operand[0], val.operand[1] + return pParameterOption{name: name, value: value}, nil - case "allow": fallthrough - case "deny": fallthrough - case "ignore": - if len(val.operand) < 1 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterGrant : %v",val.operand) - } - attribute := strings.Join(val.operand," ") - return pParameterGrant{verb: strings.ToLower(val.name), attribute: attribute},nil + case "allow": + fallthrough + case "deny": + fallthrough + case "ignore": + if len(val.operand) < 1 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterGrant : %v", val.operand) + } + attribute := strings.Join(val.operand, " ") + return pParameterGrant{verb: strings.ToLower(val.name), attribute: attribute}, nil - case "range": - if len(val.operand) < 1 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterRange4 : %v",val.operand) - } - idxAddress := map[bool]int{true:1,false:0}[strings.ToLower(val.operand[0]) == "bootp"] - if len(val.operand) > 2 + idxAddress { - return nil,fmt.Errorf("Invalid number of parameters for pParameterRange : %v",val.operand) - } - if idxAddress + 1 > len(val.operand) { - res := net.ParseIP(val.operand[idxAddress]) - return pParameterRange4{min: res, max: res},nil - } - addr1 := net.ParseIP(val.operand[idxAddress]) - addr2 := net.ParseIP(val.operand[idxAddress+1]) - return pParameterRange4{min: addr1, max: addr2},nil + case "range": + if len(val.operand) < 1 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterRange4 : %v", val.operand) + } + idxAddress := map[bool]int{true: 1, false: 0}[strings.ToLower(val.operand[0]) == "bootp"] + if len(val.operand) > 2+idxAddress { + return nil, fmt.Errorf("Invalid number of parameters for pParameterRange : %v", val.operand) + } + if idxAddress+1 > len(val.operand) { + res := net.ParseIP(val.operand[idxAddress]) + return pParameterRange4{min: res, max: res}, nil + } + addr1 := net.ParseIP(val.operand[idxAddress]) + addr2 := net.ParseIP(val.operand[idxAddress+1]) + return pParameterRange4{min: addr1, max: addr2}, nil - case "range6": - if len(val.operand) == 1 { - address := val.operand[0] - if (strings.Contains(address, "/")) { - cidr := strings.SplitN(address, "/", 2) - if len(cidr) != 2 { return nil,fmt.Errorf("Unknown ipv6 format : %v", address) } - address := net.ParseIP(cidr[0]) - bits,err := strconv.Atoi(cidr[1]) - if err != nil { return nil,err } - mask := net.CIDRMask(bits, net.IPv6len*8) - - // figure out the network address - network := address.Mask(mask) - - // make a broadcast address - broadcast := network - networkSize,totalSize := mask.Size() - hostSize := totalSize-networkSize - for i := networkSize / 8; i < totalSize / 8; i++ { - broadcast[i] = byte(0xff) - } - octetIndex := network[networkSize / 8] - bitsLeft := (uint32)(hostSize%8) - broadcast[octetIndex] = network[octetIndex] | ((1<<bitsLeft)-1) - - // FIXME: check that the broadcast address was made correctly - return pParameterRange6{min: network, max: broadcast},nil + case "range6": + if len(val.operand) == 1 { + address := val.operand[0] + if strings.Contains(address, "/") { + cidr := strings.SplitN(address, "/", 2) + if len(cidr) != 2 { + return nil, fmt.Errorf("Unknown ipv6 format : %v", address) } - res := net.ParseIP(address) - return pParameterRange6{min: res, max:res},nil - } - if len(val.operand) == 2 { - addr := net.ParseIP(val.operand[0]) - if strings.ToLower(val.operand[1]) == "temporary" { - return pParameterRange6{min: addr, max: addr},nil + address := net.ParseIP(cidr[0]) + bits, err := strconv.Atoi(cidr[1]) + if err != nil { + return nil, err } - other := net.ParseIP(val.operand[1]) - return pParameterRange6{min: addr, max: other},nil - } - return nil,fmt.Errorf("Invalid number of parameters for pParameterRange6 : %v",val.operand) + mask := net.CIDRMask(bits, net.IPv6len*8) - case "prefix6": - if len(val.operand) != 3 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterRange6 : %v",val.operand) + // figure out the network address + network := address.Mask(mask) + + // make a broadcast address + broadcast := network + networkSize, totalSize := mask.Size() + hostSize := totalSize - networkSize + for i := networkSize / 8; i < totalSize/8; i++ { + broadcast[i] = byte(0xff) + } + octetIndex := network[networkSize/8] + bitsLeft := (uint32)(hostSize % 8) + broadcast[octetIndex] = network[octetIndex] | ((1 << bitsLeft) - 1) + + // FIXME: check that the broadcast address was made correctly + return pParameterRange6{min: network, max: broadcast}, nil } - bits,err := strconv.Atoi(val.operand[2]) + res := net.ParseIP(address) + return pParameterRange6{min: res, max: res}, nil + } + if len(val.operand) == 2 { + addr := net.ParseIP(val.operand[0]) + if strings.ToLower(val.operand[1]) == "temporary" { + return pParameterRange6{min: addr, max: addr}, nil + } + other := net.ParseIP(val.operand[1]) + return pParameterRange6{min: addr, max: other}, nil + } + return nil, fmt.Errorf("Invalid number of parameters for pParameterRange6 : %v", val.operand) + + case "prefix6": + if len(val.operand) != 3 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterRange6 : %v", val.operand) + } + bits, err := strconv.Atoi(val.operand[2]) + if err != nil { + return nil, fmt.Errorf("Invalid bits for pParameterPrefix6 : %v", val.operand[2]) + } + minaddr := net.ParseIP(val.operand[0]) + maxaddr := net.ParseIP(val.operand[1]) + return pParameterPrefix6{min: minaddr, max: maxaddr, bits: bits}, nil + + case "hardware": + if len(val.operand) != 2 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterHardware : %v", val.operand) + } + class := val.operand[0] + octets := strings.Split(val.operand[1], ":") + address := make([]byte, 0) + for _, v := range octets { + b, err := strconv.ParseInt(v, 16, 0) if err != nil { - return nil,fmt.Errorf("Invalid bits for pParameterPrefix6 : %v",val.operand[2]) + return nil, err } - minaddr := net.ParseIP(val.operand[0]) - maxaddr := net.ParseIP(val.operand[1]) - return pParameterPrefix6{min: minaddr, max: maxaddr, bits:bits},nil + address = append(address, byte(b)) + } + return pParameterHardware{class: class, address: address}, nil - case "hardware": - if len(val.operand) != 2 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterHardware : %v",val.operand) - } - class := val.operand[0] - octets := strings.Split(val.operand[1], ":") - address := make([]byte, 0) - for _,v := range octets { - b,err := strconv.ParseInt(v, 16, 0) - if err != nil { return nil,err } - address = append(address, byte(b)) - } - return pParameterHardware{class: class, address: address},nil + case "fixed-address": + ip4addrs := make(pParameterAddress4, len(val.operand)) + copy(ip4addrs, val.operand) + return ip4addrs, nil - case "fixed-address": - ip4addrs := make(pParameterAddress4,len(val.operand)) - copy(ip4addrs, val.operand) - return ip4addrs,nil + case "fixed-address6": + ip6addrs := make(pParameterAddress6, len(val.operand)) + copy(ip6addrs, val.operand) + return ip6addrs, nil - case "fixed-address6": - ip6addrs := make(pParameterAddress6,len(val.operand)) - copy(ip6addrs, val.operand) - return ip6addrs,nil + case "host-identifier": + if len(val.operand) != 3 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterClientMatch : %v", val.operand) + } + if val.operand[0] != "option" { + return nil, fmt.Errorf("Invalid match parameter : %v", val.operand[0]) + } + optionName := val.operand[1] + optionData := val.operand[2] + return pParameterClientMatch{name: optionName, data: optionData}, nil - case "host-identifier": - if len(val.operand) != 3 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterClientMatch : %v",val.operand) + default: + length := len(val.operand) + if length < 1 { + return pParameterBoolean{parameter: val.name, truancy: true}, nil + } else if length > 1 { + if val.operand[0] == "=" { + return pParameterExpression{parameter: val.name, expression: strings.Join(val.operand[1:], "")}, nil } - if val.operand[0] != "option" { - return nil,fmt.Errorf("Invalid match parameter : %v",val.operand[0]) - } - optionName := val.operand[1] - optionData := val.operand[2] - return pParameterClientMatch{name: optionName, data: optionData},nil - - default: - length := len(val.operand) - if length < 1 { - return pParameterBoolean{parameter: val.name, truancy: true},nil - } else if length > 1 { - if val.operand[0] == "=" { - return pParameterExpression{parameter: val.name, expression: strings.Join(val.operand[1:],"")},nil - } - } - if length != 1 { - return nil,fmt.Errorf("Invalid number of parameters for pParameterOther : %v",val.operand) - } - if strings.ToLower(val.name) == "not" { - return pParameterBoolean{parameter: val.operand[0], truancy: false},nil - } - return pParameterOther{parameter: val.name, value: val.operand[0]}, nil + } + if length != 1 { + return nil, fmt.Errorf("Invalid number of parameters for pParameterOther : %v", val.operand) + } + if strings.ToLower(val.name) == "not" { + return pParameterBoolean{parameter: val.operand[0], truancy: false}, nil + } + return pParameterOther{parameter: val.name, value: val.operand[0]}, nil } } -func parseTokenGroup(val tkGroup) (*pDeclaration,error) { +func parseTokenGroup(val tkGroup) (*pDeclaration, error) { params := val.id.operand switch val.id.name { - case "group": - return &pDeclaration{id:pDeclarationGroup{}},nil + case "group": + return &pDeclaration{id: pDeclarationGroup{}}, nil - case "pool": - return &pDeclaration{id:pDeclarationPool{}},nil + case "pool": + return &pDeclaration{id: pDeclarationPool{}}, nil - case "host": - if len(params) == 1 { - return &pDeclaration{id:pDeclarationHost{name: params[0]}},nil - } + case "host": + if len(params) == 1 { + return &pDeclaration{id: pDeclarationHost{name: params[0]}}, nil + } - case "subnet": - if len(params) == 3 && strings.ToLower(params[1]) == "netmask" { - addr := make([]byte, 4) - for i,v := range strings.SplitN(params[2], ".", 4) { - res,err := strconv.ParseInt(v, 10, 0) - if err != nil { return nil,err } - addr[i] = byte(res) + case "subnet": + if len(params) == 3 && strings.ToLower(params[1]) == "netmask" { + addr := make([]byte, 4) + for i, v := range strings.SplitN(params[2], ".", 4) { + res, err := strconv.ParseInt(v, 10, 0) + if err != nil { + return nil, err } - oc1,oc2,oc3,oc4 := addr[0],addr[1],addr[2],addr[3] - if subnet,mask := net.ParseIP(params[0]),net.IPv4Mask(oc1,oc2,oc3,oc4); subnet != nil && mask != nil { - return &pDeclaration{id:pDeclarationSubnet4{net.IPNet{IP:subnet,Mask:mask}}},nil + addr[i] = byte(res) + } + oc1, oc2, oc3, oc4 := addr[0], addr[1], addr[2], addr[3] + if subnet, mask := net.ParseIP(params[0]), net.IPv4Mask(oc1, oc2, oc3, oc4); subnet != nil && mask != nil { + return &pDeclaration{id: pDeclarationSubnet4{net.IPNet{IP: subnet, Mask: mask}}}, nil + } + } + case "subnet6": + if len(params) == 1 { + ip6 := strings.SplitN(params[0], "/", 2) + if len(ip6) == 2 && strings.Contains(ip6[0], ":") { + address := net.ParseIP(ip6[0]) + prefix, err := strconv.Atoi(ip6[1]) + if err != nil { + return nil, err } + return &pDeclaration{id: pDeclarationSubnet6{net.IPNet{IP: address, Mask: net.CIDRMask(prefix, net.IPv6len*8)}}}, nil } - case "subnet6": - if len(params) == 1 { - ip6 := strings.SplitN(params[0], "/", 2) - if len(ip6) == 2 && strings.Contains(ip6[0], ":") { - address := net.ParseIP(ip6[0]) - prefix,err := strconv.Atoi(ip6[1]) - if err != nil { return nil, err } - return &pDeclaration{id:pDeclarationSubnet6{net.IPNet{IP:address,Mask:net.CIDRMask(prefix, net.IPv6len*8)}}},nil - } - } - case "shared-network": - if len(params) == 1 { - return &pDeclaration{id:pDeclarationShared{name: params[0]}},nil - } - case "": - return &pDeclaration{id:pDeclarationGlobal{}},nil + } + case "shared-network": + if len(params) == 1 { + return &pDeclaration{id: pDeclarationShared{name: params[0]}}, nil + } + case "": + return &pDeclaration{id: pDeclarationGlobal{}}, nil } - return nil,fmt.Errorf("Invalid pDeclaration : %v : %v", val.id.name, params) + return nil, fmt.Errorf("Invalid pDeclaration : %v : %v", val.id.name, params) } -func flattenDhcpConfig(root tkGroup) (*pDeclaration,error) { +func flattenDhcpConfig(root tkGroup) (*pDeclaration, error) { var result *pDeclaration - result,err := parseTokenGroup(root) - if err != nil { return nil,err } + result, err := parseTokenGroup(root) + if err != nil { + return nil, err + } - for _,p := range root.params { - param,err := parseParameter(p) - if err != nil { return nil,err } + for _, p := range root.params { + param, err := parseParameter(p) + if err != nil { + return nil, err + } result.parameters = append(result.parameters, param) } - for _,p := range root.groups { - group,err := flattenDhcpConfig(*p) - if err != nil { return nil,err } + for _, p := range root.groups { + group, err := flattenDhcpConfig(*p) + if err != nil { + return nil, err + } group.parent = result result.declarations = append(result.declarations, *group) } - return result,nil + return result, nil } /** reduce the tree into the things that we care about */ type grant uint + const ( - ALLOW grant = iota + ALLOW grant = iota IGNORE grant = iota - DENY grant = iota + DENY grant = iota ) + type configDeclaration struct { - id []pDeclarationIdentifier + id []pDeclarationIdentifier composites []pDeclaration address []pParameter - options map[string]string - grants map[string]grant - attributes map[string]bool - parameters map[string]string + options map[string]string + grants map[string]grant + attributes map[string]bool + parameters map[string]string expressions map[string]string hostid []pParameterClientMatch @@ -715,28 +817,28 @@ func createDeclaration(node pDeclaration) configDeclaration { result.hostid = make([]pParameterClientMatch, 0) // walk from globals to pDeclaration collecting all parameters - for i := len(hierarchy)-1; i >= 0; i-- { - result.composites = append(result.composites, hierarchy[(len(hierarchy)-1) - i]) - result.id = append(result.id, hierarchy[(len(hierarchy)-1) - i].id) + for i := len(hierarchy) - 1; i >= 0; i-- { + result.composites = append(result.composites, hierarchy[(len(hierarchy)-1)-i]) + result.id = append(result.id, hierarchy[(len(hierarchy)-1)-i].id) // update configDeclaration parameters - for _,p := range hierarchy[i].parameters { + for _, p := range hierarchy[i].parameters { switch p.(type) { - case pParameterOption: - result.options[p.(pParameterOption).name] = p.(pParameterOption).value - case pParameterGrant: - Grant := map[string]grant{"ignore":IGNORE, "allow":ALLOW, "deny":DENY} - result.grants[p.(pParameterGrant).attribute] = Grant[p.(pParameterGrant).verb] - case pParameterBoolean: - result.attributes[p.(pParameterBoolean).parameter] = p.(pParameterBoolean).truancy - case pParameterClientMatch: - result.hostid = append(result.hostid, p.(pParameterClientMatch)) - case pParameterExpression: - result.expressions[p.(pParameterExpression).parameter] = p.(pParameterExpression).expression - case pParameterOther: - result.parameters[p.(pParameterOther).parameter] = p.(pParameterOther).value - default: - result.address = append(result.address, p) + case pParameterOption: + result.options[p.(pParameterOption).name] = p.(pParameterOption).value + case pParameterGrant: + Grant := map[string]grant{"ignore": IGNORE, "allow": ALLOW, "deny": DENY} + result.grants[p.(pParameterGrant).attribute] = Grant[p.(pParameterGrant).verb] + case pParameterBoolean: + result.attributes[p.(pParameterBoolean).parameter] = p.(pParameterBoolean).truancy + case pParameterClientMatch: + result.hostid = append(result.hostid, p.(pParameterClientMatch)) + case pParameterExpression: + result.expressions[p.(pParameterExpression).parameter] = p.(pParameterExpression).expression + case pParameterOther: + result.parameters[p.(pParameterOther).parameter] = p.(pParameterOther).value + default: + result.address = append(result.address, p) } } } @@ -749,112 +851,141 @@ func (e *configDeclaration) repr() string { var res []string res = make([]string, 0) - for _,v := range e.id { res = append(res, v.repr()) } + for _, v := range e.id { + res = append(res, v.repr()) + } result = append(result, strings.Join(res, ",")) if len(e.address) > 0 { res = make([]string, 0) - for _,v := range e.address { res = append(res, v.repr()) } + for _, v := range e.address { + res = append(res, v.repr()) + } result = append(result, fmt.Sprintf("address : %v", strings.Join(res, ","))) } - if len(e.options) > 0 { result = append(result, fmt.Sprintf("options : %v", e.options)) } - if len(e.grants) > 0 { result = append(result, fmt.Sprintf("grants : %v", e.grants)) } - if len(e.attributes) > 0 { result = append(result, fmt.Sprintf("attributes : %v", e.attributes)) } - if len(e.parameters) > 0 { result = append(result, fmt.Sprintf("parameters : %v", e.parameters)) } - if len(e.expressions) > 0 { result = append(result, fmt.Sprintf("parameter-expressions : %v", e.expressions)) } + if len(e.options) > 0 { + result = append(result, fmt.Sprintf("options : %v", e.options)) + } + if len(e.grants) > 0 { + result = append(result, fmt.Sprintf("grants : %v", e.grants)) + } + if len(e.attributes) > 0 { + result = append(result, fmt.Sprintf("attributes : %v", e.attributes)) + } + if len(e.parameters) > 0 { + result = append(result, fmt.Sprintf("parameters : %v", e.parameters)) + } + if len(e.expressions) > 0 { + result = append(result, fmt.Sprintf("parameter-expressions : %v", e.expressions)) + } if len(e.hostid) > 0 { res = make([]string, 0) - for _,v := range e.hostid { res = append(res, v.repr()) } + for _, v := range e.hostid { + res = append(res, v.repr()) + } result = append(result, fmt.Sprintf("hostid : %v", strings.Join(res, " "))) } return strings.Join(result, "\n") + "\n" } -func (e *configDeclaration) IP4() (net.IP,error) { +func (e *configDeclaration) IP4() (net.IP, error) { var result []string - for _,entry := range e.address { + for _, entry := range e.address { switch entry.(type) { - case pParameterAddress4: - for _,s := range entry.(pParameterAddress4) { - result = append(result, s) - } + case pParameterAddress4: + for _, s := range entry.(pParameterAddress4) { + result = append(result, s) + } } } if len(result) > 1 { - return nil,fmt.Errorf("More than one address4 returned : %v", result) + return nil, fmt.Errorf("More than one address4 returned : %v", result) } else if len(result) == 0 { - return nil,fmt.Errorf("No IP4 addresses found") + return nil, fmt.Errorf("No IP4 addresses found") } - if res := net.ParseIP(result[0]); res != nil { return res,nil } - res,err := net.ResolveIPAddr("ip4", result[0]) - if err != nil { return nil,err } - return res.IP,nil + if res := net.ParseIP(result[0]); res != nil { + return res, nil + } + res, err := net.ResolveIPAddr("ip4", result[0]) + if err != nil { + return nil, err + } + return res.IP, nil } -func (e *configDeclaration) IP6() (net.IP,error) { +func (e *configDeclaration) IP6() (net.IP, error) { var result []string - for _,entry := range e.address { + for _, entry := range e.address { switch entry.(type) { - case pParameterAddress6: - for _,s := range entry.(pParameterAddress6) { - result = append(result, s) - } + case pParameterAddress6: + for _, s := range entry.(pParameterAddress6) { + result = append(result, s) + } } } if len(result) > 1 { - return nil,fmt.Errorf("More than one address6 returned : %v", result) + return nil, fmt.Errorf("More than one address6 returned : %v", result) } else if len(result) == 0 { - return nil,fmt.Errorf("No IP6 addresses found") + return nil, fmt.Errorf("No IP6 addresses found") } - if res := net.ParseIP(result[0]); res != nil { return res,nil } - res,err := net.ResolveIPAddr("ip6", result[0]) - if err != nil { return nil,err } - return res.IP,nil + if res := net.ParseIP(result[0]); res != nil { + return res, nil + } + res, err := net.ResolveIPAddr("ip6", result[0]) + if err != nil { + return nil, err + } + return res.IP, nil } -func (e *configDeclaration) Hardware() (net.HardwareAddr,error) { +func (e *configDeclaration) Hardware() (net.HardwareAddr, error) { var result []pParameterHardware - for _,addr := range e.address { + for _, addr := range e.address { switch addr.(type) { - case pParameterHardware: - result = append(result, addr.(pParameterHardware)) + case pParameterHardware: + result = append(result, addr.(pParameterHardware)) } } if len(result) > 0 { - return nil,fmt.Errorf("More than one hardware address returned : %v", result) + return nil, fmt.Errorf("More than one hardware address returned : %v", result) } res := make(net.HardwareAddr, 0) - for _,by := range result[0].address { + for _, by := range result[0].address { res = append(res, by) } - return res,nil + return res, nil } /*** Dhcp Configuration */ type DhcpConfiguration []configDeclaration -func ReadDhcpConfiguration(fd *os.File) (DhcpConfiguration,error) { - fromfile,eof := consumeFile(fd) + +func ReadDhcpConfiguration(fd *os.File) (DhcpConfiguration, error) { + fromfile, eof := consumeFile(fd) uncommented := uncomment(eof, fromfile) tokenized := tokenizeDhcpConfig(eof, uncommented) - parsetree,err := parseDhcpConfig(eof, tokenized) - if err != nil { return nil,err } + parsetree, err := parseDhcpConfig(eof, tokenized) + if err != nil { + return nil, err + } - global,err := flattenDhcpConfig(parsetree) - if err != nil { return nil,err } + global, err := flattenDhcpConfig(parsetree) + if err != nil { + return nil, err + } - var walkDeclarations func(root pDeclaration, out chan*configDeclaration); - walkDeclarations = func(root pDeclaration, out chan*configDeclaration) { + var walkDeclarations func(root pDeclaration, out chan *configDeclaration) + walkDeclarations = func(root pDeclaration, out chan *configDeclaration) { res := createDeclaration(root) out <- &res - for _,p := range root.declarations { + for _, p := range root.declarations { walkDeclarations(p, out) } } - each := make(chan*configDeclaration) - go func(out chan*configDeclaration) { + each := make(chan *configDeclaration) + go func(out chan *configDeclaration) { walkDeclarations(*global, out) out <- nil }(each) @@ -863,7 +994,7 @@ func ReadDhcpConfiguration(fd *os.File) (DhcpConfiguration,error) { for decl := <-each; decl != nil; decl = <-each { result = append(result, *decl) } - return result,nil + return result, nil } func (e *DhcpConfiguration) Global() configDeclaration { @@ -874,83 +1005,86 @@ func (e *DhcpConfiguration) Global() configDeclaration { return result } -func (e *DhcpConfiguration) SubnetByAddress(address net.IP) (configDeclaration,error) { +func (e *DhcpConfiguration) SubnetByAddress(address net.IP) (configDeclaration, error) { var result []configDeclaration - for _,entry := range *e { + for _, entry := range *e { switch entry.id[0].(type) { - case pDeclarationSubnet4: - id := entry.id[0].(pDeclarationSubnet4) - if id.Contains(address) { - result = append(result, entry) - } - case pDeclarationSubnet6: - id := entry.id[0].(pDeclarationSubnet6) - if id.Contains(address) { - result = append(result, entry) - } + case pDeclarationSubnet4: + id := entry.id[0].(pDeclarationSubnet4) + if id.Contains(address) { + result = append(result, entry) + } + case pDeclarationSubnet6: + id := entry.id[0].(pDeclarationSubnet6) + if id.Contains(address) { + result = append(result, entry) + } } } if len(result) == 0 { - return configDeclaration{},fmt.Errorf("No network declarations containing %s found", address.String()) + return configDeclaration{}, fmt.Errorf("No network declarations containing %s found", address.String()) } if len(result) > 1 { - return configDeclaration{},fmt.Errorf("More than 1 network declaration found : %v", result) + return configDeclaration{}, fmt.Errorf("More than 1 network declaration found : %v", result) } - return result[0],nil + return result[0], nil } -func (e *DhcpConfiguration) HostByName(host string) (configDeclaration,error) { +func (e *DhcpConfiguration) HostByName(host string) (configDeclaration, error) { var result []configDeclaration - for _,entry := range *e { + for _, entry := range *e { switch entry.id[0].(type) { - case pDeclarationHost: - id := entry.id[0].(pDeclarationHost) - if strings.ToLower(id.name) == strings.ToLower(host) { - result = append(result, entry) - } + case pDeclarationHost: + id := entry.id[0].(pDeclarationHost) + if strings.ToLower(id.name) == strings.ToLower(host) { + result = append(result, entry) + } } } if len(result) == 0 { - return configDeclaration{},fmt.Errorf("No host declarations containing %s found", host) + return configDeclaration{}, fmt.Errorf("No host declarations containing %s found", host) } if len(result) > 1 { - return configDeclaration{},fmt.Errorf("More than 1 host declaration found : %v", result) + return configDeclaration{}, fmt.Errorf("More than 1 host declaration found : %v", result) } - return result[0],nil + return result[0], nil } /*** Network Map */ type NetworkMap []map[string]string -func ReadNetworkMap(fd *os.File) (NetworkMap,error) { - fromfile,eof := consumeFile(fd) - uncommented := uncomment(eof,fromfile) +func ReadNetworkMap(fd *os.File) (NetworkMap, error) { + + fromfile, eof := consumeFile(fd) + uncommented := uncomment(eof, fromfile) tokenized := tokenizeNetworkMapConfig(eof, uncommented) - result,err := parseNetworkMapConfig(eof, tokenized) - if err != nil { return nil,err } - return result,nil + result, err := parseNetworkMapConfig(eof, tokenized) + if err != nil { + return nil, err + } + return result, nil } -func (e *NetworkMap) NameIntoDevice(name string) (string,error) { - for _,val := range *e { +func (e *NetworkMap) NameIntoDevice(name string) (string, error) { + for _, val := range *e { if strings.ToLower(val["name"]) == strings.ToLower(name) { - return val["device"],nil + return val["device"], nil } } - return "",fmt.Errorf("Network name not found : %v", name) + return "", fmt.Errorf("Network name not found : %v", name) } -func (e *NetworkMap) DeviceIntoName(device string) (string,error) { - for _,val := range *e { +func (e *NetworkMap) DeviceIntoName(device string) (string, error) { + for _, val := range *e { if strings.ToLower(val["device"]) == strings.ToLower(device) { - return val["name"],nil + return val["name"], nil } } - return "",fmt.Errorf("Device name not found : %v", device) + return "", fmt.Errorf("Device name not found : %v", device) } func (e *NetworkMap) repr() string { var result []string - for idx,val := range *e { + for idx, val := range *e { result = append(result, fmt.Sprintf("network%d.name = \"%s\"", idx, val["name"])) result = append(result, fmt.Sprintf("network%d.device = \"%s\"", idx, val["device"])) } @@ -958,17 +1092,19 @@ func (e *NetworkMap) repr() string { } /** main */ -func consumeFile(fd *os.File) (chan byte,sentinelSignaller) { +func consumeFile(fd *os.File) (chan byte, sentinelSignaller) { fromfile := make(chan byte) eof := make(sentinelSignaller) go func() { b := make([]byte, 1) for { - _,err := fd.Read(b) - if err == io.EOF { break } + _, err := fd.Read(b) + if err == io.EOF { + break + } fromfile <- b[0] } close(eof) }() - return fromfile,eof + return fromfile, eof } diff --git a/builder/vmware/common/driver_player_unix.go b/builder/vmware/common/driver_player_unix.go index 01b877d92..068720a6c 100644 --- a/builder/vmware/common/driver_player_unix.go +++ b/builder/vmware/common/driver_player_unix.go @@ -8,9 +8,9 @@ import ( "fmt" "log" "os/exec" + "path/filepath" "regexp" "runtime" - "path/filepath" ) func playerFindVdiskManager() (string, error) { diff --git a/builder/vmware/common/driver_workstation10.go b/builder/vmware/common/driver_workstation10.go index 716717e39..7e6ac8b8f 100644 --- a/builder/vmware/common/driver_workstation10.go +++ b/builder/vmware/common/driver_workstation10.go @@ -33,4 +33,3 @@ func (d *Workstation10Driver) Verify() error { return workstationVerifyVersion(VMWARE_WS_VERSION) } - diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 2cce8fd3c..2dcc082ac 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -39,38 +39,35 @@ type Config struct { vmwcommon.VMXConfig `mapstructure:",squash"` // disk drives - AdditionalDiskSize []uint `mapstructure:"disk_additional_size"` - DiskName string `mapstructure:"vmdk_name"` - DiskSize uint `mapstructure:"disk_size"` - DiskTypeId string `mapstructure:"disk_type_id"` - Format string `mapstructure:"format"` + AdditionalDiskSize []uint `mapstructure:"disk_additional_size"` + DiskName string `mapstructure:"vmdk_name"` + DiskSize uint `mapstructure:"disk_size"` + DiskTypeId string `mapstructure:"disk_type_id"` + Format string `mapstructure:"format"` // platform information - GuestOSType string `mapstructure:"guest_os_type"` - Version string `mapstructure:"version"` - VMName string `mapstructure:"vm_name"` + GuestOSType string `mapstructure:"guest_os_type"` + Version string `mapstructure:"version"` + VMName string `mapstructure:"vm_name"` // Network type - Network string `mapstructure:"network"` + Network string `mapstructure:"network"` // device presence - Sound bool `mapstructure:"sound"` - USB bool `mapstructure:"usb"` + Sound bool `mapstructure:"sound"` + USB bool `mapstructure:"usb"` // communication ports - Serial string `mapstructure:"serial"` - Parallel string `mapstructure:"parallel"` + Serial string `mapstructure:"serial"` + Parallel string `mapstructure:"parallel"` // booting a guest - BootCommand []string `mapstructure:"boot_command"` KeepRegistered bool `mapstructure:"keep_registered"` OVFToolOptions []string `mapstructure:"ovftool_options"` SkipCompaction bool `mapstructure:"skip_compaction"` SkipExport bool `mapstructure:"skip_export"` - VMName string `mapstructure:"vm_name"` VMXDiskTemplatePath string `mapstructure:"vmx_disk_template_path"` VMXTemplatePath string `mapstructure:"vmx_template_path"` - Version string `mapstructure:"version"` // remote vsphere RemoteType string `mapstructure:"remote_type"` diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index d37f00969..0261123a6 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" vmwcommon "github.com/hashicorp/packer/builder/vmware/common" @@ -21,24 +22,24 @@ type vmxTemplateData struct { ISOPath string Version string - Network_Type string - Network_Device string + Network_Type string + Network_Device string Sound_Present string - Usb_Present string + Usb_Present string - Serial_Present string - Serial_Type string + Serial_Present string + Serial_Type string Serial_Endpoint string - Serial_Host string - Serial_Yield string + Serial_Host string + Serial_Yield string Serial_Filename string - Serial_Auto string + Serial_Auto string - Parallel_Present string + Parallel_Present string Parallel_Bidirectional string - Parallel_Filename string - Parallel_Auto string + Parallel_Filename string + Parallel_Auto string } type additionalDiskTemplateData struct { @@ -63,34 +64,34 @@ type stepCreateVMX struct { type serialConfigPipe struct { filename string endpoint string - host string - yield string + host string + yield string } type serialConfigFile struct { filename string - yield string + yield string } type serialConfigDevice struct { devicename string - yield string + yield string } type serialConfigAuto struct { devicename string - yield string + yield string } type serialUnion struct { serialType interface{} - pipe *serialConfigPipe - file *serialConfigFile - device *serialConfigDevice - auto *serialConfigAuto + pipe *serialConfigPipe + file *serialConfigFile + device *serialConfigDevice + auto *serialConfigAuto } -func unformat_serial(config string) (*serialUnion,error) { +func unformat_serial(config string) (*serialUnion, error) { var defaultSerialPort string if runtime.GOOS == "windows" { defaultSerialPort = "COM1" @@ -100,7 +101,7 @@ func unformat_serial(config string) (*serialUnion,error) { input := strings.SplitN(config, ":", 2) if len(input) < 1 { - return nil,fmt.Errorf("Unexpected format for serial port: %s", config) + return nil, fmt.Errorf("Unexpected format for serial port: %s", config) } var formatType, formatOptions string @@ -112,116 +113,116 @@ func unformat_serial(config string) (*serialUnion,error) { } switch strings.ToUpper(formatType) { - case "PIPE": - comp := strings.Split(formatOptions, ",") - if len(comp) < 3 || len(comp) > 4 { - return nil,fmt.Errorf("Unexpected format for serial port : pipe : %s", config) - } - if res := strings.ToLower(comp[1]); res != "client" && res != "server" { - return nil,fmt.Errorf("Unexpected format for serial port : pipe : endpoint : %s : %s", res, config) - } - if res := strings.ToLower(comp[2]); res != "app" && res != "vm" { - return nil,fmt.Errorf("Unexpected format for serial port : pipe : host : %s : %s", res, config) - } - res := &serialConfigPipe{ - filename : comp[0], - endpoint : comp[1], - host : map[string]string{"app":"TRUE","vm":"FALSE"}[strings.ToLower(comp[2])], - yield : "FALSE", - } - if len(comp) == 4 { - res.yield = strings.ToUpper(comp[3]) - } - if res.yield != "TRUE" && res.yield != "FALSE" { - return nil,fmt.Errorf("Unexpected format for serial port : pipe : yield : %s : %s", res.yield, config) - } - return &serialUnion{serialType:res, pipe:res},nil + case "PIPE": + comp := strings.Split(formatOptions, ",") + if len(comp) < 3 || len(comp) > 4 { + return nil, fmt.Errorf("Unexpected format for serial port : pipe : %s", config) + } + if res := strings.ToLower(comp[1]); res != "client" && res != "server" { + return nil, fmt.Errorf("Unexpected format for serial port : pipe : endpoint : %s : %s", res, config) + } + if res := strings.ToLower(comp[2]); res != "app" && res != "vm" { + return nil, fmt.Errorf("Unexpected format for serial port : pipe : host : %s : %s", res, config) + } + res := &serialConfigPipe{ + filename: comp[0], + endpoint: comp[1], + host: map[string]string{"app": "TRUE", "vm": "FALSE"}[strings.ToLower(comp[2])], + yield: "FALSE", + } + if len(comp) == 4 { + res.yield = strings.ToUpper(comp[3]) + } + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil, fmt.Errorf("Unexpected format for serial port : pipe : yield : %s : %s", res.yield, config) + } + return &serialUnion{serialType: res, pipe: res}, nil - case "FILE": - comp := strings.Split(formatOptions, ",") - if len(comp) > 2 { - return nil,fmt.Errorf("Unexpected format for serial port : file : %s", config) - } + case "FILE": + comp := strings.Split(formatOptions, ",") + if len(comp) > 2 { + return nil, fmt.Errorf("Unexpected format for serial port : file : %s", config) + } - res := &serialConfigFile{ yield : "FALSE" } + res := &serialConfigFile{yield: "FALSE"} - res.filename = filepath.FromSlash(comp[0]) + res.filename = filepath.FromSlash(comp[0]) - res.yield = map[bool]string{true:strings.ToUpper(comp[0]), false:"FALSE"}[len(comp) > 1] - if res.yield != "TRUE" && res.yield != "FALSE" { - return nil,fmt.Errorf("Unexpected format for serial port : file : yield : %s : %s", res.yield, config) - } + res.yield = map[bool]string{true: strings.ToUpper(comp[0]), false: "FALSE"}[len(comp) > 1] + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil, fmt.Errorf("Unexpected format for serial port : file : yield : %s : %s", res.yield, config) + } - return &serialUnion{serialType:res, file:res},nil + return &serialUnion{serialType: res, file: res}, nil - case "DEVICE": - comp := strings.Split(formatOptions, ",") - if len(comp) > 2 { - return nil,fmt.Errorf("Unexpected format for serial port : device : %s", config) - } + case "DEVICE": + comp := strings.Split(formatOptions, ",") + if len(comp) > 2 { + return nil, fmt.Errorf("Unexpected format for serial port : device : %s", config) + } - res := new(serialConfigDevice) + res := new(serialConfigDevice) - if len(comp) == 2 { - res.devicename = map[bool]string{true:filepath.FromSlash(comp[0]), false:defaultSerialPort}[len(comp[0]) > 0] - res.yield = strings.ToUpper(comp[1]) - } else if len(comp) == 1 { - res.devicename = map[bool]string{true:filepath.FromSlash(comp[0]), false:defaultSerialPort}[len(comp[0]) > 0] - res.yield = "FALSE" - } else if len(comp) == 0 { - res.devicename = defaultSerialPort - res.yield = "FALSE" - } - - if res.yield != "TRUE" && res.yield != "FALSE" { - return nil,fmt.Errorf("Unexpected format for serial port : device : yield : %s : %s", res.yield, config) - } - - return &serialUnion{serialType:res, device:res},nil - - case "AUTO": - res := new(serialConfigAuto) + if len(comp) == 2 { + res.devicename = map[bool]string{true: filepath.FromSlash(comp[0]), false: defaultSerialPort}[len(comp[0]) > 0] + res.yield = strings.ToUpper(comp[1]) + } else if len(comp) == 1 { + res.devicename = map[bool]string{true: filepath.FromSlash(comp[0]), false: defaultSerialPort}[len(comp[0]) > 0] + res.yield = "FALSE" + } else if len(comp) == 0 { res.devicename = defaultSerialPort + res.yield = "FALSE" + } - if len(formatOptions) > 0 { - res.yield = strings.ToUpper(formatOptions) - } else { - res.yield = "FALSE" - } + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil, fmt.Errorf("Unexpected format for serial port : device : yield : %s : %s", res.yield, config) + } - if res.yield != "TRUE" && res.yield != "FALSE" { - return nil,fmt.Errorf("Unexpected format for serial port : auto : yield : %s : %s", res.yield, config) - } + return &serialUnion{serialType: res, device: res}, nil - return &serialUnion{serialType:res, auto:res},nil + case "AUTO": + res := new(serialConfigAuto) + res.devicename = defaultSerialPort - default: - return nil,fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(formatType), config) + if len(formatOptions) > 0 { + res.yield = strings.ToUpper(formatOptions) + } else { + res.yield = "FALSE" + } + + if res.yield != "TRUE" && res.yield != "FALSE" { + return nil, fmt.Errorf("Unexpected format for serial port : auto : yield : %s : %s", res.yield, config) + } + + return &serialUnion{serialType: res, auto: res}, nil + + default: + return nil, fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(formatType), config) } } /* parallel port */ type parallelUnion struct { parallelType interface{} - file *parallelPortFile - device *parallelPortDevice - auto *parallelPortAuto + file *parallelPortFile + device *parallelPortDevice + auto *parallelPortAuto } type parallelPortFile struct { filename string } type parallelPortDevice struct { bidirectional string - devicename string + devicename string } type parallelPortAuto struct { bidirectional string } -func unformat_parallel(config string) (*parallelUnion,error) { +func unformat_parallel(config string) (*parallelUnion, error) { input := strings.SplitN(config, ":", 2) if len(input) < 1 { - return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) + return nil, fmt.Errorf("Unexpected format for parallel port: %s", config) } var formatType, formatOptions string @@ -233,39 +234,44 @@ func unformat_parallel(config string) (*parallelUnion,error) { } switch strings.ToUpper(formatType) { - case "FILE": - res := &parallelPortFile{ filename: filepath.FromSlash(formatOptions) } - return &parallelUnion{ parallelType:res, file: res},nil - case "DEVICE": - comp := strings.Split(formatOptions, ",") - if len(comp) < 1 || len(comp) > 2 { - return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) + case "FILE": + res := &parallelPortFile{filename: filepath.FromSlash(formatOptions)} + return &parallelUnion{parallelType: res, file: res}, nil + case "DEVICE": + comp := strings.Split(formatOptions, ",") + if len(comp) < 1 || len(comp) > 2 { + return nil, fmt.Errorf("Unexpected format for parallel port: %s", config) + } + res := new(parallelPortDevice) + res.bidirectional = "FALSE" + res.devicename = filepath.FromSlash(comp[0]) + if len(comp) > 1 { + switch strings.ToUpper(comp[1]) { + case "BI": + res.bidirectional = "TRUE" + case "UNI": + res.bidirectional = "FALSE" + default: + return nil, fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(comp[0]), config) } - res := new(parallelPortDevice) - res.bidirectional = "FALSE" - res.devicename = strings.ToUpper(comp[0]) - if len(comp) > 1 { - switch strings.ToUpper(comp[1]) { - case "BI": res.bidirectional = "TRUE" - case "UNI": res.bidirectional = "FALSE" - default: - return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(comp[0]), config) - } - } - return &parallelUnion{ parallelType:res, device:res },nil + } + return &parallelUnion{parallelType: res, device: res}, nil - case "AUTO": - res := new(parallelPortAuto) - switch strings.ToUpper(formatOptions) { - case "": fallthrough - case "UNI": res.bidirectional = "FALSE" - case "BI": res.bidirectional = "TRUE" - default: - return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(formatOptions), config) - } - return &parallelUnion{ parallelType:res, auto:res },nil + case "AUTO": + res := new(parallelPortAuto) + switch strings.ToUpper(formatOptions) { + case "": + fallthrough + case "UNI": + res.bidirectional = "FALSE" + case "BI": + res.bidirectional = "TRUE" + default: + return nil, fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(formatOptions), config) + } + return &parallelUnion{parallelType: res, auto: res}, nil } - return nil,fmt.Errorf("Unexpected format for parallel port: %s", config) + return nil, fmt.Errorf("Unexpected format for parallel port: %s", config) } /* regular steps */ @@ -348,11 +354,11 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist Version: config.Version, ISOPath: isoPath, - Sound_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.Sound)], - Usb_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.USB)], + Sound_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.Sound)], + Usb_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.USB)], - Serial_Present: "FALSE", - Parallel_Present: "FALSE", + Serial_Present: "FALSE", + Parallel_Present: "FALSE", } /// Check the network type that the user specified @@ -367,7 +373,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist ui.Error(err.Error()) return multistep.ActionHalt } - netmap,res := vmwcommon.ReadNetmapConfig(pathNetmap) + netmap, res := vmwcommon.ReadNetmapConfig(pathNetmap) if res != nil { err := fmt.Errorf("Unable to read netmap conf file: %s: %v", pathNetmap, res) state.Put("error", err) @@ -376,13 +382,13 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } // try and convert the specified network to a device - device,err := netmap.NameIntoDevice(network) + device, err := netmap.NameIntoDevice(network) // success. so we know that it's an actual network type inside netmap.conf if err == nil { templateData.Network_Type = network templateData.Network_Device = device - // we were unable to find the type, so assume it's a custom network device. + // we were unable to find the type, so assume it's a custom network device. } else { templateData.Network_Type = "custom" templateData.Network_Device = network @@ -392,7 +398,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist /// check if serial port has been configured if config.Serial != "" { - serial,err := unformat_serial(config.Serial) + serial, err := unformat_serial(config.Serial) if err != nil { err := fmt.Errorf("Error procesing VMX template: %s", err) state.Put("error", err) @@ -408,35 +414,35 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Serial_Auto = "FALSE" switch serial.serialType.(type) { - case *serialConfigPipe: - templateData.Serial_Type = "pipe" - templateData.Serial_Endpoint = serial.pipe.endpoint - templateData.Serial_Host = serial.pipe.host - templateData.Serial_Yield = serial.pipe.yield - templateData.Serial_Filename = filepath.FromSlash(serial.pipe.filename) - case *serialConfigFile: - templateData.Serial_Type = "file" - templateData.Serial_Filename = filepath.FromSlash(serial.file.filename) - case *serialConfigDevice: - templateData.Serial_Type = "device" - templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename) - case *serialConfigAuto: - templateData.Serial_Type = "device" - templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename) - templateData.Serial_Yield = serial.auto.yield - templateData.Serial_Auto = "TRUE" + case *serialConfigPipe: + templateData.Serial_Type = "pipe" + templateData.Serial_Endpoint = serial.pipe.endpoint + templateData.Serial_Host = serial.pipe.host + templateData.Serial_Yield = serial.pipe.yield + templateData.Serial_Filename = filepath.FromSlash(serial.pipe.filename) + case *serialConfigFile: + templateData.Serial_Type = "file" + templateData.Serial_Filename = filepath.FromSlash(serial.file.filename) + case *serialConfigDevice: + templateData.Serial_Type = "device" + templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename) + case *serialConfigAuto: + templateData.Serial_Type = "device" + templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename) + templateData.Serial_Yield = serial.auto.yield + templateData.Serial_Auto = "TRUE" - default: - err := fmt.Errorf("Error procesing VMX template: %v", serial) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + default: + err := fmt.Errorf("Error procesing VMX template: %v", serial) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } } /// check if parallel port has been configured if config.Parallel != "" { - parallel,err := unformat_parallel(config.Parallel) + parallel, err := unformat_parallel(config.Parallel) if err != nil { err := fmt.Errorf("Error procesing VMX template: %s", err) state.Put("error", err) @@ -446,22 +452,22 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Parallel_Auto = "FALSE" switch parallel.parallelType.(type) { - case *parallelPortFile: - templateData.Parallel_Present = "TRUE" - templateData.Parallel_Filename = filepath.FromSlash(parallel.file.filename) - case *parallelPortDevice: - templateData.Parallel_Present = "TRUE" - templateData.Parallel_Bidirectional = parallel.device.bidirectional - templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename) - case *parallelPortAuto: - templateData.Parallel_Present = "TRUE" - templateData.Parallel_Auto = "TRUE" - templateData.Parallel_Bidirectional = parallel.auto.bidirectional - default: - err := fmt.Errorf("Error procesing VMX template: %v", parallel) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + case *parallelPortFile: + templateData.Parallel_Present = "TRUE" + templateData.Parallel_Filename = filepath.FromSlash(parallel.file.filename) + case *parallelPortDevice: + templateData.Parallel_Present = "TRUE" + templateData.Parallel_Bidirectional = parallel.device.bidirectional + templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename) + case *parallelPortAuto: + templateData.Parallel_Present = "TRUE" + templateData.Parallel_Auto = "TRUE" + templateData.Parallel_Bidirectional = parallel.auto.bidirectional + default: + err := fmt.Errorf("Error procesing VMX template: %v", parallel) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } } diff --git a/builder/vmware/iso/step_create_vmx_test.go b/builder/vmware/iso/step_create_vmx_test.go index e540eee8a..7f5c1d91c 100644 --- a/builder/vmware/iso/step_create_vmx_test.go +++ b/builder/vmware/iso/step_create_vmx_test.go @@ -1,37 +1,37 @@ package iso import ( + "bytes" "fmt" - "os" - "path/filepath" - "strings" + "io/ioutil" "math" "math/rand" - "strconv" - "io/ioutil" - "bytes" + "os" + "path/filepath" "runtime" + "strconv" + "strings" - "testing" "github.com/mitchellh/packer/packer" - "github.com/mitchellh/packer/template" "github.com/mitchellh/packer/provisioner/shell" + "github.com/mitchellh/packer/template" + "testing" ) var vmxTestBuilderConfig = map[string]string{ - "type": `"vmware-iso"`, - "iso_url": `"https://archive.org/download/ut-ttylinux-i686-12.6/ut-ttylinux-i686-12.6.iso"`, + "type": `"vmware-iso"`, + "iso_url": `"https://archive.org/download/ut-ttylinux-i686-12.6/ut-ttylinux-i686-12.6.iso"`, "iso_checksum_type": `"md5"`, - "iso_checksum": `"43c1feeae55a44c6ef694b8eb18408a6"`, - "ssh_username": `"root"`, - "ssh_password": `"password"`, - "ssh_wait_timeout": `"45s"`, - "boot_command": `["<enter><wait5><wait10>","root<enter><wait>password<enter><wait>","udhcpc<enter><wait>"]`, - "shutdown_command": `"/sbin/shutdown -h; exit 0"`, + "iso_checksum": `"43c1feeae55a44c6ef694b8eb18408a6"`, + "ssh_username": `"root"`, + "ssh_password": `"password"`, + "ssh_wait_timeout": `"45s"`, + "boot_command": `["<enter><wait5><wait10>","root<enter><wait>password<enter><wait>","udhcpc<enter><wait>"]`, + "shutdown_command": `"/sbin/shutdown -h; exit 0"`, } var vmxTestProvisionerConfig = map[string]string{ - "type": `"shell"`, + "type": `"shell"`, "inline": `["echo hola mundo"]`, } @@ -40,24 +40,26 @@ const vmxTestTemplate string = `{"builders":[{%s}],"provisioners":[{%s}]}` func tmpnam(prefix string) string { var path string var err error - + const length = 16 - + dir := os.TempDir() max := int(math.Pow(2, float64(length))) - n,err := rand.Intn(max),nil - for path = filepath.Join(dir, prefix + strconv.Itoa(n)); err == nil; _,err = os.Stat(path) { + n, err := rand.Intn(max), nil + for path = filepath.Join(dir, prefix+strconv.Itoa(n)); err == nil; _, err = os.Stat(path) { n = rand.Intn(max) - path = filepath.Join(dir, prefix + strconv.Itoa(n)) + path = filepath.Join(dir, prefix+strconv.Itoa(n)) } return path } -func createFloppyOutput(prefix string) (string,string,error) { +func createFloppyOutput(prefix string) (string, string, error) { output := tmpnam(prefix) - f,err := os.Create(output) - if err != nil { return "","",fmt.Errorf("Unable to create empty %s: %s", output, err) } + f, err := os.Create(output) + if err != nil { + return "", "", fmt.Errorf("Unable to create empty %s: %s", output, err) + } f.Close() vmxData := []string{ @@ -69,18 +71,24 @@ func createFloppyOutput(prefix string) (string,string,error) { } outputFile := strings.Replace(output, "\\", "\\\\", -1) - vmxString := fmt.Sprintf("{" + strings.Join(vmxData, ",") + "}", outputFile) - return output,vmxString,nil + vmxString := fmt.Sprintf("{"+strings.Join(vmxData, ",")+"}", outputFile) + return output, vmxString, nil } -func readFloppyOutput(path string) (string,error) { - f,err := os.Open(path) - if err != nil { return "",fmt.Errorf("Unable to open file %s", path) } +func readFloppyOutput(path string) (string, error) { + f, err := os.Open(path) + if err != nil { + return "", fmt.Errorf("Unable to open file %s", path) + } defer f.Close() - data,err := ioutil.ReadAll(f) - if err != nil { return "",fmt.Errorf("Unable to read file: %s", err) } - if len(data) == 0 { return "", nil } - return string(data[:bytes.IndexByte(data,0)]),nil + data, err := ioutil.ReadAll(f) + if err != nil { + return "", fmt.Errorf("Unable to read file: %s", err) + } + if len(data) == 0 { + return "", nil + } + return string(data[:bytes.IndexByte(data, 0)]), nil } func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisionerConfig map[string]string) error { @@ -88,72 +96,84 @@ func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisioner // create builder config and update with user-supplied options cfgBuilder := map[string]string{} - for k,v := range vmxTestBuilderConfig { cfgBuilder[k] = v } - for k,v := range builderConfig { cfgBuilder[k] = v } + for k, v := range vmxTestBuilderConfig { + cfgBuilder[k] = v + } + for k, v := range builderConfig { + cfgBuilder[k] = v + } // convert our builder config into a single sprintfable string builderLines := []string{} - for k,v := range cfgBuilder { + for k, v := range cfgBuilder { builderLines = append(builderLines, fmt.Sprintf(`"%s":%s`, k, v)) } // create provisioner config and update with user-supplied options cfgProvisioner := map[string]string{} - for k,v := range vmxTestProvisionerConfig { cfgProvisioner[k] = v } - for k,v := range provisionerConfig { cfgProvisioner[k] = v } + for k, v := range vmxTestProvisionerConfig { + cfgProvisioner[k] = v + } + for k, v := range provisionerConfig { + cfgProvisioner[k] = v + } // convert our provisioner config into a single sprintfable string provisionerLines := []string{} - for k,v := range cfgProvisioner { + for k, v := range cfgProvisioner { provisionerLines = append(provisionerLines, fmt.Sprintf(`"%s":%s`, k, v)) } // and now parse them into a template - configString := fmt.Sprintf(vmxTestTemplate, strings.Join(builderLines,`,`), strings.Join(provisionerLines,`,`)) + configString := fmt.Sprintf(vmxTestTemplate, strings.Join(builderLines, `,`), strings.Join(provisionerLines, `,`)) - tpl,err := template.Parse(strings.NewReader(configString)) + tpl, err := template.Parse(strings.NewReader(configString)) if err != nil { t.Fatalf("Unable to parse test config: %s", err) } // create our config to test the vmware-iso builder components := packer.ComponentFinder{ - Builder: func(n string) (packer.Builder,error) { - return &Builder{},nil + Builder: func(n string) (packer.Builder, error) { + return &Builder{}, nil }, - Hook: func(n string) (packer.Hook,error) { - return &packer.DispatchHook{},nil + Hook: func(n string) (packer.Hook, error) { + return &packer.DispatchHook{}, nil }, - PostProcessor: func(n string) (packer.PostProcessor,error) { - return &packer.MockPostProcessor{},nil + PostProcessor: func(n string) (packer.PostProcessor, error) { + return &packer.MockPostProcessor{}, nil }, - Provisioner: func(n string) (packer.Provisioner,error) { - return &shell.Provisioner{},nil + Provisioner: func(n string) (packer.Provisioner, error) { + return &shell.Provisioner{}, nil }, } config := packer.CoreConfig{ - Template: tpl, + Template: tpl, Components: components, } // create a core using our template - core,err := packer.NewCore(&config) - if err != nil { t.Fatalf("Unable to create core: %s", err) } + core, err := packer.NewCore(&config) + if err != nil { + t.Fatalf("Unable to create core: %s", err) + } // now we can prepare our build - b,err := core.Build("vmware-iso") - if err != nil { t.Fatalf("Unable to create build: %s", err) } + b, err := core.Build("vmware-iso") + if err != nil { + t.Fatalf("Unable to create build: %s", err) + } - warn,err := b.Prepare() + warn, err := b.Prepare() if len(warn) > 0 { - for _,w := range warn { + for _, w := range warn { t.Logf("Configuration warning: %s", w) } } // and then finally build it cache := &packer.FileCache{CacheDir: os.TempDir()} - artifacts,err := b.Run(ui, cache) + artifacts, err := b.Run(ui, cache) if err != nil { t.Fatalf("Failed to build artifact: %s", err) } @@ -166,7 +186,7 @@ func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisioner // otherwise some number of errors happened t.Logf("Unexpected number of artifacts returned: %d", len(artifacts)) errors := make([]error, 0) - for _,artifact := range artifacts { + for _, artifact := range artifacts { if err := artifact.Destroy(); err != nil { errors = append(errors, err) } @@ -186,9 +206,11 @@ func TestStepCreateVmx_SerialFile(t *testing.T) { } error := setupVMwareBuild(t, serialConfig, map[string]string{}) - if error != nil { t.Errorf("Unable to read file: %s", error) } + if error != nil { + t.Errorf("Unable to read file: %s", error) + } - f,err := os.Stat(tmpfile) + f, err := os.Stat(tmpfile) if err != nil { t.Errorf("VMware builder did not create a file for serial port: %s", err) } @@ -216,19 +238,29 @@ func TestStepCreateVmx_SerialPort(t *testing.T) { } // where to write output - output,vmxData,err := createFloppyOutput("SerialPortOutput.") - if err != nil { t.Fatalf("Error creating output: %s", err) } - defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + output, vmxData, err := createFloppyOutput("SerialPortOutput.") + if err != nil { + t.Fatalf("Error creating output: %s", err) + } + defer func() { + if _, err := os.Stat(output); err == nil { + os.Remove(output) + } + }() config["vmx_data"] = vmxData t.Logf("Preparing to write output to %s", output) // whee err = setupVMwareBuild(t, config, provision) - if err != nil { t.Errorf("%s", err) } + if err != nil { + t.Errorf("%s", err) + } // check the output - data,err := readFloppyOutput(output) - if err != nil { t.Errorf("%s", err) } + data, err := readFloppyOutput(output) + if err != nil { + t.Errorf("%s", err) + } if data != "serial8250: ttyS1 at\n" { t.Errorf("Serial port not detected : %v", data) @@ -251,19 +283,29 @@ func TestStepCreateVmx_ParallelPort(t *testing.T) { } // where to write output - output,vmxData,err := createFloppyOutput("ParallelPortOutput.") - if err != nil { t.Fatalf("Error creating output: %s", err) } - defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + output, vmxData, err := createFloppyOutput("ParallelPortOutput.") + if err != nil { + t.Fatalf("Error creating output: %s", err) + } + defer func() { + if _, err := os.Stat(output); err == nil { + os.Remove(output) + } + }() config["vmx_data"] = vmxData t.Logf("Preparing to write output to %s", output) // whee error := setupVMwareBuild(t, config, provision) - if error != nil { t.Errorf("%s", error) } + if error != nil { + t.Errorf("%s", error) + } // check the output - data,err := readFloppyOutput(output) - if err != nil { t.Errorf("%s", err) } + data, err := readFloppyOutput(output) + if err != nil { + t.Errorf("%s", err) + } if data != "parport \n" { t.Errorf("Parallel port not detected : %v", data) @@ -279,19 +321,29 @@ func TestStepCreateVmx_Usb(t *testing.T) { } // where to write output - output,vmxData,err := createFloppyOutput("UsbOutput.") - if err != nil { t.Fatalf("Error creating output: %s", err) } - defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + output, vmxData, err := createFloppyOutput("UsbOutput.") + if err != nil { + t.Fatalf("Error creating output: %s", err) + } + defer func() { + if _, err := os.Stat(output); err == nil { + os.Remove(output) + } + }() config["vmx_data"] = vmxData t.Logf("Preparing to write output to %s", output) // whee error := setupVMwareBuild(t, config, provision) - if error != nil { t.Errorf("%s", error) } + if error != nil { + t.Errorf("%s", error) + } // check the output - data,err := readFloppyOutput(output) - if err != nil { t.Errorf("%s", err) } + data, err := readFloppyOutput(output) + if err != nil { + t.Errorf("%s", err) + } if data != "USB hub found\n" { t.Errorf("USB support not detected : %v", data) @@ -302,24 +354,34 @@ func TestStepCreateVmx_Sound(t *testing.T) { config := map[string]string{ "sound": `"TRUE"`, } - provision := map[string]string { + provision := map[string]string{ "inline": `"cat /proc/modules | egrep -o '^soundcore' > /dev/fd0"`, } // where to write output - output,vmxData,err := createFloppyOutput("SoundOutput.") - if err != nil { t.Fatalf("Error creating output: %s", err) } - defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }() + output, vmxData, err := createFloppyOutput("SoundOutput.") + if err != nil { + t.Fatalf("Error creating output: %s", err) + } + defer func() { + if _, err := os.Stat(output); err == nil { + os.Remove(output) + } + }() config["vmx_data"] = vmxData t.Logf("Preparing to write output to %s", output) // whee error := setupVMwareBuild(t, config, provision) - if error != nil { t.Errorf("Unable to read file: %s", error) } + if error != nil { + t.Errorf("Unable to read file: %s", error) + } // check the output - data,err := readFloppyOutput(output) - if err != nil { t.Errorf("%s", err) } + data, err := readFloppyOutput(output) + if err != nil { + t.Errorf("%s", err) + } if data != "soundcore\n" { t.Errorf("Soundcard not detected : %v", data) From 898b27c16d7f0cb2d8cf0b63384c8b9b4e26a6f6 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 12 Apr 2017 17:41:36 -0500 Subject: [PATCH 0560/1007] Added support for the NONE option to be specified for parallel and serial ports in the vmware iso builder. --- builder/vmware/iso/step_create_vmx.go | 12 ++++++++++++ website/source/docs/builders/vmware-iso.html.md | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 0261123a6..207d38caa 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -196,6 +196,9 @@ func unformat_serial(config string) (*serialUnion, error) { return &serialUnion{serialType: res, auto: res}, nil + case "NONE": + return &serialUnion{serialType: nil}, nil + default: return nil, fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(formatType), config) } @@ -270,7 +273,11 @@ func unformat_parallel(config string) (*parallelUnion, error) { return nil, fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(formatOptions), config) } return &parallelUnion{parallelType: res, auto: res}, nil + + case "NONE": + return &parallelUnion{parallelType: nil}, nil } + return nil, fmt.Errorf("Unexpected format for parallel port: %s", config) } @@ -431,6 +438,8 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename) templateData.Serial_Yield = serial.auto.yield templateData.Serial_Auto = "TRUE" + case nil: + break default: err := fmt.Errorf("Error procesing VMX template: %v", serial) @@ -463,6 +472,9 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Parallel_Present = "TRUE" templateData.Parallel_Auto = "TRUE" templateData.Parallel_Bidirectional = parallel.auto.bidirectional + case nil: + break + default: err := fmt.Errorf("Error procesing VMX template: %v", parallel) state.Put("error", err) diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 44285a850..95ab31bef 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -207,7 +207,7 @@ builder. - `parallel` (string) - This specifies a parallel port to add to the VM. It has the format of `Type:option1,option2,...`. Type can be one of the - following values: "FILE", "DEVICE", or "AUTO". + following values: "FILE", "DEVICE", "AUTO", or "NONE". * `FILE:path` - Specifies the path to the local file to be used for the parallel port. @@ -217,6 +217,7 @@ builder. parallel port. Direction can be `BI` to specify bidirectional communication or `UNI` to specify unidirectional communication. + * `NONE` - Specifies to not use a parallel port. (default) - `remote_cache_datastore` (string) - The path to the datastore where supporting files will be stored during the build on the remote machine. By @@ -254,7 +255,7 @@ builder. - `serial` (string) - This specifies a serial port to add to the VM. It has a format of `Type:option1,option2,...`. The field `Type` can be one - of the following values: `FILE`, `DEVICE`, `PIPE`, or `AUTO`. + of the following values: `FILE`, `DEVICE`, `PIPE`, `AUTO`, or `NONE`. * `FILE:path(,yield)` - Specifies the path to the local file to be used as the serial port. @@ -285,6 +286,7 @@ builder. * `yield` (bool) - This is an optional boolean that specifies whether the vm should yield the cpu when polling the port. By default, the builder will assume this as `FALSE`. + * `NONE` - Specifies to not use a serial port. (default) - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty From 75fbfa0763bf94b2456d041a6649ce235770d870 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 13 Apr 2017 17:39:55 -0500 Subject: [PATCH 0561/1007] Replaced a hacky type assertion in the VMware builder with a call to Driver.GetVmwareDriver() that returns the driver-specific structure for ip and addressing information. Also implemented the addressing functions for the ESXi driver interface. This fixes an issue where a driver might not have defined a VmwareDriver by forcing a developer to implement it via the standard Driver interface. --- builder/vmware/common/driver.go | 1 + builder/vmware/common/driver_fusion5.go | 4 + builder/vmware/common/driver_fusion6.go | 4 + builder/vmware/common/driver_player5.go | 4 + builder/vmware/common/driver_player6.go | 4 + builder/vmware/common/driver_workstation10.go | 4 + builder/vmware/common/driver_workstation9.go | 4 + builder/vmware/iso/driver_esx5.go | 101 +++++++++++++++++- builder/vmware/iso/step_create_vmx.go | 2 +- 9 files changed, 126 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 745b48d69..3e38442a2 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -64,6 +64,7 @@ type Driver interface { /// These methods are generally implemented by the VmwareDriver /// structure within this file. A driver implementation can /// reimplement these, though, if it wants. + GetVmwareDriver() VmwareDriver // Get the guest hw address for the vm GuestAddress(multistep.StateBag) (string, error) diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index 4bc5ae301..e8c49155c 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -173,3 +173,7 @@ const fusionSuppressPlist = `<?xml version="1.0" encoding="UTF-8"?> <true/> </dict> </plist>` + +func (d *Fusion5Driver) GetVmwareDriver() VmwareDriver { + return d.VmwareDriver +} diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index af42c7ef9..2f0563eb5 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -68,3 +68,7 @@ func (d *Fusion6Driver) Verify() error { return compareVersions(matches[1], VMWARE_FUSION_VERSION, "Fusion Professional") } + +func (d *Fusion6Driver) GetVmwareDriver() VmwareDriver { + return d.Fusion5Driver.VmwareDriver +} diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 240b44a11..04fb4e897 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -209,3 +209,7 @@ func (d *Player5Driver) ToolsIsoPath(flavor string) string { func (d *Player5Driver) ToolsInstall() error { return nil } + +func (d *Player5Driver) GetVmwareDriver() VmwareDriver { + return d.VmwareDriver +} diff --git a/builder/vmware/common/driver_player6.go b/builder/vmware/common/driver_player6.go index d1cc7be88..1ccb84b85 100644 --- a/builder/vmware/common/driver_player6.go +++ b/builder/vmware/common/driver_player6.go @@ -35,3 +35,7 @@ func (d *Player6Driver) Verify() error { return playerVerifyVersion(VMWARE_PLAYER_VERSION) } + +func (d *Player6Driver) GetVmwareDriver() VmwareDriver { + return d.Player5Driver.VmwareDriver +} diff --git a/builder/vmware/common/driver_workstation10.go b/builder/vmware/common/driver_workstation10.go index 7e6ac8b8f..471fce37d 100644 --- a/builder/vmware/common/driver_workstation10.go +++ b/builder/vmware/common/driver_workstation10.go @@ -33,3 +33,7 @@ func (d *Workstation10Driver) Verify() error { return workstationVerifyVersion(VMWARE_WS_VERSION) } + +func (d *Workstation10Driver) GetVmwareDriver() VmwareDriver { + return d.Workstation9Driver.VmwareDriver +} diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index 8a6eb5556..af2d7df35 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -170,3 +170,7 @@ func (d *Workstation9Driver) ToolsIsoPath(flavor string) string { func (d *Workstation9Driver) ToolsInstall() error { return nil } + +func (d *Workstation9Driver) GetVmwareDriver() VmwareDriver { + return d.VmwareDriver +} diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 6df8271f6..d2f00ea81 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -26,7 +26,7 @@ import ( // ESX5 driver talks to an ESXi5 hypervisor remotely over SSH to build // virtual machines. This driver can only manage one machine at a time. type ESX5Driver struct { - vmwcommon.VmwareDriver + base vmwcommon.VmwareDriver Host string Port uint @@ -173,6 +173,101 @@ func (d *ESX5Driver) HostIP(multistep.StateBag) (string, error) { return host, err } +func (d *ESX5Driver) GuestIP(multistep.StateBag) (string, error) { + // GuestIP is defined by the user as d.Host..but let's validate it just to be sure + conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", d.Host, d.Port)) + defer conn.Close() + if err != nil { + return "", err + } + + host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) + return host, err +} + +func (d *ESX5Driver) HostAddress(multistep.StateBag) (string, error) { + // make a connection + conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", d.Host, d.Port)) + defer conn.Close() + if err != nil { + return "", err + } + + // get the local address (the host) + host, _, err := net.SplitHostPort(conn.LocalAddr().String()) + if err != nil { + return "", fmt.Errorf("Unable to determine host address for ESXi: %v", err) + } + + // iterate through all the interfaces.. + interfaces, err := net.Interfaces() + if err != nil { + return "", fmt.Errorf("Unable to enumerate host interfaces : %v", err) + } + + for _, intf := range interfaces { + addrs, err := intf.Addrs() + if err != nil { + continue + } + + // ..checking to see if any if it's addrs match the host address + for _, addr := range addrs { + if addr.String() == host { // FIXME: Is this the proper way to compare two HardwareAddrs? + return intf.HardwareAddr.String(), nil + } + } + } + + // ..unfortunately nothing was found + return "", fmt.Errorf("Unable to locate interface matching host address in ESXi: %v", host) +} + +func (d *ESX5Driver) GuestAddress(multistep.StateBag) (string, error) { + // list all the interfaces on the esx host + r, err := d.esxcli("network", "ip", "interface", "list") + if err != nil { + return "", fmt.Errorf("Could not retrieve network interfaces for ESXi: %v", err) + } + + // rip out the interface name and the MAC address from the csv output + addrs := make(map[string]string) + for record, err := r.read(); record != nil && err == nil; record, err = r.read() { + if strings.ToUpper(record["Enabled"]) != "TRUE" { + continue + } + addrs[record["Name"]] = record["MAC Address"] + } + + // list all the addresses on the esx host + r, err = d.esxcli("network", "ip", "interface", "ipv4", "get") + if err != nil { + return "", fmt.Errorf("Could not retrieve network addresses for ESXi: %v", err) + } + + // figure out the interface name that matches the specified d.Host address + var intf string + intf = "" + for record, err := r.read(); record != nil && err == nil; record, err = r.read() { + if record["IPv4 Address"] == d.Host && record["Name"] != "" { + intf = record["Name"] + break + } + } + if intf == "" { + return "", fmt.Errorf("Unable to find matching address for ESXi guest") + } + + // find the MAC address according to the interface name + result, ok := addrs[intf] + if !ok { + return "", fmt.Errorf("Unable to find address for ESXi guest interface") + } + + // ..and we're good + return result, nil +} + func (d *ESX5Driver) VNCAddress(_ string, portMin, portMax uint) (string, uint, error) { var vncPort uint @@ -530,6 +625,10 @@ func (d *ESX5Driver) esxcli(args ...string) (*esxcliReader, error) { return &esxcliReader{r, header}, nil } +func (d *ESX5Driver) GetVmwareDriver() vmwcommon.VmwareDriver { + return d.base +} + type esxcliReader struct { cr *csv.Reader header []string diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 207d38caa..bf6bb3d6c 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -370,7 +370,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist /// Check the network type that the user specified network := config.Network - driver := state.Get("driver").(vmwcommon.VmwareDriver) + driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver() // read netmap config pathNetmap := driver.NetmapConfPath() From 6423525a33562ca891fef4c8ab89b833a9f70971 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 13 Apr 2017 19:10:40 -0500 Subject: [PATCH 0562/1007] Updated imports of github.com/mitchellh/packer to new naming scheme github.com/hashicorp/packer --- builder/vmware/iso/driver_esx5.go | 2 +- builder/vmware/iso/step_create_vmx_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index d2f00ea81..3f18656d0 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -14,12 +14,12 @@ import ( "strings" "time" + vmwcommon "github.com/hashicorp/packer/builder/vmware/common" commonssh "github.com/hashicorp/packer/common/ssh" "github.com/hashicorp/packer/communicator/ssh" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" - vmwcommon "github.com/mitchellh/packer/builder/vmware/common" gossh "golang.org/x/crypto/ssh" ) diff --git a/builder/vmware/iso/step_create_vmx_test.go b/builder/vmware/iso/step_create_vmx_test.go index 7f5c1d91c..31177957f 100644 --- a/builder/vmware/iso/step_create_vmx_test.go +++ b/builder/vmware/iso/step_create_vmx_test.go @@ -12,9 +12,9 @@ import ( "strconv" "strings" - "github.com/mitchellh/packer/packer" - "github.com/mitchellh/packer/provisioner/shell" - "github.com/mitchellh/packer/template" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/provisioner/shell" + "github.com/hashicorp/packer/template" "testing" ) From 258804106bff27a6b9d8fd8efed727fb2ce289f4 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 13 Apr 2017 19:19:43 -0500 Subject: [PATCH 0563/1007] Added missing GetVmwareDriver() method to VMware Builder's DriverMock. --- builder/vmware/common/driver_mock.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 562eab382..8b533db88 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -206,3 +206,20 @@ func (d *DriverMock) Verify() error { d.VerifyCalled = true return d.VerifyErr } + +func (d *DriverMock) GetVmwareDriver() VmwareDriver { + var state VmwareDriver + state.DhcpLeasesPath = func(string) string { + return "/path/to/dhcp.leases" + } + state.DhcpConfPath = func(string) string { + return "/path/to/dhcp.conf" + } + state.VmnetnatConfPath = func(string) string { + return "/path/to/vmnetnat.conf" + } + state.NetmapConfPath = func() string { + return "/path/to/netmap.conf" + } + return state +} From 58ebc5c9a5cc932678f7b1624171a4704ea133fc Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 13 Apr 2017 20:01:10 -0500 Subject: [PATCH 0564/1007] When specifying NONE for serial or parallel in the VMware builder, disable the serial and parallel port devices entirely. --- builder/vmware/iso/step_create_vmx.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index bf6bb3d6c..137b0c736 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -404,7 +404,9 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist state.Put("vmnetwork", network) /// check if serial port has been configured - if config.Serial != "" { + if config.Serial == "" { + templateData.Serial_Present = "FALSE" + } else { serial, err := unformat_serial(config.Serial) if err != nil { err := fmt.Errorf("Error procesing VMX template: %s", err) @@ -439,6 +441,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Serial_Yield = serial.auto.yield templateData.Serial_Auto = "TRUE" case nil: + templateData.Serial_Present = "FALSE" break default: @@ -450,7 +453,9 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } /// check if parallel port has been configured - if config.Parallel != "" { + if config.Parallel == "" { + templateData.Parallel_Present = "FALSE" + } else { parallel, err := unformat_parallel(config.Parallel) if err != nil { err := fmt.Errorf("Error procesing VMX template: %s", err) @@ -473,6 +478,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.Parallel_Auto = "TRUE" templateData.Parallel_Bidirectional = parallel.auto.bidirectional case nil: + templateData.Parallel_Present = "FALSE" break default: From 029c357d8c52e86d6733b6d342da3c55d8fecbc6 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sat, 17 Jun 2017 15:35:58 -0500 Subject: [PATCH 0565/1007] Modified some tests to require the PACKER_ACC environment variable to be set before executing them. This turns them into acceptance tests as per CONTRIBUTING.md. --- builder/vmware/common/step_shutdown_test.go | 4 ++++ builder/vmware/iso/step_create_vmx_test.go | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/builder/vmware/common/step_shutdown_test.go b/builder/vmware/common/step_shutdown_test.go index ed0eae486..ff775f2f2 100644 --- a/builder/vmware/common/step_shutdown_test.go +++ b/builder/vmware/common/step_shutdown_test.go @@ -116,6 +116,10 @@ func TestStepShutdown_noCommand(t *testing.T) { } func TestStepShutdown_locks(t *testing.T) { + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.") + } + state := testStepShutdownState(t) step := new(StepShutdown) step.Testing = true diff --git a/builder/vmware/iso/step_create_vmx_test.go b/builder/vmware/iso/step_create_vmx_test.go index 31177957f..7553dff82 100644 --- a/builder/vmware/iso/step_create_vmx_test.go +++ b/builder/vmware/iso/step_create_vmx_test.go @@ -199,6 +199,10 @@ func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisioner } func TestStepCreateVmx_SerialFile(t *testing.T) { + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.") + } + tmpfile := tmpnam("SerialFileInput.") serialConfig := map[string]string{ @@ -223,6 +227,10 @@ func TestStepCreateVmx_SerialFile(t *testing.T) { } func TestStepCreateVmx_SerialPort(t *testing.T) { + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.") + } + var defaultSerial string if runtime.GOOS == "windows" { defaultSerial = "COM1" @@ -268,6 +276,10 @@ func TestStepCreateVmx_SerialPort(t *testing.T) { } func TestStepCreateVmx_ParallelPort(t *testing.T) { + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.") + } + var defaultParallel string if runtime.GOOS == "windows" { defaultParallel = "LPT1" @@ -313,6 +325,10 @@ func TestStepCreateVmx_ParallelPort(t *testing.T) { } func TestStepCreateVmx_Usb(t *testing.T) { + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.") + } + config := map[string]string{ "usb": `"TRUE"`, } @@ -351,6 +367,10 @@ func TestStepCreateVmx_Usb(t *testing.T) { } func TestStepCreateVmx_Sound(t *testing.T) { + if os.Getenv("PACKER_ACC") == "" { + t.Skip("This test is only run with PACKER_ACC=1 due to the requirement of access to the VMware binaries.") + } + config := map[string]string{ "sound": `"TRUE"`, } From 8cc0776f3a0d5335a5ef1eb5b35a1f19121fb5e4 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sun, 10 Sep 2017 16:02:45 -0500 Subject: [PATCH 0566/1007] Fixed oversight in VMware builder's mock-driver that neglected to initialize 'HostAddressResult'. --- builder/vmware/common/driver_mock.go | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 8b533db88..9c63a7bf9 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -1,6 +1,7 @@ package common import ( + "net" "sync" "github.com/hashicorp/packer/helper/multistep" @@ -127,13 +128,41 @@ func (d *DriverMock) CommHost(state multistep.StateBag) (string, error) { return d.CommHostResult, d.CommHostErr } +func MockInterface() net.Interface { + interfaces, err := net.Interfaces() + + // Build a dummy interface due to being unable to enumerate interfaces + if err != nil || len(interfaces) == 0 { + return net.Interface{ + Index: 0, + MTU: -1, + Name: "dummy", + HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0}, + Flags: net.FlagLoopback, + } + } + + // Find the first loopback interface + for _, intf := range interfaces { + if intf.Flags&net.FlagLoopback == net.FlagLoopback { + return intf + } + } + + // Fall-back to just the first one + return interfaces[0] +} + func (d *DriverMock) HostAddress(state multistep.StateBag) (string, error) { + intf := MockInterface() + d.HostAddressResult = intf.HardwareAddr.String() d.HostAddressCalled = true d.HostAddressState = state return d.HostAddressResult, d.HostAddressErr } func (d *DriverMock) HostIP(state multistep.StateBag) (string, error) { + d.HostIPResult = "127.0.0.1" d.HostIPCalled = true d.HostIPState = state return d.HostIPResult, d.HostIPErr From 069d00f70b871ded6517a5034aa7a4c1c5b7ccfc Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Mon, 16 Oct 2017 11:59:10 -0500 Subject: [PATCH 0567/1007] Added the paths suggested by @phekmat and @SwampDragons for VMware Fusion... Although parser for the new mapper format is likely to be needed still. --- builder/vmware/common/driver_fusion5.go | 13 ++++++++++++- builder/vmware/common/driver_fusion6.go | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index e8c49155c..c6b3780dc 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -141,10 +141,21 @@ func (d *Fusion5Driver) Verify() error { return err } - // default paths + libpath := filepath.Join("Library", "Preferences", "VMware Fusion") + d.VmwareDriver.DhcpLeasesPath = func(device string) string { return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases" } + d.VmwareDriver.DhcpConfPath = func(device string) string { + return filepath.Join(libpath, device, "dhcpd.conf") + } + d.VmwareDriver.VmnetnatConfPath = func(device string) string { + return filepath.Join(libpath, device, "nat.conf") + } + d.VmwareDriver.NetmapConfPath = func() string { + // FIXME: Suggested by @phekmat. This will need another parser to be implemented. + return filepath.Join(libpath, "networking") + } return nil } diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index 2f0563eb5..e68bb0de4 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -66,6 +66,23 @@ func (d *Fusion6Driver) Verify() error { } log.Printf("Detected VMware version: %s", matches[1]) + libpath := filepath.Join("Library", "Preferences", "VMware Fusion") + + d.VmwareDriver.DhcpLeasesPath = func(device string) string { + return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases" + } + d.VmwareDriver.DhcpConfPath = func(device string) string { + return filepath.Join(libpath, device, "dhcpd.conf") + } + + d.VmwareDriver.VmnetnatConfPath = func(device string) string { + return filepath.Join(libpath, device, "nat.conf") + } + d.VmwareDriver.NetmapConfPath = func() string { + // FIXME: Suggested by @phekmat. This will need another parser to be implemented. + return filepath.Join(libpath, "networking") + } + return compareVersions(matches[1], VMWARE_FUSION_VERSION, "Fusion Professional") } From b2fec18b1e32dc37932323d84156fa5b5d1a8d8a Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Mon, 23 Oct 2017 20:26:16 -0500 Subject: [PATCH 0568/1007] Added parser for VMware Fusion's networking file. Replaced VmwareDriver's NetmapConfPath with a NetworkMapperInterface in order to handle the differences between VMware Fusion and the rest of the VMware suite. --- builder/vmware/common/driver.go | 29 +- builder/vmware/common/driver_fusion5.go | 16 +- builder/vmware/common/driver_fusion6.go | 16 +- builder/vmware/common/driver_mock.go | 18 +- builder/vmware/common/driver_parser.go | 847 ++++++++++++++++++- builder/vmware/common/driver_player5.go | 15 +- builder/vmware/common/driver_workstation9.go | 15 +- builder/vmware/iso/step_create_vmx.go | 12 +- 8 files changed, 922 insertions(+), 46 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 3e38442a2..6b5cfde1f 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -274,7 +274,10 @@ type VmwareDriver struct { DhcpLeasesPath func(string) string DhcpConfPath func(string) string VmnetnatConfPath func(string) string - NetmapConfPath func() string + + /// This method returns an object with the NetworkNameMapper interface + /// that maps network to device and vice-versa. + NetworkMapper func() (NetworkNameMapper, error) } func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string, error) { @@ -304,12 +307,8 @@ func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string, error) { func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { - // read netmap config - pathNetmap := d.NetmapConfPath() - if _, err := os.Stat(pathNetmap); err != nil { - return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) - } - netmap, err := ReadNetmapConfig(pathNetmap) + // grab network mapper + netmap, err := d.NetworkMapper() if err != nil { return "", err } @@ -401,12 +400,8 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { - // parse network<->device mapping - pathNetmap := d.NetmapConfPath() - if _, err := os.Stat(pathNetmap); err != nil { - return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) - } - netmap, err := ReadNetmapConfig(pathNetmap) + // grab mapper for converting network<->device + netmap, err := d.NetworkMapper() if err != nil { return "", err } @@ -471,12 +466,8 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { - // parse network<->device mapping - pathNetmap := d.NetmapConfPath() - if _, err := os.Stat(pathNetmap); err != nil { - return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) - } - netmap, err := ReadNetmapConfig(pathNetmap) + // grab mapper for converting network<->device + netmap, err := d.NetworkMapper() if err != nil { return "", err } diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index c6b3780dc..c450e1f61 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -152,9 +152,19 @@ func (d *Fusion5Driver) Verify() error { d.VmwareDriver.VmnetnatConfPath = func(device string) string { return filepath.Join(libpath, device, "nat.conf") } - d.VmwareDriver.NetmapConfPath = func() string { - // FIXME: Suggested by @phekmat. This will need another parser to be implemented. - return filepath.Join(libpath, "networking") + d.VmwareDriver.NetworkMapper = func() (NetworkNameMapper, error) { + pathNetworking := filepath.Join(libpath, "networking") + if _, err := os.Stat(pathNetworking); err != nil { + return nil, fmt.Errorf("Could not find networking conf file: %s", pathNetworking) + } + + fd, err := os.Open(pathNetworking) + if err != nil { + return nil, err + } + defer fd.Close() + + return ReadNetworkingConfig(fd) } return nil diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index e68bb0de4..62dd7b218 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -78,9 +78,19 @@ func (d *Fusion6Driver) Verify() error { d.VmwareDriver.VmnetnatConfPath = func(device string) string { return filepath.Join(libpath, device, "nat.conf") } - d.VmwareDriver.NetmapConfPath = func() string { - // FIXME: Suggested by @phekmat. This will need another parser to be implemented. - return filepath.Join(libpath, "networking") + d.VmwareDriver.NetworkMapper = func() (NetworkNameMapper, error) { + pathNetworking := filepath.Join(libpath, "networking") + if _, err := os.Stat(pathNetworking); err != nil { + return nil, fmt.Errorf("Could not find networking conf file: %s", pathNetworking) + } + + fd, err := os.Open(pathNetworking) + if err != nil { + return nil, err + } + defer fd.Close() + + return ReadNetworkingConfig(fd) } return compareVersions(matches[1], VMWARE_FUSION_VERSION, "Fusion Professional") diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index 9c63a7bf9..f857f4adc 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -92,6 +92,20 @@ type DriverMock struct { VerifyErr error } +type NetworkMapperMock struct { + NameIntoDeviceCalled int + DeviceIntoNameCalled int +} + +func (m NetworkMapperMock) NameIntoDevice(name string) (string, error) { + m.NameIntoDeviceCalled += 1 + return "", nil +} +func (m NetworkMapperMock) DeviceIntoName(device string) (string, error) { + m.DeviceIntoNameCalled += 1 + return "", nil +} + func (d *DriverMock) Clone(dst string, src string) error { d.CloneCalled = true d.CloneDst = dst @@ -247,8 +261,8 @@ func (d *DriverMock) GetVmwareDriver() VmwareDriver { state.VmnetnatConfPath = func(string) string { return "/path/to/vmnetnat.conf" } - state.NetmapConfPath = func() string { - return "/path/to/netmap.conf" + state.NetworkMapper = func() (NetworkNameMapper, error) { + return NetworkMapperMock{}, nil } return state } diff --git a/builder/vmware/common/driver_parser.go b/builder/vmware/common/driver_parser.go index dbf15b5b5..7a026fea8 100644 --- a/builder/vmware/common/driver_parser.go +++ b/builder/vmware/common/driver_parser.go @@ -3,8 +3,11 @@ package common import ( "fmt" "io" + "log" + "math" "net" "os" + "reflect" "sort" "strconv" "strings" @@ -1053,6 +1056,11 @@ func (e *DhcpConfiguration) HostByName(host string) (configDeclaration, error) { /*** Network Map */ type NetworkMap []map[string]string +type NetworkNameMapper interface { + NameIntoDevice(string) (string, error) + DeviceIntoName(string) (string, error) +} + func ReadNetworkMap(fd *os.File) (NetworkMap, error) { fromfile, eof := consumeFile(fd) @@ -1066,16 +1074,16 @@ func ReadNetworkMap(fd *os.File) (NetworkMap, error) { return result, nil } -func (e *NetworkMap) NameIntoDevice(name string) (string, error) { - for _, val := range *e { +func (e NetworkMap) NameIntoDevice(name string) (string, error) { + for _, val := range e { if strings.ToLower(val["name"]) == strings.ToLower(name) { return val["device"], nil } } return "", fmt.Errorf("Network name not found : %v", name) } -func (e *NetworkMap) DeviceIntoName(device string) (string, error) { - for _, val := range *e { +func (e NetworkMap) DeviceIntoName(device string) (string, error) { + for _, val := range e { if strings.ToLower(val["device"]) == strings.ToLower(device) { return val["name"], nil } @@ -1091,7 +1099,836 @@ func (e *NetworkMap) repr() string { return strings.Join(result, "\n") } -/** main */ +/*** parser for VMware Fusion's networking file */ +func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) chan string { + var ch byte + var state string + var repeat_newline bool + + out := make(chan string) + go func(out chan string) { + for reading := true; reading; { + select { + case <-eof: + reading = false + + case ch = <-in: + switch ch { + case '\r': + fallthrough + case '\t': + fallthrough + case ' ': + if len(state) == 0 { + continue + } + out <- state + state = "" + case '\n': + if repeat_newline { + continue + } + if len(state) > 0 { + out <- state + } + out <- string(ch) + state = "" + repeat_newline = true + continue + default: + state += string(ch) + } + repeat_newline = false + } + } + if len(state) > 0 { + out <- state + } + }(out) + return out +} + +func splitNetworkingConfig(eof sentinelSignaller, in chan string) chan []string { + var out chan []string + + out = make(chan []string) + go func(out chan []string) { + row := make([]string, 0) + for reading := true; reading; { + select { + case <-eof: + reading = false + + case tk := <-in: + switch tk { + case "\n": + if len(row) > 0 { + out <- row + } + row = make([]string, 0) + default: + row = append(row, tk) + } + } + } + if len(row) > 0 { + out <- row + } + }(out) + return out +} + +/// All token types in networking file. +// VERSION token +type networkingVERSION struct { + value string +} + +func networkingReadVersion(row []string) (*networkingVERSION, error) { + if len(row) != 1 { + return nil, fmt.Errorf("Unexpected format for VERSION entry : %v", row) + } + res := &networkingVERSION{value: row[0]} + if !res.Valid() { + return nil, fmt.Errorf("Unexpected format for VERSION entry : %v", row) + } + return res, nil +} + +func (s networkingVERSION) Repr() string { + if !s.Valid() { + return fmt.Sprintf("VERSION{INVALID=\"%v\"}", s.value) + } + return fmt.Sprintf("VERSION{%f}", s.Number()) +} + +func (s networkingVERSION) Valid() bool { + tokens := strings.SplitN(s.value, "=", 2) + if len(tokens) != 2 || tokens[0] != "VERSION" { + return false + } + + tokens = strings.Split(tokens[1], ",") + if len(tokens) != 2 { + return false + } + + for _, t := range tokens { + _, err := strconv.ParseUint(t, 10, 64) + if err != nil { + return false + } + } + return true +} + +func (s networkingVERSION) Number() float64 { + var result float64 + tokens := strings.SplitN(s.value, "=", 2) + tokens = strings.Split(tokens[1], ",") + + integer, err := strconv.ParseUint(tokens[0], 10, 64) + if err != nil { + integer = 0 + } + result = float64(integer) + + mantissa, err := strconv.ParseUint(tokens[1], 10, 64) + if err != nil { + return result + } + denomination := math.Pow(10.0, float64(len(tokens[1]))) + return result + (float64(mantissa) / denomination) +} + +// VNET_X token +type networkingVNET struct { + value string +} + +func (s networkingVNET) Valid() bool { + if strings.ToUpper(s.value) != s.value { + return false + } + tokens := strings.SplitN(s.value, "_", 3) + if len(tokens) != 3 || tokens[0] != "VNET" { + return false + } + _, err := strconv.ParseUint(tokens[1], 10, 64) + if err != nil { + return false + } + return true +} + +func (s networkingVNET) Number() int { + tokens := strings.SplitN(s.value, "_", 3) + res, err := strconv.Atoi(tokens[1]) + if err != nil { + return ^int(0) + } + return res +} + +func (s networkingVNET) Option() string { + tokens := strings.SplitN(s.value, "_", 3) + if len(tokens) == 3 { + return tokens[2] + } + return "" +} + +func (s networkingVNET) Repr() string { + if !s.Valid() { + tokens := strings.SplitN(s.value, "_", 3) + return fmt.Sprintf("VNET{INVALID=%v}", tokens) + } + return fmt.Sprintf("VNET{%d} %s", s.Number(), s.Option()) +} + +// Interface name +type networkingInterface struct { + name string +} + +func (s networkingInterface) Interface() (*net.Interface, error) { + return net.InterfaceByName(s.name) +} + +// networking command entry types +type networkingCommandEntry_answer struct { + vnet networkingVNET + value string +} +type networkingCommandEntry_remove_answer struct { + vnet networkingVNET +} +type networkingCommandEntry_add_nat_portfwd struct { + vnet int + protocol string + port int + target_host net.IP + target_port int +} +type networkingCommandEntry_remove_nat_portfwd struct { + vnet int + protocol string + port int +} +type networkingCommandEntry_add_dhcp_mac_to_ip struct { + vnet int + mac net.HardwareAddr + ip net.IP +} +type networkingCommandEntry_remove_dhcp_mac_to_ip struct { + vnet int + mac net.HardwareAddr +} +type networkingCommandEntry_add_bridge_mapping struct { + intf networkingInterface + vnet int +} +type networkingCommandEntry_remove_bridge_mapping struct { + intf networkingInterface +} +type networkingCommandEntry_add_nat_prefix struct { + vnet int + prefix int +} +type networkingCommandEntry_remove_nat_prefix struct { + vnet int + prefix int +} + +type networkingCommandEntry struct { + entry interface{} + answer *networkingCommandEntry_answer + remove_answer *networkingCommandEntry_remove_answer + add_nat_portfwd *networkingCommandEntry_add_nat_portfwd + remove_nat_portfwd *networkingCommandEntry_remove_nat_portfwd + add_dhcp_mac_to_ip *networkingCommandEntry_add_dhcp_mac_to_ip + remove_dhcp_mac_to_ip *networkingCommandEntry_remove_dhcp_mac_to_ip + add_bridge_mapping *networkingCommandEntry_add_bridge_mapping + remove_bridge_mapping *networkingCommandEntry_remove_bridge_mapping + add_nat_prefix *networkingCommandEntry_add_nat_prefix + remove_nat_prefix *networkingCommandEntry_remove_nat_prefix +} + +func (e networkingCommandEntry) Name() string { + switch e.entry.(type) { + case networkingCommandEntry_answer: + return "answer" + case networkingCommandEntry_remove_answer: + return "remove_answer" + case networkingCommandEntry_add_nat_portfwd: + return "add_nat_portfwd" + case networkingCommandEntry_remove_nat_portfwd: + return "remove_nat_portfwd" + case networkingCommandEntry_add_dhcp_mac_to_ip: + return "add_dhcp_mac_to_ip" + case networkingCommandEntry_remove_dhcp_mac_to_ip: + return "remove_dhcp_mac_to_ip" + case networkingCommandEntry_add_bridge_mapping: + return "add_bridge_mapping" + case networkingCommandEntry_remove_bridge_mapping: + return "remove_bridge_mapping" + case networkingCommandEntry_add_nat_prefix: + return "add_nat_prefix" + case networkingCommandEntry_remove_nat_prefix: + return "remove_nat_prefix" + } + return "" +} + +func (e networkingCommandEntry) Entry() reflect.Value { + this := reflect.ValueOf(e) + switch e.entry.(type) { + case networkingCommandEntry_answer: + return reflect.Indirect(this.FieldByName("answer")) + case networkingCommandEntry_remove_answer: + return reflect.Indirect(this.FieldByName("remove_answer")) + case networkingCommandEntry_add_nat_portfwd: + return reflect.Indirect(this.FieldByName("add_nat_portfwd")) + case networkingCommandEntry_remove_nat_portfwd: + return reflect.Indirect(this.FieldByName("remove_nat_portfwd")) + case networkingCommandEntry_add_dhcp_mac_to_ip: + return reflect.Indirect(this.FieldByName("add_dhcp_mac_to_ip")) + case networkingCommandEntry_remove_dhcp_mac_to_ip: + return reflect.Indirect(this.FieldByName("remove_dhcp_mac_to_ip")) + case networkingCommandEntry_add_bridge_mapping: + return reflect.Indirect(this.FieldByName("add_bridge_mapping")) + case networkingCommandEntry_remove_bridge_mapping: + return reflect.Indirect(this.FieldByName("remove_bridge_mapping")) + case networkingCommandEntry_add_nat_prefix: + return reflect.Indirect(this.FieldByName("add_nat_prefix")) + case networkingCommandEntry_remove_nat_prefix: + return reflect.Indirect(this.FieldByName("remove_nat_prefix")) + } + return reflect.Value{} +} + +func (e networkingCommandEntry) Repr() string { + var result map[string]interface{} + result = make(map[string]interface{}) + + entryN, entry := e.Name(), e.Entry() + entryT := entry.Type() + for i := 0; i < entry.NumField(); i++ { + fld, fldT := entry.Field(i), entryT.Field(i) + result[fldT.Name] = fld + } + return fmt.Sprintf("%s -> %v", entryN, result) +} + +// networking command entry parsers +func parseNetworkingCommand_answer(row []string) (*networkingCommandEntry, error) { + if len(row) != 2 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 2, len(row)) + } + vnet := networkingVNET{value: row[0]} + if !vnet.Valid() { + return nil, fmt.Errorf("Invalid format for VNET.") + } + value := row[1] + + result := networkingCommandEntry_answer{vnet: vnet, value: value} + return &networkingCommandEntry{entry: result, answer: &result}, nil +} +func parseNetworkingCommand_remove_answer(row []string) (*networkingCommandEntry, error) { + if len(row) != 1 { + return nil, fmt.Errorf("Expected %d argument. Received %d.", 1, len(row)) + } + vnet := networkingVNET{value: row[0]} + if !vnet.Valid() { + return nil, fmt.Errorf("Invalid format for VNET.") + } + + result := networkingCommandEntry_remove_answer{vnet: vnet} + return &networkingCommandEntry{entry: result, remove_answer: &result}, nil +} +func parseNetworkingCommand_add_nat_portfwd(row []string) (*networkingCommandEntry, error) { + if len(row) != 5 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 5, len(row)) + } + + vnet, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + + protocol := strings.ToLower(row[1]) + if !(protocol == "tcp" || protocol == "udp") { + return nil, fmt.Errorf("Expected \"tcp\" or \"udp\" for second argument. : %v", row[1]) + } + + sport, err := strconv.Atoi(row[2]) + if err != nil { + return nil, fmt.Errorf("Unable to parse third argument as an integer. : %v", row[2]) + } + + dest := net.ParseIP(row[3]) + if dest == nil { + return nil, fmt.Errorf("Unable to parse fourth argument as an IPv4 address. : %v", row[2]) + } + + dport, err := strconv.Atoi(row[4]) + if err != nil { + return nil, fmt.Errorf("Unable to parse fifth argument as an integer. : %v", row[4]) + } + + result := networkingCommandEntry_add_nat_portfwd{vnet: vnet - 1, protocol: protocol, port: sport, target_host: dest, target_port: dport} + return &networkingCommandEntry{entry: result, add_nat_portfwd: &result}, nil +} +func parseNetworkingCommand_remove_nat_portfwd(row []string) (*networkingCommandEntry, error) { + if len(row) != 3 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 3, len(row)) + } + + vnet, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + + protocol := strings.ToLower(row[1]) + if !(protocol == "tcp" || protocol == "udp") { + return nil, fmt.Errorf("Expected \"tcp\" or \"udp\" for second argument. : %v", row[1]) + } + + sport, err := strconv.Atoi(row[2]) + if err != nil { + return nil, fmt.Errorf("Unable to parse third argument as an integer. : %v", row[2]) + } + + result := networkingCommandEntry_remove_nat_portfwd{vnet: vnet - 1, protocol: protocol, port: sport} + return &networkingCommandEntry{entry: result, remove_nat_portfwd: &result}, nil +} +func parseNetworkingCommand_add_dhcp_mac_to_ip(row []string) (*networkingCommandEntry, error) { + if len(row) != 3 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 3, len(row)) + } + + vnet, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + + mac, err := net.ParseMAC(row[1]) + if err != nil { + return nil, fmt.Errorf("Unable to parse second argument as hwaddr. : %v", row[1]) + } + + ip := net.ParseIP(row[2]) + if ip != nil { + return nil, fmt.Errorf("Unable to parse third argument as ipv4. : %v", row[2]) + } + + result := networkingCommandEntry_add_dhcp_mac_to_ip{vnet: vnet - 1, mac: mac, ip: ip} + return &networkingCommandEntry{entry: result, add_dhcp_mac_to_ip: &result}, nil +} +func parseNetworkingCommand_remove_dhcp_mac_to_ip(row []string) (*networkingCommandEntry, error) { + if len(row) != 2 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 2, len(row)) + } + + vnet, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + + mac, err := net.ParseMAC(row[1]) + if err != nil { + return nil, fmt.Errorf("Unable to parse second argument as hwaddr. : %v", row[1]) + } + + result := networkingCommandEntry_remove_dhcp_mac_to_ip{vnet: vnet - 1, mac: mac} + return &networkingCommandEntry{entry: result, remove_dhcp_mac_to_ip: &result}, nil +} +func parseNetworkingCommand_add_bridge_mapping(row []string) (*networkingCommandEntry, error) { + if len(row) != 2 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 2, len(row)) + } + intf := networkingInterface{name: row[0]} + + vnet, err := strconv.Atoi(row[1]) + if err != nil { + return nil, fmt.Errorf("Unable to parse second argument as an integer. : %v", row[2]) + } + + result := networkingCommandEntry_add_bridge_mapping{intf: intf, vnet: vnet - 1} + return &networkingCommandEntry{entry: result, add_bridge_mapping: &result}, nil +} +func parseNetworkingCommand_remove_bridge_mapping(row []string) (*networkingCommandEntry, error) { + if len(row) != 1 { + return nil, fmt.Errorf("Expected %d argument. Received %d.", 1, len(row)) + } + intf := networkingInterface{name: row[0]} + /* + number, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + */ + result := networkingCommandEntry_remove_bridge_mapping{intf: intf} + return &networkingCommandEntry{entry: result, remove_bridge_mapping: &result}, nil +} +func parseNetworkingCommand_add_nat_prefix(row []string) (*networkingCommandEntry, error) { + if len(row) != 2 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 2, len(row)) + } + + vnet, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + + if !strings.HasPrefix(row[1], "/") { + return nil, fmt.Errorf("Expected second argument to begin with \"/\". : %v", row[1]) + } + + prefix, err := strconv.Atoi(row[1][1:]) + if err != nil { + return nil, fmt.Errorf("Unable to parse prefix out of second argument. : %v", row[1]) + } + + result := networkingCommandEntry_add_nat_prefix{vnet: vnet - 1, prefix: prefix} + return &networkingCommandEntry{entry: result, add_nat_prefix: &result}, nil +} +func parseNetworkingCommand_remove_nat_prefix(row []string) (*networkingCommandEntry, error) { + if len(row) != 2 { + return nil, fmt.Errorf("Expected %d arguments. Received only %d.", 2, len(row)) + } + + vnet, err := strconv.Atoi(row[0]) + if err != nil { + return nil, fmt.Errorf("Unable to parse first argument as an integer. : %v", row[0]) + } + + if !strings.HasPrefix(row[1], "/") { + return nil, fmt.Errorf("Expected second argument to begin with \"/\". : %v", row[1]) + } + prefix, err := strconv.Atoi(row[1][1:]) + if err != nil { + return nil, fmt.Errorf("Unable to parse prefix out of second argument. : %v", row[1]) + } + + result := networkingCommandEntry_remove_nat_prefix{vnet: vnet - 1, prefix: prefix} + return &networkingCommandEntry{entry: result, remove_nat_prefix: &result}, nil +} + +type networkingCommandParser struct { + command string + callback func([]string) (*networkingCommandEntry, error) +} + +var NetworkingCommandParsers = []networkingCommandParser{ + /* DictRecordParseFunct */ {command: "answer", callback: parseNetworkingCommand_answer}, + /* DictRecordParseFunct */ {command: "remove_answer", callback: parseNetworkingCommand_remove_answer}, + /* NatFwdRecordParseFunct */ {command: "add_nat_portfwd", callback: parseNetworkingCommand_add_nat_portfwd}, + /* NatFwdRecordParseFunct */ {command: "remove_nat_portfwd", callback: parseNetworkingCommand_remove_nat_portfwd}, + /* DhcpMacRecordParseFunct */ {command: "add_dhcp_mac_to_ip", callback: parseNetworkingCommand_add_dhcp_mac_to_ip}, + /* DhcpMacRecordParseFunct */ {command: "remove_dhcp_mac_to_ip", callback: parseNetworkingCommand_remove_dhcp_mac_to_ip}, + /* BridgeMappingRecordParseFunct */ {command: "add_bridge_mapping", callback: parseNetworkingCommand_add_bridge_mapping}, + /* BridgeMappingRecordParseFunct */ {command: "remove_bridge_mapping", callback: parseNetworkingCommand_remove_bridge_mapping}, + /* NatPrefixRecordParseFunct */ {command: "add_nat_prefix", callback: parseNetworkingCommand_add_nat_prefix}, + /* NatPrefixRecordParseFunct */ {command: "remove_nat_prefix", callback: parseNetworkingCommand_remove_nat_prefix}, +} + +func NetworkingParserByCommand(command string) *func([]string) (*networkingCommandEntry, error) { + for _, p := range NetworkingCommandParsers { + if p.command == command { + return &p.callback + } + } + return nil +} + +func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) chan networkingCommandEntry { + var out chan networkingCommandEntry + + out = make(chan networkingCommandEntry) + go func(in chan []string, out chan networkingCommandEntry) { + for reading := true; reading; { + select { + case <-eof: + reading = false + case row := <-in: + if len(row) >= 1 { + parser := NetworkingParserByCommand(row[0]) + if parser == nil { + log.Printf("Invalid command : %v", row) + continue + } + callback := *parser + entry, err := callback(row[1:]) + if err != nil { + log.Printf("Unable to parse command : %v %v", err, row) + continue + } + out <- *entry + } + } + } + }(rows, out) + return out +} + +type NetworkingConfig struct { + answer map[int]map[string]string + nat_portfwd map[int]map[string]string + dhcp_mac_to_ip map[int]map[string]net.IP + //bridge_mapping map[net.Interface]uint64 // XXX: we don't need the actual interface for anything but informing the user. + bridge_mapping map[string]int + nat_prefix map[int][]int +} + +func (c NetworkingConfig) repr() string { + return fmt.Sprintf("answer -> %v\nnat_portfwd -> %v\ndhcp_mac_to_ip -> %v\nbridge_mapping -> %v\nnat_prefix -> %v", c.answer, c.nat_portfwd, c.dhcp_mac_to_ip, c.bridge_mapping, c.nat_prefix) +} + +func flattenNetworkingConfig(eof sentinelSignaller, in chan networkingCommandEntry) NetworkingConfig { + var result NetworkingConfig + var vmnet int + + result.answer = make(map[int]map[string]string) + result.nat_portfwd = make(map[int]map[string]string) + result.dhcp_mac_to_ip = make(map[int]map[string]net.IP) + result.bridge_mapping = make(map[string]int) + result.nat_prefix = make(map[int][]int) + + for reading := true; reading; { + select { + case <-eof: + reading = false + case e := <-in: + switch e.entry.(type) { + case networkingCommandEntry_answer: + vnet := e.answer.vnet + answers, exists := result.answer[vnet.Number()] + if !exists { + answers = make(map[string]string) + result.answer[vnet.Number()] = answers + } + answers[vnet.Option()] = e.answer.value + case networkingCommandEntry_remove_answer: + vnet := e.remove_answer.vnet + answers, exists := result.answer[vnet.Number()] + if exists { + delete(answers, vnet.Option()) + } else { + log.Printf("Unable to remove answer %s as specified by `remove_answer`.\n", vnet.Repr()) + } + case networkingCommandEntry_add_nat_portfwd: + vmnet = e.add_nat_portfwd.vnet + protoport := fmt.Sprintf("%s/%d", e.add_nat_portfwd.protocol, e.add_nat_portfwd.port) + target := fmt.Sprintf("%s:%d", e.add_nat_portfwd.target_host, e.add_nat_portfwd.target_port) + portfwds, exists := result.nat_portfwd[vmnet] + if !exists { + portfwds = make(map[string]string) + result.nat_portfwd[vmnet] = portfwds + } + portfwds[protoport] = target + case networkingCommandEntry_remove_nat_portfwd: + vmnet = e.remove_nat_portfwd.vnet + protoport := fmt.Sprintf("%s/%d", e.remove_nat_portfwd.protocol, e.remove_nat_portfwd.port) + portfwds, exists := result.nat_portfwd[vmnet] + if exists { + delete(portfwds, protoport) + } else { + log.Printf("Unable to remove nat port-forward %s from interface %s%d as requested by `remove_nat_portfwd`.\n", protoport, NetworkingInterfacePrefix, vmnet) + } + case networkingCommandEntry_add_dhcp_mac_to_ip: + vmnet = e.add_dhcp_mac_to_ip.vnet + dhcpmacs, exists := result.dhcp_mac_to_ip[vmnet] + if !exists { + dhcpmacs = make(map[string]net.IP) + result.dhcp_mac_to_ip[vmnet] = dhcpmacs + } + dhcpmacs[e.add_dhcp_mac_to_ip.mac.String()] = e.add_dhcp_mac_to_ip.ip + case networkingCommandEntry_remove_dhcp_mac_to_ip: + vmnet = e.remove_dhcp_mac_to_ip.vnet + dhcpmacs, exists := result.dhcp_mac_to_ip[vmnet] + if exists { + delete(dhcpmacs, e.remove_dhcp_mac_to_ip.mac.String()) + } else { + log.Printf("Unable to remove dhcp_mac_to_ip entry %v from interface %s%d as specified by `remove_dhcp_mac_to_ip`.\n", e.remove_dhcp_mac_to_ip, NetworkingInterfacePrefix, vmnet) + } + case networkingCommandEntry_add_bridge_mapping: + intf := e.add_bridge_mapping.intf + if _, err := intf.Interface(); err != nil { + log.Printf("Interface \"%s\" as specified by `add_bridge_mapping` was not found on the current platform. This is a non-critical error. Ignoring.", intf.name) + } + result.bridge_mapping[intf.name] = e.add_bridge_mapping.vnet + case networkingCommandEntry_remove_bridge_mapping: + intf := e.remove_bridge_mapping.intf + if _, err := intf.Interface(); err != nil { + log.Printf("Interface \"%s\" as specified by `remove_bridge_mapping` was not found on the current platform. This is a non-critical error. Ignoring.", intf.name) + } + delete(result.bridge_mapping, intf.name) + case networkingCommandEntry_add_nat_prefix: + vmnet = e.add_nat_prefix.vnet + _, exists := result.nat_prefix[vmnet] + if exists { + result.nat_prefix[vmnet] = append(result.nat_prefix[vmnet], e.add_nat_prefix.prefix) + } else { + result.nat_prefix[vmnet] = []int{e.add_nat_prefix.prefix} + } + case networkingCommandEntry_remove_nat_prefix: + vmnet = e.remove_nat_prefix.vnet + prefixes, exists := result.nat_prefix[vmnet] + if exists { + for index := 0; index < len(prefixes); index++ { + if prefixes[index] == e.remove_nat_prefix.prefix { + result.nat_prefix[vmnet] = append(prefixes[:index], prefixes[index+1:]...) + break + } + } + } else { + log.Printf("Unable to remove nat prefix /%d from interface %s%d as specified by `remove_nat_prefix`.\n", e.remove_nat_prefix.prefix, NetworkingInterfacePrefix, vmnet) + } + } + } + } + return result +} + +// Constructor for networking file +func ReadNetworkingConfig(fd *os.File) (NetworkingConfig, error) { + // start piecing together different parts of the file + fromfile, eof := consumeFile(fd) + tokenized := tokenizeNetworkingConfig(eof, fromfile) + rows := splitNetworkingConfig(eof, tokenized) + entries := parseNetworkingConfig(eof, rows) + + // parse the version + parsed_version, err := networkingReadVersion(<-rows) + if err != nil { + return NetworkingConfig{}, err + } + + // verify that it's 1.0 since that's all we support. + version := parsed_version.Number() + if version != 1.0 { + return NetworkingConfig{}, fmt.Errorf("Expected version %f of networking file. Received version %f.", 1.0, version) + } + + // convert to a configuration + result := flattenNetworkingConfig(eof, entries) + return result, nil +} + +// netmapper interface +type NetworkingType int + +const ( + NetworkingType_HOSTONLY = iota + 1 + NetworkingType_NAT + NetworkingType_BRIDGED +) + +func networkingConfig_InterfaceTypes(config NetworkingConfig) map[int]NetworkingType { + var result map[int]NetworkingType + result = make(map[int]NetworkingType) + + // defaults + result[0] = NetworkingType_BRIDGED + result[1] = NetworkingType_HOSTONLY + result[8] = NetworkingType_NAT + + // walk through config collecting bridged interfaces + for _, vmnet := range config.bridge_mapping { + result[vmnet] = NetworkingType_BRIDGED + } + + // walk through answers finding out which ones are nat versus hostonly + for vmnet, table := range config.answer { + // everything should be defined as a virtual adapter... + if table["VIRTUAL_ADAPTER"] == "yes" { + + // validate that the VNET entry contains everything we expect it to + _, subnetQ := table["HOSTONLY_SUBNET"] + _, netmaskQ := table["HOSTONLY_NETMASK"] + if !(subnetQ && netmaskQ) { + log.Printf("Interface %s%d is missing some expected keys (HOSTONLY_SUBNET, HOSTONLY_NETMASK). This is non-critical. Ignoring..", NetworkingInterfacePrefix, vmnet) + } + + // distinguish between nat or hostonly + if table["NAT"] == "yes" { + result[vmnet] = NetworkingType_NAT + } else { + result[vmnet] = NetworkingType_HOSTONLY + } + + // if it's not a virtual_adapter, then it must be an alias (really a bridge). + } else { + result[vmnet] = NetworkingType_BRIDGED + } + } + return result +} + +func networkingConfig_NamesToVmnet(config NetworkingConfig) map[NetworkingType][]int { + types := networkingConfig_InterfaceTypes(config) + + // now sort the keys + var keys []int + for vmnet := range types { + keys = append(keys, vmnet) + } + sort.Ints(keys) + + // build result dictionary + var result map[NetworkingType][]int + result = make(map[NetworkingType][]int) + for i := 0; i < len(keys); i++ { + t := types[keys[i]] + result[t] = append(result[t], keys[i]) + } + return result +} + +const NetworkingInterfacePrefix = "vmnet" + +func (e NetworkingConfig) NameIntoDevice(name string) (string, error) { + netmapper := networkingConfig_NamesToVmnet(e) + name = strings.ToLower(name) + + var vmnet int + if name == "hostonly" && len(netmapper[NetworkingType_HOSTONLY]) > 0 { + vmnet = netmapper[NetworkingType_HOSTONLY][0] + } else if name == "nat" && len(netmapper[NetworkingType_NAT]) > 0 { + vmnet = netmapper[NetworkingType_NAT][0] + } else if name == "bridged" && len(netmapper[NetworkingType_BRIDGED]) > 0 { + vmnet = netmapper[NetworkingType_BRIDGED][0] + } else { + return "", fmt.Errorf("Network name not found : %v", name) + } + return fmt.Sprintf("%s%d", NetworkingInterfacePrefix, vmnet), nil +} + +func (e NetworkingConfig) DeviceIntoName(device string) (string, error) { + types := networkingConfig_InterfaceTypes(e) + + lowerdevice := strings.ToLower(device) + if !strings.HasPrefix(lowerdevice, NetworkingInterfacePrefix) { + return device, nil + } + vmnet, err := strconv.Atoi(lowerdevice[len(NetworkingInterfacePrefix):]) + if err != nil { + return "", err + } + network := types[vmnet] + switch network { + case NetworkingType_HOSTONLY: + return "hostonly", nil + case NetworkingType_NAT: + return "nat", nil + case NetworkingType_BRIDGED: + return "bridged", nil + } + return "", fmt.Errorf("Unable to determine network type for device %s%d.", NetworkingInterfacePrefix, vmnet) +} + +/** generic async file reader */ func consumeFile(fd *os.File) (chan byte, sentinelSignaller) { fromfile := make(chan byte) eof := make(sentinelSignaller) diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 04fb4e897..2814cbad3 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -196,8 +196,19 @@ func (d *Player5Driver) Verify() error { return playerVmnetnatConfPath(device) } - d.VmwareDriver.NetmapConfPath = func() string { - return playerNetmapConfPath() + d.VmwareDriver.NetworkMapper = func() (NetworkNameMapper, error) { + pathNetmap := playerNetmapConfPath() + if _, err := os.Stat(pathNetmap); err != nil { + return nil, fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) + } + + fd, err := os.Open(pathNetmap) + if err != nil { + return nil, err + } + defer fd.Close() + + return ReadNetworkMap(fd) } return nil } diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index af2d7df35..c2c905922 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -157,8 +157,19 @@ func (d *Workstation9Driver) Verify() error { return workstationVmnetnatConfPath(device) } - d.VmwareDriver.NetmapConfPath = func() string { - return workstationNetmapConfPath() + d.VmwareDriver.NetworkMapper = func() (NetworkNameMapper, error) { + pathNetmap := workstationNetmapConfPath() + if _, err := os.Stat(pathNetmap); err != nil { + return nil, fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) + } + + fd, err := os.Open(pathNetmap) + if err != nil { + return nil, err + } + defer fd.Close() + + return ReadNetworkMap(fd) } return nil } diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 137b0c736..7728260ad 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -373,16 +373,8 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver() // read netmap config - pathNetmap := driver.NetmapConfPath() - if _, err := os.Stat(pathNetmap); err != nil { - err := fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - netmap, res := vmwcommon.ReadNetmapConfig(pathNetmap) - if res != nil { - err := fmt.Errorf("Unable to read netmap conf file: %s: %v", pathNetmap, res) + netmap, err := driver.NetworkMapper() + if err != nil { state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt From 737e951685e1ddb89e130668634de493e6e6db09 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 17 Nov 2017 10:26:40 -0600 Subject: [PATCH 0569/1007] Added missing root path to path-finders for the VMware Fusion implementation in the vmware builder as mentioned by @SwampDragons. --- builder/vmware/common/driver_fusion5.go | 2 +- builder/vmware/common/driver_fusion6.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index c450e1f61..e3c0f061e 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -141,7 +141,7 @@ func (d *Fusion5Driver) Verify() error { return err } - libpath := filepath.Join("Library", "Preferences", "VMware Fusion") + libpath := filepath.Join("/", "Library", "Preferences", "VMware Fusion") d.VmwareDriver.DhcpLeasesPath = func(device string) string { return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases" diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index 62dd7b218..1f959d35d 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -66,7 +66,7 @@ func (d *Fusion6Driver) Verify() error { } log.Printf("Detected VMware version: %s", matches[1]) - libpath := filepath.Join("Library", "Preferences", "VMware Fusion") + libpath := filepath.Join("/", "Library", "Preferences", "VMware Fusion") d.VmwareDriver.DhcpLeasesPath = func(device string) string { return "/var/db/vmware/vmnet-dhcpd-" + device + ".leases" From 594ed950c7bcb076ef70704d8a3ef9b9a6a7eb4d Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 22 Nov 2017 17:11:13 -0600 Subject: [PATCH 0570/1007] Fixed a race condition in builder/vmware/common/driver_parser.go due to a misunderstanding how channels work when you close them. --- builder/vmware/common/driver_parser.go | 61 ++++++++++++++++---------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/builder/vmware/common/driver_parser.go b/builder/vmware/common/driver_parser.go index 7a026fea8..24ecaf0df 100644 --- a/builder/vmware/common/driver_parser.go +++ b/builder/vmware/common/driver_parser.go @@ -17,8 +17,9 @@ type sentinelSignaller chan struct{} /** low-level parsing */ // strip the comments and extraneous newlines from a byte channel -func uncomment(eof sentinelSignaller, in <-chan byte) chan byte { +func uncomment(eof sentinelSignaller, in <-chan byte) (chan byte, sentinelSignaller) { out := make(chan byte) + eoc := make(sentinelSignaller) go func(in <-chan byte, out chan byte) { var endofline bool @@ -40,16 +41,19 @@ func uncomment(eof sentinelSignaller, in <-chan byte) chan byte { } } } + close(eoc) }(in, out) - return out + return out, eoc } // convert a byte channel into a channel of pseudo-tokens -func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) chan string { +func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) (chan string, sentinelSignaller) { var ch byte var state string var quote bool + eot := make(sentinelSignaller) + out := make(chan string) go func(out chan string) { for stillReading := true; stillReading; { @@ -106,8 +110,9 @@ func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) chan string { if len(state) > 0 { out <- state } + close(eot) }(out) - return out + return out, eot } /** mid-level parsing */ @@ -220,12 +225,14 @@ func parseDhcpConfig(eof sentinelSignaller, in chan string) (tkGroup, error) { return result, nil } -func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string { +func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) (chan string, sentinelSignaller) { var ch byte var state string var quote bool var lastnewline bool + eot := make(sentinelSignaller) + out := make(chan string) go func(out chan string) { for stillReading := true; stillReading; { @@ -291,8 +298,9 @@ func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string { if len(state) > 0 { out <- state } + close(eot) }(out) - return out + return out, eot } func parseNetworkMapConfig(eof sentinelSignaller, in chan string) (NetworkMap, error) { @@ -966,9 +974,9 @@ type DhcpConfiguration []configDeclaration func ReadDhcpConfiguration(fd *os.File) (DhcpConfiguration, error) { fromfile, eof := consumeFile(fd) - uncommented := uncomment(eof, fromfile) - tokenized := tokenizeDhcpConfig(eof, uncommented) - parsetree, err := parseDhcpConfig(eof, tokenized) + uncommented, eoc := uncomment(eof, fromfile) + tokenized, eot := tokenizeDhcpConfig(eoc, uncommented) + parsetree, err := parseDhcpConfig(eot, tokenized) if err != nil { return nil, err } @@ -1064,10 +1072,10 @@ type NetworkNameMapper interface { func ReadNetworkMap(fd *os.File) (NetworkMap, error) { fromfile, eof := consumeFile(fd) - uncommented := uncomment(eof, fromfile) - tokenized := tokenizeNetworkMapConfig(eof, uncommented) + uncommented, eoc := uncomment(eof, fromfile) + tokenized, eot := tokenizeNetworkMapConfig(eoc, uncommented) - result, err := parseNetworkMapConfig(eof, tokenized) + result, err := parseNetworkMapConfig(eot, tokenized) if err != nil { return nil, err } @@ -1100,11 +1108,13 @@ func (e *NetworkMap) repr() string { } /*** parser for VMware Fusion's networking file */ -func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) chan string { +func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) (chan string, sentinelSignaller) { var ch byte var state string var repeat_newline bool + eot := make(sentinelSignaller) + out := make(chan string) go func(out chan string) { for reading := true; reading; { @@ -1144,13 +1154,16 @@ func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) chan string { if len(state) > 0 { out <- state } + close(eot) }(out) - return out + return out, eot } -func splitNetworkingConfig(eof sentinelSignaller, in chan string) chan []string { +func splitNetworkingConfig(eof sentinelSignaller, in chan string) (chan []string, sentinelSignaller) { var out chan []string + eos := make(sentinelSignaller) + out = make(chan []string) go func(out chan []string) { row := make([]string, 0) @@ -1174,8 +1187,9 @@ func splitNetworkingConfig(eof sentinelSignaller, in chan string) chan []string if len(row) > 0 { out <- row } + close(eos) }(out) - return out + return out, eos } /// All token types in networking file. @@ -1642,9 +1656,11 @@ func NetworkingParserByCommand(command string) *func([]string) (*networkingComma return nil } -func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) chan networkingCommandEntry { +func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) (chan networkingCommandEntry, sentinelSignaller) { var out chan networkingCommandEntry + eop := make(sentinelSignaller) + out = make(chan networkingCommandEntry) go func(in chan []string, out chan networkingCommandEntry) { for reading := true; reading; { @@ -1668,8 +1684,9 @@ func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) chan netwo } } } + close(eop) }(rows, out) - return out + return out, eop } type NetworkingConfig struct { @@ -1795,9 +1812,9 @@ func flattenNetworkingConfig(eof sentinelSignaller, in chan networkingCommandEnt func ReadNetworkingConfig(fd *os.File) (NetworkingConfig, error) { // start piecing together different parts of the file fromfile, eof := consumeFile(fd) - tokenized := tokenizeNetworkingConfig(eof, fromfile) - rows := splitNetworkingConfig(eof, tokenized) - entries := parseNetworkingConfig(eof, rows) + tokenized, eot := tokenizeNetworkingConfig(eof, fromfile) + rows, eos := splitNetworkingConfig(eot, tokenized) + entries, eop := parseNetworkingConfig(eos, rows) // parse the version parsed_version, err := networkingReadVersion(<-rows) @@ -1812,7 +1829,7 @@ func ReadNetworkingConfig(fd *os.File) (NetworkingConfig, error) { } // convert to a configuration - result := flattenNetworkingConfig(eof, entries) + result := flattenNetworkingConfig(eop, entries) return result, nil } From 74946071d255e74145240232aa9cc6770685c840 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Mon, 25 Dec 2017 14:08:08 -0600 Subject: [PATCH 0571/1007] Added support for specifying the disk adapter type to the vmware builders. This was squashed from the vmware-diskAdapterType branch (#2968) as submitted by Rami Abughazaleh <icnocop@users.noreply.github.com>. This closes #5671 and possibly #4885. arizvisa: Updated icnocop's documentation to include the possible disk adapter types that one can specify. arizvisa: Tweaked icnocop's support for the `disk_adapter_type` option to the VMWare builder that caused conflicts due to version skew. icnocop: Updated links to the Virtual Disk Manager User's Guide PDF to open in a new window and also added the Adobe PDF icon icnocop: Added support for vmware to specify the disk adapter type, ide or scsi (lsilogic or buslogic) --- builder/vmware/common/driver.go | 2 +- builder/vmware/common/driver_fusion5.go | 4 +- builder/vmware/common/driver_mock.go | 14 +-- builder/vmware/common/driver_player5.go | 4 +- builder/vmware/common/driver_workstation9.go | 4 +- builder/vmware/iso/builder.go | 6 ++ builder/vmware/iso/driver_esx5.go | 4 +- builder/vmware/iso/step_create_disk.go | 4 +- builder/vmware/iso/step_create_vmx.go | 87 +++++++++++++++--- .../images/Adobe_PDF_file_icon_24x24.png | Bin 0 -> 1288 bytes .../source/docs/builders/vmware-iso.html.md | 11 ++- 11 files changed, 108 insertions(+), 32 deletions(-) create mode 100644 website/source/assets/images/Adobe_PDF_file_icon_24x24.png diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 6b5cfde1f..8fa185efd 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -29,7 +29,7 @@ type Driver interface { CompactDisk(string) error // CreateDisk creates a virtual disk with the given size. - CreateDisk(string, string, string) error + CreateDisk(string, string, string, string) error // Checks if the VMX file at the given path is running. IsRunning(string) (bool, error) diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index e3c0f061e..9c81efd4a 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -41,8 +41,8 @@ func (d *Fusion5Driver) CompactDisk(diskPath string) error { return nil } -func (d *Fusion5Driver) CreateDisk(output string, size string, type_id string) error { - cmd := exec.Command(d.vdiskManagerPath(), "-c", "-s", size, "-a", "lsilogic", "-t", type_id, output) +func (d *Fusion5Driver) CreateDisk(output string, size string, adapter_type string, type_id string) error { + cmd := exec.Command(d.vdiskManagerPath(), "-c", "-s", size, "-a", adapter_type, "-t", type_id, output) if _, _, err := runAndLog(cmd); err != nil { return err } diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index f857f4adc..a0955db88 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -19,11 +19,12 @@ type DriverMock struct { CompactDiskPath string CompactDiskErr error - CreateDiskCalled bool - CreateDiskOutput string - CreateDiskSize string - CreateDiskTypeId string - CreateDiskErr error + CreateDiskCalled bool + CreateDiskOutput string + CreateDiskSize string + CreateDiskAdapterType string + CreateDiskTypeId string + CreateDiskErr error IsRunningCalled bool IsRunningPath string @@ -119,10 +120,11 @@ func (d *DriverMock) CompactDisk(path string) error { return d.CompactDiskErr } -func (d *DriverMock) CreateDisk(output string, size string, typeId string) error { +func (d *DriverMock) CreateDisk(output string, size string, adapterType string, typeId string) error { d.CreateDiskCalled = true d.CreateDiskOutput = output d.CreateDiskSize = size + d.CreateDiskAdapterType = adapterType d.CreateDiskTypeId = typeId return d.CreateDiskErr } diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index 2814cbad3..fb14dcb52 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -64,12 +64,12 @@ func (d *Player5Driver) qemuCompactDisk(diskPath string) error { return nil } -func (d *Player5Driver) CreateDisk(output string, size string, type_id string) error { +func (d *Player5Driver) CreateDisk(output string, size string, adapter_type string, type_id string) error { var cmd *exec.Cmd if d.QemuImgPath != "" { cmd = exec.Command(d.QemuImgPath, "create", "-f", "vmdk", "-o", "compat6", output, size) } else { - cmd = exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", "lsilogic", "-t", type_id, output) + cmd = exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", adapter_type, "-t", type_id, output) } if _, _, err := runAndLog(cmd); err != nil { return err diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index c2c905922..25b4ddd2c 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -42,8 +42,8 @@ func (d *Workstation9Driver) CompactDisk(diskPath string) error { return nil } -func (d *Workstation9Driver) CreateDisk(output string, size string, type_id string) error { - cmd := exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", "lsilogic", "-t", type_id, output) +func (d *Workstation9Driver) CreateDisk(output string, size string, adapter_type string, type_id string) error { + cmd := exec.Command(d.VdiskManagerPath, "-c", "-s", size, "-a", adapter_type, "-t", type_id, output) if _, _, err := runAndLog(cmd); err != nil { return err } diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 2dcc082ac..5e2908964 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -40,6 +40,7 @@ type Config struct { // disk drives AdditionalDiskSize []uint `mapstructure:"disk_additional_size"` + DiskAdapterType string `mapstructure:"disk_adapter_type"` DiskName string `mapstructure:"vmdk_name"` DiskSize uint `mapstructure:"disk_size"` DiskTypeId string `mapstructure:"disk_type_id"` @@ -126,6 +127,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.DiskSize = 40000 } + if b.config.DiskAdapterType == "" { + // Default is lsilogic + b.config.DiskAdapterType = "lsilogic" + } + if b.config.DiskTypeId == "" { // Default is growable virtual disk split in 2GB files. b.config.DiskTypeId = "1" diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 3f18656d0..40cc35eb1 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -50,9 +50,9 @@ func (d *ESX5Driver) CompactDisk(diskPathLocal string) error { return nil } -func (d *ESX5Driver) CreateDisk(diskPathLocal string, size string, typeId string) error { +func (d *ESX5Driver) CreateDisk(diskPathLocal string, size string, adapter_type string, typeId string) error { diskPath := d.datastorePath(diskPathLocal) - return d.sh("vmkfstools", "-c", size, "-d", typeId, "-a", "lsilogic", diskPath) + return d.sh("vmkfstools", "-c", size, "-d", typeId, "-a", adapter_type, diskPath) } func (d *ESX5Driver) IsRunning(string) (bool, error) { diff --git a/builder/vmware/iso/step_create_disk.go b/builder/vmware/iso/step_create_disk.go index ddee55c7f..788de2ddc 100644 --- a/builder/vmware/iso/step_create_disk.go +++ b/builder/vmware/iso/step_create_disk.go @@ -28,7 +28,7 @@ func (stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multistep ui.Say("Creating virtual machine disk") full_disk_path := filepath.Join(config.OutputDir, config.DiskName+".vmdk") - if err := driver.CreateDisk(full_disk_path, fmt.Sprintf("%dM", config.DiskSize), config.DiskTypeId); err != nil { + if err := driver.CreateDisk(full_disk_path, fmt.Sprintf("%dM", config.DiskSize), config.DiskAdapterType, config.DiskTypeId); err != nil { err := fmt.Errorf("Error creating disk: %s", err) state.Put("error", err) ui.Error(err.Error()) @@ -46,7 +46,7 @@ func (stepCreateDisk) Run(_ context.Context, state multistep.StateBag) multistep additionalpath := filepath.Join(config.OutputDir, fmt.Sprintf("%s-%d.vmdk", config.DiskName, i+1)) size := fmt.Sprintf("%dM", uint64(additionalsize)) - if err := driver.CreateDisk(additionalpath, size, config.DiskTypeId); err != nil { + if err := driver.CreateDisk(additionalpath, size, config.DiskAdapterType, config.DiskTypeId); err != nil { err := fmt.Errorf("Error creating additional disk: %s", err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 7728260ad..4c3eb58ae 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -16,11 +16,20 @@ import ( ) type vmxTemplateData struct { - Name string - GuestOS string - DiskName string - ISOPath string - Version string + Name string + GuestOS string + ISOPath string + Version string + + SCSI_Present string + SCSI_diskAdapterType string + SATA_Present string + NVME_Present string + + DiskName string + DiskType string + CDROMType string + CDROMType_MasterSlave string Network_Type string Network_Device string @@ -287,6 +296,11 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist isoPath := state.Get("iso_path").(string) ui := state.Get("ui").(packer.Ui) + // Convert the iso_path into a path relative to the .vmx file if possible + if relativeIsoPath, err := filepath.Rel(config.VMXTemplatePath, filepath.FromSlash(isoPath)); err == nil { + isoPath = relativeIsoPath + } + ui.Say("Building and writing VMX file") vmxTemplate := DefaultVMXTemplate @@ -361,6 +375,15 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist Version: config.Version, ISOPath: isoPath, + SCSI_Present: "FALSE", + SCSI_diskAdapterType: "lsilogic", + SATA_Present: "FALSE", + NVME_Present: "FALSE", + + DiskType: "scsi", + CDROMType: "ide", + CDROMType_MasterSlave: "0", + Sound_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.Sound)], Usb_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.USB)], @@ -368,6 +391,36 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist Parallel_Present: "FALSE", } + /// Use the disk adapter type that the user specified to tweak the .vmx + // Also sync the cdrom adapter type according to what's common for that disk type. + diskAdapterType := strings.ToLower(config.DiskAdapterType) + switch diskAdapterType { + case "ide": + templateData.DiskType = "ide" + templateData.CDROMType = "ide" + templateData.CDROMType_MasterSlave = "1" + case "sata": + templateData.SATA_Present = "TRUE" + templateData.DiskType = "sata" + templateData.CDROMType = "sata" + templateData.CDROMType_MasterSlave = "1" + case "nvme": + templateData.NVME_Present = "TRUE" + templateData.DiskType = "nvme" + templateData.SATA_Present = "TRUE" + templateData.CDROMType = "sata" + templateData.CDROMType_MasterSlave = "0" + case "scsi": + diskAdapterType = "lsilogic" + fallthrough + default: + templateData.SCSI_Present = "TRUE" + templateData.SCSI_diskAdapterType = diskAdapterType + templateData.DiskType = "scsi" + templateData.CDROMType = "ide" + templateData.CDROMType_MasterSlave = "0" + } + /// Check the network type that the user specified network := config.Network driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver() @@ -556,9 +609,21 @@ gui.fullScreenAtPowerOn = "FALSE" gui.viewModeAtPowerOn = "windowed" hgfs.linkRootShare = "TRUE" hgfs.mapRootShare = "TRUE" -ide1:0.present = "TRUE" -ide1:0.fileName = "{{ .ISOPath }}" -ide1:0.deviceType = "cdrom-image" + +scsi0.present = "{{ .SCSI_Present }}" +scsi0.virtualDev = "{{ .SCSI_diskAdapterType }}" +scsi0.pciSlotNumber = "16" +scsi0:0.redo = "" +sata0.present = "{{ .SATA_Present }}" +nvme0.present = "{{ .NVME_Present }}" + +{{ .DiskType }}0:0.present = "TRUE" +{{ .DiskType }}0:0.fileName = "{{ .DiskName }}.vmdk" + +{{ .CDROMType }}0:{{ .CDROMType_MasterSlave }}.present = "TRUE" +{{ .CDROMType }}0:{{ .CDROMType_MasterSlave }}.fileName = "{{ .ISOPath }}" +{{ .CDROMType }}0:{{ .CDROMType_MasterSlave }}.deviceType = "cdrom-image" + isolation.tools.hgfs.disable = "FALSE" memsize = "512" nvram = "{{ .Name }}.nvram" @@ -587,12 +652,6 @@ powerType.suspend = "soft" proxyApps.publishToHost = "FALSE" replay.filename = "" replay.supported = "FALSE" -scsi0.pciSlotNumber = "16" -scsi0.present = "TRUE" -scsi0.virtualDev = "lsilogic" -scsi0:0.fileName = "{{ .DiskName }}.vmdk" -scsi0:0.present = "TRUE" -scsi0:0.redo = "" // Sound sound.startConnected = "{{ .Sound_Present }}" diff --git a/website/source/assets/images/Adobe_PDF_file_icon_24x24.png b/website/source/assets/images/Adobe_PDF_file_icon_24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..a722e5b334140fcb2a527b44465dbf4ca6e05cd4 GIT binary patch literal 1288 zcmV+j1^4=iP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00006VoOIv0RI60 z0RN!9r;`8x1ieW_K~zY`m6lzIUDXxGe{1c1&beQ6uSo`<YH=>5)P}~C2Cc=S;&*9j zNffFDZ6Bl*O8Znwp|lTus1LpfT3TAc4+vN&eGoJ+l82T;tCmzu;tY<)iN>)rCNpzy z?#DT2@70HM?|8@Qh%VUd^Rf3@>%Z3jzt53NSL0Cy0PoSI+=?H3(~W=j@O6MQGXp?C zL{L#w6$1oA8%?3s403tvALrISi1YLFGTpPVuz)aQ=Qn#0BNnYLiTeQ2x`hY=>Rc7a zKvfX|)Zy|GHXN{i@#61#TU)<2v-Nhnt&K(_0?4HW`J1SMfR%=AMl0rA&3)<6VfsCh zMibOy{Y`KVZM7>n-Xj;+2;ch=@qwSj!8_+t@yT=R>+APzY;0WacDqhQf{*HMbged& z1v=lx-}V*U(i!CKW&Dw^QJ#Jk20i?BUndTSl&}09VuUP(^FxXoR=^3(dc8;*&2Opd z)7@_O`~7~um!_#`QI=u2xfurU_CmSvg`hwEZHV7^FqGHdg#7$bikt7Hxc(O8hreKy zwHTT(ECa(lFcK&;K@7&@JP9F~nH^nQTYEOo^Uw7AebZpLD7dJ&n2#Lep)1dyb5WJS zA09(H9jIpz0#Q6Mltdt6L<5TvRVAxs#2BT~Xp9dWIB<8CWe;_`U9<oSgS>>$KEU|& zOKd*=1Z5GZ9s4dN5M0W5=?wi7f29;hVNgWK4FaG7S(=fiDQTK&qtRe67|a3q(x{kI zgVEAyij56o3x=<q!oU0?z32aoh9TpX70Lm`BtQfdD8Zqqz?98qhM7?mg#!2j#%3ne zAb(>S&MqVKNU^$_^ndv)+!X?%*xT<QS7uO@h$^HBRx8N7L!f#lQfWmMkxBvn!T)k_ zXk-#GZ8c>u&WlcM-)A2^{_G1bt0h*JhzO#B#E3SUkfi9Kj|ep9uf+9wNRm`KnK<4K z@UJn;6Tn<Gw_jdbdO6&4^jKK9=8NWiGJ$T@2IrC2Uq#NHg&S{&EW=f**v{IlT00Fe zIU_1!+<oVr@%YovkR?gXyeIQ+GCWz5lI0_6@4iKP_7vG$i)5`fUSwP4)6932X!fWu z5ln<i<5G=nxCUv4wfAEiTaaW`?Ps!`o&Rru*_W!5Lu~@tLJ6Htb-j5BJ$M*~m#g*D zCVyoAt^gm+X2-oMgousCSQ(IEAMNY|i--x7#fNpDp3XBpU@s)w8KyNf9}!>qC;qPQ zP(Jxb;;Dbb$_n=Wd&s2jyI8cR(+Nzoh-7svA5lK@1mWyyl4JKHJ|lnfPsqOggg2IH zJ^p*7-9bXwfx_>FKvhu@%%{Y~GlUmUP@Z^>+HW4geeUz<!9)04?;yVUCUJEYS8pH_ zqRiSZ1XGHsD&iAtYlHmwQ;;NN5B-?r%SW&fAkT4g9o(U7k!ufEDxR|M69=$}w&qBV zd=;6SBfa@nEQG3Y-lG<=spCCtrw+`BF%o0M%*x68n11_c1wWKbKF-_f#0;Cv6Cb5> zE{QS5k884c@4a(QcQDQE*|OOrZQ{%A3b44iNC<%o7cPuXo;>-N@p#;sCi+P&#u)4M ydTVuc^*_7*DrT$(w1Fm675Ee;KnZLD{r>^{G#E%4x}j_U0000<MNUMnLSTZNL2yU_ literal 0 HcmV?d00001 diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 95ab31bef..0efe03a0f 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -131,7 +131,16 @@ builder. Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. -* `disable_vnc` (boolean) - Whether to create a VNC connection or not. +- `disk_adapter_type` (string) - The adapter type of the VMware virtual disk + to create. This option is for advanced usage, modify only if you know what + you're doing. Some of the options you can specify are "ide", "sata", "nvme" + or "scsi" (which uses the "lsilogic" scsi interface by default). If you + specify another option, Packer will assume that you're specifying a "scsi" + interface of that specified type. For more information, please consult the + <a href="http://www.vmware.com/pdf/VirtualDiskManager.pdf" target="_blank"><img src="../../assets/images/Adobe_PDF_file_icon_24x24.png"/> Virtual Disk Manager User's Guide</a> for desktop VMware clients. + For ESXi, refer to the proper ESXi documentation. + +- `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. - `floppy_files` (array of strings) - A list of files to place onto a floppy From eb0445ca961eac0c40c6ae0a631936fffa15247c Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 16 Jan 2018 13:17:37 -0600 Subject: [PATCH 0572/1007] Added support for specifying both the network adapter type and cdrom adapter type as requested by @night199uk. Also included the respective documentation for these new options. --- builder/vmware/iso/builder.go | 8 +++- builder/vmware/iso/step_create_vmx.go | 41 +++++++++++++++++-- .../source/docs/builders/vmware-iso.html.md | 12 ++++++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 5e2908964..cc5a9673b 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -46,13 +46,17 @@ type Config struct { DiskTypeId string `mapstructure:"disk_type_id"` Format string `mapstructure:"format"` + // cdrom drive + CdromAdapterType string `mapstructure:"cdrom_adapter_type"` + // platform information GuestOSType string `mapstructure:"guest_os_type"` Version string `mapstructure:"version"` VMName string `mapstructure:"vm_name"` - // Network type - Network string `mapstructure:"network"` + // Network adapter and type + NetworkAdapterType string `mapstructure:"network_adapter_type"` + Network string `mapstructure:"network"` // device presence Sound bool `mapstructure:"sound"` diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 4c3eb58ae..0eb753dc8 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -31,8 +31,9 @@ type vmxTemplateData struct { CDROMType string CDROMType_MasterSlave string - Network_Type string - Network_Device string + Network_Type string + Network_Device string + Network_Adapter string Sound_Present string Usb_Present string @@ -384,6 +385,8 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist CDROMType: "ide", CDROMType_MasterSlave: "0", + Network_Adapter: "e1000", + Sound_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.Sound)], Usb_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.USB)], @@ -421,6 +424,38 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.CDROMType_MasterSlave = "0" } + /// Handle the cdrom adapter type. If the disk adapter type and the + // cdrom adapter type are the same, then ensure that the cdrom is the + // slave device on whatever bus the disk adapter is on. + cdromAdapterType := strings.ToLower(config.CdromAdapterType) + if cdromAdapterType == diskAdapterType { + templateData.CDROMType_MasterSlave = "1" + } else { + templateData.CDROMType_MasterSlave = "0" + } + + switch cdromAdapterType { + case "ide": + templateData.CDROMType = "ide" + case "sata": + templateData.SATA_Present = "TRUE" + templateData.CDROMType = "sata" + case "scsi": + templateData.SCSI_Present = "TRUE" + templateData.CDROMType = "scsi" + default: + err := fmt.Errorf("Error procesing VMX template: %s", cdromAdapterType) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + /// Assign the network adapter type into the template if one was specified. + network_adapter := strings.ToLower(config.NetworkAdapterType) + if network_adapter != "" { + templateData.Network_Adapter = network_adapter + } + /// Check the network type that the user specified network := config.Network driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver() @@ -600,7 +635,7 @@ ethernet0.displayName = "Ethernet" ethernet0.linkStatePropagation.enable = "FALSE" ethernet0.pciSlotNumber = "33" ethernet0.present = "TRUE" -ethernet0.virtualDev = "e1000" +ethernet0.virtualDev = "{{ .Network_Adapter }}" ethernet0.wakeOnPcktRcv = "FALSE" extendedConfigFile = "{{ .Name }}.vmxf" floppy0.present = "FALSE" diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 0efe03a0f..2f4e3e44f 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -140,6 +140,12 @@ builder. <a href="http://www.vmware.com/pdf/VirtualDiskManager.pdf" target="_blank"><img src="../../assets/images/Adobe_PDF_file_icon_24x24.png"/> Virtual Disk Manager User's Guide</a> for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. +- `cdrom_adapter_type` (string) - The adapter type (or bus) that will be used + by the cdrom device. This is chosen by default based on the disk adapter + type. VMware tends to lean towards "ide" for the cdrom device unless + "sata" is chosen for the disk adapter and so Packer attempts to mirror + this logic. This field can be specified as either "ide", "sata", or "scsi". + - `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. @@ -207,6 +213,12 @@ builder. such as "hostonly", "nat", or "bridged". If the network is not one of these values, then it is assumed to be a VMware network device. (VMnet0..x) +- `network_adapter_type` (string) - This is the ethernet adapter type the the + virtual machine will be created with. By default the "e1000" network adapter + type will be used by Packer. For more information, please consult the + <a href="https://kb.vmware.com/s/article/1001805" target="_blank">Choosing a network adapter for your virtual machine</a> for desktop VMware + clients. For ESXi, refer to the proper ESXi documentation. + - `output_directory` (string) - This is the path to the directory where the resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` From aefe41a44ad0631d2095a6d99464f080e4f28533 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 16 Jan 2018 13:27:21 -0600 Subject: [PATCH 0573/1007] Fixed an issue with the previous commit so that when the user does not specify the cdrom_adapter_type to fallback to the original decision made by the disk adapter type selection. --- builder/vmware/iso/step_create_vmx.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index 0eb753dc8..ffff9d999 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -428,7 +428,9 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist // cdrom adapter type are the same, then ensure that the cdrom is the // slave device on whatever bus the disk adapter is on. cdromAdapterType := strings.ToLower(config.CdromAdapterType) - if cdromAdapterType == diskAdapterType { + if cdromAdapterType == "" { + cdromAdapterType = templateData.CDROMType + } else if cdromAdapterType == diskAdapterType { templateData.CDROMType_MasterSlave = "1" } else { templateData.CDROMType_MasterSlave = "0" From fa2dddd26d1584f952f6d1bf71db14415d43bd70 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 2 Feb 2018 19:45:18 -0600 Subject: [PATCH 0574/1007] Fixed some things mucked up during rebase. --- builder/vmware/common/step_type_boot_command.go | 1 - builder/vmware/iso/driver_esx5.go | 1 - 2 files changed, 2 deletions(-) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index c169c59eb..02404af91 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -7,7 +7,6 @@ import ( "net" "os" "regexp" - "runtime" "strings" "time" "unicode" diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 40cc35eb1..1dc352999 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -19,7 +19,6 @@ import ( "github.com/hashicorp/packer/communicator/ssh" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" gossh "golang.org/x/crypto/ssh" ) From c366a1e1607aae9ca84bb8a7acc65808f81b37d1 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 2 Feb 2018 20:16:54 -0600 Subject: [PATCH 0575/1007] Inverted the logic of FileExistsLocally as suggested by @SwampDragons as remote URLs are assumed to exist locally. --- common/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config.go b/common/config.go index 269d52dd1..aa632ceae 100644 --- a/common/config.go +++ b/common/config.go @@ -195,7 +195,7 @@ func FileExistsLocally(original string) bool { // Check to see that it's got a Local way of doing things. local, ok := d.(LocalDownloader) if !ok { - return false + return true // XXX: Remote URLs short-circuit this logic. } // Figure out where we're at. From efc97dbda2fedd12cb8825db3cdaff2017159654 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 2 Feb 2018 20:29:10 -0600 Subject: [PATCH 0576/1007] Fixed TestFileExistsLocally tests in common/config_test.go so that they're actually being run. Added a non-existent-protocol:// test. --- common/config_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/config_test.go b/common/config_test.go index 35697291d..29574ee4e 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -285,7 +285,7 @@ func TestDownloadableURL_FilePaths(t *testing.T) { } } -func test_FileExistsLocally(t *testing.T) { +func TestFileExistsLocally(t *testing.T) { portablepath := GetPortablePathToTestFixtures(t) dirCases := []struct { @@ -294,15 +294,17 @@ func test_FileExistsLocally(t *testing.T) { }{ // file exists locally {fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), true}, - // file is not supposed to exist locally + // remote protocols short-circuit and are considered to exist locally {"https://myfile.iso", true}, + // non-existent protocols do not exist and hence fail + {"nonexistent-protocol://myfile.iso", false}, // file does not exist locally {"file:///C/i/dont/exist", false}, } // Run through test cases to make sure they all parse correctly for _, tc := range dirCases { fileOK := FileExistsLocally(tc.Input) - if !fileOK { + if fileOK != tc.Output { t.Fatalf("Test Case failed: Expected %#v, received = %#v, input = %s", tc.Output, fileOK, tc.Input) } From d4b00b722add485cf9472bf47efa61a4854922e4 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 2 Feb 2018 20:36:08 -0600 Subject: [PATCH 0577/1007] Removed an extra '/' from the TestFileExistsLocally test in common/config_test.go --- common/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config_test.go b/common/config_test.go index 29574ee4e..8f170fe1d 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -293,7 +293,7 @@ func TestFileExistsLocally(t *testing.T) { Output bool }{ // file exists locally - {fmt.Sprintf("file:///%s/SomeDir/myfile.txt", portablepath), true}, + {fmt.Sprintf("file://%s/SomeDir/myfile.txt", portablepath), true}, // remote protocols short-circuit and are considered to exist locally {"https://myfile.iso", true}, // non-existent protocols do not exist and hence fail From 9eb2f3742941c2370864b445dad0b863efda936b Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 2 Feb 2018 20:44:22 -0600 Subject: [PATCH 0578/1007] Ack! Forgot to include the test-fixtures/SomeDir/myfile.txt file... --- common/test-fixtures/SomeDir/myfile.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 common/test-fixtures/SomeDir/myfile.txt diff --git a/common/test-fixtures/SomeDir/myfile.txt b/common/test-fixtures/SomeDir/myfile.txt new file mode 100644 index 000000000..e69de29bb From eaef2961cb40b214cb744214998a02097053c00f Mon Sep 17 00:00:00 2001 From: Petr Hosek <phosek@google.com> Date: Mon, 18 Dec 2017 12:51:39 -0800 Subject: [PATCH 0579/1007] Support specifying licenses for Google Compute images This is needed to enable features such as the nested virtualization: https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances --- builder/googlecompute/config.go | 1 + builder/googlecompute/config_test.go | 3 +++ builder/googlecompute/driver.go | 2 +- builder/googlecompute/driver_gce.go | 3 ++- builder/googlecompute/driver_mock.go | 7 ++++--- builder/googlecompute/step_create_image.go | 2 +- builder/googlecompute/step_create_image_test.go | 3 +-- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index 8ed3897d6..c8863d4d9 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -36,6 +36,7 @@ type Config struct { ImageDescription string `mapstructure:"image_description"` ImageFamily string `mapstructure:"image_family"` ImageLabels map[string]string `mapstructure:"image_labels"` + ImageLicenses []string `mapstructure:"image_licenses"` InstanceName string `mapstructure:"instance_name"` Labels map[string]string `mapstructure:"labels"` MachineType string `mapstructure:"machine_type"` diff --git a/builder/googlecompute/config_test.go b/builder/googlecompute/config_test.go index 551692b29..a4b862a1a 100644 --- a/builder/googlecompute/config_test.go +++ b/builder/googlecompute/config_test.go @@ -309,6 +309,9 @@ func testConfig(t *testing.T) map[string]interface{} { "label-1": "value-1", "label-2": "value-2", }, + "image_licenses": []string{ + "test-license", + }, "zone": "us-east1-a", } } diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index bd302ddc0..fdb7d9442 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -11,7 +11,7 @@ import ( type Driver interface { // CreateImage creates an image from the given disk in Google Compute // Engine. - CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) + CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) // DeleteImage deletes the image with the given name. DeleteImage(name string) <-chan error diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 44dcb85c6..c84ab222f 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -97,12 +97,13 @@ func NewDriverGCE(ui packer.Ui, p string, a *AccountFile) (Driver, error) { }, nil } -func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) { +func (d *driverGCE) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) { gce_image := &compute.Image{ Description: description, Name: name, Family: family, Labels: image_labels, + Licenses: image_licenses, SourceDisk: fmt.Sprintf("%s%s/zones/%s/disks/%s", d.service.BasePath, d.projectId, zone, disk), SourceType: "RAW", } diff --git a/builder/googlecompute/driver_mock.go b/builder/googlecompute/driver_mock.go index 895775da5..720f9d60b 100644 --- a/builder/googlecompute/driver_mock.go +++ b/builder/googlecompute/driver_mock.go @@ -9,9 +9,9 @@ type DriverMock struct { CreateImageDesc string CreateImageFamily string CreateImageLabels map[string]string + CreateImageLicenses []string CreateImageZone string CreateImageDisk string - CreateImageResultLicenses []string CreateImageResultProjectId string CreateImageResultSelfLink string CreateImageResultSizeGb int64 @@ -82,11 +82,12 @@ type DriverMock struct { WaitForInstanceErrCh <-chan error } -func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string) (<-chan *Image, <-chan error) { +func (d *DriverMock) CreateImage(name, description, family, zone, disk string, image_labels map[string]string, image_licenses []string) (<-chan *Image, <-chan error) { d.CreateImageName = name d.CreateImageDesc = description d.CreateImageFamily = family d.CreateImageLabels = image_labels + d.CreateImageLicenses = image_licenses d.CreateImageZone = zone d.CreateImageDisk = disk if d.CreateImageResultProjectId == "" { @@ -106,7 +107,7 @@ func (d *DriverMock) CreateImage(name, description, family, zone, disk string, i ch := make(chan *Image, 1) ch <- &Image{ Labels: d.CreateImageLabels, - Licenses: d.CreateImageResultLicenses, + Licenses: d.CreateImageLicenses, Name: name, ProjectId: d.CreateImageResultProjectId, SelfLink: d.CreateImageResultSelfLink, diff --git a/builder/googlecompute/step_create_image.go b/builder/googlecompute/step_create_image.go index 72e6a06eb..c2bde16c8 100644 --- a/builder/googlecompute/step_create_image.go +++ b/builder/googlecompute/step_create_image.go @@ -40,7 +40,7 @@ func (s *StepCreateImage) Run(_ context.Context, state multistep.StateBag) multi imageCh, errCh := driver.CreateImage( config.ImageName, config.ImageDescription, config.ImageFamily, config.Zone, - config.DiskName, config.ImageLabels) + config.DiskName, config.ImageLabels, config.ImageLicenses) var err error select { case err = <-errCh: diff --git a/builder/googlecompute/step_create_image_test.go b/builder/googlecompute/step_create_image_test.go index 6f1121a9f..65ccca313 100644 --- a/builder/googlecompute/step_create_image_test.go +++ b/builder/googlecompute/step_create_image_test.go @@ -22,7 +22,6 @@ func TestStepCreateImage(t *testing.T) { d := state.Get("driver").(*DriverMock) // These are the values of the image the driver will return. - d.CreateImageResultLicenses = []string{"test-license"} d.CreateImageResultProjectId = "test-project" d.CreateImageResultSizeGb = 100 @@ -36,7 +35,6 @@ func TestStepCreateImage(t *testing.T) { assert.True(t, ok, "Image in state is not an Image.") // Verify created Image results. - assert.Equal(t, image.Licenses, d.CreateImageResultLicenses, "Created image licenses don't match the licenses returned by the driver.") assert.Equal(t, image.Name, c.ImageName, "Created image does not match config name.") assert.Equal(t, image.ProjectId, d.CreateImageResultProjectId, "Created image project does not match driver project.") assert.Equal(t, image.SizeGb, d.CreateImageResultSizeGb, "Created image size does not match the size returned by the driver.") @@ -48,6 +46,7 @@ func TestStepCreateImage(t *testing.T) { assert.Equal(t, d.CreateImageZone, c.Zone, "Incorrect image zone passed to driver.") assert.Equal(t, d.CreateImageDisk, c.DiskName, "Incorrect disk passed to driver.") assert.Equal(t, d.CreateImageLabels, c.ImageLabels, "Incorrect image_labels passed to driver.") + assert.Equal(t, d.CreateImageLicenses, c.ImageLicenses, "Incorrect image_licenses passed to driver.") } func TestStepCreateImage_errorOnChannel(t *testing.T) { From 1c9f18603c475ce83d8649200c0b57dd6855c771 Mon Sep 17 00:00:00 2001 From: Sean Malloy <spinelli85@gmail.com> Date: Sat, 3 Feb 2018 15:32:10 -0600 Subject: [PATCH 0580/1007] Fix Google Compute Builder Documentation Added required configuration option ssh_username to basic config example. --- website/source/docs/builders/googlecompute.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index 1c4717768..e8147e966 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -109,6 +109,7 @@ is assumed to be the path to the file containing the JSON. "account_file": "account.json", "project_id": "my project", "source_image": "debian-7-wheezy-v20150127", + "ssh_username": "packer", "zone": "us-central1-a" } ] From c75db88f6b8e7ff1b8a0c7cffebc77c9ae02a0f2 Mon Sep 17 00:00:00 2001 From: Sean Malloy <spinelli85@gmail.com> Date: Sat, 3 Feb 2018 15:56:29 -0600 Subject: [PATCH 0581/1007] Add documentation for new googlecompute builder image_licenses configuration option --- .../docs/builders/googlecompute.html.md | 63 ++++++++++++++----- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index e8147e966..d9be8cd28 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -93,7 +93,9 @@ Packer looks for credentials in the following places, preferring the first locat 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches credentials from the metadata server. (Needs a correct VM authentication scope configuration, see above) -## Basic Example +## Examples + +### Basic Example Below is a fully functioning example. It doesn't do anything useful, since no provisioners or startup-script metadata are defined, but it will effectively @@ -123,25 +125,50 @@ user used to connect in a startup-script. ``` {.json} { - "builders": [{ - "type": "googlecompute", - "account_file": "account.json", - "project_id": "my project", - "source_image": "windows-server-2016-dc-v20170227", - "disk_size": "50", - "machine_type": "n1-standard-1", - "communicator": "winrm", - "winrm_username": "packer_user", - "winrm_insecure": true, - "winrm_use_ssl": true, - "metadata": { - "windows-startup-script-cmd": "winrm quickconfig -quiet & net user /add packer_user & net localgroup administrators packer_user /add & winrm set winrm/config/service/auth @{Basic=\"true\"}" - }, - "zone": "us-central1-a" - }] + "builders": [ + { + "type": "googlecompute", + "account_file": "account.json", + "project_id": "my project", + "source_image": "windows-server-2016-dc-v20170227", + "disk_size": "50", + "machine_type": "n1-standard-1", + "communicator": "winrm", + "winrm_username": "packer_user", + "winrm_insecure": true, + "winrm_use_ssl": true, + "metadata": { + "windows-startup-script-cmd": "winrm quickconfig -quiet & net user /add packer_user & net localgroup administrators packer_user /add & winrm set winrm/config/service/auth @{Basic=\"true\"}" + }, + "zone": "us-central1-a" + } + ] } ``` +### Nested Hypervisor Example + +This is an example of using the `image_licenses` configuration option to create a GCE image that has nested virtualization enabled. See +[Enabling Nested Virtualization for VM Instances](https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances) +for details. + +``` json +{ + "builders": [ + { + "type": "googlecompute", + "account_file": "account.json", + "project_id": "my project", + "source_image_family": "centos-7", + "ssh_username": "packer", + "zone": "us-central1-a", + "image_licenses": ["projects/vm-options/global/licenses/enable-vmx"] + } + ] +} + +``` + ## Configuration Reference Configuration options are organized below into two categories: required and @@ -202,6 +229,8 @@ builder. - `image_labels` (object of key/value strings) - Key/value pair labels to apply to the created image. +- `image_licenses` (array of strings) - Licenses to apply to the created image. + - `image_name` (string) - The unique name of the resulting image. Defaults to `"packer-{{timestamp}}"`. From 22deb5045dceb96afaca506299f4bf60dd92bd52 Mon Sep 17 00:00:00 2001 From: Sean Malloy <spinelli85@gmail.com> Date: Sun, 4 Feb 2018 01:16:34 -0600 Subject: [PATCH 0582/1007] Remove extra new line from googlecompute docs --- website/source/docs/builders/googlecompute.html.md | 1 - 1 file changed, 1 deletion(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index d9be8cd28..cda97b02c 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -166,7 +166,6 @@ for details. } ] } - ``` ## Configuration Reference From 8827df1ed2e534d0632bd388a2b131135ed0892e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 5 Feb 2018 14:21:28 -0800 Subject: [PATCH 0583/1007] update go-aws-sdk to v1.12.71 --- vendor/github.com/aws/aws-sdk-go/CHANGELOG.md | 1119 ++++++++ .../github.com/aws/aws-sdk-go/CONTRIBUTING.md | 2 +- vendor/github.com/aws/aws-sdk-go/Gopkg.lock | 20 + vendor/github.com/aws/aws-sdk-go/Gopkg.toml | 48 + vendor/github.com/aws/aws-sdk-go/Makefile | 9 +- vendor/github.com/aws/aws-sdk-go/README.md | 6 +- .../aws-sdk-go/aws/client/default_retryer.go | 58 +- .../github.com/aws/aws-sdk-go/aws/config.go | 2 +- .../aws/aws-sdk-go/aws/defaults/defaults.go | 34 +- .../aws/aws-sdk-go/aws/endpoints/decode.go | 24 + .../aws/aws-sdk-go/aws/endpoints/defaults.go | 402 ++- .../aws/aws-sdk-go/aws/request/request.go | 146 +- .../aws/request/request_pagination.go | 25 +- .../aws/aws-sdk-go/aws/session/env_config.go | 5 +- .../aws/aws-sdk-go/aws/signer/v4/v4.go | 18 +- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../github.com/aws/aws-sdk-go/buildspec.yml | 21 + vendor/github.com/aws/aws-sdk-go/doc.go | 2 +- .../private/protocol/json/jsonutil/build.go | 21 +- .../protocol/json/jsonutil/unmarshal.go | 15 +- .../aws-sdk-go/private/protocol/jsonvalue.go | 76 + .../protocol/query/queryutil/queryutil.go | 4 + .../aws-sdk-go/private/protocol/rest/build.go | 21 +- .../private/protocol/rest/unmarshal.go | 14 +- .../aws/aws-sdk-go/service/ec2/api.go | 60 +- .../aws/aws-sdk-go/service/ec2/doc.go | 5 +- .../aws/aws-sdk-go/service/ecr/api.go | 1426 +++++++++- .../aws/aws-sdk-go/service/ecr/doc.go | 12 +- .../aws/aws-sdk-go/service/ecr/errors.go | 23 +- .../aws/aws-sdk-go/service/s3/api.go | 2340 ++++++++++++++--- .../aws/aws-sdk-go/service/s3/doc.go | 2 +- .../aws/aws-sdk-go/service/s3/doc_custom.go | 4 +- .../service/s3/s3iface/interface.go | 12 + .../aws-sdk-go/service/s3/s3manager/batch.go | 14 +- .../aws-sdk-go/service/s3/s3manager/upload.go | 10 +- .../aws/aws-sdk-go/service/sts/api.go | 62 +- .../aws/aws-sdk-go/service/sts/doc.go | 2 +- vendor/vendor.json | 304 +-- 38 files changed, 5557 insertions(+), 813 deletions(-) create mode 100644 vendor/github.com/aws/aws-sdk-go/Gopkg.lock create mode 100644 vendor/github.com/aws/aws-sdk-go/Gopkg.toml create mode 100644 vendor/github.com/aws/aws-sdk-go/buildspec.yml create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go diff --git a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md index b52655b67..0fc7f9c88 100644 --- a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md @@ -1,3 +1,1122 @@ +Release v1.12.71 (2018-02-05) +=== + +### Service Client Updates +* `service/acm`: Updates service documentation + * Documentation updates for acm +* `service/cloud9`: Updates service documentation and examples + * API usage examples for AWS Cloud9. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/kinesis`: Updates service API and documentation + * Using ListShards a Kinesis Data Streams customer or client can get information about shards in a data stream (including meta-data for each shard) without obtaining data stream level information. +* `service/opsworks`: Updates service API, documentation, and waiters + * AWS OpsWorks Stacks supports EBS encryption and HDD volume types. Also, a new DescribeOperatingSystems API is available, which lists all operating systems supported by OpsWorks Stacks. + +Release v1.12.70 (2018-01-26) +=== + +### Service Client Updates +* `service/devicefarm`: Updates service API and documentation + * Add InteractionMode in CreateRemoteAccessSession for DirectDeviceAccess feature. +* `service/medialive`: Updates service API and documentation + * Add InputSpecification to CreateChannel (specification of input attributes is used for channel sizing and affects pricing); add NotFoundException to DeleteInputSecurityGroups. +* `service/mturk-requester`: Updates service documentation + +Release v1.12.69 (2018-01-26) +=== + +### SDK Bugs +* `models/api`: Fix colliding names [#1754](https://github.com/aws/aws-sdk-go/pull/1754) [#1756](https://github.com/aws/aws-sdk-go/pull/1756) + * SDK had duplicate folders that were causing errors in some builds. + * Fixes [#1753](https://github.com/aws/aws-sdk-go/issues/1753) +Release v1.12.68 (2018-01-25) +=== + +### Service Client Updates +* `service/alexaforbusiness`: Updates service API and documentation +* `service/codebuild`: Updates service API and documentation + * Adding support for Shallow Clone and GitHub Enterprise in AWS CodeBuild. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/guardduty`: Adds new service + * Added the missing AccessKeyDetails object to the resource shape. +* `service/lambda`: Updates service API and documentation + * AWS Lambda now supports Revision ID on your function versions and aliases, to track and apply conditional updates when you are updating your function version or alias resources. + +### SDK Bugs +* `service/s3/s3manager`: Fix check for nil OrigErr in Error() [#1749](https://github.com/aws/aws-sdk-go/issues/1749) + * S3 Manager's `Error` type did not check for nil of `OrigErr` when calling `Error()` + * Fixes [#1748](https://github.com/aws/aws-sdk-go/issues/1748) +Release v1.12.67 (2018-01-22) +=== + +### Service Client Updates +* `service/budgets`: Updates service API and documentation + * Add additional costTypes: IncludeDiscount, UseAmortized, to support finer control for different charges included in a cost budget. + +Release v1.12.66 (2018-01-19) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/glue`: Updates service API and documentation + * New AWS Glue DataCatalog APIs to manage table versions and a new feature to skip archiving of the old table version when updating table. +* `service/transcribe`: Adds new service + +Release v1.12.65 (2018-01-18) +=== + +### Service Client Updates +* `service/sagemaker`: Updates service API and documentation + * CreateTrainingJob and CreateEndpointConfig now supports KMS Key for volume encryption. + +Release v1.12.64 (2018-01-17) +=== + +### Service Client Updates +* `service/autoscaling-plans`: Updates service documentation +* `service/ec2`: Updates service documentation + * Documentation updates for EC2 + +Release v1.12.63 (2018-01-17) +=== + +### Service Client Updates +* `service/application-autoscaling`: Updates service API and documentation +* `service/autoscaling-plans`: Adds new service +* `service/rds`: Updates service API and documentation + * With this release you can now integrate RDS DB instances with CloudWatch Logs. We have added parameters to the operations for creating and modifying DB instances (for example CreateDBInstance) to allow you to take advantage of this capability through the CLI and API. Once you enable this feature, a stream of log events will publish to CloudWatch Logs for each log type you enable. + +Release v1.12.62 (2018-01-15) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/lambda`: Updates service API and documentation + * Support for creating Lambda Functions using 'dotnetcore2.0' and 'go1.x'. + +Release v1.12.61 (2018-01-12) +=== + +### Service Client Updates +* `service/glue`: Updates service API and documentation + * Support is added to generate ETL scripts in Scala which can now be run by AWS Glue ETL jobs. In addition, the trigger API now supports firing when any conditions are met (in addition to all conditions). Also, jobs can be triggered based on a "failed" or "stopped" job run (in addition to a "succeeded" job run). + +Release v1.12.60 (2018-01-11) +=== + +### Service Client Updates +* `service/elasticloadbalancing`: Updates service API and documentation +* `service/elasticloadbalancingv2`: Updates service API and documentation +* `service/rds`: Updates service API and documentation + * Read Replicas for Amazon RDS for MySQL, MariaDB, and PostgreSQL now support Multi-AZ deployments.Amazon RDS Read Replicas enable you to create one or more read-only copies of your database instance within the same AWS Region or in a different AWS Region. Updates made to the source database are asynchronously copied to the Read Replicas. In addition to providing scalability for read-heavy workloads, you can choose to promote a Read Replica to become standalone a DB instance when needed.Amazon RDS Multi-AZ Deployments provide enhanced availability for database instances within a single AWS Region. With Multi-AZ, your data is synchronously replicated to a standby in a different Availability Zone (AZ). In case of an infrastructure failure, Amazon RDS performs an automatic failover to the standby, minimizing disruption to your applications.You can now combine Read Replicas with Multi-AZ as part of a disaster recovery strategy for your production databases. A well-designed and tested plan is critical for maintaining business continuity after a disaster. Since Read Replicas can also be created in different regions than the source database, your Read Replica can be promoted to become the new production database in case of a regional disruption.You can also combine Read Replicas with Multi-AZ for your database engine upgrade process. You can create a Read Replica of your production database instance and upgrade it to a new database engine version. When the upgrade is complete, you can stop applications, promote the Read Replica to a standalone database instance and switch over your applications. Since the database instance is already a Multi-AZ deployment, no additional steps are needed.For more information, see the Amazon RDS User Guide. +* `service/ssm`: Updates service documentation + * Updates documentation for the HierarchyLevelLimitExceededException error. + +Release v1.12.59 (2018-01-09) +=== + +### Service Client Updates +* `service/kms`: Updates service documentation + * Documentation updates for AWS KMS + +Release v1.12.58 (2018-01-09) +=== + +### Service Client Updates +* `service/ds`: Updates service API and documentation + * On October 24 we introduced AWS Directory Service for Microsoft Active Directory (Standard Edition), also known as AWS Microsoft AD (Standard Edition), which is a managed Microsoft Active Directory (AD) that is optimized for small and midsize businesses (SMBs). With this SDK release, you can now create an AWS Microsoft AD directory using API. This enables you to run typical SMB workloads using a cost-effective, highly available, and managed Microsoft AD in the AWS Cloud. + +Release v1.12.57 (2018-01-08) +=== + +### Service Client Updates +* `service/codedeploy`: Updates service API and documentation + * The AWS CodeDeploy API was updated to support DeleteGitHubAccountToken, a new method that deletes a GitHub account connection. +* `service/discovery`: Updates service API and documentation + * Documentation updates for AWS Application Discovery Service. +* `service/route53`: Updates service API and documentation + * This release adds an exception to the CreateTrafficPolicyVersion API operation. + +Release v1.12.56 (2018-01-05) +=== + +### Service Client Updates +* `service/inspector`: Updates service API, documentation, and examples + * Added 2 new attributes to the DescribeAssessmentTemplate response, indicating the total number of assessment runs and last assessment run ARN (if present.) +* `service/snowball`: Updates service documentation + * Documentation updates for snowball +* `service/ssm`: Updates service documentation + * Documentation updates for ssm + +Release v1.12.55 (2018-01-02) +=== + +### Service Client Updates +* `service/rds`: Updates service documentation + * Documentation updates for rds + +Release v1.12.54 (2017-12-29) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/workspaces`: Updates service API and documentation + * Modify WorkSpaces have been updated with flexible storage and switching of hardware bundles feature. The following configurations have been added to ModifyWorkSpacesProperties: storage and compute. This update provides the capability to configure the storage of a WorkSpace. It also adds the capability of switching hardware bundle of a WorkSpace by specifying an eligible compute (Value, Standard, Performance, Power). + +Release v1.12.53 (2017-12-22) +=== + +### Service Client Updates +* `service/ec2`: Updates service API + * This release fixes an issue with tags not showing in DescribeAddresses responses. +* `service/ecs`: Updates service API and documentation + * Amazon ECS users can now set a health check initialization wait period of their ECS services, the services that are associated with an Elastic Load Balancer (ELB) will wait for a period of time before the ELB become healthy. You can now configure this in Create and Update Service. +* `service/inspector`: Updates service API and documentation + * PreviewAgents API now returns additional fields within the AgentPreview data type. The API now shows the agent health and availability status for all instances included in the assessment target. This allows users to check the health status of Inspector Agents before running an assessment. In addition, it shows the instance ID, hostname, and IP address of the targeted instances. +* `service/sagemaker`: Updates service API and documentation + * SageMaker Models no longer support SupplementalContainers. API's that have been affected are CreateModel and DescribeModel. + +Release v1.12.52 (2017-12-21) +=== + +### Service Client Updates +* `service/codebuild`: Updates service API and documentation + * Adding support allowing AWS CodeBuild customers to select specific curated image versions. +* `service/ec2`: Updates service API and documentation + * Elastic IP tagging enables you to add key and value metadata to your Elastic IPs so that you can search, filter, and organize them according to your organization's needs. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/kinesisanalytics`: Updates service API and documentation + * Kinesis Analytics now supports AWS Lambda functions as output. + +Release v1.12.51 (2017-12-21) +=== + +### Service Client Updates +* `service/config`: Updates service API +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/iot`: Updates service API and documentation + * This release adds support for code signed Over-the-air update functionality for Amazon FreeRTOS. Users can now create and schedule Over-the-air updates to their Amazon FreeRTOS devices using these new APIs. + +Release v1.12.50 (2017-12-19) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * API Gateway now adds support for calling API with compressed payloads using one of the supported content codings, tagging an API stage for cost allocation, and returning API keys from a custom authorizer for use with a usage plan. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/mediastore-data`: Updates service documentation +* `service/route53`: Updates service API and documentation + * Route 53 added support for a new China (Ningxia) region, cn-northwest-1. You can now specify cn-northwest-1 as the region for latency-based or geoproximity routing. Route 53 also added support for a new EU (Paris) region, eu-west-3. You can now associate VPCs in eu-west-3 with private hosted zones and create alias records that route traffic to resources in eu-west-3. + +Release v1.12.49 (2017-12-19) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/monitoring`: Updates service documentation + * Documentation updates for monitoring + +Release v1.12.48 (2017-12-15) +=== + +### Service Client Updates +* `service/appstream`: Updates service API and documentation + * This API update is to enable customers to add tags to their Amazon AppStream 2.0 resources + +Release v1.12.47 (2017-12-14) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * Adds support for Cognito Authorizer scopes at the API method level. +* `service/email`: Updates service documentation + * Added information about the maximum number of transactions per second for the SendCustomVerificationEmail operation. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.46 (2017-12-12) +=== + +### Service Client Updates +* `service/workmail`: Adds new service + * Today, Amazon WorkMail released an administrative SDK and enabled AWS CloudTrail integration. With the administrative SDK, you can natively integrate WorkMail with your existing services. The SDK enables programmatic user, resource, and group management through API calls. This means your existing IT tools and workflows can now automate WorkMail management, and third party applications can streamline WorkMail migrations and account actions. + +Release v1.12.45 (2017-12-11) +=== + +### Service Client Updates +* `service/cognito-idp`: Updates service API and documentation +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/lex-models`: Updates service API and documentation +* `service/sagemaker`: Updates service API + * CreateModel API Update: The request parameter 'ExecutionRoleArn' has changed from optional to required. + +Release v1.12.44 (2017-12-08) +=== + +### Service Client Updates +* `service/appstream`: Updates service API and documentation + * This API update is to support the feature that allows customers to automatically consume the latest Amazon AppStream 2.0 agent as and when published by AWS. +* `service/ecs`: Updates service documentation + * Documentation updates for Windows containers. +* `service/monitoring`: Updates service API and documentation + * With this launch, you can now create a CloudWatch alarm that alerts you when M out of N datapoints of a metric are breaching your predefined threshold, such as three out of five times in any given five minutes interval or two out of six times in a thirty minutes interval. When M out of N datapoints are not breaching your threshold in an interval, the alarm will be in OK state. Please note that the M datapoints out of N datapoints in an interval can be of any order and does not need to be consecutive. Consequently, you can now get alerted even when the spikes in your metrics are intermittent over an interval. + +Release v1.12.43 (2017-12-07) +=== + +### Service Client Updates +* `service/email`: Updates service API, documentation, and paginators + * Customers can customize the emails that Amazon SES sends when verifying new identities. This feature is helpful for developers whose applications send email through Amazon SES on behalf of their customers. +* `service/es`: Updates service API and documentation + * Added support for encryption of data at rest on Amazon Elasticsearch Service using AWS KMS + +### SDK Bugs +* `models/apis` Fixes removes colliding sagemaker models folders ([#1686](https://github.com/aws/aws-sdk-go/pull/1686)) + * Fixes Release v1.12.42's SageMaker vs sagemaker model folders. +Release v1.12.42 (2017-12-06) +=== + +### Service Client Updates +* `service/clouddirectory`: Updates service API and documentation + * Amazon Cloud Directory makes it easier for you to apply schema changes across your directories with in-place schema upgrades. Your directories now remain available while backward-compatible schema changes are being applied, such as the addition of new fields. You also can view the history of your schema changes in Cloud Directory by using both major and minor version identifiers, which can help you track and audit schema versions across directories. +* `service/elasticbeanstalk`: Updates service documentation + * Documentation updates for AWS Elastic Beanstalk. +* `service/sagemaker`: Adds new service + * Initial waiters for common SageMaker workflows. + +Release v1.12.41 (2017-12-05) +=== + +### Service Client Updates +* `service/iot`: Updates service API and documentation + * Add error action API for RulesEngine. +* `service/servicecatalog`: Updates service API and documentation + * ServiceCatalog has two distinct personas for its use, an "admin" persona (who creates sets of products with different versions and prescribes who has access to them) and an "end-user" persona (who can launch cloud resources based on the configuration data their admins have given them access to). This API update will allow admin users to deactivate/activate product versions, end-user will only be able to access and launch active product versions. +* `service/servicediscovery`: Adds new service + * Amazon Route 53 Auto Naming lets you configure public or private namespaces that your microservice applications run in. When instances of the service become available, you can call the Auto Naming API to register the instance, and Amazon Route 53 automatically creates up to five DNS records and an optional health check. Clients that submit DNS queries for the service receive an answer that contains up to eight healthy records. + +Release v1.12.40 (2017-12-04) +=== + +### Service Client Updates +* `service/budgets`: Updates service API and documentation + * Add additional costTypes to support finer control for different charges included in a cost budget. +* `service/ecs`: Updates service documentation + * Documentation updates for ecs + +Release v1.12.39 (2017-12-01) +=== + +### Service Client Updates +* `service/SageMaker`: Updates service waiters + +Release v1.12.38 (2017-11-30) +=== + +### Service Client Updates +* `service/AWSMoneypenny`: Adds new service +* `service/Cloud9`: Adds new service +* `service/Serverless Registry`: Adds new service +* `service/apigateway`: Updates service API, documentation, and paginators + * Added support Private Integration and VPC Link features in API Gateway. This allows to create an API with the API Gateway private integration, thus providing clients access to HTTP/HTTPS resources in an Amazon VPC from outside of the VPC through a VpcLink resource. +* `service/ec2`: Updates service API and documentation + * Adds the following updates: 1. Spread Placement ensures that instances are placed on distinct hardware in order to reduce correlated failures. 2. Inter-region VPC Peering allows customers to peer VPCs across different AWS regions without requiring additional gateways, VPN connections or physical hardware +* `service/lambda`: Updates service API and documentation + * AWS Lambda now supports the ability to set the concurrency limits for individual functions, and increasing memory to 3008 MB. + +Release v1.12.37 (2017-11-30) +=== + +### Service Client Updates +* `service/Ardi`: Adds new service +* `service/autoscaling`: Updates service API and documentation + * You can now use Auto Scaling with EC2 Launch Templates via the CreateAutoScalingGroup and UpdateAutoScalingGroup APIs. +* `service/ec2`: Updates service API and documentation + * Adds the following updates: 1. T2 Unlimited enables high CPU performance for any period of time whenever required 2. You are now able to create and launch EC2 m5 and h1 instances +* `service/lightsail`: Updates service API and documentation + * This release adds support for load balancer and TLS/SSL certificate management. This set of APIs allows customers to create, manage, and scale secure load balanced applications on Lightsail infrastructure. To provide support for customers who manage their DNS on Lightsail, we've added the ability create an Alias A type record which can point to a load balancer DNS name via the CreateDomainEntry API http://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_CreateDomainEntry.html. +* `service/ssm`: Updates service API and documentation + * This release updates AWS Systems Manager APIs to enable executing automations at controlled rate, target resources in a resource groups and execute entire automation at once or single step at a time. It is now also possible to use YAML, in addition to JSON, when creating Systems Manager documents. +* `service/waf`: Updates service API and documentation + * This release adds support for rule group and managed rule group. Rule group is a container of rules that customers can create, put rules in it and associate the rule group to a WebACL. All rules in a rule group will function identically as they would if each rule was individually associated to the WebACL. Managed rule group is a pre-configured rule group composed by our security partners and made available via the AWS Marketplace. Customers can subscribe to these managed rule groups, associate the managed rule group to their WebACL and start using them immediately to protect their resources. +* `service/waf-regional`: Updates service API and documentation + +Release v1.12.36 (2017-11-29) +=== + +### Service Client Updates +* `service/DeepInsight`: Adds new service +* `service/IronmanRuntime`: Adds new service +* `service/Orchestra - Laser`: Adds new service +* `service/SageMaker`: Adds new service +* `service/Shine`: Adds new service +* `service/archived.kinesisvideo`: Adds new service +* `service/data.kinesisvideo`: Adds new service +* `service/dynamodb`: Updates service API and documentation + * Amazon DynamoDB now supports the following features: Global Table and On-Demand Backup. Global Table is a fully-managed, multi-region, multi-master database. DynamoDB customers can now write anywhere and read anywhere with single-digit millisecond latency by performing database operations closest to where end users reside. Global Table also enables customers to disaster-proof their applications, keeping them running and data accessible even in the face of natural disasters or region disruptions. Customers can set up Global Table with just a few clicks in the AWS Management Console-no application rewrites required. On-Demand Backup capability is to protect data from loss due to application errors, and meet customers' archival needs for compliance and regulatory reasons. Customers can backup and restore their DynamoDB table data anytime, with a single-click in the AWS management console or a single API call. Backup and restore actions execute with zero impact on table performance or availability. For more information, see the Amazon DynamoDB Developer Guide. +* `service/ecs`: Updates service API and documentation + * Amazon Elastic Container Service (Amazon ECS) released a new launch type for running containers on a serverless infrastructure. The Fargate launch type allows you to run your containerized applications without the need to provision and manage the backend infrastructure. Just register your task definition and Fargate launches the container for you. +* `service/glacier`: Updates service API and documentation + * This release includes support for Glacier Select, a new feature that allows you to filter and analyze your Glacier archives and store the results in a user-specified S3 location. +* `service/greengrass`: Updates service API and documentation + * Greengrass OTA feature allows updating Greengrass Core and Greengrass OTA Agent. Local Resource Access feature allows Greengrass Lambdas to access local resources such as peripheral devices and volumes. +* `service/iot`: Updates service API and documentation + * This release adds support for a number of new IoT features, including AWS IoT Device Management (Jobs, Fleet Index and Thing Registration), Thing Groups, Policies on Thing Groups, Registry & Job Events, JSON Logs, Fine-Grained Logging Controls, Custom Authorization and AWS Service Authentication Using X.509 Certificates. +* `service/kinesisvideo`: Adds new service + * Announcing Amazon Kinesis Video Streams, a fully managed video ingestion and storage service. Kinesis Video Streams makes it easy to securely stream video from connected devices to AWS for machine learning, analytics, and processing. You can also stream other time-encoded data like RADAR and LIDAR signals using Kinesis Video Streams. +* `service/rekognition`: Updates service API, documentation, and paginators + * This release introduces Amazon Rekognition support for video analysis. +* `service/s3`: Updates service API and documentation + * This release includes support for Glacier Select, a new feature that allows you to filter and analyze your Glacier storage class objects and store the results in a user-specified S3 location. + +Release v1.12.35 (2017-11-29) +=== + +### Service Client Updates +* `service/AmazonMQ`: Adds new service +* `service/GuardDuty`: Adds new service +* `service/apigateway`: Updates service API and documentation + * Changes related to CanaryReleaseDeployment feature. Enables API developer to create a deployment as canary deployment and test API changes with percentage of customers before promoting changes to all customers. +* `service/batch`: Updates service API and documentation + * Add support for Array Jobs which allow users to easily submit many copies of a job with a single API call. This change also enhances the job dependency model to support N_TO_N and sequential dependency chains. The ListJobs and DescribeJobs APIs now have the ability to list or describe the status of entire Array Jobs or individual elements within the array. +* `service/cognito-idp`: Updates service API and documentation +* `service/deepdish`: Adds new service + * AWS AppSync is an enterprise-level, fully managed GraphQL service with real-time data synchronization and offline programming features. +* `service/ec2`: Updates service API and documentation + * Adds the following updates: 1. You are now able to host a service powered by AWS PrivateLink to provide private connectivity to other VPCs. You are now also able to create endpoints to other services powered by PrivateLink including AWS services, Marketplace Seller services or custom services created by yourself or other AWS VPC customers. 2. You are now able to save launch parameters in a single template that can be used with Auto Scaling, Spot Fleet, Spot, and On Demand instances. 3. You are now able to launch Spot instances via the RunInstances API, using a single additional parameter. RunInstances will response synchronously with an instance ID should capacity be available for your Spot request. 4. A simplified Spot pricing model which delivers low, predictable prices that adjust gradually, based on long-term trends in supply and demand. 5. Amazon EC2 Spot can now hibernate Amazon EBS-backed instances in the event of an interruption, so your workloads pick up from where they left off. Spot can fulfill your request by resuming instances from a hibernated state when capacity is available. +* `service/lambda`: Updates service API and documentation + * Lambda aliases can now shift traffic between two function versions, based on preassigned weights. + +Release v1.12.34 (2017-11-27) +=== + +### Service Client Updates +* `service/data.mediastore`: Adds new service +* `service/mediaconvert`: Adds new service + * AWS Elemental MediaConvert is a file-based video conversion service that transforms media into formats required for traditional broadcast and for internet streaming to multi-screen devices. +* `service/medialive`: Adds new service + * AWS Elemental MediaLive is a video service that lets you easily create live outputs for broadcast and streaming delivery. +* `service/mediapackage`: Adds new service + * AWS Elemental MediaPackage is a just-in-time video packaging and origination service that lets you format highly secure and reliable live outputs for a variety of devices. +* `service/mediastore`: Adds new service + * AWS Elemental MediaStore is an AWS storage service optimized for media. It gives you the performance, consistency, and low latency required to deliver live and on-demand video content. AWS Elemental MediaStore acts as the origin store in your video workflow. + +Release v1.12.33 (2017-11-22) +=== + +### Service Client Updates +* `service/acm`: Updates service API and documentation + * AWS Certificate Manager now supports the ability to import domainless certs and additional Key Types as well as an additional validation method for DNS. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.32 (2017-11-22) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * Add support for Access logs and customizable integration timeouts +* `service/cloudformation`: Updates service API and documentation + * 1) Instance-level parameter overrides (CloudFormation-StackSet feature): This feature will allow the customers to override the template parameters on specific stackInstances. Customers will also have ability to update their existing instances with/without parameter-overrides using a new API "UpdateStackInstances" 2) Add support for SSM parameters in CloudFormation - This feature will allow the customers to use Systems Manager parameters in CloudFormation templates. They will be able to see values for these parameters in Describe APIs. +* `service/codebuild`: Updates service API and documentation + * Adding support for accessing Amazon VPC resources from AWS CodeBuild, dependency caching and build badges. +* `service/elasticmapreduce`: Updates service API and documentation + * Enable Kerberos on Amazon EMR. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/rekognition`: Updates service API and documentation + * This release includes updates to Amazon Rekognition for the following APIs. The new DetectText API allows you to recognize and extract textual content from images. Face Model Versioning has been added to operations that deal with face detection. +* `service/shield`: Updates service API, documentation, and paginators + * The AWS Shield SDK has been updated in order to support Elastic IP address protections, the addition of AttackProperties objects in DescribeAttack responses, and a new GetSubscriptionState operation. +* `service/storagegateway`: Updates service API and documentation + * AWS Storage Gateway now enables you to get notification when all your files written to your NFS file share have been uploaded to Amazon S3. Storage Gateway also enables guessing of the MIME type for uploaded objects based on file extensions. +* `service/xray`: Updates service API, documentation, and paginators + * Added automatic pagination support for AWS X-Ray APIs in the SDKs that support this feature. + +Release v1.12.31 (2017-11-20) +=== + +### Service Client Updates +* `service/apigateway`: Updates service documentation + * Documentation updates for Apigateway +* `service/codecommit`: Updates service API, documentation, and paginators + * AWS CodeCommit now supports pull requests. You can use pull requests to collaboratively review code changes for minor changes or fixes, major feature additions, or new versions of your released software. +* `service/firehose`: Updates service API and documentation + * This release includes a new Kinesis Firehose feature that supports Splunk as Kinesis Firehose delivery destination. You can now use Kinesis Firehose to ingest real-time data to Splunk in a serverless, reliable, and salable manner. This release also includes a new feature that allows you to configure Lambda buffer size in Kinesis Firehose data transformation feature. You can now customize the data buffer size before invoking Lambda function in Kinesis Firehose for data transformation. This feature allows you to flexibly trade-off processing and delivery latency with cost and efficiency based on your specific use cases and requirements. +* `service/iis`: Adds new service + * The AWS Cost Explorer API gives customers programmatic access to AWS cost and usage information, allowing them to perform adhoc queries and build interactive cost management applications that leverage this dataset. +* `service/kinesis`: Updates service API and documentation + * Customers can now obtain the important characteristics of their stream with DescribeStreamSummary. The response will not include the shard list for the stream but will have the number of open shards, and all the other fields included in the DescribeStream response. +* `service/workdocs`: Updates service API and documentation + * DescribeGroups API and miscellaneous enhancements + +### SDK Bugs +* `aws/client`: Retry delays for throttled exception were not limited to 5 mintues [#1654](https://github.com/aws/aws-sdk-go/pull/1654) + * Fixes [#1653](https://github.com/aws/aws-sdk-go/issues/1653) +Release v1.12.30 (2017-11-17) +=== + +### Service Client Updates +* `service/application-autoscaling`: Updates service API and documentation +* `service/dms`: Updates service API, documentation, and paginators + * Support for migration task assessment. Support for data validation after the migration. +* `service/elasticloadbalancingv2`: Updates service API and documentation +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/rds`: Updates service API and documentation + * Amazon RDS now supports importing MySQL databases by using backup files from Amazon S3. +* `service/s3`: Updates service API + * Added ORC to the supported S3 Inventory formats. + +### SDK Bugs +* `private/protocol/restjson`: Define JSONValue marshaling for body and querystring ([#1640](https://github.com/aws/aws-sdk-go/pull/1640)) + * Adds support for APIs which use JSONValue for body and querystring targets. + * Fixes [#1636](https://github.com/aws/aws-sdk-go/issues/1636) +Release v1.12.29 (2017-11-16) +=== + +### Service Client Updates +* `service/application-autoscaling`: Updates service API and documentation +* `service/ec2`: Updates service API + * You are now able to create and launch EC2 x1e smaller instance sizes +* `service/glue`: Updates service API and documentation + * API update for AWS Glue. New crawler configuration attribute enables customers to specify crawler behavior. New XML classifier enables classification of XML data. +* `service/opsworkscm`: Updates service API, documentation, and waiters + * Documentation updates for OpsWorks-cm: a new feature, OpsWorks for Puppet Enterprise, that allows users to create and manage OpsWorks-hosted Puppet Enterprise servers. +* `service/organizations`: Updates service API, documentation, and paginators + * This release adds APIs that you can use to enable and disable integration with AWS services designed to work with AWS Organizations. This integration allows the AWS service to perform operations on your behalf on all of the accounts in your organization. Although you can use these APIs yourself, we recommend that you instead use the commands provided in the other AWS service to enable integration with AWS Organizations. +* `service/route53`: Updates service API and documentation + * You can use Route 53's GetAccountLimit/GetHostedZoneLimit/GetReusableDelegationSetLimit APIs to view your current limits (including custom set limits) on Route 53 resources such as hosted zones and health checks. These APIs also return the number of each resource you're currently using to enable comparison against your current limits. + +Release v1.12.28 (2017-11-15) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * 1. Extended GetDocumentationParts operation to support retrieving documentation parts resources without contents. 2. Added hosted zone ID in the custom domain response. +* `service/email`: Updates service API, documentation, and examples + * SES launches Configuration Set Reputation Metrics and Email Pausing Today, two features that build upon the capabilities of the reputation dashboard. The first is the ability to export reputation metrics for individual configuration sets. The second is the ability to temporarily pause email sending, either at the configuration set level, or across your entire Amazon SES account. +* `service/polly`: Updates service API + * Amazon Polly adds Korean language support with new female voice - "Seoyeon" and new Indian English female voice - "Aditi" +* `service/states`: Updates service API and documentation + * You can now use the UpdateStateMachine API to update your state machine definition and role ARN. Existing executions will continue to use the previous definition and role ARN. You can use the DescribeStateMachineForExecution API to determine which state machine definition and role ARN is associated with an execution + +Release v1.12.27 (2017-11-14) +=== + +### Service Client Updates +* `service/ecs`: Updates service API and documentation + * Added new mode for Task Networking in ECS, called awsvpc mode. Mode configuration parameters to be passed in via awsvpcConfiguration. Updated APIs now use/show this new mode - RegisterTaskDefinition, CreateService, UpdateService, RunTask, StartTask. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/lightsail`: Updates service API and documentation + * Lightsail now supports attached block storage, which allows you to scale your applications and protect application data with additional SSD-backed storage disks. This feature allows Lightsail customers to attach secure storage disks to their Lightsail instances and manage their attached disks, including creating and deleting disks, attaching and detaching disks from instances, and backing up disks via snapshot. +* `service/route53`: Updates service API and documentation + * When a Route 53 health check or hosted zone is created by a linked AWS service, the object now includes information about the service that created it. Hosted zones or health checks that are created by a linked service can't be updated or deleted using Route 53. +* `service/ssm`: Updates service API and documentation + * EC2 Systems Manager GetInventory API adds support for aggregation. + +### SDK Enhancements +* `aws/request`: Remove default port from HTTP host header ([#1618](https://github.com/aws/aws-sdk-go/pull/1618)) + * Updates the SDK to automatically remove default ports based on the URL's scheme when setting the HTTP Host header's value. + * Fixes [#1537](https://github.com/aws/aws-sdk-go/issues/1537) + +Release v1.12.26 (2017-11-09) +=== + +### Service Client Updates +* `service/ec2`: Updates service API and documentation + * Introduces the following features: 1. Create a default subnet in an Availability Zone if no default subnet exists. 2. Spot Fleet integrates with Elastic Load Balancing to enable you to attach one or more load balancers to a Spot Fleet request. When you attach the load balancer, it automatically registers the instance in the Spot Fleet to the load balancers which distributes incoming traffic across the instances. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.25 (2017-11-08) +=== + +### Service Client Updates +* `service/application-autoscaling`: Updates service API and documentation +* `service/batch`: Updates service documentation + * Documentation updates for AWS Batch. +* `service/ec2`: Updates service API and documentation + * AWS PrivateLink for Amazon Services - Customers can now privately access Amazon services from their Amazon Virtual Private Cloud (VPC), without using public IPs, and without requiring the traffic to traverse across the Internet. +* `service/elasticache`: Updates service API and documentation + * This release adds online resharding for ElastiCache for Redis offering, providing the ability to add and remove shards from a running cluster. Developers can now dynamically scale-out or scale-in their Redis cluster workloads to adapt to changes in demand. ElastiCache will resize the cluster by adding or removing shards and redistribute hash slots uniformly across the new shard configuration, all while the cluster continues to stay online and serves requests. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.24 (2017-11-07) +=== + +### Service Client Updates +* `service/elasticloadbalancingv2`: Updates service documentation +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/rds`: Updates service API and documentation + * DescribeOrderableDBInstanceOptions now returns the minimum and maximum allowed values for storage size, total provisioned IOPS, and provisioned IOPS per GiB for a DB instance. +* `service/s3`: Updates service API, documentation, and examples + * This releases adds support for 4 features: 1. Default encryption for S3 Bucket, 2. Encryption status in inventory and Encryption support for inventory. 3. Cross region replication of KMS-encrypted objects, and 4. ownership overwrite for CRR. + +Release v1.12.23 (2017-11-07) +=== + +### Service Client Updates +* `service/api.pricing`: Adds new service +* `service/ec2`: Updates service API + * You are now able to create and launch EC2 C5 instances, the next generation of EC2's compute-optimized instances, in us-east-1, us-west-2 and eu-west-1. C5 instances offer up to 72 vCPUs, 144 GiB of DDR4 instance memory, 25 Gbps in Network bandwidth and improved EBS and Networking bandwidth on smaller instance sizes to deliver improved performance for compute-intensive workloads. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/kms`: Updates service API, documentation, and examples + * Documentation updates for AWS KMS. +* `service/organizations`: Updates service documentation + * This release updates permission statements for several API operations, and corrects some other minor errors. +* `service/states`: Updates service API, documentation, and paginators + * Documentation update. + +Release v1.12.22 (2017-11-03) +=== + +### Service Client Updates +* `service/ecs`: Updates service API and documentation + * Amazon ECS users can now add devices to their containers and enable init process in containers through the use of docker's 'devices' and 'init' features. These fields can be specified under linuxParameters in ContainerDefinition in the Task Definition Template. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.21 (2017-11-02) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * This release supports creating and managing Regional and Edge-Optimized API endpoints. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +### SDK Bugs +* `aws/request`: Fix bug in request presign creating invalide URL ([#1624](https://github.com/aws/aws-sdk-go/pull/1624)) + * Fixes a bug the Request Presign and PresignRequest methods that would allow a invalid expire duration as input. A expire time of 0 would be interpreted by the SDK to generate a normal request signature, not a presigned URL. This caused the returned URL unusable. + * Fixes [#1617](https://github.com/aws/aws-sdk-go/issues/1617) +Release v1.12.20 (2017-11-01) +=== + +### Service Client Updates +* `service/acm`: Updates service documentation + * Documentation updates for ACM +* `service/cloudhsmv2`: Updates service documentation + * Minor documentation update for AWS CloudHSM (cloudhsmv2). +* `service/directconnect`: Updates service API and documentation + * AWS DirectConnect now provides support for Global Access for Virtual Private Cloud (VPC) via a new feature called Direct Connect Gateway. A Direct Connect Gateway will allow you to group multiple Direct Connect Private Virtual Interfaces (DX-VIF) and Private Virtual Gateways (VGW) from different AWS regions (but belonging to the same AWS Account) and pass traffic from any DX-VIF to any VPC in the grouping. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +### SDK Enhancements +* `aws/client`: Adding status code 429 to throttlable status codes in default retryer (#1621) + +Release v1.12.19 (2017-10-26) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.18 (2017-10-26) +=== + +### Service Client Updates +* `service/cloudfront`: Updates service API and documentation + * You can now specify additional options for MinimumProtocolVersion, which controls the SSL/TLS protocol that CloudFront uses to communicate with viewers. The minimum protocol version that you choose also determines the ciphers that CloudFront uses to encrypt the content that it returns to viewers. +* `service/ec2`: Updates service API + * You are now able to create and launch EC2 P3 instance, next generation GPU instances, optimized for machine learning and high performance computing applications. With up to eight NVIDIA Tesla V100 GPUs, P3 instances provide up to one petaflop of mixed-precision, 125 teraflops of single-precision, and 62 teraflops of double-precision floating point performance, as well as a 300 GB/s second-generation NVLink interconnect that enables high-speed, low-latency GPU-to-GPU communication. P3 instances also feature up to 64 vCPUs based on custom Intel Xeon E5 (Broadwell) processors, 488 GB of DRAM, and 25 Gbps of dedicated aggregate network bandwidth using the Elastic Network Adapter (ENA). +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.17 (2017-10-24) +=== + +### Service Client Updates +* `service/config`: Updates service API +* `service/elasticache`: Updates service API, documentation, and examples + * Amazon ElastiCache for Redis today announced support for data encryption both for data in-transit and data at-rest. The new encryption in-transit functionality enables ElastiCache for Redis customers to encrypt data for all communication between clients and Redis engine, and all intra-cluster Redis communication. The encryption at-rest functionality allows customers to encrypt their S3 based backups. Customers can begin using the new functionality by simply enabling this functionality via AWS console, and a small configuration change in their Redis clients. The ElastiCache for Redis service automatically manages life cycle of the certificates required for encryption, including the issuance, renewal and expiration of certificates. Additionally, as part of this launch, customers will gain the ability to start using the Redis AUTH command that provides an added level of authentication. +* `service/glue`: Adds new service + * AWS Glue: Adding a new API, BatchStopJobRun, to stop one or more job runs for a specified Job. +* `service/pinpoint`: Updates service API and documentation + * Added support for APNs VoIP messages. Added support for collapsible IDs, message priority, and TTL for APNs and FCM/GCM. + +Release v1.12.16 (2017-10-23) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/organizations`: Updates service API and documentation + * This release supports integrating other AWS services with AWS Organizations through the use of an IAM service-linked role called AWSServiceRoleForOrganizations. Certain operations automatically create that role if it does not already exist. + +Release v1.12.15 (2017-10-20) +=== + +### Service Client Updates +* `service/ec2`: Updates service API and documentation + * Adding pagination support for DescribeSecurityGroups for EC2 Classic and VPC Security Groups + +Release v1.12.14 (2017-10-19) +=== + +### Service Client Updates +* `service/sqs`: Updates service API and documentation + * Added support for tracking cost allocation by adding, updating, removing, and listing the metadata tags of Amazon SQS queues. +* `service/ssm`: Updates service API and documentation + * EC2 Systems Manager versioning support for Parameter Store. Also support for referencing parameter versions in SSM Documents. + +Release v1.12.13 (2017-10-18) +=== + +### Service Client Updates +* `service/lightsail`: Updates service API and documentation + * This release adds support for Windows Server-based Lightsail instances. The GetInstanceAccessDetails API now returns the password of your Windows Server-based instance when using the default key pair. GetInstanceAccessDetails also returns a PasswordData object for Windows Server instances containing the ciphertext and keyPairName. The Blueprint data type now includes a list of platform values (LINUX_UNIX or WINDOWS). The Bundle data type now includes a list of SupportedPlatforms values (LINUX_UNIX or WINDOWS). + +Release v1.12.12 (2017-10-17) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/es`: Updates service API and documentation + * This release adds support for VPC access to Amazon Elasticsearch Service. + * This release adds support for VPC access to Amazon Elasticsearch Service. + +Release v1.12.11 (2017-10-16) +=== + +### Service Client Updates +* `service/cloudhsm`: Updates service API and documentation + * Documentation updates for AWS CloudHSM Classic. +* `service/ec2`: Updates service API and documentation + * You can now change the tenancy of your VPC from dedicated to default with a single API operation. For more details refer to the documentation for changing VPC tenancy. +* `service/es`: Updates service API and documentation + * AWS Elasticsearch adds support for enabling slow log publishing. Using slow log publishing options customers can configure and enable index/query slow log publishing of their domain to preferred AWS Cloudwatch log group. +* `service/rds`: Updates service API and waiters + * Adds waiters for DBSnapshotAvailable and DBSnapshotDeleted. +* `service/waf`: Updates service API and documentation + * This release adds support for regular expressions as match conditions in rules, and support for geographical location by country of request IP address as a match condition in rules. +* `service/waf-regional`: Updates service API and documentation + +Release v1.12.10 (2017-10-12) +=== + +### Service Client Updates +* `service/codecommit`: Updates service API and documentation + * This release includes the DeleteBranch API and a change to the contents of a Commit object. +* `service/dms`: Updates service API and documentation + * This change includes addition of new optional parameter to an existing API +* `service/elasticbeanstalk`: Updates service API and documentation + * Added the ability to add, delete or update Tags +* `service/polly`: Updates service API + * Amazon Polly exposes two new voices: "Matthew" (US English) and "Takumi" (Japanese) +* `service/rds`: Updates service API and documentation + * You can now call DescribeValidDBInstanceModifications to learn what modifications you can make to your DB instance. You can use this information when you call ModifyDBInstance. + +Release v1.12.9 (2017-10-11) +=== + +### Service Client Updates +* `service/ecr`: Updates service API, documentation, and paginators + * Adds support for new API set used to manage Amazon ECR repository lifecycle policies. Amazon ECR lifecycle policies enable you to specify the lifecycle management of images in a repository. The configuration is a set of one or more rules, where each rule defines an action for Amazon ECR to apply to an image. This allows the automation of cleaning up unused images, for example expiring images based on age or status. A lifecycle policy preview API is provided as well, which allows you to see the impact of a lifecycle policy on an image repository before you execute it +* `service/email`: Updates service API and documentation + * Added content related to email template management and templated email sending operations. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.12.8 (2017-10-10) +=== + +### Service Client Updates +* `service/ec2`: Updates service API and documentation + * This release includes updates to AWS Virtual Private Gateway. +* `service/elasticloadbalancingv2`: Updates service API and documentation +* `service/opsworkscm`: Updates service API and documentation + * Provide engine specific information for node associations. + +Release v1.12.7 (2017-10-06) +=== + +### Service Client Updates +* `service/sqs`: Updates service documentation + * Documentation updates regarding availability of FIFO queues and miscellaneous corrections. + +Release v1.12.6 (2017-10-05) +=== + +### Service Client Updates +* `service/redshift`: Updates service API and documentation + * DescribeEventSubscriptions API supports tag keys and tag values as request parameters. + +Release v1.12.5 (2017-10-04) +=== + +### Service Client Updates +* `service/kinesisanalytics`: Updates service API and documentation + * Kinesis Analytics now supports schema discovery on objects in S3. Additionally, Kinesis Analytics now supports input data preprocessing through Lambda. +* `service/route53domains`: Updates service API and documentation + * Added a new API that checks whether a domain name can be transferred to Amazon Route 53. + +### SDK Bugs +* `service/s3/s3crypto`: Correct PutObjectRequest documentation ([#1568](https://github.com/aws/aws-sdk-go/pull/1568)) + * s3Crypto's PutObjectRequest docstring example was using an incorrect value. Corrected the type used in the example. +Release v1.12.4 (2017-10-03) +=== + +### Service Client Updates +* `service/ec2`: Updates service API, documentation, and waiters + * This release includes service updates to AWS VPN. +* `service/ssm`: Updates service API and documentation + * EC2 Systems Manager support for tagging SSM Documents. Also support for tag-based permissions to restrict access to SSM Documents based on these tags. + +Release v1.12.3 (2017-10-02) +=== + +### Service Client Updates +* `service/cloudhsm`: Updates service documentation and paginators + * Documentation updates for CloudHSM + +Release v1.12.2 (2017-09-29) +=== + +### Service Client Updates +* `service/appstream`: Updates service API and documentation + * Includes APIs for managing and accessing image builders, and deleting images. +* `service/codebuild`: Updates service API and documentation + * Adding support for Building GitHub Pull Requests in AWS CodeBuild +* `service/mturk-requester`: Updates service API and documentation +* `service/organizations`: Updates service API and documentation + * This release flags the HandshakeParty structure's Type and Id fields as 'required'. They effectively were required in the past, as you received an error if you did not include them. This is now reflected at the API definition level. +* `service/route53`: Updates service API and documentation + * This change allows customers to reset elements of health check. + +### SDK Bugs +* `private/protocol/query`: Fix query protocol handling of nested byte slices ([#1557](https://github.com/aws/aws-sdk-go/issues/1557)) + * Fixes the query protocol to correctly marshal nested []byte values of API operations. +* `service/s3`: Fix PutObject and UploadPart API to include ContentMD5 field ([#1559](https://github.com/aws/aws-sdk-go/pull/1559)) + * Fixes the SDK's S3 PutObject and UploadPart API code generation to correctly render the ContentMD5 field into the associated input types for these two API operations. + * Fixes [#1553](https://github.com/aws/aws-sdk-go/pull/1553) +Release v1.12.1 (2017-09-27) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/pinpoint`: Updates service API and documentation + * Added two new push notification channels: Amazon Device Messaging (ADM) and, for push notification support in China, Baidu Cloud Push. Added support for APNs auth via .p8 key file. Added operation for direct message deliveries to user IDs, enabling you to message an individual user on multiple endpoints. + +Release v1.12.0 (2017-09-26) +=== + +### SDK Bugs +* `API Marshaler`: Revert REST JSON and XML protocol marshaler improvements + * Bug [#1550](https://github.com/aws/aws-sdk-go/issues/1550) identified a missed condition in the Amazon Route 53 RESTXML protocol marshaling causing requests to that service to fail. Reverting the marshaler improvements until the bug can be fixed. + +Release v1.11.0 (2017-09-26) +=== + +### Service Client Updates +* `service/cloudformation`: Updates service API and documentation + * You can now prevent a stack from being accidentally deleted by enabling termination protection on the stack. If you attempt to delete a stack with termination protection enabled, the deletion fails and the stack, including its status, remains unchanged. You can enable termination protection on a stack when you create it. Termination protection on stacks is disabled by default. After creation, you can set termination protection on a stack whose status is CREATE_COMPLETE, UPDATE_COMPLETE, or UPDATE_ROLLBACK_COMPLETE. + +### SDK Features +* Add dep Go dependency management metadata files (#1544) + * Adds the Go `dep` dependency management metadata files to the SDK. + * Fixes [#1451](https://github.com/aws/aws-sdk-go/issues/1451) + * Fixes [#634](https://github.com/aws/aws-sdk-go/issues/634) +* `service/dynamodb/expression`: Add expression building utility for DynamoDB ([#1527](https://github.com/aws/aws-sdk-go/pull/1527)) + * Adds a new package, expression, to the SDK providing builder utilities to create DynamoDB expressions safely taking advantage of type safety. +* `API Marshaler`: Add generated marshalers for RESTXML protocol ([#1409](https://github.com/aws/aws-sdk-go/pull/1409)) + * Updates the RESTXML protocol marshaler to use generated code instead of reflection for REST XML based services. +* `API Marshaler`: Add generated marshalers for RESTJSON protocol ([#1547](https://github.com/aws/aws-sdk-go/pull/1547)) + * Updates the RESTJSON protocol marshaler to use generated code instead of reflection for REST JSON based services. + +### SDK Enhancements +* `private/protocol`: Update format of REST JSON and XMl benchmarks ([#1546](https://github.com/aws/aws-sdk-go/pull/1546)) + * Updates the format of the REST JSON and XML benchmarks to be readable. RESTJSON benchmarks were updated to more accurately bench building of the protocol. + +Release v1.10.51 (2017-09-22) +=== + +### Service Client Updates +* `service/config`: Updates service API and documentation +* `service/ecs`: Updates service API and documentation + * Amazon ECS users can now add and drop Linux capabilities to their containers through the use of docker's cap-add and cap-drop features. Customers can specify the capabilities they wish to add or drop for each container in their task definition. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/rds`: Updates service documentation + * Documentation updates for rds + +Release v1.10.50 (2017-09-21) +=== + +### Service Client Updates +* `service/budgets`: Updates service API + * Including "DuplicateRecordException" in UpdateNotification and UpdateSubscriber. +* `service/ec2`: Updates service API and documentation + * Add EC2 APIs to copy Amazon FPGA Images (AFIs) within the same region and across multiple regions, delete AFIs, and modify AFI attributes. AFI attributes include name, description and granting/denying other AWS accounts to load the AFI. +* `service/logs`: Updates service API and documentation + * Adds support for associating LogGroups with KMS Keys. + +### SDK Bugs +* Fix greengrass service model being duplicated with different casing. ([#1541](https://github.com/aws/aws-sdk-go/pull/1541)) + * Fixes [#1540](https://github.com/aws/aws-sdk-go/issues/1540) + * Fixes [#1539](https://github.com/aws/aws-sdk-go/issues/1539) +Release v1.10.49 (2017-09-20) +=== + +### Service Client Updates +* `service/Greengrass`: Adds new service +* `service/appstream`: Updates service API and documentation + * API updates for supporting On-Demand fleets. +* `service/codepipeline`: Updates service API and documentation + * This change includes a PipelineMetadata object that is part of the output from the GetPipeline API that includes the Pipeline ARN, created, and updated timestamp. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/rds`: Updates service API and documentation + * Introduces the --option-group-name parameter to the ModifyDBSnapshot CLI command. You can specify this parameter when you upgrade an Oracle DB snapshot. The same option group considerations apply when upgrading a DB snapshot as when upgrading a DB instance. For more information, see http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Oracle.html#USER_UpgradeDBInstance.Oracle.OGPG.OG +* `service/runtime.lex`: Updates service API and documentation + +Release v1.10.48 (2017-09-19) +=== + +### Service Client Updates +* `service/ec2`: Updates service API + * Fixed bug in EC2 clients preventing ElasticGpuSet from being set. + +### SDK Enhancements +* `aws/credentials`: Add EnvProviderName constant. ([#1531](https://github.com/aws/aws-sdk-go/issues/1531)) + * Adds the "EnvConfigCredentials" string literal as EnvProviderName constant. + * Fixes [#1444](https://github.com/aws/aws-sdk-go/issues/1444) + +Release v1.10.47 (2017-09-18) +=== + +### Service Client Updates +* `service/ec2`: Updates service API and documentation + * Amazon EC2 now lets you opt for Spot instances to be stopped in the event of an interruption instead of being terminated. Your Spot request can be fulfilled again by restarting instances from a previously stopped state, subject to availability of capacity at or below your preferred price. When you submit a persistent Spot request, you can choose from "terminate" or "stop" as the instance interruption behavior. Choosing "stop" will shutdown your Spot instances so you can continue from this stopped state later on. This feature is only available for instances with Amazon EBS volume as their root device. +* `service/email`: Updates service API and documentation + * Amazon Simple Email Service (Amazon SES) now lets you customize the domains used for tracking open and click events. Previously, open and click tracking links referred to destinations hosted on domains operated by Amazon SES. With this feature, you can use your own branded domains for capturing open and click events. +* `service/iam`: Updates service API and documentation + * A new API, DeleteServiceLinkedRole, submits a service-linked role deletion request and returns a DeletionTaskId, which you can use to check the status of the deletion. + +Release v1.10.46 (2017-09-15) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * Add a new enum "REQUEST" to '--type <value>' field in the current create-authorizer API, and make "identitySource" optional. + +Release v1.10.45 (2017-09-14) +=== + +### Service Client Updates +* `service/codebuild`: Updates service API and documentation + * Supporting Parameter Store in environment variables for AWS CodeBuild +* `service/organizations`: Updates service documentation + * Documentation updates for AWS Organizations +* `service/servicecatalog`: Updates service API, documentation, and paginators + * This release of Service Catalog adds API support to copy products. + +Release v1.10.44 (2017-09-13) +=== + +### Service Client Updates +* `service/autoscaling`: Updates service API and documentation + * Customers can create Life Cycle Hooks at the time of creating Auto Scaling Groups through the CreateAutoScalingGroup API +* `service/batch`: Updates service documentation and examples + * Documentation updates for batch +* `service/ec2`: Updates service API + * You are now able to create and launch EC2 x1e.32xlarge instance, a new EC2 instance in the X1 family, in us-east-1, us-west-2, eu-west-1, and ap-northeast-1. x1e.32xlarge offers 128 vCPUs, 3,904 GiB of DDR4 instance memory, high memory bandwidth, large L3 caches, and leading reliability capabilities to boost the performance and reliability of in-memory applications. +* `service/events`: Updates service API and documentation + * Exposes ConcurrentModificationException as one of the valid exceptions for PutPermission and RemovePermission operation. + +### SDK Enhancements +* `service/autoscaling`: Fix documentation for PutScalingPolicy.AutoScalingGroupName [#1522](https://github.com/aws/aws-sdk-go/pull/1522) +* `service/s3/s3manager`: Clarify S3 Upload manager Concurrency config [#1521](https://github.com/aws/aws-sdk-go/pull/1521) + * Fixes [#1458](https://github.com/aws/aws-sdk-go/issues/1458) +* `service/dynamodb/dynamodbattribute`: Add support for time alias. [#1520](https://github.com/aws/aws-sdk-go/pull/1520) + * Related to [#1505](https://github.com/aws/aws-sdk-go/pull/1505) + +Release v1.10.43 (2017-09-12) +=== + +### Service Client Updates +* `service/ec2`: Updates service API + * Fixed bug in EC2 clients preventing HostOfferingSet from being set +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.10.42 (2017-09-12) +=== + +### Service Client Updates +* `service/devicefarm`: Updates service API and documentation + * DeviceFarm has added support for two features - RemoteDebugging and Customer Artifacts. Customers can now do remote Debugging on their Private Devices and can now retrieve custom files generated by their tests on the device and the device host (execution environment) on both public and private devices. + +Release v1.10.41 (2017-09-08) +=== + +### Service Client Updates +* `service/logs`: Updates service API and documentation + * Adds support for the PutResourcePolicy, DescribeResourcePolicy and DeleteResourcePolicy APIs. + +Release v1.10.40 (2017-09-07) +=== + +### Service Client Updates +* `service/application-autoscaling`: Updates service documentation +* `service/ec2`: Updates service API and documentation + * With Tagging support, you can add Key and Value metadata to search, filter and organize your NAT Gateways according to your organization's needs. +* `service/elasticloadbalancingv2`: Updates service API and documentation +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/lex-models`: Updates service API and documentation +* `service/route53`: Updates service API and documentation + * You can configure Amazon Route 53 to log information about the DNS queries that Amazon Route 53 receives for your domains and subdomains. When you configure query logging, Amazon Route 53 starts to send logs to CloudWatch Logs. You can use various tools, including the AWS console, to access the query logs. + +Release v1.10.39 (2017-09-06) +=== + +### Service Client Updates +* `service/budgets`: Updates service API and documentation + * Add an optional "thresholdType" to notifications to support percentage or absolute value thresholds. + +Release v1.10.38 (2017-09-05) +=== + +### Service Client Updates +* `service/codestar`: Updates service API and documentation + * Added support to tag CodeStar projects. Tags can be used to organize and find CodeStar projects on key-value pairs that you can choose. For example, you could add a tag with a key of "Release" and a value of "Beta" to projects your organization is working on for an upcoming beta release. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.10.37 (2017-09-01) +=== + +### Service Client Updates +* `service/MobileHub`: Adds new service +* `service/gamelift`: Updates service API and documentation + * GameLift VPC resources can be peered with any other AWS VPC. R4 memory-optimized instances now available to deploy. +* `service/ssm`: Updates service API and documentation + * Adding KMS encryption support to SSM Inventory Resource Data Sync. Exposes the ClientToken parameter on SSM StartAutomationExecution to provide idempotent execution requests. + +Release v1.10.36 (2017-08-31) +=== + +### Service Client Updates +* `service/codebuild`: Updates service API, documentation, and examples + * The AWS CodeBuild HTTP API now provides the BatchDeleteBuilds operation, which enables you to delete existing builds. +* `service/ec2`: Updates service API and documentation + * Descriptions for Security Group Rules enables customers to be able to define a description for ingress and egress security group rules . The Descriptions for Security Group Rules feature supports one description field per Security Group rule for both ingress and egress rules . Descriptions for Security Group Rules provides a simple way to describe the purpose or function of a Security Group Rule allowing for easier customer identification of configuration elements . Prior to the release of Descriptions for Security Group Rules , customers had to maintain a separate system outside of AWS if they wanted to track Security Group Rule mapping and their purpose for being implemented. If a security group rule has already been created and you would like to update or change your description for that security group rule you can use the UpdateSecurityGroupRuleDescription API. +* `service/elasticloadbalancingv2`: Updates service API and documentation +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/lex-models`: Updates service API and documentation + +### SDK Bugs +* `aws/signer/v4`: Revert [#1491](https://github.com/aws/aws-sdk-go/issues/1491) as change conflicts with an undocumented AWS v4 signature test case. + * Related to: [#1495](https://github.com/aws/aws-sdk-go/issues/1495). +Release v1.10.35 (2017-08-30) +=== + +### Service Client Updates +* `service/application-autoscaling`: Updates service API and documentation +* `service/organizations`: Updates service API and documentation + * The exception ConstraintViolationException now contains a new reason subcode MASTERACCOUNT_MISSING_CONTACT_INFO to make it easier to understand why attempting to remove an account from an Organization can fail. We also improved several other of the text descriptions and examples. + +Release v1.10.34 (2017-08-29) +=== + +### Service Client Updates +* `service/config`: Updates service API and documentation +* `service/ec2`: Updates service API and documentation + * Provides capability to add secondary CIDR blocks to a VPC. + +### SDK Bugs +* `aws/signer/v4`: Fix Signing Unordered Multi Value Query Parameters ([#1491](https://github.com/aws/aws-sdk-go/pull/1491)) + * Removes sorting of query string values when calculating v4 signing as this is not part of the spec. The spec only requires the keys, not values, to be sorted which is achieved by Query.Encode(). +Release v1.10.33 (2017-08-25) +=== + +### Service Client Updates +* `service/cloudformation`: Updates service API and documentation + * Rollback triggers enable you to have AWS CloudFormation monitor the state of your application during stack creation and updating, and to roll back that operation if the application breaches the threshold of any of the alarms you've specified. +* `service/gamelift`: Updates service API + * Update spelling of MatchmakingTicket status values for internal consistency. +* `service/rds`: Updates service API and documentation + * Option group options now contain additional properties that identify requirements for certain options. Check these properties to determine if your DB instance must be in a VPC or have auto minor upgrade turned on before you can use an option. Check to see if you can downgrade the version of an option after you have installed it. + +### SDK Enhancements +* `example/service/ec2`: Add EC2 list instances example ([#1492](https://github.com/aws/aws-sdk-go/pull/1492)) + +Release v1.10.32 (2017-08-25) +=== + +### Service Client Updates +* `service/rekognition`: Updates service API, documentation, and examples + * Update the enum value of LandmarkType and GenderType to be consistent with service response + +Release v1.10.31 (2017-08-23) +=== + +### Service Client Updates +* `service/appstream`: Updates service documentation + * Documentation updates for appstream +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.10.30 (2017-08-22) +=== + +### Service Client Updates +* `service/ssm`: Updates service API and documentation + * Changes to associations in Systems Manager State Manager can now be recorded. Previously, when you edited associations, you could not go back and review older association settings. Now, associations are versioned, and can be named using human-readable strings, allowing you to see a trail of association changes. You can also perform rate-based scheduling, which allows you to schedule associations more granularly. + +Release v1.10.29 (2017-08-21) +=== + +### Service Client Updates +* `service/firehose`: Updates service API, documentation, and paginators + * This change will allow customers to attach a Firehose delivery stream to an existing Kinesis stream directly. You no longer need a forwarder to move data from a Kinesis stream to a Firehose delivery stream. You can now run your streaming applications on your Kinesis stream and easily attach a Firehose delivery stream to it for data delivery to S3, Redshift, or Elasticsearch concurrently. +* `service/route53`: Updates service API and documentation + * Amazon Route 53 now supports CAA resource record type. A CAA record controls which certificate authorities are allowed to issue certificates for the domain or subdomain. + +Release v1.10.28 (2017-08-18) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.10.27 (2017-08-16) +=== + +### Service Client Updates +* `service/gamelift`: Updates service API and documentation + * The Matchmaking Grouping Service is a new feature that groups player match requests for a given game together into game sessions based on developer configured rules. + +### SDK Enhancements +* `aws/arn`: aws/arn: Package for parsing and producing ARNs ([#1463](https://github.com/aws/aws-sdk-go/pull/1463)) + * Adds the `arn` package for AWS ARN parsing and building. Use this package to build AWS ARNs for services such as outlined in the [documentation](http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + +### SDK Bugs +* `aws/signer/v4`: Correct V4 presign signature to include content sha25 in URL ([#1469](https://github.com/aws/aws-sdk-go/pull/1469)) + * Updates the V4 signer so that when a Presign is generated the `X-Amz-Content-Sha256` header is added to the query string instead of being required to be in the header. This allows you to generate presigned URLs for GET requests, e.g S3.GetObject that do not require additional headers to be set by the downstream users of the presigned URL. + * Related To: [#1467](https://github.com/aws/aws-sdk-go/issues/1467) + +Release v1.10.26 (2017-08-15) +=== + +### Service Client Updates +* `service/ec2`: Updates service API + * Fixed bug in EC2 clients preventing HostReservation from being set +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.10.25 (2017-08-14) +=== + +### Service Client Updates +* `service/AWS Glue`: Adds new service +* `service/batch`: Updates service API and documentation + * This release enhances the DescribeJobs API to include the CloudWatch logStreamName attribute in ContainerDetail and ContainerDetailAttempt +* `service/cloudhsmv2`: Adds new service + * CloudHSM provides hardware security modules for protecting sensitive data and cryptographic keys within an EC2 VPC, and enable the customer to maintain control over key access and use. This is a second-generation of the service that will improve security, lower cost and provide better customer usability. +* `service/elasticfilesystem`: Updates service API, documentation, and paginators + * Customers can create encrypted EFS file systems and specify a KMS master key to encrypt it with. +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/mgh`: Adds new service + * AWS Migration Hub provides a single location to track migrations across multiple AWS and partner solutions. Using Migration Hub allows you to choose the AWS and partner migration tools that best fit your needs, while providing visibility into the status of your entire migration portfolio. Migration Hub also provides key metrics and progress for individual applications, regardless of which tools are being used to migrate them. For example, you might use AWS Database Migration Service, AWS Server Migration Service, and partner migration tools to migrate an application comprised of a database, virtualized web servers, and a bare metal server. Using Migration Hub will provide you with a single screen that shows the migration progress of all the resources in the application. This allows you to quickly get progress updates across all of your migrations, easily identify and troubleshoot any issues, and reduce the overall time and effort spent on your migration projects. Migration Hub is available to all AWS customers at no additional charge. You only pay for the cost of the migration tools you use, and any resources being consumed on AWS. +* `service/ssm`: Updates service API and documentation + * Systems Manager Maintenance Windows include the following changes or enhancements: New task options using Systems Manager Automation, AWS Lambda, and AWS Step Functions; enhanced ability to edit the targets of a Maintenance Window, including specifying a target name and description, and ability to edit the owner field; enhanced ability to edits tasks; enhanced support for Run Command parameters; and you can now use a --safe flag when attempting to deregister a target. If this flag is enabled when you attempt to deregister a target, the system returns an error if the target is referenced by any task. Also, Systems Manager now includes Configuration Compliance to scan your fleet of managed instances for patch compliance and configuration inconsistencies. You can collect and aggregate data from multiple AWS accounts and Regions, and then drill down into specific resources that aren't compliant. +* `service/storagegateway`: Updates service API and documentation + * Add optional field ForceDelete to DeleteFileShare api. + +Release v1.10.24 (2017-08-11) +=== + +### Service Client Updates +* `service/codedeploy`: Updates service API and documentation + * Adds support for specifying Application Load Balancers in deployment groups, for both in-place and blue/green deployments. +* `service/cognito-idp`: Updates service API and documentation +* `service/ec2`: Updates service API and documentation + * Provides customers an opportunity to recover an EIP that was released + Release v1.10.23 (2017-08-10) === diff --git a/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md b/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md index 7c0186f0c..6f422a95e 100644 --- a/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md +++ b/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md @@ -67,7 +67,7 @@ Please be aware of the following notes prior to opening a pull request: 5. The JSON files under the SDK's `models` folder are sourced from outside the SDK. Such as `models/apis/ec2/2016-11-15/api.json`. We will not accept pull requests directly on these models. If you discover an issue with the models please - create a Github [issue](issues) describing the issue. + create a [GitHub issue][issues] describing the issue. ### Testing diff --git a/vendor/github.com/aws/aws-sdk-go/Gopkg.lock b/vendor/github.com/aws/aws-sdk-go/Gopkg.lock new file mode 100644 index 000000000..854c94fdf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/Gopkg.lock @@ -0,0 +1,20 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/go-ini/ini" + packages = ["."] + revision = "300e940a926eb277d3901b20bdfcc54928ad3642" + version = "v1.25.4" + +[[projects]] + name = "github.com/jmespath/go-jmespath" + packages = ["."] + revision = "0b12d6b5" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "51a86a867df617990082dec6b868e4efe2fdb2ed0e02a3daa93cd30f962b5085" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/aws/aws-sdk-go/Gopkg.toml b/vendor/github.com/aws/aws-sdk-go/Gopkg.toml new file mode 100644 index 000000000..664fc5955 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/Gopkg.toml @@ -0,0 +1,48 @@ + +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + +ignored = [ + # Testing/Example/Codegen dependencies + "github.com/stretchr/testify", + "github.com/stretchr/testify/assert", + "github.com/stretchr/testify/require", + "github.com/go-sql-driver/mysql", + "github.com/gucumber/gucumber", + "github.com/pkg/errors", + "golang.org/x/net", + "golang.org/x/net/html", + "golang.org/x/net/http2", + "golang.org/x/text", + "golang.org/x/text/html", + "golang.org/x/tools", + "golang.org/x/tools/go/loader", +] + + +[[constraint]] + name = "github.com/go-ini/ini" + version = "1.25.4" + +[[constraint]] + name = "github.com/jmespath/go-jmespath" + revision = "0b12d6b5" + #version = "0.2.2" diff --git a/vendor/github.com/aws/aws-sdk-go/Makefile b/vendor/github.com/aws/aws-sdk-go/Makefile index df9803c2a..83ccc1e62 100644 --- a/vendor/github.com/aws/aws-sdk-go/Makefile +++ b/vendor/github.com/aws/aws-sdk-go/Makefile @@ -74,7 +74,7 @@ smoke-tests: get-deps-tests performance: get-deps-tests AWS_TESTING_LOG_RESULTS=${log-detailed} AWS_TESTING_REGION=$(region) AWS_TESTING_DB_TABLE=$(table) gucumber -go-tags "integration" ./awstesting/performance -sandbox-tests: sandbox-test-go15 sandbox-test-go15-novendorexp sandbox-test-go16 sandbox-test-go17 sandbox-test-go18 sandbox-test-gotip +sandbox-tests: sandbox-test-go15 sandbox-test-go15-novendorexp sandbox-test-go16 sandbox-test-go17 sandbox-test-go18 sandbox-test-go19 sandbox-test-gotip sandbox-build-go15: docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5 -t "aws-sdk-go-1.5" . @@ -111,6 +111,13 @@ sandbox-go18: sandbox-build-go18 sandbox-test-go18: sandbox-build-go18 docker run -t aws-sdk-go-1.8 +sandbox-build-go19: + docker build -f ./awstesting/sandbox/Dockerfile.test.go1.8 -t "aws-sdk-go-1.9" . +sandbox-go19: sandbox-build-go19 + docker run -i -t aws-sdk-go-1.9 bash +sandbox-test-go19: sandbox-build-go19 + docker run -t aws-sdk-go-1.9 + sandbox-build-gotip: @echo "Run make update-aws-golang-tip, if this test fails because missing aws-golang:tip container" docker build -f ./awstesting/sandbox/Dockerfile.test.gotip -t "aws-sdk-go-tip" . diff --git a/vendor/github.com/aws/aws-sdk-go/README.md b/vendor/github.com/aws/aws-sdk-go/README.md index d5e048a5f..c32774491 100644 --- a/vendor/github.com/aws/aws-sdk-go/README.md +++ b/vendor/github.com/aws/aws-sdk-go/README.md @@ -6,6 +6,8 @@ aws-sdk-go is the official AWS SDK for the Go programming language. Checkout our [release notes](https://github.com/aws/aws-sdk-go/releases) for information about the latest bug fixes, updates, and features added to the SDK. +We [announced](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-2-0-developer-preview/) the Developer Preview for the [v2 AWS SDK for Go](). The v2 SDK is available at https://github.com/aws/aws-sdk-go-v2, and `go get github.com/aws/aws-sdk-go-v2` via `go get`. Check out the v2 SDK's [changes and updates](https://github.com/aws/aws-sdk-go-v2/blob/master/CHANGELOG.md), and let us know what you think. We want your feedback. + ## Installing If you are using Go 1.5 with the `GO15VENDOREXPERIMENT=1` vendoring flag, or 1.6 and higher you can use the following command to retrieve the SDK. The SDK's non-testing dependencies will be included and are vendored in the `vendor` folder. @@ -185,7 +187,7 @@ Option's SharedConfigState parameter. })) ``` -[credentials_pkg]: ttps://docs.aws.amazon.com/sdk-for-go/api/aws/credentials +[credentials_pkg]: https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials ### Configuring AWS Region @@ -305,7 +307,7 @@ documentation for the errors that could be returned. // will leak connections. defer result.Body.Close() - fmt.Println("Object Size:", aws.StringValue(result.ContentLength)) + fmt.Println("Object Size:", aws.Int64Value(result.ContentLength)) ``` ### API Request Pagination and Resource Waiters diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go index e25a460fb..63d2df67c 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go @@ -2,6 +2,7 @@ package client import ( "math/rand" + "strconv" "sync" "time" @@ -38,14 +39,18 @@ func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { minTime := 30 throttle := d.shouldThrottle(r) if throttle { + if delay, ok := getRetryDelay(r); ok { + return delay + } + minTime = 500 } retryCount := r.RetryCount - if retryCount > 13 { - retryCount = 13 - } else if throttle && retryCount > 8 { + if throttle && retryCount > 8 { retryCount = 8 + } else if retryCount > 13 { + retryCount = 13 } delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime) @@ -68,12 +73,49 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { // ShouldThrottle returns true if the request should be throttled. func (d DefaultRetryer) shouldThrottle(r *request.Request) bool { - if r.HTTPResponse.StatusCode == 502 || - r.HTTPResponse.StatusCode == 503 || - r.HTTPResponse.StatusCode == 504 { - return true + switch r.HTTPResponse.StatusCode { + case 429: + case 502: + case 503: + case 504: + default: + return r.IsErrorThrottle() } - return r.IsErrorThrottle() + + return true +} + +// This will look in the Retry-After header, RFC 7231, for how long +// it will wait before attempting another request +func getRetryDelay(r *request.Request) (time.Duration, bool) { + if !canUseRetryAfterHeader(r) { + return 0, false + } + + delayStr := r.HTTPResponse.Header.Get("Retry-After") + if len(delayStr) == 0 { + return 0, false + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + return 0, false + } + + return time.Duration(delay) * time.Second, true +} + +// Will look at the status code to see if the retry header pertains to +// the status code. +func canUseRetryAfterHeader(r *request.Request) bool { + switch r.HTTPResponse.StatusCode { + case 429: + case 503: + default: + return false + } + + return true } // lockedSource is a thread-safe implementation of rand.Source diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go index ae3a28696..4fd0d0724 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -168,7 +168,7 @@ type Config struct { // EC2MetadataDisableTimeoutOverride *bool - // Instructs the endpiont to be generated for a service client to + // Instructs the endpoint to be generated for a service client to // be the dual stack endpoint. The dual stack endpoint will support // both IPv4 and IPv6 addressing. // diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go index 07afe3b8e..2cb08182f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -9,6 +9,7 @@ package defaults import ( "fmt" + "net" "net/http" "net/url" "os" @@ -118,14 +119,43 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P return ec2RoleProvider(cfg, handlers) } +var lookupHostFn = net.LookupHost + +func isLoopbackHost(host string) (bool, error) { + ip := net.ParseIP(host) + if ip != nil { + return ip.IsLoopback(), nil + } + + // Host is not an ip, perform lookup + addrs, err := lookupHostFn(host) + if err != nil { + return false, err + } + for _, addr := range addrs { + if !net.ParseIP(addr).IsLoopback() { + return false, nil + } + } + + return true, nil +} + func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { var errMsg string parsed, err := url.Parse(u) if err != nil { errMsg = fmt.Sprintf("invalid URL, %v", err) - } else if host := aws.URLHostname(parsed); !(host == "localhost" || host == "127.0.0.1") { - errMsg = fmt.Sprintf("invalid host address, %q, only localhost and 127.0.0.1 are valid.", host) + } else { + host := aws.URLHostname(parsed) + if len(host) == 0 { + errMsg = "unable to parse host from local HTTP cred provider URL" + } else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil { + errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr) + } else if !isLoopback { + errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host) + } } if len(errMsg) > 0 { diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go index 74f72de07..6dc035a53 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "io" + "os" "github.com/aws/aws-sdk-go/aws/awserr" ) @@ -84,11 +85,34 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol custAddEC2Metadata(p) custAddS3DualStack(p) custRmIotDataService(p) + + custFixCloudHSMv2SigningName(p) } return ps, nil } +func custFixCloudHSMv2SigningName(p *partition) { + // Workaround for aws/aws-sdk-go#1745 until the endpoint model can be + // fixed upstream. TODO remove this once the endpoints model is updated. + + s, ok := p.Services["cloudhsmv2"] + if !ok { + return + } + + if len(s.Defaults.CredentialScope.Service) != 0 { + fmt.Fprintf(os.Stderr, "cloudhsmv2 signing name already set, ignoring override.\n") + // If the value is already set don't override + return + } + + s.Defaults.CredentialScope.Service = "cloudhsm" + fmt.Fprintf(os.Stderr, "cloudhsmv2 signing name not set, overriding.\n") + + p.Services["cloudhsmv2"] = s +} + func custAddS3DualStack(p *partition) { if p.ID != "aws" { return diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 899087ec5..689c380b4 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -24,6 +24,7 @@ const ( EuCentral1RegionID = "eu-central-1" // EU (Frankfurt). EuWest1RegionID = "eu-west-1" // EU (Ireland). EuWest2RegionID = "eu-west-2" // EU (London). + EuWest3RegionID = "eu-west-3" // EU (Paris). SaEast1RegionID = "sa-east-1" // South America (Sao Paulo). UsEast1RegionID = "us-east-1" // US East (N. Virginia). UsEast2RegionID = "us-east-2" // US East (Ohio). @@ -33,7 +34,8 @@ const ( // AWS China partition's regions. const ( - CnNorth1RegionID = "cn-north-1" // China (Beijing). + CnNorth1RegionID = "cn-north-1" // China (Beijing). + CnNorthwest1RegionID = "cn-northwest-1" // China (Ningxia). ) // AWS GovCloud (US) partition's regions. @@ -44,17 +46,20 @@ const ( // Service identifiers const ( AcmServiceID = "acm" // Acm. + ApiPricingServiceID = "api.pricing" // ApiPricing. ApigatewayServiceID = "apigateway" // Apigateway. ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling. Appstream2ServiceID = "appstream2" // Appstream2. AthenaServiceID = "athena" // Athena. AutoscalingServiceID = "autoscaling" // Autoscaling. + AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans. BatchServiceID = "batch" // Batch. BudgetsServiceID = "budgets" // Budgets. ClouddirectoryServiceID = "clouddirectory" // Clouddirectory. CloudformationServiceID = "cloudformation" // Cloudformation. CloudfrontServiceID = "cloudfront" // Cloudfront. CloudhsmServiceID = "cloudhsm" // Cloudhsm. + Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2. CloudsearchServiceID = "cloudsearch" // Cloudsearch. CloudtrailServiceID = "cloudtrail" // Cloudtrail. CodebuildServiceID = "codebuild" // Codebuild. @@ -68,6 +73,7 @@ const ( ConfigServiceID = "config" // Config. CurServiceID = "cur" // Cur. DatapipelineServiceID = "datapipeline" // Datapipeline. + DaxServiceID = "dax" // Dax. DevicefarmServiceID = "devicefarm" // Devicefarm. DirectconnectServiceID = "directconnect" // Directconnect. DiscoveryServiceID = "discovery" // Discovery. @@ -91,6 +97,7 @@ const ( FirehoseServiceID = "firehose" // Firehose. GameliftServiceID = "gamelift" // Gamelift. GlacierServiceID = "glacier" // Glacier. + GlueServiceID = "glue" // Glue. GreengrassServiceID = "greengrass" // Greengrass. HealthServiceID = "health" // Health. IamServiceID = "iam" // Iam. @@ -106,6 +113,7 @@ const ( MachinelearningServiceID = "machinelearning" // Machinelearning. MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics. MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace. + MghServiceID = "mgh" // Mgh. MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics. ModelsLexServiceID = "models.lex" // ModelsLex. MonitoringServiceID = "monitoring" // Monitoring. @@ -217,6 +225,9 @@ var awsPartition = partition{ "eu-west-2": region{ Description: "EU (London)", }, + "eu-west-3": region{ + Description: "EU (Paris)", + }, "sa-east-1": region{ Description: "South America (Sao Paulo)", }, @@ -246,6 +257,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -253,6 +265,17 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "api.pricing": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "pricing", + }, + }, + Endpoints: endpoints{ + "ap-south-1": endpoint{}, + "us-east-1": endpoint{}, + }, + }, "apigateway": service{ Endpoints: endpoints{ @@ -265,6 +288,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -290,6 +314,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -316,6 +341,8 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -336,6 +363,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -343,10 +371,27 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "autoscaling-plans": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "autoscaling-plans", + }, + }, + Endpoints: endpoints{ + "ap-southeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "batch": service{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, @@ -393,6 +438,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -429,6 +475,26 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "cloudhsmv2": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "cloudsearch": service{ Endpoints: endpoints{ @@ -456,6 +522,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -467,6 +534,7 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, @@ -510,6 +578,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -521,6 +590,8 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, @@ -537,12 +608,16 @@ var awsPartition = partition{ "codestar": service{ Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -552,6 +627,7 @@ var awsPartition = partition{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, @@ -567,6 +643,7 @@ var awsPartition = partition{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, @@ -582,6 +659,7 @@ var awsPartition = partition{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, @@ -603,6 +681,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -626,6 +705,18 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "dax": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "devicefarm": service{ Endpoints: endpoints{ @@ -644,6 +735,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -669,6 +761,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -681,14 +774,17 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -706,6 +802,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "local": endpoint{ Hostname: "localhost:8000", Protocols: []string{"http"}, @@ -734,6 +831,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -756,12 +854,16 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-1": endpoint{}, @@ -772,12 +874,16 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-1": endpoint{}, @@ -796,6 +902,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -815,6 +922,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -826,6 +934,7 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -834,7 +943,7 @@ var awsPartition = partition{ }, "elasticloadbalancing": service{ Defaults: endpoint{ - Protocols: []string{"http", "https"}, + Protocols: []string{"https"}, }, Endpoints: endpoints{ "ap-northeast-1": endpoint{}, @@ -846,6 +955,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -870,6 +980,7 @@ var awsPartition = partition{ }, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{ SSLCommonName: "{service}.{region}.{dnsSuffix}", @@ -922,6 +1033,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -941,6 +1053,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -951,9 +1064,15 @@ var awsPartition = partition{ "firehose": service{ Endpoints: endpoints{ - "eu-west-1": endpoint{}, - "us-east-1": endpoint{}, - "us-west-2": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, }, }, "gamelift": service{ @@ -963,10 +1082,15 @@ var awsPartition = partition{ "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -978,23 +1102,36 @@ var awsPartition = partition{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, + "glue": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "greengrass": service{ IsRegionalized: boxedTrue, Defaults: endpoint{ Protocols: []string{"https"}, }, Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "us-east-1": endpoint{}, @@ -1042,6 +1179,7 @@ var awsPartition = partition{ "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "us-east-1": endpoint{}, "us-west-1": endpoint{}, @@ -1079,6 +1217,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1106,6 +1245,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1125,6 +1265,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1159,6 +1300,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1202,6 +1344,12 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "mgh": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, "mobileanalytics": service{ Endpoints: endpoints{ @@ -1232,6 +1380,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1260,6 +1409,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1301,10 +1451,21 @@ var awsPartition = partition{ "polly": service{ Endpoints: endpoints{ - "eu-west-1": endpoint{}, - "us-east-1": endpoint{}, - "us-east-2": endpoint{}, - "us-west-2": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, }, }, "rds": service{ @@ -1319,6 +1480,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{ SSLCommonName: "{service}.{dnsSuffix}", @@ -1340,6 +1502,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1352,6 +1515,7 @@ var awsPartition = partition{ Endpoints: endpoints{ "eu-west-1": endpoint{}, "us-east-1": endpoint{}, + "us-east-2": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -1381,6 +1545,7 @@ var awsPartition = partition{ }, }, Endpoints: endpoints{ + "eu-west-1": endpoint{}, "us-east-1": endpoint{}, }, }, @@ -1396,26 +1561,27 @@ var awsPartition = partition{ }, Endpoints: endpoints{ "ap-northeast-1": endpoint{ - Hostname: "s3-ap-northeast-1.amazonaws.com", + Hostname: "s3.ap-northeast-1.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{ - Hostname: "s3-ap-southeast-1.amazonaws.com", + Hostname: "s3.ap-southeast-1.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, "ap-southeast-2": endpoint{ - Hostname: "s3-ap-southeast-2.amazonaws.com", + Hostname: "s3.ap-southeast-2.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{ - Hostname: "s3-eu-west-1.amazonaws.com", + Hostname: "s3.eu-west-1.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "s3-external-1": endpoint{ Hostname: "s3-external-1.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, @@ -1424,7 +1590,7 @@ var awsPartition = partition{ }, }, "sa-east-1": endpoint{ - Hostname: "s3-sa-east-1.amazonaws.com", + Hostname: "s3.sa-east-1.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, "us-east-1": endpoint{ @@ -1433,11 +1599,11 @@ var awsPartition = partition{ }, "us-east-2": endpoint{}, "us-west-1": endpoint{ - Hostname: "s3-us-west-1.amazonaws.com", + Hostname: "s3.us-west-1.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, "us-west-2": endpoint{ - Hostname: "s3-us-west-2.amazonaws.com", + Hostname: "s3.us-west-2.amazonaws.com", SignatureVersions: []string{"s3", "s3v4"}, }, }, @@ -1464,14 +1630,19 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -1495,19 +1666,24 @@ var awsPartition = partition{ "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-3": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, "snowball": service{ Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, "ap-south-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-1": endpoint{}, @@ -1528,6 +1704,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1550,6 +1727,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{ SSLCommonName: "queue.{dnsSuffix}", @@ -1571,6 +1749,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1582,9 +1761,12 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-2": endpoint{}, @@ -1602,6 +1784,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1626,6 +1809,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "local": endpoint{ Hostname: "localhost:8000", Protocols: []string{"http"}, @@ -1664,6 +1848,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-1-fips": endpoint{ @@ -1713,6 +1898,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1756,8 +1942,11 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "us-east-1": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -1780,6 +1969,7 @@ var awsPartition = partition{ "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-west-2": endpoint{}, }, @@ -1830,30 +2020,62 @@ var awscnPartition = partition{ "cn-north-1": region{ Description: "China (Beijing)", }, + "cn-northwest-1": region{ + Description: "China (Ningxia)", + }, }, Services: services{ + "apigateway": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, "autoscaling": service{ Defaults: endpoint{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "cloudformation": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "cloudtrail": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "codedeploy": service{ + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cognito-identity": service{ + Endpoints: endpoints{ "cn-north-1": endpoint{}, }, @@ -1861,13 +2083,15 @@ var awscnPartition = partition{ "config": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "directconnect": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "dynamodb": service{ @@ -1875,7 +2099,8 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "ec2": service{ @@ -1883,7 +2108,8 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "ec2metadata": service{ @@ -1912,21 +2138,24 @@ var awscnPartition = partition{ "elasticache": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "elasticbeanstalk": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "elasticloadbalancing": service{ Defaults: endpoint{ - Protocols: []string{"http", "https"}, + Protocols: []string{"https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "elasticmapreduce": service{ @@ -1934,13 +2163,21 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "cn-northwest-1": endpoint{}, }, }, "events": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "glacier": service{ @@ -1948,7 +2185,8 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "iam": service{ @@ -1964,8 +2202,25 @@ var awscnPartition = partition{ }, }, }, + "iot": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, "kinesis": service{ + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "lambda": service{ + Endpoints: endpoints{ "cn-north-1": endpoint{}, }, @@ -1973,7 +2228,8 @@ var awscnPartition = partition{ "logs": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "monitoring": service{ @@ -1981,19 +2237,22 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "rds": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "redshift": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "s3": service{ @@ -2001,6 +2260,19 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, SignatureVersions: []string{"s3v4"}, }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "snowball": service{ + Endpoints: endpoints{ "cn-north-1": endpoint{}, }, @@ -2010,7 +2282,8 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "sqs": service{ @@ -2019,13 +2292,15 @@ var awscnPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "ssm": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "storagegateway": service{ @@ -2042,19 +2317,22 @@ var awscnPartition = partition{ }, }, Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "sts": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "swf": service{ Endpoints: endpoints{ - "cn-north-1": endpoint{}, + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, }, }, "tagging": service{ @@ -2092,6 +2370,18 @@ var awsusgovPartition = partition{ }, }, Services: services{ + "acm": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "apigateway": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, "autoscaling": service{ Endpoints: endpoints{ @@ -2136,10 +2426,22 @@ var awsusgovPartition = partition{ "us-gov-west-1": endpoint{}, }, }, + "dms": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, "dynamodb": service{ Endpoints: endpoints{ "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "ec2": service{ @@ -2159,12 +2461,24 @@ var awsusgovPartition = partition{ }, }, }, + "ecs": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, "elasticache": service{ Endpoints: endpoints{ "us-gov-west-1": endpoint{}, }, }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, "elasticloadbalancing": service{ Endpoints: endpoints{ @@ -2268,7 +2582,7 @@ var awsusgovPartition = partition{ }, }, "us-gov-west-1": endpoint{ - Hostname: "s3-us-gov-west-1.amazonaws.com", + Hostname: "s3.us-gov-west-1.amazonaws.com", Protocols: []string{"http", "https"}, }, }, @@ -2316,6 +2630,12 @@ var awsusgovPartition = partition{ }, Endpoints: endpoints{ "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "sts": service{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go index 088ba5290..5c7db4982 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -28,6 +28,10 @@ const ( // during body reads. ErrCodeResponseTimeout = "ResponseTimeout" + // ErrCodeInvalidPresignExpire is returned when the expire time provided to + // presign is invalid + ErrCodeInvalidPresignExpire = "InvalidPresignExpireError" + // CanceledErrorCode is the error code that will be returned by an // API request that was canceled. Requests given a aws.Context may // return this error when canceled. @@ -42,7 +46,6 @@ type Request struct { Retryer Time time.Time - ExpireTime time.Duration Operation *Operation HTTPRequest *http.Request HTTPResponse *http.Response @@ -60,6 +63,11 @@ type Request struct { LastSignedAt time.Time DisableFollowRedirects bool + // A value greater than 0 instructs the request to be signed as Presigned URL + // You should not set this field directly. Instead use Request's + // Presign or PresignRequest methods. + ExpireTime time.Duration + context aws.Context built bool @@ -104,6 +112,8 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err) } + SanitizeHostForHeader(httpReq) + r := &Request{ Config: cfg, ClientInfo: clientInfo, @@ -250,34 +260,59 @@ func (r *Request) SetReaderBody(reader io.ReadSeeker) { // Presign returns the request's signed URL. Error will be returned // if the signing fails. -func (r *Request) Presign(expireTime time.Duration) (string, error) { - r.ExpireTime = expireTime +// +// It is invalid to create a presigned URL with a expire duration 0 or less. An +// error is returned if expire duration is 0 or less. +func (r *Request) Presign(expire time.Duration) (string, error) { + r = r.copy() + + // Presign requires all headers be hoisted. There is no way to retrieve + // the signed headers not hoisted without this. Making the presigned URL + // useless. r.NotHoist = false + u, _, err := getPresignedURL(r, expire) + return u, err +} + +// PresignRequest behaves just like presign, with the addition of returning a +// set of headers that were signed. +// +// It is invalid to create a presigned URL with a expire duration 0 or less. An +// error is returned if expire duration is 0 or less. +// +// Returns the URL string for the API operation with signature in the query string, +// and the HTTP headers that were included in the signature. These headers must +// be included in any HTTP request made with the presigned URL. +// +// To prevent hoisting any headers to the query string set NotHoist to true on +// this Request value prior to calling PresignRequest. +func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) { + r = r.copy() + return getPresignedURL(r, expire) +} + +func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) { + if expire <= 0 { + return "", nil, awserr.New( + ErrCodeInvalidPresignExpire, + "presigned URL requires an expire duration greater than 0", + nil, + ) + } + + r.ExpireTime = expire + if r.Operation.BeforePresignFn != nil { - r = r.copy() - err := r.Operation.BeforePresignFn(r) - if err != nil { - return "", err + if err := r.Operation.BeforePresignFn(r); err != nil { + return "", nil, err } } - r.Sign() - if r.Error != nil { - return "", r.Error + if err := r.Sign(); err != nil { + return "", nil, err } - return r.HTTPRequest.URL.String(), nil -} -// PresignRequest behaves just like presign, but hoists all headers and signs them. -// Also returns the signed hash back to the user -func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) { - r.ExpireTime = expireTime - r.NotHoist = true - r.Sign() - if r.Error != nil { - return "", nil, r.Error - } return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil } @@ -573,3 +608,72 @@ func shouldRetryCancel(r *Request) bool { errStr != "net/http: request canceled while waiting for connection") } + +// SanitizeHostForHeader removes default port from host and updates request.Host +func SanitizeHostForHeader(r *http.Request) { + host := getHost(r) + port := portOnly(host) + if port != "" && isDefaultPort(r.URL.Scheme, port) { + r.Host = stripPort(host) + } +} + +// Returns host from request +func getHost(r *http.Request) string { + if r.Host != "" { + return r.Host + } + + return r.URL.Host +} + +// Hostname returns u.Host, without any port number. +// +// If Host is an IPv6 literal with a port number, Hostname returns the +// IPv6 literal without the square brackets. IPv6 literals may include +// a zone identifier. +// +// Copied from the Go 1.8 standard library (net/url) +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} + +// Port returns the port part of u.Host, without the leading colon. +// If u.Host doesn't contain a port, Port returns an empty string. +// +// Copied from the Go 1.8 standard library (net/url) +func portOnly(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return "" + } + if i := strings.Index(hostport, "]:"); i != -1 { + return hostport[i+len("]:"):] + } + if strings.Contains(hostport, "]") { + return "" + } + return hostport[colon+len(":"):] +} + +// Returns true if the specified URI is using the standard port +// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs) +func isDefaultPort(scheme, port string) bool { + if port == "" { + return true + } + + lowerCaseScheme := strings.ToLower(scheme) + if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") { + return true + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go index 59de6736b..159518a75 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go @@ -142,13 +142,28 @@ func (r *Request) nextPageTokens() []interface{} { tokens := []interface{}{} tokenAdded := false for _, outToken := range r.Operation.OutputTokens { - v, _ := awsutil.ValuesAtPath(r.Data, outToken) - if len(v) > 0 { - tokens = append(tokens, v[0]) - tokenAdded = true - } else { + vs, _ := awsutil.ValuesAtPath(r.Data, outToken) + if len(vs) == 0 { tokens = append(tokens, nil) + continue } + v := vs[0] + + switch tv := v.(type) { + case *string: + if len(aws.StringValue(tv)) == 0 { + tokens = append(tokens, nil) + continue + } + case string: + if len(tv) == 0 { + tokens = append(tokens, nil) + continue + } + } + + tokenAdded = true + tokens = append(tokens, v) } if !tokenAdded { return nil diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go index 4b102f8f2..f1adcf481 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -7,6 +7,9 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials" ) +// EnvProviderName provides a name of the provider when config is loaded from environment. +const EnvProviderName = "EnvConfigCredentials" + // envConfig is a collection of environment values the SDK will read // setup config from. All environment values are optional. But some values // such as credentials require multiple values to be complete or the values @@ -157,7 +160,7 @@ func envConfigLoad(enableSharedConfig bool) envConfig { if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 { cfg.Creds = credentials.Value{} } else { - cfg.Creds.ProviderName = "EnvConfigCredentials" + cfg.Creds.ProviderName = EnvProviderName } regionKeys := regionEnvKeys diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go index d68905acb..ccc88b4ac 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -268,7 +268,7 @@ type signingCtx struct { // "X-Amz-Content-Sha256" header with a precomputed value. The signer will // only compute the hash if the request header value is empty. func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) { - return v4.signWithBody(r, body, service, region, 0, signTime) + return v4.signWithBody(r, body, service, region, 0, false, signTime) } // Presign signs AWS v4 requests with the provided body, service name, region @@ -302,10 +302,10 @@ func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region strin // presigned request's signature you can set the "X-Amz-Content-Sha256" // HTTP header and that will be included in the request's signature. func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { - return v4.signWithBody(r, body, service, region, exp, signTime) + return v4.signWithBody(r, body, service, region, exp, true, signTime) } -func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { +func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) { currentTimeFn := v4.currentTimeFn if currentTimeFn == nil { currentTimeFn = time.Now @@ -317,7 +317,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi Query: r.URL.Query(), Time: signTime, ExpireTime: exp, - isPresign: exp != 0, + isPresign: isPresign, ServiceName: service, Region: region, DisableURIPathEscaping: v4.DisableURIPathEscaping, @@ -339,6 +339,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi return http.Header{}, err } + ctx.sanitizeHostForHeader() ctx.assignAmzQueryValues() ctx.build(v4.DisableHeaderHoisting) @@ -363,6 +364,10 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi return ctx.SignedHeaderVals, nil } +func (ctx *signingCtx) sanitizeHostForHeader() { + request.SanitizeHostForHeader(ctx.Request) +} + func (ctx *signingCtx) handlePresignRemoval() { if !ctx.isPresign { return @@ -467,7 +472,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time } signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), - name, region, req.ExpireTime, signingTime, + name, region, req.ExpireTime, req.ExpireTime > 0, signingTime, ) if err != nil { req.Error = err @@ -502,6 +507,8 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) { ctx.buildTime() // no depends ctx.buildCredentialString() // no depends + ctx.buildBodyDigest() + unsignedHeaders := ctx.Request.Header if ctx.isPresign { if !disableHeaderHoisting { @@ -513,7 +520,6 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) { } } - ctx.buildBodyDigest() ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) ctx.buildCanonicalString() // depends on canon headers / signed headers ctx.buildStringToSign() // depends on canon string diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 7a4f26e39..b55286b31 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.10.23" +const SDKVersion = "1.12.71" diff --git a/vendor/github.com/aws/aws-sdk-go/buildspec.yml b/vendor/github.com/aws/aws-sdk-go/buildspec.yml new file mode 100644 index 000000000..427208edf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/buildspec.yml @@ -0,0 +1,21 @@ +version: 0.2 + +phases: + build: + commands: + - echo Build started on `date` + - export GOPATH=/go + - export SDK_CB_ROOT=`pwd` + - export SDK_GO_ROOT=/go/src/github.com/aws/aws-sdk-go + - mkdir -p /go/src/github.com/aws + - ln -s $SDK_CB_ROOT $SDK_GO_ROOT + - cd $SDK_GO_ROOT + - make unit + - cd $SDK_CB_ROOT + - #echo Compiling the Go code... + post_build: + commands: + - echo Build completed on `date` +#artifacts: +# files: +# - hello diff --git a/vendor/github.com/aws/aws-sdk-go/doc.go b/vendor/github.com/aws/aws-sdk-go/doc.go index 3e077e51d..32b806a4a 100644 --- a/vendor/github.com/aws/aws-sdk-go/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/doc.go @@ -197,7 +197,7 @@ // regions different from the Session's region. // // svc := s3.New(sess, &aws.Config{ -// Region: aws.String(ednpoints.UsWest2RegionID), +// Region: aws.String(endpoints.UsWest2RegionID), // }) // // See the Config type in the aws package for more information and additional diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go index 6efe43d5f..ec765ba25 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go @@ -12,6 +12,7 @@ import ( "strconv" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/private/protocol" ) @@ -49,7 +50,10 @@ func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) err t = "list" } case reflect.Map: - t = "map" + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } } } @@ -210,14 +214,11 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro } buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) default: - switch value.Type() { - case timeType: - converted := v.Interface().(*time.Time) - + switch converted := value.Interface().(type) { + case time.Time: buf.Write(strconv.AppendInt(scratch[:0], converted.UTC().Unix(), 10)) - case byteSliceType: + case []byte: if !value.IsNil() { - converted := value.Interface().([]byte) buf.WriteByte('"') if len(converted) < 1024 { // for small buffers, using Encode directly is much faster. @@ -233,6 +234,12 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro } buf.WriteByte('"') } + case aws.JSONValue: + str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) + if err != nil { + return fmt.Errorf("unable to encode JSONValue, %v", err) + } + buf.WriteString(str) default: return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) } diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go index fea535613..037e1e7be 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go @@ -8,6 +8,9 @@ import ( "io/ioutil" "reflect" "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/private/protocol" ) // UnmarshalJSON reads a stream and unmarshals the results in object v. @@ -50,7 +53,10 @@ func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) t = "list" } case reflect.Map: - t = "map" + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } } } @@ -183,6 +189,13 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa return err } value.Set(reflect.ValueOf(b)) + case aws.JSONValue: + // No need to use escaping as the value is a non-quoted string. + v, err := protocol.DecodeJSONValue(d, protocol.NoEscape) + if err != nil { + return err + } + value.Set(reflect.ValueOf(v)) default: return errf() } diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go new file mode 100644 index 000000000..776d11018 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go @@ -0,0 +1,76 @@ +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/aws/aws-sdk-go/aws" +) + +// EscapeMode is the mode that should be use for escaping a value +type EscapeMode uint + +// The modes for escaping a value before it is marshaled, and unmarshaled. +const ( + NoEscape EscapeMode = iota + Base64Escape + QuotedEscape +) + +// EncodeJSONValue marshals the value into a JSON string, and optionally base64 +// encodes the string before returning it. +// +// Will panic if the escape mode is unknown. +func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + + switch escape { + case NoEscape: + return string(b), nil + case Base64Escape: + return base64.StdEncoding.EncodeToString(b), nil + case QuotedEscape: + return strconv.Quote(string(b)), nil + } + + panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape)) +} + +// DecodeJSONValue will attempt to decode the string input as a JSONValue. +// Optionally decoding base64 the value first before JSON unmarshaling. +// +// Will panic if the escape mode is unknown. +func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) { + var b []byte + var err error + + switch escape { + case NoEscape: + b = []byte(v) + case Base64Escape: + b, err = base64.StdEncoding.DecodeString(v) + case QuotedEscape: + var u string + u, err = strconv.Unquote(v) + b = []byte(u) + default: + panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape)) + } + + if err != nil { + return nil, err + } + + m := aws.JSONValue{} + err = json.Unmarshal(b, &m) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go index 524ca952a..5ce9cba32 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go @@ -121,6 +121,10 @@ func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string return nil } + if _, ok := value.Interface().([]byte); ok { + return q.parseScalar(v, value, prefix, tag) + } + // check for unflattened list member if !q.isEC2 && tag.Get("flattened") == "" { if listName := tag.Get("locationNameList"); listName == "" { diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go index 716183564..c405288d7 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go @@ -4,7 +4,6 @@ package rest import ( "bytes" "encoding/base64" - "encoding/json" "fmt" "io" "net/http" @@ -18,6 +17,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" ) // RFC822 returns an RFC822 formatted timestamp for AWS protocols @@ -252,13 +252,12 @@ func EscapePath(path string, encodeSep bool) string { return buf.String() } -func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { +func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) { v = reflect.Indirect(v) if !v.IsValid() { return "", errValueNotSet } - var str string switch value := v.Interface().(type) { case string: str = value @@ -273,17 +272,19 @@ func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { case time.Time: str = value.UTC().Format(RFC822) case aws.JSONValue: - b, err := json.Marshal(value) - if err != nil { - return "", err + if len(value) == 0 { + return "", errValueNotSet } + escaping := protocol.NoEscape if tag.Get("location") == "header" { - str = base64.StdEncoding.EncodeToString(b) - } else { - str = string(b) + escaping = protocol.Base64Escape + } + str, err = protocol.EncodeJSONValue(value, escaping) + if err != nil { + return "", fmt.Errorf("unable to encode JSONValue, %v", err) } default: - err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type()) return "", err } return str, nil diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go index 7a779ee22..823f045ee 100644 --- a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go @@ -3,7 +3,6 @@ package rest import ( "bytes" "encoding/base64" - "encoding/json" "fmt" "io" "io/ioutil" @@ -16,6 +15,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" ) // UnmarshalHandler is a named request handler for unmarshaling rest protocol requests @@ -204,17 +204,11 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro } v.Set(reflect.ValueOf(&t)) case aws.JSONValue: - b := []byte(header) - var err error + escaping := protocol.NoEscape if tag.Get("location") == "header" { - b, err = base64.StdEncoding.DecodeString(header) - if err != nil { - return err - } + escaping = protocol.Base64Escape } - - m := aws.JSONValue{} - err = json.Unmarshal(b, &m) + m, err := protocol.DecodeJSONValue(header, escaping) if err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index 4598ccd82..1743b3449 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -5428,6 +5428,10 @@ func (c *EC2) CreateVpcPeeringConnectionRequest(input *CreateVpcPeeringConnectio // the requester VPC. The requester VPC and accepter VPC cannot have overlapping // CIDR blocks. // +// Limitations and rules apply to a VPC peering connection. For more information, +// see the limitations (http://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/vpc-peering-basics.html#vpc-peering-limitations) +// section in the VPC Peering Guide. +// // The owner of the accepter VPC must accept the peering request to activate // the peering connection. The VPC peering connection request expires after // 7 days, after which it cannot be accepted or rejected. @@ -18933,9 +18937,9 @@ func (c *EC2) ModifyVpcEndpointServicePermissionsRequest(input *ModifyVpcEndpoin // ModifyVpcEndpointServicePermissions API operation for Amazon Elastic Compute Cloud. // -// Modifies the permissions for your VPC endpoint service. You can add or remove -// permissions for service consumers (IAM users, IAM roles, and AWS accounts) -// to discover your endpoint service. +// Modifies the permissions for your VPC endpoint service (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/endpoint-service.html). +// You can add or remove permissions for service consumers (IAM users, IAM roles, +// and AWS accounts) to connect to your endpoint service. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -29784,7 +29788,7 @@ type CreateVpcEndpointInput struct { SecurityGroupIds []*string `locationName:"SecurityGroupId" locationNameList:"item" type:"list"` // The service name. To get a list of available services, use the DescribeVpcEndpointServices - // request. + // request, or get the name from the service provider. // // ServiceName is a required field ServiceName *string `type:"string" required:"true"` @@ -33150,6 +33154,18 @@ type DescribeAddressesInput struct { // the Elastic IP address. // // * public-ip - The Elastic IP address. + // + // * tag:key=value - The key/value combination of a tag assigned to the resource. + // Specify the key of the tag in the filter name and the value of the tag + // in the filter value. For example, for the tag Purpose=X, specify tag:Purpose + // for the filter name and X for the filter value. + // + // * tag-key - The key of a tag assigned to the resource. This filter is + // independent of the tag-value filter. For example, if you use both the + // filter "tag-key=Purpose" and the filter "tag-value=X", you get any resources + // assigned both the tag key Purpose (regardless of what the tag's value + // is), and the tag value X (regardless of the tag's key). If you want to + // list only resources where Purpose is X, see the tag:key=value filter. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // [EC2-Classic] One or more Elastic IP addresses. @@ -36657,6 +36673,18 @@ type DescribeLaunchTemplatesInput struct { // * create-time - The time the launch template was created. // // * launch-template-name - The name of the launch template. + // + // * tag:key=value - The key/value combination of a tag assigned to the resource. + // Specify the key of the tag in the filter name and the value of the tag + // in the filter value. For example, for the tag Purpose=X, specify tag:Purpose + // for the filter name and X for the filter value. + // + // * tag-key - The key of a tag assigned to the resource. This filter is + // independent of the tag-value filter. For example, if you use both the + // filter "tag-key=Purpose" and the filter "tag-value=X", you get any resources + // assigned both the tag key Purpose (regardless of what the tag's value + // is), and the tag value X (regardless of the tag's key). If you want to + // list only resources where Purpose is X, see the tag:key=value filter. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // One or more launch template IDs. @@ -40335,9 +40363,10 @@ type DescribeTagsInput struct { // * resource-id - The resource ID. // // * resource-type - The resource type (customer-gateway | dhcp-options | - // image | instance | internet-gateway | network-acl | network-interface - // | reserved-instances | route-table | security-group | snapshot | spot-instances-request - // | subnet | volume | vpc | vpn-connection | vpn-gateway). + // elastic-ip | fpga-image | image | instance | internet-gateway | launch-template + // | natgateway | network-acl | network-interface | reserved-instances | + // route-table | security-group | snapshot | spot-instances-request | subnet + // | volume | vpc | vpc-peering-connection | vpn-connection | vpn-gateway). // // * value - The tag value. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` @@ -49533,7 +49562,8 @@ func (s *InternetGateway) SetTags(v []*Tag) *InternetGateway { type InternetGatewayAttachment struct { _ struct{} `type:"structure"` - // The current state of the attachment. + // The current state of the attachment. For an Internet gateway, the state is + // available when attached to a VPC; otherwise, this value is not returned. State *string `locationName:"state" type:"string" enum:"AttachmentStatus"` // The ID of the VPC. @@ -60763,7 +60793,9 @@ type RunInstancesInput struct { // The IAM instance profile. IamInstanceProfile *IamInstanceProfileSpecification `locationName:"iamInstanceProfile" type:"structure"` - // The ID of the AMI, which you can get by calling DescribeImages. + // The ID of the AMI, which you can get by calling DescribeImages. An AMI is + // required to launch an instance and must be specified here or in a launch + // template. ImageId *string `type:"string"` // Indicates whether an instance stops or terminates when you initiate shutdown @@ -66149,13 +66181,19 @@ type UserIdGroupPair struct { // The name of the security group. In a request, use this parameter for a security // group in EC2-Classic or a default VPC only. For a security group in a nondefault // VPC, use the security group ID. + // + // For a referenced security group in another VPC, this value is not returned + // if the referenced security group is deleted. GroupName *string `locationName:"groupName" type:"string"` // The status of a VPC peering connection, if applicable. PeeringStatus *string `locationName:"peeringStatus" type:"string"` - // The ID of an AWS account. For a referenced security group in another VPC, - // the account ID of the referenced security group is returned. + // The ID of an AWS account. + // + // For a referenced security group in another VPC, the account ID of the referenced + // security group is returned in the response. If the referenced security group + // is deleted, this value is not returned. // // [EC2-Classic] Required when adding or removing rules that reference a security // group in another AWS account. diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go index 1ba51125e..432a54df4 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/doc.go @@ -4,9 +4,8 @@ // requests to Amazon Elastic Compute Cloud. // // Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity -// in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your -// need to invest in hardware up front, so you can develop and deploy applications -// faster. +// in the AWS Cloud. Using Amazon EC2 eliminates your need to invest in hardware +// up front, so you can develop and deploy applications faster. // // See https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15 for more information on this service. // diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go b/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go index f9136852f..984aec965 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go @@ -35,7 +35,7 @@ const opBatchCheckLayerAvailability = "BatchCheckLayerAvailability" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailability +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailability func (c *ECR) BatchCheckLayerAvailabilityRequest(input *BatchCheckLayerAvailabilityInput) (req *request.Request, output *BatchCheckLayerAvailabilityOutput) { op := &request.Operation{ Name: opBatchCheckLayerAvailability, @@ -80,7 +80,7 @@ func (c *ECR) BatchCheckLayerAvailabilityRequest(input *BatchCheckLayerAvailabil // * ErrCodeServerException "ServerException" // These errors are usually caused by a server-side issue. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailability +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailability func (c *ECR) BatchCheckLayerAvailability(input *BatchCheckLayerAvailabilityInput) (*BatchCheckLayerAvailabilityOutput, error) { req, out := c.BatchCheckLayerAvailabilityRequest(input) return out, req.Send() @@ -127,7 +127,7 @@ const opBatchDeleteImage = "BatchDeleteImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImage func (c *ECR) BatchDeleteImageRequest(input *BatchDeleteImageInput) (req *request.Request, output *BatchDeleteImageOutput) { op := &request.Operation{ Name: opBatchDeleteImage, @@ -175,7 +175,7 @@ func (c *ECR) BatchDeleteImageRequest(input *BatchDeleteImageInput) (req *reques // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImage func (c *ECR) BatchDeleteImage(input *BatchDeleteImageInput) (*BatchDeleteImageOutput, error) { req, out := c.BatchDeleteImageRequest(input) return out, req.Send() @@ -222,7 +222,7 @@ const opBatchGetImage = "BatchGetImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImage func (c *ECR) BatchGetImageRequest(input *BatchGetImageInput) (req *request.Request, output *BatchGetImageOutput) { op := &request.Operation{ Name: opBatchGetImage, @@ -263,7 +263,7 @@ func (c *ECR) BatchGetImageRequest(input *BatchGetImageInput) (req *request.Requ // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImage func (c *ECR) BatchGetImage(input *BatchGetImageInput) (*BatchGetImageOutput, error) { req, out := c.BatchGetImageRequest(input) return out, req.Send() @@ -310,7 +310,7 @@ const opCompleteLayerUpload = "CompleteLayerUpload" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUpload func (c *ECR) CompleteLayerUploadRequest(input *CompleteLayerUploadInput) (req *request.Request, output *CompleteLayerUploadOutput) { op := &request.Operation{ Name: opCompleteLayerUpload, @@ -329,9 +329,9 @@ func (c *ECR) CompleteLayerUploadRequest(input *CompleteLayerUploadInput) (req * // CompleteLayerUpload API operation for Amazon EC2 Container Registry. // -// Inform Amazon ECR that the image layer upload for a specified registry, repository -// name, and upload ID, has completed. You can optionally provide a sha256 digest -// of the image layer for data validation purposes. +// Informs Amazon ECR that the image layer upload has completed for a specified +// registry, repository name, and upload ID. You can optionally provide a sha256 +// digest of the image layer for data validation purposes. // // This operation is used by the Amazon ECR proxy, and it is not intended for // general use by customers for pulling and pushing images. In most cases, you @@ -373,7 +373,7 @@ func (c *ECR) CompleteLayerUploadRequest(input *CompleteLayerUploadInput) (req * // * ErrCodeEmptyUploadException "EmptyUploadException" // The specified layer upload does not contain any layer parts. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUpload func (c *ECR) CompleteLayerUpload(input *CompleteLayerUploadInput) (*CompleteLayerUploadOutput, error) { req, out := c.CompleteLayerUploadRequest(input) return out, req.Send() @@ -420,7 +420,7 @@ const opCreateRepository = "CreateRepository" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository func (c *ECR) CreateRepositoryRequest(input *CreateRepositoryInput) (req *request.Request, output *CreateRepositoryOutput) { op := &request.Operation{ Name: opCreateRepository, @@ -465,7 +465,7 @@ func (c *ECR) CreateRepositoryRequest(input *CreateRepositoryInput) (req *reques // (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) // in the Amazon EC2 Container Registry User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository func (c *ECR) CreateRepository(input *CreateRepositoryInput) (*CreateRepositoryOutput, error) { req, out := c.CreateRepositoryRequest(input) return out, req.Send() @@ -487,6 +487,96 @@ func (c *ECR) CreateRepositoryWithContext(ctx aws.Context, input *CreateReposito return out, req.Send() } +const opDeleteLifecyclePolicy = "DeleteLifecyclePolicy" + +// DeleteLifecyclePolicyRequest generates a "aws/request.Request" representing the +// client's request for the DeleteLifecyclePolicy operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteLifecyclePolicy for more information on using the DeleteLifecyclePolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteLifecyclePolicyRequest method. +// req, resp := client.DeleteLifecyclePolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicy +func (c *ECR) DeleteLifecyclePolicyRequest(input *DeleteLifecyclePolicyInput) (req *request.Request, output *DeleteLifecyclePolicyOutput) { + op := &request.Operation{ + Name: opDeleteLifecyclePolicy, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteLifecyclePolicyInput{} + } + + output = &DeleteLifecyclePolicyOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteLifecyclePolicy API operation for Amazon EC2 Container Registry. +// +// Deletes the specified lifecycle policy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon EC2 Container Registry's +// API operation DeleteLifecyclePolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServerException "ServerException" +// These errors are usually caused by a server-side issue. +// +// * ErrCodeInvalidParameterException "InvalidParameterException" +// The specified parameter is invalid. Review the available parameters for the +// API request. +// +// * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException" +// The specified repository could not be found. Check the spelling of the specified +// repository and ensure that you are performing operations on the correct registry. +// +// * ErrCodeLifecyclePolicyNotFoundException "LifecyclePolicyNotFoundException" +// The lifecycle policy could not be found, and no policy is set to the repository. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicy +func (c *ECR) DeleteLifecyclePolicy(input *DeleteLifecyclePolicyInput) (*DeleteLifecyclePolicyOutput, error) { + req, out := c.DeleteLifecyclePolicyRequest(input) + return out, req.Send() +} + +// DeleteLifecyclePolicyWithContext is the same as DeleteLifecyclePolicy with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteLifecyclePolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *ECR) DeleteLifecyclePolicyWithContext(ctx aws.Context, input *DeleteLifecyclePolicyInput, opts ...request.Option) (*DeleteLifecyclePolicyOutput, error) { + req, out := c.DeleteLifecyclePolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeleteRepository = "DeleteRepository" // DeleteRepositoryRequest generates a "aws/request.Request" representing the @@ -512,7 +602,7 @@ const opDeleteRepository = "DeleteRepository" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepository +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepository func (c *ECR) DeleteRepositoryRequest(input *DeleteRepositoryInput) (req *request.Request, output *DeleteRepositoryOutput) { op := &request.Operation{ Name: opDeleteRepository, @@ -557,7 +647,7 @@ func (c *ECR) DeleteRepositoryRequest(input *DeleteRepositoryInput) (req *reques // The specified repository contains images. To delete a repository that contains // images, you must force the deletion with the force parameter. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepository +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepository func (c *ECR) DeleteRepository(input *DeleteRepositoryInput) (*DeleteRepositoryOutput, error) { req, out := c.DeleteRepositoryRequest(input) return out, req.Send() @@ -604,7 +694,7 @@ const opDeleteRepositoryPolicy = "DeleteRepositoryPolicy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicy func (c *ECR) DeleteRepositoryPolicyRequest(input *DeleteRepositoryPolicyInput) (req *request.Request, output *DeleteRepositoryPolicyOutput) { op := &request.Operation{ Name: opDeleteRepositoryPolicy, @@ -648,7 +738,7 @@ func (c *ECR) DeleteRepositoryPolicyRequest(input *DeleteRepositoryPolicyInput) // The specified repository and registry combination does not have an associated // repository policy. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicy func (c *ECR) DeleteRepositoryPolicy(input *DeleteRepositoryPolicyInput) (*DeleteRepositoryPolicyOutput, error) { req, out := c.DeleteRepositoryPolicyRequest(input) return out, req.Send() @@ -695,7 +785,7 @@ const opDescribeImages = "DescribeImages" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImages func (c *ECR) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Request, output *DescribeImagesOutput) { op := &request.Operation{ Name: opDescribeImages, @@ -750,7 +840,7 @@ func (c *ECR) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Re // * ErrCodeImageNotFoundException "ImageNotFoundException" // The image requested does not exist in the specified repository. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImages func (c *ECR) DescribeImages(input *DescribeImagesInput) (*DescribeImagesOutput, error) { req, out := c.DescribeImagesRequest(input) return out, req.Send() @@ -847,7 +937,7 @@ const opDescribeRepositories = "DescribeRepositories" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositories +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositories func (c *ECR) DescribeRepositoriesRequest(input *DescribeRepositoriesInput) (req *request.Request, output *DescribeRepositoriesOutput) { op := &request.Operation{ Name: opDescribeRepositories, @@ -893,7 +983,7 @@ func (c *ECR) DescribeRepositoriesRequest(input *DescribeRepositoriesInput) (req // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositories +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositories func (c *ECR) DescribeRepositories(input *DescribeRepositoriesInput) (*DescribeRepositoriesOutput, error) { req, out := c.DescribeRepositoriesRequest(input) return out, req.Send() @@ -990,7 +1080,7 @@ const opGetAuthorizationToken = "GetAuthorizationToken" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationToken +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationToken func (c *ECR) GetAuthorizationTokenRequest(input *GetAuthorizationTokenInput) (req *request.Request, output *GetAuthorizationTokenOutput) { op := &request.Operation{ Name: opGetAuthorizationToken, @@ -1033,7 +1123,7 @@ func (c *ECR) GetAuthorizationTokenRequest(input *GetAuthorizationTokenInput) (r // The specified parameter is invalid. Review the available parameters for the // API request. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationToken +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationToken func (c *ECR) GetAuthorizationToken(input *GetAuthorizationTokenInput) (*GetAuthorizationTokenOutput, error) { req, out := c.GetAuthorizationTokenRequest(input) return out, req.Send() @@ -1080,7 +1170,7 @@ const opGetDownloadUrlForLayer = "GetDownloadUrlForLayer" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayer +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayer func (c *ECR) GetDownloadUrlForLayerRequest(input *GetDownloadUrlForLayerInput) (req *request.Request, output *GetDownloadUrlForLayerOutput) { op := &request.Operation{ Name: opGetDownloadUrlForLayer, @@ -1133,7 +1223,7 @@ func (c *ECR) GetDownloadUrlForLayerRequest(input *GetDownloadUrlForLayerInput) // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayer +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayer func (c *ECR) GetDownloadUrlForLayer(input *GetDownloadUrlForLayerInput) (*GetDownloadUrlForLayerOutput, error) { req, out := c.GetDownloadUrlForLayerRequest(input) return out, req.Send() @@ -1155,6 +1245,186 @@ func (c *ECR) GetDownloadUrlForLayerWithContext(ctx aws.Context, input *GetDownl return out, req.Send() } +const opGetLifecyclePolicy = "GetLifecyclePolicy" + +// GetLifecyclePolicyRequest generates a "aws/request.Request" representing the +// client's request for the GetLifecyclePolicy operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLifecyclePolicy for more information on using the GetLifecyclePolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLifecyclePolicyRequest method. +// req, resp := client.GetLifecyclePolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicy +func (c *ECR) GetLifecyclePolicyRequest(input *GetLifecyclePolicyInput) (req *request.Request, output *GetLifecyclePolicyOutput) { + op := &request.Operation{ + Name: opGetLifecyclePolicy, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLifecyclePolicyInput{} + } + + output = &GetLifecyclePolicyOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLifecyclePolicy API operation for Amazon EC2 Container Registry. +// +// Retrieves the specified lifecycle policy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon EC2 Container Registry's +// API operation GetLifecyclePolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServerException "ServerException" +// These errors are usually caused by a server-side issue. +// +// * ErrCodeInvalidParameterException "InvalidParameterException" +// The specified parameter is invalid. Review the available parameters for the +// API request. +// +// * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException" +// The specified repository could not be found. Check the spelling of the specified +// repository and ensure that you are performing operations on the correct registry. +// +// * ErrCodeLifecyclePolicyNotFoundException "LifecyclePolicyNotFoundException" +// The lifecycle policy could not be found, and no policy is set to the repository. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicy +func (c *ECR) GetLifecyclePolicy(input *GetLifecyclePolicyInput) (*GetLifecyclePolicyOutput, error) { + req, out := c.GetLifecyclePolicyRequest(input) + return out, req.Send() +} + +// GetLifecyclePolicyWithContext is the same as GetLifecyclePolicy with the addition of +// the ability to pass a context and additional request options. +// +// See GetLifecyclePolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *ECR) GetLifecyclePolicyWithContext(ctx aws.Context, input *GetLifecyclePolicyInput, opts ...request.Option) (*GetLifecyclePolicyOutput, error) { + req, out := c.GetLifecyclePolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetLifecyclePolicyPreview = "GetLifecyclePolicyPreview" + +// GetLifecyclePolicyPreviewRequest generates a "aws/request.Request" representing the +// client's request for the GetLifecyclePolicyPreview operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLifecyclePolicyPreview for more information on using the GetLifecyclePolicyPreview +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLifecyclePolicyPreviewRequest method. +// req, resp := client.GetLifecyclePolicyPreviewRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreview +func (c *ECR) GetLifecyclePolicyPreviewRequest(input *GetLifecyclePolicyPreviewInput) (req *request.Request, output *GetLifecyclePolicyPreviewOutput) { + op := &request.Operation{ + Name: opGetLifecyclePolicyPreview, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLifecyclePolicyPreviewInput{} + } + + output = &GetLifecyclePolicyPreviewOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLifecyclePolicyPreview API operation for Amazon EC2 Container Registry. +// +// Retrieves the results of the specified lifecycle policy preview request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon EC2 Container Registry's +// API operation GetLifecyclePolicyPreview for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServerException "ServerException" +// These errors are usually caused by a server-side issue. +// +// * ErrCodeInvalidParameterException "InvalidParameterException" +// The specified parameter is invalid. Review the available parameters for the +// API request. +// +// * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException" +// The specified repository could not be found. Check the spelling of the specified +// repository and ensure that you are performing operations on the correct registry. +// +// * ErrCodeLifecyclePolicyPreviewNotFoundException "LifecyclePolicyPreviewNotFoundException" +// There is no dry run for this repository. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreview +func (c *ECR) GetLifecyclePolicyPreview(input *GetLifecyclePolicyPreviewInput) (*GetLifecyclePolicyPreviewOutput, error) { + req, out := c.GetLifecyclePolicyPreviewRequest(input) + return out, req.Send() +} + +// GetLifecyclePolicyPreviewWithContext is the same as GetLifecyclePolicyPreview with the addition of +// the ability to pass a context and additional request options. +// +// See GetLifecyclePolicyPreview for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *ECR) GetLifecyclePolicyPreviewWithContext(ctx aws.Context, input *GetLifecyclePolicyPreviewInput, opts ...request.Option) (*GetLifecyclePolicyPreviewOutput, error) { + req, out := c.GetLifecyclePolicyPreviewRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opGetRepositoryPolicy = "GetRepositoryPolicy" // GetRepositoryPolicyRequest generates a "aws/request.Request" representing the @@ -1180,7 +1450,7 @@ const opGetRepositoryPolicy = "GetRepositoryPolicy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicy func (c *ECR) GetRepositoryPolicyRequest(input *GetRepositoryPolicyInput) (req *request.Request, output *GetRepositoryPolicyOutput) { op := &request.Operation{ Name: opGetRepositoryPolicy, @@ -1224,7 +1494,7 @@ func (c *ECR) GetRepositoryPolicyRequest(input *GetRepositoryPolicyInput) (req * // The specified repository and registry combination does not have an associated // repository policy. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicy func (c *ECR) GetRepositoryPolicy(input *GetRepositoryPolicyInput) (*GetRepositoryPolicyOutput, error) { req, out := c.GetRepositoryPolicyRequest(input) return out, req.Send() @@ -1271,7 +1541,7 @@ const opInitiateLayerUpload = "InitiateLayerUpload" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUpload func (c *ECR) InitiateLayerUploadRequest(input *InitiateLayerUploadInput) (req *request.Request, output *InitiateLayerUploadOutput) { op := &request.Operation{ Name: opInitiateLayerUpload, @@ -1315,7 +1585,7 @@ func (c *ECR) InitiateLayerUploadRequest(input *InitiateLayerUploadInput) (req * // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUpload func (c *ECR) InitiateLayerUpload(input *InitiateLayerUploadInput) (*InitiateLayerUploadOutput, error) { req, out := c.InitiateLayerUploadRequest(input) return out, req.Send() @@ -1362,7 +1632,7 @@ const opListImages = "ListImages" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImages func (c *ECR) ListImagesRequest(input *ListImagesInput) (req *request.Request, output *ListImagesOutput) { op := &request.Operation{ Name: opListImages, @@ -1414,7 +1684,7 @@ func (c *ECR) ListImagesRequest(input *ListImagesInput) (req *request.Request, o // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImages +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImages func (c *ECR) ListImages(input *ListImagesInput) (*ListImagesOutput, error) { req, out := c.ListImagesRequest(input) return out, req.Send() @@ -1511,7 +1781,7 @@ const opPutImage = "PutImage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImage func (c *ECR) PutImageRequest(input *PutImageInput) (req *request.Request, output *PutImageOutput) { op := &request.Operation{ Name: opPutImage, @@ -1556,8 +1826,8 @@ func (c *ECR) PutImageRequest(input *PutImageInput) (req *request.Request, outpu // repository and ensure that you are performing operations on the correct registry. // // * ErrCodeImageAlreadyExistsException "ImageAlreadyExistsException" -// The specified image has already been pushed, and there are no changes to -// the manifest or image tag since the last push. +// The specified image has already been pushed, and there were no changes to +// the manifest or image tag after the last push. // // * ErrCodeLayersNotFoundException "LayersNotFoundException" // The specified layers could not be found, or the specified layer is not valid @@ -1569,7 +1839,7 @@ func (c *ECR) PutImageRequest(input *PutImageInput) (req *request.Request, outpu // (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) // in the Amazon EC2 Container Registry User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImage +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImage func (c *ECR) PutImage(input *PutImageInput) (*PutImageOutput, error) { req, out := c.PutImageRequest(input) return out, req.Send() @@ -1591,6 +1861,93 @@ func (c *ECR) PutImageWithContext(ctx aws.Context, input *PutImageInput, opts .. return out, req.Send() } +const opPutLifecyclePolicy = "PutLifecyclePolicy" + +// PutLifecyclePolicyRequest generates a "aws/request.Request" representing the +// client's request for the PutLifecyclePolicy operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutLifecyclePolicy for more information on using the PutLifecyclePolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutLifecyclePolicyRequest method. +// req, resp := client.PutLifecyclePolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicy +func (c *ECR) PutLifecyclePolicyRequest(input *PutLifecyclePolicyInput) (req *request.Request, output *PutLifecyclePolicyOutput) { + op := &request.Operation{ + Name: opPutLifecyclePolicy, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutLifecyclePolicyInput{} + } + + output = &PutLifecyclePolicyOutput{} + req = c.newRequest(op, input, output) + return +} + +// PutLifecyclePolicy API operation for Amazon EC2 Container Registry. +// +// Creates or updates a lifecycle policy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon EC2 Container Registry's +// API operation PutLifecyclePolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServerException "ServerException" +// These errors are usually caused by a server-side issue. +// +// * ErrCodeInvalidParameterException "InvalidParameterException" +// The specified parameter is invalid. Review the available parameters for the +// API request. +// +// * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException" +// The specified repository could not be found. Check the spelling of the specified +// repository and ensure that you are performing operations on the correct registry. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicy +func (c *ECR) PutLifecyclePolicy(input *PutLifecyclePolicyInput) (*PutLifecyclePolicyOutput, error) { + req, out := c.PutLifecyclePolicyRequest(input) + return out, req.Send() +} + +// PutLifecyclePolicyWithContext is the same as PutLifecyclePolicy with the addition of +// the ability to pass a context and additional request options. +// +// See PutLifecyclePolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *ECR) PutLifecyclePolicyWithContext(ctx aws.Context, input *PutLifecyclePolicyInput, opts ...request.Option) (*PutLifecyclePolicyOutput, error) { + req, out := c.PutLifecyclePolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opSetRepositoryPolicy = "SetRepositoryPolicy" // SetRepositoryPolicyRequest generates a "aws/request.Request" representing the @@ -1616,7 +1973,7 @@ const opSetRepositoryPolicy = "SetRepositoryPolicy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicy func (c *ECR) SetRepositoryPolicyRequest(input *SetRepositoryPolicyInput) (req *request.Request, output *SetRepositoryPolicyOutput) { op := &request.Operation{ Name: opSetRepositoryPolicy, @@ -1656,7 +2013,7 @@ func (c *ECR) SetRepositoryPolicyRequest(input *SetRepositoryPolicyInput) (req * // The specified repository could not be found. Check the spelling of the specified // repository and ensure that you are performing operations on the correct registry. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicy func (c *ECR) SetRepositoryPolicy(input *SetRepositoryPolicyInput) (*SetRepositoryPolicyOutput, error) { req, out := c.SetRepositoryPolicyRequest(input) return out, req.Send() @@ -1678,6 +2035,101 @@ func (c *ECR) SetRepositoryPolicyWithContext(ctx aws.Context, input *SetReposito return out, req.Send() } +const opStartLifecyclePolicyPreview = "StartLifecyclePolicyPreview" + +// StartLifecyclePolicyPreviewRequest generates a "aws/request.Request" representing the +// client's request for the StartLifecyclePolicyPreview operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StartLifecyclePolicyPreview for more information on using the StartLifecyclePolicyPreview +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StartLifecyclePolicyPreviewRequest method. +// req, resp := client.StartLifecyclePolicyPreviewRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreview +func (c *ECR) StartLifecyclePolicyPreviewRequest(input *StartLifecyclePolicyPreviewInput) (req *request.Request, output *StartLifecyclePolicyPreviewOutput) { + op := &request.Operation{ + Name: opStartLifecyclePolicyPreview, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StartLifecyclePolicyPreviewInput{} + } + + output = &StartLifecyclePolicyPreviewOutput{} + req = c.newRequest(op, input, output) + return +} + +// StartLifecyclePolicyPreview API operation for Amazon EC2 Container Registry. +// +// Starts a preview of the specified lifecycle policy. This allows you to see +// the results before creating the lifecycle policy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon EC2 Container Registry's +// API operation StartLifecyclePolicyPreview for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServerException "ServerException" +// These errors are usually caused by a server-side issue. +// +// * ErrCodeInvalidParameterException "InvalidParameterException" +// The specified parameter is invalid. Review the available parameters for the +// API request. +// +// * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException" +// The specified repository could not be found. Check the spelling of the specified +// repository and ensure that you are performing operations on the correct registry. +// +// * ErrCodeLifecyclePolicyNotFoundException "LifecyclePolicyNotFoundException" +// The lifecycle policy could not be found, and no policy is set to the repository. +// +// * ErrCodeLifecyclePolicyPreviewInProgressException "LifecyclePolicyPreviewInProgressException" +// The previous lifecycle policy preview request has not completed. Please try +// again later. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreview +func (c *ECR) StartLifecyclePolicyPreview(input *StartLifecyclePolicyPreviewInput) (*StartLifecyclePolicyPreviewOutput, error) { + req, out := c.StartLifecyclePolicyPreviewRequest(input) + return out, req.Send() +} + +// StartLifecyclePolicyPreviewWithContext is the same as StartLifecyclePolicyPreview with the addition of +// the ability to pass a context and additional request options. +// +// See StartLifecyclePolicyPreview for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *ECR) StartLifecyclePolicyPreviewWithContext(ctx aws.Context, input *StartLifecyclePolicyPreviewInput, opts ...request.Option) (*StartLifecyclePolicyPreviewOutput, error) { + req, out := c.StartLifecyclePolicyPreviewRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opUploadLayerPart = "UploadLayerPart" // UploadLayerPartRequest generates a "aws/request.Request" representing the @@ -1703,7 +2155,7 @@ const opUploadLayerPart = "UploadLayerPart" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart func (c *ECR) UploadLayerPartRequest(input *UploadLayerPartInput) (req *request.Request, output *UploadLayerPartOutput) { op := &request.Operation{ Name: opUploadLayerPart, @@ -1761,7 +2213,7 @@ func (c *ECR) UploadLayerPartRequest(input *UploadLayerPartInput) (req *request. // (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) // in the Amazon EC2 Container Registry User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart func (c *ECR) UploadLayerPart(input *UploadLayerPartInput) (*UploadLayerPartOutput, error) { req, out := c.UploadLayerPartRequest(input) return out, req.Send() @@ -1784,7 +2236,7 @@ func (c *ECR) UploadLayerPartWithContext(ctx aws.Context, input *UploadLayerPart } // An object representing authorization data for an Amazon ECR registry. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/AuthorizationData +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/AuthorizationData type AuthorizationData struct { _ struct{} `type:"structure"` @@ -1831,7 +2283,7 @@ func (s *AuthorizationData) SetProxyEndpoint(v string) *AuthorizationData { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailabilityRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailabilityRequest type BatchCheckLayerAvailabilityInput struct { _ struct{} `type:"structure"` @@ -1900,7 +2352,7 @@ func (s *BatchCheckLayerAvailabilityInput) SetRepositoryName(v string) *BatchChe return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailabilityResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailabilityResponse type BatchCheckLayerAvailabilityOutput struct { _ struct{} `type:"structure"` @@ -1936,7 +2388,7 @@ func (s *BatchCheckLayerAvailabilityOutput) SetLayers(v []*Layer) *BatchCheckLay // Deletes specified images within a specified repository. Images are specified // with either the imageTag or imageDigest. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImageRequest type BatchDeleteImageInput struct { _ struct{} `type:"structure"` @@ -2006,7 +2458,7 @@ func (s *BatchDeleteImageInput) SetRepositoryName(v string) *BatchDeleteImageInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImageResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImageResponse type BatchDeleteImageOutput struct { _ struct{} `type:"structure"` @@ -2039,7 +2491,7 @@ func (s *BatchDeleteImageOutput) SetImageIds(v []*ImageIdentifier) *BatchDeleteI return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImageRequest type BatchGetImageInput struct { _ struct{} `type:"structure"` @@ -2124,7 +2576,7 @@ func (s *BatchGetImageInput) SetRepositoryName(v string) *BatchGetImageInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImageResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImageResponse type BatchGetImageOutput struct { _ struct{} `type:"structure"` @@ -2157,7 +2609,7 @@ func (s *BatchGetImageOutput) SetImages(v []*Image) *BatchGetImageOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUploadRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUploadRequest type CompleteLayerUploadInput struct { _ struct{} `type:"structure"` @@ -2241,7 +2693,7 @@ func (s *CompleteLayerUploadInput) SetUploadId(v string) *CompleteLayerUploadInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUploadResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUploadResponse type CompleteLayerUploadOutput struct { _ struct{} `type:"structure"` @@ -2292,7 +2744,7 @@ func (s *CompleteLayerUploadOutput) SetUploadId(v string) *CompleteLayerUploadOu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepositoryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepositoryRequest type CreateRepositoryInput struct { _ struct{} `type:"structure"` @@ -2336,7 +2788,7 @@ func (s *CreateRepositoryInput) SetRepositoryName(v string) *CreateRepositoryInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepositoryResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepositoryResponse type CreateRepositoryOutput struct { _ struct{} `type:"structure"` @@ -2360,11 +2812,115 @@ func (s *CreateRepositoryOutput) SetRepository(v *Repository) *CreateRepositoryO return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicyRequest +type DeleteLifecyclePolicyInput struct { + _ struct{} `type:"structure"` + + // The AWS account ID associated with the registry that contains the repository. + // If you do not specify a registry, the default registry is assumed. + RegistryId *string `locationName:"registryId" type:"string"` + + // The name of the repository that is associated with the repository policy + // to
 delete. + // + // RepositoryName is a required field + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteLifecyclePolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLifecyclePolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteLifecyclePolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteLifecyclePolicyInput"} + if s.RepositoryName == nil { + invalidParams.Add(request.NewErrParamRequired("RepositoryName")) + } + if s.RepositoryName != nil && len(*s.RepositoryName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegistryId sets the RegistryId field's value. +func (s *DeleteLifecyclePolicyInput) SetRegistryId(v string) *DeleteLifecyclePolicyInput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *DeleteLifecyclePolicyInput) SetRepositoryName(v string) *DeleteLifecyclePolicyInput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicyResponse +type DeleteLifecyclePolicyOutput struct { + _ struct{} `type:"structure"` + + // The time stamp of the last time that the lifecycle policy was run. + LastEvaluatedAt *time.Time `locationName:"lastEvaluatedAt" type:"timestamp" timestampFormat:"unix"` + + // The JSON repository policy text. + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"` + + // The registry ID associated with the request. + RegistryId *string `locationName:"registryId" type:"string"` + + // The repository name associated with the request. + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"` +} + +// String returns the string representation +func (s DeleteLifecyclePolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLifecyclePolicyOutput) GoString() string { + return s.String() +} + +// SetLastEvaluatedAt sets the LastEvaluatedAt field's value. +func (s *DeleteLifecyclePolicyOutput) SetLastEvaluatedAt(v time.Time) *DeleteLifecyclePolicyOutput { + s.LastEvaluatedAt = &v + return s +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *DeleteLifecyclePolicyOutput) SetLifecyclePolicyText(v string) *DeleteLifecyclePolicyOutput { + s.LifecyclePolicyText = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *DeleteLifecyclePolicyOutput) SetRegistryId(v string) *DeleteLifecyclePolicyOutput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *DeleteLifecyclePolicyOutput) SetRepositoryName(v string) *DeleteLifecyclePolicyOutput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryRequest type DeleteRepositoryInput struct { _ struct{} `type:"structure"` - // Force the deletion of the repository if it contains images. + // If a repository contains images, forces the deletion. Force *bool `locationName:"force" type:"boolean"` // The AWS account ID associated with the registry that contains the repository @@ -2421,7 +2977,7 @@ func (s *DeleteRepositoryInput) SetRepositoryName(v string) *DeleteRepositoryInp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryResponse type DeleteRepositoryOutput struct { _ struct{} `type:"structure"` @@ -2445,7 +3001,7 @@ func (s *DeleteRepositoryOutput) SetRepository(v *Repository) *DeleteRepositoryO return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicyRequest type DeleteRepositoryPolicyInput struct { _ struct{} `type:"structure"` @@ -2499,7 +3055,7 @@ func (s *DeleteRepositoryPolicyInput) SetRepositoryName(v string) *DeleteReposit return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicyResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicyResponse type DeleteRepositoryPolicyOutput struct { _ struct{} `type:"structure"` @@ -2542,7 +3098,7 @@ func (s *DeleteRepositoryPolicyOutput) SetRepositoryName(v string) *DeleteReposi } // An object representing a filter on a DescribeImages operation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesFilter type DescribeImagesFilter struct { _ struct{} `type:"structure"` @@ -2567,7 +3123,7 @@ func (s *DescribeImagesFilter) SetTagStatus(v string) *DescribeImagesFilter { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesRequest type DescribeImagesInput struct { _ struct{} `type:"structure"` @@ -2672,7 +3228,7 @@ func (s *DescribeImagesInput) SetRepositoryName(v string) *DescribeImagesInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesResponse type DescribeImagesOutput struct { _ struct{} `type:"structure"` @@ -2708,7 +3264,7 @@ func (s *DescribeImagesOutput) SetNextToken(v string) *DescribeImagesOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositoriesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositoriesRequest type DescribeRepositoriesInput struct { _ struct{} `type:"structure"` @@ -2791,7 +3347,7 @@ func (s *DescribeRepositoriesInput) SetRepositoryNames(v []*string) *DescribeRep return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositoriesResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositoriesResponse type DescribeRepositoriesOutput struct { _ struct{} `type:"structure"` @@ -2827,7 +3383,7 @@ func (s *DescribeRepositoriesOutput) SetRepositories(v []*Repository) *DescribeR return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationTokenRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationTokenRequest type GetAuthorizationTokenInput struct { _ struct{} `type:"structure"` @@ -2866,7 +3422,7 @@ func (s *GetAuthorizationTokenInput) SetRegistryIds(v []*string) *GetAuthorizati return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationTokenResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationTokenResponse type GetAuthorizationTokenOutput struct { _ struct{} `type:"structure"` @@ -2891,7 +3447,7 @@ func (s *GetAuthorizationTokenOutput) SetAuthorizationData(v []*AuthorizationDat return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayerRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayerRequest type GetDownloadUrlForLayerInput struct { _ struct{} `type:"structure"` @@ -2957,7 +3513,7 @@ func (s *GetDownloadUrlForLayerInput) SetRepositoryName(v string) *GetDownloadUr return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayerResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayerResponse type GetDownloadUrlForLayerOutput struct { _ struct{} `type:"structure"` @@ -2990,7 +3546,297 @@ func (s *GetDownloadUrlForLayerOutput) SetLayerDigest(v string) *GetDownloadUrlF return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyRequest +type GetLifecyclePolicyInput struct { + _ struct{} `type:"structure"` + + // The AWS account ID associated with the registry that contains the repository. + // If you do not specify a registry, the default registry is assumed. + RegistryId *string `locationName:"registryId" type:"string"` + + // The name of the repository with the policy to retrieve. + // + // RepositoryName is a required field + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetLifecyclePolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLifecyclePolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLifecyclePolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLifecyclePolicyInput"} + if s.RepositoryName == nil { + invalidParams.Add(request.NewErrParamRequired("RepositoryName")) + } + if s.RepositoryName != nil && len(*s.RepositoryName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRegistryId sets the RegistryId field's value. +func (s *GetLifecyclePolicyInput) SetRegistryId(v string) *GetLifecyclePolicyInput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *GetLifecyclePolicyInput) SetRepositoryName(v string) *GetLifecyclePolicyInput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyResponse +type GetLifecyclePolicyOutput struct { + _ struct{} `type:"structure"` + + // The time stamp of the last time that the lifecycle policy was run. + LastEvaluatedAt *time.Time `locationName:"lastEvaluatedAt" type:"timestamp" timestampFormat:"unix"` + + // The JSON repository policy text. + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"` + + // The registry ID associated with the request. + RegistryId *string `locationName:"registryId" type:"string"` + + // The repository name associated with the request. + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"` +} + +// String returns the string representation +func (s GetLifecyclePolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLifecyclePolicyOutput) GoString() string { + return s.String() +} + +// SetLastEvaluatedAt sets the LastEvaluatedAt field's value. +func (s *GetLifecyclePolicyOutput) SetLastEvaluatedAt(v time.Time) *GetLifecyclePolicyOutput { + s.LastEvaluatedAt = &v + return s +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *GetLifecyclePolicyOutput) SetLifecyclePolicyText(v string) *GetLifecyclePolicyOutput { + s.LifecyclePolicyText = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *GetLifecyclePolicyOutput) SetRegistryId(v string) *GetLifecyclePolicyOutput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *GetLifecyclePolicyOutput) SetRepositoryName(v string) *GetLifecyclePolicyOutput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreviewRequest +type GetLifecyclePolicyPreviewInput struct { + _ struct{} `type:"structure"` + + // An optional parameter that filters results based on image tag status and + // all tags, if tagged. + Filter *LifecyclePolicyPreviewFilter `locationName:"filter" type:"structure"` + + // The list of imageIDs to be included. + ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list"` + + // The maximum number of repository results returned by GetLifecyclePolicyPreviewRequest + // in
 paginated output. When this parameter is used, GetLifecyclePolicyPreviewRequest + // only returns
 maxResults results in a single page along with a nextToken + // response element. The remaining results of the initial request can be seen + // by sending
 another GetLifecyclePolicyPreviewRequest request with the returned + // nextToken
 value. This value can be between 1 and 100. If this
 parameter + // is not used, then GetLifecyclePolicyPreviewRequest returns up to
 100 results + // and a nextToken value, if
 applicable. + MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"` + + // The nextToken value returned from a previous paginated
 GetLifecyclePolicyPreviewRequest + // request where maxResults was used and the
 results exceeded the value of + // that parameter. Pagination continues from the end of the
 previous results + // that returned the nextToken value. This value is
 null when there are no + // more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // The AWS account ID associated with the registry that contains the repository. + // If you do not specify a registry, the default registry is assumed. + RegistryId *string `locationName:"registryId" type:"string"` + + // The name of the repository with the policy to retrieve. + // + // RepositoryName is a required field + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetLifecyclePolicyPreviewInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLifecyclePolicyPreviewInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLifecyclePolicyPreviewInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLifecyclePolicyPreviewInput"} + if s.ImageIds != nil && len(s.ImageIds) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ImageIds", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.RepositoryName == nil { + invalidParams.Add(request.NewErrParamRequired("RepositoryName")) + } + if s.RepositoryName != nil && len(*s.RepositoryName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFilter sets the Filter field's value. +func (s *GetLifecyclePolicyPreviewInput) SetFilter(v *LifecyclePolicyPreviewFilter) *GetLifecyclePolicyPreviewInput { + s.Filter = v + return s +} + +// SetImageIds sets the ImageIds field's value. +func (s *GetLifecyclePolicyPreviewInput) SetImageIds(v []*ImageIdentifier) *GetLifecyclePolicyPreviewInput { + s.ImageIds = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetLifecyclePolicyPreviewInput) SetMaxResults(v int64) *GetLifecyclePolicyPreviewInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetLifecyclePolicyPreviewInput) SetNextToken(v string) *GetLifecyclePolicyPreviewInput { + s.NextToken = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *GetLifecyclePolicyPreviewInput) SetRegistryId(v string) *GetLifecyclePolicyPreviewInput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *GetLifecyclePolicyPreviewInput) SetRepositoryName(v string) *GetLifecyclePolicyPreviewInput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreviewResponse +type GetLifecyclePolicyPreviewOutput struct { + _ struct{} `type:"structure"` + + // The JSON repository policy text. + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"` + + // The nextToken value to include in a future GetLifecyclePolicyPreview request. + // When the results of a GetLifecyclePolicyPreview request exceed maxResults, + // this value can be used to retrieve the next page of results. This value is + // null when there are no more results to return. + NextToken *string `locationName:"nextToken" type:"string"` + + // The results of the lifecycle policy preview request. + PreviewResults []*LifecyclePolicyPreviewResult `locationName:"previewResults" type:"list"` + + // The registry ID associated with the request. + RegistryId *string `locationName:"registryId" type:"string"` + + // The repository name associated with the request. + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"` + + // The status of the lifecycle policy preview request. + Status *string `locationName:"status" type:"string" enum:"LifecyclePolicyPreviewStatus"` + + // The list of images that is returned as a result of the action. + Summary *LifecyclePolicyPreviewSummary `locationName:"summary" type:"structure"` +} + +// String returns the string representation +func (s GetLifecyclePolicyPreviewOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLifecyclePolicyPreviewOutput) GoString() string { + return s.String() +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetLifecyclePolicyText(v string) *GetLifecyclePolicyPreviewOutput { + s.LifecyclePolicyText = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetNextToken(v string) *GetLifecyclePolicyPreviewOutput { + s.NextToken = &v + return s +} + +// SetPreviewResults sets the PreviewResults field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetPreviewResults(v []*LifecyclePolicyPreviewResult) *GetLifecyclePolicyPreviewOutput { + s.PreviewResults = v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetRegistryId(v string) *GetLifecyclePolicyPreviewOutput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetRepositoryName(v string) *GetLifecyclePolicyPreviewOutput { + s.RepositoryName = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetStatus(v string) *GetLifecyclePolicyPreviewOutput { + s.Status = &v + return s +} + +// SetSummary sets the Summary field's value. +func (s *GetLifecyclePolicyPreviewOutput) SetSummary(v *LifecyclePolicyPreviewSummary) *GetLifecyclePolicyPreviewOutput { + s.Summary = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicyRequest type GetRepositoryPolicyInput struct { _ struct{} `type:"structure"` @@ -2998,7 +3844,7 @@ type GetRepositoryPolicyInput struct { // If you do not specify a registry, the default registry is assumed. RegistryId *string `locationName:"registryId" type:"string"` - // The name of the repository whose policy you want to retrieve. + // The name of the repository with the policy to retrieve. // // RepositoryName is a required field RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` @@ -3042,7 +3888,7 @@ func (s *GetRepositoryPolicyInput) SetRepositoryName(v string) *GetRepositoryPol return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicyResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicyResponse type GetRepositoryPolicyOutput struct { _ struct{} `type:"structure"` @@ -3085,7 +3931,7 @@ func (s *GetRepositoryPolicyOutput) SetRepositoryName(v string) *GetRepositoryPo } // An object representing an Amazon ECR image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Image +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Image type Image struct { _ struct{} `type:"structure"` @@ -3137,7 +3983,7 @@ func (s *Image) SetRepositoryName(v string) *Image { } // An object that describes an image returned by a DescribeImages operation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageDetail +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageDetail type ImageDetail struct { _ struct{} `type:"structure"` @@ -3213,7 +4059,7 @@ func (s *ImageDetail) SetRepositoryName(v string) *ImageDetail { } // An object representing an Amazon ECR image failure. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageFailure +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageFailure type ImageFailure struct { _ struct{} `type:"structure"` @@ -3256,7 +4102,7 @@ func (s *ImageFailure) SetImageId(v *ImageIdentifier) *ImageFailure { } // An object with identifying information for an Amazon ECR image. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageIdentifier +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageIdentifier type ImageIdentifier struct { _ struct{} `type:"structure"` @@ -3289,15 +4135,15 @@ func (s *ImageIdentifier) SetImageTag(v string) *ImageIdentifier { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUploadRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUploadRequest type InitiateLayerUploadInput struct { _ struct{} `type:"structure"` - // The AWS account ID associated with the registry that you intend to upload - // layers to. If you do not specify a registry, the default registry is assumed. + // The AWS account ID associated with the registry to which you intend to upload + // layers. If you do not specify a registry, the default registry is assumed. RegistryId *string `locationName:"registryId" type:"string"` - // The name of the repository that you intend to upload layers to. + // The name of the repository to which you intend to upload layers. // // RepositoryName is a required field RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` @@ -3341,7 +4187,7 @@ func (s *InitiateLayerUploadInput) SetRepositoryName(v string) *InitiateLayerUpl return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUploadResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUploadResponse type InitiateLayerUploadOutput struct { _ struct{} `type:"structure"` @@ -3377,7 +4223,7 @@ func (s *InitiateLayerUploadOutput) SetUploadId(v string) *InitiateLayerUploadOu } // An object representing an Amazon ECR image layer. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Layer +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Layer type Layer struct { _ struct{} `type:"structure"` @@ -3430,7 +4276,7 @@ func (s *Layer) SetMediaType(v string) *Layer { } // An object representing an Amazon ECR image layer failure. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LayerFailure +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LayerFailure type LayerFailure struct { _ struct{} `type:"structure"` @@ -3472,8 +4318,145 @@ func (s *LayerFailure) SetLayerDigest(v string) *LayerFailure { return s } +// The filter for the lifecycle policy preview. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyPreviewFilter +type LifecyclePolicyPreviewFilter struct { + _ struct{} `type:"structure"` + + // The tag status of the image. + TagStatus *string `locationName:"tagStatus" type:"string" enum:"TagStatus"` +} + +// String returns the string representation +func (s LifecyclePolicyPreviewFilter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LifecyclePolicyPreviewFilter) GoString() string { + return s.String() +} + +// SetTagStatus sets the TagStatus field's value. +func (s *LifecyclePolicyPreviewFilter) SetTagStatus(v string) *LifecyclePolicyPreviewFilter { + s.TagStatus = &v + return s +} + +// The result of the lifecycle policy preview. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyPreviewResult +type LifecyclePolicyPreviewResult struct { + _ struct{} `type:"structure"` + + // The type of action to be taken. + Action *LifecyclePolicyRuleAction `locationName:"action" type:"structure"` + + // The priority of the applied rule. + AppliedRulePriority *int64 `locationName:"appliedRulePriority" min:"1" type:"integer"` + + // The sha256 digest of the image manifest. + ImageDigest *string `locationName:"imageDigest" type:"string"` + + // The date and time, expressed in standard JavaScript date format, at which + // the current image was pushed to the repository. + ImagePushedAt *time.Time `locationName:"imagePushedAt" type:"timestamp" timestampFormat:"unix"` + + // The list of tags associated with this image. + ImageTags []*string `locationName:"imageTags" type:"list"` +} + +// String returns the string representation +func (s LifecyclePolicyPreviewResult) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LifecyclePolicyPreviewResult) GoString() string { + return s.String() +} + +// SetAction sets the Action field's value. +func (s *LifecyclePolicyPreviewResult) SetAction(v *LifecyclePolicyRuleAction) *LifecyclePolicyPreviewResult { + s.Action = v + return s +} + +// SetAppliedRulePriority sets the AppliedRulePriority field's value. +func (s *LifecyclePolicyPreviewResult) SetAppliedRulePriority(v int64) *LifecyclePolicyPreviewResult { + s.AppliedRulePriority = &v + return s +} + +// SetImageDigest sets the ImageDigest field's value. +func (s *LifecyclePolicyPreviewResult) SetImageDigest(v string) *LifecyclePolicyPreviewResult { + s.ImageDigest = &v + return s +} + +// SetImagePushedAt sets the ImagePushedAt field's value. +func (s *LifecyclePolicyPreviewResult) SetImagePushedAt(v time.Time) *LifecyclePolicyPreviewResult { + s.ImagePushedAt = &v + return s +} + +// SetImageTags sets the ImageTags field's value. +func (s *LifecyclePolicyPreviewResult) SetImageTags(v []*string) *LifecyclePolicyPreviewResult { + s.ImageTags = v + return s +} + +// The summary of the lifecycle policy preview request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyPreviewSummary +type LifecyclePolicyPreviewSummary struct { + _ struct{} `type:"structure"` + + // The number of expiring images. + ExpiringImageTotalCount *int64 `locationName:"expiringImageTotalCount" type:"integer"` +} + +// String returns the string representation +func (s LifecyclePolicyPreviewSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LifecyclePolicyPreviewSummary) GoString() string { + return s.String() +} + +// SetExpiringImageTotalCount sets the ExpiringImageTotalCount field's value. +func (s *LifecyclePolicyPreviewSummary) SetExpiringImageTotalCount(v int64) *LifecyclePolicyPreviewSummary { + s.ExpiringImageTotalCount = &v + return s +} + +// The type of action to be taken. +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyRuleAction +type LifecyclePolicyRuleAction struct { + _ struct{} `type:"structure"` + + // The type of action to be taken. + Type *string `locationName:"type" type:"string" enum:"ImageActionType"` +} + +// String returns the string representation +func (s LifecyclePolicyRuleAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LifecyclePolicyRuleAction) GoString() string { + return s.String() +} + +// SetType sets the Type field's value. +func (s *LifecyclePolicyRuleAction) SetType(v string) *LifecyclePolicyRuleAction { + s.Type = &v + return s +} + // An object representing a filter on a ListImages operation. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesFilter type ListImagesFilter struct { _ struct{} `type:"structure"` @@ -3498,7 +4481,7 @@ func (s *ListImagesFilter) SetTagStatus(v string) *ListImagesFilter { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesRequest type ListImagesInput struct { _ struct{} `type:"structure"` @@ -3524,11 +4507,11 @@ type ListImagesInput struct { NextToken *string `locationName:"nextToken" type:"string"` // The AWS account ID associated with the registry that contains the repository - // to list images in. If you do not specify a registry, the default registry + // in which to list images. If you do not specify a registry, the default registry // is assumed. RegistryId *string `locationName:"registryId" type:"string"` - // The repository whose image IDs are to be listed. + // The repository with image IDs to be listed. // // RepositoryName is a required field RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` @@ -3593,7 +4576,7 @@ func (s *ListImagesInput) SetRepositoryName(v string) *ListImagesInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesResponse type ListImagesOutput struct { _ struct{} `type:"structure"` @@ -3629,7 +4612,7 @@ func (s *ListImagesOutput) SetNextToken(v string) *ListImagesOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImageRequest type PutImageInput struct { _ struct{} `type:"structure"` @@ -3706,7 +4689,7 @@ func (s *PutImageInput) SetRepositoryName(v string) *PutImageInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImageResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImageResponse type PutImageOutput struct { _ struct{} `type:"structure"` @@ -3730,28 +4713,138 @@ func (s *PutImageOutput) SetImage(v *Image) *PutImageOutput { return s } +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicyRequest +type PutLifecyclePolicyInput struct { + _ struct{} `type:"structure"` + + // The JSON repository policy text to apply to the repository. + // + // LifecyclePolicyText is a required field + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string" required:"true"` + + // The AWS account ID associated with the registry that contains the repository. + // If you do
 not specify a registry, the default registry is assumed. + RegistryId *string `locationName:"registryId" type:"string"` + + // The name of the repository to receive the policy. + // + // RepositoryName is a required field + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s PutLifecyclePolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutLifecyclePolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutLifecyclePolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutLifecyclePolicyInput"} + if s.LifecyclePolicyText == nil { + invalidParams.Add(request.NewErrParamRequired("LifecyclePolicyText")) + } + if s.LifecyclePolicyText != nil && len(*s.LifecyclePolicyText) < 100 { + invalidParams.Add(request.NewErrParamMinLen("LifecyclePolicyText", 100)) + } + if s.RepositoryName == nil { + invalidParams.Add(request.NewErrParamRequired("RepositoryName")) + } + if s.RepositoryName != nil && len(*s.RepositoryName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *PutLifecyclePolicyInput) SetLifecyclePolicyText(v string) *PutLifecyclePolicyInput { + s.LifecyclePolicyText = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *PutLifecyclePolicyInput) SetRegistryId(v string) *PutLifecyclePolicyInput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *PutLifecyclePolicyInput) SetRepositoryName(v string) *PutLifecyclePolicyInput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicyResponse +type PutLifecyclePolicyOutput struct { + _ struct{} `type:"structure"` + + // The JSON repository policy text. + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"` + + // The registry ID associated with the request. + RegistryId *string `locationName:"registryId" type:"string"` + + // The repository name associated with the request. + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"` +} + +// String returns the string representation +func (s PutLifecyclePolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutLifecyclePolicyOutput) GoString() string { + return s.String() +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *PutLifecyclePolicyOutput) SetLifecyclePolicyText(v string) *PutLifecyclePolicyOutput { + s.LifecyclePolicyText = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *PutLifecyclePolicyOutput) SetRegistryId(v string) *PutLifecyclePolicyOutput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *PutLifecyclePolicyOutput) SetRepositoryName(v string) *PutLifecyclePolicyOutput { + s.RepositoryName = &v + return s +} + // An object representing a repository. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Repository +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Repository type Repository struct { _ struct{} `type:"structure"` - // The date and time, in JavaScript date/time format, when the repository was - // created. + // The date and time, in JavaScript date format, when the repository was created. CreatedAt *time.Time `locationName:"createdAt" type:"timestamp" timestampFormat:"unix"` // The AWS account ID associated with the registry that contains the repository. RegistryId *string `locationName:"registryId" type:"string"` // The Amazon Resource Name (ARN) that identifies the repository. The ARN contains - // the arn:aws:ecr namespace, followed by the region of the repository, the - // AWS account ID of the repository owner, the repository namespace, and then - // the repository name. For example, arn:aws:ecr:region:012345678910:repository/test. + // the arn:aws:ecr namespace, followed by the region of the repository, AWS + // account ID of the repository owner, repository namespace, and repository + // name. For example, arn:aws:ecr:region:012345678910:repository/test. RepositoryArn *string `locationName:"repositoryArn" type:"string"` // The name of the repository. RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"` - // The URI for the repository. You can use this URI for Docker push and pull + // The URI for the repository. You can use this URI for Docker push or pull // operations. RepositoryUri *string `locationName:"repositoryUri" type:"string"` } @@ -3796,7 +4889,7 @@ func (s *Repository) SetRepositoryUri(v string) *Repository { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicyRequest type SetRepositoryPolicyInput struct { _ struct{} `type:"structure"` @@ -3873,7 +4966,7 @@ func (s *SetRepositoryPolicyInput) SetRepositoryName(v string) *SetRepositoryPol return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicyResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicyResponse type SetRepositoryPolicyOutput struct { _ struct{} `type:"structure"` @@ -3915,7 +5008,123 @@ func (s *SetRepositoryPolicyOutput) SetRepositoryName(v string) *SetRepositoryPo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPartRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreviewRequest +type StartLifecyclePolicyPreviewInput struct { + _ struct{} `type:"structure"` + + // The policy to be evaluated against. If you do not specify a policy, the current + // policy for the repository is used. + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"` + + // The AWS account ID associated with the registry that contains the repository. + // If you do not specify a registry, the default registry is assumed. + RegistryId *string `locationName:"registryId" type:"string"` + + // The name of the repository to be evaluated. + // + // RepositoryName is a required field + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s StartLifecyclePolicyPreviewInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartLifecyclePolicyPreviewInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StartLifecyclePolicyPreviewInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StartLifecyclePolicyPreviewInput"} + if s.LifecyclePolicyText != nil && len(*s.LifecyclePolicyText) < 100 { + invalidParams.Add(request.NewErrParamMinLen("LifecyclePolicyText", 100)) + } + if s.RepositoryName == nil { + invalidParams.Add(request.NewErrParamRequired("RepositoryName")) + } + if s.RepositoryName != nil && len(*s.RepositoryName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *StartLifecyclePolicyPreviewInput) SetLifecyclePolicyText(v string) *StartLifecyclePolicyPreviewInput { + s.LifecyclePolicyText = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *StartLifecyclePolicyPreviewInput) SetRegistryId(v string) *StartLifecyclePolicyPreviewInput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *StartLifecyclePolicyPreviewInput) SetRepositoryName(v string) *StartLifecyclePolicyPreviewInput { + s.RepositoryName = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreviewResponse +type StartLifecyclePolicyPreviewOutput struct { + _ struct{} `type:"structure"` + + // The JSON repository policy text. + LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"` + + // The registry ID associated with the request. + RegistryId *string `locationName:"registryId" type:"string"` + + // The repository name associated with the request. + RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"` + + // The status of the lifecycle policy preview request. + Status *string `locationName:"status" type:"string" enum:"LifecyclePolicyPreviewStatus"` +} + +// String returns the string representation +func (s StartLifecyclePolicyPreviewOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartLifecyclePolicyPreviewOutput) GoString() string { + return s.String() +} + +// SetLifecyclePolicyText sets the LifecyclePolicyText field's value. +func (s *StartLifecyclePolicyPreviewOutput) SetLifecyclePolicyText(v string) *StartLifecyclePolicyPreviewOutput { + s.LifecyclePolicyText = &v + return s +} + +// SetRegistryId sets the RegistryId field's value. +func (s *StartLifecyclePolicyPreviewOutput) SetRegistryId(v string) *StartLifecyclePolicyPreviewOutput { + s.RegistryId = &v + return s +} + +// SetRepositoryName sets the RepositoryName field's value. +func (s *StartLifecyclePolicyPreviewOutput) SetRepositoryName(v string) *StartLifecyclePolicyPreviewOutput { + s.RepositoryName = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *StartLifecyclePolicyPreviewOutput) SetStatus(v string) *StartLifecyclePolicyPreviewOutput { + s.Status = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPartRequest type UploadLayerPartInput struct { _ struct{} `type:"structure"` @@ -3936,11 +5145,11 @@ type UploadLayerPartInput struct { // PartLastByte is a required field PartLastByte *int64 `locationName:"partLastByte" type:"long" required:"true"` - // The AWS account ID associated with the registry that you are uploading layer - // parts to. If you do not specify a registry, the default registry is assumed. + // The AWS account ID associated with the registry to which you are uploading + // layer parts. If you do not specify a registry, the default registry is assumed. RegistryId *string `locationName:"registryId" type:"string"` - // The name of the repository that you are uploading layer parts to. + // The name of the repository to which you are uploading layer parts. // // RepositoryName is a required field RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"` @@ -4026,7 +5235,7 @@ func (s *UploadLayerPartInput) SetUploadId(v string) *UploadLayerPartInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPartResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPartResponse type UploadLayerPartOutput struct { _ struct{} `type:"structure"` @@ -4077,6 +5286,11 @@ func (s *UploadLayerPartOutput) SetUploadId(v string) *UploadLayerPartOutput { return s } +const ( + // ImageActionTypeExpire is a ImageActionType enum value + ImageActionTypeExpire = "EXPIRE" +) + const ( // ImageFailureCodeInvalidImageDigest is a ImageFailureCode enum value ImageFailureCodeInvalidImageDigest = "InvalidImageDigest" @@ -4110,6 +5324,20 @@ const ( LayerFailureCodeMissingLayerDigest = "MissingLayerDigest" ) +const ( + // LifecyclePolicyPreviewStatusInProgress is a LifecyclePolicyPreviewStatus enum value + LifecyclePolicyPreviewStatusInProgress = "IN_PROGRESS" + + // LifecyclePolicyPreviewStatusComplete is a LifecyclePolicyPreviewStatus enum value + LifecyclePolicyPreviewStatusComplete = "COMPLETE" + + // LifecyclePolicyPreviewStatusExpired is a LifecyclePolicyPreviewStatus enum value + LifecyclePolicyPreviewStatusExpired = "EXPIRED" + + // LifecyclePolicyPreviewStatusFailed is a LifecyclePolicyPreviewStatus enum value + LifecyclePolicyPreviewStatusFailed = "FAILED" +) + const ( // TagStatusTagged is a TagStatus enum value TagStatusTagged = "TAGGED" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecr/doc.go b/vendor/github.com/aws/aws-sdk-go/service/ecr/doc.go index 987aa72fa..a2aea0f6e 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecr/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecr/doc.go @@ -3,11 +3,11 @@ // Package ecr provides the client and types for making API // requests to Amazon EC2 Container Registry. // -// Amazon EC2 Container Registry (Amazon ECR) is a managed AWS Docker registry -// service. Customers can use the familiar Docker CLI to push, pull, and manage -// images. Amazon ECR provides a secure, scalable, and reliable registry. Amazon -// ECR supports private Docker repositories with resource-based permissions -// using AWS IAM so that specific users or Amazon EC2 instances can access repositories +// Amazon EC2 Container Registry (Amazon ECR) is a managed Docker registry service. +// Customers can use the familiar Docker CLI to push, pull, and manage images. +// Amazon ECR provides a secure, scalable, and reliable registry. Amazon ECR +// supports private Docker repositories with resource-based permissions using +// IAM so that specific users or Amazon EC2 instances can access repositories // and images. Developers can use the Docker CLI to author and manage images. // // See https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21 for more information on this service. @@ -17,7 +17,7 @@ // // Using the Client // -// To Amazon EC2 Container Registry with the SDK use the New function to create +// To contact Amazon EC2 Container Registry with the SDK use the New function to create // a new service client. With that client you can make API requests to the service. // These clients are safe to use concurrently. // diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go b/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go index 4399e6a29..2a2caaedd 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go @@ -13,8 +13,8 @@ const ( // ErrCodeImageAlreadyExistsException for service response error code // "ImageAlreadyExistsException". // - // The specified image has already been pushed, and there are no changes to - // the manifest or image tag since the last push. + // The specified image has already been pushed, and there were no changes to + // the manifest or image tag after the last push. ErrCodeImageAlreadyExistsException = "ImageAlreadyExistsException" // ErrCodeImageNotFoundException for service response error code @@ -70,6 +70,25 @@ const ( // for this repository. ErrCodeLayersNotFoundException = "LayersNotFoundException" + // ErrCodeLifecyclePolicyNotFoundException for service response error code + // "LifecyclePolicyNotFoundException". + // + // The lifecycle policy could not be found, and no policy is set to the repository. + ErrCodeLifecyclePolicyNotFoundException = "LifecyclePolicyNotFoundException" + + // ErrCodeLifecyclePolicyPreviewInProgressException for service response error code + // "LifecyclePolicyPreviewInProgressException". + // + // The previous lifecycle policy preview request has not completed. Please try + // again later. + ErrCodeLifecyclePolicyPreviewInProgressException = "LifecyclePolicyPreviewInProgressException" + + // ErrCodeLifecyclePolicyPreviewNotFoundException for service response error code + // "LifecyclePolicyPreviewNotFoundException". + // + // There is no dry run for this repository. + ErrCodeLifecyclePolicyPreviewNotFoundException = "LifecyclePolicyPreviewNotFoundException" + // ErrCodeLimitExceededException for service response error code // "LimitExceededException". // diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go index e65ef266f..0d852f59c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go @@ -39,7 +39,7 @@ const opAbortMultipartUpload = "AbortMultipartUpload" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload func (c *S3) AbortMultipartUploadRequest(input *AbortMultipartUploadInput) (req *request.Request, output *AbortMultipartUploadOutput) { op := &request.Operation{ Name: opAbortMultipartUpload, @@ -75,7 +75,7 @@ func (c *S3) AbortMultipartUploadRequest(input *AbortMultipartUploadInput) (req // * ErrCodeNoSuchUpload "NoSuchUpload" // The specified multipart upload does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload func (c *S3) AbortMultipartUpload(input *AbortMultipartUploadInput) (*AbortMultipartUploadOutput, error) { req, out := c.AbortMultipartUploadRequest(input) return out, req.Send() @@ -122,7 +122,7 @@ const opCompleteMultipartUpload = "CompleteMultipartUpload" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload func (c *S3) CompleteMultipartUploadRequest(input *CompleteMultipartUploadInput) (req *request.Request, output *CompleteMultipartUploadOutput) { op := &request.Operation{ Name: opCompleteMultipartUpload, @@ -149,7 +149,7 @@ func (c *S3) CompleteMultipartUploadRequest(input *CompleteMultipartUploadInput) // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation CompleteMultipartUpload for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload func (c *S3) CompleteMultipartUpload(input *CompleteMultipartUploadInput) (*CompleteMultipartUploadOutput, error) { req, out := c.CompleteMultipartUploadRequest(input) return out, req.Send() @@ -196,7 +196,7 @@ const opCopyObject = "CopyObject" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObject func (c *S3) CopyObjectRequest(input *CopyObjectInput) (req *request.Request, output *CopyObjectOutput) { op := &request.Operation{ Name: opCopyObject, @@ -229,7 +229,7 @@ func (c *S3) CopyObjectRequest(input *CopyObjectInput) (req *request.Request, ou // The source object of the COPY operation is not in the active tier and is // only stored in Amazon Glacier. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObject func (c *S3) CopyObject(input *CopyObjectInput) (*CopyObjectOutput, error) { req, out := c.CopyObjectRequest(input) return out, req.Send() @@ -276,7 +276,7 @@ const opCreateBucket = "CreateBucket" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket func (c *S3) CreateBucketRequest(input *CreateBucketInput) (req *request.Request, output *CreateBucketOutput) { op := &request.Operation{ Name: opCreateBucket, @@ -311,7 +311,7 @@ func (c *S3) CreateBucketRequest(input *CreateBucketInput) (req *request.Request // // * ErrCodeBucketAlreadyOwnedByYou "BucketAlreadyOwnedByYou" // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket func (c *S3) CreateBucket(input *CreateBucketInput) (*CreateBucketOutput, error) { req, out := c.CreateBucketRequest(input) return out, req.Send() @@ -358,7 +358,7 @@ const opCreateMultipartUpload = "CreateMultipartUpload" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUpload func (c *S3) CreateMultipartUploadRequest(input *CreateMultipartUploadInput) (req *request.Request, output *CreateMultipartUploadOutput) { op := &request.Operation{ Name: opCreateMultipartUpload, @@ -391,7 +391,7 @@ func (c *S3) CreateMultipartUploadRequest(input *CreateMultipartUploadInput) (re // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation CreateMultipartUpload for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUpload func (c *S3) CreateMultipartUpload(input *CreateMultipartUploadInput) (*CreateMultipartUploadOutput, error) { req, out := c.CreateMultipartUploadRequest(input) return out, req.Send() @@ -438,7 +438,7 @@ const opDeleteBucket = "DeleteBucket" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket func (c *S3) DeleteBucketRequest(input *DeleteBucketInput) (req *request.Request, output *DeleteBucketOutput) { op := &request.Operation{ Name: opDeleteBucket, @@ -468,7 +468,7 @@ func (c *S3) DeleteBucketRequest(input *DeleteBucketInput) (req *request.Request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucket for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket func (c *S3) DeleteBucket(input *DeleteBucketInput) (*DeleteBucketOutput, error) { req, out := c.DeleteBucketRequest(input) return out, req.Send() @@ -515,7 +515,7 @@ const opDeleteBucketAnalyticsConfiguration = "DeleteBucketAnalyticsConfiguration // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfiguration func (c *S3) DeleteBucketAnalyticsConfigurationRequest(input *DeleteBucketAnalyticsConfigurationInput) (req *request.Request, output *DeleteBucketAnalyticsConfigurationOutput) { op := &request.Operation{ Name: opDeleteBucketAnalyticsConfiguration, @@ -545,7 +545,7 @@ func (c *S3) DeleteBucketAnalyticsConfigurationRequest(input *DeleteBucketAnalyt // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketAnalyticsConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfiguration func (c *S3) DeleteBucketAnalyticsConfiguration(input *DeleteBucketAnalyticsConfigurationInput) (*DeleteBucketAnalyticsConfigurationOutput, error) { req, out := c.DeleteBucketAnalyticsConfigurationRequest(input) return out, req.Send() @@ -592,7 +592,7 @@ const opDeleteBucketCors = "DeleteBucketCors" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCors +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCors func (c *S3) DeleteBucketCorsRequest(input *DeleteBucketCorsInput) (req *request.Request, output *DeleteBucketCorsOutput) { op := &request.Operation{ Name: opDeleteBucketCors, @@ -621,7 +621,7 @@ func (c *S3) DeleteBucketCorsRequest(input *DeleteBucketCorsInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketCors for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCors +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCors func (c *S3) DeleteBucketCors(input *DeleteBucketCorsInput) (*DeleteBucketCorsOutput, error) { req, out := c.DeleteBucketCorsRequest(input) return out, req.Send() @@ -643,6 +643,82 @@ func (c *S3) DeleteBucketCorsWithContext(ctx aws.Context, input *DeleteBucketCor return out, req.Send() } +const opDeleteBucketEncryption = "DeleteBucketEncryption" + +// DeleteBucketEncryptionRequest generates a "aws/request.Request" representing the +// client's request for the DeleteBucketEncryption operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteBucketEncryption for more information on using the DeleteBucketEncryption +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteBucketEncryptionRequest method. +// req, resp := client.DeleteBucketEncryptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryption +func (c *S3) DeleteBucketEncryptionRequest(input *DeleteBucketEncryptionInput) (req *request.Request, output *DeleteBucketEncryptionOutput) { + op := &request.Operation{ + Name: opDeleteBucketEncryption, + HTTPMethod: "DELETE", + HTTPPath: "/{Bucket}?encryption", + } + + if input == nil { + input = &DeleteBucketEncryptionInput{} + } + + output = &DeleteBucketEncryptionOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteBucketEncryption API operation for Amazon Simple Storage Service. +// +// Deletes the server-side encryption configuration from the bucket. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Simple Storage Service's +// API operation DeleteBucketEncryption for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryption +func (c *S3) DeleteBucketEncryption(input *DeleteBucketEncryptionInput) (*DeleteBucketEncryptionOutput, error) { + req, out := c.DeleteBucketEncryptionRequest(input) + return out, req.Send() +} + +// DeleteBucketEncryptionWithContext is the same as DeleteBucketEncryption with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteBucketEncryption for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *S3) DeleteBucketEncryptionWithContext(ctx aws.Context, input *DeleteBucketEncryptionInput, opts ...request.Option) (*DeleteBucketEncryptionOutput, error) { + req, out := c.DeleteBucketEncryptionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeleteBucketInventoryConfiguration = "DeleteBucketInventoryConfiguration" // DeleteBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the @@ -668,7 +744,7 @@ const opDeleteBucketInventoryConfiguration = "DeleteBucketInventoryConfiguration // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfiguration func (c *S3) DeleteBucketInventoryConfigurationRequest(input *DeleteBucketInventoryConfigurationInput) (req *request.Request, output *DeleteBucketInventoryConfigurationOutput) { op := &request.Operation{ Name: opDeleteBucketInventoryConfiguration, @@ -698,7 +774,7 @@ func (c *S3) DeleteBucketInventoryConfigurationRequest(input *DeleteBucketInvent // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketInventoryConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfiguration func (c *S3) DeleteBucketInventoryConfiguration(input *DeleteBucketInventoryConfigurationInput) (*DeleteBucketInventoryConfigurationOutput, error) { req, out := c.DeleteBucketInventoryConfigurationRequest(input) return out, req.Send() @@ -745,7 +821,7 @@ const opDeleteBucketLifecycle = "DeleteBucketLifecycle" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycle +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycle func (c *S3) DeleteBucketLifecycleRequest(input *DeleteBucketLifecycleInput) (req *request.Request, output *DeleteBucketLifecycleOutput) { op := &request.Operation{ Name: opDeleteBucketLifecycle, @@ -774,7 +850,7 @@ func (c *S3) DeleteBucketLifecycleRequest(input *DeleteBucketLifecycleInput) (re // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketLifecycle for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycle +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycle func (c *S3) DeleteBucketLifecycle(input *DeleteBucketLifecycleInput) (*DeleteBucketLifecycleOutput, error) { req, out := c.DeleteBucketLifecycleRequest(input) return out, req.Send() @@ -821,7 +897,7 @@ const opDeleteBucketMetricsConfiguration = "DeleteBucketMetricsConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfiguration func (c *S3) DeleteBucketMetricsConfigurationRequest(input *DeleteBucketMetricsConfigurationInput) (req *request.Request, output *DeleteBucketMetricsConfigurationOutput) { op := &request.Operation{ Name: opDeleteBucketMetricsConfiguration, @@ -851,7 +927,7 @@ func (c *S3) DeleteBucketMetricsConfigurationRequest(input *DeleteBucketMetricsC // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketMetricsConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfiguration func (c *S3) DeleteBucketMetricsConfiguration(input *DeleteBucketMetricsConfigurationInput) (*DeleteBucketMetricsConfigurationOutput, error) { req, out := c.DeleteBucketMetricsConfigurationRequest(input) return out, req.Send() @@ -898,7 +974,7 @@ const opDeleteBucketPolicy = "DeleteBucketPolicy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicy func (c *S3) DeleteBucketPolicyRequest(input *DeleteBucketPolicyInput) (req *request.Request, output *DeleteBucketPolicyOutput) { op := &request.Operation{ Name: opDeleteBucketPolicy, @@ -927,7 +1003,7 @@ func (c *S3) DeleteBucketPolicyRequest(input *DeleteBucketPolicyInput) (req *req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketPolicy for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicy func (c *S3) DeleteBucketPolicy(input *DeleteBucketPolicyInput) (*DeleteBucketPolicyOutput, error) { req, out := c.DeleteBucketPolicyRequest(input) return out, req.Send() @@ -974,7 +1050,7 @@ const opDeleteBucketReplication = "DeleteBucketReplication" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplication +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplication func (c *S3) DeleteBucketReplicationRequest(input *DeleteBucketReplicationInput) (req *request.Request, output *DeleteBucketReplicationOutput) { op := &request.Operation{ Name: opDeleteBucketReplication, @@ -1003,7 +1079,7 @@ func (c *S3) DeleteBucketReplicationRequest(input *DeleteBucketReplicationInput) // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketReplication for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplication +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplication func (c *S3) DeleteBucketReplication(input *DeleteBucketReplicationInput) (*DeleteBucketReplicationOutput, error) { req, out := c.DeleteBucketReplicationRequest(input) return out, req.Send() @@ -1050,7 +1126,7 @@ const opDeleteBucketTagging = "DeleteBucketTagging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTagging func (c *S3) DeleteBucketTaggingRequest(input *DeleteBucketTaggingInput) (req *request.Request, output *DeleteBucketTaggingOutput) { op := &request.Operation{ Name: opDeleteBucketTagging, @@ -1079,7 +1155,7 @@ func (c *S3) DeleteBucketTaggingRequest(input *DeleteBucketTaggingInput) (req *r // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketTagging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTagging func (c *S3) DeleteBucketTagging(input *DeleteBucketTaggingInput) (*DeleteBucketTaggingOutput, error) { req, out := c.DeleteBucketTaggingRequest(input) return out, req.Send() @@ -1126,7 +1202,7 @@ const opDeleteBucketWebsite = "DeleteBucketWebsite" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsite +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsite func (c *S3) DeleteBucketWebsiteRequest(input *DeleteBucketWebsiteInput) (req *request.Request, output *DeleteBucketWebsiteOutput) { op := &request.Operation{ Name: opDeleteBucketWebsite, @@ -1155,7 +1231,7 @@ func (c *S3) DeleteBucketWebsiteRequest(input *DeleteBucketWebsiteInput) (req *r // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteBucketWebsite for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsite +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsite func (c *S3) DeleteBucketWebsite(input *DeleteBucketWebsiteInput) (*DeleteBucketWebsiteOutput, error) { req, out := c.DeleteBucketWebsiteRequest(input) return out, req.Send() @@ -1202,7 +1278,7 @@ const opDeleteObject = "DeleteObject" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject func (c *S3) DeleteObjectRequest(input *DeleteObjectInput) (req *request.Request, output *DeleteObjectOutput) { op := &request.Operation{ Name: opDeleteObject, @@ -1231,7 +1307,7 @@ func (c *S3) DeleteObjectRequest(input *DeleteObjectInput) (req *request.Request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteObject for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject func (c *S3) DeleteObject(input *DeleteObjectInput) (*DeleteObjectOutput, error) { req, out := c.DeleteObjectRequest(input) return out, req.Send() @@ -1278,7 +1354,7 @@ const opDeleteObjectTagging = "DeleteObjectTagging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTagging func (c *S3) DeleteObjectTaggingRequest(input *DeleteObjectTaggingInput) (req *request.Request, output *DeleteObjectTaggingOutput) { op := &request.Operation{ Name: opDeleteObjectTagging, @@ -1305,7 +1381,7 @@ func (c *S3) DeleteObjectTaggingRequest(input *DeleteObjectTaggingInput) (req *r // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteObjectTagging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTagging func (c *S3) DeleteObjectTagging(input *DeleteObjectTaggingInput) (*DeleteObjectTaggingOutput, error) { req, out := c.DeleteObjectTaggingRequest(input) return out, req.Send() @@ -1352,7 +1428,7 @@ const opDeleteObjects = "DeleteObjects" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjects +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjects func (c *S3) DeleteObjectsRequest(input *DeleteObjectsInput) (req *request.Request, output *DeleteObjectsOutput) { op := &request.Operation{ Name: opDeleteObjects, @@ -1380,7 +1456,7 @@ func (c *S3) DeleteObjectsRequest(input *DeleteObjectsInput) (req *request.Reque // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation DeleteObjects for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjects +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjects func (c *S3) DeleteObjects(input *DeleteObjectsInput) (*DeleteObjectsOutput, error) { req, out := c.DeleteObjectsRequest(input) return out, req.Send() @@ -1427,7 +1503,7 @@ const opGetBucketAccelerateConfiguration = "GetBucketAccelerateConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfiguration func (c *S3) GetBucketAccelerateConfigurationRequest(input *GetBucketAccelerateConfigurationInput) (req *request.Request, output *GetBucketAccelerateConfigurationOutput) { op := &request.Operation{ Name: opGetBucketAccelerateConfiguration, @@ -1454,7 +1530,7 @@ func (c *S3) GetBucketAccelerateConfigurationRequest(input *GetBucketAccelerateC // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketAccelerateConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfiguration func (c *S3) GetBucketAccelerateConfiguration(input *GetBucketAccelerateConfigurationInput) (*GetBucketAccelerateConfigurationOutput, error) { req, out := c.GetBucketAccelerateConfigurationRequest(input) return out, req.Send() @@ -1501,7 +1577,7 @@ const opGetBucketAcl = "GetBucketAcl" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAcl func (c *S3) GetBucketAclRequest(input *GetBucketAclInput) (req *request.Request, output *GetBucketAclOutput) { op := &request.Operation{ Name: opGetBucketAcl, @@ -1528,7 +1604,7 @@ func (c *S3) GetBucketAclRequest(input *GetBucketAclInput) (req *request.Request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketAcl for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAcl func (c *S3) GetBucketAcl(input *GetBucketAclInput) (*GetBucketAclOutput, error) { req, out := c.GetBucketAclRequest(input) return out, req.Send() @@ -1575,7 +1651,7 @@ const opGetBucketAnalyticsConfiguration = "GetBucketAnalyticsConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfiguration func (c *S3) GetBucketAnalyticsConfigurationRequest(input *GetBucketAnalyticsConfigurationInput) (req *request.Request, output *GetBucketAnalyticsConfigurationOutput) { op := &request.Operation{ Name: opGetBucketAnalyticsConfiguration, @@ -1603,7 +1679,7 @@ func (c *S3) GetBucketAnalyticsConfigurationRequest(input *GetBucketAnalyticsCon // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketAnalyticsConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfiguration func (c *S3) GetBucketAnalyticsConfiguration(input *GetBucketAnalyticsConfigurationInput) (*GetBucketAnalyticsConfigurationOutput, error) { req, out := c.GetBucketAnalyticsConfigurationRequest(input) return out, req.Send() @@ -1650,7 +1726,7 @@ const opGetBucketCors = "GetBucketCors" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCors +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCors func (c *S3) GetBucketCorsRequest(input *GetBucketCorsInput) (req *request.Request, output *GetBucketCorsOutput) { op := &request.Operation{ Name: opGetBucketCors, @@ -1677,7 +1753,7 @@ func (c *S3) GetBucketCorsRequest(input *GetBucketCorsInput) (req *request.Reque // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketCors for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCors +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCors func (c *S3) GetBucketCors(input *GetBucketCorsInput) (*GetBucketCorsOutput, error) { req, out := c.GetBucketCorsRequest(input) return out, req.Send() @@ -1699,6 +1775,80 @@ func (c *S3) GetBucketCorsWithContext(ctx aws.Context, input *GetBucketCorsInput return out, req.Send() } +const opGetBucketEncryption = "GetBucketEncryption" + +// GetBucketEncryptionRequest generates a "aws/request.Request" representing the +// client's request for the GetBucketEncryption operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetBucketEncryption for more information on using the GetBucketEncryption +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetBucketEncryptionRequest method. +// req, resp := client.GetBucketEncryptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryption +func (c *S3) GetBucketEncryptionRequest(input *GetBucketEncryptionInput) (req *request.Request, output *GetBucketEncryptionOutput) { + op := &request.Operation{ + Name: opGetBucketEncryption, + HTTPMethod: "GET", + HTTPPath: "/{Bucket}?encryption", + } + + if input == nil { + input = &GetBucketEncryptionInput{} + } + + output = &GetBucketEncryptionOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetBucketEncryption API operation for Amazon Simple Storage Service. +// +// Returns the server-side encryption configuration of a bucket. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Simple Storage Service's +// API operation GetBucketEncryption for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryption +func (c *S3) GetBucketEncryption(input *GetBucketEncryptionInput) (*GetBucketEncryptionOutput, error) { + req, out := c.GetBucketEncryptionRequest(input) + return out, req.Send() +} + +// GetBucketEncryptionWithContext is the same as GetBucketEncryption with the addition of +// the ability to pass a context and additional request options. +// +// See GetBucketEncryption for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *S3) GetBucketEncryptionWithContext(ctx aws.Context, input *GetBucketEncryptionInput, opts ...request.Option) (*GetBucketEncryptionOutput, error) { + req, out := c.GetBucketEncryptionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opGetBucketInventoryConfiguration = "GetBucketInventoryConfiguration" // GetBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the @@ -1724,7 +1874,7 @@ const opGetBucketInventoryConfiguration = "GetBucketInventoryConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfiguration func (c *S3) GetBucketInventoryConfigurationRequest(input *GetBucketInventoryConfigurationInput) (req *request.Request, output *GetBucketInventoryConfigurationOutput) { op := &request.Operation{ Name: opGetBucketInventoryConfiguration, @@ -1752,7 +1902,7 @@ func (c *S3) GetBucketInventoryConfigurationRequest(input *GetBucketInventoryCon // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketInventoryConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfiguration func (c *S3) GetBucketInventoryConfiguration(input *GetBucketInventoryConfigurationInput) (*GetBucketInventoryConfigurationOutput, error) { req, out := c.GetBucketInventoryConfigurationRequest(input) return out, req.Send() @@ -1799,7 +1949,7 @@ const opGetBucketLifecycle = "GetBucketLifecycle" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycle +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycle func (c *S3) GetBucketLifecycleRequest(input *GetBucketLifecycleInput) (req *request.Request, output *GetBucketLifecycleOutput) { if c.Client.Config.Logger != nil { c.Client.Config.Logger.Log("This operation, GetBucketLifecycle, has been deprecated") @@ -1829,7 +1979,7 @@ func (c *S3) GetBucketLifecycleRequest(input *GetBucketLifecycleInput) (req *req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketLifecycle for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycle +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycle func (c *S3) GetBucketLifecycle(input *GetBucketLifecycleInput) (*GetBucketLifecycleOutput, error) { req, out := c.GetBucketLifecycleRequest(input) return out, req.Send() @@ -1876,7 +2026,7 @@ const opGetBucketLifecycleConfiguration = "GetBucketLifecycleConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfiguration func (c *S3) GetBucketLifecycleConfigurationRequest(input *GetBucketLifecycleConfigurationInput) (req *request.Request, output *GetBucketLifecycleConfigurationOutput) { op := &request.Operation{ Name: opGetBucketLifecycleConfiguration, @@ -1903,7 +2053,7 @@ func (c *S3) GetBucketLifecycleConfigurationRequest(input *GetBucketLifecycleCon // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketLifecycleConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfiguration func (c *S3) GetBucketLifecycleConfiguration(input *GetBucketLifecycleConfigurationInput) (*GetBucketLifecycleConfigurationOutput, error) { req, out := c.GetBucketLifecycleConfigurationRequest(input) return out, req.Send() @@ -1950,7 +2100,7 @@ const opGetBucketLocation = "GetBucketLocation" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocation +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocation func (c *S3) GetBucketLocationRequest(input *GetBucketLocationInput) (req *request.Request, output *GetBucketLocationOutput) { op := &request.Operation{ Name: opGetBucketLocation, @@ -1977,7 +2127,7 @@ func (c *S3) GetBucketLocationRequest(input *GetBucketLocationInput) (req *reque // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketLocation for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocation +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocation func (c *S3) GetBucketLocation(input *GetBucketLocationInput) (*GetBucketLocationOutput, error) { req, out := c.GetBucketLocationRequest(input) return out, req.Send() @@ -2024,7 +2174,7 @@ const opGetBucketLogging = "GetBucketLogging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLogging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLogging func (c *S3) GetBucketLoggingRequest(input *GetBucketLoggingInput) (req *request.Request, output *GetBucketLoggingOutput) { op := &request.Operation{ Name: opGetBucketLogging, @@ -2052,7 +2202,7 @@ func (c *S3) GetBucketLoggingRequest(input *GetBucketLoggingInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketLogging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLogging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLogging func (c *S3) GetBucketLogging(input *GetBucketLoggingInput) (*GetBucketLoggingOutput, error) { req, out := c.GetBucketLoggingRequest(input) return out, req.Send() @@ -2099,7 +2249,7 @@ const opGetBucketMetricsConfiguration = "GetBucketMetricsConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfiguration func (c *S3) GetBucketMetricsConfigurationRequest(input *GetBucketMetricsConfigurationInput) (req *request.Request, output *GetBucketMetricsConfigurationOutput) { op := &request.Operation{ Name: opGetBucketMetricsConfiguration, @@ -2127,7 +2277,7 @@ func (c *S3) GetBucketMetricsConfigurationRequest(input *GetBucketMetricsConfigu // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketMetricsConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfiguration func (c *S3) GetBucketMetricsConfiguration(input *GetBucketMetricsConfigurationInput) (*GetBucketMetricsConfigurationOutput, error) { req, out := c.GetBucketMetricsConfigurationRequest(input) return out, req.Send() @@ -2174,7 +2324,7 @@ const opGetBucketNotification = "GetBucketNotification" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotification +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotification func (c *S3) GetBucketNotificationRequest(input *GetBucketNotificationConfigurationRequest) (req *request.Request, output *NotificationConfigurationDeprecated) { if c.Client.Config.Logger != nil { c.Client.Config.Logger.Log("This operation, GetBucketNotification, has been deprecated") @@ -2204,7 +2354,7 @@ func (c *S3) GetBucketNotificationRequest(input *GetBucketNotificationConfigurat // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketNotification for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotification +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotification func (c *S3) GetBucketNotification(input *GetBucketNotificationConfigurationRequest) (*NotificationConfigurationDeprecated, error) { req, out := c.GetBucketNotificationRequest(input) return out, req.Send() @@ -2251,7 +2401,7 @@ const opGetBucketNotificationConfiguration = "GetBucketNotificationConfiguration // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfiguration func (c *S3) GetBucketNotificationConfigurationRequest(input *GetBucketNotificationConfigurationRequest) (req *request.Request, output *NotificationConfiguration) { op := &request.Operation{ Name: opGetBucketNotificationConfiguration, @@ -2278,7 +2428,7 @@ func (c *S3) GetBucketNotificationConfigurationRequest(input *GetBucketNotificat // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketNotificationConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfiguration func (c *S3) GetBucketNotificationConfiguration(input *GetBucketNotificationConfigurationRequest) (*NotificationConfiguration, error) { req, out := c.GetBucketNotificationConfigurationRequest(input) return out, req.Send() @@ -2325,7 +2475,7 @@ const opGetBucketPolicy = "GetBucketPolicy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicy func (c *S3) GetBucketPolicyRequest(input *GetBucketPolicyInput) (req *request.Request, output *GetBucketPolicyOutput) { op := &request.Operation{ Name: opGetBucketPolicy, @@ -2352,7 +2502,7 @@ func (c *S3) GetBucketPolicyRequest(input *GetBucketPolicyInput) (req *request.R // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketPolicy for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicy func (c *S3) GetBucketPolicy(input *GetBucketPolicyInput) (*GetBucketPolicyOutput, error) { req, out := c.GetBucketPolicyRequest(input) return out, req.Send() @@ -2399,7 +2549,7 @@ const opGetBucketReplication = "GetBucketReplication" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplication +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplication func (c *S3) GetBucketReplicationRequest(input *GetBucketReplicationInput) (req *request.Request, output *GetBucketReplicationOutput) { op := &request.Operation{ Name: opGetBucketReplication, @@ -2426,7 +2576,7 @@ func (c *S3) GetBucketReplicationRequest(input *GetBucketReplicationInput) (req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketReplication for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplication +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplication func (c *S3) GetBucketReplication(input *GetBucketReplicationInput) (*GetBucketReplicationOutput, error) { req, out := c.GetBucketReplicationRequest(input) return out, req.Send() @@ -2473,7 +2623,7 @@ const opGetBucketRequestPayment = "GetBucketRequestPayment" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPayment +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPayment func (c *S3) GetBucketRequestPaymentRequest(input *GetBucketRequestPaymentInput) (req *request.Request, output *GetBucketRequestPaymentOutput) { op := &request.Operation{ Name: opGetBucketRequestPayment, @@ -2500,7 +2650,7 @@ func (c *S3) GetBucketRequestPaymentRequest(input *GetBucketRequestPaymentInput) // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketRequestPayment for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPayment +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPayment func (c *S3) GetBucketRequestPayment(input *GetBucketRequestPaymentInput) (*GetBucketRequestPaymentOutput, error) { req, out := c.GetBucketRequestPaymentRequest(input) return out, req.Send() @@ -2547,7 +2697,7 @@ const opGetBucketTagging = "GetBucketTagging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTagging func (c *S3) GetBucketTaggingRequest(input *GetBucketTaggingInput) (req *request.Request, output *GetBucketTaggingOutput) { op := &request.Operation{ Name: opGetBucketTagging, @@ -2574,7 +2724,7 @@ func (c *S3) GetBucketTaggingRequest(input *GetBucketTaggingInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketTagging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTagging func (c *S3) GetBucketTagging(input *GetBucketTaggingInput) (*GetBucketTaggingOutput, error) { req, out := c.GetBucketTaggingRequest(input) return out, req.Send() @@ -2621,7 +2771,7 @@ const opGetBucketVersioning = "GetBucketVersioning" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioning +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioning func (c *S3) GetBucketVersioningRequest(input *GetBucketVersioningInput) (req *request.Request, output *GetBucketVersioningOutput) { op := &request.Operation{ Name: opGetBucketVersioning, @@ -2648,7 +2798,7 @@ func (c *S3) GetBucketVersioningRequest(input *GetBucketVersioningInput) (req *r // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketVersioning for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioning +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioning func (c *S3) GetBucketVersioning(input *GetBucketVersioningInput) (*GetBucketVersioningOutput, error) { req, out := c.GetBucketVersioningRequest(input) return out, req.Send() @@ -2695,7 +2845,7 @@ const opGetBucketWebsite = "GetBucketWebsite" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsite +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsite func (c *S3) GetBucketWebsiteRequest(input *GetBucketWebsiteInput) (req *request.Request, output *GetBucketWebsiteOutput) { op := &request.Operation{ Name: opGetBucketWebsite, @@ -2722,7 +2872,7 @@ func (c *S3) GetBucketWebsiteRequest(input *GetBucketWebsiteInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetBucketWebsite for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsite +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsite func (c *S3) GetBucketWebsite(input *GetBucketWebsiteInput) (*GetBucketWebsiteOutput, error) { req, out := c.GetBucketWebsiteRequest(input) return out, req.Send() @@ -2769,7 +2919,7 @@ const opGetObject = "GetObject" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject func (c *S3) GetObjectRequest(input *GetObjectInput) (req *request.Request, output *GetObjectOutput) { op := &request.Operation{ Name: opGetObject, @@ -2801,7 +2951,7 @@ func (c *S3) GetObjectRequest(input *GetObjectInput) (req *request.Request, outp // * ErrCodeNoSuchKey "NoSuchKey" // The specified key does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject func (c *S3) GetObject(input *GetObjectInput) (*GetObjectOutput, error) { req, out := c.GetObjectRequest(input) return out, req.Send() @@ -2848,7 +2998,7 @@ const opGetObjectAcl = "GetObjectAcl" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAcl func (c *S3) GetObjectAclRequest(input *GetObjectAclInput) (req *request.Request, output *GetObjectAclOutput) { op := &request.Operation{ Name: opGetObjectAcl, @@ -2880,7 +3030,7 @@ func (c *S3) GetObjectAclRequest(input *GetObjectAclInput) (req *request.Request // * ErrCodeNoSuchKey "NoSuchKey" // The specified key does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAcl func (c *S3) GetObjectAcl(input *GetObjectAclInput) (*GetObjectAclOutput, error) { req, out := c.GetObjectAclRequest(input) return out, req.Send() @@ -2927,7 +3077,7 @@ const opGetObjectTagging = "GetObjectTagging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTagging func (c *S3) GetObjectTaggingRequest(input *GetObjectTaggingInput) (req *request.Request, output *GetObjectTaggingOutput) { op := &request.Operation{ Name: opGetObjectTagging, @@ -2954,7 +3104,7 @@ func (c *S3) GetObjectTaggingRequest(input *GetObjectTaggingInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetObjectTagging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTagging func (c *S3) GetObjectTagging(input *GetObjectTaggingInput) (*GetObjectTaggingOutput, error) { req, out := c.GetObjectTaggingRequest(input) return out, req.Send() @@ -3001,7 +3151,7 @@ const opGetObjectTorrent = "GetObjectTorrent" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrent +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrent func (c *S3) GetObjectTorrentRequest(input *GetObjectTorrentInput) (req *request.Request, output *GetObjectTorrentOutput) { op := &request.Operation{ Name: opGetObjectTorrent, @@ -3028,7 +3178,7 @@ func (c *S3) GetObjectTorrentRequest(input *GetObjectTorrentInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation GetObjectTorrent for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrent +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrent func (c *S3) GetObjectTorrent(input *GetObjectTorrentInput) (*GetObjectTorrentOutput, error) { req, out := c.GetObjectTorrentRequest(input) return out, req.Send() @@ -3075,7 +3225,7 @@ const opHeadBucket = "HeadBucket" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucket func (c *S3) HeadBucketRequest(input *HeadBucketInput) (req *request.Request, output *HeadBucketOutput) { op := &request.Operation{ Name: opHeadBucket, @@ -3110,7 +3260,7 @@ func (c *S3) HeadBucketRequest(input *HeadBucketInput) (req *request.Request, ou // * ErrCodeNoSuchBucket "NoSuchBucket" // The specified bucket does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucket func (c *S3) HeadBucket(input *HeadBucketInput) (*HeadBucketOutput, error) { req, out := c.HeadBucketRequest(input) return out, req.Send() @@ -3157,7 +3307,7 @@ const opHeadObject = "HeadObject" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject func (c *S3) HeadObjectRequest(input *HeadObjectInput) (req *request.Request, output *HeadObjectOutput) { op := &request.Operation{ Name: opHeadObject, @@ -3189,7 +3339,7 @@ func (c *S3) HeadObjectRequest(input *HeadObjectInput) (req *request.Request, ou // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation HeadObject for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject func (c *S3) HeadObject(input *HeadObjectInput) (*HeadObjectOutput, error) { req, out := c.HeadObjectRequest(input) return out, req.Send() @@ -3236,7 +3386,7 @@ const opListBucketAnalyticsConfigurations = "ListBucketAnalyticsConfigurations" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurations +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurations func (c *S3) ListBucketAnalyticsConfigurationsRequest(input *ListBucketAnalyticsConfigurationsInput) (req *request.Request, output *ListBucketAnalyticsConfigurationsOutput) { op := &request.Operation{ Name: opListBucketAnalyticsConfigurations, @@ -3263,7 +3413,7 @@ func (c *S3) ListBucketAnalyticsConfigurationsRequest(input *ListBucketAnalytics // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListBucketAnalyticsConfigurations for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurations +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurations func (c *S3) ListBucketAnalyticsConfigurations(input *ListBucketAnalyticsConfigurationsInput) (*ListBucketAnalyticsConfigurationsOutput, error) { req, out := c.ListBucketAnalyticsConfigurationsRequest(input) return out, req.Send() @@ -3310,7 +3460,7 @@ const opListBucketInventoryConfigurations = "ListBucketInventoryConfigurations" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurations +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurations func (c *S3) ListBucketInventoryConfigurationsRequest(input *ListBucketInventoryConfigurationsInput) (req *request.Request, output *ListBucketInventoryConfigurationsOutput) { op := &request.Operation{ Name: opListBucketInventoryConfigurations, @@ -3337,7 +3487,7 @@ func (c *S3) ListBucketInventoryConfigurationsRequest(input *ListBucketInventory // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListBucketInventoryConfigurations for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurations +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurations func (c *S3) ListBucketInventoryConfigurations(input *ListBucketInventoryConfigurationsInput) (*ListBucketInventoryConfigurationsOutput, error) { req, out := c.ListBucketInventoryConfigurationsRequest(input) return out, req.Send() @@ -3384,7 +3534,7 @@ const opListBucketMetricsConfigurations = "ListBucketMetricsConfigurations" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurations +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurations func (c *S3) ListBucketMetricsConfigurationsRequest(input *ListBucketMetricsConfigurationsInput) (req *request.Request, output *ListBucketMetricsConfigurationsOutput) { op := &request.Operation{ Name: opListBucketMetricsConfigurations, @@ -3411,7 +3561,7 @@ func (c *S3) ListBucketMetricsConfigurationsRequest(input *ListBucketMetricsConf // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListBucketMetricsConfigurations for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurations +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurations func (c *S3) ListBucketMetricsConfigurations(input *ListBucketMetricsConfigurationsInput) (*ListBucketMetricsConfigurationsOutput, error) { req, out := c.ListBucketMetricsConfigurationsRequest(input) return out, req.Send() @@ -3458,7 +3608,7 @@ const opListBuckets = "ListBuckets" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets func (c *S3) ListBucketsRequest(input *ListBucketsInput) (req *request.Request, output *ListBucketsOutput) { op := &request.Operation{ Name: opListBuckets, @@ -3485,7 +3635,7 @@ func (c *S3) ListBucketsRequest(input *ListBucketsInput) (req *request.Request, // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListBuckets for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets func (c *S3) ListBuckets(input *ListBucketsInput) (*ListBucketsOutput, error) { req, out := c.ListBucketsRequest(input) return out, req.Send() @@ -3532,7 +3682,7 @@ const opListMultipartUploads = "ListMultipartUploads" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploads +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploads func (c *S3) ListMultipartUploadsRequest(input *ListMultipartUploadsInput) (req *request.Request, output *ListMultipartUploadsOutput) { op := &request.Operation{ Name: opListMultipartUploads, @@ -3565,7 +3715,7 @@ func (c *S3) ListMultipartUploadsRequest(input *ListMultipartUploadsInput) (req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListMultipartUploads for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploads +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploads func (c *S3) ListMultipartUploads(input *ListMultipartUploadsInput) (*ListMultipartUploadsOutput, error) { req, out := c.ListMultipartUploadsRequest(input) return out, req.Send() @@ -3662,7 +3812,7 @@ const opListObjectVersions = "ListObjectVersions" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersions +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersions func (c *S3) ListObjectVersionsRequest(input *ListObjectVersionsInput) (req *request.Request, output *ListObjectVersionsOutput) { op := &request.Operation{ Name: opListObjectVersions, @@ -3695,7 +3845,7 @@ func (c *S3) ListObjectVersionsRequest(input *ListObjectVersionsInput) (req *req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListObjectVersions for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersions +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersions func (c *S3) ListObjectVersions(input *ListObjectVersionsInput) (*ListObjectVersionsOutput, error) { req, out := c.ListObjectVersionsRequest(input) return out, req.Send() @@ -3792,7 +3942,7 @@ const opListObjects = "ListObjects" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects func (c *S3) ListObjectsRequest(input *ListObjectsInput) (req *request.Request, output *ListObjectsOutput) { op := &request.Operation{ Name: opListObjects, @@ -3832,7 +3982,7 @@ func (c *S3) ListObjectsRequest(input *ListObjectsInput) (req *request.Request, // * ErrCodeNoSuchBucket "NoSuchBucket" // The specified bucket does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects func (c *S3) ListObjects(input *ListObjectsInput) (*ListObjectsOutput, error) { req, out := c.ListObjectsRequest(input) return out, req.Send() @@ -3929,7 +4079,7 @@ const opListObjectsV2 = "ListObjectsV2" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2 +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2 func (c *S3) ListObjectsV2Request(input *ListObjectsV2Input) (req *request.Request, output *ListObjectsV2Output) { op := &request.Operation{ Name: opListObjectsV2, @@ -3970,7 +4120,7 @@ func (c *S3) ListObjectsV2Request(input *ListObjectsV2Input) (req *request.Reque // * ErrCodeNoSuchBucket "NoSuchBucket" // The specified bucket does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2 +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2 func (c *S3) ListObjectsV2(input *ListObjectsV2Input) (*ListObjectsV2Output, error) { req, out := c.ListObjectsV2Request(input) return out, req.Send() @@ -4067,7 +4217,7 @@ const opListParts = "ListParts" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListParts +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListParts func (c *S3) ListPartsRequest(input *ListPartsInput) (req *request.Request, output *ListPartsOutput) { op := &request.Operation{ Name: opListParts, @@ -4100,7 +4250,7 @@ func (c *S3) ListPartsRequest(input *ListPartsInput) (req *request.Request, outp // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation ListParts for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListParts +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListParts func (c *S3) ListParts(input *ListPartsInput) (*ListPartsOutput, error) { req, out := c.ListPartsRequest(input) return out, req.Send() @@ -4197,7 +4347,7 @@ const opPutBucketAccelerateConfiguration = "PutBucketAccelerateConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfiguration func (c *S3) PutBucketAccelerateConfigurationRequest(input *PutBucketAccelerateConfigurationInput) (req *request.Request, output *PutBucketAccelerateConfigurationOutput) { op := &request.Operation{ Name: opPutBucketAccelerateConfiguration, @@ -4226,7 +4376,7 @@ func (c *S3) PutBucketAccelerateConfigurationRequest(input *PutBucketAccelerateC // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketAccelerateConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfiguration func (c *S3) PutBucketAccelerateConfiguration(input *PutBucketAccelerateConfigurationInput) (*PutBucketAccelerateConfigurationOutput, error) { req, out := c.PutBucketAccelerateConfigurationRequest(input) return out, req.Send() @@ -4273,7 +4423,7 @@ const opPutBucketAcl = "PutBucketAcl" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAcl func (c *S3) PutBucketAclRequest(input *PutBucketAclInput) (req *request.Request, output *PutBucketAclOutput) { op := &request.Operation{ Name: opPutBucketAcl, @@ -4302,7 +4452,7 @@ func (c *S3) PutBucketAclRequest(input *PutBucketAclInput) (req *request.Request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketAcl for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAcl func (c *S3) PutBucketAcl(input *PutBucketAclInput) (*PutBucketAclOutput, error) { req, out := c.PutBucketAclRequest(input) return out, req.Send() @@ -4349,7 +4499,7 @@ const opPutBucketAnalyticsConfiguration = "PutBucketAnalyticsConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfiguration func (c *S3) PutBucketAnalyticsConfigurationRequest(input *PutBucketAnalyticsConfigurationInput) (req *request.Request, output *PutBucketAnalyticsConfigurationOutput) { op := &request.Operation{ Name: opPutBucketAnalyticsConfiguration, @@ -4379,7 +4529,7 @@ func (c *S3) PutBucketAnalyticsConfigurationRequest(input *PutBucketAnalyticsCon // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketAnalyticsConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfiguration func (c *S3) PutBucketAnalyticsConfiguration(input *PutBucketAnalyticsConfigurationInput) (*PutBucketAnalyticsConfigurationOutput, error) { req, out := c.PutBucketAnalyticsConfigurationRequest(input) return out, req.Send() @@ -4426,7 +4576,7 @@ const opPutBucketCors = "PutBucketCors" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCors +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCors func (c *S3) PutBucketCorsRequest(input *PutBucketCorsInput) (req *request.Request, output *PutBucketCorsOutput) { op := &request.Operation{ Name: opPutBucketCors, @@ -4455,7 +4605,7 @@ func (c *S3) PutBucketCorsRequest(input *PutBucketCorsInput) (req *request.Reque // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketCors for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCors +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCors func (c *S3) PutBucketCors(input *PutBucketCorsInput) (*PutBucketCorsOutput, error) { req, out := c.PutBucketCorsRequest(input) return out, req.Send() @@ -4477,6 +4627,83 @@ func (c *S3) PutBucketCorsWithContext(ctx aws.Context, input *PutBucketCorsInput return out, req.Send() } +const opPutBucketEncryption = "PutBucketEncryption" + +// PutBucketEncryptionRequest generates a "aws/request.Request" representing the +// client's request for the PutBucketEncryption operation. The "output" return +// value will be populated with the request's response once the request complets +// successfuly. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutBucketEncryption for more information on using the PutBucketEncryption +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutBucketEncryptionRequest method. +// req, resp := client.PutBucketEncryptionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryption +func (c *S3) PutBucketEncryptionRequest(input *PutBucketEncryptionInput) (req *request.Request, output *PutBucketEncryptionOutput) { + op := &request.Operation{ + Name: opPutBucketEncryption, + HTTPMethod: "PUT", + HTTPPath: "/{Bucket}?encryption", + } + + if input == nil { + input = &PutBucketEncryptionInput{} + } + + output = &PutBucketEncryptionOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler) + req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler) + return +} + +// PutBucketEncryption API operation for Amazon Simple Storage Service. +// +// Creates a new server-side encryption configuration (or replaces an existing +// one, if present). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Simple Storage Service's +// API operation PutBucketEncryption for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryption +func (c *S3) PutBucketEncryption(input *PutBucketEncryptionInput) (*PutBucketEncryptionOutput, error) { + req, out := c.PutBucketEncryptionRequest(input) + return out, req.Send() +} + +// PutBucketEncryptionWithContext is the same as PutBucketEncryption with the addition of +// the ability to pass a context and additional request options. +// +// See PutBucketEncryption for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *S3) PutBucketEncryptionWithContext(ctx aws.Context, input *PutBucketEncryptionInput, opts ...request.Option) (*PutBucketEncryptionOutput, error) { + req, out := c.PutBucketEncryptionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opPutBucketInventoryConfiguration = "PutBucketInventoryConfiguration" // PutBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the @@ -4502,7 +4729,7 @@ const opPutBucketInventoryConfiguration = "PutBucketInventoryConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfiguration func (c *S3) PutBucketInventoryConfigurationRequest(input *PutBucketInventoryConfigurationInput) (req *request.Request, output *PutBucketInventoryConfigurationOutput) { op := &request.Operation{ Name: opPutBucketInventoryConfiguration, @@ -4532,7 +4759,7 @@ func (c *S3) PutBucketInventoryConfigurationRequest(input *PutBucketInventoryCon // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketInventoryConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfiguration func (c *S3) PutBucketInventoryConfiguration(input *PutBucketInventoryConfigurationInput) (*PutBucketInventoryConfigurationOutput, error) { req, out := c.PutBucketInventoryConfigurationRequest(input) return out, req.Send() @@ -4579,7 +4806,7 @@ const opPutBucketLifecycle = "PutBucketLifecycle" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycle +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycle func (c *S3) PutBucketLifecycleRequest(input *PutBucketLifecycleInput) (req *request.Request, output *PutBucketLifecycleOutput) { if c.Client.Config.Logger != nil { c.Client.Config.Logger.Log("This operation, PutBucketLifecycle, has been deprecated") @@ -4611,7 +4838,7 @@ func (c *S3) PutBucketLifecycleRequest(input *PutBucketLifecycleInput) (req *req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketLifecycle for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycle +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycle func (c *S3) PutBucketLifecycle(input *PutBucketLifecycleInput) (*PutBucketLifecycleOutput, error) { req, out := c.PutBucketLifecycleRequest(input) return out, req.Send() @@ -4658,7 +4885,7 @@ const opPutBucketLifecycleConfiguration = "PutBucketLifecycleConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfiguration func (c *S3) PutBucketLifecycleConfigurationRequest(input *PutBucketLifecycleConfigurationInput) (req *request.Request, output *PutBucketLifecycleConfigurationOutput) { op := &request.Operation{ Name: opPutBucketLifecycleConfiguration, @@ -4688,7 +4915,7 @@ func (c *S3) PutBucketLifecycleConfigurationRequest(input *PutBucketLifecycleCon // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketLifecycleConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfiguration func (c *S3) PutBucketLifecycleConfiguration(input *PutBucketLifecycleConfigurationInput) (*PutBucketLifecycleConfigurationOutput, error) { req, out := c.PutBucketLifecycleConfigurationRequest(input) return out, req.Send() @@ -4735,7 +4962,7 @@ const opPutBucketLogging = "PutBucketLogging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLogging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLogging func (c *S3) PutBucketLoggingRequest(input *PutBucketLoggingInput) (req *request.Request, output *PutBucketLoggingOutput) { op := &request.Operation{ Name: opPutBucketLogging, @@ -4766,7 +4993,7 @@ func (c *S3) PutBucketLoggingRequest(input *PutBucketLoggingInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketLogging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLogging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLogging func (c *S3) PutBucketLogging(input *PutBucketLoggingInput) (*PutBucketLoggingOutput, error) { req, out := c.PutBucketLoggingRequest(input) return out, req.Send() @@ -4813,7 +5040,7 @@ const opPutBucketMetricsConfiguration = "PutBucketMetricsConfiguration" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfiguration func (c *S3) PutBucketMetricsConfigurationRequest(input *PutBucketMetricsConfigurationInput) (req *request.Request, output *PutBucketMetricsConfigurationOutput) { op := &request.Operation{ Name: opPutBucketMetricsConfiguration, @@ -4843,7 +5070,7 @@ func (c *S3) PutBucketMetricsConfigurationRequest(input *PutBucketMetricsConfigu // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketMetricsConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfiguration func (c *S3) PutBucketMetricsConfiguration(input *PutBucketMetricsConfigurationInput) (*PutBucketMetricsConfigurationOutput, error) { req, out := c.PutBucketMetricsConfigurationRequest(input) return out, req.Send() @@ -4890,7 +5117,7 @@ const opPutBucketNotification = "PutBucketNotification" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotification +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotification func (c *S3) PutBucketNotificationRequest(input *PutBucketNotificationInput) (req *request.Request, output *PutBucketNotificationOutput) { if c.Client.Config.Logger != nil { c.Client.Config.Logger.Log("This operation, PutBucketNotification, has been deprecated") @@ -4922,7 +5149,7 @@ func (c *S3) PutBucketNotificationRequest(input *PutBucketNotificationInput) (re // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketNotification for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotification +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotification func (c *S3) PutBucketNotification(input *PutBucketNotificationInput) (*PutBucketNotificationOutput, error) { req, out := c.PutBucketNotificationRequest(input) return out, req.Send() @@ -4969,7 +5196,7 @@ const opPutBucketNotificationConfiguration = "PutBucketNotificationConfiguration // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfiguration func (c *S3) PutBucketNotificationConfigurationRequest(input *PutBucketNotificationConfigurationInput) (req *request.Request, output *PutBucketNotificationConfigurationOutput) { op := &request.Operation{ Name: opPutBucketNotificationConfiguration, @@ -4998,7 +5225,7 @@ func (c *S3) PutBucketNotificationConfigurationRequest(input *PutBucketNotificat // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketNotificationConfiguration for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfiguration func (c *S3) PutBucketNotificationConfiguration(input *PutBucketNotificationConfigurationInput) (*PutBucketNotificationConfigurationOutput, error) { req, out := c.PutBucketNotificationConfigurationRequest(input) return out, req.Send() @@ -5045,7 +5272,7 @@ const opPutBucketPolicy = "PutBucketPolicy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicy func (c *S3) PutBucketPolicyRequest(input *PutBucketPolicyInput) (req *request.Request, output *PutBucketPolicyOutput) { op := &request.Operation{ Name: opPutBucketPolicy, @@ -5075,7 +5302,7 @@ func (c *S3) PutBucketPolicyRequest(input *PutBucketPolicyInput) (req *request.R // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketPolicy for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicy func (c *S3) PutBucketPolicy(input *PutBucketPolicyInput) (*PutBucketPolicyOutput, error) { req, out := c.PutBucketPolicyRequest(input) return out, req.Send() @@ -5122,7 +5349,7 @@ const opPutBucketReplication = "PutBucketReplication" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplication +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplication func (c *S3) PutBucketReplicationRequest(input *PutBucketReplicationInput) (req *request.Request, output *PutBucketReplicationOutput) { op := &request.Operation{ Name: opPutBucketReplication, @@ -5152,7 +5379,7 @@ func (c *S3) PutBucketReplicationRequest(input *PutBucketReplicationInput) (req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketReplication for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplication +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplication func (c *S3) PutBucketReplication(input *PutBucketReplicationInput) (*PutBucketReplicationOutput, error) { req, out := c.PutBucketReplicationRequest(input) return out, req.Send() @@ -5199,7 +5426,7 @@ const opPutBucketRequestPayment = "PutBucketRequestPayment" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPayment +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPayment func (c *S3) PutBucketRequestPaymentRequest(input *PutBucketRequestPaymentInput) (req *request.Request, output *PutBucketRequestPaymentOutput) { op := &request.Operation{ Name: opPutBucketRequestPayment, @@ -5232,7 +5459,7 @@ func (c *S3) PutBucketRequestPaymentRequest(input *PutBucketRequestPaymentInput) // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketRequestPayment for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPayment +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPayment func (c *S3) PutBucketRequestPayment(input *PutBucketRequestPaymentInput) (*PutBucketRequestPaymentOutput, error) { req, out := c.PutBucketRequestPaymentRequest(input) return out, req.Send() @@ -5279,7 +5506,7 @@ const opPutBucketTagging = "PutBucketTagging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTagging func (c *S3) PutBucketTaggingRequest(input *PutBucketTaggingInput) (req *request.Request, output *PutBucketTaggingOutput) { op := &request.Operation{ Name: opPutBucketTagging, @@ -5308,7 +5535,7 @@ func (c *S3) PutBucketTaggingRequest(input *PutBucketTaggingInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketTagging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTagging func (c *S3) PutBucketTagging(input *PutBucketTaggingInput) (*PutBucketTaggingOutput, error) { req, out := c.PutBucketTaggingRequest(input) return out, req.Send() @@ -5355,7 +5582,7 @@ const opPutBucketVersioning = "PutBucketVersioning" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioning +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioning func (c *S3) PutBucketVersioningRequest(input *PutBucketVersioningInput) (req *request.Request, output *PutBucketVersioningOutput) { op := &request.Operation{ Name: opPutBucketVersioning, @@ -5385,7 +5612,7 @@ func (c *S3) PutBucketVersioningRequest(input *PutBucketVersioningInput) (req *r // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketVersioning for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioning +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioning func (c *S3) PutBucketVersioning(input *PutBucketVersioningInput) (*PutBucketVersioningOutput, error) { req, out := c.PutBucketVersioningRequest(input) return out, req.Send() @@ -5432,7 +5659,7 @@ const opPutBucketWebsite = "PutBucketWebsite" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsite +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsite func (c *S3) PutBucketWebsiteRequest(input *PutBucketWebsiteInput) (req *request.Request, output *PutBucketWebsiteOutput) { op := &request.Operation{ Name: opPutBucketWebsite, @@ -5461,7 +5688,7 @@ func (c *S3) PutBucketWebsiteRequest(input *PutBucketWebsiteInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutBucketWebsite for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsite +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsite func (c *S3) PutBucketWebsite(input *PutBucketWebsiteInput) (*PutBucketWebsiteOutput, error) { req, out := c.PutBucketWebsiteRequest(input) return out, req.Send() @@ -5508,7 +5735,7 @@ const opPutObject = "PutObject" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject func (c *S3) PutObjectRequest(input *PutObjectInput) (req *request.Request, output *PutObjectOutput) { op := &request.Operation{ Name: opPutObject, @@ -5535,7 +5762,7 @@ func (c *S3) PutObjectRequest(input *PutObjectInput) (req *request.Request, outp // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutObject for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject func (c *S3) PutObject(input *PutObjectInput) (*PutObjectOutput, error) { req, out := c.PutObjectRequest(input) return out, req.Send() @@ -5582,7 +5809,7 @@ const opPutObjectAcl = "PutObjectAcl" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAcl func (c *S3) PutObjectAclRequest(input *PutObjectAclInput) (req *request.Request, output *PutObjectAclOutput) { op := &request.Operation{ Name: opPutObjectAcl, @@ -5615,7 +5842,7 @@ func (c *S3) PutObjectAclRequest(input *PutObjectAclInput) (req *request.Request // * ErrCodeNoSuchKey "NoSuchKey" // The specified key does not exist. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAcl +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAcl func (c *S3) PutObjectAcl(input *PutObjectAclInput) (*PutObjectAclOutput, error) { req, out := c.PutObjectAclRequest(input) return out, req.Send() @@ -5662,7 +5889,7 @@ const opPutObjectTagging = "PutObjectTagging" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTagging func (c *S3) PutObjectTaggingRequest(input *PutObjectTaggingInput) (req *request.Request, output *PutObjectTaggingOutput) { op := &request.Operation{ Name: opPutObjectTagging, @@ -5689,7 +5916,7 @@ func (c *S3) PutObjectTaggingRequest(input *PutObjectTaggingInput) (req *request // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation PutObjectTagging for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTagging func (c *S3) PutObjectTagging(input *PutObjectTaggingInput) (*PutObjectTaggingOutput, error) { req, out := c.PutObjectTaggingRequest(input) return out, req.Send() @@ -5736,7 +5963,7 @@ const opRestoreObject = "RestoreObject" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObject func (c *S3) RestoreObjectRequest(input *RestoreObjectInput) (req *request.Request, output *RestoreObjectOutput) { op := &request.Operation{ Name: opRestoreObject, @@ -5768,7 +5995,7 @@ func (c *S3) RestoreObjectRequest(input *RestoreObjectInput) (req *request.Reque // * ErrCodeObjectAlreadyInActiveTierError "ObjectAlreadyInActiveTierError" // This operation is not allowed against this storage tier // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObject func (c *S3) RestoreObject(input *RestoreObjectInput) (*RestoreObjectOutput, error) { req, out := c.RestoreObjectRequest(input) return out, req.Send() @@ -5815,7 +6042,7 @@ const opUploadPart = "UploadPart" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart func (c *S3) UploadPartRequest(input *UploadPartInput) (req *request.Request, output *UploadPartOutput) { op := &request.Operation{ Name: opUploadPart, @@ -5848,7 +6075,7 @@ func (c *S3) UploadPartRequest(input *UploadPartInput) (req *request.Request, ou // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation UploadPart for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart func (c *S3) UploadPart(input *UploadPartInput) (*UploadPartOutput, error) { req, out := c.UploadPartRequest(input) return out, req.Send() @@ -5895,7 +6122,7 @@ const opUploadPartCopy = "UploadPartCopy" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopy func (c *S3) UploadPartCopyRequest(input *UploadPartCopyInput) (req *request.Request, output *UploadPartCopyOutput) { op := &request.Operation{ Name: opUploadPartCopy, @@ -5922,7 +6149,7 @@ func (c *S3) UploadPartCopyRequest(input *UploadPartCopyInput) (req *request.Req // // See the AWS API reference guide for Amazon Simple Storage Service's // API operation UploadPartCopy for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopy func (c *S3) UploadPartCopy(input *UploadPartCopyInput) (*UploadPartCopyOutput, error) { req, out := c.UploadPartCopyRequest(input) return out, req.Send() @@ -5946,7 +6173,7 @@ func (c *S3) UploadPartCopyWithContext(ctx aws.Context, input *UploadPartCopyInp // Specifies the days since the initiation of an Incomplete Multipart Upload // that Lifecycle will wait before permanently removing all parts of the upload. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortIncompleteMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortIncompleteMultipartUpload type AbortIncompleteMultipartUpload struct { _ struct{} `type:"structure"` @@ -5971,7 +6198,7 @@ func (s *AbortIncompleteMultipartUpload) SetDaysAfterInitiation(v int64) *AbortI return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUploadRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUploadRequest type AbortMultipartUploadInput struct { _ struct{} `type:"structure"` @@ -6054,7 +6281,7 @@ func (s *AbortMultipartUploadInput) SetUploadId(v string) *AbortMultipartUploadI return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUploadOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUploadOutput type AbortMultipartUploadOutput struct { _ struct{} `type:"structure"` @@ -6079,7 +6306,7 @@ func (s *AbortMultipartUploadOutput) SetRequestCharged(v string) *AbortMultipart return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccelerateConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccelerateConfiguration type AccelerateConfiguration struct { _ struct{} `type:"structure"` @@ -6103,7 +6330,7 @@ func (s *AccelerateConfiguration) SetStatus(v string) *AccelerateConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccessControlPolicy +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccessControlPolicy type AccessControlPolicy struct { _ struct{} `type:"structure"` @@ -6155,7 +6382,47 @@ func (s *AccessControlPolicy) SetOwner(v *Owner) *AccessControlPolicy { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsAndOperator +// Container for information regarding the access control for replicas. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccessControlTranslation +type AccessControlTranslation struct { + _ struct{} `type:"structure"` + + // The override value for the owner of the replica object. + // + // Owner is a required field + Owner *string `type:"string" required:"true" enum:"OwnerOverride"` +} + +// String returns the string representation +func (s AccessControlTranslation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccessControlTranslation) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AccessControlTranslation) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AccessControlTranslation"} + if s.Owner == nil { + invalidParams.Add(request.NewErrParamRequired("Owner")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetOwner sets the Owner field's value. +func (s *AccessControlTranslation) SetOwner(v string) *AccessControlTranslation { + s.Owner = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsAndOperator type AnalyticsAndOperator struct { _ struct{} `type:"structure"` @@ -6208,7 +6475,7 @@ func (s *AnalyticsAndOperator) SetTags(v []*Tag) *AnalyticsAndOperator { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsConfiguration type AnalyticsConfiguration struct { _ struct{} `type:"structure"` @@ -6283,7 +6550,7 @@ func (s *AnalyticsConfiguration) SetStorageClassAnalysis(v *StorageClassAnalysis return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsExportDestination +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsExportDestination type AnalyticsExportDestination struct { _ struct{} `type:"structure"` @@ -6327,7 +6594,7 @@ func (s *AnalyticsExportDestination) SetS3BucketDestination(v *AnalyticsS3Bucket return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsFilter type AnalyticsFilter struct { _ struct{} `type:"structure"` @@ -6390,7 +6657,7 @@ func (s *AnalyticsFilter) SetTag(v *Tag) *AnalyticsFilter { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsS3BucketDestination +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsS3BucketDestination type AnalyticsS3BucketDestination struct { _ struct{} `type:"structure"` @@ -6470,7 +6737,7 @@ func (s *AnalyticsS3BucketDestination) SetPrefix(v string) *AnalyticsS3BucketDes return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Bucket +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Bucket type Bucket struct { _ struct{} `type:"structure"` @@ -6503,7 +6770,7 @@ func (s *Bucket) SetName(v string) *Bucket { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/BucketLifecycleConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/BucketLifecycleConfiguration type BucketLifecycleConfiguration struct { _ struct{} `type:"structure"` @@ -6550,7 +6817,7 @@ func (s *BucketLifecycleConfiguration) SetRules(v []*LifecycleRule) *BucketLifec return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/BucketLoggingStatus +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/BucketLoggingStatus type BucketLoggingStatus struct { _ struct{} `type:"structure"` @@ -6588,7 +6855,7 @@ func (s *BucketLoggingStatus) SetLoggingEnabled(v *LoggingEnabled) *BucketLoggin return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CORSConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CORSConfiguration type CORSConfiguration struct { _ struct{} `type:"structure"` @@ -6635,7 +6902,7 @@ func (s *CORSConfiguration) SetCORSRules(v []*CORSRule) *CORSConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CORSRule +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CORSRule type CORSRule struct { _ struct{} `type:"structure"` @@ -6719,7 +6986,141 @@ func (s *CORSRule) SetMaxAgeSeconds(v int64) *CORSRule { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CloudFunctionConfiguration +// Describes how a CSV-formatted input object is formatted. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CSVInput +type CSVInput struct { + _ struct{} `type:"structure"` + + // Single character used to indicate a row should be ignored when present at + // the start of a row. + Comments *string `type:"string"` + + // Value used to separate individual fields in a record. + FieldDelimiter *string `type:"string"` + + // Describes the first line of input. Valid values: None, Ignore, Use. + FileHeaderInfo *string `type:"string" enum:"FileHeaderInfo"` + + // Value used for escaping where the field delimiter is part of the value. + QuoteCharacter *string `type:"string"` + + // Single character used for escaping the quote character inside an already + // escaped value. + QuoteEscapeCharacter *string `type:"string"` + + // Value used to separate individual records. + RecordDelimiter *string `type:"string"` +} + +// String returns the string representation +func (s CSVInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CSVInput) GoString() string { + return s.String() +} + +// SetComments sets the Comments field's value. +func (s *CSVInput) SetComments(v string) *CSVInput { + s.Comments = &v + return s +} + +// SetFieldDelimiter sets the FieldDelimiter field's value. +func (s *CSVInput) SetFieldDelimiter(v string) *CSVInput { + s.FieldDelimiter = &v + return s +} + +// SetFileHeaderInfo sets the FileHeaderInfo field's value. +func (s *CSVInput) SetFileHeaderInfo(v string) *CSVInput { + s.FileHeaderInfo = &v + return s +} + +// SetQuoteCharacter sets the QuoteCharacter field's value. +func (s *CSVInput) SetQuoteCharacter(v string) *CSVInput { + s.QuoteCharacter = &v + return s +} + +// SetQuoteEscapeCharacter sets the QuoteEscapeCharacter field's value. +func (s *CSVInput) SetQuoteEscapeCharacter(v string) *CSVInput { + s.QuoteEscapeCharacter = &v + return s +} + +// SetRecordDelimiter sets the RecordDelimiter field's value. +func (s *CSVInput) SetRecordDelimiter(v string) *CSVInput { + s.RecordDelimiter = &v + return s +} + +// Describes how CSV-formatted results are formatted. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CSVOutput +type CSVOutput struct { + _ struct{} `type:"structure"` + + // Value used to separate individual fields in a record. + FieldDelimiter *string `type:"string"` + + // Value used for escaping where the field delimiter is part of the value. + QuoteCharacter *string `type:"string"` + + // Single character used for escaping the quote character inside an already + // escaped value. + QuoteEscapeCharacter *string `type:"string"` + + // Indicates whether or not all output fields should be quoted. + QuoteFields *string `type:"string" enum:"QuoteFields"` + + // Value used to separate individual records. + RecordDelimiter *string `type:"string"` +} + +// String returns the string representation +func (s CSVOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CSVOutput) GoString() string { + return s.String() +} + +// SetFieldDelimiter sets the FieldDelimiter field's value. +func (s *CSVOutput) SetFieldDelimiter(v string) *CSVOutput { + s.FieldDelimiter = &v + return s +} + +// SetQuoteCharacter sets the QuoteCharacter field's value. +func (s *CSVOutput) SetQuoteCharacter(v string) *CSVOutput { + s.QuoteCharacter = &v + return s +} + +// SetQuoteEscapeCharacter sets the QuoteEscapeCharacter field's value. +func (s *CSVOutput) SetQuoteEscapeCharacter(v string) *CSVOutput { + s.QuoteEscapeCharacter = &v + return s +} + +// SetQuoteFields sets the QuoteFields field's value. +func (s *CSVOutput) SetQuoteFields(v string) *CSVOutput { + s.QuoteFields = &v + return s +} + +// SetRecordDelimiter sets the RecordDelimiter field's value. +func (s *CSVOutput) SetRecordDelimiter(v string) *CSVOutput { + s.RecordDelimiter = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CloudFunctionConfiguration type CloudFunctionConfiguration struct { _ struct{} `type:"structure"` @@ -6777,7 +7178,7 @@ func (s *CloudFunctionConfiguration) SetInvocationRole(v string) *CloudFunctionC return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CommonPrefix +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CommonPrefix type CommonPrefix struct { _ struct{} `type:"structure"` @@ -6800,7 +7201,7 @@ func (s *CommonPrefix) SetPrefix(v string) *CommonPrefix { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUploadRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUploadRequest type CompleteMultipartUploadInput struct { _ struct{} `type:"structure" payload:"MultipartUpload"` @@ -6891,7 +7292,7 @@ func (s *CompleteMultipartUploadInput) SetUploadId(v string) *CompleteMultipartU return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUploadOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUploadOutput type CompleteMultipartUploadOutput struct { _ struct{} `type:"structure"` @@ -6995,7 +7396,7 @@ func (s *CompleteMultipartUploadOutput) SetVersionId(v string) *CompleteMultipar return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompletedMultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompletedMultipartUpload type CompletedMultipartUpload struct { _ struct{} `type:"structure"` @@ -7018,7 +7419,7 @@ func (s *CompletedMultipartUpload) SetParts(v []*CompletedPart) *CompletedMultip return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompletedPart +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompletedPart type CompletedPart struct { _ struct{} `type:"structure"` @@ -7052,7 +7453,7 @@ func (s *CompletedPart) SetPartNumber(v int64) *CompletedPart { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Condition +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Condition type Condition struct { _ struct{} `type:"structure"` @@ -7095,7 +7496,7 @@ func (s *Condition) SetKeyPrefixEquals(v string) *Condition { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectRequest type CopyObjectInput struct { _ struct{} `type:"structure"` @@ -7479,7 +7880,7 @@ func (s *CopyObjectInput) SetWebsiteRedirectLocation(v string) *CopyObjectInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectOutput type CopyObjectOutput struct { _ struct{} `type:"structure" payload:"CopyObjectResult"` @@ -7580,7 +7981,7 @@ func (s *CopyObjectOutput) SetVersionId(v string) *CopyObjectOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectResult type CopyObjectResult struct { _ struct{} `type:"structure"` @@ -7611,7 +8012,7 @@ func (s *CopyObjectResult) SetLastModified(v time.Time) *CopyObjectResult { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyPartResult +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyPartResult type CopyPartResult struct { _ struct{} `type:"structure"` @@ -7644,7 +8045,7 @@ func (s *CopyPartResult) SetLastModified(v time.Time) *CopyPartResult { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketConfiguration type CreateBucketConfiguration struct { _ struct{} `type:"structure"` @@ -7669,7 +8070,7 @@ func (s *CreateBucketConfiguration) SetLocationConstraint(v string) *CreateBucke return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketRequest type CreateBucketInput struct { _ struct{} `type:"structure" payload:"CreateBucketConfiguration"` @@ -7776,7 +8177,7 @@ func (s *CreateBucketInput) SetGrantWriteACP(v string) *CreateBucketInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketOutput type CreateBucketOutput struct { _ struct{} `type:"structure"` @@ -7799,7 +8200,7 @@ func (s *CreateBucketOutput) SetLocation(v string) *CreateBucketOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUploadRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUploadRequest type CreateMultipartUploadInput struct { _ struct{} `type:"structure"` @@ -8071,7 +8472,7 @@ func (s *CreateMultipartUploadInput) SetWebsiteRedirectLocation(v string) *Creat return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUploadOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUploadOutput type CreateMultipartUploadOutput struct { _ struct{} `type:"structure"` @@ -8191,7 +8592,7 @@ func (s *CreateMultipartUploadOutput) SetUploadId(v string) *CreateMultipartUplo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Delete +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Delete type Delete struct { _ struct{} `type:"structure"` @@ -8248,7 +8649,7 @@ func (s *Delete) SetQuiet(v bool) *Delete { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfigurationRequest type DeleteBucketAnalyticsConfigurationInput struct { _ struct{} `type:"structure"` @@ -8308,7 +8709,7 @@ func (s *DeleteBucketAnalyticsConfigurationInput) SetId(v string) *DeleteBucketA return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfigurationOutput type DeleteBucketAnalyticsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -8323,7 +8724,7 @@ func (s DeleteBucketAnalyticsConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsRequest type DeleteBucketCorsInput struct { _ struct{} `type:"structure"` @@ -8367,7 +8768,7 @@ func (s *DeleteBucketCorsInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsOutput type DeleteBucketCorsOutput struct { _ struct{} `type:"structure"` } @@ -8382,7 +8783,69 @@ func (s DeleteBucketCorsOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryptionRequest +type DeleteBucketEncryptionInput struct { + _ struct{} `type:"structure"` + + // The name of the bucket containing the server-side encryption configuration + // to delete. + // + // Bucket is a required field + Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteBucketEncryptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteBucketEncryptionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteBucketEncryptionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteBucketEncryptionInput"} + if s.Bucket == nil { + invalidParams.Add(request.NewErrParamRequired("Bucket")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBucket sets the Bucket field's value. +func (s *DeleteBucketEncryptionInput) SetBucket(v string) *DeleteBucketEncryptionInput { + s.Bucket = &v + return s +} + +func (s *DeleteBucketEncryptionInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryptionOutput +type DeleteBucketEncryptionOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteBucketEncryptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteBucketEncryptionOutput) GoString() string { + return s.String() +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketRequest type DeleteBucketInput struct { _ struct{} `type:"structure"` @@ -8426,7 +8889,7 @@ func (s *DeleteBucketInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationRequest type DeleteBucketInventoryConfigurationInput struct { _ struct{} `type:"structure"` @@ -8486,7 +8949,7 @@ func (s *DeleteBucketInventoryConfigurationInput) SetId(v string) *DeleteBucketI return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationOutput type DeleteBucketInventoryConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -8501,7 +8964,7 @@ func (s DeleteBucketInventoryConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleRequest type DeleteBucketLifecycleInput struct { _ struct{} `type:"structure"` @@ -8545,7 +9008,7 @@ func (s *DeleteBucketLifecycleInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleOutput type DeleteBucketLifecycleOutput struct { _ struct{} `type:"structure"` } @@ -8560,7 +9023,7 @@ func (s DeleteBucketLifecycleOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfigurationRequest type DeleteBucketMetricsConfigurationInput struct { _ struct{} `type:"structure"` @@ -8620,7 +9083,7 @@ func (s *DeleteBucketMetricsConfigurationInput) SetId(v string) *DeleteBucketMet return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfigurationOutput type DeleteBucketMetricsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -8635,7 +9098,7 @@ func (s DeleteBucketMetricsConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketOutput type DeleteBucketOutput struct { _ struct{} `type:"structure"` } @@ -8650,7 +9113,7 @@ func (s DeleteBucketOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyRequest type DeleteBucketPolicyInput struct { _ struct{} `type:"structure"` @@ -8694,7 +9157,7 @@ func (s *DeleteBucketPolicyInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyOutput type DeleteBucketPolicyOutput struct { _ struct{} `type:"structure"` } @@ -8709,7 +9172,7 @@ func (s DeleteBucketPolicyOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationRequest type DeleteBucketReplicationInput struct { _ struct{} `type:"structure"` @@ -8753,7 +9216,7 @@ func (s *DeleteBucketReplicationInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationOutput type DeleteBucketReplicationOutput struct { _ struct{} `type:"structure"` } @@ -8768,7 +9231,7 @@ func (s DeleteBucketReplicationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingRequest type DeleteBucketTaggingInput struct { _ struct{} `type:"structure"` @@ -8812,7 +9275,7 @@ func (s *DeleteBucketTaggingInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingOutput type DeleteBucketTaggingOutput struct { _ struct{} `type:"structure"` } @@ -8827,7 +9290,7 @@ func (s DeleteBucketTaggingOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteRequest type DeleteBucketWebsiteInput struct { _ struct{} `type:"structure"` @@ -8871,7 +9334,7 @@ func (s *DeleteBucketWebsiteInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteOutput type DeleteBucketWebsiteOutput struct { _ struct{} `type:"structure"` } @@ -8886,7 +9349,7 @@ func (s DeleteBucketWebsiteOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteMarkerEntry +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteMarkerEntry type DeleteMarkerEntry struct { _ struct{} `type:"structure"` @@ -8946,7 +9409,7 @@ func (s *DeleteMarkerEntry) SetVersionId(v string) *DeleteMarkerEntry { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectRequest type DeleteObjectInput struct { _ struct{} `type:"structure"` @@ -9036,7 +9499,7 @@ func (s *DeleteObjectInput) SetVersionId(v string) *DeleteObjectInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectOutput type DeleteObjectOutput struct { _ struct{} `type:"structure"` @@ -9081,7 +9544,7 @@ func (s *DeleteObjectOutput) SetVersionId(v string) *DeleteObjectOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTaggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTaggingRequest type DeleteObjectTaggingInput struct { _ struct{} `type:"structure"` @@ -9149,7 +9612,7 @@ func (s *DeleteObjectTaggingInput) SetVersionId(v string) *DeleteObjectTaggingIn return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTaggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTaggingOutput type DeleteObjectTaggingOutput struct { _ struct{} `type:"structure"` @@ -9173,7 +9636,7 @@ func (s *DeleteObjectTaggingOutput) SetVersionId(v string) *DeleteObjectTaggingO return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectsRequest type DeleteObjectsInput struct { _ struct{} `type:"structure" payload:"Delete"` @@ -9256,7 +9719,7 @@ func (s *DeleteObjectsInput) SetRequestPayer(v string) *DeleteObjectsInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectsOutput type DeleteObjectsOutput struct { _ struct{} `type:"structure"` @@ -9297,7 +9760,7 @@ func (s *DeleteObjectsOutput) SetRequestCharged(v string) *DeleteObjectsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeletedObject +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeletedObject type DeletedObject struct { _ struct{} `type:"structure"` @@ -9344,16 +9807,27 @@ func (s *DeletedObject) SetVersionId(v string) *DeletedObject { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Destination +// Container for replication destination information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Destination type Destination struct { _ struct{} `type:"structure"` + // Container for information regarding the access control for replicas. + AccessControlTranslation *AccessControlTranslation `type:"structure"` + + // Account ID of the destination bucket. Currently this is only being verified + // if Access Control Translation is enabled + Account *string `type:"string"` + // Amazon resource name (ARN) of the bucket where you want Amazon S3 to store // replicas of the object identified by the rule. // // Bucket is a required field Bucket *string `type:"string" required:"true"` + // Container for information regarding encryption based configuration for replicas. + EncryptionConfiguration *EncryptionConfiguration `type:"structure"` + // The class of storage used to store the object. StorageClass *string `type:"string" enum:"StorageClass"` } @@ -9374,6 +9848,11 @@ func (s *Destination) Validate() error { if s.Bucket == nil { invalidParams.Add(request.NewErrParamRequired("Bucket")) } + if s.AccessControlTranslation != nil { + if err := s.AccessControlTranslation.Validate(); err != nil { + invalidParams.AddNested("AccessControlTranslation", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -9381,6 +9860,18 @@ func (s *Destination) Validate() error { return nil } +// SetAccessControlTranslation sets the AccessControlTranslation field's value. +func (s *Destination) SetAccessControlTranslation(v *AccessControlTranslation) *Destination { + s.AccessControlTranslation = v + return s +} + +// SetAccount sets the Account field's value. +func (s *Destination) SetAccount(v string) *Destination { + s.Account = &v + return s +} + // SetBucket sets the Bucket field's value. func (s *Destination) SetBucket(v string) *Destination { s.Bucket = &v @@ -9394,13 +9885,106 @@ func (s *Destination) getBucket() (v string) { return *s.Bucket } +// SetEncryptionConfiguration sets the EncryptionConfiguration field's value. +func (s *Destination) SetEncryptionConfiguration(v *EncryptionConfiguration) *Destination { + s.EncryptionConfiguration = v + return s +} + // SetStorageClass sets the StorageClass field's value. func (s *Destination) SetStorageClass(v string) *Destination { s.StorageClass = &v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Error +// Describes the server-side encryption that will be applied to the restore +// results. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Encryption +type Encryption struct { + _ struct{} `type:"structure"` + + // The server-side encryption algorithm used when storing job results in Amazon + // S3 (e.g., AES256, aws:kms). + // + // EncryptionType is a required field + EncryptionType *string `type:"string" required:"true" enum:"ServerSideEncryption"` + + // If the encryption type is aws:kms, this optional value can be used to specify + // the encryption context for the restore results. + KMSContext *string `type:"string"` + + // If the encryption type is aws:kms, this optional value specifies the AWS + // KMS key ID to use for encryption of job results. + KMSKeyId *string `type:"string"` +} + +// String returns the string representation +func (s Encryption) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Encryption) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Encryption) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Encryption"} + if s.EncryptionType == nil { + invalidParams.Add(request.NewErrParamRequired("EncryptionType")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEncryptionType sets the EncryptionType field's value. +func (s *Encryption) SetEncryptionType(v string) *Encryption { + s.EncryptionType = &v + return s +} + +// SetKMSContext sets the KMSContext field's value. +func (s *Encryption) SetKMSContext(v string) *Encryption { + s.KMSContext = &v + return s +} + +// SetKMSKeyId sets the KMSKeyId field's value. +func (s *Encryption) SetKMSKeyId(v string) *Encryption { + s.KMSKeyId = &v + return s +} + +// Container for information regarding encryption based configuration for replicas. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/EncryptionConfiguration +type EncryptionConfiguration struct { + _ struct{} `type:"structure"` + + // The id of the KMS key used to encrypt the replica object. + ReplicaKmsKeyID *string `type:"string"` +} + +// String returns the string representation +func (s EncryptionConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EncryptionConfiguration) GoString() string { + return s.String() +} + +// SetReplicaKmsKeyID sets the ReplicaKmsKeyID field's value. +func (s *EncryptionConfiguration) SetReplicaKmsKeyID(v string) *EncryptionConfiguration { + s.ReplicaKmsKeyID = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Error type Error struct { _ struct{} `type:"structure"` @@ -9447,7 +10031,7 @@ func (s *Error) SetVersionId(v string) *Error { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ErrorDocument +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ErrorDocument type ErrorDocument struct { _ struct{} `type:"structure"` @@ -9490,7 +10074,7 @@ func (s *ErrorDocument) SetKey(v string) *ErrorDocument { } // Container for key value pair that defines the criteria for the filter rule. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/FilterRule +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/FilterRule type FilterRule struct { _ struct{} `type:"structure"` @@ -9525,7 +10109,7 @@ func (s *FilterRule) SetValue(v string) *FilterRule { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationRequest type GetBucketAccelerateConfigurationInput struct { _ struct{} `type:"structure"` @@ -9571,7 +10155,7 @@ func (s *GetBucketAccelerateConfigurationInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationOutput type GetBucketAccelerateConfigurationOutput struct { _ struct{} `type:"structure"` @@ -9595,7 +10179,7 @@ func (s *GetBucketAccelerateConfigurationOutput) SetStatus(v string) *GetBucketA return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclRequest type GetBucketAclInput struct { _ struct{} `type:"structure"` @@ -9639,7 +10223,7 @@ func (s *GetBucketAclInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclOutput type GetBucketAclOutput struct { _ struct{} `type:"structure"` @@ -9671,7 +10255,7 @@ func (s *GetBucketAclOutput) SetOwner(v *Owner) *GetBucketAclOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfigurationRequest type GetBucketAnalyticsConfigurationInput struct { _ struct{} `type:"structure"` @@ -9731,7 +10315,7 @@ func (s *GetBucketAnalyticsConfigurationInput) SetId(v string) *GetBucketAnalyti return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfigurationOutput type GetBucketAnalyticsConfigurationOutput struct { _ struct{} `type:"structure" payload:"AnalyticsConfiguration"` @@ -9755,7 +10339,7 @@ func (s *GetBucketAnalyticsConfigurationOutput) SetAnalyticsConfiguration(v *Ana return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsRequest type GetBucketCorsInput struct { _ struct{} `type:"structure"` @@ -9799,7 +10383,7 @@ func (s *GetBucketCorsInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsOutput type GetBucketCorsOutput struct { _ struct{} `type:"structure"` @@ -9822,7 +10406,79 @@ func (s *GetBucketCorsOutput) SetCORSRules(v []*CORSRule) *GetBucketCorsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryptionRequest +type GetBucketEncryptionInput struct { + _ struct{} `type:"structure"` + + // The name of the bucket from which the server-side encryption configuration + // is retrieved. + // + // Bucket is a required field + Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetBucketEncryptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetBucketEncryptionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetBucketEncryptionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetBucketEncryptionInput"} + if s.Bucket == nil { + invalidParams.Add(request.NewErrParamRequired("Bucket")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBucket sets the Bucket field's value. +func (s *GetBucketEncryptionInput) SetBucket(v string) *GetBucketEncryptionInput { + s.Bucket = &v + return s +} + +func (s *GetBucketEncryptionInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryptionOutput +type GetBucketEncryptionOutput struct { + _ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"` + + // Container for server-side encryption configuration rules. Currently S3 supports + // one rule only. + ServerSideEncryptionConfiguration *ServerSideEncryptionConfiguration `type:"structure"` +} + +// String returns the string representation +func (s GetBucketEncryptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetBucketEncryptionOutput) GoString() string { + return s.String() +} + +// SetServerSideEncryptionConfiguration sets the ServerSideEncryptionConfiguration field's value. +func (s *GetBucketEncryptionOutput) SetServerSideEncryptionConfiguration(v *ServerSideEncryptionConfiguration) *GetBucketEncryptionOutput { + s.ServerSideEncryptionConfiguration = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfigurationRequest type GetBucketInventoryConfigurationInput struct { _ struct{} `type:"structure"` @@ -9882,7 +10538,7 @@ func (s *GetBucketInventoryConfigurationInput) SetId(v string) *GetBucketInvento return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfigurationOutput type GetBucketInventoryConfigurationOutput struct { _ struct{} `type:"structure" payload:"InventoryConfiguration"` @@ -9906,7 +10562,7 @@ func (s *GetBucketInventoryConfigurationOutput) SetInventoryConfiguration(v *Inv return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationRequest type GetBucketLifecycleConfigurationInput struct { _ struct{} `type:"structure"` @@ -9950,7 +10606,7 @@ func (s *GetBucketLifecycleConfigurationInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationOutput type GetBucketLifecycleConfigurationOutput struct { _ struct{} `type:"structure"` @@ -9973,7 +10629,7 @@ func (s *GetBucketLifecycleConfigurationOutput) SetRules(v []*LifecycleRule) *Ge return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleRequest type GetBucketLifecycleInput struct { _ struct{} `type:"structure"` @@ -10017,7 +10673,7 @@ func (s *GetBucketLifecycleInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleOutput type GetBucketLifecycleOutput struct { _ struct{} `type:"structure"` @@ -10040,7 +10696,7 @@ func (s *GetBucketLifecycleOutput) SetRules(v []*Rule) *GetBucketLifecycleOutput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationRequest type GetBucketLocationInput struct { _ struct{} `type:"structure"` @@ -10084,7 +10740,7 @@ func (s *GetBucketLocationInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationOutput type GetBucketLocationOutput struct { _ struct{} `type:"structure"` @@ -10107,7 +10763,7 @@ func (s *GetBucketLocationOutput) SetLocationConstraint(v string) *GetBucketLoca return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingRequest type GetBucketLoggingInput struct { _ struct{} `type:"structure"` @@ -10151,7 +10807,7 @@ func (s *GetBucketLoggingInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingOutput type GetBucketLoggingOutput struct { _ struct{} `type:"structure"` @@ -10174,7 +10830,7 @@ func (s *GetBucketLoggingOutput) SetLoggingEnabled(v *LoggingEnabled) *GetBucket return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfigurationRequest type GetBucketMetricsConfigurationInput struct { _ struct{} `type:"structure"` @@ -10234,7 +10890,7 @@ func (s *GetBucketMetricsConfigurationInput) SetId(v string) *GetBucketMetricsCo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfigurationOutput type GetBucketMetricsConfigurationOutput struct { _ struct{} `type:"structure" payload:"MetricsConfiguration"` @@ -10258,7 +10914,7 @@ func (s *GetBucketMetricsConfigurationOutput) SetMetricsConfiguration(v *Metrics return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfigurationRequest type GetBucketNotificationConfigurationRequest struct { _ struct{} `type:"structure"` @@ -10304,7 +10960,7 @@ func (s *GetBucketNotificationConfigurationRequest) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyRequest type GetBucketPolicyInput struct { _ struct{} `type:"structure"` @@ -10348,7 +11004,7 @@ func (s *GetBucketPolicyInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyOutput type GetBucketPolicyOutput struct { _ struct{} `type:"structure" payload:"Policy"` @@ -10372,7 +11028,7 @@ func (s *GetBucketPolicyOutput) SetPolicy(v string) *GetBucketPolicyOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationRequest type GetBucketReplicationInput struct { _ struct{} `type:"structure"` @@ -10416,7 +11072,7 @@ func (s *GetBucketReplicationInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationOutput type GetBucketReplicationOutput struct { _ struct{} `type:"structure" payload:"ReplicationConfiguration"` @@ -10441,7 +11097,7 @@ func (s *GetBucketReplicationOutput) SetReplicationConfiguration(v *ReplicationC return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentRequest type GetBucketRequestPaymentInput struct { _ struct{} `type:"structure"` @@ -10485,7 +11141,7 @@ func (s *GetBucketRequestPaymentInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentOutput type GetBucketRequestPaymentOutput struct { _ struct{} `type:"structure"` @@ -10509,7 +11165,7 @@ func (s *GetBucketRequestPaymentOutput) SetPayer(v string) *GetBucketRequestPaym return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingRequest type GetBucketTaggingInput struct { _ struct{} `type:"structure"` @@ -10553,7 +11209,7 @@ func (s *GetBucketTaggingInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingOutput type GetBucketTaggingOutput struct { _ struct{} `type:"structure"` @@ -10577,7 +11233,7 @@ func (s *GetBucketTaggingOutput) SetTagSet(v []*Tag) *GetBucketTaggingOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningRequest type GetBucketVersioningInput struct { _ struct{} `type:"structure"` @@ -10621,7 +11277,7 @@ func (s *GetBucketVersioningInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningOutput type GetBucketVersioningOutput struct { _ struct{} `type:"structure"` @@ -10656,7 +11312,7 @@ func (s *GetBucketVersioningOutput) SetStatus(v string) *GetBucketVersioningOutp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteRequest type GetBucketWebsiteInput struct { _ struct{} `type:"structure"` @@ -10700,7 +11356,7 @@ func (s *GetBucketWebsiteInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteOutput type GetBucketWebsiteOutput struct { _ struct{} `type:"structure"` @@ -10747,7 +11403,7 @@ func (s *GetBucketWebsiteOutput) SetRoutingRules(v []*RoutingRule) *GetBucketWeb return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAclRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAclRequest type GetObjectAclInput struct { _ struct{} `type:"structure"` @@ -10827,7 +11483,7 @@ func (s *GetObjectAclInput) SetVersionId(v string) *GetObjectAclInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAclOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAclOutput type GetObjectAclOutput struct { _ struct{} `type:"structure"` @@ -10869,7 +11525,7 @@ func (s *GetObjectAclOutput) SetRequestCharged(v string) *GetObjectAclOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectRequest type GetObjectInput struct { _ struct{} `type:"structure"` @@ -11104,7 +11760,7 @@ func (s *GetObjectInput) SetVersionId(v string) *GetObjectInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectOutput type GetObjectOutput struct { _ struct{} `type:"structure" payload:"Body"` @@ -11388,7 +12044,7 @@ func (s *GetObjectOutput) SetWebsiteRedirectLocation(v string) *GetObjectOutput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTaggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTaggingRequest type GetObjectTaggingInput struct { _ struct{} `type:"structure"` @@ -11455,7 +12111,7 @@ func (s *GetObjectTaggingInput) SetVersionId(v string) *GetObjectTaggingInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTaggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTaggingOutput type GetObjectTaggingOutput struct { _ struct{} `type:"structure"` @@ -11487,7 +12143,7 @@ func (s *GetObjectTaggingOutput) SetVersionId(v string) *GetObjectTaggingOutput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrentRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrentRequest type GetObjectTorrentInput struct { _ struct{} `type:"structure"` @@ -11558,7 +12214,7 @@ func (s *GetObjectTorrentInput) SetRequestPayer(v string) *GetObjectTorrentInput return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrentOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrentOutput type GetObjectTorrentOutput struct { _ struct{} `type:"structure" payload:"Body"` @@ -11591,7 +12247,7 @@ func (s *GetObjectTorrentOutput) SetRequestCharged(v string) *GetObjectTorrentOu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GlacierJobParameters +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GlacierJobParameters type GlacierJobParameters struct { _ struct{} `type:"structure"` @@ -11630,7 +12286,7 @@ func (s *GlacierJobParameters) SetTier(v string) *GlacierJobParameters { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Grant +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Grant type Grant struct { _ struct{} `type:"structure"` @@ -11677,7 +12333,7 @@ func (s *Grant) SetPermission(v string) *Grant { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Grantee +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Grantee type Grantee struct { _ struct{} `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"` @@ -11752,7 +12408,7 @@ func (s *Grantee) SetURI(v string) *Grantee { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketRequest type HeadBucketInput struct { _ struct{} `type:"structure"` @@ -11796,7 +12452,7 @@ func (s *HeadBucketInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketOutput type HeadBucketOutput struct { _ struct{} `type:"structure"` } @@ -11811,7 +12467,7 @@ func (s HeadBucketOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObjectRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObjectRequest type HeadObjectInput struct { _ struct{} `type:"structure"` @@ -11993,7 +12649,7 @@ func (s *HeadObjectInput) SetVersionId(v string) *HeadObjectInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObjectOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObjectOutput type HeadObjectOutput struct { _ struct{} `type:"structure"` @@ -12250,7 +12906,7 @@ func (s *HeadObjectOutput) SetWebsiteRedirectLocation(v string) *HeadObjectOutpu return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/IndexDocument +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/IndexDocument type IndexDocument struct { _ struct{} `type:"structure"` @@ -12292,7 +12948,7 @@ func (s *IndexDocument) SetSuffix(v string) *IndexDocument { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Initiator +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Initiator type Initiator struct { _ struct{} `type:"structure"` @@ -12326,7 +12982,32 @@ func (s *Initiator) SetID(v string) *Initiator { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryConfiguration +// Describes the serialization format of the object. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InputSerialization +type InputSerialization struct { + _ struct{} `type:"structure"` + + // Describes the serialization of a CSV-encoded object. + CSV *CSVInput `type:"structure"` +} + +// String returns the string representation +func (s InputSerialization) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InputSerialization) GoString() string { + return s.String() +} + +// SetCSV sets the CSV field's value. +func (s *InputSerialization) SetCSV(v *CSVInput) *InputSerialization { + s.CSV = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryConfiguration type InventoryConfiguration struct { _ struct{} `type:"structure"` @@ -12455,7 +13136,7 @@ func (s *InventoryConfiguration) SetSchedule(v *InventorySchedule) *InventoryCon return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryDestination +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryDestination type InventoryDestination struct { _ struct{} `type:"structure"` @@ -12500,7 +13181,57 @@ func (s *InventoryDestination) SetS3BucketDestination(v *InventoryS3BucketDestin return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryFilter +// Contains the type of server-side encryption used to encrypt the inventory +// results. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryEncryption +type InventoryEncryption struct { + _ struct{} `type:"structure"` + + // Specifies the use of SSE-KMS to encrypt delievered Inventory reports. + SSEKMS *SSEKMS `locationName:"SSE-KMS" type:"structure"` + + // Specifies the use of SSE-S3 to encrypt delievered Inventory reports. + SSES3 *SSES3 `locationName:"SSE-S3" type:"structure"` +} + +// String returns the string representation +func (s InventoryEncryption) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InventoryEncryption) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *InventoryEncryption) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "InventoryEncryption"} + if s.SSEKMS != nil { + if err := s.SSEKMS.Validate(); err != nil { + invalidParams.AddNested("SSEKMS", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSSEKMS sets the SSEKMS field's value. +func (s *InventoryEncryption) SetSSEKMS(v *SSEKMS) *InventoryEncryption { + s.SSEKMS = v + return s +} + +// SetSSES3 sets the SSES3 field's value. +func (s *InventoryEncryption) SetSSES3(v *SSES3) *InventoryEncryption { + s.SSES3 = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryFilter type InventoryFilter struct { _ struct{} `type:"structure"` @@ -12539,7 +13270,7 @@ func (s *InventoryFilter) SetPrefix(v string) *InventoryFilter { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryS3BucketDestination +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryS3BucketDestination type InventoryS3BucketDestination struct { _ struct{} `type:"structure"` @@ -12552,6 +13283,10 @@ type InventoryS3BucketDestination struct { // Bucket is a required field Bucket *string `type:"string" required:"true"` + // Contains the type of server-side encryption used to encrypt the inventory + // results. + Encryption *InventoryEncryption `type:"structure"` + // Specifies the output format of the inventory results. // // Format is a required field @@ -12580,6 +13315,11 @@ func (s *InventoryS3BucketDestination) Validate() error { if s.Format == nil { invalidParams.Add(request.NewErrParamRequired("Format")) } + if s.Encryption != nil { + if err := s.Encryption.Validate(); err != nil { + invalidParams.AddNested("Encryption", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -12606,6 +13346,12 @@ func (s *InventoryS3BucketDestination) getBucket() (v string) { return *s.Bucket } +// SetEncryption sets the Encryption field's value. +func (s *InventoryS3BucketDestination) SetEncryption(v *InventoryEncryption) *InventoryS3BucketDestination { + s.Encryption = v + return s +} + // SetFormat sets the Format field's value. func (s *InventoryS3BucketDestination) SetFormat(v string) *InventoryS3BucketDestination { s.Format = &v @@ -12618,7 +13364,7 @@ func (s *InventoryS3BucketDestination) SetPrefix(v string) *InventoryS3BucketDes return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventorySchedule +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventorySchedule type InventorySchedule struct { _ struct{} `type:"structure"` @@ -12658,7 +13404,7 @@ func (s *InventorySchedule) SetFrequency(v string) *InventorySchedule { } // Container for object key name prefix and suffix filtering rules. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/S3KeyFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/S3KeyFilter type KeyFilter struct { _ struct{} `type:"structure"` @@ -12684,7 +13430,7 @@ func (s *KeyFilter) SetFilterRules(v []*FilterRule) *KeyFilter { } // Container for specifying the AWS Lambda notification configuration. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LambdaFunctionConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LambdaFunctionConfiguration type LambdaFunctionConfiguration struct { _ struct{} `type:"structure"` @@ -12756,7 +13502,7 @@ func (s *LambdaFunctionConfiguration) SetLambdaFunctionArn(v string) *LambdaFunc return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleConfiguration type LifecycleConfiguration struct { _ struct{} `type:"structure"` @@ -12803,7 +13549,7 @@ func (s *LifecycleConfiguration) SetRules(v []*Rule) *LifecycleConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleExpiration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleExpiration type LifecycleExpiration struct { _ struct{} `type:"structure"` @@ -12850,7 +13596,7 @@ func (s *LifecycleExpiration) SetExpiredObjectDeleteMarker(v bool) *LifecycleExp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRule +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRule type LifecycleRule struct { _ struct{} `type:"structure"` @@ -12974,7 +13720,7 @@ func (s *LifecycleRule) SetTransitions(v []*Transition) *LifecycleRule { // This is used in a Lifecycle Rule Filter to apply a logical AND to two or // more predicates. The Lifecycle Rule will apply to any object matching all // of the predicates configured inside the And operator. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRuleAndOperator +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRuleAndOperator type LifecycleRuleAndOperator struct { _ struct{} `type:"structure"` @@ -13029,7 +13775,7 @@ func (s *LifecycleRuleAndOperator) SetTags(v []*Tag) *LifecycleRuleAndOperator { // The Filter is used to identify objects that a Lifecycle Rule applies to. // A Filter must have exactly one of Prefix, Tag, or And specified. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRuleFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRuleFilter type LifecycleRuleFilter struct { _ struct{} `type:"structure"` @@ -13093,7 +13839,7 @@ func (s *LifecycleRuleFilter) SetTag(v *Tag) *LifecycleRuleFilter { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurationsRequest type ListBucketAnalyticsConfigurationsInput struct { _ struct{} `type:"structure"` @@ -13149,7 +13895,7 @@ func (s *ListBucketAnalyticsConfigurationsInput) SetContinuationToken(v string) return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurationsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurationsOutput type ListBucketAnalyticsConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -13204,7 +13950,7 @@ func (s *ListBucketAnalyticsConfigurationsOutput) SetNextContinuationToken(v str return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurationsRequest type ListBucketInventoryConfigurationsInput struct { _ struct{} `type:"structure"` @@ -13262,7 +14008,7 @@ func (s *ListBucketInventoryConfigurationsInput) SetContinuationToken(v string) return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurationsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurationsOutput type ListBucketInventoryConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -13317,7 +14063,7 @@ func (s *ListBucketInventoryConfigurationsOutput) SetNextContinuationToken(v str return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurationsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurationsRequest type ListBucketMetricsConfigurationsInput struct { _ struct{} `type:"structure"` @@ -13375,7 +14121,7 @@ func (s *ListBucketMetricsConfigurationsInput) SetContinuationToken(v string) *L return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurationsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurationsOutput type ListBucketMetricsConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -13432,7 +14178,7 @@ func (s *ListBucketMetricsConfigurationsOutput) SetNextContinuationToken(v strin return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketsInput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketsInput type ListBucketsInput struct { _ struct{} `type:"structure"` } @@ -13447,7 +14193,7 @@ func (s ListBucketsInput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketsOutput type ListBucketsOutput struct { _ struct{} `type:"structure"` @@ -13478,7 +14224,7 @@ func (s *ListBucketsOutput) SetOwner(v *Owner) *ListBucketsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploadsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploadsRequest type ListMultipartUploadsInput struct { _ struct{} `type:"structure"` @@ -13587,7 +14333,7 @@ func (s *ListMultipartUploadsInput) SetUploadIdMarker(v string) *ListMultipartUp return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploadsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploadsOutput type ListMultipartUploadsOutput struct { _ struct{} `type:"structure"` @@ -13721,7 +14467,7 @@ func (s *ListMultipartUploadsOutput) SetUploads(v []*MultipartUpload) *ListMulti return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersionsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersionsRequest type ListObjectVersionsInput struct { _ struct{} `type:"structure"` @@ -13825,7 +14571,7 @@ func (s *ListObjectVersionsInput) SetVersionIdMarker(v string) *ListObjectVersio return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersionsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersionsOutput type ListObjectVersionsOutput struct { _ struct{} `type:"structure"` @@ -13953,7 +14699,7 @@ func (s *ListObjectVersionsOutput) SetVersions(v []*ObjectVersion) *ListObjectVe return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsRequest type ListObjectsInput struct { _ struct{} `type:"structure"` @@ -14059,7 +14805,7 @@ func (s *ListObjectsInput) SetRequestPayer(v string) *ListObjectsInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsOutput type ListObjectsOutput struct { _ struct{} `type:"structure"` @@ -14164,7 +14910,7 @@ func (s *ListObjectsOutput) SetPrefix(v string) *ListObjectsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2Request +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2Request type ListObjectsV2Input struct { _ struct{} `type:"structure"` @@ -14290,7 +15036,7 @@ func (s *ListObjectsV2Input) SetStartAfter(v string) *ListObjectsV2Input { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2Output +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2Output type ListObjectsV2Output struct { _ struct{} `type:"structure"` @@ -14424,7 +15170,7 @@ func (s *ListObjectsV2Output) SetStartAfter(v string) *ListObjectsV2Output { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListPartsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListPartsRequest type ListPartsInput struct { _ struct{} `type:"structure"` @@ -14528,7 +15274,7 @@ func (s *ListPartsInput) SetUploadId(v string) *ListPartsInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListPartsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListPartsOutput type ListPartsOutput struct { _ struct{} `type:"structure"` @@ -14678,7 +15424,136 @@ func (s *ListPartsOutput) SetUploadId(v string) *ListPartsOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LoggingEnabled +// Describes an S3 location that will receive the results of the restore request. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/S3Location +type Location struct { + _ struct{} `type:"structure"` + + // A list of grants that control access to the staged results. + AccessControlList []*Grant `locationNameList:"Grant" type:"list"` + + // The name of the bucket where the restore results will be placed. + // + // BucketName is a required field + BucketName *string `type:"string" required:"true"` + + // The canned ACL to apply to the restore results. + CannedACL *string `type:"string" enum:"ObjectCannedACL"` + + // Describes the server-side encryption that will be applied to the restore + // results. + Encryption *Encryption `type:"structure"` + + // The prefix that is prepended to the restore results for this request. + // + // Prefix is a required field + Prefix *string `type:"string" required:"true"` + + // The class of storage used to store the restore results. + StorageClass *string `type:"string" enum:"StorageClass"` + + // The tag-set that is applied to the restore results. + Tagging *Tagging `type:"structure"` + + // A list of metadata to store with the restore results in S3. + UserMetadata []*MetadataEntry `locationNameList:"MetadataEntry" type:"list"` +} + +// String returns the string representation +func (s Location) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Location) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Location) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Location"} + if s.BucketName == nil { + invalidParams.Add(request.NewErrParamRequired("BucketName")) + } + if s.Prefix == nil { + invalidParams.Add(request.NewErrParamRequired("Prefix")) + } + if s.AccessControlList != nil { + for i, v := range s.AccessControlList { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "AccessControlList", i), err.(request.ErrInvalidParams)) + } + } + } + if s.Encryption != nil { + if err := s.Encryption.Validate(); err != nil { + invalidParams.AddNested("Encryption", err.(request.ErrInvalidParams)) + } + } + if s.Tagging != nil { + if err := s.Tagging.Validate(); err != nil { + invalidParams.AddNested("Tagging", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAccessControlList sets the AccessControlList field's value. +func (s *Location) SetAccessControlList(v []*Grant) *Location { + s.AccessControlList = v + return s +} + +// SetBucketName sets the BucketName field's value. +func (s *Location) SetBucketName(v string) *Location { + s.BucketName = &v + return s +} + +// SetCannedACL sets the CannedACL field's value. +func (s *Location) SetCannedACL(v string) *Location { + s.CannedACL = &v + return s +} + +// SetEncryption sets the Encryption field's value. +func (s *Location) SetEncryption(v *Encryption) *Location { + s.Encryption = v + return s +} + +// SetPrefix sets the Prefix field's value. +func (s *Location) SetPrefix(v string) *Location { + s.Prefix = &v + return s +} + +// SetStorageClass sets the StorageClass field's value. +func (s *Location) SetStorageClass(v string) *Location { + s.StorageClass = &v + return s +} + +// SetTagging sets the Tagging field's value. +func (s *Location) SetTagging(v *Tagging) *Location { + s.Tagging = v + return s +} + +// SetUserMetadata sets the UserMetadata field's value. +func (s *Location) SetUserMetadata(v []*MetadataEntry) *Location { + s.UserMetadata = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LoggingEnabled type LoggingEnabled struct { _ struct{} `type:"structure"` @@ -14745,7 +15620,39 @@ func (s *LoggingEnabled) SetTargetPrefix(v string) *LoggingEnabled { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsAndOperator +// A metadata key-value pair to store with an object. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetadataEntry +type MetadataEntry struct { + _ struct{} `type:"structure"` + + Name *string `type:"string"` + + Value *string `type:"string"` +} + +// String returns the string representation +func (s MetadataEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetadataEntry) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *MetadataEntry) SetName(v string) *MetadataEntry { + s.Name = &v + return s +} + +// SetValue sets the Value field's value. +func (s *MetadataEntry) SetValue(v string) *MetadataEntry { + s.Value = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsAndOperator type MetricsAndOperator struct { _ struct{} `type:"structure"` @@ -14798,7 +15705,7 @@ func (s *MetricsAndOperator) SetTags(v []*Tag) *MetricsAndOperator { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsConfiguration type MetricsConfiguration struct { _ struct{} `type:"structure"` @@ -14853,7 +15760,7 @@ func (s *MetricsConfiguration) SetId(v string) *MetricsConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsFilter type MetricsFilter struct { _ struct{} `type:"structure"` @@ -14917,7 +15824,7 @@ func (s *MetricsFilter) SetTag(v *Tag) *MetricsFilter { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MultipartUpload +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MultipartUpload type MultipartUpload struct { _ struct{} `type:"structure"` @@ -14990,7 +15897,7 @@ func (s *MultipartUpload) SetUploadId(v string) *MultipartUpload { // configuration action on a bucket that has versioning enabled (or suspended) // to request that Amazon S3 delete noncurrent object versions at a specific // period in the object's lifetime. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NoncurrentVersionExpiration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NoncurrentVersionExpiration type NoncurrentVersionExpiration struct { _ struct{} `type:"structure"` @@ -15022,7 +15929,7 @@ func (s *NoncurrentVersionExpiration) SetNoncurrentDays(v int64) *NoncurrentVers // versioning-enabled (or versioning is suspended), you can set this action // to request that Amazon S3 transition noncurrent object versions to the STANDARD_IA // or GLACIER storage class at a specific period in the object's lifetime. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NoncurrentVersionTransition +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NoncurrentVersionTransition type NoncurrentVersionTransition struct { _ struct{} `type:"structure"` @@ -15060,7 +15967,7 @@ func (s *NoncurrentVersionTransition) SetStorageClass(v string) *NoncurrentVersi // Container for specifying the notification configuration of the bucket. If // this element is empty, notifications are turned off on the bucket. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfiguration type NotificationConfiguration struct { _ struct{} `type:"structure"` @@ -15139,7 +16046,7 @@ func (s *NotificationConfiguration) SetTopicConfigurations(v []*TopicConfigurati return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfigurationDeprecated +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfigurationDeprecated type NotificationConfigurationDeprecated struct { _ struct{} `type:"structure"` @@ -15180,7 +16087,7 @@ func (s *NotificationConfigurationDeprecated) SetTopicConfiguration(v *TopicConf // Container for object key name filtering rules. For information about key // name filtering, go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfigurationFilter +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfigurationFilter type NotificationConfigurationFilter struct { _ struct{} `type:"structure"` @@ -15204,7 +16111,7 @@ func (s *NotificationConfigurationFilter) SetKey(v *KeyFilter) *NotificationConf return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Object +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Object type Object struct { _ struct{} `type:"structure"` @@ -15268,7 +16175,7 @@ func (s *Object) SetStorageClass(v string) *Object { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ObjectIdentifier +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ObjectIdentifier type ObjectIdentifier struct { _ struct{} `type:"structure"` @@ -15319,7 +16226,7 @@ func (s *ObjectIdentifier) SetVersionId(v string) *ObjectIdentifier { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ObjectVersion +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ObjectVersion type ObjectVersion struct { _ struct{} `type:"structure"` @@ -15405,7 +16312,72 @@ func (s *ObjectVersion) SetVersionId(v string) *ObjectVersion { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Owner +// Describes the location where the restore job's output is stored. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/OutputLocation +type OutputLocation struct { + _ struct{} `type:"structure"` + + // Describes an S3 location that will receive the results of the restore request. + S3 *Location `type:"structure"` +} + +// String returns the string representation +func (s OutputLocation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s OutputLocation) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *OutputLocation) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "OutputLocation"} + if s.S3 != nil { + if err := s.S3.Validate(); err != nil { + invalidParams.AddNested("S3", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetS3 sets the S3 field's value. +func (s *OutputLocation) SetS3(v *Location) *OutputLocation { + s.S3 = v + return s +} + +// Describes how results of the Select job are serialized. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/OutputSerialization +type OutputSerialization struct { + _ struct{} `type:"structure"` + + // Describes the serialization of CSV-encoded Select results. + CSV *CSVOutput `type:"structure"` +} + +// String returns the string representation +func (s OutputSerialization) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s OutputSerialization) GoString() string { + return s.String() +} + +// SetCSV sets the CSV field's value. +func (s *OutputSerialization) SetCSV(v *CSVOutput) *OutputSerialization { + s.CSV = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Owner type Owner struct { _ struct{} `type:"structure"` @@ -15436,7 +16408,7 @@ func (s *Owner) SetID(v string) *Owner { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Part +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Part type Part struct { _ struct{} `type:"structure"` @@ -15488,7 +16460,7 @@ func (s *Part) SetSize(v int64) *Part { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationRequest type PutBucketAccelerateConfigurationInput struct { _ struct{} `type:"structure" payload:"AccelerateConfiguration"` @@ -15548,7 +16520,7 @@ func (s *PutBucketAccelerateConfigurationInput) getBucket() (v string) { return *s.Bucket } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationOutput type PutBucketAccelerateConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -15563,7 +16535,7 @@ func (s PutBucketAccelerateConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAclRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAclRequest type PutBucketAclInput struct { _ struct{} `type:"structure" payload:"AccessControlPolicy"` @@ -15675,7 +16647,7 @@ func (s *PutBucketAclInput) SetGrantWriteACP(v string) *PutBucketAclInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAclOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAclOutput type PutBucketAclOutput struct { _ struct{} `type:"structure"` } @@ -15690,7 +16662,7 @@ func (s PutBucketAclOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfigurationRequest type PutBucketAnalyticsConfigurationInput struct { _ struct{} `type:"structure" payload:"AnalyticsConfiguration"` @@ -15769,7 +16741,7 @@ func (s *PutBucketAnalyticsConfigurationInput) SetId(v string) *PutBucketAnalyti return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfigurationOutput type PutBucketAnalyticsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -15784,7 +16756,7 @@ func (s PutBucketAnalyticsConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCorsRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCorsRequest type PutBucketCorsInput struct { _ struct{} `type:"structure" payload:"CORSConfiguration"` @@ -15845,7 +16817,7 @@ func (s *PutBucketCorsInput) SetCORSConfiguration(v *CORSConfiguration) *PutBuck return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCorsOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCorsOutput type PutBucketCorsOutput struct { _ struct{} `type:"structure"` } @@ -15860,7 +16832,89 @@ func (s PutBucketCorsOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryptionRequest +type PutBucketEncryptionInput struct { + _ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"` + + // The name of the bucket for which the server-side encryption configuration + // is set. + // + // Bucket is a required field + Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + + // Container for server-side encryption configuration rules. Currently S3 supports + // one rule only. + // + // ServerSideEncryptionConfiguration is a required field + ServerSideEncryptionConfiguration *ServerSideEncryptionConfiguration `locationName:"ServerSideEncryptionConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` +} + +// String returns the string representation +func (s PutBucketEncryptionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutBucketEncryptionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutBucketEncryptionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutBucketEncryptionInput"} + if s.Bucket == nil { + invalidParams.Add(request.NewErrParamRequired("Bucket")) + } + if s.ServerSideEncryptionConfiguration == nil { + invalidParams.Add(request.NewErrParamRequired("ServerSideEncryptionConfiguration")) + } + if s.ServerSideEncryptionConfiguration != nil { + if err := s.ServerSideEncryptionConfiguration.Validate(); err != nil { + invalidParams.AddNested("ServerSideEncryptionConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBucket sets the Bucket field's value. +func (s *PutBucketEncryptionInput) SetBucket(v string) *PutBucketEncryptionInput { + s.Bucket = &v + return s +} + +func (s *PutBucketEncryptionInput) getBucket() (v string) { + if s.Bucket == nil { + return v + } + return *s.Bucket +} + +// SetServerSideEncryptionConfiguration sets the ServerSideEncryptionConfiguration field's value. +func (s *PutBucketEncryptionInput) SetServerSideEncryptionConfiguration(v *ServerSideEncryptionConfiguration) *PutBucketEncryptionInput { + s.ServerSideEncryptionConfiguration = v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryptionOutput +type PutBucketEncryptionOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s PutBucketEncryptionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutBucketEncryptionOutput) GoString() string { + return s.String() +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfigurationRequest type PutBucketInventoryConfigurationInput struct { _ struct{} `type:"structure" payload:"InventoryConfiguration"` @@ -15939,7 +16993,7 @@ func (s *PutBucketInventoryConfigurationInput) SetInventoryConfiguration(v *Inve return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfigurationOutput type PutBucketInventoryConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -15954,7 +17008,7 @@ func (s PutBucketInventoryConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfigurationRequest type PutBucketLifecycleConfigurationInput struct { _ struct{} `type:"structure" payload:"LifecycleConfiguration"` @@ -16011,7 +17065,7 @@ func (s *PutBucketLifecycleConfigurationInput) SetLifecycleConfiguration(v *Buck return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfigurationOutput type PutBucketLifecycleConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -16026,7 +17080,7 @@ func (s PutBucketLifecycleConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleRequest type PutBucketLifecycleInput struct { _ struct{} `type:"structure" payload:"LifecycleConfiguration"` @@ -16083,7 +17137,7 @@ func (s *PutBucketLifecycleInput) SetLifecycleConfiguration(v *LifecycleConfigur return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleOutput type PutBucketLifecycleOutput struct { _ struct{} `type:"structure"` } @@ -16098,7 +17152,7 @@ func (s PutBucketLifecycleOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLoggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLoggingRequest type PutBucketLoggingInput struct { _ struct{} `type:"structure" payload:"BucketLoggingStatus"` @@ -16159,7 +17213,7 @@ func (s *PutBucketLoggingInput) SetBucketLoggingStatus(v *BucketLoggingStatus) * return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLoggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLoggingOutput type PutBucketLoggingOutput struct { _ struct{} `type:"structure"` } @@ -16174,7 +17228,7 @@ func (s PutBucketLoggingOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfigurationRequest type PutBucketMetricsConfigurationInput struct { _ struct{} `type:"structure" payload:"MetricsConfiguration"` @@ -16253,7 +17307,7 @@ func (s *PutBucketMetricsConfigurationInput) SetMetricsConfiguration(v *MetricsC return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfigurationOutput type PutBucketMetricsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -16268,7 +17322,7 @@ func (s PutBucketMetricsConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfigurationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfigurationRequest type PutBucketNotificationConfigurationInput struct { _ struct{} `type:"structure" payload:"NotificationConfiguration"` @@ -16332,7 +17386,7 @@ func (s *PutBucketNotificationConfigurationInput) SetNotificationConfiguration(v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfigurationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfigurationOutput type PutBucketNotificationConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -16347,7 +17401,7 @@ func (s PutBucketNotificationConfigurationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationRequest type PutBucketNotificationInput struct { _ struct{} `type:"structure" payload:"NotificationConfiguration"` @@ -16403,7 +17457,7 @@ func (s *PutBucketNotificationInput) SetNotificationConfiguration(v *Notificatio return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationOutput type PutBucketNotificationOutput struct { _ struct{} `type:"structure"` } @@ -16418,13 +17472,17 @@ func (s PutBucketNotificationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicyRequest type PutBucketPolicyInput struct { _ struct{} `type:"structure" payload:"Policy"` // Bucket is a required field Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"` + // Set this parameter to true to confirm that you want to remove your permissions + // to change this bucket policy in the future. + ConfirmRemoveSelfBucketAccess *bool `location:"header" locationName:"x-amz-confirm-remove-self-bucket-access" type:"boolean"` + // The bucket policy as a JSON document. // // Policy is a required field @@ -16470,13 +17528,19 @@ func (s *PutBucketPolicyInput) getBucket() (v string) { return *s.Bucket } +// SetConfirmRemoveSelfBucketAccess sets the ConfirmRemoveSelfBucketAccess field's value. +func (s *PutBucketPolicyInput) SetConfirmRemoveSelfBucketAccess(v bool) *PutBucketPolicyInput { + s.ConfirmRemoveSelfBucketAccess = &v + return s +} + // SetPolicy sets the Policy field's value. func (s *PutBucketPolicyInput) SetPolicy(v string) *PutBucketPolicyInput { s.Policy = &v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicyOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicyOutput type PutBucketPolicyOutput struct { _ struct{} `type:"structure"` } @@ -16491,7 +17555,7 @@ func (s PutBucketPolicyOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplicationRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplicationRequest type PutBucketReplicationInput struct { _ struct{} `type:"structure" payload:"ReplicationConfiguration"` @@ -16555,7 +17619,7 @@ func (s *PutBucketReplicationInput) SetReplicationConfiguration(v *ReplicationCo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplicationOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplicationOutput type PutBucketReplicationOutput struct { _ struct{} `type:"structure"` } @@ -16570,7 +17634,7 @@ func (s PutBucketReplicationOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPaymentRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPaymentRequest type PutBucketRequestPaymentInput struct { _ struct{} `type:"structure" payload:"RequestPaymentConfiguration"` @@ -16631,7 +17695,7 @@ func (s *PutBucketRequestPaymentInput) SetRequestPaymentConfiguration(v *Request return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPaymentOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPaymentOutput type PutBucketRequestPaymentOutput struct { _ struct{} `type:"structure"` } @@ -16646,7 +17710,7 @@ func (s PutBucketRequestPaymentOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTaggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTaggingRequest type PutBucketTaggingInput struct { _ struct{} `type:"structure" payload:"Tagging"` @@ -16707,7 +17771,7 @@ func (s *PutBucketTaggingInput) SetTagging(v *Tagging) *PutBucketTaggingInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTaggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTaggingOutput type PutBucketTaggingOutput struct { _ struct{} `type:"structure"` } @@ -16722,7 +17786,7 @@ func (s PutBucketTaggingOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioningRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioningRequest type PutBucketVersioningInput struct { _ struct{} `type:"structure" payload:"VersioningConfiguration"` @@ -16788,7 +17852,7 @@ func (s *PutBucketVersioningInput) SetVersioningConfiguration(v *VersioningConfi return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioningOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioningOutput type PutBucketVersioningOutput struct { _ struct{} `type:"structure"` } @@ -16803,7 +17867,7 @@ func (s PutBucketVersioningOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsiteRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsiteRequest type PutBucketWebsiteInput struct { _ struct{} `type:"structure" payload:"WebsiteConfiguration"` @@ -16864,7 +17928,7 @@ func (s *PutBucketWebsiteInput) SetWebsiteConfiguration(v *WebsiteConfiguration) return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsiteOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsiteOutput type PutBucketWebsiteOutput struct { _ struct{} `type:"structure"` } @@ -16879,7 +17943,7 @@ func (s PutBucketWebsiteOutput) GoString() string { return s.String() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAclRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAclRequest type PutObjectAclInput struct { _ struct{} `type:"structure" payload:"AccessControlPolicy"` @@ -17027,7 +18091,7 @@ func (s *PutObjectAclInput) SetVersionId(v string) *PutObjectAclInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAclOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAclOutput type PutObjectAclOutput struct { _ struct{} `type:"structure"` @@ -17052,7 +18116,7 @@ func (s *PutObjectAclOutput) SetRequestCharged(v string) *PutObjectAclOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectRequest type PutObjectInput struct { _ struct{} `type:"structure" payload:"Body"` @@ -17085,6 +18149,9 @@ type PutObjectInput struct { // body cannot be determined automatically. ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"` + // The base64-encoded 128-bit MD5 digest of the part data. + ContentMD5 *string `location:"header" locationName:"Content-MD5" type:"string"` + // A standard MIME type describing the format of the object data. ContentType *string `location:"header" locationName:"Content-Type" type:"string"` @@ -17238,6 +18305,12 @@ func (s *PutObjectInput) SetContentLength(v int64) *PutObjectInput { return s } +// SetContentMD5 sets the ContentMD5 field's value. +func (s *PutObjectInput) SetContentMD5(v string) *PutObjectInput { + s.ContentMD5 = &v + return s +} + // SetContentType sets the ContentType field's value. func (s *PutObjectInput) SetContentType(v string) *PutObjectInput { s.ContentType = &v @@ -17347,7 +18420,7 @@ func (s *PutObjectInput) SetWebsiteRedirectLocation(v string) *PutObjectInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectOutput type PutObjectOutput struct { _ struct{} `type:"structure"` @@ -17442,7 +18515,7 @@ func (s *PutObjectOutput) SetVersionId(v string) *PutObjectOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTaggingRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTaggingRequest type PutObjectTaggingInput struct { _ struct{} `type:"structure" payload:"Tagging"` @@ -17526,7 +18599,7 @@ func (s *PutObjectTaggingInput) SetVersionId(v string) *PutObjectTaggingInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTaggingOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTaggingOutput type PutObjectTaggingOutput struct { _ struct{} `type:"structure"` @@ -17551,7 +18624,7 @@ func (s *PutObjectTaggingOutput) SetVersionId(v string) *PutObjectTaggingOutput // Container for specifying an configuration when you want Amazon S3 to publish // events to an Amazon Simple Queue Service (Amazon SQS) queue. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/QueueConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/QueueConfiguration type QueueConfiguration struct { _ struct{} `type:"structure"` @@ -17623,7 +18696,7 @@ func (s *QueueConfiguration) SetQueueArn(v string) *QueueConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/QueueConfigurationDeprecated +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/QueueConfigurationDeprecated type QueueConfigurationDeprecated struct { _ struct{} `type:"structure"` @@ -17673,7 +18746,7 @@ func (s *QueueConfigurationDeprecated) SetQueue(v string) *QueueConfigurationDep return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Redirect +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Redirect type Redirect struct { _ struct{} `type:"structure"` @@ -17742,7 +18815,7 @@ func (s *Redirect) SetReplaceKeyWith(v string) *Redirect { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RedirectAllRequestsTo +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RedirectAllRequestsTo type RedirectAllRequestsTo struct { _ struct{} `type:"structure"` @@ -17793,7 +18866,7 @@ func (s *RedirectAllRequestsTo) SetProtocol(v string) *RedirectAllRequestsTo { // Container for replication rules. You can add as many as 1,000 rules. Total // replication configuration size can be up to 2 MB. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ReplicationConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ReplicationConfiguration type ReplicationConfiguration struct { _ struct{} `type:"structure"` @@ -17858,10 +18931,13 @@ func (s *ReplicationConfiguration) SetRules(v []*ReplicationRule) *ReplicationCo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ReplicationRule +// Container for information about a particular replication rule. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ReplicationRule type ReplicationRule struct { _ struct{} `type:"structure"` + // Container for replication destination information. + // // Destination is a required field Destination *Destination `type:"structure" required:"true"` @@ -17875,6 +18951,9 @@ type ReplicationRule struct { // Prefix is a required field Prefix *string `type:"string" required:"true"` + // Container for filters that define which source objects should be replicated. + SourceSelectionCriteria *SourceSelectionCriteria `type:"structure"` + // The rule is ignored if status is not Enabled. // // Status is a required field @@ -17908,6 +18987,11 @@ func (s *ReplicationRule) Validate() error { invalidParams.AddNested("Destination", err.(request.ErrInvalidParams)) } } + if s.SourceSelectionCriteria != nil { + if err := s.SourceSelectionCriteria.Validate(); err != nil { + invalidParams.AddNested("SourceSelectionCriteria", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -17933,13 +19017,19 @@ func (s *ReplicationRule) SetPrefix(v string) *ReplicationRule { return s } +// SetSourceSelectionCriteria sets the SourceSelectionCriteria field's value. +func (s *ReplicationRule) SetSourceSelectionCriteria(v *SourceSelectionCriteria) *ReplicationRule { + s.SourceSelectionCriteria = v + return s +} + // SetStatus sets the Status field's value. func (s *ReplicationRule) SetStatus(v string) *ReplicationRule { s.Status = &v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RequestPaymentConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RequestPaymentConfiguration type RequestPaymentConfiguration struct { _ struct{} `type:"structure"` @@ -17978,7 +19068,7 @@ func (s *RequestPaymentConfiguration) SetPayer(v string) *RequestPaymentConfigur return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObjectRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObjectRequest type RestoreObjectInput struct { _ struct{} `type:"structure" payload:"RestoreRequest"` @@ -17994,6 +19084,7 @@ type RestoreObjectInput struct { // at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"` + // Container for restore job parameters. RestoreRequest *RestoreRequest `locationName:"RestoreRequest" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"` VersionId *string `location:"querystring" locationName:"versionId" type:"string"` @@ -18070,13 +19161,17 @@ func (s *RestoreObjectInput) SetVersionId(v string) *RestoreObjectInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObjectOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObjectOutput type RestoreObjectOutput struct { _ struct{} `type:"structure"` // If present, indicates that the requester was successfully charged for the // request. RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"` + + // Indicates the path in the provided S3 output location where Select results + // will be restored to. + RestoreOutputPath *string `location:"header" locationName:"x-amz-restore-output-path" type:"string"` } // String returns the string representation @@ -18095,17 +19190,39 @@ func (s *RestoreObjectOutput) SetRequestCharged(v string) *RestoreObjectOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreRequest +// SetRestoreOutputPath sets the RestoreOutputPath field's value. +func (s *RestoreObjectOutput) SetRestoreOutputPath(v string) *RestoreObjectOutput { + s.RestoreOutputPath = &v + return s +} + +// Container for restore job parameters. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreRequest type RestoreRequest struct { _ struct{} `type:"structure"` - // Lifetime of the active copy in days - // - // Days is a required field - Days *int64 `type:"integer" required:"true"` + // Lifetime of the active copy in days. Do not use with restores that specify + // OutputLocation. + Days *int64 `type:"integer"` - // Glacier related prameters pertaining to this job. + // The optional description for the job. + Description *string `type:"string"` + + // Glacier related parameters pertaining to this job. Do not use with restores + // that specify OutputLocation. GlacierJobParameters *GlacierJobParameters `type:"structure"` + + // Describes the location where the restore job's output is stored. + OutputLocation *OutputLocation `type:"structure"` + + // Describes the parameters for Select job types. + SelectParameters *SelectParameters `type:"structure"` + + // Glacier retrieval tier at which the restore will be processed. + Tier *string `type:"string" enum:"Tier"` + + // Type of restore request. + Type *string `type:"string" enum:"RestoreRequestType"` } // String returns the string representation @@ -18121,14 +19238,21 @@ func (s RestoreRequest) GoString() string { // Validate inspects the fields of the type to determine if they are valid. func (s *RestoreRequest) Validate() error { invalidParams := request.ErrInvalidParams{Context: "RestoreRequest"} - if s.Days == nil { - invalidParams.Add(request.NewErrParamRequired("Days")) - } if s.GlacierJobParameters != nil { if err := s.GlacierJobParameters.Validate(); err != nil { invalidParams.AddNested("GlacierJobParameters", err.(request.ErrInvalidParams)) } } + if s.OutputLocation != nil { + if err := s.OutputLocation.Validate(); err != nil { + invalidParams.AddNested("OutputLocation", err.(request.ErrInvalidParams)) + } + } + if s.SelectParameters != nil { + if err := s.SelectParameters.Validate(); err != nil { + invalidParams.AddNested("SelectParameters", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -18142,13 +19266,43 @@ func (s *RestoreRequest) SetDays(v int64) *RestoreRequest { return s } +// SetDescription sets the Description field's value. +func (s *RestoreRequest) SetDescription(v string) *RestoreRequest { + s.Description = &v + return s +} + // SetGlacierJobParameters sets the GlacierJobParameters field's value. func (s *RestoreRequest) SetGlacierJobParameters(v *GlacierJobParameters) *RestoreRequest { s.GlacierJobParameters = v return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RoutingRule +// SetOutputLocation sets the OutputLocation field's value. +func (s *RestoreRequest) SetOutputLocation(v *OutputLocation) *RestoreRequest { + s.OutputLocation = v + return s +} + +// SetSelectParameters sets the SelectParameters field's value. +func (s *RestoreRequest) SetSelectParameters(v *SelectParameters) *RestoreRequest { + s.SelectParameters = v + return s +} + +// SetTier sets the Tier field's value. +func (s *RestoreRequest) SetTier(v string) *RestoreRequest { + s.Tier = &v + return s +} + +// SetType sets the Type field's value. +func (s *RestoreRequest) SetType(v string) *RestoreRequest { + s.Type = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RoutingRule type RoutingRule struct { _ struct{} `type:"structure"` @@ -18201,7 +19355,7 @@ func (s *RoutingRule) SetRedirect(v *Redirect) *RoutingRule { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Rule +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Rule type Rule struct { _ struct{} `type:"structure"` @@ -18316,7 +19470,374 @@ func (s *Rule) SetTransition(v *Transition) *Rule { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/StorageClassAnalysis +// Specifies the use of SSE-KMS to encrypt delievered Inventory reports. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SSEKMS +type SSEKMS struct { + _ struct{} `locationName:"SSE-KMS" type:"structure"` + + // Specifies the ID of the AWS Key Management Service (KMS) master encryption + // key to use for encrypting Inventory reports. + // + // KeyId is a required field + KeyId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s SSEKMS) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SSEKMS) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SSEKMS) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SSEKMS"} + if s.KeyId == nil { + invalidParams.Add(request.NewErrParamRequired("KeyId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKeyId sets the KeyId field's value. +func (s *SSEKMS) SetKeyId(v string) *SSEKMS { + s.KeyId = &v + return s +} + +// Specifies the use of SSE-S3 to encrypt delievered Inventory reports. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SSES3 +type SSES3 struct { + _ struct{} `locationName:"SSE-S3" type:"structure"` +} + +// String returns the string representation +func (s SSES3) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SSES3) GoString() string { + return s.String() +} + +// Describes the parameters for Select job types. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SelectParameters +type SelectParameters struct { + _ struct{} `type:"structure"` + + // The expression that is used to query the object. + // + // Expression is a required field + Expression *string `type:"string" required:"true"` + + // The type of the provided expression (e.g., SQL). + // + // ExpressionType is a required field + ExpressionType *string `type:"string" required:"true" enum:"ExpressionType"` + + // Describes the serialization format of the object. + // + // InputSerialization is a required field + InputSerialization *InputSerialization `type:"structure" required:"true"` + + // Describes how the results of the Select job are serialized. + // + // OutputSerialization is a required field + OutputSerialization *OutputSerialization `type:"structure" required:"true"` +} + +// String returns the string representation +func (s SelectParameters) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SelectParameters) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SelectParameters) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SelectParameters"} + if s.Expression == nil { + invalidParams.Add(request.NewErrParamRequired("Expression")) + } + if s.ExpressionType == nil { + invalidParams.Add(request.NewErrParamRequired("ExpressionType")) + } + if s.InputSerialization == nil { + invalidParams.Add(request.NewErrParamRequired("InputSerialization")) + } + if s.OutputSerialization == nil { + invalidParams.Add(request.NewErrParamRequired("OutputSerialization")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExpression sets the Expression field's value. +func (s *SelectParameters) SetExpression(v string) *SelectParameters { + s.Expression = &v + return s +} + +// SetExpressionType sets the ExpressionType field's value. +func (s *SelectParameters) SetExpressionType(v string) *SelectParameters { + s.ExpressionType = &v + return s +} + +// SetInputSerialization sets the InputSerialization field's value. +func (s *SelectParameters) SetInputSerialization(v *InputSerialization) *SelectParameters { + s.InputSerialization = v + return s +} + +// SetOutputSerialization sets the OutputSerialization field's value. +func (s *SelectParameters) SetOutputSerialization(v *OutputSerialization) *SelectParameters { + s.OutputSerialization = v + return s +} + +// Describes the default server-side encryption to apply to new objects in the +// bucket. If Put Object request does not specify any server-side encryption, +// this default encryption will be applied. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ServerSideEncryptionByDefault +type ServerSideEncryptionByDefault struct { + _ struct{} `type:"structure"` + + // KMS master key ID to use for the default encryption. This parameter is allowed + // if SSEAlgorithm is aws:kms. + KMSMasterKeyID *string `type:"string"` + + // Server-side encryption algorithm to use for the default encryption. + // + // SSEAlgorithm is a required field + SSEAlgorithm *string `type:"string" required:"true" enum:"ServerSideEncryption"` +} + +// String returns the string representation +func (s ServerSideEncryptionByDefault) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServerSideEncryptionByDefault) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ServerSideEncryptionByDefault) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ServerSideEncryptionByDefault"} + if s.SSEAlgorithm == nil { + invalidParams.Add(request.NewErrParamRequired("SSEAlgorithm")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKMSMasterKeyID sets the KMSMasterKeyID field's value. +func (s *ServerSideEncryptionByDefault) SetKMSMasterKeyID(v string) *ServerSideEncryptionByDefault { + s.KMSMasterKeyID = &v + return s +} + +// SetSSEAlgorithm sets the SSEAlgorithm field's value. +func (s *ServerSideEncryptionByDefault) SetSSEAlgorithm(v string) *ServerSideEncryptionByDefault { + s.SSEAlgorithm = &v + return s +} + +// Container for server-side encryption configuration rules. Currently S3 supports +// one rule only. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ServerSideEncryptionConfiguration +type ServerSideEncryptionConfiguration struct { + _ struct{} `type:"structure"` + + // Container for information about a particular server-side encryption configuration + // rule. + // + // Rules is a required field + Rules []*ServerSideEncryptionRule `locationName:"Rule" type:"list" flattened:"true" required:"true"` +} + +// String returns the string representation +func (s ServerSideEncryptionConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServerSideEncryptionConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ServerSideEncryptionConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ServerSideEncryptionConfiguration"} + if s.Rules == nil { + invalidParams.Add(request.NewErrParamRequired("Rules")) + } + if s.Rules != nil { + for i, v := range s.Rules { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Rules", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRules sets the Rules field's value. +func (s *ServerSideEncryptionConfiguration) SetRules(v []*ServerSideEncryptionRule) *ServerSideEncryptionConfiguration { + s.Rules = v + return s +} + +// Container for information about a particular server-side encryption configuration +// rule. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ServerSideEncryptionRule +type ServerSideEncryptionRule struct { + _ struct{} `type:"structure"` + + // Describes the default server-side encryption to apply to new objects in the + // bucket. If Put Object request does not specify any server-side encryption, + // this default encryption will be applied. + ApplyServerSideEncryptionByDefault *ServerSideEncryptionByDefault `type:"structure"` +} + +// String returns the string representation +func (s ServerSideEncryptionRule) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServerSideEncryptionRule) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ServerSideEncryptionRule) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ServerSideEncryptionRule"} + if s.ApplyServerSideEncryptionByDefault != nil { + if err := s.ApplyServerSideEncryptionByDefault.Validate(); err != nil { + invalidParams.AddNested("ApplyServerSideEncryptionByDefault", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetApplyServerSideEncryptionByDefault sets the ApplyServerSideEncryptionByDefault field's value. +func (s *ServerSideEncryptionRule) SetApplyServerSideEncryptionByDefault(v *ServerSideEncryptionByDefault) *ServerSideEncryptionRule { + s.ApplyServerSideEncryptionByDefault = v + return s +} + +// Container for filters that define which source objects should be replicated. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SourceSelectionCriteria +type SourceSelectionCriteria struct { + _ struct{} `type:"structure"` + + // Container for filter information of selection of KMS Encrypted S3 objects. + SseKmsEncryptedObjects *SseKmsEncryptedObjects `type:"structure"` +} + +// String returns the string representation +func (s SourceSelectionCriteria) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SourceSelectionCriteria) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SourceSelectionCriteria) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SourceSelectionCriteria"} + if s.SseKmsEncryptedObjects != nil { + if err := s.SseKmsEncryptedObjects.Validate(); err != nil { + invalidParams.AddNested("SseKmsEncryptedObjects", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSseKmsEncryptedObjects sets the SseKmsEncryptedObjects field's value. +func (s *SourceSelectionCriteria) SetSseKmsEncryptedObjects(v *SseKmsEncryptedObjects) *SourceSelectionCriteria { + s.SseKmsEncryptedObjects = v + return s +} + +// Container for filter information of selection of KMS Encrypted S3 objects. +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SseKmsEncryptedObjects +type SseKmsEncryptedObjects struct { + _ struct{} `type:"structure"` + + // The replication for KMS encrypted S3 objects is disabled if status is not + // Enabled. + // + // Status is a required field + Status *string `type:"string" required:"true" enum:"SseKmsEncryptedObjectsStatus"` +} + +// String returns the string representation +func (s SseKmsEncryptedObjects) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SseKmsEncryptedObjects) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SseKmsEncryptedObjects) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SseKmsEncryptedObjects"} + if s.Status == nil { + invalidParams.Add(request.NewErrParamRequired("Status")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStatus sets the Status field's value. +func (s *SseKmsEncryptedObjects) SetStatus(v string) *SseKmsEncryptedObjects { + s.Status = &v + return s +} + +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/StorageClassAnalysis type StorageClassAnalysis struct { _ struct{} `type:"structure"` @@ -18356,7 +19877,7 @@ func (s *StorageClassAnalysis) SetDataExport(v *StorageClassAnalysisDataExport) return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/StorageClassAnalysisDataExport +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/StorageClassAnalysisDataExport type StorageClassAnalysisDataExport struct { _ struct{} `type:"structure"` @@ -18414,7 +19935,7 @@ func (s *StorageClassAnalysisDataExport) SetOutputSchemaVersion(v string) *Stora return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Tag +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Tag type Tag struct { _ struct{} `type:"structure"` @@ -18470,7 +19991,7 @@ func (s *Tag) SetValue(v string) *Tag { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Tagging +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Tagging type Tagging struct { _ struct{} `type:"structure"` @@ -18517,7 +20038,7 @@ func (s *Tagging) SetTagSet(v []*Tag) *Tagging { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TargetGrant +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TargetGrant type TargetGrant struct { _ struct{} `type:"structure"` @@ -18566,7 +20087,7 @@ func (s *TargetGrant) SetPermission(v string) *TargetGrant { // Container for specifying the configuration when you want Amazon S3 to publish // events to an Amazon Simple Notification Service (Amazon SNS) topic. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TopicConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TopicConfiguration type TopicConfiguration struct { _ struct{} `type:"structure"` @@ -18638,7 +20159,7 @@ func (s *TopicConfiguration) SetTopicArn(v string) *TopicConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TopicConfigurationDeprecated +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TopicConfigurationDeprecated type TopicConfigurationDeprecated struct { _ struct{} `type:"structure"` @@ -18690,7 +20211,7 @@ func (s *TopicConfigurationDeprecated) SetTopic(v string) *TopicConfigurationDep return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Transition +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Transition type Transition struct { _ struct{} `type:"structure"` @@ -18734,7 +20255,7 @@ func (s *Transition) SetStorageClass(v string) *Transition { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopyRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopyRequest type UploadPartCopyInput struct { _ struct{} `type:"structure"` @@ -18978,7 +20499,7 @@ func (s *UploadPartCopyInput) SetUploadId(v string) *UploadPartCopyInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopyOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopyOutput type UploadPartCopyOutput struct { _ struct{} `type:"structure" payload:"CopyPartResult"` @@ -19063,7 +20584,7 @@ func (s *UploadPartCopyOutput) SetServerSideEncryption(v string) *UploadPartCopy return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartRequest type UploadPartInput struct { _ struct{} `type:"structure" payload:"Body"` @@ -19079,6 +20600,9 @@ type UploadPartInput struct { // body cannot be determined automatically. ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"` + // The base64-encoded 128-bit MD5 digest of the part data. + ContentMD5 *string `location:"header" locationName:"Content-MD5" type:"string"` + // Object key for which the multipart upload was initiated. // // Key is a required field @@ -19178,6 +20702,12 @@ func (s *UploadPartInput) SetContentLength(v int64) *UploadPartInput { return s } +// SetContentMD5 sets the ContentMD5 field's value. +func (s *UploadPartInput) SetContentMD5(v string) *UploadPartInput { + s.ContentMD5 = &v + return s +} + // SetKey sets the Key field's value. func (s *UploadPartInput) SetKey(v string) *UploadPartInput { s.Key = &v @@ -19227,7 +20757,7 @@ func (s *UploadPartInput) SetUploadId(v string) *UploadPartInput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartOutput +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartOutput type UploadPartOutput struct { _ struct{} `type:"structure"` @@ -19303,7 +20833,7 @@ func (s *UploadPartOutput) SetServerSideEncryption(v string) *UploadPartOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/VersioningConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/VersioningConfiguration type VersioningConfiguration struct { _ struct{} `type:"structure"` @@ -19338,7 +20868,7 @@ func (s *VersioningConfiguration) SetStatus(v string) *VersioningConfiguration { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/WebsiteConfiguration +// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/WebsiteConfiguration type WebsiteConfiguration struct { _ struct{} `type:"structure"` @@ -19550,6 +21080,22 @@ const ( ExpirationStatusDisabled = "Disabled" ) +const ( + // ExpressionTypeSql is a ExpressionType enum value + ExpressionTypeSql = "SQL" +) + +const ( + // FileHeaderInfoUse is a FileHeaderInfo enum value + FileHeaderInfoUse = "USE" + + // FileHeaderInfoIgnore is a FileHeaderInfo enum value + FileHeaderInfoIgnore = "IGNORE" + + // FileHeaderInfoNone is a FileHeaderInfo enum value + FileHeaderInfoNone = "NONE" +) + const ( // FilterRuleNamePrefix is a FilterRuleName enum value FilterRuleNamePrefix = "prefix" @@ -19561,6 +21107,9 @@ const ( const ( // InventoryFormatCsv is a InventoryFormat enum value InventoryFormatCsv = "CSV" + + // InventoryFormatOrc is a InventoryFormat enum value + InventoryFormatOrc = "ORC" ) const ( @@ -19597,6 +21146,9 @@ const ( // InventoryOptionalFieldReplicationStatus is a InventoryOptionalField enum value InventoryOptionalFieldReplicationStatus = "ReplicationStatus" + + // InventoryOptionalFieldEncryptionStatus is a InventoryOptionalField enum value + InventoryOptionalFieldEncryptionStatus = "EncryptionStatus" ) const ( @@ -19662,6 +21214,11 @@ const ( ObjectVersionStorageClassStandard = "STANDARD" ) +const ( + // OwnerOverrideDestination is a OwnerOverride enum value + OwnerOverrideDestination = "Destination" +) + const ( // PayerRequester is a Payer enum value PayerRequester = "Requester" @@ -19695,6 +21252,14 @@ const ( ProtocolHttps = "https" ) +const ( + // QuoteFieldsAlways is a QuoteFields enum value + QuoteFieldsAlways = "ALWAYS" + + // QuoteFieldsAsneeded is a QuoteFields enum value + QuoteFieldsAsneeded = "ASNEEDED" +) + const ( // ReplicationRuleStatusEnabled is a ReplicationRuleStatus enum value ReplicationRuleStatusEnabled = "Enabled" @@ -19733,6 +21298,11 @@ const ( RequestPayerRequester = "requester" ) +const ( + // RestoreRequestTypeSelect is a RestoreRequestType enum value + RestoreRequestTypeSelect = "SELECT" +) + const ( // ServerSideEncryptionAes256 is a ServerSideEncryption enum value ServerSideEncryptionAes256 = "AES256" @@ -19741,6 +21311,14 @@ const ( ServerSideEncryptionAwsKms = "aws:kms" ) +const ( + // SseKmsEncryptedObjectsStatusEnabled is a SseKmsEncryptedObjectsStatus enum value + SseKmsEncryptedObjectsStatusEnabled = "Enabled" + + // SseKmsEncryptedObjectsStatusDisabled is a SseKmsEncryptedObjectsStatus enum value + SseKmsEncryptedObjectsStatusDisabled = "Disabled" +) + const ( // StorageClassStandard is a StorageClass enum value StorageClassStandard = "STANDARD" diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go b/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go index 30068d159..0def02255 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go @@ -10,7 +10,7 @@ // // Using the Client // -// To Amazon Simple Storage Service with the SDK use the New function to create +// To contact Amazon Simple Storage Service with the SDK use the New function to create // a new service client. With that client you can make API requests to the service. // These clients are safe to use concurrently. // diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go b/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go index b794a63ba..39b912c26 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go @@ -35,7 +35,7 @@ // // The s3manager package's Downloader provides concurrently downloading of Objects // from S3. The Downloader will write S3 Object content with an io.WriterAt. -// Once the Downloader instance is created you can call Upload concurrently from +// Once the Downloader instance is created you can call Download concurrently from // multiple goroutines safely. // // // The session the S3 Downloader will use @@ -56,7 +56,7 @@ // Key: aws.String(myString), // }) // if err != nil { -// return fmt.Errorf("failed to upload file, %v", err) +// return fmt.Errorf("failed to download file, %v", err) // } // fmt.Printf("file downloaded, %d bytes\n", n) // diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/s3iface/interface.go b/vendor/github.com/aws/aws-sdk-go/service/s3/s3iface/interface.go index 34e71df0f..28c30d976 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/s3iface/interface.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/s3iface/interface.go @@ -92,6 +92,10 @@ type S3API interface { DeleteBucketCorsWithContext(aws.Context, *s3.DeleteBucketCorsInput, ...request.Option) (*s3.DeleteBucketCorsOutput, error) DeleteBucketCorsRequest(*s3.DeleteBucketCorsInput) (*request.Request, *s3.DeleteBucketCorsOutput) + DeleteBucketEncryption(*s3.DeleteBucketEncryptionInput) (*s3.DeleteBucketEncryptionOutput, error) + DeleteBucketEncryptionWithContext(aws.Context, *s3.DeleteBucketEncryptionInput, ...request.Option) (*s3.DeleteBucketEncryptionOutput, error) + DeleteBucketEncryptionRequest(*s3.DeleteBucketEncryptionInput) (*request.Request, *s3.DeleteBucketEncryptionOutput) + DeleteBucketInventoryConfiguration(*s3.DeleteBucketInventoryConfigurationInput) (*s3.DeleteBucketInventoryConfigurationOutput, error) DeleteBucketInventoryConfigurationWithContext(aws.Context, *s3.DeleteBucketInventoryConfigurationInput, ...request.Option) (*s3.DeleteBucketInventoryConfigurationOutput, error) DeleteBucketInventoryConfigurationRequest(*s3.DeleteBucketInventoryConfigurationInput) (*request.Request, *s3.DeleteBucketInventoryConfigurationOutput) @@ -148,6 +152,10 @@ type S3API interface { GetBucketCorsWithContext(aws.Context, *s3.GetBucketCorsInput, ...request.Option) (*s3.GetBucketCorsOutput, error) GetBucketCorsRequest(*s3.GetBucketCorsInput) (*request.Request, *s3.GetBucketCorsOutput) + GetBucketEncryption(*s3.GetBucketEncryptionInput) (*s3.GetBucketEncryptionOutput, error) + GetBucketEncryptionWithContext(aws.Context, *s3.GetBucketEncryptionInput, ...request.Option) (*s3.GetBucketEncryptionOutput, error) + GetBucketEncryptionRequest(*s3.GetBucketEncryptionInput) (*request.Request, *s3.GetBucketEncryptionOutput) + GetBucketInventoryConfiguration(*s3.GetBucketInventoryConfigurationInput) (*s3.GetBucketInventoryConfigurationOutput, error) GetBucketInventoryConfigurationWithContext(aws.Context, *s3.GetBucketInventoryConfigurationInput, ...request.Option) (*s3.GetBucketInventoryConfigurationOutput, error) GetBucketInventoryConfigurationRequest(*s3.GetBucketInventoryConfigurationInput) (*request.Request, *s3.GetBucketInventoryConfigurationOutput) @@ -295,6 +303,10 @@ type S3API interface { PutBucketCorsWithContext(aws.Context, *s3.PutBucketCorsInput, ...request.Option) (*s3.PutBucketCorsOutput, error) PutBucketCorsRequest(*s3.PutBucketCorsInput) (*request.Request, *s3.PutBucketCorsOutput) + PutBucketEncryption(*s3.PutBucketEncryptionInput) (*s3.PutBucketEncryptionOutput, error) + PutBucketEncryptionWithContext(aws.Context, *s3.PutBucketEncryptionInput, ...request.Option) (*s3.PutBucketEncryptionOutput, error) + PutBucketEncryptionRequest(*s3.PutBucketEncryptionInput) (*request.Request, *s3.PutBucketEncryptionOutput) + PutBucketInventoryConfiguration(*s3.PutBucketInventoryConfigurationInput) (*s3.PutBucketInventoryConfigurationOutput, error) PutBucketInventoryConfigurationWithContext(aws.Context, *s3.PutBucketInventoryConfigurationInput, ...request.Option) (*s3.PutBucketInventoryConfigurationOutput, error) PutBucketInventoryConfigurationRequest(*s3.PutBucketInventoryConfigurationInput) (*request.Request, *s3.PutBucketInventoryConfigurationOutput) diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/batch.go b/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/batch.go index 33931c6a6..7f1674f4f 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/batch.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/batch.go @@ -60,7 +60,15 @@ func newError(err error, bucket, key *string) Error { } func (err *Error) Error() string { - return fmt.Sprintf("failed to upload %q to %q:\n%s", err.Key, err.Bucket, err.OrigErr.Error()) + origErr := "" + if err.OrigErr != nil { + origErr = ":\n" + err.OrigErr.Error() + } + return fmt.Sprintf("failed to upload %q to %q%s", + aws.StringValue(err.Key), + aws.StringValue(err.Bucket), + origErr, + ) } // NewBatchError will return a BatchError that satisfies the awserr.Error interface. @@ -206,7 +214,7 @@ type BatchDelete struct { // }, // } // -// if err := batcher.Delete(&s3manager.DeleteObjectsIterator{ +// if err := batcher.Delete(aws.BackgroundContext(), &s3manager.DeleteObjectsIterator{ // Objects: objects, // }); err != nil { // return err @@ -239,7 +247,7 @@ func NewBatchDeleteWithClient(client s3iface.S3API, options ...func(*BatchDelete // }, // } // -// if err := batcher.Delete(&s3manager.DeleteObjectsIterator{ +// if err := batcher.Delete(aws.BackgroundContext(), &s3manager.DeleteObjectsIterator{ // Objects: objects, // }); err != nil { // return err diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/upload.go b/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/upload.go index fc1f47205..a4079b83e 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/upload.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/upload.go @@ -117,6 +117,9 @@ type UploadInput struct { // The language the content is in. ContentLanguage *string `location:"header" locationName:"Content-Language" type:"string"` + // The base64-encoded 128-bit MD5 digest of the part data. + ContentMD5 *string `location:"header" locationName:"Content-MD5" type:"string"` + // A standard MIME type describing the format of the object data. ContentType *string `location:"header" locationName:"Content-Type" type:"string"` @@ -218,8 +221,11 @@ type Uploader struct { // if this value is set to zero, the DefaultUploadPartSize value will be used. PartSize int64 - // The number of goroutines to spin up in parallel when sending parts. - // If this is set to zero, the DefaultUploadConcurrency value will be used. + // The number of goroutines to spin up in parallel per call to Upload when + // sending parts. If this is set to zero, the DefaultUploadConcurrency value + // will be used. + // + // The concurrency pool is not shared between calls to Upload. Concurrency int // Setting this value to true will cause the SDK to avoid calling diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go index 3b8be4378..23f0a06db 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -35,7 +35,7 @@ const opAssumeRole = "AssumeRole" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) { op := &request.Operation{ Name: opAssumeRole, @@ -168,7 +168,7 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o // and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // in the IAM User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) { req, out := c.AssumeRoleRequest(input) return out, req.Send() @@ -215,7 +215,7 @@ const opAssumeRoleWithSAML = "AssumeRoleWithSAML" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) { op := &request.Operation{ Name: opAssumeRoleWithSAML, @@ -341,7 +341,7 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re // and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // in the IAM User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) { req, out := c.AssumeRoleWithSAMLRequest(input) return out, req.Send() @@ -388,7 +388,7 @@ const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) { op := &request.Operation{ Name: opAssumeRoleWithWebIdentity, @@ -543,7 +543,7 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI // and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // in the IAM User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) { req, out := c.AssumeRoleWithWebIdentityRequest(input) return out, req.Send() @@ -590,7 +590,7 @@ const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) { op := &request.Operation{ Name: opDecodeAuthorizationMessage, @@ -655,7 +655,7 @@ func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessag // invalid. This can happen if the token contains invalid characters, such as // linebreaks. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) { req, out := c.DecodeAuthorizationMessageRequest(input) return out, req.Send() @@ -702,7 +702,7 @@ const opGetCallerIdentity = "GetCallerIdentity" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) { op := &request.Operation{ Name: opGetCallerIdentity, @@ -730,7 +730,7 @@ func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *requ // // See the AWS API reference guide for AWS Security Token Service's // API operation GetCallerIdentity for usage and error information. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) { req, out := c.GetCallerIdentityRequest(input) return out, req.Send() @@ -777,7 +777,7 @@ const opGetFederationToken = "GetFederationToken" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) { op := &request.Operation{ Name: opGetFederationToken, @@ -899,7 +899,7 @@ func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *re // and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // in the IAM User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) { req, out := c.GetFederationTokenRequest(input) return out, req.Send() @@ -946,7 +946,7 @@ const opGetSessionToken = "GetSessionToken" // fmt.Println(resp) // } // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) { op := &request.Operation{ Name: opGetSessionToken, @@ -1027,7 +1027,7 @@ func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request. // and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // in the IAM User Guide. // -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) { req, out := c.GetSessionTokenRequest(input) return out, req.Send() @@ -1049,7 +1049,7 @@ func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionToken return out, req.Send() } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest type AssumeRoleInput struct { _ struct{} `type:"structure"` @@ -1241,7 +1241,7 @@ func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput { // Contains the response to a successful AssumeRole request, including temporary // AWS credentials that can be used to make AWS requests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse type AssumeRoleOutput struct { _ struct{} `type:"structure"` @@ -1295,7 +1295,7 @@ func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest type AssumeRoleWithSAMLInput struct { _ struct{} `type:"structure"` @@ -1436,7 +1436,7 @@ func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAML // Contains the response to a successful AssumeRoleWithSAML request, including // temporary AWS credentials that can be used to make AWS requests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse type AssumeRoleWithSAMLOutput struct { _ struct{} `type:"structure"` @@ -1548,7 +1548,7 @@ func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLO return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest type AssumeRoleWithWebIdentityInput struct { _ struct{} `type:"structure"` @@ -1711,7 +1711,7 @@ func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRo // Contains the response to a successful AssumeRoleWithWebIdentity request, // including temporary AWS credentials that can be used to make AWS requests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse type AssumeRoleWithWebIdentityOutput struct { _ struct{} `type:"structure"` @@ -1804,7 +1804,7 @@ func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v strin // The identifiers for the temporary security credentials that the operation // returns. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser type AssumedRoleUser struct { _ struct{} `type:"structure"` @@ -1847,7 +1847,7 @@ func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser { } // AWS credentials for API authentication. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials type Credentials struct { _ struct{} `type:"structure"` @@ -1906,7 +1906,7 @@ func (s *Credentials) SetSessionToken(v string) *Credentials { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest type DecodeAuthorizationMessageInput struct { _ struct{} `type:"structure"` @@ -1951,7 +1951,7 @@ func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAut // A document that contains additional information about the authorization status // of a request from an encoded message that is returned in response to an AWS // request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse type DecodeAuthorizationMessageOutput struct { _ struct{} `type:"structure"` @@ -1976,7 +1976,7 @@ func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAu } // Identifiers for the federated user that is associated with the credentials. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser type FederatedUser struct { _ struct{} `type:"structure"` @@ -2017,7 +2017,7 @@ func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest type GetCallerIdentityInput struct { _ struct{} `type:"structure"` } @@ -2034,7 +2034,7 @@ func (s GetCallerIdentityInput) GoString() string { // Contains the response to a successful GetCallerIdentity request, including // information about the entity making the request. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse type GetCallerIdentityOutput struct { _ struct{} `type:"structure"` @@ -2080,7 +2080,7 @@ func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput { return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest type GetFederationTokenInput struct { _ struct{} `type:"structure"` @@ -2189,7 +2189,7 @@ func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput { // Contains the response to a successful GetFederationToken request, including // temporary AWS credentials that can be used to make AWS requests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse type GetFederationTokenOutput struct { _ struct{} `type:"structure"` @@ -2242,7 +2242,7 @@ func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTo return s } -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest type GetSessionTokenInput struct { _ struct{} `type:"structure"` @@ -2327,7 +2327,7 @@ func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput { // Contains the response to a successful GetSessionToken request, including // temporary AWS credentials that can be used to make AWS requests. -// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse type GetSessionTokenOutput struct { _ struct{} `type:"structure"` diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go index a43fa8055..ef681ab0c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go @@ -56,7 +56,7 @@ // // Using the Client // -// To AWS Security Token Service with the SDK use the New function to create +// To contact AWS Security Token Service with the SDK use the New function to create // a new service client. With that client you can make API requests to the service. // These clients are safe to use concurrently. // diff --git a/vendor/vendor.json b/vendor/vendor.json index 421c8710a..5c96bdf85 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -248,244 +248,244 @@ "revision": "4239b77079c7b5d1243b7b4736304ce8ddb6f0f2" }, { - "checksumSHA1": "7vSTKBRZq6azJnhm1k6XmNxu97M=", + "checksumSHA1": "tN8pbihy8mw+m0UVqNNFJmx7p+Y=", "path": "github.com/aws/aws-sdk-go", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "BRgDFkYJonSbN+/ugKMUuSXkS4c=", + "checksumSHA1": "NQu/L+9CIJLpgrZt3UMlbma9Pk0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "n98FANpNeRT5kf6pizdpI7nm6Sw=", + "checksumSHA1": "9nE/FjZ4pYrT883KtV2/aI+Gayo=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "7/8j/q0TWtOgXyvEcv4B2Dhl00o=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "Y+cPwQL0dZMyqp3wI+KJWmA9KQ8=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "JEYqmF83O5n5bHkupAzA6STm0no=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "ZdtYh3ZHSgP/WEIaqwJHTEhpkbs=", + "checksumSHA1": "OnU/n7R33oYXiB4SAGd5pK7I0Bs=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "/EXbk/z2TWjWc1Hvb4QYs3Wmhb8=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "W45tSKW4ZVgBk9H4lx5RbGi9OVg=", + "checksumSHA1": "bV8wC0xzF08ztv57EXbeLjNxmsI=", "path": "github.com/aws/aws-sdk-go/aws/endpoints", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "Rdm9v0vpqsO1Ka9rwktfL19D8A8=", + "checksumSHA1": "JZ49s4cNe3nIttx3hWp04CQif4o=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "SK5Mn4Ga9+equOQTYA1DTSb3LWY=", + "checksumSHA1": "HcGL4e6Uep4/80eCUI5xkcWjpQ0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "1+ZxEwzc1Vz8X2l+kXkS2iATtas=", + "checksumSHA1": "iU00ZjhAml/13g+1YXT21IqoXqg=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "04ypv4x12l4q0TksA1zEVsmgpvw=", "path": "github.com/aws/aws-sdk-go/internal/shareddefaults", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "wk7EyvDaHwb5qqoOP/4d3cV0708=", + "checksumSHA1": "NStHCXEvYqG72GknZyv1jaKaeH0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "O6hcK24yI6w7FA+g4Pbr+eQ7pys=", + "checksumSHA1": "yHfT5DTbeCLs4NE2Rgnqrhe15ls=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "Drt1JfLMa0DQEZLWrnMlTWaIcC8=", + "checksumSHA1": "9V1PvtFQ9MObZTc3sa86WcuOtOU=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "VCTh+dEaqqhog5ncy/WTt9+/gFM=", + "checksumSHA1": "pkeoOfZpHRvFG/AOZeTf0lwtsFg=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "0qYPUga28aQVkxZgBR3Z86AbGUQ=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", @@ -493,62 +493,62 @@ "path": "github.com/aws/aws-sdk-go/private/waiter", "revision": "1bd588c8b2dba4da57dd4664b2b2750d260a5915", "revisionTime": "2017-02-24T22:28:38Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "INaeHZ2L5x6RlrcQBm4q1hFqNRM=", + "checksumSHA1": "4igS6faf4hrhDj6Jj9ErVcN1qKo=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "5177d71d80f123f6d82aaf762387e39b88c5ba23", - "revisionTime": "2018-01-09T00:04:15Z", - "version": "v1.12.57", - "versionExact": "v1.12.57" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "YNq7YhasHn9ceelWX2aG0Cg0Ga0=", + "checksumSHA1": "uEv9kkBsVIjg7K4+Y8TVlU0Cc8o=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/ecr", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "SEKg+cGyOj6dKdK5ltUHsoL4R4Y=", + "checksumSHA1": "sCaHoPWsJXRHFbilUKwN71qFTOI=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "RVrBBPDYg3ViwQDLBanFehkdqkM=", + "checksumSHA1": "ZP6QI0X9BNKk8o1p3AyLfjabS20=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/s3/s3iface", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "LlIpD3fzngPXshFh/5tuCWlrYzI=", + "checksumSHA1": "g6Eo2gEoj6YEZ+tLwydnfhwo7zg=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/s3/s3manager", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { - "checksumSHA1": "MerduaV3PxtZAWvOGpgoBIglo38=", + "checksumSHA1": "W1oFtpaT4TWIIJrAvFcn/XdcT7g=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "dd3acff9dc16f9a6fd87f6b4501590a532e7206a", - "revisionTime": "2017-08-10T20:40:06Z", - "version": "v1.10.23", - "versionExact": "v1.10.23" + "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", + "revisionTime": "2018-02-05T21:18:42Z", + "version": "v1.12.71", + "versionExact": "v1.12.71" }, { "checksumSHA1": "7SbTaY0kaYxgQrG3/9cjrI+BcyU=", From b651571b30d14c08874bf991c156f8c8394744ac Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 5 Feb 2018 15:44:25 -0800 Subject: [PATCH 0584/1007] update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d73eb0ec..0e8424cb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ### BACKWARDS INCOMPATIBILITIES: * core: Affects Windows guests: User variables containing Powershell special characters no longer need to be escaped.[GH-5376] * provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] -* 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will break; the work to fix them is minimal and documented in GH-5810. [GH-5810] +* 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will no longer compile (however existing builds will still work fine); the work to fix them is minimal and documented in GH-5810. [GH-5810] +* provisioner/file: We've made destination semantics more consistent across the various communicators. In general, if the destination is a directory, files will be uploaded into the directory instead of failing. This mirrors the behavior of `rsync`. There's a chance some users might be depending on the previous buggy behavior, so it's worth ensuring your configuration is correct. [GH-5426] ### IMPROVEMENTS: From 21812fa17f50cad3dbc5b3a2fab18b054db0aa6f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 2 Feb 2018 20:16:23 -0800 Subject: [PATCH 0585/1007] Add volume and run tags if in us-gov/china We can't tag on instance creation when we're in "restricted" regions, so let's add the tags after the resources have been created. Adds methods to AccessConfig to detect if we're in China or US Gov regions (i.e. "restricted"). Also turns tag:tag maps into a type, and moves methods around validating and converting them to ec2Tags to methods of the type. --- builder/amazon/chroot/device_test.go | 10 +++ builder/amazon/common/access_config.go | 16 ++++ builder/amazon/common/access_config_test.go | 20 +++++ builder/amazon/common/ami_config.go | 4 +- builder/amazon/common/step_create_tags.go | 47 ++--------- .../amazon/common/step_run_source_instance.go | 84 +++++++++++++++++-- .../amazon/common/step_run_spot_instance.go | 18 ++-- builder/amazon/common/tags.go | 47 +++++++++++ builder/amazon/ebs/builder.go | 3 +- builder/amazon/ebssurrogate/builder.go | 5 +- builder/amazon/ebsvolume/block_device.go | 2 +- builder/amazon/ebsvolume/builder.go | 1 + .../amazon/ebsvolume/step_tag_ebs_volumes.go | 5 +- builder/amazon/instance/builder.go | 1 + 14 files changed, 198 insertions(+), 65 deletions(-) create mode 100644 builder/amazon/chroot/device_test.go create mode 100644 builder/amazon/common/tags.go diff --git a/builder/amazon/chroot/device_test.go b/builder/amazon/chroot/device_test.go new file mode 100644 index 000000000..a47fc7dff --- /dev/null +++ b/builder/amazon/chroot/device_test.go @@ -0,0 +1,10 @@ +package chroot + +import "testing" + +func TestDevicePrefixMatch(t *testing.T) { + /* + if devicePrefixMatch("nvme0n1") != "" { + } + */ +} diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index b569d0314..c24ab25be 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "os" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -80,6 +81,21 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } +func (c *AccessConfig) SessionRegion() string { + if c.session == nil { + panic("access config session should be set.") + } + return aws.StringValue(c.session.Config.Region) +} + +func (c *AccessConfig) IsGovCloud() bool { + return strings.HasPrefix(c.SessionRegion(), "us-gov-") +} + +func (c *AccessConfig) IsChinaCloud() bool { + return strings.HasPrefix(c.SessionRegion(), "cn-") +} + // metadataRegion returns the region from the metadata service func (c *AccessConfig) metadataRegion() string { diff --git a/builder/amazon/common/access_config_test.go b/builder/amazon/common/access_config_test.go index 20d4851ba..e1c44cb89 100644 --- a/builder/amazon/common/access_config_test.go +++ b/builder/amazon/common/access_config_test.go @@ -2,6 +2,9 @@ package common import ( "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" ) func testAccessConfig() *AccessConfig { @@ -38,3 +41,20 @@ func TestAccessConfigPrepare_Region(t *testing.T) { c.SkipValidation = false } + +func TestAccessConfigPrepare_RegionRestrictd(t *testing.T) { + c := testAccessConfig() + + // Create a Session with a custom region + c.session = session.Must(session.NewSession(&aws.Config{ + Region: aws.String("us-gov-west-1"), + })) + + if err := c.Prepare(nil); err != nil { + t.Fatalf("shouldn't have err: %s", err) + } + + if !c.IsGovCloud() { + t.Fatal("We should be in gov region.") + } +} diff --git a/builder/amazon/common/ami_config.go b/builder/amazon/common/ami_config.go index 9af2244ee..a3b2d2b4e 100644 --- a/builder/amazon/common/ami_config.go +++ b/builder/amazon/common/ami_config.go @@ -17,7 +17,7 @@ type AMIConfig struct { AMIProductCodes []string `mapstructure:"ami_product_codes"` AMIRegions []string `mapstructure:"ami_regions"` AMISkipRegionValidation bool `mapstructure:"skip_region_validation"` - AMITags map[string]string `mapstructure:"tags"` + AMITags TagMap `mapstructure:"tags"` AMIENASupport bool `mapstructure:"ena_support"` AMISriovNetSupport bool `mapstructure:"sriov_support"` AMIForceDeregister bool `mapstructure:"force_deregister"` @@ -25,7 +25,7 @@ type AMIConfig struct { AMIEncryptBootVolume bool `mapstructure:"encrypt_boot"` AMIKmsKeyId string `mapstructure:"kms_key_id"` AMIRegionKMSKeyIDs map[string]string `mapstructure:"region_kms_key_ids"` - SnapshotTags map[string]string `mapstructure:"snapshot_tags"` + SnapshotTags TagMap `mapstructure:"snapshot_tags"` SnapshotUsers []string `mapstructure:"snapshot_users"` SnapshotGroups []string `mapstructure:"snapshot_groups"` } diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 47078b6ac..96177c8a8 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -15,8 +15,8 @@ import ( ) type StepCreateTags struct { - Tags map[string]string - SnapshotTags map[string]string + Tags TagMap + SnapshotTags TagMap Ctx interpolate.Context } @@ -33,7 +33,7 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis sourceAMI = "" } - if len(s.Tags) == 0 && len(s.SnapshotTags) == 0 { + if !s.Tags.IsSet() && !s.SnapshotTags.IsSet() { return multistep.ActionContinue } @@ -79,22 +79,22 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis // Convert tags to ec2.Tag format ui.Say("Creating AMI tags") - amiTags, err := ConvertToEC2Tags(s.Tags, *ec2conn.Config.Region, sourceAMI, s.Ctx) + amiTags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, sourceAMI) if err != nil { state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - ReportTags(ui, amiTags) + amiTags.Report(ui) ui.Say("Creating snapshot tags") - snapshotTags, err := ConvertToEC2Tags(s.SnapshotTags, *ec2conn.Config.Region, sourceAMI, s.Ctx) + snapshotTags, err := s.SnapshotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, sourceAMI) if err != nil { state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - ReportTags(ui, snapshotTags) + snapshotTags.Report(ui) // Retry creating tags for about 2.5 minutes err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { @@ -142,36 +142,3 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis func (s *StepCreateTags) Cleanup(state multistep.StateBag) { // No cleanup... } - -func ReportTags(ui packer.Ui, tags []*ec2.Tag) { - for _, tag := range tags { - ui.Message(fmt.Sprintf("Adding tag: \"%s\": \"%s\"", - aws.StringValue(tag.Key), aws.StringValue(tag.Value))) - } -} - -func ConvertToEC2Tags(tags map[string]string, region, sourceAmiId string, ctx interpolate.Context) ([]*ec2.Tag, error) { - var ec2Tags []*ec2.Tag - for key, value := range tags { - - ctx.Data = &BuildInfoTemplate{ - SourceAMI: sourceAmiId, - BuildRegion: region, - } - interpolatedKey, err := interpolate.Render(key, &ctx) - if err != nil { - return ec2Tags, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) - } - interpolatedValue, err := interpolate.Render(value, &ctx) - if err != nil { - return ec2Tags, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) - } - - ec2Tags = append(ec2Tags, &ec2.Tag{ - Key: aws.String(interpolatedKey), - Value: aws.String(interpolatedValue), - }) - } - - return ec2Tags, nil -} diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index cc343961d..761e6f09c 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -8,8 +8,10 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" + retry "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -19,19 +21,20 @@ type StepRunSourceInstance struct { AssociatePublicIpAddress bool AvailabilityZone string BlockDevices BlockDevices + Ctx interpolate.Context Debug bool EbsOptimized bool ExpectedRootDevice string IamInstanceProfile string InstanceInitiatedShutdownBehavior string InstanceType string + IsRestricted bool SourceAMI string SubnetId string - Tags map[string]string - VolumeTags map[string]string + Tags TagMap UserData string UserDataFile string - Ctx interpolate.Context + VolumeTags TagMap instanceId string } @@ -85,16 +88,15 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) s.Tags["Name"] = "Packer Builder" } - ec2Tags, err := ConvertToEC2Tags(s.Tags, *ec2conn.Config.Region, s.SourceAMI, s.Ctx) + ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) if err != nil { err := fmt.Errorf("Error tagging source instance: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - ReportTags(ui, ec2Tags) - volTags, err := ConvertToEC2Tags(s.VolumeTags, *ec2conn.Config.Region, s.SourceAMI, s.Ctx) + volTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) if err != nil { err := fmt.Errorf("Error tagging volumes: %s", err) state.Put("error", err) @@ -114,6 +116,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) EbsOptimized: &s.EbsOptimized, } + // Collect tags for tagging on resource creation var tagSpecs []*ec2.TagSpecification if len(ec2Tags) > 0 { @@ -134,8 +137,11 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) tagSpecs = append(tagSpecs, runVolTags) } - if len(tagSpecs) > 0 { + // If our region supports it, set tag specifications + if len(tagSpecs) > 0 && !s.IsRestricted { runOpts.SetTagSpecifications(tagSpecs) + ec2Tags.Report(ui) + volTags.Report(ui) } if keyName != "" { @@ -212,6 +218,70 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) state.Put("instance", instance) + // If we're in a region that doesn't support tagging on instance creation, + // do that now. + + if s.IsRestricted { + ec2Tags.Report(ui) + // Retry creating tags for about 2.5 minutes + err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { + _, err := ec2conn.CreateTags(&ec2.CreateTagsInput{ + Tags: ec2Tags, + Resources: []*string{instance.InstanceId}, + }) + if err == nil { + return true, nil + } + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "InvalidInstanceID.NotFound" { + return false, nil + } + } + return true, err + }) + + if err != nil { + err := fmt.Errorf("Error tagging source instance: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // Now tag volumes + + volumeIds := make([]*string, 0) + for _, v := range instance.BlockDeviceMappings { + if ebs := v.Ebs; ebs != nil { + volumeIds = append(volumeIds, ebs.VolumeId) + } + } + + if len(volumeIds) > 0 && s.VolumeTags.IsSet() { + ui.Say("Adding tags to source EBS Volumes") + + volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + if err != nil { + err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + volumeTags.Report(ui) + + _, err = ec2conn.CreateTags(&ec2.CreateTagsInput{ + Resources: volumeIds, + Tags: volumeTags, + }) + + if err != nil { + err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + } + return multistep.ActionContinue } diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index c5e3382ec..0f08ea90b 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -33,8 +33,8 @@ type StepRunSpotInstance struct { SpotPrice string SpotPriceProduct string SubnetId string - Tags map[string]string - VolumeTags map[string]string + Tags TagMap + VolumeTags TagMap UserData string UserDataFile string Ctx interpolate.Context @@ -143,14 +143,14 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m s.Tags["Name"] = "Packer Builder" } - ec2Tags, err := ConvertToEC2Tags(s.Tags, *ec2conn.Config.Region, s.SourceAMI, s.Ctx) + ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) if err != nil { err := fmt.Errorf("Error tagging source instance: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - ReportTags(ui, ec2Tags) + ec2Tags.Report(ui) ui.Message(fmt.Sprintf( "Requesting spot instance '%s' for: %s", @@ -284,21 +284,21 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m } } - if len(volumeIds) > 0 && len(s.VolumeTags) > 0 { + if len(volumeIds) > 0 && s.VolumeTags.IsSet() { ui.Say("Adding tags to source EBS Volumes") - tags, err := ConvertToEC2Tags(s.VolumeTags, *ec2conn.Config.Region, s.SourceAMI, s.Ctx) + + volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) if err != nil { err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - - ReportTags(ui, tags) + volumeTags.Report(ui) _, err = ec2conn.CreateTags(&ec2.CreateTagsInput{ Resources: volumeIds, - Tags: tags, + Tags: volumeTags, }) if err != nil { diff --git a/builder/amazon/common/tags.go b/builder/amazon/common/tags.go new file mode 100644 index 000000000..3c257e10f --- /dev/null +++ b/builder/amazon/common/tags.go @@ -0,0 +1,47 @@ +package common + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" +) + +type TagMap map[string]string +type EC2Tags []*ec2.Tag + +func (t EC2Tags) Report(ui packer.Ui) { + for _, tag := range t { + ui.Message(fmt.Sprintf("Adding tag: \"%s\": \"%s\"", + aws.StringValue(tag.Key), aws.StringValue(tag.Value))) + } +} + +func (t TagMap) IsSet() bool { + return len(t) > 0 +} + +func (t TagMap) EC2Tags(ctx interpolate.Context, region, sourceAMIID string) (EC2Tags, error) { + var ec2Tags []*ec2.Tag + ctx.Data = &BuildInfoTemplate{ + SourceAMI: sourceAMIID, + BuildRegion: region, + } + for key, value := range t { + interpolatedKey, err := interpolate.Render(key, &ctx) + if err != nil { + return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) + } + interpolatedValue, err := interpolate.Render(value, &ctx) + if err != nil { + return nil, fmt.Errorf("Error processing tag: %s:%s - %s", key, value, err) + } + ec2Tags = append(ec2Tags, &ec2.Tag{ + Key: aws.String(interpolatedKey), + Value: aws.String(interpolatedValue), + }) + } + return ec2Tags, nil +} diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 44e14b695..87354223c 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -28,7 +28,7 @@ type Config struct { awscommon.AMIConfig `mapstructure:",squash"` awscommon.BlockDevices `mapstructure:",squash"` awscommon.RunConfig `mapstructure:",squash"` - VolumeRunTags map[string]string `mapstructure:"run_volume_tags"` + VolumeRunTags awscommon.TagMap `mapstructure:"run_volume_tags"` ctx interpolate.Context } @@ -152,6 +152,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, InstanceType: b.config.InstanceType, + IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(), SourceAMI: b.config.SourceAmi, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 6dba669d8..b990c5758 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -26,8 +26,8 @@ type Config struct { awscommon.BlockDevices `mapstructure:",squash"` awscommon.AMIConfig `mapstructure:",squash"` - RootDevice RootBlockDevice `mapstructure:"ami_root_device"` - VolumeRunTags map[string]string `mapstructure:"run_volume_tags"` + RootDevice RootBlockDevice `mapstructure:"ami_root_device"` + VolumeRunTags awscommon.TagMap `mapstructure:"run_volume_tags"` ctx interpolate.Context } @@ -166,6 +166,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, InstanceType: b.config.InstanceType, + IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(), SourceAMI: b.config.SourceAmi, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, diff --git a/builder/amazon/ebsvolume/block_device.go b/builder/amazon/ebsvolume/block_device.go index 5a23821b3..0d2b04613 100644 --- a/builder/amazon/ebsvolume/block_device.go +++ b/builder/amazon/ebsvolume/block_device.go @@ -7,7 +7,7 @@ import ( type BlockDevice struct { awscommon.BlockDevice `mapstructure:"-,squash"` - Tags map[string]string `mapstructure:"tags"` + Tags awscommon.TagMap `mapstructure:"tags"` } func commonBlockDevices(mappings []BlockDevice, ctx *interpolate.Context) (awscommon.BlockDevices, error) { diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 83fc271fb..cdfda8e14 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -149,6 +149,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe IamInstanceProfile: b.config.IamInstanceProfile, InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior, InstanceType: b.config.InstanceType, + IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(), SourceAMI: b.config.SourceAmi, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, diff --git a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go index a638ec439..31e6799b1 100644 --- a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go +++ b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go/service/ec2" - awscommon "github.com/hashicorp/packer/builder/amazon/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -44,14 +43,14 @@ func (s *stepTagEBSVolumes) Run(_ context.Context, state multistep.StateBag) mul continue } - tags, err := awscommon.ConvertToEC2Tags(mapping.Tags, *ec2conn.Config.Region, *sourceAMI.ImageId, s.Ctx) + tags, err := mapping.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, *sourceAMI.ImageId) if err != nil { err := fmt.Errorf("Error tagging device %s with %s", mapping.DeviceName, err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } - awscommon.ReportTags(ui, tags) + tags.Report(ui) for _, v := range instance.BlockDeviceMappings { if *v.DeviceName == mapping.DeviceName { diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 828733a9f..98d9dc24d 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -232,6 +232,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EbsOptimized: b.config.EbsOptimized, IamInstanceProfile: b.config.IamInstanceProfile, InstanceType: b.config.InstanceType, + IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(), SourceAMI: b.config.SourceAmi, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, From 0ebdad293447c2b82c59a7ae7320d63af40db5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Wed, 7 Feb 2018 10:29:56 +0900 Subject: [PATCH 0586/1007] fix communicator type : Windows -> winrm --- builder/ncloud/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/ncloud/builder.go b/builder/ncloud/builder.go index b1aaef790..d5d546024 100644 --- a/builder/ncloud/builder.go +++ b/builder/ncloud/builder.go @@ -59,7 +59,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepDeleteBlockStorageInstance(conn, ui, b.config), NewStepTerminateServerInstance(conn, ui), } - } else if b.config.Comm.Type == "Windows" { + } else if b.config.Comm.Type == "winrm" { steps = []multistep.Step{ NewStepValidateTemplate(conn, ui, b.config), NewStepCreateLoginKey(conn, ui), From c29e5de38122872cab55cf049580ebd5e8517f6d Mon Sep 17 00:00:00 2001 From: Edward <freesky.edward@gmail.com> Date: Fri, 17 Nov 2017 10:28:15 +0800 Subject: [PATCH 0587/1007] Remove the deprecated extensions The Nova extension API was deprecated from OpenStack N release. this parts of code cannot work well with the newest OpenStack version. This patch is to remove the relative parts: 1. Remove the step_load_extensions.go 2. Remove the step of extension from builder.go 3. Remove the parameter parsing from step_stop_server.go Resolves: #5581 --- builder/openstack/builder.go | 1 - builder/openstack/step_load_extensions.go | 59 ----------------------- builder/openstack/step_stop_server.go | 7 --- 3 files changed, 67 deletions(-) mode change 100644 => 100755 builder/openstack/builder.go delete mode 100644 builder/openstack/step_load_extensions.go mode change 100644 => 100755 builder/openstack/step_stop_server.go diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go old mode 100644 new mode 100755 index f3c6fd13b..42770c625 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -70,7 +70,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // Build the steps steps := []multistep.Step{ - &StepLoadExtensions{}, &StepLoadFlavor{ Flavor: b.config.Flavor, }, diff --git a/builder/openstack/step_load_extensions.go b/builder/openstack/step_load_extensions.go deleted file mode 100644 index b11cf5527..000000000 --- a/builder/openstack/step_load_extensions.go +++ /dev/null @@ -1,59 +0,0 @@ -package openstack - -import ( - "context" - "fmt" - "log" - - "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions" - "github.com/gophercloud/gophercloud/pagination" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepLoadExtensions gets the FlavorRef from a Flavor. It first assumes -// that the Flavor is a ref and verifies it. Otherwise, it tries to find -// the flavor by name. -type StepLoadExtensions struct{} - -func (s *StepLoadExtensions) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(Config) - ui := state.Get("ui").(packer.Ui) - - // We need the v2 compute client - client, err := config.computeV2Client() - if err != nil { - err = fmt.Errorf("Error initializing compute client: %s", err) - state.Put("error", err) - return multistep.ActionHalt - } - - ui.Say("Discovering enabled extensions...") - result := make(map[string]struct{}, 15) - pager := extensions.List(client) - err = pager.EachPage(func(p pagination.Page) (bool, error) { - // Extract the extensions from this page - exts, err := extensions.ExtractExtensions(p) - if err != nil { - return false, err - } - - for _, ext := range exts { - log.Printf("[DEBUG] Discovered extension: %s", ext.Alias) - result[ext.Alias] = struct{}{} - } - - return true, nil - }) - if err != nil { - err = fmt.Errorf("Error loading extensions: %s", err) - state.Put("error", err) - return multistep.ActionHalt - } - - state.Put("extensions", result) - return multistep.ActionContinue -} - -func (s *StepLoadExtensions) Cleanup(state multistep.StateBag) { -} diff --git a/builder/openstack/step_stop_server.go b/builder/openstack/step_stop_server.go old mode 100644 new mode 100755 index 1c864eef0..4a0f867b0 --- a/builder/openstack/step_stop_server.go +++ b/builder/openstack/step_stop_server.go @@ -15,15 +15,8 @@ type StepStopServer struct{} func (s *StepStopServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) config := state.Get("config").(Config) - extensions := state.Get("extensions").(map[string]struct{}) server := state.Get("server").(*servers.Server) - // Verify we have the extension - if _, ok := extensions["os-server-start-stop"]; !ok { - ui.Say("OpenStack cluster doesn't support stop, skipping...") - return multistep.ActionContinue - } - // We need the v2 compute client client, err := config.computeV2Client() if err != nil { From c918e4113ffe1d2f2db5b4c41ad289e34df29987 Mon Sep 17 00:00:00 2001 From: Edward <freesky.edward@gmail.com> Date: Wed, 29 Nov 2017 10:36:05 +0800 Subject: [PATCH 0588/1007] Add the version note in OpenStack builder section --- website/source/docs/builders/openstack.html.md | 4 ++++ 1 file changed, 4 insertions(+) mode change 100644 => 100755 website/source/docs/builders/openstack.html.md diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md old mode 100644 new mode 100755 index 5406f90ed..709d39246 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -25,6 +25,9 @@ created. This simplifies configuration quite a bit. The builder does *not* manage images. Once it creates an image, it is up to you to use it or delete it. +~&gt; **Note:** To use OpenStack builder with the OpenStack Newton (Oct 2016) +or earlier, we recommend you use Packer v1.1.2 or earlier version. + ~&gt; **OpenStack Liberty or later requires OpenSSL!** To use the OpenStack builder with OpenStack Liberty (Oct 2015) or later you need to have OpenSSL installed *if you are using temporary key pairs*, i.e. don't use @@ -32,6 +35,7 @@ installed *if you are using temporary key pairs*, i.e. don't use [`ssh_password`](/docs/templates/communicator.html#ssh_password). All major OS'es have OpenSSL installed by default except Windows. + ## Configuration Reference There are many configuration options available for the builder. They are From 578de6ea890e6458e24b6887db7a10445f3ecbb4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 6 Feb 2018 17:39:28 -0800 Subject: [PATCH 0589/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e8424cb8..a8c3105e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] * 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will no longer compile (however existing builds will still work fine); the work to fix them is minimal and documented in GH-5810. [GH-5810] * provisioner/file: We've made destination semantics more consistent across the various communicators. In general, if the destination is a directory, files will be uploaded into the directory instead of failing. This mirrors the behavior of `rsync`. There's a chance some users might be depending on the previous buggy behavior, so it's worth ensuring your configuration is correct. [GH-5426] +* builder/openstack: Extension support has been removed. To use OpenStack builder with the OpenStack Newton (Oct 2016) or earlier, we recommend you use Packer v1.1.2 or earlier version. ### IMPROVEMENTS: From 2ae73162e506decfe4abca12bd3028183fef1344 Mon Sep 17 00:00:00 2001 From: James Cunningham <james.earl.3@gmail.com> Date: Tue, 6 Feb 2018 19:58:54 -0700 Subject: [PATCH 0590/1007] fix docs mountpoint typo --- website/source/docs/builders/amazon-chroot.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 1ffe84f38..3f7839fdc 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -335,7 +335,7 @@ chroot by Packer: These default mounts are usually good enough for anyone and are sane defaults. However, if you want to change or add the mount points, you may using the `chroot_mounts` configuration. Here is an example configuration which only -mounts `/prod` and `/dev`: +mounts `/proc` and `/dev`: ``` json { From f3c361de6bab206a7fc71f4f1bc2ba0764238ce4 Mon Sep 17 00:00:00 2001 From: Anthony Allen <anthony.allen@snowsoftware.com> Date: Wed, 7 Feb 2018 08:01:05 +0100 Subject: [PATCH 0591/1007] Fully qualify hyper-v powershell commands --- common/powershell/hyperv/hyperv.go | 166 ++++++++++++++--------------- common/powershell/powershell.go | 10 +- 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index d26ec5eeb..d5b58f5db 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -12,7 +12,7 @@ func GetHostAdapterIpAddressForSwitch(switchName string) (string, error) { var script = ` param([string]$switchName, [int]$addressIndex) -$HostVMAdapter = Get-VMNetworkAdapter -ManagementOS -SwitchName $switchName +$HostVMAdapter = Hyper-V\Get-VMNetworkAdapter -ManagementOS -SwitchName $switchName if ($HostVMAdapter){ $HostNetAdapter = Get-NetAdapter | ?{ $_.DeviceID -eq $HostVMAdapter.DeviceId } if ($HostNetAdapter){ @@ -36,7 +36,7 @@ func GetVirtualMachineNetworkAdapterAddress(vmName string) (string, error) { var script = ` param([string]$vmName, [int]$addressIndex) try { - $adapter = Get-VMNetworkAdapter -VMName $vmName -ErrorAction SilentlyContinue + $adapter = Hyper-V\Get-VMNetworkAdapter -VMName $vmName -ErrorAction SilentlyContinue $ip = $adapter.IPAddresses[$addressIndex] if($ip -eq $null) { return $false @@ -59,8 +59,8 @@ func CreateDvdDrive(vmName string, isoPath string, generation uint) (uint, uint, script = ` param([string]$vmName, [string]$isoPath) -$dvdController = Add-VMDvdDrive -VMName $vmName -path $isoPath -Passthru -$dvdController | Set-VMDvdDrive -path $null +$dvdController = Hyper-V\Add-VMDvdDrive -VMName $vmName -path $isoPath -Passthru +$dvdController | Hyper-V\Set-VMDvdDrive -path $null $result = "$($dvdController.ControllerNumber),$($dvdController.ControllerLocation)" $result ` @@ -94,9 +94,9 @@ func MountDvdDrive(vmName string, path string, controllerNumber uint, controller var script = ` param([string]$vmName,[string]$path,[string]$controllerNumber,[string]$controllerLocation) -$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation +$vmDvdDrive = Hyper-V\Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation if (!$vmDvdDrive) {throw 'unable to find dvd drive'} -Set-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation -Path $path +Hyper-V\Set-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation -Path $path ` var ps powershell.PowerShellCmd @@ -107,9 +107,9 @@ Set-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLo func UnmountDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error { var script = ` param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation) -$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation +$vmDvdDrive = Hyper-V\Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation if (!$vmDvdDrive) {throw 'unable to find dvd drive'} -Set-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation -Path $null +Hyper-V\Set-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation -Path $null ` var ps powershell.PowerShellCmd @@ -122,7 +122,7 @@ func SetBootDvdDrive(vmName string, controllerNumber uint, controllerLocation ui if generation < 2 { script := ` param([string]$vmName) -Set-VMBios -VMName $vmName -StartupOrder @("CD", "IDE","LegacyNetworkAdapter","Floppy") +Hyper-V\Set-VMBios -VMName $vmName -StartupOrder @("CD", "IDE","LegacyNetworkAdapter","Floppy") ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName) @@ -130,9 +130,9 @@ Set-VMBios -VMName $vmName -StartupOrder @("CD", "IDE","LegacyNetworkAdapter","F } else { script := ` param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation) -$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation +$vmDvdDrive = Hyper-V\Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation if (!$vmDvdDrive) {throw 'unable to find dvd drive'} -Set-VMFirmware -VMName $vmName -FirstBootDevice $vmDvdDrive -ErrorAction SilentlyContinue +Hyper-V\Set-VMFirmware -VMName $vmName -FirstBootDevice $vmDvdDrive -ErrorAction SilentlyContinue ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName, strconv.FormatInt(int64(controllerNumber), 10), strconv.FormatInt(int64(controllerLocation), 10)) @@ -143,9 +143,9 @@ Set-VMFirmware -VMName $vmName -FirstBootDevice $vmDvdDrive -ErrorAction Silentl func DeleteDvdDrive(vmName string, controllerNumber uint, controllerLocation uint) error { var script = ` param([string]$vmName,[int]$controllerNumber,[int]$controllerLocation) -$vmDvdDrive = Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation +$vmDvdDrive = Hyper-V\Get-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation if (!$vmDvdDrive) {throw 'unable to find dvd drive'} -Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation +Hyper-V\Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -ControllerLocation $controllerLocation ` var ps powershell.PowerShellCmd @@ -156,7 +156,7 @@ Remove-VMDvdDrive -VMName $vmName -ControllerNumber $controllerNumber -Controlle func DeleteAllDvdDrives(vmName string) error { var script = ` param([string]$vmName) -Get-VMDvdDrive -VMName $vmName | Remove-VMDvdDrive +Hyper-V\Get-VMDvdDrive -VMName $vmName | Hyper-V\Remove-VMDvdDrive ` var ps powershell.PowerShellCmd @@ -167,7 +167,7 @@ Get-VMDvdDrive -VMName $vmName | Remove-VMDvdDrive func MountFloppyDrive(vmName string, path string) error { var script = ` param([string]$vmName, [string]$path) -Set-VMFloppyDiskDrive -VMName $vmName -Path $path +Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $path ` var ps powershell.PowerShellCmd @@ -179,7 +179,7 @@ func UnmountFloppyDrive(vmName string) error { var script = ` param([string]$vmName) -Set-VMFloppyDiskDrive -VMName $vmName -Path $null +Hyper-V\Set-VMFloppyDiskDrive -VMName $vmName -Path $null ` var ps powershell.PowerShellCmd @@ -200,9 +200,9 @@ if ($harddrivePath){ } else { Copy-Item -Path $harddrivePath -Destination $vhdPath } - New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation + Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation } else { - New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation + Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation } ` var ps powershell.PowerShellCmd @@ -223,9 +223,9 @@ if ($harddrivePath){ else{ Copy-Item -Path $harddrivePath -Destination $vhdPath } - New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName + Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName } else { - New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName + Hyper-V\New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName } ` var ps powershell.PowerShellCmd @@ -244,8 +244,8 @@ if ($harddrivePath){ func DisableAutomaticCheckpoints(vmName string) error { var script = ` param([string]$vmName) -if ((Get-Command Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { - Set-Vm -Name $vmName -AutomaticCheckpointsEnabled $false } +if ((Get-Command Hyper-V\Set-Vm).Parameters["AutomaticCheckpointsEnabled"]) { + Hyper-V\Set-Vm -Name $vmName -AutomaticCheckpointsEnabled $false } ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName) @@ -265,22 +265,22 @@ if (Test-Path $WorkingPath) { $allSnapshots = [System.Boolean]::Parse($allSnapshotsString) if ($snapshotName) { - $snapshot = Get-VMSnapshot -VMName $vmName -Name $snapshotName - Export-VMSnapshot -VMSnapshot $snapshot -Path $exportPath -ErrorAction Stop + $snapshot = Hyper-V\Get-VMSnapshot -VMName $vmName -Name $snapshotName + Hyper-V\Export-VMSnapshot -VMSnapshot $snapshot -Path $exportPath -ErrorAction Stop } else { if (!$allSnapshots) { #Use last snapshot if one was not specified - $snapshot = Get-VMSnapshot -VMName $vmName | Select -Last 1 + $snapshot = Hyper-V\Get-VMSnapshot -VMName $vmName | Select -Last 1 } else { $snapshot = $null } if (!$snapshot) { #No snapshot clone - Export-VM -Name $vmName -Path $exportPath -ErrorAction Stop + Hyper-V\Export-VM -Name $vmName -Path $exportPath -ErrorAction Stop } else { #Snapshot clone - Export-VMSnapshot -VMSnapshot $snapshot -Path $exportPath -ErrorAction Stop + Hyper-V\Export-VMSnapshot -VMSnapshot $snapshot -Path $exportPath -ErrorAction Stop } } @@ -322,7 +322,7 @@ Copy-Item $cloneFromVmxcPath $exportPath -Recurse -Force func SetVmNetworkAdapterMacAddress(vmName string, mac string) error { var script = ` param([string]$vmName, [string]$mac) -Set-VMNetworkAdapter $vmName -staticmacaddress $mac +Hyper-V\Set-VMNetworkAdapter $vmName -staticmacaddress $mac ` var ps powershell.PowerShellCmd @@ -359,24 +359,24 @@ if (!$VirtualMachinePath){ $VirtualMachinePath = Get-ChildItem -Path $importPath -Filter *.xml -Recurse -ErrorAction SilentlyContinue | select -First 1 | %{$_.FullName} } -$compatibilityReport = Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy:$false +$compatibilityReport = Hyper-V\Compare-VM -Path $VirtualMachinePath -VirtualMachinePath $importPath -SmartPagingFilePath $importPath -SnapshotFilePath $importPath -VhdDestinationPath $VirtualHarddisksPath -GenerateNewId -Copy:$false if ($vhdPath){ Copy-Item -Path $harddrivePath -Destination $vhdPath $existingFirstHarddrive = $compatibilityReport.VM.HardDrives | Select -First 1 if ($existingFirstHarddrive) { - $existingFirstHarddrive | Set-VMHardDiskDrive -Path $vhdPath + $existingFirstHarddrive | Hyper-V\Set-VMHardDiskDrive -Path $vhdPath } else { - Add-VMHardDiskDrive -VM $compatibilityReport.VM -Path $vhdPath + Hyper-V\Add-VMHardDiskDrive -VM $compatibilityReport.VM -Path $vhdPath } } -Set-VMMemory -VM $compatibilityReport.VM -StartupBytes $memoryStartupBytes +Hyper-V\Set-VMMemory -VM $compatibilityReport.VM -StartupBytes $memoryStartupBytes $networkAdaptor = $compatibilityReport.VM.NetworkAdapters | Select -First 1 -Disconnect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -Connect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -SwitchName $switchName -$vm = Import-VM -CompatibilityReport $compatibilityReport +Hyper-V\Disconnect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor +Hyper-V\Connect-VMNetworkAdapter -VMNetworkAdapter $networkAdaptor -SwitchName $switchName +$vm = Hyper-V\Import-VM -CompatibilityReport $compatibilityReport if ($vm) { - $result = Rename-VM -VM $vm -NewName $VMName + $result = Hyper-V\Rename-VM -VM $vm -NewName $VMName } ` @@ -409,7 +409,7 @@ func CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, clone func GetVirtualMachineGeneration(vmName string) (uint, error) { var script = ` param([string]$vmName) -$generation = Get-Vm -Name $vmName | %{$_.Generation} +$generation = Hyper-V\Get-Vm -Name $vmName | %{$_.Generation} if (!$generation){ $generation = 1 } @@ -437,7 +437,7 @@ func SetVirtualMachineCpuCount(vmName string, cpu uint) error { var script = ` param([string]$vmName, [int]$cpu) -Set-VMProcessor -VMName $vmName -Count $cpu +Hyper-V\Set-VMProcessor -VMName $vmName -Count $cpu ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName, strconv.FormatInt(int64(cpu), 10)) @@ -449,7 +449,7 @@ func SetVirtualMachineVirtualizationExtensions(vmName string, enableVirtualizati var script = ` param([string]$vmName, [string]$exposeVirtualizationExtensionsString) $exposeVirtualizationExtensions = [System.Boolean]::Parse($exposeVirtualizationExtensionsString) -Set-VMProcessor -VMName $vmName -ExposeVirtualizationExtensions $exposeVirtualizationExtensions +Hyper-V\Set-VMProcessor -VMName $vmName -ExposeVirtualizationExtensions $exposeVirtualizationExtensions ` exposeVirtualizationExtensionsString := "False" if enableVirtualizationExtensions { @@ -465,7 +465,7 @@ func SetVirtualMachineDynamicMemory(vmName string, enableDynamicMemory bool) err var script = ` param([string]$vmName, [string]$enableDynamicMemoryString) $enableDynamicMemory = [System.Boolean]::Parse($enableDynamicMemoryString) -Set-VMMemory -VMName $vmName -DynamicMemoryEnabled $enableDynamicMemory +Hyper-V\Set-VMMemory -VMName $vmName -DynamicMemoryEnabled $enableDynamicMemory ` enableDynamicMemoryString := "False" if enableDynamicMemory { @@ -479,7 +479,7 @@ Set-VMMemory -VMName $vmName -DynamicMemoryEnabled $enableDynamicMemory func SetVirtualMachineMacSpoofing(vmName string, enableMacSpoofing bool) error { var script = ` param([string]$vmName, $enableMacSpoofing) -Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing $enableMacSpoofing +Hyper-V\Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing $enableMacSpoofing ` var ps powershell.PowerShellCmd @@ -496,7 +496,7 @@ Set-VMNetworkAdapter -VMName $vmName -MacAddressSpoofing $enableMacSpoofing func SetVirtualMachineSecureBoot(vmName string, enableSecureBoot bool) error { var script = ` param([string]$vmName, $enableSecureBoot) -Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot +Hyper-V\Set-VMFirmware -VMName $vmName -EnableSecureBoot $enableSecureBoot ` var ps powershell.PowerShellCmd @@ -515,12 +515,12 @@ func DeleteVirtualMachine(vmName string) error { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName +$vm = Hyper-V\Get-VM -Name $vmName if (($vm.State -ne [Microsoft.HyperV.PowerShell.VMState]::Off) -and ($vm.State -ne [Microsoft.HyperV.PowerShell.VMState]::OffCritical)) { - Stop-VM -VM $vm -TurnOff -Force -Confirm:$false + Hyper-V\Stop-VM -VM $vm -TurnOff -Force -Confirm:$false } -Remove-VM -Name $vmName -Force -Confirm:$false +Hyper-V\Remove-VM -Name $vmName -Force -Confirm:$false ` var ps powershell.PowerShellCmd @@ -532,12 +532,12 @@ func ExportVirtualMachine(vmName string, path string) error { var script = ` param([string]$vmName, [string]$path) -Export-VM -Name $vmName -Path $path +Hyper-V\Export-VM -Name $vmName -Path $path if (Test-Path -Path ([IO.Path]::Combine($path, $vmName, 'Virtual Machines', '*.VMCX'))) { - $vm = Get-VM -Name $vmName - $vm_adapter = Get-VMNetworkAdapter -VM $vm | Select -First 1 + $vm = Hyper-V\Get-VM -Name $vmName + $vm_adapter = Hyper-V\Get-VMNetworkAdapter -VM $vm | Select -First 1 $config = [xml]@" <?xml version="1.0" ?> @@ -571,17 +571,17 @@ if (Test-Path -Path ([IO.Path]::Combine($path, $vmName, 'Virtual Machines', '*.V if ($vm.Generation -eq 1) { - $vm_controllers = Get-VMIdeController -VM $vm + $vm_controllers = Hyper-V\Get-VMIdeController -VM $vm $controller_type = $config.SelectSingleNode('/configuration/vm-controllers') # IDE controllers are not stored in a special XML container } else { - $vm_controllers = Get-VMScsiController -VM $vm + $vm_controllers = Hyper-V\Get-VMScsiController -VM $vm $controller_type = $config.CreateElement('scsi') $controller_type.SetAttribute('ChannelInstanceGuid', 'x') # SCSI controllers are stored in the scsi XML container - if ((Get-VMFirmware -VM $vm).SecureBoot -eq [Microsoft.HyperV.PowerShell.OnOffState]::On) + if ((Hyper-V\Get-VMFirmware -VM $vm).SecureBoot -eq [Microsoft.HyperV.PowerShell.OnOffState]::On) { $config.configuration.secure_boot_enabled.'#text' = 'True' } @@ -663,9 +663,9 @@ func CreateVirtualSwitch(switchName string, switchType string) (bool, error) { var script = ` param([string]$switchName,[string]$switchType) -$switches = Get-VMSwitch -Name $switchName -ErrorAction SilentlyContinue +$switches = Hyper-V\Get-VMSwitch -Name $switchName -ErrorAction SilentlyContinue if ($switches.Count -eq 0) { - New-VMSwitch -Name $switchName -SwitchType $switchType + Hyper-V\New-VMSwitch -Name $switchName -SwitchType $switchType return $true } return $false @@ -681,9 +681,9 @@ func DeleteVirtualSwitch(switchName string) error { var script = ` param([string]$switchName) -$switch = Get-VMSwitch -Name $switchName -ErrorAction SilentlyContinue +$switch = Hyper-V\Get-VMSwitch -Name $switchName -ErrorAction SilentlyContinue if ($switch -ne $null) { - $switch | Remove-VMSwitch -Force -Confirm:$false + $switch | Hyper-V\Remove-VMSwitch -Force -Confirm:$false } ` @@ -696,9 +696,9 @@ func StartVirtualMachine(vmName string) error { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Off) { - Start-VM -Name $vmName -Confirm:$false + Hyper-V\Start-VM -Name $vmName -Confirm:$false } ` @@ -711,7 +711,7 @@ func RestartVirtualMachine(vmName string) error { var script = ` param([string]$vmName) -Restart-VM $vmName -Force -Confirm:$false +Hyper-V\Restart-VM $vmName -Force -Confirm:$false ` var ps powershell.PowerShellCmd @@ -723,9 +723,9 @@ func StopVirtualMachine(vmName string) error { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName +$vm = Hyper-V\Get-VM -Name $vmName if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running) { - Stop-VM -VM $vm -Force -Confirm:$false + Hyper-V\Stop-VM -VM $vm -Force -Confirm:$false } ` @@ -756,7 +756,7 @@ func EnableVirtualMachineIntegrationService(vmName string, integrationServiceNam var script = ` param([string]$vmName,[string]$integrationServiceId) -Get-VMIntegrationService -VmName $vmName | ?{$_.Id -match $integrationServiceId} | Enable-VMIntegrationService +Hyper-V\Get-VMIntegrationService -VmName $vmName | ?{$_.Id -match $integrationServiceId} | Hyper-V\Enable-VMIntegrationService ` var ps powershell.PowerShellCmd @@ -768,7 +768,7 @@ func SetNetworkAdapterVlanId(switchName string, vlanId string) error { var script = ` param([string]$networkAdapterName,[string]$vlanId) -Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $networkAdapterName -Access -VlanId $vlanId +Hyper-V\Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $networkAdapterName -Access -VlanId $vlanId ` var ps powershell.PowerShellCmd @@ -780,7 +780,7 @@ func SetVirtualMachineVlanId(vmName string, vlanId string) error { var script = ` param([string]$vmName,[string]$vlanId) -Set-VMNetworkAdapterVlan -VMName $vmName -Access -VlanId $vlanId +Hyper-V\Set-VMNetworkAdapterVlan -VMName $vmName -Access -VlanId $vlanId ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName, vlanId) @@ -792,7 +792,7 @@ func GetExternalOnlineVirtualSwitch() (string, error) { var script = ` $adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq 'Up' } | Sort-Object -Descending -Property Speed foreach ($adapter in $adapters) { - $switch = Get-VMSwitch -SwitchType External | Where-Object { $_.NetAdapterInterfaceDescription -eq $adapter.InterfaceDescription } + $switch = Hyper-V\Get-VMSwitch -SwitchType External | Where-Object { $_.NetAdapterInterfaceDescription -eq $adapter.InterfaceDescription } if ($switch -ne $null) { $switch.Name @@ -822,10 +822,10 @@ $adapters = foreach ($name in $names) { } foreach ($adapter in $adapters) { - $switch = Get-VMSwitch -SwitchType External | where { $_.NetAdapterInterfaceDescription -eq $adapter.InterfaceDescription } + $switch = Hyper-V\Get-VMSwitch -SwitchType External | where { $_.NetAdapterInterfaceDescription -eq $adapter.InterfaceDescription } if ($switch -eq $null) { - $switch = New-VMSwitch -Name $switchName -NetAdapterName $adapter.Name -AllowManagementOS $true -Notes 'Parent OS, VMs, WiFi' + $switch = Hyper-V\New-VMSwitch -Name $switchName -NetAdapterName $adapter.Name -AllowManagementOS $true -Notes 'Parent OS, VMs, WiFi' } if ($switch -ne $null) { @@ -834,7 +834,7 @@ foreach ($adapter in $adapters) { } if($switch -ne $null) { - Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -VMSwitch $switch + Hyper-V\Get-VMNetworkAdapter -VMName $vmName | Hyper-V\Connect-VMNetworkAdapter -VMSwitch $switch } else { Write-Error 'No internet adapters found' } @@ -848,7 +848,7 @@ func GetVirtualMachineSwitchName(vmName string) (string, error) { var script = ` param([string]$vmName) -(Get-VMNetworkAdapter -VMName $vmName).SwitchName +(Hyper-V\Get-VMNetworkAdapter -VMName $vmName).SwitchName ` var ps powershell.PowerShellCmd @@ -864,7 +864,7 @@ func ConnectVirtualMachineNetworkAdapterToSwitch(vmName string, switchName strin var script = ` param([string]$vmName,[string]$switchName) -Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -SwitchName $switchName +Hyper-V\Get-VMNetworkAdapter -VMName $vmName | Hyper-V\Connect-VMNetworkAdapter -SwitchName $switchName ` var ps powershell.PowerShellCmd @@ -878,7 +878,7 @@ func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName strin param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes, [string]$controllerType) $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdName New-VHD $vhdPath -SizeBytes $vhdSizeInBytes -Add-VMHardDiskDrive -VMName $vmName -path $vhdPath -controllerType $controllerType +Hyper-V\Add-VMHardDiskDrive -VMName $vmName -path $vhdPath -controllerType $controllerType ` var ps powershell.PowerShellCmd err := ps.Run(script, vmName, vhdRoot, vhdName, strconv.FormatInt(vhdSizeBytes, 10), controllerType) @@ -889,8 +889,8 @@ func UntagVirtualMachineNetworkAdapterVlan(vmName string, switchName string) err var script = ` param([string]$vmName,[string]$switchName) -Set-VMNetworkAdapterVlan -VMName $vmName -Untagged -Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $switchName -Untagged +Hyper-V\Set-VMNetworkAdapterVlan -VMName $vmName -Untagged +Hyper-V\Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $switchName -Untagged ` var ps powershell.PowerShellCmd @@ -902,7 +902,7 @@ func IsRunning(vmName string) (bool, error) { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue $vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running ` @@ -921,7 +921,7 @@ func IsOff(vmName string) (bool, error) { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue $vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Off ` @@ -940,7 +940,7 @@ func Uptime(vmName string) (uint64, error) { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue $vm.Uptime.TotalSeconds ` var ps powershell.PowerShellCmd @@ -959,7 +959,7 @@ func Mac(vmName string) (string, error) { var script = ` param([string]$vmName, [int]$adapterIndex) try { - $adapter = Get-VMNetworkAdapter -VMName $vmName -ErrorAction SilentlyContinue + $adapter = Hyper-V\Get-VMNetworkAdapter -VMName $vmName -ErrorAction SilentlyContinue $mac = $adapter[$adapterIndex].MacAddress if($mac -eq $null) { return "" @@ -980,7 +980,7 @@ func IpAddress(mac string) (string, error) { var script = ` param([string]$mac, [int]$addressIndex) try { - $ip = Get-Vm | %{$_.NetworkAdapters} | ?{$_.MacAddress -eq $mac} | %{$_.IpAddresses[$addressIndex]} + $ip = Hyper-V\Get-Vm | %{$_.NetworkAdapters} | ?{$_.MacAddress -eq $mac} | %{$_.IpAddresses[$addressIndex]} if($ip -eq $null) { return "" @@ -1001,9 +1001,9 @@ func TurnOff(vmName string) error { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running) { - Stop-VM -Name $vmName -TurnOff -Force -Confirm:$false + Hyper-V\Stop-VM -Name $vmName -TurnOff -Force -Confirm:$false } ` @@ -1016,9 +1016,9 @@ func ShutDown(vmName string) error { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue if ($vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running) { - Stop-VM -Name $vmName -Force -Confirm:$false + Hyper-V\Stop-VM -Name $vmName -Force -Confirm:$false } ` @@ -1036,7 +1036,7 @@ func TypeScanCodes(vmName string, scanCodes string) error { param([string]$vmName, [string]$scanCodes) #Requires -Version 3 - function Get-VMConsole + function Hyper-V\Get-VMConsole { [CmdletBinding()] param ( @@ -1164,7 +1164,7 @@ param([string]$vmName, [string]$scanCodes) return $console } - $vmConsole = Get-VMConsole -VMName $vmName + $vmConsole = Hyper-V\Get-VMConsole -VMName $vmName $scanCodesToSend = '' $scanCodes.Split(' ') | %{ $scanCode = $_ diff --git a/common/powershell/powershell.go b/common/powershell/powershell.go index 4d550cb8b..6540c7705 100644 --- a/common/powershell/powershell.go +++ b/common/powershell/powershell.go @@ -240,7 +240,7 @@ param([string]$moduleName) func HasVirtualMachineVirtualizationExtensions() (bool, error) { var script = ` -(GET-Command Set-VMProcessor).parameters.keys -contains "ExposeVirtualizationExtensions" +(GET-Command Hyper-V\Set-VMProcessor).parameters.keys -contains "ExposeVirtualizationExtensions" ` var ps PowerShellCmd @@ -258,7 +258,7 @@ func DoesVirtualMachineExist(vmName string) (bool, error) { var script = ` param([string]$vmName) -return (Get-VM | ?{$_.Name -eq $vmName}) -ne $null +return (Hyper-V\Get-VM | ?{$_.Name -eq $vmName}) -ne $null ` var ps PowerShellCmd @@ -276,7 +276,7 @@ func DoesVirtualMachineSnapshotExist(vmName string, snapshotName string) (bool, var script = ` param([string]$vmName, [string]$snapshotName) -return (Get-VMSnapshot -VMName $vmName | ?{$_.Name -eq $snapshotName}) -ne $null +return (Hyper-V\Get-VMSnapshot -VMName $vmName | ?{$_.Name -eq $snapshotName}) -ne $null ` var ps PowerShellCmd @@ -294,7 +294,7 @@ func IsVirtualMachineOn(vmName string) (bool, error) { var script = ` param([string]$vmName) -$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue +$vm = Hyper-V\Get-VM -Name $vmName -ErrorAction SilentlyContinue $vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running ` @@ -312,7 +312,7 @@ $vm.State -eq [Microsoft.HyperV.PowerShell.VMState]::Running func GetVirtualMachineGeneration(vmName string) (uint, error) { var script = ` param([string]$vmName) -$generation = Get-Vm -Name $vmName | %{$_.Generation} +$generation = Hyper-V\Get-Vm -Name $vmName | %{$_.Generation} if (!$generation){ $generation = 1 } From f8f256354f953d6a3cb01422a3babc4e3455e31f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 6 Feb 2018 16:53:26 -0800 Subject: [PATCH 0592/1007] use winrmcp logic when creating new winrm client for uploads and downloads --- communicator/winrm/communicator.go | 52 ++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go index 3970d1af8..6cf2bce37 100644 --- a/communicator/winrm/communicator.go +++ b/communicator/winrm/communicator.go @@ -128,12 +128,10 @@ func (c *Communicator) Upload(path string, input io.Reader, fi *os.FileInfo) err return err } - // Get information about destination path - endpoint := winrm.NewEndpoint(c.endpoint.Host, c.endpoint.Port, c.config.Https, c.config.Insecure, nil, nil, nil, c.config.Timeout) - client, err := winrm.NewClient(endpoint, c.config.Username, c.config.Password) if err != nil { return fmt.Errorf("Was unable to create winrm client: %s", err) } + client, err := c.newWinRMClient() stdout, _, _, err := client.RunWithString(fmt.Sprintf("powershell -Command \"(Get-Item %s) -is [System.IO.DirectoryInfo]\"", path), "") if err != nil { return fmt.Errorf("Couldn't determine whether destination was a folder or file: %s", err) @@ -162,8 +160,7 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error } func (c *Communicator) Download(src string, dst io.Writer) error { - endpoint := winrm.NewEndpoint(c.endpoint.Host, c.endpoint.Port, c.config.Https, c.config.Insecure, nil, nil, nil, c.config.Timeout) - client, err := winrm.NewClient(endpoint, c.config.Username, c.config.Password) + client, err := c.newWinRMClient() if err != nil { return err } @@ -182,9 +179,8 @@ func (c *Communicator) DownloadDir(src string, dst string, exclude []string) err return fmt.Errorf("WinRM doesn't support download dir.") } -func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) { - addr := fmt.Sprintf("%s:%d", c.endpoint.Host, c.endpoint.Port) - return winrmcp.New(addr, &winrmcp.Config{ +func (c *Communicator) getClientConfig() *winrmcp.Config { + return &winrmcp.Config{ Auth: winrmcp.Auth{ User: c.config.Username, Password: c.config.Password, @@ -194,7 +190,45 @@ func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) { OperationTimeout: c.config.Timeout, MaxOperationsPerShell: 15, // lowest common denominator TransportDecorator: c.config.TransportDecorator, - }) + } +} + +func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) { + addr := fmt.Sprintf("%s:%d", c.endpoint.Host, c.endpoint.Port) + clientConfig := c.getClientConfig() + return winrmcp.New(addr, clientConfig) +} + +func (c *Communicator) newWinRMClient() (*winrm.Client, error) { + conf := c.getClientConfig() + + // Shamelessly borrowed from the winrmcp client to ensure + // that the client is configured using the same defaulting behaviors that + // winrmcp uses even we we aren't using winrmcp. This ensures similar + // behavior between upload, download, and copy functions. We can't use the + // one generated by winrmcp because it isn't exported. + var endpoint *winrm.Endpoint + endpoint = &winrm.Endpoint{ + Host: c.endpoint.Host, + Port: c.endpoint.Port, + HTTPS: conf.Https, + Insecure: conf.Insecure, + TLSServerName: conf.TLSServerName, + CACert: conf.CACertBytes, + Timeout: conf.ConnectTimeout, + } + params := winrm.NewParameters( + winrm.DefaultParameters.Timeout, + winrm.DefaultParameters.Locale, + winrm.DefaultParameters.EnvelopeSize, + ) + + params.TransportDecorator = conf.TransportDecorator + params.Timeout = "PT3M" + + client, err := winrm.NewClientWithParameters( + endpoint, conf.Auth.User, conf.Auth.Password, params) + return client, err } type Base64Pipe struct { From 974d9974fe1d6aaa0dc99f3abaec2159b2864f45 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 7 Feb 2018 11:34:18 -0800 Subject: [PATCH 0593/1007] add workaround for azure bug. --- provisioner/windows-restart/provisioner.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/provisioner/windows-restart/provisioner.go b/provisioner/windows-restart/provisioner.go index 0568516aa..ecf15e6a1 100644 --- a/provisioner/windows-restart/provisioner.go +++ b/provisioner/windows-restart/provisioner.go @@ -114,6 +114,12 @@ var waitForRestart = func(p *Provisioner, comm packer.Communicator) error { var cmd *packer.RemoteCmd trycommand := TryCheckReboot abortcommand := AbortReboot + + // This sleep works around an azure/winrm bug. For more info see + // https://github.com/hashicorp/packer/issues/5257; we can remove the + // sleep when the underlying bug has been resolved. + time.Sleep(1 * time.Second) + // Stolen from Vagrant reboot checker for { log.Printf("Check if machine is rebooting...") From c03ce222b20404d0cd97f906f3dca0a5f042f985 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 7 Feb 2018 15:45:00 -0800 Subject: [PATCH 0594/1007] add atlas deprecation warnings. --- command/push.go | 24 +++++++++++++++++------- post-processor/atlas/post-processor.go | 11 +++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/command/push.go b/command/push.go index 723e9d92c..f063ae0d3 100644 --- a/command/push.go +++ b/command/push.go @@ -183,15 +183,15 @@ func (c *PushCommand) Run(args []string) int { info := &uploadBuildInfo{Type: b.Type} // todo: remove post-migration if b.Type == "vagrant" { - c.Ui.Message("\n-----------------------------------------------------------------------------------\n" + - "Warning: Vagrant-related functionality will be moved from Terraform Enterprise into \n" + - "its own product, Vagrant Cloud. This migration is currently planned for June 27th, \n" + - "2017 at 6PM EDT/3PM PDT/10PM UTC. For more information see \n" + + c.Ui.Error("\n-----------------------------------------------------------------------------------\n" + + "Vagrant-related functionality has been moved from Terraform Enterprise into \n" + + "its own product, Vagrant Cloud. For more information see " + "https://www.vagrantup.com/docs/vagrant-cloud/vagrant-cloud-migration.html\n" + - "In the meantime, you should activate your Vagrant Cloud account and replace your \n" + - "Atlas post-processor with the Vagrant Cloud post-processor. See\n" + - "https://www.packer.io/docs/post-processors/vagrant-cloud.html for more details." + + "Please replace the Atlas post-processor with the Vagrant Cloud post-processor,\n" + + "and see https://www.packer.io/docs/post-processors/vagrant-cloud.html for\n" + + "more detail.\n" + "-----------------------------------------------------------------------------------\n") + return 1 } // Determine if we're artifacting this build @@ -251,6 +251,16 @@ func (c *PushCommand) Run(args []string) int { "Builds: %s\n\n", strings.Join(badBuilds, ", "))) } + c.Ui.Message("\n-----------------------------------------------------------------------\n" + + "Deprecation warning: The Packer and Artifact Registry features of Atlas\n" + + "will no longer be actively developed or maintained and will be fully\n" + + "decommissioned on Friday, March 30, 2018. Please see our guide on\n" + + "building immutable infrastructure with Packer on CI/CD for ideas on\n" + + "implementing these features yourself:\n" + + "https://www.packer.io/guides/packer-on-cicd/\n" + + "-----------------------------------------------------------------------\n", + ) + // Start the archiving process r, err := archive.CreateArchive(path, &opts) if err != nil { diff --git a/post-processor/atlas/post-processor.go b/post-processor/atlas/post-processor.go index 9b06e61ec..a0df0db06 100644 --- a/post-processor/atlas/post-processor.go +++ b/post-processor/atlas/post-processor.go @@ -151,6 +151,17 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac "and see https://www.packer.io/docs/post-processors/vagrant-cloud.html for\n" + "more detail.\n") } + + ui.Message("\n-----------------------------------------------------------------------\n" + + "Deprecation warning: The Packer and Artifact Registry features of Atlas\n" + + "will no longer be actively developed or maintained and will be fully\n" + + "decommissioned on Friday, March 30, 2018. Please see our guide on\n" + + "building immutable infrastructure with Packer on CI/CD for ideas on\n" + + "implementing these features yourself:\n" + + "https://www.packer.io/guides/packer-on-cicd/\n" + + "-----------------------------------------------------------------------\n", + ) + if _, err := p.client.Artifact(p.config.user, p.config.name); err != nil { if err != atlas.ErrNotFound { return nil, false, fmt.Errorf( From 5d67f77f4325b7c9922e72170f52030fa9dfade0 Mon Sep 17 00:00:00 2001 From: Marc Mercer <mmercer@apixio.com> Date: Wed, 7 Feb 2018 19:41:01 -0800 Subject: [PATCH 0595/1007] Fixing 5852 --- provisioner/ansible/provisioner.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index 18965d220..4992b532c 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -327,7 +327,11 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri p.config.PackerBuildName, p.config.PackerBuilderType), "-i", inventory, playbook} if len(privKeyFile) > 0 { - args = append(args, "--private-key", privKeyFile) + // Changed this from using --private-key to supplying -e ansible_ssh_private_key as the latter + // is treated as a highest priority variable, and thus prevents overriding by dynamic variables + // as seen in #5852 + // args = append(args, "--private-key", privKeyFile) + args = append(args, "-e", fmt.Sprintf("ansible_ssh_private_key_file=%s", privKeyFile)) } args = append(args, p.config.ExtraArguments...) if len(p.config.AnsibleEnvVars) > 0 { From d3c7d43f20236706414c735012280e72baf38223 Mon Sep 17 00:00:00 2001 From: Marc Mercer <mmercer@apixio.com> Date: Wed, 7 Feb 2018 19:47:01 -0800 Subject: [PATCH 0596/1007] Small typo correction --- provisioner/ansible/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index 4992b532c..2984e496a 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -327,7 +327,7 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri p.config.PackerBuildName, p.config.PackerBuilderType), "-i", inventory, playbook} if len(privKeyFile) > 0 { - // Changed this from using --private-key to supplying -e ansible_ssh_private_key as the latter + // Changed this from using --private-key to supplying -e ansible_ssh_private_key_file as the latter // is treated as a highest priority variable, and thus prevents overriding by dynamic variables // as seen in #5852 // args = append(args, "--private-key", privKeyFile) From 22666153f9b2161adb9929d2547ae1901adf6e84 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 7 Feb 2018 20:16:15 -0800 Subject: [PATCH 0597/1007] Add `winrm_no_proxy` option. Setting this adds the remote host:ip to the `NO_PROXY` environment variable. --- helper/communicator/config.go | 9 ++++--- helper/communicator/step_connect_test.go | 24 +++++++++++++++++ helper/communicator/step_connect_winrm.go | 26 +++++++++++++++++++ .../docs/templates/communicator.html.md | 15 +++++++---- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/helper/communicator/config.go b/helper/communicator/config.go index f2664b192..52b81a3a6 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -41,14 +41,15 @@ type Config struct { SSHReadWriteTimeout time.Duration `mapstructure:"ssh_read_write_timeout"` // WinRM - WinRMUser string `mapstructure:"winrm_username"` - WinRMPassword string `mapstructure:"winrm_password"` WinRMHost string `mapstructure:"winrm_host"` + WinRMInsecure bool `mapstructure:"winrm_insecure"` + WinRMNoProxy bool `mapstructure:"winrm_no_proxy"` + WinRMPassword string `mapstructure:"winrm_password"` WinRMPort int `mapstructure:"winrm_port"` WinRMTimeout time.Duration `mapstructure:"winrm_timeout"` - WinRMUseSSL bool `mapstructure:"winrm_use_ssl"` - WinRMInsecure bool `mapstructure:"winrm_insecure"` WinRMUseNTLM bool `mapstructure:"winrm_use_ntlm"` + WinRMUseSSL bool `mapstructure:"winrm_use_ssl"` + WinRMUser string `mapstructure:"winrm_username"` WinRMTransportDecorator func() winrm.Transporter } diff --git a/helper/communicator/step_connect_test.go b/helper/communicator/step_connect_test.go index fb61f6463..6db32fba5 100644 --- a/helper/communicator/step_connect_test.go +++ b/helper/communicator/step_connect_test.go @@ -3,10 +3,12 @@ package communicator import ( "bytes" "context" + "os" "testing" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "github.com/stretchr/testify/assert" ) func TestStepConnect_impl(t *testing.T) { @@ -29,6 +31,28 @@ func TestStepConnect_none(t *testing.T) { } } +var noProxyTests = []struct { + current string + expected string +}{ + {"", "foo:1"}, + {"foo:1", "foo:1"}, + {"foo:1,bar:2", "foo:1,bar:2"}, + {"bar:2", "bar:2,foo:1"}, +} + +func TestStepConnect_setNoProxy(t *testing.T) { + key := "NO_PROXY" + for _, tt := range noProxyTests { + if value := os.Getenv(key); value != "" { + os.Unsetenv(key) + defer func() { os.Setenv(key, value) }() + os.Setenv(key, tt.current) + assert.Equal(t, tt.expected, os.Getenv(key), "env not set correctly.") + } + } +} + func testState(t *testing.T) multistep.StateBag { state := new(multistep.BasicStateBag) state.Put("hook", &packer.MockHook{}) diff --git a/helper/communicator/step_connect_winrm.go b/helper/communicator/step_connect_winrm.go index 06e6236f8..cdda73a5a 100644 --- a/helper/communicator/step_connect_winrm.go +++ b/helper/communicator/step_connect_winrm.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "log" + "os" "strings" "time" @@ -128,6 +129,12 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, cancel <-chan } } + if s.Config.WinRMNoProxy { + if err := setNoProxy(host, port); err != nil { + return nil, fmt.Errorf("Error setting no_proxy: %s", err) + } + } + log.Println("[INFO] Attempting WinRM connection...") comm, err = winrm.New(&winrm.Config{ Host: host, @@ -182,3 +189,22 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, cancel <-chan return comm, nil } + +// setNoProxy configures the $NO_PROXY env var +func setNoProxy(host string, port int) error { + current := os.Getenv("NO_PROXY") + p := fmt.Sprintf("%s:%d", host, port) + // not set + // set + // is set and not contains + // set + // is set and contains + if current == "" { + return os.Setenv("NO_PROXY", p) + } + if !strings.Contains(current, p) { + return os.Setenv("NO_PROXY", strings.Join([]string{current, p}, ",")) + } + return nil + +} diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 0165ab5a1..db768a90a 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -139,16 +139,21 @@ The WinRM communicator has the following options. - `winrm_password` (string) - The password to use to connect to WinRM. +- `winrm_insecure` (boolean) - If true, do not check server certificate + chain and host name + +* `winrm_no_proxy` (boolean) - Setting this to `true` adds the remote + `host:post` to the `NO_PROXY` environment variable. This has the effect of + bypassing any configured proxies when connecting to the remote host. + Default to `false`. + - `winrm_timeout` (string) - The amount of time to wait for WinRM to become available. This defaults to "30m" since setting up a Windows machine generally takes a long time. -- `winrm_use_ssl` (boolean) - If true, use HTTPS for WinRM - -- `winrm_insecure` (boolean) - If true, do not check server certificate - chain and host name - - `winrm_use_ntlm` (boolean) - If true, NTLM authentication will be used for WinRM, rather than default (basic authentication), removing the requirement for basic authentication to be enabled within the target guest. Further reading for remote connection authentication can be found [here](https://msdn.microsoft.com/en-us/library/aa384295(v=vs.85).aspx). + +- `winrm_use_ssl` (boolean) - If true, use HTTPS for WinRM From 478589abec270dd76afea0abff85aa1ddcbf76ca Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 25 Oct 2017 13:50:58 +0100 Subject: [PATCH 0598/1007] Extend upload and subsequent 'dot sourcing' of env vars to std PS command * Wrap funcs to flatten and upload env vars with new func prepareEnvVars. While the wrapped funcs could be combined, keeping them separate simplifies testing. * Configure/refactor std and elevated PS to use new funcs to prepare, upload and dot source env vars. * Dot sourcing the env vars in this way avoids the need to embed them directly in the command string. This avoids the need to escape the env vars to ensure the command string is correctly parsed. * Characters within the env vars that are special to PS (such as $'s and backticks) will still need to be escaped to allow them to be correctly interpreted by PS. * The std and elevated PS commands now inject env vars into the remote env via the same mechanism. This ensures consistent behaviour across the two command types. Fixes #5471 --- provisioner/powershell/provisioner.go | 52 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 4297acf08..8b9b53440 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -113,7 +113,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.EnvVarFormat == "" { - p.config.EnvVarFormat = `$env:%s=\"%s\"; ` + p.config.EnvVarFormat = `$env:%s="%s"; ` } if p.config.ElevatedEnvVarFormat == "" { @@ -121,7 +121,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.ExecuteCommand == "" { - p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` + p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"` } if p.config.ElevatedExecuteCommand == "" { @@ -331,6 +331,19 @@ func (p *Provisioner) retryable(f func() error) error { } } +// Enviroment variables required within the remote environment are uploaded within a PS script and +// then enabled by 'dot sourcing' the script immediately prior to execution of the main command +func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err error) { + // Collate all required env vars into a plain string with required formatting applied + flattenedEnvVars := p.createFlattenedEnvVars(elevated) + // Create a powershell script on the target build fs containing the flattened env vars + envVarPath, err = p.uploadEnvVars(flattenedEnvVars) + if err != nil { + return "", err + } + return +} + func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { flattened = "" envVars := make(map[string]string) @@ -367,6 +380,19 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { return } +func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (envVarPath string, err error) { + // Upload all env vars to a powershell script on the target build file system + envVarReader := strings.NewReader(flattenedEnvVars) + uuid := uuid.TimeOrderedUUID() + envVarPath = fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) + log.Printf("Uploading env vars to %s", envVarPath) + err = p.communicator.Upload(envVarPath, envVarReader, nil) + if err != nil { + return "", fmt.Errorf("Error uploading ps script containing env vars: %s", err) + } + return +} + func (p *Provisioner) createCommandText() (command string, err error) { // Return the interpolated command if p.config.ElevatedUser == "" { @@ -377,12 +403,15 @@ func (p *Provisioner) createCommandText() (command string, err error) { } func (p *Provisioner) createCommandTextNonPrivileged() (command string, err error) { - // Create environment variables to set before executing the command - flattenedEnvVars := p.createFlattenedEnvVars(false) + // Prepare everything needed to enable the required env vars within the remote environment + envVarPath, err := p.prepareEnvVars(false) + if err != nil { + return "", err + } p.config.ctx.Data = &ExecuteCommandTemplate{ - Vars: flattenedEnvVars, Path: p.config.RemotePath, + Vars: envVarPath, } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -395,17 +424,10 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro } func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { - // Can't double escape the env vars, lets create shiny new ones - flattenedEnvVars := p.createFlattenedEnvVars(true) - // Need to create a mini ps1 script containing all of the environment variables we want; - // we'll be dot-sourcing this later - envVarReader := strings.NewReader(flattenedEnvVars) - uuid := uuid.TimeOrderedUUID() - envVarPath := fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) - log.Printf("Uploading env vars to %s", envVarPath) - err = p.communicator.Upload(envVarPath, envVarReader, nil) + // Prepare everything needed to enable the required env vars within the remote environment + envVarPath, err := p.prepareEnvVars(true) if err != nil { - return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) + return "", err } p.config.ctx.Data = &ExecuteCommandTemplate{ From a7b118ed94791a96056992398db8257d1a779a38 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 25 Oct 2017 22:47:08 +0100 Subject: [PATCH 0599/1007] Fix tests post changes. Add test for upload func. --- provisioner/powershell/provisioner_test.go | 85 +++++++++++++++------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index e7e64d52e..749564d4d 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -79,8 +79,8 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { t.Error("expected elevated_password to be empty") } - if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` { - t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) + if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"` { + t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand) } if p.config.ElevatedExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` { @@ -403,7 +403,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { ui := testUi() p := new(Provisioner) - // Defaults provided by Packer + // Defaults provided by Packer - env vars should not appear in cmd p.config.PackerBuildName = "vmware" p.config.PackerBuilderType = "iso" comm := new(packer.MockCommunicator) @@ -413,11 +413,14 @@ func TestProvisionerProvision_Inline(t *testing.T) { t.Fatal("should not have error") } - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd := comm.StartCmd.Command + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } + // User supplied env vars should not change things envVars := make([]string, 2) envVars[0] = "FOO=BAR" envVars[1] = "BAR=BAZ" @@ -430,9 +433,11 @@ func TestProvisionerProvision_Inline(t *testing.T) { t.Fatal("should not have error") } - expectedCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd = comm.StartCmd.Command + re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + matched = re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } } @@ -455,11 +460,12 @@ func TestProvisionerProvision_Scripts(t *testing.T) { t.Fatal("should not have error") } - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd := comm.StartCmd.Command + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } - } func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { @@ -488,9 +494,11 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { t.Fatal("should not have error") } - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` - if comm.StartCmd.Command != expectedCommand { - t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) + cmd := comm.StartCmd.Command + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } } @@ -547,11 +555,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { {"FOO==bar"}, // User env var with value starting with equals } expected := []string{ - `$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:BAZ=\"qux\"; $env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:FOO=\"bar=baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, - `$env:FOO=\"=bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `, + `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, } p := new(Provisioner) @@ -571,7 +579,6 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { } func TestProvision_createCommandText(t *testing.T) { - config := testConfig() config["remote_path"] = "c:/Windows/Temp/script.ps1" p := new(Provisioner) @@ -586,22 +593,46 @@ func TestProvision_createCommandText(t *testing.T) { // Non-elevated cmd, _ := p.createCommandText() - expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"` - - if cmd != expectedCommand { - t.Fatalf("Expected Non-elevated command: %s, got %s", expectedCommand, cmd) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + matched := re.MatchString(cmd) + if !matched { + t.Fatalf("Got unexpected command: %s", cmd) } // Elevated p.config.ElevatedUser = "vagrant" p.config.ElevatedPassword = "vagrant" cmd, _ = p.createCommandText() - matched, _ := regexp.MatchString("powershell -executionpolicy bypass -file \"%TEMP%(.{1})packer-elevated-shell.*", cmd) + re = regexp.MustCompile(`powershell -executionpolicy bypass -file "%TEMP%\\packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) + matched = re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected elevated command: %s", cmd) } } +func TestProvision_uploadEnvVars(t *testing.T) { + p := new(Provisioner) + comm := new(packer.MockCommunicator) + p.communicator = comm + + flattenedEnvVars := `$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild";` + + envVarPath, err := p.uploadEnvVars(flattenedEnvVars) + if err != nil { + t.Fatalf("Did not expect error: %s", err.Error()) + } + + if comm.UploadCalled != true { + t.Fatalf("Failed to upload env var file") + } + + re := regexp.MustCompile(`\${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1`) + matched := re.MatchString(envVarPath) + if !matched { + t.Fatalf("Got unexpected path for env var file: %s", envVarPath) + } +} + func TestProvision_generateElevatedShellRunner(t *testing.T) { // Non-elevated From 2b1aa0458340692fe755ef6423ea6911573c107e Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 7 Feb 2018 15:47:21 +0000 Subject: [PATCH 0600/1007] Update docs to reflect new upload and dot source of env var for std ps cmd --- .../docs/provisioners/powershell.html.md | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index f085a6e82..1eabd848c 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -29,20 +29,21 @@ The example below is fully functional. ## Configuration Reference The reference of available configuration options is listed below. The only -required element is either "inline" or "script". Every other option is optional. +required element is either "inline" or "script". Every other option is +optional. Exactly *one* of the following is required: - `inline` (array of strings) - This is an array of commands to execute. The - commands are concatenated by newlines and turned into a single file, so they - are all executed within the same context. This allows you to change + commands are concatenated by newlines and turned into a single file, so + they are all executed within the same context. This allows you to change directories in one command and use something in the directory in the next and so on. Inline scripts are the easiest way to pull off simple tasks within the machine. - `script` (string) - The path to a script to upload and execute in - the machine. This path can be absolute or relative. If it is relative, it is - relative to the working directory when Packer is executed. + the machine. This path can be absolute or relative. If it is relative, it + is relative to the working directory when Packer is executed. - `scripts` (array of strings) - An array of scripts to execute. The scripts will be uploaded and executed in the order specified. Each script is @@ -51,12 +52,12 @@ Exactly *one* of the following is required: Optional parameters: -- `binary` (boolean) - If true, specifies that the script(s) are binary files, - and Packer should therefore not convert Windows line endings to Unix line - endings (if there are any). By default this is false. +- `binary` (boolean) - If true, specifies that the script(s) are binary + files, and Packer should therefore not convert Windows line endings to Unix + line endings (if there are any). By default this is false. -- `elevated_execute_command` (string) - The command to use to execute the elevated - script. By default this is as follows: +- `elevated_execute_command` (string) - The command to use to execute the + elevated script. By default this is as follows: ``` powershell powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }" @@ -65,32 +66,34 @@ Optional parameters: The value of this is treated as [configuration template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and - `Vars`, which is the location of a temp file containing the list of `environment_vars`, if configured. + `Vars`, which is the location of a temp file containing the list of + `environment_vars`, if configured. - `environment_vars` (array of strings) - An array of key/value pairs to inject prior to the execute\_command. The format should be `key=value`. - Packer injects some environmental variables by default into the environment, - as well, which are covered in the section below. + Packer injects some environmental variables by default into the + environment, as well, which are covered in the section below. - `execute_command` (string) - The command to use to execute the script. By default this is as follows: ``` powershell - powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }" + powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }" ``` The value of this is treated as [configuration template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and - `Vars`, which is the list of `environment_vars`, if configured. + `Vars`, which is the location of a temp file containing the list of + `environment_vars`, if configured. - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given Windows user. - `remote_path` (string) - The path where the script will be uploaded to in - the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must be a - writable location and any parent directories must already exist. + the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must + be a writable location and any parent directories must already exist. - `start_retry_timeout` (string) - The amount of time to attempt to *start* the remote process. By default this is "5m" or 5 minutes. This setting @@ -111,9 +114,10 @@ commonly useful environmental variables: This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. -- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create the - machine that the script is running on. This is useful if you want to run - only certain parts of the script on systems built with certain builders. +- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create + the machine that the script is running on. This is useful if you want to + run only certain parts of the script on systems built with certain + builders. - `PACKER_HTTP_ADDR` If using a builder that provides an http server for file transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this From e982bc4ea5af42d66c34dd56fa511c83602b3431 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 7 Feb 2018 15:51:58 +0000 Subject: [PATCH 0601/1007] Fix copy/paste of description from shell provisioner --- website/source/docs/provisioners/powershell.html.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index 1eabd848c..ae897489f 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -1,8 +1,8 @@ --- description: | - The shell Packer provisioner provisions machines built by Packer using shell - scripts. Shell provisioning is the easiest way to get software installed and - configured on a machine. + The PowerShell Packer provisioner runs PowerShell scripts on Windows + machines. + It assumes that the communicator in use is WinRM. layout: docs page_title: 'PowerShell - Provisioners' sidebar_current: 'docs-provisioners-powershell' From aaf7102b9a7a5ba71e79ee5f78e7629858944568 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 21 Sep 2017 23:26:14 +0100 Subject: [PATCH 0602/1007] Tests for escape of chars special to PowerShell in user supplied data --- provisioner/powershell/provisioner_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 749564d4d..2791601fa 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -518,6 +518,12 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { {"FOO=bar", "BAZ=qux"}, // Multiple user env vars {"FOO=bar=baz"}, // User env var with value containing equals {"FOO==bar"}, // User env var with value starting with equals + // Test escaping of characters special to PowerShell + {"FOO=bar$baz"}, // User env var with value containing dollar + {"FOO=bar\"baz"}, // User env var with value containing a double quote + {"FOO=bar'baz"}, // User env var with value containing a single quote + {"FOO=bar`baz"}, // User env var with value containing a backtick + } expected := []string{ `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, @@ -525,6 +531,10 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) { `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", } p := new(Provisioner) @@ -553,6 +563,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { {"FOO=bar", "BAZ=qux"}, // Multiple user env vars {"FOO=bar=baz"}, // User env var with value containing equals {"FOO==bar"}, // User env var with value starting with equals + // Test escaping of characters special to PowerShell + {"FOO=bar$baz"}, // User env var with value containing dollar + {"FOO=bar\"baz"}, // User env var with value containing a double quote + {"FOO=bar'baz"}, // User env var with value containing a single quote + {"FOO=bar`baz"}, // User env var with value containing a backtick } expected := []string{ `$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, @@ -560,6 +575,10 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) { `$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, `$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `, + "$env:FOO=\"bar`$baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`\"baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar`'baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", + "$env:FOO=\"bar``baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; ", } p := new(Provisioner) From 2d830d5d43c5136ee7498fe297cd48d0b17ae59b Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Sun, 15 Oct 2017 13:28:59 +0100 Subject: [PATCH 0603/1007] Auto escape chars special to PowerShell in user supplied data --- provisioner/powershell/provisioner.go | 34 +++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 8b9b53440..92f881314 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -24,6 +24,13 @@ import ( var retryableSleep = 2 * time.Second +var psEscape = strings.NewReplacer( + "$", "`$", + "\"", "`\"", + "`", "``", + "'", "`'", +) + type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -359,7 +366,13 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Split vars into key/value components for _, envVar := range p.config.Vars { keyValue := strings.SplitN(envVar, "=", 2) - envVars[keyValue[0]] = keyValue[1] + // Escape chars special to PS in each env var value + escapedEnvVarValue := psEscape.Replace(keyValue[1]) + if escapedEnvVarValue != keyValue[1] { + log.Printf("Env var %s converted to %s after escaping chars special to PS", keyValue[1], + escapedEnvVarValue) + } + envVars[keyValue[0]] = escapedEnvVarValue } // Create a list of env var keys in sorted order @@ -480,13 +493,26 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } escapedCommand := buffer.String() log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) - buffer.Reset() + // Escape chars special to PowerShell in the ElevatedUser string + escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) + if escapedElevatedUser != p.config.ElevatedUser { + log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedUser, escapedElevatedUser) + } + + // Escape chars special to PowerShell in the ElevatedPassword string + escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) + if escapedElevatedPassword != p.config.ElevatedPassword { + log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedPassword, escapedElevatedPassword) + } + // Generate command err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: p.config.ElevatedUser, - Password: p.config.ElevatedPassword, + User: escapedElevatedUser, + Password: escapedElevatedPassword, TaskName: taskName, TaskDescription: "Packer elevated task", LogFile: logFile, From 4cc078256d4bcbde8874641a39a3aa58ca067dc2 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Mon, 30 Oct 2017 00:14:06 +0000 Subject: [PATCH 0604/1007] Fixer for templates affected by auto escape of special powershell chars --- fix/fixer.go | 2 + fix/fixer_powershell_escapes.go | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 fix/fixer_powershell_escapes.go diff --git a/fix/fixer.go b/fix/fixer.go index 5ca0b3a18..d5622b299 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -34,6 +34,7 @@ func init() { "amazon-shutdown_behavior": new(FixerAmazonShutdownBehavior), "amazon-enhanced-networking": new(FixerAmazonEnhancedNetworking), "docker-email": new(FixerDockerEmail), + "powershell-escapes": new(FixerPowerShellEscapes), } FixerOrder = []string{ @@ -51,5 +52,6 @@ func init() { "amazon-shutdown_behavior", "amazon-enhanced-networking", "docker-email", + "powershell-escapes", } } diff --git a/fix/fixer_powershell_escapes.go b/fix/fixer_powershell_escapes.go new file mode 100644 index 000000000..9da9ae91f --- /dev/null +++ b/fix/fixer_powershell_escapes.go @@ -0,0 +1,73 @@ +package fix + +import ( + "github.com/mitchellh/mapstructure" + "strings" +) + +// FixerPowerShellEscapes removes the PowerShell escape character from user +// environment variables and elevated username and password strings +type FixerPowerShellEscapes struct{} + +func (FixerPowerShellEscapes) Fix(input map[string]interface{}) (map[string]interface{}, error) { + type template struct { + Provisioners []interface{} + } + + var psUnescape = strings.NewReplacer( + "`$", "$", + "`\"", "\"", + "``", "`", + "`'", "'", + ) + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.WeakDecode(input, &tpl); err != nil { + return nil, err + } + + for i, raw := range tpl.Provisioners { + var provisioners map[string]interface{} + if err := mapstructure.Decode(raw, &provisioners); err != nil { + // Ignore errors, could be a non-map + continue + } + + if ok := provisioners["type"] == "powershell"; !ok { + continue + } + + if _, ok := provisioners["elevated_user"]; ok { + provisioners["elevated_user"] = psUnescape.Replace(provisioners["elevated_user"].(string)) + } + if _, ok := provisioners["elevated_password"]; ok { + provisioners["elevated_password"] = psUnescape.Replace(provisioners["elevated_password"].(string)) + } + if raw, ok := provisioners["environment_vars"]; ok { + var env_vars []string + if err := mapstructure.Decode(raw, &env_vars); err != nil { + continue + } + env_vars_unescaped := make([]interface{}, len(env_vars)) + for j, env_var := range env_vars { + env_vars_unescaped[j] = psUnescape.Replace(env_var) + } + // Replace with unescaped environment variables + provisioners["environment_vars"] = env_vars_unescaped + } + + // Write all changes back to template + tpl.Provisioners[i] = provisioners + } + + if len(tpl.Provisioners) > 0 { + input["provisioners"] = tpl.Provisioners + } + + return input, nil +} + +func (FixerPowerShellEscapes) Synopsis() string { + return `Removes PowerShell escapes from user env vars and elevated username and password strings` +} From 6559a26c1106bbd689c63aa8797ec86354e349ae Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 8 Feb 2018 18:03:44 +0000 Subject: [PATCH 0605/1007] Update Windows build demo script and template to reflect new PS behaviour --- .../intro/getting-started/build-image.html.md | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index ba0683797..273618294 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -448,14 +448,19 @@ variables we will set in our build template; copy the contents into your own `sample_script.ps1` and provide the path to it in your build template: ```powershell -Write-Host "PACKER_BUILD_NAME is automatically set for you, " -NoNewline -Write-Host "or you can set it in your builder variables; " -NoNewline +Write-Host "PACKER_BUILD_NAME is an env var Packer automatically sets for you." +Write-Host "...or you can set it in your builder variables." Write-Host "The default for this builder is:" $Env:PACKER_BUILD_NAME -Write-Host "Use backticks as the escape character when required in powershell:" +Write-Host "The PowerShell provisioner will automatically escape characters" +Write-Host "considered special to PowerShell when it encounters them in" +Write-Host "your environment variables or in the PowerShell elevated" +Write-Host "username/password fields." Write-Host "For example, VAR1 from our config is:" $Env:VAR1 Write-Host "Likewise, VAR2 is:" $Env:VAR2 -Write-Host "Finally, VAR3 is:" $Env:VAR3 +Write-Host "VAR3 is:" $Env:VAR3 +Write-Host "Finally, VAR4 is:" $Env:VAR4 +Write-Host "None of the special characters needed escaping in the template" ``` Finally, we need to create the actual [build template]( @@ -514,7 +519,12 @@ customize and control the build process: { "type": "powershell", "environment_vars": ["DEVOPS_LIFE_IMPROVER=PACKER"], - "inline": "Write-Host \"HELLO NEW USER; WELCOME TO $Env:DEVOPS_LIFE_IMPROVER\"" + "inline": [ + "Write-Host \"HELLO NEW USER; WELCOME TO $Env:DEVOPS_LIFE_IMPROVER\"", + "Write-Host \"You need to use backtick escapes when using\"", + "Write-Host \"characters such as DOLLAR`$ directly in a command\"", + "Write-Host \"or in your own scripts.\"" + ] }, { "type": "windows-restart" @@ -523,9 +533,10 @@ customize and control the build process: "script": "./sample_script.ps1", "type": "powershell", "environment_vars": [ - "VAR1=A`$Dollar", - "VAR2=A``Backtick", - "VAR3=A`'SingleQuote" + "VAR1=A$Dollar", + "VAR2=A`Backtick", + "VAR3=A'SingleQuote", + "VAR4=A\"DoubleQuote" ] } ] @@ -550,39 +561,49 @@ You should see output like this: ``` amazon-ebs output will be in this color. -==> amazon-ebs: Prevalidating AMI Name: packer-demo-1507933843 - amazon-ebs: Found Image ID: ami-23d93c59 -==> amazon-ebs: Creating temporary keypair: packer_59e13e94-203a-1bca-5327-bebf0d5ad15a -==> amazon-ebs: Creating temporary security group for this instance: packer_59e13ea9-3220-8dab-29c0-ed7f71e221a1 +==> amazon-ebs: Prevalidating AMI Name: packer-demo-1518111383 + amazon-ebs: Found Image ID: ami-013e197b +==> amazon-ebs: Creating temporary keypair: packer_5a7c8a97-f27f-6708-cc3c-6ab9b4688b13 +==> amazon-ebs: Creating temporary security group for this instance: packer_5a7c8ab5-444c-13f2-0aa1-18d124cdb975 ==> amazon-ebs: Authorizing access to port 5985 from 0.0.0.0/0 in the temporary security group... ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Adding tags to source instance amazon-ebs: Adding tag: "Name": "Packer Builder" - amazon-ebs: Instance ID: i-0349406ac85f02166 -==> amazon-ebs: Waiting for instance (i-0349406ac85f02166) to become ready... + amazon-ebs: Instance ID: i-0c8c808a3b945782a +==> amazon-ebs: Waiting for instance (i-0c8c808a3b945782a) to become ready... ==> amazon-ebs: Skipping waiting for password since WinRM password set... ==> amazon-ebs: Waiting for WinRM to become available... amazon-ebs: WinRM connected. ==> amazon-ebs: Connected to WinRM! ==> amazon-ebs: Provisioning with Powershell... -==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner175214995 +==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner943573503 amazon-ebs: HELLO NEW USER; WELCOME TO PACKER + amazon-ebs: You need to use backtick escapes when using + amazon-ebs: characters such as DOLLAR$ directly in a command + amazon-ebs: or in your own scripts. ==> amazon-ebs: Restarting Machine ==> amazon-ebs: Waiting for machine to restart... - amazon-ebs: WIN-TEM0TDL751M restarted. + amazon-ebs: WIN-NI8N45RPJ23 restarted. ==> amazon-ebs: Machine successfully restarted, moving on ==> amazon-ebs: Provisioning with Powershell... ==> amazon-ebs: Provisioning with powershell script: ./sample_script.ps1 - amazon-ebs: PACKER_BUILD_NAME is automatically set for you, or you can set it in your builder variables; The default for this builder is: amazon-ebs - amazon-ebs: Use backticks as the escape character when required in powershell: + amazon-ebs: PACKER_BUILD_NAME is an env var Packer automatically sets for you. + amazon-ebs: ...or you can set it in your builder variables. + amazon-ebs: The default for this builder is: amazon-ebs + amazon-ebs: The PowerShell provisioner will automatically escape characters + amazon-ebs: considered special to PowerShell when it encounters them in + amazon-ebs: your environment variables or in the PowerShell elevated + amazon-ebs: username/password fields. amazon-ebs: For example, VAR1 from our config is: A$Dollar amazon-ebs: Likewise, VAR2 is: A`Backtick - amazon-ebs: Finally, VAR3 is: A'SingleQuote + amazon-ebs: VAR3 is: A'SingleQuote + amazon-ebs: Finally, VAR4 is: A"DoubleQuote + amazon-ebs: None of the special characters needed escaping in the template ==> amazon-ebs: Stopping the source instance... amazon-ebs: Stopping instance, attempt 1 ==> amazon-ebs: Waiting for the instance to stop... -==> amazon-ebs: Creating the AMI: packer-demo-1507933843 - amazon-ebs: AMI: ami-100fc56a +==> amazon-ebs: Creating the AMI: packer-demo-1518111383 + amazon-ebs: AMI: ami-f0060c8a ==> amazon-ebs: Waiting for AMI to become ready... ==> amazon-ebs: Terminating the source AWS instance... ==> amazon-ebs: Cleaning up any extra volumes... @@ -593,7 +614,7 @@ Build 'amazon-ebs' finished. ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: -us-east-1: ami-100fc56a +us-east-1: ami-f0060c8a ``` And if you navigate to your EC2 dashboard you should see your shiny new AMI From 472a9226423cfa0d6c2fd709c2d0ab32b38a5f6d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 11:47:28 -0800 Subject: [PATCH 0606/1007] clean up ncloud docs --- website/source/docs/builders/ncloud.html.md | 96 ++++++++++++++------- website/source/layouts/docs.erb | 3 + 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/website/source/docs/builders/ncloud.html.md b/website/source/docs/builders/ncloud.html.md index ce38a9c71..9148ae568 100644 --- a/website/source/docs/builders/ncloud.html.md +++ b/website/source/docs/builders/ncloud.html.md @@ -1,7 +1,6 @@ --- description: | - As Packer allows users to develop a custom builder as a plugin, NAVER CLOUD PLATFORM provides its own Packer builder for your convenience. -You can use NAVER CLOUD PLATFORM's Packer builder to easily create your server images. + The ncloud builder allows you to create server images using the NAVER Cloud Platform. layout: docs page_title: 'Naver Cloud Platform - Builders' sidebar_current: 'docs-builders-ncloud' @@ -9,10 +8,61 @@ sidebar_current: 'docs-builders-ncloud' # NAVER CLOUD PLATFORM Builder -As Packer allows users to develop a custom builder as a plugin, NAVER CLOUD PLATFORM provides its own Packer builder for your convenience. -You can use NAVER CLOUD PLATFORM's Packer builder to easily create your server images. +The `ncloud` builder allows you to create server images using the [NAVER Cloud +Platform](https://www.ncloud.com/). -#### Sample code of template.json +## Configuration Reference + +### Required: + +- `ncloud_access_key` (string) - User's access key. Go to [\[Account + Management \> Authentication + Key\]](https://www.ncloud.com/mypage/manage/authkey) to create and view + your authentication key. + +- `ncloud_secret_key` (string) - User's secret key paired with the access + key. Go to [\[Account Management \> Authentication + Key\]](https://www.ncloud.com/mypage/manage/authkey) to create and view + your authentication key. + +- `server_image_product_code` (string) - Product code of an image to create. + (member\_server\_image\_no is required if not specified) + +- `server_product_code` (string) - Product (spec) code to create. + +### Optional: + +- `member_server_image_no` (string) - Previous image code. If there is an + image previously created, it can be used to create a new image. + (`server_image_product_code` is required if not specified) + +- `server_image_name` (string) - Name of an image to create. + +- `server_image_description` (string) - Description of an image to create. + +- `block_storage_size` (number) - You can add block storage ranging from 10 + GB to 2000 GB, in increments of 10 GB. + +- `access_control_group_configuration_no` (string) - This is used to allow + winrm access when you create a Windows server. An ACG that specifies an + access source (`0.0.0.0/0`) and allowed port (5985) must be created in + advance. + +- `user_data` (string) - Init script to run when an instance is created. + - For Linux servers, Python, Perl, and Shell scripts can be used. The + path of the script to run should be included at the beginning of the + script, like \#!/usr/bin/env python, \#!/bin/perl, or \#!/bin/bash. + - For Windows servers, only Visual Basic scripts can be used. + - All scripts must be written in English. +- `user_data_file` (string) - A path to a file containing a `user_data` + script. See above for more information. + +- `region` (string) - Name of the region where you want to create an image. + (default: Korea) + - values: Korea / US-West / HongKong / Singapore / Japan / Germany + + +## Sample code of template.json ``` { @@ -38,28 +88,10 @@ You can use NAVER CLOUD PLATFORM's Packer builder to easily create your server i } ``` -#### Description +## Requirements for creating Windows images -* type(required): "ncloud" -* ncloud_access_key (required): User's access key. Go to [[Account Management > Authentication Key]](https://www.ncloud.com/mypage/manage/authkey) to create and view your authentication key. -* ncloud_secret_key (required): User's secret key paired with the access key. Go to [[Account Management > Authentication Key]](https://www.ncloud.com/mypage/manage/authkey) to create and view your authentication key. -* server_image_product_code: Product code of an image to create. (member_server_image_no is required if not specified) -* server_product_code (required): Product (spec) code to create. -* member_server_image_no: Previous image code. If there is an image previously created, it can be used to create a new image. (server_image_product_code is required if not specified) -* server_image_name (option): Name of an image to create. -* server_image_description (option): Description of an image to create. -* block_storage_size (option): You can add block storage ranging from 10 GB to 2000 GB, in increments of 10 GB. -* access_control_group_configuration_no: This is used to allow winrm access when you create a Windows server. An ACG that specifies an access source ("0.0.0.0/0") and allowed port (5985) must be created in advance. -* user_data (option): Init script to run when an instance is created. - * For Linux servers, Python, Perl, and Shell scripts can be used. The path of the script to run should be included at the beginning of the script, like #!/usr/bin/env python, #!/bin/perl, or #!/bin/bash. - * For Windows servers, only Visual Basic scripts can be used. - * All scripts must be written in English. -* region (option): Name of the region where you want to create an image. (default: Korea) - * values: Korea / US-West / HongKong / Singapore / Japan / Germany - -### Requirements for creating Windows images - -You should include the following code in the packer configuration file for provision when creating a Windows server. +You should include the following code in the packer configuration file for +provision when creating a Windows server. ``` "builders": [ @@ -82,7 +114,13 @@ You should include the following code in the packer configuration file for provi ] ``` -### Note +## Note -* You can only create as many public IP addresses as the number of server instances you own. Before running Packer, please make sure that the number of public IP addresses previously created is not larger than the number of server instances (including those to be used to create server images). -* When you forcibly terminate the packer process or close the terminal (command) window where the process is running, the resources may not be cleaned up as the packer process no longer runs. In this case, you should manually clean up the resources associated with the process. +* You can only create as many public IP addresses as the number of server + instances you own. Before running Packer, please make sure that the number of + public IP addresses previously created is not larger than the number of + server instances (including those to be used to create server images). +* When you forcibly terminate the packer process or close the terminal + (command) window where the process is running, the resources may not be + cleaned up as the packer process no longer runs. In this case, you should + manually clean up the resources associated with the process. diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 8470e0d35..7f12d326c 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -122,6 +122,9 @@ <li<%= sidebar_current("docs-builders-lxd") %>> <a href="/docs/builders/lxd.html">LXD</a> </li> + <li<%= sidebar_current("docs-builders-ncloud") %>> + <a href="/docs/builders/ncloud.html">Naver</a> + </li> <li<%= sidebar_current("docs-builders-null") %>> <a href="/docs/builders/null.html">Null</a> </li> From 57faecbdd441869339bfd542431d21579abe3431 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 11:54:02 -0800 Subject: [PATCH 0607/1007] add @YuSungDuk as codeowner for ncloud --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index c037a38d4..050f4d084 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -13,6 +13,7 @@ /builder/oracle/ @prydie @owainlewis /builder/profitbricks/ @jasmingacic /builder/triton/ @jen20 @sean- +/builder/ncloud/ @YuSungDuk # provisioners From 7e36cfcff1e09470a3919d9fea08a7cd151fe960 Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Thu, 6 Apr 2017 11:19:17 +0200 Subject: [PATCH 0608/1007] Add Scaleway builder --- builder/scaleway/artifact.go | 49 ++++ builder/scaleway/artifact_test.go | 33 +++ builder/scaleway/builder.go | 89 +++++++ builder/scaleway/builder_test.go | 237 ++++++++++++++++++ builder/scaleway/config.go | 103 ++++++++ builder/scaleway/ssh.go | 30 +++ builder/scaleway/step_create_server.go | 61 +++++ builder/scaleway/step_create_ssh_key.go | 88 +++++++ builder/scaleway/step_server_info.go | 44 ++++ builder/scaleway/step_shutdown.go | 43 ++++ builder/scaleway/step_snapshot.go | 48 ++++ builder/scaleway/step_terminate.go | 34 +++ command/plugin.go | 2 + .../vagrant-cloud/post-processor.go | 2 + post-processor/vagrant/post-processor.go | 3 + post-processor/vagrant/scaleway.go | 52 ++++ vendor/vendor.json | 84 +++++++ 17 files changed, 1002 insertions(+) create mode 100644 builder/scaleway/artifact.go create mode 100644 builder/scaleway/artifact_test.go create mode 100644 builder/scaleway/builder.go create mode 100644 builder/scaleway/builder_test.go create mode 100644 builder/scaleway/config.go create mode 100644 builder/scaleway/ssh.go create mode 100644 builder/scaleway/step_create_server.go create mode 100644 builder/scaleway/step_create_ssh_key.go create mode 100644 builder/scaleway/step_server_info.go create mode 100644 builder/scaleway/step_shutdown.go create mode 100644 builder/scaleway/step_snapshot.go create mode 100644 builder/scaleway/step_terminate.go create mode 100644 post-processor/vagrant/scaleway.go diff --git a/builder/scaleway/artifact.go b/builder/scaleway/artifact.go new file mode 100644 index 000000000..fe1efb96f --- /dev/null +++ b/builder/scaleway/artifact.go @@ -0,0 +1,49 @@ +package scaleway + +import ( + "fmt" + "log" + + "github.com/scaleway/scaleway-cli/pkg/api" +) + +type Artifact struct { + // The name of the snapshot + snapshotName string + + // The ID of the snapshot + snapshotId string + + // The name of the region + regionName string + + // The client for making API calls + client *api.ScalewayAPI +} + +func (*Artifact) BuilderId() string { + return BuilderId +} + +func (*Artifact) Files() []string { + // No files with Scaleway + return nil +} + +func (a *Artifact) Id() string { + return fmt.Sprintf("%s:%s", a.regionName, a.snapshotId) +} + +func (a *Artifact) String() string { + return fmt.Sprintf("A snapshot was created: '%v' (ID: %v) in region '%v'", a.snapshotName, a.snapshotId, a.regionName) +} + +func (a *Artifact) State(name string) interface{} { + return nil +} + +func (a *Artifact) Destroy() error { + log.Printf("Destroying image: %s (%s)", a.snapshotId, a.snapshotName) + err := a.client.DeleteSnapshot(a.snapshotId) + return err +} diff --git a/builder/scaleway/artifact_test.go b/builder/scaleway/artifact_test.go new file mode 100644 index 000000000..8805ad686 --- /dev/null +++ b/builder/scaleway/artifact_test.go @@ -0,0 +1,33 @@ +package scaleway + +import ( + "testing" + + "github.com/hashicorp/packer/packer" +) + +func TestArtifact_Impl(t *testing.T) { + var raw interface{} + raw = &Artifact{} + if _, ok := raw.(packer.Artifact); !ok { + t.Fatalf("Artifact should be artifact") + } +} + +func TestArtifactId(t *testing.T) { + a := &Artifact{"packer-foobar", "cc586e45-5156-4f71-b223-cf406b10dd1c", "ams1", nil} + expected := "ams1:cc586e45-5156-4f71-b223-cf406b10dd1c" + + if a.Id() != expected { + t.Fatalf("artifact ID should match: %v", expected) + } +} + +func TestArtifactString(t *testing.T) { + a := &Artifact{"packer-foobar", "cc586e45-5156-4f71-b223-cf406b10dd1c", "ams1", nil} + expected := "A snapshot was created: 'packer-foobar' (ID: cc586e45-5156-4f71-b223-cf406b10dd1c) in region 'ams1'" + + if a.String() != expected { + t.Fatalf("artifact string should match: %v", expected) + } +} diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go new file mode 100644 index 000000000..2c92e31b6 --- /dev/null +++ b/builder/scaleway/builder.go @@ -0,0 +1,89 @@ +// The scaleway package contains a packer.Builder implementation +// that builds Scaleway images (snapshots). + +package scaleway + +import ( + "fmt" + "log" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +// The unique id for the builder +const BuilderId = "pearkes.scaleway" + +type Builder struct { + config Config + runner multistep.Runner +} + +func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { + c, warnings, errs := NewConfig(raws...) + if errs != nil { + return warnings, errs + } + b.config = *c + + return nil, nil +} + +func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { + client, _ := api.NewScalewayAPI(b.config.Organization, b.config.Token, b.config.UserAgent, b.config.Region) + + state := new(multistep.BasicStateBag) + state.Put("config", b.config) + state.Put("client", client) + state.Put("hook", hook) + state.Put("ui", ui) + + steps := []multistep.Step{ + &stepCreateSSHKey{ + Debug: b.config.PackerDebug, + DebugKeyPath: fmt.Sprintf("scw_%s.pem", b.config.PackerBuildName), + }, + new(stepCreateServer), + new(stepServerInfo), + &communicator.StepConnect{ + Config: &b.config.Comm, + Host: commHost, + SSHConfig: sshConfig, + }, + new(common.StepProvision), + new(stepShutdown), + new(stepSnapshot), + new(stepTerminate), + } + + b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner.Run(state) + + if rawErr, ok := state.GetOk("error"); ok { + return nil, rawErr.(error) + } + + if _, ok := state.GetOk("snapshot_name"); !ok { + log.Println("Failed to find snapshot_name in state. Bug?") + return nil, nil + } + + artifact := &Artifact{ + snapshotName: state.Get("snapshot_name").(string), + snapshotId: state.Get("snapshot_id").(string), + regionName: state.Get("region").(string), + client: client, + } + + return artifact, nil +} + +func (b *Builder) Cancel() { + if b.runner != nil { + log.Println("Cancelling the step runner...") + b.runner.Cancel() + } +} diff --git a/builder/scaleway/builder_test.go b/builder/scaleway/builder_test.go new file mode 100644 index 000000000..ff83e1556 --- /dev/null +++ b/builder/scaleway/builder_test.go @@ -0,0 +1,237 @@ +package scaleway + +import ( + "strconv" + "testing" + + "github.com/hashicorp/packer/packer" +) + +func testConfig() map[string]interface{} { + return map[string]interface{}{ + "api_organization": "foo", + "api_token": "bar", + "region": "ams1", + "commercial_type": "VC1S", + "ssh_username": "root", + "image": "image-uuid", + } +} + +func TestBuilder_ImplementsBuilder(t *testing.T) { + var raw interface{} + raw = &Builder{} + if _, ok := raw.(packer.Builder); !ok { + t.Fatalf("Builder should be a builder") + } +} + +func TestBuilder_Prepare_BadType(t *testing.T) { + b := &Builder{} + c := map[string]interface{}{ + "api_token": []string{}, + } + + warnings, err := b.Prepare(c) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatalf("prepare should fail") + } +} + +func TestBuilderPrepare_InvalidKey(t *testing.T) { + var b Builder + config := testConfig() + + config["i_should_not_be_valid"] = true + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } +} + +func TestBuilderPrepare_Region(t *testing.T) { + var b Builder + config := testConfig() + + delete(config, "region") + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatalf("should error") + } + + expected := "ams1" + + config["region"] = expected + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.Region != expected { + t.Errorf("found %s, expected %s", b.config.Region, expected) + } +} + +func TestBuilderPrepare_CommercialType(t *testing.T) { + var b Builder + config := testConfig() + + delete(config, "commercial_type") + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatalf("should error") + } + + expected := "VC1S" + + config["commercial_type"] = expected + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.CommercialType != expected { + t.Errorf("found %s, expected %s", b.config.CommercialType, expected) + } +} + +func TestBuilderPrepare_Image(t *testing.T) { + var b Builder + config := testConfig() + + delete(config, "image") + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should error") + } + + expected := "cc586e45-5156-4f71-b223-cf406b10dd1c" + + config["image"] = expected + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.Image != expected { + t.Errorf("found %s, expected %s", b.config.Image, expected) + } +} + +func TestBuilderPrepare_SnapshotName(t *testing.T) { + var b Builder + config := testConfig() + + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.SnapshotName == "" { + t.Errorf("invalid: %s", b.config.SnapshotName) + } + + config["snapshot_name"] = "foobarbaz" + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + config["snapshot_name"] = "{{timestamp}}" + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + _, err = strconv.ParseInt(b.config.SnapshotName, 0, 0) + if err != nil { + t.Fatalf("failed to parse int in template: %s", err) + } + +} + +func TestBuilderPrepare_ServerName(t *testing.T) { + var b Builder + config := testConfig() + + warnings, err := b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + if b.config.ServerName == "" { + t.Errorf("invalid: %s", b.config.ServerName) + } + + config["server_name"] = "foobar" + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + config["server_name"] = "foobar-{{timestamp}}" + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err != nil { + t.Fatalf("should not have error: %s", err) + } + + config["server_name"] = "foobar-{{" + b = Builder{} + warnings, err = b.Prepare(config) + if len(warnings) > 0 { + t.Fatalf("bad: %#v", warnings) + } + if err == nil { + t.Fatal("should have error") + } + +} diff --git a/builder/scaleway/config.go b/builder/scaleway/config.go new file mode 100644 index 000000000..eb9575140 --- /dev/null +++ b/builder/scaleway/config.go @@ -0,0 +1,103 @@ +package scaleway + +import ( + "errors" + "fmt" + + "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/uuid" + "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/packer" + "github.com/hashicorp/packer/template/interpolate" + "github.com/mitchellh/mapstructure" +) + +type Config struct { + common.PackerConfig `mapstructure:",squash"` + Comm communicator.Config `mapstructure:",squash"` + + Token string `mapstructure:"api_token"` + Organization string `mapstructure:"api_organization"` + + Region string `mapstructure:"region"` + Image string `mapstructure:"image"` + CommercialType string `mapstructure:"commercial_type"` + + SnapshotName string `mapstructure:"snapshot_name"` + ServerName string `mapstructure:"server_name"` + + UserAgent string + ctx interpolate.Context +} + +func NewConfig(raws ...interface{}) (*Config, []string, error) { + c := new(Config) + + var md mapstructure.Metadata + err := config.Decode(c, &config.DecodeOpts{ + Metadata: &md, + Interpolate: true, + InterpolateContext: &c.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{ + "run_command", + }, + }, + }, raws...) + if err != nil { + return nil, nil, err + } + + c.UserAgent = "Packer - Scaleway builder" + + if c.SnapshotName == "" { + def, err := interpolate.Render("packer-{{timestamp}}", nil) + if err != nil { + panic(err) + } + + c.SnapshotName = def + } + + if c.ServerName == "" { + // Default to packer-[time-ordered-uuid] + c.ServerName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) + } + + var errs *packer.MultiError + if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { + errs = packer.MultiErrorAppend(errs, es...) + } + if c.Organization == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("Scaleway Organization ID must be specified")) + } + + if c.Token == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("Scaleway Token must be specified")) + } + + if c.Region == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("region is required")) + } + + if c.CommercialType == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("commercial type is required")) + } + + if c.Image == "" { + errs = packer.MultiErrorAppend( + errs, errors.New("image is required")) + } + + if errs != nil && len(errs.Errors) > 0 { + return nil, nil, errs + } + + common.ScrubConfig(c, c.Token) + return c, nil, nil +} diff --git a/builder/scaleway/ssh.go b/builder/scaleway/ssh.go new file mode 100644 index 000000000..017138022 --- /dev/null +++ b/builder/scaleway/ssh.go @@ -0,0 +1,30 @@ +package scaleway + +import ( + "fmt" + "golang.org/x/crypto/ssh" + + "github.com/mitchellh/multistep" +) + +func commHost(state multistep.StateBag) (string, error) { + ipAddress := state.Get("server_ip").(string) + return ipAddress, nil +} + +func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) { + config := state.Get("config").(Config) + privateKey := state.Get("privateKey").(string) + + signer, err := ssh.ParsePrivateKey([]byte(privateKey)) + if err != nil { + return nil, fmt.Errorf("Error setting up SSH config: %s", err) + } + + return &ssh.ClientConfig{ + User: config.Comm.SSHUsername, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + }, nil +} diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go new file mode 100644 index 000000000..c961b6110 --- /dev/null +++ b/builder/scaleway/step_create_server.go @@ -0,0 +1,61 @@ +package scaleway + +import ( + "fmt" + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" + "strings" +) + +type stepCreateServer struct { + serverId string +} + +func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + c := state.Get("config").(Config) + sshPubKey := state.Get("ssh_pubkey").(string) + + ui.Say("Creating server...") + + server, err := client.PostServer(api.ScalewayServerDefinition{ + Name: c.ServerName, + Image: &c.Image, + Organization: c.Organization, + CommercialType: c.CommercialType, + Tags: []string{fmt.Sprintf("AUTHORIZED_KEY=%s", strings.TrimSpace(sshPubKey))}, + }) + + err = client.PostServerAction(server, "poweron") + + if err != nil { + err := fmt.Errorf("Error creating server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + s.serverId = server + + state.Put("server_id", server) + + return multistep.ActionContinue +} + +func (s *stepCreateServer) Cleanup(state multistep.StateBag) { + if s.serverId != "" { + return + } + + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + + ui.Say("Destroying server...") + err := client.PostServerAction(s.serverId, "terminate") + if err != nil { + ui.Error(fmt.Sprintf( + "Error destroying server. Please destroy it manually: %s", err)) + } +} diff --git a/builder/scaleway/step_create_ssh_key.go b/builder/scaleway/step_create_ssh_key.go new file mode 100644 index 000000000..8a3618619 --- /dev/null +++ b/builder/scaleway/step_create_ssh_key.go @@ -0,0 +1,88 @@ +package scaleway + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "log" + "os" + "runtime" + "strings" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "golang.org/x/crypto/ssh" +) + +type stepCreateSSHKey struct { + Debug bool + DebugKeyPath string +} + +func (s *stepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + ui.Say("Creating temporary ssh key for server...") + + priv, err := rsa.GenerateKey(rand.Reader, 2014) + if err != nil { + err := fmt.Errorf("Error creating temporary SSH key: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + // ASN.1 DER encoded form + priv_der := x509.MarshalPKCS1PrivateKey(priv) + priv_blk := pem.Block{ + Type: "RSA PRIVATE KEY", + Headers: nil, + Bytes: priv_der, + } + + // Set the private key in the statebag for later + state.Put("privateKey", string(pem.EncodeToMemory(&priv_blk))) + + pub, _ := ssh.NewPublicKey(&priv.PublicKey) + pub_sshformat := string(ssh.MarshalAuthorizedKey(pub)) + pub_sshformat = strings.Replace(pub_sshformat, " ", "_", -1) + + log.Printf("temporary ssh key created") + + // Remember some state for the future + state.Put("ssh_pubkey", string(pub_sshformat)) + + // If we're in debug mode, output the private key to the working directory. + if s.Debug { + ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) + f, err := os.Create(s.DebugKeyPath) + if err != nil { + state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) + return multistep.ActionHalt + } + defer f.Close() + + // Write the key out + if _, err := f.Write(pem.EncodeToMemory(&priv_blk)); err != nil { + state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) + return multistep.ActionHalt + } + + // Chmod it so that it is SSH ready + if runtime.GOOS != "windows" { + if err := f.Chmod(0600); err != nil { + state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err)) + return multistep.ActionHalt + } + } + } + + return multistep.ActionContinue +} + +func (s *stepCreateSSHKey) Cleanup(state multistep.StateBag) { + // SSH key is passed via tag. Nothing to do here. + return +} diff --git a/builder/scaleway/step_server_info.go b/builder/scaleway/step_server_info.go new file mode 100644 index 000000000..38502fe4d --- /dev/null +++ b/builder/scaleway/step_server_info.go @@ -0,0 +1,44 @@ +package scaleway + +import ( + "fmt" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +type stepServerInfo struct{} + +func (s *stepServerInfo) Run(state multistep.StateBag) multistep.StepAction { + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + serverID := state.Get("server_id").(string) + + ui.Say("Waiting for server to become active...") + + _, err := api.WaitForServerState(client, serverID, "running") + if err != nil { + err := fmt.Errorf("Error waiting for server to become booted: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + server, err := client.GetServer(serverID) + if err != nil { + err := fmt.Errorf("Error retrieving server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + state.Put("server_ip", server.PublicAddress.IP) + state.Put("root_volume_id", server.Volumes["0"].Identifier) + + return multistep.ActionContinue +} + +func (s *stepServerInfo) Cleanup(state multistep.StateBag) { + // no cleanup +} diff --git a/builder/scaleway/step_shutdown.go b/builder/scaleway/step_shutdown.go new file mode 100644 index 000000000..8d246974d --- /dev/null +++ b/builder/scaleway/step_shutdown.go @@ -0,0 +1,43 @@ +package scaleway + +import ( + "fmt" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +type stepShutdown struct{} + +func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + serverId := state.Get("server_id").(string) + + ui.Say("Shutting down server...") + + err := client.PostServerAction(serverId, "poweroff") + + if err != nil { + err := fmt.Errorf("Error stopping server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + _, err = api.WaitForServerState(client, serverId, "stopped") + + if err != nil { + err := fmt.Errorf("Error shutting down server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *stepShutdown) Cleanup(state multistep.StateBag) { + // no cleanup +} diff --git a/builder/scaleway/step_snapshot.go b/builder/scaleway/step_snapshot.go new file mode 100644 index 000000000..26bfa6934 --- /dev/null +++ b/builder/scaleway/step_snapshot.go @@ -0,0 +1,48 @@ +package scaleway + +import ( + "fmt" + "log" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +type stepSnapshot struct{} + +func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + c := state.Get("config").(Config) + volumeId := state.Get("root_volume_id").(string) + + ui.Say(fmt.Sprintf("Creating snapshot: %v", c.SnapshotName)) + snapshot, err := client.PostSnapshot(volumeId, c.SnapshotName) + if err != nil { + err := fmt.Errorf("Error creating snapshot: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Looking up snapshot ID for snapshot: %s", c.SnapshotName) + _, err = client.GetSnapshot(snapshot) + if err != nil { + err := fmt.Errorf("Error looking up snapshot ID: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Snapshot ID: %s", snapshot) + state.Put("snapshot_id", snapshot) + state.Put("snapshot_name", c.SnapshotName) + state.Put("region", c.Region) + + return multistep.ActionContinue +} + +func (s *stepSnapshot) Cleanup(state multistep.StateBag) { + // no cleanup +} diff --git a/builder/scaleway/step_terminate.go b/builder/scaleway/step_terminate.go new file mode 100644 index 000000000..0951b6a94 --- /dev/null +++ b/builder/scaleway/step_terminate.go @@ -0,0 +1,34 @@ +package scaleway + +import ( + "fmt" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +type stepTerminate struct{} + +func (s *stepTerminate) Run(state multistep.StateBag) multistep.StepAction { + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + serverId := state.Get("server_id").(string) + + ui.Say("Terminating server...") + + err := client.DeleteServerForce(serverId) + + if err != nil { + err := fmt.Errorf("Error terminating server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + return multistep.ActionContinue +} + +func (s *stepTerminate) Cleanup(state multistep.StateBag) { + // no cleanup +} diff --git a/command/plugin.go b/command/plugin.go index 55cfacc60..60651332d 100644 --- a/command/plugin.go +++ b/command/plugin.go @@ -39,6 +39,7 @@ import ( parallelspvmbuilder "github.com/hashicorp/packer/builder/parallels/pvm" profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks" qemubuilder "github.com/hashicorp/packer/builder/qemu" + scalewaybuilder "github.com/hashicorp/packer/builder/scaleway" tritonbuilder "github.com/hashicorp/packer/builder/triton" virtualboxisobuilder "github.com/hashicorp/packer/builder/virtualbox/iso" virtualboxovfbuilder "github.com/hashicorp/packer/builder/virtualbox/ovf" @@ -108,6 +109,7 @@ var Builders = map[string]packer.Builder{ "parallels-pvm": new(parallelspvmbuilder.Builder), "profitbricks": new(profitbricksbuilder.Builder), "qemu": new(qemubuilder.Builder), + "scaleway": new(scalewaybuilder.Builder), "triton": new(tritonbuilder.Builder), "virtualbox-iso": new(virtualboxisobuilder.Builder), "virtualbox-ovf": new(virtualboxovfbuilder.Builder), diff --git a/post-processor/vagrant-cloud/post-processor.go b/post-processor/vagrant-cloud/post-processor.go index f6c7f19d6..273d2fdb8 100644 --- a/post-processor/vagrant-cloud/post-processor.go +++ b/post-processor/vagrant-cloud/post-processor.go @@ -189,6 +189,8 @@ func providerFromBuilderName(name string) string { switch name { case "aws": return "aws" + case "scaleway": + return "scaleway" case "digitalocean": return "digitalocean" case "virtualbox": diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 310270809..18357923f 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -26,6 +26,7 @@ var builtins = map[string]string{ "mitchellh.vmware-esx": "vmware", "pearkes.digitalocean": "digitalocean", "packer.googlecompute": "google", + "pearkes.scaleway": "scaleway", "packer.parallels": "parallels", "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", @@ -221,6 +222,8 @@ func providerForName(name string) Provider { switch name { case "aws": return new(AWSProvider) + case "scaleway": + return new(ScalewayProvider) case "digitalocean": return new(DigitalOceanProvider) case "virtualbox": diff --git a/post-processor/vagrant/scaleway.go b/post-processor/vagrant/scaleway.go new file mode 100644 index 000000000..879f2b59e --- /dev/null +++ b/post-processor/vagrant/scaleway.go @@ -0,0 +1,52 @@ +package vagrant + +import ( + "bytes" + "fmt" + "github.com/hashicorp/packer/packer" + "strings" + "text/template" +) + +type scalewayVagrantfileTemplate struct { + Image string "" + Region string "" +} + +type ScalewayProvider struct{} + +func (p *ScalewayProvider) KeepInputArtifact() bool { + return true +} + +func (p *ScalewayProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + // Create the metadata + metadata = map[string]interface{}{"provider": "scaleway"} + + // Determine the image and region... + tplData := &scalewayVagrantfileTemplate{} + + parts := strings.Split(artifact.Id(), ":") + if len(parts) != 2 { + err = fmt.Errorf("Poorly formatted artifact ID: %s", artifact.Id()) + return + } + tplData.Region = parts[0] + tplData.Image = parts[1] + + // Build up the Vagrantfile + var contents bytes.Buffer + t := template.Must(template.New("vf").Parse(defaultScalewayVagrantfile)) + err = t.Execute(&contents, tplData) + vagrantfile = contents.String() + return +} + +var defaultScalewayVagrantfile = ` +Vagrant.configure("2") do |config| + config.vm.provider :scaleway do |scaleway| + scaleway.image = "{{ .Image }}" + scaleway.region = "{{ .Region }}" + end +end +` diff --git a/vendor/vendor.json b/vendor/vendor.json index 1ad929935..97a1a27f8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -232,6 +232,12 @@ "path": "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk", "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", "revisionTime": "2018-01-10T05:50:12Z" + }, + { + "checksumSHA1": "8dVO3L8yAdQ17X3lAhIziyF3OFk=", + "path": "github.com/Sirupsen/logrus", + "revision": "10f801ebc38b33738c9d17d50860f484a0988ff5", + "revisionTime": "2017-03-17T14:32:14Z" }, { "checksumSHA1": "HttiPj314X1a0i2Jen1p6lRH/vE=", @@ -589,6 +595,12 @@ "path": "github.com/biogo/hts/bgzf", "revision": "50da7d4131a3b5c9d063932461cab4d1fafb20b0" }, + { + "checksumSHA1": "bFj0ceSRvaFFCfmS4el1PjWhcgw=", + "path": "github.com/creack/goselect", + "revision": "1bd5ca702c6154bccc56ecd598932ee8b295cab2", + "revisionTime": "2016-07-14T17:28:59Z" + }, { "checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=", "comment": "v1.0.0-3-g6d21280", @@ -638,6 +650,24 @@ "revision": "4c04abe183f449bd9ede285f0e5c7ee575d0dbe4", "revisionTime": "2017-04-07T15:15:42Z" }, + { + "checksumSHA1": "1n5MBJthemxmfqU2gN3qLCd8s04=", + "path": "github.com/docker/docker/pkg/namesgenerator", + "revision": "fa3e2d5ab9b577cecd24201902bbe72b3f1b851c", + "revisionTime": "2017-04-06T12:40:27Z" + }, + { + "checksumSHA1": "lThih54jzz9A4zHKEFb9SIV3Ed0=", + "path": "github.com/docker/docker/pkg/random", + "revision": "fa3e2d5ab9b577cecd24201902bbe72b3f1b851c", + "revisionTime": "2017-04-06T12:40:27Z" + }, + { + "checksumSHA1": "rhLUtXvcmouYuBwOq9X/nYKzvNg=", + "path": "github.com/dustin/go-humanize", + "revision": "259d2a102b871d17f30e3cd9881a642961a1e486", + "revisionTime": "2017-02-28T07:34:54Z" + }, { "checksumSHA1": "GCskdwYAPW2S34918Z5CgNMJ2Wc=", "path": "github.com/dylanmei/iso8601", @@ -779,6 +809,12 @@ "revision": "95a28eb606def6aaaed082b6b82d3244b0552184", "revisionTime": "2017-06-23T01:44:30Z" }, + { + "checksumSHA1": "xSmii71kfQASGNG2C8ttmHx9KTE=", + "path": "github.com/gorilla/websocket", + "revision": "a91eba7f97777409bc2c443f5534d41dd20c5720", + "revisionTime": "2017-03-19T17:27:27Z" + }, { "checksumSHA1": "izBSRxLAHN+a/XpAku0in05UzlY=", "comment": "20141209094003-92-g95fa852", @@ -1032,6 +1068,18 @@ "path": "github.com/mitchellh/reflectwalk", "revision": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6" }, + { + "checksumSHA1": "KhOVzKefFYORHdIVe+/gNAHB23A=", + "path": "github.com/moul/anonuuid", + "revision": "609b752a95effbbef26d134ac18ed6f57e01b98e", + "revisionTime": "2016-02-22T16:21:17Z" + }, + { + "checksumSHA1": "WcXDSYIAP73RAvy22iD57nE/peI=", + "path": "github.com/moul/gotty-client", + "revision": "99224eea3278d662fce9124bb2bf6c2bb39f5160", + "revisionTime": "2017-02-05T09:54:39Z" + }, { "checksumSHA1": "gcLub3oB+u4QrOJZcYmk/y2AP4k=", "path": "github.com/nu7hatch/gouuid", @@ -1117,6 +1165,12 @@ "revision": "7bdb11aecb0e457ea23c86898c6b49bfc0eb4bb1", "revisionTime": "2017-08-01T13:52:49Z" }, + { + "checksumSHA1": "DF3jZEw4lCq/SEaC7DIl/R+7S70=", + "path": "github.com/renstrom/fuzzysearch/fuzzy", + "revision": "2d205ac6ec17a839a94bdbfd16d2fa6c6dada2e0", + "revisionTime": "2016-03-31T20:48:55Z" + }, { "checksumSHA1": "zmC8/3V4ls53DJlNTKDZwPSC/dA=", "path": "github.com/satori/go.uuid", @@ -1129,6 +1183,24 @@ "revision": "5bf94b69c6b68ee1b541973bb8e1144db23a194b", "revisionTime": "2017-03-21T23:07:31Z" }, + { + "checksumSHA1": "FFhSGe3Y3J1laR/6rwSS7U2esrk=", + "path": "github.com/scaleway/scaleway-cli/pkg/api", + "revision": "e50cb485747a4f25a361c90ef3ba05be79944c56", + "revisionTime": "2017-04-03T16:01:47Z" + }, + { + "checksumSHA1": "kveaAmNlnvmIIuEkFcMlB+N7TqY=", + "path": "github.com/scaleway/scaleway-cli/pkg/sshcommand", + "revision": "e50cb485747a4f25a361c90ef3ba05be79944c56", + "revisionTime": "2017-04-03T16:01:47Z" + }, + { + "checksumSHA1": "xM3G5ct9YYYnVIL3XMRrcf41xVw=", + "path": "github.com/scaleway/scaleway-cli/pkg/utils", + "revision": "e50cb485747a4f25a361c90ef3ba05be79944c56", + "revisionTime": "2017-04-03T16:01:47Z" + }, { "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", "comment": "v1.1.4-4-g976c720", @@ -1281,6 +1353,12 @@ "revision": "453249f01cfeb54c3d549ddb75ff152ca243f9d8", "revisionTime": "2017-02-08T20:51:15Z" }, + { + "checksumSHA1": "xiderUuvye8Kpn7yX3niiJg32bE=", + "path": "golang.org/x/crypto/ssh/terminal", + "revision": "c2303dcbe84172e0c0da4c9f083eeca54c06f298", + "revisionTime": "2017-01-17T19:20:27Z" + }, { "checksumSHA1": "GtamqiJoL7PGHsN454AoffBFMa8=", "path": "golang.org/x/net/context", @@ -1342,6 +1420,12 @@ "path": "golang.org/x/oauth2/jwt", "revision": "8a57ed94ffd43444c0879fe75701732a38afc985" }, + { + "checksumSHA1": "S0DP7Pn7sZUmXc55IzZnNvERu6s=", + "path": "golang.org/x/sync/errgroup", + "revision": "5a06fca2c336a4b2b2fcb45702e8c47621b2aa2c", + "revisionTime": "2017-03-17T17:13:11Z" + }, { "checksumSHA1": "NzQ3QYllWwK+3GZliu11jMU6xwo=", "path": "golang.org/x/sys/unix", From 5a2f37896ebd2ae4db41ceb4b1ad11809268534a Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Thu, 6 Apr 2017 16:08:54 +0200 Subject: [PATCH 0609/1007] Add documentation --- website/source/docs/builders/scaleway.html.md | 77 +++++++++++++++++++ website/source/layouts/docs.erb | 3 + 2 files changed, 80 insertions(+) create mode 100644 website/source/docs/builders/scaleway.html.md diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md new file mode 100644 index 000000000..01852c70c --- /dev/null +++ b/website/source/docs/builders/scaleway.html.md @@ -0,0 +1,77 @@ +--- +layout: docs +sidebar_current: docs-builders-scaleway +page_title: Scaleway - Builders +description: |- + The Scaleway Packer builder is able to create new snapshots for use with + Scaleway BareMetal and Virtual cloud server. The builder takes a source image, runs any provisioning + necessary on the image after launching it, then snapshots it into a reusable + image. This reusable image can then be used as the foundation of new servers + that are launched within Scaleway. +--- + + +# Scaleway Builder + +Type: `scaleway` + +The `scaleway` Packer builder is able to create new snapshots for use with +[Scaleway](https://www.scaleway.com). The builder takes a source image, +runs any provisioning necessary on the image after launching it, then snapshots +it into a reusable image. This reusable image can then be used as the foundation +of new servers that are launched within Scaleway. + +The builder does *not* manage snapshots. Once it creates an image, it is up to you +to use it or delete it. + +## Configuration Reference + +There are many configuration options available for the builder. They are +segmented below into two categories: required and optional parameters. Within +each category, the available configuration keys are alphabetized. + +In addition to the options listed here, a +[communicator](/docs/templates/communicator.html) can be configured for this +builder. + +### Required: + +- `api_organization` (string) - The organization ID to use to access your account. + +- `api_token` (string) - The organization TOKEN to use to access your account. + +- `image` (string) - The UUID of the base image to use. This is the + image that will be used to launch a new server and provision it. See + [https://api-marketplace.scaleway.com/images](https://api-marketplace.scaleway.com/images) to + get the complete list of the accepted image UUID. + +- `region` (string) - The name of the region to launch the + server in (`par1` or `ams1`). Consequently, this is the region where the snapshot will + be available. + +- `commercial_type` (string) - The name of the server commercial type: `C1`, `C2S`, `C2M`, + `C2L`, `X64-2GB`, `X64-4GB`, `X64-8GB`, `X64-15GB`, `X64-30GB`, `X64-60GB`, `X64-120GB` + +### Optional: + +- `server_name` (string) - The name assigned to the server. + +- `snapshot_name` (string) - The name of the resulting snapshot that will + appear in your account. + +## Basic Example + +Here is a basic example. It is completely valid as soon as you enter your own +access tokens: + +```json +{ + "type": "scaleway", + "api_organization": "YOUR ORGANIZATION KEY", + "api_token": "YOUR TOKEN", + "image": "f01f8a48-c026-48ac-9771-a70eaac0890e", + "region": "par1", + "commercial_type": "X64-2GB", + "ssh_username": "root" +} +``` diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 7f12d326c..271de572f 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -90,6 +90,9 @@ </li> </ul> </li> + <li<%= sidebar_current("docs-builders-scaleway") %>> + <a href="/docs/builders/scaleway.html">Scaleway</a> + </li> <li<%= sidebar_current("docs-builders-cloudstack") %>> <a href="/docs/builders/cloudstack.html">CloudStack</a> </li> From e46108298ccf90d155630f77d74d328142cebd60 Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Thu, 6 Apr 2017 16:31:35 +0200 Subject: [PATCH 0610/1007] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5249f515e..1c30fd877 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ comes out of the box with support for the following platforms: * Parallels * ProfitBricks * QEMU. Both KVM and Xen images. +* Scaleway * Triton (Joyent Public Cloud) * VMware * VirtualBox From 9b611af7e6dd6e32b823751b47bbc8ea5593e769 Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Thu, 6 Apr 2017 16:37:06 +0200 Subject: [PATCH 0611/1007] Allow token and organization id to be passed via env vars --- builder/scaleway/config.go | 9 +++++++++ website/source/docs/builders/scaleway.html.md | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/builder/scaleway/config.go b/builder/scaleway/config.go index eb9575140..040b39891 100644 --- a/builder/scaleway/config.go +++ b/builder/scaleway/config.go @@ -3,6 +3,7 @@ package scaleway import ( "errors" "fmt" + "os" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/uuid" @@ -51,6 +52,14 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { c.UserAgent = "Packer - Scaleway builder" + if c.Organization == "" { + c.Organization = os.Getenv("SCALEWAY_API_ORGANIZATION") + } + + if c.Token == "" { + c.Token = os.Getenv("SCALEWAY_API_TOKEN") + } + if c.SnapshotName == "" { def, err := interpolate.Render("packer-{{timestamp}}", nil) if err != nil { diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index 01852c70c..1df9dd6ec 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -37,8 +37,12 @@ builder. ### Required: - `api_organization` (string) - The organization ID to use to access your account. + It can also be specified via + environment variable `SCALEWAY_API_ORGANIZATION`. - `api_token` (string) - The organization TOKEN to use to access your account. + It can also be specified via + environment variable `SCALEWAY_API_TOKEN`. - `image` (string) - The UUID of the base image to use. This is the image that will be used to launch a new server and provision it. See From 1fb13cc23eeebf7e3c57f47657d663dc6a13e21c Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Tue, 11 Apr 2017 12:19:28 +0200 Subject: [PATCH 0612/1007] Add image creation from snapshot Rename organization_id / access_key Update test / doc --- builder/scaleway/artifact.go | 25 ++++++--- builder/scaleway/artifact_test.go | 8 +-- builder/scaleway/builder.go | 5 +- builder/scaleway/builder_test.go | 12 ++--- builder/scaleway/config.go | 16 ++++-- builder/scaleway/step_create_image.go | 53 +++++++++++++++++++ builder/scaleway/step_create_server.go | 11 ++-- builder/scaleway/step_shutdown.go | 6 +-- builder/scaleway/step_snapshot.go | 13 +---- builder/scaleway/step_terminate.go | 4 +- website/source/docs/builders/scaleway.html.md | 15 ++++-- 11 files changed, 122 insertions(+), 46 deletions(-) create mode 100644 builder/scaleway/step_create_image.go diff --git a/builder/scaleway/artifact.go b/builder/scaleway/artifact.go index fe1efb96f..b5aea88da 100644 --- a/builder/scaleway/artifact.go +++ b/builder/scaleway/artifact.go @@ -8,11 +8,17 @@ import ( ) type Artifact struct { + // The name of the image + imageName string + + // The ID of the image + imageID string + // The name of the snapshot snapshotName string // The ID of the snapshot - snapshotId string + snapshotID string // The name of the region regionName string @@ -31,11 +37,12 @@ func (*Artifact) Files() []string { } func (a *Artifact) Id() string { - return fmt.Sprintf("%s:%s", a.regionName, a.snapshotId) + return fmt.Sprintf("%s:%s", a.regionName, a.imageID) } func (a *Artifact) String() string { - return fmt.Sprintf("A snapshot was created: '%v' (ID: %v) in region '%v'", a.snapshotName, a.snapshotId, a.regionName) + return fmt.Sprintf("An image was created: '%v' (ID: %v) in region '%v' based on snapshot '%v' (ID: %v)", + a.imageName, a.imageID, a.regionName, a.snapshotName, a.snapshotID) } func (a *Artifact) State(name string) interface{} { @@ -43,7 +50,13 @@ func (a *Artifact) State(name string) interface{} { } func (a *Artifact) Destroy() error { - log.Printf("Destroying image: %s (%s)", a.snapshotId, a.snapshotName) - err := a.client.DeleteSnapshot(a.snapshotId) - return err + log.Printf("Destroying image: %s (%s)", a.imageID, a.imageName) + if err := a.client.DeleteImage(a.imageID); err != nil { + return err + } + log.Printf("Destroying snapshot: %s (%s)", a.snapshotID, a.snapshotName) + if err := a.client.DeleteSnapshot(a.snapshotID); err != nil { + return err + } + return nil } diff --git a/builder/scaleway/artifact_test.go b/builder/scaleway/artifact_test.go index 8805ad686..8f158ef5f 100644 --- a/builder/scaleway/artifact_test.go +++ b/builder/scaleway/artifact_test.go @@ -15,8 +15,8 @@ func TestArtifact_Impl(t *testing.T) { } func TestArtifactId(t *testing.T) { - a := &Artifact{"packer-foobar", "cc586e45-5156-4f71-b223-cf406b10dd1c", "ams1", nil} - expected := "ams1:cc586e45-5156-4f71-b223-cf406b10dd1c" + a := &Artifact{"packer-foobar-image", "cc586e45-5156-4f71-b223-cf406b10dd1d", "packer-foobar-snapshot", "cc586e45-5156-4f71-b223-cf406b10dd1c", "ams1", nil} + expected := "ams1:cc586e45-5156-4f71-b223-cf406b10dd1d" if a.Id() != expected { t.Fatalf("artifact ID should match: %v", expected) @@ -24,8 +24,8 @@ func TestArtifactId(t *testing.T) { } func TestArtifactString(t *testing.T) { - a := &Artifact{"packer-foobar", "cc586e45-5156-4f71-b223-cf406b10dd1c", "ams1", nil} - expected := "A snapshot was created: 'packer-foobar' (ID: cc586e45-5156-4f71-b223-cf406b10dd1c) in region 'ams1'" + a := &Artifact{"packer-foobar-image", "cc586e45-5156-4f71-b223-cf406b10dd1d", "packer-foobar-snapshot", "cc586e45-5156-4f71-b223-cf406b10dd1c", "ams1", nil} + expected := "An image was created: 'packer-foobar-image' (ID: cc586e45-5156-4f71-b223-cf406b10dd1d) in region 'ams1' based on snapshot 'packer-foobar-snapshot' (ID: cc586e45-5156-4f71-b223-cf406b10dd1c)" if a.String() != expected { t.Fatalf("artifact string should match: %v", expected) diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index 2c92e31b6..e6265395a 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -56,6 +56,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe new(common.StepProvision), new(stepShutdown), new(stepSnapshot), + new(stepImage), new(stepTerminate), } @@ -72,8 +73,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } artifact := &Artifact{ + imageName: state.Get("image_name").(string), + imageID: state.Get("image_id").(string), snapshotName: state.Get("snapshot_name").(string), - snapshotId: state.Get("snapshot_id").(string), + snapshotID: state.Get("snapshot_id").(string), regionName: state.Get("region").(string), client: client, } diff --git a/builder/scaleway/builder_test.go b/builder/scaleway/builder_test.go index ff83e1556..230c9c0c6 100644 --- a/builder/scaleway/builder_test.go +++ b/builder/scaleway/builder_test.go @@ -9,12 +9,12 @@ import ( func testConfig() map[string]interface{} { return map[string]interface{}{ - "api_organization": "foo", - "api_token": "bar", - "region": "ams1", - "commercial_type": "VC1S", - "ssh_username": "root", - "image": "image-uuid", + "api_access_key": "foo", + "api_token": "bar", + "region": "ams1", + "commercial_type": "VC1S", + "ssh_username": "root", + "image": "image-uuid", } } diff --git a/builder/scaleway/config.go b/builder/scaleway/config.go index 040b39891..f965e1ce0 100644 --- a/builder/scaleway/config.go +++ b/builder/scaleway/config.go @@ -19,13 +19,14 @@ type Config struct { Comm communicator.Config `mapstructure:",squash"` Token string `mapstructure:"api_token"` - Organization string `mapstructure:"api_organization"` + Organization string `mapstructure:"api_access_key"` Region string `mapstructure:"region"` Image string `mapstructure:"image"` CommercialType string `mapstructure:"commercial_type"` SnapshotName string `mapstructure:"snapshot_name"` + ImageName string `mapstructure:"image_name"` ServerName string `mapstructure:"server_name"` UserAgent string @@ -53,7 +54,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { c.UserAgent = "Packer - Scaleway builder" if c.Organization == "" { - c.Organization = os.Getenv("SCALEWAY_API_ORGANIZATION") + c.Organization = os.Getenv("SCALEWAY_API_ACCESS_KEY") } if c.Token == "" { @@ -61,7 +62,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { } if c.SnapshotName == "" { - def, err := interpolate.Render("packer-{{timestamp}}", nil) + def, err := interpolate.Render("snapshot-packer-{{timestamp}}", nil) if err != nil { panic(err) } @@ -69,6 +70,15 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { c.SnapshotName = def } + if c.ImageName == "" { + def, err := interpolate.Render("image-packer-{{timestamp}}", nil) + if err != nil { + panic(err) + } + + c.ImageName = def + } + if c.ServerName == "" { // Default to packer-[time-ordered-uuid] c.ServerName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) diff --git a/builder/scaleway/step_create_image.go b/builder/scaleway/step_create_image.go new file mode 100644 index 000000000..313f2e421 --- /dev/null +++ b/builder/scaleway/step_create_image.go @@ -0,0 +1,53 @@ +package scaleway + +import ( + "fmt" + "log" + + "github.com/hashicorp/packer/packer" + "github.com/mitchellh/multistep" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +type stepImage struct{} + +func (s *stepImage) Run(state multistep.StateBag) multistep.StepAction { + client := state.Get("client").(*api.ScalewayAPI) + ui := state.Get("ui").(packer.Ui) + c := state.Get("config").(Config) + snapshotID := state.Get("snapshot_id").(string) + bootscriptID := "" + + ui.Say(fmt.Sprintf("Creating image: %v", c.ImageName)) + + image, err := client.GetImage(c.Image) + if err != nil { + err := fmt.Errorf("Error getting initial image info: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if image.DefaultBootscript != nil { + bootscriptID = image.DefaultBootscript.Identifier + } + + imageID, err := client.PostImage(snapshotID, c.ImageName, bootscriptID, image.Arch) + if err != nil { + err := fmt.Errorf("Error creating image: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + log.Printf("Image ID: %s", imageID) + state.Put("image_id", imageID) + state.Put("image_name", c.ImageName) + state.Put("region", c.Region) + + return multistep.ActionContinue +} + +func (s *stepImage) Cleanup(state multistep.StateBag) { + // no cleanup +} diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go index c961b6110..e1e8b88c6 100644 --- a/builder/scaleway/step_create_server.go +++ b/builder/scaleway/step_create_server.go @@ -2,14 +2,15 @@ package scaleway import ( "fmt" + "strings" + "github.com/hashicorp/packer/packer" "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" - "strings" ) type stepCreateServer struct { - serverId string + serverID string } func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { @@ -37,7 +38,7 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } - s.serverId = server + s.serverID = server state.Put("server_id", server) @@ -45,7 +46,7 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { } func (s *stepCreateServer) Cleanup(state multistep.StateBag) { - if s.serverId != "" { + if s.serverID != "" { return } @@ -53,7 +54,7 @@ func (s *stepCreateServer) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) ui.Say("Destroying server...") - err := client.PostServerAction(s.serverId, "terminate") + err := client.PostServerAction(s.serverID, "terminate") if err != nil { ui.Error(fmt.Sprintf( "Error destroying server. Please destroy it manually: %s", err)) diff --git a/builder/scaleway/step_shutdown.go b/builder/scaleway/step_shutdown.go index 8d246974d..b8e45be51 100644 --- a/builder/scaleway/step_shutdown.go +++ b/builder/scaleway/step_shutdown.go @@ -13,11 +13,11 @@ type stepShutdown struct{} func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) - serverId := state.Get("server_id").(string) + serverID := state.Get("server_id").(string) ui.Say("Shutting down server...") - err := client.PostServerAction(serverId, "poweroff") + err := client.PostServerAction(serverID, "poweroff") if err != nil { err := fmt.Errorf("Error stopping server: %s", err) @@ -26,7 +26,7 @@ func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } - _, err = api.WaitForServerState(client, serverId, "stopped") + _, err = api.WaitForServerState(client, serverID, "stopped") if err != nil { err := fmt.Errorf("Error shutting down server: %s", err) diff --git a/builder/scaleway/step_snapshot.go b/builder/scaleway/step_snapshot.go index 26bfa6934..20301a444 100644 --- a/builder/scaleway/step_snapshot.go +++ b/builder/scaleway/step_snapshot.go @@ -15,10 +15,10 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) - volumeId := state.Get("root_volume_id").(string) + volumeID := state.Get("root_volume_id").(string) ui.Say(fmt.Sprintf("Creating snapshot: %v", c.SnapshotName)) - snapshot, err := client.PostSnapshot(volumeId, c.SnapshotName) + snapshot, err := client.PostSnapshot(volumeID, c.SnapshotName) if err != nil { err := fmt.Errorf("Error creating snapshot: %s", err) state.Put("error", err) @@ -26,15 +26,6 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { return multistep.ActionHalt } - log.Printf("Looking up snapshot ID for snapshot: %s", c.SnapshotName) - _, err = client.GetSnapshot(snapshot) - if err != nil { - err := fmt.Errorf("Error looking up snapshot ID: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - log.Printf("Snapshot ID: %s", snapshot) state.Put("snapshot_id", snapshot) state.Put("snapshot_name", c.SnapshotName) diff --git a/builder/scaleway/step_terminate.go b/builder/scaleway/step_terminate.go index 0951b6a94..154750931 100644 --- a/builder/scaleway/step_terminate.go +++ b/builder/scaleway/step_terminate.go @@ -13,11 +13,11 @@ type stepTerminate struct{} func (s *stepTerminate) Run(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) - serverId := state.Get("server_id").(string) + serverID := state.Get("server_id").(string) ui.Say("Terminating server...") - err := client.DeleteServerForce(serverId) + err := client.DeleteServerForce(serverID) if err != nil { err := fmt.Errorf("Error terminating server: %s", err) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index 1df9dd6ec..4e0a513fc 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -3,7 +3,7 @@ layout: docs sidebar_current: docs-builders-scaleway page_title: Scaleway - Builders description: |- - The Scaleway Packer builder is able to create new snapshots for use with + The Scaleway Packer builder is able to create new images for use with Scaleway BareMetal and Virtual cloud server. The builder takes a source image, runs any provisioning necessary on the image after launching it, then snapshots it into a reusable image. This reusable image can then be used as the foundation of new servers @@ -15,7 +15,7 @@ description: |- Type: `scaleway` -The `scaleway` Packer builder is able to create new snapshots for use with +The `scaleway` Packer builder is able to create new images for use with [Scaleway](https://www.scaleway.com). The builder takes a source image, runs any provisioning necessary on the image after launching it, then snapshots it into a reusable image. This reusable image can then be used as the foundation @@ -36,13 +36,15 @@ builder. ### Required: -- `api_organization` (string) - The organization ID to use to access your account. +- `api_access_key` (string) - The api_access_key to use to access your account. It can also be specified via - environment variable `SCALEWAY_API_ORGANIZATION`. + environment variable `SCALEWAY_API_ACCESS_KEY`. + Your access key is available in the ["Credentials" section](https://cloud.scaleway.com/#/credentials) of the control panel. - `api_token` (string) - The organization TOKEN to use to access your account. It can also be specified via environment variable `SCALEWAY_API_TOKEN`. + Your tokens are available in the ["Credentials" section](https://cloud.scaleway.com/#/credentials) of the control panel. - `image` (string) - The UUID of the base image to use. This is the image that will be used to launch a new server and provision it. See @@ -60,6 +62,9 @@ builder. - `server_name` (string) - The name assigned to the server. +- `image_name` (string) - The name of the resulting image that will + appear in your account. + - `snapshot_name` (string) - The name of the resulting snapshot that will appear in your account. @@ -71,7 +76,7 @@ access tokens: ```json { "type": "scaleway", - "api_organization": "YOUR ORGANIZATION KEY", + "api_access_key": "YOUR API ACCESS KEY", "api_token": "YOUR TOKEN", "image": "f01f8a48-c026-48ac-9771-a70eaac0890e", "region": "par1", From 2de93c5ae699838cccb9720f912fc55a2a3e8c9b Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Wed, 19 Apr 2017 11:10:52 +0200 Subject: [PATCH 0613/1007] Add existing SSH key support Update documentation --- builder/scaleway/builder.go | 5 +++-- builder/scaleway/step_create_server.go | 7 ++++++- builder/scaleway/step_create_ssh_key.go | 21 +++++++++++++++++-- website/source/docs/builders/scaleway.html.md | 8 ++++++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index e6265395a..2277808e0 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -43,8 +43,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps := []multistep.Step{ &stepCreateSSHKey{ - Debug: b.config.PackerDebug, - DebugKeyPath: fmt.Sprintf("scw_%s.pem", b.config.PackerBuildName), + Debug: b.config.PackerDebug, + DebugKeyPath: fmt.Sprintf("scw_%s.pem", b.config.PackerBuildName), + PrivateKeyFile: b.config.Comm.SSHPrivateKey, }, new(stepCreateServer), new(stepServerInfo), diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go index e1e8b88c6..3cf46e1ed 100644 --- a/builder/scaleway/step_create_server.go +++ b/builder/scaleway/step_create_server.go @@ -18,15 +18,20 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) sshPubKey := state.Get("ssh_pubkey").(string) + tags := []string{} ui.Say("Creating server...") + if sshPubKey != "" { + tags = []string{fmt.Sprintf("AUTHORIZED_KEY=%s", strings.TrimSpace(sshPubKey))} + } + server, err := client.PostServer(api.ScalewayServerDefinition{ Name: c.ServerName, Image: &c.Image, Organization: c.Organization, CommercialType: c.CommercialType, - Tags: []string{fmt.Sprintf("AUTHORIZED_KEY=%s", strings.TrimSpace(sshPubKey))}, + Tags: tags, }) err = client.PostServerAction(server, "poweron") diff --git a/builder/scaleway/step_create_ssh_key.go b/builder/scaleway/step_create_ssh_key.go index 8a3618619..dab8f710b 100644 --- a/builder/scaleway/step_create_ssh_key.go +++ b/builder/scaleway/step_create_ssh_key.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "io/ioutil" "log" "os" "runtime" @@ -17,13 +18,29 @@ import ( ) type stepCreateSSHKey struct { - Debug bool - DebugKeyPath string + Debug bool + DebugKeyPath string + PrivateKeyFile string } func (s *stepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) + if s.PrivateKeyFile != "" { + ui.Say("Using existing SSH private key") + privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) + if err != nil { + state.Put("error", fmt.Errorf( + "Error loading configured private key file: %s", err)) + return multistep.ActionHalt + } + + state.Put("privateKey", string(privateKeyBytes)) + state.Put("ssh_pubkey", "") + + return multistep.ActionContinue + } + ui.Say("Creating temporary ssh key for server...") priv, err := rsa.GenerateKey(rand.Reader, 2014) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index 4e0a513fc..fa1edd827 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -68,6 +68,8 @@ builder. - `snapshot_name` (string) - The name of the resulting snapshot that will appear in your account. +- `ssh_private_key_file` (string) - Path to a PEM encoded private key file to use to authentiate with SSH. + ## Basic Example Here is a basic example. It is completely valid as soon as you enter your own @@ -81,6 +83,10 @@ access tokens: "image": "f01f8a48-c026-48ac-9771-a70eaac0890e", "region": "par1", "commercial_type": "X64-2GB", - "ssh_username": "root" + "ssh_username": "root", + "ssh_private_key_file": "~/.ssh/id_rsa", } ``` + +When you do not specified the `ssh_private_key_file`, a temporarily SSH keypair is generated to connect the server. +This key will only allows the `root` user to connect the server. \ No newline at end of file From edf9dd15174b08c13c98cafbf1085431521c632d Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Wed, 19 Apr 2017 11:37:57 +0200 Subject: [PATCH 0614/1007] Fix doc --- website/source/docs/builders/scaleway.html.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index fa1edd827..88f14a155 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -68,8 +68,6 @@ builder. - `snapshot_name` (string) - The name of the resulting snapshot that will appear in your account. -- `ssh_private_key_file` (string) - Path to a PEM encoded private key file to use to authentiate with SSH. - ## Basic Example Here is a basic example. It is completely valid as soon as you enter your own From 09805911b44b6eabcddd72e0d8adfea9844c086f Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Tue, 11 Jul 2017 08:43:04 +0200 Subject: [PATCH 0615/1007] Fix builder unique id Add new ARM64 commercial types DOC - Add default value for optional settings DOC - Fix typo --- builder/scaleway/builder.go | 2 +- website/source/docs/builders/scaleway.html.md | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index 2277808e0..14fee93a0 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -15,7 +15,7 @@ import ( ) // The unique id for the builder -const BuilderId = "pearkes.scaleway" +const BuilderId = "hashicorp.scaleway" type Builder struct { config Config diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index 88f14a155..e045f27bd 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -56,17 +56,17 @@ builder. be available. - `commercial_type` (string) - The name of the server commercial type: `C1`, `C2S`, `C2M`, - `C2L`, `X64-2GB`, `X64-4GB`, `X64-8GB`, `X64-15GB`, `X64-30GB`, `X64-60GB`, `X64-120GB` + `C2L`, `X64-2GB`, `X64-4GB`, `X64-8GB`, `X64-15GB`, `X64-30GB`, `X64-60GB`, `X64-120GB`, `ARM64-2GB`, `ARM64-4GB`, `ARM64-8GB`, `ARM64-16GB`, `ARM64-32GB`, `ARM64-64GB`, `ARM64-128GB` ### Optional: -- `server_name` (string) - The name assigned to the server. +- `server_name` (string) - The name assigned to the server. Default `packer-UUID` - `image_name` (string) - The name of the resulting image that will - appear in your account. + appear in your account. Default `packer-TIMESTAMP` - `snapshot_name` (string) - The name of the resulting snapshot that will - appear in your account. + appear in your account. Default `packer-TIMESTAMP ## Basic Example @@ -78,13 +78,14 @@ access tokens: "type": "scaleway", "api_access_key": "YOUR API ACCESS KEY", "api_token": "YOUR TOKEN", - "image": "f01f8a48-c026-48ac-9771-a70eaac0890e", + "image": "UUID OF THE BASE IMAGE", "region": "par1", "commercial_type": "X64-2GB", "ssh_username": "root", "ssh_private_key_file": "~/.ssh/id_rsa", + Extra, } ``` When you do not specified the `ssh_private_key_file`, a temporarily SSH keypair is generated to connect the server. -This key will only allows the `root` user to connect the server. \ No newline at end of file +This key will only allow the `root` user to connect the server. From ae18995ca1e7a4c038b2f26c012359ff15cfac63 Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Tue, 11 Jul 2017 08:46:55 +0200 Subject: [PATCH 0616/1007] Fix builder id --- post-processor/vagrant/post-processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index 18357923f..f3bb6e346 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -26,7 +26,7 @@ var builtins = map[string]string{ "mitchellh.vmware-esx": "vmware", "pearkes.digitalocean": "digitalocean", "packer.googlecompute": "google", - "pearkes.scaleway": "scaleway", + "hashicorp.scaleway": "scaleway", "packer.parallels": "parallels", "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", From 520433c0b8ea5f9fc123e620109933bada6c9351 Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Tue, 11 Jul 2017 14:06:53 +0200 Subject: [PATCH 0617/1007] Cleanup documentation --- website/source/docs/builders/scaleway.html.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index e045f27bd..efa26dbee 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -48,7 +48,7 @@ builder. - `image` (string) - The UUID of the base image to use. This is the image that will be used to launch a new server and provision it. See - [https://api-marketplace.scaleway.com/images](https://api-marketplace.scaleway.com/images) to + [https://api-marketplace.scaleway.com/images](https://api-marketplace.scaleway.com/images) get the complete list of the accepted image UUID. - `region` (string) - The name of the region to launch the @@ -66,7 +66,7 @@ builder. appear in your account. Default `packer-TIMESTAMP` - `snapshot_name` (string) - The name of the resulting snapshot that will - appear in your account. Default `packer-TIMESTAMP + appear in your account. Default `packer-TIMESTAMP` ## Basic Example @@ -82,8 +82,7 @@ access tokens: "region": "par1", "commercial_type": "X64-2GB", "ssh_username": "root", - "ssh_private_key_file": "~/.ssh/id_rsa", - Extra, + "ssh_private_key_file": "~/.ssh/id_rsa" } ``` From b44798b38deb5a9ac86e3e153269d36587c7ba4d Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Tue, 11 Jul 2017 16:15:00 +0200 Subject: [PATCH 0618/1007] Raise error in case of create server failure --- builder/scaleway/step_create_server.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go index 3cf46e1ed..11fe284ab 100644 --- a/builder/scaleway/step_create_server.go +++ b/builder/scaleway/step_create_server.go @@ -34,10 +34,17 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { Tags: tags, }) + if err != nil { + err := fmt.Errorf("Error creating server: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + err = client.PostServerAction(server, "poweron") if err != nil { - err := fmt.Errorf("Error creating server: %s", err) + err := fmt.Errorf("Error starting server: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -51,7 +58,7 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { } func (s *stepCreateServer) Cleanup(state multistep.StateBag) { - if s.serverID != "" { + if s.serverID == "" { return } From eb56b1b70e38b3c0dd3f0850321a3ab0822cd37c Mon Sep 17 00:00:00 2001 From: Edouard BONLIEU <ebonlieu@gmail.com> Date: Fri, 21 Jul 2017 12:26:20 +0200 Subject: [PATCH 0619/1007] Fix terminate error --- builder/scaleway/builder.go | 7 ++++-- builder/scaleway/step_create_server.go | 5 +++- builder/scaleway/step_terminate.go | 34 -------------------------- 3 files changed, 9 insertions(+), 37 deletions(-) delete mode 100644 builder/scaleway/step_terminate.go diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index 14fee93a0..f2266576e 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -33,7 +33,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { - client, _ := api.NewScalewayAPI(b.config.Organization, b.config.Token, b.config.UserAgent, b.config.Region) + client, err := api.NewScalewayAPI(b.config.Organization, b.config.Token, b.config.UserAgent, b.config.Region) + + if err != nil { + return nil, err + } state := new(multistep.BasicStateBag) state.Put("config", b.config) @@ -58,7 +62,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe new(stepShutdown), new(stepSnapshot), new(stepImage), - new(stepTerminate), } b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go index 11fe284ab..ddd06fdf5 100644 --- a/builder/scaleway/step_create_server.go +++ b/builder/scaleway/step_create_server.go @@ -66,9 +66,12 @@ func (s *stepCreateServer) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) ui.Say("Destroying server...") - err := client.PostServerAction(s.serverID, "terminate") + + err := client.DeleteServerForce(s.serverID) + if err != nil { ui.Error(fmt.Sprintf( "Error destroying server. Please destroy it manually: %s", err)) } + } diff --git a/builder/scaleway/step_terminate.go b/builder/scaleway/step_terminate.go deleted file mode 100644 index 154750931..000000000 --- a/builder/scaleway/step_terminate.go +++ /dev/null @@ -1,34 +0,0 @@ -package scaleway - -import ( - "fmt" - - "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" - "github.com/scaleway/scaleway-cli/pkg/api" -) - -type stepTerminate struct{} - -func (s *stepTerminate) Run(state multistep.StateBag) multistep.StepAction { - client := state.Get("client").(*api.ScalewayAPI) - ui := state.Get("ui").(packer.Ui) - serverID := state.Get("server_id").(string) - - ui.Say("Terminating server...") - - err := client.DeleteServerForce(serverID) - - if err != nil { - err := fmt.Errorf("Error terminating server: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - return multistep.ActionContinue -} - -func (s *stepTerminate) Cleanup(state multistep.StateBag) { - // no cleanup -} From fc7d89eb79887f21cdb67a1e97f3e6e848134ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Carr?= <lcarr@online.net> Date: Fri, 5 Jan 2018 09:43:52 +0100 Subject: [PATCH 0620/1007] builder/scaleway: support password auth --- builder/scaleway/ssh.go | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/builder/scaleway/ssh.go b/builder/scaleway/ssh.go index 017138022..d1ac5dfc8 100644 --- a/builder/scaleway/ssh.go +++ b/builder/scaleway/ssh.go @@ -2,9 +2,10 @@ package scaleway import ( "fmt" - "golang.org/x/crypto/ssh" + packerssh "github.com/hashicorp/packer/communicator/ssh" "github.com/mitchellh/multistep" + "golang.org/x/crypto/ssh" ) func commHost(state multistep.StateBag) (string, error) { @@ -14,17 +15,32 @@ func commHost(state multistep.StateBag) (string, error) { func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) { config := state.Get("config").(Config) - privateKey := state.Get("privateKey").(string) + var privateKey string - signer, err := ssh.ParsePrivateKey([]byte(privateKey)) - if err != nil { - return nil, fmt.Errorf("Error setting up SSH config: %s", err) + var auth []ssh.AuthMethod + + if config.Comm.SSHPassword != "" { + auth = []ssh.AuthMethod{ + ssh.Password(config.Comm.SSHPassword), + ssh.KeyboardInteractive( + packerssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), + } + } + + if config.Comm.SSHPrivateKey != "" { + if priv, ok := state.GetOk("privateKey"); ok { + privateKey = priv.(string) + } + signer, err := ssh.ParsePrivateKey([]byte(privateKey)) + if err != nil { + return nil, fmt.Errorf("Error setting up SSH config: %s", err) + } + auth = append(auth, ssh.PublicKeys(signer)) } return &ssh.ClientConfig{ - User: config.Comm.SSHUsername, - Auth: []ssh.AuthMethod{ - ssh.PublicKeys(signer), - }, + User: config.Comm.SSHUsername, + Auth: auth, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), }, nil } From 7f8ed28bc6d89a8ce24e382caa09ffacc6a48288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Carr?= <lcarr@online.net> Date: Fri, 5 Jan 2018 09:57:59 +0100 Subject: [PATCH 0621/1007] builder/scaleway: Make use of NewRunnerWithPauseFn --- builder/scaleway/builder.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index f2266576e..266b9e41b 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -4,6 +4,7 @@ package scaleway import ( + "errors" "fmt" "log" @@ -64,16 +65,24 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe new(stepImage), } - b.runner = common.NewRunner(steps, b.config.PackerConfig, ui) + b.runner = common.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state) b.runner.Run(state) if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } + // If we were interrupted or cancelled, then just exit. + if _, ok := state.GetOk(multistep.StateCancelled); ok { + return nil, errors.New("Build was cancelled.") + } + + if _, ok := state.GetOk(multistep.StateHalted); ok { + return nil, errors.New("Build was halted.") + } + if _, ok := state.GetOk("snapshot_name"); !ok { - log.Println("Failed to find snapshot_name in state. Bug?") - return nil, nil + return nil, errors.New("Cannot find snapshot_name in state.") } artifact := &Artifact{ From 1f7c32db98036f1c149813b0c2f5165928350cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Carr?= <lcarr@online.net> Date: Fri, 5 Jan 2018 10:07:03 +0100 Subject: [PATCH 0622/1007] builder/scaleway: report to ui scw api startup error --- builder/scaleway/builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index 266b9e41b..8c5d79fde 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -37,6 +37,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe client, err := api.NewScalewayAPI(b.config.Organization, b.config.Token, b.config.UserAgent, b.config.Region) if err != nil { + ui.Error(err.Error()) return nil, err } From 22b12432db290af7589dcdcd49eba39c95470c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Carr?= <lcarr@online.net> Date: Sat, 6 Jan 2018 14:56:46 +0100 Subject: [PATCH 0623/1007] builder/scaleway: support ssh agent authentication --- builder/scaleway/ssh.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/builder/scaleway/ssh.go b/builder/scaleway/ssh.go index d1ac5dfc8..2e566936e 100644 --- a/builder/scaleway/ssh.go +++ b/builder/scaleway/ssh.go @@ -2,10 +2,13 @@ package scaleway import ( "fmt" + "net" + "os" packerssh "github.com/hashicorp/packer/communicator/ssh" "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/agent" ) func commHost(state multistep.StateBag) (string, error) { @@ -19,12 +22,27 @@ func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) { var auth []ssh.AuthMethod - if config.Comm.SSHPassword != "" { + if config.Comm.SSHAgentAuth { + authSock := os.Getenv("SSH_AUTH_SOCK") + if authSock == "" { + return nil, fmt.Errorf("SSH_AUTH_SOCK is not set") + } + + sshAgent, err := net.Dial("unix", authSock) + if err != nil { + return nil, fmt.Errorf("Cannot connect to SSH Agent socket %q: %s", authSock, err) + } auth = []ssh.AuthMethod{ + ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers), + } + } + + if config.Comm.SSHPassword != "" { + auth = append(auth, ssh.Password(config.Comm.SSHPassword), ssh.KeyboardInteractive( packerssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), - } + ) } if config.Comm.SSHPrivateKey != "" { From e752e3a01847351130f3854d77a3d00ccd5dca4b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 5 Feb 2018 16:50:32 -0800 Subject: [PATCH 0624/1007] use new internal multistep helper --- builder/scaleway/builder.go | 2 +- builder/scaleway/ssh.go | 2 +- builder/scaleway/step_create_image.go | 5 +++-- builder/scaleway/step_create_server.go | 5 +++-- builder/scaleway/step_create_ssh_key.go | 5 +++-- builder/scaleway/step_server_info.go | 5 +++-- builder/scaleway/step_shutdown.go | 5 +++-- builder/scaleway/step_snapshot.go | 5 +++-- 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/builder/scaleway/builder.go b/builder/scaleway/builder.go index 8c5d79fde..457002c74 100644 --- a/builder/scaleway/builder.go +++ b/builder/scaleway/builder.go @@ -10,8 +10,8 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" ) diff --git a/builder/scaleway/ssh.go b/builder/scaleway/ssh.go index 2e566936e..a2c9b8f16 100644 --- a/builder/scaleway/ssh.go +++ b/builder/scaleway/ssh.go @@ -6,7 +6,7 @@ import ( "os" packerssh "github.com/hashicorp/packer/communicator/ssh" - "github.com/mitchellh/multistep" + "github.com/hashicorp/packer/helper/multistep" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" ) diff --git a/builder/scaleway/step_create_image.go b/builder/scaleway/step_create_image.go index 313f2e421..16345e74d 100644 --- a/builder/scaleway/step_create_image.go +++ b/builder/scaleway/step_create_image.go @@ -1,17 +1,18 @@ package scaleway import ( + "context" "fmt" "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" ) type stepImage struct{} -func (s *stepImage) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepImage) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) diff --git a/builder/scaleway/step_create_server.go b/builder/scaleway/step_create_server.go index ddd06fdf5..57511d149 100644 --- a/builder/scaleway/step_create_server.go +++ b/builder/scaleway/step_create_server.go @@ -1,11 +1,12 @@ package scaleway import ( + "context" "fmt" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" ) @@ -13,7 +14,7 @@ type stepCreateServer struct { serverID string } -func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) diff --git a/builder/scaleway/step_create_ssh_key.go b/builder/scaleway/step_create_ssh_key.go index dab8f710b..c5405ccd6 100644 --- a/builder/scaleway/step_create_ssh_key.go +++ b/builder/scaleway/step_create_ssh_key.go @@ -1,6 +1,7 @@ package scaleway import ( + "context" "crypto/rand" "crypto/rsa" "crypto/x509" @@ -12,8 +13,8 @@ import ( "runtime" "strings" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "golang.org/x/crypto/ssh" ) @@ -23,7 +24,7 @@ type stepCreateSSHKey struct { PrivateKeyFile string } -func (s *stepCreateSSHKey) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) if s.PrivateKeyFile != "" { diff --git a/builder/scaleway/step_server_info.go b/builder/scaleway/step_server_info.go index 38502fe4d..7ab14658f 100644 --- a/builder/scaleway/step_server_info.go +++ b/builder/scaleway/step_server_info.go @@ -1,16 +1,17 @@ package scaleway import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" ) type stepServerInfo struct{} -func (s *stepServerInfo) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepServerInfo) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) serverID := state.Get("server_id").(string) diff --git a/builder/scaleway/step_shutdown.go b/builder/scaleway/step_shutdown.go index b8e45be51..a8a029259 100644 --- a/builder/scaleway/step_shutdown.go +++ b/builder/scaleway/step_shutdown.go @@ -1,16 +1,17 @@ package scaleway import ( + "context" "fmt" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" ) type stepShutdown struct{} -func (s *stepShutdown) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepShutdown) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) serverID := state.Get("server_id").(string) diff --git a/builder/scaleway/step_snapshot.go b/builder/scaleway/step_snapshot.go index 20301a444..fd0dcb593 100644 --- a/builder/scaleway/step_snapshot.go +++ b/builder/scaleway/step_snapshot.go @@ -1,17 +1,18 @@ package scaleway import ( + "context" "fmt" "log" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/mitchellh/multistep" "github.com/scaleway/scaleway-cli/pkg/api" ) type stepSnapshot struct{} -func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction { +func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*api.ScalewayAPI) ui := state.Get("ui").(packer.Ui) c := state.Get("config").(Config) From 8b7982480fcf5772aed796753eedf5a537885c66 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 5 Feb 2018 16:51:54 -0800 Subject: [PATCH 0625/1007] fix sidebar placement --- website/source/layouts/docs.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 271de572f..5f089e041 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -90,9 +90,6 @@ </li> </ul> </li> - <li<%= sidebar_current("docs-builders-scaleway") %>> - <a href="/docs/builders/scaleway.html">Scaleway</a> - </li> <li<%= sidebar_current("docs-builders-cloudstack") %>> <a href="/docs/builders/cloudstack.html">CloudStack</a> </li> @@ -165,6 +162,9 @@ <li<%= sidebar_current("docs-builders-qemu") %>> <a href="/docs/builders/qemu.html">QEMU</a> </li> + <li<%= sidebar_current("docs-builders-scaleway") %>> + <a href="/docs/builders/scaleway.html">Scaleway</a> + </li> <li<%= sidebar_current("docs-builders-triton") %>> <a href="/docs/builders/triton.html">Triton</a> </li> From 44647ea185befa9b21668b011d0c17ffe0a212a9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 5 Feb 2018 16:52:44 -0800 Subject: [PATCH 0626/1007] add vendor deps --- .../github.com/Sirupsen/logrus/CHANGELOG.md | 94 + vendor/github.com/Sirupsen/logrus/LICENSE | 21 + vendor/github.com/Sirupsen/logrus/README.md | 479 +++ vendor/github.com/Sirupsen/logrus/alt_exit.go | 64 + vendor/github.com/Sirupsen/logrus/doc.go | 26 + vendor/github.com/Sirupsen/logrus/entry.go | 275 ++ vendor/github.com/Sirupsen/logrus/exported.go | 193 ++ .../github.com/Sirupsen/logrus/formatter.go | 45 + vendor/github.com/Sirupsen/logrus/hooks.go | 34 + .../Sirupsen/logrus/json_formatter.go | 74 + vendor/github.com/Sirupsen/logrus/logger.go | 308 ++ vendor/github.com/Sirupsen/logrus/logrus.go | 143 + .../Sirupsen/logrus/terminal_bsd.go | 10 + .../Sirupsen/logrus/terminal_linux.go | 14 + .../Sirupsen/logrus/terminal_notwindows.go | 28 + .../Sirupsen/logrus/terminal_solaris.go | 21 + .../Sirupsen/logrus/terminal_windows.go | 33 + .../Sirupsen/logrus/text_formatter.go | 189 ++ vendor/github.com/Sirupsen/logrus/writer.go | 62 + vendor/github.com/creack/goselect/Dockerfile | 5 + vendor/github.com/creack/goselect/LICENSE | 22 + vendor/github.com/creack/goselect/README.md | 30 + vendor/github.com/creack/goselect/fdset.go | 33 + vendor/github.com/creack/goselect/fdset_32.go | 10 + vendor/github.com/creack/goselect/fdset_64.go | 11 + .../github.com/creack/goselect/fdset_doc.go | 93 + .../creack/goselect/fdset_freebsd.go | 33 + .../creack/goselect/fdset_unsupported.go | 20 + .../creack/goselect/fdset_windows.go | 57 + vendor/github.com/creack/goselect/select.go | 28 + .../creack/goselect/select_linux.go | 10 + .../creack/goselect/select_other.go | 9 + .../creack/goselect/select_unsupported.go | 16 + .../creack/goselect/select_windows.go | 13 + .../creack/goselect/test_crosscompile.sh | 17 + .../creack/goselect/zselect_windows.go | 41 + vendor/github.com/docker/docker/LICENSE | 191 ++ vendor/github.com/docker/docker/NOTICE | 19 + .../pkg/namesgenerator/names-generator.go | 608 ++++ .../docker/docker/pkg/random/random.go | 71 + vendor/github.com/dustin/go-humanize/LICENSE | 21 + .../dustin/go-humanize/README.markdown | 92 + vendor/github.com/dustin/go-humanize/big.go | 31 + .../github.com/dustin/go-humanize/bigbytes.go | 173 ++ vendor/github.com/dustin/go-humanize/bytes.go | 143 + vendor/github.com/dustin/go-humanize/comma.go | 108 + .../github.com/dustin/go-humanize/commaf.go | 40 + vendor/github.com/dustin/go-humanize/ftoa.go | 23 + .../github.com/dustin/go-humanize/humanize.go | 8 + .../github.com/dustin/go-humanize/number.go | 192 ++ .../github.com/dustin/go-humanize/ordinals.go | 25 + vendor/github.com/dustin/go-humanize/si.go | 113 + vendor/github.com/dustin/go-humanize/times.go | 117 + vendor/github.com/gorilla/websocket/AUTHORS | 8 + vendor/github.com/gorilla/websocket/LICENSE | 22 + vendor/github.com/gorilla/websocket/README.md | 64 + vendor/github.com/gorilla/websocket/client.go | 392 +++ .../gorilla/websocket/client_clone.go | 16 + .../gorilla/websocket/client_clone_legacy.go | 38 + .../gorilla/websocket/compression.go | 148 + vendor/github.com/gorilla/websocket/conn.go | 1149 +++++++ .../github.com/gorilla/websocket/conn_read.go | 18 + .../gorilla/websocket/conn_read_legacy.go | 21 + vendor/github.com/gorilla/websocket/doc.go | 180 ++ vendor/github.com/gorilla/websocket/json.go | 55 + vendor/github.com/gorilla/websocket/mask.go | 55 + .../github.com/gorilla/websocket/prepared.go | 103 + vendor/github.com/gorilla/websocket/server.go | 291 ++ vendor/github.com/gorilla/websocket/util.go | 214 ++ vendor/github.com/moul/anonuuid/LICENSE | 22 + vendor/github.com/moul/anonuuid/Makefile | 73 + vendor/github.com/moul/anonuuid/README.md | 170 + vendor/github.com/moul/anonuuid/anonuuid.go | 229 ++ vendor/github.com/moul/gotty-client/LICENSE | 22 + vendor/github.com/moul/gotty-client/Makefile | 81 + vendor/github.com/moul/gotty-client/README.md | 201 ++ vendor/github.com/moul/gotty-client/arch.go | 34 + .../moul/gotty-client/arch_windows.go | 16 + .../github.com/moul/gotty-client/glide.lock | 37 + .../github.com/moul/gotty-client/glide.yaml | 35 + .../moul/gotty-client/gotty-client.go | 469 +++ .../github.com/renstrom/fuzzysearch/LICENSE | 21 + .../renstrom/fuzzysearch/fuzzy/fuzzy.go | 167 + .../renstrom/fuzzysearch/fuzzy/levenshtein.go | 43 + .../scaleway/scaleway-cli/LICENSE.md | 22 + .../scaleway/scaleway-cli/pkg/api/README.md | 25 + .../scaleway/scaleway-cli/pkg/api/api.go | 2754 +++++++++++++++++ .../scaleway/scaleway-cli/pkg/api/cache.go | 814 +++++ .../scaleway/scaleway-cli/pkg/api/helpers.go | 685 ++++ .../scaleway/scaleway-cli/pkg/api/logger.go | 77 + .../scaleway-cli/pkg/sshcommand/sshcommand.go | 124 + .../scaleway/scaleway-cli/pkg/utils/quiet.go | 30 + .../scaleway/scaleway-cli/pkg/utils/utils.go | 253 ++ .../x/crypto/ssh/terminal/terminal.go | 951 ++++++ .../golang.org/x/crypto/ssh/terminal/util.go | 119 + .../x/crypto/ssh/terminal/util_bsd.go | 12 + .../x/crypto/ssh/terminal/util_linux.go | 11 + .../x/crypto/ssh/terminal/util_plan9.go | 58 + .../x/crypto/ssh/terminal/util_solaris.go | 73 + .../x/crypto/ssh/terminal/util_windows.go | 155 + vendor/golang.org/x/sync/LICENSE | 27 + vendor/golang.org/x/sync/PATENTS | 22 + vendor/golang.org/x/sync/errgroup/errgroup.go | 67 + 103 files changed, 15209 insertions(+) create mode 100644 vendor/github.com/Sirupsen/logrus/CHANGELOG.md create mode 100644 vendor/github.com/Sirupsen/logrus/LICENSE create mode 100644 vendor/github.com/Sirupsen/logrus/README.md create mode 100644 vendor/github.com/Sirupsen/logrus/alt_exit.go create mode 100644 vendor/github.com/Sirupsen/logrus/doc.go create mode 100644 vendor/github.com/Sirupsen/logrus/entry.go create mode 100644 vendor/github.com/Sirupsen/logrus/exported.go create mode 100644 vendor/github.com/Sirupsen/logrus/formatter.go create mode 100644 vendor/github.com/Sirupsen/logrus/hooks.go create mode 100644 vendor/github.com/Sirupsen/logrus/json_formatter.go create mode 100644 vendor/github.com/Sirupsen/logrus/logger.go create mode 100644 vendor/github.com/Sirupsen/logrus/logrus.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_bsd.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_linux.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_notwindows.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_solaris.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_windows.go create mode 100644 vendor/github.com/Sirupsen/logrus/text_formatter.go create mode 100644 vendor/github.com/Sirupsen/logrus/writer.go create mode 100644 vendor/github.com/creack/goselect/Dockerfile create mode 100644 vendor/github.com/creack/goselect/LICENSE create mode 100644 vendor/github.com/creack/goselect/README.md create mode 100644 vendor/github.com/creack/goselect/fdset.go create mode 100644 vendor/github.com/creack/goselect/fdset_32.go create mode 100644 vendor/github.com/creack/goselect/fdset_64.go create mode 100644 vendor/github.com/creack/goselect/fdset_doc.go create mode 100644 vendor/github.com/creack/goselect/fdset_freebsd.go create mode 100644 vendor/github.com/creack/goselect/fdset_unsupported.go create mode 100644 vendor/github.com/creack/goselect/fdset_windows.go create mode 100644 vendor/github.com/creack/goselect/select.go create mode 100644 vendor/github.com/creack/goselect/select_linux.go create mode 100644 vendor/github.com/creack/goselect/select_other.go create mode 100644 vendor/github.com/creack/goselect/select_unsupported.go create mode 100644 vendor/github.com/creack/goselect/select_windows.go create mode 100755 vendor/github.com/creack/goselect/test_crosscompile.sh create mode 100644 vendor/github.com/creack/goselect/zselect_windows.go create mode 100644 vendor/github.com/docker/docker/LICENSE create mode 100644 vendor/github.com/docker/docker/NOTICE create mode 100644 vendor/github.com/docker/docker/pkg/namesgenerator/names-generator.go create mode 100644 vendor/github.com/docker/docker/pkg/random/random.go create mode 100644 vendor/github.com/dustin/go-humanize/LICENSE create mode 100644 vendor/github.com/dustin/go-humanize/README.markdown create mode 100644 vendor/github.com/dustin/go-humanize/big.go create mode 100644 vendor/github.com/dustin/go-humanize/bigbytes.go create mode 100644 vendor/github.com/dustin/go-humanize/bytes.go create mode 100644 vendor/github.com/dustin/go-humanize/comma.go create mode 100644 vendor/github.com/dustin/go-humanize/commaf.go create mode 100644 vendor/github.com/dustin/go-humanize/ftoa.go create mode 100644 vendor/github.com/dustin/go-humanize/humanize.go create mode 100644 vendor/github.com/dustin/go-humanize/number.go create mode 100644 vendor/github.com/dustin/go-humanize/ordinals.go create mode 100644 vendor/github.com/dustin/go-humanize/si.go create mode 100644 vendor/github.com/dustin/go-humanize/times.go create mode 100644 vendor/github.com/gorilla/websocket/AUTHORS create mode 100644 vendor/github.com/gorilla/websocket/LICENSE create mode 100644 vendor/github.com/gorilla/websocket/README.md create mode 100644 vendor/github.com/gorilla/websocket/client.go create mode 100644 vendor/github.com/gorilla/websocket/client_clone.go create mode 100644 vendor/github.com/gorilla/websocket/client_clone_legacy.go create mode 100644 vendor/github.com/gorilla/websocket/compression.go create mode 100644 vendor/github.com/gorilla/websocket/conn.go create mode 100644 vendor/github.com/gorilla/websocket/conn_read.go create mode 100644 vendor/github.com/gorilla/websocket/conn_read_legacy.go create mode 100644 vendor/github.com/gorilla/websocket/doc.go create mode 100644 vendor/github.com/gorilla/websocket/json.go create mode 100644 vendor/github.com/gorilla/websocket/mask.go create mode 100644 vendor/github.com/gorilla/websocket/prepared.go create mode 100644 vendor/github.com/gorilla/websocket/server.go create mode 100644 vendor/github.com/gorilla/websocket/util.go create mode 100644 vendor/github.com/moul/anonuuid/LICENSE create mode 100644 vendor/github.com/moul/anonuuid/Makefile create mode 100644 vendor/github.com/moul/anonuuid/README.md create mode 100644 vendor/github.com/moul/anonuuid/anonuuid.go create mode 100644 vendor/github.com/moul/gotty-client/LICENSE create mode 100644 vendor/github.com/moul/gotty-client/Makefile create mode 100644 vendor/github.com/moul/gotty-client/README.md create mode 100644 vendor/github.com/moul/gotty-client/arch.go create mode 100644 vendor/github.com/moul/gotty-client/arch_windows.go create mode 100644 vendor/github.com/moul/gotty-client/glide.lock create mode 100644 vendor/github.com/moul/gotty-client/glide.yaml create mode 100644 vendor/github.com/moul/gotty-client/gotty-client.go create mode 100644 vendor/github.com/renstrom/fuzzysearch/LICENSE create mode 100644 vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go create mode 100644 vendor/github.com/renstrom/fuzzysearch/fuzzy/levenshtein.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/LICENSE.md create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/api/logger.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/sshcommand/sshcommand.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/utils/quiet.go create mode 100644 vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_linux.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_windows.go create mode 100644 vendor/golang.org/x/sync/LICENSE create mode 100644 vendor/golang.org/x/sync/PATENTS create mode 100644 vendor/golang.org/x/sync/errgroup/errgroup.go diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md new file mode 100644 index 000000000..747e4d89a --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md @@ -0,0 +1,94 @@ +# 0.11.5 + +* feature: add writer and writerlevel to entry (#372) + +# 0.11.4 + +* bug: fix undefined variable on solaris (#493) + +# 0.11.3 + +* formatter: configure quoting of empty values (#484) +* formatter: configure quoting character (default is `"`) (#484) +* bug: fix not importing io correctly in non-linux environments (#481) + +# 0.11.2 + +* bug: fix windows terminal detection (#476) + +# 0.11.1 + +* bug: fix tty detection with custom out (#471) + +# 0.11.0 + +* performance: Use bufferpool to allocate (#370) +* terminal: terminal detection for app-engine (#343) +* feature: exit handler (#375) + +# 0.10.0 + +* feature: Add a test hook (#180) +* feature: `ParseLevel` is now case-insensitive (#326) +* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) +* performance: avoid re-allocations on `WithFields` (#335) + +# 0.9.0 + +* logrus/text_formatter: don't emit empty msg +* logrus/hooks/airbrake: move out of main repository +* logrus/hooks/sentry: move out of main repository +* logrus/hooks/papertrail: move out of main repository +* logrus/hooks/bugsnag: move out of main repository +* logrus/core: run tests with `-race` +* logrus/core: detect TTY based on `stderr` +* logrus/core: support `WithError` on logger +* logrus/core: Solaris support + +# 0.8.7 + +* logrus/core: fix possible race (#216) +* logrus/doc: small typo fixes and doc improvements + + +# 0.8.6 + +* hooks/raven: allow passing an initialized client + +# 0.8.5 + +* logrus/core: revert #208 + +# 0.8.4 + +* formatter/text: fix data race (#218) + +# 0.8.3 + +* logrus/core: fix entry log level (#208) +* logrus/core: improve performance of text formatter by 40% +* logrus/core: expose `LevelHooks` type +* logrus/core: add support for DragonflyBSD and NetBSD +* formatter/text: print structs more verbosely + +# 0.8.2 + +* logrus: fix more Fatal family functions + +# 0.8.1 + +* logrus: fix not exiting on `Fatalf` and `Fatalln` + +# 0.8.0 + +* logrus: defaults to stderr instead of stdout +* hooks/sentry: add special field for `*http.Request` +* formatter/text: ignore Windows for colors + +# 0.7.3 + +* formatter/\*: allow configuration of timestamp layout + +# 0.7.2 + +* formatter/text: Add configuration option for time format (#158) diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/Sirupsen/logrus/LICENSE new file mode 100644 index 000000000..f090cb42f --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Simon Eskildsen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md new file mode 100644 index 000000000..c32287611 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/README.md @@ -0,0 +1,479 @@ +# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>&nbsp;[![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus)&nbsp;[![GoDoc](https://godoc.org/github.com/Sirupsen/logrus?status.svg)](https://godoc.org/github.com/Sirupsen/logrus) + +**Seeing weird case-sensitive problems?** See [this +issue](https://github.com/sirupsen/logrus/issues/451#issuecomment-264332021). +This change has been reverted. I apologize for causing this. I greatly +underestimated the impact this would have. Logrus strives for stability and +backwards compatibility and failed to provide that. + +Logrus is a structured logger for Go (golang), completely API compatible with +the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not +yet stable (pre 1.0). Logrus itself is completely stable and has been used in +many large deployments. The core API is unlikely to change much but please +version control your Logrus to make sure you aren't fetching latest `master` on +every build.** + +Nicely color-coded in development (when a TTY is attached, otherwise just +plain text): + +![Colored](http://i.imgur.com/PY7qMwd.png) + +With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash +or Splunk: + +```json +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the +ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} + +{"level":"warning","msg":"The group's number increased tremendously!", +"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"A giant walrus appears!", +"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", +"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} + +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, +"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +``` + +With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not +attached, the output is compatible with the +[logfmt](http://godoc.org/github.com/kr/logfmt) format: + +```text +time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 +time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 +time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true +time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 +time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 +time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true +exit status 1 +``` + +#### Example + +The simplest way to use Logrus is simply the package-level exported logger: + +```go +package main + +import ( + log "github.com/Sirupsen/logrus" +) + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + }).Info("A walrus appears") +} +``` + +Note that it's completely api-compatible with the stdlib logger, so you can +replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` +and you'll now have the flexibility of Logrus. You can customize it all you +want: + +```go +package main + +import ( + "os" + log "github.com/Sirupsen/logrus" +) + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&log.JSONFormatter{}) + + // Output to stdout instead of the default stderr + // Can be any io.Writer, see below for File example + log.SetOutput(os.Stdout) + + // Only log the warning severity or above. + log.SetLevel(log.WarnLevel) +} + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(log.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(log.Fields{ + "omg": true, + "number": 100, + }).Fatal("The ice breaks!") + + // A common pattern is to re-use fields between logging statements by re-using + // the logrus.Entry returned from WithFields() + contextLogger := log.WithFields(log.Fields{ + "common": "this is a common field", + "other": "I also should be logged always", + }) + + contextLogger.Info("I'll be logged with common and other field") + contextLogger.Info("Me too") +} +``` + +For more advanced usage such as logging to multiple locations from the same +application, you can also create an instance of the `logrus` Logger: + +```go +package main + +import ( + "os" + "github.com/Sirupsen/logrus" +) + +// Create a new instance of the logger. You can have any number of instances. +var log = logrus.New() + +func main() { + // The API for setting attributes is a little different than the package level + // exported logger. See Godoc. + log.Out = os.Stdout + + // You could set this to any `io.Writer` such as a file + // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) + // if err == nil { + // log.Out = file + // } else { + // log.Info("Failed to log to file, using default stderr") + // } + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") +} +``` + +#### Fields + +Logrus encourages careful, structured logging though logging fields instead of +long, unparseable error messages. For example, instead of: `log.Fatalf("Failed +to send event %s to topic %s with key %d")`, you should log the much more +discoverable: + +```go +log.WithFields(log.Fields{ + "event": event, + "topic": topic, + "key": key, +}).Fatal("Failed to send event") +``` + +We've found this API forces you to think about logging in a way that produces +much more useful logging messages. We've been in countless situations where just +a single added field to a log statement that was already there would've saved us +hours. The `WithFields` call is optional. + +In general, with Logrus using any of the `printf`-family functions should be +seen as a hint you should add a field, however, you can still use the +`printf`-family functions with Logrus. + +#### Default Fields + +Often it's helpful to have fields _always_ attached to log statements in an +application or parts of one. For example, you may want to always log the +`request_id` and `user_ip` in the context of a request. Instead of writing +`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on +every line, you can create a `logrus.Entry` to pass around instead: + +```go +requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}) +requestLogger.Info("something happened on that request") # will log request_id and user_ip +requestLogger.Warn("something not great happened") +``` + +#### Hooks + +You can add hooks for logging levels. For example to send errors to an exception +tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to +multiple places simultaneously, e.g. syslog. + +Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in +`init`: + +```go +import ( + log "github.com/Sirupsen/logrus" + "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake" + logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" + "log/syslog" +) + +func init() { + + // Use the Airbrake hook to report errors that have Error severity or above to + // an exception tracker. You can create custom hooks, see the Hooks section. + log.AddHook(airbrake.NewHook(123, "xyz", "production")) + + hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") + if err != nil { + log.Error("Unable to connect to local syslog daemon") + } else { + log.AddHook(hook) + } +} +``` +Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). + +| Hook | Description | +| ----- | ----------- | +| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | +| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. | +| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) | +| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) | +| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | +| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic | +| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) | +| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch| +| [Firehose](https://github.com/beaubrewer/firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/) +| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | +| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) | +| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) | +| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | +| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | +| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb | +| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) | +| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | +| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka | +| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | +| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) | +| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) | +| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) | +| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | +| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) | +| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | +| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | +| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) | +| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit | +| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. | +| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) | +| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) | +| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | +| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) | +| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | +| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)| +| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. | +| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | +| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) | +| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)| +| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | +| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) | +| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) | +| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash | + +#### Level logging + +Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. + +```go +log.Debug("Useful debugging information.") +log.Info("Something noteworthy happened!") +log.Warn("You should probably take a look at this.") +log.Error("Something failed but I'm not quitting.") +// Calls os.Exit(1) after logging +log.Fatal("Bye.") +// Calls panic() after logging +log.Panic("I'm bailing.") +``` + +You can set the logging level on a `Logger`, then it will only log entries with +that severity or anything above it: + +```go +// Will log anything that is info or above (warn, error, fatal, panic). Default. +log.SetLevel(log.InfoLevel) +``` + +It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose +environment if your application has that. + +#### Entries + +Besides the fields added with `WithField` or `WithFields` some fields are +automatically added to all logging events: + +1. `time`. The timestamp when the entry was created. +2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after + the `AddFields` call. E.g. `Failed to send event.` +3. `level`. The logging level. E.g. `info`. + +#### Environments + +Logrus has no notion of environment. + +If you wish for hooks and formatters to only be used in specific environments, +you should handle that yourself. For example, if your application has a global +variable `Environment`, which is a string representation of the environment you +could do: + +```go +import ( + log "github.com/Sirupsen/logrus" +) + +init() { + // do something here to set environment depending on an environment variable + // or command-line flag + if Environment == "production" { + log.SetFormatter(&log.JSONFormatter{}) + } else { + // The TextFormatter is default, you don't actually have to do this. + log.SetFormatter(&log.TextFormatter{}) + } +} +``` + +This configuration is how `logrus` was intended to be used, but JSON in +production is mostly only useful if you do log aggregation with tools like +Splunk or Logstash. + +#### Formatters + +The built-in logging formatters are: + +* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise + without colors. + * *Note:* to force colored output when there is no TTY, set the `ForceColors` + field to `true`. To force no colored output even if there is a TTY set the + `DisableColors` field to `true`. For Windows, see + [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). + * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). +* `logrus.JSONFormatter`. Logs fields as JSON. + * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). + +Third party logging formatters: + +* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events. +* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. +* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. + +You can define your formatter by implementing the `Formatter` interface, +requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a +`Fields` type (`map[string]interface{}`) with all your fields as well as the +default ones (see Entries section above): + +```go +type MyJSONFormatter struct { +} + +log.SetFormatter(new(MyJSONFormatter)) + +func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { + // Note this doesn't include Time, Level and Message which are available on + // the Entry. Consult `godoc` on information about those fields or read the + // source of the official loggers. + serialized, err := json.Marshal(entry.Data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} +``` + +#### Logger as an `io.Writer` + +Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. + +```go +w := logger.Writer() +defer w.Close() + +srv := http.Server{ + // create a stdlib log.Logger that writes to + // logrus.Logger. + ErrorLog: log.New(w, "", 0), +} +``` + +Each line written to that writer will be printed the usual way, using formatters +and hooks. The level for those entries is `info`. + +This means that we can override the standard library logger easily: + +```go +logger := logrus.New() +logger.Formatter = &logrus.JSONFormatter{} + +// Use logrus for standard log output +// Note that `log` here references stdlib's log +// Not logrus imported under the name `log`. +log.SetOutput(logger.Writer()) +``` + +#### Rotation + +Log rotation is not provided with Logrus. Log rotation should be done by an +external program (like `logrotate(8)`) that can compress and delete old log +entries. It should not be a feature of the application-level logger. + +#### Tools + +| Tool | Description | +| ---- | ----------- | +|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.| +|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | + +#### Testing + +Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: + +* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook +* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): + +```go +logger, hook := NewNullLogger() +logger.Error("Hello error") + +assert.Equal(1, len(hook.Entries)) +assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level) +assert.Equal("Hello error", hook.LastEntry().Message) + +hook.Reset() +assert.Nil(hook.LastEntry()) +``` + +#### Fatal handlers + +Logrus can register one or more functions that will be called when any `fatal` +level message is logged. The registered handlers will be executed before +logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need +to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. + +``` +... +handler := func() { + // gracefully shutdown something... +} +logrus.RegisterExitHandler(handler) +... +``` + +#### Thread safety + +By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs. +If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking. + +Situation when locking is not needed includes: + +* You have no hooks registered, or hooks calling is already thread-safe. + +* Writing to logger.Out is already thread-safe, for example: + + 1) logger.Out is protected by locks. + + 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing) + + (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/Sirupsen/logrus/alt_exit.go new file mode 100644 index 000000000..8af90637a --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/alt_exit.go @@ -0,0 +1,64 @@ +package logrus + +// The following code was sourced and modified from the +// https://github.com/tebeka/atexit package governed by the following license: +// +// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import ( + "fmt" + "os" +) + +var handlers = []func(){} + +func runHandler(handler func()) { + defer func() { + if err := recover(); err != nil { + fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) + } + }() + + handler() +} + +func runHandlers() { + for _, handler := range handlers { + runHandler(handler) + } +} + +// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) +func Exit(code int) { + runHandlers() + os.Exit(code) +} + +// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke +// all handlers. The handlers will also be invoked when any Fatal log entry is +// made. +// +// This method is useful when a caller wishes to use logrus to log a fatal +// message but also needs to gracefully shutdown. An example usecase could be +// closing database connections, or sending a alert that the application is +// closing. +func RegisterExitHandler(handler func()) { + handlers = append(handlers, handler) +} diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/Sirupsen/logrus/doc.go new file mode 100644 index 000000000..dddd5f877 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/doc.go @@ -0,0 +1,26 @@ +/* +Package logrus is a structured logger for Go, completely API compatible with the standard library logger. + + +The simplest way to use Logrus is simply the package-level exported logger: + + package main + + import ( + log "github.com/Sirupsen/logrus" + ) + + func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "number": 1, + "size": 10, + }).Info("A walrus appears") + } + +Output: + time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 + +For a full guide visit https://github.com/Sirupsen/logrus +*/ +package logrus diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go new file mode 100644 index 000000000..4edbe7a2d --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/entry.go @@ -0,0 +1,275 @@ +package logrus + +import ( + "bytes" + "fmt" + "os" + "sync" + "time" +) + +var bufferPool *sync.Pool + +func init() { + bufferPool = &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + } +} + +// Defines the key when adding errors using WithError. +var ErrorKey = "error" + +// An entry is the final or intermediate Logrus logging entry. It contains all +// the fields passed with WithField{,s}. It's finally logged when Debug, Info, +// Warn, Error, Fatal or Panic is called on it. These objects can be reused and +// passed around as much as you wish to avoid field duplication. +type Entry struct { + Logger *Logger + + // Contains all the fields set by the user. + Data Fields + + // Time at which the log entry was created + Time time.Time + + // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic + Level Level + + // Message passed to Debug, Info, Warn, Error, Fatal or Panic + Message string + + // When formatter is called in entry.log(), an Buffer may be set to entry + Buffer *bytes.Buffer +} + +func NewEntry(logger *Logger) *Entry { + return &Entry{ + Logger: logger, + // Default is three fields, give a little extra room + Data: make(Fields, 5), + } +} + +// Returns the string representation from the reader and ultimately the +// formatter. +func (entry *Entry) String() (string, error) { + serialized, err := entry.Logger.Formatter.Format(entry) + if err != nil { + return "", err + } + str := string(serialized) + return str, nil +} + +// Add an error as single field (using the key defined in ErrorKey) to the Entry. +func (entry *Entry) WithError(err error) *Entry { + return entry.WithField(ErrorKey, err) +} + +// Add a single field to the Entry. +func (entry *Entry) WithField(key string, value interface{}) *Entry { + return entry.WithFields(Fields{key: value}) +} + +// Add a map of fields to the Entry. +func (entry *Entry) WithFields(fields Fields) *Entry { + data := make(Fields, len(entry.Data)+len(fields)) + for k, v := range entry.Data { + data[k] = v + } + for k, v := range fields { + data[k] = v + } + return &Entry{Logger: entry.Logger, Data: data} +} + +// This function is not declared with a pointer value because otherwise +// race conditions will occur when using multiple goroutines +func (entry Entry) log(level Level, msg string) { + var buffer *bytes.Buffer + entry.Time = time.Now() + entry.Level = level + entry.Message = msg + + if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + entry.Logger.mu.Unlock() + } + buffer = bufferPool.Get().(*bytes.Buffer) + buffer.Reset() + defer bufferPool.Put(buffer) + entry.Buffer = buffer + serialized, err := entry.Logger.Formatter.Format(&entry) + entry.Buffer = nil + if err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + entry.Logger.mu.Unlock() + } else { + entry.Logger.mu.Lock() + _, err = entry.Logger.Out.Write(serialized) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } + entry.Logger.mu.Unlock() + } + + // To avoid Entry#log() returning a value that only would make sense for + // panic() to use in Entry#Panic(), we avoid the allocation by checking + // directly here. + if level <= PanicLevel { + panic(&entry) + } +} + +func (entry *Entry) Debug(args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.log(DebugLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Print(args ...interface{}) { + entry.Info(args...) +} + +func (entry *Entry) Info(args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.log(InfoLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warn(args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.log(WarnLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warning(args ...interface{}) { + entry.Warn(args...) +} + +func (entry *Entry) Error(args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.log(ErrorLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Fatal(args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.log(FatalLevel, fmt.Sprint(args...)) + } + Exit(1) +} + +func (entry *Entry) Panic(args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.log(PanicLevel, fmt.Sprint(args...)) + } + panic(fmt.Sprint(args...)) +} + +// Entry Printf family functions + +func (entry *Entry) Debugf(format string, args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.Debug(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Infof(format string, args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.Info(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Printf(format string, args ...interface{}) { + entry.Infof(format, args...) +} + +func (entry *Entry) Warnf(format string, args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.Warn(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Warningf(format string, args ...interface{}) { + entry.Warnf(format, args...) +} + +func (entry *Entry) Errorf(format string, args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.Error(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Fatalf(format string, args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.Fatal(fmt.Sprintf(format, args...)) + } + Exit(1) +} + +func (entry *Entry) Panicf(format string, args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.Panic(fmt.Sprintf(format, args...)) + } +} + +// Entry Println family functions + +func (entry *Entry) Debugln(args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.Debug(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Infoln(args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.Info(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Println(args ...interface{}) { + entry.Infoln(args...) +} + +func (entry *Entry) Warnln(args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.Warn(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Warningln(args ...interface{}) { + entry.Warnln(args...) +} + +func (entry *Entry) Errorln(args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.Error(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Fatalln(args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.Fatal(entry.sprintlnn(args...)) + } + Exit(1) +} + +func (entry *Entry) Panicln(args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.Panic(entry.sprintlnn(args...)) + } +} + +// Sprintlnn => Sprint no newline. This is to get the behavior of how +// fmt.Sprintln where spaces are always added between operands, regardless of +// their type. Instead of vendoring the Sprintln implementation to spare a +// string allocation, we do the simplest thing. +func (entry *Entry) sprintlnn(args ...interface{}) string { + msg := fmt.Sprintln(args...) + return msg[:len(msg)-1] +} diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go new file mode 100644 index 000000000..9a0120ac1 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/exported.go @@ -0,0 +1,193 @@ +package logrus + +import ( + "io" +) + +var ( + // std is the name of the standard logger in stdlib `log` + std = New() +) + +func StandardLogger() *Logger { + return std +} + +// SetOutput sets the standard logger output. +func SetOutput(out io.Writer) { + std.mu.Lock() + defer std.mu.Unlock() + std.Out = out +} + +// SetFormatter sets the standard logger formatter. +func SetFormatter(formatter Formatter) { + std.mu.Lock() + defer std.mu.Unlock() + std.Formatter = formatter +} + +// SetLevel sets the standard logger level. +func SetLevel(level Level) { + std.mu.Lock() + defer std.mu.Unlock() + std.Level = level +} + +// GetLevel returns the standard logger level. +func GetLevel() Level { + std.mu.Lock() + defer std.mu.Unlock() + return std.Level +} + +// AddHook adds a hook to the standard logger hooks. +func AddHook(hook Hook) { + std.mu.Lock() + defer std.mu.Unlock() + std.Hooks.Add(hook) +} + +// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +func WithError(err error) *Entry { + return std.WithField(ErrorKey, err) +} + +// WithField creates an entry from the standard logger and adds a field to +// it. If you want multiple fields, use `WithFields`. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithField(key string, value interface{}) *Entry { + return std.WithField(key, value) +} + +// WithFields creates an entry from the standard logger and adds multiple +// fields to it. This is simply a helper for `WithField`, invoking it +// once for each field. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithFields(fields Fields) *Entry { + return std.WithFields(fields) +} + +// Debug logs a message at level Debug on the standard logger. +func Debug(args ...interface{}) { + std.Debug(args...) +} + +// Print logs a message at level Info on the standard logger. +func Print(args ...interface{}) { + std.Print(args...) +} + +// Info logs a message at level Info on the standard logger. +func Info(args ...interface{}) { + std.Info(args...) +} + +// Warn logs a message at level Warn on the standard logger. +func Warn(args ...interface{}) { + std.Warn(args...) +} + +// Warning logs a message at level Warn on the standard logger. +func Warning(args ...interface{}) { + std.Warning(args...) +} + +// Error logs a message at level Error on the standard logger. +func Error(args ...interface{}) { + std.Error(args...) +} + +// Panic logs a message at level Panic on the standard logger. +func Panic(args ...interface{}) { + std.Panic(args...) +} + +// Fatal logs a message at level Fatal on the standard logger. +func Fatal(args ...interface{}) { + std.Fatal(args...) +} + +// Debugf logs a message at level Debug on the standard logger. +func Debugf(format string, args ...interface{}) { + std.Debugf(format, args...) +} + +// Printf logs a message at level Info on the standard logger. +func Printf(format string, args ...interface{}) { + std.Printf(format, args...) +} + +// Infof logs a message at level Info on the standard logger. +func Infof(format string, args ...interface{}) { + std.Infof(format, args...) +} + +// Warnf logs a message at level Warn on the standard logger. +func Warnf(format string, args ...interface{}) { + std.Warnf(format, args...) +} + +// Warningf logs a message at level Warn on the standard logger. +func Warningf(format string, args ...interface{}) { + std.Warningf(format, args...) +} + +// Errorf logs a message at level Error on the standard logger. +func Errorf(format string, args ...interface{}) { + std.Errorf(format, args...) +} + +// Panicf logs a message at level Panic on the standard logger. +func Panicf(format string, args ...interface{}) { + std.Panicf(format, args...) +} + +// Fatalf logs a message at level Fatal on the standard logger. +func Fatalf(format string, args ...interface{}) { + std.Fatalf(format, args...) +} + +// Debugln logs a message at level Debug on the standard logger. +func Debugln(args ...interface{}) { + std.Debugln(args...) +} + +// Println logs a message at level Info on the standard logger. +func Println(args ...interface{}) { + std.Println(args...) +} + +// Infoln logs a message at level Info on the standard logger. +func Infoln(args ...interface{}) { + std.Infoln(args...) +} + +// Warnln logs a message at level Warn on the standard logger. +func Warnln(args ...interface{}) { + std.Warnln(args...) +} + +// Warningln logs a message at level Warn on the standard logger. +func Warningln(args ...interface{}) { + std.Warningln(args...) +} + +// Errorln logs a message at level Error on the standard logger. +func Errorln(args ...interface{}) { + std.Errorln(args...) +} + +// Panicln logs a message at level Panic on the standard logger. +func Panicln(args ...interface{}) { + std.Panicln(args...) +} + +// Fatalln logs a message at level Fatal on the standard logger. +func Fatalln(args ...interface{}) { + std.Fatalln(args...) +} diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go new file mode 100644 index 000000000..b5fbe934d --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/formatter.go @@ -0,0 +1,45 @@ +package logrus + +import "time" + +const DefaultTimestampFormat = time.RFC3339 + +// The Formatter interface is used to implement a custom Formatter. It takes an +// `Entry`. It exposes all the fields, including the default ones: +// +// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. +// * `entry.Data["time"]`. The timestamp. +// * `entry.Data["level"]. The level the entry was logged at. +// +// Any additional fields added with `WithField` or `WithFields` are also in +// `entry.Data`. Format is expected to return an array of bytes which are then +// logged to `logger.Out`. +type Formatter interface { + Format(*Entry) ([]byte, error) +} + +// This is to not silently overwrite `time`, `msg` and `level` fields when +// dumping it. If this code wasn't there doing: +// +// logrus.WithField("level", 1).Info("hello") +// +// Would just silently drop the user provided level. Instead with this code +// it'll logged as: +// +// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} +// +// It's not exported because it's still using Data in an opinionated way. It's to +// avoid code duplication between the two default formatters. +func prefixFieldClashes(data Fields) { + if t, ok := data["time"]; ok { + data["fields.time"] = t + } + + if m, ok := data["msg"]; ok { + data["fields.msg"] = m + } + + if l, ok := data["level"]; ok { + data["fields.level"] = l + } +} diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/Sirupsen/logrus/hooks.go new file mode 100644 index 000000000..3f151cdc3 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/hooks.go @@ -0,0 +1,34 @@ +package logrus + +// A hook to be fired when logging on the logging levels returned from +// `Levels()` on your implementation of the interface. Note that this is not +// fired in a goroutine or a channel with workers, you should handle such +// functionality yourself if your call is non-blocking and you don't wish for +// the logging calls for levels returned from `Levels()` to block. +type Hook interface { + Levels() []Level + Fire(*Entry) error +} + +// Internal type for storing the hooks on a logger instance. +type LevelHooks map[Level][]Hook + +// Add a hook to an instance of logger. This is called with +// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. +func (hooks LevelHooks) Add(hook Hook) { + for _, level := range hook.Levels() { + hooks[level] = append(hooks[level], hook) + } +} + +// Fire all the hooks for the passed level. Used by `entry.log` to fire +// appropriate hooks for a log entry. +func (hooks LevelHooks) Fire(level Level, entry *Entry) error { + for _, hook := range hooks[level] { + if err := hook.Fire(entry); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go new file mode 100644 index 000000000..266554e9f --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/json_formatter.go @@ -0,0 +1,74 @@ +package logrus + +import ( + "encoding/json" + "fmt" +) + +type fieldKey string +type FieldMap map[fieldKey]string + +const ( + FieldKeyMsg = "msg" + FieldKeyLevel = "level" + FieldKeyTime = "time" +) + +func (f FieldMap) resolve(key fieldKey) string { + if k, ok := f[key]; ok { + return k + } + + return string(key) +} + +type JSONFormatter struct { + // TimestampFormat sets the format used for marshaling timestamps. + TimestampFormat string + + // DisableTimestamp allows disabling automatic timestamps in output + DisableTimestamp bool + + // FieldMap allows users to customize the names of keys for various fields. + // As an example: + // formatter := &JSONFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyLevel: "@message", + // }, + // } + FieldMap FieldMap +} + +func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { + data := make(Fields, len(entry.Data)+3) + for k, v := range entry.Data { + switch v := v.(type) { + case error: + // Otherwise errors are ignored by `encoding/json` + // https://github.com/Sirupsen/logrus/issues/137 + data[k] = v.Error() + default: + data[k] = v + } + } + prefixFieldClashes(data) + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = DefaultTimestampFormat + } + + if !f.DisableTimestamp { + data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) + } + data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message + data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() + + serialized, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go new file mode 100644 index 000000000..b769f3d35 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/logger.go @@ -0,0 +1,308 @@ +package logrus + +import ( + "io" + "os" + "sync" +) + +type Logger struct { + // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a + // file, or leave it default which is `os.Stderr`. You can also set this to + // something more adventorous, such as logging to Kafka. + Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging + // levels and log entries. For example, to send errors to an error tracking + // service, log to StatsD or dump the core on fatal errors. + Hooks LevelHooks + // All log entries pass through the formatter before logged to Out. The + // included formatters are `TextFormatter` and `JSONFormatter` for which + // TextFormatter is the default. In development (when a TTY is attached) it + // logs with colors, but to a file it wouldn't. You can easily implement your + // own that implements the `Formatter` interface, see the `README` or included + // formatters for examples. + Formatter Formatter + // The logging level the logger should log at. This is typically (and defaults + // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be + // logged. `logrus.Debug` is useful in + Level Level + // Used to sync writing to the log. Locking is enabled by Default + mu MutexWrap + // Reusable empty entry + entryPool sync.Pool +} + +type MutexWrap struct { + lock sync.Mutex + disabled bool +} + +func (mw *MutexWrap) Lock() { + if !mw.disabled { + mw.lock.Lock() + } +} + +func (mw *MutexWrap) Unlock() { + if !mw.disabled { + mw.lock.Unlock() + } +} + +func (mw *MutexWrap) Disable() { + mw.disabled = true +} + +// Creates a new logger. Configuration should be set by changing `Formatter`, +// `Out` and `Hooks` directly on the default logger instance. You can also just +// instantiate your own: +// +// var log = &Logger{ +// Out: os.Stderr, +// Formatter: new(JSONFormatter), +// Hooks: make(LevelHooks), +// Level: logrus.DebugLevel, +// } +// +// It's recommended to make this a global instance called `log`. +func New() *Logger { + return &Logger{ + Out: os.Stderr, + Formatter: new(TextFormatter), + Hooks: make(LevelHooks), + Level: InfoLevel, + } +} + +func (logger *Logger) newEntry() *Entry { + entry, ok := logger.entryPool.Get().(*Entry) + if ok { + return entry + } + return NewEntry(logger) +} + +func (logger *Logger) releaseEntry(entry *Entry) { + logger.entryPool.Put(entry) +} + +// Adds a field to the log entry, note that it doesn't log until you call +// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. +// If you want multiple fields, use `WithFields`. +func (logger *Logger) WithField(key string, value interface{}) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithField(key, value) +} + +// Adds a struct of fields to the log entry. All it does is call `WithField` for +// each `Field`. +func (logger *Logger) WithFields(fields Fields) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithFields(fields) +} + +// Add an error as single field to the log entry. All it does is call +// `WithError` for the given `error`. +func (logger *Logger) WithError(err error) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithError(err) +} + +func (logger *Logger) Debugf(format string, args ...interface{}) { + if logger.Level >= DebugLevel { + entry := logger.newEntry() + entry.Debugf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Infof(format string, args ...interface{}) { + if logger.Level >= InfoLevel { + entry := logger.newEntry() + entry.Infof(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Printf(format string, args ...interface{}) { + entry := logger.newEntry() + entry.Printf(format, args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warnf(format string, args ...interface{}) { + if logger.Level >= WarnLevel { + entry := logger.newEntry() + entry.Warnf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Warningf(format string, args ...interface{}) { + if logger.Level >= WarnLevel { + entry := logger.newEntry() + entry.Warnf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Errorf(format string, args ...interface{}) { + if logger.Level >= ErrorLevel { + entry := logger.newEntry() + entry.Errorf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Fatalf(format string, args ...interface{}) { + if logger.Level >= FatalLevel { + entry := logger.newEntry() + entry.Fatalf(format, args...) + logger.releaseEntry(entry) + } + Exit(1) +} + +func (logger *Logger) Panicf(format string, args ...interface{}) { + if logger.Level >= PanicLevel { + entry := logger.newEntry() + entry.Panicf(format, args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Debug(args ...interface{}) { + if logger.Level >= DebugLevel { + entry := logger.newEntry() + entry.Debug(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Info(args ...interface{}) { + if logger.Level >= InfoLevel { + entry := logger.newEntry() + entry.Info(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Print(args ...interface{}) { + entry := logger.newEntry() + entry.Info(args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warn(args ...interface{}) { + if logger.Level >= WarnLevel { + entry := logger.newEntry() + entry.Warn(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Warning(args ...interface{}) { + if logger.Level >= WarnLevel { + entry := logger.newEntry() + entry.Warn(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Error(args ...interface{}) { + if logger.Level >= ErrorLevel { + entry := logger.newEntry() + entry.Error(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Fatal(args ...interface{}) { + if logger.Level >= FatalLevel { + entry := logger.newEntry() + entry.Fatal(args...) + logger.releaseEntry(entry) + } + Exit(1) +} + +func (logger *Logger) Panic(args ...interface{}) { + if logger.Level >= PanicLevel { + entry := logger.newEntry() + entry.Panic(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Debugln(args ...interface{}) { + if logger.Level >= DebugLevel { + entry := logger.newEntry() + entry.Debugln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Infoln(args ...interface{}) { + if logger.Level >= InfoLevel { + entry := logger.newEntry() + entry.Infoln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Println(args ...interface{}) { + entry := logger.newEntry() + entry.Println(args...) + logger.releaseEntry(entry) +} + +func (logger *Logger) Warnln(args ...interface{}) { + if logger.Level >= WarnLevel { + entry := logger.newEntry() + entry.Warnln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Warningln(args ...interface{}) { + if logger.Level >= WarnLevel { + entry := logger.newEntry() + entry.Warnln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Errorln(args ...interface{}) { + if logger.Level >= ErrorLevel { + entry := logger.newEntry() + entry.Errorln(args...) + logger.releaseEntry(entry) + } +} + +func (logger *Logger) Fatalln(args ...interface{}) { + if logger.Level >= FatalLevel { + entry := logger.newEntry() + entry.Fatalln(args...) + logger.releaseEntry(entry) + } + Exit(1) +} + +func (logger *Logger) Panicln(args ...interface{}) { + if logger.Level >= PanicLevel { + entry := logger.newEntry() + entry.Panicln(args...) + logger.releaseEntry(entry) + } +} + +//When file is opened with appending mode, it's safe to +//write concurrently to a file (within 4k message on Linux). +//In these cases user can choose to disable the lock. +func (logger *Logger) SetNoLock() { + logger.mu.Disable() +} diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go new file mode 100644 index 000000000..e59669111 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/logrus.go @@ -0,0 +1,143 @@ +package logrus + +import ( + "fmt" + "log" + "strings" +) + +// Fields type, used to pass to `WithFields`. +type Fields map[string]interface{} + +// Level type +type Level uint8 + +// Convert the Level to a string. E.g. PanicLevel becomes "panic". +func (level Level) String() string { + switch level { + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarnLevel: + return "warning" + case ErrorLevel: + return "error" + case FatalLevel: + return "fatal" + case PanicLevel: + return "panic" + } + + return "unknown" +} + +// ParseLevel takes a string level and returns the Logrus log level constant. +func ParseLevel(lvl string) (Level, error) { + switch strings.ToLower(lvl) { + case "panic": + return PanicLevel, nil + case "fatal": + return FatalLevel, nil + case "error": + return ErrorLevel, nil + case "warn", "warning": + return WarnLevel, nil + case "info": + return InfoLevel, nil + case "debug": + return DebugLevel, nil + } + + var l Level + return l, fmt.Errorf("not a valid logrus Level: %q", lvl) +} + +// A constant exposing all logging levels +var AllLevels = []Level{ + PanicLevel, + FatalLevel, + ErrorLevel, + WarnLevel, + InfoLevel, + DebugLevel, +} + +// These are the different logging levels. You can set the logging level to log +// on your instance of logger, obtained with `logrus.New()`. +const ( + // PanicLevel level, highest level of severity. Logs and then calls panic with the + // message passed to Debug, Info, ... + PanicLevel Level = iota + // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the + // logging level is set to Panic. + FatalLevel + // ErrorLevel level. Logs. Used for errors that should definitely be noted. + // Commonly used for hooks to send errors to an error tracking service. + ErrorLevel + // WarnLevel level. Non-critical entries that deserve eyes. + WarnLevel + // InfoLevel level. General operational entries about what's going on inside the + // application. + InfoLevel + // DebugLevel level. Usually only enabled when debugging. Very verbose logging. + DebugLevel +) + +// Won't compile if StdLogger can't be realized by a log.Logger +var ( + _ StdLogger = &log.Logger{} + _ StdLogger = &Entry{} + _ StdLogger = &Logger{} +) + +// StdLogger is what your logrus-enabled library should take, that way +// it'll accept a stdlib logger and a logrus logger. There's no standard +// interface, this is the closest we get, unfortunately. +type StdLogger interface { + Print(...interface{}) + Printf(string, ...interface{}) + Println(...interface{}) + + Fatal(...interface{}) + Fatalf(string, ...interface{}) + Fatalln(...interface{}) + + Panic(...interface{}) + Panicf(string, ...interface{}) + Panicln(...interface{}) +} + +// The FieldLogger interface generalizes the Entry and Logger types +type FieldLogger interface { + WithField(key string, value interface{}) *Entry + WithFields(fields Fields) *Entry + WithError(err error) *Entry + + Debugf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Printf(format string, args ...interface{}) + Warnf(format string, args ...interface{}) + Warningf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) + Panicf(format string, args ...interface{}) + + Debug(args ...interface{}) + Info(args ...interface{}) + Print(args ...interface{}) + Warn(args ...interface{}) + Warning(args ...interface{}) + Error(args ...interface{}) + Fatal(args ...interface{}) + Panic(args ...interface{}) + + Debugln(args ...interface{}) + Infoln(args ...interface{}) + Println(args ...interface{}) + Warnln(args ...interface{}) + Warningln(args ...interface{}) + Errorln(args ...interface{}) + Fatalln(args ...interface{}) + Panicln(args ...interface{}) +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go new file mode 100644 index 000000000..5f6be4d3c --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go @@ -0,0 +1,10 @@ +// +build darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package logrus + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA + +type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/Sirupsen/logrus/terminal_linux.go new file mode 100644 index 000000000..308160ca8 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_linux.go @@ -0,0 +1,14 @@ +// Based on ssh/terminal: +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !appengine + +package logrus + +import "syscall" + +const ioctlReadTermios = syscall.TCGETS + +type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go new file mode 100644 index 000000000..190297abf --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go @@ -0,0 +1,28 @@ +// Based on ssh/terminal: +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package logrus + +import ( + "io" + "os" + "syscall" + "unsafe" +) + +// IsTerminal returns true if stderr's file descriptor is a terminal. +func IsTerminal(f io.Writer) bool { + var termios Termios + switch v := f.(type) { + case *os.File: + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 + default: + return false + } +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go new file mode 100644 index 000000000..3c86b1abe --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go @@ -0,0 +1,21 @@ +// +build solaris,!appengine + +package logrus + +import ( + "io" + "os" + + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(f io.Writer) bool { + switch v := f.(type) { + case *os.File: + _, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA) + return err == nil + default: + return false + } +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go new file mode 100644 index 000000000..05d2f91f1 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_windows.go @@ -0,0 +1,33 @@ +// Based on ssh/terminal: +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows,!appengine + +package logrus + +import ( + "io" + "os" + "syscall" + "unsafe" +) + +var kernel32 = syscall.NewLazyDLL("kernel32.dll") + +var ( + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") +) + +// IsTerminal returns true if stderr's file descriptor is a terminal. +func IsTerminal(f io.Writer) bool { + switch v := f.(type) { + case *os.File: + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 + default: + return false + } +} diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go new file mode 100644 index 000000000..ba8885406 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/text_formatter.go @@ -0,0 +1,189 @@ +package logrus + +import ( + "bytes" + "fmt" + "sort" + "strings" + "sync" + "time" +) + +const ( + nocolor = 0 + red = 31 + green = 32 + yellow = 33 + blue = 34 + gray = 37 +) + +var ( + baseTimestamp time.Time +) + +func init() { + baseTimestamp = time.Now() +} + +type TextFormatter struct { + // Set to true to bypass checking for a TTY before outputting colors. + ForceColors bool + + // Force disabling colors. + DisableColors bool + + // Disable timestamp logging. useful when output is redirected to logging + // system that already adds timestamps. + DisableTimestamp bool + + // Enable logging the full timestamp when a TTY is attached instead of just + // the time passed since beginning of execution. + FullTimestamp bool + + // TimestampFormat to use for display when a full timestamp is printed + TimestampFormat string + + // The fields are sorted by default for a consistent output. For applications + // that log extremely frequently and don't use the JSON formatter this may not + // be desired. + DisableSorting bool + + // QuoteEmptyFields will wrap empty fields in quotes if true + QuoteEmptyFields bool + + // QuoteCharacter can be set to the override the default quoting character " + // with something else. For example: ', or `. + QuoteCharacter string + + // Whether the logger's out is to a terminal + isTerminal bool + + sync.Once +} + +func (f *TextFormatter) init(entry *Entry) { + if len(f.QuoteCharacter) == 0 { + f.QuoteCharacter = "\"" + } + if entry.Logger != nil { + f.isTerminal = IsTerminal(entry.Logger.Out) + } +} + +func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { + var b *bytes.Buffer + keys := make([]string, 0, len(entry.Data)) + for k := range entry.Data { + keys = append(keys, k) + } + + if !f.DisableSorting { + sort.Strings(keys) + } + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + + prefixFieldClashes(entry.Data) + + f.Do(func() { f.init(entry) }) + + isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = DefaultTimestampFormat + } + if isColored { + f.printColored(b, entry, keys, timestampFormat) + } else { + if !f.DisableTimestamp { + f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) + } + f.appendKeyValue(b, "level", entry.Level.String()) + if entry.Message != "" { + f.appendKeyValue(b, "msg", entry.Message) + } + for _, key := range keys { + f.appendKeyValue(b, key, entry.Data[key]) + } + } + + b.WriteByte('\n') + return b.Bytes(), nil +} + +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { + var levelColor int + switch entry.Level { + case DebugLevel: + levelColor = gray + case WarnLevel: + levelColor = yellow + case ErrorLevel, FatalLevel, PanicLevel: + levelColor = red + default: + levelColor = blue + } + + levelText := strings.ToUpper(entry.Level.String())[0:4] + + if f.DisableTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message) + } else if !f.FullTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message) + } else { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) + } + for _, k := range keys { + v := entry.Data[k] + fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) + f.appendValue(b, v) + } +} + +func (f *TextFormatter) needsQuoting(text string) bool { + if f.QuoteEmptyFields && len(text) == 0 { + return true + } + for _, ch := range text { + if !((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + ch == '-' || ch == '.') { + return true + } + } + return false +} + +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { + + b.WriteString(key) + b.WriteByte('=') + f.appendValue(b, value) + b.WriteByte(' ') +} + +func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { + switch value := value.(type) { + case string: + if !f.needsQuoting(value) { + b.WriteString(value) + } else { + fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter) + } + case error: + errmsg := value.Error() + if !f.needsQuoting(errmsg) { + b.WriteString(errmsg) + } else { + fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter) + } + default: + fmt.Fprint(b, value) + } +} diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/Sirupsen/logrus/writer.go new file mode 100644 index 000000000..7bdebedc6 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/writer.go @@ -0,0 +1,62 @@ +package logrus + +import ( + "bufio" + "io" + "runtime" +) + +func (logger *Logger) Writer() *io.PipeWriter { + return logger.WriterLevel(InfoLevel) +} + +func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { + return NewEntry(logger).WriterLevel(level) +} + +func (entry *Entry) Writer() *io.PipeWriter { + return entry.WriterLevel(InfoLevel) +} + +func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { + reader, writer := io.Pipe() + + var printFunc func(args ...interface{}) + + switch level { + case DebugLevel: + printFunc = entry.Debug + case InfoLevel: + printFunc = entry.Info + case WarnLevel: + printFunc = entry.Warn + case ErrorLevel: + printFunc = entry.Error + case FatalLevel: + printFunc = entry.Fatal + case PanicLevel: + printFunc = entry.Panic + default: + printFunc = entry.Print + } + + go entry.writerScanner(reader, printFunc) + runtime.SetFinalizer(writer, writerFinalizer) + + return writer +} + +func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + printFunc(scanner.Text()) + } + if err := scanner.Err(); err != nil { + entry.Errorf("Error while reading from Writer: %s", err) + } + reader.Close() +} + +func writerFinalizer(writer *io.PipeWriter) { + writer.Close() +} diff --git a/vendor/github.com/creack/goselect/Dockerfile b/vendor/github.com/creack/goselect/Dockerfile new file mode 100644 index 000000000..d03b5a9d9 --- /dev/null +++ b/vendor/github.com/creack/goselect/Dockerfile @@ -0,0 +1,5 @@ +FROM google/golang:stable +MAINTAINER Guillaume J. Charmes <guillaume@charmes.net> +CMD /tmp/a.out +ADD . /src +RUN cd /src && go build -o /tmp/a.out diff --git a/vendor/github.com/creack/goselect/LICENSE b/vendor/github.com/creack/goselect/LICENSE new file mode 100644 index 000000000..95c600af1 --- /dev/null +++ b/vendor/github.com/creack/goselect/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Guillaume J. Charmes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/creack/goselect/README.md b/vendor/github.com/creack/goselect/README.md new file mode 100644 index 000000000..d5d06510e --- /dev/null +++ b/vendor/github.com/creack/goselect/README.md @@ -0,0 +1,30 @@ +# go-select + +select(2) implementation in Go + +## Supported platforms + +| | 386 | amd64 | arm | arm64 | +|---------------|-----|-------|-----|-------| +| **linux** | yes | yes | yes | yes | +| **darwin** | yes | yes | n/a | ?? | +| **freebsd** | yes | yes | yes | ?? | +| **openbsd** | yes | yes | yes | ?? | +| **netbsd** | yes | yes | yes | ?? | +| **dragonfly** | n/a | yes | n/a | ?? | +| **solaris** | n/a | no | n/a | ?? | +| **plan9** | no | no | n/a | ?? | +| **windows** | yes | yes | n/a | ?? | +| **android** | n/a | n/a | no | ?? | + +*n/a: platform not supported by Go + +Go on `plan9` and `solaris` do not implement `syscall.Select` not `syscall.SYS_SELECT`. + +## Cross compile + +Using davecheney's https://github.com/davecheney/golang-crosscompile + +``` +export PLATFORMS="darwin/386 darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm linux/386 linux/amd64 linux/arm windows/386 windows/amd64 openbsd/386 openbsd/amd64 netbsd/386 netbsd/amd64 dragonfly/amd64 plan9/386 plan9/amd64 solaris/amd64" +``` diff --git a/vendor/github.com/creack/goselect/fdset.go b/vendor/github.com/creack/goselect/fdset.go new file mode 100644 index 000000000..2ff3f6c7a --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset.go @@ -0,0 +1,33 @@ +// +build !freebsd,!windows,!plan9 + +package goselect + +import "syscall" + +const FD_SETSIZE = syscall.FD_SETSIZE + +// FDSet wraps syscall.FdSet with convenience methods +type FDSet syscall.FdSet + +// Set adds the fd to the set +func (fds *FDSet) Set(fd uintptr) { + fds.Bits[fd/NFDBITS] |= (1 << (fd % NFDBITS)) +} + +// Clear remove the fd from the set +func (fds *FDSet) Clear(fd uintptr) { + fds.Bits[fd/NFDBITS] &^= (1 << (fd % NFDBITS)) +} + +// IsSet check if the given fd is set +func (fds *FDSet) IsSet(fd uintptr) bool { + return fds.Bits[fd/NFDBITS]&(1<<(fd%NFDBITS)) != 0 +} + +// Keep a null set to avoid reinstatiation +var nullFdSet = &FDSet{} + +// Zero empties the Set +func (fds *FDSet) Zero() { + copy(fds.Bits[:], (nullFdSet).Bits[:]) +} diff --git a/vendor/github.com/creack/goselect/fdset_32.go b/vendor/github.com/creack/goselect/fdset_32.go new file mode 100644 index 000000000..8b90d21a9 --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset_32.go @@ -0,0 +1,10 @@ +// +build darwin openbsd netbsd 386 arm + +package goselect + +// darwin, netbsd and openbsd uses uint32 on both amd64 and 386 + +const ( + // NFDBITS is the amount of bits per mask + NFDBITS = 4 * 8 +) diff --git a/vendor/github.com/creack/goselect/fdset_64.go b/vendor/github.com/creack/goselect/fdset_64.go new file mode 100644 index 000000000..4e032e4ea --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset_64.go @@ -0,0 +1,11 @@ +// +build !darwin,!netbsd,!openbsd +// +build amd64 arm64 + +package goselect + +// darwin, netbsd and openbsd uses uint32 on both amd64 and 386 + +const ( + // NFDBITS is the amount of bits per mask + NFDBITS = 8 * 8 +) diff --git a/vendor/github.com/creack/goselect/fdset_doc.go b/vendor/github.com/creack/goselect/fdset_doc.go new file mode 100644 index 000000000..d9f15a1ce --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset_doc.go @@ -0,0 +1,93 @@ +package goselect + +/** +From: XCode's MacOSX10.10.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/sys/select.h +-- +// darwin/amd64 / 386 +sizeof(__int32_t) == 4 +-- + +typedef __int32_t __fd_mask; + +#define FD_SETSIZE 1024 +#define __NFDBITS (sizeof(__fd_mask) * 8) +#define __howmany(x, y) ((((x) % (y)) == 0) ? ((x) / (y)) : (((x) / (y)) + 1)) + +typedef struct fd_set { + __fd_mask fds_bits[__howmany(__FD_SETSIZE, __NFDBITS)]; +} fd_set; + +#define __FD_MASK(n) ((__fd_mask)1 << ((n) % __NFDBITS)) +#define FD_SET(n, p) ((p)->fds_bits[(n)/__NFDBITS] |= __FD_MASK(n)) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/__NFDBITS] &= ~__FD_MASK(n)) +#define FD_ISSET(n, p) (((p)->fds_bits[(n)/__NFDBITS] & __FD_MASK(n)) != 0) +*/ + +/** +From: /usr/include/i386-linux-gnu/sys/select.h +-- +// linux/i686 +sizeof(long int) == 4 +-- + +typedef long int __fd_mask; + +#define FD_SETSIZE 1024 +#define __NFDBITS (sizeof(__fd_mask) * 8) + + +typedef struct fd_set { + __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; +} fd_set; + +#define __FD_MASK(n) ((__fd_mask)1 << ((n) % __NFDBITS)) +#define FD_SET(n, p) ((p)->fds_bits[(n)/__NFDBITS] |= __FD_MASK(n)) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/__NFDBITS] &= ~__FD_MASK(n)) +#define FD_ISSET(n, p) (((p)->fds_bits[(n)/__NFDBITS] & __FD_MASK(n)) != 0) +*/ + +/** +From: /usr/include/x86_64-linux-gnu/sys/select.h +-- +// linux/amd64 +sizeof(long int) == 8 +-- + +typedef long int __fd_mask; + +#define FD_SETSIZE 1024 +#define __NFDBITS (sizeof(__fd_mask) * 8) + + +typedef struct fd_set { + __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; +} fd_set; + +#define __FD_MASK(n) ((__fd_mask)1 << ((n) % __NFDBITS)) +#define FD_SET(n, p) ((p)->fds_bits[(n)/__NFDBITS] |= __FD_MASK(n)) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/__NFDBITS] &= ~__FD_MASK(n)) +#define FD_ISSET(n, p) (((p)->fds_bits[(n)/__NFDBITS] & __FD_MASK(n)) != 0) +*/ + +/** +From: /usr/include/sys/select.h +-- +// freebsd/amd64 +sizeof(unsigned long) == 8 +-- + +typedef unsigned long __fd_mask; + +#define FD_SETSIZE 1024U +#define __NFDBITS (sizeof(__fd_mask) * 8) +#define _howmany(x, y) (((x) + ((y) - 1)) / (y)) + +typedef struct fd_set { + __fd_mask fds_bits[_howmany(FD_SETSIZE, __NFDBITS)]; +} fd_set; + +#define __FD_MASK(n) ((__fd_mask)1 << ((n) % __NFDBITS)) +#define FD_SET(n, p) ((p)->fds_bits[(n)/__NFDBITS] |= __FD_MASK(n)) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/__NFDBITS] &= ~__FD_MASK(n)) +#define FD_ISSET(n, p) (((p)->fds_bits[(n)/__NFDBITS] & __FD_MASK(n)) != 0) +*/ diff --git a/vendor/github.com/creack/goselect/fdset_freebsd.go b/vendor/github.com/creack/goselect/fdset_freebsd.go new file mode 100644 index 000000000..03f7b9127 --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset_freebsd.go @@ -0,0 +1,33 @@ +// +build freebsd + +package goselect + +import "syscall" + +const FD_SETSIZE = syscall.FD_SETSIZE + +// FDSet wraps syscall.FdSet with convenience methods +type FDSet syscall.FdSet + +// Set adds the fd to the set +func (fds *FDSet) Set(fd uintptr) { + fds.X__fds_bits[fd/NFDBITS] |= (1 << (fd % NFDBITS)) +} + +// Clear remove the fd from the set +func (fds *FDSet) Clear(fd uintptr) { + fds.X__fds_bits[fd/NFDBITS] &^= (1 << (fd % NFDBITS)) +} + +// IsSet check if the given fd is set +func (fds *FDSet) IsSet(fd uintptr) bool { + return fds.X__fds_bits[fd/NFDBITS]&(1<<(fd%NFDBITS)) != 0 +} + +// Keep a null set to avoid reinstatiation +var nullFdSet = &FDSet{} + +// Zero empties the Set +func (fds *FDSet) Zero() { + copy(fds.X__fds_bits[:], (nullFdSet).X__fds_bits[:]) +} diff --git a/vendor/github.com/creack/goselect/fdset_unsupported.go b/vendor/github.com/creack/goselect/fdset_unsupported.go new file mode 100644 index 000000000..cbd8d5880 --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset_unsupported.go @@ -0,0 +1,20 @@ +// +build plan9 + +package goselect + +const FD_SETSIZE = 0 + +// FDSet wraps syscall.FdSet with convenience methods +type FDSet struct{} + +// Set adds the fd to the set +func (fds *FDSet) Set(fd uintptr) {} + +// Clear remove the fd from the set +func (fds *FDSet) Clear(fd uintptr) {} + +// IsSet check if the given fd is set +func (fds *FDSet) IsSet(fd uintptr) bool { return false } + +// Zero empties the Set +func (fds *FDSet) Zero() {} diff --git a/vendor/github.com/creack/goselect/fdset_windows.go b/vendor/github.com/creack/goselect/fdset_windows.go new file mode 100644 index 000000000..ee3491975 --- /dev/null +++ b/vendor/github.com/creack/goselect/fdset_windows.go @@ -0,0 +1,57 @@ +// +build windows + +package goselect + +import "syscall" + +const FD_SETSIZE = 64 + +// FDSet extracted from mingw libs source code +type FDSet struct { + fd_count uint + fd_array [FD_SETSIZE]uintptr +} + +// Set adds the fd to the set +func (fds *FDSet) Set(fd uintptr) { + var i uint + for i = 0; i < fds.fd_count; i++ { + if fds.fd_array[i] == fd { + break + } + } + if i == fds.fd_count { + if fds.fd_count < FD_SETSIZE { + fds.fd_array[i] = fd + fds.fd_count++ + } + } +} + +// Clear remove the fd from the set +func (fds *FDSet) Clear(fd uintptr) { + var i uint + for i = 0; i < fds.fd_count; i++ { + if fds.fd_array[i] == fd { + for i < fds.fd_count-1 { + fds.fd_array[i] = fds.fd_array[i+1] + i++ + } + fds.fd_count-- + break + } + } +} + +// IsSet check if the given fd is set +func (fds *FDSet) IsSet(fd uintptr) bool { + if isset, err := __WSAFDIsSet(syscall.Handle(fd), fds); err == nil && isset != 0 { + return true + } + return false +} + +// Zero empties the Set +func (fds *FDSet) Zero() { + fds.fd_count = 0 +} diff --git a/vendor/github.com/creack/goselect/select.go b/vendor/github.com/creack/goselect/select.go new file mode 100644 index 000000000..7f2875e73 --- /dev/null +++ b/vendor/github.com/creack/goselect/select.go @@ -0,0 +1,28 @@ +package goselect + +import ( + "syscall" + "time" +) + +// Select wraps syscall.Select with Go types +func Select(n int, r, w, e *FDSet, timeout time.Duration) error { + var timeval *syscall.Timeval + if timeout >= 0 { + t := syscall.NsecToTimeval(timeout.Nanoseconds()) + timeval = &t + } + + return sysSelect(n, r, w, e, timeval) +} + +// RetrySelect wraps syscall.Select with Go types, and retries a number of times, with a given retryDelay. +func RetrySelect(n int, r, w, e *FDSet, timeout time.Duration, retries int, retryDelay time.Duration) (err error) { + for i := 0; i < retries; i++ { + if err = Select(n, r, w, e, timeout); err != syscall.EINTR { + return err + } + time.Sleep(retryDelay) + } + return err +} diff --git a/vendor/github.com/creack/goselect/select_linux.go b/vendor/github.com/creack/goselect/select_linux.go new file mode 100644 index 000000000..acd569e9d --- /dev/null +++ b/vendor/github.com/creack/goselect/select_linux.go @@ -0,0 +1,10 @@ +// +build linux + +package goselect + +import "syscall" + +func sysSelect(n int, r, w, e *FDSet, timeout *syscall.Timeval) error { + _, err := syscall.Select(n, (*syscall.FdSet)(r), (*syscall.FdSet)(w), (*syscall.FdSet)(e), timeout) + return err +} diff --git a/vendor/github.com/creack/goselect/select_other.go b/vendor/github.com/creack/goselect/select_other.go new file mode 100644 index 000000000..6c8208147 --- /dev/null +++ b/vendor/github.com/creack/goselect/select_other.go @@ -0,0 +1,9 @@ +// +build !linux,!windows,!plan9,!solaris + +package goselect + +import "syscall" + +func sysSelect(n int, r, w, e *FDSet, timeout *syscall.Timeval) error { + return syscall.Select(n, (*syscall.FdSet)(r), (*syscall.FdSet)(w), (*syscall.FdSet)(e), timeout) +} diff --git a/vendor/github.com/creack/goselect/select_unsupported.go b/vendor/github.com/creack/goselect/select_unsupported.go new file mode 100644 index 000000000..bea0ad94a --- /dev/null +++ b/vendor/github.com/creack/goselect/select_unsupported.go @@ -0,0 +1,16 @@ +// +build plan9 solaris + +package goselect + +import ( + "fmt" + "runtime" + "syscall" +) + +// ErrUnsupported . +var ErrUnsupported = fmt.Errorf("Platofrm %s/%s unsupported", runtime.GOOS, runtime.GOARCH) + +func sysSelect(n int, r, w, e *FDSet, timeout *syscall.Timeval) error { + return ErrUnsupported +} diff --git a/vendor/github.com/creack/goselect/select_windows.go b/vendor/github.com/creack/goselect/select_windows.go new file mode 100644 index 000000000..0fb70d5d2 --- /dev/null +++ b/vendor/github.com/creack/goselect/select_windows.go @@ -0,0 +1,13 @@ +// +build windows + +package goselect + +import "syscall" + +//sys _select(nfds int, readfds *FDSet, writefds *FDSet, exceptfds *FDSet, timeout *syscall.Timeval) (total int, err error) = ws2_32.select +//sys __WSAFDIsSet(handle syscall.Handle, fdset *FDSet) (isset int, err error) = ws2_32.__WSAFDIsSet + +func sysSelect(n int, r, w, e *FDSet, timeout *syscall.Timeval) error { + _, err := _select(n, r, w, e, timeout) + return err +} diff --git a/vendor/github.com/creack/goselect/test_crosscompile.sh b/vendor/github.com/creack/goselect/test_crosscompile.sh new file mode 100755 index 000000000..533ca6647 --- /dev/null +++ b/vendor/github.com/creack/goselect/test_crosscompile.sh @@ -0,0 +1,17 @@ +export GOOS=linux; export GOARCH=arm; echo $GOOS/$GOARCH; go build +export GOOS=linux; export GOARCH=arm64; echo $GOOS/$GOARCH; go build +export GOOS=linux; export GOARCH=amd64; echo $GOOS/$GOARCH; go build +export GOOS=linux; export GOARCH=386; echo $GOOS/$GOARCH; go build +export GOOS=darwin; export GOARCH=arm; echo $GOOS/$GOARCH; go build +export GOOS=darwin; export GOARCH=arm64; echo $GOOS/$GOARCH; go build +export GOOS=darwin; export GOARCH=amd64; echo $GOOS/$GOARCH; go build +export GOOS=darwin; export GOARCH=386; echo $GOOS/$GOARCH; go build +export GOOS=freebsd; export GOARCH=arm; echo $GOOS/$GOARCH; go build +export GOOS=freebsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build +export GOOS=freebsd; export GOARCH=386; echo $GOOS/$GOARCH; go build +export GOOS=openbsd; export GOARCH=arm; echo $GOOS/$GOARCH; go build +export GOOS=openbsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build +export GOOS=openbsd; export GOARCH=386; echo $GOOS/$GOARCH; go build +export GOOS=netbsd; export GOARCH=arm; echo $GOOS/$GOARCH; go build +export GOOS=netbsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build +export GOOS=netbsd; export GOARCH=386; echo $GOOS/$GOARCH; go build diff --git a/vendor/github.com/creack/goselect/zselect_windows.go b/vendor/github.com/creack/goselect/zselect_windows.go new file mode 100644 index 000000000..c3b10e1d0 --- /dev/null +++ b/vendor/github.com/creack/goselect/zselect_windows.go @@ -0,0 +1,41 @@ +// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT + +package goselect + +import "unsafe" +import "syscall" + +var _ unsafe.Pointer + +var ( + modws2_32 = syscall.NewLazyDLL("ws2_32.dll") + + procselect = modws2_32.NewProc("select") + proc__WSAFDIsSet = modws2_32.NewProc("__WSAFDIsSet") +) + +func _select(nfds int, readfds *FDSet, writefds *FDSet, exceptfds *FDSet, timeout *syscall.Timeval) (total int, err error) { + r0, _, e1 := syscall.Syscall6(procselect.Addr(), 5, uintptr(nfds), uintptr(unsafe.Pointer(readfds)), uintptr(unsafe.Pointer(writefds)), uintptr(unsafe.Pointer(exceptfds)), uintptr(unsafe.Pointer(timeout)), 0) + total = int(r0) + if total == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func __WSAFDIsSet(handle syscall.Handle, fdset *FDSet) (isset int, err error) { + r0, _, e1 := syscall.Syscall(proc__WSAFDIsSet.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(fdset)), 0) + isset = int(r0) + if isset == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} diff --git a/vendor/github.com/docker/docker/LICENSE b/vendor/github.com/docker/docker/LICENSE new file mode 100644 index 000000000..9c8e20ab8 --- /dev/null +++ b/vendor/github.com/docker/docker/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2017 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/docker/docker/NOTICE b/vendor/github.com/docker/docker/NOTICE new file mode 100644 index 000000000..0c74e15b0 --- /dev/null +++ b/vendor/github.com/docker/docker/NOTICE @@ -0,0 +1,19 @@ +Docker +Copyright 2012-2017 Docker, Inc. + +This product includes software developed at Docker, Inc. (https://www.docker.com). + +This product contains software (https://github.com/kr/pty) developed +by Keith Rarick, licensed under the MIT License. + +The following is courtesy of our legal counsel: + + +Use and transfer of Docker may be subject to certain restrictions by the +United States and other governments. +It is your responsibility to ensure that your use and/or transfer does not +violate applicable laws. + +For more information, please see https://www.bis.doc.gov + +See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. diff --git a/vendor/github.com/docker/docker/pkg/namesgenerator/names-generator.go b/vendor/github.com/docker/docker/pkg/namesgenerator/names-generator.go new file mode 100644 index 000000000..d732a4795 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/namesgenerator/names-generator.go @@ -0,0 +1,608 @@ +package namesgenerator + +import ( + "fmt" + + "github.com/docker/docker/pkg/random" +) + +var ( + left = [...]string{ + "admiring", + "adoring", + "affectionate", + "agitated", + "amazing", + "angry", + "awesome", + "blissful", + "boring", + "brave", + "clever", + "cocky", + "compassionate", + "competent", + "condescending", + "confident", + "cranky", + "dazzling", + "determined", + "distracted", + "dreamy", + "eager", + "ecstatic", + "elastic", + "elated", + "elegant", + "eloquent", + "epic", + "fervent", + "festive", + "flamboyant", + "focused", + "friendly", + "frosty", + "gallant", + "gifted", + "goofy", + "gracious", + "happy", + "hardcore", + "heuristic", + "hopeful", + "hungry", + "infallible", + "inspiring", + "jolly", + "jovial", + "keen", + "kind", + "laughing", + "loving", + "lucid", + "mystifying", + "modest", + "musing", + "naughty", + "nervous", + "nifty", + "nostalgic", + "objective", + "optimistic", + "peaceful", + "pedantic", + "pensive", + "practical", + "priceless", + "quirky", + "quizzical", + "relaxed", + "reverent", + "romantic", + "sad", + "serene", + "sharp", + "silly", + "sleepy", + "stoic", + "stupefied", + "suspicious", + "tender", + "thirsty", + "trusting", + "unruffled", + "upbeat", + "vibrant", + "vigilant", + "vigorous", + "wizardly", + "wonderful", + "xenodochial", + "youthful", + "zealous", + "zen", + } + + // Docker, starting from 0.7.x, generates names from notable scientists and hackers. + // Please, for any amazing man that you add to the list, consider adding an equally amazing woman to it, and vice versa. + right = [...]string{ + // Muhammad ibn Jābir al-Ḥarrānī al-Battānī was a founding father of astronomy. https://en.wikipedia.org/wiki/Mu%E1%B8%A5ammad_ibn_J%C4%81bir_al-%E1%B8%A4arr%C4%81n%C4%AB_al-Batt%C4%81n%C4%AB + "albattani", + + // Frances E. Allen, became the first female IBM Fellow in 1989. In 2006, she became the first female recipient of the ACM's Turing Award. https://en.wikipedia.org/wiki/Frances_E._Allen + "allen", + + // June Almeida - Scottish virologist who took the first pictures of the rubella virus - https://en.wikipedia.org/wiki/June_Almeida + "almeida", + + // Maria Gaetana Agnesi - Italian mathematician, philosopher, theologian and humanitarian. She was the first woman to write a mathematics handbook and the first woman appointed as a Mathematics Professor at a University. https://en.wikipedia.org/wiki/Maria_Gaetana_Agnesi + "agnesi", + + // Archimedes was a physicist, engineer and mathematician who invented too many things to list them here. https://en.wikipedia.org/wiki/Archimedes + "archimedes", + + // Maria Ardinghelli - Italian translator, mathematician and physicist - https://en.wikipedia.org/wiki/Maria_Ardinghelli + "ardinghelli", + + // Aryabhata - Ancient Indian mathematician-astronomer during 476-550 CE https://en.wikipedia.org/wiki/Aryabhata + "aryabhata", + + // Wanda Austin - Wanda Austin is the President and CEO of The Aerospace Corporation, a leading architect for the US security space programs. https://en.wikipedia.org/wiki/Wanda_Austin + "austin", + + // Charles Babbage invented the concept of a programmable computer. https://en.wikipedia.org/wiki/Charles_Babbage. + "babbage", + + // Stefan Banach - Polish mathematician, was one of the founders of modern functional analysis. https://en.wikipedia.org/wiki/Stefan_Banach + "banach", + + // John Bardeen co-invented the transistor - https://en.wikipedia.org/wiki/John_Bardeen + "bardeen", + + // Jean Bartik, born Betty Jean Jennings, was one of the original programmers for the ENIAC computer. https://en.wikipedia.org/wiki/Jean_Bartik + "bartik", + + // Laura Bassi, the world's first female professor https://en.wikipedia.org/wiki/Laura_Bassi + "bassi", + + // Hugh Beaver, British engineer, founder of the Guinness Book of World Records https://en.wikipedia.org/wiki/Hugh_Beaver + "beaver", + + // Alexander Graham Bell - an eminent Scottish-born scientist, inventor, engineer and innovator who is credited with inventing the first practical telephone - https://en.wikipedia.org/wiki/Alexander_Graham_Bell + "bell", + + // Karl Friedrich Benz - a German automobile engineer. Inventor of the first practical motorcar. https://en.wikipedia.org/wiki/Karl_Benz + "benz", + + // Homi J Bhabha - was an Indian nuclear physicist, founding director, and professor of physics at the Tata Institute of Fundamental Research. Colloquially known as "father of Indian nuclear programme"- https://en.wikipedia.org/wiki/Homi_J._Bhabha + "bhabha", + + // Bhaskara II - Ancient Indian mathematician-astronomer whose work on calculus predates Newton and Leibniz by over half a millennium - https://en.wikipedia.org/wiki/Bh%C4%81skara_II#Calculus + "bhaskara", + + // Elizabeth Blackwell - American doctor and first American woman to receive a medical degree - https://en.wikipedia.org/wiki/Elizabeth_Blackwell + "blackwell", + + // Niels Bohr is the father of quantum theory. https://en.wikipedia.org/wiki/Niels_Bohr. + "bohr", + + // Kathleen Booth, she's credited with writing the first assembly language. https://en.wikipedia.org/wiki/Kathleen_Booth + "booth", + + // Anita Borg - Anita Borg was the founding director of the Institute for Women and Technology (IWT). https://en.wikipedia.org/wiki/Anita_Borg + "borg", + + // Satyendra Nath Bose - He provided the foundation for Bose–Einstein statistics and the theory of the Bose–Einstein condensate. - https://en.wikipedia.org/wiki/Satyendra_Nath_Bose + "bose", + + // Evelyn Boyd Granville - She was one of the first African-American woman to receive a Ph.D. in mathematics; she earned it in 1949 from Yale University. https://en.wikipedia.org/wiki/Evelyn_Boyd_Granville + "boyd", + + // Brahmagupta - Ancient Indian mathematician during 598-670 CE who gave rules to compute with zero - https://en.wikipedia.org/wiki/Brahmagupta#Zero + "brahmagupta", + + // Walter Houser Brattain co-invented the transistor - https://en.wikipedia.org/wiki/Walter_Houser_Brattain + "brattain", + + // Emmett Brown invented time travel. https://en.wikipedia.org/wiki/Emmett_Brown (thanks Brian Goff) + "brown", + + // Rachel Carson - American marine biologist and conservationist, her book Silent Spring and other writings are credited with advancing the global environmental movement. https://en.wikipedia.org/wiki/Rachel_Carson + "carson", + + // Subrahmanyan Chandrasekhar - Astrophysicist known for his mathematical theory on different stages and evolution in structures of the stars. He has won nobel prize for physics - https://en.wikipedia.org/wiki/Subrahmanyan_Chandrasekhar + "chandrasekhar", + + //Claude Shannon - The father of information theory and founder of digital circuit design theory. (https://en.wikipedia.org/wiki/Claude_Shannon) + "shannon", + + // Joan Clarke - Bletchley Park code breaker during the Second World War who pioneered techniques that remained top secret for decades. Also an accomplished numismatist https://en.wikipedia.org/wiki/Joan_Clarke + "clarke", + + // Jane Colden - American botanist widely considered the first female American botanist - https://en.wikipedia.org/wiki/Jane_Colden + "colden", + + // Gerty Theresa Cori - American biochemist who became the third woman—and first American woman—to win a Nobel Prize in science, and the first woman to be awarded the Nobel Prize in Physiology or Medicine. Cori was born in Prague. https://en.wikipedia.org/wiki/Gerty_Cori + "cori", + + // Seymour Roger Cray was an American electrical engineer and supercomputer architect who designed a series of computers that were the fastest in the world for decades. https://en.wikipedia.org/wiki/Seymour_Cray + "cray", + + // This entry reflects a husband and wife team who worked together: + // Joan Curran was a Welsh scientist who developed radar and invented chaff, a radar countermeasure. https://en.wikipedia.org/wiki/Joan_Curran + // Samuel Curran was an Irish physicist who worked alongside his wife during WWII and invented the proximity fuse. https://en.wikipedia.org/wiki/Samuel_Curran + "curran", + + // Marie Curie discovered radioactivity. https://en.wikipedia.org/wiki/Marie_Curie. + "curie", + + // Charles Darwin established the principles of natural evolution. https://en.wikipedia.org/wiki/Charles_Darwin. + "darwin", + + // Leonardo Da Vinci invented too many things to list here. https://en.wikipedia.org/wiki/Leonardo_da_Vinci. + "davinci", + + // Edsger Wybe Dijkstra was a Dutch computer scientist and mathematical scientist. https://en.wikipedia.org/wiki/Edsger_W._Dijkstra. + "dijkstra", + + // Donna Dubinsky - played an integral role in the development of personal digital assistants (PDAs) serving as CEO of Palm, Inc. and co-founding Handspring. https://en.wikipedia.org/wiki/Donna_Dubinsky + "dubinsky", + + // Annie Easley - She was a leading member of the team which developed software for the Centaur rocket stage and one of the first African-Americans in her field. https://en.wikipedia.org/wiki/Annie_Easley + "easley", + + // Thomas Alva Edison, prolific inventor https://en.wikipedia.org/wiki/Thomas_Edison + "edison", + + // Albert Einstein invented the general theory of relativity. https://en.wikipedia.org/wiki/Albert_Einstein + "einstein", + + // Gertrude Elion - American biochemist, pharmacologist and the 1988 recipient of the Nobel Prize in Medicine - https://en.wikipedia.org/wiki/Gertrude_Elion + "elion", + + // Douglas Engelbart gave the mother of all demos: https://en.wikipedia.org/wiki/Douglas_Engelbart + "engelbart", + + // Euclid invented geometry. https://en.wikipedia.org/wiki/Euclid + "euclid", + + // Leonhard Euler invented large parts of modern mathematics. https://de.wikipedia.org/wiki/Leonhard_Euler + "euler", + + // Pierre de Fermat pioneered several aspects of modern mathematics. https://en.wikipedia.org/wiki/Pierre_de_Fermat + "fermat", + + // Enrico Fermi invented the first nuclear reactor. https://en.wikipedia.org/wiki/Enrico_Fermi. + "fermi", + + // Richard Feynman was a key contributor to quantum mechanics and particle physics. https://en.wikipedia.org/wiki/Richard_Feynman + "feynman", + + // Benjamin Franklin is famous for his experiments in electricity and the invention of the lightning rod. + "franklin", + + // Galileo was a founding father of modern astronomy, and faced politics and obscurantism to establish scientific truth. https://en.wikipedia.org/wiki/Galileo_Galilei + "galileo", + + // William Henry "Bill" Gates III is an American business magnate, philanthropist, investor, computer programmer, and inventor. https://en.wikipedia.org/wiki/Bill_Gates + "gates", + + // Adele Goldberg, was one of the designers and developers of the Smalltalk language. https://en.wikipedia.org/wiki/Adele_Goldberg_(computer_scientist) + "goldberg", + + // Adele Goldstine, born Adele Katz, wrote the complete technical description for the first electronic digital computer, ENIAC. https://en.wikipedia.org/wiki/Adele_Goldstine + "goldstine", + + // Shafi Goldwasser is a computer scientist known for creating theoretical foundations of modern cryptography. Winner of 2012 ACM Turing Award. https://en.wikipedia.org/wiki/Shafi_Goldwasser + "goldwasser", + + // James Golick, all around gangster. + "golick", + + // Jane Goodall - British primatologist, ethologist, and anthropologist who is considered to be the world's foremost expert on chimpanzees - https://en.wikipedia.org/wiki/Jane_Goodall + "goodall", + + // Lois Haibt - American computer scientist, part of the team at IBM that developed FORTRAN - https://en.wikipedia.org/wiki/Lois_Haibt + "haibt", + + // Margaret Hamilton - Director of the Software Engineering Division of the MIT Instrumentation Laboratory, which developed on-board flight software for the Apollo space program. https://en.wikipedia.org/wiki/Margaret_Hamilton_(scientist) + "hamilton", + + // Stephen Hawking pioneered the field of cosmology by combining general relativity and quantum mechanics. https://en.wikipedia.org/wiki/Stephen_Hawking + "hawking", + + // Werner Heisenberg was a founding father of quantum mechanics. https://en.wikipedia.org/wiki/Werner_Heisenberg + "heisenberg", + + // Grete Hermann was a German philosopher noted for her philosophical work on the foundations of quantum mechanics. https://en.wikipedia.org/wiki/Grete_Hermann + "hermann", + + // Jaroslav Heyrovský was the inventor of the polarographic method, father of the electroanalytical method, and recipient of the Nobel Prize in 1959. His main field of work was polarography. https://en.wikipedia.org/wiki/Jaroslav_Heyrovsk%C3%BD + "heyrovsky", + + // Dorothy Hodgkin was a British biochemist, credited with the development of protein crystallography. She was awarded the Nobel Prize in Chemistry in 1964. https://en.wikipedia.org/wiki/Dorothy_Hodgkin + "hodgkin", + + // Erna Schneider Hoover revolutionized modern communication by inventing a computerized telephone switching method. https://en.wikipedia.org/wiki/Erna_Schneider_Hoover + "hoover", + + // Grace Hopper developed the first compiler for a computer programming language and is credited with popularizing the term "debugging" for fixing computer glitches. https://en.wikipedia.org/wiki/Grace_Hopper + "hopper", + + // Frances Hugle, she was an American scientist, engineer, and inventor who contributed to the understanding of semiconductors, integrated circuitry, and the unique electrical principles of microscopic materials. https://en.wikipedia.org/wiki/Frances_Hugle + "hugle", + + // Hypatia - Greek Alexandrine Neoplatonist philosopher in Egypt who was one of the earliest mothers of mathematics - https://en.wikipedia.org/wiki/Hypatia + "hypatia", + + // Mary Jackson, American mathematician and aerospace engineer who earned the highest title within NASA's engineering department - https://en.wikipedia.org/wiki/Mary_Jackson_(engineer) + "jackson", + + // Yeong-Sil Jang was a Korean scientist and astronomer during the Joseon Dynasty; he invented the first metal printing press and water gauge. https://en.wikipedia.org/wiki/Jang_Yeong-sil + "jang", + + // Betty Jennings - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Jean_Bartik + "jennings", + + // Mary Lou Jepsen, was the founder and chief technology officer of One Laptop Per Child (OLPC), and the founder of Pixel Qi. https://en.wikipedia.org/wiki/Mary_Lou_Jepsen + "jepsen", + + // Katherine Coleman Goble Johnson - American physicist and mathematician contributed to the NASA. https://en.wikipedia.org/wiki/Katherine_Johnson + "johnson", + + // Irène Joliot-Curie - French scientist who was awarded the Nobel Prize for Chemistry in 1935. Daughter of Marie and Pierre Curie. https://en.wikipedia.org/wiki/Ir%C3%A8ne_Joliot-Curie + "joliot", + + // Karen Spärck Jones came up with the concept of inverse document frequency, which is used in most search engines today. https://en.wikipedia.org/wiki/Karen_Sp%C3%A4rck_Jones + "jones", + + // A. P. J. Abdul Kalam - is an Indian scientist aka Missile Man of India for his work on the development of ballistic missile and launch vehicle technology - https://en.wikipedia.org/wiki/A._P._J._Abdul_Kalam + "kalam", + + // Susan Kare, created the icons and many of the interface elements for the original Apple Macintosh in the 1980s, and was an original employee of NeXT, working as the Creative Director. https://en.wikipedia.org/wiki/Susan_Kare + "kare", + + // Mary Kenneth Keller, Sister Mary Kenneth Keller became the first American woman to earn a PhD in Computer Science in 1965. https://en.wikipedia.org/wiki/Mary_Kenneth_Keller + "keller", + + // Johannes Kepler, German astronomer known for his three laws of planetary motion - https://en.wikipedia.org/wiki/Johannes_Kepler + "kepler", + + // Har Gobind Khorana - Indian-American biochemist who shared the 1968 Nobel Prize for Physiology - https://en.wikipedia.org/wiki/Har_Gobind_Khorana + "khorana", + + // Jack Kilby invented silicone integrated circuits and gave Silicon Valley its name. - https://en.wikipedia.org/wiki/Jack_Kilby + "kilby", + + // Maria Kirch - German astronomer and first woman to discover a comet - https://en.wikipedia.org/wiki/Maria_Margarethe_Kirch + "kirch", + + // Donald Knuth - American computer scientist, author of "The Art of Computer Programming" and creator of the TeX typesetting system. https://en.wikipedia.org/wiki/Donald_Knuth + "knuth", + + // Sophie Kowalevski - Russian mathematician responsible for important original contributions to analysis, differential equations and mechanics - https://en.wikipedia.org/wiki/Sofia_Kovalevskaya + "kowalevski", + + // Marie-Jeanne de Lalande - French astronomer, mathematician and cataloguer of stars - https://en.wikipedia.org/wiki/Marie-Jeanne_de_Lalande + "lalande", + + // Hedy Lamarr - Actress and inventor. The principles of her work are now incorporated into modern Wi-Fi, CDMA and Bluetooth technology. https://en.wikipedia.org/wiki/Hedy_Lamarr + "lamarr", + + // Leslie B. Lamport - American computer scientist. Lamport is best known for his seminal work in distributed systems and was the winner of the 2013 Turing Award. https://en.wikipedia.org/wiki/Leslie_Lamport + "lamport", + + // Mary Leakey - British paleoanthropologist who discovered the first fossilized Proconsul skull - https://en.wikipedia.org/wiki/Mary_Leakey + "leakey", + + // Henrietta Swan Leavitt - she was an American astronomer who discovered the relation between the luminosity and the period of Cepheid variable stars. https://en.wikipedia.org/wiki/Henrietta_Swan_Leavitt + "leavitt", + + //Daniel Lewin - Mathematician, Akamai co-founder, soldier, 9/11 victim-- Developed optimization techniques for routing traffic on the internet. Died attempting to stop the 9-11 hijackers. https://en.wikipedia.org/wiki/Daniel_Lewin + "lewin", + + // Ruth Lichterman - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Ruth_Teitelbaum + "lichterman", + + // Barbara Liskov - co-developed the Liskov substitution principle. Liskov was also the winner of the Turing Prize in 2008. - https://en.wikipedia.org/wiki/Barbara_Liskov + "liskov", + + // Ada Lovelace invented the first algorithm. https://en.wikipedia.org/wiki/Ada_Lovelace (thanks James Turnbull) + "lovelace", + + // Auguste and Louis Lumière - the first filmmakers in history - https://en.wikipedia.org/wiki/Auguste_and_Louis_Lumi%C3%A8re + "lumiere", + + // Mahavira - Ancient Indian mathematician during 9th century AD who discovered basic algebraic identities - https://en.wikipedia.org/wiki/Mah%C4%81v%C4%ABra_(mathematician) + "mahavira", + + // Maria Mayer - American theoretical physicist and Nobel laureate in Physics for proposing the nuclear shell model of the atomic nucleus - https://en.wikipedia.org/wiki/Maria_Mayer + "mayer", + + // John McCarthy invented LISP: https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist) + "mccarthy", + + // Barbara McClintock - a distinguished American cytogeneticist, 1983 Nobel Laureate in Physiology or Medicine for discovering transposons. https://en.wikipedia.org/wiki/Barbara_McClintock + "mcclintock", + + // Malcolm McLean invented the modern shipping container: https://en.wikipedia.org/wiki/Malcom_McLean + "mclean", + + // Kay McNulty - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Kathleen_Antonelli + "mcnulty", + + // Lise Meitner - Austrian/Swedish physicist who was involved in the discovery of nuclear fission. The element meitnerium is named after her - https://en.wikipedia.org/wiki/Lise_Meitner + "meitner", + + // Carla Meninsky, was the game designer and programmer for Atari 2600 games Dodge 'Em and Warlords. https://en.wikipedia.org/wiki/Carla_Meninsky + "meninsky", + + // Johanna Mestorf - German prehistoric archaeologist and first female museum director in Germany - https://en.wikipedia.org/wiki/Johanna_Mestorf + "mestorf", + + // Marvin Minsky - Pioneer in Artificial Intelligence, co-founder of the MIT's AI Lab, won the Turing Award in 1969. https://en.wikipedia.org/wiki/Marvin_Minsky + "minsky", + + // Maryam Mirzakhani - an Iranian mathematician and the first woman to win the Fields Medal. https://en.wikipedia.org/wiki/Maryam_Mirzakhani + "mirzakhani", + + // Samuel Morse - contributed to the invention of a single-wire telegraph system based on European telegraphs and was a co-developer of the Morse code - https://en.wikipedia.org/wiki/Samuel_Morse + "morse", + + // Ian Murdock - founder of the Debian project - https://en.wikipedia.org/wiki/Ian_Murdock + "murdock", + + // John von Neumann - todays computer architectures are based on the von Neumann architecture. https://en.wikipedia.org/wiki/Von_Neumann_architecture + "neumann", + + // Isaac Newton invented classic mechanics and modern optics. https://en.wikipedia.org/wiki/Isaac_Newton + "newton", + + // Florence Nightingale, more prominently known as a nurse, was also the first female member of the Royal Statistical Society and a pioneer in statistical graphics https://en.wikipedia.org/wiki/Florence_Nightingale#Statistics_and_sanitary_reform + "nightingale", + + // Alfred Nobel - a Swedish chemist, engineer, innovator, and armaments manufacturer (inventor of dynamite) - https://en.wikipedia.org/wiki/Alfred_Nobel + "nobel", + + // Emmy Noether, German mathematician. Noether's Theorem is named after her. https://en.wikipedia.org/wiki/Emmy_Noether + "noether", + + // Poppy Northcutt. Poppy Northcutt was the first woman to work as part of NASA’s Mission Control. http://www.businessinsider.com/poppy-northcutt-helped-apollo-astronauts-2014-12?op=1 + "northcutt", + + // Robert Noyce invented silicone integrated circuits and gave Silicon Valley its name. - https://en.wikipedia.org/wiki/Robert_Noyce + "noyce", + + // Panini - Ancient Indian linguist and grammarian from 4th century CE who worked on the world's first formal system - https://en.wikipedia.org/wiki/P%C4%81%E1%B9%87ini#Comparison_with_modern_formal_systems + "panini", + + // Ambroise Pare invented modern surgery. https://en.wikipedia.org/wiki/Ambroise_Par%C3%A9 + "pare", + + // Louis Pasteur discovered vaccination, fermentation and pasteurization. https://en.wikipedia.org/wiki/Louis_Pasteur. + "pasteur", + + // Cecilia Payne-Gaposchkin was an astronomer and astrophysicist who, in 1925, proposed in her Ph.D. thesis an explanation for the composition of stars in terms of the relative abundances of hydrogen and helium. https://en.wikipedia.org/wiki/Cecilia_Payne-Gaposchkin + "payne", + + // Radia Perlman is a software designer and network engineer and most famous for her invention of the spanning-tree protocol (STP). https://en.wikipedia.org/wiki/Radia_Perlman + "perlman", + + // Rob Pike was a key contributor to Unix, Plan 9, the X graphic system, utf-8, and the Go programming language. https://en.wikipedia.org/wiki/Rob_Pike + "pike", + + // Henri Poincaré made fundamental contributions in several fields of mathematics. https://en.wikipedia.org/wiki/Henri_Poincar%C3%A9 + "poincare", + + // Laura Poitras is a director and producer whose work, made possible by open source crypto tools, advances the causes of truth and freedom of information by reporting disclosures by whistleblowers such as Edward Snowden. https://en.wikipedia.org/wiki/Laura_Poitras + "poitras", + + // Claudius Ptolemy - a Greco-Egyptian writer of Alexandria, known as a mathematician, astronomer, geographer, astrologer, and poet of a single epigram in the Greek Anthology - https://en.wikipedia.org/wiki/Ptolemy + "ptolemy", + + // C. V. Raman - Indian physicist who won the Nobel Prize in 1930 for proposing the Raman effect. - https://en.wikipedia.org/wiki/C._V._Raman + "raman", + + // Srinivasa Ramanujan - Indian mathematician and autodidact who made extraordinary contributions to mathematical analysis, number theory, infinite series, and continued fractions. - https://en.wikipedia.org/wiki/Srinivasa_Ramanujan + "ramanujan", + + // Sally Kristen Ride was an American physicist and astronaut. She was the first American woman in space, and the youngest American astronaut. https://en.wikipedia.org/wiki/Sally_Ride + "ride", + + // Rita Levi-Montalcini - Won Nobel Prize in Physiology or Medicine jointly with colleague Stanley Cohen for the discovery of nerve growth factor (https://en.wikipedia.org/wiki/Rita_Levi-Montalcini) + "montalcini", + + // Dennis Ritchie - co-creator of UNIX and the C programming language. - https://en.wikipedia.org/wiki/Dennis_Ritchie + "ritchie", + + // Wilhelm Conrad Röntgen - German physicist who was awarded the first Nobel Prize in Physics in 1901 for the discovery of X-rays (Röntgen rays). https://en.wikipedia.org/wiki/Wilhelm_R%C3%B6ntgen + "roentgen", + + // Rosalind Franklin - British biophysicist and X-ray crystallographer whose research was critical to the understanding of DNA - https://en.wikipedia.org/wiki/Rosalind_Franklin + "rosalind", + + // Meghnad Saha - Indian astrophysicist best known for his development of the Saha equation, used to describe chemical and physical conditions in stars - https://en.wikipedia.org/wiki/Meghnad_Saha + "saha", + + // Jean E. Sammet developed FORMAC, the first widely used computer language for symbolic manipulation of mathematical formulas. https://en.wikipedia.org/wiki/Jean_E._Sammet + "sammet", + + // Carol Shaw - Originally an Atari employee, Carol Shaw is said to be the first female video game designer. https://en.wikipedia.org/wiki/Carol_Shaw_(video_game_designer) + "shaw", + + // Dame Stephanie "Steve" Shirley - Founded a software company in 1962 employing women working from home. https://en.wikipedia.org/wiki/Steve_Shirley + "shirley", + + // William Shockley co-invented the transistor - https://en.wikipedia.org/wiki/William_Shockley + "shockley", + + // Françoise Barré-Sinoussi - French virologist and Nobel Prize Laureate in Physiology or Medicine; her work was fundamental in identifying HIV as the cause of AIDS. https://en.wikipedia.org/wiki/Fran%C3%A7oise_Barr%C3%A9-Sinoussi + "sinoussi", + + // Betty Snyder - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Betty_Holberton + "snyder", + + // Frances Spence - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Frances_Spence + "spence", + + // Richard Matthew Stallman - the founder of the Free Software movement, the GNU project, the Free Software Foundation, and the League for Programming Freedom. He also invented the concept of copyleft to protect the ideals of this movement, and enshrined this concept in the widely-used GPL (General Public License) for software. https://en.wikiquote.org/wiki/Richard_Stallman + "stallman", + + // Michael Stonebraker is a database research pioneer and architect of Ingres, Postgres, VoltDB and SciDB. Winner of 2014 ACM Turing Award. https://en.wikipedia.org/wiki/Michael_Stonebraker + "stonebraker", + + // Janese Swanson (with others) developed the first of the Carmen Sandiego games. She went on to found Girl Tech. https://en.wikipedia.org/wiki/Janese_Swanson + "swanson", + + // Aaron Swartz was influential in creating RSS, Markdown, Creative Commons, Reddit, and much of the internet as we know it today. He was devoted to freedom of information on the web. https://en.wikiquote.org/wiki/Aaron_Swartz + "swartz", + + // Bertha Swirles was a theoretical physicist who made a number of contributions to early quantum theory. https://en.wikipedia.org/wiki/Bertha_Swirles + "swirles", + + // Nikola Tesla invented the AC electric system and every gadget ever used by a James Bond villain. https://en.wikipedia.org/wiki/Nikola_Tesla + "tesla", + + // Ken Thompson - co-creator of UNIX and the C programming language - https://en.wikipedia.org/wiki/Ken_Thompson + "thompson", + + // Linus Torvalds invented Linux and Git. https://en.wikipedia.org/wiki/Linus_Torvalds + "torvalds", + + // Alan Turing was a founding father of computer science. https://en.wikipedia.org/wiki/Alan_Turing. + "turing", + + // Varahamihira - Ancient Indian mathematician who discovered trigonometric formulae during 505-587 CE - https://en.wikipedia.org/wiki/Var%C4%81hamihira#Contributions + "varahamihira", + + // Sir Mokshagundam Visvesvaraya - is a notable Indian engineer. He is a recipient of the Indian Republic's highest honour, the Bharat Ratna, in 1955. On his birthday, 15 September is celebrated as Engineer's Day in India in his memory - https://en.wikipedia.org/wiki/Visvesvaraya + "visvesvaraya", + + // Christiane Nüsslein-Volhard - German biologist, won Nobel Prize in Physiology or Medicine in 1995 for research on the genetic control of embryonic development. https://en.wikipedia.org/wiki/Christiane_N%C3%BCsslein-Volhard + "volhard", + + // Marlyn Wescoff - one of the original programmers of the ENIAC. https://en.wikipedia.org/wiki/ENIAC - https://en.wikipedia.org/wiki/Marlyn_Meltzer + "wescoff", + + // Andrew Wiles - Notable British mathematician who proved the enigmatic Fermat's Last Theorem - https://en.wikipedia.org/wiki/Andrew_Wiles + "wiles", + + // Roberta Williams, did pioneering work in graphical adventure games for personal computers, particularly the King's Quest series. https://en.wikipedia.org/wiki/Roberta_Williams + "williams", + + // Sophie Wilson designed the first Acorn Micro-Computer and the instruction set for ARM processors. https://en.wikipedia.org/wiki/Sophie_Wilson + "wilson", + + // Jeannette Wing - co-developed the Liskov substitution principle. - https://en.wikipedia.org/wiki/Jeannette_Wing + "wing", + + // Steve Wozniak invented the Apple I and Apple II. https://en.wikipedia.org/wiki/Steve_Wozniak + "wozniak", + + // The Wright brothers, Orville and Wilbur - credited with inventing and building the world's first successful airplane and making the first controlled, powered and sustained heavier-than-air human flight - https://en.wikipedia.org/wiki/Wright_brothers + "wright", + + // Rosalyn Sussman Yalow - Rosalyn Sussman Yalow was an American medical physicist, and a co-winner of the 1977 Nobel Prize in Physiology or Medicine for development of the radioimmunoassay technique. https://en.wikipedia.org/wiki/Rosalyn_Sussman_Yalow + "yalow", + + // Ada Yonath - an Israeli crystallographer, the first woman from the Middle East to win a Nobel prize in the sciences. https://en.wikipedia.org/wiki/Ada_Yonath + "yonath", + } +) + +// GetRandomName generates a random name from the list of adjectives and surnames in this package +// formatted as "adjective_surname". For example 'focused_turing'. If retry is non-zero, a random +// integer between 0 and 10 will be added to the end of the name, e.g `focused_turing3` +func GetRandomName(retry int) string { + rnd := random.Rand +begin: + name := fmt.Sprintf("%s_%s", left[rnd.Intn(len(left))], right[rnd.Intn(len(right))]) + if name == "boring_wozniak" /* Steve Wozniak is not boring */ { + goto begin + } + + if retry > 0 { + name = fmt.Sprintf("%s%d", name, rnd.Intn(10)) + } + return name +} diff --git a/vendor/github.com/docker/docker/pkg/random/random.go b/vendor/github.com/docker/docker/pkg/random/random.go new file mode 100644 index 000000000..70de4d130 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/random/random.go @@ -0,0 +1,71 @@ +package random + +import ( + cryptorand "crypto/rand" + "io" + "math" + "math/big" + "math/rand" + "sync" + "time" +) + +// Rand is a global *rand.Rand instance, which initialized with NewSource() source. +var Rand = rand.New(NewSource()) + +// Reader is a global, shared instance of a pseudorandom bytes generator. +// It doesn't consume entropy. +var Reader io.Reader = &reader{rnd: Rand} + +// copypaste from standard math/rand +type lockedSource struct { + lk sync.Mutex + src rand.Source +} + +func (r *lockedSource) Int63() (n int64) { + r.lk.Lock() + n = r.src.Int63() + r.lk.Unlock() + return +} + +func (r *lockedSource) Seed(seed int64) { + r.lk.Lock() + r.src.Seed(seed) + r.lk.Unlock() +} + +// NewSource returns math/rand.Source safe for concurrent use and initialized +// with current unix-nano timestamp +func NewSource() rand.Source { + var seed int64 + if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil { + // This should not happen, but worst-case fallback to time-based seed. + seed = time.Now().UnixNano() + } else { + seed = cryptoseed.Int64() + } + return &lockedSource{ + src: rand.NewSource(seed), + } +} + +type reader struct { + rnd *rand.Rand +} + +func (r *reader) Read(b []byte) (int, error) { + i := 0 + for { + val := r.rnd.Int63() + for val > 0 { + b[i] = byte(val) + i++ + if i == len(b) { + return i, nil + } + val >>= 8 + } + } +} diff --git a/vendor/github.com/dustin/go-humanize/LICENSE b/vendor/github.com/dustin/go-humanize/LICENSE new file mode 100644 index 000000000..8d9a94a90 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2005-2008 Dustin Sallings <dustin@spy.net> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +<http://www.opensource.org/licenses/mit-license.php> diff --git a/vendor/github.com/dustin/go-humanize/README.markdown b/vendor/github.com/dustin/go-humanize/README.markdown new file mode 100644 index 000000000..f69d3c870 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/README.markdown @@ -0,0 +1,92 @@ +# Humane Units [![Build Status](https://travis-ci.org/dustin/go-humanize.svg?branch=master)](https://travis-ci.org/dustin/go-humanize) [![GoDoc](https://godoc.org/github.com/dustin/go-humanize?status.svg)](https://godoc.org/github.com/dustin/go-humanize) + +Just a few functions for helping humanize times and sizes. + +`go get` it as `github.com/dustin/go-humanize`, import it as +`"github.com/dustin/go-humanize"`, use it as `humanize`. + +See [godoc](https://godoc.org/github.com/dustin/go-humanize) for +complete documentation. + +## Sizes + +This lets you take numbers like `82854982` and convert them to useful +strings like, `83 MB` or `79 MiB` (whichever you prefer). + +Example: + +```go +fmt.Printf("That file is %s.", humanize.Bytes(82854982)) // That file is 83 MB. +``` + +## Times + +This lets you take a `time.Time` and spit it out in relative terms. +For example, `12 seconds ago` or `3 days from now`. + +Example: + +```go +fmt.Printf("This was touched %s.", humanize.Time(someTimeInstance)) // This was touched 7 hours ago. +``` + +Thanks to Kyle Lemons for the time implementation from an IRC +conversation one day. It's pretty neat. + +## Ordinals + +From a [mailing list discussion][odisc] where a user wanted to be able +to label ordinals. + + 0 -> 0th + 1 -> 1st + 2 -> 2nd + 3 -> 3rd + 4 -> 4th + [...] + +Example: + +```go +fmt.Printf("You're my %s best friend.", humanize.Ordinal(193)) // You are my 193rd best friend. +``` + +## Commas + +Want to shove commas into numbers? Be my guest. + + 0 -> 0 + 100 -> 100 + 1000 -> 1,000 + 1000000000 -> 1,000,000,000 + -100000 -> -100,000 + +Example: + +```go +fmt.Printf("You owe $%s.\n", humanize.Comma(6582491)) // You owe $6,582,491. +``` + +## Ftoa + +Nicer float64 formatter that removes trailing zeros. + +```go +fmt.Printf("%f", 2.24) // 2.240000 +fmt.Printf("%s", humanize.Ftoa(2.24)) // 2.24 +fmt.Printf("%f", 2.0) // 2.000000 +fmt.Printf("%s", humanize.Ftoa(2.0)) // 2 +``` + +## SI notation + +Format numbers with [SI notation][sinotation]. + +Example: + +```go +humanize.SI(0.00000000223, "M") // 2.23 nM +``` + +[odisc]: https://groups.google.com/d/topic/golang-nuts/l8NhI74jl-4/discussion +[sinotation]: http://en.wikipedia.org/wiki/Metric_prefix diff --git a/vendor/github.com/dustin/go-humanize/big.go b/vendor/github.com/dustin/go-humanize/big.go new file mode 100644 index 000000000..f49dc337d --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/big.go @@ -0,0 +1,31 @@ +package humanize + +import ( + "math/big" +) + +// order of magnitude (to a max order) +func oomm(n, b *big.Int, maxmag int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + if mag == maxmag && maxmag >= 0 { + break + } + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} + +// total order of magnitude +// (same as above, but with no upper limit) +func oom(n, b *big.Int) (float64, int) { + mag := 0 + m := &big.Int{} + for n.Cmp(b) >= 0 { + n.DivMod(n, b, m) + mag++ + } + return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag +} diff --git a/vendor/github.com/dustin/go-humanize/bigbytes.go b/vendor/github.com/dustin/go-humanize/bigbytes.go new file mode 100644 index 000000000..1a2bf6172 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bigbytes.go @@ -0,0 +1,173 @@ +package humanize + +import ( + "fmt" + "math/big" + "strings" + "unicode" +) + +var ( + bigIECExp = big.NewInt(1024) + + // BigByte is one byte in bit.Ints + BigByte = big.NewInt(1) + // BigKiByte is 1,024 bytes in bit.Ints + BigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp) + // BigMiByte is 1,024 k bytes in bit.Ints + BigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp) + // BigGiByte is 1,024 m bytes in bit.Ints + BigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp) + // BigTiByte is 1,024 g bytes in bit.Ints + BigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp) + // BigPiByte is 1,024 t bytes in bit.Ints + BigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp) + // BigEiByte is 1,024 p bytes in bit.Ints + BigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp) + // BigZiByte is 1,024 e bytes in bit.Ints + BigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp) + // BigYiByte is 1,024 z bytes in bit.Ints + BigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp) +) + +var ( + bigSIExp = big.NewInt(1000) + + // BigSIByte is one SI byte in big.Ints + BigSIByte = big.NewInt(1) + // BigKByte is 1,000 SI bytes in big.Ints + BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp) + // BigMByte is 1,000 SI k bytes in big.Ints + BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp) + // BigGByte is 1,000 SI m bytes in big.Ints + BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp) + // BigTByte is 1,000 SI g bytes in big.Ints + BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp) + // BigPByte is 1,000 SI t bytes in big.Ints + BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp) + // BigEByte is 1,000 SI p bytes in big.Ints + BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp) + // BigZByte is 1,000 SI e bytes in big.Ints + BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp) + // BigYByte is 1,000 SI z bytes in big.Ints + BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp) +) + +var bigBytesSizeTable = map[string]*big.Int{ + "b": BigByte, + "kib": BigKiByte, + "kb": BigKByte, + "mib": BigMiByte, + "mb": BigMByte, + "gib": BigGiByte, + "gb": BigGByte, + "tib": BigTiByte, + "tb": BigTByte, + "pib": BigPiByte, + "pb": BigPByte, + "eib": BigEiByte, + "eb": BigEByte, + "zib": BigZiByte, + "zb": BigZByte, + "yib": BigYiByte, + "yb": BigYByte, + // Without suffix + "": BigByte, + "ki": BigKiByte, + "k": BigKByte, + "mi": BigMiByte, + "m": BigMByte, + "gi": BigGiByte, + "g": BigGByte, + "ti": BigTiByte, + "t": BigTByte, + "pi": BigPiByte, + "p": BigPByte, + "ei": BigEiByte, + "e": BigEByte, + "z": BigZByte, + "zi": BigZiByte, + "y": BigYByte, + "yi": BigYiByte, +} + +var ten = big.NewInt(10) + +func humanateBigBytes(s, base *big.Int, sizes []string) string { + if s.Cmp(ten) < 0 { + return fmt.Sprintf("%d B", s) + } + c := (&big.Int{}).Set(s) + val, mag := oomm(c, base, len(sizes)-1) + suffix := sizes[mag] + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) + +} + +// BigBytes produces a human readable representation of an SI size. +// +// See also: ParseBigBytes. +// +// BigBytes(82854982) -> 83 MB +func BigBytes(s *big.Int) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + return humanateBigBytes(s, bigSIExp, sizes) +} + +// BigIBytes produces a human readable representation of an IEC size. +// +// See also: ParseBigBytes. +// +// BigIBytes(82854982) -> 79 MiB +func BigIBytes(s *big.Int) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} + return humanateBigBytes(s, bigIECExp, sizes) +} + +// ParseBigBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See also: BigBytes, BigIBytes. +// +// ParseBigBytes("42 MB") -> 42000000, nil +// ParseBigBytes("42 mib") -> 44040192, nil +func ParseBigBytes(s string) (*big.Int, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break + } + if r == ',' { + hasComma = true + } + lastDigit++ + } + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + val := &big.Rat{} + _, err := fmt.Sscanf(num, "%f", val) + if err != nil { + return nil, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bigBytesSizeTable[extra]; ok { + mv := (&big.Rat{}).SetInt(m) + val.Mul(val, mv) + rv := &big.Int{} + rv.Div(val.Num(), val.Denom()) + return rv, nil + } + + return nil, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/bytes.go b/vendor/github.com/dustin/go-humanize/bytes.go new file mode 100644 index 000000000..0b498f488 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bytes.go @@ -0,0 +1,143 @@ +package humanize + +import ( + "fmt" + "math" + "strconv" + "strings" + "unicode" +) + +// IEC Sizes. +// kibis of bits +const ( + Byte = 1 << (iota * 10) + KiByte + MiByte + GiByte + TiByte + PiByte + EiByte +) + +// SI Sizes. +const ( + IByte = 1 + KByte = IByte * 1000 + MByte = KByte * 1000 + GByte = MByte * 1000 + TByte = GByte * 1000 + PByte = TByte * 1000 + EByte = PByte * 1000 +) + +var bytesSizeTable = map[string]uint64{ + "b": Byte, + "kib": KiByte, + "kb": KByte, + "mib": MiByte, + "mb": MByte, + "gib": GiByte, + "gb": GByte, + "tib": TiByte, + "tb": TByte, + "pib": PiByte, + "pb": PByte, + "eib": EiByte, + "eb": EByte, + // Without suffix + "": Byte, + "ki": KiByte, + "k": KByte, + "mi": MiByte, + "m": MByte, + "gi": GiByte, + "g": GByte, + "ti": TiByte, + "t": TByte, + "pi": PiByte, + "p": PByte, + "ei": EiByte, + "e": EByte, +} + +func logn(n, b float64) float64 { + return math.Log(n) / math.Log(b) +} + +func humanateBytes(s uint64, base float64, sizes []string) string { + if s < 10 { + return fmt.Sprintf("%d B", s) + } + e := math.Floor(logn(float64(s), base)) + suffix := sizes[int(e)] + val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10 + f := "%.0f %s" + if val < 10 { + f = "%.1f %s" + } + + return fmt.Sprintf(f, val, suffix) +} + +// Bytes produces a human readable representation of an SI size. +// +// See also: ParseBytes. +// +// Bytes(82854982) -> 83 MB +func Bytes(s uint64) string { + sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"} + return humanateBytes(s, 1000, sizes) +} + +// IBytes produces a human readable representation of an IEC size. +// +// See also: ParseBytes. +// +// IBytes(82854982) -> 79 MiB +func IBytes(s uint64) string { + sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"} + return humanateBytes(s, 1024, sizes) +} + +// ParseBytes parses a string representation of bytes into the number +// of bytes it represents. +// +// See Also: Bytes, IBytes. +// +// ParseBytes("42 MB") -> 42000000, nil +// ParseBytes("42 mib") -> 44040192, nil +func ParseBytes(s string) (uint64, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break + } + if r == ',' { + hasComma = true + } + lastDigit++ + } + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + f, err := strconv.ParseFloat(num, 64) + if err != nil { + return 0, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + if m, ok := bytesSizeTable[extra]; ok { + f *= float64(m) + if f >= math.MaxUint64 { + return 0, fmt.Errorf("too large: %v", s) + } + return uint64(f), nil + } + + return 0, fmt.Errorf("unhandled size name: %v", extra) +} diff --git a/vendor/github.com/dustin/go-humanize/comma.go b/vendor/github.com/dustin/go-humanize/comma.go new file mode 100644 index 000000000..eb285cb95 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/comma.go @@ -0,0 +1,108 @@ +package humanize + +import ( + "bytes" + "math" + "math/big" + "strconv" + "strings" +) + +// Comma produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Comma(834142) -> 834,142 +func Comma(v int64) string { + sign := "" + + // minin64 can't be negated to a usable value, so it has to be special cased. + if v == math.MinInt64 { + return "-9,223,372,036,854,775,808" + } + + if v < 0 { + sign = "-" + v = 0 - v + } + + parts := []string{"", "", "", "", "", "", ""} + j := len(parts) - 1 + + for v > 999 { + parts[j] = strconv.FormatInt(v%1000, 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + v = v / 1000 + j-- + } + parts[j] = strconv.Itoa(int(v)) + return sign + strings.Join(parts[j:], ",") +} + +// Commaf produces a string form of the given number in base 10 with +// commas after every three orders of magnitude. +// +// e.g. Commaf(834142.32) -> 834,142.32 +func Commaf(v float64) string { + buf := &bytes.Buffer{} + if v < 0 { + buf.Write([]byte{'-'}) + v = 0 - v + } + + comma := []byte{','} + + parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} + +// BigComma produces a string form of the given big.Int in base 10 +// with commas after every three orders of magnitude. +func BigComma(b *big.Int) string { + sign := "" + if b.Sign() < 0 { + sign = "-" + b.Abs(b) + } + + athousand := big.NewInt(1000) + c := (&big.Int{}).Set(b) + _, m := oom(c, athousand) + parts := make([]string, m+1) + j := len(parts) - 1 + + mod := &big.Int{} + for b.Cmp(athousand) >= 0 { + b.DivMod(b, athousand, mod) + parts[j] = strconv.FormatInt(mod.Int64(), 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + j-- + } + parts[j] = strconv.Itoa(int(b.Int64())) + return sign + strings.Join(parts[j:], ",") +} diff --git a/vendor/github.com/dustin/go-humanize/commaf.go b/vendor/github.com/dustin/go-humanize/commaf.go new file mode 100644 index 000000000..620690dec --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/commaf.go @@ -0,0 +1,40 @@ +// +build go1.6 + +package humanize + +import ( + "bytes" + "math/big" + "strings" +) + +// BigCommaf produces a string form of the given big.Float in base 10 +// with commas after every three orders of magnitude. +func BigCommaf(v *big.Float) string { + buf := &bytes.Buffer{} + if v.Sign() < 0 { + buf.Write([]byte{'-'}) + v.Abs(v) + } + + comma := []byte{','} + + parts := strings.Split(v.Text('f', -1), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} diff --git a/vendor/github.com/dustin/go-humanize/ftoa.go b/vendor/github.com/dustin/go-humanize/ftoa.go new file mode 100644 index 000000000..c76190b10 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ftoa.go @@ -0,0 +1,23 @@ +package humanize + +import "strconv" + +func stripTrailingZeros(s string) string { + offset := len(s) - 1 + for offset > 0 { + if s[offset] == '.' { + offset-- + break + } + if s[offset] != '0' { + break + } + offset-- + } + return s[:offset+1] +} + +// Ftoa converts a float to a string with no trailing zeros. +func Ftoa(num float64) string { + return stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64)) +} diff --git a/vendor/github.com/dustin/go-humanize/humanize.go b/vendor/github.com/dustin/go-humanize/humanize.go new file mode 100644 index 000000000..a2c2da31e --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/humanize.go @@ -0,0 +1,8 @@ +/* +Package humanize converts boring ugly numbers to human-friendly strings and back. + +Durations can be turned into strings such as "3 days ago", numbers +representing sizes like 82854982 into useful strings like, "83 MB" or +"79 MiB" (whichever you prefer). +*/ +package humanize diff --git a/vendor/github.com/dustin/go-humanize/number.go b/vendor/github.com/dustin/go-humanize/number.go new file mode 100644 index 000000000..dec618659 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/number.go @@ -0,0 +1,192 @@ +package humanize + +/* +Slightly adapted from the source to fit go-humanize. + +Author: https://github.com/gorhill +Source: https://gist.github.com/gorhill/5285193 + +*/ + +import ( + "math" + "strconv" +) + +var ( + renderFloatPrecisionMultipliers = [...]float64{ + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + } + + renderFloatPrecisionRounders = [...]float64{ + 0.5, + 0.05, + 0.005, + 0.0005, + 0.00005, + 0.000005, + 0.0000005, + 0.00000005, + 0.000000005, + 0.0000000005, + } +) + +// FormatFloat produces a formatted number as string based on the following user-specified criteria: +// * thousands separator +// * decimal separator +// * decimal precision +// +// Usage: s := RenderFloat(format, n) +// The format parameter tells how to render the number n. +// +// See examples: http://play.golang.org/p/LXc1Ddm1lJ +// +// Examples of format strings, given n = 12345.6789: +// "#,###.##" => "12,345.67" +// "#,###." => "12,345" +// "#,###" => "12345,678" +// "#\u202F###,##" => "12 345,68" +// "#.###,###### => 12.345,678900 +// "" (aka default format) => 12,345.67 +// +// The highest precision allowed is 9 digits after the decimal symbol. +// There is also a version for integer number, FormatInteger(), +// which is convenient for calls within template. +func FormatFloat(format string, n float64) string { + // Special cases: + // NaN = "NaN" + // +Inf = "+Infinity" + // -Inf = "-Infinity" + if math.IsNaN(n) { + return "NaN" + } + if n > math.MaxFloat64 { + return "Infinity" + } + if n < -math.MaxFloat64 { + return "-Infinity" + } + + // default format + precision := 2 + decimalStr := "." + thousandStr := "," + positiveStr := "" + negativeStr := "-" + + if len(format) > 0 { + format := []rune(format) + + // If there is an explicit format directive, + // then default values are these: + precision = 9 + thousandStr = "" + + // collect indices of meaningful formatting directives + formatIndx := []int{} + for i, char := range format { + if char != '#' && char != '0' { + formatIndx = append(formatIndx, i) + } + } + + if len(formatIndx) > 0 { + // Directive at index 0: + // Must be a '+' + // Raise an error if not the case + // index: 0123456789 + // +0.000,000 + // +000,000.0 + // +0000.00 + // +0000 + if formatIndx[0] == 0 { + if format[formatIndx[0]] != '+' { + panic("RenderFloat(): invalid positive sign directive") + } + positiveStr = "+" + formatIndx = formatIndx[1:] + } + + // Two directives: + // First is thousands separator + // Raise an error if not followed by 3-digit + // 0123456789 + // 0.000,000 + // 000,000.00 + if len(formatIndx) == 2 { + if (formatIndx[1] - formatIndx[0]) != 4 { + panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers") + } + thousandStr = string(format[formatIndx[0]]) + formatIndx = formatIndx[1:] + } + + // One directive: + // Directive is decimal separator + // The number of digit-specifier following the separator indicates wanted precision + // 0123456789 + // 0.00 + // 000,0000 + if len(formatIndx) == 1 { + decimalStr = string(format[formatIndx[0]]) + precision = len(format) - formatIndx[0] - 1 + } + } + } + + // generate sign part + var signStr string + if n >= 0.000000001 { + signStr = positiveStr + } else if n <= -0.000000001 { + signStr = negativeStr + n = -n + } else { + signStr = "" + n = 0.0 + } + + // split number into integer and fractional parts + intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision]) + + // generate integer part string + intStr := strconv.FormatInt(int64(intf), 10) + + // add thousand separator if required + if len(thousandStr) > 0 { + for i := len(intStr); i > 3; { + i -= 3 + intStr = intStr[:i] + thousandStr + intStr[i:] + } + } + + // no fractional part, we can leave now + if precision == 0 { + return signStr + intStr + } + + // generate fractional part + fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision])) + // may need padding + if len(fracStr) < precision { + fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr + } + + return signStr + intStr + decimalStr + fracStr +} + +// FormatInteger produces a formatted number as string. +// See FormatFloat. +func FormatInteger(format string, n int) string { + return FormatFloat(format, float64(n)) +} diff --git a/vendor/github.com/dustin/go-humanize/ordinals.go b/vendor/github.com/dustin/go-humanize/ordinals.go new file mode 100644 index 000000000..43d88a861 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/ordinals.go @@ -0,0 +1,25 @@ +package humanize + +import "strconv" + +// Ordinal gives you the input number in a rank/ordinal format. +// +// Ordinal(3) -> 3rd +func Ordinal(x int) string { + suffix := "th" + switch x % 10 { + case 1: + if x%100 != 11 { + suffix = "st" + } + case 2: + if x%100 != 12 { + suffix = "nd" + } + case 3: + if x%100 != 13 { + suffix = "rd" + } + } + return strconv.Itoa(x) + suffix +} diff --git a/vendor/github.com/dustin/go-humanize/si.go b/vendor/github.com/dustin/go-humanize/si.go new file mode 100644 index 000000000..b24e48169 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/si.go @@ -0,0 +1,113 @@ +package humanize + +import ( + "errors" + "math" + "regexp" + "strconv" +) + +var siPrefixTable = map[float64]string{ + -24: "y", // yocto + -21: "z", // zepto + -18: "a", // atto + -15: "f", // femto + -12: "p", // pico + -9: "n", // nano + -6: "µ", // micro + -3: "m", // milli + 0: "", + 3: "k", // kilo + 6: "M", // mega + 9: "G", // giga + 12: "T", // tera + 15: "P", // peta + 18: "E", // exa + 21: "Z", // zetta + 24: "Y", // yotta +} + +var revSIPrefixTable = revfmap(siPrefixTable) + +// revfmap reverses the map and precomputes the power multiplier +func revfmap(in map[float64]string) map[string]float64 { + rv := map[string]float64{} + for k, v := range in { + rv[v] = math.Pow(10, k) + } + return rv +} + +var riParseRegex *regexp.Regexp + +func init() { + ri := `^([\-0-9.]+)\s?([` + for _, v := range siPrefixTable { + ri += v + } + ri += `]?)(.*)` + + riParseRegex = regexp.MustCompile(ri) +} + +// ComputeSI finds the most appropriate SI prefix for the given number +// and returns the prefix along with the value adjusted to be within +// that prefix. +// +// See also: SI, ParseSI. +// +// e.g. ComputeSI(2.2345e-12) -> (2.2345, "p") +func ComputeSI(input float64) (float64, string) { + if input == 0 { + return 0, "" + } + mag := math.Abs(input) + exponent := math.Floor(logn(mag, 10)) + exponent = math.Floor(exponent/3) * 3 + + value := mag / math.Pow(10, exponent) + + // Handle special case where value is exactly 1000.0 + // Should return 1 M instead of 1000 k + if value == 1000.0 { + exponent += 3 + value = mag / math.Pow(10, exponent) + } + + value = math.Copysign(value, input) + + prefix := siPrefixTable[exponent] + return value, prefix +} + +// SI returns a string with default formatting. +// +// SI uses Ftoa to format float value, removing trailing zeros. +// +// See also: ComputeSI, ParseSI. +// +// e.g. SI(1000000, "B") -> 1 MB +// e.g. SI(2.2345e-12, "F") -> 2.2345 pF +func SI(input float64, unit string) string { + value, prefix := ComputeSI(input) + return Ftoa(value) + " " + prefix + unit +} + +var errInvalid = errors.New("invalid input") + +// ParseSI parses an SI string back into the number and unit. +// +// See also: SI, ComputeSI. +// +// e.g. ParseSI("2.2345 pF") -> (2.2345e-12, "F", nil) +func ParseSI(input string) (float64, string, error) { + found := riParseRegex.FindStringSubmatch(input) + if len(found) != 4 { + return 0, "", errInvalid + } + mag := revSIPrefixTable[found[2]] + unit := found[3] + + base, err := strconv.ParseFloat(found[1], 64) + return base * mag, unit, err +} diff --git a/vendor/github.com/dustin/go-humanize/times.go b/vendor/github.com/dustin/go-humanize/times.go new file mode 100644 index 000000000..b311f11c8 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/times.go @@ -0,0 +1,117 @@ +package humanize + +import ( + "fmt" + "math" + "sort" + "time" +) + +// Seconds-based time units +const ( + Day = 24 * time.Hour + Week = 7 * Day + Month = 30 * Day + Year = 12 * Month + LongTime = 37 * Year +) + +// Time formats a time into a relative string. +// +// Time(someT) -> "3 weeks ago" +func Time(then time.Time) string { + return RelTime(then, time.Now(), "ago", "from now") +} + +// A RelTimeMagnitude struct contains a relative time point at which +// the relative format of time will switch to a new format string. A +// slice of these in ascending order by their "D" field is passed to +// CustomRelTime to format durations. +// +// The Format field is a string that may contain a "%s" which will be +// replaced with the appropriate signed label (e.g. "ago" or "from +// now") and a "%d" that will be replaced by the quantity. +// +// The DivBy field is the amount of time the time difference must be +// divided by in order to display correctly. +// +// e.g. if D is 2*time.Minute and you want to display "%d minutes %s" +// DivBy should be time.Minute so whatever the duration is will be +// expressed in minutes. +type RelTimeMagnitude struct { + D time.Duration + Format string + DivBy time.Duration +} + +var defaultMagnitudes = []RelTimeMagnitude{ + {time.Second, "now", time.Second}, + {2 * time.Second, "1 second %s", 1}, + {time.Minute, "%d seconds %s", time.Second}, + {2 * time.Minute, "1 minute %s", 1}, + {time.Hour, "%d minutes %s", time.Minute}, + {2 * time.Hour, "1 hour %s", 1}, + {Day, "%d hours %s", time.Hour}, + {2 * Day, "1 day %s", 1}, + {Week, "%d days %s", Day}, + {2 * Week, "1 week %s", 1}, + {Month, "%d weeks %s", Week}, + {2 * Month, "1 month %s", 1}, + {Year, "%d months %s", Month}, + {18 * Month, "1 year %s", 1}, + {2 * Year, "2 years %s", 1}, + {LongTime, "%d years %s", Year}, + {math.MaxInt64, "a long while %s", 1}, +} + +// RelTime formats a time into a relative string. +// +// It takes two times and two labels. In addition to the generic time +// delta string (e.g. 5 minutes), the labels are used applied so that +// the label corresponding to the smaller time is applied. +// +// RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier" +func RelTime(a, b time.Time, albl, blbl string) string { + return CustomRelTime(a, b, albl, blbl, defaultMagnitudes) +} + +// CustomRelTime formats a time into a relative string. +// +// It takes two times two labels and a table of relative time formats. +// In addition to the generic time delta string (e.g. 5 minutes), the +// labels are used applied so that the label corresponding to the +// smaller time is applied. +func CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string { + lbl := albl + diff := b.Sub(a) + + if a.After(b) { + lbl = blbl + diff = a.Sub(b) + } + + n := sort.Search(len(magnitudes), func(i int) bool { + return magnitudes[i].D >= diff + }) + + if n >= len(magnitudes) { + n = len(magnitudes) - 1 + } + mag := magnitudes[n] + args := []interface{}{} + escaped := false + for _, ch := range mag.Format { + if escaped { + switch ch { + case 's': + args = append(args, lbl) + case 'd': + args = append(args, diff/mag.DivBy) + } + escaped = false + } else { + escaped = ch == '%' + } + } + return fmt.Sprintf(mag.Format, args...) +} diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS new file mode 100644 index 000000000..b003eca0c --- /dev/null +++ b/vendor/github.com/gorilla/websocket/AUTHORS @@ -0,0 +1,8 @@ +# This is the official list of Gorilla WebSocket authors for copyright +# purposes. +# +# Please keep the list sorted. + +Gary Burd <gary@beagledreams.com> +Joachim Bauch <mail@joachim-bauch.de> + diff --git a/vendor/github.com/gorilla/websocket/LICENSE b/vendor/github.com/gorilla/websocket/LICENSE new file mode 100644 index 000000000..9171c9722 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md new file mode 100644 index 000000000..33c3d2be3 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/README.md @@ -0,0 +1,64 @@ +# Gorilla WebSocket + +Gorilla WebSocket is a [Go](http://golang.org/) implementation of the +[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. + +[![Build Status](https://travis-ci.org/gorilla/websocket.svg?branch=master)](https://travis-ci.org/gorilla/websocket) +[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) + +### Documentation + +* [API Reference](http://godoc.org/github.com/gorilla/websocket) +* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) +* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) +* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) +* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) + +### Status + +The Gorilla WebSocket package provides a complete and tested implementation of +the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The +package API is stable. + +### Installation + + go get github.com/gorilla/websocket + +### Protocol Compliance + +The Gorilla WebSocket package passes the server tests in the [Autobahn Test +Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn +subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). + +### Gorilla WebSocket compared with other packages + +<table> +<tr> +<th></th> +<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th> +<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th> +</tr> +<tr> +<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr> +<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr> +<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr> +<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr> +<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr> +<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr> +<tr><td colspan="3">Other Features</tr></td> +<tr><td><a href="https://tools.ietf.org/html/rfc7692">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr> +<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr> +<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr> +</table> + +Notes: + +1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). +2. The application can get the type of a received data message by implementing + a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) + function. +3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. + Read returns when the input buffer is full or a frame boundary is + encountered. Each call to Write sends a single frame message. The Gorilla + io.Reader and io.WriteCloser operate on a single WebSocket message. + diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go new file mode 100644 index 000000000..43a87c753 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client.go @@ -0,0 +1,392 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "bytes" + "crypto/tls" + "encoding/base64" + "errors" + "io" + "io/ioutil" + "net" + "net/http" + "net/url" + "strings" + "time" +) + +// ErrBadHandshake is returned when the server response to opening handshake is +// invalid. +var ErrBadHandshake = errors.New("websocket: bad handshake") + +var errInvalidCompression = errors.New("websocket: invalid compression negotiation") + +// NewClient creates a new client connection using the given net connection. +// The URL u specifies the host and request URI. Use requestHeader to specify +// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies +// (Cookie). Use the response.Header to get the selected subprotocol +// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). +// +// If the WebSocket handshake fails, ErrBadHandshake is returned along with a +// non-nil *http.Response so that callers can handle redirects, authentication, +// etc. +// +// Deprecated: Use Dialer instead. +func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { + d := Dialer{ + ReadBufferSize: readBufSize, + WriteBufferSize: writeBufSize, + NetDial: func(net, addr string) (net.Conn, error) { + return netConn, nil + }, + } + return d.Dial(u.String(), requestHeader) +} + +// A Dialer contains options for connecting to WebSocket server. +type Dialer struct { + // NetDial specifies the dial function for creating TCP connections. If + // NetDial is nil, net.Dial is used. + NetDial func(network, addr string) (net.Conn, error) + + // Proxy specifies a function to return a proxy for a given + // Request. If the function returns a non-nil error, the + // request is aborted with the provided error. + // If Proxy is nil or returns a nil *URL, no proxy is used. + Proxy func(*http.Request) (*url.URL, error) + + // TLSClientConfig specifies the TLS configuration to use with tls.Client. + // If nil, the default configuration is used. + TLSClientConfig *tls.Config + + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer + // size is zero, then a useful default size is used. The I/O buffer sizes + // do not limit the size of the messages that can be sent or received. + ReadBufferSize, WriteBufferSize int + + // Subprotocols specifies the client's requested subprotocols. + Subprotocols []string + + // EnableCompression specifies if the client should attempt to negotiate + // per message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool + + // Jar specifies the cookie jar. + // If Jar is nil, cookies are not sent in requests and ignored + // in responses. + Jar http.CookieJar +} + +var errMalformedURL = errors.New("malformed ws or wss URL") + +// parseURL parses the URL. +// +// This function is a replacement for the standard library url.Parse function. +// In Go 1.4 and earlier, url.Parse loses information from the path. +func parseURL(s string) (*url.URL, error) { + // From the RFC: + // + // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ] + // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ] + var u url.URL + switch { + case strings.HasPrefix(s, "ws://"): + u.Scheme = "ws" + s = s[len("ws://"):] + case strings.HasPrefix(s, "wss://"): + u.Scheme = "wss" + s = s[len("wss://"):] + default: + return nil, errMalformedURL + } + + if i := strings.Index(s, "?"); i >= 0 { + u.RawQuery = s[i+1:] + s = s[:i] + } + + if i := strings.Index(s, "/"); i >= 0 { + u.Opaque = s[i:] + s = s[:i] + } else { + u.Opaque = "/" + } + + u.Host = s + + if strings.Contains(u.Host, "@") { + // Don't bother parsing user information because user information is + // not allowed in websocket URIs. + return nil, errMalformedURL + } + + return &u, nil +} + +func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { + hostPort = u.Host + hostNoPort = u.Host + if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { + hostNoPort = hostNoPort[:i] + } else { + switch u.Scheme { + case "wss": + hostPort += ":443" + case "https": + hostPort += ":443" + default: + hostPort += ":80" + } + } + return hostPort, hostNoPort +} + +// DefaultDialer is a dialer with all fields set to the default zero values. +var DefaultDialer = &Dialer{ + Proxy: http.ProxyFromEnvironment, +} + +// Dial creates a new client connection. Use requestHeader to specify the +// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). +// Use the response.Header to get the selected subprotocol +// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). +// +// If the WebSocket handshake fails, ErrBadHandshake is returned along with a +// non-nil *http.Response so that callers can handle redirects, authentication, +// etcetera. The response body may not contain the entire response and does not +// need to be closed by the application. +func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + + if d == nil { + d = &Dialer{ + Proxy: http.ProxyFromEnvironment, + } + } + + challengeKey, err := generateChallengeKey() + if err != nil { + return nil, nil, err + } + + u, err := parseURL(urlStr) + if err != nil { + return nil, nil, err + } + + switch u.Scheme { + case "ws": + u.Scheme = "http" + case "wss": + u.Scheme = "https" + default: + return nil, nil, errMalformedURL + } + + if u.User != nil { + // User name and password are not allowed in websocket URIs. + return nil, nil, errMalformedURL + } + + req := &http.Request{ + Method: "GET", + URL: u, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + Host: u.Host, + } + + // Set the cookies present in the cookie jar of the dialer + if d.Jar != nil { + for _, cookie := range d.Jar.Cookies(u) { + req.AddCookie(cookie) + } + } + + // Set the request headers using the capitalization for names and values in + // RFC examples. Although the capitalization shouldn't matter, there are + // servers that depend on it. The Header.Set method is not used because the + // method canonicalizes the header names. + req.Header["Upgrade"] = []string{"websocket"} + req.Header["Connection"] = []string{"Upgrade"} + req.Header["Sec-WebSocket-Key"] = []string{challengeKey} + req.Header["Sec-WebSocket-Version"] = []string{"13"} + if len(d.Subprotocols) > 0 { + req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} + } + for k, vs := range requestHeader { + switch { + case k == "Host": + if len(vs) > 0 { + req.Host = vs[0] + } + case k == "Upgrade" || + k == "Connection" || + k == "Sec-Websocket-Key" || + k == "Sec-Websocket-Version" || + k == "Sec-Websocket-Extensions" || + (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0): + return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) + default: + req.Header[k] = vs + } + } + + if d.EnableCompression { + req.Header.Set("Sec-Websocket-Extensions", "permessage-deflate; server_no_context_takeover; client_no_context_takeover") + } + + hostPort, hostNoPort := hostPortNoPort(u) + + var proxyURL *url.URL + // Check wether the proxy method has been configured + if d.Proxy != nil { + proxyURL, err = d.Proxy(req) + } + if err != nil { + return nil, nil, err + } + + var targetHostPort string + if proxyURL != nil { + targetHostPort, _ = hostPortNoPort(proxyURL) + } else { + targetHostPort = hostPort + } + + var deadline time.Time + if d.HandshakeTimeout != 0 { + deadline = time.Now().Add(d.HandshakeTimeout) + } + + netDial := d.NetDial + if netDial == nil { + netDialer := &net.Dialer{Deadline: deadline} + netDial = netDialer.Dial + } + + netConn, err := netDial("tcp", targetHostPort) + if err != nil { + return nil, nil, err + } + + defer func() { + if netConn != nil { + netConn.Close() + } + }() + + if err := netConn.SetDeadline(deadline); err != nil { + return nil, nil, err + } + + if proxyURL != nil { + connectHeader := make(http.Header) + if user := proxyURL.User; user != nil { + proxyUser := user.Username() + if proxyPassword, passwordSet := user.Password(); passwordSet { + credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) + connectHeader.Set("Proxy-Authorization", "Basic "+credential) + } + } + connectReq := &http.Request{ + Method: "CONNECT", + URL: &url.URL{Opaque: hostPort}, + Host: hostPort, + Header: connectHeader, + } + + connectReq.Write(netConn) + + // Read response. + // Okay to use and discard buffered reader here, because + // TLS server will not speak until spoken to. + br := bufio.NewReader(netConn) + resp, err := http.ReadResponse(br, connectReq) + if err != nil { + return nil, nil, err + } + if resp.StatusCode != 200 { + f := strings.SplitN(resp.Status, " ", 2) + return nil, nil, errors.New(f[1]) + } + } + + if u.Scheme == "https" { + cfg := cloneTLSConfig(d.TLSClientConfig) + if cfg.ServerName == "" { + cfg.ServerName = hostNoPort + } + tlsConn := tls.Client(netConn, cfg) + netConn = tlsConn + if err := tlsConn.Handshake(); err != nil { + return nil, nil, err + } + if !cfg.InsecureSkipVerify { + if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { + return nil, nil, err + } + } + } + + conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize) + + if err := req.Write(netConn); err != nil { + return nil, nil, err + } + + resp, err := http.ReadResponse(conn.br, req) + if err != nil { + return nil, nil, err + } + + if d.Jar != nil { + if rc := resp.Cookies(); len(rc) > 0 { + d.Jar.SetCookies(u, rc) + } + } + + if resp.StatusCode != 101 || + !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || + !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || + resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { + // Before closing the network connection on return from this + // function, slurp up some of the response to aid application + // debugging. + buf := make([]byte, 1024) + n, _ := io.ReadFull(resp.Body, buf) + resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) + return nil, resp, ErrBadHandshake + } + + for _, ext := range parseExtensions(resp.Header) { + if ext[""] != "permessage-deflate" { + continue + } + _, snct := ext["server_no_context_takeover"] + _, cnct := ext["client_no_context_takeover"] + if !snct || !cnct { + return nil, resp, errInvalidCompression + } + conn.newCompressionWriter = compressNoContextTakeover + conn.newDecompressionReader = decompressNoContextTakeover + break + } + + resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) + conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") + + netConn.SetDeadline(time.Time{}) + netConn = nil // to avoid close in defer. + return conn, resp, nil +} diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go new file mode 100644 index 000000000..4f0d94372 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone.go @@ -0,0 +1,16 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package websocket + +import "crypto/tls" + +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return cfg.Clone() +} diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go new file mode 100644 index 000000000..babb007fb --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone_legacy.go @@ -0,0 +1,38 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.8 + +package websocket + +import "crypto/tls" + +// cloneTLSConfig clones all public fields except the fields +// SessionTicketsDisabled and SessionTicketKey. This avoids copying the +// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a +// config in active use. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } +} diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go new file mode 100644 index 000000000..813ffb1e8 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/compression.go @@ -0,0 +1,148 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "compress/flate" + "errors" + "io" + "strings" + "sync" +) + +const ( + minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 + maxCompressionLevel = flate.BestCompression + defaultCompressionLevel = 1 +) + +var ( + flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool + flateReaderPool = sync.Pool{New: func() interface{} { + return flate.NewReader(nil) + }} +) + +func decompressNoContextTakeover(r io.Reader) io.ReadCloser { + const tail = + // Add four bytes as specified in RFC + "\x00\x00\xff\xff" + + // Add final block to squelch unexpected EOF error from flate reader. + "\x01\x00\x00\xff\xff" + + fr, _ := flateReaderPool.Get().(io.ReadCloser) + fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) + return &flateReadWrapper{fr} +} + +func isValidCompressionLevel(level int) bool { + return minCompressionLevel <= level && level <= maxCompressionLevel +} + +func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { + p := &flateWriterPools[level-minCompressionLevel] + tw := &truncWriter{w: w} + fw, _ := p.Get().(*flate.Writer) + if fw == nil { + fw, _ = flate.NewWriter(tw, level) + } else { + fw.Reset(tw) + } + return &flateWriteWrapper{fw: fw, tw: tw, p: p} +} + +// truncWriter is an io.Writer that writes all but the last four bytes of the +// stream to another io.Writer. +type truncWriter struct { + w io.WriteCloser + n int + p [4]byte +} + +func (w *truncWriter) Write(p []byte) (int, error) { + n := 0 + + // fill buffer first for simplicity. + if w.n < len(w.p) { + n = copy(w.p[w.n:], p) + p = p[n:] + w.n += n + if len(p) == 0 { + return n, nil + } + } + + m := len(p) + if m > len(w.p) { + m = len(w.p) + } + + if nn, err := w.w.Write(w.p[:m]); err != nil { + return n + nn, err + } + + copy(w.p[:], w.p[m:]) + copy(w.p[len(w.p)-m:], p[len(p)-m:]) + nn, err := w.w.Write(p[:len(p)-m]) + return n + nn, err +} + +type flateWriteWrapper struct { + fw *flate.Writer + tw *truncWriter + p *sync.Pool +} + +func (w *flateWriteWrapper) Write(p []byte) (int, error) { + if w.fw == nil { + return 0, errWriteClosed + } + return w.fw.Write(p) +} + +func (w *flateWriteWrapper) Close() error { + if w.fw == nil { + return errWriteClosed + } + err1 := w.fw.Flush() + w.p.Put(w.fw) + w.fw = nil + if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { + return errors.New("websocket: internal error, unexpected bytes at end of flate stream") + } + err2 := w.tw.w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +type flateReadWrapper struct { + fr io.ReadCloser +} + +func (r *flateReadWrapper) Read(p []byte) (int, error) { + if r.fr == nil { + return 0, io.ErrClosedPipe + } + n, err := r.fr.Read(p) + if err == io.EOF { + // Preemptively place the reader back in the pool. This helps with + // scenarios where the application does not call NextReader() soon after + // this final read. + r.Close() + } + return n, err +} + +func (r *flateReadWrapper) Close() error { + if r.fr == nil { + return io.ErrClosedPipe + } + err := r.fr.Close() + flateReaderPool.Put(r.fr) + r.fr = nil + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go new file mode 100644 index 000000000..97e1dbacb --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -0,0 +1,1149 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "encoding/binary" + "errors" + "io" + "io/ioutil" + "math/rand" + "net" + "strconv" + "sync" + "time" + "unicode/utf8" +) + +const ( + // Frame header byte 0 bits from Section 5.2 of RFC 6455 + finalBit = 1 << 7 + rsv1Bit = 1 << 6 + rsv2Bit = 1 << 5 + rsv3Bit = 1 << 4 + + // Frame header byte 1 bits from Section 5.2 of RFC 6455 + maskBit = 1 << 7 + + maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask + maxControlFramePayloadSize = 125 + + writeWait = time.Second + + defaultReadBufferSize = 4096 + defaultWriteBufferSize = 4096 + + continuationFrame = 0 + noFrame = -1 +) + +// Close codes defined in RFC 6455, section 11.7. +const ( + CloseNormalClosure = 1000 + CloseGoingAway = 1001 + CloseProtocolError = 1002 + CloseUnsupportedData = 1003 + CloseNoStatusReceived = 1005 + CloseAbnormalClosure = 1006 + CloseInvalidFramePayloadData = 1007 + ClosePolicyViolation = 1008 + CloseMessageTooBig = 1009 + CloseMandatoryExtension = 1010 + CloseInternalServerErr = 1011 + CloseServiceRestart = 1012 + CloseTryAgainLater = 1013 + CloseTLSHandshake = 1015 +) + +// The message types are defined in RFC 6455, section 11.8. +const ( + // TextMessage denotes a text data message. The text message payload is + // interpreted as UTF-8 encoded text data. + TextMessage = 1 + + // BinaryMessage denotes a binary data message. + BinaryMessage = 2 + + // CloseMessage denotes a close control message. The optional message + // payload contains a numeric code and text. Use the FormatCloseMessage + // function to format a close message payload. + CloseMessage = 8 + + // PingMessage denotes a ping control message. The optional message payload + // is UTF-8 encoded text. + PingMessage = 9 + + // PongMessage denotes a ping control message. The optional message payload + // is UTF-8 encoded text. + PongMessage = 10 +) + +// ErrCloseSent is returned when the application writes a message to the +// connection after sending a close message. +var ErrCloseSent = errors.New("websocket: close sent") + +// ErrReadLimit is returned when reading a message that is larger than the +// read limit set for the connection. +var ErrReadLimit = errors.New("websocket: read limit exceeded") + +// netError satisfies the net Error interface. +type netError struct { + msg string + temporary bool + timeout bool +} + +func (e *netError) Error() string { return e.msg } +func (e *netError) Temporary() bool { return e.temporary } +func (e *netError) Timeout() bool { return e.timeout } + +// CloseError represents close frame. +type CloseError struct { + + // Code is defined in RFC 6455, section 11.7. + Code int + + // Text is the optional text payload. + Text string +} + +func (e *CloseError) Error() string { + s := []byte("websocket: close ") + s = strconv.AppendInt(s, int64(e.Code), 10) + switch e.Code { + case CloseNormalClosure: + s = append(s, " (normal)"...) + case CloseGoingAway: + s = append(s, " (going away)"...) + case CloseProtocolError: + s = append(s, " (protocol error)"...) + case CloseUnsupportedData: + s = append(s, " (unsupported data)"...) + case CloseNoStatusReceived: + s = append(s, " (no status)"...) + case CloseAbnormalClosure: + s = append(s, " (abnormal closure)"...) + case CloseInvalidFramePayloadData: + s = append(s, " (invalid payload data)"...) + case ClosePolicyViolation: + s = append(s, " (policy violation)"...) + case CloseMessageTooBig: + s = append(s, " (message too big)"...) + case CloseMandatoryExtension: + s = append(s, " (mandatory extension missing)"...) + case CloseInternalServerErr: + s = append(s, " (internal server error)"...) + case CloseTLSHandshake: + s = append(s, " (TLS handshake error)"...) + } + if e.Text != "" { + s = append(s, ": "...) + s = append(s, e.Text...) + } + return string(s) +} + +// IsCloseError returns boolean indicating whether the error is a *CloseError +// with one of the specified codes. +func IsCloseError(err error, codes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range codes { + if e.Code == code { + return true + } + } + } + return false +} + +// IsUnexpectedCloseError returns boolean indicating whether the error is a +// *CloseError with a code not in the list of expected codes. +func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range expectedCodes { + if e.Code == code { + return false + } + } + return true + } + return false +} + +var ( + errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true} + errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()} + errBadWriteOpCode = errors.New("websocket: bad write message type") + errWriteClosed = errors.New("websocket: write closed") + errInvalidControlFrame = errors.New("websocket: invalid control frame") +) + +func newMaskKey() [4]byte { + n := rand.Uint32() + return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} +} + +func hideTempErr(err error) error { + if e, ok := err.(net.Error); ok && e.Temporary() { + err = &netError{msg: e.Error(), timeout: e.Timeout()} + } + return err +} + +func isControl(frameType int) bool { + return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage +} + +func isData(frameType int) bool { + return frameType == TextMessage || frameType == BinaryMessage +} + +var validReceivedCloseCodes = map[int]bool{ + // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number + + CloseNormalClosure: true, + CloseGoingAway: true, + CloseProtocolError: true, + CloseUnsupportedData: true, + CloseNoStatusReceived: false, + CloseAbnormalClosure: false, + CloseInvalidFramePayloadData: true, + ClosePolicyViolation: true, + CloseMessageTooBig: true, + CloseMandatoryExtension: true, + CloseInternalServerErr: true, + CloseServiceRestart: true, + CloseTryAgainLater: true, + CloseTLSHandshake: false, +} + +func isValidReceivedCloseCode(code int) bool { + return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999) +} + +// The Conn type represents a WebSocket connection. +type Conn struct { + conn net.Conn + isServer bool + subprotocol string + + // Write fields + mu chan bool // used as mutex to protect write to conn + writeBuf []byte // frame is constructed in this buffer. + writeDeadline time.Time + writer io.WriteCloser // the current writer returned to the application + isWriting bool // for best-effort concurrent write detection + + writeErrMu sync.Mutex + writeErr error + + enableWriteCompression bool + compressionLevel int + newCompressionWriter func(io.WriteCloser, int) io.WriteCloser + + // Read fields + reader io.ReadCloser // the current reader returned to the application + readErr error + br *bufio.Reader + readRemaining int64 // bytes remaining in current frame. + readFinal bool // true the current message has more frames. + readLength int64 // Message size. + readLimit int64 // Maximum message size. + readMaskPos int + readMaskKey [4]byte + handlePong func(string) error + handlePing func(string) error + handleClose func(int, string) error + readErrCount int + messageReader *messageReader // the current low-level reader + + readDecompress bool // whether last read frame had RSV1 set + newDecompressionReader func(io.Reader) io.ReadCloser +} + +func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn { + return newConnBRW(conn, isServer, readBufferSize, writeBufferSize, nil) +} + +type writeHook struct { + p []byte +} + +func (wh *writeHook) Write(p []byte) (int, error) { + wh.p = p + return len(p), nil +} + +func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, brw *bufio.ReadWriter) *Conn { + mu := make(chan bool, 1) + mu <- true + + var br *bufio.Reader + if readBufferSize == 0 && brw != nil && brw.Reader != nil { + // Reuse the supplied bufio.Reader if the buffer has a useful size. + // This code assumes that peek on a reader returns + // bufio.Reader.buf[:0]. + brw.Reader.Reset(conn) + if p, err := brw.Reader.Peek(0); err == nil && cap(p) >= 256 { + br = brw.Reader + } + } + if br == nil { + if readBufferSize == 0 { + readBufferSize = defaultReadBufferSize + } + if readBufferSize < maxControlFramePayloadSize { + readBufferSize = maxControlFramePayloadSize + } + br = bufio.NewReaderSize(conn, readBufferSize) + } + + var writeBuf []byte + if writeBufferSize == 0 && brw != nil && brw.Writer != nil { + // Use the bufio.Writer's buffer if the buffer has a useful size. This + // code assumes that bufio.Writer.buf[:1] is passed to the + // bufio.Writer's underlying writer. + var wh writeHook + brw.Writer.Reset(&wh) + brw.Writer.WriteByte(0) + brw.Flush() + if cap(wh.p) >= maxFrameHeaderSize+256 { + writeBuf = wh.p[:cap(wh.p)] + } + } + + if writeBuf == nil { + if writeBufferSize == 0 { + writeBufferSize = defaultWriteBufferSize + } + writeBuf = make([]byte, writeBufferSize+maxFrameHeaderSize) + } + + c := &Conn{ + isServer: isServer, + br: br, + conn: conn, + mu: mu, + readFinal: true, + writeBuf: writeBuf, + enableWriteCompression: true, + compressionLevel: defaultCompressionLevel, + } + c.SetCloseHandler(nil) + c.SetPingHandler(nil) + c.SetPongHandler(nil) + return c +} + +// Subprotocol returns the negotiated protocol for the connection. +func (c *Conn) Subprotocol() string { + return c.subprotocol +} + +// Close closes the underlying network connection without sending or waiting for a close frame. +func (c *Conn) Close() error { + return c.conn.Close() +} + +// LocalAddr returns the local network address. +func (c *Conn) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +// RemoteAddr returns the remote network address. +func (c *Conn) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +// Write methods + +func (c *Conn) writeFatal(err error) error { + err = hideTempErr(err) + c.writeErrMu.Lock() + if c.writeErr == nil { + c.writeErr = err + } + c.writeErrMu.Unlock() + return err +} + +func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error { + <-c.mu + defer func() { c.mu <- true }() + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + c.conn.SetWriteDeadline(deadline) + for _, buf := range bufs { + if len(buf) > 0 { + _, err := c.conn.Write(buf) + if err != nil { + return c.writeFatal(err) + } + } + } + + if frameType == CloseMessage { + c.writeFatal(ErrCloseSent) + } + return nil +} + +// WriteControl writes a control message with the given deadline. The allowed +// message types are CloseMessage, PingMessage and PongMessage. +func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { + if !isControl(messageType) { + return errBadWriteOpCode + } + if len(data) > maxControlFramePayloadSize { + return errInvalidControlFrame + } + + b0 := byte(messageType) | finalBit + b1 := byte(len(data)) + if !c.isServer { + b1 |= maskBit + } + + buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize) + buf = append(buf, b0, b1) + + if c.isServer { + buf = append(buf, data...) + } else { + key := newMaskKey() + buf = append(buf, key[:]...) + buf = append(buf, data...) + maskBytes(key, 0, buf[6:]) + } + + d := time.Hour * 1000 + if !deadline.IsZero() { + d = deadline.Sub(time.Now()) + if d < 0 { + return errWriteTimeout + } + } + + timer := time.NewTimer(d) + select { + case <-c.mu: + timer.Stop() + case <-timer.C: + return errWriteTimeout + } + defer func() { c.mu <- true }() + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + c.conn.SetWriteDeadline(deadline) + _, err = c.conn.Write(buf) + if err != nil { + return c.writeFatal(err) + } + if messageType == CloseMessage { + c.writeFatal(ErrCloseSent) + } + return err +} + +func (c *Conn) prepWrite(messageType int) error { + // Close previous writer if not already closed by the application. It's + // probably better to return an error in this situation, but we cannot + // change this without breaking existing applications. + if c.writer != nil { + c.writer.Close() + c.writer = nil + } + + if !isControl(messageType) && !isData(messageType) { + return errBadWriteOpCode + } + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + return err +} + +// NextWriter returns a writer for the next message to send. The writer's Close +// method flushes the complete message to the network. +// +// There can be at most one open writer on a connection. NextWriter closes the +// previous writer if the application has not already done so. +func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { + if err := c.prepWrite(messageType); err != nil { + return nil, err + } + + mw := &messageWriter{ + c: c, + frameType: messageType, + pos: maxFrameHeaderSize, + } + c.writer = mw + if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { + w := c.newCompressionWriter(c.writer, c.compressionLevel) + mw.compress = true + c.writer = w + } + return c.writer, nil +} + +type messageWriter struct { + c *Conn + compress bool // whether next call to flushFrame should set RSV1 + pos int // end of data in writeBuf. + frameType int // type of the current frame. + err error +} + +func (w *messageWriter) fatal(err error) error { + if w.err != nil { + w.err = err + w.c.writer = nil + } + return err +} + +// flushFrame writes buffered data and extra as a frame to the network. The +// final argument indicates that this is the last frame in the message. +func (w *messageWriter) flushFrame(final bool, extra []byte) error { + c := w.c + length := w.pos - maxFrameHeaderSize + len(extra) + + // Check for invalid control frames. + if isControl(w.frameType) && + (!final || length > maxControlFramePayloadSize) { + return w.fatal(errInvalidControlFrame) + } + + b0 := byte(w.frameType) + if final { + b0 |= finalBit + } + if w.compress { + b0 |= rsv1Bit + } + w.compress = false + + b1 := byte(0) + if !c.isServer { + b1 |= maskBit + } + + // Assume that the frame starts at beginning of c.writeBuf. + framePos := 0 + if c.isServer { + // Adjust up if mask not included in the header. + framePos = 4 + } + + switch { + case length >= 65536: + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | 127 + binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length)) + case length > 125: + framePos += 6 + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | 126 + binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length)) + default: + framePos += 8 + c.writeBuf[framePos] = b0 + c.writeBuf[framePos+1] = b1 | byte(length) + } + + if !c.isServer { + key := newMaskKey() + copy(c.writeBuf[maxFrameHeaderSize-4:], key[:]) + maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos]) + if len(extra) > 0 { + return c.writeFatal(errors.New("websocket: internal error, extra used in client mode")) + } + } + + // Write the buffers to the connection with best-effort detection of + // concurrent writes. See the concurrency section in the package + // documentation for more info. + + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + + err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra) + + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + + if err != nil { + return w.fatal(err) + } + + if final { + c.writer = nil + return nil + } + + // Setup for next frame. + w.pos = maxFrameHeaderSize + w.frameType = continuationFrame + return nil +} + +func (w *messageWriter) ncopy(max int) (int, error) { + n := len(w.c.writeBuf) - w.pos + if n <= 0 { + if err := w.flushFrame(false, nil); err != nil { + return 0, err + } + n = len(w.c.writeBuf) - w.pos + } + if n > max { + n = max + } + return n, nil +} + +func (w *messageWriter) Write(p []byte) (int, error) { + if w.err != nil { + return 0, w.err + } + + if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { + // Don't buffer large messages. + err := w.flushFrame(false, p) + if err != nil { + return 0, err + } + return len(p), nil + } + + nn := len(p) + for len(p) > 0 { + n, err := w.ncopy(len(p)) + if err != nil { + return 0, err + } + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n + p = p[n:] + } + return nn, nil +} + +func (w *messageWriter) WriteString(p string) (int, error) { + if w.err != nil { + return 0, w.err + } + + nn := len(p) + for len(p) > 0 { + n, err := w.ncopy(len(p)) + if err != nil { + return 0, err + } + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n + p = p[n:] + } + return nn, nil +} + +func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { + if w.err != nil { + return 0, w.err + } + for { + if w.pos == len(w.c.writeBuf) { + err = w.flushFrame(false, nil) + if err != nil { + break + } + } + var n int + n, err = r.Read(w.c.writeBuf[w.pos:]) + w.pos += n + nn += int64(n) + if err != nil { + if err == io.EOF { + err = nil + } + break + } + } + return nn, err +} + +func (w *messageWriter) Close() error { + if w.err != nil { + return w.err + } + if err := w.flushFrame(true, nil); err != nil { + return err + } + w.err = errWriteClosed + return nil +} + +// WritePreparedMessage writes prepared message into connection. +func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error { + frameType, frameData, err := pm.frame(prepareKey{ + isServer: c.isServer, + compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType), + compressionLevel: c.compressionLevel, + }) + if err != nil { + return err + } + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + err = c.write(frameType, c.writeDeadline, frameData, nil) + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + return err +} + +// WriteMessage is a helper method for getting a writer using NextWriter, +// writing the message and closing the writer. +func (c *Conn) WriteMessage(messageType int, data []byte) error { + + if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) { + // Fast path with no allocations and single frame. + + if err := c.prepWrite(messageType); err != nil { + return err + } + mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize} + n := copy(c.writeBuf[mw.pos:], data) + mw.pos += n + data = data[n:] + return mw.flushFrame(true, data) + } + + w, err := c.NextWriter(messageType) + if err != nil { + return err + } + if _, err = w.Write(data); err != nil { + return err + } + return w.Close() +} + +// SetWriteDeadline sets the write deadline on the underlying network +// connection. After a write has timed out, the websocket state is corrupt and +// all future writes will return an error. A zero value for t means writes will +// not time out. +func (c *Conn) SetWriteDeadline(t time.Time) error { + c.writeDeadline = t + return nil +} + +// Read methods + +func (c *Conn) advanceFrame() (int, error) { + + // 1. Skip remainder of previous frame. + + if c.readRemaining > 0 { + if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil { + return noFrame, err + } + } + + // 2. Read and parse first two bytes of frame header. + + p, err := c.read(2) + if err != nil { + return noFrame, err + } + + final := p[0]&finalBit != 0 + frameType := int(p[0] & 0xf) + mask := p[1]&maskBit != 0 + c.readRemaining = int64(p[1] & 0x7f) + + c.readDecompress = false + if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { + c.readDecompress = true + p[0] &^= rsv1Bit + } + + if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { + return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) + } + + switch frameType { + case CloseMessage, PingMessage, PongMessage: + if c.readRemaining > maxControlFramePayloadSize { + return noFrame, c.handleProtocolError("control frame length > 125") + } + if !final { + return noFrame, c.handleProtocolError("control frame not final") + } + case TextMessage, BinaryMessage: + if !c.readFinal { + return noFrame, c.handleProtocolError("message start before final message frame") + } + c.readFinal = final + case continuationFrame: + if c.readFinal { + return noFrame, c.handleProtocolError("continuation after final message frame") + } + c.readFinal = final + default: + return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType)) + } + + // 3. Read and parse frame length. + + switch c.readRemaining { + case 126: + p, err := c.read(2) + if err != nil { + return noFrame, err + } + c.readRemaining = int64(binary.BigEndian.Uint16(p)) + case 127: + p, err := c.read(8) + if err != nil { + return noFrame, err + } + c.readRemaining = int64(binary.BigEndian.Uint64(p)) + } + + // 4. Handle frame masking. + + if mask != c.isServer { + return noFrame, c.handleProtocolError("incorrect mask flag") + } + + if mask { + c.readMaskPos = 0 + p, err := c.read(len(c.readMaskKey)) + if err != nil { + return noFrame, err + } + copy(c.readMaskKey[:], p) + } + + // 5. For text and binary messages, enforce read limit and return. + + if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage { + + c.readLength += c.readRemaining + if c.readLimit > 0 && c.readLength > c.readLimit { + c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) + return noFrame, ErrReadLimit + } + + return frameType, nil + } + + // 6. Read control frame payload. + + var payload []byte + if c.readRemaining > 0 { + payload, err = c.read(int(c.readRemaining)) + c.readRemaining = 0 + if err != nil { + return noFrame, err + } + if c.isServer { + maskBytes(c.readMaskKey, 0, payload) + } + } + + // 7. Process control frame payload. + + switch frameType { + case PongMessage: + if err := c.handlePong(string(payload)); err != nil { + return noFrame, err + } + case PingMessage: + if err := c.handlePing(string(payload)); err != nil { + return noFrame, err + } + case CloseMessage: + closeCode := CloseNoStatusReceived + closeText := "" + if len(payload) >= 2 { + closeCode = int(binary.BigEndian.Uint16(payload)) + if !isValidReceivedCloseCode(closeCode) { + return noFrame, c.handleProtocolError("invalid close code") + } + closeText = string(payload[2:]) + if !utf8.ValidString(closeText) { + return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") + } + } + if err := c.handleClose(closeCode, closeText); err != nil { + return noFrame, err + } + return noFrame, &CloseError{Code: closeCode, Text: closeText} + } + + return frameType, nil +} + +func (c *Conn) handleProtocolError(message string) error { + c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait)) + return errors.New("websocket: " + message) +} + +// NextReader returns the next data message received from the peer. The +// returned messageType is either TextMessage or BinaryMessage. +// +// There can be at most one open reader on a connection. NextReader discards +// the previous message if the application has not already consumed it. +// +// Applications must break out of the application's read loop when this method +// returns a non-nil error value. Errors returned from this method are +// permanent. Once this method returns a non-nil error, all subsequent calls to +// this method return the same error. +func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { + // Close previous reader, only relevant for decompression. + if c.reader != nil { + c.reader.Close() + c.reader = nil + } + + c.messageReader = nil + c.readLength = 0 + + for c.readErr == nil { + frameType, err := c.advanceFrame() + if err != nil { + c.readErr = hideTempErr(err) + break + } + if frameType == TextMessage || frameType == BinaryMessage { + c.messageReader = &messageReader{c} + c.reader = c.messageReader + if c.readDecompress { + c.reader = c.newDecompressionReader(c.reader) + } + return frameType, c.reader, nil + } + } + + // Applications that do handle the error returned from this method spin in + // tight loop on connection failure. To help application developers detect + // this error, panic on repeated reads to the failed connection. + c.readErrCount++ + if c.readErrCount >= 1000 { + panic("repeated read on failed websocket connection") + } + + return noFrame, nil, c.readErr +} + +type messageReader struct{ c *Conn } + +func (r *messageReader) Read(b []byte) (int, error) { + c := r.c + if c.messageReader != r { + return 0, io.EOF + } + + for c.readErr == nil { + + if c.readRemaining > 0 { + if int64(len(b)) > c.readRemaining { + b = b[:c.readRemaining] + } + n, err := c.br.Read(b) + c.readErr = hideTempErr(err) + if c.isServer { + c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) + } + c.readRemaining -= int64(n) + if c.readRemaining > 0 && c.readErr == io.EOF { + c.readErr = errUnexpectedEOF + } + return n, c.readErr + } + + if c.readFinal { + c.messageReader = nil + return 0, io.EOF + } + + frameType, err := c.advanceFrame() + switch { + case err != nil: + c.readErr = hideTempErr(err) + case frameType == TextMessage || frameType == BinaryMessage: + c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") + } + } + + err := c.readErr + if err == io.EOF && c.messageReader == r { + err = errUnexpectedEOF + } + return 0, err +} + +func (r *messageReader) Close() error { + return nil +} + +// ReadMessage is a helper method for getting a reader using NextReader and +// reading from that reader to a buffer. +func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { + var r io.Reader + messageType, r, err = c.NextReader() + if err != nil { + return messageType, nil, err + } + p, err = ioutil.ReadAll(r) + return messageType, p, err +} + +// SetReadDeadline sets the read deadline on the underlying network connection. +// After a read has timed out, the websocket connection state is corrupt and +// all future reads will return an error. A zero value for t means reads will +// not time out. +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.conn.SetReadDeadline(t) +} + +// SetReadLimit sets the maximum size for a message read from the peer. If a +// message exceeds the limit, the connection sends a close frame to the peer +// and returns ErrReadLimit to the application. +func (c *Conn) SetReadLimit(limit int64) { + c.readLimit = limit +} + +// CloseHandler returns the current close handler +func (c *Conn) CloseHandler() func(code int, text string) error { + return c.handleClose +} + +// SetCloseHandler sets the handler for close messages received from the peer. +// The code argument to h is the received close code or CloseNoStatusReceived +// if the close message is empty. The default close handler sends a close frame +// back to the peer. +// +// The application must read the connection to process close messages as +// described in the section on Control Frames above. +// +// The connection read methods return a CloseError when a close frame is +// received. Most applications should handle close messages as part of their +// normal error handling. Applications should only set a close handler when the +// application must perform some action before sending a close frame back to +// the peer. +func (c *Conn) SetCloseHandler(h func(code int, text string) error) { + if h == nil { + h = func(code int, text string) error { + message := []byte{} + if code != CloseNoStatusReceived { + message = FormatCloseMessage(code, "") + } + c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) + return nil + } + } + c.handleClose = h +} + +// PingHandler returns the current ping handler +func (c *Conn) PingHandler() func(appData string) error { + return c.handlePing +} + +// SetPingHandler sets the handler for ping messages received from the peer. +// The appData argument to h is the PING frame application data. The default +// ping handler sends a pong to the peer. +// +// The application must read the connection to process ping messages as +// described in the section on Control Frames above. +func (c *Conn) SetPingHandler(h func(appData string) error) { + if h == nil { + h = func(message string) error { + err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) + if err == ErrCloseSent { + return nil + } else if e, ok := err.(net.Error); ok && e.Temporary() { + return nil + } + return err + } + } + c.handlePing = h +} + +// PongHandler returns the current pong handler +func (c *Conn) PongHandler() func(appData string) error { + return c.handlePong +} + +// SetPongHandler sets the handler for pong messages received from the peer. +// The appData argument to h is the PONG frame application data. The default +// pong handler does nothing. +// +// The application must read the connection to process ping messages as +// described in the section on Control Frames above. +func (c *Conn) SetPongHandler(h func(appData string) error) { + if h == nil { + h = func(string) error { return nil } + } + c.handlePong = h +} + +// UnderlyingConn returns the internal net.Conn. This can be used to further +// modifications to connection specific flags. +func (c *Conn) UnderlyingConn() net.Conn { + return c.conn +} + +// EnableWriteCompression enables and disables write compression of +// subsequent text and binary messages. This function is a noop if +// compression was not negotiated with the peer. +func (c *Conn) EnableWriteCompression(enable bool) { + c.enableWriteCompression = enable +} + +// SetCompressionLevel sets the flate compression level for subsequent text and +// binary messages. This function is a noop if compression was not negotiated +// with the peer. See the compress/flate package for a description of +// compression levels. +func (c *Conn) SetCompressionLevel(level int) error { + if !isValidCompressionLevel(level) { + return errors.New("websocket: invalid compression level") + } + c.compressionLevel = level + return nil +} + +// FormatCloseMessage formats closeCode and text as a WebSocket close message. +func FormatCloseMessage(closeCode int, text string) []byte { + buf := make([]byte, 2+len(text)) + binary.BigEndian.PutUint16(buf, uint16(closeCode)) + copy(buf[2:], text) + return buf +} diff --git a/vendor/github.com/gorilla/websocket/conn_read.go b/vendor/github.com/gorilla/websocket/conn_read.go new file mode 100644 index 000000000..1ea15059e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_read.go @@ -0,0 +1,18 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.5 + +package websocket + +import "io" + +func (c *Conn) read(n int) ([]byte, error) { + p, err := c.br.Peek(n) + if err == io.EOF { + err = errUnexpectedEOF + } + c.br.Discard(len(p)) + return p, err +} diff --git a/vendor/github.com/gorilla/websocket/conn_read_legacy.go b/vendor/github.com/gorilla/websocket/conn_read_legacy.go new file mode 100644 index 000000000..018541cf6 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_read_legacy.go @@ -0,0 +1,21 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.5 + +package websocket + +import "io" + +func (c *Conn) read(n int) ([]byte, error) { + p, err := c.br.Peek(n) + if err == io.EOF { + err = errUnexpectedEOF + } + if len(p) > 0 { + // advance over the bytes just read + io.ReadFull(c.br, p) + } + return p, err +} diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go new file mode 100644 index 000000000..e291a952c --- /dev/null +++ b/vendor/github.com/gorilla/websocket/doc.go @@ -0,0 +1,180 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package websocket implements the WebSocket protocol defined in RFC 6455. +// +// Overview +// +// The Conn type represents a WebSocket connection. A server application uses +// the Upgrade function from an Upgrader object with a HTTP request handler +// to get a pointer to a Conn: +// +// var upgrader = websocket.Upgrader{ +// ReadBufferSize: 1024, +// WriteBufferSize: 1024, +// } +// +// func handler(w http.ResponseWriter, r *http.Request) { +// conn, err := upgrader.Upgrade(w, r, nil) +// if err != nil { +// log.Println(err) +// return +// } +// ... Use conn to send and receive messages. +// } +// +// Call the connection's WriteMessage and ReadMessage methods to send and +// receive messages as a slice of bytes. This snippet of code shows how to echo +// messages using these methods: +// +// for { +// messageType, p, err := conn.ReadMessage() +// if err != nil { +// return +// } +// if err = conn.WriteMessage(messageType, p); err != nil { +// return err +// } +// } +// +// In above snippet of code, p is a []byte and messageType is an int with value +// websocket.BinaryMessage or websocket.TextMessage. +// +// An application can also send and receive messages using the io.WriteCloser +// and io.Reader interfaces. To send a message, call the connection NextWriter +// method to get an io.WriteCloser, write the message to the writer and close +// the writer when done. To receive a message, call the connection NextReader +// method to get an io.Reader and read until io.EOF is returned. This snippet +// shows how to echo messages using the NextWriter and NextReader methods: +// +// for { +// messageType, r, err := conn.NextReader() +// if err != nil { +// return +// } +// w, err := conn.NextWriter(messageType) +// if err != nil { +// return err +// } +// if _, err := io.Copy(w, r); err != nil { +// return err +// } +// if err := w.Close(); err != nil { +// return err +// } +// } +// +// Data Messages +// +// The WebSocket protocol distinguishes between text and binary data messages. +// Text messages are interpreted as UTF-8 encoded text. The interpretation of +// binary messages is left to the application. +// +// This package uses the TextMessage and BinaryMessage integer constants to +// identify the two data message types. The ReadMessage and NextReader methods +// return the type of the received message. The messageType argument to the +// WriteMessage and NextWriter methods specifies the type of a sent message. +// +// It is the application's responsibility to ensure that text messages are +// valid UTF-8 encoded text. +// +// Control Messages +// +// The WebSocket protocol defines three types of control messages: close, ping +// and pong. Call the connection WriteControl, WriteMessage or NextWriter +// methods to send a control message to the peer. +// +// Connections handle received close messages by sending a close message to the +// peer and returning a *CloseError from the the NextReader, ReadMessage or the +// message Read method. +// +// Connections handle received ping and pong messages by invoking callback +// functions set with SetPingHandler and SetPongHandler methods. The callback +// functions are called from the NextReader, ReadMessage and the message Read +// methods. +// +// The default ping handler sends a pong to the peer. The application's reading +// goroutine can block for a short time while the handler writes the pong data +// to the connection. +// +// The application must read the connection to process ping, pong and close +// messages sent from the peer. If the application is not otherwise interested +// in messages from the peer, then the application should start a goroutine to +// read and discard messages from the peer. A simple example is: +// +// func readLoop(c *websocket.Conn) { +// for { +// if _, _, err := c.NextReader(); err != nil { +// c.Close() +// break +// } +// } +// } +// +// Concurrency +// +// Connections support one concurrent reader and one concurrent writer. +// +// Applications are responsible for ensuring that no more than one goroutine +// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, +// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and +// that no more than one goroutine calls the read methods (NextReader, +// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) +// concurrently. +// +// The Close and WriteControl methods can be called concurrently with all other +// methods. +// +// Origin Considerations +// +// Web browsers allow Javascript applications to open a WebSocket connection to +// any host. It's up to the server to enforce an origin policy using the Origin +// request header sent by the browser. +// +// The Upgrader calls the function specified in the CheckOrigin field to check +// the origin. If the CheckOrigin function returns false, then the Upgrade +// method fails the WebSocket handshake with HTTP status 403. +// +// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail +// the handshake if the Origin request header is present and not equal to the +// Host request header. +// +// An application can allow connections from any origin by specifying a +// function that always returns true: +// +// var upgrader = websocket.Upgrader{ +// CheckOrigin: func(r *http.Request) bool { return true }, +// } +// +// The deprecated Upgrade function does not enforce an origin policy. It's the +// application's responsibility to check the Origin header before calling +// Upgrade. +// +// Compression EXPERIMENTAL +// +// Per message compression extensions (RFC 7692) are experimentally supported +// by this package in a limited capacity. Setting the EnableCompression option +// to true in Dialer or Upgrader will attempt to negotiate per message deflate +// support. +// +// var upgrader = websocket.Upgrader{ +// EnableCompression: true, +// } +// +// If compression was successfully negotiated with the connection's peer, any +// message received in compressed form will be automatically decompressed. +// All Read methods will return uncompressed bytes. +// +// Per message compression of messages written to a connection can be enabled +// or disabled by calling the corresponding Conn method: +// +// conn.EnableWriteCompression(false) +// +// Currently this package does not support compression with "context takeover". +// This means that messages must be compressed and decompressed in isolation, +// without retaining sliding window or dictionary state across messages. For +// more details refer to RFC 7692. +// +// Use of compression is experimental and may result in decreased performance. +package websocket diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go new file mode 100644 index 000000000..4f0e36875 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/json.go @@ -0,0 +1,55 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "encoding/json" + "io" +) + +// WriteJSON is deprecated, use c.WriteJSON instead. +func WriteJSON(c *Conn, v interface{}) error { + return c.WriteJSON(v) +} + +// WriteJSON writes the JSON encoding of v to the connection. +// +// See the documentation for encoding/json Marshal for details about the +// conversion of Go values to JSON. +func (c *Conn) WriteJSON(v interface{}) error { + w, err := c.NextWriter(TextMessage) + if err != nil { + return err + } + err1 := json.NewEncoder(w).Encode(v) + err2 := w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +// ReadJSON is deprecated, use c.ReadJSON instead. +func ReadJSON(c *Conn, v interface{}) error { + return c.ReadJSON(v) +} + +// ReadJSON reads the next JSON-encoded message from the connection and stores +// it in the value pointed to by v. +// +// See the documentation for the encoding/json Unmarshal function for details +// about the conversion of JSON to a Go value. +func (c *Conn) ReadJSON(v interface{}) error { + _, r, err := c.NextReader() + if err != nil { + return err + } + err = json.NewDecoder(r).Decode(v) + if err == io.EOF { + // One value is expected in the message. + err = io.ErrUnexpectedEOF + } + return err +} diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go new file mode 100644 index 000000000..6a88bbc74 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask.go @@ -0,0 +1,55 @@ +// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of +// this source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +// +build !appengine + +package websocket + +import "unsafe" + +const wordSize = int(unsafe.Sizeof(uintptr(0))) + +func maskBytes(key [4]byte, pos int, b []byte) int { + + // Mask one byte at a time for small buffers. + if len(b) < 2*wordSize { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 + } + + // Mask one byte at a time to word boundary. + if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { + n = wordSize - n + for i := range b[:n] { + b[i] ^= key[pos&3] + pos++ + } + b = b[n:] + } + + // Create aligned word size key. + var k [wordSize]byte + for i := range k { + k[i] = key[(pos+i)&3] + } + kw := *(*uintptr)(unsafe.Pointer(&k)) + + // Mask one word at a time. + n := (len(b) / wordSize) * wordSize + for i := 0; i < n; i += wordSize { + *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw + } + + // Mask one byte at a time for remaining bytes. + b = b[n:] + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go new file mode 100644 index 000000000..1efffbd1e --- /dev/null +++ b/vendor/github.com/gorilla/websocket/prepared.go @@ -0,0 +1,103 @@ +// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bytes" + "net" + "sync" + "time" +) + +// PreparedMessage caches on the wire representations of a message payload. +// Use PreparedMessage to efficiently send a message payload to multiple +// connections. PreparedMessage is especially useful when compression is used +// because the CPU and memory expensive compression operation can be executed +// once for a given set of compression options. +type PreparedMessage struct { + messageType int + data []byte + err error + mu sync.Mutex + frames map[prepareKey]*preparedFrame +} + +// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. +type prepareKey struct { + isServer bool + compress bool + compressionLevel int +} + +// preparedFrame contains data in wire representation. +type preparedFrame struct { + once sync.Once + data []byte +} + +// NewPreparedMessage returns an initialized PreparedMessage. You can then send +// it to connection using WritePreparedMessage method. Valid wire +// representation will be calculated lazily only once for a set of current +// connection options. +func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { + pm := &PreparedMessage{ + messageType: messageType, + frames: make(map[prepareKey]*preparedFrame), + data: data, + } + + // Prepare a plain server frame. + _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) + if err != nil { + return nil, err + } + + // To protect against caller modifying the data argument, remember the data + // copied to the plain server frame. + pm.data = frameData[len(frameData)-len(data):] + return pm, nil +} + +func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { + pm.mu.Lock() + frame, ok := pm.frames[key] + if !ok { + frame = &preparedFrame{} + pm.frames[key] = frame + } + pm.mu.Unlock() + + var err error + frame.once.Do(func() { + // Prepare a frame using a 'fake' connection. + // TODO: Refactor code in conn.go to allow more direct construction of + // the frame. + mu := make(chan bool, 1) + mu <- true + var nc prepareConn + c := &Conn{ + conn: &nc, + mu: mu, + isServer: key.isServer, + compressionLevel: key.compressionLevel, + enableWriteCompression: true, + writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), + } + if key.compress { + c.newCompressionWriter = compressNoContextTakeover + } + err = c.WriteMessage(pm.messageType, pm.data) + frame.data = nc.buf.Bytes() + }) + return pm.messageType, frame.data, err +} + +type prepareConn struct { + buf bytes.Buffer + net.Conn +} + +func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } +func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go new file mode 100644 index 000000000..3495e0f1a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/server.go @@ -0,0 +1,291 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "bufio" + "errors" + "net" + "net/http" + "net/url" + "strings" + "time" +) + +// HandshakeError describes an error with the handshake from the peer. +type HandshakeError struct { + message string +} + +func (e HandshakeError) Error() string { return e.message } + +// Upgrader specifies parameters for upgrading an HTTP connection to a +// WebSocket connection. +type Upgrader struct { + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer + // size is zero, then buffers allocated by the HTTP server are used. The + // I/O buffer sizes do not limit the size of the messages that can be sent + // or received. + ReadBufferSize, WriteBufferSize int + + // Subprotocols specifies the server's supported protocols in order of + // preference. If this field is set, then the Upgrade method negotiates a + // subprotocol by selecting the first match in this list with a protocol + // requested by the client. + Subprotocols []string + + // Error specifies the function for generating HTTP error responses. If Error + // is nil, then http.Error is used to generate the HTTP response. + Error func(w http.ResponseWriter, r *http.Request, status int, reason error) + + // CheckOrigin returns true if the request Origin header is acceptable. If + // CheckOrigin is nil, the host in the Origin header must not be set or + // must match the host of the request. + CheckOrigin func(r *http.Request) bool + + // EnableCompression specify if the server should attempt to negotiate per + // message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool +} + +func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) { + err := HandshakeError{reason} + if u.Error != nil { + u.Error(w, r, status, err) + } else { + w.Header().Set("Sec-Websocket-Version", "13") + http.Error(w, http.StatusText(status), status) + } + return nil, err +} + +// checkSameOrigin returns true if the origin is not set or is equal to the request host. +func checkSameOrigin(r *http.Request) bool { + origin := r.Header["Origin"] + if len(origin) == 0 { + return true + } + u, err := url.Parse(origin[0]) + if err != nil { + return false + } + return u.Host == r.Host +} + +func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { + if u.Subprotocols != nil { + clientProtocols := Subprotocols(r) + for _, serverProtocol := range u.Subprotocols { + for _, clientProtocol := range clientProtocols { + if clientProtocol == serverProtocol { + return clientProtocol + } + } + } + } else if responseHeader != nil { + return responseHeader.Get("Sec-Websocket-Protocol") + } + return "" +} + +// Upgrade upgrades the HTTP server connection to the WebSocket protocol. +// +// The responseHeader is included in the response to the client's upgrade +// request. Use the responseHeader to specify cookies (Set-Cookie) and the +// application negotiated subprotocol (Sec-Websocket-Protocol). +// +// If the upgrade fails, then Upgrade replies to the client with an HTTP error +// response. +func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { + if r.Method != "GET" { + return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: not a websocket handshake: request method is not GET") + } + + if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-Websocket-Extensions' headers are unsupported") + } + + if !tokenListContainsValue(r.Header, "Connection", "upgrade") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'upgrade' token not found in 'Connection' header") + } + + if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'websocket' token not found in 'Upgrade' header") + } + + if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") + } + + checkOrigin := u.CheckOrigin + if checkOrigin == nil { + checkOrigin = checkSameOrigin + } + if !checkOrigin(r) { + return u.returnError(w, r, http.StatusForbidden, "websocket: 'Origin' header value not allowed") + } + + challengeKey := r.Header.Get("Sec-Websocket-Key") + if challengeKey == "" { + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-Websocket-Key' header is missing or blank") + } + + subprotocol := u.selectSubprotocol(r, responseHeader) + + // Negotiate PMCE + var compress bool + if u.EnableCompression { + for _, ext := range parseExtensions(r.Header) { + if ext[""] != "permessage-deflate" { + continue + } + compress = true + break + } + } + + var ( + netConn net.Conn + err error + ) + + h, ok := w.(http.Hijacker) + if !ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") + } + var brw *bufio.ReadWriter + netConn, brw, err = h.Hijack() + if err != nil { + return u.returnError(w, r, http.StatusInternalServerError, err.Error()) + } + + if brw.Reader.Buffered() > 0 { + netConn.Close() + return nil, errors.New("websocket: client sent data before handshake is complete") + } + + c := newConnBRW(netConn, true, u.ReadBufferSize, u.WriteBufferSize, brw) + c.subprotocol = subprotocol + + if compress { + c.newCompressionWriter = compressNoContextTakeover + c.newDecompressionReader = decompressNoContextTakeover + } + + p := c.writeBuf[:0] + p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...) + p = append(p, computeAcceptKey(challengeKey)...) + p = append(p, "\r\n"...) + if c.subprotocol != "" { + p = append(p, "Sec-Websocket-Protocol: "...) + p = append(p, c.subprotocol...) + p = append(p, "\r\n"...) + } + if compress { + p = append(p, "Sec-Websocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...) + } + for k, vs := range responseHeader { + if k == "Sec-Websocket-Protocol" { + continue + } + for _, v := range vs { + p = append(p, k...) + p = append(p, ": "...) + for i := 0; i < len(v); i++ { + b := v[i] + if b <= 31 { + // prevent response splitting. + b = ' ' + } + p = append(p, b) + } + p = append(p, "\r\n"...) + } + } + p = append(p, "\r\n"...) + + // Clear deadlines set by HTTP server. + netConn.SetDeadline(time.Time{}) + + if u.HandshakeTimeout > 0 { + netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)) + } + if _, err = netConn.Write(p); err != nil { + netConn.Close() + return nil, err + } + if u.HandshakeTimeout > 0 { + netConn.SetWriteDeadline(time.Time{}) + } + + return c, nil +} + +// Upgrade upgrades the HTTP server connection to the WebSocket protocol. +// +// This function is deprecated, use websocket.Upgrader instead. +// +// The application is responsible for checking the request origin before +// calling Upgrade. An example implementation of the same origin policy is: +// +// if req.Header.Get("Origin") != "http://"+req.Host { +// http.Error(w, "Origin not allowed", 403) +// return +// } +// +// If the endpoint supports subprotocols, then the application is responsible +// for negotiating the protocol used on the connection. Use the Subprotocols() +// function to get the subprotocols requested by the client. Use the +// Sec-Websocket-Protocol response header to specify the subprotocol selected +// by the application. +// +// The responseHeader is included in the response to the client's upgrade +// request. Use the responseHeader to specify cookies (Set-Cookie) and the +// negotiated subprotocol (Sec-Websocket-Protocol). +// +// The connection buffers IO to the underlying network connection. The +// readBufSize and writeBufSize parameters specify the size of the buffers to +// use. Messages can be larger than the buffers. +// +// If the request is not a valid WebSocket handshake, then Upgrade returns an +// error of type HandshakeError. Applications should handle this error by +// replying to the client with an HTTP error response. +func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) { + u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize} + u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) { + // don't return errors to maintain backwards compatibility + } + u.CheckOrigin = func(r *http.Request) bool { + // allow all connections by default + return true + } + return u.Upgrade(w, r, responseHeader) +} + +// Subprotocols returns the subprotocols requested by the client in the +// Sec-Websocket-Protocol header. +func Subprotocols(r *http.Request) []string { + h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol")) + if h == "" { + return nil + } + protocols := strings.Split(h, ",") + for i := range protocols { + protocols[i] = strings.TrimSpace(protocols[i]) + } + return protocols +} + +// IsWebSocketUpgrade returns true if the client requested upgrade to the +// WebSocket protocol. +func IsWebSocketUpgrade(r *http.Request) bool { + return tokenListContainsValue(r.Header, "Connection", "upgrade") && + tokenListContainsValue(r.Header, "Upgrade", "websocket") +} diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go new file mode 100644 index 000000000..9a4908df2 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/util.go @@ -0,0 +1,214 @@ +// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package websocket + +import ( + "crypto/rand" + "crypto/sha1" + "encoding/base64" + "io" + "net/http" + "strings" +) + +var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") + +func computeAcceptKey(challengeKey string) string { + h := sha1.New() + h.Write([]byte(challengeKey)) + h.Write(keyGUID) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func generateChallengeKey() (string, error) { + p := make([]byte, 16) + if _, err := io.ReadFull(rand.Reader, p); err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(p), nil +} + +// Octet types from RFC 2616. +var octetTypes [256]byte + +const ( + isTokenOctet = 1 << iota + isSpaceOctet +) + +func init() { + // From RFC 2616 + // + // OCTET = <any 8-bit sequence of data> + // CHAR = <any US-ASCII character (octets 0 - 127)> + // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> + // CR = <US-ASCII CR, carriage return (13)> + // LF = <US-ASCII LF, linefeed (10)> + // SP = <US-ASCII SP, space (32)> + // HT = <US-ASCII HT, horizontal-tab (9)> + // <"> = <US-ASCII double-quote mark (34)> + // CRLF = CR LF + // LWS = [CRLF] 1*( SP | HT ) + // TEXT = <any OCTET except CTLs, but including LWS> + // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> + // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT + // token = 1*<any CHAR except CTLs or separators> + // qdtext = <any TEXT except <">> + + for c := 0; c < 256; c++ { + var t byte + isCtl := c <= 31 || c == 127 + isChar := 0 <= c && c <= 127 + isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0 + if strings.IndexRune(" \t\r\n", rune(c)) >= 0 { + t |= isSpaceOctet + } + if isChar && !isCtl && !isSeparator { + t |= isTokenOctet + } + octetTypes[c] = t + } +} + +func skipSpace(s string) (rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isSpaceOctet == 0 { + break + } + } + return s[i:] +} + +func nextToken(s string) (token, rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isTokenOctet == 0 { + break + } + } + return s[:i], s[i:] +} + +func nextTokenOrQuoted(s string) (value string, rest string) { + if !strings.HasPrefix(s, "\"") { + return nextToken(s) + } + s = s[1:] + for i := 0; i < len(s); i++ { + switch s[i] { + case '"': + return s[:i], s[i+1:] + case '\\': + p := make([]byte, len(s)-1) + j := copy(p, s[:i]) + escape := true + for i = i + 1; i < len(s); i++ { + b := s[i] + switch { + case escape: + escape = false + p[j] = b + j += 1 + case b == '\\': + escape = true + case b == '"': + return string(p[:j]), s[i+1:] + default: + p[j] = b + j += 1 + } + } + return "", "" + } + } + return "", "" +} + +// tokenListContainsValue returns true if the 1#token header with the given +// name contains token. +func tokenListContainsValue(header http.Header, name string, value string) bool { +headers: + for _, s := range header[name] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + s = skipSpace(s) + if s != "" && s[0] != ',' { + continue headers + } + if strings.EqualFold(t, value) { + return true + } + if s == "" { + continue headers + } + s = s[1:] + } + } + return false +} + +// parseExtensiosn parses WebSocket extensions from a header. +func parseExtensions(header http.Header) []map[string]string { + + // From RFC 6455: + // + // Sec-WebSocket-Extensions = extension-list + // extension-list = 1#extension + // extension = extension-token *( ";" extension-param ) + // extension-token = registered-token + // registered-token = token + // extension-param = token [ "=" (token | quoted-string) ] + // ;When using the quoted-string syntax variant, the value + // ;after quoted-string unescaping MUST conform to the + // ;'token' ABNF. + + var result []map[string]string +headers: + for _, s := range header["Sec-Websocket-Extensions"] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + ext := map[string]string{"": t} + for { + s = skipSpace(s) + if !strings.HasPrefix(s, ";") { + break + } + var k string + k, s = nextToken(skipSpace(s[1:])) + if k == "" { + continue headers + } + s = skipSpace(s) + var v string + if strings.HasPrefix(s, "=") { + v, s = nextTokenOrQuoted(skipSpace(s[1:])) + s = skipSpace(s) + } + if s != "" && s[0] != ',' && s[0] != ';' { + continue headers + } + ext[k] = v + } + if s != "" && s[0] != ',' { + continue headers + } + result = append(result, ext) + if s == "" { + continue headers + } + s = s[1:] + } + } + return result +} diff --git a/vendor/github.com/moul/anonuuid/LICENSE b/vendor/github.com/moul/anonuuid/LICENSE new file mode 100644 index 000000000..492e2c629 --- /dev/null +++ b/vendor/github.com/moul/anonuuid/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Manfred Touron + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/moul/anonuuid/Makefile b/vendor/github.com/moul/anonuuid/Makefile new file mode 100644 index 000000000..4e2f3bb44 --- /dev/null +++ b/vendor/github.com/moul/anonuuid/Makefile @@ -0,0 +1,73 @@ +# Project-specific variables +BINARIES ?= anonuuid +CONVEY_PORT ?= 9042 + + +# Common variables +SOURCES := $(shell find . -name "*.go") +COMMANDS := $(shell go list ./... | grep -v /vendor/ | grep /cmd/) +PACKAGES := $(shell go list ./... | grep -v /vendor/ | grep -v /cmd/) +GOENV ?= GO15VENDOREXPERIMENT=1 +GO ?= $(GOENV) go +GODEP ?= $(GOENV) godep +USER ?= $(shell whoami) + + +all: build + + +.PHONY: build +build: $(BINARIES) + + +$(BINARIES): $(SOURCES) + $(GO) build -o $@ ./cmd/$@ + + +.PHONY: test +test: + $(GO) get -t . + $(GO) test -v . + + +.PHONY: godep-save +godep-save: + $(GODEP) save $(PACKAGES) $(COMMANDS) + + +.PHONY: clean +clean: + rm -f $(BINARIES) + + +.PHONY: re +re: clean all + + +.PHONY: convey +convey: + $(GO) get github.com/smartystreets/goconvey + goconvey -cover -port=$(CONVEY_PORT) -workDir="$(realpath .)" -depth=1 + + +.PHONY: cover +cover: profile.out + + +profile.out: $(SOURCES) + rm -f $@ + $(GO) test -covermode=count -coverpkg=. -coverprofile=$@ . + + +.PHONY: docker-build +docker-build: + go get github.com/laher/goxc + rm -rf contrib/docker/linux_386 + for binary in $(BINARIES); do \ + goxc -bc="linux,386" -d . -pv contrib/docker -n $$binary xc; \ + mv contrib/docker/linux_386/$$binary contrib/docker/entrypoint; \ + docker build -t $(USER)/$$binary contrib/docker; \ + docker run -it --rm $(USER)/$$binary || true; \ + docker inspect --type=image --format="{{ .Id }}" moul/$$binary || true; \ + echo "Now you can run 'docker push $(USER)/$$binary'"; \ + done diff --git a/vendor/github.com/moul/anonuuid/README.md b/vendor/github.com/moul/anonuuid/README.md new file mode 100644 index 000000000..f5c9a57eb --- /dev/null +++ b/vendor/github.com/moul/anonuuid/README.md @@ -0,0 +1,170 @@ +# AnonUUID + +[![Build Status](https://travis-ci.org/moul/anonuuid.svg)](https://travis-ci.org/moul/anonuuid) +[![GoDoc](https://godoc.org/github.com/moul/anonuuid?status.svg)](https://godoc.org/github.com/moul/anonuuid) +[![Coverage Status](https://coveralls.io/repos/moul/anonuuid/badge.svg?branch=master&service=github)](https://coveralls.io/github/moul/anonuuid?branch=master) + +:wrench: Anonymize UUIDs outputs (written in Golang) + +![AnonUUID Logo](https://raw.githubusercontent.com/moul/anonuuid/master/assets/anonuuid.png) + +**anonuuid** anonymize an input string by replacing all UUIDs by an anonymized +new one. + +The fake UUIDs are cached, so if AnonUUID encounter the same real UUIDs multiple +times, the translation will be the same. + +## Usage + +```console +$ anonuuid --help +NAME: + anonuuid - Anonymize UUIDs outputs + +USAGE: + anonuuid [global options] command [command options] [arguments...] + +VERSION: + 1.0.0-dev + +AUTHOR(S): + Manfred Touron <https://github.com/moul> + +COMMANDS: + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --hexspeak Generate hexspeak style fake UUIDs + --random, -r Generate random fake UUIDs + --keep-beginning Keep first part of the UUID unchanged + --keep-end Keep last part of the UUID unchanged + --prefix, -p Prefix generated UUIDs + --suffix Suffix generated UUIDs + --help, -h show help + --version, -v print the version + ``` + +## Example + +Replace all UUIDs and cache the correspondance. + +```command +$ anonuuid git:(master) ✗ cat <<EOF | anonuuid +VOLUMES_0_SERVER_ID=15573749-c89d-41dd-a655-16e79bed52e0 +VOLUMES_0_SERVER_NAME=hello +VOLUMES_0_ID=c245c3cb-3336-4567-ada1-70cb1fe4eefe +VOLUMES_0_SIZE=50000000000 +ORGANIZATION=fe1e54e8-d69d-4f7c-a9f1-42069e03da31 +TEST=15573749-c89d-41dd-a655-16e79bed52e0 +EOF +VOLUMES_0_SERVER_ID=00000000-0000-0000-0000-000000000000 +VOLUMES_0_SERVER_NAME=hello +VOLUMES_0_ID=11111111-1111-1111-1111-111111111111 +VOLUMES_0_SIZE=50000000000 +ORGANIZATION=22222222-2222-2222-2222-222222222222 +TEST=00000000-0000-0000-0000-000000000000 +``` + +--- + +Inline + +```command +$ echo 'VOLUMES_0_SERVER_ID=15573749-c89d-41dd-a655-16e79bed52e0 VOLUMES_0_SERVER_NAME=bitrig1 VOLUMES_0_ID=c245c3cb-3336-4567-ada1-70cb1fe4eefe VOLUMES_0_SIZE=50000000000 ORGANIZATION=fe1e54e8-d69d-4f7c-a9f1-42069e03da31 TEST=15573749-c89d-41dd-a655-16e79bed52e0' | ./anonuuid +VOLUMES_0_SERVER_ID=00000000-0000-0000-0000-000000000000 VOLUMES_0_SERVER_NAME=bitrig1 VOLUMES_0_ID=11111111-1111-1111-1111-111111111111 VOLUMES_0_SIZE=50000000000 ORGANIZATION=22222222-2222-2222-2222-222222222222 TEST=00000000-0000-0000-0000-000000000000 +``` + +--- + +```command +$ curl -s https://api.pathwar.net/achievements\?max_results\=2 | anonuuid | jq . +{ + "_items": [ + { + "_updated": "Thu, 30 Apr 2015 13:00:58 GMT", + "description": "You", + "_links": { + "self": { + "href": "achievements/00000000-0000-0000-0000-000000000000", + "title": "achievement" + } + }, + "_created": "Thu, 30 Apr 2015 13:00:58 GMT", + "_id": "00000000-0000-0000-0000-000000000000", + "_etag": "b1e9f850accfcb952c58384db41d89728890a69f", + "name": "finish-20-levels" + }, + { + "_updated": "Thu, 30 Apr 2015 13:01:07 GMT", + "description": "You", + "_links": { + "self": { + "href": "achievements/11111111-1111-1111-1111-111111111111", + "title": "achievement" + } + }, + "_created": "Thu, 30 Apr 2015 13:01:07 GMT", + "_id": "11111111-1111-1111-1111-111111111111", + "_etag": "c346f5e1c4f7658f2dfc4124efa87aba909a9821", + "name": "buy-30-levels" + } + ], + "_links": { + "self": { + "href": "achievements?max_results=2", + "title": "achievements" + }, + "last": { + "href": "achievements?max_results=2&page=23", + "title": "last page" + }, + "parent": { + "href": "/", + "title": "home" + }, + "next": { + "href": "achievements?max_results=2&page=2", + "title": "next page" + } + }, + "_meta": { + "max_results": 2, + "total": 46, + "page": 1 + } +} +``` + +## Install + +Using go + +- `go get github.com/moul/anonuuid/...` + +## Changelog + +### master (unreleased) + +* Add mutex to protect the cache field ([@QuentinPerez](https://github.com/QuentinPerez)) +* Switch from `Party` to `Godep` +* Support of `--suffix=xxx`, `--keep-beginning` and `--keep-end` options ([#4](https://github.com/moul/anonuuid/issues/4)) +* Using **party** to stabilize vendor package versions ([#8](https://github.com/moul/anonuuid/issues/8)) +* Add homebrew package ([#6](https://github.com/moul/anonuuid/issues/6)) + +[full commits list](https://github.com/moul/anonuuid/compare/v1.0.0...master) + +### [v1.0.0](https://github.com/moul/anonuuid/releases/tag/v1.0.0) (2015-10-07) + +**Initial release** + +#### Features + +* Support of `--hexspeak` option +* Support of `--random` option +* Support of `--prefix` option +* Anonymize input stream +* Anonymize files + +## License + +MIT diff --git a/vendor/github.com/moul/anonuuid/anonuuid.go b/vendor/github.com/moul/anonuuid/anonuuid.go new file mode 100644 index 000000000..eb636f0e4 --- /dev/null +++ b/vendor/github.com/moul/anonuuid/anonuuid.go @@ -0,0 +1,229 @@ +package anonuuid + +import ( + "fmt" + "log" + "math/rand" + "regexp" + "strings" + "sync" + "time" +) + +var ( + // UUIDRegex is the regex used to find UUIDs in texts + UUIDRegex = "[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}" +) + +// AnonUUID is the main structure, it contains the cache map and helpers +type AnonUUID struct { + cache map[string]string + + guard sync.Mutex // cache guard + + // Hexspeak flag will generate hexspeak style fake UUIDs + Hexspeak bool + + // Random flag will generate random fake UUIDs + Random bool + + // Prefix will be the beginning of all the generated UUIDs + Prefix string + + // Suffix will be the end of all the generated UUIDs + Suffix string + + // AllowNonUUIDInput tells FakeUUID to accept non UUID input string + AllowNonUUIDInput bool + + // KeepBeginning tells FakeUUID to let the beginning of the UUID as it is + KeepBeginning bool + + // KeepEnd tells FakeUUID to let the last part of the UUID as it is + KeepEnd bool +} + +// Sanitize takes a string as input and return sanitized string +func (a *AnonUUID) Sanitize(input string) string { + r := regexp.MustCompile(UUIDRegex) + + return r.ReplaceAllStringFunc(input, func(m string) string { + parts := r.FindStringSubmatch(m) + return a.FakeUUID(parts[0]) + }) +} + +// FakeUUID takes a word (real UUID or standard string) and returns its corresponding (mapped) fakeUUID +func (a *AnonUUID) FakeUUID(input string) string { + if !a.AllowNonUUIDInput { + err := IsUUID(input) + if err != nil { + return "invaliduuid" + } + } + a.guard.Lock() + defer a.guard.Unlock() + if _, ok := a.cache[input]; !ok { + + if a.KeepBeginning { + a.Prefix = input[:8] + } + + if a.KeepEnd { + a.Suffix = input[36-12:] + } + + if a.Prefix != "" { + matched, err := regexp.MatchString("^[a-z0-9]+$", a.Prefix) + if err != nil || !matched { + a.Prefix = "invalidprefix" + } + } + + if a.Suffix != "" { + matched, err := regexp.MatchString("^[a-z0-9]+$", a.Suffix) + if err != nil || !matched { + a.Suffix = "invalsuffix" + } + } + + var fakeUUID string + var err error + if a.Hexspeak { + fakeUUID, err = GenerateHexspeakUUID(len(a.cache)) + } else if a.Random { + fakeUUID, err = GenerateRandomUUID(10) + } else { + fakeUUID, err = GenerateLenUUID(len(a.cache)) + } + if err != nil { + log.Fatalf("Failed to generate an UUID: %v", err) + } + + if a.Prefix != "" { + fakeUUID, err = PrefixUUID(a.Prefix, fakeUUID) + if err != nil { + panic(err) + } + } + + if a.Suffix != "" { + fakeUUID, err = SuffixUUID(a.Suffix, fakeUUID) + if err != nil { + panic(err) + } + } + + // FIXME: check for duplicates and retry + + a.cache[input] = fakeUUID + } + return a.cache[input] +} + +// New returns a prepared AnonUUID structure +func New() *AnonUUID { + return &AnonUUID{ + cache: make(map[string]string), + Hexspeak: false, + Random: false, + } +} + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + +// PrefixUUID returns a prefixed UUID +func PrefixUUID(prefix string, uuid string) (string, error) { + uuidLetters := uuid[:8] + uuid[9:13] + uuid[14:18] + uuid[19:23] + uuid[24:36] + prefixedUUID, err := FormatUUID(prefix + uuidLetters) + if err != nil { + return "", err + } + return prefixedUUID, nil +} + +// SuffixUUID returns a suffixed UUID +func SuffixUUID(suffix string, uuid string) (string, error) { + uuidLetters := uuid[:8] + uuid[9:13] + uuid[14:18] + uuid[19:23] + uuid[24:36] + uuidLetters = uuidLetters[:32-len(suffix)] + suffix + suffixedUUID, err := FormatUUID(uuidLetters) + if err != nil { + return "", err + } + return suffixedUUID, nil +} + +// IsUUID returns nil if the input is an UUID, else it returns an error +func IsUUID(input string) error { + matched, err := regexp.MatchString("^"+UUIDRegex+"$", input) + if err != nil { + return err + } + if !matched { + return fmt.Errorf("String '%s' is not a valid UUID", input) + } + return nil +} + +// FormatUUID takes a string in input and return an UUID formatted string by repeating the string and placing dashes if necessary +func FormatUUID(part string) (string, error) { + if len(part) < 1 { + return "", fmt.Errorf("Empty UUID") + } + if len(part) < 32 { + part = strings.Repeat(part, 32) + } + if len(part) > 32 { + part = part[:32] + } + uuid := part[:8] + "-" + part[8:12] + "-1" + part[13:16] + "-" + part[16:20] + "-" + part[20:32] + + err := IsUUID(uuid) + if err != nil { + return "", err + } + + return uuid, nil +} + +// GenerateRandomUUID returns an UUID based on random strings +func GenerateRandomUUID(length int) (string, error) { + var letters = []rune("abcdef0123456789") + + b := make([]rune, length) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return FormatUUID(string(b)) +} + +// GenerateHexspeakUUID returns an UUID formatted string containing hexspeak words +func GenerateHexspeakUUID(i int) (string, error) { + if i < 0 { + i = -i + } + hexspeaks := []string{ + "0ff1ce", + "31337", + "4b1d", + "badc0de", + "badcafe", + "badf00d", + "deadbabe", + "deadbeef", + "deadc0de", + "deadfeed", + "fee1bad", + } + return FormatUUID(hexspeaks[i%len(hexspeaks)]) +} + +// GenerateLenUUID returns an UUID formatted string based on an index number +func GenerateLenUUID(i int) (string, error) { + if i < 0 { + i = 2<<29 + i + } + return FormatUUID(fmt.Sprintf("%x", i)) +} diff --git a/vendor/github.com/moul/gotty-client/LICENSE b/vendor/github.com/moul/gotty-client/LICENSE new file mode 100644 index 000000000..492e2c629 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Manfred Touron + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/moul/gotty-client/Makefile b/vendor/github.com/moul/gotty-client/Makefile new file mode 100644 index 000000000..4952ef990 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/Makefile @@ -0,0 +1,81 @@ +# Project-specific variables +BINARIES ?= gotty-client +GOTTY_URL := http://localhost:8081/ +VERSION := $(shell cat .goxc.json | jq -c .PackageVersion | sed 's/"//g') + +CONVEY_PORT ?= 9042 + + +# Common variables +SOURCES := $(shell find . -type f -name "*.go") +COMMANDS := $(shell go list ./... | grep -v /vendor/ | grep /cmd/) +PACKAGES := $(shell go list ./... | grep -v /vendor/ | grep -v /cmd/) +GOENV ?= GO15VENDOREXPERIMENT=1 +GO ?= $(GOENV) go +GODEP ?= $(GOENV) godep +USER ?= $(shell whoami) + + +all: build + + +.PHONY: build +build: $(BINARIES) + + +.PHONY: install +install: + $(GO) install ./cmd/gotty-client + + +$(BINARIES): $(SOURCES) + $(GO) build -o $@ ./cmd/$@ + + +.PHONY: test +test: + $(GO) get -t . + $(GO) test -v . + + +.PHONY: godep-save +godep-save: + $(GODEP) save $(PACKAGES) $(COMMANDS) + + +.PHONY: clean +clean: + rm -f $(BINARIES) + + +.PHONY: re +re: clean all + + +.PHONY: convey +convey: + $(GO) get github.com/smartystreets/goconvey + goconvey -cover -port=$(CONVEY_PORT) -workDir="$(realpath .)" -depth=1 + + +.PHONY: cover +cover: profile.out + + +profile.out: $(SOURCES) + rm -f $@ + $(GO) test -covermode=count -coverpkg=. -coverprofile=$@ . + + +.PHONY: docker-build +docker-build: + go get github.com/laher/goxc + rm -rf contrib/docker/linux_386 + for binary in $(BINARIES); do \ + goxc -bc="linux,386" -d . -pv contrib/docker -n $$binary xc; \ + mv contrib/docker/linux_386/$$binary contrib/docker/entrypoint; \ + docker build -t $(USER)/$$binary contrib/docker; \ + docker run -it --rm $(USER)/$$binary || true; \ + docker inspect --type=image --format="{{ .Id }}" moul/$$binary || true; \ + echo "Now you can run 'docker push $(USER)/$$binary'"; \ + done diff --git a/vendor/github.com/moul/gotty-client/README.md b/vendor/github.com/moul/gotty-client/README.md new file mode 100644 index 000000000..2fb562b32 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/README.md @@ -0,0 +1,201 @@ +# gotty-client +:wrench: Terminal client for [GoTTY](https://github.com/yudai/gotty). + +![](https://raw.githubusercontent.com/moul/gotty-client/master/resources/gotty-client.png) + +[![Build Status](https://travis-ci.org/moul/gotty-client.svg?branch=master)](https://travis-ci.org/moul/gotty-client) +[![GoDoc](https://godoc.org/github.com/moul/gotty-client?status.svg)](https://godoc.org/github.com/moul/gotty-client) + +```ruby + ┌─────────────────┐ + ┌──────▶│ /bin/bash │ + │ └─────────────────┘ + ┌──────────────┐ ┌──────────┐ + │ │ │ Gotty │ +┌───────┐ ┌──▶│ Browser │───────┐ │ │ +│ │ │ │ │ │ │ │ +│ │ │ └──────────────┘ │ │ │ ┌─────────────────┐ +│ Bob │───┤ websockets─▶│ │─▶│ emacs /var/www │ +│ │ │ ╔═ ══ ══ ══ ══ ╗ │ │ │ └─────────────────┘ +│ │ │ ║ ║ │ │ │ +└───────┘ └──▶║ gotty-client ───────┘ │ │ + ║ │ │ + ╚═ ══ ══ ══ ══ ╝ └──────────┘ + │ ┌─────────────────┐ + └──────▶│ tmux attach │ + └─────────────────┘ +``` + +## Example + +Server side ([GoTTY](https://github.com/yudai/gotty)) + +```console +$ gotty -p 9191 sh -c 'while true; do date; sleep 1; done' +2015/08/24 18:54:31 Server is starting with command: sh -c while true; do date; sleep 1; done +2015/08/24 18:54:31 URL: http://[::1]:9191/ +2015/08/24 18:54:34 GET /ws +2015/08/24 18:54:34 New client connected: 127.0.0.1:61811 +2015/08/24 18:54:34 Command is running for client 127.0.0.1:61811 with PID 64834 +2015/08/24 18:54:39 Command exited for: 127.0.0.1:61811 +2015/08/24 18:54:39 Connection closed: 127.0.0.1:61811 +... +``` + +**Client side** + +```console +$ gotty-client http://localhost:9191/ +INFO[0000] New title: GoTTY - sh -c while true; do date; sleep 1; done (jean-michel-van-damme.local) +WARN[0000] Unhandled protocol message: json pref: 2{} +Mon Aug 24 18:54:34 CEST 2015 +Mon Aug 24 18:54:35 CEST 2015 +Mon Aug 24 18:54:36 CEST 2015 +Mon Aug 24 18:54:37 CEST 2015 +Mon Aug 24 18:54:38 CEST 2015 +^C +``` + +## Usage + +```console +$ gotty-client -h +NAME: + gotty-client - GoTTY client for your terminal + +USAGE: + gotty-client [global options] command [command options] GOTTY_URL + +VERSION: + 1.3.0+ + +AUTHOR(S): + Manfred Touron <https://github.com/moul/gotty-client> + +COMMANDS: + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --debug, -D Enable debug mode [$GOTTY_CLIENT_DEBUG] + --help, -h show help + --version, -v print the version +``` + +## Install + +Install latest version using Golang (recommended) + +```console +$ go get github.com/moul/gotty-client/cmd/gotty-client +``` + +--- + +Install latest version using Homebrew (Mac OS X) + +```console +$ brew install https://raw.githubusercontent.com/moul/gotty-client/master/contrib/homebrew/gotty-client.rb --HEAD +``` + +or the latest released version + +```console +$ brew install https://raw.githubusercontent.com/moul/gotty-client/master/contrib/homebrew/gotty-client.rb +``` + +## Changelog + +### master (unreleased) + +* No entry + +[full commits list](https://github.com/moul/gotty-client/compare/v1.6.1...master) + +### [v1.6.1](https://github.com/moul/gotty-client/releases/tag/v1.6.1) (2017-01-19) + +* Do not exit on EOF ([#45](https://github.com/moul/gotty-client/pull/45)) ([@gurjeet](https://github.com/gurjeet)) + +[full commits list](https://github.com/moul/gotty-client/compare/v1.6.0...v1.6.1) + +### [v1.6.0](https://github.com/moul/gotty-client/releases/tag/v1.6.0) (2016-05-23) + +* Support of `--use-proxy-from-env` (Add Proxy support) ([#36](https://github.com/moul/gotty-client/pull/36)) ([@byung2](https://github.com/byung2)) +* Add debug mode ([#18](https://github.com/moul/gotty-client/issues/18)) +* Fix argument passing ([#16](https://github.com/moul/gotty-client/issues/16)) +* Remove warnings + golang fixes and refactoring ([@QuentinPerez](https://github.com/QuentinPerez)) + +[full commits list](https://github.com/moul/gotty-client/compare/v1.5.0...v1.6.0) + +### [v1.5.0](https://github.com/moul/gotty-client/releases/tag/v1.5.0) (2016-02-18) + +* Add autocomplete support ([#19](https://github.com/moul/gotty-client/issues/19)) +* Switch from `Party` to `Godep` +* Fix terminal data being interpreted as format string ([#34](https://github.com/moul/gotty-client/pull/34)) ([@mickael9](https://github.com/mickael9)) + +[full commits list](https://github.com/moul/gotty-client/compare/v1.4.0...v1.5.0) + +### [v1.4.0](https://github.com/moul/gotty-client/releases/tag/v1.4.0) (2015-12-09) + +* Remove solaris,plan9,nacl for `.goxc.json` +* Add an error if the go version is lower than 1.5 +* Flexible parsing of the input URL +* Add tests +* Support of `--skip-tls-verify` + +[full commits list](https://github.com/moul/gotty-client/compare/v1.3.0...v1.4.0) + +### [v1.3.0](https://github.com/moul/gotty-client/releases/tag/v1.3.0) (2015-10-27) + +* Fix `connected` state when using `Connect()` + `Loop()` methods +* Add `ExitLoop` which allow to exit from `Loop` function + +[full commits list](https://github.com/moul/gotty-client/compare/v1.2.0...v1.3.0) + +### [v1.2.0](https://github.com/moul/gotty-client/releases/tag/v1.2.0) (2015-10-23) + +* Removed an annoying warning when exiting connection ([#22](https://github.com/moul/gotty-client/issues/22)) ([@QuentinPerez](https://github.com/QuentinPerez)) +* Add the ability to configure alternative stdout ([#21](https://github.com/moul/gotty-client/issues/21)) ([@QuentinPerez](https://github.com/QuentinPerez)) +* Refactored the goroutine system with select, improve speed and stability ([@QuentinPerez](https://github.com/QuentinPerez)) +* Add debug mode (`--debug`/`-D`) ([#18](https://github.com/moul/gotty-client/issues/18)) +* Improve error message when connecting by checking HTTP status code +* Fix arguments passing ([#16](https://github.com/moul/gotty-client/issues/16)) +* Dropped support for golang<1.5 +* Small fixes + +[full commits list](https://github.com/moul/gotty-client/compare/v1.1.0...v1.2.0) + +### [v1.1.0](https://github.com/moul/gotty-client/releases/tag/v1.1.0) (2015-10-10) + +* Handling arguments + using mutexes (thanks to [@QuentinPerez](https://github.com/QuentinPerez)) +* Add logo ([#9](https://github.com/moul/gotty-client/issues/9)) +* Using codegansta/cli for CLI parsing ([#3](https://github.com/moul/gotty-client/issues/3)) +* Fix panic when running on older GoTTY server ([#13](https://github.com/moul/gotty-client/issues/13)) +* Add 'homebrew support' ([#1](https://github.com/moul/gotty-client/issues/1)) +* Add Changelog ([#5](https://github.com/moul/gotty-client/issues/5)) +* Add GOXC configuration to build binaries for multiple architectures ([#2](https://github.com/moul/gotty-client/issues/2)) + +[full commits list](https://github.com/moul/gotty-client/compare/v1.0.1...v1.1.0) + +### [v1.0.1](https://github.com/moul/gotty-client/releases/tag/v1.0.1) (2015-09-27) + +* Using party to manage dependencies + +[full commits list](https://github.com/moul/gotty-client/compare/v1.0.0...v1.0.1) + +### [v1.0.0](https://github.com/moul/gotty-client/releases/tag/v1.0.0) (2015-09-27) + +Compatible with [GoTTY](https://github.com/yudai/gotty) version: [v0.0.10](https://github.com/yudai/gotty/releases/tag/v0.0.10) + +#### Features + +* Support **basic-auth** +* Support **terminal-(re)size** +* Support **write** +* Support **title** +* Support **custom URI** + +[full commits list](https://github.com/moul/gotty-client/compare/cf0c1146c7ce20fe0bd65764c13253bc575cd43a...v1.0.0) + +## License + +MIT diff --git a/vendor/github.com/moul/gotty-client/arch.go b/vendor/github.com/moul/gotty-client/arch.go new file mode 100644 index 000000000..d856fbd2c --- /dev/null +++ b/vendor/github.com/moul/gotty-client/arch.go @@ -0,0 +1,34 @@ +// +build !windows + +package gottyclient + +import ( + "encoding/json" + "fmt" + "os" + "os/signal" + "syscall" + "unsafe" +) + +func notifySignalSIGWINCH(c chan<- os.Signal) { + signal.Notify(c, syscall.SIGWINCH) +} + +func resetSignalSIGWINCH() { + signal.Reset(syscall.SIGWINCH) +} + +func syscallTIOCGWINSZ() ([]byte, error) { + ws := winsize{} + + syscall.Syscall(syscall.SYS_IOCTL, + uintptr(0), uintptr(syscall.TIOCGWINSZ), + uintptr(unsafe.Pointer(&ws))) + + b, err := json.Marshal(ws) + if err != nil { + return nil, fmt.Errorf("json.Marshal error: %v", err) + } + return b, err +} diff --git a/vendor/github.com/moul/gotty-client/arch_windows.go b/vendor/github.com/moul/gotty-client/arch_windows.go new file mode 100644 index 000000000..53aaffc5f --- /dev/null +++ b/vendor/github.com/moul/gotty-client/arch_windows.go @@ -0,0 +1,16 @@ +package gottyclient + +import ( + "errors" + "os" +) + +func notifySignalSIGWINCH(c chan<- os.Signal) { +} + +func resetSignalSIGWINCH() { +} + +func syscallTIOCGWINSZ() ([]byte, error) { + return nil, errors.New("SIGWINCH isn't supported on this ARCH") +} diff --git a/vendor/github.com/moul/gotty-client/glide.lock b/vendor/github.com/moul/gotty-client/glide.lock new file mode 100644 index 000000000..61d5aeee3 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/glide.lock @@ -0,0 +1,37 @@ +hash: 5ba4ef945563e8e85097f2699126b1577f9c667fdbbcdd71604e553ab7dd2a03 +updated: 2017-02-04T23:03:32.03375088+01:00 +imports: +- name: github.com/codegangsta/cli + version: 2ae9042f5bcbaf15b01229f8395ba8e72e01bded +- name: github.com/creack/goselect + version: 40085cf5fd629ccd88dc328895f1f137d09a1de4 +- name: github.com/gopherjs/gopherjs + version: db27c7c470d7404b6b201f82d6fd4821260bd13e + subpackages: + - js +- name: github.com/gorilla/websocket + version: 1f512fc3f05332ba7117626cdfb4e07474e58e60 +- name: github.com/jtolds/gls + version: 8ddce2a84170772b95dd5d576c48d517b22cac63 +- name: github.com/Sirupsen/logrus + version: cd7d1bbe41066b6c1f19780f895901052150a575 +- name: github.com/smartystreets/assertions + version: 40711f7748186bbf9c99977cd89f21ce1a229447 + subpackages: + - internal/go-render/render + - internal/oglematchers +- name: github.com/smartystreets/goconvey + version: d4c757aa9afd1e2fc1832aaab209b5794eb336e1 + subpackages: + - convey + - convey/gotest + - convey/reporting +- name: golang.org/x/crypto + version: 5bcd134fee4dd1475da17714aac19c0aa0142e2f + subpackages: + - ssh/terminal +- name: golang.org/x/sys + version: d4feaf1a7e61e1d9e79e6c4e76c6349e9cab0a03 + subpackages: + - unix +testImports: [] diff --git a/vendor/github.com/moul/gotty-client/glide.yaml b/vendor/github.com/moul/gotty-client/glide.yaml new file mode 100644 index 000000000..287efb9d8 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/glide.yaml @@ -0,0 +1,35 @@ +package: github.com/moul/gotty-client +import: +- package: github.com/Sirupsen/logrus + version: cd7d1bbe41066b6c1f19780f895901052150a575 +- package: github.com/codegangsta/cli + version: 2ae9042f5bcbaf15b01229f8395ba8e72e01bded +- package: github.com/creack/goselect + version: 40085cf5fd629ccd88dc328895f1f137d09a1de4 +- package: github.com/gopherjs/gopherjs + version: db27c7c470d7404b6b201f82d6fd4821260bd13e + subpackages: + - js +- package: github.com/gorilla/websocket + version: 1f512fc3f05332ba7117626cdfb4e07474e58e60 +- package: github.com/jtolds/gls + version: 8ddce2a84170772b95dd5d576c48d517b22cac63 +- package: github.com/smartystreets/assertions + version: 40711f7748186bbf9c99977cd89f21ce1a229447 + subpackages: + - internal/go-render/render + - internal/oglematchers +- package: github.com/smartystreets/goconvey + version: d4c757aa9afd1e2fc1832aaab209b5794eb336e1 + subpackages: + - convey + - convey/gotest + - convey/reporting +- package: golang.org/x/crypto + version: 5bcd134fee4dd1475da17714aac19c0aa0142e2f + subpackages: + - ssh/terminal +- package: golang.org/x/sys + version: d4feaf1a7e61e1d9e79e6c4e76c6349e9cab0a03 + subpackages: + - unix diff --git a/vendor/github.com/moul/gotty-client/gotty-client.go b/vendor/github.com/moul/gotty-client/gotty-client.go new file mode 100644 index 000000000..35e599d9b --- /dev/null +++ b/vendor/github.com/moul/gotty-client/gotty-client.go @@ -0,0 +1,469 @@ +package gottyclient + +import ( + "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "regexp" + "strings" + "sync" + "time" + + "github.com/Sirupsen/logrus" + "github.com/creack/goselect" + "github.com/gorilla/websocket" + "golang.org/x/crypto/ssh/terminal" +) + +// GetAuthTokenURL transforms a GoTTY http URL to its AuthToken file URL +func GetAuthTokenURL(httpURL string) (*url.URL, *http.Header, error) { + header := http.Header{} + target, err := url.Parse(httpURL) + if err != nil { + return nil, nil, err + } + + target.Path = strings.TrimLeft(target.Path+"auth_token.js", "/") + + if target.User != nil { + header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(target.User.String()))) + target.User = nil + } + + return target, &header, nil +} + +// GetURLQuery returns url.query +func GetURLQuery(rawurl string) (url.Values, error) { + target, err := url.Parse(rawurl) + if err != nil { + return nil, err + } + return target.Query(), nil +} + +// GetWebsocketURL transforms a GoTTY http URL to its WebSocket URL +func GetWebsocketURL(httpURL string) (*url.URL, *http.Header, error) { + header := http.Header{} + target, err := url.Parse(httpURL) + if err != nil { + return nil, nil, err + } + + if target.Scheme == "https" { + target.Scheme = "wss" + } else { + target.Scheme = "ws" + } + + target.Path = strings.TrimLeft(target.Path+"ws", "/") + + if target.User != nil { + header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(target.User.String()))) + target.User = nil + } + + return target, &header, nil +} + +type Client struct { + Dialer *websocket.Dialer + Conn *websocket.Conn + URL string + WriteMutex *sync.Mutex + Output io.Writer + poison chan bool + SkipTLSVerify bool + UseProxyFromEnv bool + Connected bool +} + +type querySingleType struct { + AuthToken string `json:"AuthToken"` + Arguments string `json:"Arguments"` +} + +func (c *Client) write(data []byte) error { + c.WriteMutex.Lock() + defer c.WriteMutex.Unlock() + return c.Conn.WriteMessage(websocket.TextMessage, data) +} + +// GetAuthToken retrieves an Auth Token from dynamic auth_token.js file +func (c *Client) GetAuthToken() (string, error) { + target, header, err := GetAuthTokenURL(c.URL) + if err != nil { + return "", err + } + + logrus.Debugf("Fetching auth token auth-token: %q", target.String()) + req, err := http.NewRequest("GET", target.String(), nil) + req.Header = *header + tr := &http.Transport{} + if c.SkipTLSVerify { + conf := &tls.Config{InsecureSkipVerify: true} + tr.TLSClientConfig = conf + } + if c.UseProxyFromEnv { + tr.Proxy = http.ProxyFromEnvironment + } + client := &http.Client{Transport: tr} + resp, err := client.Do(req) + if err != nil { + return "", err + } + + switch resp.StatusCode { + case 200: + // Everything is OK + default: + return "", fmt.Errorf("unknown status code: %d (%s)", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + re := regexp.MustCompile("var gotty_auth_token = '(.*)'") + output := re.FindStringSubmatch(string(body)) + if len(output) == 0 { + return "", fmt.Errorf("Cannot fetch GoTTY auth-token, please upgrade your GoTTY server.") + } + + return output[1], nil +} + +// Connect tries to dial a websocket server +func (c *Client) Connect() error { + // Retrieve AuthToken + authToken, err := c.GetAuthToken() + if err != nil { + return err + } + logrus.Debugf("Auth-token: %q", authToken) + + // Open WebSocket connection + target, header, err := GetWebsocketURL(c.URL) + if err != nil { + return err + } + logrus.Debugf("Connecting to websocket: %q", target.String()) + if c.SkipTLSVerify { + c.Dialer.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + if c.UseProxyFromEnv { + c.Dialer.Proxy = http.ProxyFromEnvironment + } + conn, _, err := c.Dialer.Dial(target.String(), *header) + if err != nil { + return err + } + c.Conn = conn + c.Connected = true + + // Pass arguments and auth-token + query, err := GetURLQuery(c.URL) + if err != nil { + return err + } + querySingle := querySingleType{ + Arguments: "?" + query.Encode(), + AuthToken: authToken, + } + json, err := json.Marshal(querySingle) + if err != nil { + logrus.Errorf("Failed to parse init message %v", err) + return err + } + // Send Json + logrus.Debugf("Sending arguments and auth-token") + err = c.write(json) + if err != nil { + return err + } + + go c.pingLoop() + + return nil +} + +func (c *Client) pingLoop() { + for { + logrus.Debugf("Sending ping") + c.write([]byte("1")) + time.Sleep(30 * time.Second) + } +} + +// Close will nicely close the dialer +func (c *Client) Close() { + c.Conn.Close() +} + +// ExitLoop will kill all goroutines launched by c.Loop() +// ExitLoop() -> wait Loop() -> Close() +func (c *Client) ExitLoop() { + fname := "ExitLoop" + openPoison(fname, c.poison) +} + +// Loop will look indefinitely for new messages +func (c *Client) Loop() error { + if !c.Connected { + err := c.Connect() + if err != nil { + return err + } + } + + wg := &sync.WaitGroup{} + + wg.Add(1) + go c.termsizeLoop(wg) + + wg.Add(1) + go c.readLoop(wg) + + wg.Add(1) + go c.writeLoop(wg) + + /* Wait for all of the above goroutines to finish */ + wg.Wait() + + logrus.Debug("Client.Loop() exiting") + return nil +} + +type winsize struct { + Rows uint16 `json:"rows"` + Columns uint16 `json:"columns"` + // unused + x uint16 + y uint16 +} + +type posionReason int + +const ( + committedSuicide = iota + killed +) + +func openPoison(fname string, poison chan bool) posionReason { + logrus.Debug(fname + " suicide") + + /* + * The close() may raise panic if multiple goroutines commit suicide at the + * same time. Prevent that panic from bubbling up. + */ + defer func() { + if r := recover(); r != nil { + logrus.Debug("Prevented panic() of simultaneous suicides", r) + } + }() + + /* Signal others to die */ + close(poison) + return committedSuicide +} + +func die(fname string, poison chan bool) posionReason { + logrus.Debug(fname + " died") + + wasOpen := <-poison + if wasOpen { + logrus.Error("ERROR: The channel was open when it wasn't suppoed to be") + } + + return killed +} + +func (c *Client) termsizeLoop(wg *sync.WaitGroup) posionReason { + + defer wg.Done() + fname := "termsizeLoop" + + ch := make(chan os.Signal, 1) + notifySignalSIGWINCH(ch) + defer resetSignalSIGWINCH() + + for { + if b, err := syscallTIOCGWINSZ(); err != nil { + logrus.Warn(err) + } else { + if err = c.write(append([]byte("2"), b...)); err != nil { + logrus.Warnf("ws.WriteMessage failed: %v", err) + } + } + select { + case <-c.poison: + /* Somebody poisoned the well; die */ + return die(fname, c.poison) + case <-ch: + } + } +} + +type exposeFd interface { + Fd() uintptr +} + +func (c *Client) writeLoop(wg *sync.WaitGroup) posionReason { + + defer wg.Done() + fname := "writeLoop" + + buff := make([]byte, 128) + oldState, err := terminal.MakeRaw(0) + if err == nil { + defer terminal.Restore(0, oldState) + } + + rdfs := &goselect.FDSet{} + reader := io.Reader(os.Stdin) + for { + select { + case <-c.poison: + /* Somebody poisoned the well; die */ + return die(fname, c.poison) + default: + } + + rdfs.Zero() + rdfs.Set(reader.(exposeFd).Fd()) + err := goselect.Select(1, rdfs, nil, nil, 50*time.Millisecond) + if err != nil { + return openPoison(fname, c.poison) + } + if rdfs.IsSet(reader.(exposeFd).Fd()) { + size, err := reader.Read(buff) + + if err != nil { + if err == io.EOF { + // Send EOF to GoTTY + + // Send 'Input' marker, as defined in GoTTY::client_context.go, + // followed by EOT (a translation of Ctrl-D for terminals) + err = c.write(append([]byte("0"), byte(4))) + + if err != nil { + return openPoison(fname, c.poison) + } + continue + } else { + return openPoison(fname, c.poison) + } + } + + if size <= 0 { + continue + } + + data := buff[:size] + err = c.write(append([]byte("0"), data...)) + if err != nil { + return openPoison(fname, c.poison) + } + } + } +} + +func (c *Client) readLoop(wg *sync.WaitGroup) posionReason { + + defer wg.Done() + fname := "readLoop" + + type MessageNonBlocking struct { + Data []byte + Err error + } + msgChan := make(chan MessageNonBlocking) + + for { + go func() { + _, data, err := c.Conn.ReadMessage() + msgChan <- MessageNonBlocking{Data: data, Err: err} + }() + + select { + case <-c.poison: + /* Somebody poisoned the well; die */ + return die(fname, c.poison) + case msg := <-msgChan: + if msg.Err != nil { + + if _, ok := msg.Err.(*websocket.CloseError); !ok { + logrus.Warnf("c.Conn.ReadMessage: %v", msg.Err) + } + return openPoison(fname, c.poison) + } + if len(msg.Data) == 0 { + + logrus.Warnf("An error has occured") + return openPoison(fname, c.poison) + } + switch msg.Data[0] { + case '0': // data + buf, err := base64.StdEncoding.DecodeString(string(msg.Data[1:])) + if err != nil { + logrus.Warnf("Invalid base64 content: %q", msg.Data[1:]) + break + } + c.Output.Write(buf) + case '1': // pong + case '2': // new title + newTitle := string(msg.Data[1:]) + fmt.Fprintf(c.Output, "\033]0;%s\007", newTitle) + case '3': // json prefs + logrus.Debugf("Unhandled protocol message: json pref: %s", string(msg.Data[1:])) + case '4': // autoreconnect + logrus.Debugf("Unhandled protocol message: autoreconnect: %s", string(msg.Data)) + default: + logrus.Warnf("Unhandled protocol message: %s", string(msg.Data)) + } + } + } +} + +// SetOutput changes the output stream +func (c *Client) SetOutput(w io.Writer) { + c.Output = w +} + +// ParseURL parses an URL which may be incomplete and tries to standardize it +func ParseURL(input string) (string, error) { + parsed, err := url.Parse(input) + if err != nil { + return "", err + } + switch parsed.Scheme { + case "http", "https": + // everything is ok + default: + return ParseURL(fmt.Sprintf("http://%s", input)) + } + return parsed.String(), nil +} + +// NewClient returns a GoTTY client object +func NewClient(inputURL string) (*Client, error) { + url, err := ParseURL(inputURL) + if err != nil { + return nil, err + } + return &Client{ + Dialer: &websocket.Dialer{}, + URL: url, + WriteMutex: &sync.Mutex{}, + Output: os.Stdout, + poison: make(chan bool), + }, nil +} diff --git a/vendor/github.com/renstrom/fuzzysearch/LICENSE b/vendor/github.com/renstrom/fuzzysearch/LICENSE new file mode 100644 index 000000000..9cc753370 --- /dev/null +++ b/vendor/github.com/renstrom/fuzzysearch/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Peter Renström + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go b/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go new file mode 100644 index 000000000..63277d51e --- /dev/null +++ b/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go @@ -0,0 +1,167 @@ +// Fuzzy searching allows for flexibly matching a string with partial input, +// useful for filtering data very quickly based on lightweight user input. +package fuzzy + +import ( + "unicode" + "unicode/utf8" +) + +var noop = func(r rune) rune { return r } + +// Match returns true if source matches target using a fuzzy-searching +// algorithm. Note that it doesn't implement Levenshtein distance (see +// RankMatch instead), but rather a simplified version where there's no +// approximation. The method will return true only if each character in the +// source can be found in the target and occurs after the preceding matches. +func Match(source, target string) bool { + return match(source, target, noop) +} + +// MatchFold is a case-insensitive version of Match. +func MatchFold(source, target string) bool { + return match(source, target, unicode.ToLower) +} + +func match(source, target string, fn func(rune) rune) bool { + lenDiff := len(target) - len(source) + + if lenDiff < 0 { + return false + } + + if lenDiff == 0 && source == target { + return true + } + +Outer: + for _, r1 := range source { + for i, r2 := range target { + if fn(r1) == fn(r2) { + target = target[i+utf8.RuneLen(r2):] + continue Outer + } + } + return false + } + + return true +} + +// Find will return a list of strings in targets that fuzzy matches source. +func Find(source string, targets []string) []string { + return find(source, targets, noop) +} + +// FindFold is a case-insensitive version of Find. +func FindFold(source string, targets []string) []string { + return find(source, targets, unicode.ToLower) +} + +func find(source string, targets []string, fn func(rune) rune) []string { + var matches []string + + for _, target := range targets { + if match(source, target, fn) { + matches = append(matches, target) + } + } + + return matches +} + +// RankMatch is similar to Match except it will measure the Levenshtein +// distance between the source and the target and return its result. If there +// was no match, it will return -1. +// Given the requirements of match, RankMatch only needs to perform a subset of +// the Levenshtein calculation, only deletions need be considered, required +// additions and substitutions would fail the match test. +func RankMatch(source, target string) int { + return rank(source, target, noop) +} + +// RankMatchFold is a case-insensitive version of RankMatch. +func RankMatchFold(source, target string) int { + return rank(source, target, unicode.ToLower) +} + +func rank(source, target string, fn func(rune) rune) int { + lenDiff := len(target) - len(source) + + if lenDiff < 0 { + return -1 + } + + if lenDiff == 0 && source == target { + return 0 + } + + runeDiff := 0 + +Outer: + for _, r1 := range source { + for i, r2 := range target { + if fn(r1) == fn(r2) { + target = target[i+utf8.RuneLen(r2):] + continue Outer + } else { + runeDiff++ + } + } + return -1 + } + + // Count up remaining char + for len(target) > 0 { + target = target[utf8.RuneLen(rune(target[0])):] + runeDiff++ + } + + return runeDiff +} + +// RankFind is similar to Find, except it will also rank all matches using +// Levenshtein distance. +func RankFind(source string, targets []string) Ranks { + var r Ranks + for _, target := range find(source, targets, noop) { + distance := LevenshteinDistance(source, target) + r = append(r, Rank{source, target, distance}) + } + return r +} + +// RankFindFold is a case-insensitive version of RankFind. +func RankFindFold(source string, targets []string) Ranks { + var r Ranks + for _, target := range find(source, targets, unicode.ToLower) { + distance := LevenshteinDistance(source, target) + r = append(r, Rank{source, target, distance}) + } + return r +} + +type Rank struct { + // Source is used as the source for matching. + Source string + + // Target is the word matched against. + Target string + + // Distance is the Levenshtein distance between Source and Target. + Distance int +} + +type Ranks []Rank + +func (r Ranks) Len() int { + return len(r) +} + +func (r Ranks) Swap(i, j int) { + r[i], r[j] = r[j], r[i] +} + +func (r Ranks) Less(i, j int) bool { + return r[i].Distance < r[j].Distance +} diff --git a/vendor/github.com/renstrom/fuzzysearch/fuzzy/levenshtein.go b/vendor/github.com/renstrom/fuzzysearch/fuzzy/levenshtein.go new file mode 100644 index 000000000..237923d34 --- /dev/null +++ b/vendor/github.com/renstrom/fuzzysearch/fuzzy/levenshtein.go @@ -0,0 +1,43 @@ +package fuzzy + +// LevenshteinDistance measures the difference between two strings. +// The Levenshtein distance between two words is the minimum number of +// single-character edits (i.e. insertions, deletions or substitutions) +// required to change one word into the other. +// +// This implemention is optimized to use O(min(m,n)) space and is based on the +// optimized C version found here: +// http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Levenshtein_distance#C +func LevenshteinDistance(s, t string) int { + r1, r2 := []rune(s), []rune(t) + column := make([]int, len(r1)+1) + + for y := 1; y <= len(r1); y++ { + column[y] = y + } + + for x := 1; x <= len(r2); x++ { + column[0] = x + + for y, lastDiag := 1, x-1; y <= len(r1); y++ { + oldDiag := column[y] + cost := 0 + if r1[y-1] != r2[x-1] { + cost = 1 + } + column[y] = min(column[y]+1, column[y-1]+1, lastDiag+cost) + lastDiag = oldDiag + } + } + + return column[len(r1)] +} + +func min(a, b, c int) int { + if a < b && a < c { + return a + } else if b < c { + return b + } + return c +} diff --git a/vendor/github.com/scaleway/scaleway-cli/LICENSE.md b/vendor/github.com/scaleway/scaleway-cli/LICENSE.md new file mode 100644 index 000000000..7503a16ca --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/LICENSE.md @@ -0,0 +1,22 @@ +The MIT License +=============== + +Copyright (c) **2014-2016 Scaleway <opensource@scaleway.com> ([@scaleway](https://twitter.com/scaleway))** + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md b/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md new file mode 100644 index 000000000..559a7018d --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md @@ -0,0 +1,25 @@ +# Scaleway's API + +[![GoDoc](https://godoc.org/github.com/scaleway/scaleway-cli/pkg/api?status.svg)](https://godoc.org/github.com/scaleway/scaleway-cli/pkg/api) + +This package contains facilities to play with the Scaleway API, it includes the following features: + +- dedicated configuration file containing credentials to deal with the API +- caching to resolve UUIDs without contacting the API + +## Links + +- [API documentation](https://developer.scaleway.com) +- [Official Python SDK](https://github.com/scaleway/python-scaleway) +- Projects using this SDK + - https://github.com/scaleway/devhub + - https://github.com/scaleway/docker-machine-driver-scaleway + - https://github.com/scaleway-community/scaleway-ubuntu-coreos/blob/master/overlay/usr/local/update-firewall/scw-api/cache.go + - https://github.com/pulcy/quark + - https://github.com/hex-sh/terraform-provider-scaleway + - https://github.com/tscolari/bosh-scaleway-cpi +- Other **golang** clients + - https://github.com/lalyos/onlabs + - https://github.com/meatballhat/packer-builder-onlinelabs + - https://github.com/nlamirault/go-scaleway + - https://github.com/golang/build/blob/master/cmd/scaleway/scaleway.go diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go new file mode 100644 index 000000000..5ce0157dc --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go @@ -0,0 +1,2754 @@ +// Copyright (C) 2015 Scaleway. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE.md file. + +// Interact with Scaleway API + +// Package api contains client and functions to interact with Scaleway API +package api + +import ( + "bytes" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net" + "net/http" + "net/http/httputil" + "net/url" + "os" + "sort" + "strconv" + "strings" + "text/tabwriter" + "text/template" + "time" + + "golang.org/x/sync/errgroup" +) + +// Default values +var ( + AccountAPI = "https://account.scaleway.com/" + MetadataAPI = "http://169.254.42.42/" + MarketplaceAPI = "https://api-marketplace.scaleway.com" + ComputeAPIPar1 = "https://cp-par1.scaleway.com/" + ComputeAPIAms1 = "https://cp-ams1.scaleway.com" + + URLPublicDNS = ".pub.cloud.scaleway.com" + URLPrivateDNS = ".priv.cloud.scaleway.com" +) + +func init() { + if url := os.Getenv("SCW_ACCOUNT_API"); url != "" { + AccountAPI = url + } + if url := os.Getenv("SCW_METADATA_API"); url != "" { + MetadataAPI = url + } + if url := os.Getenv("SCW_MARKETPLACE_API"); url != "" { + MarketplaceAPI = url + } +} + +const ( + perPage = 50 +) + +// ScalewayAPI is the interface used to communicate with the Scaleway API +type ScalewayAPI struct { + // Organization is the identifier of the Scaleway organization + Organization string + + // Token is the authentication token for the Scaleway organization + Token string + + // Password is the authentication password + password string + + userAgent string + + // Cache is used to quickly resolve identifiers from names + Cache *ScalewayCache + + client *http.Client + verbose bool + computeAPI string + + Region string + // + Logger +} + +// ScalewayAPIError represents a Scaleway API Error +type ScalewayAPIError struct { + // Message is a human-friendly error message + APIMessage string `json:"message,omitempty"` + + // Type is a string code that defines the kind of error + Type string `json:"type,omitempty"` + + // Fields contains detail about validation error + Fields map[string][]string `json:"fields,omitempty"` + + // StatusCode is the HTTP status code received + StatusCode int `json:"-"` + + // Message + Message string `json:"-"` +} + +// Error returns a string representing the error +func (e ScalewayAPIError) Error() string { + var b bytes.Buffer + + fmt.Fprintf(&b, "StatusCode: %v, ", e.StatusCode) + fmt.Fprintf(&b, "Type: %v, ", e.Type) + fmt.Fprintf(&b, "APIMessage: \x1b[31m%v\x1b[0m", e.APIMessage) + if len(e.Fields) > 0 { + fmt.Fprintf(&b, ", Details: %v", e.Fields) + } + return b.String() +} + +// HideAPICredentials removes API credentials from a string +func (s *ScalewayAPI) HideAPICredentials(input string) string { + output := input + if s.Token != "" { + output = strings.Replace(output, s.Token, "00000000-0000-4000-8000-000000000000", -1) + } + if s.Organization != "" { + output = strings.Replace(output, s.Organization, "00000000-0000-5000-9000-000000000000", -1) + } + if s.password != "" { + output = strings.Replace(output, s.password, "XX-XX-XX-XX", -1) + } + return output +} + +// ScalewayIPAddress represents a Scaleway IP address +type ScalewayIPAddress struct { + // Identifier is a unique identifier for the IP address + Identifier string `json:"id,omitempty"` + + // IP is an IPv4 address + IP string `json:"address,omitempty"` + + // Dynamic is a flag that defines an IP that change on each reboot + Dynamic *bool `json:"dynamic,omitempty"` +} + +// ScalewayVolume represents a Scaleway Volume +type ScalewayVolume struct { + // Identifier is a unique identifier for the volume + Identifier string `json:"id,omitempty"` + + // Size is the allocated size of the volume + Size uint64 `json:"size,omitempty"` + + // CreationDate is the creation date of the volume + CreationDate string `json:"creation_date,omitempty"` + + // ModificationDate is the date of the last modification of the volume + ModificationDate string `json:"modification_date,omitempty"` + + // Organization is the organization owning the volume + Organization string `json:"organization,omitempty"` + + // Name is the name of the volume + Name string `json:"name,omitempty"` + + // Server is the server using this image + Server *struct { + Identifier string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + } `json:"server,omitempty"` + + // VolumeType is a Scaleway identifier for the kind of volume (default: l_ssd) + VolumeType string `json:"volume_type,omitempty"` + + // ExportURI represents the url used by initrd/scripts to attach the volume + ExportURI string `json:"export_uri,omitempty"` +} + +// ScalewayOneVolume represents the response of a GET /volumes/UUID API call +type ScalewayOneVolume struct { + Volume ScalewayVolume `json:"volume,omitempty"` +} + +// ScalewayVolumes represents a group of Scaleway volumes +type ScalewayVolumes struct { + // Volumes holds scaleway volumes of the response + Volumes []ScalewayVolume `json:"volumes,omitempty"` +} + +// ScalewayVolumeDefinition represents a Scaleway volume definition +type ScalewayVolumeDefinition struct { + // Name is the user-defined name of the volume + Name string `json:"name"` + + // Image is the image used by the volume + Size uint64 `json:"size"` + + // Bootscript is the bootscript used by the volume + Type string `json:"volume_type"` + + // Organization is the owner of the volume + Organization string `json:"organization"` +} + +// ScalewayVolumePutDefinition represents a Scaleway volume with nullable fields (for PUT) +type ScalewayVolumePutDefinition struct { + Identifier *string `json:"id,omitempty"` + Size *uint64 `json:"size,omitempty"` + CreationDate *string `json:"creation_date,omitempty"` + ModificationDate *string `json:"modification_date,omitempty"` + Organization *string `json:"organization,omitempty"` + Name *string `json:"name,omitempty"` + Server struct { + Identifier *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + } `json:"server,omitempty"` + VolumeType *string `json:"volume_type,omitempty"` + ExportURI *string `json:"export_uri,omitempty"` +} + +// ScalewayImage represents a Scaleway Image +type ScalewayImage struct { + // Identifier is a unique identifier for the image + Identifier string `json:"id,omitempty"` + + // Name is a user-defined name for the image + Name string `json:"name,omitempty"` + + // CreationDate is the creation date of the image + CreationDate string `json:"creation_date,omitempty"` + + // ModificationDate is the date of the last modification of the image + ModificationDate string `json:"modification_date,omitempty"` + + // RootVolume is the root volume bound to the image + RootVolume ScalewayVolume `json:"root_volume,omitempty"` + + // Public is true for public images and false for user images + Public bool `json:"public,omitempty"` + + // Bootscript is the bootscript bound to the image + DefaultBootscript *ScalewayBootscript `json:"default_bootscript,omitempty"` + + // Organization is the owner of the image + Organization string `json:"organization,omitempty"` + + // Arch is the architecture target of the image + Arch string `json:"arch,omitempty"` + + // FIXME: extra_volumes +} + +// ScalewayImageIdentifier represents a Scaleway Image Identifier +type ScalewayImageIdentifier struct { + Identifier string + Arch string + Region string + Owner string +} + +// ScalewayOneImage represents the response of a GET /images/UUID API call +type ScalewayOneImage struct { + Image ScalewayImage `json:"image,omitempty"` +} + +// ScalewayImages represents a group of Scaleway images +type ScalewayImages struct { + // Images holds scaleway images of the response + Images []ScalewayImage `json:"images,omitempty"` +} + +// ScalewaySnapshot represents a Scaleway Snapshot +type ScalewaySnapshot struct { + // Identifier is a unique identifier for the snapshot + Identifier string `json:"id,omitempty"` + + // Name is a user-defined name for the snapshot + Name string `json:"name,omitempty"` + + // CreationDate is the creation date of the snapshot + CreationDate string `json:"creation_date,omitempty"` + + // ModificationDate is the date of the last modification of the snapshot + ModificationDate string `json:"modification_date,omitempty"` + + // Size is the allocated size of the volume + Size uint64 `json:"size,omitempty"` + + // Organization is the owner of the snapshot + Organization string `json:"organization"` + + // State is the current state of the snapshot + State string `json:"state"` + + // VolumeType is the kind of volume behind the snapshot + VolumeType string `json:"volume_type"` + + // BaseVolume is the volume from which the snapshot inherits + BaseVolume ScalewayVolume `json:"base_volume,omitempty"` +} + +// ScalewayOneSnapshot represents the response of a GET /snapshots/UUID API call +type ScalewayOneSnapshot struct { + Snapshot ScalewaySnapshot `json:"snapshot,omitempty"` +} + +// ScalewaySnapshots represents a group of Scaleway snapshots +type ScalewaySnapshots struct { + // Snapshots holds scaleway snapshots of the response + Snapshots []ScalewaySnapshot `json:"snapshots,omitempty"` +} + +// ScalewayBootscript represents a Scaleway Bootscript +type ScalewayBootscript struct { + Bootcmdargs string `json:"bootcmdargs,omitempty"` + Dtb string `json:"dtb,omitempty"` + Initrd string `json:"initrd,omitempty"` + Kernel string `json:"kernel,omitempty"` + + // Arch is the architecture target of the bootscript + Arch string `json:"architecture,omitempty"` + + // Identifier is a unique identifier for the bootscript + Identifier string `json:"id,omitempty"` + + // Organization is the owner of the bootscript + Organization string `json:"organization,omitempty"` + + // Name is a user-defined name for the bootscript + Title string `json:"title,omitempty"` + + // Public is true for public bootscripts and false for user bootscripts + Public bool `json:"public,omitempty"` + + Default bool `json:"default,omitempty"` +} + +// ScalewayOneBootscript represents the response of a GET /bootscripts/UUID API call +type ScalewayOneBootscript struct { + Bootscript ScalewayBootscript `json:"bootscript,omitempty"` +} + +// ScalewayBootscripts represents a group of Scaleway bootscripts +type ScalewayBootscripts struct { + // Bootscripts holds Scaleway bootscripts of the response + Bootscripts []ScalewayBootscript `json:"bootscripts,omitempty"` +} + +// ScalewayTask represents a Scaleway Task +type ScalewayTask struct { + // Identifier is a unique identifier for the task + Identifier string `json:"id,omitempty"` + + // StartDate is the start date of the task + StartDate string `json:"started_at,omitempty"` + + // TerminationDate is the termination date of the task + TerminationDate string `json:"terminated_at,omitempty"` + + HrefFrom string `json:"href_from,omitempty"` + + Description string `json:"description,omitempty"` + + Status string `json:"status,omitempty"` + + Progress int `json:"progress,omitempty"` +} + +// ScalewayOneTask represents the response of a GET /tasks/UUID API call +type ScalewayOneTask struct { + Task ScalewayTask `json:"task,omitempty"` +} + +// ScalewayTasks represents a group of Scaleway tasks +type ScalewayTasks struct { + // Tasks holds scaleway tasks of the response + Tasks []ScalewayTask `json:"tasks,omitempty"` +} + +// ScalewaySecurityGroupRule definition +type ScalewaySecurityGroupRule struct { + Direction string `json:"direction"` + Protocol string `json:"protocol"` + IPRange string `json:"ip_range"` + DestPortFrom int `json:"dest_port_from,omitempty"` + Action string `json:"action"` + Position int `json:"position"` + DestPortTo string `json:"dest_port_to"` + Editable bool `json:"editable"` + ID string `json:"id"` +} + +// ScalewayGetSecurityGroupRules represents the response of a GET /security_group/{groupID}/rules +type ScalewayGetSecurityGroupRules struct { + Rules []ScalewaySecurityGroupRule `json:"rules"` +} + +// ScalewayGetSecurityGroupRule represents the response of a GET /security_group/{groupID}/rules/{ruleID} +type ScalewayGetSecurityGroupRule struct { + Rules ScalewaySecurityGroupRule `json:"rule"` +} + +// ScalewayNewSecurityGroupRule definition POST/PUT request /security_group/{groupID} +type ScalewayNewSecurityGroupRule struct { + Action string `json:"action"` + Direction string `json:"direction"` + IPRange string `json:"ip_range"` + Protocol string `json:"protocol"` + DestPortFrom int `json:"dest_port_from,omitempty"` +} + +// ScalewaySecurityGroups definition +type ScalewaySecurityGroups struct { + Description string `json:"description"` + ID string `json:"id"` + Organization string `json:"organization"` + Name string `json:"name"` + Servers []ScalewaySecurityGroup `json:"servers"` + EnableDefaultSecurity bool `json:"enable_default_security"` + OrganizationDefault bool `json:"organization_default"` +} + +// ScalewayGetSecurityGroups represents the response of a GET /security_groups/ +type ScalewayGetSecurityGroups struct { + SecurityGroups []ScalewaySecurityGroups `json:"security_groups"` +} + +// ScalewayGetSecurityGroup represents the response of a GET /security_groups/{groupID} +type ScalewayGetSecurityGroup struct { + SecurityGroups ScalewaySecurityGroups `json:"security_group"` +} + +// ScalewayIPDefinition represents the IP's fields +type ScalewayIPDefinition struct { + Organization string `json:"organization"` + Reverse *string `json:"reverse"` + ID string `json:"id"` + Server *struct { + Identifier string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + } `json:"server"` + Address string `json:"address"` +} + +// ScalewayGetIPS represents the response of a GET /ips/ +type ScalewayGetIPS struct { + IPS []ScalewayIPDefinition `json:"ips"` +} + +// ScalewayGetIP represents the response of a GET /ips/{id_ip} +type ScalewayGetIP struct { + IP ScalewayIPDefinition `json:"ip"` +} + +// ScalewaySecurityGroup represents a Scaleway security group +type ScalewaySecurityGroup struct { + // Identifier is a unique identifier for the security group + Identifier string `json:"id,omitempty"` + + // Name is the user-defined name of the security group + Name string `json:"name,omitempty"` +} + +// ScalewayNewSecurityGroup definition POST request /security_groups +type ScalewayNewSecurityGroup struct { + Organization string `json:"organization"` + Name string `json:"name"` + Description string `json:"description"` +} + +// ScalewayUpdateSecurityGroup definition PUT request /security_groups +type ScalewayUpdateSecurityGroup struct { + Organization string `json:"organization"` + Name string `json:"name"` + Description string `json:"description"` + OrganizationDefault bool `json:"organization_default"` +} + +// ScalewayServer represents a Scaleway server +type ScalewayServer struct { + // Arch is the architecture target of the server + Arch string `json:"arch,omitempty"` + + // Identifier is a unique identifier for the server + Identifier string `json:"id,omitempty"` + + // Name is the user-defined name of the server + Name string `json:"name,omitempty"` + + // CreationDate is the creation date of the server + CreationDate string `json:"creation_date,omitempty"` + + // ModificationDate is the date of the last modification of the server + ModificationDate string `json:"modification_date,omitempty"` + + // Image is the image used by the server + Image ScalewayImage `json:"image,omitempty"` + + // DynamicIPRequired is a flag that defines a server with a dynamic ip address attached + DynamicIPRequired *bool `json:"dynamic_ip_required,omitempty"` + + // PublicIP is the public IP address bound to the server + PublicAddress ScalewayIPAddress `json:"public_ip,omitempty"` + + // State is the current status of the server + State string `json:"state,omitempty"` + + // StateDetail is the detailed status of the server + StateDetail string `json:"state_detail,omitempty"` + + // PrivateIP represents the private IPV4 attached to the server (changes on each boot) + PrivateIP string `json:"private_ip,omitempty"` + + // Bootscript is the unique identifier of the selected bootscript + Bootscript *ScalewayBootscript `json:"bootscript,omitempty"` + + // Hostname represents the ServerName in a format compatible with unix's hostname + Hostname string `json:"hostname,omitempty"` + + // Tags represents user-defined tags + Tags []string `json:"tags,omitempty"` + + // Volumes are the attached volumes + Volumes map[string]ScalewayVolume `json:"volumes,omitempty"` + + // SecurityGroup is the selected security group object + SecurityGroup ScalewaySecurityGroup `json:"security_group,omitempty"` + + // Organization is the owner of the server + Organization string `json:"organization,omitempty"` + + // CommercialType is the commercial type of the server (i.e: C1, C2[SML], VC1S) + CommercialType string `json:"commercial_type,omitempty"` + + // Location of the server + Location struct { + Platform string `json:"platform_id,omitempty"` + Chassis string `json:"chassis_id,omitempty"` + Cluster string `json:"cluster_id,omitempty"` + Hypervisor string `json:"hypervisor_id,omitempty"` + Blade string `json:"blade_id,omitempty"` + Node string `json:"node_id,omitempty"` + ZoneID string `json:"zone_id,omitempty"` + } `json:"location,omitempty"` + + IPV6 *ScalewayIPV6Definition `json:"ipv6,omitempty"` + + EnableIPV6 bool `json:"enable_ipv6,omitempty"` + + // This fields are not returned by the API, we generate it + DNSPublic string `json:"dns_public,omitempty"` + DNSPrivate string `json:"dns_private,omitempty"` +} + +// ScalewayIPV6Definition represents a Scaleway ipv6 +type ScalewayIPV6Definition struct { + Netmask string `json:"netmask"` + Gateway string `json:"gateway"` + Address string `json:"address"` +} + +// ScalewayServerPatchDefinition represents a Scaleway server with nullable fields (for PATCH) +type ScalewayServerPatchDefinition struct { + Arch *string `json:"arch,omitempty"` + Name *string `json:"name,omitempty"` + CreationDate *string `json:"creation_date,omitempty"` + ModificationDate *string `json:"modification_date,omitempty"` + Image *ScalewayImage `json:"image,omitempty"` + DynamicIPRequired *bool `json:"dynamic_ip_required,omitempty"` + PublicAddress *ScalewayIPAddress `json:"public_ip,omitempty"` + State *string `json:"state,omitempty"` + StateDetail *string `json:"state_detail,omitempty"` + PrivateIP *string `json:"private_ip,omitempty"` + Bootscript *string `json:"bootscript,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Volumes *map[string]ScalewayVolume `json:"volumes,omitempty"` + SecurityGroup *ScalewaySecurityGroup `json:"security_group,omitempty"` + Organization *string `json:"organization,omitempty"` + Tags *[]string `json:"tags,omitempty"` + IPV6 *ScalewayIPV6Definition `json:"ipv6,omitempty"` + EnableIPV6 *bool `json:"enable_ipv6,omitempty"` +} + +// ScalewayServerDefinition represents a Scaleway server with image definition +type ScalewayServerDefinition struct { + // Name is the user-defined name of the server + Name string `json:"name"` + + // Image is the image used by the server + Image *string `json:"image,omitempty"` + + // Volumes are the attached volumes + Volumes map[string]string `json:"volumes,omitempty"` + + // DynamicIPRequired is a flag that defines a server with a dynamic ip address attached + DynamicIPRequired *bool `json:"dynamic_ip_required,omitempty"` + + // Bootscript is the bootscript used by the server + Bootscript *string `json:"bootscript"` + + // Tags are the metadata tags attached to the server + Tags []string `json:"tags,omitempty"` + + // Organization is the owner of the server + Organization string `json:"organization"` + + // CommercialType is the commercial type of the server (i.e: C1, C2[SML], VC1S) + CommercialType string `json:"commercial_type"` + + PublicIP string `json:"public_ip,omitempty"` + + EnableIPV6 bool `json:"enable_ipv6,omitempty"` + + SecurityGroup string `json:"security_group,omitempty"` +} + +// ScalewayOneServer represents the response of a GET /servers/UUID API call +type ScalewayOneServer struct { + Server ScalewayServer `json:"server,omitempty"` +} + +// ScalewayServers represents a group of Scaleway servers +type ScalewayServers struct { + // Servers holds scaleway servers of the response + Servers []ScalewayServer `json:"servers,omitempty"` +} + +// ScalewayServerAction represents an action to perform on a Scaleway server +type ScalewayServerAction struct { + // Action is the name of the action to trigger + Action string `json:"action,omitempty"` +} + +// ScalewaySnapshotDefinition represents a Scaleway snapshot definition +type ScalewaySnapshotDefinition struct { + VolumeIDentifier string `json:"volume_id"` + Name string `json:"name,omitempty"` + Organization string `json:"organization"` +} + +// ScalewayImageDefinition represents a Scaleway image definition +type ScalewayImageDefinition struct { + SnapshotIDentifier string `json:"root_volume"` + Name string `json:"name,omitempty"` + Organization string `json:"organization"` + Arch string `json:"arch"` + DefaultBootscript *string `json:"default_bootscript,omitempty"` +} + +// ScalewayRoleDefinition represents a Scaleway Token UserId Role +type ScalewayRoleDefinition struct { + Organization ScalewayOrganizationDefinition `json:"organization,omitempty"` + Role string `json:"role,omitempty"` +} + +// ScalewayTokenDefinition represents a Scaleway Token +type ScalewayTokenDefinition struct { + UserID string `json:"user_id"` + Description string `json:"description,omitempty"` + Roles ScalewayRoleDefinition `json:"roles"` + Expires string `json:"expires"` + InheritsUsersPerms bool `json:"inherits_user_perms"` + ID string `json:"id"` +} + +// ScalewayTokensDefinition represents a Scaleway Tokens +type ScalewayTokensDefinition struct { + Token ScalewayTokenDefinition `json:"token"` +} + +// ScalewayGetTokens represents a list of Scaleway Tokens +type ScalewayGetTokens struct { + Tokens []ScalewayTokenDefinition `json:"tokens"` +} + +// ScalewayContainerData represents a Scaleway container data (S3) +type ScalewayContainerData struct { + LastModified string `json:"last_modified"` + Name string `json:"name"` + Size string `json:"size"` +} + +// ScalewayGetContainerDatas represents a list of Scaleway containers data (S3) +type ScalewayGetContainerDatas struct { + Container []ScalewayContainerData `json:"container"` +} + +// ScalewayContainer represents a Scaleway container (S3) +type ScalewayContainer struct { + ScalewayOrganizationDefinition `json:"organization"` + Name string `json:"name"` + Size string `json:"size"` +} + +// ScalewayGetContainers represents a list of Scaleway containers (S3) +type ScalewayGetContainers struct { + Containers []ScalewayContainer `json:"containers"` +} + +// ScalewayConnectResponse represents the answer from POST /tokens +type ScalewayConnectResponse struct { + Token ScalewayTokenDefinition `json:"token"` +} + +// ScalewayConnect represents the data to connect +type ScalewayConnect struct { + Email string `json:"email"` + Password string `json:"password"` + Description string `json:"description"` + Expires bool `json:"expires"` +} + +// ScalewayOrganizationDefinition represents a Scaleway Organization +type ScalewayOrganizationDefinition struct { + ID string `json:"id"` + Name string `json:"name"` + Users []ScalewayUserDefinition `json:"users"` +} + +// ScalewayOrganizationsDefinition represents a Scaleway Organizations +type ScalewayOrganizationsDefinition struct { + Organizations []ScalewayOrganizationDefinition `json:"organizations"` +} + +// ScalewayUserDefinition represents a Scaleway User +type ScalewayUserDefinition struct { + Email string `json:"email"` + Firstname string `json:"firstname"` + Fullname string `json:"fullname"` + ID string `json:"id"` + Lastname string `json:"lastname"` + Organizations []ScalewayOrganizationDefinition `json:"organizations"` + Roles []ScalewayRoleDefinition `json:"roles"` + SSHPublicKeys []ScalewayKeyDefinition `json:"ssh_public_keys"` +} + +// ScalewayUsersDefinition represents the response of a GET /user +type ScalewayUsersDefinition struct { + User ScalewayUserDefinition `json:"user"` +} + +// ScalewayKeyDefinition represents a key +type ScalewayKeyDefinition struct { + Key string `json:"key"` + Fingerprint string `json:"fingerprint,omitempty"` +} + +// ScalewayUserPatchSSHKeyDefinition represents a User Patch +type ScalewayUserPatchSSHKeyDefinition struct { + SSHPublicKeys []ScalewayKeyDefinition `json:"ssh_public_keys"` +} + +// ScalewayDashboardResp represents a dashboard received from the API +type ScalewayDashboardResp struct { + Dashboard ScalewayDashboard +} + +// ScalewayDashboard represents a dashboard +type ScalewayDashboard struct { + VolumesCount int `json:"volumes_count"` + RunningServersCount int `json:"running_servers_count"` + ImagesCount int `json:"images_count"` + SnapshotsCount int `json:"snapshots_count"` + ServersCount int `json:"servers_count"` + IPsCount int `json:"ips_count"` +} + +// ScalewayPermissions represents the response of GET /permissions +type ScalewayPermissions map[string]ScalewayPermCategory + +// ScalewayPermCategory represents ScalewayPermissions's fields +type ScalewayPermCategory map[string][]string + +// ScalewayPermissionDefinition represents the permissions +type ScalewayPermissionDefinition struct { + Permissions ScalewayPermissions `json:"permissions"` +} + +// ScalewayUserdatas represents the response of a GET /user_data +type ScalewayUserdatas struct { + UserData []string `json:"user_data"` +} + +// ScalewayQuota represents a map of quota (name, value) +type ScalewayQuota map[string]int + +// ScalewayGetQuotas represents the response of GET /organizations/{orga_id}/quotas +type ScalewayGetQuotas struct { + Quotas ScalewayQuota `json:"quotas"` +} + +// ScalewayUserdata represents []byte +type ScalewayUserdata []byte + +// FuncMap used for json inspection +var FuncMap = template.FuncMap{ + "json": func(v interface{}) string { + a, _ := json.Marshal(v) + return string(a) + }, +} + +// MarketLocalImageDefinition represents localImage of marketplace version +type MarketLocalImageDefinition struct { + Arch string `json:"arch"` + ID string `json:"id"` + Zone string `json:"zone"` +} + +// MarketLocalImages represents an array of local images +type MarketLocalImages struct { + LocalImages []MarketLocalImageDefinition `json:"local_images"` +} + +// MarketLocalImage represents local image +type MarketLocalImage struct { + LocalImages MarketLocalImageDefinition `json:"local_image"` +} + +// MarketVersionDefinition represents version of marketplace image +type MarketVersionDefinition struct { + CreationDate string `json:"creation_date"` + ID string `json:"id"` + Image struct { + ID string `json:"id"` + Name string `json:"name"` + } `json:"image"` + ModificationDate string `json:"modification_date"` + Name string `json:"name"` + MarketLocalImages +} + +// MarketVersions represents an array of marketplace image versions +type MarketVersions struct { + Versions []MarketVersionDefinition `json:"versions"` +} + +// MarketVersion represents version of marketplace image +type MarketVersion struct { + Version MarketVersionDefinition `json:"version"` +} + +// MarketImage represents MarketPlace image +type MarketImage struct { + Categories []string `json:"categories"` + CreationDate string `json:"creation_date"` + CurrentPublicVersion string `json:"current_public_version"` + Description string `json:"description"` + ID string `json:"id"` + Logo string `json:"logo"` + ModificationDate string `json:"modification_date"` + Name string `json:"name"` + Organization struct { + ID string `json:"id"` + Name string `json:"name"` + } `json:"organization"` + Public bool `json:"-"` + MarketVersions +} + +// MarketImages represents MarketPlace images +type MarketImages struct { + Images []MarketImage `json:"images"` +} + +// NewScalewayAPI creates a ready-to-use ScalewayAPI client +func NewScalewayAPI(organization, token, userAgent, region string, options ...func(*ScalewayAPI)) (*ScalewayAPI, error) { + s := &ScalewayAPI{ + // exposed + Organization: organization, + Token: token, + Logger: NewDefaultLogger(), + + // internal + client: &http.Client{}, + verbose: os.Getenv("SCW_VERBOSE_API") != "", + password: "", + userAgent: userAgent, + } + for _, option := range options { + option(s) + } + cache, err := NewScalewayCache(func() { s.Logger.Debugf("Writing cache file to disk") }) + if err != nil { + return nil, err + } + s.Cache = cache + if os.Getenv("SCW_TLSVERIFY") == "0" { + s.client.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + } + switch region { + case "par1", "": + s.computeAPI = ComputeAPIPar1 + case "ams1": + s.computeAPI = ComputeAPIAms1 + default: + return nil, fmt.Errorf("%s isn't a valid region", region) + } + s.Region = region + if url := os.Getenv("SCW_COMPUTE_API"); url != "" { + s.computeAPI = url + } + return s, nil +} + +// ClearCache clears the cache +func (s *ScalewayAPI) ClearCache() { + s.Cache.Clear() +} + +// Sync flushes out the cache to the disk +func (s *ScalewayAPI) Sync() { + s.Cache.Save() +} + +func (s *ScalewayAPI) response(method, uri string, content io.Reader) (resp *http.Response, err error) { + var ( + req *http.Request + ) + + req, err = http.NewRequest(method, uri, content) + if err != nil { + err = fmt.Errorf("response %s %s", method, uri) + return + } + req.Header.Set("X-Auth-Token", s.Token) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", s.userAgent) + s.LogHTTP(req) + if s.verbose { + dump, _ := httputil.DumpRequest(req, true) + s.Debugf("%v", string(dump)) + } else { + s.Debugf("[%s]: %v", method, uri) + } + resp, err = s.client.Do(req) + return +} + +// GetResponsePaginate fetchs all resources and returns an http.Response object for the requested resource +func (s *ScalewayAPI) GetResponsePaginate(apiURL, resource string, values url.Values) (*http.Response, error) { + resp, err := s.response("HEAD", fmt.Sprintf("%s/%s?%s", strings.TrimRight(apiURL, "/"), resource, values.Encode()), nil) + if err != nil { + return nil, err + } + + count := resp.Header.Get("X-Total-Count") + var maxElem int + if count == "" { + maxElem = 0 + } else { + maxElem, err = strconv.Atoi(count) + if err != nil { + return nil, err + } + } + + get := maxElem / perPage + if (float32(maxElem) / perPage) > float32(get) { + get++ + } + + if get <= 1 { // If there is 0 or 1 page of result, the response is not paginated + if len(values) == 0 { + return s.response("GET", fmt.Sprintf("%s/%s", strings.TrimRight(apiURL, "/"), resource), nil) + } + return s.response("GET", fmt.Sprintf("%s/%s?%s", strings.TrimRight(apiURL, "/"), resource, values.Encode()), nil) + } + + fetchAll := !(values.Get("per_page") != "" || values.Get("page") != "") + if fetchAll { + var g errgroup.Group + + ch := make(chan *http.Response, get) + for i := 1; i <= get; i++ { + i := i // closure tricks + g.Go(func() (err error) { + var resp *http.Response + + val := url.Values{} + val.Set("per_page", fmt.Sprintf("%v", perPage)) + val.Set("page", fmt.Sprintf("%v", i)) + resp, err = s.response("GET", fmt.Sprintf("%s/%s?%s", strings.TrimRight(apiURL, "/"), resource, val.Encode()), nil) + ch <- resp + return + }) + } + if err = g.Wait(); err != nil { + return nil, err + } + newBody := make(map[string][]json.RawMessage) + body := make(map[string][]json.RawMessage) + key := "" + for i := 0; i < get; i++ { + res := <-ch + if res.StatusCode != http.StatusOK { + return res, nil + } + content, err := ioutil.ReadAll(res.Body) + res.Body.Close() + if err != nil { + return nil, err + } + if err := json.Unmarshal(content, &body); err != nil { + return nil, err + } + + if i == 0 { + resp = res + for k := range body { + key = k + break + } + } + newBody[key] = append(newBody[key], body[key]...) + } + payload := new(bytes.Buffer) + if err := json.NewEncoder(payload).Encode(newBody); err != nil { + return nil, err + } + resp.Body = ioutil.NopCloser(payload) + } else { + resp, err = s.response("GET", fmt.Sprintf("%s/%s?%s", strings.TrimRight(apiURL, "/"), resource, values.Encode()), nil) + } + return resp, err +} + +// PostResponse returns an http.Response object for the updated resource +func (s *ScalewayAPI) PostResponse(apiURL, resource string, data interface{}) (*http.Response, error) { + payload := new(bytes.Buffer) + if err := json.NewEncoder(payload).Encode(data); err != nil { + return nil, err + } + return s.response("POST", fmt.Sprintf("%s/%s", strings.TrimRight(apiURL, "/"), resource), payload) +} + +// PatchResponse returns an http.Response object for the updated resource +func (s *ScalewayAPI) PatchResponse(apiURL, resource string, data interface{}) (*http.Response, error) { + payload := new(bytes.Buffer) + if err := json.NewEncoder(payload).Encode(data); err != nil { + return nil, err + } + return s.response("PATCH", fmt.Sprintf("%s/%s", strings.TrimRight(apiURL, "/"), resource), payload) +} + +// PutResponse returns an http.Response object for the updated resource +func (s *ScalewayAPI) PutResponse(apiURL, resource string, data interface{}) (*http.Response, error) { + payload := new(bytes.Buffer) + if err := json.NewEncoder(payload).Encode(data); err != nil { + return nil, err + } + return s.response("PUT", fmt.Sprintf("%s/%s", strings.TrimRight(apiURL, "/"), resource), payload) +} + +// DeleteResponse returns an http.Response object for the deleted resource +func (s *ScalewayAPI) DeleteResponse(apiURL, resource string) (*http.Response, error) { + return s.response("DELETE", fmt.Sprintf("%s/%s", strings.TrimRight(apiURL, "/"), resource), nil) +} + +// handleHTTPError checks the statusCode and displays the error +func (s *ScalewayAPI) handleHTTPError(goodStatusCode []int, resp *http.Response) ([]byte, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if s.verbose { + resp.Body = ioutil.NopCloser(bytes.NewBuffer(body)) + dump, err := httputil.DumpResponse(resp, true) + if err == nil { + var js bytes.Buffer + + err = json.Indent(&js, body, "", " ") + if err != nil { + s.Debugf("[Response]: [%v]\n%v", resp.StatusCode, string(dump)) + } else { + s.Debugf("[Response]: [%v]\n%v", resp.StatusCode, js.String()) + } + } + } else { + s.Debugf("[Response]: [%v]\n%v", resp.StatusCode, string(body)) + } + + if resp.StatusCode >= http.StatusInternalServerError { + return nil, errors.New(string(body)) + } + good := false + for _, code := range goodStatusCode { + if code == resp.StatusCode { + good = true + } + } + if !good { + var scwError ScalewayAPIError + + if err := json.Unmarshal(body, &scwError); err != nil { + return nil, err + } + scwError.StatusCode = resp.StatusCode + s.Debugf("%s", scwError.Error()) + return nil, scwError + } + return body, nil +} + +func (s *ScalewayAPI) fetchServers(api string, query url.Values, out chan<- ScalewayServers) func() error { + return func() error { + resp, err := s.GetResponsePaginate(api, "servers", query) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return err + } + var servers ScalewayServers + + if err = json.Unmarshal(body, &servers); err != nil { + return err + } + out <- servers + return nil + } +} + +// GetServers gets the list of servers from the ScalewayAPI +func (s *ScalewayAPI) GetServers(all bool, limit int) (*[]ScalewayServer, error) { + query := url.Values{} + if !all { + query.Set("state", "running") + } + if limit > 0 { + // FIXME: wait for the API to be ready + // query.Set("per_page", strconv.Itoa(limit)) + panic("Not implemented yet") + } + if all && limit == 0 { + s.Cache.ClearServers() + } + var ( + g errgroup.Group + apis = []string{ + ComputeAPIPar1, + ComputeAPIAms1, + } + ) + + serverChan := make(chan ScalewayServers, 2) + for _, api := range apis { + g.Go(s.fetchServers(api, query, serverChan)) + } + + if err := g.Wait(); err != nil { + return nil, err + } + close(serverChan) + var servers ScalewayServers + + for server := range serverChan { + servers.Servers = append(servers.Servers, server.Servers...) + } + + for i, server := range servers.Servers { + servers.Servers[i].DNSPublic = server.Identifier + URLPublicDNS + servers.Servers[i].DNSPrivate = server.Identifier + URLPrivateDNS + s.Cache.InsertServer(server.Identifier, server.Location.ZoneID, server.Arch, server.Organization, server.Name) + } + return &servers.Servers, nil +} + +// ScalewaySortServers represents a wrapper to sort by CreationDate the servers +type ScalewaySortServers []ScalewayServer + +func (s ScalewaySortServers) Len() int { + return len(s) +} + +func (s ScalewaySortServers) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s ScalewaySortServers) Less(i, j int) bool { + date1, _ := time.Parse("2006-01-02T15:04:05.000000+00:00", s[i].CreationDate) + date2, _ := time.Parse("2006-01-02T15:04:05.000000+00:00", s[j].CreationDate) + return date2.Before(date1) +} + +// GetServer gets a server from the ScalewayAPI +func (s *ScalewayAPI) GetServer(serverID string) (*ScalewayServer, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "servers/"+serverID, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + + var oneServer ScalewayOneServer + + if err = json.Unmarshal(body, &oneServer); err != nil { + return nil, err + } + // FIXME arch, owner, title + oneServer.Server.DNSPublic = oneServer.Server.Identifier + URLPublicDNS + oneServer.Server.DNSPrivate = oneServer.Server.Identifier + URLPrivateDNS + s.Cache.InsertServer(oneServer.Server.Identifier, oneServer.Server.Location.ZoneID, oneServer.Server.Arch, oneServer.Server.Organization, oneServer.Server.Name) + return &oneServer.Server, nil +} + +// PostServerAction posts an action on a server +func (s *ScalewayAPI) PostServerAction(serverID, action string) error { + data := ScalewayServerAction{ + Action: action, + } + resp, err := s.PostResponse(s.computeAPI, fmt.Sprintf("servers/%s/action", serverID), data) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusAccepted}, resp) + return err +} + +// DeleteServer deletes a server +func (s *ScalewayAPI) DeleteServer(serverID string) error { + defer s.Cache.RemoveServer(serverID) + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("servers/%s", serverID)) + if err != nil { + return err + } + defer resp.Body.Close() + + if _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp); err != nil { + return err + } + return nil +} + +// PostServer creates a new server +func (s *ScalewayAPI) PostServer(definition ScalewayServerDefinition) (string, error) { + definition.Organization = s.Organization + + resp, err := s.PostResponse(s.computeAPI, "servers", definition) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusCreated}, resp) + if err != nil { + return "", err + } + var server ScalewayOneServer + + if err = json.Unmarshal(body, &server); err != nil { + return "", err + } + // FIXME arch, owner, title + s.Cache.InsertServer(server.Server.Identifier, server.Server.Location.ZoneID, server.Server.Arch, server.Server.Organization, server.Server.Name) + return server.Server.Identifier, nil +} + +// PatchUserSSHKey updates a user +func (s *ScalewayAPI) PatchUserSSHKey(UserID string, definition ScalewayUserPatchSSHKeyDefinition) error { + resp, err := s.PatchResponse(AccountAPI, fmt.Sprintf("users/%s", UserID), definition) + if err != nil { + return err + } + + defer resp.Body.Close() + + if _, err := s.handleHTTPError([]int{http.StatusOK}, resp); err != nil { + return err + } + return nil +} + +// PatchServer updates a server +func (s *ScalewayAPI) PatchServer(serverID string, definition ScalewayServerPatchDefinition) error { + resp, err := s.PatchResponse(s.computeAPI, fmt.Sprintf("servers/%s", serverID), definition) + if err != nil { + return err + } + defer resp.Body.Close() + + if _, err := s.handleHTTPError([]int{http.StatusOK}, resp); err != nil { + return err + } + return nil +} + +// PostSnapshot creates a new snapshot +func (s *ScalewayAPI) PostSnapshot(volumeID string, name string) (string, error) { + definition := ScalewaySnapshotDefinition{ + VolumeIDentifier: volumeID, + Name: name, + Organization: s.Organization, + } + resp, err := s.PostResponse(s.computeAPI, "snapshots", definition) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusCreated}, resp) + if err != nil { + return "", err + } + var snapshot ScalewayOneSnapshot + + if err = json.Unmarshal(body, &snapshot); err != nil { + return "", err + } + // FIXME arch, owner, title + s.Cache.InsertSnapshot(snapshot.Snapshot.Identifier, "", "", snapshot.Snapshot.Organization, snapshot.Snapshot.Name) + return snapshot.Snapshot.Identifier, nil +} + +// PostImage creates a new image +func (s *ScalewayAPI) PostImage(volumeID string, name string, bootscript string, arch string) (string, error) { + definition := ScalewayImageDefinition{ + SnapshotIDentifier: volumeID, + Name: name, + Organization: s.Organization, + Arch: arch, + } + if bootscript != "" { + definition.DefaultBootscript = &bootscript + } + + resp, err := s.PostResponse(s.computeAPI, "images", definition) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusCreated}, resp) + if err != nil { + return "", err + } + var image ScalewayOneImage + + if err = json.Unmarshal(body, &image); err != nil { + return "", err + } + // FIXME region, arch, owner, title + s.Cache.InsertImage(image.Image.Identifier, "", image.Image.Arch, image.Image.Organization, image.Image.Name, "") + return image.Image.Identifier, nil +} + +// PostVolume creates a new volume +func (s *ScalewayAPI) PostVolume(definition ScalewayVolumeDefinition) (string, error) { + definition.Organization = s.Organization + if definition.Type == "" { + definition.Type = "l_ssd" + } + + resp, err := s.PostResponse(s.computeAPI, "volumes", definition) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusCreated}, resp) + if err != nil { + return "", err + } + var volume ScalewayOneVolume + + if err = json.Unmarshal(body, &volume); err != nil { + return "", err + } + // FIXME: s.Cache.InsertVolume(volume.Volume.Identifier, volume.Volume.Name) + return volume.Volume.Identifier, nil +} + +// PutVolume updates a volume +func (s *ScalewayAPI) PutVolume(volumeID string, definition ScalewayVolumePutDefinition) error { + resp, err := s.PutResponse(s.computeAPI, fmt.Sprintf("volumes/%s", volumeID), definition) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// ResolveServer attempts to find a matching Identifier for the input string +func (s *ScalewayAPI) ResolveServer(needle string) (ScalewayResolverResults, error) { + servers, err := s.Cache.LookUpServers(needle, true) + if err != nil { + return servers, err + } + if len(servers) == 0 { + if _, err = s.GetServers(true, 0); err != nil { + return nil, err + } + servers, err = s.Cache.LookUpServers(needle, true) + } + return servers, err +} + +// ResolveVolume attempts to find a matching Identifier for the input string +func (s *ScalewayAPI) ResolveVolume(needle string) (ScalewayResolverResults, error) { + volumes, err := s.Cache.LookUpVolumes(needle, true) + if err != nil { + return volumes, err + } + if len(volumes) == 0 { + if _, err = s.GetVolumes(); err != nil { + return nil, err + } + volumes, err = s.Cache.LookUpVolumes(needle, true) + } + return volumes, err +} + +// ResolveSnapshot attempts to find a matching Identifier for the input string +func (s *ScalewayAPI) ResolveSnapshot(needle string) (ScalewayResolverResults, error) { + snapshots, err := s.Cache.LookUpSnapshots(needle, true) + if err != nil { + return snapshots, err + } + if len(snapshots) == 0 { + if _, err = s.GetSnapshots(); err != nil { + return nil, err + } + snapshots, err = s.Cache.LookUpSnapshots(needle, true) + } + return snapshots, err +} + +// ResolveImage attempts to find a matching Identifier for the input string +func (s *ScalewayAPI) ResolveImage(needle string) (ScalewayResolverResults, error) { + images, err := s.Cache.LookUpImages(needle, true) + if err != nil { + return images, err + } + if len(images) == 0 { + if _, err = s.GetImages(); err != nil { + return nil, err + } + images, err = s.Cache.LookUpImages(needle, true) + } + return images, err +} + +// ResolveBootscript attempts to find a matching Identifier for the input string +func (s *ScalewayAPI) ResolveBootscript(needle string) (ScalewayResolverResults, error) { + bootscripts, err := s.Cache.LookUpBootscripts(needle, true) + if err != nil { + return bootscripts, err + } + if len(bootscripts) == 0 { + if _, err = s.GetBootscripts(); err != nil { + return nil, err + } + bootscripts, err = s.Cache.LookUpBootscripts(needle, true) + } + return bootscripts, err +} + +// GetImages gets the list of images from the ScalewayAPI +func (s *ScalewayAPI) GetImages() (*[]MarketImage, error) { + images, err := s.GetMarketPlaceImages("") + if err != nil { + return nil, err + } + s.Cache.ClearImages() + for i, image := range images.Images { + if image.CurrentPublicVersion != "" { + for _, version := range image.Versions { + if version.ID == image.CurrentPublicVersion { + for _, localImage := range version.LocalImages { + images.Images[i].Public = true + s.Cache.InsertImage(localImage.ID, localImage.Zone, localImage.Arch, image.Organization.ID, image.Name, image.CurrentPublicVersion) + } + } + } + } + } + values := url.Values{} + values.Set("organization", s.Organization) + resp, err := s.GetResponsePaginate(s.computeAPI, "images", values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var OrgaImages ScalewayImages + + if err = json.Unmarshal(body, &OrgaImages); err != nil { + return nil, err + } + + for _, orgaImage := range OrgaImages.Images { + images.Images = append(images.Images, MarketImage{ + Categories: []string{"MyImages"}, + CreationDate: orgaImage.CreationDate, + CurrentPublicVersion: orgaImage.Identifier, + ModificationDate: orgaImage.ModificationDate, + Name: orgaImage.Name, + Public: false, + MarketVersions: MarketVersions{ + Versions: []MarketVersionDefinition{ + { + CreationDate: orgaImage.CreationDate, + ID: orgaImage.Identifier, + ModificationDate: orgaImage.ModificationDate, + MarketLocalImages: MarketLocalImages{ + LocalImages: []MarketLocalImageDefinition{ + { + Arch: orgaImage.Arch, + ID: orgaImage.Identifier, + // TODO: fecth images from ams1 and par1 + Zone: s.Region, + }, + }, + }, + }, + }, + }, + }) + s.Cache.InsertImage(orgaImage.Identifier, s.Region, orgaImage.Arch, orgaImage.Organization, orgaImage.Name, "") + } + return &images.Images, nil +} + +// GetImage gets an image from the ScalewayAPI +func (s *ScalewayAPI) GetImage(imageID string) (*ScalewayImage, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "images/"+imageID, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var oneImage ScalewayOneImage + + if err = json.Unmarshal(body, &oneImage); err != nil { + return nil, err + } + // FIXME owner, title + s.Cache.InsertImage(oneImage.Image.Identifier, s.Region, oneImage.Image.Arch, oneImage.Image.Organization, oneImage.Image.Name, "") + return &oneImage.Image, nil +} + +// DeleteImage deletes a image +func (s *ScalewayAPI) DeleteImage(imageID string) error { + defer s.Cache.RemoveImage(imageID) + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("images/%s", imageID)) + if err != nil { + return err + } + defer resp.Body.Close() + + if _, err := s.handleHTTPError([]int{http.StatusNoContent}, resp); err != nil { + return err + } + return nil +} + +// DeleteSnapshot deletes a snapshot +func (s *ScalewayAPI) DeleteSnapshot(snapshotID string) error { + defer s.Cache.RemoveSnapshot(snapshotID) + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("snapshots/%s", snapshotID)) + if err != nil { + return err + } + defer resp.Body.Close() + + if _, err := s.handleHTTPError([]int{http.StatusNoContent}, resp); err != nil { + return err + } + return nil +} + +// DeleteVolume deletes a volume +func (s *ScalewayAPI) DeleteVolume(volumeID string) error { + defer s.Cache.RemoveVolume(volumeID) + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("volumes/%s", volumeID)) + if err != nil { + return err + } + defer resp.Body.Close() + + if _, err := s.handleHTTPError([]int{http.StatusNoContent}, resp); err != nil { + return err + } + return nil +} + +// GetSnapshots gets the list of snapshots from the ScalewayAPI +func (s *ScalewayAPI) GetSnapshots() (*[]ScalewaySnapshot, error) { + query := url.Values{} + s.Cache.ClearSnapshots() + + resp, err := s.GetResponsePaginate(s.computeAPI, "snapshots", query) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var snapshots ScalewaySnapshots + + if err = json.Unmarshal(body, &snapshots); err != nil { + return nil, err + } + for _, snapshot := range snapshots.Snapshots { + // FIXME region, arch, owner, title + s.Cache.InsertSnapshot(snapshot.Identifier, "", "", snapshot.Organization, snapshot.Name) + } + return &snapshots.Snapshots, nil +} + +// GetSnapshot gets a snapshot from the ScalewayAPI +func (s *ScalewayAPI) GetSnapshot(snapshotID string) (*ScalewaySnapshot, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "snapshots/"+snapshotID, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var oneSnapshot ScalewayOneSnapshot + + if err = json.Unmarshal(body, &oneSnapshot); err != nil { + return nil, err + } + // FIXME region, arch, owner, title + s.Cache.InsertSnapshot(oneSnapshot.Snapshot.Identifier, "", "", oneSnapshot.Snapshot.Organization, oneSnapshot.Snapshot.Name) + return &oneSnapshot.Snapshot, nil +} + +// GetVolumes gets the list of volumes from the ScalewayAPI +func (s *ScalewayAPI) GetVolumes() (*[]ScalewayVolume, error) { + query := url.Values{} + s.Cache.ClearVolumes() + + resp, err := s.GetResponsePaginate(s.computeAPI, "volumes", query) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + + var volumes ScalewayVolumes + + if err = json.Unmarshal(body, &volumes); err != nil { + return nil, err + } + for _, volume := range volumes.Volumes { + // FIXME region, arch, owner, title + s.Cache.InsertVolume(volume.Identifier, "", "", volume.Organization, volume.Name) + } + return &volumes.Volumes, nil +} + +// GetVolume gets a volume from the ScalewayAPI +func (s *ScalewayAPI) GetVolume(volumeID string) (*ScalewayVolume, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "volumes/"+volumeID, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var oneVolume ScalewayOneVolume + + if err = json.Unmarshal(body, &oneVolume); err != nil { + return nil, err + } + // FIXME region, arch, owner, title + s.Cache.InsertVolume(oneVolume.Volume.Identifier, "", "", oneVolume.Volume.Organization, oneVolume.Volume.Name) + return &oneVolume.Volume, nil +} + +// GetBootscripts gets the list of bootscripts from the ScalewayAPI +func (s *ScalewayAPI) GetBootscripts() (*[]ScalewayBootscript, error) { + query := url.Values{} + + s.Cache.ClearBootscripts() + resp, err := s.GetResponsePaginate(s.computeAPI, "bootscripts", query) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var bootscripts ScalewayBootscripts + + if err = json.Unmarshal(body, &bootscripts); err != nil { + return nil, err + } + for _, bootscript := range bootscripts.Bootscripts { + // FIXME region, arch, owner, title + s.Cache.InsertBootscript(bootscript.Identifier, "", bootscript.Arch, bootscript.Organization, bootscript.Title) + } + return &bootscripts.Bootscripts, nil +} + +// GetBootscript gets a bootscript from the ScalewayAPI +func (s *ScalewayAPI) GetBootscript(bootscriptID string) (*ScalewayBootscript, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "bootscripts/"+bootscriptID, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var oneBootscript ScalewayOneBootscript + + if err = json.Unmarshal(body, &oneBootscript); err != nil { + return nil, err + } + // FIXME region, arch, owner, title + s.Cache.InsertBootscript(oneBootscript.Bootscript.Identifier, "", oneBootscript.Bootscript.Arch, oneBootscript.Bootscript.Organization, oneBootscript.Bootscript.Title) + return &oneBootscript.Bootscript, nil +} + +// GetUserdatas gets list of userdata for a server +func (s *ScalewayAPI) GetUserdatas(serverID string, metadata bool) (*ScalewayUserdatas, error) { + var uri, endpoint string + + endpoint = s.computeAPI + if metadata { + uri = "/user_data" + endpoint = MetadataAPI + } else { + uri = fmt.Sprintf("servers/%s/user_data", serverID) + } + + resp, err := s.GetResponsePaginate(endpoint, uri, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var userdatas ScalewayUserdatas + + if err = json.Unmarshal(body, &userdatas); err != nil { + return nil, err + } + return &userdatas, nil +} + +func (s *ScalewayUserdata) String() string { + return string(*s) +} + +// GetUserdata gets a specific userdata for a server +func (s *ScalewayAPI) GetUserdata(serverID, key string, metadata bool) (*ScalewayUserdata, error) { + var uri, endpoint string + + endpoint = s.computeAPI + if metadata { + uri = fmt.Sprintf("/user_data/%s", key) + endpoint = MetadataAPI + } else { + uri = fmt.Sprintf("servers/%s/user_data/%s", serverID, key) + } + + var err error + resp, err := s.GetResponsePaginate(endpoint, uri, url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("no such user_data %q (%d)", key, resp.StatusCode) + } + var data ScalewayUserdata + data, err = ioutil.ReadAll(resp.Body) + return &data, err +} + +// PatchUserdata sets a user data +func (s *ScalewayAPI) PatchUserdata(serverID, key string, value []byte, metadata bool) error { + var resource, endpoint string + + endpoint = s.computeAPI + if metadata { + resource = fmt.Sprintf("/user_data/%s", key) + endpoint = MetadataAPI + } else { + resource = fmt.Sprintf("servers/%s/user_data/%s", serverID, key) + } + + uri := fmt.Sprintf("%s/%s", strings.TrimRight(endpoint, "/"), resource) + payload := new(bytes.Buffer) + payload.Write(value) + + req, err := http.NewRequest("PATCH", uri, payload) + if err != nil { + return err + } + + req.Header.Set("X-Auth-Token", s.Token) + req.Header.Set("Content-Type", "text/plain") + req.Header.Set("User-Agent", s.userAgent) + + s.LogHTTP(req) + + resp, err := s.client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusNoContent { + return nil + } + + return fmt.Errorf("cannot set user_data (%d)", resp.StatusCode) +} + +// DeleteUserdata deletes a server user_data +func (s *ScalewayAPI) DeleteUserdata(serverID, key string, metadata bool) error { + var url, endpoint string + + endpoint = s.computeAPI + if metadata { + url = fmt.Sprintf("/user_data/%s", key) + endpoint = MetadataAPI + } else { + url = fmt.Sprintf("servers/%s/user_data/%s", serverID, key) + } + + resp, err := s.DeleteResponse(endpoint, url) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// GetTasks get the list of tasks from the ScalewayAPI +func (s *ScalewayAPI) GetTasks() (*[]ScalewayTask, error) { + query := url.Values{} + resp, err := s.GetResponsePaginate(s.computeAPI, "tasks", query) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var tasks ScalewayTasks + + if err = json.Unmarshal(body, &tasks); err != nil { + return nil, err + } + return &tasks.Tasks, nil +} + +// CheckCredentials performs a dummy check to ensure we can contact the API +func (s *ScalewayAPI) CheckCredentials() error { + query := url.Values{} + + resp, err := s.GetResponsePaginate(AccountAPI, "tokens", query) + if err != nil { + return err + } + defer resp.Body.Close() + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return err + } + found := false + var tokens ScalewayGetTokens + + if err = json.Unmarshal(body, &tokens); err != nil { + return err + } + for _, token := range tokens.Tokens { + if token.ID == s.Token { + found = true + break + } + } + if !found { + return fmt.Errorf("Invalid token %v", s.Token) + } + return nil +} + +// GetUserID returns the userID +func (s *ScalewayAPI) GetUserID() (string, error) { + resp, err := s.GetResponsePaginate(AccountAPI, fmt.Sprintf("tokens/%s", s.Token), url.Values{}) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return "", err + } + var token ScalewayTokensDefinition + + if err = json.Unmarshal(body, &token); err != nil { + return "", err + } + return token.Token.UserID, nil +} + +// GetOrganization returns Organization +func (s *ScalewayAPI) GetOrganization() (*ScalewayOrganizationsDefinition, error) { + resp, err := s.GetResponsePaginate(AccountAPI, "organizations", url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var data ScalewayOrganizationsDefinition + + if err = json.Unmarshal(body, &data); err != nil { + return nil, err + } + return &data, nil +} + +// GetUser returns the user +func (s *ScalewayAPI) GetUser() (*ScalewayUserDefinition, error) { + userID, err := s.GetUserID() + if err != nil { + return nil, err + } + resp, err := s.GetResponsePaginate(AccountAPI, fmt.Sprintf("users/%s", userID), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var user ScalewayUsersDefinition + + if err = json.Unmarshal(body, &user); err != nil { + return nil, err + } + return &user.User, nil +} + +// GetPermissions returns the permissions +func (s *ScalewayAPI) GetPermissions() (*ScalewayPermissionDefinition, error) { + resp, err := s.GetResponsePaginate(AccountAPI, fmt.Sprintf("tokens/%s/permissions", s.Token), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var permissions ScalewayPermissionDefinition + + if err = json.Unmarshal(body, &permissions); err != nil { + return nil, err + } + return &permissions, nil +} + +// GetDashboard returns the dashboard +func (s *ScalewayAPI) GetDashboard() (*ScalewayDashboard, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "dashboard", url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var dashboard ScalewayDashboardResp + + if err = json.Unmarshal(body, &dashboard); err != nil { + return nil, err + } + return &dashboard.Dashboard, nil +} + +// GetServerID returns exactly one server matching +func (s *ScalewayAPI) GetServerID(needle string) (string, error) { + // Parses optional type prefix, i.e: "server:name" -> "name" + _, needle = parseNeedle(needle) + + servers, err := s.ResolveServer(needle) + if err != nil { + return "", fmt.Errorf("Unable to resolve server %s: %s", needle, err) + } + if len(servers) == 1 { + return servers[0].Identifier, nil + } + if len(servers) == 0 { + return "", fmt.Errorf("No such server: %s", needle) + } + return "", showResolverResults(needle, servers) +} + +func showResolverResults(needle string, results ScalewayResolverResults) error { + w := tabwriter.NewWriter(os.Stderr, 20, 1, 3, ' ', 0) + defer w.Flush() + sort.Sort(results) + fmt.Fprintf(w, " IMAGEID\tFROM\tNAME\tZONE\tARCH\n") + for _, result := range results { + if result.Arch == "" { + result.Arch = "n/a" + } + fmt.Fprintf(w, "- %s\t%s\t%s\t%s\t%s\n", result.TruncIdentifier(), result.CodeName(), result.Name, result.Region, result.Arch) + } + return fmt.Errorf("Too many candidates for %s (%d)", needle, len(results)) +} + +// GetVolumeID returns exactly one volume matching +func (s *ScalewayAPI) GetVolumeID(needle string) (string, error) { + // Parses optional type prefix, i.e: "volume:name" -> "name" + _, needle = parseNeedle(needle) + + volumes, err := s.ResolveVolume(needle) + if err != nil { + return "", fmt.Errorf("Unable to resolve volume %s: %s", needle, err) + } + if len(volumes) == 1 { + return volumes[0].Identifier, nil + } + if len(volumes) == 0 { + return "", fmt.Errorf("No such volume: %s", needle) + } + return "", showResolverResults(needle, volumes) +} + +// GetSnapshotID returns exactly one snapshot matching +func (s *ScalewayAPI) GetSnapshotID(needle string) (string, error) { + // Parses optional type prefix, i.e: "snapshot:name" -> "name" + _, needle = parseNeedle(needle) + + snapshots, err := s.ResolveSnapshot(needle) + if err != nil { + return "", fmt.Errorf("Unable to resolve snapshot %s: %s", needle, err) + } + if len(snapshots) == 1 { + return snapshots[0].Identifier, nil + } + if len(snapshots) == 0 { + return "", fmt.Errorf("No such snapshot: %s", needle) + } + return "", showResolverResults(needle, snapshots) +} + +// FilterImagesByArch removes entry that doesn't match with architecture +func FilterImagesByArch(res ScalewayResolverResults, arch string) (ret ScalewayResolverResults) { + if arch == "*" { + return res + } + for _, result := range res { + if result.Arch == arch { + ret = append(ret, result) + } + } + return +} + +// FilterImagesByRegion removes entry that doesn't match with region +func FilterImagesByRegion(res ScalewayResolverResults, region string) (ret ScalewayResolverResults) { + if region == "*" { + return res + } + for _, result := range res { + if result.Region == region { + ret = append(ret, result) + } + } + return +} + +// GetImageID returns exactly one image matching +func (s *ScalewayAPI) GetImageID(needle, arch string) (*ScalewayImageIdentifier, error) { + // Parses optional type prefix, i.e: "image:name" -> "name" + _, needle = parseNeedle(needle) + + images, err := s.ResolveImage(needle) + if err != nil { + return nil, fmt.Errorf("Unable to resolve image %s: %s", needle, err) + } + images = FilterImagesByArch(images, arch) + images = FilterImagesByRegion(images, s.Region) + if len(images) == 1 { + return &ScalewayImageIdentifier{ + Identifier: images[0].Identifier, + Arch: images[0].Arch, + // FIXME region, owner hardcoded + Region: images[0].Region, + Owner: "", + }, nil + } + if len(images) == 0 { + return nil, fmt.Errorf("No such image (zone %s, arch %s) : %s", s.Region, arch, needle) + } + return nil, showResolverResults(needle, images) +} + +// GetSecurityGroups returns a ScalewaySecurityGroups +func (s *ScalewayAPI) GetSecurityGroups() (*ScalewayGetSecurityGroups, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "security_groups", url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var securityGroups ScalewayGetSecurityGroups + + if err = json.Unmarshal(body, &securityGroups); err != nil { + return nil, err + } + return &securityGroups, nil +} + +// GetSecurityGroupRules returns a ScalewaySecurityGroupRules +func (s *ScalewayAPI) GetSecurityGroupRules(groupID string) (*ScalewayGetSecurityGroupRules, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, fmt.Sprintf("security_groups/%s/rules", groupID), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var securityGroupRules ScalewayGetSecurityGroupRules + + if err = json.Unmarshal(body, &securityGroupRules); err != nil { + return nil, err + } + return &securityGroupRules, nil +} + +// GetASecurityGroupRule returns a ScalewaySecurityGroupRule +func (s *ScalewayAPI) GetASecurityGroupRule(groupID string, rulesID string) (*ScalewayGetSecurityGroupRule, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, fmt.Sprintf("security_groups/%s/rules/%s", groupID, rulesID), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var securityGroupRules ScalewayGetSecurityGroupRule + + if err = json.Unmarshal(body, &securityGroupRules); err != nil { + return nil, err + } + return &securityGroupRules, nil +} + +// GetASecurityGroup returns a ScalewaySecurityGroup +func (s *ScalewayAPI) GetASecurityGroup(groupsID string) (*ScalewayGetSecurityGroup, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, fmt.Sprintf("security_groups/%s", groupsID), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var securityGroups ScalewayGetSecurityGroup + + if err = json.Unmarshal(body, &securityGroups); err != nil { + return nil, err + } + return &securityGroups, nil +} + +// PostSecurityGroup posts a group on a server +func (s *ScalewayAPI) PostSecurityGroup(group ScalewayNewSecurityGroup) error { + resp, err := s.PostResponse(s.computeAPI, "security_groups", group) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusCreated}, resp) + return err +} + +// PostSecurityGroupRule posts a rule on a server +func (s *ScalewayAPI) PostSecurityGroupRule(SecurityGroupID string, rules ScalewayNewSecurityGroupRule) error { + resp, err := s.PostResponse(s.computeAPI, fmt.Sprintf("security_groups/%s/rules", SecurityGroupID), rules) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusCreated}, resp) + return err +} + +// DeleteSecurityGroup deletes a SecurityGroup +func (s *ScalewayAPI) DeleteSecurityGroup(securityGroupID string) error { + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("security_groups/%s", securityGroupID)) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// PutSecurityGroup updates a SecurityGroup +func (s *ScalewayAPI) PutSecurityGroup(group ScalewayUpdateSecurityGroup, securityGroupID string) error { + resp, err := s.PutResponse(s.computeAPI, fmt.Sprintf("security_groups/%s", securityGroupID), group) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// PutSecurityGroupRule updates a SecurityGroupRule +func (s *ScalewayAPI) PutSecurityGroupRule(rules ScalewayNewSecurityGroupRule, securityGroupID, RuleID string) error { + resp, err := s.PutResponse(s.computeAPI, fmt.Sprintf("security_groups/%s/rules/%s", securityGroupID, RuleID), rules) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// DeleteSecurityGroupRule deletes a SecurityGroupRule +func (s *ScalewayAPI) DeleteSecurityGroupRule(SecurityGroupID, RuleID string) error { + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("security_groups/%s/rules/%s", SecurityGroupID, RuleID)) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// GetContainers returns a ScalewayGetContainers +func (s *ScalewayAPI) GetContainers() (*ScalewayGetContainers, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "containers", url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var containers ScalewayGetContainers + + if err = json.Unmarshal(body, &containers); err != nil { + return nil, err + } + return &containers, nil +} + +// GetContainerDatas returns a ScalewayGetContainerDatas +func (s *ScalewayAPI) GetContainerDatas(container string) (*ScalewayGetContainerDatas, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, fmt.Sprintf("containers/%s", container), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var datas ScalewayGetContainerDatas + + if err = json.Unmarshal(body, &datas); err != nil { + return nil, err + } + return &datas, nil +} + +// GetIPS returns a ScalewayGetIPS +func (s *ScalewayAPI) GetIPS() (*ScalewayGetIPS, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "ips", url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var ips ScalewayGetIPS + + if err = json.Unmarshal(body, &ips); err != nil { + return nil, err + } + return &ips, nil +} + +// NewIP returns a new IP +func (s *ScalewayAPI) NewIP() (*ScalewayGetIP, error) { + var orga struct { + Organization string `json:"organization"` + } + orga.Organization = s.Organization + resp, err := s.PostResponse(s.computeAPI, "ips", orga) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusCreated}, resp) + if err != nil { + return nil, err + } + var ip ScalewayGetIP + + if err = json.Unmarshal(body, &ip); err != nil { + return nil, err + } + return &ip, nil +} + +// AttachIP attachs an IP to a server +func (s *ScalewayAPI) AttachIP(ipID, serverID string) error { + var update struct { + Address string `json:"address"` + ID string `json:"id"` + Reverse *string `json:"reverse"` + Organization string `json:"organization"` + Server string `json:"server"` + } + + ip, err := s.GetIP(ipID) + if err != nil { + return err + } + update.Address = ip.IP.Address + update.ID = ip.IP.ID + update.Organization = ip.IP.Organization + update.Server = serverID + resp, err := s.PutResponse(s.computeAPI, fmt.Sprintf("ips/%s", ipID), update) + if err != nil { + return err + } + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// DetachIP detaches an IP from a server +func (s *ScalewayAPI) DetachIP(ipID string) error { + ip, err := s.GetIP(ipID) + if err != nil { + return err + } + ip.IP.Server = nil + resp, err := s.PutResponse(s.computeAPI, fmt.Sprintf("ips/%s", ipID), ip.IP) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// DeleteIP deletes an IP +func (s *ScalewayAPI) DeleteIP(ipID string) error { + resp, err := s.DeleteResponse(s.computeAPI, fmt.Sprintf("ips/%s", ipID)) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// GetIP returns a ScalewayGetIP +func (s *ScalewayAPI) GetIP(ipID string) (*ScalewayGetIP, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, fmt.Sprintf("ips/%s", ipID), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var ip ScalewayGetIP + + if err = json.Unmarshal(body, &ip); err != nil { + return nil, err + } + return &ip, nil +} + +// GetQuotas returns a ScalewayGetQuotas +func (s *ScalewayAPI) GetQuotas() (*ScalewayGetQuotas, error) { + resp, err := s.GetResponsePaginate(AccountAPI, fmt.Sprintf("organizations/%s/quotas", s.Organization), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var quotas ScalewayGetQuotas + + if err = json.Unmarshal(body, &quotas); err != nil { + return nil, err + } + return &quotas, nil +} + +// GetBootscriptID returns exactly one bootscript matching +func (s *ScalewayAPI) GetBootscriptID(needle, arch string) (string, error) { + // Parses optional type prefix, i.e: "bootscript:name" -> "name" + _, needle = parseNeedle(needle) + + bootscripts, err := s.ResolveBootscript(needle) + if err != nil { + return "", fmt.Errorf("Unable to resolve bootscript %s: %s", needle, err) + } + bootscripts.FilterByArch(arch) + if len(bootscripts) == 1 { + return bootscripts[0].Identifier, nil + } + if len(bootscripts) == 0 { + return "", fmt.Errorf("No such bootscript: %s", needle) + } + return "", showResolverResults(needle, bootscripts) +} + +func rootNetDial(network, addr string) (net.Conn, error) { + dialer := net.Dialer{ + Timeout: 10 * time.Second, + KeepAlive: 10 * time.Second, + } + + // bruteforce privileged ports + var localAddr net.Addr + var err error + for port := 1; port <= 1024; port++ { + localAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf(":%d", port)) + + // this should never happen + if err != nil { + return nil, err + } + + dialer.LocalAddr = localAddr + + conn, err := dialer.Dial(network, addr) + + // if err is nil, dialer.Dial succeed, so let's go + // else, err != nil, but we don't care + if err == nil { + return conn, nil + } + } + // if here, all privileged ports were tried without success + return nil, fmt.Errorf("bind: permission denied, are you root ?") +} + +// SetPassword register the password +func (s *ScalewayAPI) SetPassword(password string) { + s.password = password +} + +// GetMarketPlaceImages returns images from marketplace +func (s *ScalewayAPI) GetMarketPlaceImages(uuidImage string) (*MarketImages, error) { + resp, err := s.GetResponsePaginate(MarketplaceAPI, fmt.Sprintf("images/%s", uuidImage), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var ret MarketImages + + if uuidImage != "" { + ret.Images = make([]MarketImage, 1) + + var img MarketImage + + if err = json.Unmarshal(body, &img); err != nil { + return nil, err + } + ret.Images[0] = img + } else { + if err = json.Unmarshal(body, &ret); err != nil { + return nil, err + } + } + return &ret, nil +} + +// GetMarketPlaceImageVersions returns image version +func (s *ScalewayAPI) GetMarketPlaceImageVersions(uuidImage, uuidVersion string) (*MarketVersions, error) { + resp, err := s.GetResponsePaginate(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%s", uuidImage, uuidVersion), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var ret MarketVersions + + if uuidImage != "" { + var version MarketVersion + ret.Versions = make([]MarketVersionDefinition, 1) + + if err = json.Unmarshal(body, &version); err != nil { + return nil, err + } + ret.Versions[0] = version.Version + } else { + if err = json.Unmarshal(body, &ret); err != nil { + return nil, err + } + } + return &ret, nil +} + +// GetMarketPlaceImageCurrentVersion return the image current version +func (s *ScalewayAPI) GetMarketPlaceImageCurrentVersion(uuidImage string) (*MarketVersion, error) { + resp, err := s.GetResponsePaginate(MarketplaceAPI, fmt.Sprintf("images/%v/versions/current", uuidImage), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var ret MarketVersion + + if err = json.Unmarshal(body, &ret); err != nil { + return nil, err + } + return &ret, nil +} + +// GetMarketPlaceLocalImages returns images from local region +func (s *ScalewayAPI) GetMarketPlaceLocalImages(uuidImage, uuidVersion, uuidLocalImage string) (*MarketLocalImages, error) { + resp, err := s.GetResponsePaginate(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%s/local_images/%s", uuidImage, uuidVersion, uuidLocalImage), url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + var ret MarketLocalImages + if uuidLocalImage != "" { + var localImage MarketLocalImage + ret.LocalImages = make([]MarketLocalImageDefinition, 1) + + if err = json.Unmarshal(body, &localImage); err != nil { + return nil, err + } + ret.LocalImages[0] = localImage.LocalImages + } else { + if err = json.Unmarshal(body, &ret); err != nil { + return nil, err + } + } + return &ret, nil +} + +// PostMarketPlaceImage adds new image +func (s *ScalewayAPI) PostMarketPlaceImage(images MarketImage) error { + resp, err := s.PostResponse(MarketplaceAPI, "images/", images) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusAccepted}, resp) + return err +} + +// PostMarketPlaceImageVersion adds new image version +func (s *ScalewayAPI) PostMarketPlaceImageVersion(uuidImage string, version MarketVersion) error { + resp, err := s.PostResponse(MarketplaceAPI, fmt.Sprintf("images/%v/versions", uuidImage), version) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusAccepted}, resp) + return err +} + +// PostMarketPlaceLocalImage adds new local image +func (s *ScalewayAPI) PostMarketPlaceLocalImage(uuidImage, uuidVersion, uuidLocalImage string, local MarketLocalImage) error { + resp, err := s.PostResponse(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%s/local_images/%v", uuidImage, uuidVersion, uuidLocalImage), local) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusAccepted}, resp) + return err +} + +// PutMarketPlaceImage updates image +func (s *ScalewayAPI) PutMarketPlaceImage(uudiImage string, images MarketImage) error { + resp, err := s.PutResponse(MarketplaceAPI, fmt.Sprintf("images/%v", uudiImage), images) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// PutMarketPlaceImageVersion updates image version +func (s *ScalewayAPI) PutMarketPlaceImageVersion(uuidImage, uuidVersion string, version MarketVersion) error { + resp, err := s.PutResponse(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%v", uuidImage, uuidVersion), version) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// PutMarketPlaceLocalImage updates local image +func (s *ScalewayAPI) PutMarketPlaceLocalImage(uuidImage, uuidVersion, uuidLocalImage string, local MarketLocalImage) error { + resp, err := s.PostResponse(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%s/local_images/%v", uuidImage, uuidVersion, uuidLocalImage), local) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusOK}, resp) + return err +} + +// DeleteMarketPlaceImage deletes image +func (s *ScalewayAPI) DeleteMarketPlaceImage(uudImage string) error { + resp, err := s.DeleteResponse(MarketplaceAPI, fmt.Sprintf("images/%v", uudImage)) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// DeleteMarketPlaceImageVersion delete image version +func (s *ScalewayAPI) DeleteMarketPlaceImageVersion(uuidImage, uuidVersion string) error { + resp, err := s.DeleteResponse(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%v", uuidImage, uuidVersion)) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// DeleteMarketPlaceLocalImage deletes local image +func (s *ScalewayAPI) DeleteMarketPlaceLocalImage(uuidImage, uuidVersion, uuidLocalImage string) error { + resp, err := s.DeleteResponse(MarketplaceAPI, fmt.Sprintf("images/%v/versions/%s/local_images/%v", uuidImage, uuidVersion, uuidLocalImage)) + if err != nil { + return err + } + defer resp.Body.Close() + _, err = s.handleHTTPError([]int{http.StatusNoContent}, resp) + return err +} + +// ResolveTTYUrl return an URL to get a tty +func (s *ScalewayAPI) ResolveTTYUrl() string { + switch s.Region { + case "par1", "": + return "https://tty-par1.scaleway.com/v2/" + case "ams1": + return "https://tty-ams1.scaleway.com" + } + return "" +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go new file mode 100644 index 000000000..1d9771a0e --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go @@ -0,0 +1,814 @@ +// Copyright (C) 2015 Scaleway. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE.md file. + +package api + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + + "github.com/moul/anonuuid" + "github.com/renstrom/fuzzysearch/fuzzy" +) + +const ( + // CacheRegion permits to access at the region field + CacheRegion = iota + // CacheArch permits to access at the arch field + CacheArch + // CacheOwner permits to access at the owner field + CacheOwner + // CacheTitle permits to access at the title field + CacheTitle + // CacheMarketPlaceUUID is used to determine the UUID of local images + CacheMarketPlaceUUID + // CacheMaxfield is used to determine the size of array + CacheMaxfield +) + +// ScalewayCache is used not to query the API to resolve full identifiers +type ScalewayCache struct { + // Images contains names of Scaleway images indexed by identifier + Images map[string][CacheMaxfield]string `json:"images"` + + // Snapshots contains names of Scaleway snapshots indexed by identifier + Snapshots map[string][CacheMaxfield]string `json:"snapshots"` + + // Volumes contains names of Scaleway volumes indexed by identifier + Volumes map[string][CacheMaxfield]string `json:"volumes"` + + // Bootscripts contains names of Scaleway bootscripts indexed by identifier + Bootscripts map[string][CacheMaxfield]string `json:"bootscripts"` + + // Servers contains names of Scaleway servers indexed by identifier + Servers map[string][CacheMaxfield]string `json:"servers"` + + // Path is the path to the cache file + Path string `json:"-"` + + // Modified tells if the cache needs to be overwritten or not + Modified bool `json:"-"` + + // Lock allows ScalewayCache to be used concurrently + Lock sync.Mutex `json:"-"` + + hookSave func() +} + +const ( + // IdentifierUnknown is used when we don't know explicitly the type key of the object (used for nil comparison) + IdentifierUnknown = 1 << iota + // IdentifierServer is the type key of cached server objects + IdentifierServer + // IdentifierImage is the type key of cached image objects + IdentifierImage + // IdentifierSnapshot is the type key of cached snapshot objects + IdentifierSnapshot + // IdentifierBootscript is the type key of cached bootscript objects + IdentifierBootscript + // IdentifierVolume is the type key of cached volume objects + IdentifierVolume +) + +// ScalewayResolverResult is a structure containing human-readable information +// about resolver results. This structure is used to display the user choices. +type ScalewayResolverResult struct { + Identifier string + Type int + Name string + Arch string + Needle string + RankMatch int + Region string +} + +// ScalewayResolverResults is a list of `ScalewayResolverResult` +type ScalewayResolverResults []ScalewayResolverResult + +// NewScalewayResolverResult returns a new ScalewayResolverResult +func NewScalewayResolverResult(Identifier, Name, Arch, Region string, Type int) (ScalewayResolverResult, error) { + if err := anonuuid.IsUUID(Identifier); err != nil { + return ScalewayResolverResult{}, err + } + return ScalewayResolverResult{ + Identifier: Identifier, + Type: Type, + Name: Name, + Arch: Arch, + Region: Region, + }, nil +} + +func (s ScalewayResolverResults) Len() int { + return len(s) +} + +func (s ScalewayResolverResults) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s ScalewayResolverResults) Less(i, j int) bool { + return s[i].RankMatch < s[j].RankMatch +} + +// TruncIdentifier returns first 8 characters of an Identifier (UUID) +func (s *ScalewayResolverResult) TruncIdentifier() string { + return s.Identifier[:8] +} + +func identifierTypeName(kind int) string { + switch kind { + case IdentifierServer: + return "Server" + case IdentifierImage: + return "Image" + case IdentifierSnapshot: + return "Snapshot" + case IdentifierVolume: + return "Volume" + case IdentifierBootscript: + return "Bootscript" + } + return "" +} + +// CodeName returns a full resource name with typed prefix +func (s *ScalewayResolverResult) CodeName() string { + name := strings.ToLower(s.Name) + name = regexp.MustCompile(`[^a-z0-9-]`).ReplaceAllString(name, "-") + name = regexp.MustCompile(`--+`).ReplaceAllString(name, "-") + name = strings.Trim(name, "-") + + return fmt.Sprintf("%s:%s", strings.ToLower(identifierTypeName(s.Type)), name) +} + +// FilterByArch deletes the elements which not match with arch +func (s *ScalewayResolverResults) FilterByArch(arch string) { +REDO: + for i := range *s { + if (*s)[i].Arch != arch { + (*s)[i] = (*s)[len(*s)-1] + *s = (*s)[:len(*s)-1] + goto REDO + } + } +} + +// NewScalewayCache loads a per-user cache +func NewScalewayCache(hookSave func()) (*ScalewayCache, error) { + var cache ScalewayCache + + cache.hookSave = hookSave + homeDir := os.Getenv("HOME") // *nix + if homeDir == "" { // Windows + homeDir = os.Getenv("USERPROFILE") + } + if homeDir == "" { + homeDir = "/tmp" + } + cachePath := filepath.Join(homeDir, ".scw-cache.db") + cache.Path = cachePath + _, err := os.Stat(cachePath) + if os.IsNotExist(err) { + cache.Clear() + return &cache, nil + } else if err != nil { + return nil, err + } + file, err := ioutil.ReadFile(cachePath) + if err != nil { + return nil, err + } + err = json.Unmarshal(file, &cache) + if err != nil { + // fix compatibility with older version + if err = os.Remove(cachePath); err != nil { + return nil, err + } + cache.Clear() + return &cache, nil + } + if cache.Images == nil { + cache.Images = make(map[string][CacheMaxfield]string) + } + if cache.Snapshots == nil { + cache.Snapshots = make(map[string][CacheMaxfield]string) + } + if cache.Volumes == nil { + cache.Volumes = make(map[string][CacheMaxfield]string) + } + if cache.Servers == nil { + cache.Servers = make(map[string][CacheMaxfield]string) + } + if cache.Bootscripts == nil { + cache.Bootscripts = make(map[string][CacheMaxfield]string) + } + return &cache, nil +} + +// Clear removes all information from the cache +func (c *ScalewayCache) Clear() { + c.Images = make(map[string][CacheMaxfield]string) + c.Snapshots = make(map[string][CacheMaxfield]string) + c.Volumes = make(map[string][CacheMaxfield]string) + c.Bootscripts = make(map[string][CacheMaxfield]string) + c.Servers = make(map[string][CacheMaxfield]string) + c.Modified = true +} + +// Flush flushes the cache database +func (c *ScalewayCache) Flush() error { + return os.Remove(c.Path) +} + +// Save atomically overwrites the current cache database +func (c *ScalewayCache) Save() error { + c.Lock.Lock() + defer c.Lock.Unlock() + + c.hookSave() + if c.Modified { + file, err := ioutil.TempFile(filepath.Dir(c.Path), filepath.Base(c.Path)) + if err != nil { + return err + } + defer file.Close() + if err := json.NewEncoder(file).Encode(c); err != nil { + os.Remove(file.Name()) + return err + } + + if err := os.Rename(file.Name(), c.Path); err != nil { + os.Remove(file.Name()) + return err + } + } + return nil +} + +// ComputeRankMatch fills `ScalewayResolverResult.RankMatch` with its `fuzzy` score +func (s *ScalewayResolverResult) ComputeRankMatch(needle string) { + s.Needle = needle + s.RankMatch = fuzzy.RankMatch(needle, s.Name) +} + +// LookUpImages attempts to return identifiers matching a pattern +func (c *ScalewayCache) LookUpImages(needle string, acceptUUID bool) (ScalewayResolverResults, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + var res ScalewayResolverResults + var exactMatches ScalewayResolverResults + + if acceptUUID && anonuuid.IsUUID(needle) == nil { + if fields, ok := c.Images[needle]; ok { + entry, err := NewScalewayResolverResult(needle, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierImage) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + needle = regexp.MustCompile(`^user/`).ReplaceAllString(needle, "") + // FIXME: if 'user/' is in needle, only watch for a user image + nameRegex := regexp.MustCompile(`(?i)` + regexp.MustCompile(`[_-]`).ReplaceAllString(needle, ".*")) + for identifier, fields := range c.Images { + if fields[CacheTitle] == needle { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierImage) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + exactMatches = append(exactMatches, entry) + } + if strings.HasPrefix(identifier, needle) || nameRegex.MatchString(fields[CacheTitle]) { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierImage) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } else if strings.HasPrefix(fields[CacheMarketPlaceUUID], needle) || nameRegex.MatchString(fields[CacheMarketPlaceUUID]) { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierImage) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + if len(exactMatches) == 1 { + return exactMatches, nil + } + + return removeDuplicatesResults(res), nil +} + +// LookUpSnapshots attempts to return identifiers matching a pattern +func (c *ScalewayCache) LookUpSnapshots(needle string, acceptUUID bool) (ScalewayResolverResults, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + var res ScalewayResolverResults + var exactMatches ScalewayResolverResults + + if acceptUUID && anonuuid.IsUUID(needle) == nil { + if fields, ok := c.Snapshots[needle]; ok { + entry, err := NewScalewayResolverResult(needle, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierSnapshot) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + needle = regexp.MustCompile(`^user/`).ReplaceAllString(needle, "") + nameRegex := regexp.MustCompile(`(?i)` + regexp.MustCompile(`[_-]`).ReplaceAllString(needle, ".*")) + for identifier, fields := range c.Snapshots { + if fields[CacheTitle] == needle { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierSnapshot) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + exactMatches = append(exactMatches, entry) + } + if strings.HasPrefix(identifier, needle) || nameRegex.MatchString(fields[CacheTitle]) { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierSnapshot) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + if len(exactMatches) == 1 { + return exactMatches, nil + } + + return removeDuplicatesResults(res), nil +} + +// LookUpVolumes attempts to return identifiers matching a pattern +func (c *ScalewayCache) LookUpVolumes(needle string, acceptUUID bool) (ScalewayResolverResults, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + var res ScalewayResolverResults + var exactMatches ScalewayResolverResults + + if acceptUUID && anonuuid.IsUUID(needle) == nil { + if fields, ok := c.Volumes[needle]; ok { + entry, err := NewScalewayResolverResult(needle, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierVolume) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + nameRegex := regexp.MustCompile(`(?i)` + regexp.MustCompile(`[_-]`).ReplaceAllString(needle, ".*")) + for identifier, fields := range c.Volumes { + if fields[CacheTitle] == needle { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierVolume) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + exactMatches = append(exactMatches, entry) + } + if strings.HasPrefix(identifier, needle) || nameRegex.MatchString(fields[CacheTitle]) { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierVolume) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + if len(exactMatches) == 1 { + return exactMatches, nil + } + + return removeDuplicatesResults(res), nil +} + +// LookUpBootscripts attempts to return identifiers matching a pattern +func (c *ScalewayCache) LookUpBootscripts(needle string, acceptUUID bool) (ScalewayResolverResults, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + var res ScalewayResolverResults + var exactMatches ScalewayResolverResults + + if acceptUUID && anonuuid.IsUUID(needle) == nil { + if fields, ok := c.Bootscripts[needle]; ok { + entry, err := NewScalewayResolverResult(needle, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierBootscript) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + nameRegex := regexp.MustCompile(`(?i)` + regexp.MustCompile(`[_-]`).ReplaceAllString(needle, ".*")) + for identifier, fields := range c.Bootscripts { + if fields[CacheTitle] == needle { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierBootscript) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + exactMatches = append(exactMatches, entry) + } + if strings.HasPrefix(identifier, needle) || nameRegex.MatchString(fields[CacheTitle]) { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierBootscript) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + if len(exactMatches) == 1 { + return exactMatches, nil + } + + return removeDuplicatesResults(res), nil +} + +// LookUpServers attempts to return identifiers matching a pattern +func (c *ScalewayCache) LookUpServers(needle string, acceptUUID bool) (ScalewayResolverResults, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + var res ScalewayResolverResults + var exactMatches ScalewayResolverResults + + if acceptUUID && anonuuid.IsUUID(needle) == nil { + if fields, ok := c.Servers[needle]; ok { + entry, err := NewScalewayResolverResult(needle, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierServer) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + nameRegex := regexp.MustCompile(`(?i)` + regexp.MustCompile(`[_-]`).ReplaceAllString(needle, ".*")) + for identifier, fields := range c.Servers { + if fields[CacheTitle] == needle { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierServer) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + exactMatches = append(exactMatches, entry) + } + if strings.HasPrefix(identifier, needle) || nameRegex.MatchString(fields[CacheTitle]) { + entry, err := NewScalewayResolverResult(identifier, fields[CacheTitle], fields[CacheArch], fields[CacheRegion], IdentifierServer) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + res = append(res, entry) + } + } + + if len(exactMatches) == 1 { + return exactMatches, nil + } + + return removeDuplicatesResults(res), nil +} + +// removeDuplicatesResults transforms an array into a unique array +func removeDuplicatesResults(elements ScalewayResolverResults) ScalewayResolverResults { + encountered := map[string]ScalewayResolverResult{} + + // Create a map of all unique elements. + for v := range elements { + encountered[elements[v].Identifier] = elements[v] + } + + // Place all keys from the map into a slice. + results := ScalewayResolverResults{} + for _, result := range encountered { + results = append(results, result) + } + return results +} + +// parseNeedle parses a user needle and try to extract a forced object type +// i.e: +// - server:blah-blah -> kind=server, needle=blah-blah +// - blah-blah -> kind="", needle=blah-blah +// - not-existing-type:blah-blah +func parseNeedle(input string) (identifierType int, needle string) { + parts := strings.Split(input, ":") + if len(parts) == 2 { + switch parts[0] { + case "server": + return IdentifierServer, parts[1] + case "image": + return IdentifierImage, parts[1] + case "snapshot": + return IdentifierSnapshot, parts[1] + case "bootscript": + return IdentifierBootscript, parts[1] + case "volume": + return IdentifierVolume, parts[1] + } + } + return IdentifierUnknown, input +} + +// LookUpIdentifiers attempts to return identifiers matching a pattern +func (c *ScalewayCache) LookUpIdentifiers(needle string) (ScalewayResolverResults, error) { + results := ScalewayResolverResults{} + + identifierType, needle := parseNeedle(needle) + + if identifierType&(IdentifierUnknown|IdentifierServer) > 0 { + servers, err := c.LookUpServers(needle, false) + if err != nil { + return ScalewayResolverResults{}, err + } + for _, result := range servers { + entry, err := NewScalewayResolverResult(result.Identifier, result.Name, result.Arch, result.Region, IdentifierServer) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + results = append(results, entry) + } + } + + if identifierType&(IdentifierUnknown|IdentifierImage) > 0 { + images, err := c.LookUpImages(needle, false) + if err != nil { + return ScalewayResolverResults{}, err + } + for _, result := range images { + entry, err := NewScalewayResolverResult(result.Identifier, result.Name, result.Arch, result.Region, IdentifierImage) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + results = append(results, entry) + } + } + + if identifierType&(IdentifierUnknown|IdentifierSnapshot) > 0 { + snapshots, err := c.LookUpSnapshots(needle, false) + if err != nil { + return ScalewayResolverResults{}, err + } + for _, result := range snapshots { + entry, err := NewScalewayResolverResult(result.Identifier, result.Name, result.Arch, result.Region, IdentifierSnapshot) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + results = append(results, entry) + } + } + + if identifierType&(IdentifierUnknown|IdentifierVolume) > 0 { + volumes, err := c.LookUpVolumes(needle, false) + if err != nil { + return ScalewayResolverResults{}, err + } + for _, result := range volumes { + entry, err := NewScalewayResolverResult(result.Identifier, result.Name, result.Arch, result.Region, IdentifierVolume) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + results = append(results, entry) + } + } + + if identifierType&(IdentifierUnknown|IdentifierBootscript) > 0 { + bootscripts, err := c.LookUpBootscripts(needle, false) + if err != nil { + return ScalewayResolverResults{}, err + } + for _, result := range bootscripts { + entry, err := NewScalewayResolverResult(result.Identifier, result.Name, result.Arch, result.Region, IdentifierBootscript) + if err != nil { + return ScalewayResolverResults{}, err + } + entry.ComputeRankMatch(needle) + results = append(results, entry) + } + } + return results, nil +} + +// InsertServer registers a server in the cache +func (c *ScalewayCache) InsertServer(identifier, region, arch, owner, name string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + fields, exists := c.Servers[identifier] + if !exists || fields[CacheTitle] != name { + c.Servers[identifier] = [CacheMaxfield]string{region, arch, owner, name} + c.Modified = true + } +} + +// RemoveServer removes a server from the cache +func (c *ScalewayCache) RemoveServer(identifier string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + delete(c.Servers, identifier) + c.Modified = true +} + +// ClearServers removes all servers from the cache +func (c *ScalewayCache) ClearServers() { + c.Lock.Lock() + defer c.Lock.Unlock() + + c.Servers = make(map[string][CacheMaxfield]string) + c.Modified = true +} + +// InsertImage registers an image in the cache +func (c *ScalewayCache) InsertImage(identifier, region, arch, owner, name, marketPlaceUUID string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + fields, exists := c.Images[identifier] + if !exists || fields[CacheTitle] != name { + c.Images[identifier] = [CacheMaxfield]string{region, arch, owner, name, marketPlaceUUID} + c.Modified = true + } +} + +// RemoveImage removes a server from the cache +func (c *ScalewayCache) RemoveImage(identifier string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + delete(c.Images, identifier) + c.Modified = true +} + +// ClearImages removes all images from the cache +func (c *ScalewayCache) ClearImages() { + c.Lock.Lock() + defer c.Lock.Unlock() + + c.Images = make(map[string][CacheMaxfield]string) + c.Modified = true +} + +// InsertSnapshot registers an snapshot in the cache +func (c *ScalewayCache) InsertSnapshot(identifier, region, arch, owner, name string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + fields, exists := c.Snapshots[identifier] + if !exists || fields[CacheTitle] != name { + c.Snapshots[identifier] = [CacheMaxfield]string{region, arch, owner, name} + c.Modified = true + } +} + +// RemoveSnapshot removes a server from the cache +func (c *ScalewayCache) RemoveSnapshot(identifier string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + delete(c.Snapshots, identifier) + c.Modified = true +} + +// ClearSnapshots removes all snapshots from the cache +func (c *ScalewayCache) ClearSnapshots() { + c.Lock.Lock() + defer c.Lock.Unlock() + + c.Snapshots = make(map[string][CacheMaxfield]string) + c.Modified = true +} + +// InsertVolume registers an volume in the cache +func (c *ScalewayCache) InsertVolume(identifier, region, arch, owner, name string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + fields, exists := c.Volumes[identifier] + if !exists || fields[CacheTitle] != name { + c.Volumes[identifier] = [CacheMaxfield]string{region, arch, owner, name} + c.Modified = true + } +} + +// RemoveVolume removes a server from the cache +func (c *ScalewayCache) RemoveVolume(identifier string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + delete(c.Volumes, identifier) + c.Modified = true +} + +// ClearVolumes removes all volumes from the cache +func (c *ScalewayCache) ClearVolumes() { + c.Lock.Lock() + defer c.Lock.Unlock() + + c.Volumes = make(map[string][CacheMaxfield]string) + c.Modified = true +} + +// InsertBootscript registers an bootscript in the cache +func (c *ScalewayCache) InsertBootscript(identifier, region, arch, owner, name string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + fields, exists := c.Bootscripts[identifier] + if !exists || fields[CacheTitle] != name { + c.Bootscripts[identifier] = [CacheMaxfield]string{region, arch, owner, name} + c.Modified = true + } +} + +// RemoveBootscript removes a bootscript from the cache +func (c *ScalewayCache) RemoveBootscript(identifier string) { + c.Lock.Lock() + defer c.Lock.Unlock() + + delete(c.Bootscripts, identifier) + c.Modified = true +} + +// ClearBootscripts removes all bootscripts from the cache +func (c *ScalewayCache) ClearBootscripts() { + c.Lock.Lock() + defer c.Lock.Unlock() + + c.Bootscripts = make(map[string][CacheMaxfield]string) + c.Modified = true +} + +// GetNbServers returns the number of servers in the cache +func (c *ScalewayCache) GetNbServers() int { + c.Lock.Lock() + defer c.Lock.Unlock() + + return len(c.Servers) +} + +// GetNbImages returns the number of images in the cache +func (c *ScalewayCache) GetNbImages() int { + c.Lock.Lock() + defer c.Lock.Unlock() + + return len(c.Images) +} + +// GetNbSnapshots returns the number of snapshots in the cache +func (c *ScalewayCache) GetNbSnapshots() int { + c.Lock.Lock() + defer c.Lock.Unlock() + + return len(c.Snapshots) +} + +// GetNbVolumes returns the number of volumes in the cache +func (c *ScalewayCache) GetNbVolumes() int { + c.Lock.Lock() + defer c.Lock.Unlock() + + return len(c.Volumes) +} + +// GetNbBootscripts returns the number of bootscripts in the cache +func (c *ScalewayCache) GetNbBootscripts() int { + c.Lock.Lock() + defer c.Lock.Unlock() + + return len(c.Bootscripts) +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go new file mode 100644 index 000000000..3a59e465d --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go @@ -0,0 +1,685 @@ +// Copyright (C) 2015 Scaleway. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE.md file. + +package api + +import ( + "errors" + "fmt" + "os" + "sort" + "strings" + "sync" + "time" + + "github.com/Sirupsen/logrus" + log "github.com/Sirupsen/logrus" + "github.com/docker/docker/pkg/namesgenerator" + "github.com/dustin/go-humanize" + "github.com/moul/anonuuid" + "github.com/scaleway/scaleway-cli/pkg/utils" +) + +// ScalewayResolvedIdentifier represents a list of matching identifier for a specifier pattern +type ScalewayResolvedIdentifier struct { + // Identifiers holds matching identifiers + Identifiers ScalewayResolverResults + + // Needle is the criteria used to lookup identifiers + Needle string +} + +// ScalewayImageInterface is an interface to multiple Scaleway items +type ScalewayImageInterface struct { + CreationDate time.Time + Identifier string + Name string + Tag string + VirtualSize uint64 + Public bool + Type string + Organization string + Archs []string + Region []string +} + +// ResolveGateway tries to resolve a server public ip address, else returns the input string, i.e. IPv4, hostname +func ResolveGateway(api *ScalewayAPI, gateway string) (string, error) { + if gateway == "" { + return "", nil + } + + // Parses optional type prefix, i.e: "server:name" -> "name" + _, gateway = parseNeedle(gateway) + + servers, err := api.ResolveServer(gateway) + if err != nil { + return "", err + } + + if len(servers) == 0 { + return gateway, nil + } + + if len(servers) > 1 { + return "", showResolverResults(gateway, servers) + } + + // if len(servers) == 1 { + server, err := api.GetServer(servers[0].Identifier) + if err != nil { + return "", err + } + return server.PublicAddress.IP, nil +} + +// CreateVolumeFromHumanSize creates a volume on the API with a human readable size +func CreateVolumeFromHumanSize(api *ScalewayAPI, size string) (*string, error) { + bytes, err := humanize.ParseBytes(size) + if err != nil { + return nil, err + } + + var newVolume ScalewayVolumeDefinition + newVolume.Name = size + newVolume.Size = bytes + newVolume.Type = "l_ssd" + + volumeID, err := api.PostVolume(newVolume) + if err != nil { + return nil, err + } + + return &volumeID, nil +} + +// fillIdentifierCache fills the cache by fetching from the API +func fillIdentifierCache(api *ScalewayAPI, identifierType int) { + log.Debugf("Filling the cache") + var wg sync.WaitGroup + wg.Add(5) + go func() { + if identifierType&(IdentifierUnknown|IdentifierServer) > 0 { + api.GetServers(true, 0) + } + wg.Done() + }() + go func() { + if identifierType&(IdentifierUnknown|IdentifierImage) > 0 { + api.GetImages() + } + wg.Done() + }() + go func() { + if identifierType&(IdentifierUnknown|IdentifierSnapshot) > 0 { + api.GetSnapshots() + } + wg.Done() + }() + go func() { + if identifierType&(IdentifierUnknown|IdentifierVolume) > 0 { + api.GetVolumes() + } + wg.Done() + }() + go func() { + if identifierType&(IdentifierUnknown|IdentifierBootscript) > 0 { + api.GetBootscripts() + } + wg.Done() + }() + wg.Wait() +} + +// GetIdentifier returns a an identifier if the resolved needles only match one element, else, it exists the program +func GetIdentifier(api *ScalewayAPI, needle string) (*ScalewayResolverResult, error) { + idents, err := ResolveIdentifier(api, needle) + if err != nil { + return nil, err + } + + if len(idents) == 1 { + return &idents[0], nil + } + if len(idents) == 0 { + return nil, fmt.Errorf("No such identifier: %s", needle) + } + + sort.Sort(idents) + for _, identifier := range idents { + // FIXME: also print the name + fmt.Fprintf(os.Stderr, "- %s\n", identifier.Identifier) + } + return nil, fmt.Errorf("Too many candidates for %s (%d)", needle, len(idents)) +} + +// ResolveIdentifier resolves needle provided by the user +func ResolveIdentifier(api *ScalewayAPI, needle string) (ScalewayResolverResults, error) { + idents, err := api.Cache.LookUpIdentifiers(needle) + if err != nil { + return idents, err + } + if len(idents) > 0 { + return idents, nil + } + + identifierType, _ := parseNeedle(needle) + fillIdentifierCache(api, identifierType) + + return api.Cache.LookUpIdentifiers(needle) +} + +// ResolveIdentifiers resolves needles provided by the user +func ResolveIdentifiers(api *ScalewayAPI, needles []string, out chan ScalewayResolvedIdentifier) { + // first attempt, only lookup from the cache + var unresolved []string + for _, needle := range needles { + idents, err := api.Cache.LookUpIdentifiers(needle) + if err != nil { + api.Logger.Fatalf("%s", err) + } + if len(idents) == 0 { + unresolved = append(unresolved, needle) + } else { + out <- ScalewayResolvedIdentifier{ + Identifiers: idents, + Needle: needle, + } + } + } + // fill the cache by fetching from the API and resolve missing identifiers + if len(unresolved) > 0 { + // compute identifierType: + // if identifierType is the same for every unresolved needle, + // we use it directly, else, we choose IdentifierUnknown to + // fulfill every types of cache + identifierType, _ := parseNeedle(unresolved[0]) + for _, needle := range unresolved { + newIdentifierType, _ := parseNeedle(needle) + if identifierType != newIdentifierType { + identifierType = IdentifierUnknown + break + } + } + + // fill all the cache + fillIdentifierCache(api, identifierType) + + // lookup again in the cache + for _, needle := range unresolved { + idents, err := api.Cache.LookUpIdentifiers(needle) + if err != nil { + api.Logger.Fatalf("%s", err) + } + out <- ScalewayResolvedIdentifier{ + Identifiers: idents, + Needle: needle, + } + } + } + + close(out) +} + +// InspectIdentifierResult is returned by `InspectIdentifiers` and contains the inspected `Object` with its `Type` +type InspectIdentifierResult struct { + Type int + Object interface{} +} + +// InspectIdentifiers inspects identifiers concurrently +func InspectIdentifiers(api *ScalewayAPI, ci chan ScalewayResolvedIdentifier, cj chan InspectIdentifierResult, arch string) { + var wg sync.WaitGroup + for { + idents, ok := <-ci + if !ok { + break + } + idents.Identifiers = FilterImagesByArch(idents.Identifiers, arch) + idents.Identifiers = FilterImagesByRegion(idents.Identifiers, api.Region) + if len(idents.Identifiers) != 1 { + if len(idents.Identifiers) == 0 { + log.Errorf("Unable to resolve identifier %s", idents.Needle) + } else { + logrus.Fatal(showResolverResults(idents.Needle, idents.Identifiers)) + } + } else { + ident := idents.Identifiers[0] + wg.Add(1) + go func() { + var obj interface{} + var err error + + switch ident.Type { + case IdentifierServer: + obj, err = api.GetServer(ident.Identifier) + case IdentifierImage: + obj, err = api.GetImage(ident.Identifier) + case IdentifierSnapshot: + obj, err = api.GetSnapshot(ident.Identifier) + case IdentifierVolume: + obj, err = api.GetVolume(ident.Identifier) + case IdentifierBootscript: + obj, err = api.GetBootscript(ident.Identifier) + } + if err == nil && obj != nil { + cj <- InspectIdentifierResult{ + Type: ident.Type, + Object: obj, + } + } + wg.Done() + }() + } + } + wg.Wait() + close(cj) +} + +// ConfigCreateServer represents the options sent to CreateServer and defining a server +type ConfigCreateServer struct { + ImageName string + Name string + Bootscript string + Env string + AdditionalVolumes string + IP string + CommercialType string + DynamicIPRequired bool + EnableIPV6 bool +} + +// CreateServer creates a server using API based on typical server fields +func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) { + commercialType := os.Getenv("SCW_COMMERCIAL_TYPE") + if commercialType == "" { + commercialType = c.CommercialType + } + if len(commercialType) < 2 { + return "", errors.New("Invalid commercial type") + } + + if c.Name == "" { + c.Name = strings.Replace(namesgenerator.GetRandomName(0), "_", "-", -1) + } + + var server ScalewayServerDefinition + + server.CommercialType = commercialType + server.Volumes = make(map[string]string) + server.DynamicIPRequired = &c.DynamicIPRequired + server.EnableIPV6 = c.EnableIPV6 + if commercialType == "" { + return "", errors.New("You need to specify a commercial-type") + } + if c.IP != "" { + if anonuuid.IsUUID(c.IP) == nil { + server.PublicIP = c.IP + } else { + ips, err := api.GetIPS() + if err != nil { + return "", err + } + for _, ip := range ips.IPS { + if ip.Address == c.IP { + server.PublicIP = ip.ID + break + } + } + if server.PublicIP == "" { + return "", fmt.Errorf("IP address %v not found", c.IP) + } + } + } + server.Tags = []string{} + if c.Env != "" { + server.Tags = strings.Split(c.Env, " ") + } + switch c.CommercialType { + case "VC1M", "X64-4GB": + if c.AdditionalVolumes == "" { + c.AdditionalVolumes = "50G" + log.Debugf("This server needs a least 50G") + } + case "VC1L", "X64-8GB", "X64-15GB": + if c.AdditionalVolumes == "" { + c.AdditionalVolumes = "150G" + log.Debugf("This server needs a least 150G") + } + case "X64-30GB": + if c.AdditionalVolumes == "" { + c.AdditionalVolumes = "100G 150G" + log.Debugf("This server needs a least 300G") + } + case "X64-60GB": + if c.AdditionalVolumes == "" { + c.AdditionalVolumes = "50G 150G 150G" + log.Debugf("This server needs a least 400G") + } + case "X64-120GB": + if c.AdditionalVolumes == "" { + c.AdditionalVolumes = "150G 150G 150G" + log.Debugf("This server needs a least 500G") + } + } + if c.AdditionalVolumes != "" { + volumes := strings.Split(c.AdditionalVolumes, " ") + for i := range volumes { + volumeID, err := CreateVolumeFromHumanSize(api, volumes[i]) + if err != nil { + return "", err + } + + volumeIDx := fmt.Sprintf("%d", i+1) + server.Volumes[volumeIDx] = *volumeID + } + } + arch := os.Getenv("SCW_TARGET_ARCH") + if arch == "" { + server.CommercialType = strings.ToUpper(server.CommercialType) + switch server.CommercialType[:2] { + case "C1": + arch = "arm" + case "C2", "VC", "X6": + arch = "x86_64" + default: + return "", fmt.Errorf("%s wrong commercial type", server.CommercialType) + } + } + imageIdentifier := &ScalewayImageIdentifier{ + Arch: arch, + } + server.Name = c.Name + inheritingVolume := false + _, err := humanize.ParseBytes(c.ImageName) + if err == nil { + // Create a new root volume + volumeID, errCreateVol := CreateVolumeFromHumanSize(api, c.ImageName) + if errCreateVol != nil { + return "", errCreateVol + } + server.Volumes["0"] = *volumeID + } else { + // Use an existing image + inheritingVolume = true + if anonuuid.IsUUID(c.ImageName) == nil { + server.Image = &c.ImageName + } else { + imageIdentifier, err = api.GetImageID(c.ImageName, arch) + if err != nil { + return "", err + } + if imageIdentifier.Identifier != "" { + server.Image = &imageIdentifier.Identifier + } else { + snapshotID, errGetSnapID := api.GetSnapshotID(c.ImageName) + if errGetSnapID != nil { + return "", errGetSnapID + } + snapshot, errGetSnap := api.GetSnapshot(snapshotID) + if errGetSnap != nil { + return "", errGetSnap + } + if snapshot.BaseVolume.Identifier == "" { + return "", fmt.Errorf("snapshot %v does not have base volume", snapshot.Name) + } + server.Volumes["0"] = snapshot.BaseVolume.Identifier + } + } + } + + if c.Bootscript != "" { + bootscript := "" + + if anonuuid.IsUUID(c.Bootscript) == nil { + bootscript = c.Bootscript + } else { + var errGetBootScript error + + bootscript, errGetBootScript = api.GetBootscriptID(c.Bootscript, imageIdentifier.Arch) + if errGetBootScript != nil { + return "", errGetBootScript + } + } + server.Bootscript = &bootscript + } + serverID, err := api.PostServer(server) + if err != nil { + return "", err + } + + // For inherited volumes, we prefix the name with server hostname + if inheritingVolume { + createdServer, err := api.GetServer(serverID) + if err != nil { + return "", err + } + currentVolume := createdServer.Volumes["0"] + + var volumePayload ScalewayVolumePutDefinition + newName := fmt.Sprintf("%s-%s", createdServer.Hostname, currentVolume.Name) + volumePayload.Name = &newName + volumePayload.CreationDate = &currentVolume.CreationDate + volumePayload.Organization = &currentVolume.Organization + volumePayload.Server.Identifier = &currentVolume.Server.Identifier + volumePayload.Server.Name = &currentVolume.Server.Name + volumePayload.Identifier = &currentVolume.Identifier + volumePayload.Size = &currentVolume.Size + volumePayload.ModificationDate = &currentVolume.ModificationDate + volumePayload.ExportURI = &currentVolume.ExportURI + volumePayload.VolumeType = &currentVolume.VolumeType + + err = api.PutVolume(currentVolume.Identifier, volumePayload) + if err != nil { + return "", err + } + } + + return serverID, nil +} + +// WaitForServerState asks API in a loop until a server matches a wanted state +func WaitForServerState(api *ScalewayAPI, serverID string, targetState string) (*ScalewayServer, error) { + var server *ScalewayServer + var err error + + var currentState string + + for { + server, err = api.GetServer(serverID) + if err != nil { + return nil, err + } + if currentState != server.State { + log.Infof("Server changed state to '%s'", server.State) + currentState = server.State + } + if server.State == targetState { + break + } + time.Sleep(1 * time.Second) + } + + return server, nil +} + +// WaitForServerReady wait for a server state to be running, then wait for the SSH port to be available +func WaitForServerReady(api *ScalewayAPI, serverID, gateway string) (*ScalewayServer, error) { + promise := make(chan bool) + var server *ScalewayServer + var err error + var currentState string + + go func() { + defer close(promise) + + for { + server, err = api.GetServer(serverID) + if err != nil { + promise <- false + return + } + if currentState != server.State { + log.Infof("Server changed state to '%s'", server.State) + currentState = server.State + } + if server.State == "running" { + break + } + if server.State == "stopped" { + err = fmt.Errorf("The server has been stopped") + promise <- false + return + } + time.Sleep(1 * time.Second) + } + + if gateway == "" { + dest := fmt.Sprintf("%s:22", server.PublicAddress.IP) + log.Debugf("Waiting for server SSH port %s", dest) + err = utils.WaitForTCPPortOpen(dest) + if err != nil { + promise <- false + return + } + } else { + dest := fmt.Sprintf("%s:22", gateway) + log.Debugf("Waiting for server SSH port %s", dest) + err = utils.WaitForTCPPortOpen(dest) + if err != nil { + promise <- false + return + } + log.Debugf("Check for SSH port through the gateway: %s", server.PrivateIP) + timeout := time.Tick(120 * time.Second) + for { + select { + case <-timeout: + err = fmt.Errorf("Timeout: unable to ping %s", server.PrivateIP) + goto OUT + default: + if utils.SSHExec("", server.PrivateIP, "root", 22, []string{ + "nc", + "-z", + "-w", + "1", + server.PrivateIP, + "22", + }, false, gateway, false) == nil { + goto OUT + } + time.Sleep(2 * time.Second) + } + } + OUT: + if err != nil { + logrus.Info(err) + err = nil + } + } + promise <- true + }() + + loop := 0 + for { + select { + case done := <-promise: + utils.LogQuiet("\r \r") + if !done { + return nil, err + } + return server, nil + case <-time.After(time.Millisecond * 100): + utils.LogQuiet(fmt.Sprintf("\r%c\r", "-\\|/"[loop%4])) + loop = loop + 1 + if loop == 5 { + loop = 0 + } + } + } +} + +// WaitForServerStopped wait for a server state to be stopped +func WaitForServerStopped(api *ScalewayAPI, serverID string) (*ScalewayServer, error) { + server, err := WaitForServerState(api, serverID, "stopped") + if err != nil { + return nil, err + } + return server, nil +} + +// ByCreationDate sorts images by CreationDate field +type ByCreationDate []ScalewayImageInterface + +func (a ByCreationDate) Len() int { return len(a) } +func (a ByCreationDate) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByCreationDate) Less(i, j int) bool { return a[j].CreationDate.Before(a[i].CreationDate) } + +// StartServer start a server based on its needle, can optionaly block while server is booting +func StartServer(api *ScalewayAPI, needle string, wait bool) error { + server, err := api.GetServerID(needle) + if err != nil { + return err + } + + if err = api.PostServerAction(server, "poweron"); err != nil { + return err + } + + if wait { + _, err = WaitForServerReady(api, server, "") + if err != nil { + return fmt.Errorf("failed to wait for server %s to be ready, %v", needle, err) + } + } + return nil +} + +// StartServerOnce wraps StartServer for golang channel +func StartServerOnce(api *ScalewayAPI, needle string, wait bool, successChan chan string, errChan chan error) { + err := StartServer(api, needle, wait) + + if err != nil { + errChan <- err + return + } + successChan <- needle +} + +// DeleteServerForce tries to delete a server using multiple ways +func (a *ScalewayAPI) DeleteServerForce(serverID string) error { + // FIXME: also delete attached volumes and ip address + // FIXME: call delete and stop -t in parallel to speed up process + err := a.DeleteServer(serverID) + if err == nil { + logrus.Infof("Server '%s' successfully deleted", serverID) + return nil + } + + err = a.PostServerAction(serverID, "terminate") + if err == nil { + logrus.Infof("Server '%s' successfully terminated", serverID) + return nil + } + + // FIXME: retry in a loop until timeout or Control+C + logrus.Errorf("Failed to delete server %s", serverID) + logrus.Errorf("Try to run 'scw rm -f %s' later", serverID) + return err +} + +// GetSSHFingerprintFromServer returns an array which containts ssh-host-fingerprints +func (a *ScalewayAPI) GetSSHFingerprintFromServer(serverID string) []string { + ret := []string{} + + if value, err := a.GetUserdata(serverID, "ssh-host-fingerprints", false); err == nil { + PublicKeys := strings.Split(string(*value), "\n") + for i := range PublicKeys { + if fingerprint, err := utils.SSHGetFingerprint([]byte(PublicKeys[i])); err == nil { + ret = append(ret, fingerprint) + } + } + } + return ret +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/logger.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/logger.go new file mode 100644 index 000000000..58ad93716 --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/logger.go @@ -0,0 +1,77 @@ +// Copyright (C) 2015 Scaleway. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE.md file. + +package api + +import ( + "fmt" + "log" + "net/http" + "os" +) + +// Logger handles logging concerns for the Scaleway API SDK +type Logger interface { + LogHTTP(*http.Request) + Fatalf(format string, v ...interface{}) + Debugf(format string, v ...interface{}) + Infof(format string, v ...interface{}) + Warnf(format string, v ...interface{}) +} + +// NewDefaultLogger returns a logger which is configured for stdout +func NewDefaultLogger() Logger { + return &defaultLogger{ + Logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +type defaultLogger struct { + *log.Logger +} + +func (l *defaultLogger) LogHTTP(r *http.Request) { + l.Printf("%s %s\n", r.Method, r.URL.RawPath) +} + +func (l *defaultLogger) Fatalf(format string, v ...interface{}) { + l.Printf("[FATAL] %s\n", fmt.Sprintf(format, v)) + os.Exit(1) +} + +func (l *defaultLogger) Debugf(format string, v ...interface{}) { + l.Printf("[DEBUG] %s\n", fmt.Sprintf(format, v)) +} + +func (l *defaultLogger) Infof(format string, v ...interface{}) { + l.Printf("[INFO ] %s\n", fmt.Sprintf(format, v)) +} + +func (l *defaultLogger) Warnf(format string, v ...interface{}) { + l.Printf("[WARN ] %s\n", fmt.Sprintf(format, v)) +} + +type disableLogger struct { +} + +// NewDisableLogger returns a logger which is configured to do nothing +func NewDisableLogger() Logger { + return &disableLogger{} +} + +func (d *disableLogger) LogHTTP(r *http.Request) { +} + +func (d *disableLogger) Fatalf(format string, v ...interface{}) { + panic(fmt.Sprintf(format, v)) +} + +func (d *disableLogger) Debugf(format string, v ...interface{}) { +} + +func (d *disableLogger) Infof(format string, v ...interface{}) { +} + +func (d *disableLogger) Warnf(format string, v ...interface{}) { +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/sshcommand/sshcommand.go b/vendor/github.com/scaleway/scaleway-cli/pkg/sshcommand/sshcommand.go new file mode 100644 index 000000000..676b2f976 --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/sshcommand/sshcommand.go @@ -0,0 +1,124 @@ +package sshcommand + +import ( + "fmt" + "runtime" + "strings" +) + +// Command contains settings to build a ssh command +type Command struct { + Host string + User string + Port int + SSHOptions []string + Gateway *Command + Command []string + Debug bool + NoEscapeCommand bool + SkipHostKeyChecking bool + Quiet bool + AllocateTTY bool + EnableSSHKeyForwarding bool + + isGateway bool +} + +// New returns a minimal Command +func New(host string) *Command { + return &Command{ + Host: host, + } +} + +func (c *Command) applyDefaults() { + if strings.Contains(c.Host, "@") { + parts := strings.Split(c.Host, "@") + c.User = parts[0] + c.Host = parts[1] + } + + if c.Port == 0 { + c.Port = 22 + } + + if c.isGateway { + c.SSHOptions = []string{"-W", "%h:%p"} + } +} + +// Slice returns an execve compatible slice of arguments +func (c *Command) Slice() []string { + c.applyDefaults() + + slice := []string{} + + slice = append(slice, "ssh") + + if c.EnableSSHKeyForwarding { + slice = append(slice, "-A") + } + + if c.Quiet { + slice = append(slice, "-q") + } + + if c.SkipHostKeyChecking { + slice = append(slice, "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no") + } + + if len(c.SSHOptions) > 0 { + slice = append(slice, c.SSHOptions...) + } + + if c.Gateway != nil { + c.Gateway.isGateway = true + slice = append(slice, "-o", "ProxyCommand="+c.Gateway.String()) + } + + if c.User != "" { + slice = append(slice, "-l", c.User) + } + + slice = append(slice, c.Host) + + if c.AllocateTTY { + slice = append(slice, "-t", "-t") + } + + slice = append(slice, "-p", fmt.Sprintf("%d", c.Port)) + if len(c.Command) > 0 { + slice = append(slice, "--", "/bin/sh", "-e") + if c.Debug { + slice = append(slice, "-x") + } + slice = append(slice, "-c") + + var escapedCommand []string + if c.NoEscapeCommand { + escapedCommand = c.Command + } else { + escapedCommand = []string{} + for _, part := range c.Command { + escapedCommand = append(escapedCommand, fmt.Sprintf("%q", part)) + } + } + slice = append(slice, fmt.Sprintf("%q", strings.Join(escapedCommand, " "))) + } + if runtime.GOOS == "windows" { + slice[len(slice)-1] = slice[len(slice)-1] + " " // Why ? + } + return slice +} + +// String returns a copy-pasteable command, useful for debugging +func (c *Command) String() string { + slice := c.Slice() + for i := range slice { + quoted := fmt.Sprintf("%q", slice[i]) + if strings.Contains(slice[i], " ") || len(quoted) != len(slice[i])+2 { + slice[i] = quoted + } + } + return strings.Join(slice, " ") +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/utils/quiet.go b/vendor/github.com/scaleway/scaleway-cli/pkg/utils/quiet.go new file mode 100644 index 000000000..775918d8d --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/utils/quiet.go @@ -0,0 +1,30 @@ +// Copyright (C) 2015 Scaleway. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE.md file. + +// Package utils contains logquiet +package utils + +import ( + "fmt" + "os" +) + +// LogQuietStruct is a struct to store information about quiet state +type LogQuietStruct struct { + quiet bool +} + +var instanceQuiet LogQuietStruct + +// Quiet enable or disable quiet +func Quiet(option bool) { + instanceQuiet.quiet = option +} + +// LogQuiet Displays info if quiet is activated +func LogQuiet(str string) { + if !instanceQuiet.quiet { + fmt.Fprintf(os.Stderr, "%s", str) + } +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go b/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go new file mode 100644 index 000000000..6f11f4869 --- /dev/null +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go @@ -0,0 +1,253 @@ +// Copyright (C) 2015 Scaleway. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE.md file. + +// scw helpers + +// Package utils contains helpers +package utils + +import ( + "crypto/md5" + "errors" + "fmt" + "io" + "net" + "os" + "os/exec" + "path" + "path/filepath" + "reflect" + "regexp" + "strings" + "time" + + "golang.org/x/crypto/ssh" + + "github.com/Sirupsen/logrus" + log "github.com/Sirupsen/logrus" + "github.com/mattn/go-isatty" + "github.com/moul/gotty-client" + "github.com/scaleway/scaleway-cli/pkg/sshcommand" +) + +// SpawnRedirection is used to redirects the fluxes +type SpawnRedirection struct { + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer +} + +// SSHExec executes a command over SSH and redirects file-descriptors +func SSHExec(publicIPAddress, privateIPAddress, user string, port int, command []string, checkConnection bool, gateway string, enableSSHKeyForwarding bool) error { + gatewayUser := "root" + gatewayIPAddress := gateway + if strings.Contains(gateway, "@") { + parts := strings.Split(gatewayIPAddress, "@") + if len(parts) != 2 { + return fmt.Errorf("gateway: must be like root@IP") + } + gatewayUser = parts[0] + gatewayIPAddress = parts[1] + gateway = gatewayUser + "@" + gatewayIPAddress + } + + if publicIPAddress == "" && gatewayIPAddress == "" { + return errors.New("server does not have public IP") + } + if privateIPAddress == "" && gatewayIPAddress != "" { + return errors.New("server does not have private IP") + } + + if checkConnection { + useGateway := gatewayIPAddress != "" + if useGateway && !IsTCPPortOpen(fmt.Sprintf("%s:22", gatewayIPAddress)) { + return errors.New("gateway is not available, try again later") + } + if !useGateway && !IsTCPPortOpen(fmt.Sprintf("%s:%d", publicIPAddress, port)) { + return errors.New("server is not ready, try again later") + } + } + + sshCommand := NewSSHExecCmd(publicIPAddress, privateIPAddress, user, port, isatty.IsTerminal(os.Stdin.Fd()), command, gateway, enableSSHKeyForwarding) + + log.Debugf("Executing: %s", sshCommand) + + spawn := exec.Command("ssh", sshCommand.Slice()[1:]...) + spawn.Stdout = os.Stdout + spawn.Stdin = os.Stdin + spawn.Stderr = os.Stderr + return spawn.Run() +} + +// NewSSHExecCmd computes execve compatible arguments to run a command via ssh +func NewSSHExecCmd(publicIPAddress, privateIPAddress, user string, port int, allocateTTY bool, command []string, gatewayIPAddress string, enableSSHKeyForwarding bool) *sshcommand.Command { + quiet := os.Getenv("DEBUG") != "1" + secureExec := os.Getenv("SCW_SECURE_EXEC") == "1" + sshCommand := &sshcommand.Command{ + AllocateTTY: allocateTTY, + Command: command, + Host: publicIPAddress, + Quiet: quiet, + SkipHostKeyChecking: !secureExec, + User: user, + NoEscapeCommand: true, + Port: port, + EnableSSHKeyForwarding: enableSSHKeyForwarding, + } + if gatewayIPAddress != "" { + sshCommand.Host = privateIPAddress + sshCommand.Gateway = &sshcommand.Command{ + Host: gatewayIPAddress, + SkipHostKeyChecking: !secureExec, + AllocateTTY: allocateTTY, + Quiet: quiet, + User: user, + Port: port, + } + } + + return sshCommand +} + +// GeneratingAnSSHKey generates an SSH key +func GeneratingAnSSHKey(cfg SpawnRedirection, path string, name string) (string, error) { + args := []string{ + "-t", + "rsa", + "-b", + "4096", + "-f", + filepath.Join(path, name), + "-N", + "", + "-C", + "", + } + log.Infof("Executing commands %v", args) + spawn := exec.Command("ssh-keygen", args...) + spawn.Stdout = cfg.Stdout + spawn.Stdin = cfg.Stdin + spawn.Stderr = cfg.Stderr + return args[5], spawn.Run() +} + +// WaitForTCPPortOpen calls IsTCPPortOpen in a loop +func WaitForTCPPortOpen(dest string) error { + for { + if IsTCPPortOpen(dest) { + break + } + time.Sleep(1 * time.Second) + } + return nil +} + +// IsTCPPortOpen returns true if a TCP communication with "host:port" can be initialized +func IsTCPPortOpen(dest string) bool { + conn, err := net.DialTimeout("tcp", dest, time.Duration(2000)*time.Millisecond) + if err == nil { + defer conn.Close() + } + return err == nil +} + +// TruncIf ensures the input string does not exceed max size if cond is met +func TruncIf(str string, max int, cond bool) string { + if cond && len(str) > max { + return str[:max] + } + return str +} + +// Wordify convert complex name to a single word without special shell characters +func Wordify(str string) string { + str = regexp.MustCompile(`[^a-zA-Z0-9-]`).ReplaceAllString(str, "_") + str = regexp.MustCompile(`__+`).ReplaceAllString(str, "_") + str = strings.Trim(str, "_") + return str +} + +// PathToTARPathparts returns the two parts of a unix path +func PathToTARPathparts(fullPath string) (string, string) { + fullPath = strings.TrimRight(fullPath, "/") + return path.Dir(fullPath), path.Base(fullPath) +} + +// RemoveDuplicates transforms an array into a unique array +func RemoveDuplicates(elements []string) []string { + encountered := map[string]bool{} + + // Create a map of all unique elements. + for v := range elements { + encountered[elements[v]] = true + } + + // Place all keys from the map into a slice. + result := []string{} + for key := range encountered { + result = append(result, key) + } + return result +} + +// AttachToSerial tries to connect to server serial using 'gotty-client' and fallback with a help message +func AttachToSerial(serverID, apiToken, url string) (*gottyclient.Client, chan bool, error) { + gottyURL := os.Getenv("SCW_GOTTY_URL") + if gottyURL == "" { + gottyURL = url + } + URL := fmt.Sprintf("%s?arg=%s&arg=%s", gottyURL, apiToken, serverID) + + logrus.Debug("Connection to ", URL) + gottycli, err := gottyclient.NewClient(URL) + if err != nil { + return nil, nil, err + } + + if os.Getenv("SCW_TLSVERIFY") == "0" { + gottycli.SkipTLSVerify = true + } + + gottycli.UseProxyFromEnv = true + + if err = gottycli.Connect(); err != nil { + return nil, nil, err + } + done := make(chan bool) + + fmt.Println("You are connected, type 'Ctrl+q' to quit.") + go func() { + gottycli.Loop() + gottycli.Close() + done <- true + }() + return gottycli, done, nil +} + +func rfc4716hex(data []byte) string { + fingerprint := "" + + for i := 0; i < len(data); i++ { + fingerprint = fmt.Sprintf("%s%0.2x", fingerprint, data[i]) + if i != len(data)-1 { + fingerprint = fingerprint + ":" + } + } + return fingerprint +} + +// SSHGetFingerprint returns the fingerprint of an SSH key +func SSHGetFingerprint(key []byte) (string, error) { + publicKey, comment, _, _, err := ssh.ParseAuthorizedKey(key) + if err != nil { + return "", err + } + switch reflect.TypeOf(publicKey).String() { + case "*ssh.rsaPublicKey", "*ssh.dsaPublicKey", "*ssh.ecdsaPublicKey": + md5sum := md5.Sum(publicKey.Marshal()) + return publicKey.Type() + " " + rfc4716hex(md5sum[:]) + " " + comment, nil + default: + return "", errors.New("Can't handle this key") + } +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go new file mode 100644 index 000000000..18379a935 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go @@ -0,0 +1,951 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package terminal + +import ( + "bytes" + "io" + "sync" + "unicode/utf8" +) + +// EscapeCodes contains escape sequences that can be written to the terminal in +// order to achieve different styles of text. +type EscapeCodes struct { + // Foreground colors + Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte + + // Reset all attributes + Reset []byte +} + +var vt100EscapeCodes = EscapeCodes{ + Black: []byte{keyEscape, '[', '3', '0', 'm'}, + Red: []byte{keyEscape, '[', '3', '1', 'm'}, + Green: []byte{keyEscape, '[', '3', '2', 'm'}, + Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, + Blue: []byte{keyEscape, '[', '3', '4', 'm'}, + Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, + Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, + White: []byte{keyEscape, '[', '3', '7', 'm'}, + + Reset: []byte{keyEscape, '[', '0', 'm'}, +} + +// Terminal contains the state for running a VT100 terminal that is capable of +// reading lines of input. +type Terminal struct { + // AutoCompleteCallback, if non-null, is called for each keypress with + // the full input line and the current position of the cursor (in + // bytes, as an index into |line|). If it returns ok=false, the key + // press is processed normally. Otherwise it returns a replacement line + // and the new cursor position. + AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) + + // Escape contains a pointer to the escape codes for this terminal. + // It's always a valid pointer, although the escape codes themselves + // may be empty if the terminal doesn't support them. + Escape *EscapeCodes + + // lock protects the terminal and the state in this object from + // concurrent processing of a key press and a Write() call. + lock sync.Mutex + + c io.ReadWriter + prompt []rune + + // line is the current line being entered. + line []rune + // pos is the logical position of the cursor in line + pos int + // echo is true if local echo is enabled + echo bool + // pasteActive is true iff there is a bracketed paste operation in + // progress. + pasteActive bool + + // cursorX contains the current X value of the cursor where the left + // edge is 0. cursorY contains the row number where the first row of + // the current line is 0. + cursorX, cursorY int + // maxLine is the greatest value of cursorY so far. + maxLine int + + termWidth, termHeight int + + // outBuf contains the terminal data to be sent. + outBuf []byte + // remainder contains the remainder of any partial key sequences after + // a read. It aliases into inBuf. + remainder []byte + inBuf [256]byte + + // history contains previously entered commands so that they can be + // accessed with the up and down keys. + history stRingBuffer + // historyIndex stores the currently accessed history entry, where zero + // means the immediately previous entry. + historyIndex int + // When navigating up and down the history it's possible to return to + // the incomplete, initial line. That value is stored in + // historyPending. + historyPending string +} + +// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is +// a local terminal, that terminal must first have been put into raw mode. +// prompt is a string that is written at the start of each input line (i.e. +// "> "). +func NewTerminal(c io.ReadWriter, prompt string) *Terminal { + return &Terminal{ + Escape: &vt100EscapeCodes, + c: c, + prompt: []rune(prompt), + termWidth: 80, + termHeight: 24, + echo: true, + historyIndex: -1, + } +} + +const ( + keyCtrlD = 4 + keyCtrlU = 21 + keyEnter = '\r' + keyEscape = 27 + keyBackspace = 127 + keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota + keyUp + keyDown + keyLeft + keyRight + keyAltLeft + keyAltRight + keyHome + keyEnd + keyDeleteWord + keyDeleteLine + keyClearScreen + keyPasteStart + keyPasteEnd +) + +var ( + crlf = []byte{'\r', '\n'} + pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'} + pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'} +) + +// bytesToKey tries to parse a key sequence from b. If successful, it returns +// the key and the remainder of the input. Otherwise it returns utf8.RuneError. +func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { + if len(b) == 0 { + return utf8.RuneError, nil + } + + if !pasteActive { + switch b[0] { + case 1: // ^A + return keyHome, b[1:] + case 5: // ^E + return keyEnd, b[1:] + case 8: // ^H + return keyBackspace, b[1:] + case 11: // ^K + return keyDeleteLine, b[1:] + case 12: // ^L + return keyClearScreen, b[1:] + case 23: // ^W + return keyDeleteWord, b[1:] + } + } + + if b[0] != keyEscape { + if !utf8.FullRune(b) { + return utf8.RuneError, b + } + r, l := utf8.DecodeRune(b) + return r, b[l:] + } + + if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { + switch b[2] { + case 'A': + return keyUp, b[3:] + case 'B': + return keyDown, b[3:] + case 'C': + return keyRight, b[3:] + case 'D': + return keyLeft, b[3:] + case 'H': + return keyHome, b[3:] + case 'F': + return keyEnd, b[3:] + } + } + + if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { + switch b[5] { + case 'C': + return keyAltRight, b[6:] + case 'D': + return keyAltLeft, b[6:] + } + } + + if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) { + return keyPasteStart, b[6:] + } + + if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) { + return keyPasteEnd, b[6:] + } + + // If we get here then we have a key that we don't recognise, or a + // partial sequence. It's not clear how one should find the end of a + // sequence without knowing them all, but it seems that [a-zA-Z~] only + // appears at the end of a sequence. + for i, c := range b[0:] { + if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' { + return keyUnknown, b[i+1:] + } + } + + return utf8.RuneError, b +} + +// queue appends data to the end of t.outBuf +func (t *Terminal) queue(data []rune) { + t.outBuf = append(t.outBuf, []byte(string(data))...) +} + +var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'} +var space = []rune{' '} + +func isPrintable(key rune) bool { + isInSurrogateArea := key >= 0xd800 && key <= 0xdbff + return key >= 32 && !isInSurrogateArea +} + +// moveCursorToPos appends data to t.outBuf which will move the cursor to the +// given, logical position in the text. +func (t *Terminal) moveCursorToPos(pos int) { + if !t.echo { + return + } + + x := visualLength(t.prompt) + pos + y := x / t.termWidth + x = x % t.termWidth + + up := 0 + if y < t.cursorY { + up = t.cursorY - y + } + + down := 0 + if y > t.cursorY { + down = y - t.cursorY + } + + left := 0 + if x < t.cursorX { + left = t.cursorX - x + } + + right := 0 + if x > t.cursorX { + right = x - t.cursorX + } + + t.cursorX = x + t.cursorY = y + t.move(up, down, left, right) +} + +func (t *Terminal) move(up, down, left, right int) { + movement := make([]rune, 3*(up+down+left+right)) + m := movement + for i := 0; i < up; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'A' + m = m[3:] + } + for i := 0; i < down; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'B' + m = m[3:] + } + for i := 0; i < left; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'D' + m = m[3:] + } + for i := 0; i < right; i++ { + m[0] = keyEscape + m[1] = '[' + m[2] = 'C' + m = m[3:] + } + + t.queue(movement) +} + +func (t *Terminal) clearLineToRight() { + op := []rune{keyEscape, '[', 'K'} + t.queue(op) +} + +const maxLineLength = 4096 + +func (t *Terminal) setLine(newLine []rune, newPos int) { + if t.echo { + t.moveCursorToPos(0) + t.writeLine(newLine) + for i := len(newLine); i < len(t.line); i++ { + t.writeLine(space) + } + t.moveCursorToPos(newPos) + } + t.line = newLine + t.pos = newPos +} + +func (t *Terminal) advanceCursor(places int) { + t.cursorX += places + t.cursorY += t.cursorX / t.termWidth + if t.cursorY > t.maxLine { + t.maxLine = t.cursorY + } + t.cursorX = t.cursorX % t.termWidth + + if places > 0 && t.cursorX == 0 { + // Normally terminals will advance the current position + // when writing a character. But that doesn't happen + // for the last character in a line. However, when + // writing a character (except a new line) that causes + // a line wrap, the position will be advanced two + // places. + // + // So, if we are stopping at the end of a line, we + // need to write a newline so that our cursor can be + // advanced to the next line. + t.outBuf = append(t.outBuf, '\r', '\n') + } +} + +func (t *Terminal) eraseNPreviousChars(n int) { + if n == 0 { + return + } + + if t.pos < n { + n = t.pos + } + t.pos -= n + t.moveCursorToPos(t.pos) + + copy(t.line[t.pos:], t.line[n+t.pos:]) + t.line = t.line[:len(t.line)-n] + if t.echo { + t.writeLine(t.line[t.pos:]) + for i := 0; i < n; i++ { + t.queue(space) + } + t.advanceCursor(n) + t.moveCursorToPos(t.pos) + } +} + +// countToLeftWord returns then number of characters from the cursor to the +// start of the previous word. +func (t *Terminal) countToLeftWord() int { + if t.pos == 0 { + return 0 + } + + pos := t.pos - 1 + for pos > 0 { + if t.line[pos] != ' ' { + break + } + pos-- + } + for pos > 0 { + if t.line[pos] == ' ' { + pos++ + break + } + pos-- + } + + return t.pos - pos +} + +// countToRightWord returns then number of characters from the cursor to the +// start of the next word. +func (t *Terminal) countToRightWord() int { + pos := t.pos + for pos < len(t.line) { + if t.line[pos] == ' ' { + break + } + pos++ + } + for pos < len(t.line) { + if t.line[pos] != ' ' { + break + } + pos++ + } + return pos - t.pos +} + +// visualLength returns the number of visible glyphs in s. +func visualLength(runes []rune) int { + inEscapeSeq := false + length := 0 + + for _, r := range runes { + switch { + case inEscapeSeq: + if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { + inEscapeSeq = false + } + case r == '\x1b': + inEscapeSeq = true + default: + length++ + } + } + + return length +} + +// handleKey processes the given key and, optionally, returns a line of text +// that the user has entered. +func (t *Terminal) handleKey(key rune) (line string, ok bool) { + if t.pasteActive && key != keyEnter { + t.addKeyToLine(key) + return + } + + switch key { + case keyBackspace: + if t.pos == 0 { + return + } + t.eraseNPreviousChars(1) + case keyAltLeft: + // move left by a word. + t.pos -= t.countToLeftWord() + t.moveCursorToPos(t.pos) + case keyAltRight: + // move right by a word. + t.pos += t.countToRightWord() + t.moveCursorToPos(t.pos) + case keyLeft: + if t.pos == 0 { + return + } + t.pos-- + t.moveCursorToPos(t.pos) + case keyRight: + if t.pos == len(t.line) { + return + } + t.pos++ + t.moveCursorToPos(t.pos) + case keyHome: + if t.pos == 0 { + return + } + t.pos = 0 + t.moveCursorToPos(t.pos) + case keyEnd: + if t.pos == len(t.line) { + return + } + t.pos = len(t.line) + t.moveCursorToPos(t.pos) + case keyUp: + entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) + if !ok { + return "", false + } + if t.historyIndex == -1 { + t.historyPending = string(t.line) + } + t.historyIndex++ + runes := []rune(entry) + t.setLine(runes, len(runes)) + case keyDown: + switch t.historyIndex { + case -1: + return + case 0: + runes := []rune(t.historyPending) + t.setLine(runes, len(runes)) + t.historyIndex-- + default: + entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) + if ok { + t.historyIndex-- + runes := []rune(entry) + t.setLine(runes, len(runes)) + } + } + case keyEnter: + t.moveCursorToPos(len(t.line)) + t.queue([]rune("\r\n")) + line = string(t.line) + ok = true + t.line = t.line[:0] + t.pos = 0 + t.cursorX = 0 + t.cursorY = 0 + t.maxLine = 0 + case keyDeleteWord: + // Delete zero or more spaces and then one or more characters. + t.eraseNPreviousChars(t.countToLeftWord()) + case keyDeleteLine: + // Delete everything from the current cursor position to the + // end of line. + for i := t.pos; i < len(t.line); i++ { + t.queue(space) + t.advanceCursor(1) + } + t.line = t.line[:t.pos] + t.moveCursorToPos(t.pos) + case keyCtrlD: + // Erase the character under the current position. + // The EOF case when the line is empty is handled in + // readLine(). + if t.pos < len(t.line) { + t.pos++ + t.eraseNPreviousChars(1) + } + case keyCtrlU: + t.eraseNPreviousChars(t.pos) + case keyClearScreen: + // Erases the screen and moves the cursor to the home position. + t.queue([]rune("\x1b[2J\x1b[H")) + t.queue(t.prompt) + t.cursorX, t.cursorY = 0, 0 + t.advanceCursor(visualLength(t.prompt)) + t.setLine(t.line, t.pos) + default: + if t.AutoCompleteCallback != nil { + prefix := string(t.line[:t.pos]) + suffix := string(t.line[t.pos:]) + + t.lock.Unlock() + newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key) + t.lock.Lock() + + if completeOk { + t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos])) + return + } + } + if !isPrintable(key) { + return + } + if len(t.line) == maxLineLength { + return + } + t.addKeyToLine(key) + } + return +} + +// addKeyToLine inserts the given key at the current position in the current +// line. +func (t *Terminal) addKeyToLine(key rune) { + if len(t.line) == cap(t.line) { + newLine := make([]rune, len(t.line), 2*(1+len(t.line))) + copy(newLine, t.line) + t.line = newLine + } + t.line = t.line[:len(t.line)+1] + copy(t.line[t.pos+1:], t.line[t.pos:]) + t.line[t.pos] = key + if t.echo { + t.writeLine(t.line[t.pos:]) + } + t.pos++ + t.moveCursorToPos(t.pos) +} + +func (t *Terminal) writeLine(line []rune) { + for len(line) != 0 { + remainingOnLine := t.termWidth - t.cursorX + todo := len(line) + if todo > remainingOnLine { + todo = remainingOnLine + } + t.queue(line[:todo]) + t.advanceCursor(visualLength(line[:todo])) + line = line[todo:] + } +} + +// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n. +func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) { + for len(buf) > 0 { + i := bytes.IndexByte(buf, '\n') + todo := len(buf) + if i >= 0 { + todo = i + } + + var nn int + nn, err = w.Write(buf[:todo]) + n += nn + if err != nil { + return n, err + } + buf = buf[todo:] + + if i >= 0 { + if _, err = w.Write(crlf); err != nil { + return n, err + } + n += 1 + buf = buf[1:] + } + } + + return n, nil +} + +func (t *Terminal) Write(buf []byte) (n int, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + if t.cursorX == 0 && t.cursorY == 0 { + // This is the easy case: there's nothing on the screen that we + // have to move out of the way. + return writeWithCRLF(t.c, buf) + } + + // We have a prompt and possibly user input on the screen. We + // have to clear it first. + t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) + t.cursorX = 0 + t.clearLineToRight() + + for t.cursorY > 0 { + t.move(1 /* up */, 0, 0, 0) + t.cursorY-- + t.clearLineToRight() + } + + if _, err = t.c.Write(t.outBuf); err != nil { + return + } + t.outBuf = t.outBuf[:0] + + if n, err = writeWithCRLF(t.c, buf); err != nil { + return + } + + t.writeLine(t.prompt) + if t.echo { + t.writeLine(t.line) + } + + t.moveCursorToPos(t.pos) + + if _, err = t.c.Write(t.outBuf); err != nil { + return + } + t.outBuf = t.outBuf[:0] + return +} + +// ReadPassword temporarily changes the prompt and reads a password, without +// echo, from the terminal. +func (t *Terminal) ReadPassword(prompt string) (line string, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + oldPrompt := t.prompt + t.prompt = []rune(prompt) + t.echo = false + + line, err = t.readLine() + + t.prompt = oldPrompt + t.echo = true + + return +} + +// ReadLine returns a line of input from the terminal. +func (t *Terminal) ReadLine() (line string, err error) { + t.lock.Lock() + defer t.lock.Unlock() + + return t.readLine() +} + +func (t *Terminal) readLine() (line string, err error) { + // t.lock must be held at this point + + if t.cursorX == 0 && t.cursorY == 0 { + t.writeLine(t.prompt) + t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + } + + lineIsPasted := t.pasteActive + + for { + rest := t.remainder + lineOk := false + for !lineOk { + var key rune + key, rest = bytesToKey(rest, t.pasteActive) + if key == utf8.RuneError { + break + } + if !t.pasteActive { + if key == keyCtrlD { + if len(t.line) == 0 { + return "", io.EOF + } + } + if key == keyPasteStart { + t.pasteActive = true + if len(t.line) == 0 { + lineIsPasted = true + } + continue + } + } else if key == keyPasteEnd { + t.pasteActive = false + continue + } + if !t.pasteActive { + lineIsPasted = false + } + line, lineOk = t.handleKey(key) + } + if len(rest) > 0 { + n := copy(t.inBuf[:], rest) + t.remainder = t.inBuf[:n] + } else { + t.remainder = nil + } + t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + if lineOk { + if t.echo { + t.historyIndex = -1 + t.history.Add(line) + } + if lineIsPasted { + err = ErrPasteIndicator + } + return + } + + // t.remainder is a slice at the beginning of t.inBuf + // containing a partial key sequence + readBuf := t.inBuf[len(t.remainder):] + var n int + + t.lock.Unlock() + n, err = t.c.Read(readBuf) + t.lock.Lock() + + if err != nil { + return + } + + t.remainder = t.inBuf[:n+len(t.remainder)] + } +} + +// SetPrompt sets the prompt to be used when reading subsequent lines. +func (t *Terminal) SetPrompt(prompt string) { + t.lock.Lock() + defer t.lock.Unlock() + + t.prompt = []rune(prompt) +} + +func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) { + // Move cursor to column zero at the start of the line. + t.move(t.cursorY, 0, t.cursorX, 0) + t.cursorX, t.cursorY = 0, 0 + t.clearLineToRight() + for t.cursorY < numPrevLines { + // Move down a line + t.move(0, 1, 0, 0) + t.cursorY++ + t.clearLineToRight() + } + // Move back to beginning. + t.move(t.cursorY, 0, 0, 0) + t.cursorX, t.cursorY = 0, 0 + + t.queue(t.prompt) + t.advanceCursor(visualLength(t.prompt)) + t.writeLine(t.line) + t.moveCursorToPos(t.pos) +} + +func (t *Terminal) SetSize(width, height int) error { + t.lock.Lock() + defer t.lock.Unlock() + + if width == 0 { + width = 1 + } + + oldWidth := t.termWidth + t.termWidth, t.termHeight = width, height + + switch { + case width == oldWidth: + // If the width didn't change then nothing else needs to be + // done. + return nil + case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0: + // If there is nothing on current line and no prompt printed, + // just do nothing + return nil + case width < oldWidth: + // Some terminals (e.g. xterm) will truncate lines that were + // too long when shinking. Others, (e.g. gnome-terminal) will + // attempt to wrap them. For the former, repainting t.maxLine + // works great, but that behaviour goes badly wrong in the case + // of the latter because they have doubled every full line. + + // We assume that we are working on a terminal that wraps lines + // and adjust the cursor position based on every previous line + // wrapping and turning into two. This causes the prompt on + // xterms to move upwards, which isn't great, but it avoids a + // huge mess with gnome-terminal. + if t.cursorX >= t.termWidth { + t.cursorX = t.termWidth - 1 + } + t.cursorY *= 2 + t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2) + case width > oldWidth: + // If the terminal expands then our position calculations will + // be wrong in the future because we think the cursor is + // |t.pos| chars into the string, but there will be a gap at + // the end of any wrapped line. + // + // But the position will actually be correct until we move, so + // we can move back to the beginning and repaint everything. + t.clearAndRepaintLinePlusNPrevious(t.maxLine) + } + + _, err := t.c.Write(t.outBuf) + t.outBuf = t.outBuf[:0] + return err +} + +type pasteIndicatorError struct{} + +func (pasteIndicatorError) Error() string { + return "terminal: ErrPasteIndicator not correctly handled" +} + +// ErrPasteIndicator may be returned from ReadLine as the error, in addition +// to valid line data. It indicates that bracketed paste mode is enabled and +// that the returned line consists only of pasted data. Programs may wish to +// interpret pasted data more literally than typed data. +var ErrPasteIndicator = pasteIndicatorError{} + +// SetBracketedPasteMode requests that the terminal bracket paste operations +// with markers. Not all terminals support this but, if it is supported, then +// enabling this mode will stop any autocomplete callback from running due to +// pastes. Additionally, any lines that are completely pasted will be returned +// from ReadLine with the error set to ErrPasteIndicator. +func (t *Terminal) SetBracketedPasteMode(on bool) { + if on { + io.WriteString(t.c, "\x1b[?2004h") + } else { + io.WriteString(t.c, "\x1b[?2004l") + } +} + +// stRingBuffer is a ring buffer of strings. +type stRingBuffer struct { + // entries contains max elements. + entries []string + max int + // head contains the index of the element most recently added to the ring. + head int + // size contains the number of elements in the ring. + size int +} + +func (s *stRingBuffer) Add(a string) { + if s.entries == nil { + const defaultNumEntries = 100 + s.entries = make([]string, defaultNumEntries) + s.max = defaultNumEntries + } + + s.head = (s.head + 1) % s.max + s.entries[s.head] = a + if s.size < s.max { + s.size++ + } +} + +// NthPreviousEntry returns the value passed to the nth previous call to Add. +// If n is zero then the immediately prior value is returned, if one, then the +// next most recent, and so on. If such an element doesn't exist then ok is +// false. +func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { + if n >= s.size { + return "", false + } + index := s.head - n + if index < 0 { + index += s.max + } + return s.entries[index], true +} + +// readPasswordLine reads from reader until it finds \n or io.EOF. +// The slice returned does not include the \n. +// readPasswordLine also ignores any \r it finds. +func readPasswordLine(reader io.Reader) ([]byte, error) { + var buf [1]byte + var ret []byte + + for { + n, err := reader.Read(buf[:]) + if n > 0 { + switch buf[0] { + case '\n': + return ret, nil + case '\r': + // remove \r from passwords on Windows + default: + ret = append(ret, buf[0]) + } + continue + } + if err != nil { + if err == io.EOF && len(ret) > 0 { + return ret, nil + } + return ret, err + } + } +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go new file mode 100644 index 000000000..d01919614 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util.go @@ -0,0 +1,119 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal // import "golang.org/x/crypto/ssh/terminal" + +import ( + "syscall" + "unsafe" +) + +// State contains the state of a terminal. +type State struct { + termios syscall.Termios +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + var oldState State + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + return nil, err + } + + newState := oldState.termios + // This attempts to replicate the behaviour documented for cfmakeraw in + // the termios(3) manpage. + newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON + newState.Oflag &^= syscall.OPOST + newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN + newState.Cflag &^= syscall.CSIZE | syscall.PARENB + newState.Cflag |= syscall.CS8 + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { + return nil, err + } + + return &oldState, nil +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + var oldState State + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + return nil, err + } + + return &oldState, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0); err != 0 { + return err + } + return nil +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + var dimensions [4]uint16 + + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { + return -1, -1, err + } + return int(dimensions[1]), int(dimensions[0]), nil +} + +// passwordReader is an io.Reader that reads from a specific file descriptor. +type passwordReader int + +func (r passwordReader) Read(buf []byte) (int, error) { + return syscall.Read(int(r), buf) +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + var oldState syscall.Termios + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { + return nil, err + } + + newState := oldState + newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL + if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { + return nil, err + } + + defer func() { + syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) + }() + + return readPasswordLine(passwordReader(fd)) +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go new file mode 100644 index 000000000..9c1ffd145 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go @@ -0,0 +1,12 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd netbsd openbsd + +package terminal + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA +const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go new file mode 100644 index 000000000..5883b22d7 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go @@ -0,0 +1,11 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package terminal + +// These constants are declared here, rather than importing +// them from the syscall package as some syscall packages, even +// on linux, for example gccgo, do not declare them. +const ioctlReadTermios = 0x5401 // syscall.TCGETS +const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go new file mode 100644 index 000000000..799f049f0 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go @@ -0,0 +1,58 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal + +import ( + "fmt" + "runtime" +) + +type State struct{} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + return false +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go new file mode 100644 index 000000000..07eb5edd7 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go @@ -0,0 +1,73 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build solaris + +package terminal // import "golang.org/x/crypto/ssh/terminal" + +import ( + "golang.org/x/sys/unix" + "io" + "syscall" +) + +// State contains the state of a terminal. +type State struct { + termios syscall.Termios +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + // see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c + var termio unix.Termio + err := unix.IoctlSetTermio(fd, unix.TCGETA, &termio) + return err == nil +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + // see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c + val, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + oldState := *val + + newState := oldState + newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL + err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState) + if err != nil { + return nil, err + } + + defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState) + + var buf [16]byte + var ret []byte + for { + n, err := syscall.Read(fd, buf[:]) + if err != nil { + return nil, err + } + if n == 0 { + if len(ret) == 0 { + return nil, io.EOF + } + break + } + if buf[n-1] == '\n' { + n-- + } + ret = append(ret, buf[:n]...) + if n < len(buf) { + break + } + } + + return ret, nil +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go new file mode 100644 index 000000000..e0a1f36ce --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go @@ -0,0 +1,155 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +// Package terminal provides support functions for dealing with terminals, as +// commonly found on UNIX systems. +// +// Putting a terminal into raw mode is the most common requirement: +// +// oldState, err := terminal.MakeRaw(0) +// if err != nil { +// panic(err) +// } +// defer terminal.Restore(0, oldState) +package terminal + +import ( + "syscall" + "unsafe" +) + +const ( + enableLineInput = 2 + enableEchoInput = 4 + enableProcessedInput = 1 + enableWindowInput = 8 + enableMouseInput = 16 + enableInsertMode = 32 + enableQuickEditMode = 64 + enableExtendedFlags = 128 + enableAutoPosition = 256 + enableProcessedOutput = 1 + enableWrapAtEolOutput = 2 +) + +var kernel32 = syscall.NewLazyDLL("kernel32.dll") + +var ( + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procSetConsoleMode = kernel32.NewProc("SetConsoleMode") + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") +) + +type ( + short int16 + word uint16 + + coord struct { + x short + y short + } + smallRect struct { + left short + top short + right short + bottom short + } + consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes word + window smallRect + maximumWindowSize coord + } +) + +type State struct { + mode uint32 +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd int) bool { + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + var st uint32 + _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + if e != 0 { + return nil, error(e) + } + raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) + _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0) + if e != 0 { + return nil, error(e) + } + return &State{st}, nil +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + var st uint32 + _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + if e != 0 { + return nil, error(e) + } + return &State{st}, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, state *State) error { + _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0) + return err +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return 0, 0, error(e) + } + return int(info.size.x), int(info.size.y), nil +} + +// passwordReader is an io.Reader that reads from a specific Windows HANDLE. +type passwordReader int + +func (r passwordReader) Read(buf []byte) (int, error) { + return syscall.Read(syscall.Handle(r), buf) +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + var st uint32 + _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + if e != 0 { + return nil, error(e) + } + old := st + + st &^= (enableEchoInput) + st |= (enableProcessedInput | enableLineInput | enableProcessedOutput) + _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) + if e != 0 { + return nil, error(e) + } + + defer func() { + syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0) + }() + + return readPasswordLine(passwordReader(fd)) +} diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE new file mode 100644 index 000000000..6a66aea5e --- /dev/null +++ b/vendor/golang.org/x/sync/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/sync/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go new file mode 100644 index 000000000..533438d91 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -0,0 +1,67 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package errgroup provides synchronization, error propagation, and Context +// cancelation for groups of goroutines working on subtasks of a common task. +package errgroup + +import ( + "sync" + + "golang.org/x/net/context" +) + +// A Group is a collection of goroutines working on subtasks that are part of +// the same overall task. +// +// A zero Group is valid and does not cancel on error. +type Group struct { + cancel func() + + wg sync.WaitGroup + + errOnce sync.Once + err error +} + +// WithContext returns a new Group and an associated Context derived from ctx. +// +// The derived Context is canceled the first time a function passed to Go +// returns a non-nil error or the first time Wait returns, whichever occurs +// first. +func WithContext(ctx context.Context) (*Group, context.Context) { + ctx, cancel := context.WithCancel(ctx) + return &Group{cancel: cancel}, ctx +} + +// Wait blocks until all function calls from the Go method have returned, then +// returns the first non-nil error (if any) from them. +func (g *Group) Wait() error { + g.wg.Wait() + if g.cancel != nil { + g.cancel() + } + return g.err +} + +// Go calls the given function in a new goroutine. +// +// The first call to return a non-nil error cancels the group; its error will be +// returned by Wait. +func (g *Group) Go(f func() error) { + g.wg.Add(1) + + go func() { + defer g.wg.Done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel() + } + }) + } + }() +} From 4c7a467e9e7ac5a69754a6d616cd5a0c98ce0f13 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 11:53:05 -0800 Subject: [PATCH 0627/1007] format scaleway docs --- website/source/docs/builders/scaleway.html.md | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index efa26dbee..b1864bdb0 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -4,10 +4,10 @@ sidebar_current: docs-builders-scaleway page_title: Scaleway - Builders description: |- The Scaleway Packer builder is able to create new images for use with - Scaleway BareMetal and Virtual cloud server. The builder takes a source image, runs any provisioning - necessary on the image after launching it, then snapshots it into a reusable - image. This reusable image can then be used as the foundation of new servers - that are launched within Scaleway. + Scaleway BareMetal and Virtual cloud server. The builder takes a source + image, runs any provisioning necessary on the image after launching it, then + snapshots it into a reusable image. This reusable image can then be used as + the foundation of new servers that are launched within Scaleway. --- @@ -36,36 +36,40 @@ builder. ### Required: -- `api_access_key` (string) - The api_access_key to use to access your account. - It can also be specified via - environment variable `SCALEWAY_API_ACCESS_KEY`. - Your access key is available in the ["Credentials" section](https://cloud.scaleway.com/#/credentials) of the control panel. +- `api_access_key` (string) - The api\_access\_key to use to access your + account. It can also be specified via environment variable + `SCALEWAY_API_ACCESS_KEY`. Your access key is available in the + ["Credentials" section](https://cloud.scaleway.com/#/credentials) of the + control panel. -- `api_token` (string) - The organization TOKEN to use to access your account. - It can also be specified via - environment variable `SCALEWAY_API_TOKEN`. - Your tokens are available in the ["Credentials" section](https://cloud.scaleway.com/#/credentials) of the control panel. +- `api_token` (string) - The organization TOKEN to use to access your + account. It can also be specified via environment variable + `SCALEWAY_API_TOKEN`. Your tokens are available in the ["Credentials" + section](https://cloud.scaleway.com/#/credentials) of the control panel. -- `image` (string) - The UUID of the base image to use. This is the - image that will be used to launch a new server and provision it. See - [https://api-marketplace.scaleway.com/images](https://api-marketplace.scaleway.com/images) - get the complete list of the accepted image UUID. +- `image` (string) - The UUID of the base image to use. This is the image + that will be used to launch a new server and provision it. See + <https://api-marketplace.scaleway.com/images> get the complete list of the + accepted image UUID. -- `region` (string) - The name of the region to launch the - server in (`par1` or `ams1`). Consequently, this is the region where the snapshot will - be available. +- `region` (string) - The name of the region to launch the server in (`par1` + or `ams1`). Consequently, this is the region where the snapshot will be + available. -- `commercial_type` (string) - The name of the server commercial type: `C1`, `C2S`, `C2M`, - `C2L`, `X64-2GB`, `X64-4GB`, `X64-8GB`, `X64-15GB`, `X64-30GB`, `X64-60GB`, `X64-120GB`, `ARM64-2GB`, `ARM64-4GB`, `ARM64-8GB`, `ARM64-16GB`, `ARM64-32GB`, `ARM64-64GB`, `ARM64-128GB` +- `commercial_type` (string) - The name of the server commercial type: `C1`, + `C2S`, `C2M`, `C2L`, `X64-2GB`, `X64-4GB`, `X64-8GB`, `X64-15GB`, + `X64-30GB`, `X64-60GB`, `X64-120GB`, `ARM64-2GB`, `ARM64-4GB`, `ARM64-8GB`, + `ARM64-16GB`, `ARM64-32GB`, `ARM64-64GB`, `ARM64-128GB` ### Optional: -- `server_name` (string) - The name assigned to the server. Default `packer-UUID` +- `server_name` (string) - The name assigned to the server. Default + `packer-UUID` -- `image_name` (string) - The name of the resulting image that will - appear in your account. Default `packer-TIMESTAMP` +- `image_name` (string) - The name of the resulting image that will appear in + your account. Default `packer-TIMESTAMP` -- `snapshot_name` (string) - The name of the resulting snapshot that will +- `snapshot_name` (string) - The name of the resulting snapshot that will appear in your account. Default `packer-TIMESTAMP` ## Basic Example @@ -86,5 +90,6 @@ access tokens: } ``` -When you do not specified the `ssh_private_key_file`, a temporarily SSH keypair is generated to connect the server. -This key will only allow the `root` user to connect the server. +When you do not specified the `ssh_private_key_file`, a temporarily SSH keypair +is generated to connect the server. This key will only allow the `root` user to +connect the server. From e5ab2062769b8d8232ed622f3c774d560af07647 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 12:33:51 -0800 Subject: [PATCH 0628/1007] add our 3 new builders to changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8c3105e8..ada8d8e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ ### IMPROVEMENTS: +* **New builder:** `scaleway` - The Scaleway Packer builder is able to create new images for use with Scaleway BareMetal and Virtual cloud server. [GH-4770] +* **New builder:** `ncloud` for building server images using the NAVER Cloud Platform. [GH-5791] +* **New builder:** `oci-classic` for building new custom images for use with Oracle Cloud Infrastructure Classic Compute. [GH-5819] * builder/docker: Remove credentials from being shown in the log. [GH-5666] * builder/triton: Triton RBAC is now supported. [GH-5741] * provisioner/ansible: Improve user retrieval. [GH-5758] From ad2e5f1f08c97058d135cb19c0ee484fc6c29399 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 8 Feb 2018 12:52:44 -0800 Subject: [PATCH 0629/1007] fail in oracle classic builder if user tries winrm since it doesn't work yet, and add attributes and attributes_file fields to oracle builder --- builder/oracle/classic/config.go | 16 ++++++++++ .../oracle/classic/step_create_instance.go | 30 +++++++++++++++++++ builder/oracle/classic/step_list_images.go | 30 ++++++++++++++++--- .../docs/builders/oracle-classic.html.md | 13 +++++++- 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 4cd7c42a7..52a08cbe9 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -3,6 +3,7 @@ package classic import ( "fmt" "net/url" + "os" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -27,6 +28,9 @@ type Config struct { Shape string `mapstructure:"shape"` SourceImageList string `mapstructure:"source_image_list"` DestImageList string `mapstructure:"dest_image_list"` + // Attributes and Atributes file are both optional and mutually exclusive. + Attributes string `mapstructure:"attributes"` + AttributesFile string `mapstructure:"attributes_file"` // Optional; if you don't enter anything, the image list description // will read "Packer-built image list" DestImageListDescription string `mapstructure:"image_description"` @@ -81,9 +85,21 @@ func NewConfig(raws ...interface{}) (*Config, error) { } } + if c.Attributes != "" && c.AttributesFile != "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) + } else if c.AttributesFile != "" { + if _, err := os.Stat(c.AttributesFile); err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("attributes_file not found: %s", c.AttributesFile)) + } + } + if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { errs = packer.MultiErrorAppend(errs, es...) } + if c.Comm.Type == "winrm" { + err = fmt.Errorf("winRM is not supported with the oracle-classic builder yet.") + errs = packer.MultiErrorAppend(errs, err) + } if errs != nil && len(errs.Errors) > 0 { return nil, errs diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index 041889ab1..cf4b043fe 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -2,7 +2,9 @@ package classic import ( "context" + "encoding/json" "fmt" + "io/ioutil" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/helper/multistep" @@ -30,6 +32,33 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu // get instances client instanceClient := client.Instances() + var data map[string]interface{} + + if config.Attributes != "" { + err := json.Unmarshal([]byte(config.Attributes), &data) + if err != nil { + err = fmt.Errorf("Problem parsing json from attributes: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + } else if config.AttributesFile != "" { + fidata, err := ioutil.ReadFile(config.AttributesFile) + if err != nil { + err = fmt.Errorf("Problem reading attributes_file: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + err = json.Unmarshal(fidata, &data) + if err != nil { + err = fmt.Errorf("Problem parsing json from attrinutes_file: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + } + // Instances Input input := &compute.CreateInstanceInput{ Name: config.ImageName, @@ -37,6 +66,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu ImageList: config.SourceImageList, SSHKeys: []string{keyName}, Networking: map[string]compute.NetworkingInfo{"eth0": netInfo}, + Attributes: data, } instanceInfo, err := instanceClient.CreateInstance(input) diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go index a99612c14..247b96146 100644 --- a/builder/oracle/classic/step_list_images.go +++ b/builder/oracle/classic/step_list_images.go @@ -11,11 +11,10 @@ import ( type stepListImages struct{} -func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - // get variables from state - ui := state.Get("ui").(packer.Ui) - config := state.Get("config").(*Config) +func (s *stepListImages) listForSSH(state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*compute.ComputeClient) + config := state.Get("config").(*Config) + ui := state.Get("ui").(packer.Ui) ui.Say("Adding image to image list...") imageListClient := client.ImageList() @@ -98,6 +97,29 @@ func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multis return multistep.ActionContinue } +func (s *stepListImages) listForWinRM(state multistep.StateBag) multistep.StepAction { + // This is a placeholder function; we will never reach this because we already + // return an error when winRM is set when validating the Packer config. + ui := state.Get("ui").(packer.Ui) + err := fmt.Errorf("The Oracle Classic builder does not currently support winRM.") + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt +} + +func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // get variables from state + config := state.Get("config").(*Config) + + var action multistep.StepAction + if config.Comm.Type == "winrm" { + action = s.listForWinRM(state) + } else if config.Comm.Type == "ssh" { + action = s.listForSSH(state) + } + return action +} + func (s *stepListImages) Cleanup(state multistep.StateBag) { // Nothing to do return diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index f8991b968..98db5f2aa 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -63,6 +63,16 @@ This builder currently only works with the SSH communicator. ### Optional + - `attributes` (string) - (string) - Attributes to apply when launching the + instance. Note that you need to be careful about escaping characters due to + the templates being JSON. It is often more convenient to use + `attributes_file`, instead. You may only define either `attributes` or + `attributes_file`, not both. + + - `attributes_file` (string) - Path to a json file that will be used for the + attributes when launching the instance. You may only define either + `attributes` or `attributes_file`, not both. + - `image_description` (string) - a description for your destination image list. If you don't provide one, Packer will provide a generic description. @@ -91,7 +101,8 @@ obfuscated; you will need to add a working `username`, `password`, "api_endpoint": "https://api-###.compute.###.oraclecloud.com/", "source_image_list": "/oracle/public/OL_7.2_UEKR4_x86_64", "shape": "oc3", - "image_name": "Packer_Builder_Test_{{timestamp}}" + "image_name": "Packer_Builder_Test_{{timestamp}}", + "attributes": "{\"userdata\": {\"pre-bootstrap\": {\"script\": [\"...\"]}}}", "dest_image_list": "Packer_Builder_Test_List" } ], From ff717c57844bdfb2a934f1a41f7b538596070a2e Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 8 Feb 2018 13:21:21 -0800 Subject: [PATCH 0630/1007] wrong place for differentiation between ssh and winrm --- builder/oracle/classic/step_list_images.go | 30 +++------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/builder/oracle/classic/step_list_images.go b/builder/oracle/classic/step_list_images.go index 247b96146..a99612c14 100644 --- a/builder/oracle/classic/step_list_images.go +++ b/builder/oracle/classic/step_list_images.go @@ -11,10 +11,11 @@ import ( type stepListImages struct{} -func (s *stepListImages) listForSSH(state multistep.StateBag) multistep.StepAction { - client := state.Get("client").(*compute.ComputeClient) - config := state.Get("config").(*Config) +func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // get variables from state ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) + client := state.Get("client").(*compute.ComputeClient) ui.Say("Adding image to image list...") imageListClient := client.ImageList() @@ -97,29 +98,6 @@ func (s *stepListImages) listForSSH(state multistep.StateBag) multistep.StepActi return multistep.ActionContinue } -func (s *stepListImages) listForWinRM(state multistep.StateBag) multistep.StepAction { - // This is a placeholder function; we will never reach this because we already - // return an error when winRM is set when validating the Packer config. - ui := state.Get("ui").(packer.Ui) - err := fmt.Errorf("The Oracle Classic builder does not currently support winRM.") - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt -} - -func (s *stepListImages) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - // get variables from state - config := state.Get("config").(*Config) - - var action multistep.StepAction - if config.Comm.Type == "winrm" { - action = s.listForWinRM(state) - } else if config.Comm.Type == "ssh" { - action = s.listForSSH(state) - } - return action -} - func (s *stepListImages) Cleanup(state multistep.StateBag) { // Nothing to do return From 7f631fcb772616af9d8da80d66f4a4133acdaa7f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 8 Feb 2018 14:12:39 -0800 Subject: [PATCH 0631/1007] unpack attributes in oracle-classic builder earlier so that we error fast if there's an issue --- builder/oracle/classic/config.go | 28 +++++++++++++++++ .../oracle/classic/step_create_instance.go | 31 +------------------ 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 52a08cbe9..233a3a0d1 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -1,7 +1,9 @@ package classic import ( + "encoding/json" "fmt" + "io/ioutil" "net/url" "os" @@ -15,6 +17,7 @@ import ( type Config struct { common.PackerConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` + attribs map[string]interface{} // Access config overrides Username string `mapstructure:"username"` @@ -105,5 +108,30 @@ func NewConfig(raws ...interface{}) (*Config, error) { return nil, errs } + // unpack attributes from json into config + var data map[string]interface{} + + if c.Attributes != "" { + err := json.Unmarshal([]byte(c.Attributes), &data) + if err != nil { + err = fmt.Errorf("Problem parsing json from attributes: %s", err) + packer.MultiErrorAppend(errs, err) + } + c.attribs = data + } else if c.AttributesFile != "" { + fidata, err := ioutil.ReadFile(c.AttributesFile) + if err != nil { + err = fmt.Errorf("Problem reading attributes_file: %s", err) + packer.MultiErrorAppend(errs, err) + } + err = json.Unmarshal(fidata, &data) + c.attribs = data + if err != nil { + err = fmt.Errorf("Problem parsing json from attrinutes_file: %s", err) + packer.MultiErrorAppend(errs, err) + } + c.attribs = data + } + return c, nil } diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index cf4b043fe..cda67122c 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -2,9 +2,7 @@ package classic import ( "context" - "encoding/json" "fmt" - "io/ioutil" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/helper/multistep" @@ -32,33 +30,6 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu // get instances client instanceClient := client.Instances() - var data map[string]interface{} - - if config.Attributes != "" { - err := json.Unmarshal([]byte(config.Attributes), &data) - if err != nil { - err = fmt.Errorf("Problem parsing json from attributes: %s", err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt - } - } else if config.AttributesFile != "" { - fidata, err := ioutil.ReadFile(config.AttributesFile) - if err != nil { - err = fmt.Errorf("Problem reading attributes_file: %s", err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt - } - err = json.Unmarshal(fidata, &data) - if err != nil { - err = fmt.Errorf("Problem parsing json from attrinutes_file: %s", err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt - } - } - // Instances Input input := &compute.CreateInstanceInput{ Name: config.ImageName, @@ -66,7 +37,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu ImageList: config.SourceImageList, SSHKeys: []string{keyName}, Networking: map[string]compute.NetworkingInfo{"eth0": netInfo}, - Attributes: data, + Attributes: config.attribs, } instanceInfo, err := instanceClient.CreateInstance(input) From a9b48309c90ae67598af90b4398bbd16958a0abd Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 14:48:04 -0800 Subject: [PATCH 0632/1007] update amazon authentication docs Correct docs to reflect new behavior. This is largely borrowed from terraform. --- website/source/docs/builders/amazon.html.md | 105 ++++++++++++++------ 1 file changed, 73 insertions(+), 32 deletions(-) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index e77e4bf79..7e7b763c9 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -49,49 +49,90 @@ filesystem and data. <span id="specifying-amazon-credentials"></span> -## Specifying Amazon Credentials +## Authentication -When you use any of the amazon builders, you must provide credentials to the API -in the form of an access key id and secret. These look like: +The AWS provider offers a flexible means of providing credentials for +authentication. The following methods are supported, in this order, and +explained below: - access key id: AKIAIOSFODNN7EXAMPLE - secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY +- Static credentials +- Environment variables +- Shared credentials file +- EC2 Role -If you use other AWS tools you may already have these configured. If so, packer -will try to use them, *unless* they are specified in your packer template. -Credentials are resolved in the following order: +### Static Credentials -1. Values hard-coded in the packer template are always authoritative. -2. *Variables* in the packer template may be resolved from command-line flags - or from environment variables. Please read about [User - Variables](https://www.packer.io/docs/templates/user-variables.html) - for details. -3. If no credentials are found, packer falls back to automatic lookup. +Static credentials can be provided in the form of an access key id and secret. +These look like: -### Automatic Lookup +```json +{ + "access_key": "AKIAIOSFODNN7EXAMPLE", + "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "region": "us-east-1", + "type": "amazon-ebs" +} +``` -Packer depends on the [AWS -SDK](https://aws.amazon.com/documentation/sdk-for-go/) to perform automatic -lookup using *credential chains*. In short, the SDK looks for credentials in -the following order: +### Environment variables -1. Environment variables. -2. Shared credentials file. -3. If your application is running on an Amazon EC2 instance, IAM role for Amazon EC2. +You can provide your credentials via the `AWS_ACCESS_KEY_ID` and +`AWS_SECRET_ACCESS_KEY`, environment variables, representing your AWS Access +Key and AWS Secret Key, respectively. Note that setting your AWS credentials +using either these environment variables will override the use of +`AWS_SHARED_CREDENTIALS_FILE` and `AWS_PROFILE`. The `AWS_DEFAULT_REGION` and +`AWS_SESSION_TOKEN` environment variables are also used, if applicable: -Please refer to the SDK's documentation on [specifying -credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials) -for more information. -## Using an IAM Task or Instance Role +Usage: -If AWS keys are not specified in the template, a -[shared credentials file](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-config-files) -or through environment variables Packer will use credentials provided by -the task's or instance's IAM role, if it has one. +``` +$ export AWS_ACCESS_KEY_ID="anaccesskey" +$ export AWS_SECRET_ACCESS_KEY="asecretkey" +$ export AWS_DEFAULT_REGION="us-west-2" +$ packer build packer.json +``` -The following policy document provides the minimal set permissions necessary for -Packer to work: +### Shared Credentials file + +You can use an AWS credentials file to specify your credentials. The default +location is &#36;HOME/.aws/credentials on Linux and OS X, or +"%USERPROFILE%.aws\credentials" for Windows users. If we fail to detect +credentials inline, or in the environment, Packer will check this location. You +can optionally specify a different location in the configuration by setting the +environment with the `AWS_SHARED_CREDENTIALS_FILE` variable. + +You may also configure the profile to use by setting the `profile` +configuration option, or setting the `AWS_PROFILE` environment variable: + +```json +{ + "profile": "customprofile", + "region": "us-east-1", + "type": "amazon-ebs" +} +``` + + +### IAM Task or Instance Role + +Finally, Packer will use credentials provided by the task's or instance's IAM +role, if it has one. + +This is a preferred approach over any other when running in EC2 as you can +avoid hard coding credentials. Instead these are leased on-the-fly by Packer, +which reduces the chance of leakage. + +The default deadline for the EC2 metadata API endpoint is 100 milliseconds, +which can be overidden by setting the `AWS_METADATA_TIMEOUT` environment +variable. The variable expects a positive golang Time.Duration string, which is +a sequence of decimal numbers and a unit suffix; valid suffixes are `ns` +(nanoseconds), `us` (microseconds), `ms` (milliseconds), `s` (seconds), `m` +(minutes), and `h` (hours). Examples of valid inputs: `100ms`, `250ms`, `1s`, +`2.5s`, `2.5m`, `1m30s`. + +The following policy document provides the minimal set permissions necessary +for Packer to work: ``` json { From c11627fba7a0e88a921e7510e5203af3a1596b63 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 14:52:51 -0800 Subject: [PATCH 0633/1007] document new skip_metadata_api_check option --- website/source/docs/builders/amazon-chroot.html.md | 6 ++++++ website/source/docs/builders/amazon-ebs.html.md | 6 ++++++ website/source/docs/builders/amazon-ebssurrogate.html.md | 6 ++++++ website/source/docs/builders/amazon-ebsvolume.html.md | 6 ++++++ website/source/docs/builders/amazon-instance.html.md | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index a983305c2..1757b06bf 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -243,6 +243,12 @@ each category, the available configuration keys are alphabetized. of the `source_ami` unless `from_scratch` is `true`, in which case this field must be defined. +- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. + Useful for AWS API implementations that do not have a metadata API + endpoint. Setting to `true` prevents Packer from authenticating via the + Metadata API. You may need to use other authentication methods like static + credentials, configuration variables, or environment variables. + - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the `ami_regions` configuration option. Default `false`. diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 6b48621b4..c83698569 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -244,6 +244,12 @@ builder. in case Packer exits ungracefully. Possible values are "stop" and "terminate", default is `stop`. +- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. + Useful for AWS API implementations that do not have a metadata API + endpoint. Setting to `true` prevents Packer from authenticating via the + Metadata API. You may need to use other authentication methods like static + credentials, configuration variables, or environment variables. + - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the region configuration option. Default `false`. diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 7b995fa87..aeffe2f09 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -237,6 +237,12 @@ builder. incase packer exits ungracefully. Possible values are "stop" and "terminate", default is `stop`. +- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. + Useful for AWS API implementations that do not have a metadata API + endpoint. Setting to `true` prevents Packer from authenticating via the + Metadata API. You may need to use other authentication methods like static + credentials, configuration variables, or environment variables. + - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the region configuration option. Default `false`. diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index b500aa2bd..174673ed0 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -156,6 +156,12 @@ builder. in case Packer exits ungracefully. Possible values are `stop` and `terminate`. Defaults to `stop`. +- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. + Useful for AWS API implementations that do not have a metadata API + endpoint. Setting to `true` prevents Packer from authenticating via the + Metadata API. You may need to use other authentication methods like static + credentials, configuration variables, or environment variables. + - `skip_region_validation` (boolean) - Set to `true` if you want to skip validation of the region configuration option. Defaults to `false`. diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index f8f72708a..299222837 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -248,6 +248,12 @@ builder. The default is `0.0.0.0/0` (ie, allow any IPv4 source). This is only used when `security_group_id` or `security_group_ids` is not specified. +- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. + Useful for AWS API implementations that do not have a metadata API + endpoint. Setting to `true` prevents Packer from authenticating via the + Metadata API. You may need to use other authentication methods like static + credentials, configuration variables, or environment variables. + - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the region configuration option. Defaults to `false`. From 5af42ee9e285501c0ae8fdc1f2c2086ed1bf2fd1 Mon Sep 17 00:00:00 2001 From: SwampDragons <megan@hashicorp.com> Date: Thu, 8 Feb 2018 15:10:53 -0800 Subject: [PATCH 0634/1007] Revert "Add `winrm_no_proxy` option." --- helper/communicator/config.go | 9 +++---- helper/communicator/step_connect_test.go | 24 ----------------- helper/communicator/step_connect_winrm.go | 26 ------------------- .../docs/templates/communicator.html.md | 15 ++++------- 4 files changed, 9 insertions(+), 65 deletions(-) diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 52b81a3a6..f2664b192 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -41,15 +41,14 @@ type Config struct { SSHReadWriteTimeout time.Duration `mapstructure:"ssh_read_write_timeout"` // WinRM - WinRMHost string `mapstructure:"winrm_host"` - WinRMInsecure bool `mapstructure:"winrm_insecure"` - WinRMNoProxy bool `mapstructure:"winrm_no_proxy"` + WinRMUser string `mapstructure:"winrm_username"` WinRMPassword string `mapstructure:"winrm_password"` + WinRMHost string `mapstructure:"winrm_host"` WinRMPort int `mapstructure:"winrm_port"` WinRMTimeout time.Duration `mapstructure:"winrm_timeout"` - WinRMUseNTLM bool `mapstructure:"winrm_use_ntlm"` WinRMUseSSL bool `mapstructure:"winrm_use_ssl"` - WinRMUser string `mapstructure:"winrm_username"` + WinRMInsecure bool `mapstructure:"winrm_insecure"` + WinRMUseNTLM bool `mapstructure:"winrm_use_ntlm"` WinRMTransportDecorator func() winrm.Transporter } diff --git a/helper/communicator/step_connect_test.go b/helper/communicator/step_connect_test.go index 6db32fba5..fb61f6463 100644 --- a/helper/communicator/step_connect_test.go +++ b/helper/communicator/step_connect_test.go @@ -3,12 +3,10 @@ package communicator import ( "bytes" "context" - "os" "testing" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - "github.com/stretchr/testify/assert" ) func TestStepConnect_impl(t *testing.T) { @@ -31,28 +29,6 @@ func TestStepConnect_none(t *testing.T) { } } -var noProxyTests = []struct { - current string - expected string -}{ - {"", "foo:1"}, - {"foo:1", "foo:1"}, - {"foo:1,bar:2", "foo:1,bar:2"}, - {"bar:2", "bar:2,foo:1"}, -} - -func TestStepConnect_setNoProxy(t *testing.T) { - key := "NO_PROXY" - for _, tt := range noProxyTests { - if value := os.Getenv(key); value != "" { - os.Unsetenv(key) - defer func() { os.Setenv(key, value) }() - os.Setenv(key, tt.current) - assert.Equal(t, tt.expected, os.Getenv(key), "env not set correctly.") - } - } -} - func testState(t *testing.T) multistep.StateBag { state := new(multistep.BasicStateBag) state.Put("hook", &packer.MockHook{}) diff --git a/helper/communicator/step_connect_winrm.go b/helper/communicator/step_connect_winrm.go index cdda73a5a..06e6236f8 100644 --- a/helper/communicator/step_connect_winrm.go +++ b/helper/communicator/step_connect_winrm.go @@ -7,7 +7,6 @@ import ( "fmt" "io" "log" - "os" "strings" "time" @@ -129,12 +128,6 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, cancel <-chan } } - if s.Config.WinRMNoProxy { - if err := setNoProxy(host, port); err != nil { - return nil, fmt.Errorf("Error setting no_proxy: %s", err) - } - } - log.Println("[INFO] Attempting WinRM connection...") comm, err = winrm.New(&winrm.Config{ Host: host, @@ -189,22 +182,3 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, cancel <-chan return comm, nil } - -// setNoProxy configures the $NO_PROXY env var -func setNoProxy(host string, port int) error { - current := os.Getenv("NO_PROXY") - p := fmt.Sprintf("%s:%d", host, port) - // not set - // set - // is set and not contains - // set - // is set and contains - if current == "" { - return os.Setenv("NO_PROXY", p) - } - if !strings.Contains(current, p) { - return os.Setenv("NO_PROXY", strings.Join([]string{current, p}, ",")) - } - return nil - -} diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index db768a90a..0165ab5a1 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -139,21 +139,16 @@ The WinRM communicator has the following options. - `winrm_password` (string) - The password to use to connect to WinRM. -- `winrm_insecure` (boolean) - If true, do not check server certificate - chain and host name - -* `winrm_no_proxy` (boolean) - Setting this to `true` adds the remote - `host:post` to the `NO_PROXY` environment variable. This has the effect of - bypassing any configured proxies when connecting to the remote host. - Default to `false`. - - `winrm_timeout` (string) - The amount of time to wait for WinRM to become available. This defaults to "30m" since setting up a Windows machine generally takes a long time. +- `winrm_use_ssl` (boolean) - If true, use HTTPS for WinRM + +- `winrm_insecure` (boolean) - If true, do not check server certificate + chain and host name + - `winrm_use_ntlm` (boolean) - If true, NTLM authentication will be used for WinRM, rather than default (basic authentication), removing the requirement for basic authentication to be enabled within the target guest. Further reading for remote connection authentication can be found [here](https://msdn.microsoft.com/en-us/library/aa384295(v=vs.85).aspx). - -- `winrm_use_ssl` (boolean) - If true, use HTTPS for WinRM From 49f9d318377591bbba2de56395e6b8fa94020903 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 8 Feb 2018 23:15:15 +0000 Subject: [PATCH 0635/1007] Update docs to explain new auto escape of chars special to PowerShell --- .../docs/provisioners/powershell.html.md | 100 +++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index ae897489f..a9c218638 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -56,7 +56,7 @@ Optional parameters: files, and Packer should therefore not convert Windows line endings to Unix line endings (if there are any). By default this is false. -- `elevated_execute_command` (string) - The command to use to execute the +- `elevated_execute_command` (string) - The command to use to execute the elevated script. By default this is as follows: ``` powershell @@ -125,3 +125,101 @@ commonly useful environmental variables: download large files over http. This may be useful if you're experiencing slower speeds using the default file provisioner. A file provisioner using the `winrm` communicator may experience these types of difficulties. + +## Packer's Handling of Characters Special to PowerShell + +The escape character in PowerShell is the `backtick`, also sometimes +referred to as the `grave accent`. When, and when not, to escape characters +special to PowerShell is probably best demonstrated with a series of examples. + +### When To Escape... + +Users need to deal with escaping characters special to PowerShell when they +appear *directly* in commands used in the `inline` PowerShell provisioner and +when they appear *directly* in the users own scripts. +Note that where double quotes appear within double quotes, the addition of +a backslash escape is required for the JSON template to be parsed correctly. + +``` json + "provisioners": [ + { + "type": "powershell", + "inline": [ + "Write-Host \"A literal dollar `$ must be escaped\"", + "Write-Host \"A literal backtick `` must be escaped\"", + "Write-Host \"Here `\"double quotes`\" must be escaped\"", + "Write-Host \"Here `'single quotes`' don`'t really need to be\"", + "Write-Host \"escaped... but it doesn`'t hurt to do so.\"", + ] + }, +``` + +The above snippet should result in the following output on the Packer console: + +``` +==> amazon-ebs: Provisioning with Powershell... +==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner508190439 + amazon-ebs: A literal dollar $ must be escaped + amazon-ebs: A literal backtick ` must be escaped + amazon-ebs: Here "double quotes" must be escaped + amazon-ebs: Here 'single quotes' don't really need to be + amazon-ebs: escaped... but it doesn't hurt to do so. +``` + +### When Not To Escape... + +Special characters appearing in user environment variable values and in the +`elevated_user` and `elevated_password` fields will be automatically +dealt with for the user. There is no need to use escapes in these instances. + +``` json +{ + "variables": { + "psvar": "My$tring" + }, + ... + "provisioners": [ + { + "type": "powershell", + "elevated_user": "Administrator", + "elevated_password": "Super$3cr3t!", + "inline": "Write-Output \"The dollar in the elevated_password is interpreted correctly\"" + }, + { + "type": "powershell", + "environment_vars": [ + "VAR1=A$Dollar", + "VAR2=A`Backtick", + "VAR3=A'SingleQuote", + "VAR4=A\"DoubleQuote", + "VAR5={{user `psvar`}}" + ], + "inline": [ + "Write-Output \"In the following examples the special character is interpreted correctly:\"", + "Write-Output \"The dollar in VAR1: $Env:VAR1\"", + "Write-Output \"The backtick in VAR2: $Env:VAR2\"", + "Write-Output \"The single quote in VAR3: $Env:VAR3\"", + "Write-Output \"The double quote in VAR4: $Env:VAR4\"", + "Write-Output \"The dollar in VAR5 (expanded from a user var): $Env:VAR5\"" + ] + } + ] + ... +} +``` + +The above snippet should result in the following output on the Packer console: + +``` +==> amazon-ebs: Provisioning with Powershell... +==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner961728919 + amazon-ebs: The dollar in the elevated_password is interpreted correctly +==> amazon-ebs: Provisioning with Powershell... +==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner142826554 + amazon-ebs: In the following examples the special character is interpreted correctly: + amazon-ebs: The dollar in VAR1: A$Dollar + amazon-ebs: The backtick in VAR2: A`Backtick + amazon-ebs: The single quote in VAR3: A'SingleQuote + amazon-ebs: The double quote in VAR4: A"DoubleQuote + amazon-ebs: The dollar in VAR5 (expanded from a user var): My$tring +``` From 19a89a101ec0a38fec88885eba4c0ba880a3bedc Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 8 Feb 2018 16:47:17 -0800 Subject: [PATCH 0636/1007] builder/amazon: remove ssh_private_ip ssh_private_ip should now be set through ssh_interface. Adds fixer to automatically fix existing json files --- builder/amazon/common/run_config.go | 9 --- fix/fixer.go | 2 + fix/fixer_amazon_enhanced_networking.go | 15 +++++ fix/fixer_amazon_enhanced_networking_test.go | 8 +-- fix/fixer_amazon_private_ip.go | 70 ++++++++++++++++++++ fix/fixer_amazon_private_ip_test.go | 64 ++++++++++++++++++ fix/fixer_amazon_shutdown_behavior.go | 4 +- 7 files changed, 158 insertions(+), 14 deletions(-) create mode 100644 fix/fixer_amazon_private_ip.go create mode 100644 fix/fixer_amazon_private_ip_test.go diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 1b50b4842..289a461b9 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -53,7 +53,6 @@ type RunConfig struct { // Communicator settings Comm communicator.Config `mapstructure:",squash"` SSHKeyPairName string `mapstructure:"ssh_keypair_name"` - SSHPrivateIp bool `mapstructure:"ssh_private_ip"` SSHInterface string `mapstructure:"ssh_interface"` } @@ -78,14 +77,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { // Validation errs := c.Comm.Prepare(ctx) - if c.SSHPrivateIp && c.SSHInterface != "" { - errs = append(errs, errors.New("ssh_interface and ssh_private_ip should not both be specified")) - } - - // Legacy configurable - if c.SSHPrivateIp { - c.SSHInterface = "private_ip" - } // Valadating ssh_interface if c.SSHInterface != "public_ip" && diff --git a/fix/fixer.go b/fix/fixer.go index 5ca0b3a18..9f6247ee9 100644 --- a/fix/fixer.go +++ b/fix/fixer.go @@ -33,6 +33,7 @@ func init() { "manifest-filename": new(FixerManifestFilename), "amazon-shutdown_behavior": new(FixerAmazonShutdownBehavior), "amazon-enhanced-networking": new(FixerAmazonEnhancedNetworking), + "amazon-private-ip": new(FixerAmazonPrivateIP), "docker-email": new(FixerDockerEmail), } @@ -50,6 +51,7 @@ func init() { "manifest-filename", "amazon-shutdown_behavior", "amazon-enhanced-networking", + "amazon-private-ip", "docker-email", } } diff --git a/fix/fixer_amazon_enhanced_networking.go b/fix/fixer_amazon_enhanced_networking.go index 4c9330ebe..7188da7f7 100644 --- a/fix/fixer_amazon_enhanced_networking.go +++ b/fix/fixer_amazon_enhanced_networking.go @@ -1,6 +1,8 @@ package fix import ( + "strings" + "github.com/mitchellh/mapstructure" ) @@ -22,6 +24,19 @@ func (FixerAmazonEnhancedNetworking) Fix(input map[string]interface{}) (map[stri // Go through each builder and replace the enhanced_networking if we can for _, builder := range tpl.Builders { + builderTypeRaw, ok := builder["type"] + if !ok { + continue + } + + builderType, ok := builderTypeRaw.(string) + if !ok { + continue + } + + if !strings.HasPrefix(builderType, "amazon-") { + continue + } enhancedNetworkingRaw, ok := builder["enhanced_networking"] if !ok { continue diff --git a/fix/fixer_amazon_enhanced_networking_test.go b/fix/fixer_amazon_enhanced_networking_test.go index f8b5be178..78b58d582 100644 --- a/fix/fixer_amazon_enhanced_networking_test.go +++ b/fix/fixer_amazon_enhanced_networking_test.go @@ -17,12 +17,12 @@ func TestFixerAmazonEnhancedNetworking(t *testing.T) { // Attach field == false { Input: map[string]interface{}{ - "type": "ebs", + "type": "amazon-ebs", "enhanced_networking": false, }, Expected: map[string]interface{}{ - "type": "ebs", + "type": "amazon-ebs", "ena_support": false, }, }, @@ -30,12 +30,12 @@ func TestFixerAmazonEnhancedNetworking(t *testing.T) { // Attach field == true { Input: map[string]interface{}{ - "type": "ebs", + "type": "amazon-ebs", "enhanced_networking": true, }, Expected: map[string]interface{}{ - "type": "ebs", + "type": "amazon-ebs", "ena_support": true, }, }, diff --git a/fix/fixer_amazon_private_ip.go b/fix/fixer_amazon_private_ip.go new file mode 100644 index 000000000..7bfce1291 --- /dev/null +++ b/fix/fixer_amazon_private_ip.go @@ -0,0 +1,70 @@ +package fix + +import ( + "log" + "strings" + + "github.com/mitchellh/mapstructure" +) + +// FixerAmazonPrivateIP is a Fixer that replaces instances of `"private_ip": +// true` with `"ssh_interface": "private_ip"` +type FixerAmazonPrivateIP struct{} + +func (FixerAmazonPrivateIP) Fix(input map[string]interface{}) (map[string]interface{}, error) { + type template struct { + Builders []map[string]interface{} + } + + // Decode the input into our structure, if we can + var tpl template + if err := mapstructure.Decode(input, &tpl); err != nil { + return nil, err + } + + // Go through each builder and replace the enhanced_networking if we can + for _, builder := range tpl.Builders { + builderTypeRaw, ok := builder["type"] + if !ok { + continue + } + + builderType, ok := builderTypeRaw.(string) + if !ok { + continue + } + + if !strings.HasPrefix(builderType, "amazon-") { + continue + } + + // if ssh_interface already set, do nothing + if _, ok := builder["ssh_interface"]; ok { + continue + } + + privateIPi, ok := builder["ssh_private_ip"] + if !ok { + continue + } + privateIP, ok := privateIPi.(bool) + if !ok { + log.Fatalf("Wrong type for ssh_private_ip") + continue + } + + delete(builder, "ssh_private_ip") + if privateIP { + builder["ssh_interface"] = "private_ip" + } else { + builder["ssh_interface"] = "public_ip" + } + } + + input["builders"] = tpl.Builders + return input, nil +} + +func (FixerAmazonPrivateIP) Synopsis() string { + return "Replaces `\"ssh_private_ip\": true` in amazon builders with `\"ssh_interface\": \"private_ip\"`" +} diff --git a/fix/fixer_amazon_private_ip_test.go b/fix/fixer_amazon_private_ip_test.go new file mode 100644 index 000000000..554584ded --- /dev/null +++ b/fix/fixer_amazon_private_ip_test.go @@ -0,0 +1,64 @@ +package fix + +import ( + "reflect" + "testing" +) + +func TestFixerAmazonPrivateIP_Impl(t *testing.T) { + var _ Fixer = new(FixerAmazonPrivateIP) +} + +func TestFixerAmazonPrivateIP(t *testing.T) { + cases := []struct { + Input map[string]interface{} + Expected map[string]interface{} + }{ + // Attach field == false + { + Input: map[string]interface{}{ + "type": "amazon-ebs", + "ssh_private_ip": false, + }, + + Expected: map[string]interface{}{ + "type": "amazon-ebs", + "ssh_interface": "public_ip", + }, + }, + + // Attach field == true + { + Input: map[string]interface{}{ + "type": "amazon-ebs", + "ssh_private_ip": true, + }, + + Expected: map[string]interface{}{ + "type": "amazon-ebs", + "ssh_interface": "private_ip", + }, + }, + } + + for _, tc := range cases { + var f FixerAmazonPrivateIP + + input := map[string]interface{}{ + "builders": []map[string]interface{}{tc.Input}, + } + + expected := map[string]interface{}{ + "builders": []map[string]interface{}{tc.Expected}, + } + + output, err := f.Fix(input) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(output, expected) { + t.Fatalf("unexpected: %#v\nexpected: %#v\n", output, expected) + } + } +} diff --git a/fix/fixer_amazon_shutdown_behavior.go b/fix/fixer_amazon_shutdown_behavior.go index 2e47c5592..686ef5119 100644 --- a/fix/fixer_amazon_shutdown_behavior.go +++ b/fix/fixer_amazon_shutdown_behavior.go @@ -1,6 +1,8 @@ package fix import ( + "strings" + "github.com/mitchellh/mapstructure" ) @@ -31,7 +33,7 @@ func (FixerAmazonShutdownBehavior) Fix(input map[string]interface{}) (map[string continue } - if builderType != "amazon-ebs" && builderType != "amazon-ebsvolume" && builderType != "amazon-instance" && builderType != "amazon-chroot" { + if !strings.HasPrefix(builderType, "amazon-") { continue } From 87f8a2e8fe47f41d20b1c1b155772712737fee0e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 10:08:59 -0800 Subject: [PATCH 0637/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ada8d8e5e..4b4fc6b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will no longer compile (however existing builds will still work fine); the work to fix them is minimal and documented in GH-5810. [GH-5810] * provisioner/file: We've made destination semantics more consistent across the various communicators. In general, if the destination is a directory, files will be uploaded into the directory instead of failing. This mirrors the behavior of `rsync`. There's a chance some users might be depending on the previous buggy behavior, so it's worth ensuring your configuration is correct. [GH-5426] * builder/openstack: Extension support has been removed. To use OpenStack builder with the OpenStack Newton (Oct 2016) or earlier, we recommend you use Packer v1.1.2 or earlier version. +* builder/amazon: The `ssh_private_ip` option has been removed. Instead, please use `"ssh_interface": "private"`. A fixer has been written for this, which can be invoked with `packer fix`. [GH-5876] ### IMPROVEMENTS: From b863b7ab9ea3c6b13fd2f8031bf81deeddcbb13d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 14:28:49 -0800 Subject: [PATCH 0638/1007] fix outgoing links --- .../assets/images/Adobe_PDF_file_icon_24x24.png | Bin 1288 -> 0 bytes website/source/docs/builders/vmware-iso.html.md | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 website/source/assets/images/Adobe_PDF_file_icon_24x24.png diff --git a/website/source/assets/images/Adobe_PDF_file_icon_24x24.png b/website/source/assets/images/Adobe_PDF_file_icon_24x24.png deleted file mode 100644 index a722e5b334140fcb2a527b44465dbf4ca6e05cd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1288 zcmV+j1^4=iP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00006VoOIv0RI60 z0RN!9r;`8x1ieW_K~zY`m6lzIUDXxGe{1c1&beQ6uSo`<YH=>5)P}~C2Cc=S;&*9j zNffFDZ6Bl*O8Znwp|lTus1LpfT3TAc4+vN&eGoJ+l82T;tCmzu;tY<)iN>)rCNpzy z?#DT2@70HM?|8@Qh%VUd^Rf3@>%Z3jzt53NSL0Cy0PoSI+=?H3(~W=j@O6MQGXp?C zL{L#w6$1oA8%?3s403tvALrISi1YLFGTpPVuz)aQ=Qn#0BNnYLiTeQ2x`hY=>Rc7a zKvfX|)Zy|GHXN{i@#61#TU)<2v-Nhnt&K(_0?4HW`J1SMfR%=AMl0rA&3)<6VfsCh zMibOy{Y`KVZM7>n-Xj;+2;ch=@qwSj!8_+t@yT=R>+APzY;0WacDqhQf{*HMbged& z1v=lx-}V*U(i!CKW&Dw^QJ#Jk20i?BUndTSl&}09VuUP(^FxXoR=^3(dc8;*&2Opd z)7@_O`~7~um!_#`QI=u2xfurU_CmSvg`hwEZHV7^FqGHdg#7$bikt7Hxc(O8hreKy zwHTT(ECa(lFcK&;K@7&@JP9F~nH^nQTYEOo^Uw7AebZpLD7dJ&n2#Lep)1dyb5WJS zA09(H9jIpz0#Q6Mltdt6L<5TvRVAxs#2BT~Xp9dWIB<8CWe;_`U9<oSgS>>$KEU|& zOKd*=1Z5GZ9s4dN5M0W5=?wi7f29;hVNgWK4FaG7S(=fiDQTK&qtRe67|a3q(x{kI zgVEAyij56o3x=<q!oU0?z32aoh9TpX70Lm`BtQfdD8Zqqz?98qhM7?mg#!2j#%3ne zAb(>S&MqVKNU^$_^ndv)+!X?%*xT<QS7uO@h$^HBRx8N7L!f#lQfWmMkxBvn!T)k_ zXk-#GZ8c>u&WlcM-)A2^{_G1bt0h*JhzO#B#E3SUkfi9Kj|ep9uf+9wNRm`KnK<4K z@UJn;6Tn<Gw_jdbdO6&4^jKK9=8NWiGJ$T@2IrC2Uq#NHg&S{&EW=f**v{IlT00Fe zIU_1!+<oVr@%YovkR?gXyeIQ+GCWz5lI0_6@4iKP_7vG$i)5`fUSwP4)6932X!fWu z5ln<i<5G=nxCUv4wfAEiTaaW`?Ps!`o&Rru*_W!5Lu~@tLJ6Htb-j5BJ$M*~m#g*D zCVyoAt^gm+X2-oMgousCSQ(IEAMNY|i--x7#fNpDp3XBpU@s)w8KyNf9}!>qC;qPQ zP(Jxb;;Dbb$_n=Wd&s2jyI8cR(+Nzoh-7svA5lK@1mWyyl4JKHJ|lnfPsqOggg2IH zJ^p*7-9bXwfx_>FKvhu@%%{Y~GlUmUP@Z^>+HW4geeUz<!9)04?;yVUCUJEYS8pH_ zqRiSZ1XGHsD&iAtYlHmwQ;;NN5B-?r%SW&fAkT4g9o(U7k!ufEDxR|M69=$}w&qBV zd=;6SBfa@nEQG3Y-lG<=spCCtrw+`BF%o0M%*x68n11_c1wWKbKF-_f#0;Cv6Cb5> zE{QS5k884c@4a(QcQDQE*|OOrZQ{%A3b44iNC<%o7cPuXo;>-N@p#;sCi+P&#u)4M ydTVuc^*_7*DrT$(w1Fm675Ee;KnZLD{r>^{G#E%4x}j_U0000<MNUMnLSTZNL2yU_ diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 2f4e3e44f..7784ac439 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -137,7 +137,9 @@ builder. or "scsi" (which uses the "lsilogic" scsi interface by default). If you specify another option, Packer will assume that you're specifying a "scsi" interface of that specified type. For more information, please consult the - <a href="http://www.vmware.com/pdf/VirtualDiskManager.pdf" target="_blank"><img src="../../assets/images/Adobe_PDF_file_icon_24x24.png"/> Virtual Disk Manager User's Guide</a> for desktop VMware clients. + <a href="http://www.vmware.com/pdf/VirtualDiskManager.pdf" target="_blank" + rel="nofollow noopener noreferrer"> + Virtual Disk Manager User's Guide</a> for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. - `cdrom_adapter_type` (string) - The adapter type (or bus) that will be used @@ -216,7 +218,9 @@ builder. - `network_adapter_type` (string) - This is the ethernet adapter type the the virtual machine will be created with. By default the "e1000" network adapter type will be used by Packer. For more information, please consult the - <a href="https://kb.vmware.com/s/article/1001805" target="_blank">Choosing a network adapter for your virtual machine</a> for desktop VMware + <a href="https://kb.vmware.com/s/article/1001805" target="_blank" + rel="nofollow noopener noreferrer"> + Choosing a network adapter for your virtual machine</a> for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. - `output_directory` (string) - This is the path to the directory where the From 593577c139bb57a468c414cd5c7b143469cf8a78 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 15:01:44 -0800 Subject: [PATCH 0639/1007] populate missing lines from changelog --- CHANGELOG.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b4fc6b10..00abba155 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### BACKWARDS INCOMPATIBILITIES: * core: Affects Windows guests: User variables containing Powershell special characters no longer need to be escaped.[GH-5376] -* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] +* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] [GH-5872] * 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will no longer compile (however existing builds will still work fine); the work to fix them is minimal and documented in GH-5810. [GH-5810] * provisioner/file: We've made destination semantics more consistent across the various communicators. In general, if the destination is a directory, files will be uploaded into the directory instead of failing. This mirrors the behavior of `rsync`. There's a chance some users might be depending on the previous buggy behavior, so it's worth ensuring your configuration is correct. [GH-5426] * builder/openstack: Extension support has been removed. To use OpenStack builder with the OpenStack Newton (Oct 2016) or earlier, we recommend you use Packer v1.1.2 or earlier version. @@ -33,17 +33,39 @@ * builder/amazon: Add Paris region (eu-west-3) [GH-5718] * builder/azure: Add validation for incorrect VHD URLs [GH-5695] * builder/amazon: Remove Session Token (STS) from being shown in the log. [GH-5665] +* post-processor/vsphere-template: Now accepts artifacts from the vSphere post-processor. [GH-5380] +* builder/vmware-iso: Add support for usb/serial/parallel ports. [GH-3417] +* builder/vmware-iso: Add support for virtual soundcards. [GH-3417] +* builder/vmware-iso: Add support for setting network type and network adapter type. [GH-3417] +* builder/vmware-iso: Add support for cdrom and disk adapter types. [GH-3417] +* builder/vmware-iso: More reliably retrieve the guest networking configuration. [GH-3417] +* builder/amazon: Timeout early if metadata service can't be reached. [GH-5764] +* builder/amazon: Report which authentication provider we're using. [GH-5764] +* builder/amazon: Give better error messages if we have trouble during authentication. [GH-5764] +* builder/amazon: Add `skip_metadata_api_check` option to skip consulting the amazon metadata service. [GH-5764] +* core: Improved support for downloading and validating a uri containing a Windows UNC path or a relative file:// scheme. [GH-2906] +* builder/google: Support specifying licenses for images. [GH-5842] +* post-processor/google-export: Synchronize credential semantics with the Google builder. [GH-4148] +* builder/vmware: Add support for "super" key in `boot_command`. [GH-5681] +* core: Gracefully clean up resources on SIGTERM. [GH-5318] +* builder/hyper-v: Allow MAC address specification. [GH-5709] +* communicator/ssh: Detect dead connections. [GH-4709] ### BUG FIXES: +* provisioner/ansible-remote: Fixes an error where Packer's private key can be overridden by inherited `ansible_ssh_private_key` options. [GH-5869] * builder/alicloud-ecs: Attach keypair before starting instance in alicloud builder [GH-5739] * builder/vmware: Fixed file handle leak that may have caused race conditions in vmware builder [GH-5767] -* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] +* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] [GH-5872] * provisioner/ansible: The "default extra variables" feature added in Packer v1.0.1 caused the ansible-local provisioner to fail when an --extra-vars argument was specified in the extra_arguments configuration option; this has been fixed. [GH-5335] * communicator/ssh: Add deadline to SSH connection to prevent Packer hangs after script provisioner reboots vm [GH-4684] * builder/virtualbox: Fix regression affecting users running Packer on a Windows host that kept Packer from finding Virtualbox guest additions if Packer ran on a different drive from the one where the guest additions were stored. [GH-5761] * builder/virtualbox: Fix interpolation ordering so that edge cases around guest_additions_url are handled correctly [GH-5757] * builder/amazon: NewSession now inherits MaxRetries and other settings. [GH-5719] +* builder/amazon: Fix tagging support when building in us-gov/china. [GH-5841] +* builder/vmware: Fix case where artifacts might not be cleaned up correctly. [GH-5835] +* provisioner/ansible-local: Fix support for `--extra-vars` in `extra_arguments`. [GH-5703] +* communicator/winrm: Fix issue copying empty directories. [GH-5763] ## 1.1.3 (December 8, 2017) From 034e722650794a98efd4dec48050fe4e175289c8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 15:02:32 -0800 Subject: [PATCH 0640/1007] format changelog --- CHANGELOG.md | 154 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00abba155..c9e38a60b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,71 +1,125 @@ ## (UNRELEASED) ### BACKWARDS INCOMPATIBILITIES: -* core: Affects Windows guests: User variables containing Powershell special characters no longer need to be escaped.[GH-5376] -* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] [GH-5872] -* 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will no longer compile (however existing builds will still work fine); the work to fix them is minimal and documented in GH-5810. [GH-5810] -* provisioner/file: We've made destination semantics more consistent across the various communicators. In general, if the destination is a directory, files will be uploaded into the directory instead of failing. This mirrors the behavior of `rsync`. There's a chance some users might be depending on the previous buggy behavior, so it's worth ensuring your configuration is correct. [GH-5426] -* builder/openstack: Extension support has been removed. To use OpenStack builder with the OpenStack Newton (Oct 2016) or earlier, we recommend you use Packer v1.1.2 or earlier version. -* builder/amazon: The `ssh_private_ip` option has been removed. Instead, please use `"ssh_interface": "private"`. A fixer has been written for this, which can be invoked with `packer fix`. [GH-5876] +* 3rd party plugins: We have moved internal dependencies, meaning your 3rd + party plugins will no longer compile (however existing builds will still + work fine); the work to fix them is minimal and documented in GH-5810. + [GH-5810] +* builder/amazon: The `ssh_private_ip` option has been removed. Instead, please + use `"ssh_interface": "private"`. A fixer has been written for this, which + can be invoked with `packer fix`. [GH-5876] +* builder/openstack: Extension support has been removed. To use OpenStack + builder with the OpenStack Newton (Oct 2016) or earlier, we recommend you + use Packer v1.1.2 or earlier version. +* core: Affects Windows guests: User variables containing Powershell special + characters no longer need to be escaped.[GH-5376] +* provisioner/file: We've made destination semantics more consistent across the + various communicators. In general, if the destination is a directory, files + will be uploaded into the directory instead of failing. This mirrors the + behavior of `rsync`. There's a chance some users might be depending on the + previous buggy behavior, so it's worth ensuring your configuration is + correct. [GH-5426] +* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of + environment variables in the non-elevated provisioner has been fixed. + [GH-5515] [GH-5872] ### IMPROVEMENTS: -* **New builder:** `scaleway` - The Scaleway Packer builder is able to create new images for use with Scaleway BareMetal and Virtual cloud server. [GH-4770] -* **New builder:** `ncloud` for building server images using the NAVER Cloud Platform. [GH-5791] -* **New builder:** `oci-classic` for building new custom images for use with Oracle Cloud Infrastructure Classic Compute. [GH-5819] -* builder/docker: Remove credentials from being shown in the log. [GH-5666] -* builder/triton: Triton RBAC is now supported. [GH-5741] -* provisioner/ansible: Improve user retrieval. [GH-5758] -* post-processor/docker: Remove credentials from being shown in the log. [GH-5666] -* builder/amazon: Warn during prepare if we didn't get both an access key and a secret key when we were expecting one. [GH-5762] -* builder/amazon: Replace `InstanceStatusOK` check with `InstanceReady`. This reduces build times universally while still working for all instance types. [GH-5678] +* **New builder:** `ncloud` for building server images using the NAVER Cloud + Platform. [GH-5791] +* **New builder:** `oci-classic` for building new custom images for use with + Oracle Cloud Infrastructure Classic Compute. [GH-5819] +* **New builder:** `scaleway` - The Scaleway Packer builder is able to create + new images for use with Scaleway BareMetal and Virtual cloud server. + [GH-4770] * builder/amazon: Add `kms_key_id` option to block device mappings. [GH-5774] -* builder/hyper-v: New option to use differential disks and Inline disk creation to improve build time and reduce disk usage [GH-5631] -* post-processor/vagrant: Add vagrant post-processor support for Google [GH-5732] -* provisioner/chef: Added Policyfile support to chef-client provisioner. [GH-5831] -* builder/qemu: Add Intel HAXM support to QEMU builder [GH-5738] -* communicator/ssh: Add session-level keep-alives [GH-5830] -* post-processor/amazon-import: Allow user to specify role name in amazon-import [GH-5817] -* provisioner/chef: Add support for 'trusted_certs_dir' chef-client configuration option [GH-5790] -* builder/triton: Updated triton-go dependencies, allowing better error handling. [GH-5795] -* core: Improved error logging in floppy file handling. [GH-5802] -* provisioner/amazon: Use Amazon SDK's InstanceRunning waiter instead of InstanceStatusOK waiter [GH-5773] +* builder/amazon: Add `skip_metadata_api_check` option to skip consulting the + amazon metadata service. [GH-5764] * builder/amazon: Add Paris region (eu-west-3) [GH-5718] +* builder/amazon: Give better error messages if we have trouble during + authentication. [GH-5764] +* builder/amazon: Remove Session Token (STS) from being shown in the log. + [GH-5665] +* builder/amazon: Replace `InstanceStatusOK` check with `InstanceReady`. This + reduces build times universally while still working for all instance types. + [GH-5678] +* builder/amazon: Report which authentication provider we're using. [GH-5764] +* builder/amazon: Timeout early if metadata service can't be reached. [GH-5764] +* builder/amazon: Warn during prepare if we didn't get both an access key and a + secret key when we were expecting one. [GH-5762] * builder/azure: Add validation for incorrect VHD URLs [GH-5695] -* builder/amazon: Remove Session Token (STS) from being shown in the log. [GH-5665] -* post-processor/vsphere-template: Now accepts artifacts from the vSphere post-processor. [GH-5380] +* builder/docker: Remove credentials from being shown in the log. [GH-5666] +* builder/google: Support specifying licenses for images. [GH-5842] +* builder/hyper-v: Allow MAC address specification. [GH-5709] +* builder/hyper-v: New option to use differential disks and Inline disk + creation to improve build time and reduce disk usage [GH-5631] +* builder/qemu: Add Intel HAXM support to QEMU builder [GH-5738] +* builder/triton: Triton RBAC is now supported. [GH-5741] +* builder/triton: Updated triton-go dependencies, allowing better error + handling. [GH-5795] +* builder/vmware-iso: Add support for cdrom and disk adapter types. [GH-3417] +* builder/vmware-iso: Add support for setting network type and network adapter + type. [GH-3417] * builder/vmware-iso: Add support for usb/serial/parallel ports. [GH-3417] * builder/vmware-iso: Add support for virtual soundcards. [GH-3417] -* builder/vmware-iso: Add support for setting network type and network adapter type. [GH-3417] -* builder/vmware-iso: Add support for cdrom and disk adapter types. [GH-3417] -* builder/vmware-iso: More reliably retrieve the guest networking configuration. [GH-3417] -* builder/amazon: Timeout early if metadata service can't be reached. [GH-5764] -* builder/amazon: Report which authentication provider we're using. [GH-5764] -* builder/amazon: Give better error messages if we have trouble during authentication. [GH-5764] -* builder/amazon: Add `skip_metadata_api_check` option to skip consulting the amazon metadata service. [GH-5764] -* core: Improved support for downloading and validating a uri containing a Windows UNC path or a relative file:// scheme. [GH-2906] -* builder/google: Support specifying licenses for images. [GH-5842] -* post-processor/google-export: Synchronize credential semantics with the Google builder. [GH-4148] +* builder/vmware-iso: More reliably retrieve the guest networking + configuration. [GH-3417] * builder/vmware: Add support for "super" key in `boot_command`. [GH-5681] -* core: Gracefully clean up resources on SIGTERM. [GH-5318] -* builder/hyper-v: Allow MAC address specification. [GH-5709] +* communicator/ssh: Add session-level keep-alives [GH-5830] * communicator/ssh: Detect dead connections. [GH-4709] +* core: Gracefully clean up resources on SIGTERM. [GH-5318] +* core: Improved error logging in floppy file handling. [GH-5802] +* core: Improved support for downloading and validating a uri containing a + Windows UNC path or a relative file:// scheme. [GH-2906] +* post-processor/amazon-import: Allow user to specify role name in amazon- + import [GH-5817] +* post-processor/docker: Remove credentials from being shown in the log. + [GH-5666] +* post-processor/google-export: Synchronize credential semantics with the + Google builder. [GH-4148] +* post-processor/vagrant: Add vagrant post-processor support for Google + [GH-5732] +* post-processor/vsphere-template: Now accepts artifacts from the vSphere post- + processor. [GH-5380] +* provisioner/amazon: Use Amazon SDK's InstanceRunning waiter instead of + InstanceStatusOK waiter [GH-5773] +* provisioner/ansible: Improve user retrieval. [GH-5758] +* provisioner/chef: Add support for 'trusted_certs_dir' chef-client + configuration option [GH-5790] +* provisioner/chef: Added Policyfile support to chef-client provisioner. + [GH-5831] ### BUG FIXES: -* provisioner/ansible-remote: Fixes an error where Packer's private key can be overridden by inherited `ansible_ssh_private_key` options. [GH-5869] -* builder/alicloud-ecs: Attach keypair before starting instance in alicloud builder [GH-5739] -* builder/vmware: Fixed file handle leak that may have caused race conditions in vmware builder [GH-5767] -* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of environment variables in the non-elevated provisioner has been fixed. [GH-5515] [GH-5872] -* provisioner/ansible: The "default extra variables" feature added in Packer v1.0.1 caused the ansible-local provisioner to fail when an --extra-vars argument was specified in the extra_arguments configuration option; this has been fixed. [GH-5335] -* communicator/ssh: Add deadline to SSH connection to prevent Packer hangs after script provisioner reboots vm [GH-4684] -* builder/virtualbox: Fix regression affecting users running Packer on a Windows host that kept Packer from finding Virtualbox guest additions if Packer ran on a different drive from the one where the guest additions were stored. [GH-5761] -* builder/virtualbox: Fix interpolation ordering so that edge cases around guest_additions_url are handled correctly [GH-5757] -* builder/amazon: NewSession now inherits MaxRetries and other settings. [GH-5719] +* builder/alicloud-ecs: Attach keypair before starting instance in alicloud + builder [GH-5739] * builder/amazon: Fix tagging support when building in us-gov/china. [GH-5841] -* builder/vmware: Fix case where artifacts might not be cleaned up correctly. [GH-5835] -* provisioner/ansible-local: Fix support for `--extra-vars` in `extra_arguments`. [GH-5703] +* builder/amazon: NewSession now inherits MaxRetries and other settings. + [GH-5719] +* builder/virtualbox: Fix interpolation ordering so that edge cases around + guest_additions_url are handled correctly [GH-5757] +* builder/virtualbox: Fix regression affecting users running Packer on a + Windows host that kept Packer from finding Virtualbox guest additions if + Packer ran on a different drive from the one where the guest additions were + stored. [GH-5761] +* builder/vmware: Fix case where artifacts might not be cleaned up correctly. + [GH-5835] +* builder/vmware: Fixed file handle leak that may have caused race conditions + in vmware builder [GH-5767] +* communicator/ssh: Add deadline to SSH connection to prevent Packer hangs + after script provisioner reboots vm [GH-4684] * communicator/winrm: Fix issue copying empty directories. [GH-5763] +* provisioner/ansible-local: Fix support for `--extra-vars` in + `extra_arguments`. [GH-5703] +* provisioner/ansible-remote: Fixes an error where Packer's private key can be + overridden by inherited `ansible_ssh_private_key` options. [GH-5869] +* provisioner/ansible: The "default extra variables" feature added in Packer + v1.0.1 caused the ansible-local provisioner to fail when an --extra-vars + argument was specified in the extra_arguments configuration option; this + has been fixed. [GH-5335] +* provisioner/powershell: Regression from v1.1.1 forcing extra escaping of + environment variables in the non-elevated provisioner has been fixed. + [GH-5515] [GH-5872] ## 1.1.3 (December 8, 2017) From 0093f48614379d11248f2b971fa7cb86de59bd0a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 15:07:10 -0800 Subject: [PATCH 0641/1007] prep for 1.2.0 --- CHANGELOG.md | 2 +- version/version.go | 4 ++-- website/config.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9e38a60b..622d01f9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## (UNRELEASED) +## 1.2.0 (February 9, 2018) ### BACKWARDS INCOMPATIBILITIES: * 3rd party plugins: We have moved internal dependencies, meaning your 3rd diff --git a/version/version.go b/version/version.go index 03ee6f644..5538683af 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.1.4" +const Version = "1.2.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index fc5caf4e5..e6d530fdc 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.1.3" + h.version = "1.2.0" h.github_slug = "hashicorp/packer" h.website_root = "website" end From f2a94a97b7714ae210230435e81d6f137585a183 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 16:11:32 -0800 Subject: [PATCH 0643/1007] next version is 1.2.1 --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 5538683af..93fffef3e 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.2.0" +const Version = "1.2.1" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From 9e636f01ed51bda8e1325885d938587d078a9468 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Feb 2018 16:18:08 -0800 Subject: [PATCH 0644/1007] prep changelog for next release --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 622d01f9f..d8878587c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## UNRELEASED + + ## 1.2.0 (February 9, 2018) ### BACKWARDS INCOMPATIBILITIES: From 21313f4cf3740e8d1f7f7fe8efb8c2f0f4d23b07 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sat, 10 Feb 2018 13:59:28 -0800 Subject: [PATCH 0645/1007] fix link --- website/source/docs/builders/oracle.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/oracle.html.md b/website/source/docs/builders/oracle.html.md index 70a1917d0..7184b0a59 100644 --- a/website/source/docs/builders/oracle.html.md +++ b/website/source/docs/builders/oracle.html.md @@ -17,6 +17,6 @@ designed to support both platforms. Please choose the one that's right for you: instance and creating an image list from a snapshot of it after provisioning. -- [oracle-oci](/docs/builders/amazon-instance.html) - Create custom images in +- [oracle-oci](/docs/builders/oracle-oci.html) - Create custom images in Oracle Cloud Infrastructure (OCI) by launching a base instance and creating an image from it after provisioning. From 2747562708efe81983f70445c058f9ee7413b82d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sun, 11 Feb 2018 13:57:25 -0800 Subject: [PATCH 0646/1007] remove ssh_private_ip from docs --- website/source/docs/builders/amazon-ebs.html.md | 4 ++-- website/source/docs/builders/amazon-ebssurrogate.html.md | 4 ++-- website/source/docs/builders/amazon-ebsvolume.html.md | 4 ++-- website/source/docs/builders/amazon-instance.html.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 892029d26..4f2a44498 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -337,8 +337,8 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, - then SSH will always use the private IP if available. Also works for WinRM. +- `ssh_private_ip` (boolean) - No longer supported. See + [`ssh_interface`](#ssh_interface). A fixer exists to migrate. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 42aaa8664..c01c3c493 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -330,8 +330,8 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, - then SSH will always use the private IP if available. Also works for WinRM. +- `ssh_private_ip` (boolean) - No longer supported. See + [`ssh_interface`](#ssh_interface). A fixer exists to migrate. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 5580897f2..186295b87 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -224,8 +224,8 @@ builder. [`ssh_private_key_file`](/docs/templates/communicator.html#ssh_private_key_file) must be specified with this. -- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, - then SSH will always use the private IP if available. Also works for WinRM. +- `ssh_private_ip` (boolean) - No longer supported. See + [`ssh_interface`](#ssh_interface). A fixer exists to migrate. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 624c5d6e0..924e174dd 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -338,8 +338,8 @@ builder. in AWS with the source instance, set the `ssh_keypair_name` field to the name of the key pair. -- `ssh_private_ip` (boolean) - *Deprecated* use `ssh_interface` instead. If `true`, - then SSH will always use the private IP if available. Also works for WinRM. +- `ssh_private_ip` (boolean) - No longer supported. See + [`ssh_interface`](#ssh_interface). A fixer exists to migrate. - `ssh_interface` (string) - One of `public_ip`, `private_ip`, `public_dns` or `private_dns`. If set, either the public IP address, From a4123eabe35e3d29e3aa6d50efa107800aa87cb6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 12 Feb 2018 10:45:53 -0800 Subject: [PATCH 0647/1007] prevent 0-value ticker during ssh keepalive --- communicator/ssh/communicator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 5c2cfac9d..b5b67633c 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -112,7 +112,7 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) { } go func() { - if c.config.KeepAliveInterval < 0 { + if c.config.KeepAliveInterval <= 0 { return } c := time.NewTicker(c.config.KeepAliveInterval) From 7d9a86becb0d4790ce4cd10ecd6eb7c3f059db89 Mon Sep 17 00:00:00 2001 From: SwampDragons <megan@hashicorp.com> Date: Mon, 12 Feb 2018 11:03:19 -0800 Subject: [PATCH 0648/1007] Revert "Fix #5335" --- provisioner/ansible-local/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/ansible-local/provisioner.go b/provisioner/ansible-local/provisioner.go index e007bfb85..ec1eec041 100644 --- a/provisioner/ansible-local/provisioner.go +++ b/provisioner/ansible-local/provisioner.go @@ -304,7 +304,7 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) err playbook := filepath.ToSlash(filepath.Join(p.config.StagingDir, filepath.Base(p.config.PlaybookFile))) inventory := filepath.ToSlash(filepath.Join(p.config.StagingDir, filepath.Base(p.config.InventoryFile))) - extraArgs := fmt.Sprintf(" --extra-vars \\\"packer_build_name=%s packer_builder_type=%s packer_http_addr=%s\\\" ", + extraArgs := fmt.Sprintf(" --extra-vars \"packer_build_name=%s packer_builder_type=%s packer_http_addr=%s\" ", p.config.PackerBuildName, p.config.PackerBuilderType, common.GetHTTPAddr()) if len(p.config.ExtraArguments) > 0 { extraArgs = extraArgs + strings.Join(p.config.ExtraArguments, " ") From f3ac1af5dfbb37cb6de1e247be13cc45d4c65f6c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 12 Feb 2018 11:18:50 -0800 Subject: [PATCH 0649/1007] add scaleway codeowners --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index 050f4d084..216cce578 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -14,6 +14,7 @@ /builder/profitbricks/ @jasmingacic /builder/triton/ @jen20 @sean- /builder/ncloud/ @YuSungDuk +/builder/scaleway/ @dimtion @edouardb # provisioners From 7966e202b7f4de1d45e316e3e0fb5ca5f344cd05 Mon Sep 17 00:00:00 2001 From: Robert Neumayer <neumayer@protonmail.com> Date: Tue, 13 Feb 2018 13:25:48 +0100 Subject: [PATCH 0650/1007] Fix typo --- builder/oracle/oci/config_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index 9a6bd6486..84002e937 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -24,7 +24,8 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { "subnet_ocid": "ocd1...", // Comm - "ssh_username": "opc", + "ssh_username": "opc", + "use_private_ip": false, } } @@ -167,7 +168,7 @@ func TestConfig(t *testing.T) { }) // Test that AccessCfgFile properties are overridden by their - // corosponding template keys. + // corresponding template keys. accessOverrides := map[string]string{ "user_ocid": "User", "tenancy_ocid": "Tenancy", From 20b93e753d134888b5efa9dc6822fabfb19136b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B2=E1=84=89=E1=85=A5=E1=86=BC=E1=84=83?= =?UTF-8?q?=E1=85=A5=E1=86=A8?= <sungduk.yu@navercorp.com> Date: Tue, 13 Feb 2018 21:52:23 +0900 Subject: [PATCH 0651/1007] Fix `naver` of build docs to `NAVER Cloud` --- website/source/layouts/docs.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 5f089e041..552b154ab 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -123,7 +123,7 @@ <a href="/docs/builders/lxd.html">LXD</a> </li> <li<%= sidebar_current("docs-builders-ncloud") %>> - <a href="/docs/builders/ncloud.html">Naver</a> + <a href="/docs/builders/ncloud.html">NAVER Cloud</a> </li> <li<%= sidebar_current("docs-builders-null") %>> <a href="/docs/builders/null.html">Null</a> From 30fa1494d54021db786ce0732e7acc3559addbdf Mon Sep 17 00:00:00 2001 From: Robert Neumayer <neumayer@protonmail.com> Date: Tue, 13 Feb 2018 14:20:26 +0100 Subject: [PATCH 0652/1007] Add option to use prive ip for oci builder --- builder/oracle/oci/config.go | 13 ++++---- builder/oracle/oci/config_test.go | 3 +- builder/oracle/oci/driver_mock.go | 7 +++- builder/oracle/oci/driver_oci.go | 5 ++- builder/oracle/oci/step_instance_info_test.go | 32 +++++++++++++++++++ builder/oracle/oci/step_test.go | 8 +++-- 6 files changed, 56 insertions(+), 12 deletions(-) diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 36f8bb8e9..881ed1e35 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -26,12 +26,13 @@ type Config struct { AccessCfgFileAccount string `mapstructure:"access_cfg_file_account"` // Access config overrides - UserID string `mapstructure:"user_ocid"` - TenancyID string `mapstructure:"tenancy_ocid"` - Region string `mapstructure:"region"` - Fingerprint string `mapstructure:"fingerprint"` - KeyFile string `mapstructure:"key_file"` - PassPhrase string `mapstructure:"pass_phrase"` + UserID string `mapstructure:"user_ocid"` + TenancyID string `mapstructure:"tenancy_ocid"` + Region string `mapstructure:"region"` + Fingerprint string `mapstructure:"fingerprint"` + KeyFile string `mapstructure:"key_file"` + PassPhrase string `mapstructure:"pass_phrase"` + UsePrivateIP bool `mapstructure:"use_private_ip"` AvailabilityDomain string `mapstructure:"availability_domain"` CompartmentID string `mapstructure:"compartment_ocid"` diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index 9a6bd6486..7953e7354 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -24,7 +24,8 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { "subnet_ocid": "ocd1...", // Comm - "ssh_username": "opc", + "ssh_username": "opc", + "use_private_ip": false, } } diff --git a/builder/oracle/oci/driver_mock.go b/builder/oracle/oci/driver_mock.go index 6173760fc..f8bd9f920 100644 --- a/builder/oracle/oci/driver_mock.go +++ b/builder/oracle/oci/driver_mock.go @@ -24,6 +24,8 @@ type driverMock struct { WaitForImageCreationErr error WaitForInstanceStateErr error + + cfg *Config } // CreateInstance creates a new compute instance. @@ -57,11 +59,14 @@ func (d *driverMock) DeleteImage(id string) error { return nil } -// GetInstanceIP returns the public IP corresponding to the given instance id. +// GetInstanceIP returns the public or private IP corresponding to the given instance id. func (d *driverMock) GetInstanceIP(id string) (string, error) { if d.GetInstanceIPErr != nil { return "", d.GetInstanceIPErr } + if d.cfg.UsePrivateIP { + return "private_ip", nil + } return "ip", nil } diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index 1d6f943c0..ead05a12d 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -63,7 +63,7 @@ func (d *driverOCI) DeleteImage(id string) error { return d.client.Compute.Images.Delete(&client.DeleteImageParams{ID: id}) } -// GetInstanceIP returns the public IP corresponding to the given instance id. +// GetInstanceIP returns the public or private IP corresponding to the given instance id. func (d *driverOCI) GetInstanceIP(id string) (string, error) { // get nvic and cross ref to find pub ip address vnics, err := d.client.Compute.VNICAttachments.List( @@ -85,6 +85,9 @@ func (d *driverOCI) GetInstanceIP(id string) (string, error) { return "", fmt.Errorf("Error getting VNIC details: %s", err) } + if d.cfg.UsePrivateIP { + return vnic.PrivateIP, nil + } return vnic.PublicIP, nil } diff --git a/builder/oracle/oci/step_instance_info_test.go b/builder/oracle/oci/step_instance_info_test.go index 7117ec44a..d4e18dd44 100644 --- a/builder/oracle/oci/step_instance_info_test.go +++ b/builder/oracle/oci/step_instance_info_test.go @@ -1,11 +1,13 @@ package oci import ( + "bytes" "context" "errors" "testing" "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" ) func TestInstanceInfo(t *testing.T) { @@ -29,6 +31,36 @@ func TestInstanceInfo(t *testing.T) { } } +func TestInstanceInfoPrivateIP(t *testing.T) { + baseTestConfig := baseTestConfig() + baseTestConfig.UsePrivateIP = true + state := new(multistep.BasicStateBag) + state.Put("config", baseTestConfig) + state.Put("driver", &driverMock{cfg: baseTestConfig}) + state.Put("hook", &packer.MockHook{}) + state.Put("ui", &packer.BasicUi{ + Reader: new(bytes.Buffer), + Writer: new(bytes.Buffer), + }) + state.Put("instance_id", "ocid1...") + + step := new(stepInstanceInfo) + defer step.Cleanup(state) + + if action := step.Run(context.Background(), state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + + instanceIPRaw, ok := state.GetOk("instance_ip") + if !ok { + t.Fatalf("should have instance_ip") + } + + if instanceIPRaw.(string) != "private_ip" { + t.Fatalf("should've got ip ('%s' != 'private_ip')", instanceIPRaw.(string)) + } +} + func TestInstanceInfo_GetInstanceIPErr(t *testing.T) { state := testState() state.Put("instance_id", "ocid1...") diff --git a/builder/oracle/oci/step_test.go b/builder/oracle/oci/step_test.go index f46ffa1e4..cca58666c 100644 --- a/builder/oracle/oci/step_test.go +++ b/builder/oracle/oci/step_test.go @@ -36,7 +36,8 @@ func baseTestConfig() *Config { "key_file": keyFile.Name(), // Comm - "ssh_username": "opc", + "ssh_username": "opc", + "use_private_ip": false, }) // Once we have a config object they key file isn't re-read so we can @@ -50,9 +51,10 @@ func baseTestConfig() *Config { } func testState() multistep.StateBag { + baseTestConfig := baseTestConfig() state := new(multistep.BasicStateBag) - state.Put("config", baseTestConfig()) - state.Put("driver", &driverMock{}) + state.Put("config", baseTestConfig) + state.Put("driver", &driverMock{cfg: baseTestConfig}) state.Put("hook", &packer.MockHook{}) state.Put("ui", &packer.BasicUi{ Reader: new(bytes.Buffer), From ff30b3b3f706ab952e0a6962fa06107bd503e013 Mon Sep 17 00:00:00 2001 From: Robert Neumayer <neumayer@protonmail.com> Date: Tue, 13 Feb 2018 14:23:19 +0100 Subject: [PATCH 0653/1007] Remove unrelated changes --- builder/oracle/oci/config_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index 84002e937..f1352aafa 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -24,8 +24,7 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { "subnet_ocid": "ocd1...", // Comm - "ssh_username": "opc", - "use_private_ip": false, + "ssh_username": "opc", } } From 0534e3420c151adc10d0cd652cf43463ae8a5c98 Mon Sep 17 00:00:00 2001 From: Robert Neumayer <neumayer@protonmail.com> Date: Tue, 13 Feb 2018 14:41:51 +0100 Subject: [PATCH 0654/1007] Update docs --- website/source/docs/builders/oracle-oci.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index 6271c5830..ea4b08404 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -123,6 +123,8 @@ builder. value provided by the [OCI config file](https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdkconfig.htm) if present. + - `use_private_ip` (boolean) - Use private ip addresses to connect to the instance via ssh. + ## Basic Example From d6e5342ecef48411afb3a85cfd4af5b492cc1bd1 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 13 Feb 2018 17:27:12 -0600 Subject: [PATCH 0655/1007] Fixed a type-o in the VMWare builder when locating the dhcp configuration file on Linux. Closes issue #5882. --- builder/vmware/common/driver_workstation_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vmware/common/driver_workstation_unix.go b/builder/vmware/common/driver_workstation_unix.go index 45e94d21e..8b6a7f60b 100644 --- a/builder/vmware/common/driver_workstation_unix.go +++ b/builder/vmware/common/driver_workstation_unix.go @@ -59,7 +59,7 @@ func workstationDhcpConfPath(device string) string { log.Printf("Error finding VMware root: %s", err) return "" } - return filepath.Join(base, device, "dhcp/dhcpd.conf") + return filepath.Join(base, device, "dhcp/dhcp.conf") } func workstationVmnetnatConfPath(device string) string { From 3e3c16d6276440844190215be3d16339e769f747 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 13 Feb 2018 16:48:39 -0800 Subject: [PATCH 0656/1007] update docs --- website/source/docs/builders/amazon-chroot.html.md | 6 ++++++ website/source/docs/builders/amazon-ebs.html.md | 6 ++++++ website/source/docs/builders/amazon-ebssurrogate.html.md | 6 ++++++ website/source/docs/builders/amazon-ebsvolume.html.md | 6 ++++++ website/source/docs/builders/amazon-instance.html.md | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 7bb0adcec..53c21ff30 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -300,6 +300,12 @@ each category, the available configuration keys are alphabetized. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. + You may set this in place of `source_ami` or in conjunction with it. If you + set this in conjunction with `source_ami`, the `source_ami` will be added to + the filter. The provided `source_ami` must meet all of the filtering criteria + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 4f2a44498..effa6e5ef 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -302,6 +302,12 @@ builder. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. + You may set this in place of `source_ami` or in conjunction with it. If you + set this in conjunction with `source_ami`, the `source_ami` will be added to + the filter. The provided `source_ami` must meet all of the filtering criteria + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. + - `spot_price` (string) - The maximum hourly price to pay for a spot instance to create the AMI. Spot instances are a type of instance that EC2 starts when the current spot price is less than the maximum price you specify. Spot diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index c01c3c493..757ae1229 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -294,6 +294,12 @@ builder. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. + + You may set this in place of `source_ami` or in conjunction with it. If you + set this in conjunction with `source_ami`, the `source_ami` will be added to + the filter. The provided `source_ami` must meet all of the filtering criteria + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. - `spot_price` (string) - The maximum hourly price to pay for a spot instance to create the AMI. Spot instances are a type of instance that EC2 starts diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 186295b87..c8604cc25 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -198,6 +198,12 @@ builder. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. + You may set this in place of `source_ami` or in conjunction with it. If you + set this in conjunction with `source_ami`, the `source_ami` will be added to + the filter. The provided `source_ami` must meet all of the filtering criteria + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. + - `spot_price` (string) - The maximum hourly price to pay for a spot instance to create the AMI. Spot instances are a type of instance that EC2 starts when the current spot price is less than the maximum price you specify. Spot diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 924e174dd..5773c8bdd 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -299,6 +299,12 @@ builder. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. + + You may set this in place of `source_ami` or in conjunction with it. If you + set this in conjunction with `source_ami`, the `source_ami` will be added to + the filter. The provided `source_ami` must meet all of the filtering criteria + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. - `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. They will override AMI tags if already applied to snapshot. From 27ed479b0a42dd1e15c673ee421fceab01f306ab Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Wed, 14 Feb 2018 00:08:10 -0600 Subject: [PATCH 0657/1007] Reinforced the VMWare Workstation builder methodology for locating the dhcp.conf and dhcpd.leases files on Linux. It was reported that on WS14 on Linux, that the path may be different than stated in the documentation. This modifies `workstationDhcpConfPath` and `workstationDhcpLeasesPath` functions to walk through every permutation while attempting to find the correct file. This reinforces the fix for issue #5882. --- .../vmware/common/driver_workstation_unix.go | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/driver_workstation_unix.go b/builder/vmware/common/driver_workstation_unix.go index 8b6a7f60b..5bbbc7d1d 100644 --- a/builder/vmware/common/driver_workstation_unix.go +++ b/builder/vmware/common/driver_workstation_unix.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "log" + "os" "os/exec" "path/filepath" "regexp" @@ -50,7 +51,24 @@ func workstationDhcpLeasesPath(device string) string { log.Printf("Error finding VMware root: %s", err) return "" } - return filepath.Join(base, device, "dhcpd/dhcpd.leases") + + // Build the base path to VMware configuration for specified device: `/etc/vmware/${device}` + devicebase := filepath.Join(base, device) + + // Walk through a list of paths searching for the correct permutation... + // ...as it appears that in >= WS14 and < WS14, the leases file may be labelled differently. + + // Docs say we should expect: dhcpd/dhcpd.leases + paths := []string{"dhcpd/dhcpd.leases", "dhcpd/dhcp.leases", "dhcp/dhcpd.leases", "dhcp/dhcp.leases"} + for _, p := range paths { + fp := filepath.Join(devicebase, p) + if _, err := os.Stat(fp); !os.IsNotExist(err) { + return fp + } + } + + log.Printf("Error finding VMWare DHCP Server Leases (dhcpd.leases) under device path: %s", devicebase) + return "" } func workstationDhcpConfPath(device string) string { @@ -59,7 +77,24 @@ func workstationDhcpConfPath(device string) string { log.Printf("Error finding VMware root: %s", err) return "" } - return filepath.Join(base, device, "dhcp/dhcp.conf") + + // Build the base path to VMware configuration for specified device: `/etc/vmware/${device}` + devicebase := filepath.Join(base, device) + + // Walk through a list of paths searching for the correct permutation... + // ...as it appears that in >= WS14 and < WS14, the dhcp config may be labelled differently. + + // Docs say we should expect: dhcp/dhcp.conf + paths := []string{"dhcp/dhcp.conf", "dhcp/dhcpd.conf", "dhcpd/dhcp.conf", "dhcpd/dhcpd.conf"} + for _, p := range paths { + fp := filepath.Join(devicebase, p) + if _, err := os.Stat(fp); !os.IsNotExist(err) { + return fp + } + } + + log.Printf("Error finding VMWare DHCP Server Configuration (dhcp.conf) under device path: %s", devicebase) + return "" } func workstationVmnetnatConfPath(device string) string { From d3848903e046dcd3473d2debe289bad1d8f79731 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 14 Feb 2018 19:07:40 -0800 Subject: [PATCH 0658/1007] Clarify behavior or launch_block_device_mappings. cf https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateImage.html https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateVolume.html --- .../source/docs/builders/amazon-ebs.html.md | 18 ++++++++++------- .../docs/builders/amazon-ebssurrogate.html.md | 20 +++++++++++-------- .../docs/builders/amazon-instance.html.md | 20 +++++++++++-------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index effa6e5ef..4c57611f4 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -192,10 +192,14 @@ builder. profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) to launch the EC2 instance with. -- `launch_block_device_mappings` (array of block device mappings) - Add one or - more block devices before the Packer build starts. These are not necessarily - preserved when booting from the AMI built with Packer. See - `ami_block_device_mappings`, above, for details. +- `launch_block_device_mappings` (array of block device mappings) - Add one + or more block devices before the Packer build starts. If you add instance + store volumes or EBS volumes in addition to the root device volume, the + created AMI will contain block device mapping information for those + volumes. Amazon creates snapshots of the source instance's root volume and + any other EBS volumes described here. When you launch an instance from this + new AMI, the instance automatically launches with these additional volumes, + and will restore them from snapshots taken from the source instance. - `mfa_code` (string) - The MFA [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) code. This should probably be a user variable since it changes all the time. @@ -303,10 +307,10 @@ builder. This is most useful for selecting a daily distro build. You may set this in place of `source_ami` or in conjunction with it. If you - set this in conjunction with `source_ami`, the `source_ami` will be added to + set this in conjunction with `source_ami`, the `source_ami` will be added to the filter. The provided `source_ami` must meet all of the filtering criteria - provided in `source_ami_filter`; this pins the AMI returned by the filter, - but will cause Packer to fail if the `source_ami` does not exist. + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. - `spot_price` (string) - The maximum hourly price to pay for a spot instance to create the AMI. Spot instances are a type of instance that EC2 starts diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 757ae1229..d40ec04e1 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -185,10 +185,14 @@ builder. profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) to launch the EC2 instance with. -- `launch_block_device_mappings` (array of block device mappings) - Add one or - more block devices before the packer build starts. These are not necessarily - preserved when booting from the AMI built with packer. See - `ami_block_device_mappings`, above, for details. +- `launch_block_device_mappings` (array of block device mappings) - Add one + or more block devices before the Packer build starts. If you add instance + store volumes or EBS volumes in addition to the root device volume, the + created AMI will contain block device mapping information for those + volumes. Amazon creates snapshots of the source instance's root volume and + any other EBS volumes described here. When you launch an instance from this + new AMI, the instance automatically launches with these additional volumes, + and will restore them from snapshots taken from the source instance. - `mfa_code` (string) - The MFA [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) code. This should probably be a user variable since it changes all the time. @@ -294,12 +298,12 @@ builder. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - + You may set this in place of `source_ami` or in conjunction with it. If you - set this in conjunction with `source_ami`, the `source_ami` will be added to + set this in conjunction with `source_ami`, the `source_ami` will be added to the filter. The provided `source_ami` must meet all of the filtering criteria - provided in `source_ami_filter`; this pins the AMI returned by the filter, - but will cause Packer to fail if the `source_ami` does not exist. + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. - `spot_price` (string) - The maximum hourly price to pay for a spot instance to create the AMI. Spot instances are a type of instance that EC2 starts diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 5773c8bdd..62417e1b7 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -207,10 +207,14 @@ builder. profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) to launch the EC2 instance with. -- `launch_block_device_mappings` (array of block device mappings) - Add one or - more block devices before the Packer build starts. These are not necessarily - preserved when booting from the AMI built with Packer. See - `ami_block_device_mappings`, above, for details. +- `launch_block_device_mappings` (array of block device mappings) - Add one + or more block devices before the Packer build starts. If you add instance + store volumes or EBS volumes in addition to the root device volume, the + created AMI will contain block device mapping information for those + volumes. Amazon creates snapshots of the source instance's root volume and + any other EBS volumes described here. When you launch an instance from this + new AMI, the instance automatically launches with these additional volumes, + and will restore them from snapshots taken from the source instance. - `mfa_code` (string) - The MFA [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) code. This should probably be a user variable since it changes all the time. @@ -299,12 +303,12 @@ builder. - `most_recent` (boolean) - Selects the newest created image when true. This is most useful for selecting a daily distro build. - + You may set this in place of `source_ami` or in conjunction with it. If you - set this in conjunction with `source_ami`, the `source_ami` will be added to + set this in conjunction with `source_ami`, the `source_ami` will be added to the filter. The provided `source_ami` must meet all of the filtering criteria - provided in `source_ami_filter`; this pins the AMI returned by the filter, - but will cause Packer to fail if the `source_ami` does not exist. + provided in `source_ami_filter`; this pins the AMI returned by the filter, + but will cause Packer to fail if the `source_ami` does not exist. - `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. They will override AMI tags if already applied to snapshot. From 7fd71c35ef076bff25d15f2f93b3898766c6fdc5 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 15 Feb 2018 13:38:28 -0800 Subject: [PATCH 0659/1007] update go-aws-sdk to v1.12.72 --- vendor/github.com/aws/aws-sdk-go/CHANGELOG.md | 24 + .../aws/aws-sdk-go/aws/endpoints/defaults.go | 1 + .../aws/aws-sdk-go/aws/session/env_config.go | 8 + .../aws/aws-sdk-go/aws/session/session.go | 14 +- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws/aws-sdk-go/service/ec2/api.go | 811 ------------------ .../aws/aws-sdk-go/service/ecr/api.go | 58 -- .../aws/aws-sdk-go/service/s3/api.go | 250 ------ .../aws/aws-sdk-go/service/sts/api.go | 17 - vendor/vendor.json | 290 +++---- 10 files changed, 185 insertions(+), 1290 deletions(-) diff --git a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md index 0fc7f9c88..dd7465367 100644 --- a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md @@ -1,3 +1,27 @@ +Release v1.12.72 (2018-02-07) +=== + +### Service Client Updates +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/glue`: Updates service API and documentation + * This new feature will now allow customers to add a customized json classifier. They can specify a json path to indicate the object, array or field of the json documents they'd like crawlers to inspect when they crawl json files. +* `service/servicecatalog`: Updates service API, documentation, and paginators + * This release of Service Catalog adds SearchProvisionedProducts API and ProvisionedProductPlan APIs. +* `service/servicediscovery`: Updates service API and documentation + * This release adds support for registering CNAME record types and creating Route 53 alias records that route traffic to Amazon Elastic Load Balancers using Amazon Route 53 Auto Naming APIs. +* `service/ssm`: Updates service API and documentation + * This Patch Manager release supports configuring Linux repos as part of patch baselines, controlling updates of non-OS security packages and also creating patch baselines for SUSE12 + +### SDK Enhancements +* `private/model/api`: Add validation to ensure there is no duplication of services in models/apis ([#1758](https://github.com/aws/aws-sdk-go/pull/1758)) + * Prevents the SDK from mistakenly generating code a single service multiple times with different model versions. +* `example/service/ec2/instancesbyRegion`: Fix typos in example ([#1762](https://github.com/aws/aws-sdk-go/pull/1762)) +* `private/model/api`: removing SDK API reference crosslinks from input/output shapes. (#1765) + +### SDK Bugs +* `aws/session`: Fix bug in session.New not supporting AWS_SDK_LOAD_CONFIG ([#1770](https://github.com/aws/aws-sdk-go/pull/1770)) + * Fixes a bug in the session.New function that was not correctly sourcing the shared configuration files' path. + * Fixes [#1771](https://github.com/aws/aws-sdk-go/pull/1771) Release v1.12.71 (2018-02-05) === diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 689c380b4..9e728feee 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -1182,6 +1182,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "us-east-1": endpoint{}, + "us-east-2": endpoint{}, "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go index f1adcf481..12b452177 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/defaults" ) // EnvProviderName provides a name of the provider when config is loaded from environment. @@ -176,6 +177,13 @@ func envConfigLoad(enableSharedConfig bool) envConfig { setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey) setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey) + if len(cfg.SharedCredentialsFile) == 0 { + cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename() + } + if len(cfg.SharedConfigFile) == 0 { + cfg.SharedConfigFile = defaults.SharedConfigFilename() + } + cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") return cfg diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go index 9f75d5ac5..2fc789d6d 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go @@ -58,7 +58,12 @@ func New(cfgs ...*aws.Config) *Session { envCfg := loadEnvConfig() if envCfg.EnableSharedConfig { - s, err := newSession(Options{}, envCfg, cfgs...) + var cfg aws.Config + cfg.MergeIn(cfgs...) + s, err := NewSessionWithOptions(Options{ + Config: cfg, + SharedConfigState: SharedConfigEnable, + }) if err != nil { // Old session.New expected all errors to be discovered when // a request is made, and would report the errors then. This @@ -243,13 +248,6 @@ func NewSessionWithOptions(opts Options) (*Session, error) { envCfg.EnableSharedConfig = true } - if len(envCfg.SharedCredentialsFile) == 0 { - envCfg.SharedCredentialsFile = defaults.SharedCredentialsFilename() - } - if len(envCfg.SharedConfigFile) == 0 { - envCfg.SharedConfigFile = defaults.SharedConfigFilename() - } - // Only use AWS_CA_BUNDLE if session option is not provided. if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil { f, err := os.Open(envCfg.CustomCABundle) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index b55286b31..02dfdd9e2 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.12.71" +const SDKVersion = "1.12.72" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index 1743b3449..3461bb96a 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -22266,7 +22266,6 @@ func (c *EC2) UpdateSecurityGroupRuleDescriptionsIngressWithContext(ctx aws.Cont } // Contains the parameters for accepting the quote. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuoteRequest type AcceptReservedInstancesExchangeQuoteInput struct { _ struct{} `type:"structure"` @@ -22339,7 +22338,6 @@ func (s *AcceptReservedInstancesExchangeQuoteInput) SetTargetConfigurations(v [] } // The result of the exchange and whether it was successful. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptReservedInstancesExchangeQuoteResult type AcceptReservedInstancesExchangeQuoteOutput struct { _ struct{} `type:"structure"` @@ -22363,7 +22361,6 @@ func (s *AcceptReservedInstancesExchangeQuoteOutput) SetExchangeId(v string) *Ac return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcEndpointConnectionsRequest type AcceptVpcEndpointConnectionsInput struct { _ struct{} `type:"structure"` @@ -22428,7 +22425,6 @@ func (s *AcceptVpcEndpointConnectionsInput) SetVpcEndpointIds(v []*string) *Acce return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcEndpointConnectionsResult type AcceptVpcEndpointConnectionsOutput struct { _ struct{} `type:"structure"` @@ -22453,7 +22449,6 @@ func (s *AcceptVpcEndpointConnectionsOutput) SetUnsuccessful(v []*UnsuccessfulIt } // Contains the parameters for AcceptVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnectionRequest type AcceptVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -22491,7 +22486,6 @@ func (s *AcceptVpcPeeringConnectionInput) SetVpcPeeringConnectionId(v string) *A } // Contains the output of AcceptVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AcceptVpcPeeringConnectionResult type AcceptVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -22516,7 +22510,6 @@ func (s *AcceptVpcPeeringConnectionOutput) SetVpcPeeringConnection(v *VpcPeering } // Describes an account attribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AccountAttribute type AccountAttribute struct { _ struct{} `type:"structure"` @@ -22550,7 +22543,6 @@ func (s *AccountAttribute) SetAttributeValues(v []*AccountAttributeValue) *Accou } // Describes a value of an account attribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AccountAttributeValue type AccountAttributeValue struct { _ struct{} `type:"structure"` @@ -22575,7 +22567,6 @@ func (s *AccountAttributeValue) SetAttributeValue(v string) *AccountAttributeVal } // Describes a running instance in a Spot Fleet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ActiveInstance type ActiveInstance struct { _ struct{} `type:"structure"` @@ -22629,7 +22620,6 @@ func (s *ActiveInstance) SetSpotInstanceRequestId(v string) *ActiveInstance { } // Describes an Elastic IP address. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Address type Address struct { _ struct{} `type:"structure"` @@ -22728,7 +22718,6 @@ func (s *Address) SetTags(v []*Tag) *Address { } // Contains the parameters for AllocateAddress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddressRequest type AllocateAddressInput struct { _ struct{} `type:"structure"` @@ -22776,7 +22765,6 @@ func (s *AllocateAddressInput) SetDryRun(v bool) *AllocateAddressInput { } // Contains the output of AllocateAddress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateAddressResult type AllocateAddressOutput struct { _ struct{} `type:"structure"` @@ -22821,7 +22809,6 @@ func (s *AllocateAddressOutput) SetPublicIp(v string) *AllocateAddressOutput { } // Contains the parameters for AllocateHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHostsRequest type AllocateHostsInput struct { _ struct{} `type:"structure"` @@ -22916,7 +22903,6 @@ func (s *AllocateHostsInput) SetQuantity(v int64) *AllocateHostsInput { } // Contains the output of AllocateHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllocateHostsResult type AllocateHostsOutput struct { _ struct{} `type:"structure"` @@ -22942,7 +22928,6 @@ func (s *AllocateHostsOutput) SetHostIds(v []*string) *AllocateHostsOutput { } // Describes a principal. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AllowedPrincipal type AllowedPrincipal struct { _ struct{} `type:"structure"` @@ -22975,7 +22960,6 @@ func (s *AllowedPrincipal) SetPrincipalType(v string) *AllowedPrincipal { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6AddressesRequest type AssignIpv6AddressesInput struct { _ struct{} `type:"structure"` @@ -23035,7 +23019,6 @@ func (s *AssignIpv6AddressesInput) SetNetworkInterfaceId(v string) *AssignIpv6Ad return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignIpv6AddressesResult type AssignIpv6AddressesOutput struct { _ struct{} `type:"structure"` @@ -23069,7 +23052,6 @@ func (s *AssignIpv6AddressesOutput) SetNetworkInterfaceId(v string) *AssignIpv6A } // Contains the parameters for AssignPrivateIpAddresses. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddressesRequest type AssignPrivateIpAddressesInput struct { _ struct{} `type:"structure"` @@ -23142,7 +23124,6 @@ func (s *AssignPrivateIpAddressesInput) SetSecondaryPrivateIpAddressCount(v int6 return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssignPrivateIpAddressesOutput type AssignPrivateIpAddressesOutput struct { _ struct{} `type:"structure"` } @@ -23158,7 +23139,6 @@ func (s AssignPrivateIpAddressesOutput) GoString() string { } // Contains the parameters for AssociateAddress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddressRequest type AssociateAddressInput struct { _ struct{} `type:"structure"` @@ -23251,7 +23231,6 @@ func (s *AssociateAddressInput) SetPublicIp(v string) *AssociateAddressInput { } // Contains the output of AssociateAddress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateAddressResult type AssociateAddressOutput struct { _ struct{} `type:"structure"` @@ -23277,7 +23256,6 @@ func (s *AssociateAddressOutput) SetAssociationId(v string) *AssociateAddressOut } // Contains the parameters for AssociateDhcpOptions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptionsRequest type AssociateDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -23343,7 +23321,6 @@ func (s *AssociateDhcpOptionsInput) SetVpcId(v string) *AssociateDhcpOptionsInpu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateDhcpOptionsOutput type AssociateDhcpOptionsOutput struct { _ struct{} `type:"structure"` } @@ -23358,7 +23335,6 @@ func (s AssociateDhcpOptionsOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfileRequest type AssociateIamInstanceProfileInput struct { _ struct{} `type:"structure"` @@ -23411,7 +23387,6 @@ func (s *AssociateIamInstanceProfileInput) SetInstanceId(v string) *AssociateIam return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateIamInstanceProfileResult type AssociateIamInstanceProfileOutput struct { _ struct{} `type:"structure"` @@ -23436,7 +23411,6 @@ func (s *AssociateIamInstanceProfileOutput) SetIamInstanceProfileAssociation(v * } // Contains the parameters for AssociateRouteTable. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTableRequest type AssociateRouteTableInput struct { _ struct{} `type:"structure"` @@ -23502,7 +23476,6 @@ func (s *AssociateRouteTableInput) SetSubnetId(v string) *AssociateRouteTableInp } // Contains the output of AssociateRouteTable. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateRouteTableResult type AssociateRouteTableOutput struct { _ struct{} `type:"structure"` @@ -23526,7 +23499,6 @@ func (s *AssociateRouteTableOutput) SetAssociationId(v string) *AssociateRouteTa return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlockRequest type AssociateSubnetCidrBlockInput struct { _ struct{} `type:"structure"` @@ -23579,7 +23551,6 @@ func (s *AssociateSubnetCidrBlockInput) SetSubnetId(v string) *AssociateSubnetCi return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateSubnetCidrBlockResult type AssociateSubnetCidrBlockOutput struct { _ struct{} `type:"structure"` @@ -23612,7 +23583,6 @@ func (s *AssociateSubnetCidrBlockOutput) SetSubnetId(v string) *AssociateSubnetC return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlockRequest type AssociateVpcCidrBlockInput struct { _ struct{} `type:"structure"` @@ -23671,7 +23641,6 @@ func (s *AssociateVpcCidrBlockInput) SetVpcId(v string) *AssociateVpcCidrBlockIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AssociateVpcCidrBlockResult type AssociateVpcCidrBlockOutput struct { _ struct{} `type:"structure"` @@ -23714,7 +23683,6 @@ func (s *AssociateVpcCidrBlockOutput) SetVpcId(v string) *AssociateVpcCidrBlockO } // Contains the parameters for AttachClassicLinkVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpcRequest type AttachClassicLinkVpcInput struct { _ struct{} `type:"structure"` @@ -23795,7 +23763,6 @@ func (s *AttachClassicLinkVpcInput) SetVpcId(v string) *AttachClassicLinkVpcInpu } // Contains the output of AttachClassicLinkVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachClassicLinkVpcResult type AttachClassicLinkVpcOutput struct { _ struct{} `type:"structure"` @@ -23820,7 +23787,6 @@ func (s *AttachClassicLinkVpcOutput) SetReturn(v bool) *AttachClassicLinkVpcOutp } // Contains the parameters for AttachInternetGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGatewayRequest type AttachInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -23885,7 +23851,6 @@ func (s *AttachInternetGatewayInput) SetVpcId(v string) *AttachInternetGatewayIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachInternetGatewayOutput type AttachInternetGatewayOutput struct { _ struct{} `type:"structure"` } @@ -23901,7 +23866,6 @@ func (s AttachInternetGatewayOutput) GoString() string { } // Contains the parameters for AttachNetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterfaceRequest type AttachNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -23981,7 +23945,6 @@ func (s *AttachNetworkInterfaceInput) SetNetworkInterfaceId(v string) *AttachNet } // Contains the output of AttachNetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachNetworkInterfaceResult type AttachNetworkInterfaceOutput struct { _ struct{} `type:"structure"` @@ -24006,7 +23969,6 @@ func (s *AttachNetworkInterfaceOutput) SetAttachmentId(v string) *AttachNetworkI } // Contains the parameters for AttachVolume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVolumeRequest type AttachVolumeInput struct { _ struct{} `type:"structure"` @@ -24087,7 +24049,6 @@ func (s *AttachVolumeInput) SetVolumeId(v string) *AttachVolumeInput { } // Contains the parameters for AttachVpnGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGatewayRequest type AttachVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -24153,7 +24114,6 @@ func (s *AttachVpnGatewayInput) SetVpnGatewayId(v string) *AttachVpnGatewayInput } // Contains the output of AttachVpnGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttachVpnGatewayResult type AttachVpnGatewayOutput struct { _ struct{} `type:"structure"` @@ -24178,7 +24138,6 @@ func (s *AttachVpnGatewayOutput) SetVpcAttachment(v *VpcAttachment) *AttachVpnGa } // Describes a value for a resource attribute that is a Boolean value. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttributeBooleanValue type AttributeBooleanValue struct { _ struct{} `type:"structure"` @@ -24203,7 +24162,6 @@ func (s *AttributeBooleanValue) SetValue(v bool) *AttributeBooleanValue { } // Describes a value for a resource attribute that is a String. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AttributeValue type AttributeValue struct { _ struct{} `type:"structure"` @@ -24228,7 +24186,6 @@ func (s *AttributeValue) SetValue(v string) *AttributeValue { } // Contains the parameters for AuthorizeSecurityGroupEgress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgressRequest type AuthorizeSecurityGroupEgressInput struct { _ struct{} `type:"structure"` @@ -24346,7 +24303,6 @@ func (s *AuthorizeSecurityGroupEgressInput) SetToPort(v int64) *AuthorizeSecurit return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupEgressOutput type AuthorizeSecurityGroupEgressOutput struct { _ struct{} `type:"structure"` } @@ -24362,7 +24318,6 @@ func (s AuthorizeSecurityGroupEgressOutput) GoString() string { } // Contains the parameters for AuthorizeSecurityGroupIngress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngressRequest type AuthorizeSecurityGroupIngressInput struct { _ struct{} `type:"structure"` @@ -24495,7 +24450,6 @@ func (s *AuthorizeSecurityGroupIngressInput) SetToPort(v int64) *AuthorizeSecuri return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AuthorizeSecurityGroupIngressOutput type AuthorizeSecurityGroupIngressOutput struct { _ struct{} `type:"structure"` } @@ -24511,7 +24465,6 @@ func (s AuthorizeSecurityGroupIngressOutput) GoString() string { } // Describes an Availability Zone. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailabilityZone type AvailabilityZone struct { _ struct{} `type:"structure"` @@ -24563,7 +24516,6 @@ func (s *AvailabilityZone) SetZoneName(v string) *AvailabilityZone { } // Describes a message about an Availability Zone. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailabilityZoneMessage type AvailabilityZoneMessage struct { _ struct{} `type:"structure"` @@ -24588,7 +24540,6 @@ func (s *AvailabilityZoneMessage) SetMessage(v string) *AvailabilityZoneMessage } // The capacity information for instances launched onto the Dedicated Host. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/AvailableCapacity type AvailableCapacity struct { _ struct{} `type:"structure"` @@ -24621,7 +24572,6 @@ func (s *AvailableCapacity) SetAvailableVCpus(v int64) *AvailableCapacity { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BlobAttributeValue type BlobAttributeValue struct { _ struct{} `type:"structure"` @@ -24646,7 +24596,6 @@ func (s *BlobAttributeValue) SetValue(v []byte) *BlobAttributeValue { } // Describes a block device mapping. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BlockDeviceMapping type BlockDeviceMapping struct { _ struct{} `type:"structure"` @@ -24709,7 +24658,6 @@ func (s *BlockDeviceMapping) SetVirtualName(v string) *BlockDeviceMapping { } // Contains the parameters for BundleInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstanceRequest type BundleInstanceInput struct { _ struct{} `type:"structure"` @@ -24783,7 +24731,6 @@ func (s *BundleInstanceInput) SetStorage(v *Storage) *BundleInstanceInput { } // Contains the output of BundleInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleInstanceResult type BundleInstanceOutput struct { _ struct{} `type:"structure"` @@ -24808,7 +24755,6 @@ func (s *BundleInstanceOutput) SetBundleTask(v *BundleTask) *BundleInstanceOutpu } // Describes a bundle task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleTask type BundleTask struct { _ struct{} `type:"structure"` @@ -24896,7 +24842,6 @@ func (s *BundleTask) SetUpdateTime(v time.Time) *BundleTask { } // Describes an error for BundleInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/BundleTaskError type BundleTaskError struct { _ struct{} `type:"structure"` @@ -24930,7 +24875,6 @@ func (s *BundleTaskError) SetMessage(v string) *BundleTaskError { } // Contains the parameters for CancelBundleTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTaskRequest type CancelBundleTaskInput struct { _ struct{} `type:"structure"` @@ -24982,7 +24926,6 @@ func (s *CancelBundleTaskInput) SetDryRun(v bool) *CancelBundleTaskInput { } // Contains the output of CancelBundleTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelBundleTaskResult type CancelBundleTaskOutput struct { _ struct{} `type:"structure"` @@ -25007,7 +24950,6 @@ func (s *CancelBundleTaskOutput) SetBundleTask(v *BundleTask) *CancelBundleTaskO } // Contains the parameters for CancelConversionTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionRequest type CancelConversionTaskInput struct { _ struct{} `type:"structure"` @@ -25067,7 +25009,6 @@ func (s *CancelConversionTaskInput) SetReasonMessage(v string) *CancelConversion return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelConversionTaskOutput type CancelConversionTaskOutput struct { _ struct{} `type:"structure"` } @@ -25083,7 +25024,6 @@ func (s CancelConversionTaskOutput) GoString() string { } // Contains the parameters for CancelExportTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTaskRequest type CancelExportTaskInput struct { _ struct{} `type:"structure"` @@ -25122,7 +25062,6 @@ func (s *CancelExportTaskInput) SetExportTaskId(v string) *CancelExportTaskInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelExportTaskOutput type CancelExportTaskOutput struct { _ struct{} `type:"structure"` } @@ -25138,7 +25077,6 @@ func (s CancelExportTaskOutput) GoString() string { } // Contains the parameters for CancelImportTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTaskRequest type CancelImportTaskInput struct { _ struct{} `type:"structure"` @@ -25184,7 +25122,6 @@ func (s *CancelImportTaskInput) SetImportTaskId(v string) *CancelImportTaskInput } // Contains the output for CancelImportTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelImportTaskResult type CancelImportTaskOutput struct { _ struct{} `type:"structure"` @@ -25227,7 +25164,6 @@ func (s *CancelImportTaskOutput) SetState(v string) *CancelImportTaskOutput { } // Contains the parameters for CancelReservedInstancesListing. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListingRequest type CancelReservedInstancesListingInput struct { _ struct{} `type:"structure"` @@ -25267,7 +25203,6 @@ func (s *CancelReservedInstancesListingInput) SetReservedInstancesListingId(v st } // Contains the output of CancelReservedInstancesListing. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelReservedInstancesListingResult type CancelReservedInstancesListingOutput struct { _ struct{} `type:"structure"` @@ -25292,7 +25227,6 @@ func (s *CancelReservedInstancesListingOutput) SetReservedInstancesListings(v [] } // Describes a Spot Fleet error. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsError type CancelSpotFleetRequestsError struct { _ struct{} `type:"structure"` @@ -25330,7 +25264,6 @@ func (s *CancelSpotFleetRequestsError) SetMessage(v string) *CancelSpotFleetRequ } // Describes a Spot Fleet request that was not successfully canceled. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsErrorItem type CancelSpotFleetRequestsErrorItem struct { _ struct{} `type:"structure"` @@ -25368,7 +25301,6 @@ func (s *CancelSpotFleetRequestsErrorItem) SetSpotFleetRequestId(v string) *Canc } // Contains the parameters for CancelSpotFleetRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsRequest type CancelSpotFleetRequestsInput struct { _ struct{} `type:"structure"` @@ -25435,7 +25367,6 @@ func (s *CancelSpotFleetRequestsInput) SetTerminateInstances(v bool) *CancelSpot } // Contains the output of CancelSpotFleetRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsResponse type CancelSpotFleetRequestsOutput struct { _ struct{} `type:"structure"` @@ -25469,7 +25400,6 @@ func (s *CancelSpotFleetRequestsOutput) SetUnsuccessfulFleetRequests(v []*Cancel } // Describes a Spot Fleet request that was successfully canceled. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotFleetRequestsSuccessItem type CancelSpotFleetRequestsSuccessItem struct { _ struct{} `type:"structure"` @@ -25518,7 +25448,6 @@ func (s *CancelSpotFleetRequestsSuccessItem) SetSpotFleetRequestId(v string) *Ca } // Contains the parameters for CancelSpotInstanceRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequestsRequest type CancelSpotInstanceRequestsInput struct { _ struct{} `type:"structure"` @@ -25570,7 +25499,6 @@ func (s *CancelSpotInstanceRequestsInput) SetSpotInstanceRequestIds(v []*string) } // Contains the output of CancelSpotInstanceRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelSpotInstanceRequestsResult type CancelSpotInstanceRequestsOutput struct { _ struct{} `type:"structure"` @@ -25595,7 +25523,6 @@ func (s *CancelSpotInstanceRequestsOutput) SetCancelledSpotInstanceRequests(v [] } // Describes a request to cancel a Spot Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CancelledSpotInstanceRequest type CancelledSpotInstanceRequest struct { _ struct{} `type:"structure"` @@ -25629,7 +25556,6 @@ func (s *CancelledSpotInstanceRequest) SetState(v string) *CancelledSpotInstance } // Describes an IPv4 CIDR block. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CidrBlock type CidrBlock struct { _ struct{} `type:"structure"` @@ -25654,7 +25580,6 @@ func (s *CidrBlock) SetCidrBlock(v string) *CidrBlock { } // Describes the ClassicLink DNS support status of a VPC. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLinkDnsSupport type ClassicLinkDnsSupport struct { _ struct{} `type:"structure"` @@ -25688,7 +25613,6 @@ func (s *ClassicLinkDnsSupport) SetVpcId(v string) *ClassicLinkDnsSupport { } // Describes a linked EC2-Classic instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLinkInstance type ClassicLinkInstance struct { _ struct{} `type:"structure"` @@ -25740,7 +25664,6 @@ func (s *ClassicLinkInstance) SetVpcId(v string) *ClassicLinkInstance { } // Describes a Classic Load Balancer. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLoadBalancer type ClassicLoadBalancer struct { _ struct{} `type:"structure"` @@ -25781,7 +25704,6 @@ func (s *ClassicLoadBalancer) SetName(v string) *ClassicLoadBalancer { // Describes the Classic Load Balancers to attach to a Spot Fleet. Spot Fleet // registers the running Spot Instances with these Classic Load Balancers. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClassicLoadBalancersConfig type ClassicLoadBalancersConfig struct { _ struct{} `type:"structure"` @@ -25834,7 +25756,6 @@ func (s *ClassicLoadBalancersConfig) SetClassicLoadBalancers(v []*ClassicLoadBal } // Describes the client-specific data. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ClientData type ClientData struct { _ struct{} `type:"structure"` @@ -25886,7 +25807,6 @@ func (s *ClientData) SetUploadStart(v time.Time) *ClientData { } // Contains the parameters for ConfirmProductInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstanceRequest type ConfirmProductInstanceInput struct { _ struct{} `type:"structure"` @@ -25952,7 +25872,6 @@ func (s *ConfirmProductInstanceInput) SetProductCode(v string) *ConfirmProductIn } // Contains the output of ConfirmProductInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConfirmProductInstanceResult type ConfirmProductInstanceOutput struct { _ struct{} `type:"structure"` @@ -25988,7 +25907,6 @@ func (s *ConfirmProductInstanceOutput) SetReturn(v bool) *ConfirmProductInstance } // Describes a connection notification for a VPC endpoint or VPC endpoint service. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConnectionNotification type ConnectionNotification struct { _ struct{} `type:"structure"` @@ -26068,7 +25986,6 @@ func (s *ConnectionNotification) SetVpcEndpointId(v string) *ConnectionNotificat } // Describes a conversion task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ConversionTask type ConversionTask struct { _ struct{} `type:"structure"` @@ -26153,7 +26070,6 @@ func (s *ConversionTask) SetTags(v []*Tag) *ConversionTask { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyFpgaImageRequest type CopyFpgaImageInput struct { _ struct{} `type:"structure"` @@ -26246,7 +26162,6 @@ func (s *CopyFpgaImageInput) SetSourceRegion(v string) *CopyFpgaImageInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyFpgaImageResult type CopyFpgaImageOutput struct { _ struct{} `type:"structure"` @@ -26271,7 +26186,6 @@ func (s *CopyFpgaImageOutput) SetFpgaImageId(v string) *CopyFpgaImageOutput { } // Contains the parameters for CopyImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImageRequest type CopyImageInput struct { _ struct{} `type:"structure"` @@ -26400,7 +26314,6 @@ func (s *CopyImageInput) SetSourceRegion(v string) *CopyImageInput { } // Contains the output of CopyImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopyImageResult type CopyImageOutput struct { _ struct{} `type:"structure"` @@ -26425,7 +26338,6 @@ func (s *CopyImageOutput) SetImageId(v string) *CopyImageOutput { } // Contains the parameters for CopySnapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshotRequest type CopySnapshotInput struct { _ struct{} `type:"structure"` @@ -26567,7 +26479,6 @@ func (s *CopySnapshotInput) SetSourceSnapshotId(v string) *CopySnapshotInput { } // Contains the output of CopySnapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CopySnapshotResult type CopySnapshotOutput struct { _ struct{} `type:"structure"` @@ -26592,7 +26503,6 @@ func (s *CopySnapshotOutput) SetSnapshotId(v string) *CopySnapshotOutput { } // Contains the parameters for CreateCustomerGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGatewayRequest type CreateCustomerGatewayInput struct { _ struct{} `type:"structure"` @@ -26675,7 +26585,6 @@ func (s *CreateCustomerGatewayInput) SetType(v string) *CreateCustomerGatewayInp } // Contains the output of CreateCustomerGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateCustomerGatewayResult type CreateCustomerGatewayOutput struct { _ struct{} `type:"structure"` @@ -26699,7 +26608,6 @@ func (s *CreateCustomerGatewayOutput) SetCustomerGateway(v *CustomerGateway) *Cr return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultSubnetRequest type CreateDefaultSubnetInput struct { _ struct{} `type:"structure"` @@ -26750,7 +26658,6 @@ func (s *CreateDefaultSubnetInput) SetDryRun(v bool) *CreateDefaultSubnetInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultSubnetResult type CreateDefaultSubnetOutput struct { _ struct{} `type:"structure"` @@ -26775,7 +26682,6 @@ func (s *CreateDefaultSubnetOutput) SetSubnet(v *Subnet) *CreateDefaultSubnetOut } // Contains the parameters for CreateDefaultVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcRequest type CreateDefaultVpcInput struct { _ struct{} `type:"structure"` @@ -26803,7 +26709,6 @@ func (s *CreateDefaultVpcInput) SetDryRun(v bool) *CreateDefaultVpcInput { } // Contains the output of CreateDefaultVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDefaultVpcResult type CreateDefaultVpcOutput struct { _ struct{} `type:"structure"` @@ -26828,7 +26733,6 @@ func (s *CreateDefaultVpcOutput) SetVpc(v *Vpc) *CreateDefaultVpcOutput { } // Contains the parameters for CreateDhcpOptions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsRequest type CreateDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -26880,7 +26784,6 @@ func (s *CreateDhcpOptionsInput) SetDryRun(v bool) *CreateDhcpOptionsInput { } // Contains the output of CreateDhcpOptions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateDhcpOptionsResult type CreateDhcpOptionsOutput struct { _ struct{} `type:"structure"` @@ -26904,7 +26807,6 @@ func (s *CreateDhcpOptionsOutput) SetDhcpOptions(v *DhcpOptions) *CreateDhcpOpti return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGatewayRequest type CreateEgressOnlyInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -26965,7 +26867,6 @@ func (s *CreateEgressOnlyInternetGatewayInput) SetVpcId(v string) *CreateEgressO return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateEgressOnlyInternetGatewayResult type CreateEgressOnlyInternetGatewayOutput struct { _ struct{} `type:"structure"` @@ -27000,7 +26901,6 @@ func (s *CreateEgressOnlyInternetGatewayOutput) SetEgressOnlyInternetGateway(v * } // Contains the parameters for CreateFlowLogs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogsRequest type CreateFlowLogsInput struct { _ struct{} `type:"structure"` @@ -27109,7 +27009,6 @@ func (s *CreateFlowLogsInput) SetTrafficType(v string) *CreateFlowLogsInput { } // Contains the output of CreateFlowLogs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFlowLogsResult type CreateFlowLogsOutput struct { _ struct{} `type:"structure"` @@ -27152,7 +27051,6 @@ func (s *CreateFlowLogsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *CreateFlo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageRequest type CreateFpgaImageInput struct { _ struct{} `type:"structure"` @@ -27241,7 +27139,6 @@ func (s *CreateFpgaImageInput) SetName(v string) *CreateFpgaImageInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateFpgaImageResult type CreateFpgaImageOutput struct { _ struct{} `type:"structure"` @@ -27275,7 +27172,6 @@ func (s *CreateFpgaImageOutput) SetFpgaImageId(v string) *CreateFpgaImageOutput } // Contains the parameters for CreateImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageRequest type CreateImageInput struct { _ struct{} `type:"structure"` @@ -27375,7 +27271,6 @@ func (s *CreateImageInput) SetNoReboot(v bool) *CreateImageInput { } // Contains the output of CreateImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateImageResult type CreateImageOutput struct { _ struct{} `type:"structure"` @@ -27400,7 +27295,6 @@ func (s *CreateImageOutput) SetImageId(v string) *CreateImageOutput { } // Contains the parameters for CreateInstanceExportTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTaskRequest type CreateInstanceExportTaskInput struct { _ struct{} `type:"structure"` @@ -27468,7 +27362,6 @@ func (s *CreateInstanceExportTaskInput) SetTargetEnvironment(v string) *CreateIn } // Contains the output for CreateInstanceExportTask. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInstanceExportTaskResult type CreateInstanceExportTaskOutput struct { _ struct{} `type:"structure"` @@ -27493,7 +27386,6 @@ func (s *CreateInstanceExportTaskOutput) SetExportTask(v *ExportTask) *CreateIns } // Contains the parameters for CreateInternetGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGatewayRequest type CreateInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -27521,7 +27413,6 @@ func (s *CreateInternetGatewayInput) SetDryRun(v bool) *CreateInternetGatewayInp } // Contains the output of CreateInternetGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateInternetGatewayResult type CreateInternetGatewayOutput struct { _ struct{} `type:"structure"` @@ -27546,7 +27437,6 @@ func (s *CreateInternetGatewayOutput) SetInternetGateway(v *InternetGateway) *Cr } // Contains the parameters for CreateKeyPair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateKeyPairRequest type CreateKeyPairInput struct { _ struct{} `type:"structure"` @@ -27600,7 +27490,6 @@ func (s *CreateKeyPairInput) SetKeyName(v string) *CreateKeyPairInput { } // Describes a key pair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/KeyPair type CreateKeyPairOutput struct { _ struct{} `type:"structure"` @@ -27642,7 +27531,6 @@ func (s *CreateKeyPairOutput) SetKeyName(v string) *CreateKeyPairOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateRequest type CreateLaunchTemplateInput struct { _ struct{} `type:"structure"` @@ -27734,7 +27622,6 @@ func (s *CreateLaunchTemplateInput) SetVersionDescription(v string) *CreateLaunc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateResult type CreateLaunchTemplateOutput struct { _ struct{} `type:"structure"` @@ -27758,7 +27645,6 @@ func (s *CreateLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *Creat return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateVersionRequest type CreateLaunchTemplateVersionInput struct { _ struct{} `type:"structure"` @@ -27867,7 +27753,6 @@ func (s *CreateLaunchTemplateVersionInput) SetVersionDescription(v string) *Crea return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateLaunchTemplateVersionResult type CreateLaunchTemplateVersionOutput struct { _ struct{} `type:"structure"` @@ -27892,7 +27777,6 @@ func (s *CreateLaunchTemplateVersionOutput) SetLaunchTemplateVersion(v *LaunchTe } // Contains the parameters for CreateNatGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGatewayRequest type CreateNatGatewayInput struct { _ struct{} `type:"structure"` @@ -27960,7 +27844,6 @@ func (s *CreateNatGatewayInput) SetSubnetId(v string) *CreateNatGatewayInput { } // Contains the output of CreateNatGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNatGatewayResult type CreateNatGatewayOutput struct { _ struct{} `type:"structure"` @@ -27995,7 +27878,6 @@ func (s *CreateNatGatewayOutput) SetNatGateway(v *NatGateway) *CreateNatGatewayO } // Contains the parameters for CreateNetworkAclEntry. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntryRequest type CreateNetworkAclEntryInput struct { _ struct{} `type:"structure"` @@ -28150,7 +28032,6 @@ func (s *CreateNetworkAclEntryInput) SetRuleNumber(v int64) *CreateNetworkAclEnt return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclEntryOutput type CreateNetworkAclEntryOutput struct { _ struct{} `type:"structure"` } @@ -28166,7 +28047,6 @@ func (s CreateNetworkAclEntryOutput) GoString() string { } // Contains the parameters for CreateNetworkAcl. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclRequest type CreateNetworkAclInput struct { _ struct{} `type:"structure"` @@ -28218,7 +28098,6 @@ func (s *CreateNetworkAclInput) SetVpcId(v string) *CreateNetworkAclInput { } // Contains the output of CreateNetworkAcl. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkAclResult type CreateNetworkAclOutput struct { _ struct{} `type:"structure"` @@ -28243,7 +28122,6 @@ func (s *CreateNetworkAclOutput) SetNetworkAcl(v *NetworkAcl) *CreateNetworkAclO } // Contains the parameters for CreateNetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfaceRequest type CreateNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -28385,7 +28263,6 @@ func (s *CreateNetworkInterfaceInput) SetSubnetId(v string) *CreateNetworkInterf } // Contains the output of CreateNetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfaceResult type CreateNetworkInterfaceOutput struct { _ struct{} `type:"structure"` @@ -28410,7 +28287,6 @@ func (s *CreateNetworkInterfaceOutput) SetNetworkInterface(v *NetworkInterface) } // Contains the parameters for CreateNetworkInterfacePermission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionRequest type CreateNetworkInterfacePermissionInput struct { _ struct{} `type:"structure"` @@ -28494,7 +28370,6 @@ func (s *CreateNetworkInterfacePermissionInput) SetPermission(v string) *CreateN } // Contains the output of CreateNetworkInterfacePermission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionResult type CreateNetworkInterfacePermissionOutput struct { _ struct{} `type:"structure"` @@ -28519,7 +28394,6 @@ func (s *CreateNetworkInterfacePermissionOutput) SetInterfacePermission(v *Netwo } // Contains the parameters for CreatePlacementGroup. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupRequest type CreatePlacementGroupInput struct { _ struct{} `type:"structure"` @@ -28587,7 +28461,6 @@ func (s *CreatePlacementGroupInput) SetStrategy(v string) *CreatePlacementGroupI return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreatePlacementGroupOutput type CreatePlacementGroupOutput struct { _ struct{} `type:"structure"` } @@ -28603,7 +28476,6 @@ func (s CreatePlacementGroupOutput) GoString() string { } // Contains the parameters for CreateReservedInstancesListing. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListingRequest type CreateReservedInstancesListingInput struct { _ struct{} `type:"structure"` @@ -28691,7 +28563,6 @@ func (s *CreateReservedInstancesListingInput) SetReservedInstancesId(v string) * } // Contains the output of CreateReservedInstancesListing. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateReservedInstancesListingResult type CreateReservedInstancesListingOutput struct { _ struct{} `type:"structure"` @@ -28716,7 +28587,6 @@ func (s *CreateReservedInstancesListingOutput) SetReservedInstancesListings(v [] } // Contains the parameters for CreateRoute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteRequest type CreateRouteInput struct { _ struct{} `type:"structure"` @@ -28844,7 +28714,6 @@ func (s *CreateRouteInput) SetVpcPeeringConnectionId(v string) *CreateRouteInput } // Contains the output of CreateRoute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteResult type CreateRouteOutput struct { _ struct{} `type:"structure"` @@ -28869,7 +28738,6 @@ func (s *CreateRouteOutput) SetReturn(v bool) *CreateRouteOutput { } // Contains the parameters for CreateRouteTable. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTableRequest type CreateRouteTableInput struct { _ struct{} `type:"structure"` @@ -28921,7 +28789,6 @@ func (s *CreateRouteTableInput) SetVpcId(v string) *CreateRouteTableInput { } // Contains the output of CreateRouteTable. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateRouteTableResult type CreateRouteTableOutput struct { _ struct{} `type:"structure"` @@ -28946,7 +28813,6 @@ func (s *CreateRouteTableOutput) SetRouteTable(v *RouteTable) *CreateRouteTableO } // Contains the parameters for CreateSecurityGroup. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroupRequest type CreateSecurityGroupInput struct { _ struct{} `type:"structure"` @@ -29033,7 +28899,6 @@ func (s *CreateSecurityGroupInput) SetVpcId(v string) *CreateSecurityGroupInput } // Contains the output of CreateSecurityGroup. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSecurityGroupResult type CreateSecurityGroupOutput struct { _ struct{} `type:"structure"` @@ -29058,7 +28923,6 @@ func (s *CreateSecurityGroupOutput) SetGroupId(v string) *CreateSecurityGroupOut } // Contains the parameters for CreateSnapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSnapshotRequest type CreateSnapshotInput struct { _ struct{} `type:"structure"` @@ -29119,7 +28983,6 @@ func (s *CreateSnapshotInput) SetVolumeId(v string) *CreateSnapshotInput { } // Contains the parameters for CreateSpotDatafeedSubscription. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscriptionRequest type CreateSpotDatafeedSubscriptionInput struct { _ struct{} `type:"structure"` @@ -29180,7 +29043,6 @@ func (s *CreateSpotDatafeedSubscriptionInput) SetPrefix(v string) *CreateSpotDat } // Contains the output of CreateSpotDatafeedSubscription. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSpotDatafeedSubscriptionResult type CreateSpotDatafeedSubscriptionOutput struct { _ struct{} `type:"structure"` @@ -29205,7 +29067,6 @@ func (s *CreateSpotDatafeedSubscriptionOutput) SetSpotDatafeedSubscription(v *Sp } // Contains the parameters for CreateSubnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnetRequest type CreateSubnetInput struct { _ struct{} `type:"structure"` @@ -29293,7 +29154,6 @@ func (s *CreateSubnetInput) SetVpcId(v string) *CreateSubnetInput { } // Contains the output of CreateSubnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateSubnetResult type CreateSubnetOutput struct { _ struct{} `type:"structure"` @@ -29318,7 +29178,6 @@ func (s *CreateSubnetOutput) SetSubnet(v *Subnet) *CreateSubnetOutput { } // Contains the parameters for CreateTags. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTagsRequest type CreateTagsInput struct { _ struct{} `type:"structure"` @@ -29385,7 +29244,6 @@ func (s *CreateTagsInput) SetTags(v []*Tag) *CreateTagsInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateTagsOutput type CreateTagsOutput struct { _ struct{} `type:"structure"` } @@ -29401,7 +29259,6 @@ func (s CreateTagsOutput) GoString() string { } // Contains the parameters for CreateVolume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumeRequest type CreateVolumeInput struct { _ struct{} `type:"structure"` @@ -29545,7 +29402,6 @@ func (s *CreateVolumeInput) SetVolumeType(v string) *CreateVolumeInput { // Describes the user or group to be added or removed from the permissions for // a volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumePermission type CreateVolumePermission struct { _ struct{} `type:"structure"` @@ -29581,7 +29437,6 @@ func (s *CreateVolumePermission) SetUserId(v string) *CreateVolumePermission { } // Describes modifications to the permissions for a volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVolumePermissionModifications type CreateVolumePermissionModifications struct { _ struct{} `type:"structure"` @@ -29616,7 +29471,6 @@ func (s *CreateVolumePermissionModifications) SetRemove(v []*CreateVolumePermiss return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointConnectionNotificationRequest type CreateVpcEndpointConnectionNotificationInput struct { _ struct{} `type:"structure"` @@ -29710,7 +29564,6 @@ func (s *CreateVpcEndpointConnectionNotificationInput) SetVpcEndpointId(v string return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointConnectionNotificationResult type CreateVpcEndpointConnectionNotificationOutput struct { _ struct{} `type:"structure"` @@ -29745,7 +29598,6 @@ func (s *CreateVpcEndpointConnectionNotificationOutput) SetConnectionNotificatio } // Contains the parameters for CreateVpcEndpoint. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointRequest type CreateVpcEndpointInput struct { _ struct{} `type:"structure"` @@ -29895,7 +29747,6 @@ func (s *CreateVpcEndpointInput) SetVpcId(v string) *CreateVpcEndpointInput { } // Contains the output of CreateVpcEndpoint. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointResult type CreateVpcEndpointOutput struct { _ struct{} `type:"structure"` @@ -29929,7 +29780,6 @@ func (s *CreateVpcEndpointOutput) SetVpcEndpoint(v *VpcEndpoint) *CreateVpcEndpo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointServiceConfigurationRequest type CreateVpcEndpointServiceConfigurationInput struct { _ struct{} `type:"structure"` @@ -30001,7 +29851,6 @@ func (s *CreateVpcEndpointServiceConfigurationInput) SetNetworkLoadBalancerArns( return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcEndpointServiceConfigurationResult type CreateVpcEndpointServiceConfigurationOutput struct { _ struct{} `type:"structure"` @@ -30036,7 +29885,6 @@ func (s *CreateVpcEndpointServiceConfigurationOutput) SetServiceConfiguration(v } // Contains the parameters for CreateVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcRequest type CreateVpcInput struct { _ struct{} `type:"structure"` @@ -30117,7 +29965,6 @@ func (s *CreateVpcInput) SetInstanceTenancy(v string) *CreateVpcInput { } // Contains the output of CreateVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcResult type CreateVpcOutput struct { _ struct{} `type:"structure"` @@ -30142,7 +29989,6 @@ func (s *CreateVpcOutput) SetVpc(v *Vpc) *CreateVpcOutput { } // Contains the parameters for CreateVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnectionRequest type CreateVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -30212,7 +30058,6 @@ func (s *CreateVpcPeeringConnectionInput) SetVpcId(v string) *CreateVpcPeeringCo } // Contains the output of CreateVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpcPeeringConnectionResult type CreateVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -30237,7 +30082,6 @@ func (s *CreateVpcPeeringConnectionOutput) SetVpcPeeringConnection(v *VpcPeering } // Contains the parameters for CreateVpnConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRequest type CreateVpnConnectionInput struct { _ struct{} `type:"structure"` @@ -30326,7 +30170,6 @@ func (s *CreateVpnConnectionInput) SetVpnGatewayId(v string) *CreateVpnConnectio } // Contains the output of CreateVpnConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionResult type CreateVpnConnectionOutput struct { _ struct{} `type:"structure"` @@ -30351,7 +30194,6 @@ func (s *CreateVpnConnectionOutput) SetVpnConnection(v *VpnConnection) *CreateVp } // Contains the parameters for CreateVpnConnectionRoute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRouteRequest type CreateVpnConnectionRouteInput struct { _ struct{} `type:"structure"` @@ -30404,7 +30246,6 @@ func (s *CreateVpnConnectionRouteInput) SetVpnConnectionId(v string) *CreateVpnC return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnConnectionRouteOutput type CreateVpnConnectionRouteOutput struct { _ struct{} `type:"structure"` } @@ -30420,7 +30261,6 @@ func (s CreateVpnConnectionRouteOutput) GoString() string { } // Contains the parameters for CreateVpnGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGatewayRequest type CreateVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -30494,7 +30334,6 @@ func (s *CreateVpnGatewayInput) SetType(v string) *CreateVpnGatewayInput { } // Contains the output of CreateVpnGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateVpnGatewayResult type CreateVpnGatewayOutput struct { _ struct{} `type:"structure"` @@ -30519,7 +30358,6 @@ func (s *CreateVpnGatewayOutput) SetVpnGateway(v *VpnGateway) *CreateVpnGatewayO } // Describes the credit option for CPU usage of a T2 instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreditSpecification type CreditSpecification struct { _ struct{} `type:"structure"` @@ -30544,7 +30382,6 @@ func (s *CreditSpecification) SetCpuCredits(v string) *CreditSpecification { } // The credit option for CPU usage of a T2 instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreditSpecificationRequest type CreditSpecificationRequest struct { _ struct{} `type:"structure"` @@ -30585,7 +30422,6 @@ func (s *CreditSpecificationRequest) SetCpuCredits(v string) *CreditSpecificatio } // Describes a customer gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CustomerGateway type CustomerGateway struct { _ struct{} `type:"structure"` @@ -30657,7 +30493,6 @@ func (s *CustomerGateway) SetType(v string) *CustomerGateway { } // Contains the parameters for DeleteCustomerGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGatewayRequest type DeleteCustomerGatewayInput struct { _ struct{} `type:"structure"` @@ -30708,7 +30543,6 @@ func (s *DeleteCustomerGatewayInput) SetDryRun(v bool) *DeleteCustomerGatewayInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteCustomerGatewayOutput type DeleteCustomerGatewayOutput struct { _ struct{} `type:"structure"` } @@ -30724,7 +30558,6 @@ func (s DeleteCustomerGatewayOutput) GoString() string { } // Contains the parameters for DeleteDhcpOptions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptionsRequest type DeleteDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -30775,7 +30608,6 @@ func (s *DeleteDhcpOptionsInput) SetDryRun(v bool) *DeleteDhcpOptionsInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteDhcpOptionsOutput type DeleteDhcpOptionsOutput struct { _ struct{} `type:"structure"` } @@ -30790,7 +30622,6 @@ func (s DeleteDhcpOptionsOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGatewayRequest type DeleteEgressOnlyInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -30841,7 +30672,6 @@ func (s *DeleteEgressOnlyInternetGatewayInput) SetEgressOnlyInternetGatewayId(v return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteEgressOnlyInternetGatewayResult type DeleteEgressOnlyInternetGatewayOutput struct { _ struct{} `type:"structure"` @@ -30866,7 +30696,6 @@ func (s *DeleteEgressOnlyInternetGatewayOutput) SetReturnCode(v bool) *DeleteEgr } // Contains the parameters for DeleteFlowLogs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogsRequest type DeleteFlowLogsInput struct { _ struct{} `type:"structure"` @@ -30906,7 +30735,6 @@ func (s *DeleteFlowLogsInput) SetFlowLogIds(v []*string) *DeleteFlowLogsInput { } // Contains the output of DeleteFlowLogs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFlowLogsResult type DeleteFlowLogsOutput struct { _ struct{} `type:"structure"` @@ -30930,7 +30758,6 @@ func (s *DeleteFlowLogsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *DeleteFlo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFpgaImageRequest type DeleteFpgaImageInput struct { _ struct{} `type:"structure"` @@ -30981,7 +30808,6 @@ func (s *DeleteFpgaImageInput) SetFpgaImageId(v string) *DeleteFpgaImageInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteFpgaImageResult type DeleteFpgaImageOutput struct { _ struct{} `type:"structure"` @@ -31006,7 +30832,6 @@ func (s *DeleteFpgaImageOutput) SetReturn(v bool) *DeleteFpgaImageOutput { } // Contains the parameters for DeleteInternetGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGatewayRequest type DeleteInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -31057,7 +30882,6 @@ func (s *DeleteInternetGatewayInput) SetInternetGatewayId(v string) *DeleteInter return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteInternetGatewayOutput type DeleteInternetGatewayOutput struct { _ struct{} `type:"structure"` } @@ -31073,7 +30897,6 @@ func (s DeleteInternetGatewayOutput) GoString() string { } // Contains the parameters for DeleteKeyPair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPairRequest type DeleteKeyPairInput struct { _ struct{} `type:"structure"` @@ -31124,7 +30947,6 @@ func (s *DeleteKeyPairInput) SetKeyName(v string) *DeleteKeyPairInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteKeyPairOutput type DeleteKeyPairOutput struct { _ struct{} `type:"structure"` } @@ -31139,7 +30961,6 @@ func (s DeleteKeyPairOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateRequest type DeleteLaunchTemplateInput struct { _ struct{} `type:"structure"` @@ -31199,7 +31020,6 @@ func (s *DeleteLaunchTemplateInput) SetLaunchTemplateName(v string) *DeleteLaunc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateResult type DeleteLaunchTemplateOutput struct { _ struct{} `type:"structure"` @@ -31223,7 +31043,6 @@ func (s *DeleteLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *Delet return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsRequest type DeleteLaunchTemplateVersionsInput struct { _ struct{} `type:"structure"` @@ -31297,7 +31116,6 @@ func (s *DeleteLaunchTemplateVersionsInput) SetVersions(v []*string) *DeleteLaun return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsResult type DeleteLaunchTemplateVersionsOutput struct { _ struct{} `type:"structure"` @@ -31331,7 +31149,6 @@ func (s *DeleteLaunchTemplateVersionsOutput) SetUnsuccessfullyDeletedLaunchTempl } // Describes a launch template version that could not be deleted. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsResponseErrorItem type DeleteLaunchTemplateVersionsResponseErrorItem struct { _ struct{} `type:"structure"` @@ -31383,7 +31200,6 @@ func (s *DeleteLaunchTemplateVersionsResponseErrorItem) SetVersionNumber(v int64 } // Describes a launch template version that was successfully deleted. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteLaunchTemplateVersionsResponseSuccessItem type DeleteLaunchTemplateVersionsResponseSuccessItem struct { _ struct{} `type:"structure"` @@ -31426,7 +31242,6 @@ func (s *DeleteLaunchTemplateVersionsResponseSuccessItem) SetVersionNumber(v int } // Contains the parameters for DeleteNatGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGatewayRequest type DeleteNatGatewayInput struct { _ struct{} `type:"structure"` @@ -31466,7 +31281,6 @@ func (s *DeleteNatGatewayInput) SetNatGatewayId(v string) *DeleteNatGatewayInput } // Contains the output of DeleteNatGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNatGatewayResult type DeleteNatGatewayOutput struct { _ struct{} `type:"structure"` @@ -31491,7 +31305,6 @@ func (s *DeleteNatGatewayOutput) SetNatGatewayId(v string) *DeleteNatGatewayOutp } // Contains the parameters for DeleteNetworkAclEntry. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntryRequest type DeleteNetworkAclEntryInput struct { _ struct{} `type:"structure"` @@ -31570,7 +31383,6 @@ func (s *DeleteNetworkAclEntryInput) SetRuleNumber(v int64) *DeleteNetworkAclEnt return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclEntryOutput type DeleteNetworkAclEntryOutput struct { _ struct{} `type:"structure"` } @@ -31586,7 +31398,6 @@ func (s DeleteNetworkAclEntryOutput) GoString() string { } // Contains the parameters for DeleteNetworkAcl. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclRequest type DeleteNetworkAclInput struct { _ struct{} `type:"structure"` @@ -31637,7 +31448,6 @@ func (s *DeleteNetworkAclInput) SetNetworkAclId(v string) *DeleteNetworkAclInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkAclOutput type DeleteNetworkAclOutput struct { _ struct{} `type:"structure"` } @@ -31653,7 +31463,6 @@ func (s DeleteNetworkAclOutput) GoString() string { } // Contains the parameters for DeleteNetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfaceRequest type DeleteNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -31704,7 +31513,6 @@ func (s *DeleteNetworkInterfaceInput) SetNetworkInterfaceId(v string) *DeleteNet return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfaceOutput type DeleteNetworkInterfaceOutput struct { _ struct{} `type:"structure"` } @@ -31720,7 +31528,6 @@ func (s DeleteNetworkInterfaceOutput) GoString() string { } // Contains the parameters for DeleteNetworkInterfacePermission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionRequest type DeleteNetworkInterfacePermissionInput struct { _ struct{} `type:"structure"` @@ -31782,7 +31589,6 @@ func (s *DeleteNetworkInterfacePermissionInput) SetNetworkInterfacePermissionId( } // Contains the output for DeleteNetworkInterfacePermission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionResult type DeleteNetworkInterfacePermissionOutput struct { _ struct{} `type:"structure"` @@ -31807,7 +31613,6 @@ func (s *DeleteNetworkInterfacePermissionOutput) SetReturn(v bool) *DeleteNetwor } // Contains the parameters for DeletePlacementGroup. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupRequest type DeletePlacementGroupInput struct { _ struct{} `type:"structure"` @@ -31858,7 +31663,6 @@ func (s *DeletePlacementGroupInput) SetGroupName(v string) *DeletePlacementGroup return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeletePlacementGroupOutput type DeletePlacementGroupOutput struct { _ struct{} `type:"structure"` } @@ -31874,7 +31678,6 @@ func (s DeletePlacementGroupOutput) GoString() string { } // Contains the parameters for DeleteRoute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteRequest type DeleteRouteInput struct { _ struct{} `type:"structure"` @@ -31945,7 +31748,6 @@ func (s *DeleteRouteInput) SetRouteTableId(v string) *DeleteRouteInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteOutput type DeleteRouteOutput struct { _ struct{} `type:"structure"` } @@ -31961,7 +31763,6 @@ func (s DeleteRouteOutput) GoString() string { } // Contains the parameters for DeleteRouteTable. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTableRequest type DeleteRouteTableInput struct { _ struct{} `type:"structure"` @@ -32012,7 +31813,6 @@ func (s *DeleteRouteTableInput) SetRouteTableId(v string) *DeleteRouteTableInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteRouteTableOutput type DeleteRouteTableOutput struct { _ struct{} `type:"structure"` } @@ -32028,7 +31828,6 @@ func (s DeleteRouteTableOutput) GoString() string { } // Contains the parameters for DeleteSecurityGroup. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroupRequest type DeleteSecurityGroupInput struct { _ struct{} `type:"structure"` @@ -32074,7 +31873,6 @@ func (s *DeleteSecurityGroupInput) SetGroupName(v string) *DeleteSecurityGroupIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSecurityGroupOutput type DeleteSecurityGroupOutput struct { _ struct{} `type:"structure"` } @@ -32090,7 +31888,6 @@ func (s DeleteSecurityGroupOutput) GoString() string { } // Contains the parameters for DeleteSnapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshotRequest type DeleteSnapshotInput struct { _ struct{} `type:"structure"` @@ -32141,7 +31938,6 @@ func (s *DeleteSnapshotInput) SetSnapshotId(v string) *DeleteSnapshotInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSnapshotOutput type DeleteSnapshotOutput struct { _ struct{} `type:"structure"` } @@ -32157,7 +31953,6 @@ func (s DeleteSnapshotOutput) GoString() string { } // Contains the parameters for DeleteSpotDatafeedSubscription. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscriptionRequest type DeleteSpotDatafeedSubscriptionInput struct { _ struct{} `type:"structure"` @@ -32184,7 +31979,6 @@ func (s *DeleteSpotDatafeedSubscriptionInput) SetDryRun(v bool) *DeleteSpotDataf return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSpotDatafeedSubscriptionOutput type DeleteSpotDatafeedSubscriptionOutput struct { _ struct{} `type:"structure"` } @@ -32200,7 +31994,6 @@ func (s DeleteSpotDatafeedSubscriptionOutput) GoString() string { } // Contains the parameters for DeleteSubnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnetRequest type DeleteSubnetInput struct { _ struct{} `type:"structure"` @@ -32251,7 +32044,6 @@ func (s *DeleteSubnetInput) SetSubnetId(v string) *DeleteSubnetInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteSubnetOutput type DeleteSubnetOutput struct { _ struct{} `type:"structure"` } @@ -32267,7 +32059,6 @@ func (s DeleteSubnetOutput) GoString() string { } // Contains the parameters for DeleteTags. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTagsRequest type DeleteTagsInput struct { _ struct{} `type:"structure"` @@ -32332,7 +32123,6 @@ func (s *DeleteTagsInput) SetTags(v []*Tag) *DeleteTagsInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteTagsOutput type DeleteTagsOutput struct { _ struct{} `type:"structure"` } @@ -32348,7 +32138,6 @@ func (s DeleteTagsOutput) GoString() string { } // Contains the parameters for DeleteVolume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolumeRequest type DeleteVolumeInput struct { _ struct{} `type:"structure"` @@ -32399,7 +32188,6 @@ func (s *DeleteVolumeInput) SetVolumeId(v string) *DeleteVolumeInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVolumeOutput type DeleteVolumeOutput struct { _ struct{} `type:"structure"` } @@ -32414,7 +32202,6 @@ func (s DeleteVolumeOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointConnectionNotificationsRequest type DeleteVpcEndpointConnectionNotificationsInput struct { _ struct{} `type:"structure"` @@ -32465,7 +32252,6 @@ func (s *DeleteVpcEndpointConnectionNotificationsInput) SetDryRun(v bool) *Delet return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointConnectionNotificationsResult type DeleteVpcEndpointConnectionNotificationsOutput struct { _ struct{} `type:"structure"` @@ -32489,7 +32275,6 @@ func (s *DeleteVpcEndpointConnectionNotificationsOutput) SetUnsuccessful(v []*Un return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointServiceConfigurationsRequest type DeleteVpcEndpointServiceConfigurationsInput struct { _ struct{} `type:"structure"` @@ -32540,7 +32325,6 @@ func (s *DeleteVpcEndpointServiceConfigurationsInput) SetServiceIds(v []*string) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointServiceConfigurationsResult type DeleteVpcEndpointServiceConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -32565,7 +32349,6 @@ func (s *DeleteVpcEndpointServiceConfigurationsOutput) SetUnsuccessful(v []*Unsu } // Contains the parameters for DeleteVpcEndpoints. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointsRequest type DeleteVpcEndpointsInput struct { _ struct{} `type:"structure"` @@ -32617,7 +32400,6 @@ func (s *DeleteVpcEndpointsInput) SetVpcEndpointIds(v []*string) *DeleteVpcEndpo } // Contains the output of DeleteVpcEndpoints. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcEndpointsResult type DeleteVpcEndpointsOutput struct { _ struct{} `type:"structure"` @@ -32642,7 +32424,6 @@ func (s *DeleteVpcEndpointsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *Delet } // Contains the parameters for DeleteVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcRequest type DeleteVpcInput struct { _ struct{} `type:"structure"` @@ -32693,7 +32474,6 @@ func (s *DeleteVpcInput) SetVpcId(v string) *DeleteVpcInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcOutput type DeleteVpcOutput struct { _ struct{} `type:"structure"` } @@ -32709,7 +32489,6 @@ func (s DeleteVpcOutput) GoString() string { } // Contains the parameters for DeleteVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnectionRequest type DeleteVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -32761,7 +32540,6 @@ func (s *DeleteVpcPeeringConnectionInput) SetVpcPeeringConnectionId(v string) *D } // Contains the output of DeleteVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpcPeeringConnectionResult type DeleteVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -32786,7 +32564,6 @@ func (s *DeleteVpcPeeringConnectionOutput) SetReturn(v bool) *DeleteVpcPeeringCo } // Contains the parameters for DeleteVpnConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRequest type DeleteVpnConnectionInput struct { _ struct{} `type:"structure"` @@ -32837,7 +32614,6 @@ func (s *DeleteVpnConnectionInput) SetVpnConnectionId(v string) *DeleteVpnConnec return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionOutput type DeleteVpnConnectionOutput struct { _ struct{} `type:"structure"` } @@ -32853,7 +32629,6 @@ func (s DeleteVpnConnectionOutput) GoString() string { } // Contains the parameters for DeleteVpnConnectionRoute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRouteRequest type DeleteVpnConnectionRouteInput struct { _ struct{} `type:"structure"` @@ -32906,7 +32681,6 @@ func (s *DeleteVpnConnectionRouteInput) SetVpnConnectionId(v string) *DeleteVpnC return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnConnectionRouteOutput type DeleteVpnConnectionRouteOutput struct { _ struct{} `type:"structure"` } @@ -32922,7 +32696,6 @@ func (s DeleteVpnConnectionRouteOutput) GoString() string { } // Contains the parameters for DeleteVpnGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGatewayRequest type DeleteVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -32973,7 +32746,6 @@ func (s *DeleteVpnGatewayInput) SetVpnGatewayId(v string) *DeleteVpnGatewayInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteVpnGatewayOutput type DeleteVpnGatewayOutput struct { _ struct{} `type:"structure"` } @@ -32989,7 +32761,6 @@ func (s DeleteVpnGatewayOutput) GoString() string { } // Contains the parameters for DeregisterImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImageRequest type DeregisterImageInput struct { _ struct{} `type:"structure"` @@ -33040,7 +32811,6 @@ func (s *DeregisterImageInput) SetImageId(v string) *DeregisterImageInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeregisterImageOutput type DeregisterImageOutput struct { _ struct{} `type:"structure"` } @@ -33056,7 +32826,6 @@ func (s DeregisterImageOutput) GoString() string { } // Contains the parameters for DescribeAccountAttributes. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributesRequest type DescribeAccountAttributesInput struct { _ struct{} `type:"structure"` @@ -33093,7 +32862,6 @@ func (s *DescribeAccountAttributesInput) SetDryRun(v bool) *DescribeAccountAttri } // Contains the output of DescribeAccountAttributes. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAccountAttributesResult type DescribeAccountAttributesOutput struct { _ struct{} `type:"structure"` @@ -33118,7 +32886,6 @@ func (s *DescribeAccountAttributesOutput) SetAccountAttributes(v []*AccountAttri } // Contains the parameters for DescribeAddresses. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddressesRequest type DescribeAddressesInput struct { _ struct{} `type:"structure"` @@ -33209,7 +32976,6 @@ func (s *DescribeAddressesInput) SetPublicIps(v []*string) *DescribeAddressesInp } // Contains the output of DescribeAddresses. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAddressesResult type DescribeAddressesOutput struct { _ struct{} `type:"structure"` @@ -33234,7 +33000,6 @@ func (s *DescribeAddressesOutput) SetAddresses(v []*Address) *DescribeAddressesO } // Contains the parameters for DescribeAvailabilityZones. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZonesRequest type DescribeAvailabilityZonesInput struct { _ struct{} `type:"structure"` @@ -33290,7 +33055,6 @@ func (s *DescribeAvailabilityZonesInput) SetZoneNames(v []*string) *DescribeAvai } // Contains the output of DescribeAvailabiltyZones. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeAvailabilityZonesResult type DescribeAvailabilityZonesOutput struct { _ struct{} `type:"structure"` @@ -33315,7 +33079,6 @@ func (s *DescribeAvailabilityZonesOutput) SetAvailabilityZones(v []*Availability } // Contains the parameters for DescribeBundleTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasksRequest type DescribeBundleTasksInput struct { _ struct{} `type:"structure"` @@ -33385,7 +33148,6 @@ func (s *DescribeBundleTasksInput) SetFilters(v []*Filter) *DescribeBundleTasksI } // Contains the output of DescribeBundleTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeBundleTasksResult type DescribeBundleTasksOutput struct { _ struct{} `type:"structure"` @@ -33410,7 +33172,6 @@ func (s *DescribeBundleTasksOutput) SetBundleTasks(v []*BundleTask) *DescribeBun } // Contains the parameters for DescribeClassicLinkInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstancesRequest type DescribeClassicLinkInstancesInput struct { _ struct{} `type:"structure"` @@ -33501,7 +33262,6 @@ func (s *DescribeClassicLinkInstancesInput) SetNextToken(v string) *DescribeClas } // Contains the output of DescribeClassicLinkInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeClassicLinkInstancesResult type DescribeClassicLinkInstancesOutput struct { _ struct{} `type:"structure"` @@ -33536,7 +33296,6 @@ func (s *DescribeClassicLinkInstancesOutput) SetNextToken(v string) *DescribeCla } // Contains the parameters for DescribeConversionTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasksRequest type DescribeConversionTasksInput struct { _ struct{} `type:"structure"` @@ -33573,7 +33332,6 @@ func (s *DescribeConversionTasksInput) SetDryRun(v bool) *DescribeConversionTask } // Contains the output for DescribeConversionTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeConversionTasksResult type DescribeConversionTasksOutput struct { _ struct{} `type:"structure"` @@ -33598,7 +33356,6 @@ func (s *DescribeConversionTasksOutput) SetConversionTasks(v []*ConversionTask) } // Contains the parameters for DescribeCustomerGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGatewaysRequest type DescribeCustomerGatewaysInput struct { _ struct{} `type:"structure"` @@ -33676,7 +33433,6 @@ func (s *DescribeCustomerGatewaysInput) SetFilters(v []*Filter) *DescribeCustome } // Contains the output of DescribeCustomerGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeCustomerGatewaysResult type DescribeCustomerGatewaysOutput struct { _ struct{} `type:"structure"` @@ -33701,7 +33457,6 @@ func (s *DescribeCustomerGatewaysOutput) SetCustomerGateways(v []*CustomerGatewa } // Contains the parameters for DescribeDhcpOptions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptionsRequest type DescribeDhcpOptionsInput struct { _ struct{} `type:"structure"` @@ -33771,7 +33526,6 @@ func (s *DescribeDhcpOptionsInput) SetFilters(v []*Filter) *DescribeDhcpOptionsI } // Contains the output of DescribeDhcpOptions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeDhcpOptionsResult type DescribeDhcpOptionsOutput struct { _ struct{} `type:"structure"` @@ -33795,7 +33549,6 @@ func (s *DescribeDhcpOptionsOutput) SetDhcpOptions(v []*DhcpOptions) *DescribeDh return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGatewaysRequest type DescribeEgressOnlyInternetGatewaysInput struct { _ struct{} `type:"structure"` @@ -33852,7 +33605,6 @@ func (s *DescribeEgressOnlyInternetGatewaysInput) SetNextToken(v string) *Descri return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeEgressOnlyInternetGatewaysResult type DescribeEgressOnlyInternetGatewaysOutput struct { _ struct{} `type:"structure"` @@ -33885,7 +33637,6 @@ func (s *DescribeEgressOnlyInternetGatewaysOutput) SetNextToken(v string) *Descr return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusRequest type DescribeElasticGpusInput struct { _ struct{} `type:"structure"` @@ -33960,7 +33711,6 @@ func (s *DescribeElasticGpusInput) SetNextToken(v string) *DescribeElasticGpusIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeElasticGpusResult type DescribeElasticGpusOutput struct { _ struct{} `type:"structure"` @@ -34006,7 +33756,6 @@ func (s *DescribeElasticGpusOutput) SetNextToken(v string) *DescribeElasticGpusO } // Contains the parameters for DescribeExportTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksRequest type DescribeExportTasksInput struct { _ struct{} `type:"structure"` @@ -34031,7 +33780,6 @@ func (s *DescribeExportTasksInput) SetExportTaskIds(v []*string) *DescribeExport } // Contains the output for DescribeExportTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeExportTasksResult type DescribeExportTasksOutput struct { _ struct{} `type:"structure"` @@ -34056,7 +33804,6 @@ func (s *DescribeExportTasksOutput) SetExportTasks(v []*ExportTask) *DescribeExp } // Contains the parameters for DescribeFlowLogs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogsRequest type DescribeFlowLogsInput struct { _ struct{} `type:"structure"` @@ -34122,7 +33869,6 @@ func (s *DescribeFlowLogsInput) SetNextToken(v string) *DescribeFlowLogsInput { } // Contains the output of DescribeFlowLogs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFlowLogsResult type DescribeFlowLogsOutput struct { _ struct{} `type:"structure"` @@ -34156,7 +33902,6 @@ func (s *DescribeFlowLogsOutput) SetNextToken(v string) *DescribeFlowLogsOutput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImageAttributeRequest type DescribeFpgaImageAttributeInput struct { _ struct{} `type:"structure"` @@ -34221,7 +33966,6 @@ func (s *DescribeFpgaImageAttributeInput) SetFpgaImageId(v string) *DescribeFpga return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImageAttributeResult type DescribeFpgaImageAttributeOutput struct { _ struct{} `type:"structure"` @@ -34245,7 +33989,6 @@ func (s *DescribeFpgaImageAttributeOutput) SetFpgaImageAttribute(v *FpgaImageAtt return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesRequest type DescribeFpgaImagesInput struct { _ struct{} `type:"structure"` @@ -34369,7 +34112,6 @@ func (s *DescribeFpgaImagesInput) SetOwners(v []*string) *DescribeFpgaImagesInpu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeFpgaImagesResult type DescribeFpgaImagesOutput struct { _ struct{} `type:"structure"` @@ -34403,7 +34145,6 @@ func (s *DescribeFpgaImagesOutput) SetNextToken(v string) *DescribeFpgaImagesOut return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsRequest type DescribeHostReservationOfferingsInput struct { _ struct{} `type:"structure"` @@ -34487,7 +34228,6 @@ func (s *DescribeHostReservationOfferingsInput) SetOfferingId(v string) *Describ return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationOfferingsResult type DescribeHostReservationOfferingsOutput struct { _ struct{} `type:"structure"` @@ -34521,7 +34261,6 @@ func (s *DescribeHostReservationOfferingsOutput) SetOfferingSet(v []*HostOfferin return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationsRequest type DescribeHostReservationsInput struct { _ struct{} `type:"structure"` @@ -34582,7 +34321,6 @@ func (s *DescribeHostReservationsInput) SetNextToken(v string) *DescribeHostRese return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostReservationsResult type DescribeHostReservationsOutput struct { _ struct{} `type:"structure"` @@ -34617,7 +34355,6 @@ func (s *DescribeHostReservationsOutput) SetNextToken(v string) *DescribeHostRes } // Contains the parameters for DescribeHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostsRequest type DescribeHostsInput struct { _ struct{} `type:"structure"` @@ -34689,7 +34426,6 @@ func (s *DescribeHostsInput) SetNextToken(v string) *DescribeHostsInput { } // Contains the output of DescribeHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeHostsResult type DescribeHostsOutput struct { _ struct{} `type:"structure"` @@ -34723,7 +34459,6 @@ func (s *DescribeHostsOutput) SetNextToken(v string) *DescribeHostsOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociationsRequest type DescribeIamInstanceProfileAssociationsInput struct { _ struct{} `type:"structure"` @@ -34796,7 +34531,6 @@ func (s *DescribeIamInstanceProfileAssociationsInput) SetNextToken(v string) *De return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIamInstanceProfileAssociationsResult type DescribeIamInstanceProfileAssociationsOutput struct { _ struct{} `type:"structure"` @@ -34831,7 +34565,6 @@ func (s *DescribeIamInstanceProfileAssociationsOutput) SetNextToken(v string) *D } // Contains the parameters for DescribeIdFormat. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormatRequest type DescribeIdFormatInput struct { _ struct{} `type:"structure"` @@ -34856,7 +34589,6 @@ func (s *DescribeIdFormatInput) SetResource(v string) *DescribeIdFormatInput { } // Contains the output of DescribeIdFormat. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdFormatResult type DescribeIdFormatOutput struct { _ struct{} `type:"structure"` @@ -34881,7 +34613,6 @@ func (s *DescribeIdFormatOutput) SetStatuses(v []*IdFormat) *DescribeIdFormatOut } // Contains the parameters for DescribeIdentityIdFormat. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormatRequest type DescribeIdentityIdFormatInput struct { _ struct{} `type:"structure"` @@ -34931,7 +34662,6 @@ func (s *DescribeIdentityIdFormatInput) SetResource(v string) *DescribeIdentityI } // Contains the output of DescribeIdentityIdFormat. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeIdentityIdFormatResult type DescribeIdentityIdFormatOutput struct { _ struct{} `type:"structure"` @@ -34956,7 +34686,6 @@ func (s *DescribeIdentityIdFormatOutput) SetStatuses(v []*IdFormat) *DescribeIde } // Contains the parameters for DescribeImageAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImageAttributeRequest type DescribeImageAttributeInput struct { _ struct{} `type:"structure"` @@ -35026,7 +34755,6 @@ func (s *DescribeImageAttributeInput) SetImageId(v string) *DescribeImageAttribu } // Describes an image attribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImageAttribute type DescribeImageAttributeOutput struct { _ struct{} `type:"structure"` @@ -35115,7 +34843,6 @@ func (s *DescribeImageAttributeOutput) SetSriovNetSupport(v *AttributeValue) *De } // Contains the parameters for DescribeImages. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImagesRequest type DescribeImagesInput struct { _ struct{} `type:"structure"` @@ -35267,7 +34994,6 @@ func (s *DescribeImagesInput) SetOwners(v []*string) *DescribeImagesInput { } // Contains the output of DescribeImages. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImagesResult type DescribeImagesOutput struct { _ struct{} `type:"structure"` @@ -35292,7 +35018,6 @@ func (s *DescribeImagesOutput) SetImages(v []*Image) *DescribeImagesOutput { } // Contains the parameters for DescribeImportImageTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasksRequest type DescribeImportImageTasksInput struct { _ struct{} `type:"structure"` @@ -35358,7 +35083,6 @@ func (s *DescribeImportImageTasksInput) SetNextToken(v string) *DescribeImportIm } // Contains the output for DescribeImportImageTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportImageTasksResult type DescribeImportImageTasksOutput struct { _ struct{} `type:"structure"` @@ -35394,7 +35118,6 @@ func (s *DescribeImportImageTasksOutput) SetNextToken(v string) *DescribeImportI } // Contains the parameters for DescribeImportSnapshotTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasksRequest type DescribeImportSnapshotTasksInput struct { _ struct{} `type:"structure"` @@ -35459,7 +35182,6 @@ func (s *DescribeImportSnapshotTasksInput) SetNextToken(v string) *DescribeImpor } // Contains the output for DescribeImportSnapshotTasks. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeImportSnapshotTasksResult type DescribeImportSnapshotTasksOutput struct { _ struct{} `type:"structure"` @@ -35495,7 +35217,6 @@ func (s *DescribeImportSnapshotTasksOutput) SetNextToken(v string) *DescribeImpo } // Contains the parameters for DescribeInstanceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceAttributeRequest type DescribeInstanceAttributeInput struct { _ struct{} `type:"structure"` @@ -35563,7 +35284,6 @@ func (s *DescribeInstanceAttributeInput) SetInstanceId(v string) *DescribeInstan } // Describes an instance attribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceAttribute type DescribeInstanceAttributeOutput struct { _ struct{} `type:"structure"` @@ -35718,7 +35438,6 @@ func (s *DescribeInstanceAttributeOutput) SetUserData(v *AttributeValue) *Descri return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceCreditSpecificationsRequest type DescribeInstanceCreditSpecificationsInput struct { _ struct{} `type:"structure"` @@ -35790,7 +35509,6 @@ func (s *DescribeInstanceCreditSpecificationsInput) SetNextToken(v string) *Desc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceCreditSpecificationsResult type DescribeInstanceCreditSpecificationsOutput struct { _ struct{} `type:"structure"` @@ -35825,7 +35543,6 @@ func (s *DescribeInstanceCreditSpecificationsOutput) SetNextToken(v string) *Des } // Contains the parameters for DescribeInstanceStatus. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatusRequest type DescribeInstanceStatusInput struct { _ struct{} `type:"structure"` @@ -35942,7 +35659,6 @@ func (s *DescribeInstanceStatusInput) SetNextToken(v string) *DescribeInstanceSt } // Contains the output of DescribeInstanceStatus. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstanceStatusResult type DescribeInstanceStatusOutput struct { _ struct{} `type:"structure"` @@ -35977,7 +35693,6 @@ func (s *DescribeInstanceStatusOutput) SetNextToken(v string) *DescribeInstanceS } // Contains the parameters for DescribeInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstancesRequest type DescribeInstancesInput struct { _ struct{} `type:"structure"` @@ -36283,7 +35998,6 @@ func (s *DescribeInstancesInput) SetNextToken(v string) *DescribeInstancesInput } // Contains the output of DescribeInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInstancesResult type DescribeInstancesOutput struct { _ struct{} `type:"structure"` @@ -36318,7 +36032,6 @@ func (s *DescribeInstancesOutput) SetReservations(v []*Reservation) *DescribeIns } // Contains the parameters for DescribeInternetGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGatewaysRequest type DescribeInternetGatewaysInput struct { _ struct{} `type:"structure"` @@ -36389,7 +36102,6 @@ func (s *DescribeInternetGatewaysInput) SetInternetGatewayIds(v []*string) *Desc } // Contains the output of DescribeInternetGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeInternetGatewaysResult type DescribeInternetGatewaysOutput struct { _ struct{} `type:"structure"` @@ -36414,7 +36126,6 @@ func (s *DescribeInternetGatewaysOutput) SetInternetGateways(v []*InternetGatewa } // Contains the parameters for DescribeKeyPairs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairsRequest type DescribeKeyPairsInput struct { _ struct{} `type:"structure"` @@ -36466,7 +36177,6 @@ func (s *DescribeKeyPairsInput) SetKeyNames(v []*string) *DescribeKeyPairsInput } // Contains the output of DescribeKeyPairs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeKeyPairsResult type DescribeKeyPairsOutput struct { _ struct{} `type:"structure"` @@ -36490,7 +36200,6 @@ func (s *DescribeKeyPairsOutput) SetKeyPairs(v []*KeyPairInfo) *DescribeKeyPairs return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplateVersionsRequest type DescribeLaunchTemplateVersionsInput struct { _ struct{} `type:"structure"` @@ -36624,7 +36333,6 @@ func (s *DescribeLaunchTemplateVersionsInput) SetVersions(v []*string) *Describe return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplateVersionsResult type DescribeLaunchTemplateVersionsOutput struct { _ struct{} `type:"structure"` @@ -36658,7 +36366,6 @@ func (s *DescribeLaunchTemplateVersionsOutput) SetNextToken(v string) *DescribeL return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplatesRequest type DescribeLaunchTemplatesInput struct { _ struct{} `type:"structure"` @@ -36748,7 +36455,6 @@ func (s *DescribeLaunchTemplatesInput) SetNextToken(v string) *DescribeLaunchTem return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeLaunchTemplatesResult type DescribeLaunchTemplatesOutput struct { _ struct{} `type:"structure"` @@ -36783,7 +36489,6 @@ func (s *DescribeLaunchTemplatesOutput) SetNextToken(v string) *DescribeLaunchTe } // Contains the parameters for DescribeMovingAddresses. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddressesRequest type DescribeMovingAddressesInput struct { _ struct{} `type:"structure"` @@ -36855,7 +36560,6 @@ func (s *DescribeMovingAddressesInput) SetPublicIps(v []*string) *DescribeMoving } // Contains the output of DescribeMovingAddresses. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeMovingAddressesResult type DescribeMovingAddressesOutput struct { _ struct{} `type:"structure"` @@ -36890,7 +36594,6 @@ func (s *DescribeMovingAddressesOutput) SetNextToken(v string) *DescribeMovingAd } // Contains the parameters for DescribeNatGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGatewaysRequest type DescribeNatGatewaysInput struct { _ struct{} `type:"structure"` @@ -36972,7 +36675,6 @@ func (s *DescribeNatGatewaysInput) SetNextToken(v string) *DescribeNatGatewaysIn } // Contains the output of DescribeNatGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNatGatewaysResult type DescribeNatGatewaysOutput struct { _ struct{} `type:"structure"` @@ -37007,7 +36709,6 @@ func (s *DescribeNatGatewaysOutput) SetNextToken(v string) *DescribeNatGatewaysO } // Contains the parameters for DescribeNetworkAcls. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAclsRequest type DescribeNetworkAclsInput struct { _ struct{} `type:"structure"` @@ -37109,7 +36810,6 @@ func (s *DescribeNetworkAclsInput) SetNetworkAclIds(v []*string) *DescribeNetwor } // Contains the output of DescribeNetworkAcls. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkAclsResult type DescribeNetworkAclsOutput struct { _ struct{} `type:"structure"` @@ -37134,7 +36834,6 @@ func (s *DescribeNetworkAclsOutput) SetNetworkAcls(v []*NetworkAcl) *DescribeNet } // Contains the parameters for DescribeNetworkInterfaceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttributeRequest type DescribeNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` @@ -37195,7 +36894,6 @@ func (s *DescribeNetworkInterfaceAttributeInput) SetNetworkInterfaceId(v string) } // Contains the output of DescribeNetworkInterfaceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfaceAttributeResult type DescribeNetworkInterfaceAttributeOutput struct { _ struct{} `type:"structure"` @@ -37256,7 +36954,6 @@ func (s *DescribeNetworkInterfaceAttributeOutput) SetSourceDestCheck(v *Attribut } // Contains the parameters for DescribeNetworkInterfacePermissions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsRequest type DescribeNetworkInterfacePermissionsInput struct { _ struct{} `type:"structure"` @@ -37323,7 +37020,6 @@ func (s *DescribeNetworkInterfacePermissionsInput) SetNextToken(v string) *Descr } // Contains the output for DescribeNetworkInterfacePermissions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsResult type DescribeNetworkInterfacePermissionsOutput struct { _ struct{} `type:"structure"` @@ -37357,7 +37053,6 @@ func (s *DescribeNetworkInterfacePermissionsOutput) SetNextToken(v string) *Desc } // Contains the parameters for DescribeNetworkInterfaces. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesRequest type DescribeNetworkInterfacesInput struct { _ struct{} `type:"structure"` @@ -37515,7 +37210,6 @@ func (s *DescribeNetworkInterfacesInput) SetNetworkInterfaceIds(v []*string) *De } // Contains the output of DescribeNetworkInterfaces. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacesResult type DescribeNetworkInterfacesOutput struct { _ struct{} `type:"structure"` @@ -37540,7 +37234,6 @@ func (s *DescribeNetworkInterfacesOutput) SetNetworkInterfaces(v []*NetworkInter } // Contains the parameters for DescribePlacementGroups. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroupsRequest type DescribePlacementGroupsInput struct { _ struct{} `type:"structure"` @@ -37595,7 +37288,6 @@ func (s *DescribePlacementGroupsInput) SetGroupNames(v []*string) *DescribePlace } // Contains the output of DescribePlacementGroups. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePlacementGroupsResult type DescribePlacementGroupsOutput struct { _ struct{} `type:"structure"` @@ -37620,7 +37312,6 @@ func (s *DescribePlacementGroupsOutput) SetPlacementGroups(v []*PlacementGroup) } // Contains the parameters for DescribePrefixLists. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixListsRequest type DescribePrefixListsInput struct { _ struct{} `type:"structure"` @@ -37694,7 +37385,6 @@ func (s *DescribePrefixListsInput) SetPrefixListIds(v []*string) *DescribePrefix } // Contains the output of DescribePrefixLists. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribePrefixListsResult type DescribePrefixListsOutput struct { _ struct{} `type:"structure"` @@ -37729,7 +37419,6 @@ func (s *DescribePrefixListsOutput) SetPrefixLists(v []*PrefixList) *DescribePre } // Contains the parameters for DescribeRegions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegionsRequest type DescribeRegionsInput struct { _ struct{} `type:"structure"` @@ -37779,7 +37468,6 @@ func (s *DescribeRegionsInput) SetRegionNames(v []*string) *DescribeRegionsInput } // Contains the output of DescribeRegions. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRegionsResult type DescribeRegionsOutput struct { _ struct{} `type:"structure"` @@ -37804,7 +37492,6 @@ func (s *DescribeRegionsOutput) SetRegions(v []*Region) *DescribeRegionsOutput { } // Contains the parameters for DescribeReservedInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesRequest type DescribeReservedInstancesInput struct { _ struct{} `type:"structure"` @@ -37924,7 +37611,6 @@ func (s *DescribeReservedInstancesInput) SetReservedInstancesIds(v []*string) *D } // Contains the parameters for DescribeReservedInstancesListings. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListingsRequest type DescribeReservedInstancesListingsInput struct { _ struct{} `type:"structure"` @@ -37976,7 +37662,6 @@ func (s *DescribeReservedInstancesListingsInput) SetReservedInstancesListingId(v } // Contains the output of DescribeReservedInstancesListings. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesListingsResult type DescribeReservedInstancesListingsOutput struct { _ struct{} `type:"structure"` @@ -38001,7 +37686,6 @@ func (s *DescribeReservedInstancesListingsOutput) SetReservedInstancesListings(v } // Contains the parameters for DescribeReservedInstancesModifications. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModificationsRequest type DescribeReservedInstancesModificationsInput struct { _ struct{} `type:"structure"` @@ -38077,7 +37761,6 @@ func (s *DescribeReservedInstancesModificationsInput) SetReservedInstancesModifi } // Contains the output of DescribeReservedInstancesModifications. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesModificationsResult type DescribeReservedInstancesModificationsOutput struct { _ struct{} `type:"structure"` @@ -38112,7 +37795,6 @@ func (s *DescribeReservedInstancesModificationsOutput) SetReservedInstancesModif } // Contains the parameters for DescribeReservedInstancesOfferings. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferingsRequest type DescribeReservedInstancesOfferingsInput struct { _ struct{} `type:"structure"` @@ -38322,7 +38004,6 @@ func (s *DescribeReservedInstancesOfferingsInput) SetReservedInstancesOfferingId } // Contains the output of DescribeReservedInstancesOfferings. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesOfferingsResult type DescribeReservedInstancesOfferingsOutput struct { _ struct{} `type:"structure"` @@ -38357,7 +38038,6 @@ func (s *DescribeReservedInstancesOfferingsOutput) SetReservedInstancesOfferings } // Contains the output for DescribeReservedInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeReservedInstancesResult type DescribeReservedInstancesOutput struct { _ struct{} `type:"structure"` @@ -38382,7 +38062,6 @@ func (s *DescribeReservedInstancesOutput) SetReservedInstances(v []*ReservedInst } // Contains the parameters for DescribeRouteTables. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTablesRequest type DescribeRouteTablesInput struct { _ struct{} `type:"structure"` @@ -38495,7 +38174,6 @@ func (s *DescribeRouteTablesInput) SetRouteTableIds(v []*string) *DescribeRouteT } // Contains the output of DescribeRouteTables. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeRouteTablesResult type DescribeRouteTablesOutput struct { _ struct{} `type:"structure"` @@ -38520,7 +38198,6 @@ func (s *DescribeRouteTablesOutput) SetRouteTables(v []*RouteTable) *DescribeRou } // Contains the parameters for DescribeScheduledInstanceAvailability. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailabilityRequest type DescribeScheduledInstanceAvailabilityInput struct { _ struct{} `type:"structure"` @@ -38650,7 +38327,6 @@ func (s *DescribeScheduledInstanceAvailabilityInput) SetRecurrence(v *ScheduledI } // Contains the output of DescribeScheduledInstanceAvailability. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstanceAvailabilityResult type DescribeScheduledInstanceAvailabilityOutput struct { _ struct{} `type:"structure"` @@ -38685,7 +38361,6 @@ func (s *DescribeScheduledInstanceAvailabilityOutput) SetScheduledInstanceAvaila } // Contains the parameters for DescribeScheduledInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstancesRequest type DescribeScheduledInstancesInput struct { _ struct{} `type:"structure"` @@ -38768,7 +38443,6 @@ func (s *DescribeScheduledInstancesInput) SetSlotStartTimeRange(v *SlotStartTime } // Contains the output of DescribeScheduledInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeScheduledInstancesResult type DescribeScheduledInstancesOutput struct { _ struct{} `type:"structure"` @@ -38802,7 +38476,6 @@ func (s *DescribeScheduledInstancesOutput) SetScheduledInstanceSet(v []*Schedule return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferencesRequest type DescribeSecurityGroupReferencesInput struct { _ struct{} `type:"structure"` @@ -38853,7 +38526,6 @@ func (s *DescribeSecurityGroupReferencesInput) SetGroupId(v []*string) *Describe return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupReferencesResult type DescribeSecurityGroupReferencesOutput struct { _ struct{} `type:"structure"` @@ -38878,7 +38550,6 @@ func (s *DescribeSecurityGroupReferencesOutput) SetSecurityGroupReferenceSet(v [ } // Contains the parameters for DescribeSecurityGroups. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupsRequest type DescribeSecurityGroupsInput struct { _ struct{} `type:"structure"` @@ -39031,7 +38702,6 @@ func (s *DescribeSecurityGroupsInput) SetNextToken(v string) *DescribeSecurityGr } // Contains the output of DescribeSecurityGroups. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSecurityGroupsResult type DescribeSecurityGroupsOutput struct { _ struct{} `type:"structure"` @@ -39066,7 +38736,6 @@ func (s *DescribeSecurityGroupsOutput) SetSecurityGroups(v []*SecurityGroup) *De } // Contains the parameters for DescribeSnapshotAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttributeRequest type DescribeSnapshotAttributeInput struct { _ struct{} `type:"structure"` @@ -39132,7 +38801,6 @@ func (s *DescribeSnapshotAttributeInput) SetSnapshotId(v string) *DescribeSnapsh } // Contains the output of DescribeSnapshotAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotAttributeResult type DescribeSnapshotAttributeOutput struct { _ struct{} `type:"structure"` @@ -39175,7 +38843,6 @@ func (s *DescribeSnapshotAttributeOutput) SetSnapshotId(v string) *DescribeSnaps } // Contains the parameters for DescribeSnapshots. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotsRequest type DescribeSnapshotsInput struct { _ struct{} `type:"structure"` @@ -39309,7 +38976,6 @@ func (s *DescribeSnapshotsInput) SetSnapshotIds(v []*string) *DescribeSnapshotsI } // Contains the output of DescribeSnapshots. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSnapshotsResult type DescribeSnapshotsOutput struct { _ struct{} `type:"structure"` @@ -39346,7 +39012,6 @@ func (s *DescribeSnapshotsOutput) SetSnapshots(v []*Snapshot) *DescribeSnapshots } // Contains the parameters for DescribeSpotDatafeedSubscription. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscriptionRequest type DescribeSpotDatafeedSubscriptionInput struct { _ struct{} `type:"structure"` @@ -39374,7 +39039,6 @@ func (s *DescribeSpotDatafeedSubscriptionInput) SetDryRun(v bool) *DescribeSpotD } // Contains the output of DescribeSpotDatafeedSubscription. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotDatafeedSubscriptionResult type DescribeSpotDatafeedSubscriptionOutput struct { _ struct{} `type:"structure"` @@ -39399,7 +39063,6 @@ func (s *DescribeSpotDatafeedSubscriptionOutput) SetSpotDatafeedSubscription(v * } // Contains the parameters for DescribeSpotFleetInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstancesRequest type DescribeSpotFleetInstancesInput struct { _ struct{} `type:"structure"` @@ -39471,7 +39134,6 @@ func (s *DescribeSpotFleetInstancesInput) SetSpotFleetRequestId(v string) *Descr } // Contains the output of DescribeSpotFleetInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetInstancesResponse type DescribeSpotFleetInstancesOutput struct { _ struct{} `type:"structure"` @@ -39520,7 +39182,6 @@ func (s *DescribeSpotFleetInstancesOutput) SetSpotFleetRequestId(v string) *Desc } // Contains the parameters for DescribeSpotFleetRequestHistory. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistoryRequest type DescribeSpotFleetRequestHistoryInput struct { _ struct{} `type:"structure"` @@ -39615,7 +39276,6 @@ func (s *DescribeSpotFleetRequestHistoryInput) SetStartTime(v time.Time) *Descri } // Contains the output of DescribeSpotFleetRequestHistory. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestHistoryResponse type DescribeSpotFleetRequestHistoryOutput struct { _ struct{} `type:"structure"` @@ -39688,7 +39348,6 @@ func (s *DescribeSpotFleetRequestHistoryOutput) SetStartTime(v time.Time) *Descr } // Contains the parameters for DescribeSpotFleetRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestsRequest type DescribeSpotFleetRequestsInput struct { _ struct{} `type:"structure"` @@ -39745,7 +39404,6 @@ func (s *DescribeSpotFleetRequestsInput) SetSpotFleetRequestIds(v []*string) *De } // Contains the output of DescribeSpotFleetRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotFleetRequestsResponse type DescribeSpotFleetRequestsOutput struct { _ struct{} `type:"structure"` @@ -39782,7 +39440,6 @@ func (s *DescribeSpotFleetRequestsOutput) SetSpotFleetRequestConfigs(v []*SpotFl } // Contains the parameters for DescribeSpotInstanceRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequestsRequest type DescribeSpotInstanceRequestsInput struct { _ struct{} `type:"structure"` @@ -39937,7 +39594,6 @@ func (s *DescribeSpotInstanceRequestsInput) SetSpotInstanceRequestIds(v []*strin } // Contains the output of DescribeSpotInstanceRequests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotInstanceRequestsResult type DescribeSpotInstanceRequestsOutput struct { _ struct{} `type:"structure"` @@ -39962,7 +39618,6 @@ func (s *DescribeSpotInstanceRequestsOutput) SetSpotInstanceRequests(v []*SpotIn } // Contains the parameters for DescribeSpotPriceHistory. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistoryRequest type DescribeSpotPriceHistoryInput struct { _ struct{} `type:"structure"` @@ -40082,7 +39737,6 @@ func (s *DescribeSpotPriceHistoryInput) SetStartTime(v time.Time) *DescribeSpotP } // Contains the output of DescribeSpotPriceHistory. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSpotPriceHistoryResult type DescribeSpotPriceHistoryOutput struct { _ struct{} `type:"structure"` @@ -40116,7 +39770,6 @@ func (s *DescribeSpotPriceHistoryOutput) SetSpotPriceHistory(v []*SpotPrice) *De return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroupsRequest type DescribeStaleSecurityGroupsInput struct { _ struct{} `type:"structure"` @@ -40194,7 +39847,6 @@ func (s *DescribeStaleSecurityGroupsInput) SetVpcId(v string) *DescribeStaleSecu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeStaleSecurityGroupsResult type DescribeStaleSecurityGroupsOutput struct { _ struct{} `type:"structure"` @@ -40229,7 +39881,6 @@ func (s *DescribeStaleSecurityGroupsOutput) SetStaleSecurityGroupSet(v []*StaleS } // Contains the parameters for DescribeSubnets. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnetsRequest type DescribeSubnetsInput struct { _ struct{} `type:"structure"` @@ -40321,7 +39972,6 @@ func (s *DescribeSubnetsInput) SetSubnetIds(v []*string) *DescribeSubnetsInput { } // Contains the output of DescribeSubnets. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeSubnetsResult type DescribeSubnetsOutput struct { _ struct{} `type:"structure"` @@ -40346,7 +39996,6 @@ func (s *DescribeSubnetsOutput) SetSubnets(v []*Subnet) *DescribeSubnetsOutput { } // Contains the parameters for DescribeTags. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTagsRequest type DescribeTagsInput struct { _ struct{} `type:"structure"` @@ -40415,7 +40064,6 @@ func (s *DescribeTagsInput) SetNextToken(v string) *DescribeTagsInput { } // Contains the output of DescribeTags. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeTagsResult type DescribeTagsOutput struct { _ struct{} `type:"structure"` @@ -40450,7 +40098,6 @@ func (s *DescribeTagsOutput) SetTags(v []*TagDescription) *DescribeTagsOutput { } // Contains the parameters for DescribeVolumeAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttributeRequest type DescribeVolumeAttributeInput struct { _ struct{} `type:"structure"` @@ -40511,7 +40158,6 @@ func (s *DescribeVolumeAttributeInput) SetVolumeId(v string) *DescribeVolumeAttr } // Contains the output of DescribeVolumeAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeAttributeResult type DescribeVolumeAttributeOutput struct { _ struct{} `type:"structure"` @@ -40554,7 +40200,6 @@ func (s *DescribeVolumeAttributeOutput) SetVolumeId(v string) *DescribeVolumeAtt } // Contains the parameters for DescribeVolumeStatus. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatusRequest type DescribeVolumeStatusInput struct { _ struct{} `type:"structure"` @@ -40660,7 +40305,6 @@ func (s *DescribeVolumeStatusInput) SetVolumeIds(v []*string) *DescribeVolumeSta } // Contains the output of DescribeVolumeStatus. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumeStatusResult type DescribeVolumeStatusOutput struct { _ struct{} `type:"structure"` @@ -40695,7 +40339,6 @@ func (s *DescribeVolumeStatusOutput) SetVolumeStatuses(v []*VolumeStatusItem) *D } // Contains the parameters for DescribeVolumes. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesRequest type DescribeVolumesInput struct { _ struct{} `type:"structure"` @@ -40818,7 +40461,6 @@ func (s *DescribeVolumesInput) SetVolumeIds(v []*string) *DescribeVolumesInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModificationsRequest type DescribeVolumesModificationsInput struct { _ struct{} `type:"structure"` @@ -40884,7 +40526,6 @@ func (s *DescribeVolumesModificationsInput) SetVolumeIds(v []*string) *DescribeV return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesModificationsResult type DescribeVolumesModificationsOutput struct { _ struct{} `type:"structure"` @@ -40918,7 +40559,6 @@ func (s *DescribeVolumesModificationsOutput) SetVolumesModifications(v []*Volume } // Contains the output of DescribeVolumes. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVolumesResult type DescribeVolumesOutput struct { _ struct{} `type:"structure"` @@ -40955,7 +40595,6 @@ func (s *DescribeVolumesOutput) SetVolumes(v []*Volume) *DescribeVolumesOutput { } // Contains the parameters for DescribeVpcAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttributeRequest type DescribeVpcAttributeInput struct { _ struct{} `type:"structure"` @@ -41021,7 +40660,6 @@ func (s *DescribeVpcAttributeInput) SetVpcId(v string) *DescribeVpcAttributeInpu } // Contains the output of DescribeVpcAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcAttributeResult type DescribeVpcAttributeOutput struct { _ struct{} `type:"structure"` @@ -41068,7 +40706,6 @@ func (s *DescribeVpcAttributeOutput) SetVpcId(v string) *DescribeVpcAttributeOut } // Contains the parameters for DescribeVpcClassicLinkDnsSupport. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupportRequest type DescribeVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` @@ -41130,7 +40767,6 @@ func (s *DescribeVpcClassicLinkDnsSupportInput) SetVpcIds(v []*string) *Describe } // Contains the output of DescribeVpcClassicLinkDnsSupport. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkDnsSupportResult type DescribeVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` @@ -41164,7 +40800,6 @@ func (s *DescribeVpcClassicLinkDnsSupportOutput) SetVpcs(v []*ClassicLinkDnsSupp } // Contains the parameters for DescribeVpcClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkRequest type DescribeVpcClassicLinkInput struct { _ struct{} `type:"structure"` @@ -41229,7 +40864,6 @@ func (s *DescribeVpcClassicLinkInput) SetVpcIds(v []*string) *DescribeVpcClassic } // Contains the output of DescribeVpcClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcClassicLinkResult type DescribeVpcClassicLinkOutput struct { _ struct{} `type:"structure"` @@ -41253,7 +40887,6 @@ func (s *DescribeVpcClassicLinkOutput) SetVpcs(v []*VpcClassicLink) *DescribeVpc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionNotificationsRequest type DescribeVpcEndpointConnectionNotificationsInput struct { _ struct{} `type:"structure"` @@ -41330,7 +40963,6 @@ func (s *DescribeVpcEndpointConnectionNotificationsInput) SetNextToken(v string) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionNotificationsResult type DescribeVpcEndpointConnectionNotificationsOutput struct { _ struct{} `type:"structure"` @@ -41364,7 +40996,6 @@ func (s *DescribeVpcEndpointConnectionNotificationsOutput) SetNextToken(v string return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionsRequest type DescribeVpcEndpointConnectionsInput struct { _ struct{} `type:"structure"` @@ -41431,7 +41062,6 @@ func (s *DescribeVpcEndpointConnectionsInput) SetNextToken(v string) *DescribeVp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointConnectionsResult type DescribeVpcEndpointConnectionsOutput struct { _ struct{} `type:"structure"` @@ -41465,7 +41095,6 @@ func (s *DescribeVpcEndpointConnectionsOutput) SetVpcEndpointConnections(v []*Vp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServiceConfigurationsRequest type DescribeVpcEndpointServiceConfigurationsInput struct { _ struct{} `type:"structure"` @@ -41539,7 +41168,6 @@ func (s *DescribeVpcEndpointServiceConfigurationsInput) SetServiceIds(v []*strin return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServiceConfigurationsResult type DescribeVpcEndpointServiceConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -41573,7 +41201,6 @@ func (s *DescribeVpcEndpointServiceConfigurationsOutput) SetServiceConfiguration return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicePermissionsRequest type DescribeVpcEndpointServicePermissionsInput struct { _ struct{} `type:"structure"` @@ -41660,7 +41287,6 @@ func (s *DescribeVpcEndpointServicePermissionsInput) SetServiceId(v string) *Des return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicePermissionsResult type DescribeVpcEndpointServicePermissionsOutput struct { _ struct{} `type:"structure"` @@ -41695,7 +41321,6 @@ func (s *DescribeVpcEndpointServicePermissionsOutput) SetNextToken(v string) *De } // Contains the parameters for DescribeVpcEndpointServices. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicesRequest type DescribeVpcEndpointServicesInput struct { _ struct{} `type:"structure"` @@ -41766,7 +41391,6 @@ func (s *DescribeVpcEndpointServicesInput) SetServiceNames(v []*string) *Describ } // Contains the output of DescribeVpcEndpointServices. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointServicesResult type DescribeVpcEndpointServicesOutput struct { _ struct{} `type:"structure"` @@ -41810,7 +41434,6 @@ func (s *DescribeVpcEndpointServicesOutput) SetServiceNames(v []*string) *Descri } // Contains the parameters for DescribeVpcEndpoints. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointsRequest type DescribeVpcEndpointsInput struct { _ struct{} `type:"structure"` @@ -41888,7 +41511,6 @@ func (s *DescribeVpcEndpointsInput) SetVpcEndpointIds(v []*string) *DescribeVpcE } // Contains the output of DescribeVpcEndpoints. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcEndpointsResult type DescribeVpcEndpointsOutput struct { _ struct{} `type:"structure"` @@ -41923,7 +41545,6 @@ func (s *DescribeVpcEndpointsOutput) SetVpcEndpoints(v []*VpcEndpoint) *Describe } // Contains the parameters for DescribeVpcPeeringConnections. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnectionsRequest type DescribeVpcPeeringConnectionsInput struct { _ struct{} `type:"structure"` @@ -42012,7 +41633,6 @@ func (s *DescribeVpcPeeringConnectionsInput) SetVpcPeeringConnectionIds(v []*str } // Contains the output of DescribeVpcPeeringConnections. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcPeeringConnectionsResult type DescribeVpcPeeringConnectionsOutput struct { _ struct{} `type:"structure"` @@ -42037,7 +41657,6 @@ func (s *DescribeVpcPeeringConnectionsOutput) SetVpcPeeringConnections(v []*VpcP } // Contains the parameters for DescribeVpcs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcsRequest type DescribeVpcsInput struct { _ struct{} `type:"structure"` @@ -42132,7 +41751,6 @@ func (s *DescribeVpcsInput) SetVpcIds(v []*string) *DescribeVpcsInput { } // Contains the output of DescribeVpcs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpcsResult type DescribeVpcsOutput struct { _ struct{} `type:"structure"` @@ -42157,7 +41775,6 @@ func (s *DescribeVpcsOutput) SetVpcs(v []*Vpc) *DescribeVpcsOutput { } // Contains the parameters for DescribeVpnConnections. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnectionsRequest type DescribeVpnConnectionsInput struct { _ struct{} `type:"structure"` @@ -42248,7 +41865,6 @@ func (s *DescribeVpnConnectionsInput) SetVpnConnectionIds(v []*string) *Describe } // Contains the output of DescribeVpnConnections. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnConnectionsResult type DescribeVpnConnectionsOutput struct { _ struct{} `type:"structure"` @@ -42273,7 +41889,6 @@ func (s *DescribeVpnConnectionsOutput) SetVpnConnections(v []*VpnConnection) *De } // Contains the parameters for DescribeVpnGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGatewaysRequest type DescribeVpnGatewaysInput struct { _ struct{} `type:"structure"` @@ -42356,7 +41971,6 @@ func (s *DescribeVpnGatewaysInput) SetVpnGatewayIds(v []*string) *DescribeVpnGat } // Contains the output of DescribeVpnGateways. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeVpnGatewaysResult type DescribeVpnGatewaysOutput struct { _ struct{} `type:"structure"` @@ -42381,7 +41995,6 @@ func (s *DescribeVpnGatewaysOutput) SetVpnGateways(v []*VpnGateway) *DescribeVpn } // Contains the parameters for DetachClassicLinkVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpcRequest type DetachClassicLinkVpcInput struct { _ struct{} `type:"structure"` @@ -42447,7 +42060,6 @@ func (s *DetachClassicLinkVpcInput) SetVpcId(v string) *DetachClassicLinkVpcInpu } // Contains the output of DetachClassicLinkVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachClassicLinkVpcResult type DetachClassicLinkVpcOutput struct { _ struct{} `type:"structure"` @@ -42472,7 +42084,6 @@ func (s *DetachClassicLinkVpcOutput) SetReturn(v bool) *DetachClassicLinkVpcOutp } // Contains the parameters for DetachInternetGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGatewayRequest type DetachInternetGatewayInput struct { _ struct{} `type:"structure"` @@ -42537,7 +42148,6 @@ func (s *DetachInternetGatewayInput) SetVpcId(v string) *DetachInternetGatewayIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachInternetGatewayOutput type DetachInternetGatewayOutput struct { _ struct{} `type:"structure"` } @@ -42553,7 +42163,6 @@ func (s DetachInternetGatewayOutput) GoString() string { } // Contains the parameters for DetachNetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterfaceRequest type DetachNetworkInterfaceInput struct { _ struct{} `type:"structure"` @@ -42613,7 +42222,6 @@ func (s *DetachNetworkInterfaceInput) SetForce(v bool) *DetachNetworkInterfaceIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachNetworkInterfaceOutput type DetachNetworkInterfaceOutput struct { _ struct{} `type:"structure"` } @@ -42629,7 +42237,6 @@ func (s DetachNetworkInterfaceOutput) GoString() string { } // Contains the parameters for DetachVolume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVolumeRequest type DetachVolumeInput struct { _ struct{} `type:"structure"` @@ -42714,7 +42321,6 @@ func (s *DetachVolumeInput) SetVolumeId(v string) *DetachVolumeInput { } // Contains the parameters for DetachVpnGateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGatewayRequest type DetachVpnGatewayInput struct { _ struct{} `type:"structure"` @@ -42779,7 +42385,6 @@ func (s *DetachVpnGatewayInput) SetVpnGatewayId(v string) *DetachVpnGatewayInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DetachVpnGatewayOutput type DetachVpnGatewayOutput struct { _ struct{} `type:"structure"` } @@ -42795,7 +42400,6 @@ func (s DetachVpnGatewayOutput) GoString() string { } // Describes a DHCP configuration option. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DhcpConfiguration type DhcpConfiguration struct { _ struct{} `type:"structure"` @@ -42829,7 +42433,6 @@ func (s *DhcpConfiguration) SetValues(v []*AttributeValue) *DhcpConfiguration { } // Describes a set of DHCP options. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DhcpOptions type DhcpOptions struct { _ struct{} `type:"structure"` @@ -42872,7 +42475,6 @@ func (s *DhcpOptions) SetTags(v []*Tag) *DhcpOptions { } // Contains the parameters for DisableVgwRoutePropagation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagationRequest type DisableVgwRoutePropagationInput struct { _ struct{} `type:"structure"` @@ -42925,7 +42527,6 @@ func (s *DisableVgwRoutePropagationInput) SetRouteTableId(v string) *DisableVgwR return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVgwRoutePropagationOutput type DisableVgwRoutePropagationOutput struct { _ struct{} `type:"structure"` } @@ -42941,7 +42542,6 @@ func (s DisableVgwRoutePropagationOutput) GoString() string { } // Contains the parameters for DisableVpcClassicLinkDnsSupport. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupportRequest type DisableVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` @@ -42966,7 +42566,6 @@ func (s *DisableVpcClassicLinkDnsSupportInput) SetVpcId(v string) *DisableVpcCla } // Contains the output of DisableVpcClassicLinkDnsSupport. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkDnsSupportResult type DisableVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` @@ -42991,7 +42590,6 @@ func (s *DisableVpcClassicLinkDnsSupportOutput) SetReturn(v bool) *DisableVpcCla } // Contains the parameters for DisableVpcClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkRequest type DisableVpcClassicLinkInput struct { _ struct{} `type:"structure"` @@ -43043,7 +42641,6 @@ func (s *DisableVpcClassicLinkInput) SetVpcId(v string) *DisableVpcClassicLinkIn } // Contains the output of DisableVpcClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisableVpcClassicLinkResult type DisableVpcClassicLinkOutput struct { _ struct{} `type:"structure"` @@ -43068,7 +42665,6 @@ func (s *DisableVpcClassicLinkOutput) SetReturn(v bool) *DisableVpcClassicLinkOu } // Contains the parameters for DisassociateAddress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddressRequest type DisassociateAddressInput struct { _ struct{} `type:"structure"` @@ -43113,7 +42709,6 @@ func (s *DisassociateAddressInput) SetPublicIp(v string) *DisassociateAddressInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateAddressOutput type DisassociateAddressOutput struct { _ struct{} `type:"structure"` } @@ -43128,7 +42723,6 @@ func (s DisassociateAddressOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfileRequest type DisassociateIamInstanceProfileInput struct { _ struct{} `type:"structure"` @@ -43167,7 +42761,6 @@ func (s *DisassociateIamInstanceProfileInput) SetAssociationId(v string) *Disass return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateIamInstanceProfileResult type DisassociateIamInstanceProfileOutput struct { _ struct{} `type:"structure"` @@ -43192,7 +42785,6 @@ func (s *DisassociateIamInstanceProfileOutput) SetIamInstanceProfileAssociation( } // Contains the parameters for DisassociateRouteTable. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTableRequest type DisassociateRouteTableInput struct { _ struct{} `type:"structure"` @@ -43244,7 +42836,6 @@ func (s *DisassociateRouteTableInput) SetDryRun(v bool) *DisassociateRouteTableI return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateRouteTableOutput type DisassociateRouteTableOutput struct { _ struct{} `type:"structure"` } @@ -43259,7 +42850,6 @@ func (s DisassociateRouteTableOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlockRequest type DisassociateSubnetCidrBlockInput struct { _ struct{} `type:"structure"` @@ -43298,7 +42888,6 @@ func (s *DisassociateSubnetCidrBlockInput) SetAssociationId(v string) *Disassoci return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateSubnetCidrBlockResult type DisassociateSubnetCidrBlockOutput struct { _ struct{} `type:"structure"` @@ -43331,7 +42920,6 @@ func (s *DisassociateSubnetCidrBlockOutput) SetSubnetId(v string) *DisassociateS return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlockRequest type DisassociateVpcCidrBlockInput struct { _ struct{} `type:"structure"` @@ -43370,7 +42958,6 @@ func (s *DisassociateVpcCidrBlockInput) SetAssociationId(v string) *Disassociate return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DisassociateVpcCidrBlockResult type DisassociateVpcCidrBlockOutput struct { _ struct{} `type:"structure"` @@ -43413,7 +43000,6 @@ func (s *DisassociateVpcCidrBlockOutput) SetVpcId(v string) *DisassociateVpcCidr } // Describes a disk image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImage type DiskImage struct { _ struct{} `type:"structure"` @@ -43476,7 +43062,6 @@ func (s *DiskImage) SetVolume(v *VolumeDetail) *DiskImage { } // Describes a disk image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageDescription type DiskImageDescription struct { _ struct{} `type:"structure"` @@ -43541,7 +43126,6 @@ func (s *DiskImageDescription) SetSize(v int64) *DiskImageDescription { } // Describes a disk image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageDetail type DiskImageDetail struct { _ struct{} `type:"structure"` @@ -43616,7 +43200,6 @@ func (s *DiskImageDetail) SetImportManifestUrl(v string) *DiskImageDetail { } // Describes a disk image volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DiskImageVolumeDescription type DiskImageVolumeDescription struct { _ struct{} `type:"structure"` @@ -43652,7 +43235,6 @@ func (s *DiskImageVolumeDescription) SetSize(v int64) *DiskImageVolumeDescriptio } // Describes a DNS entry. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DnsEntry type DnsEntry struct { _ struct{} `type:"structure"` @@ -43686,7 +43268,6 @@ func (s *DnsEntry) SetHostedZoneId(v string) *DnsEntry { } // Describes a block device for an EBS volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsBlockDevice type EbsBlockDevice struct { _ struct{} `type:"structure"` @@ -43796,7 +43377,6 @@ func (s *EbsBlockDevice) SetVolumeType(v string) *EbsBlockDevice { } // Describes a parameter used to set up an EBS volume in a block device mapping. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsInstanceBlockDevice type EbsInstanceBlockDevice struct { _ struct{} `type:"structure"` @@ -43849,7 +43429,6 @@ func (s *EbsInstanceBlockDevice) SetVolumeId(v string) *EbsInstanceBlockDevice { // Describes information used to set up an EBS volume specified in a block device // mapping. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsInstanceBlockDeviceSpecification type EbsInstanceBlockDeviceSpecification struct { _ struct{} `type:"structure"` @@ -43883,7 +43462,6 @@ func (s *EbsInstanceBlockDeviceSpecification) SetVolumeId(v string) *EbsInstance } // Describes an egress-only Internet gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EgressOnlyInternetGateway type EgressOnlyInternetGateway struct { _ struct{} `type:"structure"` @@ -43917,7 +43495,6 @@ func (s *EgressOnlyInternetGateway) SetEgressOnlyInternetGatewayId(v string) *Eg } // Describes the association between an instance and an Elastic GPU. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuAssociation type ElasticGpuAssociation struct { _ struct{} `type:"structure"` @@ -43969,7 +43546,6 @@ func (s *ElasticGpuAssociation) SetElasticGpuId(v string) *ElasticGpuAssociation } // Describes the status of an Elastic GPU. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuHealth type ElasticGpuHealth struct { _ struct{} `type:"structure"` @@ -43994,7 +43570,6 @@ func (s *ElasticGpuHealth) SetStatus(v string) *ElasticGpuHealth { } // A specification for an Elastic GPU. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuSpecification type ElasticGpuSpecification struct { _ struct{} `type:"structure"` @@ -44034,7 +43609,6 @@ func (s *ElasticGpuSpecification) SetType(v string) *ElasticGpuSpecification { } // Describes an elastic GPU. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpuSpecificationResponse type ElasticGpuSpecificationResponse struct { _ struct{} `type:"structure"` @@ -44059,7 +43633,6 @@ func (s *ElasticGpuSpecificationResponse) SetType(v string) *ElasticGpuSpecifica } // Describes an Elastic GPU. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ElasticGpus type ElasticGpus struct { _ struct{} `type:"structure"` @@ -44129,7 +43702,6 @@ func (s *ElasticGpus) SetInstanceId(v string) *ElasticGpus { } // Contains the parameters for EnableVgwRoutePropagation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationRequest type EnableVgwRoutePropagationInput struct { _ struct{} `type:"structure"` @@ -44182,7 +43754,6 @@ func (s *EnableVgwRoutePropagationInput) SetRouteTableId(v string) *EnableVgwRou return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVgwRoutePropagationOutput type EnableVgwRoutePropagationOutput struct { _ struct{} `type:"structure"` } @@ -44198,7 +43769,6 @@ func (s EnableVgwRoutePropagationOutput) GoString() string { } // Contains the parameters for EnableVolumeIO. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIORequest type EnableVolumeIOInput struct { _ struct{} `type:"structure"` @@ -44249,7 +43819,6 @@ func (s *EnableVolumeIOInput) SetVolumeId(v string) *EnableVolumeIOInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVolumeIOOutput type EnableVolumeIOOutput struct { _ struct{} `type:"structure"` } @@ -44265,7 +43834,6 @@ func (s EnableVolumeIOOutput) GoString() string { } // Contains the parameters for EnableVpcClassicLinkDnsSupport. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupportRequest type EnableVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` @@ -44290,7 +43858,6 @@ func (s *EnableVpcClassicLinkDnsSupportInput) SetVpcId(v string) *EnableVpcClass } // Contains the output of EnableVpcClassicLinkDnsSupport. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkDnsSupportResult type EnableVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` @@ -44315,7 +43882,6 @@ func (s *EnableVpcClassicLinkDnsSupportOutput) SetReturn(v bool) *EnableVpcClass } // Contains the parameters for EnableVpcClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkRequest type EnableVpcClassicLinkInput struct { _ struct{} `type:"structure"` @@ -44367,7 +43933,6 @@ func (s *EnableVpcClassicLinkInput) SetVpcId(v string) *EnableVpcClassicLinkInpu } // Contains the output of EnableVpcClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EnableVpcClassicLinkResult type EnableVpcClassicLinkOutput struct { _ struct{} `type:"structure"` @@ -44392,7 +43957,6 @@ func (s *EnableVpcClassicLinkOutput) SetReturn(v bool) *EnableVpcClassicLinkOutp } // Describes a Spot Fleet event. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EventInformation type EventInformation struct { _ struct{} `type:"structure"` @@ -44496,7 +44060,6 @@ func (s *EventInformation) SetInstanceId(v string) *EventInformation { } // Describes an instance export task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportTask type ExportTask struct { _ struct{} `type:"structure"` @@ -44566,7 +44129,6 @@ func (s *ExportTask) SetStatusMessage(v string) *ExportTask { } // Describes the format and location for an instance export task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportToS3Task type ExportToS3Task struct { _ struct{} `type:"structure"` @@ -44620,7 +44182,6 @@ func (s *ExportToS3Task) SetS3Key(v string) *ExportToS3Task { } // Describes an instance export task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ExportToS3TaskSpecification type ExportToS3TaskSpecification struct { _ struct{} `type:"structure"` @@ -44677,7 +44238,6 @@ func (s *ExportToS3TaskSpecification) SetS3Prefix(v string) *ExportToS3TaskSpeci // A filter name and value pair that is used to return a more specific list // of results. Filters can be used to match a set of resources by various criteria, // such as tags, attributes, or IDs. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Filter type Filter struct { _ struct{} `type:"structure"` @@ -44711,7 +44271,6 @@ func (s *Filter) SetValues(v []*string) *Filter { } // Describes a launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FleetLaunchTemplateSpecification type FleetLaunchTemplateSpecification struct { _ struct{} `type:"structure"` @@ -44770,7 +44329,6 @@ func (s *FleetLaunchTemplateSpecification) SetVersion(v string) *FleetLaunchTemp } // Describes a flow log. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FlowLog type FlowLog struct { _ struct{} `type:"structure"` @@ -44872,7 +44430,6 @@ func (s *FlowLog) SetTrafficType(v string) *FlowLog { } // Describes an Amazon FPGA image (AFI). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImage type FpgaImage struct { _ struct{} `type:"structure"` @@ -45014,7 +44571,6 @@ func (s *FpgaImage) SetUpdateTime(v time.Time) *FpgaImage { } // Describes an Amazon FPGA image (AFI) attribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImageAttribute type FpgaImageAttribute struct { _ struct{} `type:"structure"` @@ -45076,7 +44632,6 @@ func (s *FpgaImageAttribute) SetProductCodes(v []*ProductCode) *FpgaImageAttribu // Describes the state of the bitstream generation process for an Amazon FPGA // image (AFI). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/FpgaImageState type FpgaImageState struct { _ struct{} `type:"structure"` @@ -45118,7 +44673,6 @@ func (s *FpgaImageState) SetMessage(v string) *FpgaImageState { } // Contains the parameters for GetConsoleOutput. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputRequest type GetConsoleOutputInput struct { _ struct{} `type:"structure"` @@ -45170,7 +44724,6 @@ func (s *GetConsoleOutputInput) SetInstanceId(v string) *GetConsoleOutputInput { } // Contains the output of GetConsoleOutput. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleOutputResult type GetConsoleOutputOutput struct { _ struct{} `type:"structure"` @@ -45214,7 +44767,6 @@ func (s *GetConsoleOutputOutput) SetTimestamp(v time.Time) *GetConsoleOutputOutp } // Contains the parameters for the request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshotRequest type GetConsoleScreenshotInput struct { _ struct{} `type:"structure"` @@ -45276,7 +44828,6 @@ func (s *GetConsoleScreenshotInput) SetWakeUp(v bool) *GetConsoleScreenshotInput } // Contains the output of the request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetConsoleScreenshotResult type GetConsoleScreenshotOutput struct { _ struct{} `type:"structure"` @@ -45309,7 +44860,6 @@ func (s *GetConsoleScreenshotOutput) SetInstanceId(v string) *GetConsoleScreensh return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreviewRequest type GetHostReservationPurchasePreviewInput struct { _ struct{} `type:"structure"` @@ -45363,7 +44913,6 @@ func (s *GetHostReservationPurchasePreviewInput) SetOfferingId(v string) *GetHos return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetHostReservationPurchasePreviewResult type GetHostReservationPurchasePreviewOutput struct { _ struct{} `type:"structure"` @@ -45416,7 +44965,6 @@ func (s *GetHostReservationPurchasePreviewOutput) SetTotalUpfrontPrice(v string) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetLaunchTemplateDataRequest type GetLaunchTemplateDataInput struct { _ struct{} `type:"structure"` @@ -45467,7 +45015,6 @@ func (s *GetLaunchTemplateDataInput) SetInstanceId(v string) *GetLaunchTemplateD return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetLaunchTemplateDataResult type GetLaunchTemplateDataOutput struct { _ struct{} `type:"structure"` @@ -45492,7 +45039,6 @@ func (s *GetLaunchTemplateDataOutput) SetLaunchTemplateData(v *ResponseLaunchTem } // Contains the parameters for GetPasswordData. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordDataRequest type GetPasswordDataInput struct { _ struct{} `type:"structure"` @@ -45544,7 +45090,6 @@ func (s *GetPasswordDataInput) SetInstanceId(v string) *GetPasswordDataInput { } // Contains the output of GetPasswordData. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetPasswordDataResult type GetPasswordDataOutput struct { _ struct{} `type:"structure"` @@ -45588,7 +45133,6 @@ func (s *GetPasswordDataOutput) SetTimestamp(v time.Time) *GetPasswordDataOutput } // Contains the parameters for GetReservedInstanceExchangeQuote. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuoteRequest type GetReservedInstancesExchangeQuoteInput struct { _ struct{} `type:"structure"` @@ -45660,7 +45204,6 @@ func (s *GetReservedInstancesExchangeQuoteInput) SetTargetConfigurations(v []*Ta } // Contains the output of GetReservedInstancesExchangeQuote. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GetReservedInstancesExchangeQuoteResult type GetReservedInstancesExchangeQuoteOutput struct { _ struct{} `type:"structure"` @@ -45757,7 +45300,6 @@ func (s *GetReservedInstancesExchangeQuoteOutput) SetValidationFailureReason(v s } // Describes a security group. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/GroupIdentifier type GroupIdentifier struct { _ struct{} `type:"structure"` @@ -45791,7 +45333,6 @@ func (s *GroupIdentifier) SetGroupName(v string) *GroupIdentifier { } // Describes an event in the history of the Spot Fleet request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HistoryRecord type HistoryRecord struct { _ struct{} `type:"structure"` @@ -45849,7 +45390,6 @@ func (s *HistoryRecord) SetTimestamp(v time.Time) *HistoryRecord { } // Describes the properties of the Dedicated Host. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Host type Host struct { _ struct{} `type:"structure"` @@ -45949,7 +45489,6 @@ func (s *Host) SetState(v string) *Host { } // Describes an instance running on a Dedicated Host. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostInstance type HostInstance struct { _ struct{} `type:"structure"` @@ -45983,7 +45522,6 @@ func (s *HostInstance) SetInstanceType(v string) *HostInstance { } // Details about the Dedicated Host Reservation offering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostOffering type HostOffering struct { _ struct{} `type:"structure"` @@ -46062,7 +45600,6 @@ func (s *HostOffering) SetUpfrontPrice(v string) *HostOffering { } // Describes properties of a Dedicated Host. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostProperties type HostProperties struct { _ struct{} `type:"structure"` @@ -46114,7 +45651,6 @@ func (s *HostProperties) SetTotalVCpus(v int64) *HostProperties { } // Details about the Dedicated Host Reservation and associated Dedicated Hosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/HostReservation type HostReservation struct { _ struct{} `type:"structure"` @@ -46252,7 +45788,6 @@ func (s *HostReservation) SetUpfrontPrice(v string) *HostReservation { } // Describes an IAM instance profile. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfile type IamInstanceProfile struct { _ struct{} `type:"structure"` @@ -46286,7 +45821,6 @@ func (s *IamInstanceProfile) SetId(v string) *IamInstanceProfile { } // Describes an association between an IAM instance profile and an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfileAssociation type IamInstanceProfileAssociation struct { _ struct{} `type:"structure"` @@ -46347,7 +45881,6 @@ func (s *IamInstanceProfileAssociation) SetTimestamp(v time.Time) *IamInstancePr } // Describes an IAM instance profile. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IamInstanceProfileSpecification type IamInstanceProfileSpecification struct { _ struct{} `type:"structure"` @@ -46381,7 +45914,6 @@ func (s *IamInstanceProfileSpecification) SetName(v string) *IamInstanceProfileS } // Describes the ICMP type and code. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IcmpTypeCode type IcmpTypeCode struct { _ struct{} `type:"structure"` @@ -46415,7 +45947,6 @@ func (s *IcmpTypeCode) SetType(v int64) *IcmpTypeCode { } // Describes the ID format for a resource. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IdFormat type IdFormat struct { _ struct{} `type:"structure"` @@ -46460,7 +45991,6 @@ func (s *IdFormat) SetUseLongIds(v bool) *IdFormat { } // Describes an image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Image type Image struct { _ struct{} `type:"structure"` @@ -46700,7 +46230,6 @@ func (s *Image) SetVirtualizationType(v string) *Image { } // Describes the disk container object for an import image task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImageDiskContainer type ImageDiskContainer struct { _ struct{} `type:"structure"` @@ -46773,7 +46302,6 @@ func (s *ImageDiskContainer) SetUserBucket(v *UserBucket) *ImageDiskContainer { } // Contains the parameters for ImportImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageRequest type ImportImageInput struct { _ struct{} `type:"structure"` @@ -46895,7 +46423,6 @@ func (s *ImportImageInput) SetRoleName(v string) *ImportImageInput { } // Contains the output for ImportImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageResult type ImportImageOutput struct { _ struct{} `type:"structure"` @@ -47010,7 +46537,6 @@ func (s *ImportImageOutput) SetStatusMessage(v string) *ImportImageOutput { } // Describes an import image task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportImageTask type ImportImageTask struct { _ struct{} `type:"structure"` @@ -47129,7 +46655,6 @@ func (s *ImportImageTask) SetStatusMessage(v string) *ImportImageTask { } // Contains the parameters for ImportInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceRequest type ImportInstanceInput struct { _ struct{} `type:"structure"` @@ -47218,7 +46743,6 @@ func (s *ImportInstanceInput) SetPlatform(v string) *ImportInstanceInput { } // Describes the launch specification for VM import. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceLaunchSpecification type ImportInstanceLaunchSpecification struct { _ struct{} `type:"structure"` @@ -47338,7 +46862,6 @@ func (s *ImportInstanceLaunchSpecification) SetUserData(v *UserData) *ImportInst } // Contains the output for ImportInstance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceResult type ImportInstanceOutput struct { _ struct{} `type:"structure"` @@ -47363,7 +46886,6 @@ func (s *ImportInstanceOutput) SetConversionTask(v *ConversionTask) *ImportInsta } // Describes an import instance task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceTaskDetails type ImportInstanceTaskDetails struct { _ struct{} `type:"structure"` @@ -47417,7 +46939,6 @@ func (s *ImportInstanceTaskDetails) SetVolumes(v []*ImportInstanceVolumeDetailIt } // Describes an import volume task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportInstanceVolumeDetailItem type ImportInstanceVolumeDetailItem struct { _ struct{} `type:"structure"` @@ -47506,7 +47027,6 @@ func (s *ImportInstanceVolumeDetailItem) SetVolume(v *DiskImageVolumeDescription } // Contains the parameters for ImportKeyPair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPairRequest type ImportKeyPairInput struct { _ struct{} `type:"structure"` @@ -47575,7 +47095,6 @@ func (s *ImportKeyPairInput) SetPublicKeyMaterial(v []byte) *ImportKeyPairInput } // Contains the output of ImportKeyPair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportKeyPairResult type ImportKeyPairOutput struct { _ struct{} `type:"structure"` @@ -47609,7 +47128,6 @@ func (s *ImportKeyPairOutput) SetKeyName(v string) *ImportKeyPairOutput { } // Contains the parameters for ImportSnapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotRequest type ImportSnapshotInput struct { _ struct{} `type:"structure"` @@ -47682,7 +47200,6 @@ func (s *ImportSnapshotInput) SetRoleName(v string) *ImportSnapshotInput { } // Contains the output for ImportSnapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotResult type ImportSnapshotOutput struct { _ struct{} `type:"structure"` @@ -47725,7 +47242,6 @@ func (s *ImportSnapshotOutput) SetSnapshotTaskDetail(v *SnapshotTaskDetail) *Imp } // Describes an import snapshot task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportSnapshotTask type ImportSnapshotTask struct { _ struct{} `type:"structure"` @@ -47768,7 +47284,6 @@ func (s *ImportSnapshotTask) SetSnapshotTaskDetail(v *SnapshotTaskDetail) *Impor } // Contains the parameters for ImportVolume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeRequest type ImportVolumeInput struct { _ struct{} `type:"structure"` @@ -47867,7 +47382,6 @@ func (s *ImportVolumeInput) SetVolume(v *VolumeDetail) *ImportVolumeInput { } // Contains the output for ImportVolume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeResult type ImportVolumeOutput struct { _ struct{} `type:"structure"` @@ -47892,7 +47406,6 @@ func (s *ImportVolumeOutput) SetConversionTask(v *ConversionTask) *ImportVolumeO } // Describes an import volume task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ImportVolumeTaskDetails type ImportVolumeTaskDetails struct { _ struct{} `type:"structure"` @@ -47961,7 +47474,6 @@ func (s *ImportVolumeTaskDetails) SetVolume(v *DiskImageVolumeDescription) *Impo } // Describes an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Instance type Instance struct { _ struct{} `type:"structure"` @@ -48350,7 +47862,6 @@ func (s *Instance) SetVpcId(v string) *Instance { } // Describes a block device mapping. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceBlockDeviceMapping type InstanceBlockDeviceMapping struct { _ struct{} `type:"structure"` @@ -48385,7 +47896,6 @@ func (s *InstanceBlockDeviceMapping) SetEbs(v *EbsInstanceBlockDevice) *Instance } // Describes a block device mapping entry. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceBlockDeviceMappingSpecification type InstanceBlockDeviceMappingSpecification struct { _ struct{} `type:"structure"` @@ -48438,7 +47948,6 @@ func (s *InstanceBlockDeviceMappingSpecification) SetVirtualName(v string) *Inst } // Information about the instance type that the Dedicated Host supports. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCapacity type InstanceCapacity struct { _ struct{} `type:"structure"` @@ -48481,7 +47990,6 @@ func (s *InstanceCapacity) SetTotalCapacity(v int64) *InstanceCapacity { } // Describes a Reserved Instance listing state. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCount type InstanceCount struct { _ struct{} `type:"structure"` @@ -48515,7 +48023,6 @@ func (s *InstanceCount) SetState(v string) *InstanceCount { } // Describes the credit option for CPU usage of a T2 instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCreditSpecification type InstanceCreditSpecification struct { _ struct{} `type:"structure"` @@ -48550,7 +48057,6 @@ func (s *InstanceCreditSpecification) SetInstanceId(v string) *InstanceCreditSpe } // Describes the credit option for CPU usage of a T2 instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceCreditSpecificationRequest type InstanceCreditSpecificationRequest struct { _ struct{} `type:"structure"` @@ -48585,7 +48091,6 @@ func (s *InstanceCreditSpecificationRequest) SetInstanceId(v string) *InstanceCr } // Describes an instance to export. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceExportDetails type InstanceExportDetails struct { _ struct{} `type:"structure"` @@ -48619,7 +48124,6 @@ func (s *InstanceExportDetails) SetTargetEnvironment(v string) *InstanceExportDe } // Describes an IPv6 address. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceIpv6Address type InstanceIpv6Address struct { _ struct{} `type:"structure"` @@ -48644,7 +48148,6 @@ func (s *InstanceIpv6Address) SetIpv6Address(v string) *InstanceIpv6Address { } // Describes an IPv6 address. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceIpv6AddressRequest type InstanceIpv6AddressRequest struct { _ struct{} `type:"structure"` @@ -48669,7 +48172,6 @@ func (s *InstanceIpv6AddressRequest) SetIpv6Address(v string) *InstanceIpv6Addre } // Describes the market (purchasing) option for the instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceMarketOptionsRequest type InstanceMarketOptionsRequest struct { _ struct{} `type:"structure"` @@ -48703,7 +48205,6 @@ func (s *InstanceMarketOptionsRequest) SetSpotOptions(v *SpotMarketOptions) *Ins } // Describes the monitoring of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceMonitoring type InstanceMonitoring struct { _ struct{} `type:"structure"` @@ -48737,7 +48238,6 @@ func (s *InstanceMonitoring) SetMonitoring(v *Monitoring) *InstanceMonitoring { } // Describes a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterface type InstanceNetworkInterface struct { _ struct{} `type:"structure"` @@ -48889,7 +48389,6 @@ func (s *InstanceNetworkInterface) SetVpcId(v string) *InstanceNetworkInterface } // Describes association information for an Elastic IP address (IPv4). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceAssociation type InstanceNetworkInterfaceAssociation struct { _ struct{} `type:"structure"` @@ -48932,7 +48431,6 @@ func (s *InstanceNetworkInterfaceAssociation) SetPublicIp(v string) *InstanceNet } // Describes a network interface attachment. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceAttachment type InstanceNetworkInterfaceAttachment struct { _ struct{} `type:"structure"` @@ -48993,7 +48491,6 @@ func (s *InstanceNetworkInterfaceAttachment) SetStatus(v string) *InstanceNetwor } // Describes a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceNetworkInterfaceSpecification type InstanceNetworkInterfaceSpecification struct { _ struct{} `type:"structure"` @@ -49163,7 +48660,6 @@ func (s *InstanceNetworkInterfaceSpecification) SetSubnetId(v string) *InstanceN } // Describes a private IPv4 address. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstancePrivateIpAddress type InstancePrivateIpAddress struct { _ struct{} `type:"structure"` @@ -49216,7 +48712,6 @@ func (s *InstancePrivateIpAddress) SetPrivateIpAddress(v string) *InstancePrivat } // Describes the current state of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceState type InstanceState struct { _ struct{} `type:"structure"` @@ -49263,7 +48758,6 @@ func (s *InstanceState) SetName(v string) *InstanceState { } // Describes an instance state change. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStateChange type InstanceStateChange struct { _ struct{} `type:"structure"` @@ -49306,7 +48800,6 @@ func (s *InstanceStateChange) SetPreviousState(v *InstanceState) *InstanceStateC } // Describes the status of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatus type InstanceStatus struct { _ struct{} `type:"structure"` @@ -49380,7 +48873,6 @@ func (s *InstanceStatus) SetSystemStatus(v *InstanceStatusSummary) *InstanceStat } // Describes the instance status. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusDetails type InstanceStatusDetails struct { _ struct{} `type:"structure"` @@ -49424,7 +48916,6 @@ func (s *InstanceStatusDetails) SetStatus(v string) *InstanceStatusDetails { } // Describes a scheduled event for an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusEvent type InstanceStatusEvent struct { _ struct{} `type:"structure"` @@ -49480,7 +48971,6 @@ func (s *InstanceStatusEvent) SetNotBefore(v time.Time) *InstanceStatusEvent { } // Describes the status of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InstanceStatusSummary type InstanceStatusSummary struct { _ struct{} `type:"structure"` @@ -49514,7 +49004,6 @@ func (s *InstanceStatusSummary) SetStatus(v string) *InstanceStatusSummary { } // Describes an Internet gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InternetGateway type InternetGateway struct { _ struct{} `type:"structure"` @@ -49558,7 +49047,6 @@ func (s *InternetGateway) SetTags(v []*Tag) *InternetGateway { // Describes the attachment of a VPC to an Internet gateway or an egress-only // Internet gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/InternetGatewayAttachment type InternetGatewayAttachment struct { _ struct{} `type:"structure"` @@ -49593,7 +49081,6 @@ func (s *InternetGatewayAttachment) SetVpcId(v string) *InternetGatewayAttachmen } // Describes a set of permissions for a security group rule. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IpPermission type IpPermission struct { _ struct{} `type:"structure"` @@ -49687,7 +49174,6 @@ func (s *IpPermission) SetUserIdGroupPairs(v []*UserIdGroupPair) *IpPermission { } // Describes an IPv4 range. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/IpRange type IpRange struct { _ struct{} `type:"structure"` @@ -49726,7 +49212,6 @@ func (s *IpRange) SetDescription(v string) *IpRange { } // Describes an IPv6 CIDR block. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Ipv6CidrBlock type Ipv6CidrBlock struct { _ struct{} `type:"structure"` @@ -49751,7 +49236,6 @@ func (s *Ipv6CidrBlock) SetIpv6CidrBlock(v string) *Ipv6CidrBlock { } // [EC2-VPC only] Describes an IPv6 range. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Ipv6Range type Ipv6Range struct { _ struct{} `type:"structure"` @@ -49790,7 +49274,6 @@ func (s *Ipv6Range) SetDescription(v string) *Ipv6Range { } // Describes a key pair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/KeyPairInfo type KeyPairInfo struct { _ struct{} `type:"structure"` @@ -49827,7 +49310,6 @@ func (s *KeyPairInfo) SetKeyName(v string) *KeyPairInfo { } // Describes a launch permission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchPermission type LaunchPermission struct { _ struct{} `type:"structure"` @@ -49861,7 +49343,6 @@ func (s *LaunchPermission) SetUserId(v string) *LaunchPermission { } // Describes a launch permission modification. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchPermissionModifications type LaunchPermissionModifications struct { _ struct{} `type:"structure"` @@ -49896,7 +49377,6 @@ func (s *LaunchPermissionModifications) SetRemove(v []*LaunchPermission) *Launch } // Describes the launch specification for an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchSpecification type LaunchSpecification struct { _ struct{} `type:"structure"` @@ -50058,7 +49538,6 @@ func (s *LaunchSpecification) SetUserData(v string) *LaunchSpecification { } // Describes a launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplate type LaunchTemplate struct { _ struct{} `type:"structure"` @@ -50137,7 +49616,6 @@ func (s *LaunchTemplate) SetTags(v []*Tag) *LaunchTemplate { } // Describes a block device mapping. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateBlockDeviceMapping type LaunchTemplateBlockDeviceMapping struct { _ struct{} `type:"structure"` @@ -50190,7 +49668,6 @@ func (s *LaunchTemplateBlockDeviceMapping) SetVirtualName(v string) *LaunchTempl } // Describes a block device mapping. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateBlockDeviceMappingRequest type LaunchTemplateBlockDeviceMappingRequest struct { _ struct{} `type:"structure"` @@ -50248,7 +49725,6 @@ func (s *LaunchTemplateBlockDeviceMappingRequest) SetVirtualName(v string) *Laun } // Describes a launch template and overrides. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateConfig type LaunchTemplateConfig struct { _ struct{} `type:"structure"` @@ -50298,7 +49774,6 @@ func (s *LaunchTemplateConfig) SetOverrides(v []*LaunchTemplateOverrides) *Launc } // Describes a block device for an EBS volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateEbsBlockDevice type LaunchTemplateEbsBlockDevice struct { _ struct{} `type:"structure"` @@ -50377,7 +49852,6 @@ func (s *LaunchTemplateEbsBlockDevice) SetVolumeType(v string) *LaunchTemplateEb } // The parameters for a block device for an EBS volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateEbsBlockDeviceRequest type LaunchTemplateEbsBlockDeviceRequest struct { _ struct{} `type:"structure"` @@ -50470,7 +49944,6 @@ func (s *LaunchTemplateEbsBlockDeviceRequest) SetVolumeType(v string) *LaunchTem } // Describes an IAM instance profile. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateIamInstanceProfileSpecification type LaunchTemplateIamInstanceProfileSpecification struct { _ struct{} `type:"structure"` @@ -50504,7 +49977,6 @@ func (s *LaunchTemplateIamInstanceProfileSpecification) SetName(v string) *Launc } // An IAM instance profile. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateIamInstanceProfileSpecificationRequest type LaunchTemplateIamInstanceProfileSpecificationRequest struct { _ struct{} `type:"structure"` @@ -50538,7 +50010,6 @@ func (s *LaunchTemplateIamInstanceProfileSpecificationRequest) SetName(v string) } // The market (purchasing) option for the instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceMarketOptions type LaunchTemplateInstanceMarketOptions struct { _ struct{} `type:"structure"` @@ -50572,7 +50043,6 @@ func (s *LaunchTemplateInstanceMarketOptions) SetSpotOptions(v *LaunchTemplateSp } // The market (purchasing) option for the instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceMarketOptionsRequest type LaunchTemplateInstanceMarketOptionsRequest struct { _ struct{} `type:"structure"` @@ -50606,7 +50076,6 @@ func (s *LaunchTemplateInstanceMarketOptionsRequest) SetSpotOptions(v *LaunchTem } // Describes a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceNetworkInterfaceSpecification type LaunchTemplateInstanceNetworkInterfaceSpecification struct { _ struct{} `type:"structure"` @@ -50731,7 +50200,6 @@ func (s *LaunchTemplateInstanceNetworkInterfaceSpecification) SetSubnetId(v stri } // The parameters for a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateInstanceNetworkInterfaceSpecificationRequest type LaunchTemplateInstanceNetworkInterfaceSpecificationRequest struct { _ struct{} `type:"structure"` @@ -50878,7 +50346,6 @@ func (s *LaunchTemplateInstanceNetworkInterfaceSpecificationRequest) SetSubnetId } // Describes overrides for a launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateOverrides type LaunchTemplateOverrides struct { _ struct{} `type:"structure"` @@ -50939,7 +50406,6 @@ func (s *LaunchTemplateOverrides) SetWeightedCapacity(v float64) *LaunchTemplate } // Describes the placement of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatePlacement type LaunchTemplatePlacement struct { _ struct{} `type:"structure"` @@ -51010,7 +50476,6 @@ func (s *LaunchTemplatePlacement) SetTenancy(v string) *LaunchTemplatePlacement } // The placement for the instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatePlacementRequest type LaunchTemplatePlacementRequest struct { _ struct{} `type:"structure"` @@ -51082,7 +50547,6 @@ func (s *LaunchTemplatePlacementRequest) SetTenancy(v string) *LaunchTemplatePla // The launch template to use. You must specify either the launch template ID // or launch template name in the request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateSpecification type LaunchTemplateSpecification struct { _ struct{} `type:"structure"` @@ -51127,7 +50591,6 @@ func (s *LaunchTemplateSpecification) SetVersion(v string) *LaunchTemplateSpecif } // The options for Spot Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateSpotMarketOptions type LaunchTemplateSpotMarketOptions struct { _ struct{} `type:"structure"` @@ -51193,7 +50656,6 @@ func (s *LaunchTemplateSpotMarketOptions) SetValidUntil(v time.Time) *LaunchTemp } // The options for Spot Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateSpotMarketOptionsRequest type LaunchTemplateSpotMarketOptionsRequest struct { _ struct{} `type:"structure"` @@ -51260,7 +50722,6 @@ func (s *LaunchTemplateSpotMarketOptionsRequest) SetValidUntil(v time.Time) *Lau } // The tag specification for the launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateTagSpecification type LaunchTemplateTagSpecification struct { _ struct{} `type:"structure"` @@ -51294,7 +50755,6 @@ func (s *LaunchTemplateTagSpecification) SetTags(v []*Tag) *LaunchTemplateTagSpe } // The tags specification for the launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateTagSpecificationRequest type LaunchTemplateTagSpecificationRequest struct { _ struct{} `type:"structure"` @@ -51329,7 +50789,6 @@ func (s *LaunchTemplateTagSpecificationRequest) SetTags(v []*Tag) *LaunchTemplat } // Describes a launch template version. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplateVersion type LaunchTemplateVersion struct { _ struct{} `type:"structure"` @@ -51417,7 +50876,6 @@ func (s *LaunchTemplateVersion) SetVersionNumber(v int64) *LaunchTemplateVersion } // Describes the monitoring for the instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatesMonitoring type LaunchTemplatesMonitoring struct { _ struct{} `type:"structure"` @@ -51443,7 +50901,6 @@ func (s *LaunchTemplatesMonitoring) SetEnabled(v bool) *LaunchTemplatesMonitorin } // Describes the monitoring for the instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LaunchTemplatesMonitoringRequest type LaunchTemplatesMonitoringRequest struct { _ struct{} `type:"structure"` @@ -51470,7 +50927,6 @@ func (s *LaunchTemplatesMonitoringRequest) SetEnabled(v bool) *LaunchTemplatesMo // Describes the Classic Load Balancers and target groups to attach to a Spot // Fleet request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadBalancersConfig type LoadBalancersConfig struct { _ struct{} `type:"structure"` @@ -51524,7 +50980,6 @@ func (s *LoadBalancersConfig) SetTargetGroupsConfig(v *TargetGroupsConfig) *Load } // Describes a load permission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadPermission type LoadPermission struct { _ struct{} `type:"structure"` @@ -51558,7 +51013,6 @@ func (s *LoadPermission) SetUserId(v string) *LoadPermission { } // Describes modifications to the load permissions of an Amazon FPGA image (AFI). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadPermissionModifications type LoadPermissionModifications struct { _ struct{} `type:"structure"` @@ -51592,7 +51046,6 @@ func (s *LoadPermissionModifications) SetRemove(v []*LoadPermissionRequest) *Loa } // Describes a load permission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/LoadPermissionRequest type LoadPermissionRequest struct { _ struct{} `type:"structure"` @@ -51625,7 +51078,6 @@ func (s *LoadPermissionRequest) SetUserId(v string) *LoadPermissionRequest { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyFpgaImageAttributeRequest type ModifyFpgaImageAttributeInput struct { _ struct{} `type:"structure"` @@ -51752,7 +51204,6 @@ func (s *ModifyFpgaImageAttributeInput) SetUserIds(v []*string) *ModifyFpgaImage return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyFpgaImageAttributeResult type ModifyFpgaImageAttributeOutput struct { _ struct{} `type:"structure"` @@ -51777,7 +51228,6 @@ func (s *ModifyFpgaImageAttributeOutput) SetFpgaImageAttribute(v *FpgaImageAttri } // Contains the parameters for ModifyHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHostsRequest type ModifyHostsInput struct { _ struct{} `type:"structure"` @@ -51831,7 +51281,6 @@ func (s *ModifyHostsInput) SetHostIds(v []*string) *ModifyHostsInput { } // Contains the output of ModifyHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyHostsResult type ModifyHostsOutput struct { _ struct{} `type:"structure"` @@ -51866,7 +51315,6 @@ func (s *ModifyHostsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *ModifyHostsO } // Contains the parameters of ModifyIdFormat. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormatRequest type ModifyIdFormatInput struct { _ struct{} `type:"structure"` @@ -51919,7 +51367,6 @@ func (s *ModifyIdFormatInput) SetUseLongIds(v bool) *ModifyIdFormatInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdFormatOutput type ModifyIdFormatOutput struct { _ struct{} `type:"structure"` } @@ -51935,7 +51382,6 @@ func (s ModifyIdFormatOutput) GoString() string { } // Contains the parameters of ModifyIdentityIdFormat. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormatRequest type ModifyIdentityIdFormatInput struct { _ struct{} `type:"structure"` @@ -52004,7 +51450,6 @@ func (s *ModifyIdentityIdFormatInput) SetUseLongIds(v bool) *ModifyIdentityIdFor return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyIdentityIdFormatOutput type ModifyIdentityIdFormatOutput struct { _ struct{} `type:"structure"` } @@ -52020,7 +51465,6 @@ func (s ModifyIdentityIdFormatOutput) GoString() string { } // Contains the parameters for ModifyImageAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttributeRequest type ModifyImageAttributeInput struct { _ struct{} `type:"structure"` @@ -52149,7 +51593,6 @@ func (s *ModifyImageAttributeInput) SetValue(v string) *ModifyImageAttributeInpu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyImageAttributeOutput type ModifyImageAttributeOutput struct { _ struct{} `type:"structure"` } @@ -52165,7 +51608,6 @@ func (s ModifyImageAttributeOutput) GoString() string { } // Contains the parameters for ModifyInstanceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttributeRequest type ModifyInstanceAttributeInput struct { _ struct{} `type:"structure"` @@ -52381,7 +51823,6 @@ func (s *ModifyInstanceAttributeInput) SetValue(v string) *ModifyInstanceAttribu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceAttributeOutput type ModifyInstanceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -52396,7 +51837,6 @@ func (s ModifyInstanceAttributeOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceCreditSpecificationRequest type ModifyInstanceCreditSpecificationInput struct { _ struct{} `type:"structure"` @@ -52458,7 +51898,6 @@ func (s *ModifyInstanceCreditSpecificationInput) SetInstanceCreditSpecifications return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstanceCreditSpecificationResult type ModifyInstanceCreditSpecificationOutput struct { _ struct{} `type:"structure"` @@ -52494,7 +51933,6 @@ func (s *ModifyInstanceCreditSpecificationOutput) SetUnsuccessfulInstanceCreditS } // Contains the parameters for ModifyInstancePlacement. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacementRequest type ModifyInstancePlacementInput struct { _ struct{} `type:"structure"` @@ -52561,7 +51999,6 @@ func (s *ModifyInstancePlacementInput) SetTenancy(v string) *ModifyInstancePlace } // Contains the output of ModifyInstancePlacement. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyInstancePlacementResult type ModifyInstancePlacementOutput struct { _ struct{} `type:"structure"` @@ -52585,7 +52022,6 @@ func (s *ModifyInstancePlacementOutput) SetReturn(v bool) *ModifyInstancePlaceme return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyLaunchTemplateRequest type ModifyLaunchTemplateInput struct { _ struct{} `type:"structure"` @@ -52664,7 +52100,6 @@ func (s *ModifyLaunchTemplateInput) SetLaunchTemplateName(v string) *ModifyLaunc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyLaunchTemplateResult type ModifyLaunchTemplateOutput struct { _ struct{} `type:"structure"` @@ -52689,7 +52124,6 @@ func (s *ModifyLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *Modif } // Contains the parameters for ModifyNetworkInterfaceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttributeRequest type ModifyNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` @@ -52784,7 +52218,6 @@ func (s *ModifyNetworkInterfaceAttributeInput) SetSourceDestCheck(v *AttributeBo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyNetworkInterfaceAttributeOutput type ModifyNetworkInterfaceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -52800,7 +52233,6 @@ func (s ModifyNetworkInterfaceAttributeOutput) GoString() string { } // Contains the parameters for ModifyReservedInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstancesRequest type ModifyReservedInstancesInput struct { _ struct{} `type:"structure"` @@ -52864,7 +52296,6 @@ func (s *ModifyReservedInstancesInput) SetTargetConfigurations(v []*ReservedInst } // Contains the output of ModifyReservedInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyReservedInstancesResult type ModifyReservedInstancesOutput struct { _ struct{} `type:"structure"` @@ -52889,7 +52320,6 @@ func (s *ModifyReservedInstancesOutput) SetReservedInstancesModificationId(v str } // Contains the parameters for ModifySnapshotAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttributeRequest type ModifySnapshotAttributeInput struct { _ struct{} `type:"structure"` @@ -52987,7 +52417,6 @@ func (s *ModifySnapshotAttributeInput) SetUserIds(v []*string) *ModifySnapshotAt return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySnapshotAttributeOutput type ModifySnapshotAttributeOutput struct { _ struct{} `type:"structure"` } @@ -53003,7 +52432,6 @@ func (s ModifySnapshotAttributeOutput) GoString() string { } // Contains the parameters for ModifySpotFleetRequest. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequestRequest type ModifySpotFleetRequestInput struct { _ struct{} `type:"structure"` @@ -53063,7 +52491,6 @@ func (s *ModifySpotFleetRequestInput) SetTargetCapacity(v int64) *ModifySpotFlee } // Contains the output of ModifySpotFleetRequest. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySpotFleetRequestResponse type ModifySpotFleetRequestOutput struct { _ struct{} `type:"structure"` @@ -53088,7 +52515,6 @@ func (s *ModifySpotFleetRequestOutput) SetReturn(v bool) *ModifySpotFleetRequest } // Contains the parameters for ModifySubnetAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttributeRequest type ModifySubnetAttributeInput struct { _ struct{} `type:"structure"` @@ -53155,7 +52581,6 @@ func (s *ModifySubnetAttributeInput) SetSubnetId(v string) *ModifySubnetAttribut return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifySubnetAttributeOutput type ModifySubnetAttributeOutput struct { _ struct{} `type:"structure"` } @@ -53171,7 +52596,6 @@ func (s ModifySubnetAttributeOutput) GoString() string { } // Contains the parameters for ModifyVolumeAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttributeRequest type ModifyVolumeAttributeInput struct { _ struct{} `type:"structure"` @@ -53231,7 +52655,6 @@ func (s *ModifyVolumeAttributeInput) SetVolumeId(v string) *ModifyVolumeAttribut return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeAttributeOutput type ModifyVolumeAttributeOutput struct { _ struct{} `type:"structure"` } @@ -53246,7 +52669,6 @@ func (s ModifyVolumeAttributeOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeRequest type ModifyVolumeInput struct { _ struct{} `type:"structure"` @@ -53338,7 +52760,6 @@ func (s *ModifyVolumeInput) SetVolumeType(v string) *ModifyVolumeInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVolumeResult type ModifyVolumeOutput struct { _ struct{} `type:"structure"` @@ -53363,7 +52784,6 @@ func (s *ModifyVolumeOutput) SetVolumeModification(v *VolumeModification) *Modif } // Contains the parameters for ModifyVpcAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttributeRequest type ModifyVpcAttributeInput struct { _ struct{} `type:"structure"` @@ -53432,7 +52852,6 @@ func (s *ModifyVpcAttributeInput) SetVpcId(v string) *ModifyVpcAttributeInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcAttributeOutput type ModifyVpcAttributeOutput struct { _ struct{} `type:"structure"` } @@ -53447,7 +52866,6 @@ func (s ModifyVpcAttributeOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointConnectionNotificationRequest type ModifyVpcEndpointConnectionNotificationInput struct { _ struct{} `type:"structure"` @@ -53517,7 +52935,6 @@ func (s *ModifyVpcEndpointConnectionNotificationInput) SetDryRun(v bool) *Modify return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointConnectionNotificationResult type ModifyVpcEndpointConnectionNotificationOutput struct { _ struct{} `type:"structure"` @@ -53542,7 +52959,6 @@ func (s *ModifyVpcEndpointConnectionNotificationOutput) SetReturnValue(v bool) * } // Contains the parameters for ModifyVpcEndpoint. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointRequest type ModifyVpcEndpointInput struct { _ struct{} `type:"structure"` @@ -53679,7 +53095,6 @@ func (s *ModifyVpcEndpointInput) SetVpcEndpointId(v string) *ModifyVpcEndpointIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointResult type ModifyVpcEndpointOutput struct { _ struct{} `type:"structure"` @@ -53703,7 +53118,6 @@ func (s *ModifyVpcEndpointOutput) SetReturn(v bool) *ModifyVpcEndpointOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServiceConfigurationRequest type ModifyVpcEndpointServiceConfigurationInput struct { _ struct{} `type:"structure"` @@ -53783,7 +53197,6 @@ func (s *ModifyVpcEndpointServiceConfigurationInput) SetServiceId(v string) *Mod return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServiceConfigurationResult type ModifyVpcEndpointServiceConfigurationOutput struct { _ struct{} `type:"structure"` @@ -53807,7 +53220,6 @@ func (s *ModifyVpcEndpointServiceConfigurationOutput) SetReturn(v bool) *ModifyV return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServicePermissionsRequest type ModifyVpcEndpointServicePermissionsInput struct { _ struct{} `type:"structure"` @@ -53878,7 +53290,6 @@ func (s *ModifyVpcEndpointServicePermissionsInput) SetServiceId(v string) *Modif return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcEndpointServicePermissionsResult type ModifyVpcEndpointServicePermissionsOutput struct { _ struct{} `type:"structure"` @@ -53902,7 +53313,6 @@ func (s *ModifyVpcEndpointServicePermissionsOutput) SetReturnValue(v bool) *Modi return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptionsRequest type ModifyVpcPeeringConnectionOptionsInput struct { _ struct{} `type:"structure"` @@ -53971,7 +53381,6 @@ func (s *ModifyVpcPeeringConnectionOptionsInput) SetVpcPeeringConnectionId(v str return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcPeeringConnectionOptionsResult type ModifyVpcPeeringConnectionOptionsOutput struct { _ struct{} `type:"structure"` @@ -54005,7 +53414,6 @@ func (s *ModifyVpcPeeringConnectionOptionsOutput) SetRequesterPeeringConnectionO } // Contains the parameters for ModifyVpcTenancy. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcTenancyRequest type ModifyVpcTenancyInput struct { _ struct{} `type:"structure"` @@ -54071,7 +53479,6 @@ func (s *ModifyVpcTenancyInput) SetVpcId(v string) *ModifyVpcTenancyInput { } // Contains the output of ModifyVpcTenancy. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ModifyVpcTenancyResult type ModifyVpcTenancyOutput struct { _ struct{} `type:"structure"` @@ -54096,7 +53503,6 @@ func (s *ModifyVpcTenancyOutput) SetReturnValue(v bool) *ModifyVpcTenancyOutput } // Contains the parameters for MonitorInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstancesRequest type MonitorInstancesInput struct { _ struct{} `type:"structure"` @@ -54148,7 +53554,6 @@ func (s *MonitorInstancesInput) SetInstanceIds(v []*string) *MonitorInstancesInp } // Contains the output of MonitorInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MonitorInstancesResult type MonitorInstancesOutput struct { _ struct{} `type:"structure"` @@ -54173,7 +53578,6 @@ func (s *MonitorInstancesOutput) SetInstanceMonitorings(v []*InstanceMonitoring) } // Describes the monitoring of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Monitoring type Monitoring struct { _ struct{} `type:"structure"` @@ -54199,7 +53603,6 @@ func (s *Monitoring) SetState(v string) *Monitoring { } // Contains the parameters for MoveAddressToVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpcRequest type MoveAddressToVpcInput struct { _ struct{} `type:"structure"` @@ -54251,7 +53654,6 @@ func (s *MoveAddressToVpcInput) SetPublicIp(v string) *MoveAddressToVpcInput { } // Contains the output of MoveAddressToVpc. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MoveAddressToVpcResult type MoveAddressToVpcOutput struct { _ struct{} `type:"structure"` @@ -54285,7 +53687,6 @@ func (s *MoveAddressToVpcOutput) SetStatus(v string) *MoveAddressToVpcOutput { } // Describes the status of a moving Elastic IP address. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/MovingAddressStatus type MovingAddressStatus struct { _ struct{} `type:"structure"` @@ -54320,7 +53721,6 @@ func (s *MovingAddressStatus) SetPublicIp(v string) *MovingAddressStatus { } // Describes a NAT gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NatGateway type NatGateway struct { _ struct{} `type:"structure"` @@ -54475,7 +53875,6 @@ func (s *NatGateway) SetVpcId(v string) *NatGateway { } // Describes the IP addresses and network interface associated with a NAT gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NatGatewayAddress type NatGatewayAddress struct { _ struct{} `type:"structure"` @@ -54528,7 +53927,6 @@ func (s *NatGatewayAddress) SetPublicIp(v string) *NatGatewayAddress { } // Describes a network ACL. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAcl type NetworkAcl struct { _ struct{} `type:"structure"` @@ -54598,7 +53996,6 @@ func (s *NetworkAcl) SetVpcId(v string) *NetworkAcl { } // Describes an association between a network ACL and a subnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAclAssociation type NetworkAclAssociation struct { _ struct{} `type:"structure"` @@ -54641,7 +54038,6 @@ func (s *NetworkAclAssociation) SetSubnetId(v string) *NetworkAclAssociation { } // Describes an entry in a network ACL. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkAclEntry type NetworkAclEntry struct { _ struct{} `type:"structure"` @@ -54731,7 +54127,6 @@ func (s *NetworkAclEntry) SetRuleNumber(v int64) *NetworkAclEntry { } // Describes a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterface type NetworkInterface struct { _ struct{} `type:"structure"` @@ -54929,7 +54324,6 @@ func (s *NetworkInterface) SetVpcId(v string) *NetworkInterface { } // Describes association information for an Elastic IP address (IPv4 only). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAssociation type NetworkInterfaceAssociation struct { _ struct{} `type:"structure"` @@ -54990,7 +54384,6 @@ func (s *NetworkInterfaceAssociation) SetPublicIp(v string) *NetworkInterfaceAss } // Describes a network interface attachment. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAttachment type NetworkInterfaceAttachment struct { _ struct{} `type:"structure"` @@ -55069,7 +54462,6 @@ func (s *NetworkInterfaceAttachment) SetStatus(v string) *NetworkInterfaceAttach } // Describes an attachment change. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceAttachmentChanges type NetworkInterfaceAttachmentChanges struct { _ struct{} `type:"structure"` @@ -55103,7 +54495,6 @@ func (s *NetworkInterfaceAttachmentChanges) SetDeleteOnTermination(v bool) *Netw } // Describes an IPv6 address associated with a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfaceIpv6Address type NetworkInterfaceIpv6Address struct { _ struct{} `type:"structure"` @@ -55128,7 +54519,6 @@ func (s *NetworkInterfaceIpv6Address) SetIpv6Address(v string) *NetworkInterface } // Describes a permission for a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermission type NetworkInterfacePermission struct { _ struct{} `type:"structure"` @@ -55198,7 +54588,6 @@ func (s *NetworkInterfacePermission) SetPermissionState(v *NetworkInterfacePermi } // Describes the state of a network interface permission. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePermissionState type NetworkInterfacePermissionState struct { _ struct{} `type:"structure"` @@ -55232,7 +54621,6 @@ func (s *NetworkInterfacePermissionState) SetStatusMessage(v string) *NetworkInt } // Describes the private IPv4 address of a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NetworkInterfacePrivateIpAddress type NetworkInterfacePrivateIpAddress struct { _ struct{} `type:"structure"` @@ -55285,7 +54673,6 @@ func (s *NetworkInterfacePrivateIpAddress) SetPrivateIpAddress(v string) *Networ return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/NewDhcpConfiguration type NewDhcpConfiguration struct { _ struct{} `type:"structure"` @@ -55318,7 +54705,6 @@ func (s *NewDhcpConfiguration) SetValues(v []*string) *NewDhcpConfiguration { // Describes the data that identifies an Amazon FPGA image (AFI) on the PCI // bus. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PciId type PciId struct { _ struct{} `type:"structure"` @@ -55370,7 +54756,6 @@ func (s *PciId) SetVendorId(v string) *PciId { } // Describes the VPC peering connection options. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptions type PeeringConnectionOptions struct { _ struct{} `type:"structure"` @@ -55416,7 +54801,6 @@ func (s *PeeringConnectionOptions) SetAllowEgressFromLocalVpcToRemoteClassicLink } // The VPC peering connection options. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PeeringConnectionOptionsRequest type PeeringConnectionOptionsRequest struct { _ struct{} `type:"structure"` @@ -55462,7 +54846,6 @@ func (s *PeeringConnectionOptionsRequest) SetAllowEgressFromLocalVpcToRemoteClas } // Describes the placement of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Placement type Placement struct { _ struct{} `type:"structure"` @@ -55536,7 +54919,6 @@ func (s *Placement) SetTenancy(v string) *Placement { } // Describes a placement group. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PlacementGroup type PlacementGroup struct { _ struct{} `type:"structure"` @@ -55579,7 +54961,6 @@ func (s *PlacementGroup) SetStrategy(v string) *PlacementGroup { } // Describes a range of ports. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PortRange type PortRange struct { _ struct{} `type:"structure"` @@ -55613,7 +54994,6 @@ func (s *PortRange) SetTo(v int64) *PortRange { } // Describes prefixes for AWS services. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrefixList type PrefixList struct { _ struct{} `type:"structure"` @@ -55656,7 +55036,6 @@ func (s *PrefixList) SetPrefixListName(v string) *PrefixList { } // [EC2-VPC only] The ID of the prefix. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrefixListId type PrefixListId struct { _ struct{} `type:"structure"` @@ -55694,7 +55073,6 @@ func (s *PrefixListId) SetPrefixListId(v string) *PrefixListId { } // Describes the price for a Reserved Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PriceSchedule type PriceSchedule struct { _ struct{} `type:"structure"` @@ -55757,7 +55135,6 @@ func (s *PriceSchedule) SetTerm(v int64) *PriceSchedule { } // Describes the price for a Reserved Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PriceScheduleSpecification type PriceScheduleSpecification struct { _ struct{} `type:"structure"` @@ -55802,7 +55179,6 @@ func (s *PriceScheduleSpecification) SetTerm(v int64) *PriceScheduleSpecificatio } // Describes a Reserved Instance offering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PricingDetail type PricingDetail struct { _ struct{} `type:"structure"` @@ -55836,7 +55212,6 @@ func (s *PricingDetail) SetPrice(v float64) *PricingDetail { } // Describes a secondary private IPv4 address for a network interface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PrivateIpAddressSpecification type PrivateIpAddressSpecification struct { _ struct{} `type:"structure"` @@ -55886,7 +55261,6 @@ func (s *PrivateIpAddressSpecification) SetPrivateIpAddress(v string) *PrivateIp } // Describes a product code. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ProductCode type ProductCode struct { _ struct{} `type:"structure"` @@ -55920,7 +55294,6 @@ func (s *ProductCode) SetProductCodeType(v string) *ProductCode { } // Describes a virtual private gateway propagating route. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PropagatingVgw type PropagatingVgw struct { _ struct{} `type:"structure"` @@ -55947,7 +55320,6 @@ func (s *PropagatingVgw) SetGatewayId(v string) *PropagatingVgw { // Reserved. If you need to sustain traffic greater than the documented limits // (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html), // contact us through the Support Center (https://console.aws.amazon.com/support/home?). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ProvisionedBandwidth type ProvisionedBandwidth struct { _ struct{} `type:"structure"` @@ -56018,7 +55390,6 @@ func (s *ProvisionedBandwidth) SetStatus(v string) *ProvisionedBandwidth { } // Describes the result of the purchase. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Purchase type Purchase struct { _ struct{} `type:"structure"` @@ -56107,7 +55478,6 @@ func (s *Purchase) SetUpfrontPrice(v string) *Purchase { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservationRequest type PurchaseHostReservationInput struct { _ struct{} `type:"structure"` @@ -56197,7 +55567,6 @@ func (s *PurchaseHostReservationInput) SetOfferingId(v string) *PurchaseHostRese return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseHostReservationResult type PurchaseHostReservationOutput struct { _ struct{} `type:"structure"` @@ -56262,7 +55631,6 @@ func (s *PurchaseHostReservationOutput) SetTotalUpfrontPrice(v string) *Purchase } // Describes a request to purchase Scheduled Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseRequest type PurchaseRequest struct { _ struct{} `type:"structure"` @@ -56316,7 +55684,6 @@ func (s *PurchaseRequest) SetPurchaseToken(v string) *PurchaseRequest { } // Contains the parameters for PurchaseReservedInstancesOffering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOfferingRequest type PurchaseReservedInstancesOfferingInput struct { _ struct{} `type:"structure"` @@ -56393,7 +55760,6 @@ func (s *PurchaseReservedInstancesOfferingInput) SetReservedInstancesOfferingId( } // Contains the output of PurchaseReservedInstancesOffering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseReservedInstancesOfferingResult type PurchaseReservedInstancesOfferingOutput struct { _ struct{} `type:"structure"` @@ -56418,7 +55784,6 @@ func (s *PurchaseReservedInstancesOfferingOutput) SetReservedInstancesId(v strin } // Contains the parameters for PurchaseScheduledInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstancesRequest type PurchaseScheduledInstancesInput struct { _ struct{} `type:"structure"` @@ -56493,7 +55858,6 @@ func (s *PurchaseScheduledInstancesInput) SetPurchaseRequests(v []*PurchaseReque } // Contains the output of PurchaseScheduledInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/PurchaseScheduledInstancesResult type PurchaseScheduledInstancesOutput struct { _ struct{} `type:"structure"` @@ -56518,7 +55882,6 @@ func (s *PurchaseScheduledInstancesOutput) SetScheduledInstanceSet(v []*Schedule } // Contains the parameters for RebootInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstancesRequest type RebootInstancesInput struct { _ struct{} `type:"structure"` @@ -56569,7 +55932,6 @@ func (s *RebootInstancesInput) SetInstanceIds(v []*string) *RebootInstancesInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RebootInstancesOutput type RebootInstancesOutput struct { _ struct{} `type:"structure"` } @@ -56585,7 +55947,6 @@ func (s RebootInstancesOutput) GoString() string { } // Describes a recurring charge. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RecurringCharge type RecurringCharge struct { _ struct{} `type:"structure"` @@ -56619,7 +55980,6 @@ func (s *RecurringCharge) SetFrequency(v string) *RecurringCharge { } // Describes a region. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Region type Region struct { _ struct{} `type:"structure"` @@ -56653,7 +56013,6 @@ func (s *Region) SetRegionName(v string) *Region { } // Contains the parameters for RegisterImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImageRequest type RegisterImageInput struct { _ struct{} `type:"structure"` @@ -56826,7 +56185,6 @@ func (s *RegisterImageInput) SetVirtualizationType(v string) *RegisterImageInput } // Contains the output of RegisterImage. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterImageResult type RegisterImageOutput struct { _ struct{} `type:"structure"` @@ -56850,7 +56208,6 @@ func (s *RegisterImageOutput) SetImageId(v string) *RegisterImageOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcEndpointConnectionsRequest type RejectVpcEndpointConnectionsInput struct { _ struct{} `type:"structure"` @@ -56915,7 +56272,6 @@ func (s *RejectVpcEndpointConnectionsInput) SetVpcEndpointIds(v []*string) *Reje return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcEndpointConnectionsResult type RejectVpcEndpointConnectionsOutput struct { _ struct{} `type:"structure"` @@ -56940,7 +56296,6 @@ func (s *RejectVpcEndpointConnectionsOutput) SetUnsuccessful(v []*UnsuccessfulIt } // Contains the parameters for RejectVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnectionRequest type RejectVpcPeeringConnectionInput struct { _ struct{} `type:"structure"` @@ -56992,7 +56347,6 @@ func (s *RejectVpcPeeringConnectionInput) SetVpcPeeringConnectionId(v string) *R } // Contains the output of RejectVpcPeeringConnection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RejectVpcPeeringConnectionResult type RejectVpcPeeringConnectionOutput struct { _ struct{} `type:"structure"` @@ -57017,7 +56371,6 @@ func (s *RejectVpcPeeringConnectionOutput) SetReturn(v bool) *RejectVpcPeeringCo } // Contains the parameters for ReleaseAddress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddressRequest type ReleaseAddressInput struct { _ struct{} `type:"structure"` @@ -57062,7 +56415,6 @@ func (s *ReleaseAddressInput) SetPublicIp(v string) *ReleaseAddressInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseAddressOutput type ReleaseAddressOutput struct { _ struct{} `type:"structure"` } @@ -57078,7 +56430,6 @@ func (s ReleaseAddressOutput) GoString() string { } // Contains the parameters for ReleaseHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHostsRequest type ReleaseHostsInput struct { _ struct{} `type:"structure"` @@ -57118,7 +56469,6 @@ func (s *ReleaseHostsInput) SetHostIds(v []*string) *ReleaseHostsInput { } // Contains the output of ReleaseHosts. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReleaseHostsResult type ReleaseHostsOutput struct { _ struct{} `type:"structure"` @@ -57152,7 +56502,6 @@ func (s *ReleaseHostsOutput) SetUnsuccessful(v []*UnsuccessfulItem) *ReleaseHost return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociationRequest type ReplaceIamInstanceProfileAssociationInput struct { _ struct{} `type:"structure"` @@ -57205,7 +56554,6 @@ func (s *ReplaceIamInstanceProfileAssociationInput) SetIamInstanceProfile(v *Iam return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceIamInstanceProfileAssociationResult type ReplaceIamInstanceProfileAssociationOutput struct { _ struct{} `type:"structure"` @@ -57230,7 +56578,6 @@ func (s *ReplaceIamInstanceProfileAssociationOutput) SetIamInstanceProfileAssoci } // Contains the parameters for ReplaceNetworkAclAssociation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociationRequest type ReplaceNetworkAclAssociationInput struct { _ struct{} `type:"structure"` @@ -57297,7 +56644,6 @@ func (s *ReplaceNetworkAclAssociationInput) SetNetworkAclId(v string) *ReplaceNe } // Contains the output of ReplaceNetworkAclAssociation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclAssociationResult type ReplaceNetworkAclAssociationOutput struct { _ struct{} `type:"structure"` @@ -57322,7 +56668,6 @@ func (s *ReplaceNetworkAclAssociationOutput) SetNewAssociationId(v string) *Repl } // Contains the parameters for ReplaceNetworkAclEntry. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntryRequest type ReplaceNetworkAclEntryInput struct { _ struct{} `type:"structure"` @@ -57475,7 +56820,6 @@ func (s *ReplaceNetworkAclEntryInput) SetRuleNumber(v int64) *ReplaceNetworkAclE return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceNetworkAclEntryOutput type ReplaceNetworkAclEntryOutput struct { _ struct{} `type:"structure"` } @@ -57491,7 +56835,6 @@ func (s ReplaceNetworkAclEntryOutput) GoString() string { } // Contains the parameters for ReplaceRoute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteRequest type ReplaceRouteInput struct { _ struct{} `type:"structure"` @@ -57616,7 +56959,6 @@ func (s *ReplaceRouteInput) SetVpcPeeringConnectionId(v string) *ReplaceRouteInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteOutput type ReplaceRouteOutput struct { _ struct{} `type:"structure"` } @@ -57632,7 +56974,6 @@ func (s ReplaceRouteOutput) GoString() string { } // Contains the parameters for ReplaceRouteTableAssociation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociationRequest type ReplaceRouteTableAssociationInput struct { _ struct{} `type:"structure"` @@ -57698,7 +57039,6 @@ func (s *ReplaceRouteTableAssociationInput) SetRouteTableId(v string) *ReplaceRo } // Contains the output of ReplaceRouteTableAssociation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReplaceRouteTableAssociationResult type ReplaceRouteTableAssociationOutput struct { _ struct{} `type:"structure"` @@ -57723,7 +57063,6 @@ func (s *ReplaceRouteTableAssociationOutput) SetNewAssociationId(v string) *Repl } // Contains the parameters for ReportInstanceStatus. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatusRequest type ReportInstanceStatusInput struct { _ struct{} `type:"structure"` @@ -57850,7 +57189,6 @@ func (s *ReportInstanceStatusInput) SetStatus(v string) *ReportInstanceStatusInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReportInstanceStatusOutput type ReportInstanceStatusOutput struct { _ struct{} `type:"structure"` } @@ -57866,7 +57204,6 @@ func (s ReportInstanceStatusOutput) GoString() string { } // The information to include in the launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestLaunchTemplateData type RequestLaunchTemplateData struct { _ struct{} `type:"structure"` @@ -58135,7 +57472,6 @@ func (s *RequestLaunchTemplateData) SetUserData(v string) *RequestLaunchTemplate } // Contains the parameters for RequestSpotFleet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleetRequest type RequestSpotFleetInput struct { _ struct{} `type:"structure"` @@ -58192,7 +57528,6 @@ func (s *RequestSpotFleetInput) SetSpotFleetRequestConfig(v *SpotFleetRequestCon } // Contains the output of RequestSpotFleet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotFleetResponse type RequestSpotFleetOutput struct { _ struct{} `type:"structure"` @@ -58219,7 +57554,6 @@ func (s *RequestSpotFleetOutput) SetSpotFleetRequestId(v string) *RequestSpotFle } // Contains the parameters for RequestSpotInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstancesRequest type RequestSpotInstancesInput struct { _ struct{} `type:"structure"` @@ -58407,7 +57741,6 @@ func (s *RequestSpotInstancesInput) SetValidUntil(v time.Time) *RequestSpotInsta } // Contains the output of RequestSpotInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotInstancesResult type RequestSpotInstancesOutput struct { _ struct{} `type:"structure"` @@ -58432,7 +57765,6 @@ func (s *RequestSpotInstancesOutput) SetSpotInstanceRequests(v []*SpotInstanceRe } // Describes the launch specification for an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RequestSpotLaunchSpecification type RequestSpotLaunchSpecification struct { _ struct{} `type:"structure"` @@ -58633,7 +57965,6 @@ func (s *RequestSpotLaunchSpecification) SetUserData(v string) *RequestSpotLaunc } // Describes a reservation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Reservation type Reservation struct { _ struct{} `type:"structure"` @@ -58695,7 +58026,6 @@ func (s *Reservation) SetReservationId(v string) *Reservation { } // The cost associated with the Reserved Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservationValue type ReservationValue struct { _ struct{} `type:"structure"` @@ -58739,7 +58069,6 @@ func (s *ReservationValue) SetRemainingUpfrontValue(v string) *ReservationValue } // Describes the limit price of a Reserved Instance offering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstanceLimitPrice type ReservedInstanceLimitPrice struct { _ struct{} `type:"structure"` @@ -58775,7 +58104,6 @@ func (s *ReservedInstanceLimitPrice) SetCurrencyCode(v string) *ReservedInstance } // The total value of the Convertible Reserved Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstanceReservationValue type ReservedInstanceReservationValue struct { _ struct{} `type:"structure"` @@ -58809,7 +58137,6 @@ func (s *ReservedInstanceReservationValue) SetReservedInstanceId(v string) *Rese } // Describes a Reserved Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstances type ReservedInstances struct { _ struct{} `type:"structure"` @@ -58988,7 +58315,6 @@ func (s *ReservedInstances) SetUsagePrice(v float64) *ReservedInstances { } // Describes the configuration settings for the modified Reserved Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesConfiguration type ReservedInstancesConfiguration struct { _ struct{} `type:"structure"` @@ -59051,7 +58377,6 @@ func (s *ReservedInstancesConfiguration) SetScope(v string) *ReservedInstancesCo } // Describes the ID of a Reserved Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesId type ReservedInstancesId struct { _ struct{} `type:"structure"` @@ -59076,7 +58401,6 @@ func (s *ReservedInstancesId) SetReservedInstancesId(v string) *ReservedInstance } // Describes a Reserved Instance listing. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesListing type ReservedInstancesListing struct { _ struct{} `type:"structure"` @@ -59184,7 +58508,6 @@ func (s *ReservedInstancesListing) SetUpdateDate(v time.Time) *ReservedInstances } // Describes a Reserved Instance modification. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesModification type ReservedInstancesModification struct { _ struct{} `type:"structure"` @@ -59283,7 +58606,6 @@ func (s *ReservedInstancesModification) SetUpdateDate(v time.Time) *ReservedInst } // Describes the modification request/s. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesModificationResult type ReservedInstancesModificationResult struct { _ struct{} `type:"structure"` @@ -59319,7 +58641,6 @@ func (s *ReservedInstancesModificationResult) SetTargetConfiguration(v *Reserved } // Describes a Reserved Instance offering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ReservedInstancesOffering type ReservedInstancesOffering struct { _ struct{} `type:"structure"` @@ -59477,7 +58798,6 @@ func (s *ReservedInstancesOffering) SetUsagePrice(v float64) *ReservedInstancesO return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetFpgaImageAttributeRequest type ResetFpgaImageAttributeInput struct { _ struct{} `type:"structure"` @@ -59537,7 +58857,6 @@ func (s *ResetFpgaImageAttributeInput) SetFpgaImageId(v string) *ResetFpgaImageA return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetFpgaImageAttributeResult type ResetFpgaImageAttributeOutput struct { _ struct{} `type:"structure"` @@ -59562,7 +58881,6 @@ func (s *ResetFpgaImageAttributeOutput) SetReturn(v bool) *ResetFpgaImageAttribu } // Contains the parameters for ResetImageAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttributeRequest type ResetImageAttributeInput struct { _ struct{} `type:"structure"` @@ -59628,7 +58946,6 @@ func (s *ResetImageAttributeInput) SetImageId(v string) *ResetImageAttributeInpu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetImageAttributeOutput type ResetImageAttributeOutput struct { _ struct{} `type:"structure"` } @@ -59644,7 +58961,6 @@ func (s ResetImageAttributeOutput) GoString() string { } // Contains the parameters for ResetInstanceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttributeRequest type ResetInstanceAttributeInput struct { _ struct{} `type:"structure"` @@ -59712,7 +59028,6 @@ func (s *ResetInstanceAttributeInput) SetInstanceId(v string) *ResetInstanceAttr return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetInstanceAttributeOutput type ResetInstanceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -59728,7 +59043,6 @@ func (s ResetInstanceAttributeOutput) GoString() string { } // Contains the parameters for ResetNetworkInterfaceAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttributeRequest type ResetNetworkInterfaceAttributeInput struct { _ struct{} `type:"structure"` @@ -59788,7 +59102,6 @@ func (s *ResetNetworkInterfaceAttributeInput) SetSourceDestCheck(v string) *Rese return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetNetworkInterfaceAttributeOutput type ResetNetworkInterfaceAttributeOutput struct { _ struct{} `type:"structure"` } @@ -59804,7 +59117,6 @@ func (s ResetNetworkInterfaceAttributeOutput) GoString() string { } // Contains the parameters for ResetSnapshotAttribute. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttributeRequest type ResetSnapshotAttributeInput struct { _ struct{} `type:"structure"` @@ -59870,7 +59182,6 @@ func (s *ResetSnapshotAttributeInput) SetSnapshotId(v string) *ResetSnapshotAttr return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResetSnapshotAttributeOutput type ResetSnapshotAttributeOutput struct { _ struct{} `type:"structure"` } @@ -59887,7 +59198,6 @@ func (s ResetSnapshotAttributeOutput) GoString() string { // Describes the error that's returned when you cannot delete a launch template // version. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResponseError type ResponseError struct { _ struct{} `type:"structure"` @@ -59921,7 +59231,6 @@ func (s *ResponseError) SetMessage(v string) *ResponseError { } // The information for a launch template. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ResponseLaunchTemplateData type ResponseLaunchTemplateData struct { _ struct{} `type:"structure"` @@ -60119,7 +59428,6 @@ func (s *ResponseLaunchTemplateData) SetUserData(v string) *ResponseLaunchTempla } // Contains the parameters for RestoreAddressToClassic. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassicRequest type RestoreAddressToClassicInput struct { _ struct{} `type:"structure"` @@ -60171,7 +59479,6 @@ func (s *RestoreAddressToClassicInput) SetPublicIp(v string) *RestoreAddressToCl } // Contains the output of RestoreAddressToClassic. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RestoreAddressToClassicResult type RestoreAddressToClassicOutput struct { _ struct{} `type:"structure"` @@ -60205,7 +59512,6 @@ func (s *RestoreAddressToClassicOutput) SetStatus(v string) *RestoreAddressToCla } // Contains the parameters for RevokeSecurityGroupEgress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgressRequest type RevokeSecurityGroupEgressInput struct { _ struct{} `type:"structure"` @@ -60323,7 +59629,6 @@ func (s *RevokeSecurityGroupEgressInput) SetToPort(v int64) *RevokeSecurityGroup return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupEgressOutput type RevokeSecurityGroupEgressOutput struct { _ struct{} `type:"structure"` } @@ -60339,7 +59644,6 @@ func (s RevokeSecurityGroupEgressOutput) GoString() string { } // Contains the parameters for RevokeSecurityGroupIngress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngressRequest type RevokeSecurityGroupIngressInput struct { _ struct{} `type:"structure"` @@ -60465,7 +59769,6 @@ func (s *RevokeSecurityGroupIngressInput) SetToPort(v int64) *RevokeSecurityGrou return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RevokeSecurityGroupIngressOutput type RevokeSecurityGroupIngressOutput struct { _ struct{} `type:"structure"` } @@ -60481,7 +59784,6 @@ func (s RevokeSecurityGroupIngressOutput) GoString() string { } // Describes a route in a route table. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Route type Route struct { _ struct{} `type:"structure"` @@ -60614,7 +59916,6 @@ func (s *Route) SetVpcPeeringConnectionId(v string) *Route { } // Describes a route table. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RouteTable type RouteTable struct { _ struct{} `type:"structure"` @@ -60684,7 +59985,6 @@ func (s *RouteTable) SetVpcId(v string) *RouteTable { } // Describes an association between a route table and a subnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RouteTableAssociation type RouteTableAssociation struct { _ struct{} `type:"structure"` @@ -60736,7 +60036,6 @@ func (s *RouteTableAssociation) SetSubnetId(v string) *RouteTableAssociation { } // Contains the parameters for RunInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstancesRequest type RunInstancesInput struct { _ struct{} `type:"structure"` @@ -61159,7 +60458,6 @@ func (s *RunInstancesInput) SetUserData(v string) *RunInstancesInput { } // Describes the monitoring of an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunInstancesMonitoringEnabled type RunInstancesMonitoringEnabled struct { _ struct{} `type:"structure"` @@ -61200,7 +60498,6 @@ func (s *RunInstancesMonitoringEnabled) SetEnabled(v bool) *RunInstancesMonitori } // Contains the parameters for RunScheduledInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstancesRequest type RunScheduledInstancesInput struct { _ struct{} `type:"structure"` @@ -61293,7 +60590,6 @@ func (s *RunScheduledInstancesInput) SetScheduledInstanceId(v string) *RunSchedu } // Contains the output of RunScheduledInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RunScheduledInstancesResult type RunScheduledInstancesOutput struct { _ struct{} `type:"structure"` @@ -61319,7 +60615,6 @@ func (s *RunScheduledInstancesOutput) SetInstanceIdSet(v []*string) *RunSchedule // Describes the storage parameters for S3 and S3 buckets for an instance store-backed // AMI. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/S3Storage type S3Storage struct { _ struct{} `type:"structure"` @@ -61387,7 +60682,6 @@ func (s *S3Storage) SetUploadPolicySignature(v string) *S3Storage { } // Describes a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstance type ScheduledInstance struct { _ struct{} `type:"structure"` @@ -61538,7 +60832,6 @@ func (s *ScheduledInstance) SetTotalScheduledInstanceHours(v int64) *ScheduledIn } // Describes a schedule that is available for your Scheduled Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceAvailability type ScheduledInstanceAvailability struct { _ struct{} `type:"structure"` @@ -61672,7 +60965,6 @@ func (s *ScheduledInstanceAvailability) SetTotalScheduledInstanceHours(v int64) } // Describes the recurring schedule for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceRecurrence type ScheduledInstanceRecurrence struct { _ struct{} `type:"structure"` @@ -61737,7 +61029,6 @@ func (s *ScheduledInstanceRecurrence) SetOccurrenceUnit(v string) *ScheduledInst } // Describes the recurring schedule for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstanceRecurrenceRequest type ScheduledInstanceRecurrenceRequest struct { _ struct{} `type:"structure"` @@ -61805,7 +61096,6 @@ func (s *ScheduledInstanceRecurrenceRequest) SetOccurrenceUnit(v string) *Schedu } // Describes a block device mapping for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesBlockDeviceMapping type ScheduledInstancesBlockDeviceMapping struct { _ struct{} `type:"structure"` @@ -61868,7 +61158,6 @@ func (s *ScheduledInstancesBlockDeviceMapping) SetVirtualName(v string) *Schedul } // Describes an EBS volume for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesEbs type ScheduledInstancesEbs struct { _ struct{} `type:"structure"` @@ -61957,7 +61246,6 @@ func (s *ScheduledInstancesEbs) SetVolumeType(v string) *ScheduledInstancesEbs { } // Describes an IAM instance profile for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesIamInstanceProfile type ScheduledInstancesIamInstanceProfile struct { _ struct{} `type:"structure"` @@ -61991,7 +61279,6 @@ func (s *ScheduledInstancesIamInstanceProfile) SetName(v string) *ScheduledInsta } // Describes an IPv6 address. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesIpv6Address type ScheduledInstancesIpv6Address struct { _ struct{} `type:"structure"` @@ -62020,7 +61307,6 @@ func (s *ScheduledInstancesIpv6Address) SetIpv6Address(v string) *ScheduledInsta // If you are launching the Scheduled Instance in EC2-VPC, you must specify // the ID of the subnet. You can specify the subnet using either SubnetId or // NetworkInterface. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesLaunchSpecification type ScheduledInstancesLaunchSpecification struct { _ struct{} `type:"structure"` @@ -62183,7 +61469,6 @@ func (s *ScheduledInstancesLaunchSpecification) SetUserData(v string) *Scheduled } // Describes whether monitoring is enabled for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesMonitoring type ScheduledInstancesMonitoring struct { _ struct{} `type:"structure"` @@ -62208,7 +61493,6 @@ func (s *ScheduledInstancesMonitoring) SetEnabled(v bool) *ScheduledInstancesMon } // Describes a network interface for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesNetworkInterface type ScheduledInstancesNetworkInterface struct { _ struct{} `type:"structure"` @@ -62337,7 +61621,6 @@ func (s *ScheduledInstancesNetworkInterface) SetSubnetId(v string) *ScheduledIns } // Describes the placement for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesPlacement type ScheduledInstancesPlacement struct { _ struct{} `type:"structure"` @@ -62371,7 +61654,6 @@ func (s *ScheduledInstancesPlacement) SetGroupName(v string) *ScheduledInstances } // Describes a private IPv4 address for a Scheduled Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ScheduledInstancesPrivateIpAddressConfig type ScheduledInstancesPrivateIpAddressConfig struct { _ struct{} `type:"structure"` @@ -62406,7 +61688,6 @@ func (s *ScheduledInstancesPrivateIpAddressConfig) SetPrivateIpAddress(v string) } // Describes a security group -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroup type SecurityGroup struct { _ struct{} `type:"structure"` @@ -62494,7 +61775,6 @@ func (s *SecurityGroup) SetVpcId(v string) *SecurityGroup { } // Describes a security group. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroupIdentifier type SecurityGroupIdentifier struct { _ struct{} `type:"structure"` @@ -62528,7 +61808,6 @@ func (s *SecurityGroupIdentifier) SetGroupName(v string) *SecurityGroupIdentifie } // Describes a VPC with a security group that references your security group. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SecurityGroupReference type SecurityGroupReference struct { _ struct{} `type:"structure"` @@ -62575,7 +61854,6 @@ func (s *SecurityGroupReference) SetVpcPeeringConnectionId(v string) *SecurityGr } // Describes a service configuration for a VPC endpoint service. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ServiceConfiguration type ServiceConfiguration struct { _ struct{} `type:"structure"` @@ -62673,7 +61951,6 @@ func (s *ServiceConfiguration) SetServiceType(v []*ServiceTypeDetail) *ServiceCo } // Describes a VPC endpoint service. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ServiceDetail type ServiceDetail struct { _ struct{} `type:"structure"` @@ -62762,7 +62039,6 @@ func (s *ServiceDetail) SetVpcEndpointPolicySupported(v bool) *ServiceDetail { } // Describes the type of service for a VPC endpoint. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/ServiceTypeDetail type ServiceTypeDetail struct { _ struct{} `type:"structure"` @@ -62788,7 +62064,6 @@ func (s *ServiceTypeDetail) SetServiceType(v string) *ServiceTypeDetail { // Describes the time period for a Scheduled Instance to start its first schedule. // The time period must span less than one day. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SlotDateTimeRangeRequest type SlotDateTimeRangeRequest struct { _ struct{} `type:"structure"` @@ -62844,7 +62119,6 @@ func (s *SlotDateTimeRangeRequest) SetLatestTime(v time.Time) *SlotDateTimeRange } // Describes the time period for a Scheduled Instance to start its first schedule. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SlotStartTimeRangeRequest type SlotStartTimeRangeRequest struct { _ struct{} `type:"structure"` @@ -62878,7 +62152,6 @@ func (s *SlotStartTimeRangeRequest) SetLatestTime(v time.Time) *SlotStartTimeRan } // Describes a snapshot. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Snapshot type Snapshot struct { _ struct{} `type:"structure"` @@ -63036,7 +62309,6 @@ func (s *Snapshot) SetVolumeSize(v int64) *Snapshot { } // Describes the snapshot created from the imported disk. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotDetail type SnapshotDetail struct { _ struct{} `type:"structure"` @@ -63142,7 +62414,6 @@ func (s *SnapshotDetail) SetUserBucket(v *UserBucketDetails) *SnapshotDetail { } // The disk container object for the import snapshot request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotDiskContainer type SnapshotDiskContainer struct { _ struct{} `type:"structure"` @@ -63197,7 +62468,6 @@ func (s *SnapshotDiskContainer) SetUserBucket(v *UserBucket) *SnapshotDiskContai } // Details about the import snapshot task. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SnapshotTaskDetail type SnapshotTaskDetail struct { _ struct{} `type:"structure"` @@ -63294,7 +62564,6 @@ func (s *SnapshotTaskDetail) SetUserBucket(v *UserBucketDetails) *SnapshotTaskDe } // Describes the data feed for a Spot Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotDatafeedSubscription type SpotDatafeedSubscription struct { _ struct{} `type:"structure"` @@ -63355,7 +62624,6 @@ func (s *SpotDatafeedSubscription) SetState(v string) *SpotDatafeedSubscription } // Describes the launch specification for one or more Spot Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetLaunchSpecification type SpotFleetLaunchSpecification struct { _ struct{} `type:"structure"` @@ -63577,7 +62845,6 @@ func (s *SpotFleetLaunchSpecification) SetWeightedCapacity(v float64) *SpotFleet } // Describes whether monitoring is enabled. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetMonitoring type SpotFleetMonitoring struct { _ struct{} `type:"structure"` @@ -63604,7 +62871,6 @@ func (s *SpotFleetMonitoring) SetEnabled(v bool) *SpotFleetMonitoring { } // Describes a Spot Fleet request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetRequestConfig type SpotFleetRequestConfig struct { _ struct{} `type:"structure"` @@ -63677,7 +62943,6 @@ func (s *SpotFleetRequestConfig) SetSpotFleetRequestState(v string) *SpotFleetRe } // Describes the configuration of a Spot Fleet request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetRequestConfigData type SpotFleetRequestConfigData struct { _ struct{} `type:"structure"` @@ -63912,7 +63177,6 @@ func (s *SpotFleetRequestConfigData) SetValidUntil(v time.Time) *SpotFleetReques } // The tags for a Spot Fleet resource. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetTagSpecification type SpotFleetTagSpecification struct { _ struct{} `type:"structure"` @@ -63947,7 +63211,6 @@ func (s *SpotFleetTagSpecification) SetTags(v []*Tag) *SpotFleetTagSpecification } // Describes a Spot Instance request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceRequest type SpotInstanceRequest struct { _ struct{} `type:"structure"` @@ -64148,7 +63411,6 @@ func (s *SpotInstanceRequest) SetValidUntil(v time.Time) *SpotInstanceRequest { } // Describes a Spot Instance state change. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceStateFault type SpotInstanceStateFault struct { _ struct{} `type:"structure"` @@ -64182,7 +63444,6 @@ func (s *SpotInstanceStateFault) SetMessage(v string) *SpotInstanceStateFault { } // Describes the status of a Spot Instance request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceStatus type SpotInstanceStatus struct { _ struct{} `type:"structure"` @@ -64227,7 +63488,6 @@ func (s *SpotInstanceStatus) SetUpdateTime(v time.Time) *SpotInstanceStatus { } // The options for Spot Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotMarketOptions type SpotMarketOptions struct { _ struct{} `type:"structure"` @@ -64295,7 +63555,6 @@ func (s *SpotMarketOptions) SetValidUntil(v time.Time) *SpotMarketOptions { } // Describes Spot Instance placement. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotPlacement type SpotPlacement struct { _ struct{} `type:"structure"` @@ -64344,7 +63603,6 @@ func (s *SpotPlacement) SetTenancy(v string) *SpotPlacement { // Describes the maximum price per hour that you are willing to pay for a Spot // Instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotPrice type SpotPrice struct { _ struct{} `type:"structure"` @@ -64405,7 +63663,6 @@ func (s *SpotPrice) SetTimestamp(v time.Time) *SpotPrice { } // Describes a stale rule in a security group. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StaleIpPermission type StaleIpPermission struct { _ struct{} `type:"structure"` @@ -64480,7 +63737,6 @@ func (s *StaleIpPermission) SetUserIdGroupPairs(v []*UserIdGroupPair) *StaleIpPe } // Describes a stale security group (a security group that contains stale rules). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StaleSecurityGroup type StaleSecurityGroup struct { _ struct{} `type:"structure"` @@ -64552,7 +63808,6 @@ func (s *StaleSecurityGroup) SetVpcId(v string) *StaleSecurityGroup { } // Contains the parameters for StartInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstancesRequest type StartInstancesInput struct { _ struct{} `type:"structure"` @@ -64613,7 +63868,6 @@ func (s *StartInstancesInput) SetInstanceIds(v []*string) *StartInstancesInput { } // Contains the output of StartInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StartInstancesResult type StartInstancesOutput struct { _ struct{} `type:"structure"` @@ -64638,7 +63892,6 @@ func (s *StartInstancesOutput) SetStartingInstances(v []*InstanceStateChange) *S } // Describes a state change. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StateReason type StateReason struct { _ struct{} `type:"structure"` @@ -64701,7 +63954,6 @@ func (s *StateReason) SetMessage(v string) *StateReason { } // Contains the parameters for StopInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstancesRequest type StopInstancesInput struct { _ struct{} `type:"structure"` @@ -64767,7 +64019,6 @@ func (s *StopInstancesInput) SetInstanceIds(v []*string) *StopInstancesInput { } // Contains the output of StopInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StopInstancesResult type StopInstancesOutput struct { _ struct{} `type:"structure"` @@ -64792,7 +64043,6 @@ func (s *StopInstancesOutput) SetStoppingInstances(v []*InstanceStateChange) *St } // Describes the storage location for an instance store-backed AMI. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Storage type Storage struct { _ struct{} `type:"structure"` @@ -64817,7 +64067,6 @@ func (s *Storage) SetS3(v *S3Storage) *Storage { } // Describes a storage location in Amazon S3. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/StorageLocation type StorageLocation struct { _ struct{} `type:"structure"` @@ -64851,7 +64100,6 @@ func (s *StorageLocation) SetKey(v string) *StorageLocation { } // Describes a subnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Subnet type Subnet struct { _ struct{} `type:"structure"` @@ -64969,7 +64217,6 @@ func (s *Subnet) SetVpcId(v string) *Subnet { } // Describes the state of a CIDR block. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SubnetCidrBlockState type SubnetCidrBlockState struct { _ struct{} `type:"structure"` @@ -65003,7 +64250,6 @@ func (s *SubnetCidrBlockState) SetStatusMessage(v string) *SubnetCidrBlockState } // Describes an IPv6 CIDR block associated with a subnet. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SubnetIpv6CidrBlockAssociation type SubnetIpv6CidrBlockAssociation struct { _ struct{} `type:"structure"` @@ -65047,7 +64293,6 @@ func (s *SubnetIpv6CidrBlockAssociation) SetIpv6CidrBlockState(v *SubnetCidrBloc // Describes the T2 instance whose credit option for CPU usage was successfully // modified. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SuccessfulInstanceCreditSpecificationItem type SuccessfulInstanceCreditSpecificationItem struct { _ struct{} `type:"structure"` @@ -65072,7 +64317,6 @@ func (s *SuccessfulInstanceCreditSpecificationItem) SetInstanceId(v string) *Suc } // Describes a tag. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Tag type Tag struct { _ struct{} `type:"structure"` @@ -65112,7 +64356,6 @@ func (s *Tag) SetValue(v string) *Tag { } // Describes a tag. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TagDescription type TagDescription struct { _ struct{} `type:"structure"` @@ -65164,7 +64407,6 @@ func (s *TagDescription) SetValue(v string) *TagDescription { } // The tags to apply to a resource when the resource is being created. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TagSpecification type TagSpecification struct { _ struct{} `type:"structure"` @@ -65199,7 +64441,6 @@ func (s *TagSpecification) SetTags(v []*Tag) *TagSpecification { } // Information about the Convertible Reserved Instance offering. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetConfiguration type TargetConfiguration struct { _ struct{} `type:"structure"` @@ -65234,7 +64475,6 @@ func (s *TargetConfiguration) SetOfferingId(v string) *TargetConfiguration { } // Details about the target configuration. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetConfigurationRequest type TargetConfigurationRequest struct { _ struct{} `type:"structure"` @@ -65284,7 +64524,6 @@ func (s *TargetConfigurationRequest) SetOfferingId(v string) *TargetConfiguratio } // Describes a load balancer target group. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetGroup type TargetGroup struct { _ struct{} `type:"structure"` @@ -65325,7 +64564,6 @@ func (s *TargetGroup) SetArn(v string) *TargetGroup { // Describes the target groups to attach to a Spot Fleet. Spot Fleet registers // the running Spot Instances with these target groups. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetGroupsConfig type TargetGroupsConfig struct { _ struct{} `type:"structure"` @@ -65378,7 +64616,6 @@ func (s *TargetGroupsConfig) SetTargetGroups(v []*TargetGroup) *TargetGroupsConf } // The total value of the new Convertible Reserved Instances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TargetReservationValue type TargetReservationValue struct { _ struct{} `type:"structure"` @@ -65415,7 +64652,6 @@ func (s *TargetReservationValue) SetTargetConfiguration(v *TargetConfiguration) } // Contains the parameters for TerminateInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstancesRequest type TerminateInstancesInput struct { _ struct{} `type:"structure"` @@ -65470,7 +64706,6 @@ func (s *TerminateInstancesInput) SetInstanceIds(v []*string) *TerminateInstance } // Contains the output of TerminateInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/TerminateInstancesResult type TerminateInstancesOutput struct { _ struct{} `type:"structure"` @@ -65494,7 +64729,6 @@ func (s *TerminateInstancesOutput) SetTerminatingInstances(v []*InstanceStateCha return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6AddressesRequest type UnassignIpv6AddressesInput struct { _ struct{} `type:"structure"` @@ -65547,7 +64781,6 @@ func (s *UnassignIpv6AddressesInput) SetNetworkInterfaceId(v string) *UnassignIp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignIpv6AddressesResult type UnassignIpv6AddressesOutput struct { _ struct{} `type:"structure"` @@ -65581,7 +64814,6 @@ func (s *UnassignIpv6AddressesOutput) SetUnassignedIpv6Addresses(v []*string) *U } // Contains the parameters for UnassignPrivateIpAddresses. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddressesRequest type UnassignPrivateIpAddressesInput struct { _ struct{} `type:"structure"` @@ -65635,7 +64867,6 @@ func (s *UnassignPrivateIpAddressesInput) SetPrivateIpAddresses(v []*string) *Un return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnassignPrivateIpAddressesOutput type UnassignPrivateIpAddressesOutput struct { _ struct{} `type:"structure"` } @@ -65651,7 +64882,6 @@ func (s UnassignPrivateIpAddressesOutput) GoString() string { } // Contains the parameters for UnmonitorInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstancesRequest type UnmonitorInstancesInput struct { _ struct{} `type:"structure"` @@ -65703,7 +64933,6 @@ func (s *UnmonitorInstancesInput) SetInstanceIds(v []*string) *UnmonitorInstance } // Contains the output of UnmonitorInstances. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnmonitorInstancesResult type UnmonitorInstancesOutput struct { _ struct{} `type:"structure"` @@ -65728,7 +64957,6 @@ func (s *UnmonitorInstancesOutput) SetInstanceMonitorings(v []*InstanceMonitorin } // Describes the T2 instance whose credit option for CPU usage was not modified. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulInstanceCreditSpecificationItem type UnsuccessfulInstanceCreditSpecificationItem struct { _ struct{} `type:"structure"` @@ -65764,7 +64992,6 @@ func (s *UnsuccessfulInstanceCreditSpecificationItem) SetInstanceId(v string) *U // Information about the error for the T2 instance whose credit option for CPU // usage was not modified. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulInstanceCreditSpecificationItemError type UnsuccessfulInstanceCreditSpecificationItemError struct { _ struct{} `type:"structure"` @@ -65798,7 +65025,6 @@ func (s *UnsuccessfulInstanceCreditSpecificationItemError) SetMessage(v string) } // Information about items that were not successfully processed in a batch call. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulItem type UnsuccessfulItem struct { _ struct{} `type:"structure"` @@ -65835,7 +65061,6 @@ func (s *UnsuccessfulItem) SetResourceId(v string) *UnsuccessfulItem { // Information about the error that occurred. For more information about errors, // see Error Codes (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html). -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UnsuccessfulItemError type UnsuccessfulItemError struct { _ struct{} `type:"structure"` @@ -65873,7 +65098,6 @@ func (s *UnsuccessfulItemError) SetMessage(v string) *UnsuccessfulItemError { } // Contains the parameters for UpdateSecurityGroupRuleDescriptionsEgress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsEgressRequest type UpdateSecurityGroupRuleDescriptionsEgressInput struct { _ struct{} `type:"structure"` @@ -65946,7 +65170,6 @@ func (s *UpdateSecurityGroupRuleDescriptionsEgressInput) SetIpPermissions(v []*I } // Contains the output of UpdateSecurityGroupRuleDescriptionsEgress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsEgressResult type UpdateSecurityGroupRuleDescriptionsEgressOutput struct { _ struct{} `type:"structure"` @@ -65971,7 +65194,6 @@ func (s *UpdateSecurityGroupRuleDescriptionsEgressOutput) SetReturn(v bool) *Upd } // Contains the parameters for UpdateSecurityGroupRuleDescriptionsIngress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsIngressRequest type UpdateSecurityGroupRuleDescriptionsIngressInput struct { _ struct{} `type:"structure"` @@ -66044,7 +65266,6 @@ func (s *UpdateSecurityGroupRuleDescriptionsIngressInput) SetIpPermissions(v []* } // Contains the output of UpdateSecurityGroupRuleDescriptionsIngress. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UpdateSecurityGroupRuleDescriptionsIngressResult type UpdateSecurityGroupRuleDescriptionsIngressOutput struct { _ struct{} `type:"structure"` @@ -66069,7 +65290,6 @@ func (s *UpdateSecurityGroupRuleDescriptionsIngressOutput) SetReturn(v bool) *Up } // Describes the S3 bucket for the disk image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserBucket type UserBucket struct { _ struct{} `type:"structure"` @@ -66103,7 +65323,6 @@ func (s *UserBucket) SetS3Key(v string) *UserBucket { } // Describes the S3 bucket for the disk image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserBucketDetails type UserBucketDetails struct { _ struct{} `type:"structure"` @@ -66137,7 +65356,6 @@ func (s *UserBucketDetails) SetS3Key(v string) *UserBucketDetails { } // Describes the user data for an instance. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserData type UserData struct { _ struct{} `type:"structure"` @@ -66164,7 +65382,6 @@ func (s *UserData) SetData(v string) *UserData { } // Describes a security group and AWS account ID pair. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/UserIdGroupPair type UserIdGroupPair struct { _ struct{} `type:"structure"` @@ -66259,7 +65476,6 @@ func (s *UserIdGroupPair) SetVpcPeeringConnectionId(v string) *UserIdGroupPair { } // Describes telemetry for a VPN tunnel. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VgwTelemetry type VgwTelemetry struct { _ struct{} `type:"structure"` @@ -66321,7 +65537,6 @@ func (s *VgwTelemetry) SetStatusMessage(v string) *VgwTelemetry { } // Describes a volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Volume type Volume struct { _ struct{} `type:"structure"` @@ -66460,7 +65675,6 @@ func (s *Volume) SetVolumeType(v string) *Volume { } // Describes volume attachment details. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeAttachment type VolumeAttachment struct { _ struct{} `type:"structure"` @@ -66530,7 +65744,6 @@ func (s *VolumeAttachment) SetVolumeId(v string) *VolumeAttachment { } // Describes an EBS volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeDetail type VolumeDetail struct { _ struct{} `type:"structure"` @@ -66572,7 +65785,6 @@ func (s *VolumeDetail) SetSize(v int64) *VolumeDetail { // Describes the modification status of an EBS volume. // // If the volume has never been modified, some element values will be null. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeModification type VolumeModification struct { _ struct{} `type:"structure"` @@ -66697,7 +65909,6 @@ func (s *VolumeModification) SetVolumeId(v string) *VolumeModification { } // Describes a volume status operation code. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusAction type VolumeStatusAction struct { _ struct{} `type:"structure"` @@ -66749,7 +65960,6 @@ func (s *VolumeStatusAction) SetEventType(v string) *VolumeStatusAction { } // Describes a volume status. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusDetails type VolumeStatusDetails struct { _ struct{} `type:"structure"` @@ -66783,7 +65993,6 @@ func (s *VolumeStatusDetails) SetStatus(v string) *VolumeStatusDetails { } // Describes a volume status event. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusEvent type VolumeStatusEvent struct { _ struct{} `type:"structure"` @@ -66844,7 +66053,6 @@ func (s *VolumeStatusEvent) SetNotBefore(v time.Time) *VolumeStatusEvent { } // Describes the status of a volume. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusInfo type VolumeStatusInfo struct { _ struct{} `type:"structure"` @@ -66878,7 +66086,6 @@ func (s *VolumeStatusInfo) SetStatus(v string) *VolumeStatusInfo { } // Describes the volume status. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VolumeStatusItem type VolumeStatusItem struct { _ struct{} `type:"structure"` @@ -66939,7 +66146,6 @@ func (s *VolumeStatusItem) SetVolumeStatus(v *VolumeStatusInfo) *VolumeStatusIte } // Describes a VPC. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/Vpc type Vpc struct { _ struct{} `type:"structure"` @@ -67037,7 +66243,6 @@ func (s *Vpc) SetVpcId(v string) *Vpc { } // Describes an attachment between a virtual private gateway and a VPC. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcAttachment type VpcAttachment struct { _ struct{} `type:"structure"` @@ -67071,7 +66276,6 @@ func (s *VpcAttachment) SetVpcId(v string) *VpcAttachment { } // Describes an IPv4 CIDR block associated with a VPC. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcCidrBlockAssociation type VpcCidrBlockAssociation struct { _ struct{} `type:"structure"` @@ -67114,7 +66318,6 @@ func (s *VpcCidrBlockAssociation) SetCidrBlockState(v *VpcCidrBlockState) *VpcCi } // Describes the state of a CIDR block. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcCidrBlockState type VpcCidrBlockState struct { _ struct{} `type:"structure"` @@ -67148,7 +66351,6 @@ func (s *VpcCidrBlockState) SetStatusMessage(v string) *VpcCidrBlockState { } // Describes whether a VPC is enabled for ClassicLink. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcClassicLink type VpcClassicLink struct { _ struct{} `type:"structure"` @@ -67191,7 +66393,6 @@ func (s *VpcClassicLink) SetVpcId(v string) *VpcClassicLink { } // Describes a VPC endpoint. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcEndpoint type VpcEndpoint struct { _ struct{} `type:"structure"` @@ -67326,7 +66527,6 @@ func (s *VpcEndpoint) SetVpcId(v string) *VpcEndpoint { } // Describes a VPC endpoint connection to a service. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcEndpointConnection type VpcEndpointConnection struct { _ struct{} `type:"structure"` @@ -67387,7 +66587,6 @@ func (s *VpcEndpointConnection) SetVpcEndpointState(v string) *VpcEndpointConnec } // Describes an IPv6 CIDR block associated with a VPC. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcIpv6CidrBlockAssociation type VpcIpv6CidrBlockAssociation struct { _ struct{} `type:"structure"` @@ -67430,7 +66629,6 @@ func (s *VpcIpv6CidrBlockAssociation) SetIpv6CidrBlockState(v *VpcCidrBlockState } // Describes a VPC peering connection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnection type VpcPeeringConnection struct { _ struct{} `type:"structure"` @@ -67502,7 +66700,6 @@ func (s *VpcPeeringConnection) SetVpcPeeringConnectionId(v string) *VpcPeeringCo } // Describes the VPC peering connection options. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionOptionsDescription type VpcPeeringConnectionOptionsDescription struct { _ struct{} `type:"structure"` @@ -67548,7 +66745,6 @@ func (s *VpcPeeringConnectionOptionsDescription) SetAllowEgressFromLocalVpcToRem } // Describes the status of a VPC peering connection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionStateReason type VpcPeeringConnectionStateReason struct { _ struct{} `type:"structure"` @@ -67582,7 +66778,6 @@ func (s *VpcPeeringConnectionStateReason) SetMessage(v string) *VpcPeeringConnec } // Describes a VPC in a VPC peering connection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpcPeeringConnectionVpcInfo type VpcPeeringConnectionVpcInfo struct { _ struct{} `type:"structure"` @@ -67662,7 +66857,6 @@ func (s *VpcPeeringConnectionVpcInfo) SetVpcId(v string) *VpcPeeringConnectionVp } // Describes a VPN connection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnection type VpnConnection struct { _ struct{} `type:"structure"` @@ -67783,7 +66977,6 @@ func (s *VpnConnection) SetVpnGatewayId(v string) *VpnConnection { } // Describes VPN connection options. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnectionOptions type VpnConnectionOptions struct { _ struct{} `type:"structure"` @@ -67809,7 +67002,6 @@ func (s *VpnConnectionOptions) SetStaticRoutesOnly(v bool) *VpnConnectionOptions } // Describes VPN connection options. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnConnectionOptionsSpecification type VpnConnectionOptionsSpecification struct { _ struct{} `type:"structure"` @@ -67847,7 +67039,6 @@ func (s *VpnConnectionOptionsSpecification) SetTunnelOptions(v []*VpnTunnelOptio } // Describes a virtual private gateway. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnGateway type VpnGateway struct { _ struct{} `type:"structure"` @@ -67927,7 +67118,6 @@ func (s *VpnGateway) SetVpnGatewayId(v string) *VpnGateway { } // Describes a static route for a VPN connection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnStaticRoute type VpnStaticRoute struct { _ struct{} `type:"structure"` @@ -67970,7 +67160,6 @@ func (s *VpnStaticRoute) SetState(v string) *VpnStaticRoute { } // The tunnel options for a VPN connection. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/VpnTunnelOptionsSpecification type VpnTunnelOptionsSpecification struct { _ struct{} `type:"structure"` diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go b/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go index 984aec965..bf9630e4c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go @@ -2236,7 +2236,6 @@ func (c *ECR) UploadLayerPartWithContext(ctx aws.Context, input *UploadLayerPart } // An object representing authorization data for an Amazon ECR registry. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/AuthorizationData type AuthorizationData struct { _ struct{} `type:"structure"` @@ -2283,7 +2282,6 @@ func (s *AuthorizationData) SetProxyEndpoint(v string) *AuthorizationData { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailabilityRequest type BatchCheckLayerAvailabilityInput struct { _ struct{} `type:"structure"` @@ -2352,7 +2350,6 @@ func (s *BatchCheckLayerAvailabilityInput) SetRepositoryName(v string) *BatchChe return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailabilityResponse type BatchCheckLayerAvailabilityOutput struct { _ struct{} `type:"structure"` @@ -2388,7 +2385,6 @@ func (s *BatchCheckLayerAvailabilityOutput) SetLayers(v []*Layer) *BatchCheckLay // Deletes specified images within a specified repository. Images are specified // with either the imageTag or imageDigest. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImageRequest type BatchDeleteImageInput struct { _ struct{} `type:"structure"` @@ -2458,7 +2454,6 @@ func (s *BatchDeleteImageInput) SetRepositoryName(v string) *BatchDeleteImageInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImageResponse type BatchDeleteImageOutput struct { _ struct{} `type:"structure"` @@ -2491,7 +2486,6 @@ func (s *BatchDeleteImageOutput) SetImageIds(v []*ImageIdentifier) *BatchDeleteI return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImageRequest type BatchGetImageInput struct { _ struct{} `type:"structure"` @@ -2576,7 +2570,6 @@ func (s *BatchGetImageInput) SetRepositoryName(v string) *BatchGetImageInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImageResponse type BatchGetImageOutput struct { _ struct{} `type:"structure"` @@ -2609,7 +2602,6 @@ func (s *BatchGetImageOutput) SetImages(v []*Image) *BatchGetImageOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUploadRequest type CompleteLayerUploadInput struct { _ struct{} `type:"structure"` @@ -2693,7 +2685,6 @@ func (s *CompleteLayerUploadInput) SetUploadId(v string) *CompleteLayerUploadInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUploadResponse type CompleteLayerUploadOutput struct { _ struct{} `type:"structure"` @@ -2744,7 +2735,6 @@ func (s *CompleteLayerUploadOutput) SetUploadId(v string) *CompleteLayerUploadOu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepositoryRequest type CreateRepositoryInput struct { _ struct{} `type:"structure"` @@ -2788,7 +2778,6 @@ func (s *CreateRepositoryInput) SetRepositoryName(v string) *CreateRepositoryInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepositoryResponse type CreateRepositoryOutput struct { _ struct{} `type:"structure"` @@ -2812,7 +2801,6 @@ func (s *CreateRepositoryOutput) SetRepository(v *Repository) *CreateRepositoryO return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicyRequest type DeleteLifecyclePolicyInput struct { _ struct{} `type:"structure"` @@ -2865,7 +2853,6 @@ func (s *DeleteLifecyclePolicyInput) SetRepositoryName(v string) *DeleteLifecycl return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicyResponse type DeleteLifecyclePolicyOutput struct { _ struct{} `type:"structure"` @@ -2916,7 +2903,6 @@ func (s *DeleteLifecyclePolicyOutput) SetRepositoryName(v string) *DeleteLifecyc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryRequest type DeleteRepositoryInput struct { _ struct{} `type:"structure"` @@ -2977,7 +2963,6 @@ func (s *DeleteRepositoryInput) SetRepositoryName(v string) *DeleteRepositoryInp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryResponse type DeleteRepositoryOutput struct { _ struct{} `type:"structure"` @@ -3001,7 +2986,6 @@ func (s *DeleteRepositoryOutput) SetRepository(v *Repository) *DeleteRepositoryO return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicyRequest type DeleteRepositoryPolicyInput struct { _ struct{} `type:"structure"` @@ -3055,7 +3039,6 @@ func (s *DeleteRepositoryPolicyInput) SetRepositoryName(v string) *DeleteReposit return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicyResponse type DeleteRepositoryPolicyOutput struct { _ struct{} `type:"structure"` @@ -3098,7 +3081,6 @@ func (s *DeleteRepositoryPolicyOutput) SetRepositoryName(v string) *DeleteReposi } // An object representing a filter on a DescribeImages operation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesFilter type DescribeImagesFilter struct { _ struct{} `type:"structure"` @@ -3123,7 +3105,6 @@ func (s *DescribeImagesFilter) SetTagStatus(v string) *DescribeImagesFilter { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesRequest type DescribeImagesInput struct { _ struct{} `type:"structure"` @@ -3228,7 +3209,6 @@ func (s *DescribeImagesInput) SetRepositoryName(v string) *DescribeImagesInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImagesResponse type DescribeImagesOutput struct { _ struct{} `type:"structure"` @@ -3264,7 +3244,6 @@ func (s *DescribeImagesOutput) SetNextToken(v string) *DescribeImagesOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositoriesRequest type DescribeRepositoriesInput struct { _ struct{} `type:"structure"` @@ -3347,7 +3326,6 @@ func (s *DescribeRepositoriesInput) SetRepositoryNames(v []*string) *DescribeRep return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositoriesResponse type DescribeRepositoriesOutput struct { _ struct{} `type:"structure"` @@ -3383,7 +3361,6 @@ func (s *DescribeRepositoriesOutput) SetRepositories(v []*Repository) *DescribeR return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationTokenRequest type GetAuthorizationTokenInput struct { _ struct{} `type:"structure"` @@ -3422,7 +3399,6 @@ func (s *GetAuthorizationTokenInput) SetRegistryIds(v []*string) *GetAuthorizati return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationTokenResponse type GetAuthorizationTokenOutput struct { _ struct{} `type:"structure"` @@ -3447,7 +3423,6 @@ func (s *GetAuthorizationTokenOutput) SetAuthorizationData(v []*AuthorizationDat return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayerRequest type GetDownloadUrlForLayerInput struct { _ struct{} `type:"structure"` @@ -3513,7 +3488,6 @@ func (s *GetDownloadUrlForLayerInput) SetRepositoryName(v string) *GetDownloadUr return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayerResponse type GetDownloadUrlForLayerOutput struct { _ struct{} `type:"structure"` @@ -3546,7 +3520,6 @@ func (s *GetDownloadUrlForLayerOutput) SetLayerDigest(v string) *GetDownloadUrlF return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyRequest type GetLifecyclePolicyInput struct { _ struct{} `type:"structure"` @@ -3598,7 +3571,6 @@ func (s *GetLifecyclePolicyInput) SetRepositoryName(v string) *GetLifecyclePolic return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyResponse type GetLifecyclePolicyOutput struct { _ struct{} `type:"structure"` @@ -3649,7 +3621,6 @@ func (s *GetLifecyclePolicyOutput) SetRepositoryName(v string) *GetLifecyclePoli return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreviewRequest type GetLifecyclePolicyPreviewInput struct { _ struct{} `type:"structure"` @@ -3755,7 +3726,6 @@ func (s *GetLifecyclePolicyPreviewInput) SetRepositoryName(v string) *GetLifecyc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreviewResponse type GetLifecyclePolicyPreviewOutput struct { _ struct{} `type:"structure"` @@ -3836,7 +3806,6 @@ func (s *GetLifecyclePolicyPreviewOutput) SetSummary(v *LifecyclePolicyPreviewSu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicyRequest type GetRepositoryPolicyInput struct { _ struct{} `type:"structure"` @@ -3888,7 +3857,6 @@ func (s *GetRepositoryPolicyInput) SetRepositoryName(v string) *GetRepositoryPol return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicyResponse type GetRepositoryPolicyOutput struct { _ struct{} `type:"structure"` @@ -3931,7 +3899,6 @@ func (s *GetRepositoryPolicyOutput) SetRepositoryName(v string) *GetRepositoryPo } // An object representing an Amazon ECR image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Image type Image struct { _ struct{} `type:"structure"` @@ -3983,7 +3950,6 @@ func (s *Image) SetRepositoryName(v string) *Image { } // An object that describes an image returned by a DescribeImages operation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageDetail type ImageDetail struct { _ struct{} `type:"structure"` @@ -4059,7 +4025,6 @@ func (s *ImageDetail) SetRepositoryName(v string) *ImageDetail { } // An object representing an Amazon ECR image failure. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageFailure type ImageFailure struct { _ struct{} `type:"structure"` @@ -4102,7 +4067,6 @@ func (s *ImageFailure) SetImageId(v *ImageIdentifier) *ImageFailure { } // An object with identifying information for an Amazon ECR image. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ImageIdentifier type ImageIdentifier struct { _ struct{} `type:"structure"` @@ -4135,7 +4099,6 @@ func (s *ImageIdentifier) SetImageTag(v string) *ImageIdentifier { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUploadRequest type InitiateLayerUploadInput struct { _ struct{} `type:"structure"` @@ -4187,7 +4150,6 @@ func (s *InitiateLayerUploadInput) SetRepositoryName(v string) *InitiateLayerUpl return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUploadResponse type InitiateLayerUploadOutput struct { _ struct{} `type:"structure"` @@ -4223,7 +4185,6 @@ func (s *InitiateLayerUploadOutput) SetUploadId(v string) *InitiateLayerUploadOu } // An object representing an Amazon ECR image layer. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Layer type Layer struct { _ struct{} `type:"structure"` @@ -4276,7 +4237,6 @@ func (s *Layer) SetMediaType(v string) *Layer { } // An object representing an Amazon ECR image layer failure. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LayerFailure type LayerFailure struct { _ struct{} `type:"structure"` @@ -4319,7 +4279,6 @@ func (s *LayerFailure) SetLayerDigest(v string) *LayerFailure { } // The filter for the lifecycle policy preview. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyPreviewFilter type LifecyclePolicyPreviewFilter struct { _ struct{} `type:"structure"` @@ -4344,7 +4303,6 @@ func (s *LifecyclePolicyPreviewFilter) SetTagStatus(v string) *LifecyclePolicyPr } // The result of the lifecycle policy preview. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyPreviewResult type LifecyclePolicyPreviewResult struct { _ struct{} `type:"structure"` @@ -4406,7 +4364,6 @@ func (s *LifecyclePolicyPreviewResult) SetImageTags(v []*string) *LifecyclePolic } // The summary of the lifecycle policy preview request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyPreviewSummary type LifecyclePolicyPreviewSummary struct { _ struct{} `type:"structure"` @@ -4431,7 +4388,6 @@ func (s *LifecyclePolicyPreviewSummary) SetExpiringImageTotalCount(v int64) *Lif } // The type of action to be taken. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/LifecyclePolicyRuleAction type LifecyclePolicyRuleAction struct { _ struct{} `type:"structure"` @@ -4456,7 +4412,6 @@ func (s *LifecyclePolicyRuleAction) SetType(v string) *LifecyclePolicyRuleAction } // An object representing a filter on a ListImages operation. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesFilter type ListImagesFilter struct { _ struct{} `type:"structure"` @@ -4481,7 +4436,6 @@ func (s *ListImagesFilter) SetTagStatus(v string) *ListImagesFilter { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesRequest type ListImagesInput struct { _ struct{} `type:"structure"` @@ -4576,7 +4530,6 @@ func (s *ListImagesInput) SetRepositoryName(v string) *ListImagesInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImagesResponse type ListImagesOutput struct { _ struct{} `type:"structure"` @@ -4612,7 +4565,6 @@ func (s *ListImagesOutput) SetNextToken(v string) *ListImagesOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImageRequest type PutImageInput struct { _ struct{} `type:"structure"` @@ -4689,7 +4641,6 @@ func (s *PutImageInput) SetRepositoryName(v string) *PutImageInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImageResponse type PutImageOutput struct { _ struct{} `type:"structure"` @@ -4713,7 +4664,6 @@ func (s *PutImageOutput) SetImage(v *Image) *PutImageOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicyRequest type PutLifecyclePolicyInput struct { _ struct{} `type:"structure"` @@ -4782,7 +4732,6 @@ func (s *PutLifecyclePolicyInput) SetRepositoryName(v string) *PutLifecyclePolic return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicyResponse type PutLifecyclePolicyOutput struct { _ struct{} `type:"structure"` @@ -4825,7 +4774,6 @@ func (s *PutLifecyclePolicyOutput) SetRepositoryName(v string) *PutLifecyclePoli } // An object representing a repository. -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/Repository type Repository struct { _ struct{} `type:"structure"` @@ -4889,7 +4837,6 @@ func (s *Repository) SetRepositoryUri(v string) *Repository { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicyRequest type SetRepositoryPolicyInput struct { _ struct{} `type:"structure"` @@ -4966,7 +4913,6 @@ func (s *SetRepositoryPolicyInput) SetRepositoryName(v string) *SetRepositoryPol return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicyResponse type SetRepositoryPolicyOutput struct { _ struct{} `type:"structure"` @@ -5008,7 +4954,6 @@ func (s *SetRepositoryPolicyOutput) SetRepositoryName(v string) *SetRepositoryPo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreviewRequest type StartLifecyclePolicyPreviewInput struct { _ struct{} `type:"structure"` @@ -5073,7 +5018,6 @@ func (s *StartLifecyclePolicyPreviewInput) SetRepositoryName(v string) *StartLif return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreviewResponse type StartLifecyclePolicyPreviewOutput struct { _ struct{} `type:"structure"` @@ -5124,7 +5068,6 @@ func (s *StartLifecyclePolicyPreviewOutput) SetStatus(v string) *StartLifecycleP return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPartRequest type UploadLayerPartInput struct { _ struct{} `type:"structure"` @@ -5235,7 +5178,6 @@ func (s *UploadLayerPartInput) SetUploadId(v string) *UploadLayerPartInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPartResponse type UploadLayerPartOutput struct { _ struct{} `type:"structure"` diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go index 0d852f59c..2faeee1ec 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go @@ -6173,7 +6173,6 @@ func (c *S3) UploadPartCopyWithContext(ctx aws.Context, input *UploadPartCopyInp // Specifies the days since the initiation of an Incomplete Multipart Upload // that Lifecycle will wait before permanently removing all parts of the upload. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortIncompleteMultipartUpload type AbortIncompleteMultipartUpload struct { _ struct{} `type:"structure"` @@ -6198,7 +6197,6 @@ func (s *AbortIncompleteMultipartUpload) SetDaysAfterInitiation(v int64) *AbortI return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUploadRequest type AbortMultipartUploadInput struct { _ struct{} `type:"structure"` @@ -6281,7 +6279,6 @@ func (s *AbortMultipartUploadInput) SetUploadId(v string) *AbortMultipartUploadI return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUploadOutput type AbortMultipartUploadOutput struct { _ struct{} `type:"structure"` @@ -6306,7 +6303,6 @@ func (s *AbortMultipartUploadOutput) SetRequestCharged(v string) *AbortMultipart return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccelerateConfiguration type AccelerateConfiguration struct { _ struct{} `type:"structure"` @@ -6330,7 +6326,6 @@ func (s *AccelerateConfiguration) SetStatus(v string) *AccelerateConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccessControlPolicy type AccessControlPolicy struct { _ struct{} `type:"structure"` @@ -6383,7 +6378,6 @@ func (s *AccessControlPolicy) SetOwner(v *Owner) *AccessControlPolicy { } // Container for information regarding the access control for replicas. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AccessControlTranslation type AccessControlTranslation struct { _ struct{} `type:"structure"` @@ -6422,7 +6416,6 @@ func (s *AccessControlTranslation) SetOwner(v string) *AccessControlTranslation return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsAndOperator type AnalyticsAndOperator struct { _ struct{} `type:"structure"` @@ -6475,7 +6468,6 @@ func (s *AnalyticsAndOperator) SetTags(v []*Tag) *AnalyticsAndOperator { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsConfiguration type AnalyticsConfiguration struct { _ struct{} `type:"structure"` @@ -6550,7 +6542,6 @@ func (s *AnalyticsConfiguration) SetStorageClassAnalysis(v *StorageClassAnalysis return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsExportDestination type AnalyticsExportDestination struct { _ struct{} `type:"structure"` @@ -6594,7 +6585,6 @@ func (s *AnalyticsExportDestination) SetS3BucketDestination(v *AnalyticsS3Bucket return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsFilter type AnalyticsFilter struct { _ struct{} `type:"structure"` @@ -6657,7 +6647,6 @@ func (s *AnalyticsFilter) SetTag(v *Tag) *AnalyticsFilter { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AnalyticsS3BucketDestination type AnalyticsS3BucketDestination struct { _ struct{} `type:"structure"` @@ -6737,7 +6726,6 @@ func (s *AnalyticsS3BucketDestination) SetPrefix(v string) *AnalyticsS3BucketDes return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Bucket type Bucket struct { _ struct{} `type:"structure"` @@ -6770,7 +6758,6 @@ func (s *Bucket) SetName(v string) *Bucket { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/BucketLifecycleConfiguration type BucketLifecycleConfiguration struct { _ struct{} `type:"structure"` @@ -6817,7 +6804,6 @@ func (s *BucketLifecycleConfiguration) SetRules(v []*LifecycleRule) *BucketLifec return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/BucketLoggingStatus type BucketLoggingStatus struct { _ struct{} `type:"structure"` @@ -6855,7 +6841,6 @@ func (s *BucketLoggingStatus) SetLoggingEnabled(v *LoggingEnabled) *BucketLoggin return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CORSConfiguration type CORSConfiguration struct { _ struct{} `type:"structure"` @@ -6902,7 +6887,6 @@ func (s *CORSConfiguration) SetCORSRules(v []*CORSRule) *CORSConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CORSRule type CORSRule struct { _ struct{} `type:"structure"` @@ -6987,7 +6971,6 @@ func (s *CORSRule) SetMaxAgeSeconds(v int64) *CORSRule { } // Describes how a CSV-formatted input object is formatted. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CSVInput type CSVInput struct { _ struct{} `type:"structure"` @@ -7059,7 +7042,6 @@ func (s *CSVInput) SetRecordDelimiter(v string) *CSVInput { } // Describes how CSV-formatted results are formatted. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CSVOutput type CSVOutput struct { _ struct{} `type:"structure"` @@ -7120,7 +7102,6 @@ func (s *CSVOutput) SetRecordDelimiter(v string) *CSVOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CloudFunctionConfiguration type CloudFunctionConfiguration struct { _ struct{} `type:"structure"` @@ -7178,7 +7159,6 @@ func (s *CloudFunctionConfiguration) SetInvocationRole(v string) *CloudFunctionC return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CommonPrefix type CommonPrefix struct { _ struct{} `type:"structure"` @@ -7201,7 +7181,6 @@ func (s *CommonPrefix) SetPrefix(v string) *CommonPrefix { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUploadRequest type CompleteMultipartUploadInput struct { _ struct{} `type:"structure" payload:"MultipartUpload"` @@ -7292,7 +7271,6 @@ func (s *CompleteMultipartUploadInput) SetUploadId(v string) *CompleteMultipartU return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUploadOutput type CompleteMultipartUploadOutput struct { _ struct{} `type:"structure"` @@ -7396,7 +7374,6 @@ func (s *CompleteMultipartUploadOutput) SetVersionId(v string) *CompleteMultipar return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompletedMultipartUpload type CompletedMultipartUpload struct { _ struct{} `type:"structure"` @@ -7419,7 +7396,6 @@ func (s *CompletedMultipartUpload) SetParts(v []*CompletedPart) *CompletedMultip return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompletedPart type CompletedPart struct { _ struct{} `type:"structure"` @@ -7453,7 +7429,6 @@ func (s *CompletedPart) SetPartNumber(v int64) *CompletedPart { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Condition type Condition struct { _ struct{} `type:"structure"` @@ -7496,7 +7471,6 @@ func (s *Condition) SetKeyPrefixEquals(v string) *Condition { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectRequest type CopyObjectInput struct { _ struct{} `type:"structure"` @@ -7880,7 +7854,6 @@ func (s *CopyObjectInput) SetWebsiteRedirectLocation(v string) *CopyObjectInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectOutput type CopyObjectOutput struct { _ struct{} `type:"structure" payload:"CopyObjectResult"` @@ -7981,7 +7954,6 @@ func (s *CopyObjectOutput) SetVersionId(v string) *CopyObjectOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObjectResult type CopyObjectResult struct { _ struct{} `type:"structure"` @@ -8012,7 +7984,6 @@ func (s *CopyObjectResult) SetLastModified(v time.Time) *CopyObjectResult { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyPartResult type CopyPartResult struct { _ struct{} `type:"structure"` @@ -8045,7 +8016,6 @@ func (s *CopyPartResult) SetLastModified(v time.Time) *CopyPartResult { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketConfiguration type CreateBucketConfiguration struct { _ struct{} `type:"structure"` @@ -8070,7 +8040,6 @@ func (s *CreateBucketConfiguration) SetLocationConstraint(v string) *CreateBucke return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketRequest type CreateBucketInput struct { _ struct{} `type:"structure" payload:"CreateBucketConfiguration"` @@ -8177,7 +8146,6 @@ func (s *CreateBucketInput) SetGrantWriteACP(v string) *CreateBucketInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucketOutput type CreateBucketOutput struct { _ struct{} `type:"structure"` @@ -8200,7 +8168,6 @@ func (s *CreateBucketOutput) SetLocation(v string) *CreateBucketOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUploadRequest type CreateMultipartUploadInput struct { _ struct{} `type:"structure"` @@ -8472,7 +8439,6 @@ func (s *CreateMultipartUploadInput) SetWebsiteRedirectLocation(v string) *Creat return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUploadOutput type CreateMultipartUploadOutput struct { _ struct{} `type:"structure"` @@ -8592,7 +8558,6 @@ func (s *CreateMultipartUploadOutput) SetUploadId(v string) *CreateMultipartUplo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Delete type Delete struct { _ struct{} `type:"structure"` @@ -8649,7 +8614,6 @@ func (s *Delete) SetQuiet(v bool) *Delete { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfigurationRequest type DeleteBucketAnalyticsConfigurationInput struct { _ struct{} `type:"structure"` @@ -8709,7 +8673,6 @@ func (s *DeleteBucketAnalyticsConfigurationInput) SetId(v string) *DeleteBucketA return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfigurationOutput type DeleteBucketAnalyticsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -8724,7 +8687,6 @@ func (s DeleteBucketAnalyticsConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsRequest type DeleteBucketCorsInput struct { _ struct{} `type:"structure"` @@ -8768,7 +8730,6 @@ func (s *DeleteBucketCorsInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCorsOutput type DeleteBucketCorsOutput struct { _ struct{} `type:"structure"` } @@ -8783,7 +8744,6 @@ func (s DeleteBucketCorsOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryptionRequest type DeleteBucketEncryptionInput struct { _ struct{} `type:"structure"` @@ -8830,7 +8790,6 @@ func (s *DeleteBucketEncryptionInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryptionOutput type DeleteBucketEncryptionOutput struct { _ struct{} `type:"structure"` } @@ -8845,7 +8804,6 @@ func (s DeleteBucketEncryptionOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketRequest type DeleteBucketInput struct { _ struct{} `type:"structure"` @@ -8889,7 +8847,6 @@ func (s *DeleteBucketInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationRequest type DeleteBucketInventoryConfigurationInput struct { _ struct{} `type:"structure"` @@ -8949,7 +8906,6 @@ func (s *DeleteBucketInventoryConfigurationInput) SetId(v string) *DeleteBucketI return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfigurationOutput type DeleteBucketInventoryConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -8964,7 +8920,6 @@ func (s DeleteBucketInventoryConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleRequest type DeleteBucketLifecycleInput struct { _ struct{} `type:"structure"` @@ -9008,7 +8963,6 @@ func (s *DeleteBucketLifecycleInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycleOutput type DeleteBucketLifecycleOutput struct { _ struct{} `type:"structure"` } @@ -9023,7 +8977,6 @@ func (s DeleteBucketLifecycleOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfigurationRequest type DeleteBucketMetricsConfigurationInput struct { _ struct{} `type:"structure"` @@ -9083,7 +9036,6 @@ func (s *DeleteBucketMetricsConfigurationInput) SetId(v string) *DeleteBucketMet return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfigurationOutput type DeleteBucketMetricsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -9098,7 +9050,6 @@ func (s DeleteBucketMetricsConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketOutput type DeleteBucketOutput struct { _ struct{} `type:"structure"` } @@ -9113,7 +9064,6 @@ func (s DeleteBucketOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyRequest type DeleteBucketPolicyInput struct { _ struct{} `type:"structure"` @@ -9157,7 +9107,6 @@ func (s *DeleteBucketPolicyInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicyOutput type DeleteBucketPolicyOutput struct { _ struct{} `type:"structure"` } @@ -9172,7 +9121,6 @@ func (s DeleteBucketPolicyOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationRequest type DeleteBucketReplicationInput struct { _ struct{} `type:"structure"` @@ -9216,7 +9164,6 @@ func (s *DeleteBucketReplicationInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplicationOutput type DeleteBucketReplicationOutput struct { _ struct{} `type:"structure"` } @@ -9231,7 +9178,6 @@ func (s DeleteBucketReplicationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingRequest type DeleteBucketTaggingInput struct { _ struct{} `type:"structure"` @@ -9275,7 +9221,6 @@ func (s *DeleteBucketTaggingInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTaggingOutput type DeleteBucketTaggingOutput struct { _ struct{} `type:"structure"` } @@ -9290,7 +9235,6 @@ func (s DeleteBucketTaggingOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteRequest type DeleteBucketWebsiteInput struct { _ struct{} `type:"structure"` @@ -9334,7 +9278,6 @@ func (s *DeleteBucketWebsiteInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsiteOutput type DeleteBucketWebsiteOutput struct { _ struct{} `type:"structure"` } @@ -9349,7 +9292,6 @@ func (s DeleteBucketWebsiteOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteMarkerEntry type DeleteMarkerEntry struct { _ struct{} `type:"structure"` @@ -9409,7 +9351,6 @@ func (s *DeleteMarkerEntry) SetVersionId(v string) *DeleteMarkerEntry { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectRequest type DeleteObjectInput struct { _ struct{} `type:"structure"` @@ -9499,7 +9440,6 @@ func (s *DeleteObjectInput) SetVersionId(v string) *DeleteObjectInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectOutput type DeleteObjectOutput struct { _ struct{} `type:"structure"` @@ -9544,7 +9484,6 @@ func (s *DeleteObjectOutput) SetVersionId(v string) *DeleteObjectOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTaggingRequest type DeleteObjectTaggingInput struct { _ struct{} `type:"structure"` @@ -9612,7 +9551,6 @@ func (s *DeleteObjectTaggingInput) SetVersionId(v string) *DeleteObjectTaggingIn return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTaggingOutput type DeleteObjectTaggingOutput struct { _ struct{} `type:"structure"` @@ -9636,7 +9574,6 @@ func (s *DeleteObjectTaggingOutput) SetVersionId(v string) *DeleteObjectTaggingO return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectsRequest type DeleteObjectsInput struct { _ struct{} `type:"structure" payload:"Delete"` @@ -9719,7 +9656,6 @@ func (s *DeleteObjectsInput) SetRequestPayer(v string) *DeleteObjectsInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectsOutput type DeleteObjectsOutput struct { _ struct{} `type:"structure"` @@ -9760,7 +9696,6 @@ func (s *DeleteObjectsOutput) SetRequestCharged(v string) *DeleteObjectsOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeletedObject type DeletedObject struct { _ struct{} `type:"structure"` @@ -9808,7 +9743,6 @@ func (s *DeletedObject) SetVersionId(v string) *DeletedObject { } // Container for replication destination information. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Destination type Destination struct { _ struct{} `type:"structure"` @@ -9899,7 +9833,6 @@ func (s *Destination) SetStorageClass(v string) *Destination { // Describes the server-side encryption that will be applied to the restore // results. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Encryption type Encryption struct { _ struct{} `type:"structure"` @@ -9960,7 +9893,6 @@ func (s *Encryption) SetKMSKeyId(v string) *Encryption { } // Container for information regarding encryption based configuration for replicas. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/EncryptionConfiguration type EncryptionConfiguration struct { _ struct{} `type:"structure"` @@ -9984,7 +9916,6 @@ func (s *EncryptionConfiguration) SetReplicaKmsKeyID(v string) *EncryptionConfig return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Error type Error struct { _ struct{} `type:"structure"` @@ -10031,7 +9962,6 @@ func (s *Error) SetVersionId(v string) *Error { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ErrorDocument type ErrorDocument struct { _ struct{} `type:"structure"` @@ -10074,7 +10004,6 @@ func (s *ErrorDocument) SetKey(v string) *ErrorDocument { } // Container for key value pair that defines the criteria for the filter rule. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/FilterRule type FilterRule struct { _ struct{} `type:"structure"` @@ -10109,7 +10038,6 @@ func (s *FilterRule) SetValue(v string) *FilterRule { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationRequest type GetBucketAccelerateConfigurationInput struct { _ struct{} `type:"structure"` @@ -10155,7 +10083,6 @@ func (s *GetBucketAccelerateConfigurationInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfigurationOutput type GetBucketAccelerateConfigurationOutput struct { _ struct{} `type:"structure"` @@ -10179,7 +10106,6 @@ func (s *GetBucketAccelerateConfigurationOutput) SetStatus(v string) *GetBucketA return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclRequest type GetBucketAclInput struct { _ struct{} `type:"structure"` @@ -10223,7 +10149,6 @@ func (s *GetBucketAclInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAclOutput type GetBucketAclOutput struct { _ struct{} `type:"structure"` @@ -10255,7 +10180,6 @@ func (s *GetBucketAclOutput) SetOwner(v *Owner) *GetBucketAclOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfigurationRequest type GetBucketAnalyticsConfigurationInput struct { _ struct{} `type:"structure"` @@ -10315,7 +10239,6 @@ func (s *GetBucketAnalyticsConfigurationInput) SetId(v string) *GetBucketAnalyti return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfigurationOutput type GetBucketAnalyticsConfigurationOutput struct { _ struct{} `type:"structure" payload:"AnalyticsConfiguration"` @@ -10339,7 +10262,6 @@ func (s *GetBucketAnalyticsConfigurationOutput) SetAnalyticsConfiguration(v *Ana return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsRequest type GetBucketCorsInput struct { _ struct{} `type:"structure"` @@ -10383,7 +10305,6 @@ func (s *GetBucketCorsInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCorsOutput type GetBucketCorsOutput struct { _ struct{} `type:"structure"` @@ -10406,7 +10327,6 @@ func (s *GetBucketCorsOutput) SetCORSRules(v []*CORSRule) *GetBucketCorsOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryptionRequest type GetBucketEncryptionInput struct { _ struct{} `type:"structure"` @@ -10453,7 +10373,6 @@ func (s *GetBucketEncryptionInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryptionOutput type GetBucketEncryptionOutput struct { _ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"` @@ -10478,7 +10397,6 @@ func (s *GetBucketEncryptionOutput) SetServerSideEncryptionConfiguration(v *Serv return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfigurationRequest type GetBucketInventoryConfigurationInput struct { _ struct{} `type:"structure"` @@ -10538,7 +10456,6 @@ func (s *GetBucketInventoryConfigurationInput) SetId(v string) *GetBucketInvento return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfigurationOutput type GetBucketInventoryConfigurationOutput struct { _ struct{} `type:"structure" payload:"InventoryConfiguration"` @@ -10562,7 +10479,6 @@ func (s *GetBucketInventoryConfigurationOutput) SetInventoryConfiguration(v *Inv return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationRequest type GetBucketLifecycleConfigurationInput struct { _ struct{} `type:"structure"` @@ -10606,7 +10522,6 @@ func (s *GetBucketLifecycleConfigurationInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfigurationOutput type GetBucketLifecycleConfigurationOutput struct { _ struct{} `type:"structure"` @@ -10629,7 +10544,6 @@ func (s *GetBucketLifecycleConfigurationOutput) SetRules(v []*LifecycleRule) *Ge return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleRequest type GetBucketLifecycleInput struct { _ struct{} `type:"structure"` @@ -10673,7 +10587,6 @@ func (s *GetBucketLifecycleInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleOutput type GetBucketLifecycleOutput struct { _ struct{} `type:"structure"` @@ -10696,7 +10609,6 @@ func (s *GetBucketLifecycleOutput) SetRules(v []*Rule) *GetBucketLifecycleOutput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationRequest type GetBucketLocationInput struct { _ struct{} `type:"structure"` @@ -10740,7 +10652,6 @@ func (s *GetBucketLocationInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocationOutput type GetBucketLocationOutput struct { _ struct{} `type:"structure"` @@ -10763,7 +10674,6 @@ func (s *GetBucketLocationOutput) SetLocationConstraint(v string) *GetBucketLoca return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingRequest type GetBucketLoggingInput struct { _ struct{} `type:"structure"` @@ -10807,7 +10717,6 @@ func (s *GetBucketLoggingInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLoggingOutput type GetBucketLoggingOutput struct { _ struct{} `type:"structure"` @@ -10830,7 +10739,6 @@ func (s *GetBucketLoggingOutput) SetLoggingEnabled(v *LoggingEnabled) *GetBucket return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfigurationRequest type GetBucketMetricsConfigurationInput struct { _ struct{} `type:"structure"` @@ -10890,7 +10798,6 @@ func (s *GetBucketMetricsConfigurationInput) SetId(v string) *GetBucketMetricsCo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfigurationOutput type GetBucketMetricsConfigurationOutput struct { _ struct{} `type:"structure" payload:"MetricsConfiguration"` @@ -10914,7 +10821,6 @@ func (s *GetBucketMetricsConfigurationOutput) SetMetricsConfiguration(v *Metrics return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfigurationRequest type GetBucketNotificationConfigurationRequest struct { _ struct{} `type:"structure"` @@ -10960,7 +10866,6 @@ func (s *GetBucketNotificationConfigurationRequest) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyRequest type GetBucketPolicyInput struct { _ struct{} `type:"structure"` @@ -11004,7 +10909,6 @@ func (s *GetBucketPolicyInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicyOutput type GetBucketPolicyOutput struct { _ struct{} `type:"structure" payload:"Policy"` @@ -11028,7 +10932,6 @@ func (s *GetBucketPolicyOutput) SetPolicy(v string) *GetBucketPolicyOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationRequest type GetBucketReplicationInput struct { _ struct{} `type:"structure"` @@ -11072,7 +10975,6 @@ func (s *GetBucketReplicationInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplicationOutput type GetBucketReplicationOutput struct { _ struct{} `type:"structure" payload:"ReplicationConfiguration"` @@ -11097,7 +10999,6 @@ func (s *GetBucketReplicationOutput) SetReplicationConfiguration(v *ReplicationC return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentRequest type GetBucketRequestPaymentInput struct { _ struct{} `type:"structure"` @@ -11141,7 +11042,6 @@ func (s *GetBucketRequestPaymentInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPaymentOutput type GetBucketRequestPaymentOutput struct { _ struct{} `type:"structure"` @@ -11165,7 +11065,6 @@ func (s *GetBucketRequestPaymentOutput) SetPayer(v string) *GetBucketRequestPaym return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingRequest type GetBucketTaggingInput struct { _ struct{} `type:"structure"` @@ -11209,7 +11108,6 @@ func (s *GetBucketTaggingInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTaggingOutput type GetBucketTaggingOutput struct { _ struct{} `type:"structure"` @@ -11233,7 +11131,6 @@ func (s *GetBucketTaggingOutput) SetTagSet(v []*Tag) *GetBucketTaggingOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningRequest type GetBucketVersioningInput struct { _ struct{} `type:"structure"` @@ -11277,7 +11174,6 @@ func (s *GetBucketVersioningInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioningOutput type GetBucketVersioningOutput struct { _ struct{} `type:"structure"` @@ -11312,7 +11208,6 @@ func (s *GetBucketVersioningOutput) SetStatus(v string) *GetBucketVersioningOutp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteRequest type GetBucketWebsiteInput struct { _ struct{} `type:"structure"` @@ -11356,7 +11251,6 @@ func (s *GetBucketWebsiteInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsiteOutput type GetBucketWebsiteOutput struct { _ struct{} `type:"structure"` @@ -11403,7 +11297,6 @@ func (s *GetBucketWebsiteOutput) SetRoutingRules(v []*RoutingRule) *GetBucketWeb return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAclRequest type GetObjectAclInput struct { _ struct{} `type:"structure"` @@ -11483,7 +11376,6 @@ func (s *GetObjectAclInput) SetVersionId(v string) *GetObjectAclInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAclOutput type GetObjectAclOutput struct { _ struct{} `type:"structure"` @@ -11525,7 +11417,6 @@ func (s *GetObjectAclOutput) SetRequestCharged(v string) *GetObjectAclOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectRequest type GetObjectInput struct { _ struct{} `type:"structure"` @@ -11760,7 +11651,6 @@ func (s *GetObjectInput) SetVersionId(v string) *GetObjectInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectOutput type GetObjectOutput struct { _ struct{} `type:"structure" payload:"Body"` @@ -12044,7 +11934,6 @@ func (s *GetObjectOutput) SetWebsiteRedirectLocation(v string) *GetObjectOutput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTaggingRequest type GetObjectTaggingInput struct { _ struct{} `type:"structure"` @@ -12111,7 +12000,6 @@ func (s *GetObjectTaggingInput) SetVersionId(v string) *GetObjectTaggingInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTaggingOutput type GetObjectTaggingOutput struct { _ struct{} `type:"structure"` @@ -12143,7 +12031,6 @@ func (s *GetObjectTaggingOutput) SetVersionId(v string) *GetObjectTaggingOutput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrentRequest type GetObjectTorrentInput struct { _ struct{} `type:"structure"` @@ -12214,7 +12101,6 @@ func (s *GetObjectTorrentInput) SetRequestPayer(v string) *GetObjectTorrentInput return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrentOutput type GetObjectTorrentOutput struct { _ struct{} `type:"structure" payload:"Body"` @@ -12247,7 +12133,6 @@ func (s *GetObjectTorrentOutput) SetRequestCharged(v string) *GetObjectTorrentOu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GlacierJobParameters type GlacierJobParameters struct { _ struct{} `type:"structure"` @@ -12286,7 +12171,6 @@ func (s *GlacierJobParameters) SetTier(v string) *GlacierJobParameters { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Grant type Grant struct { _ struct{} `type:"structure"` @@ -12333,7 +12217,6 @@ func (s *Grant) SetPermission(v string) *Grant { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Grantee type Grantee struct { _ struct{} `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"` @@ -12408,7 +12291,6 @@ func (s *Grantee) SetURI(v string) *Grantee { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketRequest type HeadBucketInput struct { _ struct{} `type:"structure"` @@ -12452,7 +12334,6 @@ func (s *HeadBucketInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucketOutput type HeadBucketOutput struct { _ struct{} `type:"structure"` } @@ -12467,7 +12348,6 @@ func (s HeadBucketOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObjectRequest type HeadObjectInput struct { _ struct{} `type:"structure"` @@ -12649,7 +12529,6 @@ func (s *HeadObjectInput) SetVersionId(v string) *HeadObjectInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObjectOutput type HeadObjectOutput struct { _ struct{} `type:"structure"` @@ -12906,7 +12785,6 @@ func (s *HeadObjectOutput) SetWebsiteRedirectLocation(v string) *HeadObjectOutpu return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/IndexDocument type IndexDocument struct { _ struct{} `type:"structure"` @@ -12948,7 +12826,6 @@ func (s *IndexDocument) SetSuffix(v string) *IndexDocument { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Initiator type Initiator struct { _ struct{} `type:"structure"` @@ -12983,7 +12860,6 @@ func (s *Initiator) SetID(v string) *Initiator { } // Describes the serialization format of the object. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InputSerialization type InputSerialization struct { _ struct{} `type:"structure"` @@ -13007,7 +12883,6 @@ func (s *InputSerialization) SetCSV(v *CSVInput) *InputSerialization { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryConfiguration type InventoryConfiguration struct { _ struct{} `type:"structure"` @@ -13136,7 +13011,6 @@ func (s *InventoryConfiguration) SetSchedule(v *InventorySchedule) *InventoryCon return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryDestination type InventoryDestination struct { _ struct{} `type:"structure"` @@ -13183,7 +13057,6 @@ func (s *InventoryDestination) SetS3BucketDestination(v *InventoryS3BucketDestin // Contains the type of server-side encryption used to encrypt the inventory // results. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryEncryption type InventoryEncryption struct { _ struct{} `type:"structure"` @@ -13231,7 +13104,6 @@ func (s *InventoryEncryption) SetSSES3(v *SSES3) *InventoryEncryption { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryFilter type InventoryFilter struct { _ struct{} `type:"structure"` @@ -13270,7 +13142,6 @@ func (s *InventoryFilter) SetPrefix(v string) *InventoryFilter { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventoryS3BucketDestination type InventoryS3BucketDestination struct { _ struct{} `type:"structure"` @@ -13364,7 +13235,6 @@ func (s *InventoryS3BucketDestination) SetPrefix(v string) *InventoryS3BucketDes return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/InventorySchedule type InventorySchedule struct { _ struct{} `type:"structure"` @@ -13404,7 +13274,6 @@ func (s *InventorySchedule) SetFrequency(v string) *InventorySchedule { } // Container for object key name prefix and suffix filtering rules. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/S3KeyFilter type KeyFilter struct { _ struct{} `type:"structure"` @@ -13430,7 +13299,6 @@ func (s *KeyFilter) SetFilterRules(v []*FilterRule) *KeyFilter { } // Container for specifying the AWS Lambda notification configuration. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LambdaFunctionConfiguration type LambdaFunctionConfiguration struct { _ struct{} `type:"structure"` @@ -13502,7 +13370,6 @@ func (s *LambdaFunctionConfiguration) SetLambdaFunctionArn(v string) *LambdaFunc return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleConfiguration type LifecycleConfiguration struct { _ struct{} `type:"structure"` @@ -13549,7 +13416,6 @@ func (s *LifecycleConfiguration) SetRules(v []*Rule) *LifecycleConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleExpiration type LifecycleExpiration struct { _ struct{} `type:"structure"` @@ -13596,7 +13462,6 @@ func (s *LifecycleExpiration) SetExpiredObjectDeleteMarker(v bool) *LifecycleExp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRule type LifecycleRule struct { _ struct{} `type:"structure"` @@ -13720,7 +13585,6 @@ func (s *LifecycleRule) SetTransitions(v []*Transition) *LifecycleRule { // This is used in a Lifecycle Rule Filter to apply a logical AND to two or // more predicates. The Lifecycle Rule will apply to any object matching all // of the predicates configured inside the And operator. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRuleAndOperator type LifecycleRuleAndOperator struct { _ struct{} `type:"structure"` @@ -13775,7 +13639,6 @@ func (s *LifecycleRuleAndOperator) SetTags(v []*Tag) *LifecycleRuleAndOperator { // The Filter is used to identify objects that a Lifecycle Rule applies to. // A Filter must have exactly one of Prefix, Tag, or And specified. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LifecycleRuleFilter type LifecycleRuleFilter struct { _ struct{} `type:"structure"` @@ -13839,7 +13702,6 @@ func (s *LifecycleRuleFilter) SetTag(v *Tag) *LifecycleRuleFilter { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurationsRequest type ListBucketAnalyticsConfigurationsInput struct { _ struct{} `type:"structure"` @@ -13895,7 +13757,6 @@ func (s *ListBucketAnalyticsConfigurationsInput) SetContinuationToken(v string) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurationsOutput type ListBucketAnalyticsConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -13950,7 +13811,6 @@ func (s *ListBucketAnalyticsConfigurationsOutput) SetNextContinuationToken(v str return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurationsRequest type ListBucketInventoryConfigurationsInput struct { _ struct{} `type:"structure"` @@ -14008,7 +13868,6 @@ func (s *ListBucketInventoryConfigurationsInput) SetContinuationToken(v string) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurationsOutput type ListBucketInventoryConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -14063,7 +13922,6 @@ func (s *ListBucketInventoryConfigurationsOutput) SetNextContinuationToken(v str return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurationsRequest type ListBucketMetricsConfigurationsInput struct { _ struct{} `type:"structure"` @@ -14121,7 +13979,6 @@ func (s *ListBucketMetricsConfigurationsInput) SetContinuationToken(v string) *L return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurationsOutput type ListBucketMetricsConfigurationsOutput struct { _ struct{} `type:"structure"` @@ -14178,7 +14035,6 @@ func (s *ListBucketMetricsConfigurationsOutput) SetNextContinuationToken(v strin return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketsInput type ListBucketsInput struct { _ struct{} `type:"structure"` } @@ -14193,7 +14049,6 @@ func (s ListBucketsInput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketsOutput type ListBucketsOutput struct { _ struct{} `type:"structure"` @@ -14224,7 +14079,6 @@ func (s *ListBucketsOutput) SetOwner(v *Owner) *ListBucketsOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploadsRequest type ListMultipartUploadsInput struct { _ struct{} `type:"structure"` @@ -14333,7 +14187,6 @@ func (s *ListMultipartUploadsInput) SetUploadIdMarker(v string) *ListMultipartUp return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploadsOutput type ListMultipartUploadsOutput struct { _ struct{} `type:"structure"` @@ -14467,7 +14320,6 @@ func (s *ListMultipartUploadsOutput) SetUploads(v []*MultipartUpload) *ListMulti return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersionsRequest type ListObjectVersionsInput struct { _ struct{} `type:"structure"` @@ -14571,7 +14423,6 @@ func (s *ListObjectVersionsInput) SetVersionIdMarker(v string) *ListObjectVersio return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersionsOutput type ListObjectVersionsOutput struct { _ struct{} `type:"structure"` @@ -14699,7 +14550,6 @@ func (s *ListObjectVersionsOutput) SetVersions(v []*ObjectVersion) *ListObjectVe return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsRequest type ListObjectsInput struct { _ struct{} `type:"structure"` @@ -14805,7 +14655,6 @@ func (s *ListObjectsInput) SetRequestPayer(v string) *ListObjectsInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsOutput type ListObjectsOutput struct { _ struct{} `type:"structure"` @@ -14910,7 +14759,6 @@ func (s *ListObjectsOutput) SetPrefix(v string) *ListObjectsOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2Request type ListObjectsV2Input struct { _ struct{} `type:"structure"` @@ -15036,7 +14884,6 @@ func (s *ListObjectsV2Input) SetStartAfter(v string) *ListObjectsV2Input { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2Output type ListObjectsV2Output struct { _ struct{} `type:"structure"` @@ -15170,7 +15017,6 @@ func (s *ListObjectsV2Output) SetStartAfter(v string) *ListObjectsV2Output { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListPartsRequest type ListPartsInput struct { _ struct{} `type:"structure"` @@ -15274,7 +15120,6 @@ func (s *ListPartsInput) SetUploadId(v string) *ListPartsInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListPartsOutput type ListPartsOutput struct { _ struct{} `type:"structure"` @@ -15425,7 +15270,6 @@ func (s *ListPartsOutput) SetUploadId(v string) *ListPartsOutput { } // Describes an S3 location that will receive the results of the restore request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/S3Location type Location struct { _ struct{} `type:"structure"` @@ -15553,7 +15397,6 @@ func (s *Location) SetUserMetadata(v []*MetadataEntry) *Location { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/LoggingEnabled type LoggingEnabled struct { _ struct{} `type:"structure"` @@ -15621,7 +15464,6 @@ func (s *LoggingEnabled) SetTargetPrefix(v string) *LoggingEnabled { } // A metadata key-value pair to store with an object. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetadataEntry type MetadataEntry struct { _ struct{} `type:"structure"` @@ -15652,7 +15494,6 @@ func (s *MetadataEntry) SetValue(v string) *MetadataEntry { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsAndOperator type MetricsAndOperator struct { _ struct{} `type:"structure"` @@ -15705,7 +15546,6 @@ func (s *MetricsAndOperator) SetTags(v []*Tag) *MetricsAndOperator { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsConfiguration type MetricsConfiguration struct { _ struct{} `type:"structure"` @@ -15760,7 +15600,6 @@ func (s *MetricsConfiguration) SetId(v string) *MetricsConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MetricsFilter type MetricsFilter struct { _ struct{} `type:"structure"` @@ -15824,7 +15663,6 @@ func (s *MetricsFilter) SetTag(v *Tag) *MetricsFilter { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/MultipartUpload type MultipartUpload struct { _ struct{} `type:"structure"` @@ -15897,7 +15735,6 @@ func (s *MultipartUpload) SetUploadId(v string) *MultipartUpload { // configuration action on a bucket that has versioning enabled (or suspended) // to request that Amazon S3 delete noncurrent object versions at a specific // period in the object's lifetime. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NoncurrentVersionExpiration type NoncurrentVersionExpiration struct { _ struct{} `type:"structure"` @@ -15929,7 +15766,6 @@ func (s *NoncurrentVersionExpiration) SetNoncurrentDays(v int64) *NoncurrentVers // versioning-enabled (or versioning is suspended), you can set this action // to request that Amazon S3 transition noncurrent object versions to the STANDARD_IA // or GLACIER storage class at a specific period in the object's lifetime. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NoncurrentVersionTransition type NoncurrentVersionTransition struct { _ struct{} `type:"structure"` @@ -15967,7 +15803,6 @@ func (s *NoncurrentVersionTransition) SetStorageClass(v string) *NoncurrentVersi // Container for specifying the notification configuration of the bucket. If // this element is empty, notifications are turned off on the bucket. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfiguration type NotificationConfiguration struct { _ struct{} `type:"structure"` @@ -16046,7 +15881,6 @@ func (s *NotificationConfiguration) SetTopicConfigurations(v []*TopicConfigurati return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfigurationDeprecated type NotificationConfigurationDeprecated struct { _ struct{} `type:"structure"` @@ -16087,7 +15921,6 @@ func (s *NotificationConfigurationDeprecated) SetTopicConfiguration(v *TopicConf // Container for object key name filtering rules. For information about key // name filtering, go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html) -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/NotificationConfigurationFilter type NotificationConfigurationFilter struct { _ struct{} `type:"structure"` @@ -16111,7 +15944,6 @@ func (s *NotificationConfigurationFilter) SetKey(v *KeyFilter) *NotificationConf return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Object type Object struct { _ struct{} `type:"structure"` @@ -16175,7 +16007,6 @@ func (s *Object) SetStorageClass(v string) *Object { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ObjectIdentifier type ObjectIdentifier struct { _ struct{} `type:"structure"` @@ -16226,7 +16057,6 @@ func (s *ObjectIdentifier) SetVersionId(v string) *ObjectIdentifier { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ObjectVersion type ObjectVersion struct { _ struct{} `type:"structure"` @@ -16313,7 +16143,6 @@ func (s *ObjectVersion) SetVersionId(v string) *ObjectVersion { } // Describes the location where the restore job's output is stored. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/OutputLocation type OutputLocation struct { _ struct{} `type:"structure"` @@ -16353,7 +16182,6 @@ func (s *OutputLocation) SetS3(v *Location) *OutputLocation { } // Describes how results of the Select job are serialized. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/OutputSerialization type OutputSerialization struct { _ struct{} `type:"structure"` @@ -16377,7 +16205,6 @@ func (s *OutputSerialization) SetCSV(v *CSVOutput) *OutputSerialization { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Owner type Owner struct { _ struct{} `type:"structure"` @@ -16408,7 +16235,6 @@ func (s *Owner) SetID(v string) *Owner { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Part type Part struct { _ struct{} `type:"structure"` @@ -16460,7 +16286,6 @@ func (s *Part) SetSize(v int64) *Part { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationRequest type PutBucketAccelerateConfigurationInput struct { _ struct{} `type:"structure" payload:"AccelerateConfiguration"` @@ -16520,7 +16345,6 @@ func (s *PutBucketAccelerateConfigurationInput) getBucket() (v string) { return *s.Bucket } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfigurationOutput type PutBucketAccelerateConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -16535,7 +16359,6 @@ func (s PutBucketAccelerateConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAclRequest type PutBucketAclInput struct { _ struct{} `type:"structure" payload:"AccessControlPolicy"` @@ -16647,7 +16470,6 @@ func (s *PutBucketAclInput) SetGrantWriteACP(v string) *PutBucketAclInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAclOutput type PutBucketAclOutput struct { _ struct{} `type:"structure"` } @@ -16662,7 +16484,6 @@ func (s PutBucketAclOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfigurationRequest type PutBucketAnalyticsConfigurationInput struct { _ struct{} `type:"structure" payload:"AnalyticsConfiguration"` @@ -16741,7 +16562,6 @@ func (s *PutBucketAnalyticsConfigurationInput) SetId(v string) *PutBucketAnalyti return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfigurationOutput type PutBucketAnalyticsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -16756,7 +16576,6 @@ func (s PutBucketAnalyticsConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCorsRequest type PutBucketCorsInput struct { _ struct{} `type:"structure" payload:"CORSConfiguration"` @@ -16817,7 +16636,6 @@ func (s *PutBucketCorsInput) SetCORSConfiguration(v *CORSConfiguration) *PutBuck return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCorsOutput type PutBucketCorsOutput struct { _ struct{} `type:"structure"` } @@ -16832,7 +16650,6 @@ func (s PutBucketCorsOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryptionRequest type PutBucketEncryptionInput struct { _ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"` @@ -16899,7 +16716,6 @@ func (s *PutBucketEncryptionInput) SetServerSideEncryptionConfiguration(v *Serve return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryptionOutput type PutBucketEncryptionOutput struct { _ struct{} `type:"structure"` } @@ -16914,7 +16730,6 @@ func (s PutBucketEncryptionOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfigurationRequest type PutBucketInventoryConfigurationInput struct { _ struct{} `type:"structure" payload:"InventoryConfiguration"` @@ -16993,7 +16808,6 @@ func (s *PutBucketInventoryConfigurationInput) SetInventoryConfiguration(v *Inve return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfigurationOutput type PutBucketInventoryConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -17008,7 +16822,6 @@ func (s PutBucketInventoryConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfigurationRequest type PutBucketLifecycleConfigurationInput struct { _ struct{} `type:"structure" payload:"LifecycleConfiguration"` @@ -17065,7 +16878,6 @@ func (s *PutBucketLifecycleConfigurationInput) SetLifecycleConfiguration(v *Buck return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfigurationOutput type PutBucketLifecycleConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -17080,7 +16892,6 @@ func (s PutBucketLifecycleConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleRequest type PutBucketLifecycleInput struct { _ struct{} `type:"structure" payload:"LifecycleConfiguration"` @@ -17137,7 +16948,6 @@ func (s *PutBucketLifecycleInput) SetLifecycleConfiguration(v *LifecycleConfigur return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleOutput type PutBucketLifecycleOutput struct { _ struct{} `type:"structure"` } @@ -17152,7 +16962,6 @@ func (s PutBucketLifecycleOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLoggingRequest type PutBucketLoggingInput struct { _ struct{} `type:"structure" payload:"BucketLoggingStatus"` @@ -17213,7 +17022,6 @@ func (s *PutBucketLoggingInput) SetBucketLoggingStatus(v *BucketLoggingStatus) * return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLoggingOutput type PutBucketLoggingOutput struct { _ struct{} `type:"structure"` } @@ -17228,7 +17036,6 @@ func (s PutBucketLoggingOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfigurationRequest type PutBucketMetricsConfigurationInput struct { _ struct{} `type:"structure" payload:"MetricsConfiguration"` @@ -17307,7 +17114,6 @@ func (s *PutBucketMetricsConfigurationInput) SetMetricsConfiguration(v *MetricsC return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfigurationOutput type PutBucketMetricsConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -17322,7 +17128,6 @@ func (s PutBucketMetricsConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfigurationRequest type PutBucketNotificationConfigurationInput struct { _ struct{} `type:"structure" payload:"NotificationConfiguration"` @@ -17386,7 +17191,6 @@ func (s *PutBucketNotificationConfigurationInput) SetNotificationConfiguration(v return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfigurationOutput type PutBucketNotificationConfigurationOutput struct { _ struct{} `type:"structure"` } @@ -17401,7 +17205,6 @@ func (s PutBucketNotificationConfigurationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationRequest type PutBucketNotificationInput struct { _ struct{} `type:"structure" payload:"NotificationConfiguration"` @@ -17457,7 +17260,6 @@ func (s *PutBucketNotificationInput) SetNotificationConfiguration(v *Notificatio return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationOutput type PutBucketNotificationOutput struct { _ struct{} `type:"structure"` } @@ -17472,7 +17274,6 @@ func (s PutBucketNotificationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicyRequest type PutBucketPolicyInput struct { _ struct{} `type:"structure" payload:"Policy"` @@ -17540,7 +17341,6 @@ func (s *PutBucketPolicyInput) SetPolicy(v string) *PutBucketPolicyInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicyOutput type PutBucketPolicyOutput struct { _ struct{} `type:"structure"` } @@ -17555,7 +17355,6 @@ func (s PutBucketPolicyOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplicationRequest type PutBucketReplicationInput struct { _ struct{} `type:"structure" payload:"ReplicationConfiguration"` @@ -17619,7 +17418,6 @@ func (s *PutBucketReplicationInput) SetReplicationConfiguration(v *ReplicationCo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplicationOutput type PutBucketReplicationOutput struct { _ struct{} `type:"structure"` } @@ -17634,7 +17432,6 @@ func (s PutBucketReplicationOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPaymentRequest type PutBucketRequestPaymentInput struct { _ struct{} `type:"structure" payload:"RequestPaymentConfiguration"` @@ -17695,7 +17492,6 @@ func (s *PutBucketRequestPaymentInput) SetRequestPaymentConfiguration(v *Request return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPaymentOutput type PutBucketRequestPaymentOutput struct { _ struct{} `type:"structure"` } @@ -17710,7 +17506,6 @@ func (s PutBucketRequestPaymentOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTaggingRequest type PutBucketTaggingInput struct { _ struct{} `type:"structure" payload:"Tagging"` @@ -17771,7 +17566,6 @@ func (s *PutBucketTaggingInput) SetTagging(v *Tagging) *PutBucketTaggingInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTaggingOutput type PutBucketTaggingOutput struct { _ struct{} `type:"structure"` } @@ -17786,7 +17580,6 @@ func (s PutBucketTaggingOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioningRequest type PutBucketVersioningInput struct { _ struct{} `type:"structure" payload:"VersioningConfiguration"` @@ -17852,7 +17645,6 @@ func (s *PutBucketVersioningInput) SetVersioningConfiguration(v *VersioningConfi return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioningOutput type PutBucketVersioningOutput struct { _ struct{} `type:"structure"` } @@ -17867,7 +17659,6 @@ func (s PutBucketVersioningOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsiteRequest type PutBucketWebsiteInput struct { _ struct{} `type:"structure" payload:"WebsiteConfiguration"` @@ -17928,7 +17719,6 @@ func (s *PutBucketWebsiteInput) SetWebsiteConfiguration(v *WebsiteConfiguration) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsiteOutput type PutBucketWebsiteOutput struct { _ struct{} `type:"structure"` } @@ -17943,7 +17733,6 @@ func (s PutBucketWebsiteOutput) GoString() string { return s.String() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAclRequest type PutObjectAclInput struct { _ struct{} `type:"structure" payload:"AccessControlPolicy"` @@ -18091,7 +17880,6 @@ func (s *PutObjectAclInput) SetVersionId(v string) *PutObjectAclInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAclOutput type PutObjectAclOutput struct { _ struct{} `type:"structure"` @@ -18116,7 +17904,6 @@ func (s *PutObjectAclOutput) SetRequestCharged(v string) *PutObjectAclOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectRequest type PutObjectInput struct { _ struct{} `type:"structure" payload:"Body"` @@ -18420,7 +18207,6 @@ func (s *PutObjectInput) SetWebsiteRedirectLocation(v string) *PutObjectInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectOutput type PutObjectOutput struct { _ struct{} `type:"structure"` @@ -18515,7 +18301,6 @@ func (s *PutObjectOutput) SetVersionId(v string) *PutObjectOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTaggingRequest type PutObjectTaggingInput struct { _ struct{} `type:"structure" payload:"Tagging"` @@ -18599,7 +18384,6 @@ func (s *PutObjectTaggingInput) SetVersionId(v string) *PutObjectTaggingInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTaggingOutput type PutObjectTaggingOutput struct { _ struct{} `type:"structure"` @@ -18624,7 +18408,6 @@ func (s *PutObjectTaggingOutput) SetVersionId(v string) *PutObjectTaggingOutput // Container for specifying an configuration when you want Amazon S3 to publish // events to an Amazon Simple Queue Service (Amazon SQS) queue. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/QueueConfiguration type QueueConfiguration struct { _ struct{} `type:"structure"` @@ -18696,7 +18479,6 @@ func (s *QueueConfiguration) SetQueueArn(v string) *QueueConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/QueueConfigurationDeprecated type QueueConfigurationDeprecated struct { _ struct{} `type:"structure"` @@ -18746,7 +18528,6 @@ func (s *QueueConfigurationDeprecated) SetQueue(v string) *QueueConfigurationDep return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Redirect type Redirect struct { _ struct{} `type:"structure"` @@ -18815,7 +18596,6 @@ func (s *Redirect) SetReplaceKeyWith(v string) *Redirect { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RedirectAllRequestsTo type RedirectAllRequestsTo struct { _ struct{} `type:"structure"` @@ -18866,7 +18646,6 @@ func (s *RedirectAllRequestsTo) SetProtocol(v string) *RedirectAllRequestsTo { // Container for replication rules. You can add as many as 1,000 rules. Total // replication configuration size can be up to 2 MB. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ReplicationConfiguration type ReplicationConfiguration struct { _ struct{} `type:"structure"` @@ -18932,7 +18711,6 @@ func (s *ReplicationConfiguration) SetRules(v []*ReplicationRule) *ReplicationCo } // Container for information about a particular replication rule. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ReplicationRule type ReplicationRule struct { _ struct{} `type:"structure"` @@ -19029,7 +18807,6 @@ func (s *ReplicationRule) SetStatus(v string) *ReplicationRule { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RequestPaymentConfiguration type RequestPaymentConfiguration struct { _ struct{} `type:"structure"` @@ -19068,7 +18845,6 @@ func (s *RequestPaymentConfiguration) SetPayer(v string) *RequestPaymentConfigur return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObjectRequest type RestoreObjectInput struct { _ struct{} `type:"structure" payload:"RestoreRequest"` @@ -19161,7 +18937,6 @@ func (s *RestoreObjectInput) SetVersionId(v string) *RestoreObjectInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObjectOutput type RestoreObjectOutput struct { _ struct{} `type:"structure"` @@ -19197,7 +18972,6 @@ func (s *RestoreObjectOutput) SetRestoreOutputPath(v string) *RestoreObjectOutpu } // Container for restore job parameters. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreRequest type RestoreRequest struct { _ struct{} `type:"structure"` @@ -19302,7 +19076,6 @@ func (s *RestoreRequest) SetType(v string) *RestoreRequest { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RoutingRule type RoutingRule struct { _ struct{} `type:"structure"` @@ -19355,7 +19128,6 @@ func (s *RoutingRule) SetRedirect(v *Redirect) *RoutingRule { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Rule type Rule struct { _ struct{} `type:"structure"` @@ -19471,7 +19243,6 @@ func (s *Rule) SetTransition(v *Transition) *Rule { } // Specifies the use of SSE-KMS to encrypt delievered Inventory reports. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SSEKMS type SSEKMS struct { _ struct{} `locationName:"SSE-KMS" type:"structure"` @@ -19512,7 +19283,6 @@ func (s *SSEKMS) SetKeyId(v string) *SSEKMS { } // Specifies the use of SSE-S3 to encrypt delievered Inventory reports. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SSES3 type SSES3 struct { _ struct{} `locationName:"SSE-S3" type:"structure"` } @@ -19528,7 +19298,6 @@ func (s SSES3) GoString() string { } // Describes the parameters for Select job types. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SelectParameters type SelectParameters struct { _ struct{} `type:"structure"` @@ -19612,7 +19381,6 @@ func (s *SelectParameters) SetOutputSerialization(v *OutputSerialization) *Selec // Describes the default server-side encryption to apply to new objects in the // bucket. If Put Object request does not specify any server-side encryption, // this default encryption will be applied. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ServerSideEncryptionByDefault type ServerSideEncryptionByDefault struct { _ struct{} `type:"structure"` @@ -19663,7 +19431,6 @@ func (s *ServerSideEncryptionByDefault) SetSSEAlgorithm(v string) *ServerSideEnc // Container for server-side encryption configuration rules. Currently S3 supports // one rule only. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ServerSideEncryptionConfiguration type ServerSideEncryptionConfiguration struct { _ struct{} `type:"structure"` @@ -19715,7 +19482,6 @@ func (s *ServerSideEncryptionConfiguration) SetRules(v []*ServerSideEncryptionRu // Container for information about a particular server-side encryption configuration // rule. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ServerSideEncryptionRule type ServerSideEncryptionRule struct { _ struct{} `type:"structure"` @@ -19757,7 +19523,6 @@ func (s *ServerSideEncryptionRule) SetApplyServerSideEncryptionByDefault(v *Serv } // Container for filters that define which source objects should be replicated. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SourceSelectionCriteria type SourceSelectionCriteria struct { _ struct{} `type:"structure"` @@ -19797,7 +19562,6 @@ func (s *SourceSelectionCriteria) SetSseKmsEncryptedObjects(v *SseKmsEncryptedOb } // Container for filter information of selection of KMS Encrypted S3 objects. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SseKmsEncryptedObjects type SseKmsEncryptedObjects struct { _ struct{} `type:"structure"` @@ -19837,7 +19601,6 @@ func (s *SseKmsEncryptedObjects) SetStatus(v string) *SseKmsEncryptedObjects { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/StorageClassAnalysis type StorageClassAnalysis struct { _ struct{} `type:"structure"` @@ -19877,7 +19640,6 @@ func (s *StorageClassAnalysis) SetDataExport(v *StorageClassAnalysisDataExport) return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/StorageClassAnalysisDataExport type StorageClassAnalysisDataExport struct { _ struct{} `type:"structure"` @@ -19935,7 +19697,6 @@ func (s *StorageClassAnalysisDataExport) SetOutputSchemaVersion(v string) *Stora return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Tag type Tag struct { _ struct{} `type:"structure"` @@ -19991,7 +19752,6 @@ func (s *Tag) SetValue(v string) *Tag { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Tagging type Tagging struct { _ struct{} `type:"structure"` @@ -20038,7 +19798,6 @@ func (s *Tagging) SetTagSet(v []*Tag) *Tagging { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TargetGrant type TargetGrant struct { _ struct{} `type:"structure"` @@ -20087,7 +19846,6 @@ func (s *TargetGrant) SetPermission(v string) *TargetGrant { // Container for specifying the configuration when you want Amazon S3 to publish // events to an Amazon Simple Notification Service (Amazon SNS) topic. -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TopicConfiguration type TopicConfiguration struct { _ struct{} `type:"structure"` @@ -20159,7 +19917,6 @@ func (s *TopicConfiguration) SetTopicArn(v string) *TopicConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/TopicConfigurationDeprecated type TopicConfigurationDeprecated struct { _ struct{} `type:"structure"` @@ -20211,7 +19968,6 @@ func (s *TopicConfigurationDeprecated) SetTopic(v string) *TopicConfigurationDep return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/Transition type Transition struct { _ struct{} `type:"structure"` @@ -20255,7 +20011,6 @@ func (s *Transition) SetStorageClass(v string) *Transition { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopyRequest type UploadPartCopyInput struct { _ struct{} `type:"structure"` @@ -20499,7 +20254,6 @@ func (s *UploadPartCopyInput) SetUploadId(v string) *UploadPartCopyInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopyOutput type UploadPartCopyOutput struct { _ struct{} `type:"structure" payload:"CopyPartResult"` @@ -20584,7 +20338,6 @@ func (s *UploadPartCopyOutput) SetServerSideEncryption(v string) *UploadPartCopy return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartRequest type UploadPartInput struct { _ struct{} `type:"structure" payload:"Body"` @@ -20757,7 +20510,6 @@ func (s *UploadPartInput) SetUploadId(v string) *UploadPartInput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartOutput type UploadPartOutput struct { _ struct{} `type:"structure"` @@ -20833,7 +20585,6 @@ func (s *UploadPartOutput) SetServerSideEncryption(v string) *UploadPartOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/VersioningConfiguration type VersioningConfiguration struct { _ struct{} `type:"structure"` @@ -20868,7 +20619,6 @@ func (s *VersioningConfiguration) SetStatus(v string) *VersioningConfiguration { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/WebsiteConfiguration type WebsiteConfiguration struct { _ struct{} `type:"structure"` diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go index 23f0a06db..22a0a1285 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -1049,7 +1049,6 @@ func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionToken return out, req.Send() } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest type AssumeRoleInput struct { _ struct{} `type:"structure"` @@ -1241,7 +1240,6 @@ func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput { // Contains the response to a successful AssumeRole request, including temporary // AWS credentials that can be used to make AWS requests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse type AssumeRoleOutput struct { _ struct{} `type:"structure"` @@ -1295,7 +1293,6 @@ func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest type AssumeRoleWithSAMLInput struct { _ struct{} `type:"structure"` @@ -1436,7 +1433,6 @@ func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAML // Contains the response to a successful AssumeRoleWithSAML request, including // temporary AWS credentials that can be used to make AWS requests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse type AssumeRoleWithSAMLOutput struct { _ struct{} `type:"structure"` @@ -1548,7 +1544,6 @@ func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLO return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest type AssumeRoleWithWebIdentityInput struct { _ struct{} `type:"structure"` @@ -1711,7 +1706,6 @@ func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRo // Contains the response to a successful AssumeRoleWithWebIdentity request, // including temporary AWS credentials that can be used to make AWS requests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse type AssumeRoleWithWebIdentityOutput struct { _ struct{} `type:"structure"` @@ -1804,7 +1798,6 @@ func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v strin // The identifiers for the temporary security credentials that the operation // returns. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser type AssumedRoleUser struct { _ struct{} `type:"structure"` @@ -1847,7 +1840,6 @@ func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser { } // AWS credentials for API authentication. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials type Credentials struct { _ struct{} `type:"structure"` @@ -1906,7 +1898,6 @@ func (s *Credentials) SetSessionToken(v string) *Credentials { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest type DecodeAuthorizationMessageInput struct { _ struct{} `type:"structure"` @@ -1951,7 +1942,6 @@ func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAut // A document that contains additional information about the authorization status // of a request from an encoded message that is returned in response to an AWS // request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse type DecodeAuthorizationMessageOutput struct { _ struct{} `type:"structure"` @@ -1976,7 +1966,6 @@ func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAu } // Identifiers for the federated user that is associated with the credentials. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser type FederatedUser struct { _ struct{} `type:"structure"` @@ -2017,7 +2006,6 @@ func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest type GetCallerIdentityInput struct { _ struct{} `type:"structure"` } @@ -2034,7 +2022,6 @@ func (s GetCallerIdentityInput) GoString() string { // Contains the response to a successful GetCallerIdentity request, including // information about the entity making the request. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse type GetCallerIdentityOutput struct { _ struct{} `type:"structure"` @@ -2080,7 +2067,6 @@ func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput { return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest type GetFederationTokenInput struct { _ struct{} `type:"structure"` @@ -2189,7 +2175,6 @@ func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput { // Contains the response to a successful GetFederationToken request, including // temporary AWS credentials that can be used to make AWS requests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse type GetFederationTokenOutput struct { _ struct{} `type:"structure"` @@ -2242,7 +2227,6 @@ func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTo return s } -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest type GetSessionTokenInput struct { _ struct{} `type:"structure"` @@ -2327,7 +2311,6 @@ func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput { // Contains the response to a successful GetSessionToken request, including // temporary AWS credentials that can be used to make AWS requests. -// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse type GetSessionTokenOutput struct { _ struct{} `type:"structure"` diff --git a/vendor/vendor.json b/vendor/vendor.json index 97a1a27f8..05fc0faa4 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -232,8 +232,8 @@ "path": "github.com/NaverCloudPlatform/ncloud-sdk-go/sdk", "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", "revisionTime": "2018-01-10T05:50:12Z" - }, - { + }, + { "checksumSHA1": "8dVO3L8yAdQ17X3lAhIziyF3OFk=", "path": "github.com/Sirupsen/logrus", "revision": "10f801ebc38b33738c9d17d50860f484a0988ff5", @@ -278,244 +278,244 @@ "revision": "4239b77079c7b5d1243b7b4736304ce8ddb6f0f2" }, { - "checksumSHA1": "tN8pbihy8mw+m0UVqNNFJmx7p+Y=", + "checksumSHA1": "2GR/f+rwuhlBVooyOGVaxNIYbEg=", "path": "github.com/aws/aws-sdk-go", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "NQu/L+9CIJLpgrZt3UMlbma9Pk0=", + "checksumSHA1": "mFHEkH8cgZqBuQ5qVqNP1SLN4QA=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "9nE/FjZ4pYrT883KtV2/aI+Gayo=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "7/8j/q0TWtOgXyvEcv4B2Dhl00o=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "Y+cPwQL0dZMyqp3wI+KJWmA9KQ8=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "JEYqmF83O5n5bHkupAzA6STm0no=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "OnU/n7R33oYXiB4SAGd5pK7I0Bs=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "/EXbk/z2TWjWc1Hvb4QYs3Wmhb8=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "bV8wC0xzF08ztv57EXbeLjNxmsI=", + "checksumSHA1": "CJNEM69cgdO9tZi6c5Lj07jI+dk=", "path": "github.com/aws/aws-sdk-go/aws/endpoints", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "JZ49s4cNe3nIttx3hWp04CQif4o=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "HcGL4e6Uep4/80eCUI5xkcWjpQ0=", + "checksumSHA1": "DIn7B+oP++/nw603OB95fmupzu8=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "iU00ZjhAml/13g+1YXT21IqoXqg=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "04ypv4x12l4q0TksA1zEVsmgpvw=", "path": "github.com/aws/aws-sdk-go/internal/shareddefaults", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "NStHCXEvYqG72GknZyv1jaKaeH0=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "yHfT5DTbeCLs4NE2Rgnqrhe15ls=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "9V1PvtFQ9MObZTc3sa86WcuOtOU=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "pkeoOfZpHRvFG/AOZeTf0lwtsFg=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "0qYPUga28aQVkxZgBR3Z86AbGUQ=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", @@ -523,62 +523,62 @@ "path": "github.com/aws/aws-sdk-go/private/waiter", "revision": "1bd588c8b2dba4da57dd4664b2b2750d260a5915", "revisionTime": "2017-02-24T22:28:38Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "4igS6faf4hrhDj6Jj9ErVcN1qKo=", + "checksumSHA1": "Sj6NTKuc/6+amv4RsMqrZkvkvpc=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "uEv9kkBsVIjg7K4+Y8TVlU0Cc8o=", + "checksumSHA1": "kEgV0dSAj3M3M1waEkC27JS7VnU=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/ecr", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "sCaHoPWsJXRHFbilUKwN71qFTOI=", + "checksumSHA1": "fXQn3V0ZRBZpTXUEHl4/yOjR4mQ=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "ZP6QI0X9BNKk8o1p3AyLfjabS20=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/s3/s3iface", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "g6Eo2gEoj6YEZ+tLwydnfhwo7zg=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/s3/s3manager", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { - "checksumSHA1": "W1oFtpaT4TWIIJrAvFcn/XdcT7g=", + "checksumSHA1": "x7HCNPJnQi+4P6FKpBTY1hm3m6o=", "comment": "v1.7.1", "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "0cbaf57ea311890e62f0b01652529295079e9e95", - "revisionTime": "2018-02-05T21:18:42Z", - "version": "v1.12.71", - "versionExact": "v1.12.71" + "revision": "586c9ba6027a527800564282bb843d7e6e7985c9", + "revisionTime": "2018-02-07T00:16:19Z", + "version": "v1.12.72", + "versionExact": "v1.12.72" }, { "checksumSHA1": "7SbTaY0kaYxgQrG3/9cjrI+BcyU=", @@ -1353,7 +1353,7 @@ "revision": "453249f01cfeb54c3d549ddb75ff152ca243f9d8", "revisionTime": "2017-02-08T20:51:15Z" }, - { + { "checksumSHA1": "xiderUuvye8Kpn7yX3niiJg32bE=", "path": "golang.org/x/crypto/ssh/terminal", "revision": "c2303dcbe84172e0c0da4c9f083eeca54c06f298", From d07a2dda7d3e54bca63ebbeb60592bdd2c21ac5e Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 15 Feb 2018 14:28:22 -0800 Subject: [PATCH 0660/1007] fix grammar in docs --- website/source/docs/builders/amazon.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index e40b2c17c..21dad780a 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -177,9 +177,9 @@ for Packer to work: }] } ``` -### Notes to pay for a spot instance to create the AMI -You need to add two more actions: `ec2:RequestSpotInstances` and `ec2:CancelSpotInstanceRequests` +Note that if you'd like to create a spot instance, you must also add +`ec2:RequestSpotInstances` and `ec2:CancelSpotInstanceRequests` ## Troubleshooting From 28065238348d428158956e4728f7fd1c0a389101 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 15 Feb 2018 14:20:50 -0800 Subject: [PATCH 0661/1007] Fix issue with assume role credentials --- builder/amazon/common/access_config.go | 32 +++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 61de7ff09..563030f50 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -1,7 +1,6 @@ package common import ( - "errors" "fmt" "log" "os" @@ -96,20 +95,8 @@ func (c *AccessConfig) Session() (*session.Session, error) { } creds := credentials.NewChainCredentials(providers) - cp, err := creds.Get() - if err != nil { - if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" { - return nil, errors.New("No valid credential sources found for AWS Builder. " + - "Please see https://www.packer.io/docs/builders/amazon.html#specifying-amazon-credentials " + - "for more information on providing credentials for the AWS Builder.") - } - - return nil, fmt.Errorf("Error loading credentials for AWS Provider: %s", err) - } - log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName) config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) - config = config.WithCredentials(creds) if c.RawRegion != "" { config = config.WithRegion(c.RawRegion) @@ -126,12 +113,18 @@ func (c *AccessConfig) Session() (*session.Session, error) { Config: *config, } + if c.ProfileName != "" { + opts.Profile = c.ProfileName + } + if c.MFACode != "" { opts.AssumeRoleTokenProvider = func() (string, error) { return c.MFACode, nil } } + config = config.WithCredentials(creds) + if sess, err := session.NewSessionWithOptions(opts); err != nil { return nil, err } else if *sess.Config.Region == "" { @@ -139,8 +132,19 @@ func (c *AccessConfig) Session() (*session.Session, error) { } else { log.Printf("Found region %s", *sess.Config.Region) c.session = sess - } + cp, err := c.session.Config.Credentials.Get() + if err != nil { + if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" { + return nil, fmt.Errorf("No valid credential sources found for AWS Builder. " + + "Please see https://www.packer.io/docs/builders/amazon.html#specifying-amazon-credentials " + + "for more information on providing credentials for the AWS Builder.") + } else { + return nil, fmt.Errorf("Error loading credentials for AWS Provider: %s", err) + } + } + log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName) + } return c.session, nil } From 4cfbfe5fa177781c0e6c863384d64cd80219da8b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 16 Feb 2018 11:53:47 -0800 Subject: [PATCH 0662/1007] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8878587c..0d0f6d49b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## UNRELEASED +## BUG FIXES: +* builder/amazon: Fix issues using assume role [GH-5914] + ## 1.2.0 (February 9, 2018) From 14e3effa8340abef36599fc8aa78d757f144aff8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 16 Feb 2018 12:00:33 -0800 Subject: [PATCH 0663/1007] test on go 1.9.x branch, remove 1.7.x from tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 755c0ef8f..3b83c4cd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ sudo: false language: go go: - - 1.7.x - 1.8.x + - 1.9.x - 1.x install: From 7ede3296cf0b189d3ff562f35422c5180a5cc81d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 16 Feb 2018 12:06:06 -0800 Subject: [PATCH 0664/1007] remove plugin listing from readme --- README.md | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1c30fd877..d6b01c47a 100644 --- a/README.md +++ b/README.md @@ -23,25 +23,8 @@ from a single source configuration. Packer is lightweight, runs on every major operating system, and is highly performant, creating machine images for multiple platforms in parallel. Packer -comes out of the box with support for the following platforms: - -* Amazon EC2 (AMI). Both EBS-backed and instance-store AMIs -* Azure -* CloudStack -* DigitalOcean -* Docker -* Google Compute Engine -* Hyper-V -* 1&1 -* OpenStack -* Oracle Cloud Infrastructure -* Parallels -* ProfitBricks -* QEMU. Both KVM and Xen images. -* Scaleway -* Triton (Joyent Public Cloud) -* VMware -* VirtualBox +comes out of the box with support for many platforms, the full list of which can +be found at https://www.packer.io/docs/builders/index.html. Support for other platforms can be added via plugins. From c973dd91c510f74c0a8267d2f860f65c1839ee71 Mon Sep 17 00:00:00 2001 From: Antony Jones <ant@enzy.org> Date: Mon, 19 Feb 2018 13:07:03 +0000 Subject: [PATCH 0665/1007] Fix formatting issues --- website/source/docs/builders/azure-setup.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/azure-setup.html.md b/website/source/docs/builders/azure-setup.html.md index 618e38543..697861c00 100644 --- a/website/source/docs/builders/azure-setup.html.md +++ b/website/source/docs/builders/azure-setup.html.md @@ -123,7 +123,7 @@ $ azure account show --json | jq -r ".[] | .id" ``` Python: -```shell +``` shell $ az account set "$(az account list | jq -r '.[].name')" ``` @@ -214,7 +214,7 @@ Python: ```shell $ id=$(az ad app list | jq -r '.[] | select(.displayName == "Packer") | .appId') -$ az ad sp create --appid "$id" +$ az ad sp create --id "$id" ``` ### Grant Permissions to Your Application From 1418a42bf5dfc4658aa9f709032f7abc7afd3a1e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 20 Feb 2018 10:54:18 -0800 Subject: [PATCH 0666/1007] Remove telemetry error reporting message. This seems to cause some confusion, and it's not needed anyway --- packer/telemetry.go | 1 - 1 file changed, 1 deletion(-) diff --git a/packer/telemetry.go b/packer/telemetry.go index a58b1c701..0f493a83a 100644 --- a/packer/telemetry.go +++ b/packer/telemetry.go @@ -146,7 +146,6 @@ func (s *TelemetrySpan) End(err error) { log.Printf("[INFO] (telemetry) ending %s", s.Name) if err != nil { s.Error = err.Error() - log.Printf("[INFO] (telemetry) found error: %s", err.Error()) } } From 2415ca2fd25f5cf6144689d8b62d15da89dabc0b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 20 Feb 2018 14:09:51 -0800 Subject: [PATCH 0667/1007] fix for linux/ppc64le compilation closes #5880 --- vendor/github.com/creack/goselect/fdset_64.go | 2 +- vendor/vendor.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vendor/github.com/creack/goselect/fdset_64.go b/vendor/github.com/creack/goselect/fdset_64.go index 4e032e4ea..71b7c9cc3 100644 --- a/vendor/github.com/creack/goselect/fdset_64.go +++ b/vendor/github.com/creack/goselect/fdset_64.go @@ -1,5 +1,5 @@ // +build !darwin,!netbsd,!openbsd -// +build amd64 arm64 +// +build amd64 arm64 ppc64le package goselect diff --git a/vendor/vendor.json b/vendor/vendor.json index 05fc0faa4..b48f00557 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -596,10 +596,10 @@ "revision": "50da7d4131a3b5c9d063932461cab4d1fafb20b0" }, { - "checksumSHA1": "bFj0ceSRvaFFCfmS4el1PjWhcgw=", + "checksumSHA1": "X2/71FBrn4pA3WcA620ySVO0uHU=", "path": "github.com/creack/goselect", - "revision": "1bd5ca702c6154bccc56ecd598932ee8b295cab2", - "revisionTime": "2016-07-14T17:28:59Z" + "revision": "528c74964609a58f7c17471525659c9b71cd499b", + "revisionTime": "2018-02-10T03:43:46Z" }, { "checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=", From ac2ddbcbf5e2f0c202e43a006d20e6ed95f6bb97 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Tue, 20 Feb 2018 19:42:45 -0600 Subject: [PATCH 0668/1007] Fixes the assumption that all the VMware builder's drivers will implement a network mapper for mapping a network name to it's corresponding device. The ESX5 driver doesn't have a way of mapping the network name to its device name because a .vmx template uses different field names for it and so packer let's ESX handle filling this in. This patch will check to see if the driver that packer determines is missing a NetworkMapper implementation (by checking for nil). If it is, then fall back to using "nat" despite ESX not using the network type at all. This is what packer did prior to exposing the network type to the user back in version 1.1.3. This closes issue #5916. --- builder/vmware/iso/driver_esx5.go | 23 ++++++++++++++ builder/vmware/iso/step_create_vmx.go | 45 ++++++++++++++++++--------- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 1dc352999..47fe70666 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -147,6 +147,29 @@ func (d *ESX5Driver) ToolsInstall() error { } func (d *ESX5Driver) Verify() error { + // Ensure that NetworkMapper is nil, since the mapping of device<->network + // is handled by ESX and thus can't be performed by packer unless we + // query things. + + // FIXME: If we want to expose the network devices to the user, then we can + // probably use esxcli to enumerate the portgroup and switchId + d.base.NetworkMapper = nil + + // Be safe/friendly and overwrite the rest of the utility functions with + // log functions despite the fact that these shouldn't be called anyways. + d.base.DhcpLeasesPath = func(device string) string { + log.Printf("Unexpected error, ESX5 driver attempted to call DhcpLeasesPath(%#v)\n", device) + return "" + } + d.base.DhcpConfPath = func(device string) string { + log.Printf("Unexpected error, ESX5 driver attempted to call DhcpConfPath(%#v)\n", device) + return "" + } + d.base.VmnetnatConfPath = func(device string) string { + log.Printf("Unexpected error, ESX5 driver attempted to call VmnetnatConfPath(%#v)\n", device) + return "" + } + checks := []func() error{ d.connect, d.checkSystemVersion, diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index ffff9d999..c231cfe8a 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -462,26 +462,41 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist network := config.Network driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver() - // read netmap config - netmap, err := driver.NetworkMapper() - if err != nil { - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + // check to see if the driver implements a network mapper for mapping + // the network-type to its device-name. + if driver.NetworkMapper != nil { - // try and convert the specified network to a device - device, err := netmap.NameIntoDevice(network) + // read network map configuration into a NetworkNameMapper. + netmap, err := driver.NetworkMapper() + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - // success. so we know that it's an actual network type inside netmap.conf - if err == nil { - templateData.Network_Type = network - templateData.Network_Device = device - // we were unable to find the type, so assume it's a custom network device. + // try and convert the specified network to a device. + device, err := netmap.NameIntoDevice(network) + + // success. so we know that it's an actual network type inside netmap.conf + if err == nil { + templateData.Network_Type = network + templateData.Network_Device = device + + // otherwise, we were unable to find the type, so assume its a custom device. + } else { + templateData.Network_Type = "custom" + templateData.Network_Device = network + } + + // if NetworkMapper is nil, then we're using something like ESX, so fall + // back to the previous logic of using "nat" despite it not mattering to ESX. } else { - templateData.Network_Type = "custom" + templateData.Network_Type = "nat" templateData.Network_Device = network + + network = "nat" } + // store the network so that we can later figure out what ip address to bind to state.Put("vmnetwork", network) From df45e0916dddf863d88b888f37f9c7750b7d6ab3 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 8 Feb 2018 14:55:04 -0800 Subject: [PATCH 0669/1007] Add the winRM communicator to Oracle Classic builder. update oracle classic docs with a minimal working windows example --- builder/oracle/classic/config.go | 4 - builder/oracle/classic/step_add_keys.go | 13 +- .../oracle/classic/step_create_instance.go | 7 +- builder/oracle/classic/step_security.go | 141 ++++++++++++++---- builder/oracle/classic/step_snapshot.go | 12 +- .../docs/builders/oracle-classic.html.md | 59 ++++++++ 6 files changed, 195 insertions(+), 41 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 233a3a0d1..7916478f0 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -99,10 +99,6 @@ func NewConfig(raws ...interface{}) (*Config, error) { if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { errs = packer.MultiErrorAppend(errs, es...) } - if c.Comm.Type == "winrm" { - err = fmt.Errorf("winRM is not supported with the oracle-classic builder yet.") - errs = packer.MultiErrorAppend(errs, err) - } if errs != nil && len(errs.Errors) > 0 { return nil, errs diff --git a/builder/oracle/classic/step_add_keys.go b/builder/oracle/classic/step_add_keys.go index 544c35bf2..b09310a1f 100644 --- a/builder/oracle/classic/step_add_keys.go +++ b/builder/oracle/classic/step_add_keys.go @@ -19,6 +19,11 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) + if config.Comm.Type != "ssh" { + ui.Say("Not using SSH communicator; skip generating SSH keys...") + return multistep.ActionContinue + } + // grab packer-generated key from statebag context. sshPublicKey := strings.TrimSpace(state.Get("publicKey").(string)) @@ -49,10 +54,14 @@ func (s *stepAddKeysToAPI) Run(_ context.Context, state multistep.StateBag) mult func (s *stepAddKeysToAPI) Cleanup(state multistep.StateBag) { // Delete the keys we created during this run - keyName := state.Get("key_name").(string) + keyName, ok := state.GetOk("key_name") + if !ok { + // No keys were generated; none need to be cleaned up. + return + } ui := state.Get("ui").(packer.Ui) ui.Say("Deleting SSH keys...") - deleteInput := compute.DeleteSSHKeyInput{Name: keyName} + deleteInput := compute.DeleteSSHKeyInput{Name: keyName.(string)} client := state.Get("client").(*compute.ComputeClient) deleteClient := client.SSHKeys() err := deleteClient.DeleteSSHKey(&deleteInput) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index cda67122c..d9d26b3e3 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -18,7 +18,6 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu config := state.Get("config").(*Config) client := state.Get("client").(*compute.ComputeClient) - keyName := state.Get("key_name").(string) ipAddName := state.Get("ipres_name").(string) secListName := state.Get("security_list").(string) @@ -35,10 +34,13 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu Name: config.ImageName, Shape: config.Shape, ImageList: config.SourceImageList, - SSHKeys: []string{keyName}, Networking: map[string]compute.NetworkingInfo{"eth0": netInfo}, Attributes: config.attribs, } + if config.Comm.Type == "ssh" { + keyName := state.Get("key_name").(string) + input.SSHKeys = []string{keyName} + } instanceInfo, err := instanceClient.CreateInstance(input) if err != nil { @@ -48,6 +50,7 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu return multistep.ActionHalt } + state.Put("instance_info", instanceInfo) state.Put("instance_id", instanceInfo.ID) ui.Message(fmt.Sprintf("Created instance: %s.", instanceInfo.ID)) return multistep.ActionContinue diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 22d74de08..892695f83 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -3,10 +3,10 @@ package classic import ( "context" "fmt" - "log" "strings" "github.com/hashicorp/go-oracle-terraform/compute" + "github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -15,53 +15,101 @@ type stepSecurity struct{} func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) - - ui.Say("Configuring security lists and rules to enable SSH access...") - config := state.Get("config").(*Config) - client := state.Get("client").(*compute.ComputeClient) - secListName := fmt.Sprintf("/Compute-%s/%s/Packer_SSH_Allow_%s", - config.IdentityDomain, config.Username, config.ImageName) + commType := "" + if config.Comm.Type == "ssh" { + commType = "SSH" + } else if config.Comm.Type == "winrm" { + commType = "WINRM" + } + + ui.Say(fmt.Sprintf("Configuring security lists and rules to enable %s access...", commType)) + + client := state.Get("client").(*compute.ComputeClient) + runUUID := uuid.TimeOrderedUUID() + + namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username) + secListName := fmt.Sprintf("Packer_%s_Allow_%s_%s", commType, config.ImageName, runUUID) secListClient := client.SecurityLists() secListInput := compute.CreateSecurityListInput{ - Description: "Packer-generated security list to give packer ssh access", - Name: secListName, + Description: fmt.Sprintf("Packer-generated security list to give packer %s access", commType), + Name: namePrefix + secListName, } _, err := secListClient.CreateSecurityList(&secListInput) if err != nil { if !strings.Contains(err.Error(), "already exists") { err = fmt.Errorf("Error creating security List to"+ - " allow Packer to connect to Oracle instance via SSH: %s", err) + " allow Packer to connect to Oracle instance via %s: %s", commType, err) ui.Error(err.Error()) state.Put("error", err) return multistep.ActionHalt } } // DOCS NOTE: user must have Compute_Operations role - // Create security rule that allows Packer to connect via SSH - secRulesClient := client.SecRules() - secRulesInput := compute.CreateSecRuleInput{ - Action: "PERMIT", - Application: "/oracle/public/ssh", - Description: "Packer-generated security rule to allow ssh", - DestinationList: fmt.Sprintf("seclist:%s", secListName), - Name: fmt.Sprintf("Packer-allow-SSH-Rule_%s", config.ImageName), - SourceList: config.SSHSourceList, - } - - secRuleName := fmt.Sprintf("/Compute-%s/%s/Packer-allow-SSH-Rule_%s", - config.IdentityDomain, config.Username, config.ImageName) - _, err = secRulesClient.CreateSecRule(&secRulesInput) - if err != nil { - log.Printf("Error creating security rule to allow SSH: %s", err.Error()) - if !strings.Contains(err.Error(), "already exists") { - err = fmt.Errorf("Error creating security rule to"+ - " allow Packer to connect to Oracle instance via SSH: %s", err) + // Create security rule that allows Packer to connect via SSH or winRM + var application string + if commType == "SSH" { + application = "/oracle/public/ssh" + } else if commType == "WINRM" { + // Check to see whether a winRM security protocol is already defined; + // don't need to do this for SSH becasue it is built into the Oracle API. + protocolClient := client.SecurityProtocols() + winrmProtocol := fmt.Sprintf("WINRM_%s", runUUID) + input := compute.CreateSecurityProtocolInput{ + Name: winrmProtocol, + Description: "packer-generated protocol to allow winRM communicator", + DstPortSet: []string{"5985", "5986", "443"}, // TODO make configurable + IPProtocol: "tcp", + } + _, err = protocolClient.CreateSecurityProtocol(&input) + if err != nil { + err = fmt.Errorf("Error creating security protocol to"+ + " allow Packer to connect to Oracle instance via %s: %s", commType, err) ui.Error(err.Error()) state.Put("error", err) return multistep.ActionHalt } + state.Put("winrm_protocol", winrmProtocol) + + // Check to see whether a winRM security application is already defined + applicationClient := client.SecurityApplications() + application = fmt.Sprintf("packer_winRM_%s", runUUID) + applicationInput := compute.CreateSecurityApplicationInput{ + Description: "Allows Packer to connect to instance via winRM", + DPort: "5985-5986", + Name: application, + Protocol: "TCP", + } + _, err = applicationClient.CreateSecurityApplication(&applicationInput) + if err != nil { + err = fmt.Errorf("Error creating security application to"+ + " allow Packer to connect to Oracle instance via %s: %s", commType, err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt + } + state.Put("winrm_application", application) + } + secRulesClient := client.SecRules() + secRuleName := fmt.Sprintf("Packer-allow-%s-Rule_%s_%s", commType, + config.ImageName, runUUID) + secRulesInput := compute.CreateSecRuleInput{ + Action: "PERMIT", + Application: application, + Description: "Packer-generated security rule to allow ssh/winrm", + DestinationList: "seclist:" + namePrefix + secListName, + Name: namePrefix + secRuleName, + SourceList: config.SSHSourceList, + } + + _, err = secRulesClient.CreateSecRule(&secRulesInput) + if err != nil { + err = fmt.Errorf("Error creating security rule to"+ + " allow Packer to connect to Oracle instance: %s", err) + ui.Error(err.Error()) + state.Put("error", err) + return multistep.ActionHalt } state.Put("security_rule_name", secRuleName) state.Put("security_list", secListName) @@ -71,12 +119,15 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste func (s *stepSecurity) Cleanup(state multistep.StateBag) { client := state.Get("client").(*compute.ComputeClient) ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) + ui.Say("Deleting temporary rules and lists...") + namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username) // delete security rules that Packer generated secRuleName := state.Get("security_rule_name").(string) secRulesClient := client.SecRules() - ruleInput := compute.DeleteSecRuleInput{Name: secRuleName} + ruleInput := compute.DeleteSecRuleInput{Name: namePrefix + secRuleName} err := secRulesClient.DeleteSecRule(&ruleInput) if err != nil { ui.Say(fmt.Sprintf("Error deleting the packer-generated security rule %s; "+ @@ -86,10 +137,38 @@ func (s *stepSecurity) Cleanup(state multistep.StateBag) { // delete security list that Packer generated secListName := state.Get("security_list").(string) secListClient := client.SecurityLists() - input := compute.DeleteSecurityListInput{Name: secListName} + input := compute.DeleteSecurityListInput{Name: namePrefix + secListName} err = secListClient.DeleteSecurityList(&input) if err != nil { ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+ "please delete manually. (error : %s)", secListName, err.Error())) } + + // Some extra cleanup if we used the winRM communicator + if config.Comm.Type == "winrm" { + // Delete the packer-generated protocol + protocol := state.Get("winrm_protocol").(string) + protocolClient := client.SecurityProtocols() + deleteProtocolInput := compute.DeleteSecurityProtocolInput{ + Name: namePrefix + protocol, + } + err = protocolClient.DeleteSecurityProtocol(&deleteProtocolInput) + if err != nil { + ui.Say(fmt.Sprintf("Error deleting the packer-generated winrm security protocol %s; "+ + "please delete manually. (error : %s)", protocol, err.Error())) + } + + // Delete the packer-generated application + application := state.Get("winrm_application").(string) + applicationClient := client.SecurityApplications() + deleteApplicationInput := compute.DeleteSecurityApplicationInput{ + Name: namePrefix + application, + } + err = applicationClient.DeleteSecurityApplication(&deleteApplicationInput) + if err != nil { + ui.Say(fmt.Sprintf("Error deleting the packer-generated winrm security application %s; "+ + "please delete manually. (error : %s)", application, err.Error())) + } + } + } diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index b7cbbf008..68c059897 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -3,16 +3,20 @@ package classic import ( "context" "fmt" + "time" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) -type stepSnapshot struct{} +type stepSnapshot struct { + cleanupSnap bool +} func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state + s.cleanupSnap = false ui := state.Get("ui").(packer.Ui) ui.Say("Creating Snapshot...") config := state.Get("config").(*Config) @@ -26,6 +30,7 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste snapshotInput := &compute.CreateSnapshotInput{ Instance: fmt.Sprintf("%s/%s", config.ImageName, instanceID), MachineImage: config.ImageName, + Timeout: time.Minute * 20, } snap, err := snapshotClient.CreateSnapshot(snapshotInput) @@ -35,7 +40,7 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste state.Put("error", err) return multistep.ActionHalt } - + s.cleanupSnap = true state.Put("snapshot", snap) ui.Message(fmt.Sprintf("Created snapshot: %s.", snap.Name)) return multistep.ActionContinue @@ -44,6 +49,9 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste func (s *stepSnapshot) Cleanup(state multistep.StateBag) { // Delete the snapshot ui := state.Get("ui").(packer.Ui) + if !s.cleanupSnap { + return + } ui.Say("Deleting Snapshot...") client := state.Get("client").(*compute.ComputeClient) snap := state.Get("snapshot").(*compute.Snapshot) diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 98db5f2aa..208a0a088 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -114,3 +114,62 @@ obfuscated; you will need to add a working `username`, `password`, ] } ``` + +## Basic Example -- Windows + +Attributes file is optional for connecting via ssh, but required for winrm. + +The following file contains the bare minimum necessary to get winRM working; +you have to give it the password to give to the "Administrator" user, which +will be the one winrm connects to. You must also whitelist your computer +to connect via winRM -- the empty braces below whitelist any computer to access +winRM but you can make it more secure by only allowing your build machine +access. See the [docs](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/automating-instance-initialization-using-opc-init.html#GUID-A0A107D6-3B38-47F4-8FC8-96D50D99379B) +for more details on how to define a trusted host. + +Save this file as `windows_attributes.json`: + +```{.json} +{ + "userdata": { + "administrator_password": "password", + "winrm": {} + } +} +``` + +Following is a minimal but working Packer config that references this attributes +file: +```{.json} +{ + "variables": { + "opc_username": "{{ env `OPC_USERNAME`}}", + "opc_password": "{{ env `OPC_PASSWORD`}}", + "opc_identity_domain": "{{env `OPC_IDENTITY_DOMAIN`}}", + "opc_api_endpoint": "{{ env `OPC_ENDPOINT`}}" + }, + "builders": [ + { + "type": "oracle-classic", + "username": "{{ user `opc_username`}}", + "password": "{{ user `opc_password`}}", + "identity_domain": "{{ user `opc_identity_domain`}}", + "api_endpoint": "{{ user `opc_api_endpoint`}}", + "source_image_list": "/Compute-{{ user `opc_identity_domain` }}/{{ user opc_username`}}/Microsoft_Windows_Server_2012_R2-17.3.6-20170930-124649", + "attributes_file": "./windows_attributes.json", + "shape": "oc3", + "image_name": "Packer_Windows_Demo_{{timestamp}}", + "dest_image_list": "Packer_Windows_Demo", + "communicator": "winrm", + "winrm_username": "Administrator", + "winrm_password": "password" + } + ], + "provisioners": [ + { + "type": "powershell", + "inline": "Write-Output(\"HELLO WORLD\")" + } + ] +} +``` From 33acdbf3bf1518bba67fd1f7030d14726c4463bf Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 21 Feb 2018 14:57:58 -0800 Subject: [PATCH 0670/1007] move comments so indentation is more logical --- builder/vmware/iso/step_create_vmx.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index c231cfe8a..ca5fe7bbe 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -477,13 +477,12 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist // try and convert the specified network to a device. device, err := netmap.NameIntoDevice(network) - // success. so we know that it's an actual network type inside netmap.conf if err == nil { + // success. so we know that it's an actual network type inside netmap.conf templateData.Network_Type = network templateData.Network_Device = device - - // otherwise, we were unable to find the type, so assume its a custom device. } else { + // otherwise, we were unable to find the type, so assume its a custom device. templateData.Network_Type = "custom" templateData.Network_Device = network } From 4befdce47e6c7816193ffa1337c144b863847292 Mon Sep 17 00:00:00 2001 From: Christophe Courtaut <christophe.courtaut@gmail.com> Date: Wed, 21 Feb 2018 18:22:39 +0100 Subject: [PATCH 0671/1007] builder/googlecompute: Adds ability to specify service account This commit allows user to specify the service account they want to associate with the virtual machine provisionned by setting the service_account_email field in the config. It allows to manage permissions of the instantiated VM properly, using a service account that can be tied up to IAM roles and permissions. --- builder/googlecompute/config.go | 2 ++ builder/googlecompute/driver.go | 1 + builder/googlecompute/driver_gce.go | 13 +++++++++---- builder/googlecompute/step_create_instance.go | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index c8863d4d9..3d9194c17 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -58,6 +58,8 @@ type Config struct { UseInternalIP bool `mapstructure:"use_internal_ip"` Zone string `mapstructure:"zone"` + ServiceAccountEmail string `mapstructure:"service_account_email"` + Account AccountFile stateTimeout time.Duration imageAlreadyExists bool diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index fdb7d9442..c99c38359 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -75,6 +75,7 @@ type InstanceConfig struct { OnHostMaintenance string Preemptible bool Region string + ServiceAccountEmail string Scopes []string Subnetwork string Tags []string diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index c84ab222f..5f286fa71 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -343,6 +343,14 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { guestAccelerators = append(guestAccelerators, ac) } + serviceAccount := &compute.ServiceAccount{ + Email: "default", + Scopes: c.Scopes, + } + if c.ServiceAccountEmail != "" { + serviceAccount.Email = c.ServiceAccountEmail + } + // Create the instance information instance := compute.Instance{ Description: c.Description, @@ -379,10 +387,7 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { Preemptible: c.Preemptible, }, ServiceAccounts: []*compute.ServiceAccount{ - { - Email: "default", - Scopes: c.Scopes, - }, + serviceAccount, }, Tags: &compute.Tags{ Items: c.Tags, diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index ee3b6643b..9ff74d85f 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -117,6 +117,7 @@ func (s *StepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu OnHostMaintenance: c.OnHostMaintenance, Preemptible: c.Preemptible, Region: c.Region, + ServiceAccountEmail: c.ServiceAccountEmail, Scopes: c.Scopes, Subnetwork: c.Subnetwork, Tags: c.Tags, From 16882c1252c56de28306871e5f436d9c9bd8987c Mon Sep 17 00:00:00 2001 From: Christophe Courtaut <christophe.courtaut@gmail.com> Date: Wed, 21 Feb 2018 18:25:08 +0100 Subject: [PATCH 0672/1007] builder/googlecompute: Go code formatting --- builder/googlecompute/driver.go | 42 +++++++++---------- builder/googlecompute/step_create_instance.go | 42 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index c99c38359..4c07a06cf 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -58,28 +58,28 @@ type Driver interface { } type InstanceConfig struct { - AcceleratorType string - AcceleratorCount int64 - Address string - Description string - DiskSizeGb int64 - DiskType string - Image *Image - Labels map[string]string - MachineType string - Metadata map[string]string - Name string - Network string - NetworkProjectId string - OmitExternalIP bool - OnHostMaintenance string - Preemptible bool - Region string + AcceleratorType string + AcceleratorCount int64 + Address string + Description string + DiskSizeGb int64 + DiskType string + Image *Image + Labels map[string]string + MachineType string + Metadata map[string]string + Name string + Network string + NetworkProjectId string + OmitExternalIP bool + OnHostMaintenance string + Preemptible bool + Region string ServiceAccountEmail string - Scopes []string - Subnetwork string - Tags []string - Zone string + Scopes []string + Subnetwork string + Tags []string + Zone string } // WindowsPasswordConfig is the data structue that GCE needs to encrypt the created diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index 9ff74d85f..bc37aa7b2 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -100,28 +100,28 @@ func (s *StepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu var metadata map[string]string metadata, err = c.createInstanceMetadata(sourceImage, sshPublicKey) errCh, err = d.RunInstance(&InstanceConfig{ - AcceleratorType: c.AcceleratorType, - AcceleratorCount: c.AcceleratorCount, - Address: c.Address, - Description: "New instance created by Packer", - DiskSizeGb: c.DiskSizeGb, - DiskType: c.DiskType, - Image: sourceImage, - Labels: c.Labels, - MachineType: c.MachineType, - Metadata: metadata, - Name: name, - Network: c.Network, - NetworkProjectId: c.NetworkProjectId, - OmitExternalIP: c.OmitExternalIP, - OnHostMaintenance: c.OnHostMaintenance, - Preemptible: c.Preemptible, - Region: c.Region, + AcceleratorType: c.AcceleratorType, + AcceleratorCount: c.AcceleratorCount, + Address: c.Address, + Description: "New instance created by Packer", + DiskSizeGb: c.DiskSizeGb, + DiskType: c.DiskType, + Image: sourceImage, + Labels: c.Labels, + MachineType: c.MachineType, + Metadata: metadata, + Name: name, + Network: c.Network, + NetworkProjectId: c.NetworkProjectId, + OmitExternalIP: c.OmitExternalIP, + OnHostMaintenance: c.OnHostMaintenance, + Preemptible: c.Preemptible, + Region: c.Region, ServiceAccountEmail: c.ServiceAccountEmail, - Scopes: c.Scopes, - Subnetwork: c.Subnetwork, - Tags: c.Tags, - Zone: c.Zone, + Scopes: c.Scopes, + Subnetwork: c.Subnetwork, + Tags: c.Tags, + Zone: c.Zone, }) if err == nil { From bda07497e9e11604f4d1c999b0295faae2e063e0 Mon Sep 17 00:00:00 2001 From: Christophe Courtaut <christophe.courtaut@gmail.com> Date: Thu, 22 Feb 2018 18:46:13 +0100 Subject: [PATCH 0673/1007] website/docs: Adds documentation for GCE builder service account email new field --- website/source/docs/builders/googlecompute.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index cda97b02c..fb006c7ae 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -268,6 +268,9 @@ builder. - `region` (string) - The region in which to launch the instance. Defaults to to the region hosting the specified `zone`. +- `service_account_email` (string) - The service account to be used for launched instance. Defaults to + the project's default service account. + - `scopes` (array of strings) - The service account scopes for launched instance. Defaults to: From 597ddc2192392624970b4e832c352deb6f6de6d8 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 21 Feb 2018 14:33:00 -0800 Subject: [PATCH 0674/1007] add configurable snapshot timeout to oracle-classic builder --- builder/oracle/classic/config.go | 14 ++++++++++---- builder/oracle/classic/step_snapshot.go | 3 +-- builder/vmware/common/driver.go | 3 +++ .../source/docs/builders/oracle-classic.html.md | 8 ++++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 7916478f0..b9f5d808f 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/url" "os" + "time" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" @@ -27,10 +28,11 @@ type Config struct { apiEndpointURL *url.URL // Image - ImageName string `mapstructure:"image_name"` - Shape string `mapstructure:"shape"` - SourceImageList string `mapstructure:"source_image_list"` - DestImageList string `mapstructure:"dest_image_list"` + ImageName string `mapstructure:"image_name"` + Shape string `mapstructure:"shape"` + SourceImageList string `mapstructure:"source_image_list"` + SnapshotTimeout time.Duration `mapstructure:"snapshot_timeout"` + DestImageList string `mapstructure:"dest_image_list"` // Attributes and Atributes file are both optional and mutually exclusive. Attributes string `mapstructure:"attributes"` AttributesFile string `mapstructure:"attributes_file"` @@ -71,6 +73,10 @@ func NewConfig(raws ...interface{}) (*Config, error) { c.Comm.SSHUsername = "opc" } + if c.SnapshotTimeout == 0 { + c.SnapshotTimeout = 20 * time.Minute + } + // Validate that all required fields are present var errs *packer.MultiError required := map[string]string{ diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index 68c059897..e0ebf3091 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -3,7 +3,6 @@ package classic import ( "context" "fmt" - "time" "github.com/hashicorp/go-oracle-terraform/compute" "github.com/hashicorp/packer/helper/multistep" @@ -30,7 +29,7 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste snapshotInput := &compute.CreateSnapshotInput{ Instance: fmt.Sprintf("%s/%s", config.ImageName, instanceID), MachineImage: config.ImageName, - Timeout: time.Minute * 20, + Timeout: config.SnapshotTimeout, } snap, err := snapshotClient.CreateSnapshot(snapshotInput) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 8fa185efd..c8fea88f4 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -309,12 +309,14 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // grab network mapper netmap, err := d.NetworkMapper() + log.Printf("MEGAN: NEtworkMapper is %#v", netmap) if err != nil { return "", err } // convert the stashed network to a device network := state.Get("vmnetwork").(string) + log.Printf("MEGAN: network is %#v", network) device, err := netmap.NameIntoDevice(network) // we were unable to find the device, maybe it's a custom one... @@ -337,6 +339,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { if err != nil { return "", err } + log.Printf("MEGAN mac address is %s", MACAddress) // figure out the correct dhcp leases dhcpLeasesPath := d.DhcpLeasesPath(device) diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 208a0a088..1ea03dc46 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -84,6 +84,14 @@ This builder currently only works with the SSH communicator. - `image_name` (string) - The name to assign to the resulting custom image. + - `snapshot_timeout` (string) - How long to wait for a snapshot to be + created. Expects a positive golang Time.Duration string, which is + a sequence of decimal numbers and a unit suffix; valid suffixes are `ns` + (nanoseconds), `us` (microseconds), `ms` (milliseconds), `s` (seconds), `m` + (minutes), and `h` (hours). Examples of valid inputs: `100ms`, `250ms`, `1s`, + `2.5s`, `2.5m`, `1m30s`. + Example: `"snapshot_timeout": "15m"`. Default: `20m`. + ## Basic Example Here is a basic example. Note that account specific configuration has been From d90b67ba235cbcb519b95086036ff67f407c4e1b Mon Sep 17 00:00:00 2001 From: Taeho Kim <dittos@gmail.com> Date: Fri, 23 Feb 2018 11:51:43 +0900 Subject: [PATCH 0675/1007] Fix docs on Alicloud builder - Fix the link to instance types page. - Disk configurations should go into `image_disk_mappings` array. - If `io_optimized` is not set, it's always `false`. (NOT inferred by instance type) --- .../source/docs/builders/alicloud-ecs.html.md | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index dc708379d..172bdab5c 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -35,9 +35,9 @@ builder. can also be sourced from the `ALICLOUD_REGION` environment variables. - `instance_type` (string) - Type of the instance. For values, see [Instance - Type Table](). You can also obtain the latest instance type table by invoking - the [Querying Instance Type - Table](https://intl.aliyun.com/help/doc-detail/25620.htm?spm=a3c0i.o25499en.a3.6.Dr1bik) + Type Table](https://www.alibabacloud.com/help/doc-detail/25378.htm?spm=a3c0i.o25499en.a3.9.14a36ac8iYqKRA). + You can also obtain the latest instance type table by invoking the [Querying + Instance Type Table](https://intl.aliyun.com/help/doc-detail/25620.htm?spm=a3c0i.o25499en.a3.6.Dr1bik) interface. - `image_name` (string) - The name of the user-defined image, \[2, 128\] English @@ -80,45 +80,47 @@ builder. duplicated existing image, the source snapshot of this image will be delete either. -- `disk_name` (string) - The value of disk name is blank by default. \[2, 128\] - English or Chinese characters, must begin with an uppercase/lowercase letter - or Chinese character. Can contain numbers, `.`, `_` and `-`. The disk name - will appear on the console. It cannot begin with `http://` or `https://`. +-   `image_disk_mappings` (array of image disk mappings) - Add one or more data disks + to the image. -- `disk_category` (string) - Category of the data disk. Optional values are: - - cloud - general cloud disk - - cloud\_efficiency - efficiency cloud disk - - cloud\_ssd - cloud SSD + - `disk_name` (string) - The value of disk name is blank by default. \[2, 128\] + English or Chinese characters, must begin with an uppercase/lowercase letter + or Chinese character. Can contain numbers, `.`, `_` and `-`. The disk name + will appear on the console. It cannot begin with `http://` or `https://`. - Default value: cloud. + - `disk_category` (string) - Category of the data disk. Optional values are: + - cloud - general cloud disk + - cloud\_efficiency - efficiency cloud disk + - cloud\_ssd - cloud SSD -- `disk_size` (number) - Size of the system disk, in GB, values range: - - cloud - 5 ~ 2000 - - cloud\_efficiency - 20 ~ 2048 - - cloud\_ssd - 20 ~ 2048 + Default value: cloud. - The value should be equal to or greater than the size of the specific SnapshotId. + - `disk_size` (number) - Size of the system disk, in GB, values range: + - cloud - 5 ~ 2000 + - cloud\_efficiency - 20 ~ 2048 + - cloud\_ssd - 20 ~ 2048 -- `disk_snapshot_id` (string) - Snapshots are used to create the data disk - After this parameter is specified, Size is ignored. The actual size of the - created disk is the size of the specified snapshot. + The value should be equal to or greater than the size of the specific SnapshotId. - Snapshots from on or before July 15, 2013 cannot be used to create a disk. + - `disk_snapshot_id` (string) - Snapshots are used to create the data disk + After this parameter is specified, Size is ignored. The actual size of the + created disk is the size of the specified snapshot. -- `disk_description` (string) - The value of disk description is blank by default. \[2, 256\] characters. The disk description will appear on the console. It cannot begin with `http://` or `https://`. + Snapshots from on or before July 15, 2013 cannot be used to create a disk. -- `disk_delete_with_instance` (string) - Whether or not the disk is released along with the instance: -- True indicates that when the instance is released, this disk will be released with it -- False indicates that when the instance is released, this disk will be retained. + - `disk_description` (string) - The value of disk description is blank by default. \[2, 256\] characters. The disk description will appear on the console. It cannot begin with `http://` or `https://`. -- `disk_device` (string) - Device information of the related instance: such as - `/dev/xvdb` It is null unless the Status is In\_use. + - `disk_delete_with_instance` (string) - Whether or not the disk is released along with the instance: + - True indicates that when the instance is released, this disk will be released with it + - False indicates that when the instance is released, this disk will be retained. + + - `disk_device` (string) - Device information of the related instance: such as + `/dev/xvdb` It is null unless the Status is In\_use. - `zone_id` (string) - ID of the zone to which the disk belongs. -- `io_optimized` (boolean) - I/O optimized. - - Default value: false for Generation I instances; true for other instances. +- `io_optimized` (boolean) - Whether an ECS instance is I/O optimized or not. + The default value is `false`. - `force_stop_instance` (boolean) - Whether to force shutdown upon device restart. The default value is `false`. From b1ab60031ac18abec7f8f55f169b69eff6ac8d61 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 23 Feb 2018 07:35:41 -0800 Subject: [PATCH 0676/1007] update changelog --- CHANGELOG.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d0f6d49b..0506bcca6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ -## UNRELEASED +## 1.2.1 (February 23, 2918) -## BUG FIXES: +### BUG FIXES: * builder/amazon: Fix issues using assume role [GH-5914] +* builder/vmware-esxi: Fall back to "nat" if driver does not impelment a NetworkMapper [GH-5916] +* builder/vmware: Fix VMware Workstation methodology for finding dhcp.conf and dhcpd.leases files [GH-5882] +* provisioner/ansible-local: Fix conflicting escaping schemes for vars provided + to "--extra-vars" [GH-5888] + +### IMPROVEMENTS: +* builder/oracle-classic: Implement winRM communicator for oracle-classic builder [GH-5918] +* builder/oracle-classic: Add snapshot_timeout option to builder [GH-5930] ## 1.2.0 (February 9, 2018) From 1530861866ede0fc8a4b53b574a21384df690fe8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 10:07:45 -0800 Subject: [PATCH 0677/1007] update changelog --- CHANGELOG.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0506bcca6..38055710d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,25 @@ ## 1.2.1 (February 23, 2918) ### BUG FIXES: -* builder/amazon: Fix issues using assume role [GH-5914] -* builder/vmware-esxi: Fall back to "nat" if driver does not impelment a NetworkMapper [GH-5916] -* builder/vmware: Fix VMware Workstation methodology for finding dhcp.conf and dhcpd.leases files [GH-5882] + +* builder/amazon: Fix authorization using assume role. [GH-5914] +* builder/vmware-iso: Fix panic when building on esx5 remotes. [GH-5931] +* builder/vmware: Correctly locate dhcp.conf and dhcpd.leases files. [GH-5898] + [GH-5900] * provisioner/ansible-local: Fix conflicting escaping schemes for vars provided - to "--extra-vars" [GH-5888] + via `--extra-vars`. [GH-5888] ### IMPROVEMENTS: -* builder/oracle-classic: Implement winRM communicator for oracle-classic builder [GH-5918] -* builder/oracle-classic: Add snapshot_timeout option to builder [GH-5930] + +* builder/oracle-classic: Add `snapshot_timeout` option to control how long we + wait for the snapshot to be created. [GH-5932] +* builder/oracle-classic: Add support for WinRM connections. [GH-5929] ## 1.2.0 (February 9, 2018) ### BACKWARDS INCOMPATIBILITIES: + * 3rd party plugins: We have moved internal dependencies, meaning your 3rd party plugins will no longer compile (however existing builds will still work fine); the work to fix them is minimal and documented in GH-5810. From 0028c82c2b103522fa5cb6ed9ae6bbd640ac6841 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 10:11:32 -0800 Subject: [PATCH 0678/1007] update changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38055710d..89650932c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,7 @@ * builder/amazon: Fix authorization using assume role. [GH-5914] * builder/vmware-iso: Fix panic when building on esx5 remotes. [GH-5931] -* builder/vmware: Correctly locate dhcp.conf and dhcpd.leases files. [GH-5898] - [GH-5900] +* builder/vmware: Fix issue detecting host IP. [GH-5898] [GH-5900] * provisioner/ansible-local: Fix conflicting escaping schemes for vars provided via `--extra-vars`. [GH-5888] From 170a233e5f7eab050906961dcb7b2ca92c8d606f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 10:35:42 -0800 Subject: [PATCH 0679/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89650932c..044f747e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### BUG FIXES: * builder/amazon: Fix authorization using assume role. [GH-5914] +* builder/hyper-v: Fix command collisions with VMWare PowerCLI. [GH-5861] * builder/vmware-iso: Fix panic when building on esx5 remotes. [GH-5931] * builder/vmware: Fix issue detecting host IP. [GH-5898] [GH-5900] * provisioner/ansible-local: Fix conflicting escaping schemes for vars provided From 103186af8650d8168603031fc65c82c6f2df1fcf Mon Sep 17 00:00:00 2001 From: Stefan Henseler <stefan.henseler@synax.ch> Date: Fri, 23 Feb 2018 20:19:26 +0100 Subject: [PATCH 0680/1007] Adds Support to configure hyper-v disk block size --- builder/hyperv/common/driver.go | 4 +- builder/hyperv/common/driver_mock.go | 8 +++- builder/hyperv/common/driver_ps_4.go | 8 ++-- builder/hyperv/common/step_create_vm.go | 8 +++- builder/hyperv/iso/builder.go | 32 +++++++++++++++ builder/hyperv/iso/builder_test.go | 53 +++++++++++++++++++++++++ common/powershell/hyperv/hyperv.go | 42 ++++++++++++++------ 7 files changed, 133 insertions(+), 22 deletions(-) diff --git a/builder/hyperv/common/driver.go b/builder/hyperv/common/driver.go index 571214acd..e7b58464e 100644 --- a/builder/hyperv/common/driver.go +++ b/builder/hyperv/common/driver.go @@ -66,9 +66,9 @@ type Driver interface { DeleteVirtualSwitch(string) error - CreateVirtualMachine(string, string, string, string, int64, int64, string, uint, bool) error + CreateVirtualMachine(string, string, string, string, int64, int64, int64, string, uint, bool) error - AddVirtualMachineHardDrive(string, string, string, int64, string) error + AddVirtualMachineHardDrive(string, string, string, int64, int64, string) error CloneVirtualMachine(string, string, string, bool, string, string, string, int64, string) error diff --git a/builder/hyperv/common/driver_mock.go b/builder/hyperv/common/driver_mock.go index 7d8e02c6a..8af637e66 100644 --- a/builder/hyperv/common/driver_mock.go +++ b/builder/hyperv/common/driver_mock.go @@ -112,6 +112,7 @@ type DriverMock struct { AddVirtualMachineHardDrive_VhdFile string AddVirtualMachineHardDrive_VhdName string AddVirtualMachineHardDrive_VhdSizeBytes int64 + AddVirtualMachineHardDrive_VhdBlockSize int64 AddVirtualMachineHardDrive_ControllerType string AddVirtualMachineHardDrive_Err error @@ -122,6 +123,7 @@ type DriverMock struct { CreateVirtualMachine_VhdPath string CreateVirtualMachine_Ram int64 CreateVirtualMachine_DiskSize int64 + CreateVirtualMachine_DiskBlockSize int64 CreateVirtualMachine_SwitchName string CreateVirtualMachine_Generation uint CreateVirtualMachine_DifferentialDisk bool @@ -377,17 +379,18 @@ func (d *DriverMock) CreateVirtualSwitch(switchName string, switchType string) ( return d.CreateVirtualSwitch_Return, d.CreateVirtualSwitch_Err } -func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, controllerType string) error { +func (d *DriverMock) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, vhdDiskBlockSize int64, controllerType string) error { d.AddVirtualMachineHardDrive_Called = true d.AddVirtualMachineHardDrive_VmName = vmName d.AddVirtualMachineHardDrive_VhdFile = vhdFile d.AddVirtualMachineHardDrive_VhdName = vhdName d.AddVirtualMachineHardDrive_VhdSizeBytes = vhdSizeBytes + d.AddVirtualMachineHardDrive_VhdSizeBytes = vhdDiskBlockSize d.AddVirtualMachineHardDrive_ControllerType = controllerType return d.AddVirtualMachineHardDrive_Err } -func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error { +func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error { d.CreateVirtualMachine_Called = true d.CreateVirtualMachine_VmName = vmName d.CreateVirtualMachine_Path = path @@ -395,6 +398,7 @@ func (d *DriverMock) CreateVirtualMachine(vmName string, path string, harddriveP d.CreateVirtualMachine_VhdPath = vhdPath d.CreateVirtualMachine_Ram = ram d.CreateVirtualMachine_DiskSize = diskSize + d.CreateVirtualMachine_DiskBlockSize = diskBlockSize d.CreateVirtualMachine_SwitchName = switchName d.CreateVirtualMachine_Generation = generation d.CreateVirtualMachine_DifferentialDisk = diffDisks diff --git a/builder/hyperv/common/driver_ps_4.go b/builder/hyperv/common/driver_ps_4.go index a6c1b7352..34a9edbb5 100644 --- a/builder/hyperv/common/driver_ps_4.go +++ b/builder/hyperv/common/driver_ps_4.go @@ -174,12 +174,12 @@ func (d *HypervPS4Driver) CreateVirtualSwitch(switchName string, switchType stri return hyperv.CreateVirtualSwitch(switchName, switchType) } -func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, controllerType string) error { - return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, controllerType) +func (d *HypervPS4Driver) AddVirtualMachineHardDrive(vmName string, vhdFile string, vhdName string, vhdSizeBytes int64, diskBlockSize int64, controllerType string) error { + return hyperv.AddVirtualMachineHardDiskDrive(vmName, vhdFile, vhdName, vhdSizeBytes, diskBlockSize, controllerType) } -func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error { - return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, switchName, generation, diffDisks) +func (d *HypervPS4Driver) CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdPath string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error { + return hyperv.CreateVirtualMachine(vmName, path, harddrivePath, vhdPath, ram, diskSize, diskBlockSize, switchName, generation, diffDisks) } func (d *HypervPS4Driver) CloneVirtualMachine(cloneFromVmxcPath string, cloneFromVmName string, cloneFromSnapshotName string, cloneAllSnapshots bool, vmName string, path string, harddrivePath string, ram int64, switchName string) error { diff --git a/builder/hyperv/common/step_create_vm.go b/builder/hyperv/common/step_create_vm.go index f046d1a48..f8125ed91 100644 --- a/builder/hyperv/common/step_create_vm.go +++ b/builder/hyperv/common/step_create_vm.go @@ -21,6 +21,7 @@ type StepCreateVM struct { HarddrivePath string RamSize uint DiskSize uint + DiskBlockSize uint Generation uint Cpu uint EnableMacSpoofing bool @@ -64,8 +65,9 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste // convert the MB to bytes ramSize := int64(s.RamSize * 1024 * 1024) diskSize := int64(s.DiskSize * 1024 * 1024) + diskBlockSize := int64(s.DiskBlockSize * 1024 * 1024) - err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, s.SwitchName, s.Generation, s.DifferencingDisk) + err := driver.CreateVirtualMachine(s.VMName, path, harddrivePath, vhdPath, ramSize, diskSize, diskBlockSize, s.SwitchName, s.Generation, s.DifferencingDisk) if err != nil { err := fmt.Errorf("Error creating virtual machine: %s", err) state.Put("error", err) @@ -124,7 +126,7 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste for index, size := range s.AdditionalDiskSize { diskSize := int64(size * 1024 * 1024) diskFile := fmt.Sprintf("%s-%d.vhdx", s.VMName, index) - err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, diskFile, diskSize, "SCSI") + err = driver.AddVirtualMachineHardDrive(s.VMName, vhdPath, diskFile, diskSize, diskBlockSize, "SCSI") if err != nil { err := fmt.Errorf("Error creating and attaching additional disk drive: %s", err) state.Put("error", err) @@ -163,4 +165,6 @@ func (s *StepCreateVM) Cleanup(state multistep.StateBag) { if err != nil { ui.Error(fmt.Sprintf("Error deleting virtual machine: %s", err)) } + + // TODO: Clean up created VHDX } diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index b92e779df..a95814630 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -24,6 +24,10 @@ const ( MinDiskSize = 256 // 256MB MaxDiskSize = 64 * 1024 * 1024 // 64TB + DefaultDiskBlockSize = 32 // 32MB + MinDiskBlockSize = 1 // 1MB + MaxDiskBlockSize = 256 // 256MB + DefaultRamSize = 1 * 1024 // 1GB MinRamSize = 32 // 32MB MaxRamSize = 32 * 1024 // 32GB @@ -55,9 +59,15 @@ type Config struct { // The size, in megabytes, of the hard disk to create for the VM. // By default, this is 130048 (about 127 GB). DiskSize uint `mapstructure:"disk_size"` + + // The size, in megabytes, of the block size used to create the hard disk. + // By default, this is 32768 (about 32 MB) + DiskBlockSize uint `mapstructure:"disk_block_size"` + // The size, in megabytes, of the computer memory in the VM. // By default, this is 1024 (about 1 GB). RamSize uint `mapstructure:"ram_size"` + // SecondaryDvdImages []string `mapstructure:"secondary_iso_images"` @@ -141,6 +151,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } + err = b.checkDiskBlockSize() + if err != nil { + errs = packer.MultiErrorAppend(errs, err) + } + err = b.checkRamSize() if err != nil { errs = packer.MultiErrorAppend(errs, err) @@ -352,6 +367,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchName: b.config.SwitchName, RamSize: b.config.RamSize, DiskSize: b.config.DiskSize, + DiskBlockSize: b.config.DiskBlockSize, Generation: b.config.Generation, Cpu: b.config.Cpu, EnableMacSpoofing: b.config.EnableMacSpoofing, @@ -492,6 +508,22 @@ func (b *Builder) checkDiskSize() error { return nil } +func (b *Builder) checkDiskBlockSize() error { + if b.config.DiskBlockSize == 0 { + b.config.DiskBlockSize = DefaultDiskBlockSize + } + + log.Println(fmt.Sprintf("%s: %v", "DiskBlockSize", b.config.DiskBlockSize)) + + if b.config.DiskBlockSize < MinDiskBlockSize { + return fmt.Errorf("disk_block_size: Virtual machine requires disk block size >= %v MB, but defined: %v", MinDiskBlockSize, b.config.DiskBlockSize) + } else if b.config.DiskBlockSize > MaxDiskBlockSize { + return fmt.Errorf("disk_block_size: Virtual machine requires disk block size <= %v MB, but defined: %v", MaxDiskBlockSize, b.config.DiskBlockSize) + } + + return nil +} + func (b *Builder) checkRamSize() error { if b.config.RamSize == 0 { b.config.RamSize = DefaultRamSize diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index b08a683f9..8523876ef 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -23,6 +23,7 @@ func testConfig() map[string]interface{} { "ssh_username": "foo", "ram_size": 64, "disk_size": 256, + "disk_block_size": 1, "guest_additions_mode": "none", "disk_additional_size": "50000,40000,30000", packer.BuildNameConfigKey: "foo", @@ -86,6 +87,58 @@ func TestBuilderPrepare_DiskSize(t *testing.T) { } } +func TestBuilderPrepare_DiskBlockSize(t *testing.T) { + var b Builder + config := testConfig() + expected_default_block_size := uint(32) + expected_min_block_size := uint(0) + expected_max_block_size := uint(256) + + // Test default with empty disk_block_size + delete(config, "disk_block_size") + warns, err := b.Prepare(config) + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("bad err: %s", err) + } + if b.config.DiskBlockSize != expected_default_block_size { + t.Fatalf("bad default block size with empty config: %d. Expected %d", b.config.DiskBlockSize, expected_default_block_size) + } + + test_sizes := []uint{0, 1, 32, 256, 512, 1 * 1024, 32 * 1024} + for _, test_size := range test_sizes { + config["disk_block_size"] = test_size + b = Builder{} + warns, err = b.Prepare(config) + if test_size > expected_max_block_size || test_size < expected_min_block_size { + if len(warns) > 0 { + t.Fatalf("bad, should have no warns: %#v", warns) + } + if err == nil { + t.Fatalf("bad, should have error but didn't. disk_block_size=%d outside expected valid range [%d,%d]", test_size, expected_min_block_size, expected_max_block_size) + } + } else { + if len(warns) > 0 { + t.Fatalf("bad: %#v", warns) + } + if err != nil { + t.Fatalf("bad, should not have error: %s", err) + } + if test_size == 0 { + if b.config.DiskBlockSize != expected_default_block_size { + t.Fatalf("bad default block size with 0 value config: %d. Expected: %d", b.config.DiskBlockSize, expected_default_block_size) + } + } else { + if b.config.DiskBlockSize != test_size { + t.Fatalf("bad block size with 0 value config: %d. Expected: %d", b.config.DiskBlockSize, expected_default_block_size) + } + } + } + } +} + func TestBuilderPrepare_FloppyFiles(t *testing.T) { var b Builder config := testConfig() diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index d26ec5eeb..0a296cce2 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -53,6 +53,22 @@ $ip return cmdOut, err } +//func CreateVirtualHardDiskDrive(vmName string, diskPath string, diskSize int64, diskBlockSize int64, generation uint) (uint, uint, error) { +// +// var script = ` +//param([string]$vmName, [string]$path, +// +// +//[long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) +//$vhdx = $vmName + '.vhdx' +//$vhdPath = Join-Path -Path $path -ChildPath $vhdx +//New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation +//` +// var ps powershell.PowerShellCmd +// err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) +// return err +//} + func CreateDvdDrive(vmName string, isoPath string, generation uint) (uint, uint, error) { var ps powershell.PowerShellCmd var script string @@ -187,45 +203,47 @@ Set-VMFloppyDiskDrive -VMName $vmName -Path $null return err } -func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, switchName string, generation uint, diffDisks bool) error { +func CreateVirtualMachine(vmName string, path string, harddrivePath string, vhdRoot string, ram int64, diskSize int64, diskBlockSize int64, switchName string, generation uint, diffDisks bool) error { if generation == 2 { var script = ` -param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation, [string]$diffDisks) +param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [int]$generation, [string]$diffDisks) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx if ($harddrivePath){ if($diffDisks -eq "true"){ - New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing + New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing -BlockSizeBytes $vhdBlockSizeBytes } else { Copy-Item -Path $harddrivePath -Destination $vhdPath } New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation } else { - New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation + New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes + New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName -Generation $generation } ` var ps powershell.PowerShellCmd - if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10), strconv.FormatBool(diffDisks)); err != nil { + if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), switchName, strconv.FormatInt(int64(generation), 10), strconv.FormatBool(diffDisks)); err != nil { return err } return DisableAutomaticCheckpoints(vmName) } else { var script = ` -param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [string]$diffDisks) +param([string]$vmName, [string]$path, [string]$harddrivePath, [string]$vhdRoot, [long]$memoryStartupBytes, [long]$newVHDSizeBytes, [long]$vhdBlockSizeBytes, [string]$switchName, [string]$diffDisks) $vhdx = $vmName + '.vhdx' $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdx if ($harddrivePath){ if($diffDisks -eq "true"){ - New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing + New-VHD -Path $vhdPath -ParentPath $harddrivePath -Differencing -BlockSizeBytes $vhdBlockSizeBytes } else{ Copy-Item -Path $harddrivePath -Destination $vhdPath } New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName } else { - New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName + New-VHD -Path $vhdPath -SizeBytes $newVHDSizeBytes -BlockSizeBytes $vhdBlockSizeBytes + New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -VHDPath $vhdPath -SwitchName $switchName } ` var ps powershell.PowerShellCmd @@ -872,16 +890,16 @@ Get-VMNetworkAdapter -VMName $vmName | Connect-VMNetworkAdapter -SwitchName $swi return err } -func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName string, vhdSizeBytes int64, controllerType string) error { +func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName string, vhdSizeBytes int64, vhdBlockSize int64, controllerType string) error { var script = ` -param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes, [string]$controllerType) +param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes,[string]$vhdBlockSizeInBize [string]$controllerType) $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdName -New-VHD $vhdPath -SizeBytes $vhdSizeInBytes +New-VHD -path $vhdPath -SizeBytes $vhdSizeInBytes -BlockSizeBytes $vhdBlockSizeInBize Add-VMHardDiskDrive -VMName $vmName -path $vhdPath -controllerType $controllerType ` var ps powershell.PowerShellCmd - err := ps.Run(script, vmName, vhdRoot, vhdName, strconv.FormatInt(vhdSizeBytes, 10), controllerType) + err := ps.Run(script, vmName, vhdRoot, vhdName, strconv.FormatInt(vhdSizeBytes, 10), strconv.FormatInt(vhdBlockSize, 10), controllerType) return err } From 3d5592d040456e91aa4b7223d939df2ddfd3dc24 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 11:31:07 -0800 Subject: [PATCH 0681/1007] prepare for Packer 1.2.1 --- version/version.go | 2 +- website/config.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 93fffef3e..c48756cab 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ const Version = "1.2.1" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index e6d530fdc..63b2de323 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.2.0" + h.version = "1.2.1" h.github_slug = "hashicorp/packer" h.website_root = "website" end From fb86a61100586dc9b4a85f533f86a943d6282850 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 11:57:57 -0800 Subject: [PATCH 0683/1007] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 044f747e5..2cc52892f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.2.1 (February 23, 2918) +## 1.2.1 (February 23, 2018) ### BUG FIXES: From 19bec4351448068e6f76f996a67cf2989fea9e08 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 11:59:02 -0800 Subject: [PATCH 0684/1007] next version is 1.2.2 --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index c48756cab..870a3badd 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.2.1" +const Version = "1.2.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From 487b1d716706c746b5eca793b64a4b3830e0b7ae Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Feb 2018 12:13:47 -0800 Subject: [PATCH 0685/1007] somehow fix gemfile.lock --- website/Gemfile.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/website/Gemfile.lock b/website/Gemfile.lock index 3f43b760a..acf65a9ef 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -6,7 +6,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (7.2.4) + autoprefixer-rails (7.1.5) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -51,7 +51,7 @@ GEM http_parser.rb (0.6.0) i18n (0.7.0) json (2.1.0) - kramdown (1.16.2) + kramdown (1.15.0) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -102,8 +102,8 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mini_portile2 (2.3.0) - minitest (5.11.1) - multi_json (1.13.0) + minitest (5.10.3) + multi_json (1.12.2) nokogiri (1.8.1) mini_portile2 (~> 2.3.0) padrino-helpers (0.12.8.1) @@ -115,7 +115,7 @@ GEM rack (1.6.8) rack-livereload (0.3.16) rack - rack-test (0.8.2) + rack-test (0.7.0) rack (>= 1.0, < 3) rb-fsevent (0.10.2) rb-inotify (0.9.10) @@ -137,10 +137,10 @@ GEM thor (0.20.0) thread_safe (0.3.6) tilt (1.4.1) - turbolinks (5.1.0) - turbolinks-source (~> 5.1) - turbolinks-source (5.1.0) - tzinfo (1.2.4) + turbolinks (5.0.1) + turbolinks-source (~> 5) + turbolinks-source (5.0.3) + tzinfo (1.2.3) thread_safe (~> 0.1) uber (0.0.15) uglifier (2.7.2) @@ -156,4 +156,4 @@ DEPENDENCIES middleman-hashicorp (= 0.3.29) BUNDLED WITH - 1.16.1 + 1.15.4 From efcdbfeab97b8a65d5a514f4671c53227468b61a Mon Sep 17 00:00:00 2001 From: jmajoor <jmajoor@sparklinglogic.com> Date: Fri, 23 Feb 2018 15:34:13 -0800 Subject: [PATCH 0686/1007] Add support for optionally building Azure VMs with additional disks. --- builder/azure/arm/artifact.go | 30 +++ builder/azure/arm/artifact_test.go | 113 +++++++++ builder/azure/arm/builder.go | 2 + builder/azure/arm/capture_template.go | 3 +- builder/azure/arm/capture_template_test.go | 64 ++++- builder/azure/arm/config.go | 3 + .../azure/arm/step_delete_additional_disks.go | 106 ++++++++ .../arm/step_delete_additional_disks_test.go | 227 ++++++++++++++++++ .../azure/arm/step_get_additional_disks.go | 78 ++++++ .../arm/step_get_additional_disks_test.go | 131 ++++++++++ builder/azure/arm/template_factory.go | 4 + ...stVirtualMachineDeployment11.approved.json | 177 ++++++++++++++ ...stVirtualMachineDeployment12.approved.json | 178 ++++++++++++++ builder/azure/arm/template_factory_test.go | 70 ++++++ builder/azure/common/constants/stateBag.go | 1 + builder/azure/common/template/template.go | 13 + .../azure/common/template/template_builder.go | 29 +++ ...lder_test.TestBuildWindows01.approved.json | 202 ++++++++++++++++ ...lder_test.TestBuildWindows02.approved.json | 195 +++++++++++++++ .../common/template/template_builder_test.go | 61 +++++ website/source/docs/builders/azure.html.md | 4 + 21 files changed, 1689 insertions(+), 2 deletions(-) create mode 100644 builder/azure/arm/step_delete_additional_disks.go create mode 100644 builder/azure/arm/step_delete_additional_disks_test.go create mode 100644 builder/azure/arm/step_get_additional_disks.go create mode 100644 builder/azure/arm/step_get_additional_disks_test.go create mode 100644 builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json create mode 100644 builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json create mode 100644 builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json create mode 100644 builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json diff --git a/builder/azure/arm/artifact.go b/builder/azure/arm/artifact.go index e8a72091f..c2abcc4d5 100644 --- a/builder/azure/arm/artifact.go +++ b/builder/azure/arm/artifact.go @@ -12,6 +12,11 @@ const ( BuilderId = "Azure.ResourceManagement.VMImage" ) +type AdditionalDiskArtifact struct { + AdditionalDiskUri string + AdditionalDiskUriReadOnlySas string +} + type Artifact struct { // VHD StorageAccountLocation string @@ -24,6 +29,9 @@ type Artifact struct { ManagedImageResourceGroupName string ManagedImageName string ManagedImageLocation string + + // Additional Disks + AdditionalDisks *[]AdditionalDiskArtifact } func NewManagedImageArtifact(resourceGroup, name, location string) (*Artifact, error) { @@ -53,12 +61,28 @@ func NewArtifact(template *CaptureTemplate, getSasUrl func(name string) string) return nil, err } + var additional_disks *[]AdditionalDiskArtifact + if template.Resources[0].Properties.StorageProfile.DataDisks != nil { + data_disks := make([]AdditionalDiskArtifact, len(template.Resources[0].Properties.StorageProfile.DataDisks)) + for i, additionaldisk := range template.Resources[0].Properties.StorageProfile.DataDisks { + additionalVhdUri, err := url.Parse(additionaldisk.Image.Uri) + if err != nil { + return nil, err + } + data_disks[i].AdditionalDiskUri = additionalVhdUri.String() + data_disks[i].AdditionalDiskUriReadOnlySas = getSasUrl(getStorageUrlPath(additionalVhdUri)) + } + additional_disks = &data_disks + } + return &Artifact{ OSDiskUri: vhdUri.String(), OSDiskUriReadOnlySas: getSasUrl(getStorageUrlPath(vhdUri)), TemplateUri: templateUri.String(), TemplateUriReadOnlySas: getSasUrl(getStorageUrlPath(templateUri)), + AdditionalDisks: additional_disks, + StorageAccountLocation: template.Resources[0].Location, }, nil } @@ -128,6 +152,12 @@ func (a *Artifact) String() string { buf.WriteString(fmt.Sprintf("OSDiskUriReadOnlySas: %s\n", a.OSDiskUriReadOnlySas)) buf.WriteString(fmt.Sprintf("TemplateUri: %s\n", a.TemplateUri)) buf.WriteString(fmt.Sprintf("TemplateUriReadOnlySas: %s\n", a.TemplateUriReadOnlySas)) + if a.AdditionalDisks != nil { + for i, additionaldisk := range *a.AdditionalDisks { + buf.WriteString(fmt.Sprintf("AdditionalDiskUri (datadisk-%d): %s\n", i+1, additionaldisk.AdditionalDiskUri)) + buf.WriteString(fmt.Sprintf("AdditionalDiskUriReadOnlySas (datadisk-%d): %s\n", i+1, additionaldisk.AdditionalDiskUriReadOnlySas)) + } + } } return buf.String() diff --git a/builder/azure/arm/artifact_test.go b/builder/azure/arm/artifact_test.go index 1b9a472af..13c77e2e3 100644 --- a/builder/azure/arm/artifact_test.go +++ b/builder/azure/arm/artifact_test.go @@ -82,6 +82,60 @@ func TestArtifactString(t *testing.T) { } } +func TestAdditionalDiskArtifactString(t *testing.T) { + template := CaptureTemplate{ + Resources: []CaptureResources{ + { + Properties: CaptureProperties{ + StorageProfile: CaptureStorageProfile{ + OSDisk: CaptureDisk{ + Image: CaptureUri{ + Uri: "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd", + }, + }, + DataDisks: []CaptureDisk{ + CaptureDisk{ + Image: CaptureUri{ + Uri: "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd", + }, + }, + }, + }, + }, + Location: "southcentralus", + }, + }, + } + + artifact, err := NewArtifact(&template, getFakeSasUrl) + if err != nil { + t.Fatalf("err=%s", err) + } + + testSubject := artifact.String() + if !strings.Contains(testSubject, "OSDiskUri: https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd") { + t.Errorf("Expected String() output to contain OSDiskUri") + } + if !strings.Contains(testSubject, "OSDiskUriReadOnlySas: SAS-Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd") { + t.Errorf("Expected String() output to contain OSDiskUriReadOnlySas") + } + if !strings.Contains(testSubject, "TemplateUri: https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json") { + t.Errorf("Expected String() output to contain TemplateUri") + } + if !strings.Contains(testSubject, "TemplateUriReadOnlySas: SAS-Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json") { + t.Errorf("Expected String() output to contain TemplateUriReadOnlySas") + } + if !strings.Contains(testSubject, "StorageAccountLocation: southcentralus") { + t.Errorf("Expected String() output to contain StorageAccountLocation") + } + if !strings.Contains(testSubject, "AdditionalDiskUri (datadisk-1): https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd") { + t.Errorf("Expected String() output to contain AdditionalDiskUri") + } + if !strings.Contains(testSubject, "AdditionalDiskUriReadOnlySas (datadisk-1): SAS-Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd") { + t.Errorf("Expected String() output to contain AdditionalDiskUriReadOnlySas") + } +} + func TestArtifactProperties(t *testing.T) { template := CaptureTemplate{ Resources: []CaptureResources{ @@ -122,6 +176,65 @@ func TestArtifactProperties(t *testing.T) { } } +func TestAdditionalDiskArtifactProperties(t *testing.T) { + template := CaptureTemplate{ + Resources: []CaptureResources{ + { + Properties: CaptureProperties{ + StorageProfile: CaptureStorageProfile{ + OSDisk: CaptureDisk{ + Image: CaptureUri{ + Uri: "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd", + }, + }, + DataDisks: []CaptureDisk{ + CaptureDisk{ + Image: CaptureUri{ + Uri: "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd", + }, + }, + }, + }, + }, + Location: "southcentralus", + }, + }, + } + + testSubject, err := NewArtifact(&template, getFakeSasUrl) + if err != nil { + t.Fatalf("err=%s", err) + } + + if testSubject.OSDiskUri != "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd" { + t.Errorf("Expected template to be 'https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd', but got %s", testSubject.OSDiskUri) + } + if testSubject.OSDiskUriReadOnlySas != "SAS-Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd" { + t.Errorf("Expected template to be 'SAS-Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd', but got %s", testSubject.OSDiskUriReadOnlySas) + } + if testSubject.TemplateUri != "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json" { + t.Errorf("Expected template to be 'https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json', but got %s", testSubject.TemplateUri) + } + if testSubject.TemplateUriReadOnlySas != "SAS-Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json" { + t.Errorf("Expected template to be 'SAS-Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json', but got %s", testSubject.TemplateUriReadOnlySas) + } + if testSubject.StorageAccountLocation != "southcentralus" { + t.Errorf("Expected StorageAccountLocation to be 'southcentral', but got %s", testSubject.StorageAccountLocation) + } + if testSubject.AdditionalDisks == nil { + t.Errorf("Expected AdditionalDisks to be not nil") + } + if len(*testSubject.AdditionalDisks) != 1 { + t.Errorf("Expected AdditionalDisks to have one additional disk, but got %d", len(*testSubject.AdditionalDisks)) + } + if (*testSubject.AdditionalDisks)[0].AdditionalDiskUri != "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd" { + t.Errorf("Expected additional disk uri to be 'https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd', but got %s", (*testSubject.AdditionalDisks)[0].AdditionalDiskUri) + } + if (*testSubject.AdditionalDisks)[0].AdditionalDiskUriReadOnlySas != "SAS-Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd" { + t.Errorf("Expected additional disk sas to be 'SAS-Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd', but got %s", (*testSubject.AdditionalDisks)[0].AdditionalDiskUriReadOnlySas) + } +} + func TestArtifactOverHypenatedCaptureUri(t *testing.T) { template := CaptureTemplate{ Resources: []CaptureResources{ diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index 62afe6fa5..64d791ffa 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -181,10 +181,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &packerCommon.StepProvision{}, NewStepGetOSDisk(azureClient, ui), + NewStepGetAdditionalDisks(azureClient, ui), NewStepPowerOffCompute(azureClient, ui), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), NewStepDeleteOSDisk(azureClient, ui), + NewStepDeleteAdditionalDisks(azureClient, ui), } } else { return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType) diff --git a/builder/azure/arm/capture_template.go b/builder/azure/arm/capture_template.go index 0332a02f4..2ba2c48b8 100644 --- a/builder/azure/arm/capture_template.go +++ b/builder/azure/arm/capture_template.go @@ -23,7 +23,8 @@ type CaptureDisk struct { } type CaptureStorageProfile struct { - OSDisk CaptureDisk `json:"osDisk"` + OSDisk CaptureDisk `json:"osDisk"` + DataDisks []CaptureDisk `json:"dataDisks"` } type CaptureOSProfile struct { diff --git a/builder/azure/arm/capture_template_test.go b/builder/azure/arm/capture_template_test.go index 8c7a71405..10be51ee8 100644 --- a/builder/azure/arm/capture_template_test.go +++ b/builder/azure/arm/capture_template_test.go @@ -51,7 +51,33 @@ var captureTemplate01 = `{ "uri": "http://storage.blob.core.windows.net/vmcontainerce1a1b75-f480-47cb-8e6e-55142e4a5f68/osDisk.ce1a1b75-f480-47cb-8e6e-55142e4a5f68.vhd" }, "caching": "ReadWrite" - } + }, + "dataDisks": [ + { + "lun": 0, + "name": "packer-datadisk-0.32118633-6dc9-449f-83b6-a7d2983bec14.vhd", + "createOption": "Empty", + "image": { + "uri": "http://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-0.32118633-6dc9-449f-83b6-a7d2983bec14.vhd" + }, + "vhd": { + "uri": "http://storage.blob.core.windows.net/vmcontainerce1a1b75-f480-47cb-8e6e-55142e4a5f68/datadisk-0.ce1a1b75-f480-47cb-8e6e-55142e4a5f68.vhd" + }, + "caching": "ReadWrite" + }, + { + "lun": 1, + "name": "packer-datadisk-1.32118633-6dc9-449f-83b6-a7d2983bec14.vhd", + "createOption": "Empty", + "image": { + "uri": "http://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.32118633-6dc9-449f-83b6-a7d2983bec14.vhd" + }, + "vhd": { + "uri": "http://storage.blob.core.windows.net/vmcontainerce1a1b75-f480-47cb-8e6e-55142e4a5f68/datadisk-1.ce1a1b75-f480-47cb-8e6e-55142e4a5f68.vhd" + }, + "caching": "ReadWrite" + } + ] }, "osProfile": { "computerName": "[parameters('vmName')]", @@ -169,6 +195,42 @@ func TestCaptureParseJson(t *testing.T) { t.Errorf("Resources[0].Properties.StorageProfile.OSDisk.Caching's value was unexpected: %s", osDisk.Caching) } + // == Resources/Properties/StorageProfile/DataDisks ================ + dataDisks := testSubject.Resources[0].Properties.StorageProfile.DataDisks + if len(dataDisks) != 2 { + t.Errorf("Resources[0].Properties.StorageProfile.DataDisks, 2 disks expected but was: %d", len(dataDisks)) + } + if dataDisks[0].Name != "packer-datadisk-0.32118633-6dc9-449f-83b6-a7d2983bec14.vhd" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[0].Name's value was unexpected: %s", dataDisks[0].Name) + } + if dataDisks[0].CreateOption != "Empty" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[0].CreateOption's value was unexpected: %s", dataDisks[0].CreateOption) + } + if dataDisks[0].Image.Uri != "http://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-0.32118633-6dc9-449f-83b6-a7d2983bec14.vhd" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[0].Image.Uri's value was unexpected: %s", dataDisks[0].Image.Uri) + } + if dataDisks[0].Vhd.Uri != "http://storage.blob.core.windows.net/vmcontainerce1a1b75-f480-47cb-8e6e-55142e4a5f68/datadisk-0.ce1a1b75-f480-47cb-8e6e-55142e4a5f68.vhd" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[0].Vhd.Uri's value was unexpected: %s", dataDisks[0].Vhd.Uri) + } + if dataDisks[0].Caching != "ReadWrite" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[0].Caching's value was unexpected: %s", dataDisks[0].Caching) + } + if dataDisks[1].Name != "packer-datadisk-1.32118633-6dc9-449f-83b6-a7d2983bec14.vhd" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[1].Name's value was unexpected: %s", dataDisks[1].Name) + } + if dataDisks[1].CreateOption != "Empty" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[1].CreateOption's value was unexpected: %s", dataDisks[1].CreateOption) + } + if dataDisks[1].Image.Uri != "http://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.32118633-6dc9-449f-83b6-a7d2983bec14.vhd" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[1].Image.Uri's value was unexpected: %s", dataDisks[1].Image.Uri) + } + if dataDisks[1].Vhd.Uri != "http://storage.blob.core.windows.net/vmcontainerce1a1b75-f480-47cb-8e6e-55142e4a5f68/datadisk-1.ce1a1b75-f480-47cb-8e6e-55142e4a5f68.vhd" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[1].Vhd.Uri's value was unexpected: %s", dataDisks[1].Vhd.Uri) + } + if dataDisks[1].Caching != "ReadWrite" { + t.Errorf("Resources[0].Properties.StorageProfile.dataDisks[1].Caching's value was unexpected: %s", dataDisks[1].Caching) + } + // == Resources/Properties/OSProfile ============================ osProfile := testSubject.Resources[0].Properties.OSProfile if osProfile.AdminPassword != "[parameters('adminPassword')]" { diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index f384c88bc..afa5f62a7 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -112,6 +112,9 @@ type Config struct { OSType string `mapstructure:"os_type"` OSDiskSizeGB int32 `mapstructure:"os_disk_size_gb"` + // Additional Disks + AdditionalDiskSize []int32 `mapstructure:"disk_additional_size"` + // Runtime Values UserName string Password string diff --git a/builder/azure/arm/step_delete_additional_disks.go b/builder/azure/arm/step_delete_additional_disks.go new file mode 100644 index 000000000..d43bf8253 --- /dev/null +++ b/builder/azure/arm/step_delete_additional_disks.go @@ -0,0 +1,106 @@ +package arm + +import ( + "context" + "errors" + "fmt" + "net/url" + "strings" + + "github.com/hashicorp/packer/builder/azure/common/constants" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type StepDeleteAdditionalDisk struct { + client *AzureClient + delete func(string, string) error + deleteManaged func(string, string) error + say func(message string) + error func(e error) +} + +func NewStepDeleteAdditionalDisks(client *AzureClient, ui packer.Ui) *StepDeleteAdditionalDisk { + var step = &StepDeleteAdditionalDisk{ + client: client, + say: func(message string) { ui.Say(message) }, + error: func(e error) { ui.Error(e.Error()) }, + } + + step.delete = step.deleteBlob + step.deleteManaged = step.deleteManagedDisk + return step +} + +func (s *StepDeleteAdditionalDisk) deleteBlob(storageContainerName string, blobName string) error { + blob := s.client.BlobStorageClient.GetContainerReference(storageContainerName).GetBlobReference(blobName) + err := blob.Delete(nil) + + if err != nil { + s.say(s.client.LastError.Error()) + } + return err +} + +func (s *StepDeleteAdditionalDisk) deleteManagedDisk(resourceGroupName string, imageName string) error { + xs := strings.Split(imageName, "/") + diskName := xs[len(xs)-1] + _, errChan := s.client.DisksClient.Delete(resourceGroupName, diskName, nil) + err := <-errChan + return err +} + +func (s *StepDeleteAdditionalDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + s.say("Deleting the temporary Additional disk ...") + + var dataDisks = state.Get(constants.ArmAdditionalDiskVhds).([]string) + var isManagedDisk = state.Get(constants.ArmIsManagedImage).(bool) + var isExistingResourceGroup = state.Get(constants.ArmIsExistingResourceGroup).(bool) + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) + + if dataDisks == nil { + s.say(fmt.Sprintf(" -> No Additional Disks specified")) + return multistep.ActionContinue + } + + if isManagedDisk && !isExistingResourceGroup { + s.say(fmt.Sprintf(" -> Additional Disk : skipping, managed disk was used...")) + return multistep.ActionContinue + } + + for i, additionaldisk := range dataDisks { + s.say(fmt.Sprintf(" -> Additional Disk %d: '%s'", i+1, additionaldisk)) + var err error + if isManagedDisk { + err = s.deleteManaged(resourceGroupName, additionaldisk) + if err != nil { + s.say("Failed to delete the managed Additional Disk!") + return processStepResult(err, s.error, state) + } + } else { + u, err := url.Parse(additionaldisk) + if err != nil { + s.say("Failed to parse the Additional Disk's VHD URI!") + return processStepResult(err, s.error, state) + } + + xs := strings.Split(u.Path, "/") + if len(xs) < 3 { + err = errors.New("Failed to parse Additional Disk's VHD URI!") + } else { + var storageAccountName = xs[1] + var blobName = strings.Join(xs[2:], "/") + + err = s.delete(storageAccountName, blobName) + } + if err != nil { + return processStepResult(err, s.error, state) + } + } + } + return multistep.ActionContinue +} + +func (*StepDeleteAdditionalDisk) Cleanup(multistep.StateBag) { +} diff --git a/builder/azure/arm/step_delete_additional_disks_test.go b/builder/azure/arm/step_delete_additional_disks_test.go new file mode 100644 index 000000000..80ec5b42e --- /dev/null +++ b/builder/azure/arm/step_delete_additional_disks_test.go @@ -0,0 +1,227 @@ +package arm + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/hashicorp/packer/builder/azure/common/constants" + "github.com/hashicorp/packer/helper/multistep" +) + +func TestStepDeleteAdditionalDiskShouldFailIfGetFails(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return fmt.Errorf("!! Unit Test FAIL !!") }, + deleteManaged: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepDeleteAdditionalDisk([]string{"http://storage.blob.core.windows.net/images/pkrvm_os.vhd"}) + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error) + } +} + +func TestStepDeleteAdditionalDiskShouldPassIfGetPasses(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepDeleteAdditionalDisk([]string{"http://storage.blob.core.windows.net/images/pkrvm_os.vhd"}) + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == true { + t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepDeleteAdditionalDiskShouldTakeStepArgumentsFromStateBag(t *testing.T) { + var actualStorageContainerName string + var actualBlobName string + + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(storageContainerName string, blobName string) error { + actualStorageContainerName = storageContainerName + actualBlobName = blobName + return nil + }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepDeleteAdditionalDisk([]string{"http://storage.blob.core.windows.net/images/pkrvm_os.vhd"}) + var result = testSubject.Run(context.Background(), stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if actualStorageContainerName != "images" { + t.Fatalf("Expected the storage container name to be 'images', but found '%s'.", actualStorageContainerName) + } + + if actualBlobName != "pkrvm_os.vhd" { + t.Fatalf("Expected the blob name to be 'pkrvm_os.vhd', but found '%s'.", actualBlobName) + } +} + +func TestStepDeleteAdditionalDiskShouldHandleComplexStorageContainerNames(t *testing.T) { + var actualStorageContainerName string + var actualBlobName string + + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(storageContainerName string, blobName string) error { + actualStorageContainerName = storageContainerName + actualBlobName = blobName + return nil + }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := DeleteTestStateBagStepDeleteAdditionalDisk([]string{"http://storage.blob.core.windows.net/abc/def/pkrvm_os.vhd"}) + testSubject.Run(context.Background(), stateBag) + + if actualStorageContainerName != "abc" { + t.Fatalf("Expected the storage container name to be 'abc/def', but found '%s'.", actualStorageContainerName) + } + + if actualBlobName != "def/pkrvm_os.vhd" { + t.Fatalf("Expected the blob name to be 'pkrvm_os.vhd', but found '%s'.", actualBlobName) + } +} + +func TestStepDeleteAdditionalDiskShouldFailIfVHDNameCannotBeURLParsed(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return nil }, + } + + // Invalid URL per https://golang.org/src/net/url/url_test.go + stateBag := DeleteTestStateBagStepDeleteAdditionalDisk([]string{"http://[fe80::1%en0]/"}) + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%v'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to not stateBag['%s'], but it was.", constants.Error) + } +} +func TestStepDeleteAdditionalDiskShouldFailIfVHDNameIsTooShort(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return nil }, + } + + stateBag := DeleteTestStateBagStepDeleteAdditionalDisk([]string{"storage.blob.core.windows.net/abc"}) + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to not stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepDeleteAdditionalDiskShouldPassIfManagedDiskInTempResourceGroup(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmAdditionalDiskVhds, []string{"subscriptions/123-456-789/resourceGroups/existingresourcegroup/providers/Microsoft.Compute/disks/osdisk"}) + stateBag.Put(constants.ArmIsManagedImage, true) + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == true { + t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepDeleteAdditionalDiskShouldFailIfManagedDiskInExistingResourceGroupFailsToDelete(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return errors.New("UNIT TEST FAIL!") }, + } + + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmAdditionalDiskVhds, []string{"subscriptions/123-456-789/resourceGroups/existingresourcegroup/providers/Microsoft.Compute/disks/osdisk"}) + stateBag.Put(constants.ArmIsManagedImage, true) + stateBag.Put(constants.ArmIsExistingResourceGroup, true) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to not stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepDeleteAdditionalDiskShouldFailIfManagedDiskInExistingResourceGroupIsDeleted(t *testing.T) { + var testSubject = &StepDeleteAdditionalDisk{ + delete: func(string, string) error { return nil }, + say: func(message string) {}, + error: func(e error) {}, + deleteManaged: func(string, string) error { return nil }, + } + + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmAdditionalDiskVhds, []string{"subscriptions/123-456-789/resourceGroups/existingresourcegroup/providers/Microsoft.Compute/disks/osdisk"}) + stateBag.Put(constants.ArmIsManagedImage, true) + stateBag.Put(constants.ArmIsExistingResourceGroup, true) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == true { + t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error) + } +} + +func DeleteTestStateBagStepDeleteAdditionalDisk(osDiskVhds []string) multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + stateBag.Put(constants.ArmAdditionalDiskVhds, osDiskVhds) + stateBag.Put(constants.ArmIsManagedImage, false) + stateBag.Put(constants.ArmIsExistingResourceGroup, false) + stateBag.Put(constants.ArmResourceGroupName, "testgroup") + + return stateBag +} diff --git a/builder/azure/arm/step_get_additional_disks.go b/builder/azure/arm/step_get_additional_disks.go new file mode 100644 index 000000000..68af51724 --- /dev/null +++ b/builder/azure/arm/step_get_additional_disks.go @@ -0,0 +1,78 @@ +package arm + +import ( + "context" + "fmt" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + + "github.com/hashicorp/packer/builder/azure/common/constants" + + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +type StepGetDataDisk struct { + client *AzureClient + query func(resourceGroupName string, computeName string) (compute.VirtualMachine, error) + say func(message string) + error func(e error) +} + +func NewStepGetAdditionalDisks(client *AzureClient, ui packer.Ui) *StepGetDataDisk { + var step = &StepGetDataDisk{ + client: client, + say: func(message string) { ui.Say(message) }, + error: func(e error) { ui.Error(e.Error()) }, + } + + step.query = step.queryCompute + return step +} + +func (s *StepGetDataDisk) queryCompute(resourceGroupName string, computeName string) (compute.VirtualMachine, error) { + vm, err := s.client.VirtualMachinesClient.Get(resourceGroupName, computeName, "") + if err != nil { + s.say(s.client.LastError.Error()) + } + return vm, err +} + +func (s *StepGetDataDisk) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + s.say("Querying the machine's additional disks properties ...") + + var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string) + var computeName = state.Get(constants.ArmComputeName).(string) + + s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName)) + s.say(fmt.Sprintf(" -> ComputeName : '%s'", computeName)) + + vm, err := s.query(resourceGroupName, computeName) + if err != nil { + state.Put(constants.Error, err) + s.error(err) + + return multistep.ActionHalt + } + + if vm.StorageProfile.DataDisks != nil { + var vhdUri string + additional_disks := make([]string, len(*vm.StorageProfile.DataDisks)) + for i, additionaldisk := range *vm.StorageProfile.DataDisks { + if additionaldisk.Vhd != nil { + vhdUri = *additionaldisk.Vhd.URI + s.say(fmt.Sprintf(" -> Additional Disk %d : '%s'", i+1, vhdUri)) + } else { + vhdUri = *additionaldisk.ManagedDisk.ID + s.say(fmt.Sprintf(" -> Managed Additional Disk %d : '%s'", i+1, vhdUri)) + } + additional_disks[i] = vhdUri + } + state.Put(constants.ArmAdditionalDiskVhds, additional_disks) + } + + return multistep.ActionContinue +} + +func (*StepGetDataDisk) Cleanup(multistep.StateBag) { +} diff --git a/builder/azure/arm/step_get_additional_disks_test.go b/builder/azure/arm/step_get_additional_disks_test.go new file mode 100644 index 000000000..1c6dd3380 --- /dev/null +++ b/builder/azure/arm/step_get_additional_disks_test.go @@ -0,0 +1,131 @@ +package arm + +import ( + "context" + "fmt" + "testing" + + "github.com/Azure/azure-sdk-for-go/arm/compute" + + "github.com/hashicorp/packer/builder/azure/common/constants" + + "github.com/hashicorp/packer/helper/multistep" +) + +func TestStepGetAdditionalDiskShouldFailIfGetFails(t *testing.T) { + var testSubject = &StepGetDataDisk{ + query: func(string, string) (compute.VirtualMachine, error) { + return createVirtualMachineWithDataDisksFromUri("test.vhd"), fmt.Errorf("!! Unit Test FAIL !!") + }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := createTestStateBagStepGetAdditionalDisks() + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionHalt { + t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == false { + t.Fatalf("Expected the step to set stateBag['%s'], but it was not.", constants.Error) + } +} + +func TestStepGetAdditionalDiskShouldPassIfGetPasses(t *testing.T) { + var testSubject = &StepGetDataDisk{ + query: func(string, string) (compute.VirtualMachine, error) { + return createVirtualMachineWithDataDisksFromUri("test.vhd"), nil + }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := createTestStateBagStepGetAdditionalDisks() + + var result = testSubject.Run(context.Background(), stateBag) + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + if _, ok := stateBag.GetOk(constants.Error); ok == true { + t.Fatalf("Expected the step to not set stateBag['%s'], but it was.", constants.Error) + } +} + +func TestStepGetAdditionalDiskShouldTakeValidateArgumentsFromStateBag(t *testing.T) { + var actualResourceGroupName string + var actualComputeName string + + var testSubject = &StepGetDataDisk{ + query: func(resourceGroupName string, computeName string) (compute.VirtualMachine, error) { + actualResourceGroupName = resourceGroupName + actualComputeName = computeName + + return createVirtualMachineWithDataDisksFromUri("test.vhd"), nil + }, + say: func(message string) {}, + error: func(e error) {}, + } + + stateBag := createTestStateBagStepGetAdditionalDisks() + var result = testSubject.Run(context.Background(), stateBag) + + if result != multistep.ActionContinue { + t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result) + } + + var expectedComputeName = stateBag.Get(constants.ArmComputeName).(string) + var expectedResourceGroupName = stateBag.Get(constants.ArmResourceGroupName).(string) + + if actualComputeName != expectedComputeName { + t.Fatal("Expected the step to source 'constants.ArmResourceGroupName' from the state bag, but it did not.") + } + + if actualResourceGroupName != expectedResourceGroupName { + t.Fatal("Expected the step to source 'constants.ArmResourceGroupName' from the state bag, but it did not.") + } + + expectedAdditionalDiskVhds, ok := stateBag.GetOk(constants.ArmAdditionalDiskVhds) + if !ok { + t.Fatalf("Expected the state bag to have a value for '%s', but it did not.", constants.ArmAdditionalDiskVhds) + } + + expectedAdditionalDiskVhd := expectedAdditionalDiskVhds.([]string) + if expectedAdditionalDiskVhd[0] != "test.vhd" { + t.Fatalf("Expected the value of stateBag[%s] to be 'test.vhd', but got '%s'.", constants.ArmAdditionalDiskVhds, expectedAdditionalDiskVhd[0]) + } +} + +func createTestStateBagStepGetAdditionalDisks() multistep.StateBag { + stateBag := new(multistep.BasicStateBag) + + stateBag.Put(constants.ArmComputeName, "Unit Test: ComputeName") + stateBag.Put(constants.ArmResourceGroupName, "Unit Test: ResourceGroupName") + + return stateBag +} + +func createVirtualMachineWithDataDisksFromUri(vhdUri string) compute.VirtualMachine { + vm := compute.VirtualMachine{ + VirtualMachineProperties: &compute.VirtualMachineProperties{ + StorageProfile: &compute.StorageProfile{ + OsDisk: &compute.OSDisk{ + Vhd: &compute.VirtualHardDisk{ + URI: &vhdUri, + }, + }, + DataDisks: &[]compute.DataDisk{ + compute.DataDisk{ + Vhd: &compute.VirtualHardDisk{ + URI: &vhdUri, + }, + }, + }, + }, + }, + } + + return vm +} diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index 07f2313b5..ebc7ef91c 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -73,6 +73,10 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error) builder.SetOSDiskSizeGB(config.OSDiskSizeGB) } + if len(config.AdditionalDiskSize) > 0 { + builder.SetAdditionalDisks(config.AdditionalDiskSize, config.CustomManagedImageName != "" || (config.ManagedImageName != "" && config.ImagePublisher != "")) + } + if config.customData != "" { builder.SetCustomData(config.customData) } diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json new file mode 100644 index 000000000..b5fbfaf2f --- /dev/null +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json @@ -0,0 +1,177 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "dataDisks": [ + { + "caching": "ReadWrite", + "createOption": "Empty", + "diskSizeGB": 32, + "lun": 0, + "name": "datadisk-1", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '1','.vhd')]" + } + } + ], + "imageReference": { + "offer": "--image-offer--", + "publisher": "--image-publisher--", + "sku": "--image-sku--", + "version": "--version--" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "nicName": "packerNic", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json new file mode 100644 index 000000000..531b2654b --- /dev/null +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json @@ -0,0 +1,178 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "dataDisks": [ + { + "caching": "ReadWrite", + "createOption": "Empty", + "diskSizeGB": 32, + "lun": 0, + "managedDisk": { + "storageAccountType": "Standard_LRS" + }, + "name": "datadisk-1" + } + ], + "imageReference": { + "offer": "--image-offer--", + "publisher": "--image-publisher--", + "sku": "--image-sku--", + "version": "--version--" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "fromImage", + "managedDisk": { + "storageAccountType": "Standard_LRS" + }, + "name": "osdisk", + "osType": "Linux" + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "nicName": "packerNic", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.go b/builder/azure/arm/template_factory_test.go index b571871ef..7909a0cee 100644 --- a/builder/azure/arm/template_factory_test.go +++ b/builder/azure/arm/template_factory_test.go @@ -355,6 +355,76 @@ func TestVirtualMachineDeployment10(t *testing.T) { } } +// Ensure the VM template is correct when building with additional unmanaged disks +func TestVirtualMachineDeployment11(t *testing.T) { + config := map[string]interface{}{ + "location": "ignore", + "subscription_id": "ignore", + "os_type": constants.Target_Linux, + "communicator": "none", + "image_publisher": "--image-publisher--", + "image_offer": "--image-offer--", + "image_sku": "--image-sku--", + "image_version": "--version--", + + "disk_additional_size": []uint{32}, + + "resource_group_name": "packergroup", + "storage_account": "packerartifacts", + "capture_name_prefix": "packer", + "capture_container_name": "packerimages", + } + + c, _, err := newConfig(config, getPackerConfiguration()) + if err != nil { + t.Fatal(err) + } + + deployment, err := GetVirtualMachineDeployment(c) + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) + if err != nil { + t.Fatal(err) + } +} + +// Ensure the VM template is correct when building with additional managed disks +func TestVirtualMachineDeployment12(t *testing.T) { + config := map[string]interface{}{ + "location": "ignore", + "subscription_id": "ignore", + "os_type": constants.Target_Linux, + "communicator": "none", + "image_publisher": "--image-publisher--", + "image_offer": "--image-offer--", + "image_sku": "--image-sku--", + "image_version": "--version--", + + "disk_additional_size": []uint{32}, + + "managed_image_name": "ManagedImageName", + "managed_image_resource_group_name": "ManagedImageResourceGroupName", + } + + c, _, err := newConfig(config, getPackerConfiguration()) + if err != nil { + t.Fatal(err) + } + + deployment, err := GetVirtualMachineDeployment(c) + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) + if err != nil { + t.Fatal(err) + } +} + // Ensure the link values are not set, and the concrete values are set. func TestKeyVaultDeployment00(t *testing.T) { c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration()) diff --git a/builder/azure/common/constants/stateBag.go b/builder/azure/common/constants/stateBag.go index 720979b9c..3576f6820 100644 --- a/builder/azure/common/constants/stateBag.go +++ b/builder/azure/common/constants/stateBag.go @@ -21,6 +21,7 @@ const ( ArmKeyVaultName string = "arm.KeyVaultName" ArmLocation string = "arm.Location" ArmOSDiskVhd string = "arm.OSDiskVhd" + ArmAdditionalDiskVhds string = "arm.AdditionalDiskVhds" ArmPublicIPAddressName string = "arm.PublicIPAddressName" ArmResourceGroupName string = "arm.ResourceGroupName" ArmIsResourceGroupCreated string = "arm.IsResourceGroupCreated" diff --git a/builder/azure/common/template/template.go b/builder/azure/common/template/template.go index cdea487f0..070ca3392 100644 --- a/builder/azure/common/template/template.go +++ b/builder/azure/common/template/template.go @@ -48,10 +48,23 @@ type OSDiskUnion struct { ManagedDisk *compute.ManagedDiskParameters `json:"managedDisk,omitempty"` } +type DataDiskUnion struct { + Lun *int `json:"lun,omitempty"` + BlobURI *string `json:"blobUri,omitempty"` + Name *string `json:"name,omitempty"` + Vhd *compute.VirtualHardDisk `json:"vhd,omitempty"` + Image *compute.VirtualHardDisk `json:"image,omitempty"` + Caching compute.CachingTypes `json:"caching,omitempty"` + CreateOption compute.DiskCreateOptionTypes `json:"createOption,omitempty"` + DiskSizeGB *int32 `json:"diskSizeGB,omitempty"` + ManagedDisk *compute.ManagedDiskParameters `json:"managedDisk,omitempty"` +} + // Union of the StorageProfile and ImageStorageProfile types. type StorageProfileUnion struct { ImageReference *compute.ImageReference `json:"imageReference,omitempty"` OsDisk *OSDiskUnion `json:"osDisk,omitempty"` + DataDisks *[]DataDiskUnion `json:"dataDisks,omitempty"` } ///////////////////////////////////////////////// diff --git a/builder/azure/common/template/template_builder.go b/builder/azure/common/template/template_builder.go index 7311817c2..835aff096 100644 --- a/builder/azure/common/template/template_builder.go +++ b/builder/azure/common/template/template_builder.go @@ -191,6 +191,35 @@ func (s *TemplateBuilder) SetOSDiskSizeGB(diskSizeGB int32) error { return nil } +func (s *TemplateBuilder) SetAdditionalDisks(diskSizeGB []int32, isManaged bool) error { + resource, err := s.getResourceByType(resourceVirtualMachine) + if err != nil { + return err + } + + profile := resource.Properties.StorageProfile + dataDisks := make([]DataDiskUnion, len(diskSizeGB)) + + for i, additionalsize := range diskSizeGB { + dataDisks[i].DiskSizeGB = to.Int32Ptr(additionalsize) + dataDisks[i].Lun = to.IntPtr(i) + dataDisks[i].Name = to.StringPtr(fmt.Sprintf("datadisk-%d", i+1)) + dataDisks[i].CreateOption = "Empty" + dataDisks[i].Caching = "ReadWrite" + if isManaged { + dataDisks[i].Vhd = nil + dataDisks[i].ManagedDisk = profile.OsDisk.ManagedDisk + } else { + dataDisks[i].Vhd = &compute.VirtualHardDisk{ + URI: to.StringPtr(fmt.Sprintf("[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '%d','.vhd')]", i+1)), + } + dataDisks[i].ManagedDisk = nil + } + } + profile.DataDisks = &dataDisks + return nil +} + func (s *TemplateBuilder) SetCustomData(customData string) error { resource, err := s.getResourceByType(resourceVirtualMachine) if err != nil { diff --git a/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json b/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json new file mode 100644 index 000000000..b7a145df9 --- /dev/null +++ b/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json @@ -0,0 +1,202 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "secrets": [ + { + "sourceVault": { + "id": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults', '--test-key-vault-name')]" + }, + "vaultCertificates": [ + { + "certificateStore": "My", + "certificateUrl": "--test-winrm-certificate-url--" + } + ] + } + ], + "windowsConfiguration": { + "provisionVMAgent": true, + "winRM": { + "listeners": [ + { + "certificateUrl": "--test-winrm-certificate-url--", + "protocol": "https" + } + ] + } + } + }, + "storageProfile": { + "dataDisks": [ + { + "caching": "ReadWrite", + "createOption": "Empty", + "diskSizeGB": 32, + "lun": 0, + "managedDisk": { + "storageAccountType": "Premium_LRS" + }, + "name": "datadisk-1" + }, + { + "caching": "ReadWrite", + "createOption": "Empty", + "diskSizeGB": 64, + "lun": 1, + "managedDisk": { + "storageAccountType": "Premium_LRS" + }, + "name": "datadisk-2" + } + ], + "imageReference": { + "offer": "2012-R2-Datacenter", + "publisher": "WindowsServer", + "sku": "latest", + "version": "2015-1" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "fromImage", + "managedDisk": { + "storageAccountType": "Premium_LRS" + }, + "name": "osdisk", + "osType": "Windows" + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "nicName": "packerNic", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json b/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json new file mode 100644 index 000000000..61b05a125 --- /dev/null +++ b/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json @@ -0,0 +1,195 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "secrets": [ + { + "sourceVault": { + "id": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults', '--test-key-vault-name')]" + }, + "vaultCertificates": [ + { + "certificateStore": "My", + "certificateUrl": "--test-winrm-certificate-url--" + } + ] + } + ], + "windowsConfiguration": { + "provisionVMAgent": true, + "winRM": { + "listeners": [ + { + "certificateUrl": "--test-winrm-certificate-url--", + "protocol": "https" + } + ] + } + } + }, + "storageProfile": { + "dataDisks": [ + { + "caching": "ReadWrite", + "createOption": "Empty", + "diskSizeGB": 32, + "lun": 0, + "name": "datadisk-1", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '1','.vhd')]" + } + }, + { + "caching": "ReadWrite", + "createOption": "Empty", + "diskSizeGB": 64, + "lun": 1, + "name": "datadisk-2", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/datadisk-', '2','.vhd')]" + } + } + ], + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "nicName": "packerNic", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/common/template/template_builder_test.go b/builder/azure/common/template/template_builder_test.go index ec93a61a7..6eac5334f 100644 --- a/builder/azure/common/template/template_builder_test.go +++ b/builder/azure/common/template/template_builder_test.go @@ -120,3 +120,64 @@ func TestBuildWindows00(t *testing.T) { t.Fatal(err) } } + +// Windows build with additional disk for an managed build +func TestBuildWindows01(t *testing.T) { + testSubject, err := NewTemplateBuilder(BasicTemplate) + if err != nil { + t.Fatal(err) + } + + err = testSubject.BuildWindows("--test-key-vault-name", "--test-winrm-certificate-url--") + if err != nil { + t.Fatal(err) + } + + err = testSubject.SetManagedMarketplaceImage("MicrosoftWindowsServer", "WindowsServer", "2012-R2-Datacenter", "latest", "2015-1", "1", "Premium_LRS") + if err != nil { + t.Fatal(err) + } + + err = testSubject.SetAdditionalDisks([]int32{32, 64}, true) + if err != nil { + t.Fatal(err) + } + + doc, err := testSubject.ToJSON() + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONBytes(t, []byte(*doc)) + if err != nil { + t.Fatal(err) + } +} + +// Windows build with additional disk for an unmanaged build +func TestBuildWindows02(t *testing.T) { + testSubject, err := NewTemplateBuilder(BasicTemplate) + if err != nil { + t.Fatal(err) + } + + err = testSubject.BuildWindows("--test-key-vault-name", "--test-winrm-certificate-url--") + if err != nil { + t.Fatal(err) + } + + err = testSubject.SetAdditionalDisks([]int32{32, 64}, false) + if err != nil { + t.Fatal(err) + } + + doc, err := testSubject.ToJSON() + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONBytes(t, []byte(*doc)) + if err != nil { + t.Fatal(err) + } +} diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 8fa59f4e8..71e8be385 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -149,6 +149,10 @@ Providing `temp_resource_group_name` or `location` in combination with `build_re - `os_disk_size_gb` (number) Specify the size of the OS disk in GB (gigabytes). Values of zero or less than zero are ignored. +- `disk_additional_size` (array of integers) - The size(s) of any additional + hard disks for the VM in gigabytes. If this is not specified then the VM + will only contain an OS disk. + - `os_type` (string) If either `Linux` or `Windows` is specified Packer will automatically configure authentication credentials for the provisioned machine. For `Linux` this configures an SSH authorized key. For `Windows` this From 47947bd0f6753cfad327177705efc485023166cf Mon Sep 17 00:00:00 2001 From: jmajoor <jmajoor@sparklinglogic.com> Date: Fri, 23 Feb 2018 18:43:55 -0800 Subject: [PATCH 0687/1007] Apply gofmt --- builder/azure/arm/artifact_test.go | 4 ++-- builder/azure/arm/step_get_additional_disks_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/azure/arm/artifact_test.go b/builder/azure/arm/artifact_test.go index 13c77e2e3..4aff7cee6 100644 --- a/builder/azure/arm/artifact_test.go +++ b/builder/azure/arm/artifact_test.go @@ -94,7 +94,7 @@ func TestAdditionalDiskArtifactString(t *testing.T) { }, }, DataDisks: []CaptureDisk{ - CaptureDisk{ + { Image: CaptureUri{ Uri: "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd", }, @@ -188,7 +188,7 @@ func TestAdditionalDiskArtifactProperties(t *testing.T) { }, }, DataDisks: []CaptureDisk{ - CaptureDisk{ + { Image: CaptureUri{ Uri: "https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-datadisk-1.4085bb15-3644-4641-b9cd-f575918640b4.vhd", }, diff --git a/builder/azure/arm/step_get_additional_disks_test.go b/builder/azure/arm/step_get_additional_disks_test.go index 1c6dd3380..b0ca112c3 100644 --- a/builder/azure/arm/step_get_additional_disks_test.go +++ b/builder/azure/arm/step_get_additional_disks_test.go @@ -117,7 +117,7 @@ func createVirtualMachineWithDataDisksFromUri(vhdUri string) compute.VirtualMach }, }, DataDisks: &[]compute.DataDisk{ - compute.DataDisk{ + { Vhd: &compute.VirtualHardDisk{ URI: &vhdUri, }, From dfc75acb632af78a02474257df858da87d3ebb8b Mon Sep 17 00:00:00 2001 From: Taeho Kim <dittos@gmail.com> Date: Sat, 24 Feb 2018 12:29:50 +0900 Subject: [PATCH 0688/1007] Sort options alphabetically --- .../source/docs/builders/alicloud-ecs.html.md | 169 +++++++++--------- 1 file changed, 84 insertions(+), 85 deletions(-) diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index 172bdab5c..5c4330778 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -27,12 +27,10 @@ builder. but it can also be sourced from the `ALICLOUD_ACCESS_KEY` environment variable. -- `secret_key` (string) - This is the Alicloud secret key. It must be provided, - but it can also be sourced from the `ALICLOUD_SECRET_KEY` environment - variable. - -- `region` (string) - This is the Alicloud region. It must be provided, but it - can also be sourced from the `ALICLOUD_REGION` environment variables. +- `image_name` (string) - The name of the user-defined image, \[2, 128\] English + or Chinese characters. It must begin with an uppercase/lowercase letter or + a Chinese character, and may contain numbers, `_` or `-`. It cannot begin with + `http://` or `https://`. - `instance_type` (string) - Type of the instance. For values, see [Instance Type Table](https://www.alibabacloud.com/help/doc-detail/25378.htm?spm=a3c0i.o25499en.a3.9.14a36ac8iYqKRA). @@ -40,54 +38,38 @@ builder. Instance Type Table](https://intl.aliyun.com/help/doc-detail/25620.htm?spm=a3c0i.o25499en.a3.6.Dr1bik) interface. -- `image_name` (string) - The name of the user-defined image, \[2, 128\] English - or Chinese characters. It must begin with an uppercase/lowercase letter or - a Chinese character, and may contain numbers, `_` or `-`. It cannot begin with - `http://` or `https://`. +- `region` (string) - This is the Alicloud region. It must be provided, but it + can also be sourced from the `ALICLOUD_REGION` environment variables. + +- `secret_key` (string) - This is the Alicloud secret key. It must be provided, + but it can also be sourced from the `ALICLOUD_SECRET_KEY` environment + variable. - `source_image` (string) - This is the base image id which you want to create your customized images. ### Optional: -- `skip_region_validation` (boolean) - The region validation can be skipped if this - value is true, the default value is false. +- `force_stop_instance` (boolean) - Whether to force shutdown upon device restart. + The default value is `false`. -- `image_description` (string) - The description of the image, with a length - limit of 0 to 256 characters. Leaving it blank means null, which is the - default value. It cannot begin with `http://` or `https://`. - -- `image_version` (string) - The version number of the image, with a length limit - of 1 to 40 English characters. - -- `image_share_account` (array of string) - The IDs of to-be-added Aliyun - accounts to which the image is shared. The number of accounts is 1 to 10. If - number of accounts is greater than 10, this parameter is ignored. - -- `image_copy_regions` (array of string) - Copy to the destination regionIds. + If it is set to `false`, the system is shut down normally; if it is set to + `true`, the system is forced to shut down. - `image_copy_names` (array of string) - The name of the destination image, \[2, 128\] English or Chinese characters. It must begin with an uppercase/lowercase letter or a Chinese character, and may contain numbers, `_` or `-`. It cannot begin with `http://` or `https://`. -- `image_force_delete` (boolean) - If this value is true, when the target image name - is duplicated with an existing image, it will delete the existing image and - then create the target image, otherwise, the creation will fail. The default - value is false. +- `image_copy_regions` (array of string) - Copy to the destination regionIds. -- `image_force_delete_snapshots` (boolean) - If this value is true, when delete the - duplicated existing image, the source snapshot of this image will be delete - either. +- `image_description` (string) - The description of the image, with a length + limit of 0 to 256 characters. Leaving it blank means null, which is the + default value. It cannot begin with `http://` or `https://`. -   `image_disk_mappings` (array of image disk mappings) - Add one or more data disks to the image. - - `disk_name` (string) - The value of disk name is blank by default. \[2, 128\] - English or Chinese characters, must begin with an uppercase/lowercase letter - or Chinese character. Can contain numbers, `.`, `_` and `-`. The disk name - will appear on the console. It cannot begin with `http://` or `https://`. - - `disk_category` (string) - Category of the data disk. Optional values are: - cloud - general cloud disk - cloud\_efficiency - efficiency cloud disk @@ -95,6 +77,20 @@ builder. Default value: cloud. + - `disk_delete_with_instance` (string) - Whether or not the disk is released along with the instance: + - True indicates that when the instance is released, this disk will be released with it + - False indicates that when the instance is released, this disk will be retained. + + - `disk_description` (string) - The value of disk description is blank by default. \[2, 256\] characters. The disk description will appear on the console. It cannot begin with `http://` or `https://`. + + - `disk_device` (string) - Device information of the related instance: such as + `/dev/xvdb` It is null unless the Status is In\_use. + + - `disk_name` (string) - The value of disk name is blank by default. \[2, 128\] + English or Chinese characters, must begin with an uppercase/lowercase letter + or Chinese character. Can contain numbers, `.`, `_` and `-`. The disk name + will appear on the console. It cannot begin with `http://` or `https://`. + - `disk_size` (number) - Size of the system disk, in GB, values range: - cloud - 5 ~ 2000 - cloud\_efficiency - 20 ~ 2048 @@ -108,54 +104,21 @@ builder. Snapshots from on or before July 15, 2013 cannot be used to create a disk. - - `disk_description` (string) - The value of disk description is blank by default. \[2, 256\] characters. The disk description will appear on the console. It cannot begin with `http://` or `https://`. +- `image_force_delete` (boolean) - If this value is true, when the target image name + is duplicated with an existing image, it will delete the existing image and + then create the target image, otherwise, the creation will fail. The default + value is false. - - `disk_delete_with_instance` (string) - Whether or not the disk is released along with the instance: - - True indicates that when the instance is released, this disk will be released with it - - False indicates that when the instance is released, this disk will be retained. +- `image_force_delete_snapshots` (boolean) - If this value is true, when delete the + duplicated existing image, the source snapshot of this image will be delete + either. - - `disk_device` (string) - Device information of the related instance: such as - `/dev/xvdb` It is null unless the Status is In\_use. +- `image_share_account` (array of string) - The IDs of to-be-added Aliyun + accounts to which the image is shared. The number of accounts is 1 to 10. If + number of accounts is greater than 10, this parameter is ignored. -- `zone_id` (string) - ID of the zone to which the disk belongs. - -- `io_optimized` (boolean) - Whether an ECS instance is I/O optimized or not. - The default value is `false`. - -- `force_stop_instance` (boolean) - Whether to force shutdown upon device restart. - The default value is `false`. - - If it is set to `false`, the system is shut down normally; if it is set to - `true`, the system is forced to shut down. - -- `security_group_id` (string) - ID of the security group to which a newly - created instance belongs. Mutual access is allowed between instances in one - security group. If not specified, the newly created instance will be added to - the default security group. If the default group doesn’t exist, or the number - of instances in it has reached the maximum limit, a new security group will - be created automatically. - -- `security_group_name` (string) - The security group name. The default value is - blank. \[2, 128\] English or Chinese characters, must begin with an - uppercase/lowercase letter or Chinese character. Can contain numbers, `.`, - `_` or `-`. It cannot begin with `http://` or `https://`. - -- `user_data` (string) - The UserData of an instance must be encoded in `Base64` - format, and the maximum size of the raw data is `16 KB`. - -- `user_data_file` (string) - The file name of the userdata. - -- `vpc_id` (string) - VPC ID allocated by the system. - -- `vpc_name` (string) - The VPC name. The default value is blank. \[2, 128\] - English or Chinese characters, must begin with an uppercase/lowercase letter - or Chinese character. Can contain numbers, `_` and `-`. The disk description - will appear on the console. Cannot begin with `http://` or `https://`. - -- `vpc_cidr_block` (string) - Value options: `192.168.0.0/16` and `172.16.0.0/16`. - When not specified, the default value is `172.16.0.0/16`. - -- `vswitch_id` (string) - The ID of the VSwitch to be used. +- `image_version` (string) - The version number of the image, with a length limit + of 1 to 40 English characters. - `instance_name` (string) - Display name of the instance, which is a string of 2 to 128 Chinese or English characters. It must begin with an @@ -173,7 +136,6 @@ builder. For the regions out of China, currently only support `PayByTraffic`, you must set it manfully. - - `internet_max_bandwidth_out` (string) - Maximum outgoing bandwidth to the public network, measured in Mbps (Mega bit per second). @@ -181,16 +143,53 @@ builder. - PayByBandwidth: \[0, 100\]. If this parameter is not specified, API automatically sets it to 0 Mbps. - PayByTraffic: \[1, 100\]. If this parameter is not specified, an error is returned. -- `temporary_key_pair_name` (string) - The name of the temporary key pair to - generate. By default, Packer generates a name that looks like `packer_<UUID>`, - where `<UUID>` is a 36 character unique identifier. +- `io_optimized` (boolean) - Whether an ECS instance is I/O optimized or not. + The default value is `false`. + +- `security_group_id` (string) - ID of the security group to which a newly + created instance belongs. Mutual access is allowed between instances in one + security group. If not specified, the newly created instance will be added to + the default security group. If the default group doesn’t exist, or the number + of instances in it has reached the maximum limit, a new security group will + be created automatically. + +- `security_group_name` (string) - The security group name. The default value is + blank. \[2, 128\] English or Chinese characters, must begin with an + uppercase/lowercase letter or Chinese character. Can contain numbers, `.`, + `_` or `-`. It cannot begin with `http://` or `https://`. - `security_token` (string) - STS access token, can be set through template or by exporting as environment vairalbe such "export SecurityToken=value". +- `skip_region_validation` (boolean) - The region validation can be skipped if this + value is true, the default value is false. + +- `temporary_key_pair_name` (string) - The name of the temporary key pair to + generate. By default, Packer generates a name that looks like `packer_<UUID>`, + where `<UUID>` is a 36 character unique identifier. + - `TLSHandshakeTimeout` (int) - When happen "net/http: TLS handshake timeout" problem, set this environment variable to a bigger such as "export TLSHandshakeTimeout=30", it will set the TLS handshake timeout value to 30s. +- `user_data` (string) - The UserData of an instance must be encoded in `Base64` + format, and the maximum size of the raw data is `16 KB`. + +- `user_data_file` (string) - The file name of the userdata. + +- `vpc_cidr_block` (string) - Value options: `192.168.0.0/16` and `172.16.0.0/16`. + When not specified, the default value is `172.16.0.0/16`. + +- `vpc_id` (string) - VPC ID allocated by the system. + +- `vpc_name` (string) - The VPC name. The default value is blank. \[2, 128\] + English or Chinese characters, must begin with an uppercase/lowercase letter + or Chinese character. Can contain numbers, `_` and `-`. The disk description + will appear on the console. Cannot begin with `http://` or `https://`. + +- `vswitch_id` (string) - The ID of the VSwitch to be used. + +- `zone_id` (string) - ID of the zone to which the disk belongs. + ## Basic Example Here is a basic example for Alicloud. From 33c3d2885de042d027ec1460c4818aaa9a14fdcd Mon Sep 17 00:00:00 2001 From: jmajoor <jmajoor@sparklinglogic.com> Date: Mon, 26 Feb 2018 17:33:40 -0800 Subject: [PATCH 0689/1007] Add the additional disk steps to the Linux build --- builder/azure/arm/builder.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index 64d791ffa..f2bc66135 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -151,10 +151,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &packerCommon.StepProvision{}, NewStepGetOSDisk(azureClient, ui), + NewStepGetAdditionalDisks(azureClient, ui), NewStepPowerOffCompute(azureClient, ui), NewStepCaptureImage(azureClient, ui), NewStepDeleteResourceGroup(azureClient, ui), NewStepDeleteOSDisk(azureClient, ui), + NewStepDeleteAdditionalDisks(azureClient, ui), } } else if b.config.OSType == constants.Target_Windows { keyVaultDeploymentName := b.stateBag.Get(constants.ArmKeyVaultDeploymentName).(string) From 675dc0696782f4927f424c053ebe523b3db36581 Mon Sep 17 00:00:00 2001 From: jmajoor <jmajoor@sparklinglogic.com> Date: Mon, 26 Feb 2018 17:37:46 -0800 Subject: [PATCH 0690/1007] Tests for the optional disk_additional_size configuration. --- builder/azure/arm/config_test.go | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index 4cefd6730..d69c24a33 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -1057,6 +1057,46 @@ func TestConfigShouldRejectManagedDiskNames(t *testing.T) { } } +func TestConfigAdditionalDiskDefaultIsNil(t *testing.T) { + + c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration()) + if c.AdditionalDiskSize != nil { + t.Errorf("Expected Config to not have a set of additional disks, but got a non nil value") + } +} + +func TestConfigAdditionalDiskOverrideDefault(t *testing.T) { + config := map[string]string{ + "capture_name_prefix": "ignore", + "capture_container_name": "ignore", + "location": "ignore", + "image_url": "ignore", + "storage_account": "ignore", + "resource_group_name": "ignore", + "subscription_id": "ignore", + "os_type": constants.Target_Linux, + "communicator": "none", + } + + diskconfig := map[string][]int32{ + "disk_additional_size": {32, 64}, + } + + c, _, _ := newConfig(config, diskconfig, getPackerConfiguration()) + if c.AdditionalDiskSize == nil { + t.Errorf("Expected Config to have a set of additional disks, but got nil") + } + if len(c.AdditionalDiskSize) != 2 { + t.Errorf("Expected Config to have a 2 additional disks, but got %d additional disks", len(c.AdditionalDiskSize)) + } + if c.AdditionalDiskSize[0] != 32 { + t.Errorf("Expected Config to have the first additional disks of size 32Gb, but got %dGb", c.AdditionalDiskSize[0]) + } + if c.AdditionalDiskSize[1] != 64 { + t.Errorf("Expected Config to have the second additional disks of size 64Gb, but got %dGb", c.AdditionalDiskSize[1]) + } +} + func getArmBuilderConfiguration() map[string]string { m := make(map[string]string) for _, v := range requiredConfigValues { From 863f4ec1daaced25afdab7e217015601a276f692 Mon Sep 17 00:00:00 2001 From: jmajoor <jmajoor@sparklinglogic.com> Date: Mon, 26 Feb 2018 17:41:28 -0800 Subject: [PATCH 0691/1007] Add additional documentation for the additional disks configuration --- website/source/docs/builders/azure.html.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 71e8be385..b7d937acd 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -151,7 +151,11 @@ Providing `temp_resource_group_name` or `location` in combination with `build_re - `disk_additional_size` (array of integers) - The size(s) of any additional hard disks for the VM in gigabytes. If this is not specified then the VM - will only contain an OS disk. + will only contain an OS disk. The number of additional disks and maximum size of a disk depends on the configuration of your VM. See [Windows](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/about-disks-and-vhds) or [Linux](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/about-disks-and-vhds) for more information. + + For VHD builds the final artifacts will be named `PREFIX-dataDisk-<n>.UUID.vhd` and stored in the specified capture container along side the OS disk. The additional disks are included in the deployment template `PREFIX-vmTemplate.UUID`. + + For Managed build the final artifacts are included in the managed image. The additional disk will have the same storage account type as the OS disk, as specified with the `managed_image_storage_account_type` setting. - `os_type` (string) If either `Linux` or `Windows` is specified Packer will automatically configure authentication credentials for the provisioned machine. For From 686cacb4359da332341ac102db049641f2faee0e Mon Sep 17 00:00:00 2001 From: Less Mo <mqf@tradeshift.com> Date: Fri, 2 Mar 2018 16:34:19 +0800 Subject: [PATCH 0692/1007] builder/amazon: Added new region cn-northwest-1 Add new region China Ningxia cn-northwest-1. --- builder/amazon/common/regions.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/amazon/common/regions.go b/builder/amazon/common/regions.go index 9b4492459..66b0c490e 100644 --- a/builder/amazon/common/regions.go +++ b/builder/amazon/common/regions.go @@ -21,6 +21,7 @@ func listEC2Regions() []string { // not part of autogenerated list "us-gov-west-1", "cn-north-1", + "cn-northwest-1", } } From 2e174220d80e665cde0929f3445a688d65f693ff Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Sat, 3 Mar 2018 00:14:35 -0800 Subject: [PATCH 0693/1007] azure: remove azure-merge.sh This script was used to import the Azure builder source code, and it is no longer necessary. --- azure-merge.sh | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100755 azure-merge.sh diff --git a/azure-merge.sh b/azure-merge.sh deleted file mode 100755 index 07c79b8b3..000000000 --- a/azure-merge.sh +++ /dev/null @@ -1,18 +0,0 @@ -PACKER=$GOPATH/src/github.com/mitchellh/packer -AZURE=/tmp/packer-azure - -ls $AZURE >/dev/null || git clone https://github.com/Azure/packer-azure /tmp/packer-azure -PWD=`pwd` -cd $AZURE && git pull -cd $PWD - -# copy things -cp -r $AZURE/packer/builder/azure $PACKER/builder/ -cp -r $AZURE/packer/communicator/* $PACKER/communicator/ -cp -r $AZURE/packer/provisioner/azureVmCustomScriptExtension $PACKER/provisioner/ - -# remove legacy API client -rm -rf $PACKER/builder/azure/smapi - -# fix imports -find $PACKER/builder/azure/ -type f | grep ".go" | xargs sed -e 's/Azure\/packer-azure\/packer\/builder\/azure/mitchellh\/packer\/builder\/azure/g' -i '' From 00ed312e047f311cddc5c0e1f315def50b8fba76 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Sat, 3 Mar 2018 08:46:22 +0000 Subject: [PATCH 0694/1007] azure: fix commands, improve UX --- contrib/azure-setup.sh | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 105cea88c..ef855b353 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -49,7 +49,7 @@ showhelp() { requirements() { found=0 - azureversion=$(az -v) + azureversion=$(az --version) if [ $? -eq 0 ]; then found=$((found + 1)) echo "Found azure-cli version: $azureversion" @@ -74,7 +74,7 @@ requirements() { } askSubscription() { - az account list + az account list -otable echo "" echo "Please enter the Id of the account you wish to use. If you do not see" echo "a valid account in the list press Ctrl+C to abort and create one." @@ -120,7 +120,7 @@ askSecret() { } askLocation() { - az account list-locations + az account list-locations -otable echo "" echo "Choose which region your resource group and storage account will be created. example: westus" echo -n "> " @@ -140,7 +140,7 @@ createResourceGroup() { createStorageAccount() { echo "==> Creating storage account" - az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage + az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage --sku Standard_LRS if [ $? -eq 0 ]; then azure_storage_name=$meta_name else @@ -170,21 +170,8 @@ createApplication() { createServicePrincipal() { echo "==> Creating service principal" - # Azure CLI 0.10.2 introduced a breaking change, where appId must be supplied with the -a switch - # prior version accepted appId as the only parameter without a switch - newer_syntax=false - IFS='.' read -ra azureversionsemver <<< "$azureversion" - if [ ${azureversionsemver[0]} -ge 0 ] && [ ${azureversionsemver[1]} -ge 10 ] && [ ${azureversionsemver[2]} -ge 2 ]; then - newer_syntax=true - fi - - if [ "${newer_syntax}" = true ]; then - azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) - echo $azure_object_id "was selected." - else - azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) - echo $azure_object_id "was selected." - fi + azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) + echo $azure_object_id "was selected." if [ $? -ne 0 ]; then echo "Error creating service principal: $azure_client_id" @@ -195,8 +182,9 @@ createServicePrincipal() { createPermissions() { echo "==> Creating permissions" az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id - # We want to use this more conservative scope but it does not work with the - # current implementation which uses temporary resource groups + # If the user wants to use a more conserative scope, she can. She must + # configure the Azure builder to use build_resource_group_name. The + # easiest solution is subscription wide permission. # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" if [ $? -ne 0 ]; then echo "Error creating permissions for: http://$meta_name" From e0ac07f5db87559326151cc84d323c13a7c7f7c5 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Sat, 3 Mar 2018 08:53:10 +0000 Subject: [PATCH 0695/1007] azure: correct function name spelling --- builder/azure/arm/artifact.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/azure/arm/artifact.go b/builder/azure/arm/artifact.go index c2abcc4d5..8e42fa43d 100644 --- a/builder/azure/arm/artifact.go +++ b/builder/azure/arm/artifact.go @@ -113,7 +113,7 @@ func storageUriToTemplateUri(su *url.URL) (*url.URL, error) { return url.Parse(strings.Replace(su.String(), filename, templateFilename, 1)) } -func (a *Artifact) isMangedImage() bool { +func (a *Artifact) isManagedImage() bool { return a.ManagedImageResourceGroupName != "" } @@ -142,7 +142,7 @@ func (a *Artifact) String() string { var buf bytes.Buffer buf.WriteString(fmt.Sprintf("%s:\n\n", a.BuilderId())) - if a.isMangedImage() { + if a.isManagedImage() { buf.WriteString(fmt.Sprintf("ManagedImageResourceGroupName: %s\n", a.ManagedImageResourceGroupName)) buf.WriteString(fmt.Sprintf("ManagedImageName: %s\n", a.ManagedImageName)) buf.WriteString(fmt.Sprintf("ManagedImageLocation: %s\n", a.ManagedImageLocation)) From 8166ba2d8dda96bd3b3e53b114e48de32d8976f6 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Sun, 4 Mar 2018 21:21:02 -0800 Subject: [PATCH 0696/1007] azure: better error message --- builder/azure/arm/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index afa5f62a7..8b879f93e 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -604,7 +604,7 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { } if !xor(c.Location != "", c.BuildResourceGroupName != "") { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Must specify either a location to create the resource group in or an existing build_resource_group_name.")) + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Specify either a location to create the resource group in or an existing build_resource_group_name, but not both.")) } if c.ManagedImageName == "" && c.ManagedImageResourceGroupName == "" { From 676fb590901c7445198f83da458a9afa2ef87bd5 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Mon, 5 Mar 2018 01:58:30 -0800 Subject: [PATCH 0697/1007] Better override support for PS build script Developers can now independently controls XC_OS and XC_ARCH. --- scripts/build.ps1 | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 5603ea078..972dcd414 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -53,10 +53,18 @@ if ($LastExitCode -eq 0) { if (Test-Path env:PACKER_DEV) { $XC_OS=$(go.exe env GOOS) $XC_ARCH=$(go.exe env GOARCH) -} -elseif (-not (Test-Path env:XC_ARCH)) { - $XC_ARCH="386 amd64 arm arm64 ppc64le" - $XC_OS="linux darwin windows freebsd openbsd solaris" +} else { + if (Test-Path env:XC_ARCH) { + $XC_ARCH = $(Get-Content env:XC_ARCH) + } else { + $XC_ARCH="386 amd64 arm arm64 ppc64le" + } + + if (Test-Path env:XC_OS) { + $XC_OS = $(Get-Content env:XC_OS) + } else { + $XC_OS = "linux darwin windows freebsd openbsd solaris" + } } # Delete the old dir From d2e593de378e24b476482bfe1ca61594d30f4391 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Mon, 5 Mar 2018 01:27:52 -0800 Subject: [PATCH 0698/1007] azure: support for marketplace plan information --- builder/azure/arm/config.go | 14 ++ builder/azure/arm/config_test.go | 51 ++++++ builder/azure/arm/template_factory.go | 4 + ..._factory_test.TestPlanInfo01.approved.json | 170 +++++++++++++++++ ..._factory_test.TestPlanInfo02.approved.json | 171 ++++++++++++++++++ builder/azure/arm/template_factory_test.go | 39 ++++ builder/azure/common/template/template.go | 8 + .../azure/common/template/template_builder.go | 31 ++++ website/source/docs/builders/azure.html.md | 11 ++ 9 files changed, 499 insertions(+) create mode 100644 builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json create mode 100644 builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index afa5f62a7..e8ed6bd81 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -115,6 +115,12 @@ type Config struct { // Additional Disks AdditionalDiskSize []int32 `mapstructure:"disk_additional_size"` + // Plan Info + PlanName string `mapstructure:"plan_name"` + PlanProduct string `mapstructure:"plan_product"` + PlanPublisher string `mapstructure:"plan_publisher"` + PlanPromotionCode string `mapstructure:"plan_promotion_code"` + // Runtime Values UserName string Password string @@ -647,6 +653,14 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("If virtual_network_subnet_name is specified, so must virtual_network_name")) } + ///////////////////////////////////////////// + // Plan Info + if c.PlanName != "" || c.PlanProduct != "" || c.PlanPublisher != "" || c.PlanPromotionCode != "" { + if c.PlanName == "" || c.PlanProduct == "" || c.PlanPublisher == "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("if either plan_name, plan_product, plan_publisher, or plan_promotion_code are defined then plan_name, plan_product, and plan_publisher must be defined")) + } + } + ///////////////////////////////////////////// // OS if strings.EqualFold(c.OSType, constants.Target_Linux) { diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index d69c24a33..b56a260e3 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -1097,6 +1097,57 @@ func TestConfigAdditionalDiskOverrideDefault(t *testing.T) { } } +// Test that configuration handles plan info +// +// The use of plan info requires that the following three properties are set. +// +// 1. plan_name +// 2. plan_product +// 3. plan_publisher +func TestPlanInfoConfiguration(t *testing.T) { + config := map[string]interface{}{ + "capture_name_prefix": "ignore", + "capture_container_name": "ignore", + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "storage_account": "ignore", + "resource_group_name": "ignore", + "subscription_id": "ignore", + "os_type": "linux", + "communicator": "none", + } + + config["plan_name"] = "--plan-name--" + _, _, err := newConfig(config, getPackerConfiguration()) + if err == nil { + t.Fatal("expected config to reject the use of plan_name without plan_product and plan_publisher") + } + + config["plan_product"] = "--plan-product--" + _, _, err = newConfig(config, getPackerConfiguration()) + if err == nil { + t.Fatal("expected config to reject the use of plan_name and plan_product without plan_publisher") + } + + config["plan_publisher"] = "--plan-publisher--" + c, _, err := newConfig(config, getPackerConfiguration()) + if err != nil { + t.Fatalf("expected config to accept a complete plan configuration: %s", err) + } + + if c.PlanName != "--plan-name--" { + t.Fatalf("Expected PlanName to be '--plan-name--', but got %q", c.PlanName) + } + if c.PlanProduct != "--plan-product--" { + t.Fatalf("Expected PlanProduct to be '--plan-product--', but got %q", c.PlanProduct) + } + if c.PlanPublisher != "--plan-publisher--" { + t.Fatalf("Expected PlanPublisher to be '--plan-publisher--, but got %q", c.PlanPublisher) + } +} + func getArmBuilderConfiguration() map[string]string { m := make(map[string]string) for _, v := range requiredConfigValues { diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index ebc7ef91c..a68b13f22 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -81,6 +81,10 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error) builder.SetCustomData(config.customData) } + if config.PlanName != "" { + builder.SetPlanInfo(config.PlanName, config.PlanProduct, config.PlanPublisher, config.PlanPromotionCode) + } + if config.VirtualNetworkName != "" && DefaultPrivateVirtualNetworkWithPublicIp != config.PrivateVirtualNetworkWithPublicIp { builder.SetPrivateVirtualNetworWithPublicIp( config.VirtualNetworkResourceGroupName, diff --git a/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json b/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json new file mode 100644 index 000000000..9af488f98 --- /dev/null +++ b/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json @@ -0,0 +1,170 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "plan": { + "name": "planName00", + "product": "planProduct00", + "publisher": "planPublisher00" + }, + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "offer": "ignored00", + "publisher": "ignored00", + "sku": "ignored00", + "version": "latest" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "nicName": "packerNic", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json b/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json new file mode 100644 index 000000000..3cd802107 --- /dev/null +++ b/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json @@ -0,0 +1,171 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('publicIPAddressApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('virtualNetworksApiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('networkInterfacesApiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "plan": { + "name": "planName00", + "product": "planProduct00", + "promotionCode": "planPromotionCode00", + "publisher": "planPublisher00" + }, + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "offer": "ignored00", + "publisher": "ignored00", + "sku": "ignored00", + "version": "latest" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2017-03-30", + "location": "[resourceGroup().location]", + "managedDiskApiVersion": "2017-03-30", + "networkInterfacesApiVersion": "2017-04-01", + "nicName": "packerNic", + "publicIPAddressApiVersion": "2017-04-01", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworksApiVersion": "2017-04-01", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } +} \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.go b/builder/azure/arm/template_factory_test.go index 7909a0cee..292c56389 100644 --- a/builder/azure/arm/template_factory_test.go +++ b/builder/azure/arm/template_factory_test.go @@ -523,3 +523,42 @@ func TestKeyVaultDeployment03(t *testing.T) { t.Fatal(err) } } + +func TestPlanInfo01(t *testing.T) { + planInfo := map[string]interface{}{ + "plan_name": "planName00", + "plan_product": "planProduct00", + "plan_publisher": "planPublisher00", + } + + c, _, _ := newConfig(planInfo, getArmBuilderConfiguration(), getPackerConfiguration()) + deployment, err := GetVirtualMachineDeployment(c) + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) + if err != nil { + t.Fatal(err) + } +} + +func TestPlanInfo02(t *testing.T) { + planInfo := map[string]interface{}{ + "plan_name": "planName00", + "plan_product": "planProduct00", + "plan_publisher": "planPublisher00", + "plan_promotion_code": "planPromotionCode00", + } + + c, _, _ := newConfig(planInfo, getArmBuilderConfiguration(), getPackerConfiguration()) + deployment, err := GetVirtualMachineDeployment(c) + if err != nil { + t.Fatal(err) + } + + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) + if err != nil { + t.Fatal(err) + } +} diff --git a/builder/azure/common/template/template.go b/builder/azure/common/template/template.go index 070ca3392..d6273fa46 100644 --- a/builder/azure/common/template/template.go +++ b/builder/azure/common/template/template.go @@ -30,11 +30,19 @@ type Resource struct { Type *string `json:"type"` Location *string `json:"location,omitempty"` DependsOn *[]string `json:"dependsOn,omitempty"` + Plan *Plan `json:"plan,omitempty"` Properties *Properties `json:"properties,omitempty"` Tags *map[string]*string `json:"tags,omitempty"` Resources *[]Resource `json:"resources,omitempty"` } +type Plan struct { + Name *string `json:"name"` + Product *string `json:"product"` + Publisher *string `json:"publisher"` + PromotionCode *string `json:"promotionCode,omitempty"` +} + type OSDiskUnion struct { OsType compute.OperatingSystemTypes `json:"osType,omitempty"` OsState compute.OperatingSystemStateTypes `json:"osState,omitempty"` diff --git a/builder/azure/common/template/template_builder.go b/builder/azure/common/template/template_builder.go index 835aff096..a05b66ab3 100644 --- a/builder/azure/common/template/template_builder.go +++ b/builder/azure/common/template/template_builder.go @@ -179,6 +179,26 @@ func (s *TemplateBuilder) SetImageUrl(imageUrl string, osType compute.OperatingS return nil } +func (s *TemplateBuilder) SetPlanInfo(name, product, publisher, promotionCode string) error { + var promotionCodeVal *string = nil + if promotionCode != "" { + promotionCodeVal = to.StringPtr(promotionCode) + } + + for i, x := range *s.template.Resources { + if strings.EqualFold(*x.Type, resourceVirtualMachine) { + (*s.template.Resources)[i].Plan = &Plan{ + Name: to.StringPtr(name), + Product: to.StringPtr(product), + Publisher: to.StringPtr(publisher), + PromotionCode: promotionCodeVal, + } + } + } + + return nil +} + func (s *TemplateBuilder) SetOSDiskSizeGB(diskSizeGB int32) error { resource, err := s.getResourceByType(resourceVirtualMachine) if err != nil { @@ -302,6 +322,17 @@ func (s *TemplateBuilder) getResourceByType(t string) (*Resource, error) { return nil, fmt.Errorf("template: could not find a resource of type %s", t) } +func (s *TemplateBuilder) getResourceByType2(t string) (**Resource, error) { + for _, x := range *s.template.Resources { + if strings.EqualFold(*x.Type, t) { + p := &x + return &p, nil + } + } + + return nil, fmt.Errorf("template: could not find a resource of type %s", t) +} + func (s *TemplateBuilder) setVariable(name string, value string) { (*s.template.Variables)[name] = value } diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index b7d937acd..94e0d0a0c 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -162,6 +162,17 @@ Providing `temp_resource_group_name` or `location` in combination with `build_re `Linux` this configures an SSH authorized key. For `Windows` this configures a WinRM certificate. +- `plan_name` (string) The plan name. This setting (`plan_product`, `plan_publisher`, and `plan_promotion_code`) are + only needed for Marketplace images. Please refer to [Deploy an image with Marketplace terms](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-ps-findimage#deploy-an-image-with-marketplace-terms) for more details. + +- `plan_product` (string) The plan product. See `plan_name` for more information. + +- `plan_publisher` (string) Specifies the produce of the image from the Marketplace. This value is the same value as + Offer (`image_offer`). See `plan_name` for more information. + +- `plan_promotion_code` (string) Some Marketplace images use a promotion code. See `plan_name` for more + information. + - `temp_compute_name` (string) temporary name assigned to the VM. If this value is not set, a random value will be assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer build, e.g. attach a resource disk to the VM. From df6cdcc7f7e123b122b94b191f800a098f6fbf6e Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Mon, 5 Mar 2018 20:58:43 -0600 Subject: [PATCH 0699/1007] Disable the usage of the XHCI bus for USB on the vmware-iso builder. Some platforms with incomplete XHCI implementations (i.e. FreeBSD) will poll the bus despite there being no usb devices available. This disables XHCI by default and documents how to enable it using the vmx_data option. This closes issue #5961. --- builder/vmware/iso/step_create_vmx.go | 1 - website/source/docs/builders/vmware-iso.html.md | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index ca5fe7bbe..ffeb724ec 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -716,7 +716,6 @@ tools.upgrade.policy = "upgradeAtPowerCycle" // USB usb.pciSlotNumber = "32" usb.present = "{{ .Usb_Present }}" -usb_xhci.present = "TRUE" // Serial serial0.present = "{{ .Serial_Present }}" diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 7784ac439..86d79e93b 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -357,7 +357,9 @@ builder. By default the upload path is set to `{{.Flavor}}.iso`. This setting is not used when `remote_type` is "esx5". -- `usb` (boolean) - Enable VMware's USB bus for the VM. +- `usb` (boolean) - Enable VMware's USB bus for the guest VM. To enable usage + of the XHCI bus for USB 3 (5 Gbit/s), one can use the `vmx_data` option to + enable it by specifying "true" for the `usb_xhci.present` property. - `version` (string) - The [vmx hardware version](http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1003746) From ac2e02b938e3913a98c6f66b620b4ad53e889496 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 6 Mar 2018 14:12:39 -0800 Subject: [PATCH 0700/1007] remove loglines that should not have made it onto master --- builder/vmware/common/driver.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index c8fea88f4..8fa185efd 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -309,14 +309,12 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // grab network mapper netmap, err := d.NetworkMapper() - log.Printf("MEGAN: NEtworkMapper is %#v", netmap) if err != nil { return "", err } // convert the stashed network to a device network := state.Get("vmnetwork").(string) - log.Printf("MEGAN: network is %#v", network) device, err := netmap.NameIntoDevice(network) // we were unable to find the device, maybe it's a custom one... @@ -339,7 +337,6 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { if err != nil { return "", err } - log.Printf("MEGAN mac address is %s", MACAddress) // figure out the correct dhcp leases dhcpLeasesPath := d.DhcpLeasesPath(device) From edd9df14ed6f34c7c032dc6f667c87612ce79f0b Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Tue, 6 Mar 2018 19:05:39 -0500 Subject: [PATCH 0701/1007] prepend 'Packer' with 'HashiCorp' on first instance --- website/source/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/index.html.erb b/website/source/index.html.erb index 61990b4ba..18222370b 100644 --- a/website/source/index.html.erb +++ b/website/source/index.html.erb @@ -59,7 +59,7 @@ description: |- <span class="callout">Infrastructure as code</span> <h2>Modern, Automated</h2> <p> - Packer is easy to use and automates the creation of any type of + HashiCorp Packer is easy to use and automates the creation of any type of machine image. It embraces modern configuration management by encouraging you to use automated scripts to install and configure the software within your Packer-made images. Packer brings machine From 5132b684b20cf920b9525cd9f2ff354a8184fc15 Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Tue, 6 Mar 2018 19:06:05 -0500 Subject: [PATCH 0702/1007] update dependencies + middleman-hashicorp --- website/Gemfile | 2 +- website/Gemfile.lock | 42 +++++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/website/Gemfile b/website/Gemfile index bb10a536e..d21d35e45 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.29" +gem "middleman-hashicorp", "0.3.30" diff --git a/website/Gemfile.lock b/website/Gemfile.lock index acf65a9ef..e567bf2ed 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -6,7 +6,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (7.1.5) + autoprefixer-rails (8.1.0) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -18,7 +18,7 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - chunky_png (1.3.8) + chunky_png (1.3.10) coffee-script (2.4.1) coffee-script-source execjs @@ -41,7 +41,7 @@ GEM erubis (2.7.0) eventmachine (1.2.5) execjs (2.7.0) - ffi (1.9.18) + ffi (1.9.23) haml (5.0.4) temple (>= 0.8.0) tilt @@ -51,7 +51,7 @@ GEM http_parser.rb (0.6.0) i18n (0.7.0) json (2.1.0) - kramdown (1.15.0) + kramdown (1.16.2) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -78,7 +78,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.29) + middleman-hashicorp (0.3.30) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -102,22 +102,22 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mini_portile2 (2.3.0) - minitest (5.10.3) - multi_json (1.12.2) - nokogiri (1.8.1) + minitest (5.11.3) + multi_json (1.13.1) + nokogiri (1.8.2) mini_portile2 (~> 2.3.0) - padrino-helpers (0.12.8.1) + padrino-helpers (0.12.9) i18n (~> 0.6, >= 0.6.7) - padrino-support (= 0.12.8.1) - tilt (~> 1.4.1) - padrino-support (0.12.8.1) + padrino-support (= 0.12.9) + tilt (>= 1.4.1, < 3) + padrino-support (0.12.9) activesupport (>= 3.1) - rack (1.6.8) + rack (1.6.9) rack-livereload (0.3.16) rack - rack-test (0.7.0) + rack-test (0.8.3) rack (>= 1.0, < 3) - rb-fsevent (0.10.2) + rb-fsevent (0.10.3) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) redcarpet (3.4.0) @@ -137,10 +137,10 @@ GEM thor (0.20.0) thread_safe (0.3.6) tilt (1.4.1) - turbolinks (5.0.1) - turbolinks-source (~> 5) - turbolinks-source (5.0.3) - tzinfo (1.2.3) + turbolinks (5.1.0) + turbolinks-source (~> 5.1) + turbolinks-source (5.1.0) + tzinfo (1.2.5) thread_safe (~> 0.1) uber (0.0.15) uglifier (2.7.2) @@ -153,7 +153,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.29) + middleman-hashicorp (= 0.3.30) BUNDLED WITH - 1.15.4 + 1.16.1 From ff92fb883d3cbcccb42036645c6f732b7de69b59 Mon Sep 17 00:00:00 2001 From: Andreas Sommer <andreas.sommer87@googlemail.com> Date: Wed, 7 Mar 2018 10:59:55 +0100 Subject: [PATCH 0703/1007] Handle multiple devices per VMware network type Fixes #5979 --- builder/vmware/common/driver.go | 239 ++++++++++++++----------- builder/vmware/common/driver_mock.go | 4 +- builder/vmware/common/driver_parser.go | 31 ++-- builder/vmware/iso/step_create_vmx.go | 15 +- 4 files changed, 162 insertions(+), 127 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 8fa185efd..47dc6e8b6 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -315,7 +315,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // convert the stashed network to a device network := state.Get("vmnetwork").(string) - device, err := netmap.NameIntoDevice(network) + devices, err := netmap.NameIntoDevices(network) // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration @@ -326,7 +326,9 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { return "", err } + var device string device, err = readCustomDeviceName(vmxData) + devices = append(devices, device) if err != nil { return "", err } @@ -338,64 +340,67 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { return "", err } - // figure out the correct dhcp leases - dhcpLeasesPath := d.DhcpLeasesPath(device) - log.Printf("DHCP leases path: %s", dhcpLeasesPath) - if dhcpLeasesPath == "" { - return "", errors.New("no DHCP leases path found.") - } - - // open up the lease and read its contents - fh, err := os.Open(dhcpLeasesPath) - if err != nil { - return "", err - } - defer fh.Close() - - dhcpBytes, err := ioutil.ReadAll(fh) - if err != nil { - return "", err - } - - // start grepping through the file looking for fields that we care about - var lastIp string - var lastLeaseEnd time.Time - - var curIp string - var curLeaseEnd time.Time - - ipLineRe := regexp.MustCompile(`^lease (.+?) {$`) - endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`) - macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) - - for _, line := range strings.Split(string(dhcpBytes), "\n") { - // Need to trim off CR character when running in windows - line = strings.TrimRight(line, "\r") - - matches := ipLineRe.FindStringSubmatch(line) - if matches != nil { - lastIp = matches[1] - continue + for _, device := range devices { + // figure out the correct dhcp leases + dhcpLeasesPath := d.DhcpLeasesPath(device) + log.Printf("Trying DHCP leases path: %s", dhcpLeasesPath) + if dhcpLeasesPath == "" { + return "", fmt.Errorf("no DHCP leases path found for device %s", device) } - matches = endTimeLineRe.FindStringSubmatch(line) - if matches != nil { - lastLeaseEnd, _ = time.Parse("2006/01/02 15:04:05", matches[1]) - continue + // open up the lease and read its contents + fh, err := os.Open(dhcpLeasesPath) + if err != nil { + return "", err + } + defer fh.Close() + + dhcpBytes, err := ioutil.ReadAll(fh) + if err != nil { + return "", err } - // If the mac address matches and this lease ends farther in the - // future than the last match we might have, then choose it. - matches = macLineRe.FindStringSubmatch(line) - if matches != nil && strings.EqualFold(matches[1], MACAddress) && curLeaseEnd.Before(lastLeaseEnd) { - curIp = lastIp - curLeaseEnd = lastLeaseEnd + // start grepping through the file looking for fields that we care about + var lastIp string + var lastLeaseEnd time.Time + + var curIp string + var curLeaseEnd time.Time + + ipLineRe := regexp.MustCompile(`^lease (.+?) {$`) + endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`) + macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`) + + for _, line := range strings.Split(string(dhcpBytes), "\n") { + // Need to trim off CR character when running in windows + line = strings.TrimRight(line, "\r") + + matches := ipLineRe.FindStringSubmatch(line) + if matches != nil { + lastIp = matches[1] + continue + } + + matches = endTimeLineRe.FindStringSubmatch(line) + if matches != nil { + lastLeaseEnd, _ = time.Parse("2006/01/02 15:04:05", matches[1]) + continue + } + + // If the mac address matches and this lease ends farther in the + // future than the last match we might have, then choose it. + matches = macLineRe.FindStringSubmatch(line) + if matches != nil && strings.EqualFold(matches[1], MACAddress) && curLeaseEnd.Before(lastLeaseEnd) { + curIp = lastIp + curLeaseEnd = lastLeaseEnd + } + } + if curIp != "" { + return curIp, nil } } - if curIp == "" { - return "", fmt.Errorf("IP not found for MAC %s in DHCP leases at %s", MACAddress, dhcpLeasesPath) - } - return curIp, nil + + return "", fmt.Errorf("None of the found device(s) %v has a DHCP lease for MAC %s", devices, MACAddress) } func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { @@ -408,7 +413,7 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { // convert network to name network := state.Get("vmnetwork").(string) - device, err := netmap.NameIntoDevice(network) + devices, err := netmap.NameIntoDevices(network) // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration @@ -419,49 +424,56 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { return "", err } + var device string device, err = readCustomDeviceName(vmxData) + devices = append(devices, device) if err != nil { return "", err } } - // parse dhcpd configuration - pathDhcpConfig := d.DhcpConfPath(device) - if _, err := os.Stat(pathDhcpConfig); err != nil { - return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) - } - - config, err := ReadDhcpConfig(pathDhcpConfig) - if err != nil { - return "", err - } - - // find the entry configured in the dhcpd - interfaceConfig, err := config.HostByName(device) - if err != nil { - return "", err - } - - // finally grab the hardware address - address, err := interfaceConfig.Hardware() - if err == nil { - return address.String(), nil - } - - // we didn't find it, so search through our interfaces for the device name - interfaceList, err := net.Interfaces() - if err == nil { - return "", err - } - - names := make([]string, 0) - for _, intf := range interfaceList { - if strings.HasSuffix(strings.ToLower(intf.Name), device) { - return intf.HardwareAddr.String(), nil + var lastError error + for _, device := range devices { + // parse dhcpd configuration + pathDhcpConfig := d.DhcpConfPath(device) + if _, err := os.Stat(pathDhcpConfig); err != nil { + return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) + } + + config, err := ReadDhcpConfig(pathDhcpConfig) + if err != nil { + lastError = err + continue + } + + // find the entry configured in the dhcpd + interfaceConfig, err := config.HostByName(device) + if err != nil { + lastError = err + continue + } + + // finally grab the hardware address + address, err := interfaceConfig.Hardware() + if err == nil { + return address.String(), nil + } + + // we didn't find it, so search through our interfaces for the device name + interfaceList, err := net.Interfaces() + if err == nil { + return "", err + } + + names := make([]string, 0) + for _, intf := range interfaceList { + if strings.HasSuffix(strings.ToLower(intf.Name), device) { + return intf.HardwareAddr.String(), nil + } + names = append(names, intf.Name) } - names = append(names, intf.Name) } - return "", fmt.Errorf("Unable to find device %s : %v", device, names) + return "", fmt.Errorf("Unable to find host address from devices %v, last error: %s", devices, lastError) } func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { @@ -474,7 +486,7 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { // convert network to name network := state.Get("vmnetwork").(string) - device, err := netmap.NameIntoDevice(network) + devices, err := netmap.NameIntoDevices(network) // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration @@ -485,32 +497,41 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { return "", err } + var device string device, err = readCustomDeviceName(vmxData) + devices = append(devices, device) if err != nil { return "", err } } - // parse dhcpd configuration - pathDhcpConfig := d.DhcpConfPath(device) - if _, err := os.Stat(pathDhcpConfig); err != nil { - return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) - } - config, err := ReadDhcpConfig(pathDhcpConfig) - if err != nil { - return "", err - } + var lastError error + for _, device := range devices { + // parse dhcpd configuration + pathDhcpConfig := d.DhcpConfPath(device) + if _, err := os.Stat(pathDhcpConfig); err != nil { + return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig) + } + config, err := ReadDhcpConfig(pathDhcpConfig) + if err != nil { + lastError = err + continue + } - // find the entry configured in the dhcpd - interfaceConfig, err := config.HostByName(device) - if err != nil { - return "", err - } + // find the entry configured in the dhcpd + interfaceConfig, err := config.HostByName(device) + if err != nil { + lastError = err + continue + } - address, err := interfaceConfig.IP4() - if err != nil { - return "", err - } + address, err := interfaceConfig.IP4() + if err != nil { + lastError = err + continue + } - return address.String(), nil + return address.String(), nil + } + return "", fmt.Errorf("Unable to find host IP from devices %v, last error: %s", devices, lastError) } diff --git a/builder/vmware/common/driver_mock.go b/builder/vmware/common/driver_mock.go index a0955db88..8c540913e 100644 --- a/builder/vmware/common/driver_mock.go +++ b/builder/vmware/common/driver_mock.go @@ -98,9 +98,9 @@ type NetworkMapperMock struct { DeviceIntoNameCalled int } -func (m NetworkMapperMock) NameIntoDevice(name string) (string, error) { +func (m NetworkMapperMock) NameIntoDevices(name string) ([]string, error) { m.NameIntoDeviceCalled += 1 - return "", nil + return make([]string, 0), nil } func (m NetworkMapperMock) DeviceIntoName(device string) (string, error) { m.DeviceIntoNameCalled += 1 diff --git a/builder/vmware/common/driver_parser.go b/builder/vmware/common/driver_parser.go index 24ecaf0df..fc54b8221 100644 --- a/builder/vmware/common/driver_parser.go +++ b/builder/vmware/common/driver_parser.go @@ -1065,7 +1065,7 @@ func (e *DhcpConfiguration) HostByName(host string) (configDeclaration, error) { type NetworkMap []map[string]string type NetworkNameMapper interface { - NameIntoDevice(string) (string, error) + NameIntoDevices(string) ([]string, error) DeviceIntoName(string) (string, error) } @@ -1082,13 +1082,17 @@ func ReadNetworkMap(fd *os.File) (NetworkMap, error) { return result, nil } -func (e NetworkMap) NameIntoDevice(name string) (string, error) { +func (e NetworkMap) NameIntoDevices(name string) ([]string, error) { + var devices []string for _, val := range e { if strings.ToLower(val["name"]) == strings.ToLower(name) { - return val["device"], nil + devices = append(devices, val["device"]) } } - return "", fmt.Errorf("Network name not found : %v", name) + if len(devices) > 0 { + return devices, nil + } + return make([]string, 0), fmt.Errorf("Network name not found : %v", name) } func (e NetworkMap) DeviceIntoName(device string) (string, error) { for _, val := range e { @@ -1905,21 +1909,26 @@ func networkingConfig_NamesToVmnet(config NetworkingConfig) map[NetworkingType][ const NetworkingInterfacePrefix = "vmnet" -func (e NetworkingConfig) NameIntoDevice(name string) (string, error) { +func (e NetworkingConfig) NameIntoDevices(name string) ([]string, error) { netmapper := networkingConfig_NamesToVmnet(e) name = strings.ToLower(name) - var vmnet int + var vmnets []string + var networkingType NetworkingType if name == "hostonly" && len(netmapper[NetworkingType_HOSTONLY]) > 0 { - vmnet = netmapper[NetworkingType_HOSTONLY][0] + networkingType = NetworkingType_HOSTONLY } else if name == "nat" && len(netmapper[NetworkingType_NAT]) > 0 { - vmnet = netmapper[NetworkingType_NAT][0] + networkingType = NetworkingType_NAT } else if name == "bridged" && len(netmapper[NetworkingType_BRIDGED]) > 0 { - vmnet = netmapper[NetworkingType_BRIDGED][0] + networkingType = NetworkingType_BRIDGED } else { - return "", fmt.Errorf("Network name not found : %v", name) + return make([]string, 0), fmt.Errorf("Network name not found: %v", name) } - return fmt.Sprintf("%s%d", NetworkingInterfacePrefix, vmnet), nil + + for i := 0; i < len(netmapper[networkingType]); i++ { + vmnets = append(vmnets, fmt.Sprintf("%s%d", NetworkingInterfacePrefix, netmapper[networkingType][i])) + } + return vmnets, nil } func (e NetworkingConfig) DeviceIntoName(device string) (string, error) { diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index ffeb724ec..7dbb01b79 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -475,14 +475,19 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } // try and convert the specified network to a device. - device, err := netmap.NameIntoDevice(network) + devices, err := netmap.NameIntoDevices(network) - if err == nil { - // success. so we know that it's an actual network type inside netmap.conf + if err == nil && len(devices) > 0 { + // If multiple devices exist, for example for network "nat", VMware chooses + // the actual device. Only type "custom" allows the exact choice of a + // specific virtual network (see below). We allow VMware to choose the device + // and for device-specific operations like GuestIP, try to go over all + // devices that match a name (e.g. "nat"). + // https://pubs.vmware.com/workstation-9/index.jsp?topic=%2Fcom.vmware.ws.using.doc%2FGUID-3B504F2F-7A0B-415F-AE01-62363A95D052.html templateData.Network_Type = network - templateData.Network_Device = device + templateData.Network_Device = "" } else { - // otherwise, we were unable to find the type, so assume its a custom device. + // otherwise, we were unable to find the type, so assume it's a custom device templateData.Network_Type = "custom" templateData.Network_Device = network } From 91d60d6b8197c4cb9cdcaad800d2848e8191614d Mon Sep 17 00:00:00 2001 From: Graham Hayes <gr@ham.ie> Date: Tue, 6 Mar 2018 20:02:19 +0000 Subject: [PATCH 0704/1007] Add LXC to vagrant post-processor --- post-processor/vagrant/lxc.go | 34 +++++++++++++++++++ post-processor/vagrant/lxc_test.go | 9 +++++ post-processor/vagrant/post-processor.go | 3 ++ .../docs/post-processors/vagrant.html.md | 15 ++++++-- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 post-processor/vagrant/lxc.go create mode 100644 post-processor/vagrant/lxc_test.go diff --git a/post-processor/vagrant/lxc.go b/post-processor/vagrant/lxc.go new file mode 100644 index 000000000..771df9509 --- /dev/null +++ b/post-processor/vagrant/lxc.go @@ -0,0 +1,34 @@ +package vagrant + +import ( + "fmt" + "path/filepath" + + "github.com/hashicorp/packer/packer" +) + +type LXCProvider struct{} + +func (p *LXCProvider) KeepInputArtifact() bool { + return false +} + +func (p *LXCProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + // Create the metadata + metadata = map[string]interface{}{ + "provider": "lxc", + "version": "1.0.0", + } + + // Copy all of the original contents into the temporary directory + for _, path := range artifact.Files() { + ui.Message(fmt.Sprintf("Copying: %s", path)) + + dstPath := filepath.Join(dir, filepath.Base(path)) + if err = CopyContents(dstPath, path); err != nil { + return + } + } + + return +} diff --git a/post-processor/vagrant/lxc_test.go b/post-processor/vagrant/lxc_test.go new file mode 100644 index 000000000..da5532c3b --- /dev/null +++ b/post-processor/vagrant/lxc_test.go @@ -0,0 +1,9 @@ +package vagrant + +import ( + "testing" +) + +func TestLXCProvider_impl(t *testing.T) { + var _ Provider = new(LXCProvider) +} diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index f3bb6e346..de93628c0 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -30,6 +30,7 @@ var builtins = map[string]string{ "packer.parallels": "parallels", "MSOpenTech.hyperv": "hyperv", "transcend.qemu": "libvirt", + "ustream.lxc": "lxc", } type Config struct { @@ -238,6 +239,8 @@ func providerForName(name string) Provider { return new(LibVirtProvider) case "google": return new(GoogleProvider) + case "lxc": + return new(LXCProvider) default: return nil } diff --git a/website/source/docs/post-processors/vagrant.html.md b/website/source/docs/post-processors/vagrant.html.md index 8feabbbbf..099051a81 100644 --- a/website/source/docs/post-processors/vagrant.html.md +++ b/website/source/docs/post-processors/vagrant.html.md @@ -34,6 +34,7 @@ providers. - DigitalOcean - Google - Hyper-V +- LXC - Parallels - QEMU - VirtualBox @@ -101,8 +102,18 @@ Specify overrides within the `override` configuration by provider name: In the example above, the compression level will be set to 1 except for VMware, where it will be set to 0. -The available provider names are: `aws`, `digitalocean`, `google`, `virtualbox`, -`vmware`, and `parallels`. +The available provider names are: + +- `aws` +- `digitalocean` +- `google` +- `hyperv` +- `parallels` +- `libvirt` +- `lxc` +- `scaleway` +- `virtualbox` +- `vmware` ## Input Artifacts From f305a2f4c22330c8283995b4388003f7c0140acf Mon Sep 17 00:00:00 2001 From: Andrew Pennebaker <andrew.pennebaker@gmail.com> Date: Wed, 7 Mar 2018 10:59:02 -0600 Subject: [PATCH 0705/1007] send multibyte scancodes accurately to virtualbox --- builder/virtualbox/common/step_type_boot_command.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index cb5b43648..77a82fb4b 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -91,7 +91,16 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - if err := driver.VBoxManage("controlvm", vmName, "keyboardputscancode", code); err != nil { + var codes []string + + for i := 0; i < len(code)/2; i++ { + codes = append(codes, code[i*2:i*2+2]) + } + + args := []string{"controlvm", vmName, "keyboardputscancode"} + args = append(args, codes...) + + if err := driver.VBoxManage(args...); err != nil { err := fmt.Errorf("Error sending boot command: %s", err) state.Put("error", err) ui.Error(err.Error()) From 4a2c124ea218ccea59850f661217df35701fd8d3 Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Wed, 7 Mar 2018 15:35:01 -0800 Subject: [PATCH 0706/1007] builder/googlecompute: Optionally disable service account The ability to use a service account other than the default was introduced in #5928. This change adds to that by introducing the 'disable_default_service_account' config option. If true - and 'service_account_email' is not set - Packer will create a GCE VM with no service account. --- builder/googlecompute/config.go | 66 +++++++++---------- builder/googlecompute/config_test.go | 26 ++++++++ builder/googlecompute/driver.go | 45 ++++++------- builder/googlecompute/driver_gce.go | 12 +++- builder/googlecompute/step_create_instance.go | 45 ++++++------- .../step_create_instance_test.go | 48 ++++++++++++++ .../docs/builders/googlecompute.html.md | 5 +- 7 files changed, 166 insertions(+), 81 deletions(-) diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index 3d9194c17..537fc7422 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -26,39 +26,39 @@ type Config struct { AccountFile string `mapstructure:"account_file"` ProjectId string `mapstructure:"project_id"` - AcceleratorType string `mapstructure:"accelerator_type"` - AcceleratorCount int64 `mapstructure:"accelerator_count"` - Address string `mapstructure:"address"` - DiskName string `mapstructure:"disk_name"` - DiskSizeGb int64 `mapstructure:"disk_size"` - DiskType string `mapstructure:"disk_type"` - ImageName string `mapstructure:"image_name"` - ImageDescription string `mapstructure:"image_description"` - ImageFamily string `mapstructure:"image_family"` - ImageLabels map[string]string `mapstructure:"image_labels"` - ImageLicenses []string `mapstructure:"image_licenses"` - InstanceName string `mapstructure:"instance_name"` - Labels map[string]string `mapstructure:"labels"` - MachineType string `mapstructure:"machine_type"` - Metadata map[string]string `mapstructure:"metadata"` - Network string `mapstructure:"network"` - NetworkProjectId string `mapstructure:"network_project_id"` - OmitExternalIP bool `mapstructure:"omit_external_ip"` - OnHostMaintenance string `mapstructure:"on_host_maintenance"` - Preemptible bool `mapstructure:"preemptible"` - RawStateTimeout string `mapstructure:"state_timeout"` - Region string `mapstructure:"region"` - Scopes []string `mapstructure:"scopes"` - SourceImage string `mapstructure:"source_image"` - SourceImageFamily string `mapstructure:"source_image_family"` - SourceImageProjectId string `mapstructure:"source_image_project_id"` - StartupScriptFile string `mapstructure:"startup_script_file"` - Subnetwork string `mapstructure:"subnetwork"` - Tags []string `mapstructure:"tags"` - UseInternalIP bool `mapstructure:"use_internal_ip"` - Zone string `mapstructure:"zone"` - - ServiceAccountEmail string `mapstructure:"service_account_email"` + AcceleratorType string `mapstructure:"accelerator_type"` + AcceleratorCount int64 `mapstructure:"accelerator_count"` + Address string `mapstructure:"address"` + DisableDefaultServiceAccount bool `mapstructure:"disable_default_service_account"` + DiskName string `mapstructure:"disk_name"` + DiskSizeGb int64 `mapstructure:"disk_size"` + DiskType string `mapstructure:"disk_type"` + ImageName string `mapstructure:"image_name"` + ImageDescription string `mapstructure:"image_description"` + ImageFamily string `mapstructure:"image_family"` + ImageLabels map[string]string `mapstructure:"image_labels"` + ImageLicenses []string `mapstructure:"image_licenses"` + InstanceName string `mapstructure:"instance_name"` + Labels map[string]string `mapstructure:"labels"` + MachineType string `mapstructure:"machine_type"` + Metadata map[string]string `mapstructure:"metadata"` + Network string `mapstructure:"network"` + NetworkProjectId string `mapstructure:"network_project_id"` + OmitExternalIP bool `mapstructure:"omit_external_ip"` + OnHostMaintenance string `mapstructure:"on_host_maintenance"` + Preemptible bool `mapstructure:"preemptible"` + RawStateTimeout string `mapstructure:"state_timeout"` + Region string `mapstructure:"region"` + Scopes []string `mapstructure:"scopes"` + ServiceAccountEmail string `mapstructure:"service_account_email"` + SourceImage string `mapstructure:"source_image"` + SourceImageFamily string `mapstructure:"source_image_family"` + SourceImageProjectId string `mapstructure:"source_image_project_id"` + StartupScriptFile string `mapstructure:"startup_script_file"` + Subnetwork string `mapstructure:"subnetwork"` + Tags []string `mapstructure:"tags"` + UseInternalIP bool `mapstructure:"use_internal_ip"` + Zone string `mapstructure:"zone"` Account AccountFile stateTimeout time.Duration diff --git a/builder/googlecompute/config_test.go b/builder/googlecompute/config_test.go index a4b862a1a..508b3c528 100644 --- a/builder/googlecompute/config_test.go +++ b/builder/googlecompute/config_test.go @@ -170,6 +170,32 @@ func TestConfigPrepare(t *testing.T) { []string{"https://www.googleapis.com/auth/cloud-platform"}, false, }, + + { + "disable_default_service_account", + "", + false, + }, + { + "disable_default_service_account", + nil, + false, + }, + { + "disable_default_service_account", + false, + false, + }, + { + "disable_default_service_account", + true, + false, + }, + { + "disable_default_service_account", + "NOT A BOOL", + true, + }, } for _, tc := range cases { diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index 4c07a06cf..22ec62707 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -58,28 +58,29 @@ type Driver interface { } type InstanceConfig struct { - AcceleratorType string - AcceleratorCount int64 - Address string - Description string - DiskSizeGb int64 - DiskType string - Image *Image - Labels map[string]string - MachineType string - Metadata map[string]string - Name string - Network string - NetworkProjectId string - OmitExternalIP bool - OnHostMaintenance string - Preemptible bool - Region string - ServiceAccountEmail string - Scopes []string - Subnetwork string - Tags []string - Zone string + AcceleratorType string + AcceleratorCount int64 + Address string + Description string + DisableDefaultServiceAccount bool + DiskSizeGb int64 + DiskType string + Image *Image + Labels map[string]string + MachineType string + Metadata map[string]string + Name string + Network string + NetworkProjectId string + OmitExternalIP bool + OnHostMaintenance string + Preemptible bool + Region string + ServiceAccountEmail string + Scopes []string + Subnetwork string + Tags []string + Zone string } // WindowsPasswordConfig is the data structue that GCE needs to encrypt the created diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 5f286fa71..8adbd833e 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -343,12 +343,18 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { guestAccelerators = append(guestAccelerators, ac) } - serviceAccount := &compute.ServiceAccount{ - Email: "default", - Scopes: c.Scopes, + // Configure the instance's service account. If the user has set + // disable_default_service_account, then the default service account + // will not be used. If they also do not set service_account_email, then + // the instance will be created with no service account or scopes. + serviceAccount := &compute.ServiceAccount{} + if !c.DisableDefaultServiceAccount { + serviceAccount.Email = "default" + serviceAccount.Scopes = c.Scopes } if c.ServiceAccountEmail != "" { serviceAccount.Email = c.ServiceAccountEmail + serviceAccount.Scopes = c.Scopes } // Create the instance information diff --git a/builder/googlecompute/step_create_instance.go b/builder/googlecompute/step_create_instance.go index bc37aa7b2..06e5b8eb1 100644 --- a/builder/googlecompute/step_create_instance.go +++ b/builder/googlecompute/step_create_instance.go @@ -100,28 +100,29 @@ func (s *StepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu var metadata map[string]string metadata, err = c.createInstanceMetadata(sourceImage, sshPublicKey) errCh, err = d.RunInstance(&InstanceConfig{ - AcceleratorType: c.AcceleratorType, - AcceleratorCount: c.AcceleratorCount, - Address: c.Address, - Description: "New instance created by Packer", - DiskSizeGb: c.DiskSizeGb, - DiskType: c.DiskType, - Image: sourceImage, - Labels: c.Labels, - MachineType: c.MachineType, - Metadata: metadata, - Name: name, - Network: c.Network, - NetworkProjectId: c.NetworkProjectId, - OmitExternalIP: c.OmitExternalIP, - OnHostMaintenance: c.OnHostMaintenance, - Preemptible: c.Preemptible, - Region: c.Region, - ServiceAccountEmail: c.ServiceAccountEmail, - Scopes: c.Scopes, - Subnetwork: c.Subnetwork, - Tags: c.Tags, - Zone: c.Zone, + AcceleratorType: c.AcceleratorType, + AcceleratorCount: c.AcceleratorCount, + Address: c.Address, + Description: "New instance created by Packer", + DisableDefaultServiceAccount: c.DisableDefaultServiceAccount, + DiskSizeGb: c.DiskSizeGb, + DiskType: c.DiskType, + Image: sourceImage, + Labels: c.Labels, + MachineType: c.MachineType, + Metadata: metadata, + Name: name, + Network: c.Network, + NetworkProjectId: c.NetworkProjectId, + OmitExternalIP: c.OmitExternalIP, + OnHostMaintenance: c.OnHostMaintenance, + Preemptible: c.Preemptible, + Region: c.Region, + ServiceAccountEmail: c.ServiceAccountEmail, + Scopes: c.Scopes, + Subnetwork: c.Subnetwork, + Tags: c.Tags, + Zone: c.Zone, }) if err == nil { diff --git a/builder/googlecompute/step_create_instance_test.go b/builder/googlecompute/step_create_instance_test.go index f8196e3d0..e56159138 100644 --- a/builder/googlecompute/step_create_instance_test.go +++ b/builder/googlecompute/step_create_instance_test.go @@ -248,6 +248,54 @@ func TestStepCreateInstance_errorTimeout(t *testing.T) { assert.False(t, ok, "State should not have an instance name.") } +func TestStepCreateInstance_noServiceAccount(t *testing.T) { + state := testState(t) + step := new(StepCreateInstance) + defer step.Cleanup(state) + + state.Put("ssh_public_key", "key") + + c := state.Get("config").(*Config) + c.DisableDefaultServiceAccount = true + c.ServiceAccountEmail = "" + d := state.Get("driver").(*DriverMock) + d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) + + // run the step + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") + + // cleanup + step.Cleanup(state) + + // Check args passed to the driver. + assert.Equal(t, d.RunInstanceConfig.DisableDefaultServiceAccount, c.DisableDefaultServiceAccount, "Incorrect value for DisableDefaultServiceAccount passed to driver.") + assert.Equal(t, d.RunInstanceConfig.ServiceAccountEmail, c.ServiceAccountEmail, "Incorrect value for ServiceAccountEmail passed to driver.") +} + +func TestStepCreateInstance_customServiceAccount(t *testing.T) { + state := testState(t) + step := new(StepCreateInstance) + defer step.Cleanup(state) + + state.Put("ssh_public_key", "key") + + c := state.Get("config").(*Config) + c.DisableDefaultServiceAccount = true + c.ServiceAccountEmail = "custom-service-account" + d := state.Get("driver").(*DriverMock) + d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) + + // run the step + assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") + + // cleanup + step.Cleanup(state) + + // Check args passed to the driver. + assert.Equal(t, d.RunInstanceConfig.DisableDefaultServiceAccount, c.DisableDefaultServiceAccount, "Incorrect value for DisableDefaultServiceAccount passed to driver.") + assert.Equal(t, d.RunInstanceConfig.ServiceAccountEmail, c.ServiceAccountEmail, "Incorrect value for ServiceAccountEmail passed to driver.") +} + func TestCreateInstanceMetadata(t *testing.T) { state := testState(t) c := state.Get("config").(*Config) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index fb006c7ae..89e57a1f7 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -210,6 +210,9 @@ builder. - `address` (string) - The name of a pre-allocated static external IP address. Note, must be the name and not the actual IP address. +- `disable_default_service_account` (bool) - If true, the default service account will not be used if `service_account_email` + is not specified. Set this value to true and omit `service_account_email` to provision a VM with no service account. + - `disk_name` (string) - The name of the disk, if unset the instance name will be used. @@ -269,7 +272,7 @@ builder. to the region hosting the specified `zone`. - `service_account_email` (string) - The service account to be used for launched instance. Defaults to - the project's default service account. + the project's default service account unless `disable_default_service_account` is true. - `scopes` (array of strings) - The service account scopes for launched instance. Defaults to: From 7dfa827a4c52ef94ed41b0fa361d9c5b03cb9de3 Mon Sep 17 00:00:00 2001 From: Rickard von Essen <rickard.von.essen@gmail.com> Date: Thu, 8 Mar 2018 13:56:34 +0100 Subject: [PATCH 0707/1007] builder/docker: Small doc update - Correcting docs about communicator for Docker - Clarifying that the docker builder will not work with remote hosts. --- website/source/docs/builders/docker.html.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index e1390ff12..23080e3ce 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -24,9 +24,11 @@ has a simple mental model: you provision containers much the same way you provision a normal virtualized or dedicated server. For more information, read the section on [Dockerfiles](#dockerfiles). -The Docker builder must run on a machine that has Docker installed. Therefore -the builder only works on machines that support Docker. You can learn about -what [platforms Docker supports and how to install onto them](https://docs.docker.com/engine/installation/) in the Docker documentation. +The Docker builder must run on a machine that has Docker Engine installed. +Therefore the builder only works on machines that support Docker and _does not +support running on a Docker remote host_. You can learn about what +[platforms Docker supports and how to install onto them](https://docs.docker.com/engine/installation/) +in the Docker documentation. ## Basic Example: Export @@ -125,9 +127,8 @@ Configuration options are organized below into two categories: required and optional. Within each category, the available options are alphabetized and described. -In addition to the options listed here, a -[communicator](/docs/templates/communicator.html) can be configured for this -builder. +The Docker builder uses a special Docker communicator _and will not use_ the +standard [communicators](/docs/templates/communicator.html). ### Required: From 1ef491d4c8969385f0030af919cbc12f0a125de2 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Thu, 8 Mar 2018 22:39:23 -0800 Subject: [PATCH 0708/1007] incorporate reviewer feedback --- builder/azure/arm/config.go | 27 +++-- builder/azure/arm/config_test.go | 98 +++++++++++++++++-- builder/azure/arm/template_factory.go | 4 +- ..._factory_test.TestPlanInfo01.approved.json | 24 +++++ ..._factory_test.TestPlanInfo02.approved.json | 28 ++++++ builder/azure/arm/template_factory_test.go | 21 ++-- examples/azure/marketplace_plan_info.json | 51 ++++++++++ website/source/docs/builders/azure.html.md | 33 +++++-- 8 files changed, 253 insertions(+), 33 deletions(-) create mode 100644 examples/azure/marketplace_plan_info.json diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index e8ed6bd81..df507930a 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -57,6 +57,13 @@ var ( reResourceGroupName = regexp.MustCompile(validResourceGroupNameRe) ) +type PlanInformation struct { + PlanName string `mapstructure:"plan_name"` + PlanProduct string `mapstructure:"plan_product"` + PlanPublisher string `mapstructure:"plan_publisher"` + PlanPromotionCode string `mapstructure:"plan_promotion_code"` +} + type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -107,6 +114,7 @@ type Config struct { VirtualNetworkResourceGroupName string `mapstructure:"virtual_network_resource_group_name"` CustomDataFile string `mapstructure:"custom_data_file"` customData string + PlanInfo PlanInformation `mapstructure:"plan_info"` // OS OSType string `mapstructure:"os_type"` @@ -115,12 +123,6 @@ type Config struct { // Additional Disks AdditionalDiskSize []int32 `mapstructure:"disk_additional_size"` - // Plan Info - PlanName string `mapstructure:"plan_name"` - PlanProduct string `mapstructure:"plan_product"` - PlanPublisher string `mapstructure:"plan_publisher"` - PlanPromotionCode string `mapstructure:"plan_promotion_code"` - // Runtime Values UserName string Password string @@ -655,9 +657,18 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) { ///////////////////////////////////////////// // Plan Info - if c.PlanName != "" || c.PlanProduct != "" || c.PlanPublisher != "" || c.PlanPromotionCode != "" { - if c.PlanName == "" || c.PlanProduct == "" || c.PlanPublisher == "" { + if c.PlanInfo.PlanName != "" || c.PlanInfo.PlanProduct != "" || c.PlanInfo.PlanPublisher != "" || c.PlanInfo.PlanPromotionCode != "" { + if c.PlanInfo.PlanName == "" || c.PlanInfo.PlanProduct == "" || c.PlanInfo.PlanPublisher == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("if either plan_name, plan_product, plan_publisher, or plan_promotion_code are defined then plan_name, plan_product, and plan_publisher must be defined")) + } else { + if c.AzureTags == nil { + c.AzureTags = make(map[string]*string) + } + + c.AzureTags["PlanInfo"] = &c.PlanInfo.PlanName + c.AzureTags["PlanProduct"] = &c.PlanInfo.PlanProduct + c.AzureTags["PlanPublisher"] = &c.PlanInfo.PlanPublisher + c.AzureTags["PlanPromotionCode"] = &c.PlanInfo.PlanPromotionCode } } diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index b56a260e3..c7758fb91 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -1119,32 +1119,112 @@ func TestPlanInfoConfiguration(t *testing.T) { "communicator": "none", } - config["plan_name"] = "--plan-name--" + planInfo := map[string]string{ + "plan_name": "--plan-name--", + } + config["plan_info"] = planInfo + _, _, err := newConfig(config, getPackerConfiguration()) if err == nil { t.Fatal("expected config to reject the use of plan_name without plan_product and plan_publisher") } - config["plan_product"] = "--plan-product--" + planInfo["plan_product"] = "--plan-product--" _, _, err = newConfig(config, getPackerConfiguration()) if err == nil { t.Fatal("expected config to reject the use of plan_name and plan_product without plan_publisher") } - config["plan_publisher"] = "--plan-publisher--" + planInfo["plan_publisher"] = "--plan-publisher--" c, _, err := newConfig(config, getPackerConfiguration()) if err != nil { t.Fatalf("expected config to accept a complete plan configuration: %s", err) } - if c.PlanName != "--plan-name--" { - t.Fatalf("Expected PlanName to be '--plan-name--', but got %q", c.PlanName) + if c.PlanInfo.PlanName != "--plan-name--" { + t.Fatalf("Expected PlanName to be '--plan-name--', but got %q", c.PlanInfo.PlanName) } - if c.PlanProduct != "--plan-product--" { - t.Fatalf("Expected PlanProduct to be '--plan-product--', but got %q", c.PlanProduct) + if c.PlanInfo.PlanProduct != "--plan-product--" { + t.Fatalf("Expected PlanProduct to be '--plan-product--', but got %q", c.PlanInfo.PlanProduct) } - if c.PlanPublisher != "--plan-publisher--" { - t.Fatalf("Expected PlanPublisher to be '--plan-publisher--, but got %q", c.PlanPublisher) + if c.PlanInfo.PlanPublisher != "--plan-publisher--" { + t.Fatalf("Expected PlanPublisher to be '--plan-publisher--, but got %q", c.PlanInfo.PlanPublisher) + } +} + +func TestPlanInfoPromotionCode(t *testing.T) { + config := map[string]interface{}{ + "capture_name_prefix": "ignore", + "capture_container_name": "ignore", + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "storage_account": "ignore", + "resource_group_name": "ignore", + "subscription_id": "ignore", + "os_type": "linux", + "communicator": "none", + "plan_info": map[string]string{ + "plan_name": "--plan-name--", + "plan_product": "--plan-product--", + "plan_publisher": "--plan-publisher--", + "plan_promotion_code": "--plan-promotion-code--", + }, + } + + c, _, err := newConfig(config, getPackerConfiguration()) + if err != nil { + t.Fatalf("expected config to accept plan_info configuration, but got %s", err) + } + + if c.PlanInfo.PlanName != "--plan-name--" { + t.Fatalf("Expected PlanName to be '--plan-name--', but got %q", c.PlanInfo.PlanName) + } + if c.PlanInfo.PlanProduct != "--plan-product--" { + t.Fatalf("Expected PlanProduct to be '--plan-product--', but got %q", c.PlanInfo.PlanProduct) + } + if c.PlanInfo.PlanPublisher != "--plan-publisher--" { + t.Fatalf("Expected PlanPublisher to be '--plan-publisher--, but got %q", c.PlanInfo.PlanPublisher) + } + if c.PlanInfo.PlanPromotionCode != "--plan-promotion-code--" { + t.Fatalf("Expected PlanPublisher to be '--plan-promotion-code----, but got %q", c.PlanInfo.PlanPromotionCode) + } +} + +// plan_info defines 3 or 4 tags based on plan data. +// The user can define up to 15 tags. If the combination of these two +// exceeds the max tag amount, the builder should reject the configuration. +func TestPlanInfoTooManyTagsErrors(t *testing.T) { + exactMaxNumberOfTags := map[string]string{} + for i := 0; i < 15; i++ { + exactMaxNumberOfTags[fmt.Sprintf("tag%.2d", i)] = "ignored" + } + + config := map[string]interface{}{ + "capture_name_prefix": "ignore", + "capture_container_name": "ignore", + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "storage_account": "ignore", + "resource_group_name": "ignore", + "subscription_id": "ignore", + "os_type": "linux", + "communicator": "none", + "azure_tags": exactMaxNumberOfTags, + "plan_info": map[string]string{ + "plan_name": "--plan-name--", + "plan_product": "--plan-product--", + "plan_publisher": "--plan-publisher--", + "plan_promotion_code": "--plan-promotion-code--", + }, + } + + _, _, err := newConfig(config, getPackerConfiguration()) + if err == nil { + t.Fatal("expected config to reject configuration due to excess tags") } } diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index a68b13f22..843580fd2 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -81,8 +81,8 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error) builder.SetCustomData(config.customData) } - if config.PlanName != "" { - builder.SetPlanInfo(config.PlanName, config.PlanProduct, config.PlanPublisher, config.PlanPromotionCode) + if config.PlanInfo.PlanName != "" { + builder.SetPlanInfo(config.PlanInfo.PlanName, config.PlanInfo.PlanProduct, config.PlanInfo.PlanPublisher, config.PlanInfo.PlanPromotionCode) } if config.VirtualNetworkName != "" && DefaultPrivateVirtualNetworkWithPublicIp != config.PrivateVirtualNetworkWithPublicIp { diff --git a/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json b/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json index 9af488f98..74546c490 100644 --- a/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json +++ b/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json @@ -35,6 +35,12 @@ }, "publicIPAllocationMethod": "[variables('publicIPAddressType')]" }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "", + "PlanPublisher": "planPublisher00" + }, "type": "Microsoft.Network/publicIPAddresses" }, { @@ -56,6 +62,12 @@ } ] }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "", + "PlanPublisher": "planPublisher00" + }, "type": "Microsoft.Network/virtualNetworks" }, { @@ -82,6 +94,12 @@ } ] }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "", + "PlanPublisher": "planPublisher00" + }, "type": "Microsoft.Network/networkInterfaces" }, { @@ -144,6 +162,12 @@ } } }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "", + "PlanPublisher": "planPublisher00" + }, "type": "Microsoft.Compute/virtualMachines" } ], diff --git a/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json b/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json index 3cd802107..8f93bb530 100644 --- a/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json +++ b/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json @@ -35,6 +35,13 @@ }, "publicIPAllocationMethod": "[variables('publicIPAddressType')]" }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "planPromotionCode00", + "PlanPublisher": "planPublisher00", + "dept": "engineering" + }, "type": "Microsoft.Network/publicIPAddresses" }, { @@ -56,6 +63,13 @@ } ] }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "planPromotionCode00", + "PlanPublisher": "planPublisher00", + "dept": "engineering" + }, "type": "Microsoft.Network/virtualNetworks" }, { @@ -82,6 +96,13 @@ } ] }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "planPromotionCode00", + "PlanPublisher": "planPublisher00", + "dept": "engineering" + }, "type": "Microsoft.Network/networkInterfaces" }, { @@ -145,6 +166,13 @@ } } }, + "tags": { + "PlanInfo": "planName00", + "PlanProduct": "planProduct00", + "PlanPromotionCode": "planPromotionCode00", + "PlanPublisher": "planPublisher00", + "dept": "engineering" + }, "type": "Microsoft.Compute/virtualMachines" } ], diff --git a/builder/azure/arm/template_factory_test.go b/builder/azure/arm/template_factory_test.go index 292c56389..a6d31d7d9 100644 --- a/builder/azure/arm/template_factory_test.go +++ b/builder/azure/arm/template_factory_test.go @@ -526,9 +526,11 @@ func TestKeyVaultDeployment03(t *testing.T) { func TestPlanInfo01(t *testing.T) { planInfo := map[string]interface{}{ - "plan_name": "planName00", - "plan_product": "planProduct00", - "plan_publisher": "planPublisher00", + "plan_info": map[string]string{ + "plan_name": "planName00", + "plan_product": "planProduct00", + "plan_publisher": "planPublisher00", + }, } c, _, _ := newConfig(planInfo, getArmBuilderConfiguration(), getPackerConfiguration()) @@ -545,10 +547,15 @@ func TestPlanInfo01(t *testing.T) { func TestPlanInfo02(t *testing.T) { planInfo := map[string]interface{}{ - "plan_name": "planName00", - "plan_product": "planProduct00", - "plan_publisher": "planPublisher00", - "plan_promotion_code": "planPromotionCode00", + "azure_tags": map[string]string{ + "dept": "engineering", + }, + "plan_info": map[string]string{ + "plan_name": "planName00", + "plan_product": "planProduct00", + "plan_publisher": "planPublisher00", + "plan_promotion_code": "planPromotionCode00", + }, } c, _, _ := newConfig(planInfo, getArmBuilderConfiguration(), getPackerConfiguration()) diff --git a/examples/azure/marketplace_plan_info.json b/examples/azure/marketplace_plan_info.json new file mode 100644 index 000000000..4891a9e6b --- /dev/null +++ b/examples/azure/marketplace_plan_info.json @@ -0,0 +1,51 @@ +{ + "variables": { + "client_id": "{{env `ARM_CLIENT_ID`}}", + "client_secret": "{{env `ARM_CLIENT_SECRET`}}", + "resource_group": "{{env `ARM_RESOURCE_GROUP`}}", + "storage_account": "{{env `ARM_STORAGE_ACCOUNT`}}", + "subscription_id": "{{env `ARM_SUBSCRIPTION_ID`}}" + }, + "builders": [{ + "type": "azure-arm", + + "client_id": "{{user `client_id`}}", + "client_secret": "{{user `client_secret`}}", + "resource_group_name": "{{user `resource_group`}}", + "storage_account": "{{user `storage_account`}}", + "subscription_id": "{{user `subscription_id`}}", + + "capture_container_name": "images", + "capture_name_prefix": "packer", + + "os_type": "Linux", + "image_publisher": "Canonical", + "image_offer": "UbuntuServer", + "image_sku": "16.04-LTS", + + "azure_tags": { + "dept": "engineering", + "task": "image deployment" + }, + + "plan_info": { + "plan_name": "rabbitmq", + "plan_product": "rabbitmq", + "plan_publisher": "bitnami" + }, + + "location": "West US", + "vm_size": "Standard_DS2_v2" + }], + "provisioners": [{ + "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", + "inline": [ + "apt-get update", + "apt-get upgrade -y", + + "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" + ], + "inline_shebang": "/bin/sh -x", + "type": "shell" + }] +} diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 94e0d0a0c..13b2b46a3 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -162,16 +162,35 @@ Providing `temp_resource_group_name` or `location` in combination with `build_re `Linux` this configures an SSH authorized key. For `Windows` this configures a WinRM certificate. -- `plan_name` (string) The plan name. This setting (`plan_product`, `plan_publisher`, and `plan_promotion_code`) are - only needed for Marketplace images. Please refer to [Deploy an image with Marketplace terms](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-ps-findimage#deploy-an-image-with-marketplace-terms) for more details. +- `plan_info` (object) - Used for creating images from Marketplace images. Please refer to [Deploy an image with + Marketplace terms](https://aka.ms/azuremarketplaceapideployment) for more details. Not all Marketplace images + support programmatic deployment, and support is controlled by the image publisher. -- `plan_product` (string) The plan product. See `plan_name` for more information. + An example plan_info object is defined below. -- `plan_publisher` (string) Specifies the produce of the image from the Marketplace. This value is the same value as - Offer (`image_offer`). See `plan_name` for more information. + ```json + { + "plan_info": { + "plan_name": "rabbitmq", + "plan_product": "rabbitmq", + "plan_publisher": "bitnami" + } + } + ``` -- `plan_promotion_code` (string) Some Marketplace images use a promotion code. See `plan_name` for more - information. + `plan_name` (string) - The plan name, required. + `plan_product` (string) - The plan product, required. + `plan_publisher` (string) - The plan publisher, required. + `plan_promotion_code` (string) - Some images accept a promotion code, optional. + + Images created from the Marketplace with `plan_info` **must** specify `plan_info` whenever the image is deployed. + The builder automatically adds tags to the image to ensure this information is not lost. The following tags are + added. + + 1. PlanName + 1. PlanProduct + 1. PlanPublisher + 1. PlanPromotionCode - `temp_compute_name` (string) temporary name assigned to the VM. If this value is not set, a random value will be assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer From 3faf73b5f38e26c73c33e3e9b218a80647bea1f7 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 5 Mar 2018 14:18:23 -0800 Subject: [PATCH 0709/1007] change backslashes to forward slashes in powershell provisioner; was breaking with cygwin --- provisioner/powershell/provisioner.go | 8 ++++---- provisioner/powershell/provisioner_test.go | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 92f881314..07b10def9 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -397,7 +397,7 @@ func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (envVarPath string, // Upload all env vars to a powershell script on the target build file system envVarReader := strings.NewReader(flattenedEnvVars) uuid := uuid.TimeOrderedUUID() - envVarPath = fmt.Sprintf(`${env:SYSTEMROOT}\Temp\packer-env-vars-%s.ps1`, uuid) + envVarPath = fmt.Sprintf(`${env:SYSTEMROOT}/Temp/packer-env-vars-%s.ps1`, uuid) log.Printf("Uploading env vars to %s", envVarPath) err = p.communicator.Upload(envVarPath, envVarReader, nil) if err != nil { @@ -482,7 +482,7 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin // Only use %ENVVAR% format for environment variables when setting // the log file path; Do NOT use $env:ENVVAR format as it won't be // expanded correctly in the elevatedTemplate - logFile := `%SYSTEMROOT%\Temp\` + taskName + ".out" + logFile := `%SYSTEMROOT%/Temp/` + taskName + ".out" command += fmt.Sprintf(" > %s 2>&1", logFile) // elevatedTemplate wraps the command in a single quoted XML text @@ -524,7 +524,7 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin return "", err } uuid := uuid.TimeOrderedUUID() - path := fmt.Sprintf(`${env:TEMP}\packer-elevated-shell-%s.ps1`, uuid) + path := fmt.Sprintf(`${env:TEMP}/packer-elevated-shell-%s.ps1`, uuid) log.Printf("Uploading elevated shell wrapper for command [%s] to [%s]", command, path) err = p.communicator.Upload(path, &buffer, nil) if err != nil { @@ -532,6 +532,6 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } // CMD formatted Path required for this op - path = fmt.Sprintf("%s-%s.ps1", "%TEMP%\\packer-elevated-shell", uuid) + path = fmt.Sprintf("%s-%s.ps1", "%TEMP%/packer-elevated-shell", uuid) return path, err } diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 2791601fa..ab68d8f42 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -414,7 +414,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { } cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -434,7 +434,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { } cmd = comm.StartCmd.Command - re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) matched = re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -461,7 +461,7 @@ func TestProvisionerProvision_Scripts(t *testing.T) { } cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -495,7 +495,7 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { } cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -612,7 +612,7 @@ func TestProvision_createCommandText(t *testing.T) { // Non-elevated cmd, _ := p.createCommandText() - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -645,7 +645,7 @@ func TestProvision_uploadEnvVars(t *testing.T) { t.Fatalf("Failed to upload env var file") } - re := regexp.MustCompile(`\${env:SYSTEMROOT}\\Temp\\packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1`) + re := regexp.MustCompile(`\${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1`) matched := re.MatchString(envVarPath) if !matched { t.Fatalf("Got unexpected path for env var file: %s", envVarPath) From f3a538db469a20a949562540667d2097c9751d3d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 9 Mar 2018 13:36:47 -0800 Subject: [PATCH 0710/1007] fix tests --- provisioner/powershell/provisioner_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index ab68d8f42..3c758ae4d 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -622,7 +622,7 @@ func TestProvision_createCommandText(t *testing.T) { p.config.ElevatedUser = "vagrant" p.config.ElevatedPassword = "vagrant" cmd, _ = p.createCommandText() - re = regexp.MustCompile(`powershell -executionpolicy bypass -file "%TEMP%\\packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) + re = regexp.MustCompile(`powershell -executionpolicy bypass -file "%TEMP%/packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) matched = re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected elevated command: %s", cmd) From 8c408df53dde76138546665ca620b48770df52aa Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 9 Mar 2018 15:33:28 -0800 Subject: [PATCH 0711/1007] add note about keymap bug in qemu 2.11. See #5769 --- website/source/docs/builders/qemu.html.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index 2d3c82d9e..ac15772a0 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -456,3 +456,7 @@ seems to be related to having a `common` directory or file in the directory they've run Packer in, like the packer source directory. This appears to be an upstream bug with qemu, and the best solution for now is to remove the file/directory or run in another directory. + +Some users have reported issues with incorrect keymaps using qemu version 2.11. +This is a bug with qemu, and the solution is to upgrade, or downgrade to 2.10.1 +or earlier. From 1d48812b34ed283000d3802ae9225436ed917216 Mon Sep 17 00:00:00 2001 From: Andrew Pennebaker <andrew.pennebaker@gmail.com> Date: Fri, 9 Mar 2018 20:17:43 -0600 Subject: [PATCH 0712/1007] fix later commands overwriting earlier commands --- .../common/step_type_boot_command.go | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index cb5b43648..d54c5560a 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -182,92 +182,92 @@ func scancodes(message string) []string { var scancode []string if strings.HasPrefix(message, "<leftAltOn>") { - scancode = []string{"38"} + scancode = append(scancode, "38") message = message[len("<leftAltOn>"):] log.Printf("Special code '<leftAltOn>' found, replacing with: 38") } if strings.HasPrefix(message, "<leftCtrlOn>") { - scancode = []string{"1d"} + scancode = append(scancode, "1d") message = message[len("<leftCtrlOn>"):] log.Printf("Special code '<leftCtrlOn>' found, replacing with: 1d") } if strings.HasPrefix(message, "<leftShiftOn>") { - scancode = []string{"2a"} + scancode = append(scancode, "2a") message = message[len("<leftShiftOn>"):] log.Printf("Special code '<leftShiftOn>' found, replacing with: 2a") } if strings.HasPrefix(message, "<leftAltOff>") { - scancode = []string{"b8"} + scancode = append(scancode, "b8") message = message[len("<leftAltOff>"):] log.Printf("Special code '<leftAltOff>' found, replacing with: b8") } if strings.HasPrefix(message, "<leftCtrlOff>") { - scancode = []string{"9d"} + scancode = append(scancode, "9d") message = message[len("<leftCtrlOff>"):] log.Printf("Special code '<leftCtrlOff>' found, replacing with: 9d") } if strings.HasPrefix(message, "<leftShiftOff>") { - scancode = []string{"aa"} + scancode = append(scancode, "aa") message = message[len("<leftShiftOff>"):] log.Printf("Special code '<leftShiftOff>' found, replacing with: aa") } if strings.HasPrefix(message, "<rightAltOn>") { - scancode = []string{"e038"} + scancode = append(scancode, "e038") message = message[len("<rightAltOn>"):] log.Printf("Special code '<rightAltOn>' found, replacing with: e038") } if strings.HasPrefix(message, "<rightCtrlOn>") { - scancode = []string{"e01d"} + scancode = append(scancode, "e01d") message = message[len("<rightCtrlOn>"):] log.Printf("Special code '<rightCtrlOn>' found, replacing with: e01d") } if strings.HasPrefix(message, "<rightShiftOn>") { - scancode = []string{"36"} + scancode = append(scancode, "36") message = message[len("<rightShiftOn>"):] log.Printf("Special code '<rightShiftOn>' found, replacing with: 36") } if strings.HasPrefix(message, "<rightAltOff>") { - scancode = []string{"e0b8"} + scancode = append(scancode, "e0b8") message = message[len("<rightAltOff>"):] log.Printf("Special code '<rightAltOff>' found, replacing with: e0b8") } if strings.HasPrefix(message, "<rightCtrlOff>") { - scancode = []string{"e09d"} + scancode = append(scancode, "e09d") message = message[len("<rightCtrlOff>"):] log.Printf("Special code '<rightCtrlOff>' found, replacing with: e09d") } if strings.HasPrefix(message, "<rightShiftOff>") { - scancode = []string{"b6"} + scancode = append(scancode, "b6") message = message[len("<rightShiftOff>"):] log.Printf("Special code '<rightShiftOff>' found, replacing with: b6") } if strings.HasPrefix(message, "<wait>") { log.Printf("Special code <wait> found, will sleep 1 second at this point.") - scancode = []string{"wait"} + scancode = append(scancode, "wait") message = message[len("<wait>"):] } if strings.HasPrefix(message, "<wait5>") { log.Printf("Special code <wait5> found, will sleep 5 seconds at this point.") - scancode = []string{"wait5"} + scancode = append(scancode, "wait5") message = message[len("<wait5>"):] } if strings.HasPrefix(message, "<wait10>") { log.Printf("Special code <wait10> found, will sleep 10 seconds at this point.") - scancode = []string{"wait10"} + scancode = append(scancode, "wait10") message = message[len("<wait10>"):] } @@ -275,7 +275,7 @@ func scancodes(message string) []string { for specialCode, specialValue := range special { if strings.HasPrefix(message, specialCode) { log.Printf("Special code '%s' found, replacing with: %s", specialCode, specialValue) - scancode = specialValue + scancode = append(scancode, specialValue...) message = message[len(specialCode):] break } From 149ce52079dfdeb9e8f23f235c78b9bbb2a297c2 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Sat, 10 Mar 2018 10:17:38 -0800 Subject: [PATCH 0713/1007] azure: respect -force for managed image deletion --- builder/azure/arm/builder.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index f2bc66135..0761b4afe 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -99,7 +99,16 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe // If a managed image already exists it cannot be overwritten. _, err = azureClient.ImagesClient.Get(b.config.ManagedImageResourceGroupName, b.config.ManagedImageName, "") if err == nil { - return nil, fmt.Errorf("A managed image named %s already exists in the resource group %s.", b.config.ManagedImageName, b.config.ManagedImageResourceGroupName) + if b.config.PackerForce { + _, errChan := azureClient.ImagesClient.Delete(b.config.ManagedImageResourceGroupName, b.config.ManagedImageName, nil) + ui.Say(fmt.Sprintf("the managed image named %s already exists, but deleting it due to -force flag", b.config.ManagedImageName)) + err = <-errChan + if err != nil { + return nil, fmt.Errorf("failed to delete the managed image named %s : %s", b.config.ManagedImageName, azureClient.LastError.Error()) + } + } else { + return nil, fmt.Errorf("the managed image named %s already exists in the resource group %s, use the -force option to automatically delete it.", b.config.ManagedImageName, b.config.ManagedImageResourceGroupName) + } } } From 2a21032964ada0ee655c345ef25e1361e6ba3400 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Sat, 10 Mar 2018 11:17:43 -0800 Subject: [PATCH 0714/1007] azure: randomize NIC and Public IP names --- ...estVirtualMachineDeployment05.approved.txt | 2 - builder/azure/arm/builder.go | 12 +++--- builder/azure/arm/config.go | 8 ++++ builder/azure/arm/template_factory.go | 13 +++++-- ..._factory_test.TestPlanInfo01.approved.json | 30 ++++++++++----- ..._factory_test.TestPlanInfo02.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment03.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment04.approved.json | 38 ++++++++++++------- ...stVirtualMachineDeployment05.approved.json | 20 +++++++--- ...stVirtualMachineDeployment06.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment07.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment08.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment09.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment10.approved.json | 26 +++++++++---- ...stVirtualMachineDeployment11.approved.json | 30 ++++++++++----- ...stVirtualMachineDeployment12.approved.json | 30 ++++++++++----- builder/azure/arm/tempname.go | 8 ++++ builder/azure/arm/tempname_test.go | 35 +++++++++++++++++ .../azure/common/template/template_builder.go | 30 ++++++++++----- ...uilder_test.TestBuildLinux00.approved.json | 38 ++++++++++++------- ...uilder_test.TestBuildLinux01.approved.json | 38 ++++++++++++------- ...uilder_test.TestBuildLinux02.approved.json | 20 +++++++--- ...lder_test.TestBuildWindows00.approved.json | 38 ++++++++++++------- ...lder_test.TestBuildWindows01.approved.json | 30 ++++++++++----- ...lder_test.TestBuildWindows02.approved.json | 30 ++++++++++----- .../common/template/template_parameters.go | 4 ++ website/source/docs/builders/azure.html.md | 4 ++ 27 files changed, 458 insertions(+), 206 deletions(-) diff --git a/builder/azure/arm/TestVirtualMachineDeployment05.approved.txt b/builder/azure/arm/TestVirtualMachineDeployment05.approved.txt index 906820f27..8a8a5d4d4 100644 --- a/builder/azure/arm/TestVirtualMachineDeployment05.approved.txt +++ b/builder/azure/arm/TestVirtualMachineDeployment05.approved.txt @@ -105,8 +105,6 @@ "addressPrefix": "10.0.0.0/16", "apiVersion": "2015-06-15", "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index f2bc66135..cfefa9008 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -29,11 +29,9 @@ type Builder struct { } const ( - DefaultNicName = "packerNic" - DefaultPublicIPAddressName = "packerPublicIP" - DefaultSasBlobContainer = "system/Microsoft.Compute" - DefaultSasBlobPermission = "r" - DefaultSecretName = "packerKeyVaultSecret" + DefaultSasBlobContainer = "system/Microsoft.Compute" + DefaultSasBlobPermission = "r" + DefaultSecretName = "packerKeyVaultSecret" ) func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { @@ -303,8 +301,8 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) { stateBag.Put(constants.ArmKeyVaultDeploymentName, fmt.Sprintf("kv%s", b.config.tmpDeploymentName)) } stateBag.Put(constants.ArmKeyVaultName, b.config.tmpKeyVaultName) - stateBag.Put(constants.ArmNicName, DefaultNicName) - stateBag.Put(constants.ArmPublicIPAddressName, DefaultPublicIPAddressName) + stateBag.Put(constants.ArmNicName, b.config.tmpNicName) + stateBag.Put(constants.ArmPublicIPAddressName, b.config.tmpPublicIPAddressName) if b.config.TempResourceGroupName != "" && b.config.BuildResourceGroupName != "" { stateBag.Put(constants.ArmDoubleResourceGroupNameSet, true) } diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 5584a15bf..55ed7956d 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -130,9 +130,13 @@ type Config struct { tmpCertificatePassword string tmpResourceGroupName string tmpComputeName string + tmpNicName string + tmpPublicIPAddressName string tmpDeploymentName string tmpKeyVaultName string tmpOSDiskName string + tmpSubnetName string + tmpVirtualNetworkName string tmpWinRMCertificateUrl string useDeviceLogin bool @@ -366,7 +370,11 @@ func setRuntimeValues(c *Config) { } else if c.TempResourceGroupName != "" && c.BuildResourceGroupName == "" { c.tmpResourceGroupName = c.TempResourceGroupName } + c.tmpNicName = tempName.NicName + c.tmpPublicIPAddressName = tempName.PublicIPAddressName c.tmpOSDiskName = tempName.OSDiskName + c.tmpSubnetName = tempName.SubnetName + c.tmpVirtualNetworkName = tempName.VirtualNetworkName c.tmpKeyVaultName = tempName.KeyVaultName } diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index 843580fd2..55ed50b01 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -34,13 +34,20 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error) AdminUsername: &template.TemplateParameter{Value: config.UserName}, AdminPassword: &template.TemplateParameter{Value: config.Password}, DnsNameForPublicIP: &template.TemplateParameter{Value: config.tmpComputeName}, + NicName: &template.TemplateParameter{Value: config.tmpNicName}, OSDiskName: &template.TemplateParameter{Value: config.tmpOSDiskName}, + PublicIPAddressName: &template.TemplateParameter{Value: config.tmpPublicIPAddressName}, + SubnetName: &template.TemplateParameter{Value: config.tmpSubnetName}, StorageAccountBlobEndpoint: &template.TemplateParameter{Value: config.storageAccountBlobEndpoint}, - VMSize: &template.TemplateParameter{Value: config.VMSize}, - VMName: &template.TemplateParameter{Value: config.tmpComputeName}, + VirtualNetworkName: &template.TemplateParameter{Value: config.tmpVirtualNetworkName}, + VMSize: &template.TemplateParameter{Value: config.VMSize}, + VMName: &template.TemplateParameter{Value: config.tmpComputeName}, } - builder, _ := template.NewTemplateBuilder(template.BasicTemplate) + builder, err := template.NewTemplateBuilder(template.BasicTemplate) + if err != nil { + return nil, err + } osType := compute.Linux switch config.OSType { diff --git a/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json b/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json index 74546c490..1d2ef2207 100644 --- a/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json +++ b/builder/azure/arm/template_factory_test.TestPlanInfo01.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -73,11 +85,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -85,7 +97,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -105,7 +117,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -126,7 +138,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -177,15 +189,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json b/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json index 8f93bb530..bc3ef83ef 100644 --- a/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json +++ b/builder/azure/arm/template_factory_test.TestPlanInfo02.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -75,11 +87,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -87,7 +99,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -108,7 +120,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -130,7 +142,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -182,15 +194,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json index a220d9822..2a9a429e5 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -148,15 +160,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json index 0be4bbef4..215acda04 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -146,18 +158,16 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworkName": "[parameters('virtualNetworkName')]", + "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - } + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment05.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment05.approved.json index 29c4750c5..c7a73e7ad 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment05.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment05.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -29,7 +41,7 @@ "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -48,7 +60,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -64,7 +76,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -107,9 +119,7 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment06.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment06.approved.json index fb5e79b9f..258fd9261 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment06.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment06.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -71,11 +83,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -83,7 +95,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -102,7 +114,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -118,7 +130,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -166,15 +178,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment07.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment07.approved.json index 6f722c765..8d7101cfe 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment07.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment07.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -147,15 +159,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment08.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment08.approved.json index c567b774c..ae0700880 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment08.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment08.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -146,15 +158,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment09.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment09.approved.json index fbbb7384e..a7baa806f 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment09.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment09.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -149,15 +161,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment10.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment10.approved.json index 0eb130138..8c27336c5 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment10.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment10.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -40,10 +52,10 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]" + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -51,7 +63,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -65,7 +77,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -81,7 +93,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -127,9 +139,7 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json index b5fbfaf2f..4776d5344 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment11.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -160,15 +172,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json index 531b2654b..25449da24 100644 --- a/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment12.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -161,15 +173,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/arm/tempname.go b/builder/azure/arm/tempname.go index 734cd74aa..bf0cb6552 100644 --- a/builder/azure/arm/tempname.go +++ b/builder/azure/arm/tempname.go @@ -19,6 +19,10 @@ type TempName struct { KeyVaultName string ResourceGroupName string OSDiskName string + NicName string + SubnetName string + PublicIPAddressName string + VirtualNetworkName string } func NewTempName() *TempName { @@ -29,6 +33,10 @@ func NewTempName() *TempName { tempName.DeploymentName = fmt.Sprintf("pkrdp%s", suffix) tempName.KeyVaultName = fmt.Sprintf("pkrkv%s", suffix) tempName.OSDiskName = fmt.Sprintf("pkros%s", suffix) + tempName.NicName = fmt.Sprintf("pkrni%s", suffix) + tempName.PublicIPAddressName = fmt.Sprintf("pkrip%s", suffix) + tempName.SubnetName = fmt.Sprintf("pkrsn%s", suffix) + tempName.VirtualNetworkName = fmt.Sprintf("pkrvn%s", suffix) tempName.ResourceGroupName = fmt.Sprintf("packer-Resource-Group-%s", suffix) tempName.AdminPassword = common.RandomString(TempPasswordAlphabet, 32) diff --git a/builder/azure/arm/tempname_test.go b/builder/azure/arm/tempname_test.go index e9a49b429..4c09f8c46 100644 --- a/builder/azure/arm/tempname_test.go +++ b/builder/azure/arm/tempname_test.go @@ -20,15 +20,35 @@ func TestTempNameShouldCreatePrefixedRandomNames(t *testing.T) { t.Errorf("Expected OSDiskName to begin with 'pkros', but got '%s'!", tempName.OSDiskName) } + if strings.Index(tempName.NicName, "pkrni") != 0 { + t.Errorf("Expected NicName to begin with 'pkrni', but got '%s'!", tempName.NicName) + } + + if strings.Index(tempName.PublicIPAddressName, "pkrip") != 0 { + t.Errorf("Expected PublicIPAddressName to begin with 'pkrip', but got '%s'!", tempName.PublicIPAddressName) + } + if strings.Index(tempName.ResourceGroupName, "packer-Resource-Group-") != 0 { t.Errorf("Expected ResourceGroupName to begin with 'packer-Resource-Group-', but got '%s'!", tempName.ResourceGroupName) } + + if strings.Index(tempName.SubnetName, "pkrsn") != 0 { + t.Errorf("Expected SubnetName to begin with 'pkrip', but got '%s'!", tempName.SubnetName) + } + + if strings.Index(tempName.VirtualNetworkName, "pkrvn") != 0 { + t.Errorf("Expected VirtualNetworkName to begin with 'pkrvn', but got '%s'!", tempName.VirtualNetworkName) + } } func TestTempNameShouldHaveSameSuffix(t *testing.T) { tempName := NewTempName() suffix := tempName.ComputeName[5:] + if strings.HasSuffix(tempName.ComputeName, suffix) != true { + t.Errorf("Expected ComputeName to end with '%s', but the value is '%s'!", suffix, tempName.ComputeName) + } + if strings.HasSuffix(tempName.DeploymentName, suffix) != true { t.Errorf("Expected DeploymentName to end with '%s', but the value is '%s'!", suffix, tempName.DeploymentName) } @@ -37,8 +57,23 @@ func TestTempNameShouldHaveSameSuffix(t *testing.T) { t.Errorf("Expected OSDiskName to end with '%s', but the value is '%s'!", suffix, tempName.OSDiskName) } + if strings.HasSuffix(tempName.NicName, suffix) != true { + t.Errorf("Expected NicName to end with '%s', but the value is '%s'!", suffix, tempName.PublicIPAddressName) + } + + if strings.HasSuffix(tempName.PublicIPAddressName, suffix) != true { + t.Errorf("Expected PublicIPAddressName to end with '%s', but the value is '%s'!", suffix, tempName.PublicIPAddressName) + } + if strings.HasSuffix(tempName.ResourceGroupName, suffix) != true { t.Errorf("Expected ResourceGroupName to end with '%s', but the value is '%s'!", suffix, tempName.ResourceGroupName) } + if strings.HasSuffix(tempName.SubnetName, suffix) != true { + t.Errorf("Expected SubnetName to end with '%s', but the value is '%s'!", suffix, tempName.SubnetName) + } + + if strings.HasSuffix(tempName.VirtualNetworkName, suffix) != true { + t.Errorf("Expected VirtualNetworkName to end with '%s', but the value is '%s'!", suffix, tempName.VirtualNetworkName) + } } diff --git a/builder/azure/common/template/template_builder.go b/builder/azure/common/template/template_builder.go index a05b66ab3..b2c15b22f 100644 --- a/builder/azure/common/template/template_builder.go +++ b/builder/azure/common/template/template_builder.go @@ -461,12 +461,24 @@ const BasicTemplate = `{ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, + "subnetName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "virtualNetworkName": { + "type": "string" + }, "vmSize": { "type": "string" }, @@ -482,14 +494,12 @@ const BasicTemplate = `{ "publicIPAddressApiVersion": "2017-04-01", "virtualNetworksApiVersion": "2017-04-01", "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetAddressPrefix": "10.0.0.0/24", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "vmStorageAccountContainerName": "images", "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" @@ -498,7 +508,7 @@ const BasicTemplate = `{ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "type": "Microsoft.Network/publicIPAddresses", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "location": "[variables('location')]", "properties": { "publicIPAllocationMethod": "[variables('publicIPAddressType')]", @@ -531,10 +541,10 @@ const BasicTemplate = `{ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "location": "[variables('location')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "properties": { @@ -544,7 +554,7 @@ const BasicTemplate = `{ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -560,7 +570,7 @@ const BasicTemplate = `{ "name": "[parameters('vmName')]", "location": "[variables('location')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "properties": { "hardwareProfile": { @@ -584,7 +594,7 @@ const BasicTemplate = `{ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, diff --git a/builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json b/builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json index b94fa0628..5a4b69427 100644 --- a/builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json +++ b/builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -148,18 +160,16 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworkName": "[parameters('virtualNetworkName')]", + "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - } + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json b/builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json index 8eac0647d..d23117b48 100644 --- a/builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json +++ b/builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -146,18 +158,16 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworkName": "[parameters('virtualNetworkName')]", + "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - } + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/common/template/template_builder_test.TestBuildLinux02.approved.json b/builder/azure/common/template/template_builder_test.TestBuildLinux02.approved.json index fffb0d7bb..68d1bc427 100644 --- a/builder/azure/common/template/template_builder_test.TestBuildLinux02.approved.json +++ b/builder/azure/common/template/template_builder_test.TestBuildLinux02.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -29,7 +41,7 @@ "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -48,7 +60,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -64,7 +76,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -108,9 +120,7 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", diff --git a/builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json b/builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json index 1c3138deb..cbf46d3e8 100644 --- a/builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json +++ b/builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -162,18 +174,16 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "virtualNetworkResourceGroup": "[resourceGroup().name]", + "virtualNetworkName": "[parameters('virtualNetworkName')]", + "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - } + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId(variables('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json b/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json index b7a145df9..c660dcd75 100644 --- a/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json +++ b/builder/azure/common/template/template_builder_test.TestBuildWindows01.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -185,15 +197,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json b/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json index 61b05a125..0507771ee 100644 --- a/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json +++ b/builder/azure/common/template/template_builder_test.TestBuildWindows02.approved.json @@ -11,12 +11,24 @@ "dnsNameForPublicIP": { "type": "string" }, + "nicName": { + "type": "string" + }, "osDiskName": { "type": "string" }, + "publicIPAddressName": { + "type": "string" + }, "storageAccountBlobEndpoint": { "type": "string" }, + "subnetName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, "vmName": { "type": "string" }, @@ -28,7 +40,7 @@ { "apiVersion": "[variables('publicIPAddressApiVersion')]", "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", + "name": "[parameters('publicIPAddressName')]", "properties": { "dnsSettings": { "domainNameLabel": "[parameters('dnsNameForPublicIP')]" @@ -61,11 +73,11 @@ { "apiVersion": "[variables('networkInterfacesApiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" ], "location": "[variables('location')]", - "name": "[variables('nicName')]", + "name": "[parameters('nicName')]", "properties": { "ipConfigurations": [ { @@ -73,7 +85,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]" }, "subnet": { "id": "[variables('subnetRef')]" @@ -87,7 +99,7 @@ { "apiVersion": "[variables('apiVersion')]", "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]" ], "location": "[variables('location')]", "name": "[parameters('vmName')]", @@ -103,7 +115,7 @@ "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, @@ -178,15 +190,13 @@ "location": "[resourceGroup().location]", "managedDiskApiVersion": "2017-03-30", "networkInterfacesApiVersion": "2017-04-01", - "nicName": "packerNic", "publicIPAddressApiVersion": "2017-04-01", - "publicIPAddressName": "packerPublicIP", "publicIPAddressType": "Dynamic", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", + "subnetName": "[parameters('subnetName')]", "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", + "virtualNetworkName": "[parameters('virtualNetworkName')]", "virtualNetworkResourceGroup": "[resourceGroup().name]", "virtualNetworksApiVersion": "2017-04-01", "vmStorageAccountContainerName": "images", diff --git a/builder/azure/common/template/template_parameters.go b/builder/azure/common/template/template_parameters.go index 424a30c89..65bc55e75 100644 --- a/builder/azure/common/template/template_parameters.go +++ b/builder/azure/common/template/template_parameters.go @@ -24,9 +24,13 @@ type TemplateParameters struct { KeyVaultName *TemplateParameter `json:"keyVaultName,omitempty"` KeyVaultSecretValue *TemplateParameter `json:"keyVaultSecretValue,omitempty"` ObjectId *TemplateParameter `json:"objectId,omitempty"` + NicName *TemplateParameter `json:"nicName,omitempty"` OSDiskName *TemplateParameter `json:"osDiskName,omitempty"` + PublicIPAddressName *TemplateParameter `json:"publicIPAddressName,omitempty"` StorageAccountBlobEndpoint *TemplateParameter `json:"storageAccountBlobEndpoint,omitempty"` + SubnetName *TemplateParameter `json:"subnetName,omitempty"` TenantId *TemplateParameter `json:"tenantId,omitempty"` + VirtualNetworkName *TemplateParameter `json:"virtualNetworkName,omitempty"` VMSize *TemplateParameter `json:"vmSize,omitempty"` VMName *TemplateParameter `json:"vmName,omitempty"` } diff --git a/website/source/docs/builders/azure.html.md b/website/source/docs/builders/azure.html.md index 13b2b46a3..9019e035e 100644 --- a/website/source/docs/builders/azure.html.md +++ b/website/source/docs/builders/azure.html.md @@ -374,9 +374,13 @@ The Azure builder creates the following random values at runtime. - Compute Name: a random 15-character name prefixed with pkrvm; the name of the VM. - Deployment Name: a random 15-character name prefixed with pkfdp; the name of the deployment. - KeyVault Name: a random 15-character name prefixed with pkrkv. +- NIC Name: a random 15-character name prefixed with pkrni. +- Public IP Name: a random 15-character name prefixed with pkrip. - OS Disk Name: a random 15-character name prefixed with pkros. - Resource Group Name: a random 33-character name prefixed with packer-Resource-Group-. +- Subnet Name: a random 15-character name prefixed with pkrsn. - SSH Key Pair: a 2,048-bit asymmetric key pair; can be overridden by the user. +- Virtual Network Name: a random 15-character name prefixed with pkrvn. The default alphabet used for random values is **0123456789bcdfghjklmnpqrstvwxyz**. The alphabet was reduced (no vowels) to prevent running afoul of Azure decency controls. From 2a88672cd96ff29c69ef9b343a8bb64c691554df Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 12 Mar 2018 15:08:19 -0700 Subject: [PATCH 0715/1007] add test for modifyer keypress commands --- .../common/step_type_boot_command_test.go | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 builder/virtualbox/common/step_type_boot_command_test.go diff --git a/builder/virtualbox/common/step_type_boot_command_test.go b/builder/virtualbox/common/step_type_boot_command_test.go new file mode 100644 index 000000000..23a5d9077 --- /dev/null +++ b/builder/virtualbox/common/step_type_boot_command_test.go @@ -0,0 +1,43 @@ +package common + +import ( + "testing" +) + +func TestScancodes(t *testing.T) { + var bootcommand = []string{ + "1234567890-=<enter><wait>", + "!@#$%^&*()_+<enter>", + "qwertyuiop[]<enter>", + "QWERTYUIOP{}<enter>", + "asdfghjkl;'`<enter>", + `ASDFGHJKL:"~<enter>`, + "\\zxcvbnm,./<enter>", + "|ZXCVBNM<>?<enter>", + "<enter>", + "<leftAltOn><esc><leftAltOff><wait5>", + "<tab><tab><tab><tab><tab><spacebar><wait5>", + } + + var expected = [][]string{ + {"02", "82", "03", "83", "04", "84", "05", "85", "06", "86", "07", "87", "08", "88", "09", "89", "0a", "8a", "0b", "8b", "0c", "8c", "0d", "8d", "1c", "9c", "wait"}, + {"2a", "02", "aa", "82", "2a", "03", "aa", "83", "2a", "04", "aa", "84", "2a", "05", "aa", "85", "2a", "06", "aa", "86", "2a", "07", "aa", "87", "2a", "08", "aa", "88", "2a", "09", "aa", "89", "2a", "0a", "aa", "8a", "2a", "0b", "aa", "8b", "2a", "0c", "aa", "8c", "2a", "0d", "aa", "8d", "1c", "9c"}, + {"10", "90", "11", "91", "12", "92", "13", "93", "14", "94", "15", "95", "16", "96", "17", "97", "18", "98", "19", "99", "1a", "9a", "1b", "9b", "1c", "9c"}, + {"2a", "10", "aa", "90", "2a", "11", "aa", "91", "2a", "12", "aa", "92", "2a", "13", "aa", "93", "2a", "14", "aa", "94", "2a", "15", "aa", "95", "2a", "16", "aa", "96", "2a", "17", "aa", "97", "2a", "18", "aa", "98", "2a", "19", "aa", "99", "2a", "1a", "aa", "9a", "2a", "1b", "aa", "9b", "1c", "9c"}, + {"1e", "9e", "1f", "9f", "20", "a0", "21", "a1", "22", "a2", "23", "a3", "24", "a4", "25", "a5", "26", "a6", "27", "a7", "28", "a8", "29", "a9", "1c", "9c"}, + {"2a", "1e", "aa", "9e", "2a", "1f", "aa", "9f", "2a", "20", "aa", "a0", "2a", "21", "aa", "a1", "2a", "22", "aa", "a2", "2a", "23", "aa", "a3", "2a", "24", "aa", "a4", "2a", "25", "aa", "a5", "2a", "26", "aa", "a6", "2a", "27", "aa", "a7", "2a", "28", "aa", "a8", "2a", "29", "aa", "a9", "1c", "9c"}, + {"2b", "ab", "2c", "ac", "2d", "ad", "2e", "ae", "2f", "af", "30", "b0", "31", "b1", "32", "b2", "33", "b3", "34", "b4", "35", "b5", "1c", "9c"}, + {"2a", "2b", "aa", "ab", "2a", "2c", "aa", "ac", "2a", "2d", "aa", "ad", "2a", "2e", "aa", "ae", "2a", "2f", "aa", "af", "2a", "30", "aa", "b0", "2a", "31", "aa", "b1", "2a", "32", "aa", "b2", "2a", "33", "aa", "b3", "2a", "34", "aa", "b4", "2a", "35", "aa", "b5", "1c", "9c"}, + {"1c", "9c"}, + {"38", "01", "81", "b8", "wait5"}, + {"0f", "8f", "0f", "8f", "0f", "8f", "0f", "8f", "0f", "8f", "39", "b9", "wait5"}, + } + + for i, command := range bootcommand { + for j, code := range scancodes(command) { + if code != expected[i][j] { + t.Fatalf("%#v should have become %#v", scancodes(command), expected[i]) + } + } + } +} From f6b1349bf32e505b80f3e695a326d2d6098063dd Mon Sep 17 00:00:00 2001 From: Hariharan Jayaraman <harijay@microsoft.com> Date: Mon, 12 Mar 2018 21:09:53 -0700 Subject: [PATCH 0716/1007] fixing marketplace sample --- examples/azure/marketplace_plan_info.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/azure/marketplace_plan_info.json b/examples/azure/marketplace_plan_info.json index 4891a9e6b..710dda8ee 100644 --- a/examples/azure/marketplace_plan_info.json +++ b/examples/azure/marketplace_plan_info.json @@ -19,9 +19,9 @@ "capture_name_prefix": "packer", "os_type": "Linux", - "image_publisher": "Canonical", - "image_offer": "UbuntuServer", - "image_sku": "16.04-LTS", + "image_publisher": "bitnami", + "image_offer": "rabbitmq", + "image_sku": "rabbitmq", "azure_tags": { "dept": "engineering", From 5c0191828f6f3ba26cf666ef5c1ba5eb01f8586c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:05:56 +0000 Subject: [PATCH 0717/1007] spelling: account --- post-processor/alicloud-import/post-processor.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/post-processor/alicloud-import/post-processor.go b/post-processor/alicloud-import/post-processor.go index 2606e5fdf..4421b170d 100644 --- a/post-processor/alicloud-import/post-processor.go +++ b/post-processor/alicloud-import/post-processor.go @@ -214,7 +214,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac if err != nil { e, _ := err.(*packercommon.Error) - if e.Code == "NoSetRoletoECSServiceAcount" { + if e.Code == "NoSetRoletoECSServiceAccount" { ramClient := ram.NewClient(p.config.AlicloudAccessKey, p.config.AlicloudSecretKey) roleResponse, err := ramClient.GetRole(ram.RoleQueryRequest{ RoleName: "AliyunECSImageImportDefaultRole", @@ -282,7 +282,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac imageId, err = ecsClient.ImportImage(imageImageArgs) if err != nil { e, _ = err.(*packercommon.Error) - if e.Code == "NoSetRoletoECSServiceAcount" { + if e.Code == "NoSetRoletoECSServiceAccount" { time.Sleep(5 * time.Second) continue } else if e.Code == "ImageIsImporting" || From 5e167e3b6d55c0b198bd49fe6af3097827eaa235 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:03:51 +0000 Subject: [PATCH 0718/1007] spelling: accumulates --- helper/multistep/multistep_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/multistep/multistep_test.go b/helper/multistep/multistep_test.go index 25bbeef9b..3ced60d83 100644 --- a/helper/multistep/multistep_test.go +++ b/helper/multistep/multistep_test.go @@ -2,7 +2,7 @@ package multistep import "context" -// A step for testing that accumuluates data into a string slice in the +// A step for testing that accumulates data into a string slice in the // the state bag. It always uses the "data" key in the state bag, and will // initialize it. type TestStepAcc struct { From fe98bcc5a109cf2629c209ca51c2264e7d2fc0b9 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:07:10 +0000 Subject: [PATCH 0719/1007] spelling: address --- builder/alicloud/ecs/step_config_public_ip.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/alicloud/ecs/step_config_public_ip.go b/builder/alicloud/ecs/step_config_public_ip.go index 7e0a246e0..594f85603 100644 --- a/builder/alicloud/ecs/step_config_public_ip.go +++ b/builder/alicloud/ecs/step_config_public_ip.go @@ -10,8 +10,8 @@ import ( ) type stepConfigAlicloudPublicIP struct { - publicIPAdress string - RegionId string + publicIPAddress string + RegionId string } func (s *stepConfigAlicloudPublicIP) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -25,7 +25,7 @@ func (s *stepConfigAlicloudPublicIP) Run(_ context.Context, state multistep.Stat ui.Say(fmt.Sprintf("Error allocating public ip: %s", err)) return multistep.ActionHalt } - s.publicIPAdress = ipaddress + s.publicIPAddress = ipaddress ui.Say(fmt.Sprintf("Allocated public ip address %s.", ipaddress)) state.Put("ipaddress", ipaddress) return multistep.ActionContinue From c38cdd043982f409074aa6bfd3f9becbde1e9e8c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:06:52 +0000 Subject: [PATCH 0720/1007] spelling: administrator --- website/source/docs/provisioners/converge.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/converge.html.md b/website/source/docs/provisioners/converge.html.md index b76652abe..1c06678ed 100644 --- a/website/source/docs/provisioners/converge.html.md +++ b/website/source/docs/provisioners/converge.html.md @@ -59,7 +59,7 @@ Optional parameters: various [configuration template variables](/docs/templates/engine.html) available. -- `prevent_sudo` (boolean) - stop Converge from running with adminstrator +- `prevent_sudo` (boolean) - stop Converge from running with administrator privileges via sudo - `bootstrap_command` (string) - the command used to bootstrap Converge. This From 75a7ceec48062171e5b282cd2a7942638210e072 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:09:12 +0000 Subject: [PATCH 0721/1007] spelling: alicloud --- builder/alicloud/ecs/run_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/alicloud/ecs/run_config.go b/builder/alicloud/ecs/run_config.go index b6098ce5c..2c52bb37b 100644 --- a/builder/alicloud/ecs/run_config.go +++ b/builder/alicloud/ecs/run_config.go @@ -57,7 +57,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } if c.InstanceType == "" { - errs = append(errs, errors.New("An aliclod_instance_type must be specified")) + errs = append(errs, errors.New("An alicloud_instance_type must be specified")) } if c.UserData != "" && c.UserDataFile != "" { From e7a30b4ba2f88cfa40086cb333996adec32878c7 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:11:42 +0000 Subject: [PATCH 0722/1007] spelling: attempt --- command/fix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/fix.go b/command/fix.go index 1a94f5786..e7cfac9ea 100644 --- a/command/fix.go +++ b/command/fix.go @@ -85,7 +85,7 @@ func (c *FixCommand) Run(args []string) int { c.Ui.Say(result) if flagValidate { - // Attemot to parse and validate the template + // Attempt to parse and validate the template tpl, err := template.Parse(strings.NewReader(result)) if err != nil { c.Ui.Error(fmt.Sprintf( From 7895051962b62e40fb01b15b4b701e4a6fd9e935 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:12:16 +0000 Subject: [PATCH 0723/1007] spelling: attribute --- builder/alicloud/ecs/step_run_instance.go | 4 ++-- builder/oracle/classic/config.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/alicloud/ecs/step_run_instance.go b/builder/alicloud/ecs/step_run_instance.go index 72491dd1d..57a799183 100644 --- a/builder/alicloud/ecs/step_run_instance.go +++ b/builder/alicloud/ecs/step_run_instance.go @@ -43,8 +43,8 @@ func (s *stepRunAlicloudInstance) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) client := state.Get("client").(*ecs.Client) instance := state.Get("instance").(*ecs.InstanceAttributesType) - instanceAttrubite, _ := client.DescribeInstanceAttribute(instance.InstanceId) - if instanceAttrubite.Status == ecs.Starting || instanceAttrubite.Status == ecs.Running { + instanceAttribute, _ := client.DescribeInstanceAttribute(instance.InstanceId) + if instanceAttribute.Status == ecs.Starting || instanceAttribute.Status == ecs.Running { if err := client.StopInstance(instance.InstanceId, true); err != nil { ui.Say(fmt.Sprintf("Error stopping instance %s, it may still be around %s", instance.InstanceId, err)) return diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index b9f5d808f..a483c8e50 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -33,7 +33,7 @@ type Config struct { SourceImageList string `mapstructure:"source_image_list"` SnapshotTimeout time.Duration `mapstructure:"snapshot_timeout"` DestImageList string `mapstructure:"dest_image_list"` - // Attributes and Atributes file are both optional and mutually exclusive. + // Attributes and Attributes file are both optional and mutually exclusive. Attributes string `mapstructure:"attributes"` AttributesFile string `mapstructure:"attributes_file"` // Optional; if you don't enter anything, the image list description @@ -129,7 +129,7 @@ func NewConfig(raws ...interface{}) (*Config, error) { err = json.Unmarshal(fidata, &data) c.attribs = data if err != nil { - err = fmt.Errorf("Problem parsing json from attrinutes_file: %s", err) + err = fmt.Errorf("Problem parsing json from attributes_file: %s", err) packer.MultiErrorAppend(errs, err) } c.attribs = data From c312493c387fe7522f631ee8322fc625d8fb569a Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:13:24 +0000 Subject: [PATCH 0724/1007] spelling: available --- examples/alicloud/chef/chef.sh | 2 +- post-processor/vagrant/post-processor.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/alicloud/chef/chef.sh b/examples/alicloud/chef/chef.sh index 6d678b7cc..3e3144561 100644 --- a/examples/alicloud/chef/chef.sh +++ b/examples/alicloud/chef/chef.sh @@ -1,5 +1,5 @@ #!/bin/sh -#if the related deb pkg not found, please replace with it other avaiable repository url +#if the related deb pkg not found, please replace with it other available repository url HOSTNAME=`ifconfig eth1|grep 'inet addr'|cut -d ":" -f2|cut -d " " -f1` if [ not $HOSTNAME ] ; then HOSTNAME=`ifconfig eth0|grep 'inet addr'|cut -d ":" -f2|cut -d " " -f1` diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index de93628c0..d4b587316 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -246,7 +246,7 @@ func providerForName(name string) Provider { } } -// OutputPathTemplate is the structure that is availalable within the +// OutputPathTemplate is the structure that is available within the // OutputPath variables. type outputPathTemplate struct { ArtifactId string From f362789174140601fc5d07fd5ed788eabb51308f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:15:08 +0000 Subject: [PATCH 0725/1007] spelling: because --- builder/oracle/classic/step_security.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 892695f83..a4b547d27 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -53,7 +53,7 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste application = "/oracle/public/ssh" } else if commType == "WINRM" { // Check to see whether a winRM security protocol is already defined; - // don't need to do this for SSH becasue it is built into the Oracle API. + // don't need to do this for SSH because it is built into the Oracle API. protocolClient := client.SecurityProtocols() winrmProtocol := fmt.Sprintf("WINRM_%s", runUUID) input := compute.CreateSecurityProtocolInput{ From 9434b0fed852323907b4bf3dc4fc249aba12e77f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:19:04 +0000 Subject: [PATCH 0726/1007] spelling: builder --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cc52892f..f7bc2926d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1321,7 +1321,7 @@ * builder/parallels: Support Parallels Desktop 11. [GH-2199] * builder/openstack: Add `rackconnect_wait` for Rackspace customers to wait for RackConnect data to appear -* buidler/openstack: Add `ssh_interface` option for rackconnect for users that +* builder/openstack: Add `ssh_interface` option for rackconnect for users that have prohibitive firewalls * builder/openstack: Flavor names can be used as well as refs * builder/openstack: Add `availability_zone` [GH-2016] From 5010bfda39811c46e27c09fe9e03b230a66942e9 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:20:55 +0000 Subject: [PATCH 0727/1007] spelling: comes --- builder/openstack/step_key_pair_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/openstack/step_key_pair_test.go b/builder/openstack/step_key_pair_test.go index 0ce45d6a7..891ad3cdc 100644 --- a/builder/openstack/step_key_pair_test.go +++ b/builder/openstack/step_key_pair_test.go @@ -81,7 +81,7 @@ func TestBerToDer(t *testing.T) { Writer: msg, } - // Test - a DER encoded key commes back unchanged. + // Test - a DER encoded key comes back unchanged. newKey := berToDer(der_encoded_key, ui) if newKey != der_encoded_key { t.Errorf("Trying to convert a DER encoded key should return the same key.") From 47a4bbd9f592222db03f10a16c33398758522c6c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:22:09 +0000 Subject: [PATCH 0728/1007] spelling: compaction --- builder/parallels/common/driver_9.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/parallels/common/driver_9.go b/builder/parallels/common/driver_9.go index b6757d891..cfdee4a5d 100644 --- a/builder/parallels/common/driver_9.go +++ b/builder/parallels/common/driver_9.go @@ -119,7 +119,7 @@ func getAppPath(bundleID string) (string, error) { return pathOutput, nil } -// CompactDisk performs the compation of the specified virtual disk image. +// CompactDisk performs the compaction of the specified virtual disk image. func (d *Parallels9Driver) CompactDisk(diskPath string) error { prlDiskToolPath, err := exec.LookPath("prl_disk_tool") if err != nil { From f6745897c5100fc536e2a36e2b75d76ad66b9e4c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:21:31 +0000 Subject: [PATCH 0729/1007] spelling: compute --- post-processor/checksum/post-processor_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/post-processor/checksum/post-processor_test.go b/post-processor/checksum/post-processor_test.go index fb4d0faf1..6b4420d39 100644 --- a/post-processor/checksum/post-processor_test.go +++ b/post-processor/checksum/post-processor_test.go @@ -35,7 +35,7 @@ func TestChecksumSHA1(t *testing.T) { t.Errorf("Unable to read checksum file: %s", err) } if buf, _ := ioutil.ReadAll(f); !bytes.Equal(buf, []byte("d3486ae9136e7856bc42212385ea797094475802\tpackage.txt\n")) { - t.Errorf("Failed to compate checksum: %s\n%s", buf, "d3486ae9136e7856bc42212385ea797094475802 package.txt") + t.Errorf("Failed to compute checksum: %s\n%s", buf, "d3486ae9136e7856bc42212385ea797094475802 package.txt") } defer f.Close() From 935c8e9a2827b429a4c38ff729f35293f81a55b2 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:19:16 +0000 Subject: [PATCH 0730/1007] spelling: configuration --- builder/parallels/common/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/parallels/common/driver.go b/builder/parallels/common/driver.go index b485d5b67..ac23a7880 100644 --- a/builder/parallels/common/driver.go +++ b/builder/parallels/common/driver.go @@ -51,7 +51,7 @@ type Driver interface { // Send scancodes to the vm using the prltype python script. SendKeyScanCodes(string, ...string) error - // Apply default сonfiguration settings to the virtual machine + // Apply default configuration settings to the virtual machine SetDefaultConfiguration(string) error // Finds the MAC address of the NIC nic0 From faf7928a4105676d1127859201c59aaca1d5ad77 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:22:23 +0000 Subject: [PATCH 0731/1007] spelling: conservative --- contrib/azure-setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index ef855b353..8ccd0cbc0 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -182,7 +182,7 @@ createServicePrincipal() { createPermissions() { echo "==> Creating permissions" az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id - # If the user wants to use a more conserative scope, she can. She must + # If the user wants to use a more conservative scope, she can. She must # configure the Azure builder to use build_resource_group_name. The # easiest solution is subscription wide permission. # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" From efb525f03ddd92f768d7946280b7097367ef1a42 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:22:37 +0000 Subject: [PATCH 0732/1007] spelling: creating --- builder/hyperv/common/step_create_external_switch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/common/step_create_external_switch.go b/builder/hyperv/common/step_create_external_switch.go index 56e6fa6e8..52626afce 100644 --- a/builder/hyperv/common/step_create_external_switch.go +++ b/builder/hyperv/common/step_create_external_switch.go @@ -23,7 +23,7 @@ func (s *StepCreateExternalSwitch) Run(_ context.Context, state multistep.StateB ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) - errorMsg := "Error createing external switch: %s" + errorMsg := "Error creating external switch: %s" var err error ui.Say("Creating external switch...") From 684a3f5d8a80e2c8da6a55d39e3076771571e1dc Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:26:33 +0000 Subject: [PATCH 0733/1007] spelling: custom --- provisioner/salt-masterless/provisioner_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/salt-masterless/provisioner_test.go b/provisioner/salt-masterless/provisioner_test.go index bad83b3f6..166e17f96 100644 --- a/provisioner/salt-masterless/provisioner_test.go +++ b/provisioner/salt-masterless/provisioner_test.go @@ -49,7 +49,7 @@ func TestProvisionerPrepare_InvalidKey(t *testing.T) { } } -func TestProvisionerPrepare_CustomeState(t *testing.T) { +func TestProvisionerPrepare_CustomState(t *testing.T) { var p Provisioner config := testConfig() From 0cff0f2f848c981c77e613d30c9ec68ac46c34ae Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:35:21 +0000 Subject: [PATCH 0734/1007] spelling: default --- website/source/docs/builders/hyperv-iso.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index e1454fea7..094e46bcb 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -101,7 +101,7 @@ can be configured for this builder. source is a vhd/vhdx. This defaults to false. - `skip_export` (boolean) - If true skips VM export. If you are interested only in the vhd/vhdx files, you can enable this option. This will create - inline disks which improves the build performance. There will not be any copying of source vhds to temp directory. This defauls to false. + inline disks which improves the build performance. There will not be any copying of source vhds to temp directory. This defaults to false. - `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual machine. This defaults to false. From dfcd5742ccfc308e3451bfaa2d6480a1aec6eac9 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:35:31 +0000 Subject: [PATCH 0735/1007] spelling: defined --- website/source/docs/builders/profitbricks.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/profitbricks.html.md b/website/source/docs/builders/profitbricks.html.md index bbb691bab..2b4bc4bc5 100644 --- a/website/source/docs/builders/profitbricks.html.md +++ b/website/source/docs/builders/profitbricks.html.md @@ -25,9 +25,9 @@ builder. - `image` (string) - ProfitBricks volume image. Only Linux public images are supported. To obtain full list of available images you can use [ProfitBricks CLI](https://github.com/profitbricks/profitbricks-cli#image). -- `password` (string) - ProfitBricks password. This can be specified via environment variable \`PROFITBRICKS\_PASSWORD', if provided. The value definded in the config has precedence over environemnt variable. +- `password` (string) - ProfitBricks password. This can be specified via environment variable \`PROFITBRICKS\_PASSWORD', if provided. The value defined in the config has precedence over environemnt variable. -- `username` (string) - ProfitBricks username. This can be specified via environment variable \`PROFITBRICKS\_USERNAME', if provided. The value definded in the config has precedence over environemnt variable. +- `username` (string) - ProfitBricks username. This can be specified via environment variable \`PROFITBRICKS\_USERNAME', if provided. The value defined in the config has precedence over environemnt variable. ### Optional From 939e7d5587fc28b4f0f2b7a9f50c97e21fb147e9 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:36:38 +0000 Subject: [PATCH 0736/1007] spelling: delete --- builder/alicloud/ecs/builder.go | 6 +++--- builder/alicloud/ecs/image_config.go | 4 ++-- builder/alicloud/ecs/step_delete_images_snapshots.go | 8 ++++---- post-processor/alicloud-import/post-processor.go | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/builder/alicloud/ecs/builder.go b/builder/alicloud/ecs/builder.go index 08a7dad08..7269bd3f0 100644 --- a/builder/alicloud/ecs/builder.go +++ b/builder/alicloud/ecs/builder.go @@ -89,7 +89,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps = []multistep.Step{ &stepPreValidate{ AlicloudDestImageName: b.config.AlicloudImageName, - ForceDelete: b.config.AlicloudImageForceDetele, + ForceDelete: b.config.AlicloudImageForceDelete, }, &stepCheckAlicloudSourceImage{ SourceECSImageId: b.config.AlicloudSourceImage, @@ -165,8 +165,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ForceStop: b.config.ForceStopInstance, }, &stepDeleteAlicloudImageSnapshots{ - AlicloudImageForceDeteleSnapshots: b.config.AlicloudImageForceDeteleSnapshots, - AlicloudImageForceDetele: b.config.AlicloudImageForceDetele, + AlicloudImageForceDeleteSnapshots: b.config.AlicloudImageForceDeleteSnapshots, + AlicloudImageForceDelete: b.config.AlicloudImageForceDelete, AlicloudImageName: b.config.AlicloudImageName, }, &stepCreateAlicloudImage{}, diff --git a/builder/alicloud/ecs/image_config.go b/builder/alicloud/ecs/image_config.go index b987558f9..d747009ef 100644 --- a/builder/alicloud/ecs/image_config.go +++ b/builder/alicloud/ecs/image_config.go @@ -32,8 +32,8 @@ type AlicloudImageConfig struct { AlicloudImageUNShareAccounts []string `mapstructure:"image_unshare_account"` AlicloudImageDestinationRegions []string `mapstructure:"image_copy_regions"` AlicloudImageDestinationNames []string `mapstructure:"image_copy_names"` - AlicloudImageForceDetele bool `mapstructure:"image_force_delete"` - AlicloudImageForceDeteleSnapshots bool `mapstructure:"image_force_delete_snapshots"` + AlicloudImageForceDelete bool `mapstructure:"image_force_delete"` + AlicloudImageForceDeleteSnapshots bool `mapstructure:"image_force_delete_snapshots"` AlicloudImageForceDeleteInstances bool `mapstructure:"image_force_delete_instances"` AlicloudImageSkipRegionValidation bool `mapstructure:"skip_region_validation"` AlicloudDiskDevices `mapstructure:",squash"` diff --git a/builder/alicloud/ecs/step_delete_images_snapshots.go b/builder/alicloud/ecs/step_delete_images_snapshots.go index d3f6139f0..9e294c45f 100644 --- a/builder/alicloud/ecs/step_delete_images_snapshots.go +++ b/builder/alicloud/ecs/step_delete_images_snapshots.go @@ -12,8 +12,8 @@ import ( ) type stepDeleteAlicloudImageSnapshots struct { - AlicloudImageForceDetele bool - AlicloudImageForceDeteleSnapshots bool + AlicloudImageForceDelete bool + AlicloudImageForceDeleteSnapshots bool AlicloudImageName string } @@ -23,7 +23,7 @@ func (s *stepDeleteAlicloudImageSnapshots) Run(_ context.Context, state multiste config := state.Get("config").(Config) ui.Say("Deleting image snapshots.") // Check for force delete - if s.AlicloudImageForceDetele { + if s.AlicloudImageForceDelete { images, _, err := client.DescribeImages(&ecs.DescribeImagesArgs{ RegionId: common.Region(config.AlicloudRegion), ImageName: s.AlicloudImageName, @@ -43,7 +43,7 @@ func (s *stepDeleteAlicloudImageSnapshots) Run(_ context.Context, state multiste ui.Error(err.Error()) return multistep.ActionHalt } - if s.AlicloudImageForceDeteleSnapshots { + if s.AlicloudImageForceDeleteSnapshots { for _, diskDevice := range image.DiskDeviceMappings.DiskDeviceMapping { if err := client.DeleteSnapshot(diskDevice.SnapshotId); err != nil { err := fmt.Errorf("Deleting ECS snapshot failed: %s", err) diff --git a/post-processor/alicloud-import/post-processor.go b/post-processor/alicloud-import/post-processor.go index 4421b170d..853e97ef1 100644 --- a/post-processor/alicloud-import/post-processor.go +++ b/post-processor/alicloud-import/post-processor.go @@ -60,7 +60,7 @@ type Config struct { Architecture string `mapstructure:"image_architecture"` Size string `mapstructure:"image_system_size"` Format string `mapstructure:"format"` - AlicloudImageForceDetele bool `mapstructure:"image_force_delete"` + AlicloudImageForceDelete bool `mapstructure:"image_force_delete"` ctx interpolate.Context } @@ -160,7 +160,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac getEndPonit(p.config.OSSBucket), p.config.OSSKey, err) } - if len(images) > 0 && !p.config.AlicloudImageForceDetele { + if len(images) > 0 && !p.config.AlicloudImageForceDelete { return nil, false, fmt.Errorf("Duplicated image exists, please delete the existing images " + "or set the 'image_force_delete' value as true") } @@ -185,7 +185,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac if err != nil { return nil, false, fmt.Errorf("Failed to upload image %s: %s", source, err) } - if len(images) > 0 && p.config.AlicloudImageForceDetele { + if len(images) > 0 && p.config.AlicloudImageForceDelete { if err = ecsClient.DeleteImage(packercommon.Region(p.config.AlicloudRegion), images[0].ImageId); err != nil { return nil, false, fmt.Errorf("Delete duplicated image %s failed", images[0].ImageName) From e4c56e3cbd0568bd4bb6824fad3208d30c4bdf5a Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:35:45 +0000 Subject: [PATCH 0737/1007] spelling: delimiters --- website/source/docs/builders/hyperv-iso.html.md | 2 +- website/source/docs/builders/hyperv-vmcx.html.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index 094e46bcb..8e481bcad 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -221,7 +221,7 @@ can be configured for this builder. - `mac_address` (string) - This allows a specific MAC address to be used on the default virtual network card. The MAC address must be a string with no - delimeters, for example "0000deadbeef". + delimiters, for example "0000deadbeef". - `vm_name` (string) - This is the name of the virtual machine for the new virtual machine, without the file extension. By default this is "packer-BUILDNAME", diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index a7afe93ce..f43372c65 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -227,7 +227,7 @@ can be configured for this builder. - `mac_address` (string) - This allows a specific MAC address to be used on the default virtual network card. The MAC address must be a string with no - delimeters, for example "0000deadbeef". + delimiters, for example "0000deadbeef". - `vm_name` (string) - This is the name of the virtual machine for the new virtual machine, without the file extension. By default this is From 9d26e6dd8670ebede82129ee3f59e55213de06a4 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:36:15 +0000 Subject: [PATCH 0738/1007] spelling: descriptive --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7bc2926d..93421f139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1598,7 +1598,7 @@ manager certs. [GH-1137] * builder/amazon/all: `delete_on_termination` set to false will work. * builder/amazon/all: Fix race condition on setting tags. [GH-1367] -* builder/amazon/all: More desctriptive error messages if Amazon only +* builder/amazon/all: More descriptive error messages if Amazon only sends an error code. [GH-1189] * builder/docker: Error if `DOCKER_HOST` is set. * builder/docker: Remove the container during cleanup. [GH-1206] From 60ef3c3374487ff5f0ec5a293505d327bbb73d12 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:37:32 +0000 Subject: [PATCH 0739/1007] spelling: directories --- builder/hyperv/common/step_create_tempdir.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/common/step_create_tempdir.go b/builder/hyperv/common/step_create_tempdir.go index 1a9767fe5..b445a4702 100644 --- a/builder/hyperv/common/step_create_tempdir.go +++ b/builder/hyperv/common/step_create_tempdir.go @@ -11,7 +11,7 @@ import ( ) type StepCreateTempDir struct { - // The user-supplied root directores into which we create subdirectories. + // The user-supplied root directories into which we create subdirectories. TempPath string VhdTempPath string // The subdirectories with the randomly generated name. From 8dfafa6a5eaa14bd0ef2b0fea66f65dc716f3d55 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:38:01 +0000 Subject: [PATCH 0740/1007] spelling: dispatchable --- packer/build_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/build_test.go b/packer/build_test.go index 8fe7bc5af..dd78bf4e7 100644 --- a/packer/build_test.go +++ b/packer/build_test.go @@ -191,7 +191,7 @@ func TestBuild_Run(t *testing.T) { t.Fatal("should be called") } - // Verify hooks are disapatchable + // Verify hooks are dispatchable dispatchHook := builder.RunHook dispatchHook.Run("foo", nil, nil, 42) From 76a7258bb46def460bef316d874ea6311f8d99b4 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:39:36 +0000 Subject: [PATCH 0741/1007] spelling: documentation --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93421f139..c99b822be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2425,7 +2425,7 @@ * Amazon EBS builder can now optionally use a pre-made security group instead of randomly generating one. * DigitalOcean API key and client IDs can now be passed in as - environmental variables. See the documentatin for more details. + environmental variables. See the documentation for more details. * VirtualBox and VMware can now have `floppy_files` specified to attach floppy disks when booting. This allows for unattended Windows installs. * `packer build` has a new `-force` flag that forces the removal of From 83471c8399aa6a9ec2b8e862e1f4129b416dec2f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:39:58 +0000 Subject: [PATCH 0742/1007] spelling: doesn't --- builder/lxd/step_lxd_launch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index de34a5cb4..7549a408d 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -31,7 +31,7 @@ func (s *stepLxdLaunch) Run(_ context.Context, state multistep.StateBag) multist return multistep.ActionHalt } // TODO: Should we check `lxc info <container>` for "Running"? - // We have to do this so /tmp doens't get cleared and lose our provisioner scripts. + // We have to do this so /tmp doesn't get cleared and lose our provisioner scripts. time.Sleep(1 * time.Second) return multistep.ActionContinue From e2f279dbaa047bacaccc992b396526357a1925d1 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:40:16 +0000 Subject: [PATCH 0743/1007] spelling: download --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c99b822be..b584f16a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2274,11 +2274,11 @@ * builder/amazon-instance: send IAM instance profile data. [GH-294] * builder/digitalocean: API request parameters are properly URL encoded. [GH-281] -* builder/virtualbox: dowload progress won't be shown until download +* builder/virtualbox: download progress won't be shown until download actually starts. [GH-288] * builder/virtualbox: floppy files names of 13 characters are now properly written to the FAT12 filesystem. [GH-285] -* builder/vmware: dowload progress won't be shown until download +* builder/vmware: download progress won't be shown until download actually starts. [GH-288] * builder/vmware: interrupt works while typing commands over VNC. * builder/virtualbox: floppy files names of 13 characters are now properly From 785b42368d234eed985b87834eadd79de477ab97 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:40:52 +0000 Subject: [PATCH 0744/1007] spelling: easily --- packer/ui_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/ui_test.go b/packer/ui_test.go index 76d0cd5b5..ef14985ec 100644 --- a/packer/ui_test.go +++ b/packer/ui_test.go @@ -215,7 +215,7 @@ func TestBasicUi_Ask(t *testing.T) { } for _, testCase := range testCases { - // Because of the internal bufio we can't eaily reset the input, so create a new one each time + // Because of the internal bufio we can't easily reset the input, so create a new one each time bufferUi := testUi() writeReader(bufferUi, testCase.Input) From 9b9ab4c492c417e835917a6c78b26871031e3684 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:41:47 +0000 Subject: [PATCH 0745/1007] spelling: encrypt --- builder/oracle/oci/client/config_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/oracle/oci/client/config_test.go b/builder/oracle/oci/client/config_test.go index 154fe1ec2..1be34c5f0 100644 --- a/builder/oracle/oci/client/config_test.go +++ b/builder/oracle/oci/client/config_test.go @@ -144,7 +144,7 @@ func TestParseEncryptedPrivateKeyValidPassword(t *testing.T) { password, cipherType) if err != nil { - t.Fatalf("Unexpected error encryting PEM block: %+v", err) + t.Fatalf("Unexpected error encrypting PEM block: %+v", err) } // Parse private key @@ -195,7 +195,7 @@ func TestParseEncryptedPrivateKeyPKCS8(t *testing.T) { password, cipherType) if err != nil { - t.Fatalf("Unexpected error encryting PEM block: %+v", err) + t.Fatalf("Unexpected error encrypting PEM block: %+v", err) } // Parse private key From 04d6bfc696c5fd2b9e474efe977064a535f983c6 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:41:21 +0000 Subject: [PATCH 0746/1007] spelling: environment --- CHANGELOG.md | 2 +- builder/azure/arm/config.go | 2 +- examples/alicloud/jenkins/jenkins.sh | 2 +- provisioner/powershell/provisioner.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b584f16a8..9707c60cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2228,7 +2228,7 @@ * core: All HTTP downloads across Packer now support the standard proxy environmental variables (`HTTP_PROXY`, `NO_PROXY`, etc.) [GH-252] * builder/amazon: API requests will use HTTP proxy if specified by - enviromental variables. + environmental variables. * builder/digitalocean: API requests will use HTTP proxy if specified by environmental variables. diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 5584a15bf..65c276a68 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -410,7 +410,7 @@ func setCloudEnvironment(c *Config) error { name := strings.ToUpper(c.CloudEnvironmentName) envName, ok := lookup[name] if !ok { - return fmt.Errorf("There is no cloud envionment matching the name '%s'!", c.CloudEnvironmentName) + return fmt.Errorf("There is no cloud environment matching the name '%s'!", c.CloudEnvironmentName) } env, err := azure.EnvironmentFromName(envName) diff --git a/examples/alicloud/jenkins/jenkins.sh b/examples/alicloud/jenkins/jenkins.sh index af3eb51a3..72972c24e 100644 --- a/examples/alicloud/jenkins/jenkins.sh +++ b/examples/alicloud/jenkins/jenkins.sh @@ -32,7 +32,7 @@ mv $TOMCAT_NAME /opt wget $JENKINS_URL mv jenkins.war $TOMCAT_PATH/webapps/ -#set emvironment +#set environment echo "TOMCAT_PATH=\"$TOMCAT_PATH\"">>/etc/profile echo "JENKINS_HOME=\"$TOMCAT_PATH/webapps/jenkins\"">>/etc/profile echo PATH="\"\$PATH:\$TOMCAT_PATH:\$JENKINS_HOME\"">>/etc/profile diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 07b10def9..9655f6fed 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -338,7 +338,7 @@ func (p *Provisioner) retryable(f func() error) error { } } -// Enviroment variables required within the remote environment are uploaded within a PS script and +// Environment variables required within the remote environment are uploaded within a PS script and // then enabled by 'dot sourcing' the script immediately prior to execution of the main command func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err error) { // Collate all required env vars into a plain string with required formatting applied From fc99dc25ae710b81ff0f353eefc9ae2fea6ba26f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:45:13 +0000 Subject: [PATCH 0747/1007] spelling: error --- communicator/ssh/communicator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index b5b67633c..0e198cb0d 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -748,7 +748,7 @@ func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) er err = session.Wait() if err != nil { if exitErr, ok := err.(*ssh.ExitError); ok { - // Otherwise, we have an ExitErorr, meaning we can just read + // Otherwise, we have an ExitError, meaning we can just read // the exit status log.Printf("non-zero exit status: %d", exitErr.ExitStatus()) stdoutB, err := ioutil.ReadAll(stdoutR) From 33bf6de9216503ba9af890604a7609e628481b73 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:46:49 +0000 Subject: [PATCH 0748/1007] spelling: exceeds --- builder/cloudstack/step_create_instance.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/cloudstack/step_create_instance.go b/builder/cloudstack/step_create_instance.go index 19f6a3c28..343d36c35 100644 --- a/builder/cloudstack/step_create_instance.go +++ b/builder/cloudstack/step_create_instance.go @@ -226,7 +226,7 @@ func (s *stepCreateInstance) generateUserData(userData string, httpGETOnly bool) if len(ud) > maxUD { return "", fmt.Errorf( "The supplied user_data contains %d bytes after encoding, "+ - "this exeeds the limit of %d bytes", len(ud), maxUD) + "this exceeds the limit of %d bytes", len(ud), maxUD) } return ud, nil From 041a115f6598cbb5d7c0a72136ab85df729d33ef Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:15:56 +0000 Subject: [PATCH 0749/1007] spelling: existent --- CHANGELOG.md | 2 +- builder/parallels/iso/builder_test.go | 2 +- builder/parallels/pvm/config_test.go | 2 +- builder/virtualbox/ovf/config_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9707c60cb..15368d2c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -658,7 +658,7 @@ * builder/amazon: Crashes when new EBS vols are used. [GH-4308] * builder/amazon: Fix crash in amazon-instance. [GH-4372] * builder/amazon: fix run volume tagging [GH-4420] -* builder/amazon: fix when using non-existant security\_group\_id. [GH-4425] +* builder/amazon: fix when using non-existent security\_group\_id. [GH-4425] * builder/amazon: Properly error if we don't have the ec2:DescribeSecurityGroups permission. [GH-4304] * builder/amazon: Properly wait for security group to exist. [GH-4369] diff --git a/builder/parallels/iso/builder_test.go b/builder/parallels/iso/builder_test.go index b4b9eb917..88a28144e 100644 --- a/builder/parallels/iso/builder_test.go +++ b/builder/parallels/iso/builder_test.go @@ -86,7 +86,7 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) { func TestBuilderPrepare_InvalidFloppies(t *testing.T) { var b Builder config := testConfig() - config["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"} + config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"} b = Builder{} _, errs := b.Prepare(config) if errs == nil { diff --git a/builder/parallels/pvm/config_test.go b/builder/parallels/pvm/config_test.go index c6c36a0b4..8c869c9fd 100644 --- a/builder/parallels/pvm/config_test.go +++ b/builder/parallels/pvm/config_test.go @@ -84,7 +84,7 @@ func TestNewConfig_FloppyFiles(t *testing.T) { func TestNewConfig_InvalidFloppies(t *testing.T) { c := testConfig(t) - c["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"} + c["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"} _, _, errs := NewConfig(c) if errs == nil { t.Fatalf("Nonexistent floppies should trigger multierror") diff --git a/builder/virtualbox/ovf/config_test.go b/builder/virtualbox/ovf/config_test.go index 51412a0c5..e36c44fcf 100644 --- a/builder/virtualbox/ovf/config_test.go +++ b/builder/virtualbox/ovf/config_test.go @@ -73,7 +73,7 @@ func TestNewConfig_sourcePath(t *testing.T) { t.Fatalf("bad: %#v", warns) } if err == nil { - t.Fatalf("Nonexistant file should throw a validation error!") + t.Fatalf("Nonexistent file should throw a validation error!") } // Bad From 466f0d2be415c1c6fe0f957adbb8877d2258a37c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:49:46 +0000 Subject: [PATCH 0750/1007] spelling: firewall --- builder/cloudstack/step_configure_networking.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/cloudstack/step_configure_networking.go b/builder/cloudstack/step_configure_networking.go index ff37a540a..4dba63ef7 100644 --- a/builder/cloudstack/step_configure_networking.go +++ b/builder/cloudstack/step_configure_networking.go @@ -187,7 +187,7 @@ func (s *stepSetupNetworking) Cleanup(state multistep.StateBag) { // Create a new parameter struct. p := client.Firewall.NewDeleteFirewallRuleParams(fwRuleID) - ui.Message("Deleting firewal rule...") + ui.Message("Deleting firewall rule...") if _, err := client.Firewall.DeleteFirewallRule(p); err != nil { // This is a very poor way to be told the ID does no longer exist :( if !strings.Contains(err.Error(), fmt.Sprintf( From dc942a0d8ade51a81c64e543d558dacb2cb0b529 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:50:00 +0000 Subject: [PATCH 0751/1007] spelling: first --- builder/parallels/common/driver_9.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/parallels/common/driver_9.go b/builder/parallels/common/driver_9.go index cfdee4a5d..b8b697ba1 100644 --- a/builder/parallels/common/driver_9.go +++ b/builder/parallels/common/driver_9.go @@ -43,7 +43,7 @@ func (d *Parallels9Driver) Import(name, srcPath, dstDir string, reassignMAC bool srcMAC := "auto" if !reassignMAC { - srcMAC, err = getFirtsMACAddress(srcPath) + srcMAC, err = getFirstMACAddress(srcPath) if err != nil { return err } @@ -70,7 +70,7 @@ func getVMID(path string) (string, error) { return getConfigValueFromXpath(path, "/ParallelsVirtualMachine/Identification/VmUuid") } -func getFirtsMACAddress(path string) (string, error) { +func getFirstMACAddress(path string) (string, error) { return getConfigValueFromXpath(path, "/ParallelsVirtualMachine/Hardware/NetworkAdapter[@id='0']/MAC") } From b545c6f87e0ec1b617e2d7083d4a5cd586b846be Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:50:25 +0000 Subject: [PATCH 0752/1007] spelling: flattened --- provisioner/windows-shell/provisioner.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/provisioner/windows-shell/provisioner.go b/provisioner/windows-shell/provisioner.go index 585fa437c..babc9b5ec 100644 --- a/provisioner/windows-shell/provisioner.go +++ b/provisioner/windows-shell/provisioner.go @@ -203,11 +203,11 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { defer f.Close() // Create environment variables to set before executing the command - flattendVars := p.createFlattenedEnvVars() + flattenedVars := p.createFlattenedEnvVars() // Compile the command p.config.ctx.Data = &ExecuteCommandTemplate{ - Vars: flattendVars, + Vars: flattenedVars, Path: p.config.RemotePath, } command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) From 24b4c36fc9a23b9ded5be57605e3a1dd23d2e481 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:52:02 +0000 Subject: [PATCH 0753/1007] spelling: function --- builder/ncloud/step_validate_template.go | 4 ++-- provisioner/powershell/provisioner_test.go | 4 ++-- provisioner/windows-shell/provisioner_test.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/builder/ncloud/step_validate_template.go b/builder/ncloud/step_validate_template.go index c63c5f04b..f00525e5c 100644 --- a/builder/ncloud/step_validate_template.go +++ b/builder/ncloud/step_validate_template.go @@ -25,7 +25,7 @@ type StepValidateTemplate struct { FeeSystemTypeCode string } -// NewStepValidateTemplate : funciton for Validation a tempalte +// NewStepValidateTemplate : function for Validation a tempalte func NewStepValidateTemplate(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepValidateTemplate { var step = &StepValidateTemplate{ Conn: conn, @@ -249,7 +249,7 @@ func (s *StepValidateTemplate) validateTemplate() error { return s.validateServerProductCode() } -// Run : main funciton for validation a template +// Run : main function for validation a template func (s *StepValidateTemplate) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { s.Say("Validating deployment template ...") diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 3c758ae4d..9c8237eb8 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -694,7 +694,7 @@ func TestRetryable(t *testing.T) { err := p.Prepare(config) err = p.retryable(retryMe) if err != nil { - t.Fatalf("should not have error retrying funuction") + t.Fatalf("should not have error retrying function") } count = 0 @@ -702,7 +702,7 @@ func TestRetryable(t *testing.T) { err = p.Prepare(config) err = p.retryable(retryMe) if err == nil { - t.Fatalf("should have error retrying funuction") + t.Fatalf("should have error retrying function") } } diff --git a/provisioner/windows-shell/provisioner_test.go b/provisioner/windows-shell/provisioner_test.go index 1f2ee2cab..e0731da10 100644 --- a/provisioner/windows-shell/provisioner_test.go +++ b/provisioner/windows-shell/provisioner_test.go @@ -434,7 +434,7 @@ func TestRetryable(t *testing.T) { err := p.Prepare(config) err = p.retryable(retryMe) if err != nil { - t.Fatalf("should not have error retrying funuction") + t.Fatalf("should not have error retrying function") } count = 0 @@ -442,7 +442,7 @@ func TestRetryable(t *testing.T) { err = p.Prepare(config) err = p.retryable(retryMe) if err == nil { - t.Fatalf("should have error retrying funuction") + t.Fatalf("should have error retrying function") } } From 210f8e8312a396ccf67e349127335ee0a4eda0d4 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 07:59:00 +0000 Subject: [PATCH 0754/1007] spelling: hyphen --- builder/azure/arm/artifact_test.go | 2 +- builder/azure/arm/config_test.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/builder/azure/arm/artifact_test.go b/builder/azure/arm/artifact_test.go index 4aff7cee6..a86a6353e 100644 --- a/builder/azure/arm/artifact_test.go +++ b/builder/azure/arm/artifact_test.go @@ -235,7 +235,7 @@ func TestAdditionalDiskArtifactProperties(t *testing.T) { } } -func TestArtifactOverHypenatedCaptureUri(t *testing.T) { +func TestArtifactOverHyphenatedCaptureUri(t *testing.T) { template := CaptureTemplate{ Resources: []CaptureResources{ { diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index c7758fb91..71f3c352d 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -499,7 +499,7 @@ func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) { wellFormedCaptureNamePrefix := []string{ "packer", "AbcdefghijklmnopqrstuvwX", - "hypen-hypen", + "hyphen-hyphen", "0leading-number", "v1.core.local", } @@ -514,8 +514,8 @@ func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) { } malformedCaptureNamePrefix := []string{ - "-leading-hypen", - "trailing-hypen-", + "-leading-hyphen", + "trailing-hyphen-", "trailing-period.", "_leading-underscore", "punc-!@#$%^&*()_+-=-punc", @@ -550,7 +550,7 @@ func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) { wellFormedCaptureContainerName := []string{ "0leading", "aleading", - "hype-hypen", + "hype-hyphen", "abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz", // 63 characters } @@ -565,9 +565,9 @@ func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) { malformedCaptureContainerName := []string{ "No-Capitals", - "double--hypens", - "-leading-hypen", - "trailing-hypen-", + "double--hyphens", + "-leading-hyphen", + "trailing-hyphen-", "punc-!@#$%^&*()_+-=-punc", "there-are-over-63-characters-in-this-string-and-that-is-a-bad-container-name", } From 57c0e9e4a7f361cd6b38cc6336c47300344d05d8 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:02:43 +0000 Subject: [PATCH 0755/1007] spelling: illegal --- builder/virtualbox/common/export_config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/common/export_config_test.go b/builder/virtualbox/common/export_config_test.go index 612bfc01d..6848a9a66 100644 --- a/builder/virtualbox/common/export_config_test.go +++ b/builder/virtualbox/common/export_config_test.go @@ -10,7 +10,7 @@ func TestExportConfigPrepare_BootWait(t *testing.T) { // Bad c = new(ExportConfig) - c.Format = "illega" + c.Format = "illegal" errs = c.Prepare(testConfigTemplate(t)) if len(errs) == 0 { t.Fatalf("bad: %#v", errs) From 3a31baae4f012f0b241669d2dbbf239bb94ae1d5 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:00:05 +0000 Subject: [PATCH 0756/1007] spelling: incorrect --- builder/alicloud/ecs/step_config_vswitch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/alicloud/ecs/step_config_vswitch.go b/builder/alicloud/ecs/step_config_vswitch.go index c1494e9d0..4bbb19773 100644 --- a/builder/alicloud/ecs/step_config_vswitch.go +++ b/builder/alicloud/ecs/step_config_vswitch.go @@ -137,7 +137,7 @@ func (s *stepConfigAlicloudVSwitch) Cleanup(state multistep.StateBag) { e, _ := err.(*common.Error) if (e.Code == "IncorrectVSwitchStatus" || e.Code == "DependencyViolation" || e.Code == "DependencyViolation.HaVip" || - e.Code == "IncorretRouteEntryStatus") && time.Now().Before(timeoutPoint) { + e.Code == "IncorrectRouteEntryStatus") && time.Now().Before(timeoutPoint) { time.Sleep(1 * time.Second) continue } From 1e99dce12bda11197a27a75aba4ab407d7c985b5 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:05:14 +0000 Subject: [PATCH 0757/1007] spelling: inertness --- builder/azure/arm/authenticate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/azure/arm/authenticate_test.go b/builder/azure/arm/authenticate_test.go index 37d7b0e1b..12791138c 100644 --- a/builder/azure/arm/authenticate_test.go +++ b/builder/azure/arm/authenticate_test.go @@ -8,7 +8,7 @@ import ( // Behavior is the most important thing to assert for ServicePrincipalToken, but // that cannot be done in a unit test because it involves network access. Instead, -// I assert the expected intertness of this class. +// I assert the expected inertness of this class. func TestNewAuthenticate(t *testing.T) { testSubject := NewAuthenticate(azure.PublicCloud, "clientID", "clientString", "tenantID") spn, err := testSubject.getServicePrincipalToken() From 074b04522fd3882580dbf06e65a21d8806c56206 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:04:26 +0000 Subject: [PATCH 0758/1007] spelling: initializing --- website/source/docs/other/debugging.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/other/debugging.html.md b/website/source/docs/other/debugging.html.md index b34f1485b..f71e8b5e4 100644 --- a/website/source/docs/other/debugging.html.md +++ b/website/source/docs/other/debugging.html.md @@ -28,7 +28,7 @@ ephemeral key will be deleted at the end of the packer run during cleanup. For a local builder, the SSH session initiated will be visible in the detail provided when `PACKER_LOG=1` environment variable is set prior to a build, and you can connect to the local machine using the userid and password defined -in the kickstart or preseed associated with initialzing the local VM. +in the kickstart or preseed associated with initializing the local VM. ### Windows From 62f59662a34768b83e79116343bcff70b8f0b65d Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:04:40 +0000 Subject: [PATCH 0759/1007] spelling: installation --- builder/hyperv/common/step_polling_installation.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/hyperv/common/step_polling_installation.go b/builder/hyperv/common/step_polling_installation.go index b9d2984f6..133418ee7 100644 --- a/builder/hyperv/common/step_polling_installation.go +++ b/builder/hyperv/common/step_polling_installation.go @@ -15,10 +15,10 @@ import ( const port string = "13000" -type StepPollingInstalation struct { +type StepPollingInstallation struct { } -func (s *StepPollingInstalation) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepPollingInstallation) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) errorMsg := "Error polling VM: %s" @@ -75,6 +75,6 @@ func (s *StepPollingInstalation) Run(_ context.Context, state multistep.StateBag return multistep.ActionContinue } -func (s *StepPollingInstalation) Cleanup(state multistep.StateBag) { +func (s *StepPollingInstallation) Cleanup(state multistep.StateBag) { } From 933ac20e68a9d4d72983889e6df4a45d0075fb79 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:04:50 +0000 Subject: [PATCH 0760/1007] spelling: instance --- builder/alicloud/ecs/builder.go | 2 +- builder/alicloud/ecs/step_create_instance.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/alicloud/ecs/builder.go b/builder/alicloud/ecs/builder.go index 7269bd3f0..e0d7c0d7c 100644 --- a/builder/alicloud/ecs/builder.go +++ b/builder/alicloud/ecs/builder.go @@ -132,7 +132,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe RegionId: b.config.AlicloudRegion, InternetChargeType: b.config.InternetChargeType, InternetMaxBandwidthOut: b.config.InternetMaxBandwidthOut, - InstnaceName: b.config.InstanceName, + InstanceName: b.config.InstanceName, ZoneId: b.config.ZoneId, }) if b.chooseNetworkType() == VpcNet { diff --git a/builder/alicloud/ecs/step_create_instance.go b/builder/alicloud/ecs/step_create_instance.go index 5001fe4df..ff41a3df6 100644 --- a/builder/alicloud/ecs/step_create_instance.go +++ b/builder/alicloud/ecs/step_create_instance.go @@ -21,7 +21,7 @@ type stepCreateAlicloudInstance struct { RegionId string InternetChargeType string InternetMaxBandwidthOut int - InstnaceName string + InstanceName string ZoneId string instance *ecs.InstanceAttributesType } @@ -63,7 +63,7 @@ func (s *stepCreateAlicloudInstance) Run(_ context.Context, state multistep.Stat IoOptimized: ioOptimized, VSwitchId: vswitchId, SecurityGroupId: securityGroupId, - InstanceName: s.InstnaceName, + InstanceName: s.InstanceName, Password: password, ZoneId: s.ZoneId, DataDisk: diskDeviceToDiskType(config.AlicloudImageConfig.ECSImagesDiskMappings), @@ -89,7 +89,7 @@ func (s *stepCreateAlicloudInstance) Run(_ context.Context, state multistep.Stat InternetMaxBandwidthOut: s.InternetMaxBandwidthOut, IoOptimized: ioOptimized, SecurityGroupId: securityGroupId, - InstanceName: s.InstnaceName, + InstanceName: s.InstanceName, Password: password, ZoneId: s.ZoneId, DataDisk: diskDeviceToDiskType(config.AlicloudImageConfig.ECSImagesDiskMappings), From eebe2365872d4553321f045ee320d7ee5e1ea857 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:07:31 +0000 Subject: [PATCH 0761/1007] spelling: keyboard --- communicator/ssh/password_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communicator/ssh/password_test.go b/communicator/ssh/password_test.go index e513716d0..47a4c7782 100644 --- a/communicator/ssh/password_test.go +++ b/communicator/ssh/password_test.go @@ -15,7 +15,7 @@ func TestPasswordKeyboardInteractive_Impl(t *testing.T) { } } -func TestPasswordKeybardInteractive_Challenge(t *testing.T) { +func TestPasswordKeyboardInteractive_Challenge(t *testing.T) { p := PasswordKeyboardInteractive("foo") result, err := p("foo", "bar", []string{"one", "two"}, nil) if err != nil { From ae4abedfa290875eaacf686cf39c2999415ecb16 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:10:59 +0000 Subject: [PATCH 0762/1007] spelling: mandatory --- builder/ncloud/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/ncloud/config_test.go b/builder/ncloud/config_test.go index 7e2591594..fb7886dbc 100644 --- a/builder/ncloud/config_test.go +++ b/builder/ncloud/config_test.go @@ -113,7 +113,7 @@ func TestEmptyConfig(t *testing.T) { _, _, err := NewConfig(raw) if err == nil { - t.Error("Expected Config to require 'access_key', 'secret_key' and some mendatory fields, but it did not") + t.Error("Expected Config to require 'access_key', 'secret_key' and some mandatory fields, but it did not") } if !strings.Contains(err.Error(), "access_key is required") { From 5c0d0322f0a9972c999e64b371e5f1a34e044b06 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:09:00 +0000 Subject: [PATCH 0763/1007] spelling: manifest --- website/source/docs/post-processors/manifest.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/post-processors/manifest.html.md b/website/source/docs/post-processors/manifest.html.md index 8ad53f451..4d5aaa398 100644 --- a/website/source/docs/post-processors/manifest.html.md +++ b/website/source/docs/post-processors/manifest.html.md @@ -67,7 +67,7 @@ An example manifest file looks like: If the build is run again, the new build artifacts will be added to the manifest file rather than replacing it. It is possible to grab specific build artifacts from the manifest by using `packer_run_uuid`. -The above mainfest was generated with this packer.json: +The above manifest was generated with this packer.json: ```json { From 964d5dd55e099a0192f4d9c1804f549398221633 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:09:41 +0000 Subject: [PATCH 0764/1007] spelling: mapstructure --- builder/virtualbox/common/export_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/common/export_config.go b/builder/virtualbox/common/export_config.go index 08dfb267c..b55941943 100644 --- a/builder/virtualbox/common/export_config.go +++ b/builder/virtualbox/common/export_config.go @@ -7,7 +7,7 @@ import ( ) type ExportConfig struct { - Format string `mapstruture:"format"` + Format string `mapstructure:"format"` } func (c *ExportConfig) Prepare(ctx *interpolate.Context) []error { From 73d3d65b84ea426a61d8e9b6cbf686a4527abf6a Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:10:01 +0000 Subject: [PATCH 0765/1007] spelling: marshal --- builder/azure/pkcs12/pkcs12.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/azure/pkcs12/pkcs12.go b/builder/azure/pkcs12/pkcs12.go index 8279cb572..806246daa 100644 --- a/builder/azure/pkcs12/pkcs12.go +++ b/builder/azure/pkcs12/pkcs12.go @@ -398,7 +398,7 @@ func Encode(derBytes []byte, privateKey interface{}, password string) (pfxBytes return nil, err } - // Marhsal []contentInfo so we can re-constitute the byte stream that will + // Marshal []contentInfo so we can re-constitute the byte stream that will // be suitable for computing the MAC bytes, err := asn1.Marshal(contentInfos) if err != nil { From cab8b6ed68ac08f4e506e2816ebf1bdac7530a6b Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:10:20 +0000 Subject: [PATCH 0766/1007] spelling: maximum --- builder/hyperv/iso/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index b92e779df..b912ab316 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -172,7 +172,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } if len(b.config.AdditionalDiskSize) > 64 { - err = errors.New("VM's currently support a maximun of 64 additional SCSI attached disks.") + err = errors.New("VM's currently support a maximum of 64 additional SCSI attached disks.") errs = packer.MultiErrorAppend(errs, err) } From abb2faf677d472fe66422c8621914c366f36eae4 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:10:53 +0000 Subject: [PATCH 0767/1007] spelling: membership --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15368d2c3..363e39dce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -411,7 +411,7 @@ * builder/cloudstack: Properly report back errors. [GH-5103] [GH-5123] * builder/docker: Fix windows filepath in docker-toolbox call [GH-4887] * builder/docker: Fix windows filepath in docker-toolbox call. [GH-4887] -* builder/hyperv: Use SID to verify membersip in Admin group, fixing for non- +* builder/hyperv: Use SID to verify membership in Admin group, fixing for non- english users. [GH-5022] * builder/hyperv: Verify membership in the group Hyper-V Administrators by SID not name. [GH-5022] From d987fcefc34bf7d38304828d4ff13067c20c3fbb Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:12:53 +0000 Subject: [PATCH 0768/1007] spelling: multiples --- builder/vmware/common/vmx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/vmx.go b/builder/vmware/common/vmx.go index 1fcdfa35e..631e0106d 100644 --- a/builder/vmware/common/vmx.go +++ b/builder/vmware/common/vmx.go @@ -44,14 +44,14 @@ func EncodeVMX(contents map[string]string) string { } // a list of VMX key fragments that the value must not be quoted - // fragments are used to cover multliples (i.e. multiple disks) + // fragments are used to cover multiples (i.e. multiple disks) // keys are still lowercase at this point, use lower fragments noQuotes := []string{ ".virtualssd", } // a list of VMX key fragments that are case sensitive - // fragments are used to cover multliples (i.e. multiple disks) + // fragments are used to cover multiples (i.e. multiple disks) caseSensitive := []string{ ".virtualSSD", } From e43b8de3b1834a47ceebccca7dd8238d20a5085c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:14:30 +0000 Subject: [PATCH 0769/1007] spelling: network --- builder/azure/arm/template_factory.go | 2 +- builder/azure/common/template/template_builder.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/azure/arm/template_factory.go b/builder/azure/arm/template_factory.go index 843580fd2..62b25dc26 100644 --- a/builder/azure/arm/template_factory.go +++ b/builder/azure/arm/template_factory.go @@ -86,7 +86,7 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error) } if config.VirtualNetworkName != "" && DefaultPrivateVirtualNetworkWithPublicIp != config.PrivateVirtualNetworkWithPublicIp { - builder.SetPrivateVirtualNetworWithPublicIp( + builder.SetPrivateVirtualNetworkWithPublicIp( config.VirtualNetworkResourceGroupName, config.VirtualNetworkName, config.VirtualNetworkSubnetName) diff --git a/builder/azure/common/template/template_builder.go b/builder/azure/common/template/template_builder.go index a05b66ab3..93de89374 100644 --- a/builder/azure/common/template/template_builder.go +++ b/builder/azure/common/template/template_builder.go @@ -274,7 +274,7 @@ func (s *TemplateBuilder) SetVirtualNetwork(virtualNetworkResourceGroup, virtual return nil } -func (s *TemplateBuilder) SetPrivateVirtualNetworWithPublicIp(virtualNetworkResourceGroup, virtualNetworkName, subnetName string) error { +func (s *TemplateBuilder) SetPrivateVirtualNetworkWithPublicIp(virtualNetworkResourceGroup, virtualNetworkName, subnetName string) error { s.setVariable("virtualNetworkResourceGroup", virtualNetworkResourceGroup) s.setVariable("virtualNetworkName", virtualNetworkName) s.setVariable("subnetName", subnetName) From 64aae1c7816e54857a8c19ae7e5983b2f3d9c1c1 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:16:48 +0000 Subject: [PATCH 0770/1007] spelling: occurring --- helper/multistep/debug_runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/multistep/debug_runner.go b/helper/multistep/debug_runner.go index 88af01c54..a6760c5f1 100644 --- a/helper/multistep/debug_runner.go +++ b/helper/multistep/debug_runner.go @@ -7,7 +7,7 @@ import ( "sync" ) -// DebugLocation is the location where the pause is occuring when debugging +// DebugLocation is the location where the pause is occurring when debugging // a step sequence. "DebugLocationAfterRun" is after the run of the named // step. "DebugLocationBeforeCleanup" is before the cleanup of the named // step. From 35353faa625303a57c7562ed8ec9749953a43249 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:17:22 +0000 Subject: [PATCH 0771/1007] spelling: omitted --- website/source/docs/builders/openstack.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index 709d39246..0809b6545 100755 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -81,7 +81,7 @@ builder. cluster will be used. This may be required for some OpenStack clusters. - `cacert` (string) - Custom CA certificate file path. - If ommited the OS\_CACERT environment variable can be used. + If omitted the OS\_CACERT environment variable can be used. - `config_drive` (boolean) - Whether or not nova should use ConfigDrive for cloud-init metadata. @@ -113,7 +113,7 @@ builder. done over an insecure connection. By default this is false. - `key` (string) - Client private key file path for SSL client authentication. - If ommited the OS\_KEY environment variable can be used. + If omitted the OS\_KEY environment variable can be used. - `metadata` (object of key/value strings) - Glance metadata that will be applied to the image. From 61030c0d85b62fd1bda77ec394d18ab43918ca7c Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:27:26 +0000 Subject: [PATCH 0772/1007] spelling: output --- builder/vmware/common/output_dir_local_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vmware/common/output_dir_local_test.go b/builder/vmware/common/output_dir_local_test.go index c3197117e..3026c6c66 100644 --- a/builder/vmware/common/output_dir_local_test.go +++ b/builder/vmware/common/output_dir_local_test.go @@ -4,6 +4,6 @@ import ( "testing" ) -func TestLocalOuputDir_impl(t *testing.T) { +func TestLocalOutputDir_impl(t *testing.T) { var _ OutputDir = new(LocalOutputDir) } From 0503e429c38ab5ef3dc58d59b5a17c436e0c3ca8 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:28:26 +0000 Subject: [PATCH 0773/1007] spelling: override --- fix/fixer_pp_vagrant_override.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fix/fixer_pp_vagrant_override.go b/fix/fixer_pp_vagrant_override.go index 36aadfa46..a0c530728 100644 --- a/fix/fixer_pp_vagrant_override.go +++ b/fix/fixer_pp_vagrant_override.go @@ -4,7 +4,7 @@ import ( "github.com/mitchellh/mapstructure" ) -// FixerVagrantPPOvveride is a Fixer that replaces the provider-specific +// FixerVagrantPPOverride is a Fixer that replaces the provider-specific // overrides for the Vagrant post-processor with the new style introduced // as part of Packer 0.5.0. type FixerVagrantPPOverride struct{} From 6a2ad49feb5b97d62e24aa2b3e193a6d5dbf3fc7 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:30:28 +0000 Subject: [PATCH 0774/1007] spelling: parameter --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 363e39dce..420424e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1352,7 +1352,7 @@ * core: Fix potential panic for post-processor plugin exits. [GH-2098] * core: `PACKER_CONFIG` may point to a non-existent file. [GH-2226] * builder/amazon: Allow spaces in AMI names when using `clean_ami_name` [GH-2182] -* builder/amazon: Remove deprecated ec2-upload-bundle paramger. [GH-1931] +* builder/amazon: Remove deprecated ec2-upload-bundle parameter. [GH-1931] * builder/amazon: Use IAM Profile to upload bundle if provided. [GH-1985] * builder/amazon: Use correct exit code after SSH authentication failed. [GH-2004] * builder/amazon: Retry finding created instance for eventual From 18f51e7338373bfed6176fc7d96891b17954526b Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 08:29:17 +0000 Subject: [PATCH 0775/1007] spelling: parameters --- builder/oracle/oci/client/image.go | 2 +- builder/oracle/oci/client/instance.go | 2 +- builder/oracle/oci/client/vnic.go | 2 +- builder/oracle/oci/client/vnic_attachment.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/oracle/oci/client/image.go b/builder/oracle/oci/client/image.go index 802b4650c..67ada02d5 100644 --- a/builder/oracle/oci/client/image.go +++ b/builder/oracle/oci/client/image.go @@ -56,7 +56,7 @@ type Image struct { TimeCreated time.Time `json:"timeCreated"` } -// GetImageParams are the paramaters available when communicating with the +// GetImageParams are the parameters available when communicating with the // GetImage API endpoint. type GetImageParams struct { ID string `url:"imageId"` diff --git a/builder/oracle/oci/client/instance.go b/builder/oracle/oci/client/instance.go index 30cdbd50b..e81ad3a44 100644 --- a/builder/oracle/oci/client/instance.go +++ b/builder/oracle/oci/client/instance.go @@ -60,7 +60,7 @@ type Instance struct { TimeCreated time.Time `json:"timeCreated"` } -// GetInstanceParams are the paramaters available when communicating with the +// GetInstanceParams are the parameters available when communicating with the // GetInstance API endpoint. type GetInstanceParams struct { ID string `url:"instanceId,omitempty"` diff --git a/builder/oracle/oci/client/vnic.go b/builder/oracle/oci/client/vnic.go index 31b37ec3e..9922d34aa 100644 --- a/builder/oracle/oci/client/vnic.go +++ b/builder/oracle/oci/client/vnic.go @@ -29,7 +29,7 @@ type VNIC struct { TimeCreated time.Time `json:"timeCreated"` } -// GetVNICParams are the paramaters available when communicating with the +// GetVNICParams are the parameters available when communicating with the // ListVNICs API endpoint. type GetVNICParams struct { ID string `url:"vnicId"` diff --git a/builder/oracle/oci/client/vnic_attachment.go b/builder/oracle/oci/client/vnic_attachment.go index 3458f7da1..1e42a0573 100644 --- a/builder/oracle/oci/client/vnic_attachment.go +++ b/builder/oracle/oci/client/vnic_attachment.go @@ -31,7 +31,7 @@ type VNICAttachment struct { VNICID string `json:"vnicId"` } -// ListVnicAttachmentsParams are the paramaters available when communicating +// ListVnicAttachmentsParams are the parameters available when communicating // with the ListVnicAttachments API endpoint. type ListVnicAttachmentsParams struct { AvailabilityDomain string `url:"availabilityDomain,omitempty"` From c14d6af5aaef2e2671e22b78980fb19e0e165062 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Tue, 13 Mar 2018 09:05:56 +0000 Subject: [PATCH 0776/1007] spelling: persistent --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 420424e40..c43badcb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1435,7 +1435,7 @@ * builder/googlecompute: Support for ubuntu-os-cloud project * builder/googlecompute: Support for OAuth2 to avoid client secrets file -* builder/googlecompute: GCE image from persistant disk instead of tarball +* builder/googlecompute: GCE image from persistent disk instead of tarball * builder/qemu: Checksum type "none" can be used * provisioner/chef: Generate a node name if none available * provisioner/chef: Added ssl_verify_mode configuration From f5156a7efbd42fc100c22d7c8e7b9c38b0d93d4a Mon Sep 17 00:00:00 2001 From: Andre Pearce <15135665+andrepearce@users.noreply.github.com> Date: Tue, 13 Mar 2018 20:11:52 +1100 Subject: [PATCH 0777/1007] Nest the additional field of `ami_root_device` --- website/source/docs/builders/amazon-ebssurrogate.html.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index d40ec04e1..f9ab61473 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -55,9 +55,9 @@ builder. the root device of the AMI. This looks like the mappings in `ami_block_device_mapping`, except with an additional field: -- `source_device_name` (string) - The device name of the block device on the - source instance to be used as the root device for the AMI. This must correspond - to a block device in `launch_block_device_mapping`. + - `source_device_name` (string) - The device name of the block device on the + source instance to be used as the root device for the AMI. This must correspond + to a block device in `launch_block_device_mapping`. ### Optional: From e31ffab30cdd6d5186793f21b68fc16814b37be4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 13 Mar 2018 10:25:47 -0700 Subject: [PATCH 0778/1007] update middleman 0.3.30 --- website/Makefile | 2 +- website/packer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/Makefile b/website/Makefile index ccc3ae634..f8e465b43 100644 --- a/website/Makefile +++ b/website/Makefile @@ -1,4 +1,4 @@ -VERSION?="0.3.29" +VERSION?="0.3.30" build: @echo "==> Starting build in Docker..." diff --git a/website/packer.json b/website/packer.json index cbfb5c565..91f87c2e9 100644 --- a/website/packer.json +++ b/website/packer.json @@ -8,7 +8,7 @@ "builders": [ { "type": "docker", - "image": "hashicorp/middleman-hashicorp:0.3.29", + "image": "hashicorp/middleman-hashicorp:0.3.30", "discard": "true", "volumes": { "{{ pwd }}": "/website" From dfa0b0cdb1ea2b9c136e169c2588f4c68a64fda8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 13 Mar 2018 10:42:08 -0700 Subject: [PATCH 0779/1007] update middleman 0.3.32 --- website/Gemfile | 2 +- website/Gemfile.lock | 6 +++--- website/Makefile | 2 +- website/packer.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/Gemfile b/website/Gemfile index d21d35e45..a7edfed49 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.30" +gem "middleman-hashicorp", "0.3.32" diff --git a/website/Gemfile.lock b/website/Gemfile.lock index e567bf2ed..913b76417 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -6,7 +6,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (8.1.0) + autoprefixer-rails (8.1.0.1) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -78,7 +78,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.30) + middleman-hashicorp (0.3.32) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -153,7 +153,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.30) + middleman-hashicorp (= 0.3.32) BUNDLED WITH 1.16.1 diff --git a/website/Makefile b/website/Makefile index f8e465b43..82b2cedc1 100644 --- a/website/Makefile +++ b/website/Makefile @@ -1,4 +1,4 @@ -VERSION?="0.3.30" +VERSION?="0.3.32" build: @echo "==> Starting build in Docker..." diff --git a/website/packer.json b/website/packer.json index 91f87c2e9..aeaa162e0 100644 --- a/website/packer.json +++ b/website/packer.json @@ -8,7 +8,7 @@ "builders": [ { "type": "docker", - "image": "hashicorp/middleman-hashicorp:0.3.30", + "image": "hashicorp/middleman-hashicorp:0.3.32", "discard": "true", "volumes": { "{{ pwd }}": "/website" From 7eda44d28c5fe40819446520c22388b3763c2da4 Mon Sep 17 00:00:00 2001 From: Evan Brown <evanbrown@google.com> Date: Tue, 13 Mar 2018 12:36:14 -0700 Subject: [PATCH 0780/1007] builder/googlecompute: disambiguate disable_default_service_account This change requires 'disable_default_service_account=false' in order to set 'service_account_email'. This is a guard against an incorrect assumption that disabling the default service account would mean that no service account would be used. --- builder/googlecompute/config.go | 5 +++ builder/googlecompute/config_test.go | 49 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/builder/googlecompute/config.go b/builder/googlecompute/config.go index 537fc7422..11e8ac47f 100644 --- a/builder/googlecompute/config.go +++ b/builder/googlecompute/config.go @@ -225,6 +225,11 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(fmt.Errorf("'on_host_maintenance' must be set to 'TERMINATE' when 'accelerator_count' is more than 0")) } + // If DisableDefaultServiceAccount is provided, don't allow a value for ServiceAccountEmail + if c.DisableDefaultServiceAccount && c.ServiceAccountEmail != "" { + errs = packer.MultiErrorAppend(fmt.Errorf("you may not specify a 'service_account_email' when 'disable_default_service_account' is true")) + } + // Check for any errors. if errs != nil && len(errs.Errors) > 0 { return nil, nil, errs diff --git a/builder/googlecompute/config_test.go b/builder/googlecompute/config_test.go index 508b3c528..d3ed84506 100644 --- a/builder/googlecompute/config_test.go +++ b/builder/googlecompute/config_test.go @@ -276,6 +276,55 @@ func TestConfigPrepareAccelerator(t *testing.T) { } } +func TestConfigPrepareServiceAccount(t *testing.T) { + cases := []struct { + Keys []string + Values []interface{} + Err bool + }{ + { + []string{"disable_default_service_account", "service_account_email"}, + []interface{}{true, "service@account.email.com"}, + true, + }, + { + []string{"disable_default_service_account", "service_account_email"}, + []interface{}{false, "service@account.email.com"}, + false, + }, + { + []string{"disable_default_service_account", "service_account_email"}, + []interface{}{true, ""}, + false, + }, + } + + for _, tc := range cases { + raw := testConfig(t) + + errStr := "" + for k := range tc.Keys { + + // Create the string for error reporting + // convert value to string if it can be converted + errStr += fmt.Sprintf("%s:%v, ", tc.Keys[k], tc.Values[k]) + if tc.Values[k] == nil { + delete(raw, tc.Keys[k]) + } else { + raw[tc.Keys[k]] = tc.Values[k] + } + } + + _, warns, errs := NewConfig(raw) + + if tc.Err { + testConfigErr(t, warns, errs, strings.TrimRight(errStr, ", ")) + } else { + testConfigOk(t, warns, errs) + } + } +} + func TestConfigDefaults(t *testing.T) { cases := []struct { Read func(c *Config) interface{} From b33d6ce82eb443a0cd6d1c0aa2a5be0f5449f6a5 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 13 Mar 2018 16:11:11 -0700 Subject: [PATCH 0781/1007] fix salt provisioner on linux --- provisioner/salt-masterless/provisioner.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/provisioner/salt-masterless/provisioner.go b/provisioner/salt-masterless/provisioner.go index f1ae1fe84..76d2ff2d3 100644 --- a/provisioner/salt-masterless/provisioner.go +++ b/provisioner/salt-masterless/provisioner.go @@ -89,9 +89,9 @@ type guestOSTypeConfig struct { var guestOSTypeConfigs = map[string]guestOSTypeConfig{ provisioner.UnixOSType: { configDir: "/etc/salt", - tempDir: "/tmp/salt/", - stateRoot: "/srv/salt/", - pillarRoot: "/srv/pillar/", + tempDir: "/tmp/salt", + stateRoot: "/srv/salt", + pillarRoot: "/srv/pillar", bootstrapFetchCmd: "curl -L https://bootstrap.saltstack.com -o /tmp/install_salt.sh || wget -O /tmp/install_salt.sh https://bootstrap.saltstack.com", bootstrapRunCmd: "sh /tmp/install_salt.sh", }, @@ -129,7 +129,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType) } - p.guestCommands, err = provisioner.NewGuestCommands(p.config.GuestOSType, !p.config.DisableSudo) + p.guestCommands, err = provisioner.NewGuestCommands(p.config.GuestOSType, false) if err != nil { return fmt.Errorf("Invalid guest_os_type: \"%s\"", p.config.GuestOSType) } @@ -413,7 +413,7 @@ func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst, sr func (p *Provisioner) moveFile(ui packer.Ui, comm packer.Communicator, dst string, src string) error { ui.Message(fmt.Sprintf("Moving %s to %s", src, dst)) cmd := &packer.RemoteCmd{ - Command: p.guestCommands.MovePath(src, dst), + Command: p.sudo(p.guestCommands.MovePath(src, dst)), } if err := cmd.StartWithUi(comm, ui); err != nil || cmd.ExitStatus != 0 { if err == nil { From 8c72bba160088b95acd25794968c5ad9d8d84c76 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:14:18 +0000 Subject: [PATCH 0782/1007] spelling: possible --- builder/lxd/communicator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/lxd/communicator.go b/builder/lxd/communicator.go index 8ce455268..d016b0990 100644 --- a/builder/lxd/communicator.go +++ b/builder/lxd/communicator.go @@ -90,7 +90,7 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error // Don't use 'z' flag as compressing may take longer and the transfer is likely local. // If this isn't the case, it is possible for the user to compress in another step then transfer. - // It wouldn't be possibe to disable compression, without exposing this option. + // It wouldn't be possible to disable compression, without exposing this option. tar, err := c.CmdWrapper(fmt.Sprintf("tar -cf - -C %s .", src)) if err != nil { return err From 8e36178e5ba3ad113a9b49f5f0b79e9093e3fd93 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:14:31 +0000 Subject: [PATCH 0783/1007] spelling: preemptible --- website/source/docs/builders/googlecompute.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index fb006c7ae..d5fd09bce 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -263,7 +263,7 @@ builder. If preemptible is true this can only be `TERMINATE`. If preemptible is false, it defaults to `MIGRATE` -- `preemptible` (boolean) - If true, launch a preembtible instance. +- `preemptible` (boolean) - If true, launch a preemptible instance. - `region` (string) - The region in which to launch the instance. Defaults to to the region hosting the specified `zone`. From 91ecc80ede958ed26e8c61510c36dfd0a725281f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:14:59 +0000 Subject: [PATCH 0784/1007] spelling: privileges --- website/source/docs/builders/oracle-classic.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 1ea03dc46..30f5bfd5e 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -78,7 +78,7 @@ This builder currently only works with the SSH communicator. - `ssh_username` (string) - The username that Packer will use to SSH into the instance; defaults to `opc`, the default oracle user, which has sudo - priveliges. If you have already configured users on your machine, you may + privileges. If you have already configured users on your machine, you may prompt Packer to use one of those instead. For more detail, see the [documentation](https://docs.oracle.com/en/cloud/iaas/compute-iaas-cloud/stcsg/accessing-oracle-linux-instance-using-ssh.html). From fa36e1d9613c7fd2c025db03f77c9b5ab1dc70e6 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:17:22 +0000 Subject: [PATCH 0785/1007] spelling: processing --- builder/vmware/iso/step_create_vmx.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index ffeb724ec..46e5da43a 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -446,7 +446,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist templateData.SCSI_Present = "TRUE" templateData.CDROMType = "scsi" default: - err := fmt.Errorf("Error procesing VMX template: %s", cdromAdapterType) + err := fmt.Errorf("Error processing VMX template: %s", cdromAdapterType) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -505,7 +505,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } else { serial, err := unformat_serial(config.Serial) if err != nil { - err := fmt.Errorf("Error procesing VMX template: %s", err) + err := fmt.Errorf("Error processing VMX template: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -541,7 +541,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist break default: - err := fmt.Errorf("Error procesing VMX template: %v", serial) + err := fmt.Errorf("Error processing VMX template: %v", serial) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -554,7 +554,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist } else { parallel, err := unformat_parallel(config.Parallel) if err != nil { - err := fmt.Errorf("Error procesing VMX template: %s", err) + err := fmt.Errorf("Error processing VMX template: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -578,7 +578,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist break default: - err := fmt.Errorf("Error procesing VMX template: %v", parallel) + err := fmt.Errorf("Error processing VMX template: %v", parallel) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -590,7 +590,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist /// render the .vmx template vmxContents, err := interpolate.Render(vmxTemplate, &ctx) if err != nil { - err := fmt.Errorf("Error procesing VMX template: %s", err) + err := fmt.Errorf("Error processing VMX template: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt From 06dcad2c33bce7e2c6292d110e493cff7b330d4f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:17:47 +0000 Subject: [PATCH 0786/1007] spelling: propagating --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c43badcb1..746909496 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2400,7 +2400,7 @@ ### BUG FIXES: * builder/amazon/all: Gracefully handle when AMI appears to not exist - while AWS state is propogating. [GH-207] + while AWS state is propagating. [GH-207] * builder/virtualbox: Trim carriage returns for Windows to properly detect VM state on Windows. [GH-218] * core: build names no longer cause invalid config errors. [GH-197] From 3c60f637384941854f2ffc89afd5c8e9c3157ebc Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:17:37 +0000 Subject: [PATCH 0787/1007] spelling: property --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 746909496..44a7fc8e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2482,7 +2482,7 @@ * core: Non-200 response codes on downloads now show proper errors. [GH-141] * amazon-ebs: SSH handshake is retried. [GH-130] -* vagrant: The `BuildName` template propery works properly in +* vagrant: The `BuildName` template property works properly in the output path. * vagrant: Properly configure the provider-specific post-processors so things like `vagrantfile_template` work. [GH-129] From d3dc5ba6d3208f3a49901fcd9b2962c600f5fd27 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:15:21 +0000 Subject: [PATCH 0788/1007] spelling: provisioner --- packer/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/provisioner.go b/packer/provisioner.go index a754f7544..93411808d 100644 --- a/packer/provisioner.go +++ b/packer/provisioner.go @@ -82,7 +82,7 @@ func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interfac return nil } -// Cancels the privisioners that are still running. +// Cancels the provisioners that are still running. func (h *ProvisionHook) Cancel() { h.lock.Lock() defer h.lock.Unlock() From 8294c8bc66add7d8f589782411d1bdbdc00d42b6 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:19:01 +0000 Subject: [PATCH 0789/1007] spelling: receive --- builder/oracle/oci/client/base_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/oracle/oci/client/base_client.go b/builder/oracle/oci/client/base_client.go index b2fd31d9b..01d66215a 100644 --- a/builder/oracle/oci/client/base_client.go +++ b/builder/oracle/oci/client/base_client.go @@ -184,7 +184,7 @@ func (c *baseClient) Request() (*http.Request, error) { return req, nil } -// Recieve creates a http request from the client and executes it returning the +// Receive creates a http request from the client and executes it returning the // response. func (c *baseClient) Receive(successV, failureV interface{}) (*http.Response, error) { req, err := c.Request() From 5178dd36e8cf8041f9d9e14951076802b4072207 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:19:10 +0000 Subject: [PATCH 0790/1007] spelling: regular --- common/step_download.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/step_download.go b/common/step_download.go index ac62fa698..5f5bb7dfe 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -63,7 +63,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description)) // First try to use any already downloaded file - // If it fails, proceed to regualar download logic + // If it fails, proceed to regular download logic var downloadConfigs = make([]*DownloadConfig, len(s.Url)) var finalPath string From 50f097b03d1fde8c338a28c42ce6cc3f4446f91a Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:19:20 +0000 Subject: [PATCH 0791/1007] spelling: repeatedly --- website/source/docs/builders/docker.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index 23080e3ce..1105e8cf0 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -357,14 +357,14 @@ shown below: This builder allows you to build Docker images *without* Dockerfiles. -With this builder, you can repeatably create Docker images without the use of a +With this builder, you can repeatedly create Docker images without the use of a Dockerfile. You don't need to know the syntax or semantics of Dockerfiles. Instead, you can just provide shell scripts, Chef recipes, Puppet manifests, etc. to provision your Docker container just like you would a regular virtualized or dedicated machine. While Docker has many features, Packer views Docker simply as an container -runner. To that end, Packer is able to repeatably build these containers +runner. To that end, Packer is able to repeatedly build these containers using portable provisioning scripts. ## Overriding the host directory From aae5b50dabc7902a24802aa2bd4d6a79383c29f5 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 02:19:26 +0000 Subject: [PATCH 0792/1007] spelling: response --- .../azure/arm/azure_error_response_test.go | 20 +++++++++---------- builder/oracle/oci/client/transport_test.go | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/builder/azure/arm/azure_error_response_test.go b/builder/azure/arm/azure_error_response_test.go index faa429ad1..2e4f7f1ac 100644 --- a/builder/azure/arm/azure_error_response_test.go +++ b/builder/azure/arm/azure_error_response_test.go @@ -12,16 +12,16 @@ const AzureErrorSimple = `{"error":{"code":"ResourceNotFound","message":"The Res const AzureErrorNested = `{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.","details":[{"code":"BadRequest","message":"{\r\n \"error\": {\r\n \"code\": \"InvalidRequestFormat\",\r\n \"message\": \"Cannot parse the request.\",\r\n \"details\": [\r\n {\r\n \"code\": \"InvalidJson\",\r\n \"message\": \"Error converting value \\\"playground\\\" to type 'Microsoft.WindowsAzure.Networking.Nrp.Frontend.Contract.Csm.Public.IpAllocationMethod'. Path 'properties.publicIPAllocationMethod', line 1, position 130.\"\r\n }\r\n ]\r\n }\r\n}"}]}}` func TestAzureErrorSimpleShouldUnmarshal(t *testing.T) { - var azureErrorReponse azureErrorResponse - err := json.Unmarshal([]byte(AzureErrorSimple), &azureErrorReponse) + var azureErrorResponse azureErrorResponse + err := json.Unmarshal([]byte(AzureErrorSimple), &azureErrorResponse) if err != nil { t.Fatal(err) } - if azureErrorReponse.ErrorDetails.Code != "ResourceNotFound" { + if azureErrorResponse.ErrorDetails.Code != "ResourceNotFound" { t.Errorf("Error.Code") } - if azureErrorReponse.ErrorDetails.Message != "The Resource 'Microsoft.Compute/images/PackerUbuntuImage' under resource group 'packer-test00' was not found." { + if azureErrorResponse.ErrorDetails.Message != "The Resource 'Microsoft.Compute/images/PackerUbuntuImage' under resource group 'packer-test00' was not found." { t.Errorf("Error.Message") } } @@ -51,26 +51,26 @@ func TestAzureErrorEmptyShouldFormat(t *testing.T) { } func TestAzureErrorSimpleShouldFormat(t *testing.T) { - var azureErrorReponse azureErrorResponse - err := json.Unmarshal([]byte(AzureErrorSimple), &azureErrorReponse) + var azureErrorResponse azureErrorResponse + err := json.Unmarshal([]byte(AzureErrorSimple), &azureErrorResponse) if err != nil { t.Fatal(err) } - err = approvaltests.VerifyString(t, azureErrorReponse.Error()) + err = approvaltests.VerifyString(t, azureErrorResponse.Error()) if err != nil { t.Fatal(err) } } func TestAzureErrorNestedShouldFormat(t *testing.T) { - var azureErrorReponse azureErrorResponse - err := json.Unmarshal([]byte(AzureErrorNested), &azureErrorReponse) + var azureErrorResponse azureErrorResponse + err := json.Unmarshal([]byte(AzureErrorNested), &azureErrorResponse) if err != nil { t.Fatal(err) } - err = approvaltests.VerifyString(t, azureErrorReponse.Error()) + err = approvaltests.VerifyString(t, azureErrorResponse.Error()) if err != nil { t.Fatal(err) } diff --git a/builder/oracle/oci/client/transport_test.go b/builder/oracle/oci/client/transport_test.go index 2299f3a0e..ebf02040b 100644 --- a/builder/oracle/oci/client/transport_test.go +++ b/builder/oracle/oci/client/transport_test.go @@ -148,7 +148,7 @@ func TestKnownGoodRequests(t *testing.T) { for header, val := range tt.expectedHeaders { if sentReq.Header.Get(header) != val { - t.Fatalf("%s: Header mismatch in responnse,\n\t expecting \"%s\"\n\t got \"%s\"", tt.name, val, sentReq.Header.Get(header)) + t.Fatalf("%s: Header mismatch in response,\n\t expecting \"%s\"\n\t got \"%s\"", tt.name, val, sentReq.Header.Get(header)) } } } From 007930ec2d3f4d50ba1d0c1e1af4276c5dd05bb4 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:20:51 +0000 Subject: [PATCH 0793/1007] spelling: restricted --- builder/amazon/common/access_config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/access_config_test.go b/builder/amazon/common/access_config_test.go index e1c44cb89..9c543816a 100644 --- a/builder/amazon/common/access_config_test.go +++ b/builder/amazon/common/access_config_test.go @@ -42,7 +42,7 @@ func TestAccessConfigPrepare_Region(t *testing.T) { } -func TestAccessConfigPrepare_RegionRestrictd(t *testing.T) { +func TestAccessConfigPrepare_RegionRestricted(t *testing.T) { c := testAccessConfig() // Create a Session with a custom region From 6c1654d421ec899f1a172e6a2e680a3793bd2c6f Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:21:38 +0000 Subject: [PATCH 0794/1007] spelling: separators --- communicator/ssh/communicator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 0e198cb0d..d81ab750a 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -591,7 +591,7 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e target_file = filepath.Base((*fi).Name()) } - // On windows, filepath.Dir uses backslash seperators (ie. "\tmp"). + // On windows, filepath.Dir uses backslash separators (ie. "\tmp"). // This does not work when the target host is unix. Switch to forward slash // which works for unix and windows target_dir = filepath.ToSlash(target_dir) From 795116ef4ff95777cc0bc270032ad41ad8f6d507 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:21:44 +0000 Subject: [PATCH 0795/1007] spelling: session --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a7fc8e3..1343ea956 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2012,7 +2012,7 @@ * builder/digitalocean: scrub API keys from config debug output. [GH-516] * builder/virtualbox: error if VirtualBox version cant be detected. [GH-488] * builder/virtualbox: detect if vboxdrv isn't properly setup. [GH-488] -* builder/virtualbox: sleep a bit before export to ensure the sesssion +* builder/virtualbox: sleep a bit before export to ensure the session is unlocked. [GH-512] * builder/virtualbox: create SATA drives properly on VirtualBox 4.3. [GH-547] * builder/virtualbox: support user templates in SSH key path. [GH-539] From 5dd9be653aca7650216b413b214ac90ff9f4d895 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:22:32 +0000 Subject: [PATCH 0796/1007] spelling: should --- packer/core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/core.go b/packer/core.go index 7da3e4510..c8ac2cfb7 100644 --- a/packer/core.go +++ b/packer/core.go @@ -67,7 +67,7 @@ func NewCore(c *CoreConfig) (*Core, error) { return nil, err } - // Go through and interpolate all the build names. We shuld be able + // Go through and interpolate all the build names. We should be able // to do this at this point with the variables. result.builds = make(map[string]*template.Builder) for _, b := range c.Template.Builders { From c7c8ed04f56d1ec2574f56d9675715bc3bd923c8 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:23:02 +0000 Subject: [PATCH 0797/1007] spelling: specify --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1343ea956..fe2f21796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2169,7 +2169,7 @@ * builder/virtualbox,vmware: Support SHA512 as a checksum type. [GH-356] * builder/vmware: The root hard drive type can now be specified with "disk_type_id" for advanced users. [GH-328] -* provisioner/salt-masterless: Ability to specfy a minion config. [GH-264] +* provisioner/salt-masterless: Ability to specify a minion config. [GH-264] * provisioner/salt-masterless: Ability to upload pillars. [GH-353] ### IMPROVEMENTS: From c563ef0797347d2402dfd9a0292f1b183996ffdd Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:23:56 +0000 Subject: [PATCH 0798/1007] spelling: structure --- builder/googlecompute/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/googlecompute/driver.go b/builder/googlecompute/driver.go index 4c07a06cf..11c4eadb9 100644 --- a/builder/googlecompute/driver.go +++ b/builder/googlecompute/driver.go @@ -82,7 +82,7 @@ type InstanceConfig struct { Zone string } -// WindowsPasswordConfig is the data structue that GCE needs to encrypt the created +// WindowsPasswordConfig is the data structure that GCE needs to encrypt the created // windows password. type WindowsPasswordConfig struct { key *rsa.PrivateKey From c49c40ac41e617099044fc4e085c7538a7e982a1 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:24:39 +0000 Subject: [PATCH 0799/1007] spelling: targeted --- packer/ui_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packer/ui_test.go b/packer/ui_test.go index ef14985ec..a1bb0193c 100644 --- a/packer/ui_test.go +++ b/packer/ui_test.go @@ -99,34 +99,34 @@ func TestColoredUi_noColorEnv(t *testing.T) { func TestTargetedUI(t *testing.T) { bufferUi := testUi() - targettedUi := &TargetedUI{ + targetedUi := &TargetedUI{ Target: "foo", Ui: bufferUi, } var actual, expected string - targettedUi.Say("foo") + targetedUi.Say("foo") actual = readWriter(bufferUi) expected = "==> foo: foo\n" if actual != expected { t.Fatalf("bad: %#v", actual) } - targettedUi.Message("foo") + targetedUi.Message("foo") actual = readWriter(bufferUi) expected = " foo: foo\n" if actual != expected { t.Fatalf("bad: %#v", actual) } - targettedUi.Error("bar") + targetedUi.Error("bar") actual = readErrorWriter(bufferUi) expected = "==> foo: bar\n" if actual != expected { t.Fatalf("bad: %#v", actual) } - targettedUi.Say("foo\nbar") + targetedUi.Say("foo\nbar") actual = readWriter(bufferUi) expected = "==> foo: foo\n==> foo: bar\n" if actual != expected { From 5a393d4fac5703762bd426cc2cf537a5f56a7166 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:24:51 +0000 Subject: [PATCH 0800/1007] spelling: template --- builder/ncloud/step_validate_template.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/ncloud/step_validate_template.go b/builder/ncloud/step_validate_template.go index f00525e5c..873cd4723 100644 --- a/builder/ncloud/step_validate_template.go +++ b/builder/ncloud/step_validate_template.go @@ -13,7 +13,7 @@ import ( "github.com/olekukonko/tablewriter" ) -//StepValidateTemplate : struct for Validation a tempalte +//StepValidateTemplate : struct for Validation a template type StepValidateTemplate struct { Conn *ncloud.Conn Validate func() error @@ -25,7 +25,7 @@ type StepValidateTemplate struct { FeeSystemTypeCode string } -// NewStepValidateTemplate : function for Validation a tempalte +// NewStepValidateTemplate : function for Validation a template func NewStepValidateTemplate(conn *ncloud.Conn, ui packer.Ui, config *Config) *StepValidateTemplate { var step = &StepValidateTemplate{ Conn: conn, From bf3bf79b8194f2efccaa3eeb785b48235908305e Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:25:12 +0000 Subject: [PATCH 0801/1007] spelling: timeoutms --- website/source/docs/builders/hyperv-iso.html.md | 2 +- website/source/docs/builders/hyperv-vmcx.html.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index 8e481bcad..3e919c925 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -656,7 +656,7 @@ Finish Setup cache proxy during installation --> </SynchronousCommand> <SynchronousCommand wcm:action="add"> <CommandLine>cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}</CommandLine> - <Description>Win RM MaxTimoutms</Description> + <Description>Win RM MaxTimeoutms</Description> <Order>5</Order> <RequiresUserInput>true</RequiresUserInput> </SynchronousCommand> diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index f43372c65..5ff7b604d 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -651,7 +651,7 @@ Finish Setup cache proxy during installation --> </SynchronousCommand> <SynchronousCommand wcm:action="add"> <CommandLine>cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}</CommandLine> - <Description>Win RM MaxTimoutms</Description> + <Description>Win RM MaxTimeoutms</Description> <Order>5</Order> <RequiresUserInput>true</RequiresUserInput> </SynchronousCommand> From 3b694feabc792db0e5b26cc45ce8dff249dc415d Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:25:35 +0000 Subject: [PATCH 0802/1007] spelling: transfer --- builder/digitalocean/wait.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/digitalocean/wait.go b/builder/digitalocean/wait.go index 2e4bd280c..684955853 100644 --- a/builder/digitalocean/wait.go +++ b/builder/digitalocean/wait.go @@ -198,12 +198,12 @@ func waitForImageState( } }() - log.Printf("Waiting for up to %d seconds for image transter to become %s", timeout/time.Second, desiredState) + log.Printf("Waiting for up to %d seconds for image transfer to become %s", timeout/time.Second, desiredState) select { case err := <-result: return err case <-time.After(timeout): - err := fmt.Errorf("Timeout while waiting to for image transter to become '%s'", desiredState) + err := fmt.Errorf("Timeout while waiting to for image transfer to become '%s'", desiredState) return err } } From 33f90d7783d4fb726536c016a2a1a0545a2dc348 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:27:22 +0000 Subject: [PATCH 0803/1007] spelling: unmarshalling --- builder/azure/pkcs12/pkcs12.go | 2 +- builder/azure/pkcs12/safebags.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/azure/pkcs12/pkcs12.go b/builder/azure/pkcs12/pkcs12.go index 806246daa..c5ce90f0d 100644 --- a/builder/azure/pkcs12/pkcs12.go +++ b/builder/azure/pkcs12/pkcs12.go @@ -92,7 +92,7 @@ const ( ) // unmarshal calls asn1.Unmarshal, but also returns an error if there is any -// trailing data after unmarshaling. +// trailing data after unmarshalling. func unmarshal(in []byte, out interface{}) error { trailing, err := asn1.Unmarshal(in, out) if err != nil { diff --git a/builder/azure/pkcs12/safebags.go b/builder/azure/pkcs12/safebags.go index bbd1526b8..836236da3 100644 --- a/builder/azure/pkcs12/safebags.go +++ b/builder/azure/pkcs12/safebags.go @@ -83,7 +83,7 @@ func decodePkcs8ShroudedKeyBag(asn1Data, password []byte) (privateKey interface{ ret := new(asn1.RawValue) if err = unmarshal(pkData, ret); err != nil { - return nil, errors.New("pkcs12: error unmarshaling decrypted private key: " + err.Error()) + return nil, errors.New("pkcs12: error unmarshalling decrypted private key: " + err.Error()) } if privateKey, err = x509.ParsePKCS8PrivateKey(pkData); err != nil { From b81672c906da1d0c5d9aaf0247ad4435a46227ee Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:28:00 +0000 Subject: [PATCH 0804/1007] spelling: valid --- builder/googlecompute/private_key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/googlecompute/private_key.go b/builder/googlecompute/private_key.go index 6bf22a309..cf81cba06 100644 --- a/builder/googlecompute/private_key.go +++ b/builder/googlecompute/private_key.go @@ -19,7 +19,7 @@ func processPrivateKeyFile(privateKeyFile, passphrase string) ([]byte, error) { PEMBlock, _ := pem.Decode(rawPrivateKeyBytes) if PEMBlock == nil { return nil, fmt.Errorf( - "%s does not contain a vaild private key", privateKeyFile) + "%s does not contain a valid private key", privateKeyFile) } if x509.IsEncryptedPEMBlock(PEMBlock) { From ecc3d12340509065d04699d9b265b02248d4505d Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:28:29 +0000 Subject: [PATCH 0805/1007] spelling: validate --- website/source/docs/templates/engine.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/templates/engine.html.md b/website/source/docs/templates/engine.html.md index 065e6001b..dd5c9e0fe 100644 --- a/website/source/docs/templates/engine.html.md +++ b/website/source/docs/templates/engine.html.md @@ -67,7 +67,7 @@ Here is a full list of the available functions for reference. This engine does not guarantee that the final image name will match the regex; it will not truncate your name if it exceeds 63 characters, and it - will not valiate that the beginning and end of the engine's output are + will not validate that the beginning and end of the engine's output are valid. For example, `"image_name": {{isotime | clean_image_name}}"` will cause your build to fail because the image name will start with a number, which is why in the From 0171dfc890e4bc7edd2434244aa309b514595ee5 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:28:19 +0000 Subject: [PATCH 0806/1007] spelling: validating --- builder/amazon/common/run_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 289a461b9..f647182aa 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -78,7 +78,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { // Validation errs := c.Comm.Prepare(ctx) - // Valadating ssh_interface + // Validating ssh_interface if c.SSHInterface != "public_ip" && c.SSHInterface != "private_ip" && c.SSHInterface != "public_dns" && From aa52f68fda11ddba7f0f9906de3a29e7312873a5 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:28:07 +0000 Subject: [PATCH 0807/1007] spelling: variable --- website/source/docs/builders/alicloud-ecs.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index 5c4330778..df7abbeff 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -159,7 +159,7 @@ builder. `_` or `-`. It cannot begin with `http://` or `https://`. - `security_token` (string) - STS access token, can be set through template or by exporting - as environment vairalbe such "export SecurityToken=value". + as environment variable such "export SecurityToken=value". - `skip_region_validation` (boolean) - The region validation can be skipped if this value is true, the default value is false. From 27dfe92f1cd5aebf889296a632abfc46e41bd56a Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:29:14 +0000 Subject: [PATCH 0808/1007] spelling: virtualization --- builder/file/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/file/builder.go b/builder/file/builder.go index f8b52e609..407bfcee5 100644 --- a/builder/file/builder.go +++ b/builder/file/builder.go @@ -2,7 +2,7 @@ package file /* The File builder creates an artifact from a file. Because it does not require -any virutalization or network resources, it's very fast and useful for testing. +any virtualization or network resources, it's very fast and useful for testing. */ import ( From c5482b3e7e77f045480099aa55af6907f42137b3 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:29:50 +0000 Subject: [PATCH 0809/1007] spelling: warnings --- packer/build_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/build_test.go b/packer/build_test.go index dd78bf4e7..a903c9803 100644 --- a/packer/build_test.go +++ b/packer/build_test.go @@ -102,7 +102,7 @@ func TestBuild_Prepare_Twice(t *testing.T) { build.Prepare() } -func TestBuildPrepare_BuilderWarniings(t *testing.T) { +func TestBuildPrepare_BuilderWarnings(t *testing.T) { expected := []string{"foo"} build := testBuild() From 38ffc65c4ec7d9d5df6cbb3fda9560574105d907 Mon Sep 17 00:00:00 2001 From: Josh Soref <jsoref@users.noreply.github.com> Date: Wed, 14 Mar 2018 03:30:07 +0000 Subject: [PATCH 0810/1007] spelling: whether --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe2f21796..8d922192d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1569,7 +1569,7 @@ * builder/docker: Can now specify login credentials to pull images. * builder/docker: Support mounting additional volumes. [GH-1430] * builder/parallels/all: Path to tools ISO is calculated automatically. [GH-1455] -* builder/parallels-pvm: `reassign_mac` option to choose wehther or not +* builder/parallels-pvm: `reassign_mac` option to choose whether or not to generate a new MAC address. [GH-1461] * builder/qemu: Can specify "none" acceleration type. [GH-1395] * builder/qemu: Can specify "tcg" acceleration type. [GH-1395] From b32a8cab4b18cb9ed18d7bc563c669a5d860e91d Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 14 Mar 2018 09:05:52 -0700 Subject: [PATCH 0811/1007] add note that packer doesn't support windows containers --- website/source/docs/builders/docker.html.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/source/docs/builders/docker.html.md b/website/source/docs/builders/docker.html.md index 23080e3ce..beab7dd28 100644 --- a/website/source/docs/builders/docker.html.md +++ b/website/source/docs/builders/docker.html.md @@ -30,6 +30,10 @@ support running on a Docker remote host_. You can learn about what [platforms Docker supports and how to install onto them](https://docs.docker.com/engine/installation/) in the Docker documentation. + + Please note: Packer does not yet have support for Windows containers. + + ## Basic Example: Export Below is a fully functioning example. It doesn't do anything useful, since no From b0937ff94d90e856238cb89571fa50fa0071dabd Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Thu, 8 Mar 2018 15:43:41 -0500 Subject: [PATCH 0812/1007] switch analytics from ga to segment --- website/Makefile | 2 +- website/config.rb | 10 ++++++++++ website/source/assets/javascripts/analytics.js | 9 +++++++++ .../source/assets/javascripts/application.js | 3 +++ website/source/layouts/layout.erb | 18 ++++++++++-------- 5 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 website/source/assets/javascripts/analytics.js diff --git a/website/Makefile b/website/Makefile index 82b2cedc1..934ed941e 100644 --- a/website/Makefile +++ b/website/Makefile @@ -8,7 +8,7 @@ build: --tty \ --volume "$(shell pwd):/website" \ hashicorp/middleman-hashicorp:${VERSION} \ - bundle exec middleman build --verbose --clean + ENV=production bundle exec middleman build --verbose --clean website: @echo "==> Starting website in Docker..." diff --git a/website/config.rb b/website/config.rb index 63b2de323..38ef7eb6f 100644 --- a/website/config.rb +++ b/website/config.rb @@ -8,6 +8,16 @@ activate :hashicorp do |h| end helpers do + # Returns a segment tracking ID such that local development is not + # tracked to production systems. + def segmentId() + if (ENV['ENV'] == 'production') + 'AjXdfmTTk1I9q9dfyePuDFHBrz1tCO3l' + else + '0EXTgkNx0Ydje2PGXVbRhpKKoe5wtzcE' + end + end + # Returns the FQDN of the image URL. # # @param [String] path diff --git a/website/source/assets/javascripts/analytics.js b/website/source/assets/javascripts/analytics.js new file mode 100644 index 000000000..17ca06dd9 --- /dev/null +++ b/website/source/assets/javascripts/analytics.js @@ -0,0 +1,9 @@ +document.addEventListener('DOMContentLoaded', () => { + track('.downloads .download a', el => { + return { + event: 'Download', + category: 'Button', + label: `Packer | v${el.href.match(/\/(\d+\.\d+\.\d+)\//)[1]}` + } + }) +}) diff --git a/website/source/assets/javascripts/application.js b/website/source/assets/javascripts/application.js index 5d2365e14..ae70e571d 100644 --- a/website/source/assets/javascripts/application.js +++ b/website/source/assets/javascripts/application.js @@ -3,3 +3,6 @@ //= require hashicorp/mega-nav //= require hashicorp/sidebar +//= require hashicorp/analytics + +//= require analytics diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index ab0f53361..aa476c059 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -119,14 +119,16 @@ </div> <script> - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - - ga('create', 'UA-43075859-1', 'packer.io'); - ga('require', 'linkid'); - ga('send', 'pageview', location.pathname); + // ga async load + window['GoogleAnalyticsObject'] = 'ga'; + window['ga'] = window['ga'] || function() { + (window['ga'].q = window['ga'].q || []).push(arguments) + }; + // analytics.js + !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; + analytics.load("<%= segmentId %>"); + analytics.page(); + }}(); </script> <script type="application/ld+json"> From d689e6b4d3cd651a90de77adafea1017c9969808 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 8 Mar 2018 15:14:57 -0800 Subject: [PATCH 0813/1007] allow users of AWS to use the dynamically-generated admin password which we use as the winRM password as an elevated password in the Powershell provisioner, as well as an environment variable in same provisoner. --- builder/amazon/common/step_get_password.go | 7 ++++++- common/step_http_server.go | 22 ++++++++-------------- provisioner/powershell/provisioner.go | 19 ++++++++++++++++++- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index 5e2a236c2..c9011d930 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -12,6 +12,7 @@ import ( "time" "github.com/aws/aws-sdk-go/service/ec2" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -92,11 +93,15 @@ WaitLoop: ui.Message(fmt.Sprintf( "Password (since debug is enabled): %s", s.Comm.WinRMPassword)) } + // store so that we can access this later during provisioning + commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword) return multistep.ActionContinue } -func (s *StepGetPassword) Cleanup(multistep.StateBag) {} +func (s *StepGetPassword) Cleanup(multistep.StateBag) { + commonhelper.RemoveSharedStateFile("winrm_password") +} func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) { ec2conn := state.Get("ec2").(*ec2.EC2) diff --git a/common/step_http_server.go b/common/step_http_server.go index e90c6ef60..953ef38c1 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -3,14 +3,12 @@ package common import ( "context" "fmt" - "io/ioutil" "log" "math/rand" "net" "net/http" - "os" - "path/filepath" + "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -77,25 +75,21 @@ func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multis return multistep.ActionContinue } -func httpAddrFilename(suffix string) string { - uuid := os.Getenv("PACKER_RUN_UUID") - return filepath.Join(os.TempDir(), fmt.Sprintf("packer-%s-%s", uuid, suffix)) -} - func SetHTTPPort(port string) error { - return ioutil.WriteFile(httpAddrFilename("port"), []byte(port), 0644) + return common.SetSharedState("port", port) } func SetHTTPIP(ip string) error { - return ioutil.WriteFile(httpAddrFilename("ip"), []byte(ip), 0644) + return common.SetSharedState("ip", ip) } func GetHTTPAddr() string { - ip, err := ioutil.ReadFile(httpAddrFilename("ip")) + ip, err := common.RetrieveSharedState("ip") if err != nil { return "" } - port, err := ioutil.ReadFile(httpAddrFilename("port")) + + port, err := common.RetrieveSharedState("port") if err != nil { return "" } @@ -107,6 +101,6 @@ func (s *StepHTTPServer) Cleanup(multistep.StateBag) { // Close the listener so that the HTTP server stops s.l.Close() } - os.Remove(httpAddrFilename("port")) - os.Remove(httpAddrFilename("ip")) + common.RemoveSharedStateFile("port") + common.RemoveSharedStateFile("ip") } diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 9655f6fed..a071a6b21 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/uuid" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -114,7 +115,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { }, }, }, raws...) - if err != nil { return err } @@ -358,10 +358,17 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Always available Packer provided env vars envVars["PACKER_BUILD_NAME"] = p.config.PackerBuildName envVars["PACKER_BUILDER_TYPE"] = p.config.PackerBuilderType + httpAddr := common.GetHTTPAddr() if httpAddr != "" { envVars["PACKER_HTTP_ADDR"] = httpAddr } + winRMPass, err := commonhelper.RetrieveSharedState("winrm_password") + // This shared state is only created by the amazon builder. + if err == nil { + envVars["AUTO_WINRM_PASSWORD"] = psEscape.Replace(winRMPass) + + } // Split vars into key/value components for _, envVar := range p.config.Vars { @@ -501,6 +508,16 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", p.config.ElevatedUser, escapedElevatedUser) } + // Replace ElevatedPassword for winrm users who used this feature + if strings.Compare(p.config.ElevatedPassword, ".AUTO_WINRM_PASSWORD") == 0 { + winRMPass, err := commonhelper.RetrieveSharedState("winrm_password") + // This shared state is only created by the amazon builder. + if err != nil { + fmt.Printf("Error reading AUTO_WINRM_PASSWORD from state: %s", err) + return "", err + } + p.config.ElevatedPassword = winRMPass + } // Escape chars special to PowerShell in the ElevatedPassword string escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) From 4d19f4f8b6cb5b923170684c438a13d62a155b61 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 8 Mar 2018 15:22:28 -0800 Subject: [PATCH 0814/1007] add all the new files --- helper/common/shared_state.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 helper/common/shared_state.go diff --git a/helper/common/shared_state.go b/helper/common/shared_state.go new file mode 100644 index 000000000..5029bfbab --- /dev/null +++ b/helper/common/shared_state.go @@ -0,0 +1,31 @@ +package common + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +// Used to set variables which we need to access later in the build, where +// state bag and config information won't work +func sharedStateFilename(suffix string) string { + uuid := os.Getenv("PACKER_RUN_UUID") + return filepath.Join(os.TempDir(), fmt.Sprintf("packer-%s-%s", uuid, suffix)) +} + +func SetSharedState(key string, value string) error { + return ioutil.WriteFile(sharedStateFilename(key), []byte(value), 0644) +} + +func RetrieveSharedState(key string) (string, error) { + value, err := ioutil.ReadFile(sharedStateFilename(key)) + if err != nil { + return "", err + } + return string(value), nil +} + +func RemoveSharedStateFile(key string) { + os.Remove(sharedStateFilename(key)) +} From 559719020cf0722c9044fb7aca74eacddf7f8ccf Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 14 Mar 2018 17:19:17 -0700 Subject: [PATCH 0815/1007] use {{.WinRMPassword}} instead of some other weirdness --- provisioner/powershell/provisioner.go | 51 +++++++++++++++++++-------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index a071a6b21..77ac61afc 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -100,11 +100,21 @@ type Provisioner struct { } type ExecuteCommandTemplate struct { - Vars string - Path string + Vars string + Path string + WinRMPassword string +} + +type EnvVarsTemplate struct { + WinRMPassword string } func (p *Provisioner) Prepare(raws ...interface{}) error { + //Create passthrough for winrm password so we can fill it in once we know it + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: `{{.WinRMPassword}}`, + } + err := config.Decode(&p.config, &config.DecodeOpts{ Interpolate: true, InterpolateContext: &p.config.ctx, @@ -115,6 +125,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { }, }, }, raws...) + if err != nil { return err } @@ -369,9 +380,16 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { envVars["AUTO_WINRM_PASSWORD"] = psEscape.Replace(winRMPass) } - + // interpolate environment variables + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: p.getWinRMPassword(), + } // Split vars into key/value components for _, envVar := range p.config.Vars { + envVar, err = interpolate.Render(envVar, &p.config.ctx) + if err != nil { + return + } keyValue := strings.SplitN(envVar, "=", 2) // Escape chars special to PS in each env var value escapedEnvVarValue := psEscape.Replace(keyValue[1]) @@ -430,8 +448,9 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro } p.config.ctx.Data = &ExecuteCommandTemplate{ - Path: p.config.RemotePath, - Vars: envVarPath, + Path: p.config.RemotePath, + Vars: envVarPath, + WinRMPassword: p.getWinRMPassword(), } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -443,6 +462,11 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro return command, nil } +func (p *Provisioner) getWinRMPassword() string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password") + return winRMPass + +} func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { // Prepare everything needed to enable the required env vars within the remote environment envVarPath, err := p.prepareEnvVars(true) @@ -451,8 +475,9 @@ func (p *Provisioner) createCommandTextPrivileged() (command string, err error) } p.config.ctx.Data = &ExecuteCommandTemplate{ - Path: p.config.RemotePath, - Vars: envVarPath, + Path: p.config.RemotePath, + Vars: envVarPath, + WinRMPassword: p.getWinRMPassword(), } command, err = interpolate.Render(p.config.ElevatedExecuteCommand, &p.config.ctx) if err != nil { @@ -509,16 +534,12 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin p.config.ElevatedUser, escapedElevatedUser) } // Replace ElevatedPassword for winrm users who used this feature - if strings.Compare(p.config.ElevatedPassword, ".AUTO_WINRM_PASSWORD") == 0 { - winRMPass, err := commonhelper.RetrieveSharedState("winrm_password") - // This shared state is only created by the amazon builder. - if err != nil { - fmt.Printf("Error reading AUTO_WINRM_PASSWORD from state: %s", err) - return "", err - } - p.config.ElevatedPassword = winRMPass + p.config.ctx.Data = &EnvVarsTemplate{ + WinRMPassword: p.getWinRMPassword(), } + p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) + // Escape chars special to PowerShell in the ElevatedPassword string escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) if escapedElevatedPassword != p.config.ElevatedPassword { From e483087574896d1578fc169d7a8d0c99b91a157f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 14 Mar 2018 22:26:33 -0700 Subject: [PATCH 0816/1007] builder/amazon: Use service default retries. Each service has its own preconfigured number of times to retry. Lets use that instead of setting a global number. --- builder/amazon/common/access_config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 563030f50..6228f35b2 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -96,7 +96,7 @@ func (c *AccessConfig) Session() (*session.Session, error) { creds := credentials.NewChainCredentials(providers) - config := aws.NewConfig().WithMaxRetries(11).WithCredentialsChainVerboseErrors(true) + config := aws.NewConfig().WithCredentialsChainVerboseErrors(true) if c.RawRegion != "" { config = config.WithRegion(c.RawRegion) From ce1ab1f021d5a6fe6d28fbced4fa1c319474f15b Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 15 Mar 2018 09:44:22 -0700 Subject: [PATCH 0817/1007] fix winrm password --- provisioner/powershell/provisioner.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 77ac61afc..e3340d771 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -374,19 +374,14 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { if httpAddr != "" { envVars["PACKER_HTTP_ADDR"] = httpAddr } - winRMPass, err := commonhelper.RetrieveSharedState("winrm_password") - // This shared state is only created by the amazon builder. - if err == nil { - envVars["AUTO_WINRM_PASSWORD"] = psEscape.Replace(winRMPass) - } // interpolate environment variables p.config.ctx.Data = &EnvVarsTemplate{ WinRMPassword: p.getWinRMPassword(), } // Split vars into key/value components for _, envVar := range p.config.Vars { - envVar, err = interpolate.Render(envVar, &p.config.ctx) + envVar, err := interpolate.Render(envVar, &p.config.ctx) if err != nil { return } From 2f420c38b2708585469e9b4b2ec3a0a9a7737e44 Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Thu, 15 Mar 2018 13:05:42 -0400 Subject: [PATCH 0818/1007] add optinmonster script, fix makefile, remove es6 --- website/Gemfile | 2 +- website/Gemfile.lock | 4 ++-- website/Makefile | 5 +++-- website/source/assets/javascripts/analytics.js | 6 +++--- website/source/layouts/layout.erb | 7 ++++++- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/website/Gemfile b/website/Gemfile index a7edfed49..177bf1774 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.32" +gem "middleman-hashicorp", "0.3.34" diff --git a/website/Gemfile.lock b/website/Gemfile.lock index 913b76417..15173900a 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -78,7 +78,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.32) + middleman-hashicorp (0.3.34) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -153,7 +153,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.32) + middleman-hashicorp (= 0.3.34) BUNDLED WITH 1.16.1 diff --git a/website/Makefile b/website/Makefile index 934ed941e..0991a7753 100644 --- a/website/Makefile +++ b/website/Makefile @@ -1,4 +1,4 @@ -VERSION?="0.3.32" +VERSION?="0.3.34" build: @echo "==> Starting build in Docker..." @@ -7,8 +7,9 @@ build: --rm \ --tty \ --volume "$(shell pwd):/website" \ + -e "ENV=production" \ hashicorp/middleman-hashicorp:${VERSION} \ - ENV=production bundle exec middleman build --verbose --clean + bundle exec middleman build --verbose --clean website: @echo "==> Starting website in Docker..." diff --git a/website/source/assets/javascripts/analytics.js b/website/source/assets/javascripts/analytics.js index 17ca06dd9..33342909a 100644 --- a/website/source/assets/javascripts/analytics.js +++ b/website/source/assets/javascripts/analytics.js @@ -1,9 +1,9 @@ -document.addEventListener('DOMContentLoaded', () => { - track('.downloads .download a', el => { +document.addEventListener('DOMContentLoaded', function() { + track('.downloads .download a', function(el) { return { event: 'Download', category: 'Button', - label: `Packer | v${el.href.match(/\/(\d+\.\d+\.\d+)\//)[1]}` + label: 'Packer | v' + el.href.match(/\/(\d+\.\d+\.\d+)\//)[1] } }) }) diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index aa476c059..a632d884e 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -130,7 +130,12 @@ analytics.page(); }}(); </script> - + <script> + // optinmonster + var om597a24292a958,om597a24292a958_poll=function(){var b=0;return function(d,c){clearInterval(b);b=setInterval(d,c)}}(); + !function(b,d,c){if(b.getElementById(c))om597a24292a958_poll(function(){if(window.om_loaded&&!om597a24292a958)return om597a24292a958=new OptinMonsterApp,om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0})},25);else{var e=!1,a=b.createElement(d);a.id=c;a.src="//a.optnmstr.com/app/js/api.min.js";a.async=!0;a.onload=a.onreadystatechange=function(){if(!(e||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState))try{e=om_loaded=!0,om597a24292a958=new OptinMonsterApp, + om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0}),a.onload=a.onreadystatechange=null}catch(f){}};(document.getElementsByTagName("head")[0]||document.documentElement).appendChild(a)}}(document,"script","omapi-script"); + </script> <script type="application/ld+json"> { "@context": "http://schema.org", From 05c1938d922aaff7577e2b26423e7338f8a98c31 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Thu, 15 Mar 2018 15:09:48 -0700 Subject: [PATCH 0819/1007] update deprcation date --- website/source/docs/commands/push.html.md | 4 ++-- website/source/docs/post-processors/atlas.html.md | 4 ++-- website/source/docs/templates/push.html.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/source/docs/commands/push.html.md b/website/source/docs/commands/push.html.md index c2cd190e5..5a40415a0 100644 --- a/website/source/docs/commands/push.html.md +++ b/website/source/docs/commands/push.html.md @@ -10,8 +10,8 @@ sidebar_current: 'docs-commands-push' # `push` Command !&gt; The Packer and Artifact Registry features of Atlas will no longer be -actively developed or maintained and will be fully decommissioned on Friday, -March 30, 2018. Please see our [guide on building immutable infrastructure with +actively developed or maintained and will be fully decommissioned on Thursday, +May 31, 2018. Please see our [guide on building immutable infrastructure with Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these features yourself. diff --git a/website/source/docs/post-processors/atlas.html.md b/website/source/docs/post-processors/atlas.html.md index e53bae48d..7edd5b041 100644 --- a/website/source/docs/post-processors/atlas.html.md +++ b/website/source/docs/post-processors/atlas.html.md @@ -11,8 +11,8 @@ sidebar_current: 'docs-post-processors-atlas' # Atlas Post-Processor !&gt; The Packer and Artifact Registry features of Atlas will no longer be -actively developed or maintained and will be fully decommissioned on Friday, -March 30, 2018. Please see our [guide on building immutable infrastructure with +actively developed or maintained and will be fully decommissioned on Thursday, +May 31, 2018. Please see our [guide on building immutable infrastructure with Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these features yourself. diff --git a/website/source/docs/templates/push.html.md b/website/source/docs/templates/push.html.md index 4934ae16d..c4cdeec08 100644 --- a/website/source/docs/templates/push.html.md +++ b/website/source/docs/templates/push.html.md @@ -10,8 +10,8 @@ sidebar_current: 'docs-templates-push' # Template Push !&gt; The Packer and Artifact Registry features of Atlas will no longer be -actively developed or maintained and will be fully decommissioned on Friday, -March 30, 2018. Please see our [guide on building immutable infrastructure with +actively developed or maintained and will be fully decommissioned on Thursday, +May 31, 2018. Please see our [guide on building immutable infrastructure with Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these features yourself. From b16f2ec64b36753e6d65d85bbb5e732080f5ccd4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 15 Mar 2018 09:49:34 -0700 Subject: [PATCH 0820/1007] builder/amazon: Use sdk default cred providers I think we were overcomplicating things. The SDK provides the correct credential chain by default, so let's use that. This patch does a quick check for static credentials and uses those if found, then defaults to the default credential provider chain. This patch also removes the metadata timeout argument. Current versions of the SDK have short timeouts by default, so I don't believe this is needed. --- builder/amazon/common/access_config.go | 70 +++------------------ website/source/docs/builders/amazon.html.md | 8 --- 2 files changed, 8 insertions(+), 70 deletions(-) diff --git a/builder/amazon/common/access_config.go b/builder/amazon/common/access_config.go index 6228f35b2..862a64d21 100644 --- a/builder/amazon/common/access_config.go +++ b/builder/amazon/common/access_config.go @@ -3,14 +3,12 @@ package common import ( "fmt" "log" - "os" "strings" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "github.com/hashicorp/go-cleanhttp" @@ -38,66 +36,13 @@ func (c *AccessConfig) Session() (*session.Session, error) { return c.session, nil } - // build a chain provider, lazy-evaluated by aws-sdk - providers := []credentials.Provider{ - &credentials.StaticProvider{Value: credentials.Value{ - AccessKeyID: c.AccessKey, - SecretAccessKey: c.SecretKey, - SessionToken: c.Token, - }}, - &credentials.EnvProvider{}, - &credentials.SharedCredentialsProvider{ - Filename: "", - Profile: c.ProfileName, - }, - } - - // Build isolated HTTP client to avoid issues with globally-shared settings - client := cleanhttp.DefaultClient() - - // Keep the default timeout (100ms) low as we don't want to wait in non-EC2 environments - client.Timeout = 100 * time.Millisecond - - const userTimeoutEnvVar = "AWS_METADATA_TIMEOUT" - userTimeout := os.Getenv(userTimeoutEnvVar) - if userTimeout != "" { - newTimeout, err := time.ParseDuration(userTimeout) - if err == nil { - if newTimeout.Nanoseconds() > 0 { - client.Timeout = newTimeout - } else { - log.Printf("[WARN] Non-positive value of %s (%s) is meaningless, ignoring", userTimeoutEnvVar, newTimeout.String()) - } - } else { - log.Printf("[WARN] Error converting %s to time.Duration: %s", userTimeoutEnvVar, err) - } - } - - log.Printf("[INFO] Setting AWS metadata API timeout to %s", client.Timeout.String()) - cfg := &aws.Config{ - HTTPClient: client, - } - if !c.SkipMetadataApiCheck { - // Real AWS should reply to a simple metadata request. - // We check it actually does to ensure something else didn't just - // happen to be listening on the same IP:Port - metadataClient := ec2metadata.New(session.New(cfg)) - if metadataClient.Available() { - providers = append(providers, &ec2rolecreds.EC2RoleProvider{ - Client: metadataClient, - }) - log.Print("[INFO] AWS EC2 instance detected via default metadata" + - " API endpoint, EC2RoleProvider added to the auth chain") - } else { - log.Printf("[INFO] Ignoring AWS metadata API endpoint " + - "as it doesn't return any instance-id") - } - } - - creds := credentials.NewChainCredentials(providers) - config := aws.NewConfig().WithCredentialsChainVerboseErrors(true) + staticCreds := credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token) + if _, err := staticCreds.Get(); err != credentials.ErrStaticCredentialsEmpty { + config.WithCredentials(staticCreds) + } + if c.RawRegion != "" { config = config.WithRegion(c.RawRegion) } else if region := c.metadataRegion(); region != "" { @@ -123,8 +68,6 @@ func (c *AccessConfig) Session() (*session.Session, error) { } } - config = config.WithCredentials(creds) - if sess, err := session.NewSessionWithOptions(opts); err != nil { return nil, err } else if *sess.Config.Region == "" { @@ -185,6 +128,9 @@ func (c *AccessConfig) metadataRegion() string { func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { var errs []error + if c.SkipMetadataApiCheck { + log.Println("(WARN) skip_metadata_api_check ignored.") + } // Either both access and secret key must be set or neither of them should // be. if (len(c.AccessKey) > 0) != (len(c.SecretKey) > 0) { diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index 21dad780a..8af3f101f 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -123,14 +123,6 @@ This is a preferred approach over any other when running in EC2 as you can avoid hard coding credentials. Instead these are leased on-the-fly by Packer, which reduces the chance of leakage. -The default deadline for the EC2 metadata API endpoint is 100 milliseconds, -which can be overidden by setting the `AWS_METADATA_TIMEOUT` environment -variable. The variable expects a positive golang Time.Duration string, which is -a sequence of decimal numbers and a unit suffix; valid suffixes are `ns` -(nanoseconds), `us` (microseconds), `ms` (milliseconds), `s` (seconds), `m` -(minutes), and `h` (hours). Examples of valid inputs: `100ms`, `250ms`, `1s`, -`2.5s`, `2.5m`, `1m30s`. - The following policy document provides the minimal set permissions necessary for Packer to work: From 1ddbc4996ed3ebb48642b6508550ad6b9b7427e1 Mon Sep 17 00:00:00 2001 From: Maciej Skierkowski <maciej@skierkowski.com> Date: Thu, 15 Mar 2018 17:26:08 -0700 Subject: [PATCH 0821/1007] remove hard date --- website/source/docs/commands/push.html.md | 4 ++-- website/source/docs/post-processors/atlas.html.md | 4 ++-- website/source/docs/templates/push.html.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/source/docs/commands/push.html.md b/website/source/docs/commands/push.html.md index 5a40415a0..134b443e7 100644 --- a/website/source/docs/commands/push.html.md +++ b/website/source/docs/commands/push.html.md @@ -10,8 +10,8 @@ sidebar_current: 'docs-commands-push' # `push` Command !&gt; The Packer and Artifact Registry features of Atlas will no longer be -actively developed or maintained and will be fully decommissioned on Thursday, -May 31, 2018. Please see our [guide on building immutable infrastructure with +actively developed or maintained and will be fully decommissioned. +Please see our [guide on building immutable infrastructure with Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these features yourself. diff --git a/website/source/docs/post-processors/atlas.html.md b/website/source/docs/post-processors/atlas.html.md index 7edd5b041..8cf78b4fc 100644 --- a/website/source/docs/post-processors/atlas.html.md +++ b/website/source/docs/post-processors/atlas.html.md @@ -11,8 +11,8 @@ sidebar_current: 'docs-post-processors-atlas' # Atlas Post-Processor !&gt; The Packer and Artifact Registry features of Atlas will no longer be -actively developed or maintained and will be fully decommissioned on Thursday, -May 31, 2018. Please see our [guide on building immutable infrastructure with +actively developed or maintained and will be fully decommissioned. +Please see our [guide on building immutable infrastructure with Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these features yourself. diff --git a/website/source/docs/templates/push.html.md b/website/source/docs/templates/push.html.md index c4cdeec08..541ff4422 100644 --- a/website/source/docs/templates/push.html.md +++ b/website/source/docs/templates/push.html.md @@ -10,8 +10,8 @@ sidebar_current: 'docs-templates-push' # Template Push !&gt; The Packer and Artifact Registry features of Atlas will no longer be -actively developed or maintained and will be fully decommissioned on Thursday, -May 31, 2018. Please see our [guide on building immutable infrastructure with +actively developed or maintained and will be fully decommissioned. +Please see our [guide on building immutable infrastructure with Packer on CI/CD](/guides/packer-on-cicd/) for ideas on implementing these features yourself. From 4e32d0da24e345b3d041612fa08faee0e64027ec Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 16 Mar 2018 14:11:32 -0700 Subject: [PATCH 0822/1007] stricter permissions on shared state file since it now contains a password --- helper/common/shared_state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/common/shared_state.go b/helper/common/shared_state.go index 5029bfbab..92ffbaeaf 100644 --- a/helper/common/shared_state.go +++ b/helper/common/shared_state.go @@ -15,7 +15,7 @@ func sharedStateFilename(suffix string) string { } func SetSharedState(key string, value string) error { - return ioutil.WriteFile(sharedStateFilename(key), []byte(value), 0644) + return ioutil.WriteFile(sharedStateFilename(key), []byte(value), 0600) } func RetrieveSharedState(key string) (string, error) { From de7d1430bdcd9430e1b9a006b260871eabbc735f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 16 Mar 2018 14:25:09 -0700 Subject: [PATCH 0823/1007] update powershell docs to include reference to the new winrmpassword template variable --- .../docs/provisioners/powershell.html.md | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index a9c218638..d2707c76a 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -72,7 +72,16 @@ Optional parameters: - `environment_vars` (array of strings) - An array of key/value pairs to inject prior to the execute\_command. The format should be `key=value`. Packer injects some environmental variables by default into the - environment, as well, which are covered in the section below. + environment, as well, which are covered in the section below. If you are + using AWS and would like to use the randomly-generated unique + If you are running on AWS and would like to access the AWS-generated + Administrator password that Packer uses to connect to the instance via + WinRM, you can use the template variable `{{.WinRMPassword}}` to set this + as an environment variable. For example: + + ```json + "environment_vars": "WINRMPASS={{.WinRMPassword}}", + ``` - `execute_command` (string) - The command to use to execute the script. By default this is as follows: @@ -89,7 +98,15 @@ Optional parameters: - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given - Windows user. + Windows user. If you are running a build on AWS and would like to run using + the AWS-generated password that Packer uses to connect to the instance via, + WinRM, you may do so by using the template variable {{.WinRMPassword}}. + For example: + + ``` json + "elevated_user": "Administrator", + "elevated_password": "{{.WinRMPassword}}", + ``` - `remote_path` (string) - The path where the script will be uploaded to in the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must From f3dc7546d4f5724dc0de4eaf491423d5b123f266 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 16 Mar 2018 14:28:20 -0700 Subject: [PATCH 0824/1007] even clearer example in winrmpassword docs --- website/source/docs/provisioners/powershell.html.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index d2707c76a..92fc00ed2 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -80,7 +80,11 @@ Optional parameters: as an environment variable. For example: ```json - "environment_vars": "WINRMPASS={{.WinRMPassword}}", + { + "type": "powershell", + "environment_vars": "WINRMPASS={{.WinRMPassword}}", + "inline": ["Write-Host \"Automatically generated aws password is: $Env:WINRMPASS\""] + }, ``` - `execute_command` (string) - The command to use to execute the script. By From 49958391b3e622aac558e4c4a521ea315616709f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 19 Mar 2018 09:58:39 -0700 Subject: [PATCH 0825/1007] better error when source_path doesn't exist. --- builder/virtualbox/ovf/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 5eef4507c..9a90b1a5b 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -104,7 +104,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { fileOK := common.FileExistsLocally(c.SourcePath) if !fileOK { packer.MultiErrorAppend(errs, - fmt.Errorf("Source file needs to exist at time of config validation!")) + fmt.Errorf("Source file '%s' needs to exist at time of config validation!", c.SourcePath)) } } From 3c37aaf4e6f8f0a3a72a6095e483c33e38124c82 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 19 Mar 2018 10:50:29 -0700 Subject: [PATCH 0826/1007] update atlas deprecation language This is a follow-on to #6018 --- command/push.go | 7 +++---- post-processor/atlas/post-processor.go | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/command/push.go b/command/push.go index f063ae0d3..ba366a5d6 100644 --- a/command/push.go +++ b/command/push.go @@ -254,10 +254,9 @@ func (c *PushCommand) Run(args []string) int { c.Ui.Message("\n-----------------------------------------------------------------------\n" + "Deprecation warning: The Packer and Artifact Registry features of Atlas\n" + "will no longer be actively developed or maintained and will be fully\n" + - "decommissioned on Friday, March 30, 2018. Please see our guide on\n" + - "building immutable infrastructure with Packer on CI/CD for ideas on\n" + - "implementing these features yourself:\n" + - "https://www.packer.io/guides/packer-on-cicd/\n" + + "decommissioned. Please see our guide on building immutable\n" + + "infrastructure with Packer on CI/CD for ideas on implementing\n" + + "these features yourself: https://www.packer.io/guides/packer-on-cicd/\n" + "-----------------------------------------------------------------------\n", ) diff --git a/post-processor/atlas/post-processor.go b/post-processor/atlas/post-processor.go index a0df0db06..42d45c054 100644 --- a/post-processor/atlas/post-processor.go +++ b/post-processor/atlas/post-processor.go @@ -155,10 +155,9 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message("\n-----------------------------------------------------------------------\n" + "Deprecation warning: The Packer and Artifact Registry features of Atlas\n" + "will no longer be actively developed or maintained and will be fully\n" + - "decommissioned on Friday, March 30, 2018. Please see our guide on\n" + - "building immutable infrastructure with Packer on CI/CD for ideas on\n" + - "implementing these features yourself:\n" + - "https://www.packer.io/guides/packer-on-cicd/\n" + + "decommissioned. Please see our guide on building immutable\n" + + "infrastructure with Packer on CI/CD for ideas on implementing\n" + + "these features yourself: https://www.packer.io/guides/packer-on-cicd/\n" + "-----------------------------------------------------------------------\n", ) From 04e938162127167487b1ad049a796f45a5c3ace6 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 19 Mar 2018 14:49:28 -0700 Subject: [PATCH 0827/1007] update changelog --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d922192d..ecd3c1a94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,30 @@ * builder/amazon: Fix authorization using assume role. [GH-5914] * builder/hyper-v: Fix command collisions with VMWare PowerCLI. [GH-5861] +* builder/virtualbox: Correctly send multi-byte scancodes when typing boot + command. [GH-5987] * builder/vmware-iso: Fix panic when building on esx5 remotes. [GH-5931] * builder/vmware: Fix issue detecting host IP. [GH-5898] [GH-5900] * provisioner/ansible-local: Fix conflicting escaping schemes for vars provided via `--extra-vars`. [GH-5888] +* provisioner/powershell: Fix environment variable file escaping. [GH-5973] ### IMPROVEMENTS: +* builder/amazon: Added new region `cn-northwest-1`. [GH-5960] +* builder/azure: Add support concurrent deployments in the same resource group. + [GH-6005] +* builder/azure: Add support for building with additional disks. [GH-5944] +* builder/azure: Add support for marketplace plan information. [GH-5970] +* builder/azure: Make all command output human readable. [GH-5967] +* builder/azure: Respect `-force` for managed image deletion. [GH-6003] +* builder/google: Add option to specify a service account, or to run without + one. [GH-5991] [GH-5928] * builder/oracle-classic: Add `snapshot_timeout` option to control how long we wait for the snapshot to be created. [GH-5932] * builder/oracle-classic: Add support for WinRM connections. [GH-5929] +* post-processor/vagrant: Add LXC support. [GH-5980] +* provisioner/salt-masterless: Added Windows support. [GH-5702] ## 1.2.0 (February 9, 2018) From eb73344e516389e9994c2a7412dc79282ee7ca99 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 19 Mar 2018 14:49:57 -0700 Subject: [PATCH 0828/1007] Revert "update changelog" This reverts commit 04e938162127167487b1ad049a796f45a5c3ace6. --- CHANGELOG.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd3c1a94..8d922192d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,30 +4,16 @@ * builder/amazon: Fix authorization using assume role. [GH-5914] * builder/hyper-v: Fix command collisions with VMWare PowerCLI. [GH-5861] -* builder/virtualbox: Correctly send multi-byte scancodes when typing boot - command. [GH-5987] * builder/vmware-iso: Fix panic when building on esx5 remotes. [GH-5931] * builder/vmware: Fix issue detecting host IP. [GH-5898] [GH-5900] * provisioner/ansible-local: Fix conflicting escaping schemes for vars provided via `--extra-vars`. [GH-5888] -* provisioner/powershell: Fix environment variable file escaping. [GH-5973] ### IMPROVEMENTS: -* builder/amazon: Added new region `cn-northwest-1`. [GH-5960] -* builder/azure: Add support concurrent deployments in the same resource group. - [GH-6005] -* builder/azure: Add support for building with additional disks. [GH-5944] -* builder/azure: Add support for marketplace plan information. [GH-5970] -* builder/azure: Make all command output human readable. [GH-5967] -* builder/azure: Respect `-force` for managed image deletion. [GH-6003] -* builder/google: Add option to specify a service account, or to run without - one. [GH-5991] [GH-5928] * builder/oracle-classic: Add `snapshot_timeout` option to control how long we wait for the snapshot to be created. [GH-5932] * builder/oracle-classic: Add support for WinRM connections. [GH-5929] -* post-processor/vagrant: Add LXC support. [GH-5980] -* provisioner/salt-masterless: Added Windows support. [GH-5702] ## 1.2.0 (February 9, 2018) From b9bcde5a97ab5b936ccb13dbe23f3ee2bd98fa8d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 19 Mar 2018 14:53:17 -0700 Subject: [PATCH 0829/1007] update changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d922192d..9873dd030 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +## (UNRELEASED) + +### BUG FIXES: + +* builder/virtualbox: Correctly send multi-byte scancodes when typing boot + command. [GH-5987] +* provisioner/powershell: Fix environment variable file escaping. [GH-5973] + +### IMPROVEMENTS: + +* builder/amazon: Added new region `cn-northwest-1`. [GH-5960] +* builder/azure: Add support concurrent deployments in the same resource group. + [GH-6005] +* builder/azure: Add support for building with additional disks. [GH-5944] +* builder/azure: Add support for marketplace plan information. [GH-5970] +* builder/azure: Make all command output human readable. [GH-5967] +* builder/azure: Respect `-force` for managed image deletion. [GH-6003] +* builder/google: Add option to specify a service account, or to run without + one. [GH-5991] [GH-5928] +* post-processor/vagrant: Add LXC support. [GH-5980] +* provisioner/salt-masterless: Added Windows support. [GH-5702] + + ## 1.2.1 (February 23, 2018) ### BUG FIXES: From e2f9204c11bc5623e9284832e2e5231f01112fa2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 19 Mar 2018 15:52:43 -0700 Subject: [PATCH 0830/1007] replace nil ptr exceptions with infinite loops --- communicator/ssh/communicator.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index d81ab750a..6fedb479c 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -423,6 +423,9 @@ func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, } cmd.Wait() if cmd.ExitStatus == 0 { + if fi == nil { + return fmt.Errorf("Upload path is a directory, unable to continue.") + } log.Printf("path is a directory; copying file into directory.") path = filepath.Join(path, filepath.Base((*fi).Name())) } @@ -586,6 +589,9 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e } cmd.Wait() if cmd.ExitStatus == 0 { + if fi == nil { + return fmt.Errorf("Upload path is a directory, unable to continue.") + } log.Printf("path is a directory; copying file into directory.") target_dir = path target_file = filepath.Base((*fi).Name()) From 2cecd73aad272e1ecd5455614db765e699bd33da Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 20 Mar 2018 11:32:01 -0700 Subject: [PATCH 0831/1007] add clarity to error message in vsphere-template postprocessor --- post-processor/vsphere-template/post-processor.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/post-processor/vsphere-template/post-processor.go b/post-processor/vsphere-template/post-processor.go index b12b53b64..bba5e33ea 100644 --- a/post-processor/vsphere-template/post-processor.go +++ b/post-processor/vsphere-template/post-processor.go @@ -89,7 +89,10 @@ func (p *PostProcessor) Configure(raws ...interface{}) error { func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { if _, ok := builtins[artifact.BuilderId()]; !ok { - return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId()) + return nil, false, fmt.Errorf("The Packer vSphere Template post-processor "+ + "can only take an artifact from the VMware-iso builder, built on "+ + "ESXi (i.e. remote) or an artifact from the vSphere post-processor. "+ + "Artifact type %s does not fit this requirement", artifact.BuilderId()) } f := artifact.State(iso.ArtifactConfFormat) From 4f5e7fe060b93821ed30a50b07f63de898d609b6 Mon Sep 17 00:00:00 2001 From: Chris Lundquist <rampantdurandal@gmail.com> Date: Tue, 20 Mar 2018 19:30:46 +0000 Subject: [PATCH 0832/1007] first pass at allowing configurable sleep timeouts, profiles, and launch configs --- builder/lxd/config.go | 15 +++++++++++++-- builder/lxd/step_lxd_launch.go | 26 ++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/builder/lxd/config.go b/builder/lxd/config.go index ea467f09b..bcd3aea80 100644 --- a/builder/lxd/config.go +++ b/builder/lxd/config.go @@ -2,7 +2,6 @@ package lxd import ( "fmt" - "time" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/config" @@ -17,8 +16,10 @@ type Config struct { ContainerName string `mapstructure:"container_name"` CommandWrapper string `mapstructure:"command_wrapper"` Image string `mapstructure:"image"` + Profile string `mapstructure:"profile"` + InitSleep string `mapstructure:"init_sleep"` PublishProperties map[string]string `mapstructure:"publish_properties"` - InitTimeout time.Duration + LaunchConfig map[string]string `mapstructure:"launch_config"` ctx interpolate.Context } @@ -54,6 +55,16 @@ func NewConfig(raws ...interface{}) (*Config, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("`image` is a required parameter for LXD. Please specify an image by alias or fingerprint. e.g. `ubuntu-daily:x`")) } + if c.Profile == "" { + c.Profile = "default" + } + + // Sadly we have to wait a few seconds for /tmp to be intialized and networking + // to finish starting. There isn't a great cross platform to check when things are ready. + if c.InitSleep == "" { + c.InitSleep = "3" + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index 7549a408d..09464cd2d 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -3,6 +3,7 @@ package lxd import ( "context" "fmt" + "strconv" "time" "github.com/hashicorp/packer/helper/multistep" @@ -17,22 +18,35 @@ func (s *stepLxdLaunch) Run(_ context.Context, state multistep.StateBag) multist name := config.ContainerName image := config.Image + profile := fmt.Sprintf("--profile=%s", config.Profile) - args := []string{ - "launch", "--ephemeral=false", image, name, + launch_args := []string{ + "launch", "--ephemeral=false", profile, image, name, + } + + for k, v := range config.LaunchConfig { + launch_args = append(launch_args, fmt.Sprintf("--config %s=%s", k, v)) } ui.Say("Creating container...") - _, err := LXDCommand(args...) + _, err := LXDCommand(launch_args...) if err != nil { err := fmt.Errorf("Error creating container: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt } + sleep_seconds, err := strconv.Atoi(config.InitSleep) + if err != nil { + err := fmt.Errorf("Error parsing InitSleep into int: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + // TODO: Should we check `lxc info <container>` for "Running"? // We have to do this so /tmp doesn't get cleared and lose our provisioner scripts. - time.Sleep(1 * time.Second) + time.Sleep(time.Duration(sleep_seconds) * time.Second) return multistep.ActionContinue } @@ -41,12 +55,12 @@ func (s *stepLxdLaunch) Cleanup(state multistep.StateBag) { config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) - args := []string{ + cleanup_args := []string{ "delete", "--force", config.ContainerName, } ui.Say("Unregistering and deleting deleting container...") - if _, err := LXDCommand(args...); err != nil { + if _, err := LXDCommand(cleanup_args...); err != nil { ui.Error(fmt.Sprintf("Error deleting container: %s", err)) } } From c877312a4d1b432e643608642e449ff0f16b5538 Mon Sep 17 00:00:00 2001 From: stack72 <public@paulstack.co.uk> Date: Tue, 20 Mar 2018 22:10:12 +0200 Subject: [PATCH 0833/1007] builder/triton: Add support to Skip TLS Verification of Triton URL In order to allow Packer to connect to Private Triton installations we now expose `insecure_skip_tls_verify` which, if set to true, will allow the user to make requests to Triton installations that use a certificate not signed by a trusted root CA --- builder/triton/access_config.go | 25 +++++++++++++++------ website/source/docs/builders/triton.html.md | 5 +++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/builder/triton/access_config.go b/builder/triton/access_config.go index 3212c37a1..3fe380e73 100644 --- a/builder/triton/access_config.go +++ b/builder/triton/access_config.go @@ -17,11 +17,12 @@ import ( // AccessConfig is for common configuration related to Triton access type AccessConfig struct { - Endpoint string `mapstructure:"triton_url"` - Account string `mapstructure:"triton_account"` - Username string `mapstructure:"triton_user"` - KeyID string `mapstructure:"triton_key_id"` - KeyMaterial string `mapstructure:"triton_key_material"` + Endpoint string `mapstructure:"triton_url"` + Account string `mapstructure:"triton_account"` + Username string `mapstructure:"triton_user"` + KeyID string `mapstructure:"triton_key_id"` + KeyMaterial string `mapstructure:"triton_key_material"` + InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify"` signer authentication.Signer } @@ -131,12 +132,14 @@ func (c *AccessConfig) CreateTritonClient() (*Client, error) { } return &Client{ - config: config, + config: config, + insecureSkipTLSVerify: c.InsecureSkipTLSVerify, }, nil } type Client struct { - config *tgo.ClientConfig + config *tgo.ClientConfig + insecureSkipTLSVerify bool } func (c *Client) Compute() (*compute.ComputeClient, error) { @@ -145,6 +148,10 @@ func (c *Client) Compute() (*compute.ComputeClient, error) { return nil, errwrap.Wrapf("Error Creating Triton Compute Client: {{err}}", err) } + if c.insecureSkipTLSVerify { + computeClient.Client.InsecureSkipTLSVerify() + } + return computeClient, nil } @@ -154,6 +161,10 @@ func (c *Client) Network() (*network.NetworkClient, error) { return nil, errwrap.Wrapf("Error Creating Triton Network Client: {{err}}", err) } + if c.insecureSkipTLSVerify { + networkClient.Client.InsecureSkipTLSVerify() + } + return networkClient, nil } diff --git a/website/source/docs/builders/triton.html.md b/website/source/docs/builders/triton.html.md index 2a62dbe12..889b0d9d8 100644 --- a/website/source/docs/builders/triton.html.md +++ b/website/source/docs/builders/triton.html.md @@ -95,6 +95,11 @@ builder. - `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 From eb201724c1e1558d86ea86c9e6ae08f864993720 Mon Sep 17 00:00:00 2001 From: Christopher Boumenot <chrboum@microsoft.com> Date: Tue, 20 Mar 2018 16:20:11 -0700 Subject: [PATCH 0834/1007] azure: unit tests for naming temp resources --- builder/azure/arm/config_test.go | 38 +++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/builder/azure/arm/config_test.go b/builder/azure/arm/config_test.go index 71f3c352d..abb0f5a7d 100644 --- a/builder/azure/arm/config_test.go +++ b/builder/azure/arm/config_test.go @@ -1058,7 +1058,6 @@ func TestConfigShouldRejectManagedDiskNames(t *testing.T) { } func TestConfigAdditionalDiskDefaultIsNil(t *testing.T) { - c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration()) if c.AdditionalDiskSize != nil { t.Errorf("Expected Config to not have a set of additional disks, but got a non nil value") @@ -1228,6 +1227,43 @@ func TestPlanInfoTooManyTagsErrors(t *testing.T) { } } +// The Azure builder creates temporary resources, but the user has some control over +// these values. This test asserts those values are controllable by the user. +func TestConfigShouldAllowTempNameOverrides(t *testing.T) { + config := map[string]interface{}{ + "image_offer": "ignore", + "image_publisher": "ignore", + "image_sku": "ignore", + "location": "ignore", + "subscription_id": "ignore", + "communicator": "none", + "os_type": "linux", + "managed_image_name": "ignore", + "managed_image_resource_group_name": "ignore", + "temp_resource_group_name": "myTempResourceGroupName", + "temp_compute_name": "myTempComputeName", + } + + c, _, err := newConfig(config, getPackerConfiguration()) + if err != nil { + t.Errorf("newConfig failed with %q", err) + } + + if c.TempResourceGroupName != "myTempResourceGroupName" { + t.Errorf("expected TempResourceGroupName to be %q, but got %q", "myTempResourceGroupName", c.TempResourceGroupName) + } + if c.tmpResourceGroupName != "myTempResourceGroupName" { + t.Errorf("expected tmpResourceGroupName to be %q, but got %q", "myTempResourceGroupName", c.tmpResourceGroupName) + } + + if c.TempComputeName != "myTempComputeName" { + t.Errorf("expected TempComputeName to be %q, but got %q", "myTempComputeName", c.TempComputeName) + } + if c.tmpComputeName != "myTempComputeName" { + t.Errorf("expected tmpComputeName to be %q, but got %q", "myTempComputeName", c.tmpResourceGroupName) + } +} + func getArmBuilderConfiguration() map[string]string { m := make(map[string]string) for _, v := range requiredConfigValues { From ccdee2550b599e087a92c402e2504006ab89447a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 20 Mar 2018 11:34:53 -0700 Subject: [PATCH 0835/1007] Treat any output directory test command as error. Surfaces any communications from the remote end during file uploads. For example, we might get notifications if we're logging in with the wrong user. Rather than swallow these, let's show them to the user. --- communicator/ssh/communicator.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 6fedb479c..b00b99220 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -413,7 +413,12 @@ func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, // find out if destination is a directory (this is to replicate rsync behavior) testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) - cmd := &packer.RemoteCmd{Command: testDirectoryCommand} + var stdout, stderr bytes.Buffer + cmd := &packer.RemoteCmd{ + Command: testDirectoryCommand, + Stdout: &stdout, + Stderr: &stderr, + } err := c.Start(cmd) @@ -422,6 +427,12 @@ func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, return err } cmd.Wait() + if stdout.Len() > 0 { + return fmt.Errorf("%s", stdout.Bytes()) + } + if stderr.Len() > 0 { + return fmt.Errorf("%s", stderr.Bytes()) + } if cmd.ExitStatus == 0 { if fi == nil { return fmt.Errorf("Upload path is a directory, unable to continue.") @@ -579,7 +590,12 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e // find out if destination is a directory (this is to replicate rsync behavior) testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) - cmd := &packer.RemoteCmd{Command: testDirectoryCommand} + var stdout, stderr bytes.Buffer + cmd := &packer.RemoteCmd{ + Command: testDirectoryCommand, + Stdout: &stdout, + Stderr: &stderr, + } err := c.Start(cmd) @@ -588,6 +604,12 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e return err } cmd.Wait() + if stdout.Len() > 0 { + return fmt.Errorf("%s", stdout.Bytes()) + } + if stderr.Len() > 0 { + return fmt.Errorf("%s", stderr.Bytes()) + } if cmd.ExitStatus == 0 { if fi == nil { return fmt.Errorf("Upload path is a directory, unable to continue.") From 67c7b9d1526e4c283dd94c1fd644b9b350a4f465 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 20 Mar 2018 16:28:23 -0700 Subject: [PATCH 0836/1007] display debug log levels --- communicator/ssh/communicator.go | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index b00b99220..329a62994 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -105,7 +105,7 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) { } } - log.Printf("starting remote command: %s", cmd.Command) + log.Printf("[DEBUG] starting remote command: %s", cmd.Command) err = session.Start(cmd.Command + "\n") if err != nil { return @@ -136,12 +136,12 @@ func (c *comm) Start(cmd *packer.RemoteCmd) (err error) { switch err.(type) { case *ssh.ExitError: exitStatus = err.(*ssh.ExitError).ExitStatus() - log.Printf("Remote command exited with '%d': %s", exitStatus, cmd.Command) + log.Printf("[ERROR] Remote command exited with '%d': %s", exitStatus, cmd.Command) case *ssh.ExitMissingError: - log.Printf("Remote command exited without exit status or exit signal.") + log.Printf("[ERROR] Remote command exited without exit status or exit signal.") exitStatus = packer.CmdDisconnect default: - log.Printf("Error occurred waiting for ssh session: %s", err.Error()) + log.Printf("[ERROR] Error occurred waiting for ssh session: %s", err.Error()) } } cmd.SetExited(exitStatus) @@ -158,7 +158,7 @@ func (c *comm) Upload(path string, input io.Reader, fi *os.FileInfo) error { } func (c *comm) UploadDir(dst string, src string, excl []string) error { - log.Printf("Upload dir '%s' to '%s'", src, dst) + log.Printf("[DEBUG] Upload dir '%s' to '%s'", src, dst) if c.config.UseSftp { return c.sftpUploadDirSession(dst, src, excl) } else { @@ -167,7 +167,7 @@ func (c *comm) UploadDir(dst string, src string, excl []string) error { } func (c *comm) DownloadDir(src string, dst string, excl []string) error { - log.Printf("Download dir '%s' to '%s'", src, dst) + log.Printf("[DEBUG] Download dir '%s' to '%s'", src, dst) scpFunc := func(w io.Writer, stdoutR *bufio.Reader) error { dirStack := []string{dst} for { @@ -202,7 +202,7 @@ func (c *comm) DownloadDir(src string, dst string, excl []string) error { var mode int64 var size int64 var name string - log.Printf("Download dir str:%s", fi) + log.Printf("[DEBUG] Download dir str:%s", fi) n, err := fmt.Sscanf(fi[1:], "%o %d %s", &mode, &size, &name) if err != nil || n != 3 { return fmt.Errorf("can't parse server response (%s)", fi) @@ -211,7 +211,7 @@ func (c *comm) DownloadDir(src string, dst string, excl []string) error { return fmt.Errorf("negative file size") } - log.Printf("Download dir mode:%0o size:%d name:%s", mode, size, name) + log.Printf("[DEBUG] Download dir mode:%0o size:%d name:%s", mode, size, name) dst = filepath.Join(dirStack...) switch fi[0] { @@ -246,7 +246,7 @@ func (c *comm) Download(path string, output io.Writer) error { } func (c *comm) newSession() (session *ssh.Session, err error) { - log.Println("opening new ssh session") + log.Println("[DEBUG] Opening new ssh session") if c.client == nil { err = errors.New("client not available") } else { @@ -254,7 +254,7 @@ func (c *comm) newSession() (session *ssh.Session, err error) { } if err != nil { - log.Printf("ssh session open error: '%s', attempting reconnect", err) + log.Printf("[ERROR] ssh session open error: '%s', attempting reconnect", err) if err := c.reconnect(); err != nil { return nil, err } @@ -279,7 +279,7 @@ func (c *comm) reconnect() (err error) { c.conn = nil c.client = nil - log.Printf("reconnecting to TCP connection for SSH") + log.Printf("[DEBUG] reconnecting to TCP connection for SSH") c.conn, err = c.config.Connection() if err != nil { // Explicitly set this to the REAL nil. Connection() can return @@ -290,7 +290,7 @@ func (c *comm) reconnect() (err error) { // http://golang.org/doc/faq#nil_error c.conn = nil - log.Printf("reconnection error: %s", err) + log.Printf("[ERROR] reconnection error: %s", err) return } @@ -298,7 +298,7 @@ func (c *comm) reconnect() (err error) { c.conn = &timeoutConn{c.conn, c.config.Timeout, c.config.Timeout} } - log.Printf("handshaking with SSH") + log.Printf("[DEBUG] handshaking with SSH") // Default timeout to 1 minute if it wasn't specified (zero value). For // when you need to handshake from low orbit. @@ -335,10 +335,10 @@ func (c *comm) reconnect() (err error) { } if err != nil { - log.Printf("handshake error: %s", err) + log.Printf("[ERROR] handshake error: %s", err) return } - log.Printf("handshake complete!") + log.Printf("[DEBUG] handshake complete!") if sshConn != nil { c.client = ssh.NewClient(sshConn, sshChan, req) } @@ -423,7 +423,7 @@ func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, err := c.Start(cmd) if err != nil { - log.Printf("Unable to check whether remote path is a dir: %s", err) + log.Printf("[ERROR] Unable to check whether remote path is a dir: %s", err) return err } cmd.Wait() @@ -466,7 +466,7 @@ func (c *comm) sftpUploadDirSession(dst string, src string, excl []string) error sftpFunc := func(client *sftp.Client) error { rootDst := dst if src[len(src)-1] != '/' { - log.Printf("No trailing slash, creating the source directory name") + log.Printf("[DEBUG] No trailing slash, creating the source directory name") rootDst = filepath.Join(dst, filepath.Base(src)) } walkFunc := func(path string, info os.FileInfo, err error) error { @@ -600,7 +600,7 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e err := c.Start(cmd) if err != nil { - log.Printf("Unable to check whether remote path is a dir: %s", err) + log.Printf("[ERROR] Unable to check whether remote path is a dir: %s", err) return err } cmd.Wait() @@ -649,7 +649,7 @@ func (c *comm) scpUploadDirSession(dst string, src string, excl []string) error } if src[len(src)-1] != '/' { - log.Printf("No trailing slash, creating the source directory name") + log.Printf("[DEBUG] No trailing slash, creating the source directory name") fi, err := os.Stat(src) if err != nil { return err @@ -750,7 +750,7 @@ func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) er // Start the sink mode on the other side // TODO(mitchellh): There are probably issues with shell escaping the path - log.Println("Starting remote scp process: ", scpCommand) + log.Println("[DEBUG] Starting remote scp process: ", scpCommand) if err := session.Start(scpCommand); err != nil { return err } @@ -758,7 +758,7 @@ func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) er // Call our callback that executes in the context of SCP. We ignore // EOF errors if they occur because it usually means that SCP prematurely // ended on the other side. - log.Println("Started SCP session, beginning transfers...") + log.Println("[DEBUG] Started SCP session, beginning transfers...") if err := f(stdinW, stdoutR); err != nil && err != io.EOF { return err } @@ -766,24 +766,24 @@ func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) er // Close the stdin, which sends an EOF, and then set w to nil so that // our defer func doesn't close it again since that is unsafe with // the Go SSH package. - log.Println("SCP session complete, closing stdin pipe.") + log.Println("[DEBUG] SCP session complete, closing stdin pipe.") stdinW.Close() stdinW = nil // Wait for the SCP connection to close, meaning it has consumed all // our data and has completed. Or has errored. - log.Println("Waiting for SSH session to complete.") + log.Println("[DEBUG] Waiting for SSH session to complete.") err = session.Wait() if err != nil { if exitErr, ok := err.(*ssh.ExitError); ok { // Otherwise, we have an ExitError, meaning we can just read // the exit status - log.Printf("non-zero exit status: %d", exitErr.ExitStatus()) + log.Printf("[DEBUG] non-zero exit status: %d", exitErr.ExitStatus()) stdoutB, err := ioutil.ReadAll(stdoutR) if err != nil { return err } - log.Printf("scp output: %s", stdoutB) + log.Printf("[DEBUG] scp output: %s", stdoutB) // If we exited with status 127, it means SCP isn't available. // Return a more descriptive error for that. @@ -797,7 +797,7 @@ func (c *comm) scpSession(scpCommand string, f func(io.Writer, *bufio.Reader) er return err } - log.Printf("scp stderr (length %d): %s", stderr.Len(), stderr.String()) + log.Printf("[DEBUG] scp stderr (length %d): %s", stderr.Len(), stderr.String()) return nil } @@ -854,7 +854,7 @@ func scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, fi * mode = 0644 - log.Println("Copying input data into temporary file so we can read the length") + log.Println("[DEBUG] Copying input data into temporary file so we can read the length") if _, err := io.Copy(tf, src); err != nil { return err } @@ -897,7 +897,7 @@ func scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, fi * } func scpUploadDirProtocol(name string, w io.Writer, r *bufio.Reader, f func() error, fi os.FileInfo) error { - log.Printf("SCP: starting directory upload: %s", name) + log.Printf("[DEBUG] SCP: starting directory upload: %s", name) mode := fi.Mode().Perm() From 732a532d0eda5ae74dd0b230f6adc92faafb660c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 20 Mar 2018 16:28:54 -0700 Subject: [PATCH 0837/1007] pass file info during shell file upload --- provisioner/shell/provisioner.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 8dd5796ce..bfecd27ff 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -230,6 +230,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Error opening shell script: %s", err) } defer f.Close() + info, _ := f.Stat() // Compile the command p.config.ctx.Data = &ExecuteCommandTemplate{ @@ -257,7 +258,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { r = &UnixReader{Reader: r} } - if err := comm.Upload(p.config.RemotePath, r, nil); err != nil { + if err := comm.Upload(p.config.RemotePath, r, &info); err != nil { return fmt.Errorf("Error uploading script: %s", err) } From c5e0710a9a1c9d99a8241bc10ec21f3766e3719c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 20 Mar 2018 16:29:09 -0700 Subject: [PATCH 0838/1007] Do nothing if we detect destination is a directory We can't modify the destination path in the communicator because it breaks assumptions in the provisioners. For example, we try to chmod in the shell provisioner. The chmod command uses the path as supplied by the user. If the communicator decides to rewrite the path, the provisioner doesn't know that, and so tries to chmod the wrong thing. The best we can do is detect that the destination is a directory and fail. Also correctly surface output from sftp uploader. --- communicator/ssh/communicator.go | 39 ++++++++++++++------------------ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 329a62994..218c11be6 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -413,11 +413,9 @@ func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, // find out if destination is a directory (this is to replicate rsync behavior) testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) - var stdout, stderr bytes.Buffer + cmd := &packer.RemoteCmd{ Command: testDirectoryCommand, - Stdout: &stdout, - Stderr: &stderr, } err := c.Start(cmd) @@ -427,18 +425,10 @@ func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, return err } cmd.Wait() - if stdout.Len() > 0 { - return fmt.Errorf("%s", stdout.Bytes()) - } - if stderr.Len() > 0 { - return fmt.Errorf("%s", stderr.Bytes()) - } if cmd.ExitStatus == 0 { - if fi == nil { - return fmt.Errorf("Upload path is a directory, unable to continue.") - } - log.Printf("path is a directory; copying file into directory.") - path = filepath.Join(path, filepath.Base((*fi).Name())) + return fmt.Errorf( + "Destination path (%s) is a directory that already exists. "+ + "Please ensure the destination is writable.", path) } f, err := client.Create(path) @@ -553,7 +543,7 @@ func (c *comm) sftpDownloadSession(path string, output io.Writer) error { func (c *comm) sftpSession(f func(*sftp.Client) error) error { client, err := c.newSftpClient() if err != nil { - return err + return fmt.Errorf("sftpSession error: %s", err.Error()) } defer client.Close() @@ -579,7 +569,15 @@ func (c *comm) newSftpClient() (*sftp.Client, error) { return nil, err } - return sftp.NewClientPipe(pr, pw) + // Capture stdout so we can return errors to the user + var stdout bytes.Buffer + tee := io.TeeReader(pr, &stdout) + client, err := sftp.NewClientPipe(tee, pw) + if err != nil && stdout.Len() > 0 { + log.Printf("[ERROR] Upload failed: %s", stdout.Bytes()) + } + + return client, err } func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) error { @@ -611,12 +609,9 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e return fmt.Errorf("%s", stderr.Bytes()) } if cmd.ExitStatus == 0 { - if fi == nil { - return fmt.Errorf("Upload path is a directory, unable to continue.") - } - log.Printf("path is a directory; copying file into directory.") - target_dir = path - target_file = filepath.Base((*fi).Name()) + return fmt.Errorf( + "Destination path (%s) is a directory that already exists. "+ + "Please ensure the destination is writable.", path) } // On windows, filepath.Dir uses backslash separators (ie. "\tmp"). From 7112212b2fde3a46977f631d817129fd05b8fb2c Mon Sep 17 00:00:00 2001 From: Petr Ruzicka <petr.ruzicka@gmail.com> Date: Sat, 17 Mar 2018 07:44:41 +0100 Subject: [PATCH 0839/1007] Adding details to PACKER_BUILD_NAME to have it clear in the documentation how the variable is created --- website/source/docs/post-processors/shell-local.html.md | 3 ++- website/source/docs/provisioners/powershell.html.md | 3 ++- website/source/docs/provisioners/shell.html.md | 3 ++- website/source/docs/provisioners/windows-shell.html.md | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/website/source/docs/post-processors/shell-local.html.md b/website/source/docs/post-processors/shell-local.html.md index 74e21993d..d23780731 100644 --- a/website/source/docs/post-processors/shell-local.html.md +++ b/website/source/docs/post-processors/shell-local.html.md @@ -82,7 +82,8 @@ In addition to being able to specify custom environmental variables using the `environment_vars` configuration, the provisioner automatically defines certain commonly useful environmental variables: -- `PACKER_BUILD_NAME` is set to the name of the build that Packer is running. +- `PACKER_BUILD_NAME` is set to the + [name of the build](/docs/templates/builders.html#named-builds) that Packer is running. This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index a9c218638..c51dfc59b 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -110,7 +110,8 @@ In addition to being able to specify custom environmental variables using the `environment_vars` configuration, the provisioner automatically defines certain commonly useful environmental variables: -- `PACKER_BUILD_NAME` is set to the name of the build that Packer is running. +- `PACKER_BUILD_NAME` is set to the + [name of the build](/docs/templates/builders.html#named-builds) that Packer is running. This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. diff --git a/website/source/docs/provisioners/shell.html.md b/website/source/docs/provisioners/shell.html.md index 827c04c62..e5c8f48b9 100644 --- a/website/source/docs/provisioners/shell.html.md +++ b/website/source/docs/provisioners/shell.html.md @@ -150,7 +150,8 @@ In addition to being able to specify custom environmental variables using the `environment_vars` configuration, the provisioner automatically defines certain commonly useful environmental variables: -- `PACKER_BUILD_NAME` is set to the name of the build that Packer is running. +- `PACKER_BUILD_NAME` is set to the + [name of the build](/docs/templates/builders.html#named-builds) that Packer is running. This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. diff --git a/website/source/docs/provisioners/windows-shell.html.md b/website/source/docs/provisioners/windows-shell.html.md index cdf4469fa..8deb6c9c9 100644 --- a/website/source/docs/provisioners/windows-shell.html.md +++ b/website/source/docs/provisioners/windows-shell.html.md @@ -81,7 +81,8 @@ In addition to being able to specify custom environmental variables using the `environment_vars` configuration, the provisioner automatically defines certain commonly useful environmental variables: -- `PACKER_BUILD_NAME` is set to the name of the build that Packer is running. +- `PACKER_BUILD_NAME` is set to the + [name of the build](/docs/templates/builders.html#named-builds) that Packer is running. This is most useful when Packer is making multiple builds and you want to distinguish them slightly from a common provisioning script. From 7184e411e5c34593e57f4b3d75660062d034aa1a Mon Sep 17 00:00:00 2001 From: Stefan Henseler <stefan.henseler@synax.ch> Date: Wed, 21 Mar 2018 22:59:04 +0100 Subject: [PATCH 0840/1007] Adds documentation for hyperv-iso disk block size feature --- website/source/docs/builders/hyperv-iso.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index e1454fea7..73e159277 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -230,6 +230,9 @@ can be configured for this builder. - `temp_path` (string) - This is the temporary path in which Packer will create the virtual machine. Default value is system `%temp%` +- `disk_block_size` (string) - The block size of the VHD to be created. + Recommended disk block size for Linux hyper-v guests is 1 MiB. This defaults to "32 MiB". + ## Boot Command The `boot_command` configuration is very important: it specifies the keys From 1f4212efa7fa459662dada64ac08e0e7d518e059 Mon Sep 17 00:00:00 2001 From: Yang Youseok <ileixe@gmail.com> Date: Tue, 20 Mar 2018 23:01:58 +0900 Subject: [PATCH 0841/1007] builder/openstack: Add instance_name config to OpenStack builder RFC952 restricts hostname not to use underline(_) and period(.), so private cloud with legacy DNS system does not allow just to use image_name for name of server. Add instance_name config option for servers which packer creates to make instance_name configurable. If instance_name is not specified, by default it works like the past using image_name for instance_name. --- builder/openstack/builder.go | 7 ++++++- builder/openstack/run_config.go | 1 + website/source/docs/builders/openstack.html.md | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/builder/openstack/builder.go b/builder/openstack/builder.go index 42770c625..a718c3d59 100755 --- a/builder/openstack/builder.go +++ b/builder/openstack/builder.go @@ -52,6 +52,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { return nil, errs } + // By default, instance name is same as image name + if b.config.InstanceName == "" { + b.config.InstanceName = b.config.ImageName + } + log.Println(common.ScrubConfig(b.config, b.config.Password)) return nil, nil } @@ -82,7 +87,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SSHAgentAuth: b.config.RunConfig.Comm.SSHAgentAuth, }, &StepRunSourceServer{ - Name: b.config.ImageName, + Name: b.config.InstanceName, SourceImage: b.config.SourceImage, SourceImageName: b.config.SourceImageName, SecurityGroups: b.config.SecurityGroups, diff --git a/builder/openstack/run_config.go b/builder/openstack/run_config.go index 55da56271..6b4e0932e 100644 --- a/builder/openstack/run_config.go +++ b/builder/openstack/run_config.go @@ -30,6 +30,7 @@ type RunConfig struct { Networks []string `mapstructure:"networks"` UserData string `mapstructure:"user_data"` UserDataFile string `mapstructure:"user_data_file"` + InstanceName string `mapstructure:"instance_name"` InstanceMetadata map[string]string `mapstructure:"instance_metadata"` ConfigDrive bool `mapstructure:"config_drive"` diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md index 0809b6545..37cc0de71 100755 --- a/website/source/docs/builders/openstack.html.md +++ b/website/source/docs/builders/openstack.html.md @@ -118,6 +118,9 @@ builder. - `metadata` (object of key/value strings) - Glance metadata that will be applied to the image. +- `instance_name` (string) - Name that is applied to the server instance + created by Packer. If this isn't specified, the default is same as `image_name`. + - `instance_metadata` (object of key/value strings) - Metadata that is applied to the server instance created by Packer. Also called server properties in some documentation. The strings have a max size of 255 bytes From dc41b086fe325fc57f3a54f28df6573f97424945 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 21 Mar 2018 22:00:39 -0700 Subject: [PATCH 0842/1007] Document missing aws config params. --- .../docs/post-processors/amazon-import.html.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/website/source/docs/post-processors/amazon-import.html.md b/website/source/docs/post-processors/amazon-import.html.md index 766bda48b..f7f8959a9 100644 --- a/website/source/docs/post-processors/amazon-import.html.md +++ b/website/source/docs/post-processors/amazon-import.html.md @@ -61,6 +61,10 @@ Optional: launch the imported AMI. By default no additional users other than the user importing the AMI has permission to launch it. +- `custom_endpoint_ec2` (string) - This option is useful if you use a cloud + provider whose API is compatible with aws EC2. Specify another endpoint + like this `https://ec2.custom.endpoint.com`. + - `license_type` (string) - The license type to be used for the Amazon Machine Image (AMI) after importing. Valid values: `AWS` or `BYOL` (default). For more details regarding licensing, see @@ -70,6 +74,11 @@ Optional: - `mfa_code` (string) - The MFA [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) code. This should probably be a user variable since it changes all the time. +- `profile` (string) - The profile to use in the shared credentials file for + AWS. See Amazon's documentation on [specifying + profiles](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-profiles) + for more details. + - `role_name` (string) - The name of the role to use when not using the default role, 'vmimport' - `s3_key_name` (string) - The name of the key in `s3_bucket_name` where the @@ -80,6 +89,9 @@ Optional: - `skip_clean` (boolean) - Whether we should skip removing the OVA file uploaded to S3 after the import process has completed. "true" means that we should leave it in the S3 bucket, "false" means to clean it out. Defaults to `false`. +- `skip_region_validation` (boolean) - Set to true if you want to skip + validation of the region configuration option. Default `false`. + - `tags` (object of key/value strings) - Tags applied to the created AMI and relevant snapshots. From 91864b842fe48f3ef21a53f5bb65c820d10636d8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 21 Mar 2018 22:03:21 -0700 Subject: [PATCH 0843/1007] remove skip_metadata_api_check from docs --- website/source/docs/builders/amazon-chroot.html.md | 6 ------ website/source/docs/builders/amazon-ebs.html.md | 6 ------ website/source/docs/builders/amazon-ebssurrogate.html.md | 6 ------ website/source/docs/builders/amazon-ebsvolume.html.md | 6 ------ website/source/docs/builders/amazon-instance.html.md | 6 ------ 5 files changed, 30 deletions(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index 53c21ff30..c9612d3b8 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -246,12 +246,6 @@ each category, the available configuration keys are alphabetized. of the `source_ami` unless `from_scratch` is `true`, in which case this field must be defined. -- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. - Useful for AWS API implementations that do not have a metadata API - endpoint. Setting to `true` prevents Packer from authenticating via the - Metadata API. You may need to use other authentication methods like static - credentials, configuration variables, or environment variables. - - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the `ami_regions` configuration option. Default `false`. diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 4c57611f4..400eb7ecb 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -251,12 +251,6 @@ builder. in case Packer exits ungracefully. Possible values are "stop" and "terminate", default is `stop`. -- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. - Useful for AWS API implementations that do not have a metadata API - endpoint. Setting to `true` prevents Packer from authenticating via the - Metadata API. You may need to use other authentication methods like static - credentials, configuration variables, or environment variables. - - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the region configuration option. Default `false`. diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index f9ab61473..1d3724533 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -244,12 +244,6 @@ builder. incase packer exits ungracefully. Possible values are "stop" and "terminate", default is `stop`. -- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. - Useful for AWS API implementations that do not have a metadata API - endpoint. Setting to `true` prevents Packer from authenticating via the - Metadata API. You may need to use other authentication methods like static - credentials, configuration variables, or environment variables. - - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the region configuration option. Default `false`. diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index c8604cc25..5a3ee9830 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -149,12 +149,6 @@ builder. in case Packer exits ungracefully. Possible values are `stop` and `terminate`. Defaults to `stop`. -- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. - Useful for AWS API implementations that do not have a metadata API - endpoint. Setting to `true` prevents Packer from authenticating via the - Metadata API. You may need to use other authentication methods like static - credentials, configuration variables, or environment variables. - - `skip_region_validation` (boolean) - Set to `true` if you want to skip validation of the region configuration option. Defaults to `false`. diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 62417e1b7..58ac7088b 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -255,12 +255,6 @@ builder. The default is `0.0.0.0/0` (ie, allow any IPv4 source). This is only used when `security_group_id` or `security_group_ids` is not specified. -- `skip_metadata_api_check` - (boolean) Skip the AWS Metadata API check. - Useful for AWS API implementations that do not have a metadata API - endpoint. Setting to `true` prevents Packer from authenticating via the - Metadata API. You may need to use other authentication methods like static - credentials, configuration variables, or environment variables. - - `skip_region_validation` (boolean) - Set to true if you want to skip validation of the region configuration option. Defaults to `false`. From 61432cd257371a28175c8928deee4588924b0d52 Mon Sep 17 00:00:00 2001 From: Robert Neumayer <neumayer@protonmail.com> Date: Thu, 22 Mar 2018 09:08:25 +0100 Subject: [PATCH 0844/1007] Update logs to talk about IP instead of public IP When logging we don't know whether we use a private or public ip, just the ip itself. --- builder/oracle/oci/step_instance_info.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/oracle/oci/step_instance_info.go b/builder/oracle/oci/step_instance_info.go index d3e024978..891a261cd 100644 --- a/builder/oracle/oci/step_instance_info.go +++ b/builder/oracle/oci/step_instance_info.go @@ -19,7 +19,7 @@ func (s *stepInstanceInfo) Run(_ context.Context, state multistep.StateBag) mult ip, err := driver.GetInstanceIP(id) if err != nil { - err = fmt.Errorf("Error getting instance's public IP: %s", err) + err = fmt.Errorf("Error getting instance's IP: %s", err) ui.Error(err.Error()) state.Put("error", err) return multistep.ActionHalt @@ -27,7 +27,7 @@ func (s *stepInstanceInfo) Run(_ context.Context, state multistep.StateBag) mult state.Put("instance_ip", ip) - ui.Say(fmt.Sprintf("Instance has public IP: %s.", ip)) + ui.Say(fmt.Sprintf("Instance has IP: %s.", ip)) return multistep.ActionContinue } From 6abd75045a7b2bebea1f9ee8abb6f16097c9d79f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 22 Mar 2018 11:56:10 -0700 Subject: [PATCH 0845/1007] update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9873dd030..2908ea5f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ * builder/virtualbox: Correctly send multi-byte scancodes when typing boot command. [GH-5987] * provisioner/powershell: Fix environment variable file escaping. [GH-5973] +* builder/vmware: Handle multiple devices per VMware network type [GH-5985] +* builder/amazon: Fix AWS credential defaulting [GH-6019] +* builder/virtualbox: Special boot-commands no longer overwrite previous commands [GH-6002] +* builder/vmware: Default to disabling XHCI bus for USB on the vmware-iso builder. [GH-5975] + ### IMPROVEMENTS: @@ -19,6 +24,8 @@ one. [GH-5991] [GH-5928] * post-processor/vagrant: Add LXC support. [GH-5980] * provisioner/salt-masterless: Added Windows support. [GH-5702] +* builder/oracle-oci: Add new "use_private_ip" option. [GH-5893] +* provisioner/salt: Add windows support to salt provisioner [GH-6012] [GH-6012] ## 1.2.1 (February 23, 2018) From 4e321b2dfa1f825d91d823ef5c3c61ce0f824e31 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 22 Mar 2018 15:54:46 -0700 Subject: [PATCH 0846/1007] don't need to use a receiver with this function --- provisioner/powershell/provisioner.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index e3340d771..6b7adfac6 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -111,6 +111,7 @@ type EnvVarsTemplate struct { func (p *Provisioner) Prepare(raws ...interface{}) error { //Create passthrough for winrm password so we can fill it in once we know it + log.Printf("MEGAN context is %#v", p.config.ctx) p.config.ctx.Data = &EnvVarsTemplate{ WinRMPassword: `{{.WinRMPassword}}`, } @@ -247,6 +248,7 @@ func extractScript(p *Provisioner) (string, error) { } func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { + log.Printf("MEGAN context is %#v", p.config.ctx) ui.Say(fmt.Sprintf("Provisioning with Powershell...")) p.communicator = comm @@ -377,7 +379,7 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // interpolate environment variables p.config.ctx.Data = &EnvVarsTemplate{ - WinRMPassword: p.getWinRMPassword(), + WinRMPassword: getWinRMPassword(), } // Split vars into key/value components for _, envVar := range p.config.Vars { @@ -445,7 +447,7 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro p.config.ctx.Data = &ExecuteCommandTemplate{ Path: p.config.RemotePath, Vars: envVarPath, - WinRMPassword: p.getWinRMPassword(), + WinRMPassword: getWinRMPassword(), } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -457,7 +459,7 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro return command, nil } -func (p *Provisioner) getWinRMPassword() string { +func getWinRMPassword() string { winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password") return winRMPass @@ -472,7 +474,7 @@ func (p *Provisioner) createCommandTextPrivileged() (command string, err error) p.config.ctx.Data = &ExecuteCommandTemplate{ Path: p.config.RemotePath, Vars: envVarPath, - WinRMPassword: p.getWinRMPassword(), + WinRMPassword: getWinRMPassword(), } command, err = interpolate.Render(p.config.ElevatedExecuteCommand, &p.config.ctx) if err != nil { @@ -530,7 +532,7 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } // Replace ElevatedPassword for winrm users who used this feature p.config.ctx.Data = &EnvVarsTemplate{ - WinRMPassword: p.getWinRMPassword(), + WinRMPassword: getWinRMPassword(), } p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) From 34db6c4ab11cb34b6170a39196e8ac7cf8fc7557 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 23 Mar 2018 12:45:49 +0000 Subject: [PATCH 0847/1007] Remove temp debugging output --- provisioner/powershell/provisioner.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 6b7adfac6..f48693e4d 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -111,7 +111,6 @@ type EnvVarsTemplate struct { func (p *Provisioner) Prepare(raws ...interface{}) error { //Create passthrough for winrm password so we can fill it in once we know it - log.Printf("MEGAN context is %#v", p.config.ctx) p.config.ctx.Data = &EnvVarsTemplate{ WinRMPassword: `{{.WinRMPassword}}`, } @@ -248,7 +247,6 @@ func extractScript(p *Provisioner) (string, error) { } func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { - log.Printf("MEGAN context is %#v", p.config.ctx) ui.Say(fmt.Sprintf("Provisioning with Powershell...")) p.communicator = comm From 191f407f5cdd0ed8f8725c899951dbde713e91a3 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 23 Mar 2018 12:54:33 +0000 Subject: [PATCH 0848/1007] Fix copy/paste error in comment --- communicator/ssh/connect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communicator/ssh/connect.go b/communicator/ssh/connect.go index 7622a90e3..80bf0a9f4 100644 --- a/communicator/ssh/connect.go +++ b/communicator/ssh/connect.go @@ -28,7 +28,7 @@ func ConnectFunc(network, addr string) func() (net.Conn, error) { } } -// ConnectFunc is a convenience method for returning a function +// ProxyConnectFunc is a convenience method for returning a function // that connects to a host using SOCKS5 proxy func ProxyConnectFunc(socksProxy string, socksAuth *proxy.Auth, network, addr string) func() (net.Conn, error) { return func() (net.Conn, error) { From ef4817d644c240a7c85a71d7d87bdf719527adef Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 23 Mar 2018 14:01:15 +0000 Subject: [PATCH 0849/1007] Fix vertical spacing --- provisioner/powershell/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index f48693e4d..e28becef0 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -460,8 +460,8 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro func getWinRMPassword() string { winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password") return winRMPass - } + func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { // Prepare everything needed to enable the required env vars within the remote environment envVarPath, err := p.prepareEnvVars(true) From 2d4c1acc67de597070a99faaa18333da18a585e1 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Mar 2018 10:21:24 -0700 Subject: [PATCH 0850/1007] set environment when we deploy website --- website/packer.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/packer.json b/website/packer.json index aeaa162e0..4ac70d626 100644 --- a/website/packer.json +++ b/website/packer.json @@ -3,6 +3,7 @@ "aws_access_key_id": "{{ env `AWS_ACCESS_KEY_ID` }}", "aws_secret_access_key": "{{ env `AWS_SECRET_ACCESS_KEY` }}", "aws_region": "{{ env `AWS_REGION` }}", + "website_environment": "production", "fastly_api_key": "{{ env `FASTLY_API_KEY` }}" }, "builders": [ @@ -22,6 +23,7 @@ "AWS_ACCESS_KEY_ID={{ user `aws_access_key_id` }}", "AWS_SECRET_ACCESS_KEY={{ user `aws_secret_access_key` }}", "AWS_REGION={{ user `aws_region` }}", + "ENV={{ user `website_environment` }}", "FASTLY_API_KEY={{ user `fastly_api_key` }}" ], "inline": [ From dee5bd3b2ed69bf285a240cf3463c59eb1713c89 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 23 Mar 2018 14:47:50 -0700 Subject: [PATCH 0851/1007] freebsd > 9 required note. --- website/source/downloads.html.erb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/source/downloads.html.erb b/website/source/downloads.html.erb index 0b975246a..12c8b8061 100644 --- a/website/source/downloads.html.erb +++ b/website/source/downloads.html.erb @@ -46,6 +46,14 @@ description: |- <li><a href="<%= url %>"><%= pretty_arch(arch) %></a></li> <% end %> </ul> + <% if os == "freebsd" %> + <div class="alert alert-info"> + Note: At least <code>FreeBSD 10-STABLE</code> is required to run Packer. + If you'd like to run on an earlier version, please + <a href="/docs/install/index.html#compiling-from-source">compile Packer yourself</a> + using the <a href="https://github.com/golang/go/wiki/FreeBSD">correct version of Go</a>. + </div> + <% end %> <div class="clearfix"></div> </div> </div> From 7253d6547b871ae8503d694b4f245456028be1b0 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 23 Mar 2018 15:46:39 -0700 Subject: [PATCH 0852/1007] minor LXD documentation tweaks --- builder/lxd/step_lxd_launch.go | 4 +++- website/source/docs/builders/lxd.html.md | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/builder/lxd/step_lxd_launch.go b/builder/lxd/step_lxd_launch.go index 09464cd2d..55b7e4954 100644 --- a/builder/lxd/step_lxd_launch.go +++ b/builder/lxd/step_lxd_launch.go @@ -3,6 +3,7 @@ package lxd import ( "context" "fmt" + "log" "strconv" "time" @@ -46,8 +47,9 @@ func (s *stepLxdLaunch) Run(_ context.Context, state multistep.StateBag) multist // TODO: Should we check `lxc info <container>` for "Running"? // We have to do this so /tmp doesn't get cleared and lose our provisioner scripts. - time.Sleep(time.Duration(sleep_seconds) * time.Second) + time.Sleep(time.Duration(sleep_seconds) * time.Second) + log.Printf("Sleeping for %d seconds...", sleep_seconds) return multistep.ActionContinue } diff --git a/website/source/docs/builders/lxd.html.md b/website/source/docs/builders/lxd.html.md index 4915e1e28..019b97534 100644 --- a/website/source/docs/builders/lxd.html.md +++ b/website/source/docs/builders/lxd.html.md @@ -54,6 +54,9 @@ Below is a fully functioning example. ### Optional: +- `init_sleep` (string) - The number of seconds to sleep between launching the + LXD instance and provisioning it; defaults to 3 seconds. + - `name` (string) - The name of the started container. Defaults to `packer-$PACKER_BUILD_NAME`. From d31e35075e603daa358cb5d268cec087ba35effb Mon Sep 17 00:00:00 2001 From: Stefan Henseler <stefan.henseler@synax.ch> Date: Sun, 25 Mar 2018 16:27:57 +0200 Subject: [PATCH 0853/1007] Removes obsolete code --- common/powershell/hyperv/hyperv.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 5fa6ea113..c019e55ce 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -53,22 +53,6 @@ $ip return cmdOut, err } -//func CreateVirtualHardDiskDrive(vmName string, diskPath string, diskSize int64, diskBlockSize int64, generation uint) (uint, uint, error) { -// -// var script = ` -//param([string]$vmName, [string]$path, -// -// -//[long]$memoryStartupBytes, [long]$newVHDSizeBytes, [string]$switchName, [int]$generation) -//$vhdx = $vmName + '.vhdx' -//$vhdPath = Join-Path -Path $path -ChildPath $vhdx -//New-VM -Name $vmName -Path $path -MemoryStartupBytes $memoryStartupBytes -NewVHDPath $vhdPath -NewVHDSizeBytes $newVHDSizeBytes -SwitchName $switchName -Generation $generation -//` -// var ps powershell.PowerShellCmd -// err := ps.Run(script, vmName, path, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatInt(int64(generation), 10)) -// return err -//} - func CreateDvdDrive(vmName string, isoPath string, generation uint) (uint, uint, error) { var ps powershell.PowerShellCmd var script string From 03f0b4aa11fead9434e9e6cab6b889110ab4b81c Mon Sep 17 00:00:00 2001 From: Stefan Henseler <stefan.henseler@synax.ch> Date: Sun, 25 Mar 2018 16:30:03 +0200 Subject: [PATCH 0854/1007] Fixes minor typo --- common/powershell/hyperv/hyperv.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index c019e55ce..54fa39d6d 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -877,9 +877,9 @@ Hyper-V\Get-VMNetworkAdapter -VMName $vmName | Hyper-V\Connect-VMNetworkAdapter func AddVirtualMachineHardDiskDrive(vmName string, vhdRoot string, vhdName string, vhdSizeBytes int64, vhdBlockSize int64, controllerType string) error { var script = ` -param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes,[string]$vhdBlockSizeInBize [string]$controllerType) +param([string]$vmName,[string]$vhdRoot, [string]$vhdName, [string]$vhdSizeInBytes,[string]$vhdBlockSizeInByte [string]$controllerType) $vhdPath = Join-Path -Path $vhdRoot -ChildPath $vhdName -Hyper-V\New-VHD -path $vhdPath -SizeBytes $vhdSizeInBytes -BlockSizeBytes $vhdBlockSizeInBize +Hyper-V\New-VHD -path $vhdPath -SizeBytes $vhdSizeInBytes -BlockSizeBytes $vhdBlockSizeInByte Hyper-V\Add-VMHardDiskDrive -VMName $vmName -path $vhdPath -controllerType $controllerType ` var ps powershell.PowerShellCmd From cb3699a58410cfcc85b1fb13988f0194a0e816d8 Mon Sep 17 00:00:00 2001 From: Joseph Wright <joseph@cloudboss.co> Date: Sun, 25 Mar 2018 19:25:53 -0400 Subject: [PATCH 0855/1007] Modify ebssurrogate builder to snapshot all launch devices Documentation for ebssurrogate states that all of the devices in `launch_block_device_mappings` are snapshotted and included in the image. In fact, only the device that was designated as the root device was snapshotted. This patch modifies the builder to create snapshots of all the devices and include them in the image. This allows creating images with separate filesystems preconfigured, rather than having to add volumes to `ami_block_device_mappings` and configure them after boot. --- builder/amazon/ebssurrogate/builder.go | 10 +- .../amazon/ebssurrogate/root_block_device.go | 20 -- .../amazon/ebssurrogate/step_register_ami.go | 46 ++- .../ebssurrogate/step_register_ami_test.go | 262 ++++++++++++++++-- .../ebssurrogate/step_snapshot_new_root.go | 103 ------- .../ebssurrogate/step_snapshot_volumes.go | 129 +++++++++ 6 files changed, 404 insertions(+), 166 deletions(-) delete mode 100644 builder/amazon/ebssurrogate/step_snapshot_new_root.go create mode 100644 builder/amazon/ebssurrogate/step_snapshot_volumes.go diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index b990c5758..002560602 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -176,6 +176,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe } } + amiDevices := b.config.BuildAMIDevices() + launchDevices := b.config.BuildLaunchDevices() + // Build the steps steps := []multistep.Step{ &awscommon.StepPreValidate{ @@ -227,8 +230,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe EnableAMISriovNetSupport: b.config.AMISriovNetSupport, EnableAMIENASupport: b.config.AMIENASupport, }, - &StepSnapshotNewRootVolume{ - NewRootMountPoint: b.config.RootDevice.SourceDeviceName, + &StepSnapshotVolumes{ + LaunchDevices: launchDevices, }, &awscommon.StepDeregisterAMI{ AccessConfig: &b.config.AccessConfig, @@ -239,7 +242,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &StepRegisterAMI{ RootDevice: b.config.RootDevice, - BlockDevices: b.config.BlockDevices.BuildAMIDevices(), + AMIDevices: amiDevices, + LaunchDevices: launchDevices, EnableAMISriovNetSupport: b.config.AMISriovNetSupport, EnableAMIENASupport: b.config.AMIENASupport, }, diff --git a/builder/amazon/ebssurrogate/root_block_device.go b/builder/amazon/ebssurrogate/root_block_device.go index 7e34b3733..09c13ca00 100644 --- a/builder/amazon/ebssurrogate/root_block_device.go +++ b/builder/amazon/ebssurrogate/root_block_device.go @@ -3,8 +3,6 @@ package ebssurrogate import ( "errors" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/packer/template/interpolate" ) @@ -46,21 +44,3 @@ func (c *RootBlockDevice) Prepare(ctx *interpolate.Context) []error { return nil } - -func (d *RootBlockDevice) createBlockDeviceMapping(snapshotId string) *ec2.BlockDeviceMapping { - rootBlockDevice := &ec2.EbsBlockDevice{ - SnapshotId: aws.String(snapshotId), - VolumeType: aws.String(d.VolumeType), - VolumeSize: aws.Int64(d.VolumeSize), - DeleteOnTermination: aws.Bool(d.DeleteOnTermination), - } - - if d.IOPS != 0 { - rootBlockDevice.Iops = aws.Int64(d.IOPS) - } - - return &ec2.BlockDeviceMapping{ - DeviceName: aws.String(d.DeviceName), - Ebs: rootBlockDevice, - } -} diff --git a/builder/amazon/ebssurrogate/step_register_ami.go b/builder/amazon/ebssurrogate/step_register_ami.go index 002ed00af..4c12adca6 100644 --- a/builder/amazon/ebssurrogate/step_register_ami.go +++ b/builder/amazon/ebssurrogate/step_register_ami.go @@ -14,7 +14,8 @@ import ( // StepRegisterAMI creates the AMI. type StepRegisterAMI struct { RootDevice RootBlockDevice - BlockDevices []*ec2.BlockDeviceMapping + AMIDevices []*ec2.BlockDeviceMapping + LaunchDevices []*ec2.BlockDeviceMapping EnableAMIENASupport bool EnableAMISriovNetSupport bool image *ec2.Image @@ -23,19 +24,19 @@ type StepRegisterAMI struct { func (s *StepRegisterAMI) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) ec2conn := state.Get("ec2").(*ec2.EC2) - snapshotId := state.Get("snapshot_id").(string) + snapshotIds := state.Get("snapshot_ids").(map[string]string) ui := state.Get("ui").(packer.Ui) ui.Say("Registering the AMI...") - blockDevicesExcludingRoot := DeduplicateRootVolume(s.BlockDevices, s.RootDevice, snapshotId) + blockDevices := s.combineDevices(snapshotIds) registerOpts := &ec2.RegisterImageInput{ Name: &config.AMIName, Architecture: aws.String(ec2.ArchitectureValuesX8664), RootDeviceName: aws.String(s.RootDevice.DeviceName), VirtualizationType: aws.String(config.AMIVirtType), - BlockDeviceMappings: blockDevicesExcludingRoot, + BlockDeviceMappings: blockDevices, } if s.EnableAMISriovNetSupport { @@ -120,17 +121,34 @@ func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) { } } -func DeduplicateRootVolume(BlockDevices []*ec2.BlockDeviceMapping, RootDevice RootBlockDevice, snapshotId string) []*ec2.BlockDeviceMapping { - // Defensive coding to make sure we only add the root volume once - blockDevicesExcludingRoot := make([]*ec2.BlockDeviceMapping, 0, len(BlockDevices)) - for _, blockDevice := range BlockDevices { - if *blockDevice.DeviceName == RootDevice.SourceDeviceName { - continue - } +func (s *StepRegisterAMI) combineDevices(snapshotIds map[string]string) []*ec2.BlockDeviceMapping { + devices := map[string]*ec2.BlockDeviceMapping{} - blockDevicesExcludingRoot = append(blockDevicesExcludingRoot, blockDevice) + for _, device := range s.AMIDevices { + devices[*device.DeviceName] = device } - blockDevicesExcludingRoot = append(blockDevicesExcludingRoot, RootDevice.createBlockDeviceMapping(snapshotId)) - return blockDevicesExcludingRoot + // Devices in launch_block_device_mappings override any with + // the same name in ami_block_device_mappings, except for the + // one designated as the root device in ami_root_device + for _, device := range s.LaunchDevices { + snapshotId, ok := snapshotIds[*device.DeviceName] + if ok { + device.Ebs.SnapshotId = aws.String(snapshotId) + // Block devices with snapshot inherit + // encryption settings from the snapshot + device.Ebs.Encrypted = nil + device.Ebs.KmsKeyId = nil + } + if *device.DeviceName == s.RootDevice.SourceDeviceName { + device.DeviceName = aws.String(s.RootDevice.DeviceName) + } + devices[*device.DeviceName] = device + } + + blockDevices := []*ec2.BlockDeviceMapping{} + for _, device := range devices { + blockDevices = append(blockDevices, device) + } + return blockDevices } diff --git a/builder/amazon/ebssurrogate/step_register_ami_test.go b/builder/amazon/ebssurrogate/step_register_ami_test.go index b2abd7827..10872bb86 100644 --- a/builder/amazon/ebssurrogate/step_register_ami_test.go +++ b/builder/amazon/ebssurrogate/step_register_ami_test.go @@ -1,37 +1,247 @@ package ebssurrogate import ( + "reflect" + "sort" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" ) -func GetStringPointer() *string { - tmp := "/dev/name" - return &tmp -} +const sourceDeviceName = "/dev/xvdf" +const rootDeviceName = "/dev/xvda" -func GetTestDevice() *ec2.BlockDeviceMapping { - TestDev := ec2.BlockDeviceMapping{ - DeviceName: GetStringPointer(), - } - return &TestDev -} - -func TestStepRegisterAmi_DeduplicateRootVolume(t *testing.T) { - TestRootDevice := RootBlockDevice{} - TestRootDevice.SourceDeviceName = "/dev/name" - - blockDevices := []*ec2.BlockDeviceMapping{} - blockDevicesExcludingRoot := DeduplicateRootVolume(blockDevices, TestRootDevice, "12342351") - if len(blockDevicesExcludingRoot) != 1 { - t.Fatalf("Unexpected length of block devices list") - } - - TestBlockDevice := GetTestDevice() - blockDevices = append(blockDevices, TestBlockDevice) - blockDevicesExcludingRoot = DeduplicateRootVolume(blockDevices, TestRootDevice, "12342351") - if len(blockDevicesExcludingRoot) != 1 { - t.Fatalf("Unexpected length of block devices list") +func newStepRegisterAMI(amiDevices, launchDevices []*ec2.BlockDeviceMapping) *StepRegisterAMI { + return &StepRegisterAMI{ + RootDevice: RootBlockDevice{ + SourceDeviceName: sourceDeviceName, + DeviceName: rootDeviceName, + DeleteOnTermination: true, + VolumeType: "ebs", + VolumeSize: 10, + }, + AMIDevices: amiDevices, + LaunchDevices: launchDevices, + } +} + +func sorted(devices []*ec2.BlockDeviceMapping) []*ec2.BlockDeviceMapping { + sort.SliceStable(devices, func(i, j int) bool { + return *devices[i].DeviceName < *devices[j].DeviceName + }) + return devices +} + +func TestStepRegisterAmi_combineDevices(t *testing.T) { + cases := []struct { + snapshotIds map[string]string + amiDevices []*ec2.BlockDeviceMapping + launchDevices []*ec2.BlockDeviceMapping + allDevices []*ec2.BlockDeviceMapping + }{ + { + snapshotIds: map[string]string{}, + amiDevices: []*ec2.BlockDeviceMapping{}, + launchDevices: []*ec2.BlockDeviceMapping{}, + allDevices: []*ec2.BlockDeviceMapping{}, + }, + { + snapshotIds: map[string]string{}, + amiDevices: []*ec2.BlockDeviceMapping{}, + launchDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String(sourceDeviceName), + }, + }, + allDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String(rootDeviceName), + }, + }, + }, + { + // Minimal single device + snapshotIds: map[string]string{ + sourceDeviceName: "snap-0123456789abcdef1", + }, + amiDevices: []*ec2.BlockDeviceMapping{}, + launchDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String(sourceDeviceName), + }, + }, + allDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef1"), + }, + DeviceName: aws.String(rootDeviceName), + }, + }, + }, + { + // Single launch device with AMI device + snapshotIds: map[string]string{ + sourceDeviceName: "snap-0123456789abcdef1", + }, + amiDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + launchDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String(sourceDeviceName), + }, + }, + allDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef1"), + }, + DeviceName: aws.String(rootDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + }, + { + // Multiple launch devices + snapshotIds: map[string]string{ + sourceDeviceName: "snap-0123456789abcdef1", + "/dev/xvdg": "snap-0123456789abcdef2", + }, + amiDevices: []*ec2.BlockDeviceMapping{}, + launchDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String(sourceDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{}, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + allDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef1"), + }, + DeviceName: aws.String(rootDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef2"), + }, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + }, + { + // Multiple launch devices with encryption + snapshotIds: map[string]string{ + sourceDeviceName: "snap-0123456789abcdef1", + "/dev/xvdg": "snap-0123456789abcdef2", + }, + amiDevices: []*ec2.BlockDeviceMapping{}, + launchDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + Encrypted: aws.Bool(true), + }, + DeviceName: aws.String(sourceDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + Encrypted: aws.Bool(true), + }, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + allDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef1"), + // Encrypted: true stripped from snapshotted devices + }, + DeviceName: aws.String(rootDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef2"), + }, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + }, + { + // Multiple launch devices and AMI devices with encryption + snapshotIds: map[string]string{ + sourceDeviceName: "snap-0123456789abcdef1", + "/dev/xvdg": "snap-0123456789abcdef2", + }, + amiDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + Encrypted: aws.Bool(true), + KmsKeyId: aws.String("keyId"), + }, + // Source device name can be used in AMI devices + // since launch device of same name gets renamed + // to root device name + DeviceName: aws.String(sourceDeviceName), + }, + }, + launchDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + Encrypted: aws.Bool(true), + }, + DeviceName: aws.String(sourceDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + Encrypted: aws.Bool(true), + }, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + allDevices: []*ec2.BlockDeviceMapping{ + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + Encrypted: aws.Bool(true), + KmsKeyId: aws.String("keyId"), + }, + DeviceName: aws.String(sourceDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef1"), + }, + DeviceName: aws.String(rootDeviceName), + }, + &ec2.BlockDeviceMapping{ + Ebs: &ec2.EbsBlockDevice{ + SnapshotId: aws.String("snap-0123456789abcdef2"), + }, + DeviceName: aws.String("/dev/xvdg"), + }, + }, + }, + } + for _, tc := range cases { + stepRegisterAmi := newStepRegisterAMI(tc.amiDevices, tc.launchDevices) + allDevices := stepRegisterAmi.combineDevices(tc.snapshotIds) + if !reflect.DeepEqual(sorted(allDevices), sorted(tc.allDevices)) { + t.Fatalf("Unexpected output from combineDevices") + } } } diff --git a/builder/amazon/ebssurrogate/step_snapshot_new_root.go b/builder/amazon/ebssurrogate/step_snapshot_new_root.go deleted file mode 100644 index 3b607fbd0..000000000 --- a/builder/amazon/ebssurrogate/step_snapshot_new_root.go +++ /dev/null @@ -1,103 +0,0 @@ -package ebssurrogate - -import ( - "context" - "errors" - "fmt" - "time" - - "github.com/aws/aws-sdk-go/service/ec2" - awscommon "github.com/hashicorp/packer/builder/amazon/common" - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// StepSnapshotNewRootVolume creates a snapshot of the created volume. -// -// Produces: -// snapshot_id string - ID of the created snapshot -type StepSnapshotNewRootVolume struct { - NewRootMountPoint string - snapshotId string -} - -func (s *StepSnapshotNewRootVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - ec2conn := state.Get("ec2").(*ec2.EC2) - ui := state.Get("ui").(packer.Ui) - instance := state.Get("instance").(*ec2.Instance) - - var newRootVolume string - for _, volume := range instance.BlockDeviceMappings { - if *volume.DeviceName == s.NewRootMountPoint { - newRootVolume = *volume.Ebs.VolumeId - } - } - - ui.Say(fmt.Sprintf("Creating snapshot of EBS Volume %s...", newRootVolume)) - description := fmt.Sprintf("Packer: %s", time.Now().String()) - - createSnapResp, err := ec2conn.CreateSnapshot(&ec2.CreateSnapshotInput{ - VolumeId: &newRootVolume, - Description: &description, - }) - if err != nil { - err := fmt.Errorf("Error creating snapshot: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - // Set the snapshot ID so we can delete it later - s.snapshotId = *createSnapResp.SnapshotId - ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId)) - - // Wait for the snapshot to be ready - stateChange := awscommon.StateChangeConf{ - Pending: []string{"pending"}, - StepState: state, - Target: "completed", - Refresh: func() (interface{}, string, error) { - resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{SnapshotIds: []*string{&s.snapshotId}}) - if err != nil { - return nil, "", err - } - - if len(resp.Snapshots) == 0 { - return nil, "", errors.New("No snapshots found.") - } - - s := resp.Snapshots[0] - return s, *s.State, nil - }, - } - - _, err = awscommon.WaitForState(&stateChange) - if err != nil { - err := fmt.Errorf("Error waiting for snapshot: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - state.Put("snapshot_id", s.snapshotId) - return multistep.ActionContinue -} - -func (s *StepSnapshotNewRootVolume) Cleanup(state multistep.StateBag) { - if s.snapshotId == "" { - return - } - - _, cancelled := state.GetOk(multistep.StateCancelled) - _, halted := state.GetOk(multistep.StateHalted) - - if cancelled || halted { - ec2conn := state.Get("ec2").(*ec2.EC2) - ui := state.Get("ui").(packer.Ui) - ui.Say("Removing snapshot since we cancelled or halted...") - _, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{SnapshotId: &s.snapshotId}) - if err != nil { - ui.Error(fmt.Sprintf("Error: %s", err)) - } - } -} diff --git a/builder/amazon/ebssurrogate/step_snapshot_volumes.go b/builder/amazon/ebssurrogate/step_snapshot_volumes.go new file mode 100644 index 000000000..9de755ca5 --- /dev/null +++ b/builder/amazon/ebssurrogate/step_snapshot_volumes.go @@ -0,0 +1,129 @@ +package ebssurrogate + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/aws/aws-sdk-go/service/ec2" + multierror "github.com/hashicorp/go-multierror" + awscommon "github.com/hashicorp/packer/builder/amazon/common" + "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/packer" +) + +// StepSnapshotVolumes creates snapshots of the created volumes. +// +// Produces: +// snapshot_ids map[string]string - IDs of the created snapshots +type StepSnapshotVolumes struct { + LaunchDevices []*ec2.BlockDeviceMapping + snapshotIds map[string]string +} + +func (s *StepSnapshotVolumes) snapshotVolume(deviceName string, state multistep.StateBag) error { + ec2conn := state.Get("ec2").(*ec2.EC2) + ui := state.Get("ui").(packer.Ui) + instance := state.Get("instance").(*ec2.Instance) + + var volumeId string + for _, volume := range instance.BlockDeviceMappings { + if *volume.DeviceName == deviceName { + volumeId = *volume.Ebs.VolumeId + } + } + if volumeId == "" { + return fmt.Errorf("Volume ID for device %s not found", deviceName) + } + + ui.Say(fmt.Sprintf("Creating snapshot of EBS Volume %s...", volumeId)) + description := fmt.Sprintf("Packer: %s", time.Now().String()) + + createSnapResp, err := ec2conn.CreateSnapshot(&ec2.CreateSnapshotInput{ + VolumeId: &volumeId, + Description: &description, + }) + if err != nil { + return err + } + + // Set the snapshot ID so we can delete it later + s.snapshotIds[deviceName] = *createSnapResp.SnapshotId + + // Wait for the snapshot to be ready + stateChange := awscommon.StateChangeConf{ + Pending: []string{"pending"}, + StepState: state, + Target: "completed", + Refresh: func() (interface{}, string, error) { + resp, err := ec2conn.DescribeSnapshots(&ec2.DescribeSnapshotsInput{ + SnapshotIds: []*string{createSnapResp.SnapshotId}, + }) + if err != nil { + return nil, "", err + } + + if len(resp.Snapshots) == 0 { + return nil, "", errors.New("No snapshots found.") + } + + s := resp.Snapshots[0] + return s, *s.State, nil + }, + } + + _, err = awscommon.WaitForState(&stateChange) + return err +} + +func (s *StepSnapshotVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + ui := state.Get("ui").(packer.Ui) + + s.snapshotIds = map[string]string{} + + var wg sync.WaitGroup + var errs *multierror.Error + for _, device := range s.LaunchDevices { + wg.Add(1) + go func(device *ec2.BlockDeviceMapping) { + defer wg.Done() + if err := s.snapshotVolume(*device.DeviceName, state); err != nil { + errs = multierror.Append(errs, err) + } + }(device) + } + + wg.Wait() + + if errs != nil { + state.Put("error", errs) + ui.Error(errs.Error()) + return multistep.ActionHalt + } + + state.Put("snapshot_ids", s.snapshotIds) + return multistep.ActionContinue +} + +func (s *StepSnapshotVolumes) Cleanup(state multistep.StateBag) { + if len(s.snapshotIds) == 0 { + return + } + + _, cancelled := state.GetOk(multistep.StateCancelled) + _, halted := state.GetOk(multistep.StateHalted) + + if cancelled || halted { + ec2conn := state.Get("ec2").(*ec2.EC2) + ui := state.Get("ui").(packer.Ui) + ui.Say("Removing snapshots since we cancelled or halted...") + for _, snapshotId := range s.snapshotIds { + _, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{SnapshotId: &snapshotId}) + if err != nil { + ui.Error(fmt.Sprintf("Error: %s", err)) + } + } + } +} From 72da7cbfbb4bd8e07320cf0562a9fea1557a136b Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sun, 25 Mar 2018 18:51:37 -0500 Subject: [PATCH 0856/1007] Fixed a case-sensitivity issue when determing the network type during cloning in the vmware-vmx builder and added also some logs that output the different options that were determined from the .vmx. This outputs more accurate debug information and helps out with issue #5925 --- builder/vmware/vmx/step_clone_vmx.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index bd644ca30..482adb46b 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -22,8 +22,10 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) + // initially we need to stash the path to the original .vmx file vmxPath := filepath.Join(s.OutputDir, s.VMName+".vmx") + // so first, let's clone the source path to the vmxPath ui.Say("Cloning source VM...") log.Printf("Cloning from: %s", s.Path) log.Printf("Cloning to: %s", vmxPath) @@ -31,13 +33,16 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste state.Put("error", err) return multistep.ActionHalt } + ui.Say("Successfully cloned source VM to: %s", vmxPath) + // now we read the .vmx so we can determine what else to stash vmxData, err := vmwcommon.ReadVMX(vmxPath) if err != nil { state.Put("error", err) return multistep.ActionHalt } + // figure out the disk filename by walking through all device types var diskName string if _, ok := vmxData["scsi0:0.filename"]; ok { diskName = vmxData["scsi0:0.filename"] @@ -53,19 +58,25 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste state.Put("error", err) return multistep.ActionHalt } + log.Printf("Found root disk filename: %s", diskName) + // determine the network type by reading out of the .vmx var networkType string - if _, ok := vmxData["ethernet0.connectionType"]; ok { - networkType = vmxData["ethernet0.connectionType"] + if _, ok := vmxData["ethernet0.connectiontype"]; ok { + networkType = vmxData["ethernet0.connectiontype"] + log.Printf("Discovered the network type: %s", networkType) } if networkType == "" { networkType = "nat" - log.Printf("Defaulting to network type : nat") + log.Printf("Defaulting to network type: %s", networkType) } + ui.Say("Using network type: %s", networkType) - state.Put("vmnetwork", networkType) - state.Put("full_disk_path", filepath.Join(s.OutputDir, diskName)) + // we were able to find everything, so stash it in our state. state.Put("vmx_path", vmxPath) + state.Put("full_disk_path", filepath.Join(s.OutputDir, diskName)) + state.Put("vmnetwork", networkType) + return multistep.ActionContinue } From 1913517d29bdc20bb421d2dcb354a0c704a3e6e9 Mon Sep 17 00:00:00 2001 From: Joseph Wright <joseph@cloudboss.co> Date: Sun, 25 Mar 2018 19:51:49 -0400 Subject: [PATCH 0857/1007] Fix formatting by running `make fmt` --- .../ebssurrogate/step_register_ami_test.go | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/builder/amazon/ebssurrogate/step_register_ami_test.go b/builder/amazon/ebssurrogate/step_register_ami_test.go index 10872bb86..d2ef67685 100644 --- a/builder/amazon/ebssurrogate/step_register_ami_test.go +++ b/builder/amazon/ebssurrogate/step_register_ami_test.go @@ -50,13 +50,13 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { snapshotIds: map[string]string{}, amiDevices: []*ec2.BlockDeviceMapping{}, launchDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String(sourceDeviceName), }, }, allDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String(rootDeviceName), }, @@ -69,13 +69,13 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { }, amiDevices: []*ec2.BlockDeviceMapping{}, launchDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String(sourceDeviceName), }, }, allDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef1"), }, @@ -89,25 +89,25 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { sourceDeviceName: "snap-0123456789abcdef1", }, amiDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String("/dev/xvdg"), }, }, launchDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String(sourceDeviceName), }, }, allDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef1"), }, DeviceName: aws.String(rootDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String("/dev/xvdg"), }, @@ -121,23 +121,23 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { }, amiDevices: []*ec2.BlockDeviceMapping{}, launchDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String(sourceDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{}, DeviceName: aws.String("/dev/xvdg"), }, }, allDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef1"), }, DeviceName: aws.String(rootDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef2"), }, @@ -153,13 +153,13 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { }, amiDevices: []*ec2.BlockDeviceMapping{}, launchDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ Encrypted: aws.Bool(true), }, DeviceName: aws.String(sourceDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ Encrypted: aws.Bool(true), }, @@ -167,14 +167,14 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { }, }, allDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef1"), // Encrypted: true stripped from snapshotted devices }, DeviceName: aws.String(rootDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef2"), }, @@ -189,7 +189,7 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { "/dev/xvdg": "snap-0123456789abcdef2", }, amiDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ Encrypted: aws.Bool(true), KmsKeyId: aws.String("keyId"), @@ -201,13 +201,13 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { }, }, launchDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ Encrypted: aws.Bool(true), }, DeviceName: aws.String(sourceDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ Encrypted: aws.Bool(true), }, @@ -215,20 +215,20 @@ func TestStepRegisterAmi_combineDevices(t *testing.T) { }, }, allDevices: []*ec2.BlockDeviceMapping{ - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ Encrypted: aws.Bool(true), KmsKeyId: aws.String("keyId"), }, DeviceName: aws.String(sourceDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef1"), }, DeviceName: aws.String(rootDeviceName), }, - &ec2.BlockDeviceMapping{ + { Ebs: &ec2.EbsBlockDevice{ SnapshotId: aws.String("snap-0123456789abcdef2"), }, From 55702a697af5b6ea63590d85eb5c2243142c6f83 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Sun, 25 Mar 2018 19:03:37 -0500 Subject: [PATCH 0858/1007] Ack, forgot to :w in vim. Changed ui.Say in step_clone_vmx.go to use fmt.Sprintf as it originally was a call to log.Printf. --- builder/vmware/vmx/step_clone_vmx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index 482adb46b..f0bdd586d 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -33,7 +33,7 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste state.Put("error", err) return multistep.ActionHalt } - ui.Say("Successfully cloned source VM to: %s", vmxPath) + ui.Say(fmt.Sprintf("Successfully cloned source VM to: %s", vmxPath)) // now we read the .vmx so we can determine what else to stash vmxData, err := vmwcommon.ReadVMX(vmxPath) @@ -70,7 +70,7 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste networkType = "nat" log.Printf("Defaulting to network type: %s", networkType) } - ui.Say("Using network type: %s", networkType) + ui.Say(fmt.Sprintf("Using network type: %s", networkType)) // we were able to find everything, so stash it in our state. state.Put("vmx_path", vmxPath) From 406bf9c4aad7c925c3f5a837fe7f9c71169af098 Mon Sep 17 00:00:00 2001 From: "Joshua C. Randall" <jcrandall@alum.mit.edu> Date: Mon, 26 Mar 2018 17:24:58 +0100 Subject: [PATCH 0859/1007] override ansible executor inventory to use InventoryDirectory instead of InventoryFile when set --- provisioner/ansible/provisioner.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index 2984e496a..bc24044b3 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -321,6 +321,9 @@ func (p *Provisioner) Cancel() { func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, privKeyFile string) error { playbook, _ := filepath.Abs(p.config.PlaybookFile) inventory := p.config.inventoryFile + if len(p.config.InventoryDirectory) > 0 { + inventory = p.config.InventoryDirectory + } var envvars []string args := []string{"--extra-vars", fmt.Sprintf("packer_build_name=%s packer_builder_type=%s", From b8313e00f177d06045b82b74f091d1c0ea889e37 Mon Sep 17 00:00:00 2001 From: Christos Varelas <cvarelas@suse.com> Date: Mon, 26 Mar 2018 21:01:54 +0200 Subject: [PATCH 0860/1007] Make minor edit H humble edit for a simple syntax error --- website/source/intro/getting-started/build-image.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/intro/getting-started/build-image.html.md b/website/source/intro/getting-started/build-image.html.md index 273618294..73a93bc7e 100644 --- a/website/source/intro/getting-started/build-image.html.md +++ b/website/source/intro/getting-started/build-image.html.md @@ -114,7 +114,7 @@ installing Redis. ## Your First Image -With a properly validated template. It is time to build your first image. This +With a properly validated template, it is time to build your first image. This is done by calling `packer build` with the template file. The output should look similar to below. Note that this process typically takes a few minutes. From 96adae122f25b625a9236b47a93105dc5b26627c Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 26 Mar 2018 13:57:00 -0700 Subject: [PATCH 0861/1007] finalized Changelog for v1.2.2 --- CHANGELOG.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2908ea5f7..e66d470f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,25 @@ -## (UNRELEASED) +## 1.2.2 (March 26, 2018) ### BUG FIXES: +* builder/amazon: Fix AWS credential defaulting [GH-6019] +* builder/LXC: make sleep timeout easily configurable [GH-6038] * builder/virtualbox: Correctly send multi-byte scancodes when typing boot command. [GH-5987] -* provisioner/powershell: Fix environment variable file escaping. [GH-5973] +* builder/virtualbox: Special boot-commands no longer overwrite previous + commands [GH-6002] +* builder/vmware: Default to disabling XHCI bus for USB on the vmware-iso + builder. [GH-5975] * builder/vmware: Handle multiple devices per VMware network type [GH-5985] -* builder/amazon: Fix AWS credential defaulting [GH-6019] -* builder/virtualbox: Special boot-commands no longer overwrite previous commands [GH-6002] -* builder/vmware: Default to disabling XHCI bus for USB on the vmware-iso builder. [GH-5975] +* communicator/ssh: Handle errors uploading files more gracefully [GH-6033] +* provisioner/powershell: Fix environment variable file escaping. [GH-5973] ### IMPROVEMENTS: * builder/amazon: Added new region `cn-northwest-1`. [GH-5960] +* builder/amazon: Users may now access the amazon-generated administrator + password [GH-5998] * builder/azure: Add support concurrent deployments in the same resource group. [GH-6005] * builder/azure: Add support for building with additional disks. [GH-5944] @@ -22,9 +28,9 @@ * builder/azure: Respect `-force` for managed image deletion. [GH-6003] * builder/google: Add option to specify a service account, or to run without one. [GH-5991] [GH-5928] +* builder/oracle-oci: Add new "use_private_ip" option. [GH-5893] * post-processor/vagrant: Add LXC support. [GH-5980] * provisioner/salt-masterless: Added Windows support. [GH-5702] -* builder/oracle-oci: Add new "use_private_ip" option. [GH-5893] * provisioner/salt: Add windows support to salt provisioner [GH-6012] [GH-6012] From 3fbab16abf2c73d175d82516fb77b6e61e2f7989 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 26 Mar 2018 13:57:48 -0700 Subject: [PATCH 0862/1007] cut v1.2.2 --- version/version.go | 2 +- website/config.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 870a3badd..c8392ce18 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ const Version = "1.2.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index 38ef7eb6f..6c4b1eb23 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.2.1" + h.version = "1.2.2" h.github_slug = "hashicorp/packer" h.website_root = "website" end From 1d97382e0f5d6eb4a32189080e388cd3ef3cac72 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 26 Mar 2018 14:23:07 -0700 Subject: [PATCH 0863/1007] version 1.2.3 dev --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index c8392ce18..ff47b820f 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.2.2" +const Version = "1.2.3" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From fdc6ac631acdbfc18fb82e29cf0a98c9d945f364 Mon Sep 17 00:00:00 2001 From: Andrew Pennebaker <andrew.pennebaker@gmail.com> Date: Mon, 19 Mar 2018 16:25:09 -0500 Subject: [PATCH 0864/1007] fix vbox scancodes and support critical key combinations during boot-time operations --- .../common/step_type_boot_command.go | 98 ++++++++++++++++--- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index fc8ee5c73..be9397e76 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "regexp" "strings" "time" "unicode" @@ -120,7 +121,7 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} func scancodes(message string) []string { - // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + // Scancodes reference: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html // // Scancodes represent raw keyboard output and are fed to the VM by the // VBoxManage controlvm keyboardputscancode program. @@ -130,7 +131,7 @@ func scancodes(message string) []string { // derived from the first by the addition of 0x80. special := make(map[string][]string) special["<bs>"] = []string{"0e", "8e"} - special["<del>"] = []string{"53", "d3"} + special["<del>"] = []string{"e053", "e0d3"} special["<enter>"] = []string{"1c", "9c"} special["<esc>"] = []string{"01", "81"} special["<f1>"] = []string{"3b", "bb"} @@ -143,24 +144,28 @@ func scancodes(message string) []string { special["<f8>"] = []string{"42", "c2"} special["<f9>"] = []string{"43", "c3"} special["<f10>"] = []string{"44", "c4"} + special["<f11>"] = []string{"57", "d7"} + special["<f12>"] = []string{"58", "d8"} special["<return>"] = []string{"1c", "9c"} special["<tab>"] = []string{"0f", "8f"} - special["<up>"] = []string{"48", "c8"} - special["<down>"] = []string{"50", "d0"} - special["<left>"] = []string{"4b", "cb"} - special["<right>"] = []string{"4d", "cd"} + special["<up>"] = []string{"e048", "e0c8"} + special["<down>"] = []string{"e050", "e0d0"} + special["<left>"] = []string{"e04b", "e0cb"} + special["<right>"] = []string{"e04d", "e0cd"} special["<spacebar>"] = []string{"39", "b9"} - special["<insert>"] = []string{"52", "d2"} - special["<home>"] = []string{"47", "c7"} - special["<end>"] = []string{"4f", "cf"} - special["<pageUp>"] = []string{"49", "c9"} - special["<pageDown>"] = []string{"51", "d1"} + special["<insert>"] = []string{"e052", "e0d2"} + special["<home>"] = []string{"e047", "e0c7"} + special["<end>"] = []string{"e04f", "e0cf"} + special["<pageUp>"] = []string{"e049", "e0c9"} + special["<pageDown>"] = []string{"e051", "e0d1"} special["<leftAlt>"] = []string{"38", "b8"} special["<leftCtrl>"] = []string{"1d", "9d"} special["<leftShift>"] = []string{"2a", "aa"} special["<rightAlt>"] = []string{"e038", "e0b8"} special["<rightCtrl>"] = []string{"e01d", "e09d"} special["<rightShift>"] = []string{"36", "b6"} + special["<leftSuper>"] = []string{"e05b", "e0db"} + special["<rightSuper>"] = []string{"e05c", "e0dc"} shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" @@ -186,10 +191,51 @@ func scancodes(message string) []string { } } + azOnRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])On>") + azOffRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])Off>") + result := make([]string, 0, len(message)*2) for len(message) > 0 { var scancode []string + if azOnRegex.MatchString(message) { + m := azOnRegex.FindStringSubmatch(message) + r, _ := utf8.DecodeRuneInString(m[1]) + message = message[len("<aOn>"):] + scancodeInt := scancodeMap[r] + keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) + + if keyShift { + scancode = append(scancode, "2a") + } + + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + + log.Printf("Sending char '%c', code '%v', shift %v", r, scancodeInt, keyShift) + } + + if azOffRegex.MatchString(message) { + m := azOffRegex.FindStringSubmatch(message) + r, _ := utf8.DecodeRuneInString(m[1]) + message = message[len("<aOff>"):] + scancodeInt := scancodeMap[r] + 0x80 + keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) + + if keyShift { + scancode = append(scancode, "aa") + } + + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + + log.Printf("Sending char '%c', code '%v', shift %v", r, scancodeInt, keyShift) + } + + if strings.HasPrefix(message, "<f12On>") { + scancode = append(scancode, "58") + message = message[len("<f12On>"):] + log.Printf("Special code '<f12On>', replacing with: 58") + } + if strings.HasPrefix(message, "<leftAltOn>") { scancode = append(scancode, "38") message = message[len("<leftAltOn>"):] @@ -208,6 +254,18 @@ func scancodes(message string) []string { log.Printf("Special code '<leftShiftOn>' found, replacing with: 2a") } + if strings.HasPrefix(message, "<leftSuperOn>") { + scancode = append(scancode, "e05b") + message = message[len("<leftSuperOn>"):] + log.Printf("Special code '<leftSuperOn>' found, replacing with: e05b") + } + + if strings.HasPrefix(message, "<f12Off>") { + scancode = append(scancode, "d8") + message = message[len("<f12Off>"):] + log.Printf("Special code '<f12Off>' found, replacing with: d8") + } + if strings.HasPrefix(message, "<leftAltOff>") { scancode = append(scancode, "b8") message = message[len("<leftAltOff>"):] @@ -226,6 +284,12 @@ func scancodes(message string) []string { log.Printf("Special code '<leftShiftOff>' found, replacing with: aa") } + if strings.HasPrefix(message, "<leftSuperOff>") { + scancode = append(scancode, "e0db") + message = message[len("<leftSuperOff>"):] + log.Printf("Special code '<leftSuperOff>' found, replacing with: e0db") + } + if strings.HasPrefix(message, "<rightAltOn>") { scancode = append(scancode, "e038") message = message[len("<rightAltOn>"):] @@ -244,6 +308,12 @@ func scancodes(message string) []string { log.Printf("Special code '<rightShiftOn>' found, replacing with: 36") } + if strings.HasPrefix(message, "<rightSuperOn>") { + scancode = append(scancode, "e05c") + message = message[len("<rightSuperOn>"):] + log.Printf("Special code '<rightSuperOn>' found, replacing with: e05c") + } + if strings.HasPrefix(message, "<rightAltOff>") { scancode = append(scancode, "e0b8") message = message[len("<rightAltOff>"):] @@ -262,6 +332,12 @@ func scancodes(message string) []string { log.Printf("Special code '<rightShiftOff>' found, replacing with: b6") } + if strings.HasPrefix(message, "<rightSuperOff>") { + scancode = append(scancode, "e0dc") + message = message[len("<rightSuperOff>"):] + log.Printf("Special code '<rightSuperOff>' found, replacing with: e0dc") + } + if strings.HasPrefix(message, "<wait>") { log.Printf("Special code <wait> found, will sleep 1 second at this point.") scancode = append(scancode, "wait") From a9660c0aeaf478b9f13cb31c8ccbc2df0b48df54 Mon Sep 17 00:00:00 2001 From: Matthew Aynalem <mayn@users.noreply.github.com> Date: Sun, 25 Mar 2018 20:38:41 -0700 Subject: [PATCH 0865/1007] docs/commands - update options to match those listed in command help output --- website/source/docs/commands/build.html.md | 5 +++++ website/source/docs/commands/fix.html.md | 4 ++++ website/source/docs/commands/validate.html.md | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/website/source/docs/commands/build.html.md b/website/source/docs/commands/build.html.md index 7d331159e..575f9ed84 100644 --- a/website/source/docs/commands/build.html.md +++ b/website/source/docs/commands/build.html.md @@ -49,3 +49,8 @@ that are created will be outputted at the end of the build. - `-parallel=false` - Disable parallelization of multiple builders (on by default). + +- `-var` - Set a variable in your packer template. This option can be used + multiple times. This is useful for setting version numbers for your build. + +- `-var-file` - Set template variables from a file. diff --git a/website/source/docs/commands/fix.html.md b/website/source/docs/commands/fix.html.md index 1793d3275..428ad0e11 100644 --- a/website/source/docs/commands/fix.html.md +++ b/website/source/docs/commands/fix.html.md @@ -35,3 +35,7 @@ human readability. The full list of fixes that the fix command performs is visible in the help output, which can be seen via `packer fix -h`. + +## Options + +- `-validate=false` - Disables validation of the fixed template. True by default. diff --git a/website/source/docs/commands/validate.html.md b/website/source/docs/commands/validate.html.md index d1102f2d1..aba07175a 100644 --- a/website/source/docs/commands/validate.html.md +++ b/website/source/docs/commands/validate.html.md @@ -32,3 +32,16 @@ Errors validating build 'vmware'. 1 error(s) occurred: - `-syntax-only` - Only the syntax of the template is checked. The configuration is not validated. + +- `-except=foo,bar,baz` - Builds all the builds except those with the given + comma-separated names. Build names by default are the names of their builders, + unless a specific `name` attribute is specified within the configuration. + +- `-only=foo,bar,baz` - Only build the builds with the given comma-separated + names. Build names by default are the names of their builders, unless a + specific `name` attribute is specified within the configuration. + +- `-var` - Set a variable in your packer template. This option can be used + multiple times. This is useful for setting version numbers for your build. + +- `-var-file` - Set template variables from a file. From f6135a440c283b88caaf3314f10272037cfe1a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Carr?= <lcarr@online.net> Date: Sat, 24 Mar 2018 12:18:46 +0100 Subject: [PATCH 0866/1007] builder/scaleway: bump dependencies This dependency bump solves #5879 --- vendor/github.com/Azure/go-ansiterm/LICENSE | 21 + vendor/github.com/Azure/go-ansiterm/README.md | 12 + .../github.com/Azure/go-ansiterm/constants.go | 188 ++ .../github.com/Azure/go-ansiterm/context.go | 7 + .../Azure/go-ansiterm/csi_entry_state.go | 49 + .../Azure/go-ansiterm/csi_param_state.go | 38 + .../go-ansiterm/escape_intermediate_state.go | 36 + .../Azure/go-ansiterm/escape_state.go | 47 + .../Azure/go-ansiterm/event_handler.go | 90 + .../Azure/go-ansiterm/ground_state.go | 24 + .../Azure/go-ansiterm/osc_string_state.go | 31 + vendor/github.com/Azure/go-ansiterm/parser.go | 151 + .../go-ansiterm/parser_action_helpers.go | 99 + .../Azure/go-ansiterm/parser_actions.go | 119 + vendor/github.com/Azure/go-ansiterm/states.go | 71 + .../github.com/Azure/go-ansiterm/utilities.go | 21 + .../Azure/go-ansiterm/winterm/ansi.go | 182 ++ .../Azure/go-ansiterm/winterm/api.go | 327 ++ .../go-ansiterm/winterm/attr_translation.go | 100 + .../go-ansiterm/winterm/cursor_helpers.go | 101 + .../go-ansiterm/winterm/erase_helpers.go | 84 + .../go-ansiterm/winterm/scroll_helper.go | 118 + .../Azure/go-ansiterm/winterm/utilities.go | 9 + .../go-ansiterm/winterm/win_event_handler.go | 743 +++++ .../github.com/Sirupsen/logrus/CHANGELOG.md | 29 + vendor/github.com/Sirupsen/logrus/README.md | 97 +- vendor/github.com/Sirupsen/logrus/doc.go | 4 +- vendor/github.com/Sirupsen/logrus/entry.go | 85 +- vendor/github.com/Sirupsen/logrus/exported.go | 4 +- .../github.com/Sirupsen/logrus/formatter.go | 2 +- .../Sirupsen/logrus/json_formatter.go | 13 +- vendor/github.com/Sirupsen/logrus/logger.go | 59 +- vendor/github.com/Sirupsen/logrus/logrus.go | 2 +- .../Sirupsen/logrus/terminal_bsd.go | 8 +- .../Sirupsen/logrus/terminal_linux.go | 8 +- .../Sirupsen/logrus/terminal_notwindows.go | 28 - .../Sirupsen/logrus/terminal_solaris.go | 21 - .../Sirupsen/logrus/terminal_windows.go | 33 - .../Sirupsen/logrus/text_formatter.go | 47 +- .../docker/pkg/term/windows/ansi_reader.go | 263 ++ .../docker/pkg/term/windows/ansi_writer.go | 64 + .../docker/docker/pkg/term/windows/console.go | 35 + .../docker/docker/pkg/term/windows/windows.go | 33 + .../github.com/moul/gotty-client/Dockerfile | 11 + .../moul/gotty-client/LICENSE.apache | 192 ++ vendor/github.com/moul/gotty-client/Makefile | 16 +- vendor/github.com/moul/gotty-client/README.md | 6 +- vendor/github.com/moul/gotty-client/arch.go | 12 +- .../github.com/moul/gotty-client/glide.lock | 37 - .../github.com/moul/gotty-client/glide.yaml | 35 - .../moul/gotty-client/gotty-client.go | 12 +- vendor/github.com/moul/gotty-client/proxy.go | 90 + .../scaleway/scaleway-cli/pkg/api/README.md | 24 +- .../scaleway/scaleway-cli/pkg/api/api.go | 86 + .../scaleway/scaleway-cli/pkg/api/cache.go | 4 +- .../scaleway/scaleway-cli/pkg/api/helpers.go | 114 +- .../scaleway/scaleway-cli/pkg/utils/utils.go | 4 +- .../github.com/sirupsen/logrus/appveyor.yml | 14 + .../logrus/terminal_check_appengine.go | 11 + .../logrus/terminal_check_notappengine.go | 19 + .../x/crypto/ssh/terminal/terminal.go | 2 +- .../golang.org/x/crypto/ssh/terminal/util.go | 69 +- .../x/crypto/ssh/terminal/util_bsd.go | 6 +- .../x/crypto/ssh/terminal/util_linux.go | 9 +- .../x/crypto/ssh/terminal/util_solaris.go | 59 +- .../x/crypto/ssh/terminal/util_windows.go | 116 +- .../golang.org/x/sys/unix/affinity_linux.go | 124 + vendor/golang.org/x/sys/unix/asm_linux_386.s | 36 +- .../golang.org/x/sys/unix/asm_linux_amd64.s | 30 +- vendor/golang.org/x/sys/unix/asm_linux_arm.s | 35 +- .../golang.org/x/sys/unix/asm_linux_arm64.s | 30 +- .../golang.org/x/sys/unix/asm_linux_mips64x.s | 36 +- .../golang.org/x/sys/unix/asm_linux_mipsx.s | 33 +- .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 30 +- .../golang.org/x/sys/unix/asm_linux_s390x.s | 28 + vendor/golang.org/x/sys/unix/dev_darwin.go | 24 + vendor/golang.org/x/sys/unix/dev_dragonfly.go | 30 + vendor/golang.org/x/sys/unix/dev_freebsd.go | 30 + vendor/golang.org/x/sys/unix/dev_linux.go | 8 +- vendor/golang.org/x/sys/unix/dev_netbsd.go | 29 + vendor/golang.org/x/sys/unix/dev_openbsd.go | 29 + vendor/golang.org/x/sys/unix/dirent.go | 89 +- vendor/golang.org/x/sys/unix/env_unix.go | 6 +- vendor/golang.org/x/sys/unix/env_unset.go | 14 - vendor/golang.org/x/sys/unix/file_unix.go | 27 - vendor/golang.org/x/sys/unix/gccgo.go | 19 +- vendor/golang.org/x/sys/unix/gccgo_c.c | 8 +- .../x/sys/unix/gccgo_linux_amd64.go | 2 +- .../x/sys/unix/gccgo_linux_sparc64.go | 20 - vendor/golang.org/x/sys/unix/mkall.sh | 27 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 30 +- vendor/golang.org/x/sys/unix/mksyscall.pl | 17 +- .../golang.org/x/sys/unix/mksysnum_netbsd.pl | 2 +- vendor/golang.org/x/sys/unix/pagesize_unix.go | 15 + vendor/golang.org/x/sys/unix/race.go | 2 +- vendor/golang.org/x/sys/unix/race0.go | 2 +- .../golang.org/x/sys/unix/sockcmsg_linux.go | 2 +- vendor/golang.org/x/sys/unix/syscall.go | 35 +- vendor/golang.org/x/sys/unix/syscall_bsd.go | 63 +- .../golang.org/x/sys/unix/syscall_darwin.go | 110 +- .../x/sys/unix/syscall_darwin_386.go | 19 +- .../x/sys/unix/syscall_darwin_amd64.go | 19 +- .../x/sys/unix/syscall_darwin_arm.go | 23 +- .../x/sys/unix/syscall_darwin_arm64.go | 19 +- .../x/sys/unix/syscall_dragonfly.go | 158 +- .../x/sys/unix/syscall_dragonfly_amd64.go | 17 +- .../golang.org/x/sys/unix/syscall_freebsd.go | 124 +- .../x/sys/unix/syscall_freebsd_386.go | 17 +- .../x/sys/unix/syscall_freebsd_amd64.go | 17 +- .../x/sys/unix/syscall_freebsd_arm.go | 17 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 107 +- .../x/sys/unix/syscall_linux_386.go | 22 +- .../x/sys/unix/syscall_linux_amd64.go | 18 +- .../x/sys/unix/syscall_linux_arm.go | 18 +- .../x/sys/unix/syscall_linux_arm64.go | 28 +- .../golang.org/x/sys/unix/syscall_linux_gc.go | 14 + .../x/sys/unix/syscall_linux_gccgo.go | 21 + .../x/sys/unix/syscall_linux_mips64x.go | 29 +- .../x/sys/unix/syscall_linux_mipsx.go | 19 +- .../x/sys/unix/syscall_linux_ppc64x.go | 21 +- .../x/sys/unix/syscall_linux_s390x.go | 18 +- .../x/sys/unix/syscall_linux_sparc64.go | 37 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 133 +- .../x/sys/unix/syscall_netbsd_386.go | 17 +- .../x/sys/unix/syscall_netbsd_amd64.go | 17 +- .../x/sys/unix/syscall_netbsd_arm.go | 17 +- .../golang.org/x/sys/unix/syscall_no_getwd.go | 11 - .../golang.org/x/sys/unix/syscall_openbsd.go | 154 +- .../x/sys/unix/syscall_openbsd_386.go | 17 +- .../x/sys/unix/syscall_openbsd_amd64.go | 17 +- .../x/sys/unix/syscall_openbsd_arm.go | 19 +- .../golang.org/x/sys/unix/syscall_solaris.go | 90 +- .../x/sys/unix/syscall_solaris_amd64.go | 15 +- vendor/golang.org/x/sys/unix/syscall_unix.go | 37 + vendor/golang.org/x/sys/unix/timestruct.go | 82 + .../x/sys/unix/zerrors_darwin_386.go | 96 + .../x/sys/unix/zerrors_darwin_amd64.go | 96 + .../x/sys/unix/zerrors_darwin_arm.go | 96 + .../x/sys/unix/zerrors_darwin_arm64.go | 96 + .../x/sys/unix/zerrors_dragonfly_amd64.go | 10 + .../x/sys/unix/zerrors_freebsd_386.go | 50 + .../x/sys/unix/zerrors_freebsd_amd64.go | 50 + .../x/sys/unix/zerrors_freebsd_arm.go | 50 + .../x/sys/unix/zerrors_linux_386.go | 134 +- .../x/sys/unix/zerrors_linux_amd64.go | 136 +- .../x/sys/unix/zerrors_linux_arm.go | 137 +- .../x/sys/unix/zerrors_linux_arm64.go | 137 +- .../x/sys/unix/zerrors_linux_mips.go | 133 +- .../x/sys/unix/zerrors_linux_mips64.go | 135 +- .../x/sys/unix/zerrors_linux_mips64le.go | 135 +- .../x/sys/unix/zerrors_linux_mipsle.go | 133 +- .../x/sys/unix/zerrors_linux_ppc64.go | 136 +- .../x/sys/unix/zerrors_linux_ppc64le.go | 136 +- .../x/sys/unix/zerrors_linux_s390x.go | 136 +- .../x/sys/unix/zerrors_netbsd_386.go | 9 +- .../x/sys/unix/zerrors_netbsd_amd64.go | 9 +- .../x/sys/unix/zerrors_netbsd_arm.go | 12 +- .../x/sys/unix/zerrors_openbsd_386.go | 9 +- .../x/sys/unix/zerrors_openbsd_amd64.go | 9 +- .../x/sys/unix/zerrors_openbsd_arm.go | 9 +- .../x/sys/unix/zerrors_solaris_amd64.go | 6 + .../golang.org/x/sys/unix/zptrace386_linux.go | 80 + .../golang.org/x/sys/unix/zptracearm_linux.go | 41 + .../x/sys/unix/zptracemips_linux.go | 50 + .../x/sys/unix/zptracemipsle_linux.go | 50 + .../x/sys/unix/zsyscall_darwin_386.go | 210 +- .../x/sys/unix/zsyscall_darwin_amd64.go | 210 +- .../x/sys/unix/zsyscall_darwin_arm.go | 196 +- .../x/sys/unix/zsyscall_darwin_arm64.go | 194 +- .../x/sys/unix/zsyscall_dragonfly_amd64.go | 251 +- .../x/sys/unix/zsyscall_freebsd_386.go | 243 +- .../x/sys/unix/zsyscall_freebsd_amd64.go | 243 +- .../x/sys/unix/zsyscall_freebsd_arm.go | 243 +- .../x/sys/unix/zsyscall_linux_386.go | 93 +- .../x/sys/unix/zsyscall_linux_amd64.go | 93 +- .../x/sys/unix/zsyscall_linux_arm.go | 93 +- .../x/sys/unix/zsyscall_linux_arm64.go | 99 +- .../x/sys/unix/zsyscall_linux_mips.go | 103 +- .../x/sys/unix/zsyscall_linux_mips64.go | 114 +- .../x/sys/unix/zsyscall_linux_mips64le.go | 114 +- .../x/sys/unix/zsyscall_linux_mipsle.go | 103 +- .../x/sys/unix/zsyscall_linux_ppc64.go | 105 +- .../x/sys/unix/zsyscall_linux_ppc64le.go | 105 +- .../x/sys/unix/zsyscall_linux_s390x.go | 93 +- .../x/sys/unix/zsyscall_linux_sparc64.go | 10 + .../x/sys/unix/zsyscall_netbsd_386.go | 263 +- .../x/sys/unix/zsyscall_netbsd_amd64.go | 263 +- .../x/sys/unix/zsyscall_netbsd_arm.go | 265 +- .../x/sys/unix/zsyscall_openbsd_386.go | 253 +- .../x/sys/unix/zsyscall_openbsd_amd64.go | 253 +- .../x/sys/unix/zsyscall_openbsd_arm.go | 207 +- .../x/sys/unix/zsyscall_solaris_amd64.go | 95 +- ...sctl_openbsd.go => zsysctl_openbsd_386.go} | 0 .../x/sys/unix/zsysctl_openbsd_amd64.go | 270 ++ .../x/sys/unix/zsysctl_openbsd_arm.go | 270 ++ .../x/sys/unix/zsysnum_darwin_386.go | 60 +- .../x/sys/unix/zsysnum_darwin_amd64.go | 60 +- .../x/sys/unix/zsysnum_darwin_arm.go | 14 +- .../x/sys/unix/zsysnum_darwin_arm64.go | 14 +- .../x/sys/unix/zsysnum_linux_386.go | 2 + .../x/sys/unix/zsysnum_linux_amd64.go | 1 + .../x/sys/unix/zsysnum_linux_arm.go | 1 + .../x/sys/unix/zsysnum_linux_arm64.go | 1 + .../x/sys/unix/zsysnum_linux_mips.go | 1 + .../x/sys/unix/zsysnum_linux_mips64.go | 1 + .../x/sys/unix/zsysnum_linux_mips64le.go | 1 + .../x/sys/unix/zsysnum_linux_mipsle.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 1 + .../x/sys/unix/zsysnum_linux_s390x.go | 3 + .../x/sys/unix/zsysnum_netbsd_386.go | 1 + .../x/sys/unix/zsysnum_netbsd_amd64.go | 1 + .../x/sys/unix/zsysnum_netbsd_arm.go | 1 + .../x/sys/unix/zsysnum_solaris_amd64.go | 13 - .../x/sys/unix/ztypes_darwin_386.go | 139 +- .../x/sys/unix/ztypes_darwin_amd64.go | 185 +- .../x/sys/unix/ztypes_darwin_arm.go | 139 +- .../x/sys/unix/ztypes_darwin_arm64.go | 190 +- .../x/sys/unix/ztypes_dragonfly_amd64.go | 143 +- .../x/sys/unix/ztypes_freebsd_386.go | 32 + .../x/sys/unix/ztypes_freebsd_amd64.go | 32 + .../x/sys/unix/ztypes_freebsd_arm.go | 32 + .../golang.org/x/sys/unix/ztypes_linux_386.go | 439 ++- .../x/sys/unix/ztypes_linux_amd64.go | 475 ++- .../golang.org/x/sys/unix/ztypes_linux_arm.go | 481 ++- .../x/sys/unix/ztypes_linux_arm64.go | 475 ++- .../x/sys/unix/ztypes_linux_mips.go | 477 ++- .../x/sys/unix/ztypes_linux_mips64.go | 475 ++- .../x/sys/unix/ztypes_linux_mips64le.go | 475 ++- .../x/sys/unix/ztypes_linux_mipsle.go | 477 ++- .../x/sys/unix/ztypes_linux_ppc64.go | 475 ++- .../x/sys/unix/ztypes_linux_ppc64le.go | 475 ++- .../x/sys/unix/ztypes_linux_s390x.go | 405 ++- .../x/sys/unix/ztypes_linux_sparc64.go | 222 +- .../x/sys/unix/ztypes_netbsd_386.go | 56 +- .../x/sys/unix/ztypes_netbsd_amd64.go | 56 +- .../x/sys/unix/ztypes_netbsd_arm.go | 56 +- .../x/sys/unix/ztypes_openbsd_386.go | 47 +- .../x/sys/unix/ztypes_openbsd_amd64.go | 47 +- .../x/sys/unix/ztypes_openbsd_arm.go | 47 +- .../x/sys/unix/ztypes_solaris_amd64.go | 205 +- .../x/sys/windows/asm_windows_386.s | 13 + .../x/sys/windows/asm_windows_amd64.s | 13 + .../golang.org/x/sys/windows/dll_windows.go | 378 +++ .../golang.org/x/sys/windows/env_windows.go | 29 + vendor/golang.org/x/sys/windows/eventlog.go | 20 + .../golang.org/x/sys/windows/exec_windows.go | 97 + .../x/sys/windows/memory_windows.go | 26 + vendor/golang.org/x/sys/windows/mksyscall.go | 7 + vendor/golang.org/x/sys/windows/race.go | 30 + vendor/golang.org/x/sys/windows/race0.go | 25 + .../x/sys/windows/security_windows.go | 476 +++ vendor/golang.org/x/sys/windows/service.go | 164 + vendor/golang.org/x/sys/windows/str.go | 22 + vendor/golang.org/x/sys/windows/syscall.go | 74 + .../x/sys/windows/syscall_windows.go | 1153 +++++++ .../golang.org/x/sys/windows/types_windows.go | 1333 ++++++++ .../x/sys/windows/types_windows_386.go | 22 + .../x/sys/windows/types_windows_amd64.go | 22 + .../x/sys/windows/zsyscall_windows.go | 2687 +++++++++++++++++ vendor/vendor.json | 52 +- 261 files changed, 23114 insertions(+), 4715 deletions(-) create mode 100644 vendor/github.com/Azure/go-ansiterm/LICENSE create mode 100644 vendor/github.com/Azure/go-ansiterm/README.md create mode 100644 vendor/github.com/Azure/go-ansiterm/constants.go create mode 100644 vendor/github.com/Azure/go-ansiterm/context.go create mode 100644 vendor/github.com/Azure/go-ansiterm/csi_entry_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/csi_param_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/escape_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/event_handler.go create mode 100644 vendor/github.com/Azure/go-ansiterm/ground_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/osc_string_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/parser.go create mode 100644 vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go create mode 100644 vendor/github.com/Azure/go-ansiterm/parser_actions.go create mode 100644 vendor/github.com/Azure/go-ansiterm/states.go create mode 100644 vendor/github.com/Azure/go-ansiterm/utilities.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/ansi.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/api.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/utilities.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_notwindows.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_solaris.go delete mode 100644 vendor/github.com/Sirupsen/logrus/terminal_windows.go create mode 100644 vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go create mode 100644 vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go create mode 100644 vendor/github.com/docker/docker/pkg/term/windows/console.go create mode 100644 vendor/github.com/docker/docker/pkg/term/windows/windows.go create mode 100644 vendor/github.com/moul/gotty-client/Dockerfile create mode 100644 vendor/github.com/moul/gotty-client/LICENSE.apache delete mode 100644 vendor/github.com/moul/gotty-client/glide.lock delete mode 100644 vendor/github.com/moul/gotty-client/glide.yaml create mode 100644 vendor/github.com/moul/gotty-client/proxy.go create mode 100644 vendor/github.com/sirupsen/logrus/appveyor.yml create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go create mode 100644 vendor/golang.org/x/sys/unix/affinity_linux.go create mode 100644 vendor/golang.org/x/sys/unix/dev_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/dev_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/dev_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_netbsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/env_unset.go delete mode 100644 vendor/golang.org/x/sys/unix/file_unix.go delete mode 100644 vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/pagesize_unix.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_no_getwd.go create mode 100644 vendor/golang.org/x/sys/unix/timestruct.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace386_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptracearm_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptracemips_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptracemipsle_linux.go rename vendor/golang.org/x/sys/unix/{zsysctl_openbsd.go => zsysctl_openbsd_386.go} (100%) create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/windows/asm_windows_386.s create mode 100644 vendor/golang.org/x/sys/windows/asm_windows_amd64.s create mode 100644 vendor/golang.org/x/sys/windows/dll_windows.go create mode 100644 vendor/golang.org/x/sys/windows/env_windows.go create mode 100644 vendor/golang.org/x/sys/windows/eventlog.go create mode 100644 vendor/golang.org/x/sys/windows/exec_windows.go create mode 100644 vendor/golang.org/x/sys/windows/memory_windows.go create mode 100644 vendor/golang.org/x/sys/windows/mksyscall.go create mode 100644 vendor/golang.org/x/sys/windows/race.go create mode 100644 vendor/golang.org/x/sys/windows/race0.go create mode 100644 vendor/golang.org/x/sys/windows/security_windows.go create mode 100644 vendor/golang.org/x/sys/windows/service.go create mode 100644 vendor/golang.org/x/sys/windows/str.go create mode 100644 vendor/golang.org/x/sys/windows/syscall.go create mode 100644 vendor/golang.org/x/sys/windows/syscall_windows.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_386.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_amd64.go create mode 100644 vendor/golang.org/x/sys/windows/zsyscall_windows.go diff --git a/vendor/github.com/Azure/go-ansiterm/LICENSE b/vendor/github.com/Azure/go-ansiterm/LICENSE new file mode 100644 index 000000000..e3d9a64d1 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/Azure/go-ansiterm/README.md b/vendor/github.com/Azure/go-ansiterm/README.md new file mode 100644 index 000000000..261c041e7 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/README.md @@ -0,0 +1,12 @@ +# go-ansiterm + +This is a cross platform Ansi Terminal Emulation library. It reads a stream of Ansi characters and produces the appropriate function calls. The results of the function calls are platform dependent. + +For example the parser might receive "ESC, [, A" as a stream of three characters. This is the code for Cursor Up (http://www.vt100.net/docs/vt510-rm/CUU). The parser then calls the cursor up function (CUU()) on an event handler. The event handler determines what platform specific work must be done to cause the cursor to move up one position. + +The parser (parser.go) is a partial implementation of this state machine (http://vt100.net/emu/vt500_parser.png). There are also two event handler implementations, one for tests (test_event_handler.go) to validate that the expected events are being produced and called, the other is a Windows implementation (winterm/win_event_handler.go). + +See parser_test.go for examples exercising the state machine and generating appropriate function calls. + +----- +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/vendor/github.com/Azure/go-ansiterm/constants.go b/vendor/github.com/Azure/go-ansiterm/constants.go new file mode 100644 index 000000000..96504a33b --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/constants.go @@ -0,0 +1,188 @@ +package ansiterm + +const LogEnv = "DEBUG_TERMINAL" + +// ANSI constants +// References: +// -- http://www.ecma-international.org/publications/standards/Ecma-048.htm +// -- http://man7.org/linux/man-pages/man4/console_codes.4.html +// -- http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html +// -- http://en.wikipedia.org/wiki/ANSI_escape_code +// -- http://vt100.net/emu/dec_ansi_parser +// -- http://vt100.net/emu/vt500_parser.svg +// -- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html +// -- http://www.inwap.com/pdp10/ansicode.txt +const ( + // ECMA-48 Set Graphics Rendition + // Note: + // -- Constants leading with an underscore (e.g., _ANSI_xxx) are unsupported or reserved + // -- Fonts could possibly be supported via SetCurrentConsoleFontEx + // -- Windows does not expose the per-window cursor (i.e., caret) blink times + ANSI_SGR_RESET = 0 + ANSI_SGR_BOLD = 1 + ANSI_SGR_DIM = 2 + _ANSI_SGR_ITALIC = 3 + ANSI_SGR_UNDERLINE = 4 + _ANSI_SGR_BLINKSLOW = 5 + _ANSI_SGR_BLINKFAST = 6 + ANSI_SGR_REVERSE = 7 + _ANSI_SGR_INVISIBLE = 8 + _ANSI_SGR_LINETHROUGH = 9 + _ANSI_SGR_FONT_00 = 10 + _ANSI_SGR_FONT_01 = 11 + _ANSI_SGR_FONT_02 = 12 + _ANSI_SGR_FONT_03 = 13 + _ANSI_SGR_FONT_04 = 14 + _ANSI_SGR_FONT_05 = 15 + _ANSI_SGR_FONT_06 = 16 + _ANSI_SGR_FONT_07 = 17 + _ANSI_SGR_FONT_08 = 18 + _ANSI_SGR_FONT_09 = 19 + _ANSI_SGR_FONT_10 = 20 + _ANSI_SGR_DOUBLEUNDERLINE = 21 + ANSI_SGR_BOLD_DIM_OFF = 22 + _ANSI_SGR_ITALIC_OFF = 23 + ANSI_SGR_UNDERLINE_OFF = 24 + _ANSI_SGR_BLINK_OFF = 25 + _ANSI_SGR_RESERVED_00 = 26 + ANSI_SGR_REVERSE_OFF = 27 + _ANSI_SGR_INVISIBLE_OFF = 28 + _ANSI_SGR_LINETHROUGH_OFF = 29 + ANSI_SGR_FOREGROUND_BLACK = 30 + ANSI_SGR_FOREGROUND_RED = 31 + ANSI_SGR_FOREGROUND_GREEN = 32 + ANSI_SGR_FOREGROUND_YELLOW = 33 + ANSI_SGR_FOREGROUND_BLUE = 34 + ANSI_SGR_FOREGROUND_MAGENTA = 35 + ANSI_SGR_FOREGROUND_CYAN = 36 + ANSI_SGR_FOREGROUND_WHITE = 37 + _ANSI_SGR_RESERVED_01 = 38 + ANSI_SGR_FOREGROUND_DEFAULT = 39 + ANSI_SGR_BACKGROUND_BLACK = 40 + ANSI_SGR_BACKGROUND_RED = 41 + ANSI_SGR_BACKGROUND_GREEN = 42 + ANSI_SGR_BACKGROUND_YELLOW = 43 + ANSI_SGR_BACKGROUND_BLUE = 44 + ANSI_SGR_BACKGROUND_MAGENTA = 45 + ANSI_SGR_BACKGROUND_CYAN = 46 + ANSI_SGR_BACKGROUND_WHITE = 47 + _ANSI_SGR_RESERVED_02 = 48 + ANSI_SGR_BACKGROUND_DEFAULT = 49 + // 50 - 65: Unsupported + + ANSI_MAX_CMD_LENGTH = 4096 + + MAX_INPUT_EVENTS = 128 + DEFAULT_WIDTH = 80 + DEFAULT_HEIGHT = 24 + + ANSI_BEL = 0x07 + ANSI_BACKSPACE = 0x08 + ANSI_TAB = 0x09 + ANSI_LINE_FEED = 0x0A + ANSI_VERTICAL_TAB = 0x0B + ANSI_FORM_FEED = 0x0C + ANSI_CARRIAGE_RETURN = 0x0D + ANSI_ESCAPE_PRIMARY = 0x1B + ANSI_ESCAPE_SECONDARY = 0x5B + ANSI_OSC_STRING_ENTRY = 0x5D + ANSI_COMMAND_FIRST = 0x40 + ANSI_COMMAND_LAST = 0x7E + DCS_ENTRY = 0x90 + CSI_ENTRY = 0x9B + OSC_STRING = 0x9D + ANSI_PARAMETER_SEP = ";" + ANSI_CMD_G0 = '(' + ANSI_CMD_G1 = ')' + ANSI_CMD_G2 = '*' + ANSI_CMD_G3 = '+' + ANSI_CMD_DECPNM = '>' + ANSI_CMD_DECPAM = '=' + ANSI_CMD_OSC = ']' + ANSI_CMD_STR_TERM = '\\' + + KEY_CONTROL_PARAM_2 = ";2" + KEY_CONTROL_PARAM_3 = ";3" + KEY_CONTROL_PARAM_4 = ";4" + KEY_CONTROL_PARAM_5 = ";5" + KEY_CONTROL_PARAM_6 = ";6" + KEY_CONTROL_PARAM_7 = ";7" + KEY_CONTROL_PARAM_8 = ";8" + KEY_ESC_CSI = "\x1B[" + KEY_ESC_N = "\x1BN" + KEY_ESC_O = "\x1BO" + + FILL_CHARACTER = ' ' +) + +func getByteRange(start byte, end byte) []byte { + bytes := make([]byte, 0, 32) + for i := start; i <= end; i++ { + bytes = append(bytes, byte(i)) + } + + return bytes +} + +var toGroundBytes = getToGroundBytes() +var executors = getExecuteBytes() + +// SPACE 20+A0 hex Always and everywhere a blank space +// Intermediate 20-2F hex !"#$%&'()*+,-./ +var intermeds = getByteRange(0x20, 0x2F) + +// Parameters 30-3F hex 0123456789:;<=>? +// CSI Parameters 30-39, 3B hex 0123456789; +var csiParams = getByteRange(0x30, 0x3F) + +var csiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...) + +// Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +var upperCase = getByteRange(0x40, 0x5F) + +// Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~ +var lowerCase = getByteRange(0x60, 0x7E) + +// Alphabetics 40-7E hex (all of upper and lower case) +var alphabetics = append(upperCase, lowerCase...) + +var printables = getByteRange(0x20, 0x7F) + +var escapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E) +var escapeToGroundBytes = getEscapeToGroundBytes() + +// See http://www.vt100.net/emu/vt500_parser.png for description of the complex +// byte ranges below + +func getEscapeToGroundBytes() []byte { + escapeToGroundBytes := getByteRange(0x30, 0x4F) + escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x51, 0x57)...) + escapeToGroundBytes = append(escapeToGroundBytes, 0x59) + escapeToGroundBytes = append(escapeToGroundBytes, 0x5A) + escapeToGroundBytes = append(escapeToGroundBytes, 0x5C) + escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x60, 0x7E)...) + return escapeToGroundBytes +} + +func getExecuteBytes() []byte { + executeBytes := getByteRange(0x00, 0x17) + executeBytes = append(executeBytes, 0x19) + executeBytes = append(executeBytes, getByteRange(0x1C, 0x1F)...) + return executeBytes +} + +func getToGroundBytes() []byte { + groundBytes := []byte{0x18} + groundBytes = append(groundBytes, 0x1A) + groundBytes = append(groundBytes, getByteRange(0x80, 0x8F)...) + groundBytes = append(groundBytes, getByteRange(0x91, 0x97)...) + groundBytes = append(groundBytes, 0x99) + groundBytes = append(groundBytes, 0x9A) + groundBytes = append(groundBytes, 0x9C) + return groundBytes +} + +// Delete 7F hex Always and everywhere ignored +// C1 Control 80-9F hex 32 additional control characters +// G1 Displayable A1-FE hex 94 additional displayable characters +// Special A0+FF hex Same as SPACE and DELETE diff --git a/vendor/github.com/Azure/go-ansiterm/context.go b/vendor/github.com/Azure/go-ansiterm/context.go new file mode 100644 index 000000000..8d66e777c --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/context.go @@ -0,0 +1,7 @@ +package ansiterm + +type ansiContext struct { + currentChar byte + paramBuffer []byte + interBuffer []byte +} diff --git a/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go b/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go new file mode 100644 index 000000000..bcbe00d0c --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go @@ -0,0 +1,49 @@ +package ansiterm + +type csiEntryState struct { + baseState +} + +func (csiState csiEntryState) Handle(b byte) (s state, e error) { + csiState.parser.logf("CsiEntry::Handle %#x", b) + + nextState, err := csiState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(alphabetics, b): + return csiState.parser.ground, nil + case sliceContains(csiCollectables, b): + return csiState.parser.csiParam, nil + case sliceContains(executors, b): + return csiState, csiState.parser.execute() + } + + return csiState, nil +} + +func (csiState csiEntryState) Transition(s state) error { + csiState.parser.logf("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name()) + csiState.baseState.Transition(s) + + switch s { + case csiState.parser.ground: + return csiState.parser.csiDispatch() + case csiState.parser.csiParam: + switch { + case sliceContains(csiParams, csiState.parser.context.currentChar): + csiState.parser.collectParam() + case sliceContains(intermeds, csiState.parser.context.currentChar): + csiState.parser.collectInter() + } + } + + return nil +} + +func (csiState csiEntryState) Enter() error { + csiState.parser.clear() + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/csi_param_state.go b/vendor/github.com/Azure/go-ansiterm/csi_param_state.go new file mode 100644 index 000000000..7ed5e01c3 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/csi_param_state.go @@ -0,0 +1,38 @@ +package ansiterm + +type csiParamState struct { + baseState +} + +func (csiState csiParamState) Handle(b byte) (s state, e error) { + csiState.parser.logf("CsiParam::Handle %#x", b) + + nextState, err := csiState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(alphabetics, b): + return csiState.parser.ground, nil + case sliceContains(csiCollectables, b): + csiState.parser.collectParam() + return csiState, nil + case sliceContains(executors, b): + return csiState, csiState.parser.execute() + } + + return csiState, nil +} + +func (csiState csiParamState) Transition(s state) error { + csiState.parser.logf("CsiParam::Transition %s --> %s", csiState.Name(), s.Name()) + csiState.baseState.Transition(s) + + switch s { + case csiState.parser.ground: + return csiState.parser.csiDispatch() + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go b/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go new file mode 100644 index 000000000..1c719db9e --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go @@ -0,0 +1,36 @@ +package ansiterm + +type escapeIntermediateState struct { + baseState +} + +func (escState escapeIntermediateState) Handle(b byte) (s state, e error) { + escState.parser.logf("escapeIntermediateState::Handle %#x", b) + nextState, err := escState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(intermeds, b): + return escState, escState.parser.collectInter() + case sliceContains(executors, b): + return escState, escState.parser.execute() + case sliceContains(escapeIntermediateToGroundBytes, b): + return escState.parser.ground, nil + } + + return escState, nil +} + +func (escState escapeIntermediateState) Transition(s state) error { + escState.parser.logf("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name()) + escState.baseState.Transition(s) + + switch s { + case escState.parser.ground: + return escState.parser.escDispatch() + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/escape_state.go b/vendor/github.com/Azure/go-ansiterm/escape_state.go new file mode 100644 index 000000000..6390abd23 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/escape_state.go @@ -0,0 +1,47 @@ +package ansiterm + +type escapeState struct { + baseState +} + +func (escState escapeState) Handle(b byte) (s state, e error) { + escState.parser.logf("escapeState::Handle %#x", b) + nextState, err := escState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case b == ANSI_ESCAPE_SECONDARY: + return escState.parser.csiEntry, nil + case b == ANSI_OSC_STRING_ENTRY: + return escState.parser.oscString, nil + case sliceContains(executors, b): + return escState, escState.parser.execute() + case sliceContains(escapeToGroundBytes, b): + return escState.parser.ground, nil + case sliceContains(intermeds, b): + return escState.parser.escapeIntermediate, nil + } + + return escState, nil +} + +func (escState escapeState) Transition(s state) error { + escState.parser.logf("Escape::Transition %s --> %s", escState.Name(), s.Name()) + escState.baseState.Transition(s) + + switch s { + case escState.parser.ground: + return escState.parser.escDispatch() + case escState.parser.escapeIntermediate: + return escState.parser.collectInter() + } + + return nil +} + +func (escState escapeState) Enter() error { + escState.parser.clear() + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/event_handler.go b/vendor/github.com/Azure/go-ansiterm/event_handler.go new file mode 100644 index 000000000..98087b38c --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/event_handler.go @@ -0,0 +1,90 @@ +package ansiterm + +type AnsiEventHandler interface { + // Print + Print(b byte) error + + // Execute C0 commands + Execute(b byte) error + + // CUrsor Up + CUU(int) error + + // CUrsor Down + CUD(int) error + + // CUrsor Forward + CUF(int) error + + // CUrsor Backward + CUB(int) error + + // Cursor to Next Line + CNL(int) error + + // Cursor to Previous Line + CPL(int) error + + // Cursor Horizontal position Absolute + CHA(int) error + + // Vertical line Position Absolute + VPA(int) error + + // CUrsor Position + CUP(int, int) error + + // Horizontal and Vertical Position (depends on PUM) + HVP(int, int) error + + // Text Cursor Enable Mode + DECTCEM(bool) error + + // Origin Mode + DECOM(bool) error + + // 132 Column Mode + DECCOLM(bool) error + + // Erase in Display + ED(int) error + + // Erase in Line + EL(int) error + + // Insert Line + IL(int) error + + // Delete Line + DL(int) error + + // Insert Character + ICH(int) error + + // Delete Character + DCH(int) error + + // Set Graphics Rendition + SGR([]int) error + + // Pan Down + SU(int) error + + // Pan Up + SD(int) error + + // Device Attributes + DA([]string) error + + // Set Top and Bottom Margins + DECSTBM(int, int) error + + // Index + IND() error + + // Reverse Index + RI() error + + // Flush updates from previous commands + Flush() error +} diff --git a/vendor/github.com/Azure/go-ansiterm/ground_state.go b/vendor/github.com/Azure/go-ansiterm/ground_state.go new file mode 100644 index 000000000..52451e946 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/ground_state.go @@ -0,0 +1,24 @@ +package ansiterm + +type groundState struct { + baseState +} + +func (gs groundState) Handle(b byte) (s state, e error) { + gs.parser.context.currentChar = b + + nextState, err := gs.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(printables, b): + return gs, gs.parser.print() + + case sliceContains(executors, b): + return gs, gs.parser.execute() + } + + return gs, nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/osc_string_state.go b/vendor/github.com/Azure/go-ansiterm/osc_string_state.go new file mode 100644 index 000000000..593b10ab6 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/osc_string_state.go @@ -0,0 +1,31 @@ +package ansiterm + +type oscStringState struct { + baseState +} + +func (oscState oscStringState) Handle(b byte) (s state, e error) { + oscState.parser.logf("OscString::Handle %#x", b) + nextState, err := oscState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case isOscStringTerminator(b): + return oscState.parser.ground, nil + } + + return oscState, nil +} + +// See below for OSC string terminators for linux +// http://man7.org/linux/man-pages/man4/console_codes.4.html +func isOscStringTerminator(b byte) bool { + + if b == ANSI_BEL || b == 0x5C { + return true + } + + return false +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser.go b/vendor/github.com/Azure/go-ansiterm/parser.go new file mode 100644 index 000000000..03cec7ada --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser.go @@ -0,0 +1,151 @@ +package ansiterm + +import ( + "errors" + "log" + "os" +) + +type AnsiParser struct { + currState state + eventHandler AnsiEventHandler + context *ansiContext + csiEntry state + csiParam state + dcsEntry state + escape state + escapeIntermediate state + error state + ground state + oscString state + stateMap []state + + logf func(string, ...interface{}) +} + +type Option func(*AnsiParser) + +func WithLogf(f func(string, ...interface{})) Option { + return func(ap *AnsiParser) { + ap.logf = f + } +} + +func CreateParser(initialState string, evtHandler AnsiEventHandler, opts ...Option) *AnsiParser { + ap := &AnsiParser{ + eventHandler: evtHandler, + context: &ansiContext{}, + } + for _, o := range opts { + o(ap) + } + + if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" { + logFile, _ := os.Create("ansiParser.log") + logger := log.New(logFile, "", log.LstdFlags) + if ap.logf != nil { + l := ap.logf + ap.logf = func(s string, v ...interface{}) { + l(s, v...) + logger.Printf(s, v...) + } + } else { + ap.logf = logger.Printf + } + } + + if ap.logf == nil { + ap.logf = func(string, ...interface{}) {} + } + + ap.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: ap}} + ap.csiParam = csiParamState{baseState{name: "CsiParam", parser: ap}} + ap.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: ap}} + ap.escape = escapeState{baseState{name: "Escape", parser: ap}} + ap.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: ap}} + ap.error = errorState{baseState{name: "Error", parser: ap}} + ap.ground = groundState{baseState{name: "Ground", parser: ap}} + ap.oscString = oscStringState{baseState{name: "OscString", parser: ap}} + + ap.stateMap = []state{ + ap.csiEntry, + ap.csiParam, + ap.dcsEntry, + ap.escape, + ap.escapeIntermediate, + ap.error, + ap.ground, + ap.oscString, + } + + ap.currState = getState(initialState, ap.stateMap) + + ap.logf("CreateParser: parser %p", ap) + return ap +} + +func getState(name string, states []state) state { + for _, el := range states { + if el.Name() == name { + return el + } + } + + return nil +} + +func (ap *AnsiParser) Parse(bytes []byte) (int, error) { + for i, b := range bytes { + if err := ap.handle(b); err != nil { + return i, err + } + } + + return len(bytes), ap.eventHandler.Flush() +} + +func (ap *AnsiParser) handle(b byte) error { + ap.context.currentChar = b + newState, err := ap.currState.Handle(b) + if err != nil { + return err + } + + if newState == nil { + ap.logf("WARNING: newState is nil") + return errors.New("New state of 'nil' is invalid.") + } + + if newState != ap.currState { + if err := ap.changeState(newState); err != nil { + return err + } + } + + return nil +} + +func (ap *AnsiParser) changeState(newState state) error { + ap.logf("ChangeState %s --> %s", ap.currState.Name(), newState.Name()) + + // Exit old state + if err := ap.currState.Exit(); err != nil { + ap.logf("Exit state '%s' failed with : '%v'", ap.currState.Name(), err) + return err + } + + // Perform transition action + if err := ap.currState.Transition(newState); err != nil { + ap.logf("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err) + return err + } + + // Enter new state + if err := newState.Enter(); err != nil { + ap.logf("Enter state '%s' failed with: '%v'", newState.Name(), err) + return err + } + + ap.currState = newState + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go b/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go new file mode 100644 index 000000000..de0a1f9cd --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go @@ -0,0 +1,99 @@ +package ansiterm + +import ( + "strconv" +) + +func parseParams(bytes []byte) ([]string, error) { + paramBuff := make([]byte, 0, 0) + params := []string{} + + for _, v := range bytes { + if v == ';' { + if len(paramBuff) > 0 { + // Completed parameter, append it to the list + s := string(paramBuff) + params = append(params, s) + paramBuff = make([]byte, 0, 0) + } + } else { + paramBuff = append(paramBuff, v) + } + } + + // Last parameter may not be terminated with ';' + if len(paramBuff) > 0 { + s := string(paramBuff) + params = append(params, s) + } + + return params, nil +} + +func parseCmd(context ansiContext) (string, error) { + return string(context.currentChar), nil +} + +func getInt(params []string, dflt int) int { + i := getInts(params, 1, dflt)[0] + return i +} + +func getInts(params []string, minCount int, dflt int) []int { + ints := []int{} + + for _, v := range params { + i, _ := strconv.Atoi(v) + // Zero is mapped to the default value in VT100. + if i == 0 { + i = dflt + } + ints = append(ints, i) + } + + if len(ints) < minCount { + remaining := minCount - len(ints) + for i := 0; i < remaining; i++ { + ints = append(ints, dflt) + } + } + + return ints +} + +func (ap *AnsiParser) modeDispatch(param string, set bool) error { + switch param { + case "?3": + return ap.eventHandler.DECCOLM(set) + case "?6": + return ap.eventHandler.DECOM(set) + case "?25": + return ap.eventHandler.DECTCEM(set) + } + return nil +} + +func (ap *AnsiParser) hDispatch(params []string) error { + if len(params) == 1 { + return ap.modeDispatch(params[0], true) + } + + return nil +} + +func (ap *AnsiParser) lDispatch(params []string) error { + if len(params) == 1 { + return ap.modeDispatch(params[0], false) + } + + return nil +} + +func getEraseParam(params []string) int { + param := getInt(params, 0) + if param < 0 || 3 < param { + param = 0 + } + + return param +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser_actions.go b/vendor/github.com/Azure/go-ansiterm/parser_actions.go new file mode 100644 index 000000000..0bb5e51e9 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser_actions.go @@ -0,0 +1,119 @@ +package ansiterm + +func (ap *AnsiParser) collectParam() error { + currChar := ap.context.currentChar + ap.logf("collectParam %#x", currChar) + ap.context.paramBuffer = append(ap.context.paramBuffer, currChar) + return nil +} + +func (ap *AnsiParser) collectInter() error { + currChar := ap.context.currentChar + ap.logf("collectInter %#x", currChar) + ap.context.paramBuffer = append(ap.context.interBuffer, currChar) + return nil +} + +func (ap *AnsiParser) escDispatch() error { + cmd, _ := parseCmd(*ap.context) + intermeds := ap.context.interBuffer + ap.logf("escDispatch currentChar: %#x", ap.context.currentChar) + ap.logf("escDispatch: %v(%v)", cmd, intermeds) + + switch cmd { + case "D": // IND + return ap.eventHandler.IND() + case "E": // NEL, equivalent to CRLF + err := ap.eventHandler.Execute(ANSI_CARRIAGE_RETURN) + if err == nil { + err = ap.eventHandler.Execute(ANSI_LINE_FEED) + } + return err + case "M": // RI + return ap.eventHandler.RI() + } + + return nil +} + +func (ap *AnsiParser) csiDispatch() error { + cmd, _ := parseCmd(*ap.context) + params, _ := parseParams(ap.context.paramBuffer) + ap.logf("Parsed params: %v with length: %d", params, len(params)) + + ap.logf("csiDispatch: %v(%v)", cmd, params) + + switch cmd { + case "@": + return ap.eventHandler.ICH(getInt(params, 1)) + case "A": + return ap.eventHandler.CUU(getInt(params, 1)) + case "B": + return ap.eventHandler.CUD(getInt(params, 1)) + case "C": + return ap.eventHandler.CUF(getInt(params, 1)) + case "D": + return ap.eventHandler.CUB(getInt(params, 1)) + case "E": + return ap.eventHandler.CNL(getInt(params, 1)) + case "F": + return ap.eventHandler.CPL(getInt(params, 1)) + case "G": + return ap.eventHandler.CHA(getInt(params, 1)) + case "H": + ints := getInts(params, 2, 1) + x, y := ints[0], ints[1] + return ap.eventHandler.CUP(x, y) + case "J": + param := getEraseParam(params) + return ap.eventHandler.ED(param) + case "K": + param := getEraseParam(params) + return ap.eventHandler.EL(param) + case "L": + return ap.eventHandler.IL(getInt(params, 1)) + case "M": + return ap.eventHandler.DL(getInt(params, 1)) + case "P": + return ap.eventHandler.DCH(getInt(params, 1)) + case "S": + return ap.eventHandler.SU(getInt(params, 1)) + case "T": + return ap.eventHandler.SD(getInt(params, 1)) + case "c": + return ap.eventHandler.DA(params) + case "d": + return ap.eventHandler.VPA(getInt(params, 1)) + case "f": + ints := getInts(params, 2, 1) + x, y := ints[0], ints[1] + return ap.eventHandler.HVP(x, y) + case "h": + return ap.hDispatch(params) + case "l": + return ap.lDispatch(params) + case "m": + return ap.eventHandler.SGR(getInts(params, 1, 0)) + case "r": + ints := getInts(params, 2, 1) + top, bottom := ints[0], ints[1] + return ap.eventHandler.DECSTBM(top, bottom) + default: + ap.logf("ERROR: Unsupported CSI command: '%s', with full context: %v", cmd, ap.context) + return nil + } + +} + +func (ap *AnsiParser) print() error { + return ap.eventHandler.Print(ap.context.currentChar) +} + +func (ap *AnsiParser) clear() error { + ap.context = &ansiContext{} + return nil +} + +func (ap *AnsiParser) execute() error { + return ap.eventHandler.Execute(ap.context.currentChar) +} diff --git a/vendor/github.com/Azure/go-ansiterm/states.go b/vendor/github.com/Azure/go-ansiterm/states.go new file mode 100644 index 000000000..f2ea1fcd1 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/states.go @@ -0,0 +1,71 @@ +package ansiterm + +type stateID int + +type state interface { + Enter() error + Exit() error + Handle(byte) (state, error) + Name() string + Transition(state) error +} + +type baseState struct { + name string + parser *AnsiParser +} + +func (base baseState) Enter() error { + return nil +} + +func (base baseState) Exit() error { + return nil +} + +func (base baseState) Handle(b byte) (s state, e error) { + + switch { + case b == CSI_ENTRY: + return base.parser.csiEntry, nil + case b == DCS_ENTRY: + return base.parser.dcsEntry, nil + case b == ANSI_ESCAPE_PRIMARY: + return base.parser.escape, nil + case b == OSC_STRING: + return base.parser.oscString, nil + case sliceContains(toGroundBytes, b): + return base.parser.ground, nil + } + + return nil, nil +} + +func (base baseState) Name() string { + return base.name +} + +func (base baseState) Transition(s state) error { + if s == base.parser.ground { + execBytes := []byte{0x18} + execBytes = append(execBytes, 0x1A) + execBytes = append(execBytes, getByteRange(0x80, 0x8F)...) + execBytes = append(execBytes, getByteRange(0x91, 0x97)...) + execBytes = append(execBytes, 0x99) + execBytes = append(execBytes, 0x9A) + + if sliceContains(execBytes, base.parser.context.currentChar) { + return base.parser.execute() + } + } + + return nil +} + +type dcsEntryState struct { + baseState +} + +type errorState struct { + baseState +} diff --git a/vendor/github.com/Azure/go-ansiterm/utilities.go b/vendor/github.com/Azure/go-ansiterm/utilities.go new file mode 100644 index 000000000..392114493 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/utilities.go @@ -0,0 +1,21 @@ +package ansiterm + +import ( + "strconv" +) + +func sliceContains(bytes []byte, b byte) bool { + for _, v := range bytes { + if v == b { + return true + } + } + + return false +} + +func convertBytesToInteger(bytes []byte) int { + s := string(bytes) + i, _ := strconv.Atoi(s) + return i +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go b/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go new file mode 100644 index 000000000..a67327972 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go @@ -0,0 +1,182 @@ +// +build windows + +package winterm + +import ( + "fmt" + "os" + "strconv" + "strings" + "syscall" + + "github.com/Azure/go-ansiterm" +) + +// Windows keyboard constants +// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx. +const ( + VK_PRIOR = 0x21 // PAGE UP key + VK_NEXT = 0x22 // PAGE DOWN key + VK_END = 0x23 // END key + VK_HOME = 0x24 // HOME key + VK_LEFT = 0x25 // LEFT ARROW key + VK_UP = 0x26 // UP ARROW key + VK_RIGHT = 0x27 // RIGHT ARROW key + VK_DOWN = 0x28 // DOWN ARROW key + VK_SELECT = 0x29 // SELECT key + VK_PRINT = 0x2A // PRINT key + VK_EXECUTE = 0x2B // EXECUTE key + VK_SNAPSHOT = 0x2C // PRINT SCREEN key + VK_INSERT = 0x2D // INS key + VK_DELETE = 0x2E // DEL key + VK_HELP = 0x2F // HELP key + VK_F1 = 0x70 // F1 key + VK_F2 = 0x71 // F2 key + VK_F3 = 0x72 // F3 key + VK_F4 = 0x73 // F4 key + VK_F5 = 0x74 // F5 key + VK_F6 = 0x75 // F6 key + VK_F7 = 0x76 // F7 key + VK_F8 = 0x77 // F8 key + VK_F9 = 0x78 // F9 key + VK_F10 = 0x79 // F10 key + VK_F11 = 0x7A // F11 key + VK_F12 = 0x7B // F12 key + + RIGHT_ALT_PRESSED = 0x0001 + LEFT_ALT_PRESSED = 0x0002 + RIGHT_CTRL_PRESSED = 0x0004 + LEFT_CTRL_PRESSED = 0x0008 + SHIFT_PRESSED = 0x0010 + NUMLOCK_ON = 0x0020 + SCROLLLOCK_ON = 0x0040 + CAPSLOCK_ON = 0x0080 + ENHANCED_KEY = 0x0100 +) + +type ansiCommand struct { + CommandBytes []byte + Command string + Parameters []string + IsSpecial bool +} + +func newAnsiCommand(command []byte) *ansiCommand { + + if isCharacterSelectionCmdChar(command[1]) { + // Is Character Set Selection commands + return &ansiCommand{ + CommandBytes: command, + Command: string(command), + IsSpecial: true, + } + } + + // last char is command character + lastCharIndex := len(command) - 1 + + ac := &ansiCommand{ + CommandBytes: command, + Command: string(command[lastCharIndex]), + IsSpecial: false, + } + + // more than a single escape + if lastCharIndex != 0 { + start := 1 + // skip if double char escape sequence + if command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY { + start++ + } + // convert this to GetNextParam method + ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP) + } + + return ac +} + +func (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 { + if index < 0 || index >= len(ac.Parameters) { + return defaultValue + } + + param, err := strconv.ParseInt(ac.Parameters[index], 10, 16) + if err != nil { + return defaultValue + } + + return int16(param) +} + +func (ac *ansiCommand) String() string { + return fmt.Sprintf("0x%v \"%v\" (\"%v\")", + bytesToHex(ac.CommandBytes), + ac.Command, + strings.Join(ac.Parameters, "\",\"")) +} + +// isAnsiCommandChar returns true if the passed byte falls within the range of ANSI commands. +// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html. +func isAnsiCommandChar(b byte) bool { + switch { + case ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY: + return true + case b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_OSC || b == ansiterm.ANSI_CMD_DECPAM || b == ansiterm.ANSI_CMD_DECPNM: + // non-CSI escape sequence terminator + return true + case b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL: + // String escape sequence terminator + return true + } + return false +} + +func isXtermOscSequence(command []byte, current byte) bool { + return (len(command) >= 2 && command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_CMD_OSC && current != ansiterm.ANSI_BEL) +} + +func isCharacterSelectionCmdChar(b byte) bool { + return (b == ansiterm.ANSI_CMD_G0 || b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_G2 || b == ansiterm.ANSI_CMD_G3) +} + +// bytesToHex converts a slice of bytes to a human-readable string. +func bytesToHex(b []byte) string { + hex := make([]string, len(b)) + for i, ch := range b { + hex[i] = fmt.Sprintf("%X", ch) + } + return strings.Join(hex, "") +} + +// ensureInRange adjusts the passed value, if necessary, to ensure it is within +// the passed min / max range. +func ensureInRange(n int16, min int16, max int16) int16 { + if n < min { + return min + } else if n > max { + return max + } else { + return n + } +} + +func GetStdFile(nFile int) (*os.File, uintptr) { + var file *os.File + switch nFile { + case syscall.STD_INPUT_HANDLE: + file = os.Stdin + case syscall.STD_OUTPUT_HANDLE: + file = os.Stdout + case syscall.STD_ERROR_HANDLE: + file = os.Stderr + default: + panic(fmt.Errorf("Invalid standard handle identifier: %v", nFile)) + } + + fd, err := syscall.GetStdHandle(nFile) + if err != nil { + panic(fmt.Errorf("Invalid standard handle identifier: %v -- %v", nFile, err)) + } + + return file, uintptr(fd) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/api.go b/vendor/github.com/Azure/go-ansiterm/winterm/api.go new file mode 100644 index 000000000..6055e33b9 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/api.go @@ -0,0 +1,327 @@ +// +build windows + +package winterm + +import ( + "fmt" + "syscall" + "unsafe" +) + +//=========================================================================================================== +// IMPORTANT NOTE: +// +// The methods below make extensive use of the "unsafe" package to obtain the required pointers. +// Beginning in Go 1.3, the garbage collector may release local variables (e.g., incoming arguments, stack +// variables) the pointers reference *before* the API completes. +// +// As a result, in those cases, the code must hint that the variables remain in active by invoking the +// dummy method "use" (see below). Newer versions of Go are planned to change the mechanism to no longer +// require unsafe pointers. +// +// If you add or modify methods, ENSURE protection of local variables through the "use" builtin to inform +// the garbage collector the variables remain in use if: +// +// -- The value is not a pointer (e.g., int32, struct) +// -- The value is not referenced by the method after passing the pointer to Windows +// +// See http://golang.org/doc/go1.3. +//=========================================================================================================== + +var ( + kernel32DLL = syscall.NewLazyDLL("kernel32.dll") + + getConsoleCursorInfoProc = kernel32DLL.NewProc("GetConsoleCursorInfo") + setConsoleCursorInfoProc = kernel32DLL.NewProc("SetConsoleCursorInfo") + setConsoleCursorPositionProc = kernel32DLL.NewProc("SetConsoleCursorPosition") + setConsoleModeProc = kernel32DLL.NewProc("SetConsoleMode") + getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") + setConsoleScreenBufferSizeProc = kernel32DLL.NewProc("SetConsoleScreenBufferSize") + scrollConsoleScreenBufferProc = kernel32DLL.NewProc("ScrollConsoleScreenBufferA") + setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute") + setConsoleWindowInfoProc = kernel32DLL.NewProc("SetConsoleWindowInfo") + writeConsoleOutputProc = kernel32DLL.NewProc("WriteConsoleOutputW") + readConsoleInputProc = kernel32DLL.NewProc("ReadConsoleInputW") + waitForSingleObjectProc = kernel32DLL.NewProc("WaitForSingleObject") +) + +// Windows Console constants +const ( + // Console modes + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. + ENABLE_PROCESSED_INPUT = 0x0001 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_WINDOW_INPUT = 0x0008 + ENABLE_MOUSE_INPUT = 0x0010 + ENABLE_INSERT_MODE = 0x0020 + ENABLE_QUICK_EDIT_MODE = 0x0040 + ENABLE_EXTENDED_FLAGS = 0x0080 + ENABLE_AUTO_POSITION = 0x0100 + ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200 + + ENABLE_PROCESSED_OUTPUT = 0x0001 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + DISABLE_NEWLINE_AUTO_RETURN = 0x0008 + ENABLE_LVB_GRID_WORLDWIDE = 0x0010 + + // Character attributes + // Note: + // -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan). + // Clearing all foreground or background colors results in black; setting all creates white. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes. + FOREGROUND_BLUE uint16 = 0x0001 + FOREGROUND_GREEN uint16 = 0x0002 + FOREGROUND_RED uint16 = 0x0004 + FOREGROUND_INTENSITY uint16 = 0x0008 + FOREGROUND_MASK uint16 = 0x000F + + BACKGROUND_BLUE uint16 = 0x0010 + BACKGROUND_GREEN uint16 = 0x0020 + BACKGROUND_RED uint16 = 0x0040 + BACKGROUND_INTENSITY uint16 = 0x0080 + BACKGROUND_MASK uint16 = 0x00F0 + + COMMON_LVB_MASK uint16 = 0xFF00 + COMMON_LVB_REVERSE_VIDEO uint16 = 0x4000 + COMMON_LVB_UNDERSCORE uint16 = 0x8000 + + // Input event types + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. + KEY_EVENT = 0x0001 + MOUSE_EVENT = 0x0002 + WINDOW_BUFFER_SIZE_EVENT = 0x0004 + MENU_EVENT = 0x0008 + FOCUS_EVENT = 0x0010 + + // WaitForSingleObject return codes + WAIT_ABANDONED = 0x00000080 + WAIT_FAILED = 0xFFFFFFFF + WAIT_SIGNALED = 0x0000000 + WAIT_TIMEOUT = 0x00000102 + + // WaitForSingleObject wait duration + WAIT_INFINITE = 0xFFFFFFFF + WAIT_ONE_SECOND = 1000 + WAIT_HALF_SECOND = 500 + WAIT_QUARTER_SECOND = 250 +) + +// Windows API Console types +// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD) +// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment +type ( + CHAR_INFO struct { + UnicodeChar uint16 + Attributes uint16 + } + + CONSOLE_CURSOR_INFO struct { + Size uint32 + Visible int32 + } + + CONSOLE_SCREEN_BUFFER_INFO struct { + Size COORD + CursorPosition COORD + Attributes uint16 + Window SMALL_RECT + MaximumWindowSize COORD + } + + COORD struct { + X int16 + Y int16 + } + + SMALL_RECT struct { + Left int16 + Top int16 + Right int16 + Bottom int16 + } + + // INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. + INPUT_RECORD struct { + EventType uint16 + KeyEvent KEY_EVENT_RECORD + } + + KEY_EVENT_RECORD struct { + KeyDown int32 + RepeatCount uint16 + VirtualKeyCode uint16 + VirtualScanCode uint16 + UnicodeChar uint16 + ControlKeyState uint32 + } + + WINDOW_BUFFER_SIZE struct { + Size COORD + } +) + +// boolToBOOL converts a Go bool into a Windows int32. +func boolToBOOL(f bool) int32 { + if f { + return int32(1) + } else { + return int32(0) + } +} + +// GetConsoleCursorInfo retrieves information about the size and visiblity of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683163(v=vs.85).aspx. +func GetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error { + r1, r2, err := getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0) + return checkError(r1, r2, err) +} + +// SetConsoleCursorInfo sets the size and visiblity of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx. +func SetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error { + r1, r2, err := setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0) + return checkError(r1, r2, err) +} + +// SetConsoleCursorPosition location of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx. +func SetConsoleCursorPosition(handle uintptr, coord COORD) error { + r1, r2, err := setConsoleCursorPositionProc.Call(handle, coordToPointer(coord)) + use(coord) + return checkError(r1, r2, err) +} + +// GetConsoleMode gets the console mode for given file descriptor +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx. +func GetConsoleMode(handle uintptr) (mode uint32, err error) { + err = syscall.GetConsoleMode(syscall.Handle(handle), &mode) + return mode, err +} + +// SetConsoleMode sets the console mode for given file descriptor +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. +func SetConsoleMode(handle uintptr, mode uint32) error { + r1, r2, err := setConsoleModeProc.Call(handle, uintptr(mode), 0) + use(mode) + return checkError(r1, r2, err) +} + +// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer. +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx. +func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) { + info := CONSOLE_SCREEN_BUFFER_INFO{} + err := checkError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)) + if err != nil { + return nil, err + } + return &info, nil +} + +func ScrollConsoleScreenBuffer(handle uintptr, scrollRect SMALL_RECT, clipRect SMALL_RECT, destOrigin COORD, char CHAR_INFO) error { + r1, r2, err := scrollConsoleScreenBufferProc.Call(handle, uintptr(unsafe.Pointer(&scrollRect)), uintptr(unsafe.Pointer(&clipRect)), coordToPointer(destOrigin), uintptr(unsafe.Pointer(&char))) + use(scrollRect) + use(clipRect) + use(destOrigin) + use(char) + return checkError(r1, r2, err) +} + +// SetConsoleScreenBufferSize sets the size of the console screen buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686044(v=vs.85).aspx. +func SetConsoleScreenBufferSize(handle uintptr, coord COORD) error { + r1, r2, err := setConsoleScreenBufferSizeProc.Call(handle, coordToPointer(coord)) + use(coord) + return checkError(r1, r2, err) +} + +// SetConsoleTextAttribute sets the attributes of characters written to the +// console screen buffer by the WriteFile or WriteConsole function. +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx. +func SetConsoleTextAttribute(handle uintptr, attribute uint16) error { + r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0) + use(attribute) + return checkError(r1, r2, err) +} + +// SetConsoleWindowInfo sets the size and position of the console screen buffer's window. +// Note that the size and location must be within and no larger than the backing console screen buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx. +func SetConsoleWindowInfo(handle uintptr, isAbsolute bool, rect SMALL_RECT) error { + r1, r2, err := setConsoleWindowInfoProc.Call(handle, uintptr(boolToBOOL(isAbsolute)), uintptr(unsafe.Pointer(&rect))) + use(isAbsolute) + use(rect) + return checkError(r1, r2, err) +} + +// WriteConsoleOutput writes the CHAR_INFOs from the provided buffer to the active console buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687404(v=vs.85).aspx. +func WriteConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) error { + r1, r2, err := writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), coordToPointer(bufferSize), coordToPointer(bufferCoord), uintptr(unsafe.Pointer(writeRegion))) + use(buffer) + use(bufferSize) + use(bufferCoord) + return checkError(r1, r2, err) +} + +// ReadConsoleInput reads (and removes) data from the console input buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx. +func ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) error { + r1, r2, err := readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), uintptr(len(buffer)), uintptr(unsafe.Pointer(count))) + use(buffer) + return checkError(r1, r2, err) +} + +// WaitForSingleObject waits for the passed handle to be signaled. +// It returns true if the handle was signaled; false otherwise. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx. +func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) { + r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait))) + switch r1 { + case WAIT_ABANDONED, WAIT_TIMEOUT: + return false, nil + case WAIT_SIGNALED: + return true, nil + } + use(msWait) + return false, err +} + +// String helpers +func (info CONSOLE_SCREEN_BUFFER_INFO) String() string { + return fmt.Sprintf("Size(%v) Cursor(%v) Window(%v) Max(%v)", info.Size, info.CursorPosition, info.Window, info.MaximumWindowSize) +} + +func (coord COORD) String() string { + return fmt.Sprintf("%v,%v", coord.X, coord.Y) +} + +func (rect SMALL_RECT) String() string { + return fmt.Sprintf("(%v,%v),(%v,%v)", rect.Left, rect.Top, rect.Right, rect.Bottom) +} + +// checkError evaluates the results of a Windows API call and returns the error if it failed. +func checkError(r1, r2 uintptr, err error) error { + // Windows APIs return non-zero to indicate success + if r1 != 0 { + return nil + } + + // Return the error if provided, otherwise default to EINVAL + if err != nil { + return err + } + return syscall.EINVAL +} + +// coordToPointer converts a COORD into a uintptr (by fooling the type system). +func coordToPointer(c COORD) uintptr { + // Note: This code assumes the two SHORTs are correctly laid out; the "cast" to uint32 is just to get a pointer to pass. + return uintptr(*((*uint32)(unsafe.Pointer(&c)))) +} + +// use is a no-op, but the compiler cannot see that it is. +// Calling use(p) ensures that p is kept live until that point. +func use(p interface{}) {} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go b/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go new file mode 100644 index 000000000..cbec8f728 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go @@ -0,0 +1,100 @@ +// +build windows + +package winterm + +import "github.com/Azure/go-ansiterm" + +const ( + FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + BACKGROUND_COLOR_MASK = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE +) + +// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the +// request represented by the passed ANSI mode. +func collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) { + switch ansiMode { + + // Mode styles + case ansiterm.ANSI_SGR_BOLD: + windowsMode = windowsMode | FOREGROUND_INTENSITY + + case ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF: + windowsMode &^= FOREGROUND_INTENSITY + + case ansiterm.ANSI_SGR_UNDERLINE: + windowsMode = windowsMode | COMMON_LVB_UNDERSCORE + + case ansiterm.ANSI_SGR_REVERSE: + inverted = true + + case ansiterm.ANSI_SGR_REVERSE_OFF: + inverted = false + + case ansiterm.ANSI_SGR_UNDERLINE_OFF: + windowsMode &^= COMMON_LVB_UNDERSCORE + + // Foreground colors + case ansiterm.ANSI_SGR_FOREGROUND_DEFAULT: + windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK) + + case ansiterm.ANSI_SGR_FOREGROUND_BLACK: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) + + case ansiterm.ANSI_SGR_FOREGROUND_RED: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED + + case ansiterm.ANSI_SGR_FOREGROUND_GREEN: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN + + case ansiterm.ANSI_SGR_FOREGROUND_YELLOW: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN + + case ansiterm.ANSI_SGR_FOREGROUND_BLUE: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_MAGENTA: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_CYAN: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_WHITE: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + + // Background colors + case ansiterm.ANSI_SGR_BACKGROUND_DEFAULT: + // Black with no intensity + windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK) + + case ansiterm.ANSI_SGR_BACKGROUND_BLACK: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) + + case ansiterm.ANSI_SGR_BACKGROUND_RED: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED + + case ansiterm.ANSI_SGR_BACKGROUND_GREEN: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN + + case ansiterm.ANSI_SGR_BACKGROUND_YELLOW: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN + + case ansiterm.ANSI_SGR_BACKGROUND_BLUE: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_MAGENTA: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_CYAN: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_WHITE: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE + } + + return windowsMode, inverted +} + +// invertAttributes inverts the foreground and background colors of a Windows attributes value +func invertAttributes(windowsMode uint16) uint16 { + return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go b/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go new file mode 100644 index 000000000..3ee06ea72 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go @@ -0,0 +1,101 @@ +// +build windows + +package winterm + +const ( + horizontal = iota + vertical +) + +func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT { + if h.originMode { + sr := h.effectiveSr(info.Window) + return SMALL_RECT{ + Top: sr.top, + Bottom: sr.bottom, + Left: 0, + Right: info.Size.X - 1, + } + } else { + return SMALL_RECT{ + Top: info.Window.Top, + Bottom: info.Window.Bottom, + Left: 0, + Right: info.Size.X - 1, + } + } +} + +// setCursorPosition sets the cursor to the specified position, bounded to the screen size +func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error { + position.X = ensureInRange(position.X, window.Left, window.Right) + position.Y = ensureInRange(position.Y, window.Top, window.Bottom) + err := SetConsoleCursorPosition(h.fd, position) + if err != nil { + return err + } + h.logf("Cursor position set: (%d, %d)", position.X, position.Y) + return err +} + +func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error { + return h.moveCursor(vertical, param) +} + +func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error { + return h.moveCursor(horizontal, param) +} + +func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + switch moveMode { + case horizontal: + position.X += int16(param) + case vertical: + position.Y += int16(param) + } + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) moveCursorLine(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + position.X = 0 + position.Y += int16(param) + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + position.X = int16(param) - 1 + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go b/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go new file mode 100644 index 000000000..244b5fa25 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go @@ -0,0 +1,84 @@ +// +build windows + +package winterm + +import "github.com/Azure/go-ansiterm" + +func (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error { + // Ignore an invalid (negative area) request + if toCoord.Y < fromCoord.Y { + return nil + } + + var err error + + var coordStart = COORD{} + var coordEnd = COORD{} + + xCurrent, yCurrent := fromCoord.X, fromCoord.Y + xEnd, yEnd := toCoord.X, toCoord.Y + + // Clear any partial initial line + if xCurrent > 0 { + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yCurrent + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + xCurrent = 0 + yCurrent += 1 + } + + // Clear intervening rectangular section + if yCurrent < yEnd { + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yEnd-1 + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + xCurrent = 0 + yCurrent = yEnd + } + + // Clear remaining partial ending line + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yEnd + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) clearRect(attributes uint16, fromCoord COORD, toCoord COORD) error { + region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X} + width := toCoord.X - fromCoord.X + 1 + height := toCoord.Y - fromCoord.Y + 1 + size := uint32(width) * uint32(height) + + if size <= 0 { + return nil + } + + buffer := make([]CHAR_INFO, size) + + char := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes} + for i := 0; i < int(size); i++ { + buffer[i] = char + } + + err := WriteConsoleOutput(h.fd, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, &region) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go b/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go new file mode 100644 index 000000000..2d27fa1d0 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go @@ -0,0 +1,118 @@ +// +build windows + +package winterm + +// effectiveSr gets the current effective scroll region in buffer coordinates +func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion { + top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom) + bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom) + if top >= bottom { + top = window.Top + bottom = window.Bottom + } + return scrollRegion{top: top, bottom: bottom} +} + +func (h *windowsAnsiEventHandler) scrollUp(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + sr := h.effectiveSr(info.Window) + return h.scroll(param, sr, info) +} + +func (h *windowsAnsiEventHandler) scrollDown(param int) error { + return h.scrollUp(-param) +} + +func (h *windowsAnsiEventHandler) deleteLines(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + start := info.CursorPosition.Y + sr := h.effectiveSr(info.Window) + // Lines cannot be inserted or deleted outside the scrolling region. + if start >= sr.top && start <= sr.bottom { + sr.top = start + return h.scroll(param, sr, info) + } else { + return nil + } +} + +func (h *windowsAnsiEventHandler) insertLines(param int) error { + return h.deleteLines(-param) +} + +// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates. +func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error { + h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom) + h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom) + + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: sr.top, + Bottom: sr.bottom, + Left: 0, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: 0, + Y: sr.top - int16(param), + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} + +func (h *windowsAnsiEventHandler) deleteCharacters(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + return h.scrollLine(param, info.CursorPosition, info) +} + +func (h *windowsAnsiEventHandler) insertCharacters(param int) error { + return h.deleteCharacters(-param) +} + +// scrollLine scrolls a line horizontally starting at the provided position by a number of columns. +func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error { + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: position.Y, + Bottom: position.Y, + Left: position.X, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: position.X - int16(columns), + Y: position.Y, + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go b/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go new file mode 100644 index 000000000..afa7635d7 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go @@ -0,0 +1,9 @@ +// +build windows + +package winterm + +// AddInRange increments a value by the passed quantity while ensuring the values +// always remain within the supplied min / max range. +func addInRange(n int16, increment int16, min int16, max int16) int16 { + return ensureInRange(n+increment, min, max) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go new file mode 100644 index 000000000..2d40fb75a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go @@ -0,0 +1,743 @@ +// +build windows + +package winterm + +import ( + "bytes" + "log" + "os" + "strconv" + + "github.com/Azure/go-ansiterm" +) + +type windowsAnsiEventHandler struct { + fd uintptr + file *os.File + infoReset *CONSOLE_SCREEN_BUFFER_INFO + sr scrollRegion + buffer bytes.Buffer + attributes uint16 + inverted bool + wrapNext bool + drewMarginByte bool + originMode bool + marginByte byte + curInfo *CONSOLE_SCREEN_BUFFER_INFO + curPos COORD + logf func(string, ...interface{}) +} + +type Option func(*windowsAnsiEventHandler) + +func WithLogf(f func(string, ...interface{})) Option { + return func(w *windowsAnsiEventHandler) { + w.logf = f + } +} + +func CreateWinEventHandler(fd uintptr, file *os.File, opts ...Option) ansiterm.AnsiEventHandler { + infoReset, err := GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil + } + + h := &windowsAnsiEventHandler{ + fd: fd, + file: file, + infoReset: infoReset, + attributes: infoReset.Attributes, + } + for _, o := range opts { + o(h) + } + + if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { + logFile, _ := os.Create("winEventHandler.log") + logger := log.New(logFile, "", log.LstdFlags) + if h.logf != nil { + l := h.logf + h.logf = func(s string, v ...interface{}) { + l(s, v...) + logger.Printf(s, v...) + } + } else { + h.logf = logger.Printf + } + } + + if h.logf == nil { + h.logf = func(string, ...interface{}) {} + } + + return h +} + +type scrollRegion struct { + top int16 + bottom int16 +} + +// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the +// current cursor position and scroll region settings, in which case it returns +// true. If no special handling is necessary, then it does nothing and returns +// false. +// +// In the false case, the caller should ensure that a carriage return +// and line feed are inserted or that the text is otherwise wrapped. +func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) { + if h.wrapNext { + if err := h.Flush(); err != nil { + return false, err + } + h.clearWrap() + } + pos, info, err := h.getCurrentInfo() + if err != nil { + return false, err + } + sr := h.effectiveSr(info.Window) + if pos.Y == sr.bottom { + // Scrolling is necessary. Let Windows automatically scroll if the scrolling region + // is the full window. + if sr.top == info.Window.Top && sr.bottom == info.Window.Bottom { + if includeCR { + pos.X = 0 + h.updatePos(pos) + } + return false, nil + } + + // A custom scroll region is active. Scroll the window manually to simulate + // the LF. + if err := h.Flush(); err != nil { + return false, err + } + h.logf("Simulating LF inside scroll region") + if err := h.scrollUp(1); err != nil { + return false, err + } + if includeCR { + pos.X = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return false, err + } + } + return true, nil + + } else if pos.Y < info.Window.Bottom { + // Let Windows handle the LF. + pos.Y++ + if includeCR { + pos.X = 0 + } + h.updatePos(pos) + return false, nil + } else { + // The cursor is at the bottom of the screen but outside the scroll + // region. Skip the LF. + h.logf("Simulating LF outside scroll region") + if includeCR { + if err := h.Flush(); err != nil { + return false, err + } + pos.X = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return false, err + } + } + return true, nil + } +} + +// executeLF executes a LF without a CR. +func (h *windowsAnsiEventHandler) executeLF() error { + handled, err := h.simulateLF(false) + if err != nil { + return err + } + if !handled { + // Windows LF will reset the cursor column position. Write the LF + // and restore the cursor position. + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED) + if pos.X != 0 { + if err := h.Flush(); err != nil { + return err + } + h.logf("Resetting cursor position for LF without CR") + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + } + } + return nil +} + +func (h *windowsAnsiEventHandler) Print(b byte) error { + if h.wrapNext { + h.buffer.WriteByte(h.marginByte) + h.clearWrap() + if _, err := h.simulateLF(true); err != nil { + return err + } + } + pos, info, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X == info.Size.X-1 { + h.wrapNext = true + h.marginByte = b + } else { + pos.X++ + h.updatePos(pos) + h.buffer.WriteByte(b) + } + return nil +} + +func (h *windowsAnsiEventHandler) Execute(b byte) error { + switch b { + case ansiterm.ANSI_TAB: + h.logf("Execute(TAB)") + // Move to the next tab stop, but preserve auto-wrap if already set. + if !h.wrapNext { + pos, info, err := h.getCurrentInfo() + if err != nil { + return err + } + pos.X = (pos.X + 8) - pos.X%8 + if pos.X >= info.Size.X { + pos.X = info.Size.X - 1 + } + if err := h.Flush(); err != nil { + return err + } + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + } + return nil + + case ansiterm.ANSI_BEL: + h.buffer.WriteByte(ansiterm.ANSI_BEL) + return nil + + case ansiterm.ANSI_BACKSPACE: + if h.wrapNext { + if err := h.Flush(); err != nil { + return err + } + h.clearWrap() + } + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X > 0 { + pos.X-- + h.updatePos(pos) + h.buffer.WriteByte(ansiterm.ANSI_BACKSPACE) + } + return nil + + case ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED: + // Treat as true LF. + return h.executeLF() + + case ansiterm.ANSI_LINE_FEED: + // Simulate a CR and LF for now since there is no way in go-ansiterm + // to tell if the LF should include CR (and more things break when it's + // missing than when it's incorrectly added). + handled, err := h.simulateLF(true) + if handled || err != nil { + return err + } + return h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED) + + case ansiterm.ANSI_CARRIAGE_RETURN: + if h.wrapNext { + if err := h.Flush(); err != nil { + return err + } + h.clearWrap() + } + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X != 0 { + pos.X = 0 + h.updatePos(pos) + h.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN) + } + return nil + + default: + return nil + } +} + +func (h *windowsAnsiEventHandler) CUU(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUU: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorVertical(-param) +} + +func (h *windowsAnsiEventHandler) CUD(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUD: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorVertical(param) +} + +func (h *windowsAnsiEventHandler) CUF(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUF: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorHorizontal(param) +} + +func (h *windowsAnsiEventHandler) CUB(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUB: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorHorizontal(-param) +} + +func (h *windowsAnsiEventHandler) CNL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CNL: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorLine(param) +} + +func (h *windowsAnsiEventHandler) CPL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CPL: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorLine(-param) +} + +func (h *windowsAnsiEventHandler) CHA(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CHA: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorColumn(param) +} + +func (h *windowsAnsiEventHandler) VPA(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("VPA: [[%d]]", param) + h.clearWrap() + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + window := h.getCursorWindow(info) + position := info.CursorPosition + position.Y = window.Top + int16(param) - 1 + return h.setCursorPosition(position, window) +} + +func (h *windowsAnsiEventHandler) CUP(row int, col int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUP: [[%d %d]]", row, col) + h.clearWrap() + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + window := h.getCursorWindow(info) + position := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1} + return h.setCursorPosition(position, window) +} + +func (h *windowsAnsiEventHandler) HVP(row int, col int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("HVP: [[%d %d]]", row, col) + h.clearWrap() + return h.CUP(row, col) +} + +func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECTCEM: [%v]", []string{strconv.FormatBool(visible)}) + h.clearWrap() + return nil +} + +func (h *windowsAnsiEventHandler) DECOM(enable bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECOM: [%v]", []string{strconv.FormatBool(enable)}) + h.clearWrap() + h.originMode = enable + return h.CUP(1, 1) +} + +func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECCOLM: [%v]", []string{strconv.FormatBool(use132)}) + h.clearWrap() + if err := h.ED(2); err != nil { + return err + } + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + targetWidth := int16(80) + if use132 { + targetWidth = 132 + } + if info.Size.X < targetWidth { + if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { + h.logf("set buffer failed: %v", err) + return err + } + } + window := info.Window + window.Left = 0 + window.Right = targetWidth - 1 + if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { + h.logf("set window failed: %v", err) + return err + } + if info.Size.X > targetWidth { + if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { + h.logf("set buffer failed: %v", err) + return err + } + } + return SetConsoleCursorPosition(h.fd, COORD{0, 0}) +} + +func (h *windowsAnsiEventHandler) ED(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("ED: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + + // [J -- Erases from the cursor to the end of the screen, including the cursor position. + // [1J -- Erases from the beginning of the screen to the cursor, including the cursor position. + // [2J -- Erases the complete display. The cursor does not move. + // Notes: + // -- Clearing the entire buffer, versus just the Window, works best for Windows Consoles + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + var start COORD + var end COORD + + switch param { + case 0: + start = info.CursorPosition + end = COORD{info.Size.X - 1, info.Size.Y - 1} + + case 1: + start = COORD{0, 0} + end = info.CursorPosition + + case 2: + start = COORD{0, 0} + end = COORD{info.Size.X - 1, info.Size.Y - 1} + } + + err = h.clearRange(h.attributes, start, end) + if err != nil { + return err + } + + // If the whole buffer was cleared, move the window to the top while preserving + // the window-relative cursor position. + if param == 2 { + pos := info.CursorPosition + window := info.Window + pos.Y -= window.Top + window.Bottom -= window.Top + window.Top = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { + return err + } + } + + return nil +} + +func (h *windowsAnsiEventHandler) EL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("EL: [%v]", strconv.Itoa(param)) + h.clearWrap() + + // [K -- Erases from the cursor to the end of the line, including the cursor position. + // [1K -- Erases from the beginning of the line to the cursor, including the cursor position. + // [2K -- Erases the complete line. + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + var start COORD + var end COORD + + switch param { + case 0: + start = info.CursorPosition + end = COORD{info.Size.X, info.CursorPosition.Y} + + case 1: + start = COORD{0, info.CursorPosition.Y} + end = info.CursorPosition + + case 2: + start = COORD{0, info.CursorPosition.Y} + end = COORD{info.Size.X, info.CursorPosition.Y} + } + + err = h.clearRange(h.attributes, start, end) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) IL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("IL: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertLines(param) +} + +func (h *windowsAnsiEventHandler) DL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DL: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteLines(param) +} + +func (h *windowsAnsiEventHandler) ICH(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("ICH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertCharacters(param) +} + +func (h *windowsAnsiEventHandler) DCH(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DCH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteCharacters(param) +} + +func (h *windowsAnsiEventHandler) SGR(params []int) error { + if err := h.Flush(); err != nil { + return err + } + strings := []string{} + for _, v := range params { + strings = append(strings, strconv.Itoa(v)) + } + + h.logf("SGR: [%v]", strings) + + if len(params) <= 0 { + h.attributes = h.infoReset.Attributes + h.inverted = false + } else { + for _, attr := range params { + + if attr == ansiterm.ANSI_SGR_RESET { + h.attributes = h.infoReset.Attributes + h.inverted = false + continue + } + + h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr)) + } + } + + attributes := h.attributes + if h.inverted { + attributes = invertAttributes(attributes) + } + err := SetConsoleTextAttribute(h.fd, attributes) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) SU(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("SU: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.scrollUp(param) +} + +func (h *windowsAnsiEventHandler) SD(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("SD: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.scrollDown(param) +} + +func (h *windowsAnsiEventHandler) DA(params []string) error { + h.logf("DA: [%v]", params) + // DA cannot be implemented because it must send data on the VT100 input stream, + // which is not available to go-ansiterm. + return nil +} + +func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECSTBM: [%d, %d]", top, bottom) + + // Windows is 0 indexed, Linux is 1 indexed + h.sr.top = int16(top - 1) + h.sr.bottom = int16(bottom - 1) + + // This command also moves the cursor to the origin. + h.clearWrap() + return h.CUP(1, 1) +} + +func (h *windowsAnsiEventHandler) RI() error { + if err := h.Flush(); err != nil { + return err + } + h.logf("RI: []") + h.clearWrap() + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + sr := h.effectiveSr(info.Window) + if info.CursorPosition.Y == sr.top { + return h.scrollDown(1) + } + + return h.moveCursorVertical(-1) +} + +func (h *windowsAnsiEventHandler) IND() error { + h.logf("IND: []") + return h.executeLF() +} + +func (h *windowsAnsiEventHandler) Flush() error { + h.curInfo = nil + if h.buffer.Len() > 0 { + h.logf("Flush: [%s]", h.buffer.Bytes()) + if _, err := h.buffer.WriteTo(h.file); err != nil { + return err + } + } + + if h.wrapNext && !h.drewMarginByte { + h.logf("Flush: drawing margin byte '%c'", h.marginByte) + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + charInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}} + size := COORD{1, 1} + position := COORD{0, 0} + region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y} + if err := WriteConsoleOutput(h.fd, charInfo, size, position, &region); err != nil { + return err + } + h.drewMarginByte = true + } + return nil +} + +// cacheConsoleInfo ensures that the current console screen information has been queried +// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos. +func (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) { + if h.curInfo == nil { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return COORD{}, nil, err + } + h.curInfo = info + h.curPos = info.CursorPosition + } + return h.curPos, h.curInfo, nil +} + +func (h *windowsAnsiEventHandler) updatePos(pos COORD) { + if h.curInfo == nil { + panic("failed to call getCurrentInfo before calling updatePos") + } + h.curPos = pos +} + +// clearWrap clears the state where the cursor is in the margin +// waiting for the next character before wrapping the line. This must +// be done before most operations that act on the cursor. +func (h *windowsAnsiEventHandler) clearWrap() { + h.wrapNext = false + h.drewMarginByte = false +} diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md index 747e4d89a..1bd1deb29 100644 --- a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md +++ b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md @@ -1,3 +1,32 @@ +# 1.0.5 + +* Fix hooks race (#707) +* Fix panic deadlock (#695) + +# 1.0.4 + +* Fix race when adding hooks (#612) +* Fix terminal check in AppEngine (#635) + +# 1.0.3 + +* Replace example files with testable examples + +# 1.0.2 + +* bug: quote non-string values in text formatter (#583) +* Make (*Logger) SetLevel a public method + +# 1.0.1 + +* bug: fix escaping in text formatter (#575) + +# 1.0.0 + +* Officially changed name to lower-case +* bug: colors on Windows 10 (#541) +* bug: fix race in accessing level (#512) + # 0.11.5 * feature: add writer and writerlevel to entry (#372) diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md index c32287611..9751da1bf 100644 --- a/vendor/github.com/Sirupsen/logrus/README.md +++ b/vendor/github.com/Sirupsen/logrus/README.md @@ -1,17 +1,24 @@ -# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>&nbsp;[![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus)&nbsp;[![GoDoc](https://godoc.org/github.com/Sirupsen/logrus?status.svg)](https://godoc.org/github.com/Sirupsen/logrus) - -**Seeing weird case-sensitive problems?** See [this -issue](https://github.com/sirupsen/logrus/issues/451#issuecomment-264332021). -This change has been reverted. I apologize for causing this. I greatly -underestimated the impact this would have. Logrus strives for stability and -backwards compatibility and failed to provide that. +# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>&nbsp;[![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus)&nbsp;[![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) Logrus is a structured logger for Go (golang), completely API compatible with -the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not -yet stable (pre 1.0). Logrus itself is completely stable and has been used in -many large deployments. The core API is unlikely to change much but please -version control your Logrus to make sure you aren't fetching latest `master` on -every build.** +the standard library logger. + +**Seeing weird case-sensitive problems?** It's in the past been possible to +import Logrus as both upper- and lower-case. Due to the Go package environment, +this caused issues in the community and we needed a standard. Some environments +experienced problems with the upper-case variant, so the lower-case was decided. +Everything using `logrus` will need to use the lower-case: +`github.com/sirupsen/logrus`. Any package that isn't, should be changed. + +To fix Glide, see [these +comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). +For an in-depth explanation of the casing issue, see [this +comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). + +**Are you interested in assisting in maintaining Logrus?** Currently I have a +lot of obligations, and I am unable to provide Logrus with the maintainership it +needs. If you'd like to help, please reach out to me at `simon at author's +username dot com`. Nicely color-coded in development (when a TTY is attached, otherwise just plain text): @@ -52,6 +59,12 @@ time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x20822 exit status 1 ``` +#### Case-sensitivity + +The organization's name was changed to lower-case--and this will not be changed +back. If you are getting import conflicts due to case sensitivity, please use +the lower-case import: `github.com/sirupsen/logrus`. + #### Example The simplest way to use Logrus is simply the package-level exported logger: @@ -60,7 +73,7 @@ The simplest way to use Logrus is simply the package-level exported logger: package main import ( - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) func main() { @@ -71,7 +84,7 @@ func main() { ``` Note that it's completely api-compatible with the stdlib logger, so you can -replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` +replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"` and you'll now have the flexibility of Logrus. You can customize it all you want: @@ -80,7 +93,7 @@ package main import ( "os" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) func init() { @@ -131,7 +144,7 @@ package main import ( "os" - "github.com/Sirupsen/logrus" + "github.com/sirupsen/logrus" ) // Create a new instance of the logger. You can have any number of instances. @@ -159,7 +172,7 @@ func main() { #### Fields -Logrus encourages careful, structured logging though logging fields instead of +Logrus encourages careful, structured logging through logging fields instead of long, unparseable error messages. For example, instead of: `log.Fatalf("Failed to send event %s to topic %s with key %d")`, you should log the much more discoverable: @@ -206,9 +219,9 @@ Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in ```go import ( - log "github.com/Sirupsen/logrus" - "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake" - logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" + log "github.com/sirupsen/logrus" + "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake" + logrus_syslog "github.com/sirupsen/logrus/hooks/syslog" "log/syslog" ) @@ -234,32 +247,39 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v | [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. | | [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) | | [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) | +| [Application Insights](https://github.com/jjcollinge/logrus-appinsights) | Hook for logging to [Application Insights](https://azure.microsoft.com/en-us/services/application-insights/) +| [AzureTableHook](https://github.com/kpfaulkner/azuretablehook/) | Hook for logging to Azure Table Storage| | [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | +| [ClickHouse](https://github.com/oxgrouby/logrus-clickhouse-hook) | Send logs to [ClickHouse](https://clickhouse.yandex/) | | [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic | | [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) | | [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch| -| [Firehose](https://github.com/beaubrewer/firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/) +| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/) | [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | | [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) | | [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) | | [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | | [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | | [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb | -| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) | +| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) | | [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | -| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka | +| [KafkaLogrus](https://github.com/tracer0tong/kafkalogrus) | Hook for logging to Kafka | +| [Kafka REST Proxy](https://github.com/Nordstrom/logrus-kafka-rest-proxy) | Hook for logging to [Kafka REST Proxy](https://docs.confluent.io/current/kafka-rest/docs) | | [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | +| [Logbeat](https://github.com/macandmia/logbeat) | Hook for logging to [Opbeat](https://opbeat.com/) | | [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) | | [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) | | [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) | | [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | | [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) | | [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | +| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) | | [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | | [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) | | [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit | | [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. | | [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) | +| [Promrus](https://github.com/weaveworks/promrus) | Expose number of log messages as [Prometheus](https://prometheus.io/) metrics | | [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) | | [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | | [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) | @@ -269,10 +289,13 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v | [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | | [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) | | [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)| -| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | +| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | +| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. | +| [Telegram](https://github.com/rossmcdonald/telegram_hook) | Hook for logging errors to [Telegram](https://telegram.org/) | | [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) | | [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) | | [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash | +| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) | #### Level logging @@ -321,7 +344,7 @@ could do: ```go import ( - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) init() { @@ -356,6 +379,7 @@ The built-in logging formatters are: Third party logging formatters: +* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine. * [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events. * [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. * [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. @@ -434,15 +458,24 @@ Logrus has a built in facility for asserting the presence of log messages. This * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): ```go -logger, hook := NewNullLogger() -logger.Error("Hello error") +import( + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" + "testing" +) -assert.Equal(1, len(hook.Entries)) -assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level) -assert.Equal("Hello error", hook.LastEntry().Message) +func TestSomething(t*testing.T){ + logger, hook := test.NewNullLogger() + logger.Error("Helloerror") -hook.Reset() -assert.Nil(hook.LastEntry()) + assert.Equal(t, 1, len(hook.Entries)) + assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level) + assert.Equal(t, "Helloerror", hook.LastEntry().Message) + + hook.Reset() + assert.Nil(t, hook.LastEntry()) +} ``` #### Fatal handlers diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/Sirupsen/logrus/doc.go index dddd5f877..da67aba06 100644 --- a/vendor/github.com/Sirupsen/logrus/doc.go +++ b/vendor/github.com/Sirupsen/logrus/doc.go @@ -7,7 +7,7 @@ The simplest way to use Logrus is simply the package-level exported logger: package main import ( - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) func main() { @@ -21,6 +21,6 @@ The simplest way to use Logrus is simply the package-level exported logger: Output: time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 -For a full guide visit https://github.com/Sirupsen/logrus +For a full guide visit https://github.com/sirupsen/logrus */ package logrus diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go index 4edbe7a2d..778f4c9f0 100644 --- a/vendor/github.com/Sirupsen/logrus/entry.go +++ b/vendor/github.com/Sirupsen/logrus/entry.go @@ -35,6 +35,7 @@ type Entry struct { Time time.Time // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic + // This field will be set on entry firing and the value will be equal to the one in Logger struct field. Level Level // Message passed to Debug, Info, Warn, Error, Fatal or Panic @@ -93,29 +94,16 @@ func (entry Entry) log(level Level, msg string) { entry.Level = level entry.Message = msg - if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) - entry.Logger.mu.Unlock() - } + entry.fireHooks() + buffer = bufferPool.Get().(*bytes.Buffer) buffer.Reset() defer bufferPool.Put(buffer) entry.Buffer = buffer - serialized, err := entry.Logger.Formatter.Format(&entry) + + entry.write() + entry.Buffer = nil - if err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) - entry.Logger.mu.Unlock() - } else { - entry.Logger.mu.Lock() - _, err = entry.Logger.Out.Write(serialized) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) - } - entry.Logger.mu.Unlock() - } // To avoid Entry#log() returning a value that only would make sense for // panic() to use in Entry#Panic(), we avoid the allocation by checking @@ -125,8 +113,33 @@ func (entry Entry) log(level Level, msg string) { } } +// This function is not declared with a pointer value because otherwise +// race conditions will occur when using multiple goroutines +func (entry Entry) fireHooks() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + err := entry.Logger.Hooks.Fire(entry.Level, &entry) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + } +} + +func (entry *Entry) write() { + serialized, err := entry.Logger.Formatter.Format(entry) + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + } else { + _, err = entry.Logger.Out.Write(serialized) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } + } +} + func (entry *Entry) Debug(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { + if entry.Logger.level() >= DebugLevel { entry.log(DebugLevel, fmt.Sprint(args...)) } } @@ -136,13 +149,13 @@ func (entry *Entry) Print(args ...interface{}) { } func (entry *Entry) Info(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { + if entry.Logger.level() >= InfoLevel { entry.log(InfoLevel, fmt.Sprint(args...)) } } func (entry *Entry) Warn(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { + if entry.Logger.level() >= WarnLevel { entry.log(WarnLevel, fmt.Sprint(args...)) } } @@ -152,20 +165,20 @@ func (entry *Entry) Warning(args ...interface{}) { } func (entry *Entry) Error(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { + if entry.Logger.level() >= ErrorLevel { entry.log(ErrorLevel, fmt.Sprint(args...)) } } func (entry *Entry) Fatal(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { + if entry.Logger.level() >= FatalLevel { entry.log(FatalLevel, fmt.Sprint(args...)) } Exit(1) } func (entry *Entry) Panic(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { + if entry.Logger.level() >= PanicLevel { entry.log(PanicLevel, fmt.Sprint(args...)) } panic(fmt.Sprint(args...)) @@ -174,13 +187,13 @@ func (entry *Entry) Panic(args ...interface{}) { // Entry Printf family functions func (entry *Entry) Debugf(format string, args ...interface{}) { - if entry.Logger.Level >= DebugLevel { + if entry.Logger.level() >= DebugLevel { entry.Debug(fmt.Sprintf(format, args...)) } } func (entry *Entry) Infof(format string, args ...interface{}) { - if entry.Logger.Level >= InfoLevel { + if entry.Logger.level() >= InfoLevel { entry.Info(fmt.Sprintf(format, args...)) } } @@ -190,7 +203,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) { } func (entry *Entry) Warnf(format string, args ...interface{}) { - if entry.Logger.Level >= WarnLevel { + if entry.Logger.level() >= WarnLevel { entry.Warn(fmt.Sprintf(format, args...)) } } @@ -200,20 +213,20 @@ func (entry *Entry) Warningf(format string, args ...interface{}) { } func (entry *Entry) Errorf(format string, args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { + if entry.Logger.level() >= ErrorLevel { entry.Error(fmt.Sprintf(format, args...)) } } func (entry *Entry) Fatalf(format string, args ...interface{}) { - if entry.Logger.Level >= FatalLevel { + if entry.Logger.level() >= FatalLevel { entry.Fatal(fmt.Sprintf(format, args...)) } Exit(1) } func (entry *Entry) Panicf(format string, args ...interface{}) { - if entry.Logger.Level >= PanicLevel { + if entry.Logger.level() >= PanicLevel { entry.Panic(fmt.Sprintf(format, args...)) } } @@ -221,13 +234,13 @@ func (entry *Entry) Panicf(format string, args ...interface{}) { // Entry Println family functions func (entry *Entry) Debugln(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { + if entry.Logger.level() >= DebugLevel { entry.Debug(entry.sprintlnn(args...)) } } func (entry *Entry) Infoln(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { + if entry.Logger.level() >= InfoLevel { entry.Info(entry.sprintlnn(args...)) } } @@ -237,7 +250,7 @@ func (entry *Entry) Println(args ...interface{}) { } func (entry *Entry) Warnln(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { + if entry.Logger.level() >= WarnLevel { entry.Warn(entry.sprintlnn(args...)) } } @@ -247,20 +260,20 @@ func (entry *Entry) Warningln(args ...interface{}) { } func (entry *Entry) Errorln(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { + if entry.Logger.level() >= ErrorLevel { entry.Error(entry.sprintlnn(args...)) } } func (entry *Entry) Fatalln(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { + if entry.Logger.level() >= FatalLevel { entry.Fatal(entry.sprintlnn(args...)) } Exit(1) } func (entry *Entry) Panicln(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { + if entry.Logger.level() >= PanicLevel { entry.Panic(entry.sprintlnn(args...)) } } diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go index 9a0120ac1..013183eda 100644 --- a/vendor/github.com/Sirupsen/logrus/exported.go +++ b/vendor/github.com/Sirupsen/logrus/exported.go @@ -31,14 +31,14 @@ func SetFormatter(formatter Formatter) { func SetLevel(level Level) { std.mu.Lock() defer std.mu.Unlock() - std.Level = level + std.SetLevel(level) } // GetLevel returns the standard logger level. func GetLevel() Level { std.mu.Lock() defer std.mu.Unlock() - return std.Level + return std.level() } // AddHook adds a hook to the standard logger hooks. diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go index b5fbe934d..b183ff5b1 100644 --- a/vendor/github.com/Sirupsen/logrus/formatter.go +++ b/vendor/github.com/Sirupsen/logrus/formatter.go @@ -2,7 +2,7 @@ package logrus import "time" -const DefaultTimestampFormat = time.RFC3339 +const defaultTimestampFormat = time.RFC3339 // The Formatter interface is used to implement a custom Formatter. It takes an // `Entry`. It exposes all the fields, including the default ones: diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go index 266554e9f..fb01c1b10 100644 --- a/vendor/github.com/Sirupsen/logrus/json_formatter.go +++ b/vendor/github.com/Sirupsen/logrus/json_formatter.go @@ -6,8 +6,11 @@ import ( ) type fieldKey string + +// FieldMap allows customization of the key names for default fields. type FieldMap map[fieldKey]string +// Default key names for the default fields const ( FieldKeyMsg = "msg" FieldKeyLevel = "level" @@ -22,6 +25,7 @@ func (f FieldMap) resolve(key fieldKey) string { return string(key) } +// JSONFormatter formats logs into parsable json type JSONFormatter struct { // TimestampFormat sets the format used for marshaling timestamps. TimestampFormat string @@ -29,25 +33,26 @@ type JSONFormatter struct { // DisableTimestamp allows disabling automatic timestamps in output DisableTimestamp bool - // FieldMap allows users to customize the names of keys for various fields. + // FieldMap allows users to customize the names of keys for default fields. // As an example: // formatter := &JSONFormatter{ // FieldMap: FieldMap{ // FieldKeyTime: "@timestamp", // FieldKeyLevel: "@level", - // FieldKeyLevel: "@message", + // FieldKeyMsg: "@message", // }, // } FieldMap FieldMap } +// Format renders a single log entry func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { data := make(Fields, len(entry.Data)+3) for k, v := range entry.Data { switch v := v.(type) { case error: // Otherwise errors are ignored by `encoding/json` - // https://github.com/Sirupsen/logrus/issues/137 + // https://github.com/sirupsen/logrus/issues/137 data[k] = v.Error() default: data[k] = v @@ -57,7 +62,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { timestampFormat := f.TimestampFormat if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat + timestampFormat = defaultTimestampFormat } if !f.DisableTimestamp { diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go index b769f3d35..fdaf8a653 100644 --- a/vendor/github.com/Sirupsen/logrus/logger.go +++ b/vendor/github.com/Sirupsen/logrus/logger.go @@ -4,6 +4,7 @@ import ( "io" "os" "sync" + "sync/atomic" ) type Logger struct { @@ -24,7 +25,7 @@ type Logger struct { Formatter Formatter // The logging level the logger should log at. This is typically (and defaults // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be - // logged. `logrus.Debug` is useful in + // logged. Level Level // Used to sync writing to the log. Locking is enabled by Default mu MutexWrap @@ -112,7 +113,7 @@ func (logger *Logger) WithError(err error) *Entry { } func (logger *Logger) Debugf(format string, args ...interface{}) { - if logger.Level >= DebugLevel { + if logger.level() >= DebugLevel { entry := logger.newEntry() entry.Debugf(format, args...) logger.releaseEntry(entry) @@ -120,7 +121,7 @@ func (logger *Logger) Debugf(format string, args ...interface{}) { } func (logger *Logger) Infof(format string, args ...interface{}) { - if logger.Level >= InfoLevel { + if logger.level() >= InfoLevel { entry := logger.newEntry() entry.Infof(format, args...) logger.releaseEntry(entry) @@ -134,7 +135,7 @@ func (logger *Logger) Printf(format string, args ...interface{}) { } func (logger *Logger) Warnf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { + if logger.level() >= WarnLevel { entry := logger.newEntry() entry.Warnf(format, args...) logger.releaseEntry(entry) @@ -142,7 +143,7 @@ func (logger *Logger) Warnf(format string, args ...interface{}) { } func (logger *Logger) Warningf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { + if logger.level() >= WarnLevel { entry := logger.newEntry() entry.Warnf(format, args...) logger.releaseEntry(entry) @@ -150,7 +151,7 @@ func (logger *Logger) Warningf(format string, args ...interface{}) { } func (logger *Logger) Errorf(format string, args ...interface{}) { - if logger.Level >= ErrorLevel { + if logger.level() >= ErrorLevel { entry := logger.newEntry() entry.Errorf(format, args...) logger.releaseEntry(entry) @@ -158,7 +159,7 @@ func (logger *Logger) Errorf(format string, args ...interface{}) { } func (logger *Logger) Fatalf(format string, args ...interface{}) { - if logger.Level >= FatalLevel { + if logger.level() >= FatalLevel { entry := logger.newEntry() entry.Fatalf(format, args...) logger.releaseEntry(entry) @@ -167,7 +168,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) { } func (logger *Logger) Panicf(format string, args ...interface{}) { - if logger.Level >= PanicLevel { + if logger.level() >= PanicLevel { entry := logger.newEntry() entry.Panicf(format, args...) logger.releaseEntry(entry) @@ -175,7 +176,7 @@ func (logger *Logger) Panicf(format string, args ...interface{}) { } func (logger *Logger) Debug(args ...interface{}) { - if logger.Level >= DebugLevel { + if logger.level() >= DebugLevel { entry := logger.newEntry() entry.Debug(args...) logger.releaseEntry(entry) @@ -183,7 +184,7 @@ func (logger *Logger) Debug(args ...interface{}) { } func (logger *Logger) Info(args ...interface{}) { - if logger.Level >= InfoLevel { + if logger.level() >= InfoLevel { entry := logger.newEntry() entry.Info(args...) logger.releaseEntry(entry) @@ -197,7 +198,7 @@ func (logger *Logger) Print(args ...interface{}) { } func (logger *Logger) Warn(args ...interface{}) { - if logger.Level >= WarnLevel { + if logger.level() >= WarnLevel { entry := logger.newEntry() entry.Warn(args...) logger.releaseEntry(entry) @@ -205,7 +206,7 @@ func (logger *Logger) Warn(args ...interface{}) { } func (logger *Logger) Warning(args ...interface{}) { - if logger.Level >= WarnLevel { + if logger.level() >= WarnLevel { entry := logger.newEntry() entry.Warn(args...) logger.releaseEntry(entry) @@ -213,7 +214,7 @@ func (logger *Logger) Warning(args ...interface{}) { } func (logger *Logger) Error(args ...interface{}) { - if logger.Level >= ErrorLevel { + if logger.level() >= ErrorLevel { entry := logger.newEntry() entry.Error(args...) logger.releaseEntry(entry) @@ -221,7 +222,7 @@ func (logger *Logger) Error(args ...interface{}) { } func (logger *Logger) Fatal(args ...interface{}) { - if logger.Level >= FatalLevel { + if logger.level() >= FatalLevel { entry := logger.newEntry() entry.Fatal(args...) logger.releaseEntry(entry) @@ -230,7 +231,7 @@ func (logger *Logger) Fatal(args ...interface{}) { } func (logger *Logger) Panic(args ...interface{}) { - if logger.Level >= PanicLevel { + if logger.level() >= PanicLevel { entry := logger.newEntry() entry.Panic(args...) logger.releaseEntry(entry) @@ -238,7 +239,7 @@ func (logger *Logger) Panic(args ...interface{}) { } func (logger *Logger) Debugln(args ...interface{}) { - if logger.Level >= DebugLevel { + if logger.level() >= DebugLevel { entry := logger.newEntry() entry.Debugln(args...) logger.releaseEntry(entry) @@ -246,7 +247,7 @@ func (logger *Logger) Debugln(args ...interface{}) { } func (logger *Logger) Infoln(args ...interface{}) { - if logger.Level >= InfoLevel { + if logger.level() >= InfoLevel { entry := logger.newEntry() entry.Infoln(args...) logger.releaseEntry(entry) @@ -260,7 +261,7 @@ func (logger *Logger) Println(args ...interface{}) { } func (logger *Logger) Warnln(args ...interface{}) { - if logger.Level >= WarnLevel { + if logger.level() >= WarnLevel { entry := logger.newEntry() entry.Warnln(args...) logger.releaseEntry(entry) @@ -268,7 +269,7 @@ func (logger *Logger) Warnln(args ...interface{}) { } func (logger *Logger) Warningln(args ...interface{}) { - if logger.Level >= WarnLevel { + if logger.level() >= WarnLevel { entry := logger.newEntry() entry.Warnln(args...) logger.releaseEntry(entry) @@ -276,7 +277,7 @@ func (logger *Logger) Warningln(args ...interface{}) { } func (logger *Logger) Errorln(args ...interface{}) { - if logger.Level >= ErrorLevel { + if logger.level() >= ErrorLevel { entry := logger.newEntry() entry.Errorln(args...) logger.releaseEntry(entry) @@ -284,7 +285,7 @@ func (logger *Logger) Errorln(args ...interface{}) { } func (logger *Logger) Fatalln(args ...interface{}) { - if logger.Level >= FatalLevel { + if logger.level() >= FatalLevel { entry := logger.newEntry() entry.Fatalln(args...) logger.releaseEntry(entry) @@ -293,7 +294,7 @@ func (logger *Logger) Fatalln(args ...interface{}) { } func (logger *Logger) Panicln(args ...interface{}) { - if logger.Level >= PanicLevel { + if logger.level() >= PanicLevel { entry := logger.newEntry() entry.Panicln(args...) logger.releaseEntry(entry) @@ -306,3 +307,17 @@ func (logger *Logger) Panicln(args ...interface{}) { func (logger *Logger) SetNoLock() { logger.mu.Disable() } + +func (logger *Logger) level() Level { + return Level(atomic.LoadUint32((*uint32)(&logger.Level))) +} + +func (logger *Logger) SetLevel(level Level) { + atomic.StoreUint32((*uint32)(&logger.Level), uint32(level)) +} + +func (logger *Logger) AddHook(hook Hook) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Hooks.Add(hook) +} diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go index e59669111..dd3899974 100644 --- a/vendor/github.com/Sirupsen/logrus/logrus.go +++ b/vendor/github.com/Sirupsen/logrus/logrus.go @@ -10,7 +10,7 @@ import ( type Fields map[string]interface{} // Level type -type Level uint8 +type Level uint32 // Convert the Level to a string. E.g. PanicLevel becomes "panic". func (level Level) String() string { diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go index 5f6be4d3c..4880d13d2 100644 --- a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go +++ b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go @@ -1,10 +1,10 @@ // +build darwin freebsd openbsd netbsd dragonfly -// +build !appengine +// +build !appengine,!gopherjs package logrus -import "syscall" +import "golang.org/x/sys/unix" -const ioctlReadTermios = syscall.TIOCGETA +const ioctlReadTermios = unix.TIOCGETA -type Termios syscall.Termios +type Termios unix.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/Sirupsen/logrus/terminal_linux.go index 308160ca8..f29a0097c 100644 --- a/vendor/github.com/Sirupsen/logrus/terminal_linux.go +++ b/vendor/github.com/Sirupsen/logrus/terminal_linux.go @@ -3,12 +3,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !appengine +// +build !appengine,!gopherjs package logrus -import "syscall" +import "golang.org/x/sys/unix" -const ioctlReadTermios = syscall.TCGETS +const ioctlReadTermios = unix.TCGETS -type Termios syscall.Termios +type Termios unix.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go deleted file mode 100644 index 190297abf..000000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go +++ /dev/null @@ -1,28 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux darwin freebsd openbsd netbsd dragonfly -// +build !appengine - -package logrus - -import ( - "io" - "os" - "syscall" - "unsafe" -) - -// IsTerminal returns true if stderr's file descriptor is a terminal. -func IsTerminal(f io.Writer) bool { - var termios Termios - switch v := f.(type) { - case *os.File: - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 - default: - return false - } -} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go deleted file mode 100644 index 3c86b1abe..000000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build solaris,!appengine - -package logrus - -import ( - "io" - "os" - - "golang.org/x/sys/unix" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(f io.Writer) bool { - switch v := f.(type) { - case *os.File: - _, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA) - return err == nil - default: - return false - } -} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go deleted file mode 100644 index 05d2f91f1..000000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_windows.go +++ /dev/null @@ -1,33 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows,!appengine - -package logrus - -import ( - "io" - "os" - "syscall" - "unsafe" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") -) - -// IsTerminal returns true if stderr's file descriptor is a terminal. -func IsTerminal(f io.Writer) bool { - switch v := f.(type) { - case *os.File: - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 - default: - return false - } -} diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go index ba8885406..61b21caea 100644 --- a/vendor/github.com/Sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/Sirupsen/logrus/text_formatter.go @@ -14,7 +14,7 @@ const ( red = 31 green = 32 yellow = 33 - blue = 34 + blue = 36 gray = 37 ) @@ -26,6 +26,7 @@ func init() { baseTimestamp = time.Now() } +// TextFormatter formats logs into text type TextFormatter struct { // Set to true to bypass checking for a TTY before outputting colors. ForceColors bool @@ -52,10 +53,6 @@ type TextFormatter struct { // QuoteEmptyFields will wrap empty fields in quotes if true QuoteEmptyFields bool - // QuoteCharacter can be set to the override the default quoting character " - // with something else. For example: ', or `. - QuoteCharacter string - // Whether the logger's out is to a terminal isTerminal bool @@ -63,14 +60,12 @@ type TextFormatter struct { } func (f *TextFormatter) init(entry *Entry) { - if len(f.QuoteCharacter) == 0 { - f.QuoteCharacter = "\"" - } if entry.Logger != nil { - f.isTerminal = IsTerminal(entry.Logger.Out) + f.isTerminal = checkIfTerminal(entry.Logger.Out) } } +// Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { var b *bytes.Buffer keys := make([]string, 0, len(entry.Data)) @@ -95,7 +90,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { timestampFormat := f.TimestampFormat if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat + timestampFormat = defaultTimestampFormat } if isColored { f.printColored(b, entry, keys, timestampFormat) @@ -153,7 +148,7 @@ func (f *TextFormatter) needsQuoting(text string) bool { if !((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || - ch == '-' || ch == '.') { + ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') { return true } } @@ -161,29 +156,23 @@ func (f *TextFormatter) needsQuoting(text string) bool { } func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { - + if b.Len() > 0 { + b.WriteByte(' ') + } b.WriteString(key) b.WriteByte('=') f.appendValue(b, value) - b.WriteByte(' ') } func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { - switch value := value.(type) { - case string: - if !f.needsQuoting(value) { - b.WriteString(value) - } else { - fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter) - } - case error: - errmsg := value.Error() - if !f.needsQuoting(errmsg) { - b.WriteString(errmsg) - } else { - fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter) - } - default: - fmt.Fprint(b, value) + stringVal, ok := value.(string) + if !ok { + stringVal = fmt.Sprint(value) + } + + if !f.needsQuoting(stringVal) { + b.WriteString(stringVal) + } else { + b.WriteString(fmt.Sprintf("%q", stringVal)) } } diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go new file mode 100644 index 000000000..1d7c452cc --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go @@ -0,0 +1,263 @@ +// +build windows + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "bytes" + "errors" + "fmt" + "io" + "os" + "strings" + "unsafe" + + ansiterm "github.com/Azure/go-ansiterm" + "github.com/Azure/go-ansiterm/winterm" +) + +const ( + escapeSequence = ansiterm.KEY_ESC_CSI +) + +// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation. +type ansiReader struct { + file *os.File + fd uintptr + buffer []byte + cbBuffer int + command []byte +} + +// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a +// Windows console input handle. +func NewAnsiReader(nFile int) io.ReadCloser { + initLogger() + file, fd := winterm.GetStdFile(nFile) + return &ansiReader{ + file: file, + fd: fd, + command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), + buffer: make([]byte, 0), + } +} + +// Close closes the wrapped file. +func (ar *ansiReader) Close() (err error) { + return ar.file.Close() +} + +// Fd returns the file descriptor of the wrapped file. +func (ar *ansiReader) Fd() uintptr { + return ar.fd +} + +// Read reads up to len(p) bytes of translated input events into p. +func (ar *ansiReader) Read(p []byte) (int, error) { + if len(p) == 0 { + return 0, nil + } + + // Previously read bytes exist, read as much as we can and return + if len(ar.buffer) > 0 { + logger.Debugf("Reading previously cached bytes") + + originalLength := len(ar.buffer) + copiedLength := copy(p, ar.buffer) + + if copiedLength == originalLength { + ar.buffer = make([]byte, 0, len(p)) + } else { + ar.buffer = ar.buffer[copiedLength:] + } + + logger.Debugf("Read from cache p[%d]: % x", copiedLength, p) + return copiedLength, nil + } + + // Read and translate key events + events, err := readInputEvents(ar.fd, len(p)) + if err != nil { + return 0, err + } else if len(events) == 0 { + logger.Debug("No input events detected") + return 0, nil + } + + keyBytes := translateKeyEvents(events, []byte(escapeSequence)) + + // Save excess bytes and right-size keyBytes + if len(keyBytes) > len(p) { + logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p)) + ar.buffer = keyBytes[len(p):] + keyBytes = keyBytes[:len(p)] + } else if len(keyBytes) == 0 { + logger.Debug("No key bytes returned from the translator") + return 0, nil + } + + copiedLength := copy(p, keyBytes) + if copiedLength != len(keyBytes) { + return 0, errors.New("unexpected copy length encountered") + } + + logger.Debugf("Read p[%d]: % x", copiedLength, p) + logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes) + return copiedLength, nil +} + +// readInputEvents polls until at least one event is available. +func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) { + // Determine the maximum number of records to retrieve + // -- Cast around the type system to obtain the size of a single INPUT_RECORD. + // unsafe.Sizeof requires an expression vs. a type-reference; the casting + // tricks the type system into believing it has such an expression. + recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes))))) + countRecords := maxBytes / recordSize + if countRecords > ansiterm.MAX_INPUT_EVENTS { + countRecords = ansiterm.MAX_INPUT_EVENTS + } else if countRecords == 0 { + countRecords = 1 + } + logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize) + + // Wait for and read input events + events := make([]winterm.INPUT_RECORD, countRecords) + nEvents := uint32(0) + eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE) + if err != nil { + return nil, err + } + + if eventsExist { + err = winterm.ReadConsoleInput(fd, events, &nEvents) + if err != nil { + return nil, err + } + } + + // Return a slice restricted to the number of returned records + logger.Debugf("[windows] readInputEvents: Read %v events", nEvents) + return events[:nEvents], nil +} + +// KeyEvent Translation Helpers + +var arrowKeyMapPrefix = map[uint16]string{ + winterm.VK_UP: "%s%sA", + winterm.VK_DOWN: "%s%sB", + winterm.VK_RIGHT: "%s%sC", + winterm.VK_LEFT: "%s%sD", +} + +var keyMapPrefix = map[uint16]string{ + winterm.VK_UP: "\x1B[%sA", + winterm.VK_DOWN: "\x1B[%sB", + winterm.VK_RIGHT: "\x1B[%sC", + winterm.VK_LEFT: "\x1B[%sD", + winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1 + winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4 + winterm.VK_INSERT: "\x1B[2%s~", + winterm.VK_DELETE: "\x1B[3%s~", + winterm.VK_PRIOR: "\x1B[5%s~", + winterm.VK_NEXT: "\x1B[6%s~", + winterm.VK_F1: "", + winterm.VK_F2: "", + winterm.VK_F3: "\x1B[13%s~", + winterm.VK_F4: "\x1B[14%s~", + winterm.VK_F5: "\x1B[15%s~", + winterm.VK_F6: "\x1B[17%s~", + winterm.VK_F7: "\x1B[18%s~", + winterm.VK_F8: "\x1B[19%s~", + winterm.VK_F9: "\x1B[20%s~", + winterm.VK_F10: "\x1B[21%s~", + winterm.VK_F11: "\x1B[23%s~", + winterm.VK_F12: "\x1B[24%s~", +} + +// translateKeyEvents converts the input events into the appropriate ANSI string. +func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte { + var buffer bytes.Buffer + for _, event := range events { + if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 { + buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence)) + } + } + + return buffer.Bytes() +} + +// keyToString maps the given input event record to the corresponding string. +func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string { + if keyEvent.UnicodeChar == 0 { + return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence) + } + + _, alt, control := getControlKeys(keyEvent.ControlKeyState) + if control { + // TODO(azlinux): Implement following control sequences + // <Ctrl>-D Signals the end of input from the keyboard; also exits current shell. + // <Ctrl>-H Deletes the first character to the left of the cursor. Also called the ERASE key. + // <Ctrl>-Q Restarts printing after it has been stopped with <Ctrl>-s. + // <Ctrl>-S Suspends printing on the screen (does not stop the program). + // <Ctrl>-U Deletes all characters on the current line. Also called the KILL key. + // <Ctrl>-E Quits current command and creates a core + + } + + // <Alt>+Key generates ESC N Key + if !control && alt { + return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar)) + } + + return string(keyEvent.UnicodeChar) +} + +// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string. +func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) string { + shift, alt, control := getControlKeys(controlState) + modifier := getControlKeysModifier(shift, alt, control) + + if format, ok := arrowKeyMapPrefix[key]; ok { + return fmt.Sprintf(format, escapeSequence, modifier) + } + + if format, ok := keyMapPrefix[key]; ok { + return fmt.Sprintf(format, modifier) + } + + return "" +} + +// getControlKeys extracts the shift, alt, and ctrl key states. +func getControlKeys(controlState uint32) (shift, alt, control bool) { + shift = 0 != (controlState & winterm.SHIFT_PRESSED) + alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED)) + control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED)) + return shift, alt, control +} + +// getControlKeysModifier returns the ANSI modifier for the given combination of control keys. +func getControlKeysModifier(shift, alt, control bool) string { + if shift && alt && control { + return ansiterm.KEY_CONTROL_PARAM_8 + } + if alt && control { + return ansiterm.KEY_CONTROL_PARAM_7 + } + if shift && control { + return ansiterm.KEY_CONTROL_PARAM_6 + } + if control { + return ansiterm.KEY_CONTROL_PARAM_5 + } + if shift && alt { + return ansiterm.KEY_CONTROL_PARAM_4 + } + if alt { + return ansiterm.KEY_CONTROL_PARAM_3 + } + if shift { + return ansiterm.KEY_CONTROL_PARAM_2 + } + return "" +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go new file mode 100644 index 000000000..7799a03fc --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go @@ -0,0 +1,64 @@ +// +build windows + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "io" + "os" + + ansiterm "github.com/Azure/go-ansiterm" + "github.com/Azure/go-ansiterm/winterm" +) + +// ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation. +type ansiWriter struct { + file *os.File + fd uintptr + infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO + command []byte + escapeSequence []byte + inAnsiSequence bool + parser *ansiterm.AnsiParser +} + +// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a +// Windows console output handle. +func NewAnsiWriter(nFile int) io.Writer { + initLogger() + file, fd := winterm.GetStdFile(nFile) + info, err := winterm.GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil + } + + parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file)) + logger.Infof("newAnsiWriter: parser %p", parser) + + aw := &ansiWriter{ + file: file, + fd: fd, + infoReset: info, + command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), + escapeSequence: []byte(ansiterm.KEY_ESC_CSI), + parser: parser, + } + + logger.Infof("newAnsiWriter: aw.parser %p", aw.parser) + logger.Infof("newAnsiWriter: %v", aw) + return aw +} + +func (aw *ansiWriter) Fd() uintptr { + return aw.fd +} + +// Write writes len(p) bytes from p to the underlying data stream. +func (aw *ansiWriter) Write(p []byte) (total int, err error) { + if len(p) == 0 { + return 0, nil + } + + logger.Infof("Write: % x", p) + logger.Infof("Write: %s", string(p)) + return aw.parser.Parse(p) +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/console.go b/vendor/github.com/docker/docker/pkg/term/windows/console.go new file mode 100644 index 000000000..527401975 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/console.go @@ -0,0 +1,35 @@ +// +build windows + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "os" + + "github.com/Azure/go-ansiterm/winterm" +) + +// GetHandleInfo returns file descriptor and bool indicating whether the file is a console. +func GetHandleInfo(in interface{}) (uintptr, bool) { + switch t := in.(type) { + case *ansiReader: + return t.Fd(), true + case *ansiWriter: + return t.Fd(), true + } + + var inFd uintptr + var isTerminal bool + + if file, ok := in.(*os.File); ok { + inFd = file.Fd() + isTerminal = IsConsole(inFd) + } + return inFd, isTerminal +} + +// IsConsole returns true if the given file descriptor is a Windows Console. +// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console. +func IsConsole(fd uintptr) bool { + _, e := winterm.GetConsoleMode(fd) + return e == nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/windows.go b/vendor/github.com/docker/docker/pkg/term/windows/windows.go new file mode 100644 index 000000000..1f8965969 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/windows/windows.go @@ -0,0 +1,33 @@ +// These files implement ANSI-aware input and output streams for use by the Docker Windows client. +// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create +// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls. + +package windowsconsole // import "github.com/docker/docker/pkg/term/windows" + +import ( + "io/ioutil" + "os" + "sync" + + ansiterm "github.com/Azure/go-ansiterm" + "github.com/sirupsen/logrus" +) + +var logger *logrus.Logger +var initOnce sync.Once + +func initLogger() { + initOnce.Do(func() { + logFile := ioutil.Discard + + if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { + logFile, _ = os.Create("ansiReaderWriter.log") + } + + logger = &logrus.Logger{ + Out: logFile, + Formatter: new(logrus.TextFormatter), + Level: logrus.DebugLevel, + } + }) +} diff --git a/vendor/github.com/moul/gotty-client/Dockerfile b/vendor/github.com/moul/gotty-client/Dockerfile new file mode 100644 index 000000000..e598be675 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/Dockerfile @@ -0,0 +1,11 @@ +# build +FROM golang:1.9 as builder +RUN apt update && apt -y install jq +COPY . /go/src/github.com/moul/gotty-client +WORKDIR /go/src/github.com/moul/gotty-client +RUN make install + +# minimal runtime +FROM scratch +COPY --from=builder /go/bin/gotty-client /bin/gotty-client +ENTRYPOINT ["/bin/gotty-client"] diff --git a/vendor/github.com/moul/gotty-client/LICENSE.apache b/vendor/github.com/moul/gotty-client/LICENSE.apache new file mode 100644 index 000000000..6fe259dd5 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/LICENSE.apache @@ -0,0 +1,192 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2017 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/github.com/moul/gotty-client/Makefile b/vendor/github.com/moul/gotty-client/Makefile index 4952ef990..e8ff3b579 100644 --- a/vendor/github.com/moul/gotty-client/Makefile +++ b/vendor/github.com/moul/gotty-client/Makefile @@ -29,12 +29,13 @@ install: $(BINARIES): $(SOURCES) - $(GO) build -o $@ ./cmd/$@ + $(GO) build -i -o $@ ./cmd/$@ .PHONY: test test: - $(GO) get -t . +# $(GO) get -t . + $(GO) test -i -v . $(GO) test -v . @@ -69,13 +70,4 @@ profile.out: $(SOURCES) .PHONY: docker-build docker-build: - go get github.com/laher/goxc - rm -rf contrib/docker/linux_386 - for binary in $(BINARIES); do \ - goxc -bc="linux,386" -d . -pv contrib/docker -n $$binary xc; \ - mv contrib/docker/linux_386/$$binary contrib/docker/entrypoint; \ - docker build -t $(USER)/$$binary contrib/docker; \ - docker run -it --rm $(USER)/$$binary || true; \ - docker inspect --type=image --format="{{ .Id }}" moul/$$binary || true; \ - echo "Now you can run 'docker push $(USER)/$$binary'"; \ - done + docker build -t moul/gotty-client . diff --git a/vendor/github.com/moul/gotty-client/README.md b/vendor/github.com/moul/gotty-client/README.md index 2fb562b32..91d3be331 100644 --- a/vendor/github.com/moul/gotty-client/README.md +++ b/vendor/github.com/moul/gotty-client/README.md @@ -5,6 +5,7 @@ [![Build Status](https://travis-ci.org/moul/gotty-client.svg?branch=master)](https://travis-ci.org/moul/gotty-client) [![GoDoc](https://godoc.org/github.com/moul/gotty-client?status.svg)](https://godoc.org/github.com/moul/gotty-client) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoul%2Fgotty-client.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoul%2Fgotty-client?ref=badge_shield) ```ruby ┌─────────────────┐ @@ -107,7 +108,7 @@ $ brew install https://raw.githubusercontent.com/moul/gotty-client/master/contri ### master (unreleased) -* No entry +* Add `--detach-keys` option ([#52](https://github.com/moul/gotty-client/issues/52)) [full commits list](https://github.com/moul/gotty-client/compare/v1.6.1...master) @@ -199,3 +200,6 @@ Compatible with [GoTTY](https://github.com/yudai/gotty) version: [v0.0.10](https ## License MIT + + +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoul%2Fgotty-client.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmoul%2Fgotty-client?ref=badge_large) diff --git a/vendor/github.com/moul/gotty-client/arch.go b/vendor/github.com/moul/gotty-client/arch.go index d856fbd2c..77a4deaec 100644 --- a/vendor/github.com/moul/gotty-client/arch.go +++ b/vendor/github.com/moul/gotty-client/arch.go @@ -5,10 +5,10 @@ package gottyclient import ( "encoding/json" "fmt" + "golang.org/x/sys/unix" "os" "os/signal" "syscall" - "unsafe" ) func notifySignalSIGWINCH(c chan<- os.Signal) { @@ -20,12 +20,10 @@ func resetSignalSIGWINCH() { } func syscallTIOCGWINSZ() ([]byte, error) { - ws := winsize{} - - syscall.Syscall(syscall.SYS_IOCTL, - uintptr(0), uintptr(syscall.TIOCGWINSZ), - uintptr(unsafe.Pointer(&ws))) - + ws, err := unix.IoctlGetWinsize(0, 0) + if err != nil { + return nil, fmt.Errorf("ioctl error: %v", err) + } b, err := json.Marshal(ws) if err != nil { return nil, fmt.Errorf("json.Marshal error: %v", err) diff --git a/vendor/github.com/moul/gotty-client/glide.lock b/vendor/github.com/moul/gotty-client/glide.lock deleted file mode 100644 index 61d5aeee3..000000000 --- a/vendor/github.com/moul/gotty-client/glide.lock +++ /dev/null @@ -1,37 +0,0 @@ -hash: 5ba4ef945563e8e85097f2699126b1577f9c667fdbbcdd71604e553ab7dd2a03 -updated: 2017-02-04T23:03:32.03375088+01:00 -imports: -- name: github.com/codegangsta/cli - version: 2ae9042f5bcbaf15b01229f8395ba8e72e01bded -- name: github.com/creack/goselect - version: 40085cf5fd629ccd88dc328895f1f137d09a1de4 -- name: github.com/gopherjs/gopherjs - version: db27c7c470d7404b6b201f82d6fd4821260bd13e - subpackages: - - js -- name: github.com/gorilla/websocket - version: 1f512fc3f05332ba7117626cdfb4e07474e58e60 -- name: github.com/jtolds/gls - version: 8ddce2a84170772b95dd5d576c48d517b22cac63 -- name: github.com/Sirupsen/logrus - version: cd7d1bbe41066b6c1f19780f895901052150a575 -- name: github.com/smartystreets/assertions - version: 40711f7748186bbf9c99977cd89f21ce1a229447 - subpackages: - - internal/go-render/render - - internal/oglematchers -- name: github.com/smartystreets/goconvey - version: d4c757aa9afd1e2fc1832aaab209b5794eb336e1 - subpackages: - - convey - - convey/gotest - - convey/reporting -- name: golang.org/x/crypto - version: 5bcd134fee4dd1475da17714aac19c0aa0142e2f - subpackages: - - ssh/terminal -- name: golang.org/x/sys - version: d4feaf1a7e61e1d9e79e6c4e76c6349e9cab0a03 - subpackages: - - unix -testImports: [] diff --git a/vendor/github.com/moul/gotty-client/glide.yaml b/vendor/github.com/moul/gotty-client/glide.yaml deleted file mode 100644 index 287efb9d8..000000000 --- a/vendor/github.com/moul/gotty-client/glide.yaml +++ /dev/null @@ -1,35 +0,0 @@ -package: github.com/moul/gotty-client -import: -- package: github.com/Sirupsen/logrus - version: cd7d1bbe41066b6c1f19780f895901052150a575 -- package: github.com/codegangsta/cli - version: 2ae9042f5bcbaf15b01229f8395ba8e72e01bded -- package: github.com/creack/goselect - version: 40085cf5fd629ccd88dc328895f1f137d09a1de4 -- package: github.com/gopherjs/gopherjs - version: db27c7c470d7404b6b201f82d6fd4821260bd13e - subpackages: - - js -- package: github.com/gorilla/websocket - version: 1f512fc3f05332ba7117626cdfb4e07474e58e60 -- package: github.com/jtolds/gls - version: 8ddce2a84170772b95dd5d576c48d517b22cac63 -- package: github.com/smartystreets/assertions - version: 40711f7748186bbf9c99977cd89f21ce1a229447 - subpackages: - - internal/go-render/render - - internal/oglematchers -- package: github.com/smartystreets/goconvey - version: d4c757aa9afd1e2fc1832aaab209b5794eb336e1 - subpackages: - - convey - - convey/gotest - - convey/reporting -- package: golang.org/x/crypto - version: 5bcd134fee4dd1475da17714aac19c0aa0142e2f - subpackages: - - ssh/terminal -- package: golang.org/x/sys - version: d4feaf1a7e61e1d9e79e6c4e76c6349e9cab0a03 - subpackages: - - unix diff --git a/vendor/github.com/moul/gotty-client/gotty-client.go b/vendor/github.com/moul/gotty-client/gotty-client.go index 35e599d9b..58f4a8547 100644 --- a/vendor/github.com/moul/gotty-client/gotty-client.go +++ b/vendor/github.com/moul/gotty-client/gotty-client.go @@ -15,9 +15,9 @@ import ( "sync" "time" - "github.com/Sirupsen/logrus" "github.com/creack/goselect" "github.com/gorilla/websocket" + "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh/terminal" ) @@ -82,6 +82,7 @@ type Client struct { SkipTLSVerify bool UseProxyFromEnv bool Connected bool + EscapeKeys []byte } type querySingleType struct { @@ -317,7 +318,6 @@ type exposeFd interface { } func (c *Client) writeLoop(wg *sync.WaitGroup) posionReason { - defer wg.Done() fname := "writeLoop" @@ -328,7 +328,11 @@ func (c *Client) writeLoop(wg *sync.WaitGroup) posionReason { } rdfs := &goselect.FDSet{} - reader := io.Reader(os.Stdin) + reader := io.ReadCloser(os.Stdin) + + pr := NewEscapeProxy(reader, c.EscapeKeys) + defer reader.Close() + for { select { case <-c.poison: @@ -344,7 +348,7 @@ func (c *Client) writeLoop(wg *sync.WaitGroup) posionReason { return openPoison(fname, c.poison) } if rdfs.IsSet(reader.(exposeFd).Fd()) { - size, err := reader.Read(buff) + size, err := pr.Read(buff) if err != nil { if err == io.EOF { diff --git a/vendor/github.com/moul/gotty-client/proxy.go b/vendor/github.com/moul/gotty-client/proxy.go new file mode 100644 index 000000000..e42143ca8 --- /dev/null +++ b/vendor/github.com/moul/gotty-client/proxy.go @@ -0,0 +1,90 @@ +// Copyright 2013-2017 Docker, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// CHANGES: +// - update package + + +package gottyclient + +import ( + "io" +) + +// EscapeError is special error which returned by a TTY proxy reader's Read() +// method in case its detach escape sequence is read. +type EscapeError struct{} + +func (EscapeError) Error() string { + return "read escape sequence" +} + +// escapeProxy is used only for attaches with a TTY. It is used to proxy +// stdin keypresses from the underlying reader and look for the passed in +// escape key sequence to signal a detach. +type escapeProxy struct { + escapeKeys []byte + escapeKeyPos int + r io.Reader +} + +// NewEscapeProxy returns a new TTY proxy reader which wraps the given reader +// and detects when the specified escape keys are read, in which case the Read +// method will return an error of type EscapeError. +func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader { + return &escapeProxy{ + escapeKeys: escapeKeys, + r: r, + } +} + +func (r *escapeProxy) Read(buf []byte) (int, error) { + nr, err := r.r.Read(buf) + + preserve := func() { + // this preserves the original key presses in the passed in buffer + nr += r.escapeKeyPos + preserve := make([]byte, 0, r.escapeKeyPos+len(buf)) + preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...) + preserve = append(preserve, buf...) + r.escapeKeyPos = 0 + copy(buf[0:nr], preserve) + } + + if nr != 1 || err != nil { + if r.escapeKeyPos > 0 { + preserve() + } + return nr, err + } + + if buf[0] != r.escapeKeys[r.escapeKeyPos] { + if r.escapeKeyPos > 0 { + preserve() + } + return nr, nil + } + + if r.escapeKeyPos == len(r.escapeKeys)-1 { + return 0, EscapeError{} + } + + // Looks like we've got an escape key, but we need to match again on the next + // read. + // Store the current escape key we found so we can look for the next one on + // the next read. + // Since this is an escape key, make sure we don't let the caller read it + // If later on we find that this is not the escape sequence, we'll add the + // keys back + r.escapeKeyPos++ + return nr - r.escapeKeyPos, nil +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md b/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md index 559a7018d..62dade6b9 100644 --- a/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/README.md @@ -1,25 +1,3 @@ # Scaleway's API -[![GoDoc](https://godoc.org/github.com/scaleway/scaleway-cli/pkg/api?status.svg)](https://godoc.org/github.com/scaleway/scaleway-cli/pkg/api) - -This package contains facilities to play with the Scaleway API, it includes the following features: - -- dedicated configuration file containing credentials to deal with the API -- caching to resolve UUIDs without contacting the API - -## Links - -- [API documentation](https://developer.scaleway.com) -- [Official Python SDK](https://github.com/scaleway/python-scaleway) -- Projects using this SDK - - https://github.com/scaleway/devhub - - https://github.com/scaleway/docker-machine-driver-scaleway - - https://github.com/scaleway-community/scaleway-ubuntu-coreos/blob/master/overlay/usr/local/update-firewall/scw-api/cache.go - - https://github.com/pulcy/quark - - https://github.com/hex-sh/terraform-provider-scaleway - - https://github.com/tscolari/bosh-scaleway-cpi -- Other **golang** clients - - https://github.com/lalyos/onlabs - - https://github.com/meatballhat/packer-builder-onlinelabs - - https://github.com/nlamirault/go-scaleway - - https://github.com/golang/build/blob/master/cmd/scaleway/scaleway.go +## Deprecated in favor of https://github.com/scaleway/go-scaleway diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go index 5ce0157dc..7c60d6624 100644 --- a/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/api.go @@ -52,6 +52,12 @@ func init() { if url := os.Getenv("SCW_MARKETPLACE_API"); url != "" { MarketplaceAPI = url } + if url := os.Getenv("SCW_COMPUTE_PAR1_API"); url != "" { + ComputeAPIPar1 = url + } + if url := os.Getenv("SCW_COMPUTE_AMS1_API"); url != "" { + ComputeAPIAms1 = url + } } const ( @@ -267,6 +273,42 @@ type ScalewayImages struct { Images []ScalewayImage `json:"images,omitempty"` } +// ProductNetworkInterface gives interval and external allowed bandwidth +type ProductNetworkInterface struct { + InternalBandwidth uint64 `json:"internal_bandwidth,omitempty"` + InternetBandwidth uint64 `json:"internet_bandwidth,omitempty"` +} + +// ProductNetwork lists all the network interfaces +type ProductNetwork struct { + Interfaces []ProductNetworkInterface `json:"interfaces,omitempty"` + TotalInternalBandwidth uint64 `json:"sum_internal_bandwidth,omitempty"` + TotalInternetBandwidth uint64 `json:"sum_internet_bandwidth,omitempty"` + IPv6_Support bool `json:"ipv6_support,omitempty"` +} + +// ProductVolumeConstraint contains any volume constraint that the offer has +type ProductVolumeConstraint struct { + MinSize uint64 `json:"min_size,omitempty"` + MaxSize uint64 `json:"max_size,omitempty"` +} + +// ProductServerOffer represents a specific offer +type ProductServer struct { + Arch string `json:"arch,omitempty"` + Ncpus uint64 `json:"ncpus,omitempty"` + Ram uint64 `json:"ram,omitempty"` + Baremetal bool `json:"baremetal,omitempty"` + VolumesConstraint ProductVolumeConstraint `json:"volumes_constraint,omitempty"` + AltNames []string `json:"alt_names,omitempty"` + Network ProductNetwork `json:"network,omitempty"` +} + +// Products holds a map of all Scaleway servers +type ScalewayProductsServers struct { + Servers map[string]ProductServer `json:"servers"` +} + // ScalewaySnapshot represents a Scaleway Snapshot type ScalewaySnapshot struct { // Identifier is a unique identifier for the snapshot @@ -708,6 +750,26 @@ type ScalewayConnect struct { Expires bool `json:"expires"` } +// ScalewayConnectInterface is the interface implemented by ScalewayConnect, +// ScalewayConnectByOTP and ScalewayConnectByBackupCode +type ScalewayConnectInterface interface { + GetPassword() string +} + +func (s *ScalewayConnect) GetPassword() string { + return s.Password +} + +type ScalewayConnectByOTP struct { + ScalewayConnect + TwoFAToken string `json:"2FA_token"` +} + +type ScalewayConnectByBackupCode struct { + ScalewayConnect + TwoFABackupCode string `json:"2FA_backup_code"` +} + // ScalewayOrganizationDefinition represents a Scaleway Organization type ScalewayOrganizationDefinition struct { ID string `json:"id"` @@ -1188,6 +1250,9 @@ func (s ScalewaySortServers) Less(i, j int) bool { // GetServer gets a server from the ScalewayAPI func (s *ScalewayAPI) GetServer(serverID string) (*ScalewayServer, error) { + if serverID == "" { + return nil, fmt.Errorf("cannot get server without serverID") + } resp, err := s.GetResponsePaginate(s.computeAPI, "servers/"+serverID, url.Values{}) if err != nil { return nil, err @@ -2752,3 +2817,24 @@ func (s *ScalewayAPI) ResolveTTYUrl() string { } return "" } + +// GetProductServers Fetches all the server type and their constraints from the Products API +func (s *ScalewayAPI) GetProductsServers() (*ScalewayProductsServers, error) { + resp, err := s.GetResponsePaginate(s.computeAPI, "products/servers", url.Values{}) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := s.handleHTTPError([]int{http.StatusOK}, resp) + if err != nil { + return nil, err + } + + var productServers ScalewayProductsServers + if err = json.Unmarshal(body, &productServers); err != nil { + return nil, err + } + + return &productServers, nil +} diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go index 1d9771a0e..0a57796e9 100644 --- a/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/cache.go @@ -239,12 +239,14 @@ func (c *ScalewayCache) Save() error { if err != nil { return err } - defer file.Close() + if err := json.NewEncoder(file).Encode(c); err != nil { + file.Close() os.Remove(file.Name()) return err } + file.Close() if err := os.Rename(file.Name(), c.Path); err != nil { os.Remove(file.Name()) return err diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go b/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go index 3a59e465d..dcd50d738 100644 --- a/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/api/helpers.go @@ -7,18 +7,19 @@ package api import ( "errors" "fmt" + "math" "os" "sort" "strings" "sync" "time" - "github.com/Sirupsen/logrus" - log "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/namesgenerator" "github.com/dustin/go-humanize" "github.com/moul/anonuuid" "github.com/scaleway/scaleway-cli/pkg/utils" + "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" ) // ScalewayResolvedIdentifier represents a list of matching identifier for a specifier pattern @@ -94,6 +95,36 @@ func CreateVolumeFromHumanSize(api *ScalewayAPI, size string) (*string, error) { return &volumeID, nil } +// VolumesFromSize returns a string of standard sized volumes from a given size +func VolumesFromSize(size uint64) string { + const DefaultVolumeSize float64 = 50000000000 + StdVolumeSizes := []struct { + kind string + capacity float64 + }{ + {"150G", 150000000000}, + {"100G", 100000000000}, + {"50G", 50000000000}, + } + + RequiredSize := float64(size) - DefaultVolumeSize + Volumes := "" + for _, v := range StdVolumeSizes { + q := RequiredSize / v.capacity + r := math.Mod(RequiredSize, v.capacity) + RequiredSize = r + + if q > 0 { + Volumes += strings.Repeat(v.kind+" ", int(q)) + } + if r == 0 { + break + } + } + + return strings.TrimSpace(Volumes) +} + // fillIdentifierCache fills the cache by fetching from the API func fillIdentifierCache(api *ScalewayAPI, identifierType int) { log.Debugf("Filling the cache") @@ -290,6 +321,25 @@ type ConfigCreateServer struct { EnableIPV6 bool } +// Return offer from any of the product name or alternate names +func OfferNameFromName(name string, products *ScalewayProductsServers) (*ProductServer, error) { + offer, ok := products.Servers[name] + if ok { + return &offer, nil + } + + for _, v := range products.Servers { + for _, alt := range v.AltNames { + alt := strings.ToUpper(alt) + if alt == name { + return &v, nil + } + } + } + + return nil, fmt.Errorf("Unknow commercial type: %v", name) +} + // CreateServer creates a server using API based on typical server fields func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) { commercialType := os.Getenv("SCW_COMMERCIAL_TYPE") @@ -306,7 +356,7 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) { var server ScalewayServerDefinition - server.CommercialType = commercialType + server.CommercialType = strings.ToUpper(commercialType) server.Volumes = make(map[string]string) server.DynamicIPRequired = &c.DynamicIPRequired server.EnableIPV6 = c.EnableIPV6 @@ -336,32 +386,19 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) { if c.Env != "" { server.Tags = strings.Split(c.Env, " ") } - switch c.CommercialType { - case "VC1M", "X64-4GB": - if c.AdditionalVolumes == "" { - c.AdditionalVolumes = "50G" - log.Debugf("This server needs a least 50G") - } - case "VC1L", "X64-8GB", "X64-15GB": - if c.AdditionalVolumes == "" { - c.AdditionalVolumes = "150G" - log.Debugf("This server needs a least 150G") - } - case "X64-30GB": - if c.AdditionalVolumes == "" { - c.AdditionalVolumes = "100G 150G" - log.Debugf("This server needs a least 300G") - } - case "X64-60GB": - if c.AdditionalVolumes == "" { - c.AdditionalVolumes = "50G 150G 150G" - log.Debugf("This server needs a least 400G") - } - case "X64-120GB": - if c.AdditionalVolumes == "" { - c.AdditionalVolumes = "150G 150G 150G" - log.Debugf("This server needs a least 500G") - } + + products, err := api.GetProductsServers() + if err != nil { + return "", fmt.Errorf("Unable to fetch products list from the Scaleway API: %v", err) + } + offer, err := OfferNameFromName(server.CommercialType, products) + if err != nil { + return "", fmt.Errorf("Unknow commercial type %v: %v", server.CommercialType, err) + } + if offer.VolumesConstraint.MinSize > 0 && c.AdditionalVolumes == "" { + c.AdditionalVolumes = VolumesFromSize(offer.VolumesConstraint.MinSize) + log.Debugf("%s needs at least %s. Automatically creates the following volumes: %s", + server.CommercialType, humanize.Bytes(offer.VolumesConstraint.MinSize), c.AdditionalVolumes) } if c.AdditionalVolumes != "" { volumes := strings.Split(c.AdditionalVolumes, " ") @@ -375,24 +412,17 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) { server.Volumes[volumeIDx] = *volumeID } } + arch := os.Getenv("SCW_TARGET_ARCH") if arch == "" { - server.CommercialType = strings.ToUpper(server.CommercialType) - switch server.CommercialType[:2] { - case "C1": - arch = "arm" - case "C2", "VC", "X6": - arch = "x86_64" - default: - return "", fmt.Errorf("%s wrong commercial type", server.CommercialType) - } + arch = offer.Arch } imageIdentifier := &ScalewayImageIdentifier{ Arch: arch, } server.Name = c.Name inheritingVolume := false - _, err := humanize.ParseBytes(c.ImageName) + _, err = humanize.ParseBytes(c.ImageName) if err == nil { // Create a new root volume volumeID, errCreateVol := CreateVolumeFromHumanSize(api, c.ImageName) @@ -536,7 +566,11 @@ func WaitForServerReady(api *ScalewayAPI, serverID, gateway string) (*ScalewaySe } if gateway == "" { - dest := fmt.Sprintf("%s:22", server.PublicAddress.IP) + ip := server.PublicAddress.IP + if ip == "" && server.EnableIPV6 { + ip = fmt.Sprintf("[%s]", server.IPV6.Address) + } + dest := fmt.Sprintf("%s:22", ip) log.Debugf("Waiting for server SSH port %s", dest) err = utils.WaitForTCPPortOpen(dest) if err != nil { diff --git a/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go b/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go index 6f11f4869..126d9c834 100644 --- a/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go +++ b/vendor/github.com/scaleway/scaleway-cli/pkg/utils/utils.go @@ -24,11 +24,11 @@ import ( "golang.org/x/crypto/ssh" - "github.com/Sirupsen/logrus" - log "github.com/Sirupsen/logrus" "github.com/mattn/go-isatty" "github.com/moul/gotty-client" "github.com/scaleway/scaleway-cli/pkg/sshcommand" + "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" ) // SpawnRedirection is used to redirects the fluxes diff --git a/vendor/github.com/sirupsen/logrus/appveyor.yml b/vendor/github.com/sirupsen/logrus/appveyor.yml new file mode 100644 index 000000000..96c2ce15f --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/appveyor.yml @@ -0,0 +1,14 @@ +version: "{build}" +platform: x64 +clone_folder: c:\gopath\src\github.com\sirupsen\logrus +environment: + GOPATH: c:\gopath +branches: + only: + - master +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version +build_script: + - go get -t + - go test diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go new file mode 100644 index 000000000..3de08e802 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go @@ -0,0 +1,11 @@ +// +build appengine gopherjs + +package logrus + +import ( + "io" +) + +func checkIfTerminal(w io.Writer) bool { + return true +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go new file mode 100644 index 000000000..067047a12 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go @@ -0,0 +1,19 @@ +// +build !appengine,!gopherjs + +package logrus + +import ( + "io" + "os" + + "golang.org/x/crypto/ssh/terminal" +) + +func checkIfTerminal(w io.Writer) bool { + switch v := w.(type) { + case *os.File: + return terminal.IsTerminal(int(v.Fd())) + default: + return false + } +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go index 18379a935..9a887598f 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go @@ -617,7 +617,7 @@ func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) { if _, err = w.Write(crlf); err != nil { return n, err } - n += 1 + n++ buf = buf[1:] } } diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go index d01919614..731c89a28 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util.go @@ -17,40 +17,41 @@ package terminal // import "golang.org/x/crypto/ssh/terminal" import ( - "syscall" - "unsafe" + "golang.org/x/sys/unix" ) // State contains the state of a terminal. type State struct { - termios syscall.Termios + termios unix.Termios } // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd int) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 + _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + return err == nil } // MakeRaw put the terminal connected to the given file descriptor into raw // mode and returns the previous state of the terminal so that it can be // restored. func MakeRaw(fd int) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { return nil, err } - newState := oldState.termios + oldState := State{termios: *termios} + // This attempts to replicate the behaviour documented for cfmakeraw in // the termios(3) manpage. - newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON - newState.Oflag &^= syscall.OPOST - newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN - newState.Cflag &^= syscall.CSIZE | syscall.PARENB - newState.Cflag |= syscall.CS8 - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { + termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON + termios.Oflag &^= unix.OPOST + termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN + termios.Cflag &^= unix.CSIZE | unix.PARENB + termios.Cflag |= unix.CS8 + termios.Cc[unix.VMIN] = 1 + termios.Cc[unix.VTIME] = 0 + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil { return nil, err } @@ -60,60 +61,54 @@ func MakeRaw(fd int) (*State, error) { // GetState returns the current state of a terminal which may be useful to // restore the terminal after a signal. func GetState(fd int) (*State, error) { - var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { return nil, err } - return &oldState, nil + return &State{termios: *termios}, nil } // Restore restores the terminal connected to the given file descriptor to a // previous state. func Restore(fd int, state *State) error { - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0); err != 0 { - return err - } - return nil + return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios) } // GetSize returns the dimensions of the given terminal. func GetSize(fd int) (width, height int, err error) { - var dimensions [4]uint16 - - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { return -1, -1, err } - return int(dimensions[1]), int(dimensions[0]), nil + return int(ws.Col), int(ws.Row), nil } // passwordReader is an io.Reader that reads from a specific file descriptor. type passwordReader int func (r passwordReader) Read(buf []byte) (int, error) { - return syscall.Read(int(r), buf) + return unix.Read(int(r), buf) } // ReadPassword reads a line of input from a terminal without local echo. This // is commonly used for inputting passwords and other sensitive data. The slice // returned does not include the \n. func ReadPassword(fd int) ([]byte, error) { - var oldState syscall.Termios - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { + termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) + if err != nil { return nil, err } - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { + newState := *termios + newState.Lflag &^= unix.ECHO + newState.Lflag |= unix.ICANON | unix.ISIG + newState.Iflag |= unix.ICRNL + if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil { return nil, err } - defer func() { - syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) - }() + defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios) return readPasswordLine(passwordReader(fd)) } diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go index 9c1ffd145..cb23a5904 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go @@ -6,7 +6,7 @@ package terminal -import "syscall" +import "golang.org/x/sys/unix" -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA +const ioctlReadTermios = unix.TIOCGETA +const ioctlWriteTermios = unix.TIOCSETA diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go index 5883b22d7..5fadfe8a1 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go @@ -4,8 +4,7 @@ package terminal -// These constants are declared here, rather than importing -// them from the syscall package as some syscall packages, even -// on linux, for example gccgo, do not declare them. -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS +import "golang.org/x/sys/unix" + +const ioctlReadTermios = unix.TCGETS +const ioctlWriteTermios = unix.TCSETS diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go index 07eb5edd7..9e41b9f43 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go @@ -14,14 +14,12 @@ import ( // State contains the state of a terminal. type State struct { - termios syscall.Termios + termios unix.Termios } // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd int) bool { - // see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c - var termio unix.Termio - err := unix.IoctlSetTermio(fd, unix.TCGETA, &termio) + _, err := unix.IoctlGetTermio(fd, unix.TCGETA) return err == nil } @@ -71,3 +69,56 @@ func ReadPassword(fd int) ([]byte, error) { return ret, nil } + +// MakeRaw puts the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +// see http://cr.illumos.org/~webrev/andy_js/1060/ +func MakeRaw(fd int) (*State, error) { + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + + oldState := State{termios: *termios} + + termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON + termios.Oflag &^= unix.OPOST + termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN + termios.Cflag &^= unix.CSIZE | unix.PARENB + termios.Cflag |= unix.CS8 + termios.Cc[unix.VMIN] = 1 + termios.Cc[unix.VTIME] = 0 + + if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil { + return nil, err + } + + return &oldState, nil +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, oldState *State) error { + return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios) +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) + if err != nil { + return nil, err + } + + return &State{termios: *termios}, nil +} + +// GetSize returns the dimensions of the given terminal. +func GetSize(fd int) (width, height int, err error) { + ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { + return 0, 0, err + } + return int(ws.Col), int(ws.Row), nil +} diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go index e0a1f36ce..8618955df 100644 --- a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go +++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go @@ -17,53 +17,9 @@ package terminal import ( - "syscall" - "unsafe" -) + "os" -const ( - enableLineInput = 2 - enableEchoInput = 4 - enableProcessedInput = 1 - enableWindowInput = 8 - enableMouseInput = 16 - enableInsertMode = 32 - enableQuickEditMode = 64 - enableExtendedFlags = 128 - enableAutoPosition = 256 - enableProcessedOutput = 1 - enableWrapAtEolOutput = 2 -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procSetConsoleMode = kernel32.NewProc("SetConsoleMode") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") -) - -type ( - short int16 - word uint16 - - coord struct { - x short - y short - } - smallRect struct { - left short - top short - right short - bottom short - } - consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord - } + "golang.org/x/sys/windows" ) type State struct { @@ -73,8 +29,8 @@ type State struct { // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd int) bool { var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 + err := windows.GetConsoleMode(windows.Handle(fd), &st) + return err == nil } // MakeRaw put the terminal connected to the given file descriptor into raw @@ -82,14 +38,12 @@ func IsTerminal(fd int) bool { // restored. func MakeRaw(fd int) (*State, error) { var st uint32 - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - if e != 0 { - return nil, error(e) + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err } - raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) - _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0) - if e != 0 { - return nil, error(e) + raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { + return nil, err } return &State{st}, nil } @@ -98,9 +52,8 @@ func MakeRaw(fd int) (*State, error) { // restore the terminal after a signal. func GetState(fd int) (*State, error) { var st uint32 - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - if e != 0 { - return nil, error(e) + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err } return &State{st}, nil } @@ -108,25 +61,16 @@ func GetState(fd int) (*State, error) { // Restore restores the terminal connected to the given file descriptor to a // previous state. func Restore(fd int, state *State) error { - _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0) - return err + return windows.SetConsoleMode(windows.Handle(fd), state.mode) } // GetSize returns the dimensions of the given terminal. func GetSize(fd int) (width, height int, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return 0, 0, error(e) + var info windows.ConsoleScreenBufferInfo + if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { + return 0, 0, err } - return int(info.size.x), int(info.size.y), nil -} - -// passwordReader is an io.Reader that reads from a specific Windows HANDLE. -type passwordReader int - -func (r passwordReader) Read(buf []byte) (int, error) { - return syscall.Read(syscall.Handle(r), buf) + return int(info.Size.X), int(info.Size.Y), nil } // ReadPassword reads a line of input from a terminal without local echo. This @@ -134,22 +78,26 @@ func (r passwordReader) Read(buf []byte) (int, error) { // returned does not include the \n. func ReadPassword(fd int) ([]byte, error) { var st uint32 - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - if e != 0 { - return nil, error(e) + if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { + return nil, err } old := st - st &^= (enableEchoInput) - st |= (enableProcessedInput | enableLineInput | enableProcessedOutput) - _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) - if e != 0 { - return nil, error(e) + st &^= (windows.ENABLE_ECHO_INPUT) + st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil { + return nil, err } - defer func() { - syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0) - }() + defer windows.SetConsoleMode(windows.Handle(fd), old) - return readPasswordLine(passwordReader(fd)) + var h windows.Handle + p, _ := windows.GetCurrentProcess() + if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil { + return nil, err + } + + f := os.NewFile(uintptr(h), "stdin") + defer f.Close() + return readPasswordLine(f) } diff --git a/vendor/golang.org/x/sys/unix/affinity_linux.go b/vendor/golang.org/x/sys/unix/affinity_linux.go new file mode 100644 index 000000000..72afe3338 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/affinity_linux.go @@ -0,0 +1,124 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// CPU affinity functions + +package unix + +import ( + "unsafe" +) + +const cpuSetSize = _CPU_SETSIZE / _NCPUBITS + +// CPUSet represents a CPU affinity mask. +type CPUSet [cpuSetSize]cpuMask + +func schedAffinity(trap uintptr, pid int, set *CPUSet) error { + _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set))) + if e != 0 { + return errnoErr(e) + } + return nil +} + +// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid. +// If pid is 0 the calling thread is used. +func SchedGetaffinity(pid int, set *CPUSet) error { + return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set) +} + +// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid. +// If pid is 0 the calling thread is used. +func SchedSetaffinity(pid int, set *CPUSet) error { + return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set) +} + +// Zero clears the set s, so that it contains no CPUs. +func (s *CPUSet) Zero() { + for i := range s { + s[i] = 0 + } +} + +func cpuBitsIndex(cpu int) int { + return cpu / _NCPUBITS +} + +func cpuBitsMask(cpu int) cpuMask { + return cpuMask(1 << (uint(cpu) % _NCPUBITS)) +} + +// Set adds cpu to the set s. +func (s *CPUSet) Set(cpu int) { + i := cpuBitsIndex(cpu) + if i < len(s) { + s[i] |= cpuBitsMask(cpu) + } +} + +// Clear removes cpu from the set s. +func (s *CPUSet) Clear(cpu int) { + i := cpuBitsIndex(cpu) + if i < len(s) { + s[i] &^= cpuBitsMask(cpu) + } +} + +// IsSet reports whether cpu is in the set s. +func (s *CPUSet) IsSet(cpu int) bool { + i := cpuBitsIndex(cpu) + if i < len(s) { + return s[i]&cpuBitsMask(cpu) != 0 + } + return false +} + +// Count returns the number of CPUs in the set s. +func (s *CPUSet) Count() int { + c := 0 + for _, b := range s { + c += onesCount64(uint64(b)) + } + return c +} + +// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64. +// Once this package can require Go 1.9, we can delete this +// and update the caller to use bits.OnesCount64. +func onesCount64(x uint64) int { + const m0 = 0x5555555555555555 // 01010101 ... + const m1 = 0x3333333333333333 // 00110011 ... + const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ... + const m3 = 0x00ff00ff00ff00ff // etc. + const m4 = 0x0000ffff0000ffff + + // Implementation: Parallel summing of adjacent bits. + // See "Hacker's Delight", Chap. 5: Counting Bits. + // The following pattern shows the general approach: + // + // x = x>>1&(m0&m) + x&(m0&m) + // x = x>>2&(m1&m) + x&(m1&m) + // x = x>>4&(m2&m) + x&(m2&m) + // x = x>>8&(m3&m) + x&(m3&m) + // x = x>>16&(m4&m) + x&(m4&m) + // x = x>>32&(m5&m) + x&(m5&m) + // return int(x) + // + // Masking (& operations) can be left away when there's no + // danger that a field's sum will carry over into the next + // field: Since the result cannot be > 64, 8 bits is enough + // and we can ignore the masks for the shifts by 8 and up. + // Per "Hacker's Delight", the first line can be simplified + // more, but it saves at best one instruction, so we leave + // it alone for clarity. + const m = 1<<64 - 1 + x = x>>1&(m0&m) + x&(m0&m) + x = x>>2&(m1&m) + x&(m1&m) + x = (x>>4 + x) & (m2 & m) + x += x >> 8 + x += x >> 16 + x += x >> 32 + return int(x) & (1<<7 - 1) +} diff --git a/vendor/golang.org/x/sys/unix/asm_linux_386.s b/vendor/golang.org/x/sys/unix/asm_linux_386.s index 4db290932..448bebbb5 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_386.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_386.s @@ -10,21 +10,51 @@ // System calls for 386, Linux // +// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80 +// instead of the glibc-specific "CALL 0x10(GS)". +#define INVOKE_SYSCALL INT $0x80 + // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-28 +TEXT ·Syscall(SB),NOSPLIT,$0-28 JMP syscall·Syscall(SB) -TEXT ·Syscall6(SB),NOSPLIT,$0-40 +TEXT ·Syscall6(SB),NOSPLIT,$0-40 JMP syscall·Syscall6(SB) +TEXT ·SyscallNoError(SB),NOSPLIT,$0-24 + CALL runtime·entersyscall(SB) + MOVL trap+0(FP), AX // syscall entry + MOVL a1+4(FP), BX + MOVL a2+8(FP), CX + MOVL a3+12(FP), DX + MOVL $0, SI + MOVL $0, DI + INVOKE_SYSCALL + MOVL AX, r1+16(FP) + MOVL DX, r2+20(FP) + CALL runtime·exitsyscall(SB) + RET + TEXT ·RawSyscall(SB),NOSPLIT,$0-28 JMP syscall·RawSyscall(SB) -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 +TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 JMP syscall·RawSyscall6(SB) +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24 + MOVL trap+0(FP), AX // syscall entry + MOVL a1+4(FP), BX + MOVL a2+8(FP), CX + MOVL a3+12(FP), DX + MOVL $0, SI + MOVL $0, DI + INVOKE_SYSCALL + MOVL AX, r1+16(FP) + MOVL DX, r2+20(FP) + RET + TEXT ·socketcall(SB),NOSPLIT,$0-36 JMP syscall·socketcall(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_linux_amd64.s b/vendor/golang.org/x/sys/unix/asm_linux_amd64.s index 44e25c62f..c6468a958 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_amd64.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_amd64.s @@ -13,17 +13,45 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-56 +TEXT ·Syscall(SB),NOSPLIT,$0-56 JMP syscall·Syscall(SB) TEXT ·Syscall6(SB),NOSPLIT,$0-80 JMP syscall·Syscall6(SB) +TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 + CALL runtime·entersyscall(SB) + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ $0, R10 + MOVQ $0, R8 + MOVQ $0, R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + MOVQ AX, r1+32(FP) + MOVQ DX, r2+40(FP) + CALL runtime·exitsyscall(SB) + RET + TEXT ·RawSyscall(SB),NOSPLIT,$0-56 JMP syscall·RawSyscall(SB) TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 JMP syscall·RawSyscall6(SB) +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ $0, R10 + MOVQ $0, R8 + MOVQ $0, R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + MOVQ AX, r1+32(FP) + MOVQ DX, r2+40(FP) + RET + TEXT ·gettimeofday(SB),NOSPLIT,$0-16 JMP syscall·gettimeofday(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_linux_arm.s b/vendor/golang.org/x/sys/unix/asm_linux_arm.s index cf0b57465..cf0f3575c 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_arm.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_arm.s @@ -13,17 +13,44 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-28 +TEXT ·Syscall(SB),NOSPLIT,$0-28 B syscall·Syscall(SB) -TEXT ·Syscall6(SB),NOSPLIT,$0-40 +TEXT ·Syscall6(SB),NOSPLIT,$0-40 B syscall·Syscall6(SB) +TEXT ·SyscallNoError(SB),NOSPLIT,$0-24 + BL runtime·entersyscall(SB) + MOVW trap+0(FP), R7 + MOVW a1+4(FP), R0 + MOVW a2+8(FP), R1 + MOVW a3+12(FP), R2 + MOVW $0, R3 + MOVW $0, R4 + MOVW $0, R5 + SWI $0 + MOVW R0, r1+16(FP) + MOVW $0, R0 + MOVW R0, r2+20(FP) + BL runtime·exitsyscall(SB) + RET + TEXT ·RawSyscall(SB),NOSPLIT,$0-28 B syscall·RawSyscall(SB) -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 +TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 B syscall·RawSyscall6(SB) -TEXT ·seek(SB),NOSPLIT,$0-32 +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24 + MOVW trap+0(FP), R7 // syscall entry + MOVW a1+4(FP), R0 + MOVW a2+8(FP), R1 + MOVW a3+12(FP), R2 + SWI $0 + MOVW R0, r1+16(FP) + MOVW $0, R0 + MOVW R0, r2+20(FP) + RET + +TEXT ·seek(SB),NOSPLIT,$0-28 B syscall·seek(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_linux_arm64.s b/vendor/golang.org/x/sys/unix/asm_linux_arm64.s index 4be9bfede..afe6fdf6b 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_arm64.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_arm64.s @@ -11,14 +11,42 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-56 +TEXT ·Syscall(SB),NOSPLIT,$0-56 B syscall·Syscall(SB) TEXT ·Syscall6(SB),NOSPLIT,$0-80 B syscall·Syscall6(SB) +TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 + BL runtime·entersyscall(SB) + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD $0, R3 + MOVD $0, R4 + MOVD $0, R5 + MOVD trap+0(FP), R8 // syscall entry + SVC + MOVD R0, r1+32(FP) // r1 + MOVD R1, r2+40(FP) // r2 + BL runtime·exitsyscall(SB) + RET + TEXT ·RawSyscall(SB),NOSPLIT,$0-56 B syscall·RawSyscall(SB) TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 B syscall·RawSyscall6(SB) + +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 + MOVD a1+8(FP), R0 + MOVD a2+16(FP), R1 + MOVD a3+24(FP), R2 + MOVD $0, R3 + MOVD $0, R4 + MOVD $0, R5 + MOVD trap+0(FP), R8 // syscall entry + SVC + MOVD R0, r1+32(FP) + MOVD R1, r2+40(FP) + RET diff --git a/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s b/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s index 724e580c4..ab9d63831 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s @@ -15,14 +15,42 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-56 +TEXT ·Syscall(SB),NOSPLIT,$0-56 JMP syscall·Syscall(SB) -TEXT ·Syscall6(SB),NOSPLIT,$0-80 +TEXT ·Syscall6(SB),NOSPLIT,$0-80 JMP syscall·Syscall6(SB) -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 +TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 + JAL runtime·entersyscall(SB) + MOVV a1+8(FP), R4 + MOVV a2+16(FP), R5 + MOVV a3+24(FP), R6 + MOVV R0, R7 + MOVV R0, R8 + MOVV R0, R9 + MOVV trap+0(FP), R2 // syscall entry + SYSCALL + MOVV R2, r1+32(FP) + MOVV R3, r2+40(FP) + JAL runtime·exitsyscall(SB) + RET + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 JMP syscall·RawSyscall(SB) -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 JMP syscall·RawSyscall6(SB) + +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 + MOVV a1+8(FP), R4 + MOVV a2+16(FP), R5 + MOVV a3+24(FP), R6 + MOVV R0, R7 + MOVV R0, R8 + MOVV R0, R9 + MOVV trap+0(FP), R2 // syscall entry + SYSCALL + MOVV R2, r1+32(FP) + MOVV R3, r2+40(FP) + RET diff --git a/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s b/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s index 2ea425755..99e539904 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s @@ -15,17 +15,40 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-28 +TEXT ·Syscall(SB),NOSPLIT,$0-28 JMP syscall·Syscall(SB) -TEXT ·Syscall6(SB),NOSPLIT,$0-40 +TEXT ·Syscall6(SB),NOSPLIT,$0-40 JMP syscall·Syscall6(SB) -TEXT ·Syscall9(SB),NOSPLIT,$0-52 +TEXT ·Syscall9(SB),NOSPLIT,$0-52 JMP syscall·Syscall9(SB) -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 +TEXT ·SyscallNoError(SB),NOSPLIT,$0-24 + JAL runtime·entersyscall(SB) + MOVW a1+4(FP), R4 + MOVW a2+8(FP), R5 + MOVW a3+12(FP), R6 + MOVW R0, R7 + MOVW trap+0(FP), R2 // syscall entry + SYSCALL + MOVW R2, r1+16(FP) // r1 + MOVW R3, r2+20(FP) // r2 + JAL runtime·exitsyscall(SB) + RET + +TEXT ·RawSyscall(SB),NOSPLIT,$0-28 JMP syscall·RawSyscall(SB) -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 +TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 JMP syscall·RawSyscall6(SB) + +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24 + MOVW a1+4(FP), R4 + MOVW a2+8(FP), R5 + MOVW a3+12(FP), R6 + MOVW trap+0(FP), R2 // syscall entry + SYSCALL + MOVW R2, r1+16(FP) + MOVW R3, r2+20(FP) + RET diff --git a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s index 8d231feb4..649e58714 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s @@ -15,14 +15,42 @@ // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. -TEXT ·Syscall(SB),NOSPLIT,$0-56 +TEXT ·Syscall(SB),NOSPLIT,$0-56 BR syscall·Syscall(SB) TEXT ·Syscall6(SB),NOSPLIT,$0-80 BR syscall·Syscall6(SB) +TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 + BL runtime·entersyscall(SB) + MOVD a1+8(FP), R3 + MOVD a2+16(FP), R4 + MOVD a3+24(FP), R5 + MOVD R0, R6 + MOVD R0, R7 + MOVD R0, R8 + MOVD trap+0(FP), R9 // syscall entry + SYSCALL R9 + MOVD R3, r1+32(FP) + MOVD R4, r2+40(FP) + BL runtime·exitsyscall(SB) + RET + TEXT ·RawSyscall(SB),NOSPLIT,$0-56 BR syscall·RawSyscall(SB) TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 BR syscall·RawSyscall6(SB) + +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 + MOVD a1+8(FP), R3 + MOVD a2+16(FP), R4 + MOVD a3+24(FP), R5 + MOVD R0, R6 + MOVD R0, R7 + MOVD R0, R8 + MOVD trap+0(FP), R9 // syscall entry + SYSCALL R9 + MOVD R3, r1+32(FP) + MOVD R4, r2+40(FP) + RET diff --git a/vendor/golang.org/x/sys/unix/asm_linux_s390x.s b/vendor/golang.org/x/sys/unix/asm_linux_s390x.s index 11889859f..a5a863c6b 100644 --- a/vendor/golang.org/x/sys/unix/asm_linux_s390x.s +++ b/vendor/golang.org/x/sys/unix/asm_linux_s390x.s @@ -21,8 +21,36 @@ TEXT ·Syscall(SB),NOSPLIT,$0-56 TEXT ·Syscall6(SB),NOSPLIT,$0-80 BR syscall·Syscall6(SB) +TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 + BL runtime·entersyscall(SB) + MOVD a1+8(FP), R2 + MOVD a2+16(FP), R3 + MOVD a3+24(FP), R4 + MOVD $0, R5 + MOVD $0, R6 + MOVD $0, R7 + MOVD trap+0(FP), R1 // syscall entry + SYSCALL + MOVD R2, r1+32(FP) + MOVD R3, r2+40(FP) + BL runtime·exitsyscall(SB) + RET + TEXT ·RawSyscall(SB),NOSPLIT,$0-56 BR syscall·RawSyscall(SB) TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 BR syscall·RawSyscall6(SB) + +TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 + MOVD a1+8(FP), R2 + MOVD a2+16(FP), R3 + MOVD a3+24(FP), R4 + MOVD $0, R5 + MOVD $0, R6 + MOVD $0, R7 + MOVD trap+0(FP), R1 // syscall entry + SYSCALL + MOVD R2, r1+32(FP) + MOVD R3, r2+40(FP) + RET diff --git a/vendor/golang.org/x/sys/unix/dev_darwin.go b/vendor/golang.org/x/sys/unix/dev_darwin.go new file mode 100644 index 000000000..8d1dc0fa3 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/dev_darwin.go @@ -0,0 +1,24 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Functions to access/create device major and minor numbers matching the +// encoding used in Darwin's sys/types.h header. + +package unix + +// Major returns the major component of a Darwin device number. +func Major(dev uint64) uint32 { + return uint32((dev >> 24) & 0xff) +} + +// Minor returns the minor component of a Darwin device number. +func Minor(dev uint64) uint32 { + return uint32(dev & 0xffffff) +} + +// Mkdev returns a Darwin device number generated from the given major and minor +// components. +func Mkdev(major, minor uint32) uint64 { + return (uint64(major) << 24) | uint64(minor) +} diff --git a/vendor/golang.org/x/sys/unix/dev_dragonfly.go b/vendor/golang.org/x/sys/unix/dev_dragonfly.go new file mode 100644 index 000000000..8502f202c --- /dev/null +++ b/vendor/golang.org/x/sys/unix/dev_dragonfly.go @@ -0,0 +1,30 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Functions to access/create device major and minor numbers matching the +// encoding used in Dragonfly's sys/types.h header. +// +// The information below is extracted and adapted from sys/types.h: +// +// Minor gives a cookie instead of an index since in order to avoid changing the +// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for +// devices that don't use them. + +package unix + +// Major returns the major component of a DragonFlyBSD device number. +func Major(dev uint64) uint32 { + return uint32((dev >> 8) & 0xff) +} + +// Minor returns the minor component of a DragonFlyBSD device number. +func Minor(dev uint64) uint32 { + return uint32(dev & 0xffff00ff) +} + +// Mkdev returns a DragonFlyBSD device number generated from the given major and +// minor components. +func Mkdev(major, minor uint32) uint64 { + return (uint64(major) << 8) | uint64(minor) +} diff --git a/vendor/golang.org/x/sys/unix/dev_freebsd.go b/vendor/golang.org/x/sys/unix/dev_freebsd.go new file mode 100644 index 000000000..eba3b4bd3 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/dev_freebsd.go @@ -0,0 +1,30 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Functions to access/create device major and minor numbers matching the +// encoding used in FreeBSD's sys/types.h header. +// +// The information below is extracted and adapted from sys/types.h: +// +// Minor gives a cookie instead of an index since in order to avoid changing the +// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for +// devices that don't use them. + +package unix + +// Major returns the major component of a FreeBSD device number. +func Major(dev uint64) uint32 { + return uint32((dev >> 8) & 0xff) +} + +// Minor returns the minor component of a FreeBSD device number. +func Minor(dev uint64) uint32 { + return uint32(dev & 0xffff00ff) +} + +// Mkdev returns a FreeBSD device number generated from the given major and +// minor components. +func Mkdev(major, minor uint32) uint64 { + return (uint64(major) << 8) | uint64(minor) +} diff --git a/vendor/golang.org/x/sys/unix/dev_linux.go b/vendor/golang.org/x/sys/unix/dev_linux.go index c902c39e8..d165d6f30 100644 --- a/vendor/golang.org/x/sys/unix/dev_linux.go +++ b/vendor/golang.org/x/sys/unix/dev_linux.go @@ -34,9 +34,9 @@ func Minor(dev uint64) uint32 { // Mkdev returns a Linux device number generated from the given major and minor // components. func Mkdev(major, minor uint32) uint64 { - dev := uint64((major & 0x00000fff) << 8) - dev |= uint64((major & 0xfffff000) << 32) - dev |= uint64((minor & 0x000000ff) << 0) - dev |= uint64((minor & 0xffffff00) << 12) + dev := (uint64(major) & 0x00000fff) << 8 + dev |= (uint64(major) & 0xfffff000) << 32 + dev |= (uint64(minor) & 0x000000ff) << 0 + dev |= (uint64(minor) & 0xffffff00) << 12 return dev } diff --git a/vendor/golang.org/x/sys/unix/dev_netbsd.go b/vendor/golang.org/x/sys/unix/dev_netbsd.go new file mode 100644 index 000000000..b4a203d0c --- /dev/null +++ b/vendor/golang.org/x/sys/unix/dev_netbsd.go @@ -0,0 +1,29 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Functions to access/create device major and minor numbers matching the +// encoding used in NetBSD's sys/types.h header. + +package unix + +// Major returns the major component of a NetBSD device number. +func Major(dev uint64) uint32 { + return uint32((dev & 0x000fff00) >> 8) +} + +// Minor returns the minor component of a NetBSD device number. +func Minor(dev uint64) uint32 { + minor := uint32((dev & 0x000000ff) >> 0) + minor |= uint32((dev & 0xfff00000) >> 12) + return minor +} + +// Mkdev returns a NetBSD device number generated from the given major and minor +// components. +func Mkdev(major, minor uint32) uint64 { + dev := (uint64(major) << 8) & 0x000fff00 + dev |= (uint64(minor) << 12) & 0xfff00000 + dev |= (uint64(minor) << 0) & 0x000000ff + return dev +} diff --git a/vendor/golang.org/x/sys/unix/dev_openbsd.go b/vendor/golang.org/x/sys/unix/dev_openbsd.go new file mode 100644 index 000000000..f3430c42f --- /dev/null +++ b/vendor/golang.org/x/sys/unix/dev_openbsd.go @@ -0,0 +1,29 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Functions to access/create device major and minor numbers matching the +// encoding used in OpenBSD's sys/types.h header. + +package unix + +// Major returns the major component of an OpenBSD device number. +func Major(dev uint64) uint32 { + return uint32((dev & 0x0000ff00) >> 8) +} + +// Minor returns the minor component of an OpenBSD device number. +func Minor(dev uint64) uint32 { + minor := uint32((dev & 0x000000ff) >> 0) + minor |= uint32((dev & 0xffff0000) >> 8) + return minor +} + +// Mkdev returns an OpenBSD device number generated from the given major and minor +// components. +func Mkdev(major, minor uint32) uint64 { + dev := (uint64(major) << 8) & 0x0000ff00 + dev |= (uint64(minor) << 8) & 0xffff0000 + dev |= (uint64(minor) << 0) & 0x000000ff + return dev +} diff --git a/vendor/golang.org/x/sys/unix/dirent.go b/vendor/golang.org/x/sys/unix/dirent.go index bd475812b..95fd35317 100644 --- a/vendor/golang.org/x/sys/unix/dirent.go +++ b/vendor/golang.org/x/sys/unix/dirent.go @@ -6,97 +6,12 @@ package unix -import "unsafe" - -// readInt returns the size-bytes unsigned integer in native byte order at offset off. -func readInt(b []byte, off, size uintptr) (u uint64, ok bool) { - if len(b) < int(off+size) { - return 0, false - } - if isBigEndian { - return readIntBE(b[off:], size), true - } - return readIntLE(b[off:], size), true -} - -func readIntBE(b []byte, size uintptr) uint64 { - switch size { - case 1: - return uint64(b[0]) - case 2: - _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[1]) | uint64(b[0])<<8 - case 4: - _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24 - case 8: - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | - uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 - default: - panic("syscall: readInt with unsupported size") - } -} - -func readIntLE(b []byte, size uintptr) uint64 { - switch size { - case 1: - return uint64(b[0]) - case 2: - _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 - case 4: - _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 - case 8: - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - default: - panic("syscall: readInt with unsupported size") - } -} +import "syscall" // ParseDirent parses up to max directory entries in buf, // appending the names to names. It returns the number of // bytes consumed from buf, the number of entries added // to names, and the new names slice. func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { - origlen := len(buf) - count = 0 - for max != 0 && len(buf) > 0 { - reclen, ok := direntReclen(buf) - if !ok || reclen > uint64(len(buf)) { - return origlen, count, names - } - rec := buf[:reclen] - buf = buf[reclen:] - ino, ok := direntIno(rec) - if !ok { - break - } - if ino == 0 { // File absent in directory. - continue - } - const namoff = uint64(unsafe.Offsetof(Dirent{}.Name)) - namlen, ok := direntNamlen(rec) - if !ok || namoff+namlen > uint64(len(rec)) { - break - } - name := rec[namoff : namoff+namlen] - for i, c := range name { - if c == 0 { - name = name[:i] - break - } - } - // Check for useless names before allocating a string. - if string(name) == "." || string(name) == ".." { - continue - } - max-- - count++ - names = append(names, string(name)) - } - return origlen - len(buf), count, names + return syscall.ParseDirent(buf, max, names) } diff --git a/vendor/golang.org/x/sys/unix/env_unix.go b/vendor/golang.org/x/sys/unix/env_unix.go index 45e281a04..706b3cd1d 100644 --- a/vendor/golang.org/x/sys/unix/env_unix.go +++ b/vendor/golang.org/x/sys/unix/env_unix.go @@ -1,4 +1,4 @@ -// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -25,3 +25,7 @@ func Clearenv() { func Environ() []string { return syscall.Environ() } + +func Unsetenv(key string) error { + return syscall.Unsetenv(key) +} diff --git a/vendor/golang.org/x/sys/unix/env_unset.go b/vendor/golang.org/x/sys/unix/env_unset.go deleted file mode 100644 index 922226255..000000000 --- a/vendor/golang.org/x/sys/unix/env_unset.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.4 - -package unix - -import "syscall" - -func Unsetenv(key string) error { - // This was added in Go 1.4. - return syscall.Unsetenv(key) -} diff --git a/vendor/golang.org/x/sys/unix/file_unix.go b/vendor/golang.org/x/sys/unix/file_unix.go deleted file mode 100644 index 47f6a83f2..000000000 --- a/vendor/golang.org/x/sys/unix/file_unix.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -import ( - "os" - "syscall" -) - -// FIXME: unexported function from os -// syscallMode returns the syscall-specific mode bits from Go's portable mode bits. -func syscallMode(i os.FileMode) (o uint32) { - o |= uint32(i.Perm()) - if i&os.ModeSetuid != 0 { - o |= syscall.S_ISUID - } - if i&os.ModeSetgid != 0 { - o |= syscall.S_ISGID - } - if i&os.ModeSticky != 0 { - o |= syscall.S_ISVTX - } - // No mapping for Go's ModeTemporary (plan9 only). - return -} diff --git a/vendor/golang.org/x/sys/unix/gccgo.go b/vendor/golang.org/x/sys/unix/gccgo.go index 94c823212..50062e3c7 100644 --- a/vendor/golang.org/x/sys/unix/gccgo.go +++ b/vendor/golang.org/x/sys/unix/gccgo.go @@ -1,4 +1,4 @@ -// Copyright 2015 The Go Authors. All rights reserved. +// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -8,12 +8,22 @@ package unix import "syscall" -// We can't use the gc-syntax .s files for gccgo. On the plus side +// We can't use the gc-syntax .s files for gccgo. On the plus side // much of the functionality can be written directly in Go. +//extern gccgoRealSyscallNoError +func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr) + //extern gccgoRealSyscall func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr) +func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) { + syscall.Entersyscall() + r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) + syscall.Exitsyscall() + return r, 0 +} + func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { syscall.Entersyscall() r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) @@ -35,6 +45,11 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, return r, 0, syscall.Errno(errno) } +func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) { + r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) + return r, 0 +} + func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0) return r, 0, syscall.Errno(errno) diff --git a/vendor/golang.org/x/sys/unix/gccgo_c.c b/vendor/golang.org/x/sys/unix/gccgo_c.c index 07f6be039..24e96b119 100644 --- a/vendor/golang.org/x/sys/unix/gccgo_c.c +++ b/vendor/golang.org/x/sys/unix/gccgo_c.c @@ -1,4 +1,4 @@ -// Copyright 2015 The Go Authors. All rights reserved. +// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -31,6 +31,12 @@ gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintp return r; } +uintptr_t +gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) +{ + return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9); +} + // Define the use function in C so that it is not inlined. extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline)); diff --git a/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go b/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go index bffe1a77d..251a977a8 100644 --- a/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go @@ -1,4 +1,4 @@ -// Copyright 2015 The Go Authors. All rights reserved. +// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go b/vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go deleted file mode 100644 index 56332692c..000000000 --- a/vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gccgo,linux,sparc64 - -package unix - -import "syscall" - -//extern sysconf -func realSysconf(name int) int64 - -func sysconf(name int) (n int64, err syscall.Errno) { - r := realSysconf(name) - if r < 0 { - return 0, syscall.GetErrno() - } - return r, 0 -} diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index 09b3c7ab6..1715122bd 100755 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -80,12 +80,6 @@ darwin_arm64) mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; -dragonfly_386) - mkerrors="$mkerrors -m32" - mksyscall="./mksyscall.pl -l32 -dragonfly" - mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl" - mktypes="GOARCH=$GOARCH go tool cgo -godefs" - ;; dragonfly_amd64) mkerrors="$mkerrors -m64" mksyscall="./mksyscall.pl -dragonfly" @@ -108,7 +102,7 @@ freebsd_arm) mksyscall="./mksyscall.pl -l32 -arm" mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" # Let the type of C char be signed for making the bare syscall - # API consistent across over platforms. + # API consistent across platforms. mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" ;; linux_sparc64) @@ -130,11 +124,18 @@ netbsd_amd64) mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; +netbsd_arm) + mkerrors="$mkerrors" + mksyscall="./mksyscall.pl -l32 -netbsd -arm" + mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" + # Let the type of C char be signed for making the bare syscall + # API consistent across platforms. + mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" + ;; openbsd_386) mkerrors="$mkerrors -m32" mksyscall="./mksyscall.pl -l32 -openbsd" mksysctl="./mksysctl_openbsd.pl" - zsysctl="zsysctl_openbsd.go" mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; @@ -142,10 +143,18 @@ openbsd_amd64) mkerrors="$mkerrors -m64" mksyscall="./mksyscall.pl -openbsd" mksysctl="./mksysctl_openbsd.pl" - zsysctl="zsysctl_openbsd.go" mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; +openbsd_arm) + mkerrors="$mkerrors" + mksyscall="./mksyscall.pl -l32 -openbsd -arm" + mksysctl="./mksysctl_openbsd.pl" + mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" + # Let the type of C char be signed for making the bare syscall + # API consistent across platforms. + mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" + ;; solaris_amd64) mksyscall="./mksyscall_solaris.pl" mkerrors="$mkerrors -m64" diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 08dd77518..3b5e2c07b 100755 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -17,8 +17,8 @@ if test -z "$GOARCH" -o -z "$GOOS"; then fi # Check that we are using the new build system if we should -if [[ "$GOOS" -eq "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then - if [[ "$GOLANG_SYS_BUILD" -ne "docker" ]]; then +if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then + if [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then echo 1>&2 "In the new build system, mkerrors should not be called directly." echo 1>&2 "See README.md" exit 1 @@ -27,7 +27,7 @@ fi CC=${CC:-cc} -if [[ "$GOOS" -eq "solaris" ]]; then +if [[ "$GOOS" = "solaris" ]]; then # Assumes GNU versions of utilities in PATH. export PATH=/usr/gnu/bin:$PATH fi @@ -38,6 +38,8 @@ includes_Darwin=' #define _DARWIN_C_SOURCE #define KERNEL #define _DARWIN_USE_64_BIT_INODE +#include <stdint.h> +#include <sys/attr.h> #include <sys/types.h> #include <sys/event.h> #include <sys/ptrace.h> @@ -46,6 +48,7 @@ includes_Darwin=' #include <sys/sysctl.h> #include <sys/mman.h> #include <sys/mount.h> +#include <sys/utsname.h> #include <sys/wait.h> #include <net/bpf.h> #include <net/if.h> @@ -84,6 +87,7 @@ includes_FreeBSD=' #include <sys/sockio.h> #include <sys/sysctl.h> #include <sys/mman.h> +#include <sys/mount.h> #include <sys/wait.h> #include <sys/ioctl.h> #include <net/bpf.h> @@ -181,6 +185,10 @@ struct ltchars { #include <linux/serial.h> #include <linux/can.h> #include <linux/vm_sockets.h> +#include <linux/taskstats.h> +#include <linux/genetlink.h> +#include <linux/stat.h> +#include <linux/watchdog.h> #include <net/route.h> #include <asm/termbits.h> @@ -281,6 +289,7 @@ includes_SunOS=' #include <sys/mman.h> #include <sys/wait.h> #include <sys/ioctl.h> +#include <sys/mkdev.h> #include <net/bpf.h> #include <net/if.h> #include <net/if_arp.h> @@ -345,6 +354,7 @@ ccflags="$@" $2 !~ /^EXPR_/ && $2 ~ /^E[A-Z0-9_]+$/ || $2 ~ /^B[0-9_]+$/ || + $2 ~ /^(OLD|NEW)DEV$/ || $2 == "BOTHER" || $2 ~ /^CI?BAUD(EX)?$/ || $2 == "IBSHIFT" || @@ -354,6 +364,7 @@ ccflags="$@" $2 ~ /^IGN/ || $2 ~ /^IX(ON|ANY|OFF)$/ || $2 ~ /^IN(LCR|PCK)$/ || + $2 !~ "X86_CR3_PCID_NOFLUSH" && $2 ~ /(^FLU?SH)|(FLU?SH$)/ || $2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ || $2 == "BRKINT" || @@ -378,7 +389,9 @@ ccflags="$@" $2 == "SOMAXCONN" || $2 == "NAME_MAX" || $2 == "IFNAMSIZ" || - $2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ || + $2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ || + $2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ || + $2 ~ /^HW_MACHINE$/ || $2 ~ /^SYSCTL_VERS/ || $2 ~ /^(MS|MNT|UMOUNT)_/ || $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || @@ -413,7 +426,16 @@ ccflags="$@" $2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SPLICE_/ || $2 ~ /^(VM|VMADDR)_/ || + $2 ~ /^IOCTL_VM_SOCKETS_/ || + $2 ~ /^(TASKSTATS|TS)_/ || + $2 ~ /^CGROUPSTATS_/ || + $2 ~ /^GENL_/ || + $2 ~ /^STATX_/ || + $2 ~ /^UTIME_/ || $2 ~ /^XATTR_(CREATE|REPLACE)/ || + $2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ || + $2 ~ /^FSOPT_/ || + $2 ~ /^WDIOC_/ || $2 !~ "WMESGLEN" && $2 ~ /^W[A-Z0-9]+$/ || $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} diff --git a/vendor/golang.org/x/sys/unix/mksyscall.pl b/vendor/golang.org/x/sys/unix/mksyscall.pl index fb929b4ce..1f6b926f8 100755 --- a/vendor/golang.org/x/sys/unix/mksyscall.pl +++ b/vendor/golang.org/x/sys/unix/mksyscall.pl @@ -210,7 +210,15 @@ while(<>) { # Determine which form to use; pad args with zeros. my $asm = "Syscall"; if ($nonblock) { - $asm = "RawSyscall"; + if ($errvar eq "" && $ENV{'GOOS'} eq "linux") { + $asm = "RawSyscallNoError"; + } else { + $asm = "RawSyscall"; + } + } else { + if ($errvar eq "" && $ENV{'GOOS'} eq "linux") { + $asm = "SyscallNoError"; + } } if(@args <= 3) { while(@args < 3) { @@ -284,7 +292,12 @@ while(<>) { if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { $text .= "\t$call\n"; } else { - $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; + if ($errvar eq "" && $ENV{'GOOS'} eq "linux") { + # raw syscall without error on Linux, see golang.org/issue/22924 + $text .= "\t$ret[0], $ret[1] := $call\n"; + } else { + $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; + } } $text .= $body; diff --git a/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl b/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl index d31f2c48f..85988b140 100755 --- a/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl +++ b/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl @@ -47,7 +47,7 @@ while(<>){ $name = "$7_$11" if $11 ne ''; $name =~ y/a-z/A-Z/; - if($compat eq '' || $compat eq '30' || $compat eq '50') { + if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') { print " $name = $num; // $proto\n"; } } diff --git a/vendor/golang.org/x/sys/unix/pagesize_unix.go b/vendor/golang.org/x/sys/unix/pagesize_unix.go new file mode 100644 index 000000000..83c85e019 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/pagesize_unix.go @@ -0,0 +1,15 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +// For Unix, get the pagesize from the runtime. + +package unix + +import "syscall" + +func Getpagesize() int { + return syscall.Getpagesize() +} diff --git a/vendor/golang.org/x/sys/unix/race.go b/vendor/golang.org/x/sys/unix/race.go index 3c7627eb5..61712b51c 100644 --- a/vendor/golang.org/x/sys/unix/race.go +++ b/vendor/golang.org/x/sys/unix/race.go @@ -1,4 +1,4 @@ -// Copyright 2012 The Go Authors. All rights reserved. +// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/golang.org/x/sys/unix/race0.go b/vendor/golang.org/x/sys/unix/race0.go index f8678e0d2..dd0820431 100644 --- a/vendor/golang.org/x/sys/unix/race0.go +++ b/vendor/golang.org/x/sys/unix/race0.go @@ -1,4 +1,4 @@ -// Copyright 2012 The Go Authors. All rights reserved. +// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/golang.org/x/sys/unix/sockcmsg_linux.go b/vendor/golang.org/x/sys/unix/sockcmsg_linux.go index d9ff4731a..6079eb4ac 100644 --- a/vendor/golang.org/x/sys/unix/sockcmsg_linux.go +++ b/vendor/golang.org/x/sys/unix/sockcmsg_linux.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 85e35020e..ef35fce80 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -5,30 +5,33 @@ // +build darwin dragonfly freebsd linux netbsd openbsd solaris // Package unix contains an interface to the low-level operating system -// primitives. OS details vary depending on the underlying system, and +// primitives. OS details vary depending on the underlying system, and // by default, godoc will display OS-specific documentation for the current -// system. If you want godoc to display OS documentation for another -// system, set $GOOS and $GOARCH to the desired system. For example, if +// system. If you want godoc to display OS documentation for another +// system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. +// // The primary use of this package is inside other packages that provide a more // portable interface to the system, such as "os", "time" and "net". Use // those packages rather than this one if you can. +// // For details of the functions and data types in this package consult // the manuals for the appropriate operating system. +// // These calls return err == nil to indicate success; otherwise // err represents an operating system error describing the failure and // holds a value of type syscall.Errno. package unix // import "golang.org/x/sys/unix" +import "strings" + // ByteSliceFromString returns a NUL-terminated slice of bytes // containing the text of s. If s contains a NUL byte at any // location, it returns (nil, EINVAL). func ByteSliceFromString(s string) ([]byte, error) { - for i := 0; i < len(s); i++ { - if s[i] == 0 { - return nil, EINVAL - } + if strings.IndexByte(s, 0) != -1 { + return nil, EINVAL } a := make([]byte, len(s)+1) copy(a, s) @@ -49,21 +52,3 @@ func BytePtrFromString(s string) (*byte, error) { // Single-word zero for use when we need a valid pointer to 0 bytes. // See mkunix.pl. var _zero uintptr - -func (ts *Timespec) Unix() (sec int64, nsec int64) { - return int64(ts.Sec), int64(ts.Nsec) -} - -func (tv *Timeval) Unix() (sec int64, nsec int64) { - return int64(tv.Sec), int64(tv.Usec) * 1000 -} - -func (ts *Timespec) Nano() int64 { - return int64(ts.Sec)*1e9 + int64(ts.Nsec) -} - -func (tv *Timeval) Nano() int64 { - return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 -} - -func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index ccb29c75c..d3903edeb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -34,7 +34,7 @@ func Getgroups() (gids []int, err error) { return nil, nil } - // Sanity check group count. Max is 16 on BSD. + // Sanity check group count. Max is 16 on BSD. if n < 0 || n > 1000 { return nil, EINVAL } @@ -352,6 +352,18 @@ func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { return &value, err } +// GetsockoptString returns the string value of the socket option opt for the +// socket associated with fd at the given socket level. +func GetsockoptString(fd, level, opt int) (string, error) { + buf := make([]byte, 256) + vallen := _Socklen(len(buf)) + err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) + if err != nil { + return "", err + } + return string(buf[:vallen-1]), nil +} + //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) @@ -561,13 +573,24 @@ func Utimes(path string, tv []Timeval) error { func UtimesNano(path string, ts []Timespec) error { if ts == nil { + err := utimensat(AT_FDCWD, path, nil, 0) + if err != ENOSYS { + return err + } return utimes(path, nil) } - // TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it - // isn't supported by darwin so this uses utimes instead if len(ts) != 2 { return EINVAL } + // Darwin setattrlist can set nanosecond timestamps + err := setattrlistTimes(path, ts, 0) + if err != ENOSYS { + return err + } + err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) + if err != ENOSYS { + return err + } // Not as efficient as it could be because Timespec and // Timeval have different types in the different OSes tv := [2]Timeval{ @@ -577,6 +600,20 @@ func UtimesNano(path string, ts []Timespec) error { return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } +func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { + if ts == nil { + return utimensat(dirfd, path, nil, flags) + } + if len(ts) != 2 { + return EINVAL + } + err := setattrlistTimes(path, ts, flags) + if err != ENOSYS { + return err + } + return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) +} + //sys futimes(fd int, timeval *[2]Timeval) (err error) func Futimes(fd int, tv []Timeval) error { @@ -591,12 +628,18 @@ func Futimes(fd int, tv []Timeval) error { //sys fcntl(fd int, cmd int, arg int) (val int, err error) +//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) + +func Poll(fds []PollFd, timeout int) (n int, err error) { + if len(fds) == 0 { + return poll(nil, 0, timeout) + } + return poll(&fds[0], len(fds), timeout) +} + // TODO: wrap // Acct(name nil-string) (err error) // Gethostuuid(uuid *byte, timeout *Timespec) (err error) -// Madvise(addr *byte, len int, behav int) (err error) -// Mprotect(addr *byte, len int, prot int) (err error) -// Msync(addr *byte, len int, flags int) (err error) // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) var mapper = &mmapper{ @@ -612,3 +655,11 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e func Munmap(b []byte) (err error) { return mapper.Munmap(b) } + +//sys Madvise(b []byte, behav int) (err error) +//sys Mlock(b []byte) (err error) +//sys Mlockall(flags int) (err error) +//sys Mprotect(b []byte, prot int) (err error) +//sys Msync(b []byte, flags int) (err error) +//sys Munlock(b []byte) (err error) +//sys Munlockall() (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 26b83602b..006e21f5d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -36,6 +36,7 @@ func Getwd() (string, error) { return "", ENOTSUP } +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -54,7 +55,7 @@ func nametomib(name string) (mib []_C_int, err error) { // NOTE(rsc): It seems strange to set the buffer to have // size CTL_MAXNAME+2 but use only CTL_MAXNAME - // as the size. I don't know why the +2 is here, but the + // as the size. I don't know why the +2 is here, but the // kernel uses +2 for its own implementation of this function. // I am scared that if we don't include the +2 here, the kernel // will silently write 2 words farther than we specify @@ -76,18 +77,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } @@ -187,6 +176,42 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } +func setattrlistTimes(path string, times []Timespec, flags int) error { + _p0, err := BytePtrFromString(path) + if err != nil { + return err + } + + var attrList attrList + attrList.bitmapCount = ATTR_BIT_MAP_COUNT + attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME + + // order is mtime, atime: the opposite of Chtimes + attributes := [2]Timespec{times[1], times[0]} + options := 0 + if flags&AT_SYMLINK_NOFOLLOW != 0 { + options |= FSOPT_NOFOLLOW + } + _, _, e1 := Syscall6( + SYS_SETATTRLIST, + uintptr(unsafe.Pointer(_p0)), + uintptr(unsafe.Pointer(&attrList)), + uintptr(unsafe.Pointer(&attributes)), + uintptr(unsafe.Sizeof(attributes)), + uintptr(options), + 0, + ) + if e1 != 0 { + return e1 + } + return nil +} + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error { + // Darwin doesn't support SYS_UTIMENSAT + return ENOSYS +} + /* * Wrapped */ @@ -234,6 +259,52 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { return &value, err } +func Uname(uname *Utsname) error { + mib := []_C_int{CTL_KERN, KERN_OSTYPE} + n := unsafe.Sizeof(uname.Sysname) + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_HOSTNAME} + n = unsafe.Sizeof(uname.Nodename) + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_OSRELEASE} + n = unsafe.Sizeof(uname.Release) + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_VERSION} + n = unsafe.Sizeof(uname.Version) + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + return err + } + + // The version might have newlines or tabs in it, convert them to + // spaces. + for i, b := range uname.Version { + if b == '\n' || b == '\t' { + if i == len(uname.Version)-1 { + uname.Version[i] = 0 + } else { + uname.Version[i] = ' ' + } + } + } + + mib = []_C_int{CTL_HW, HW_MACHINE} + n = unsafe.Sizeof(uname.Machine) + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + return err + } + + return nil +} + /* * Exposed directly */ @@ -259,6 +330,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) @@ -287,12 +359,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) -//sys Mlock(b []byte) (err error) -//sys Mlockall(flags int) (err error) -//sys Mprotect(b []byte, prot int) (err error) -//sys Msync(b []byte, flags int) (err error) -//sys Munlock(b []byte) (err error) -//sys Munlockall() (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) //sys Pathconf(path string, name int) (val int, err error) @@ -369,9 +435,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Add_profil // Kdebug_trace // Sigreturn -// Mmap -// Mlock -// Munlock // Atsocket // Kqueue_from_portset_np // Kqueue_portset @@ -381,7 +444,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Searchfs // Delete // Copyfile -// Poll // Watchevent // Waitevent // Modwatch @@ -464,8 +526,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Lio_listio // __pthread_cond_wait // Iopolicysys -// Mlockall -// Munlockall // __pthread_kill // __pthread_sigmask // __sigwait diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_386.go b/vendor/golang.org/x/sys/unix/syscall_darwin_386.go index c172a3da5..b3ac109a2 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_386.go @@ -11,27 +11,18 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int32(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: int32(sec), Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int32(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: int32(sec), Usec: int32(usec)} } //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) func Gettimeofday(tv *Timeval) (err error) { // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back + // but is otherwise unused. The answers come back // in the two registers. sec, usec, err := gettimeofday(tv) tv.Sec = int32(sec) diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go index c6c99c13a..75219444a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go @@ -11,27 +11,18 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) func Gettimeofday(tv *Timeval) (err error) { // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back + // but is otherwise unused. The answers come back // in the two registers. sec, usec, err := gettimeofday(tv) tv.Sec = sec diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go b/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go index d286cf408..faae207a4 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go @@ -9,27 +9,18 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int32(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: int32(sec), Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int32(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: int32(sec), Usec: int32(usec)} } //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) func Gettimeofday(tv *Timeval) (err error) { // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back + // but is otherwise unused. The answers come back // in the two registers. sec, usec, err := gettimeofday(tv) tv.Sec = int32(sec) @@ -69,3 +60,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e } func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic + +// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions +// of darwin/arm the syscall is called sysctl instead of __sysctl. +const SYS___SYSCTL = SYS_SYSCTL diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go index c33905cdc..d6d962801 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go @@ -11,27 +11,18 @@ import ( "unsafe" ) -func Getpagesize() int { return 16384 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) func Gettimeofday(tv *Timeval) (err error) { // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back + // but is otherwise unused. The answers come back // in the two registers. sec, usec, err := gettimeofday(tv) tv.Sec = sec diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 7e0210fc9..b5072de28 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -14,6 +14,7 @@ package unix import "unsafe" +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -56,22 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - namlen, ok := direntNamlen(buf) - if !ok { - return 0, false - } - return (16 + namlen + 1 + 7) &^ 7, true -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { @@ -110,6 +95,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { return } +const ImplementsGetwd = true + +//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD + +func Getwd() (string, error) { + var buf [PathMax]byte + _, err := Getcwd(buf[0:]) + if err != nil { + return "", err + } + n := clen(buf[:]) + if n < 1 { + return "", EINVAL + } + return string(buf[:n]), nil +} + func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { var _p0 unsafe.Pointer var bufsize uintptr @@ -125,6 +127,113 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } +func setattrlistTimes(path string, times []Timespec, flags int) error { + // used on Darwin for UtimesNano + return ENOSYS +} + +//sys ioctl(fd int, req uint, arg uintptr) (err error) + +// ioctl itself should not be exposed directly, but additional get/set +// functions for specific types are permissible. + +// IoctlSetInt performs an ioctl operation which sets an integer value +// on fd, using the specified request number. +func IoctlSetInt(fd int, req uint, value int) error { + return ioctl(fd, req, uintptr(value)) +} + +func IoctlSetWinsize(fd int, req uint, value *Winsize) error { + return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +} + +func IoctlSetTermios(fd int, req uint, value *Termios) error { + return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +} + +// IoctlGetInt performs an ioctl operation which gets an integer value +// from fd, using the specified request number. +func IoctlGetInt(fd int, req uint) (int, error) { + var value int + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return value, err +} + +func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { + var value Winsize + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func IoctlGetTermios(fd int, req uint) (*Termios, error) { + var value Termios + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error { + err := sysctl(mib, old, oldlen, nil, 0) + if err != nil { + // Utsname members on Dragonfly are only 32 bytes and + // the syscall returns ENOMEM in case the actual value + // is longer. + if err == ENOMEM { + err = nil + } + } + return err +} + +func Uname(uname *Utsname) error { + mib := []_C_int{CTL_KERN, KERN_OSTYPE} + n := unsafe.Sizeof(uname.Sysname) + if err := sysctlUname(mib, &uname.Sysname[0], &n); err != nil { + return err + } + uname.Sysname[unsafe.Sizeof(uname.Sysname)-1] = 0 + + mib = []_C_int{CTL_KERN, KERN_HOSTNAME} + n = unsafe.Sizeof(uname.Nodename) + if err := sysctlUname(mib, &uname.Nodename[0], &n); err != nil { + return err + } + uname.Nodename[unsafe.Sizeof(uname.Nodename)-1] = 0 + + mib = []_C_int{CTL_KERN, KERN_OSRELEASE} + n = unsafe.Sizeof(uname.Release) + if err := sysctlUname(mib, &uname.Release[0], &n); err != nil { + return err + } + uname.Release[unsafe.Sizeof(uname.Release)-1] = 0 + + mib = []_C_int{CTL_KERN, KERN_VERSION} + n = unsafe.Sizeof(uname.Version) + if err := sysctlUname(mib, &uname.Version[0], &n); err != nil { + return err + } + + // The version might have newlines or tabs in it, convert them to + // spaces. + for i, b := range uname.Version { + if b == '\n' || b == '\t' { + if i == len(uname.Version)-1 { + uname.Version[i] = 0 + } else { + uname.Version[i] = ' ' + } + } + } + + mib = []_C_int{CTL_HW, HW_MACHINE} + n = unsafe.Sizeof(uname.Machine) + if err := sysctlUname(mib, &uname.Machine[0], &n); err != nil { + return err + } + uname.Machine[unsafe.Sizeof(uname.Machine)-1] = 0 + + return nil +} + /* * Exposed directly */ @@ -142,10 +251,12 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) @@ -174,11 +285,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { //sys Mkdir(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) -//sys Mlock(b []byte) (err error) -//sys Mlockall(flags int) (err error) -//sys Mprotect(b []byte, prot int) (err error) -//sys Munlock(b []byte) (err error) -//sys Munlockall() (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Pathconf(path string, name int) (val int, err error) @@ -218,6 +324,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) +//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) /* * Unimplemented @@ -229,7 +336,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // Getlogin // Sigpending // Sigaltstack -// Ioctl // Reboot // Execve // Vfork @@ -252,9 +358,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // Add_profil // Kdebug_trace // Sigreturn -// Mmap -// Mlock -// Munlock // Atsocket // Kqueue_from_portset_np // Kqueue_portset @@ -264,7 +367,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // Searchfs // Delete // Copyfile -// Poll // Watchevent // Waitevent // Modwatch @@ -347,8 +449,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // Lio_listio // __pthread_cond_wait // Iopolicysys -// Mlockall -// Munlockall // __pthread_kill // __pthread_sigmask // __sigwait @@ -401,7 +501,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // Sendmsg_nocancel // Recvfrom_nocancel // Accept_nocancel -// Msync_nocancel // Fcntl_nocancel // Select_nocancel // Fsync_nocancel @@ -413,7 +512,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // Pread_nocancel // Pwrite_nocancel // Waitid_nocancel -// Poll_nocancel // Msgsnd_nocancel // Msgrcv_nocancel // Sem_wait_nocancel diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go index da7cb7982..9babb31ea 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go @@ -11,21 +11,12 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = nsec % 1e9 / 1e3 - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index e93356b4f..ba9df4ac1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -12,8 +12,12 @@ package unix -import "unsafe" +import ( + "strings" + "unsafe" +) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -32,7 +36,7 @@ func nametomib(name string) (mib []_C_int, err error) { // NOTE(rsc): It seems strange to set the buffer to have // size CTL_MAXNAME+2 but use only CTL_MAXNAME - // as the size. I don't know why the +2 is here, but the + // as the size. I don't know why the +2 is here, but the // kernel uses +2 for its own implementation of this function. // I am scared that if we don't include the +2 here, the kernel // will silently write 2 words farther than we specify @@ -54,18 +58,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { @@ -105,6 +97,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { return } +const ImplementsGetwd = true + +//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD + +func Getwd() (string, error) { + var buf [PathMax]byte + _, err := Getcwd(buf[0:]) + if err != nil { + return "", err + } + n := clen(buf[:]) + if n < 1 { + return "", EINVAL + } + return string(buf[:n]), nil +} + func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { var _p0 unsafe.Pointer var bufsize uintptr @@ -120,17 +129,15 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } +func setattrlistTimes(path string, times []Timespec, flags int) error { + // used on Darwin for UtimesNano + return ENOSYS +} + // Derive extattr namespace and attribute name func xattrnamespace(fullattr string) (ns int, attr string, err error) { - s := -1 - for idx, val := range fullattr { - if val == '.' { - s = idx - break - } - } - + s := strings.IndexByte(fullattr, '.') if s == -1 { return -1, "", ENOATTR } @@ -271,7 +278,6 @@ func Listxattr(file string, dest []byte) (sz int, err error) { // FreeBSD won't allow you to list xattrs from multiple namespaces s := 0 - var e error for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz) @@ -283,7 +289,6 @@ func Listxattr(file string, dest []byte) (sz int, err error) { * we don't have read permissions on, so don't ignore those errors */ if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - e = nil continue } else if e != nil { return s, e @@ -297,7 +302,7 @@ func Listxattr(file string, dest []byte) (sz int, err error) { d = initxattrdest(dest, s) } - return s, e + return s, nil } func Flistxattr(fd int, dest []byte) (sz int, err error) { @@ -305,11 +310,9 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) { destsiz := len(dest) s := 0 - var e error for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz) if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - e = nil continue } else if e != nil { return s, e @@ -323,7 +326,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) { d = initxattrdest(dest, s) } - return s, e + return s, nil } func Llistxattr(link string, dest []byte) (sz int, err error) { @@ -331,11 +334,9 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { destsiz := len(dest) s := 0 - var e error for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} { stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz) if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER { - e = nil continue } else if e != nil { return s, e @@ -349,7 +350,7 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { d = initxattrdest(dest, s) } - return s, e + return s, nil } //sys ioctl(fd int, req uint, arg uintptr) (err error) @@ -391,6 +392,52 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { return &value, err } +func Uname(uname *Utsname) error { + mib := []_C_int{CTL_KERN, KERN_OSTYPE} + n := unsafe.Sizeof(uname.Sysname) + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_HOSTNAME} + n = unsafe.Sizeof(uname.Nodename) + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_OSRELEASE} + n = unsafe.Sizeof(uname.Release) + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_VERSION} + n = unsafe.Sizeof(uname.Version) + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + return err + } + + // The version might have newlines or tabs in it, convert them to + // spaces. + for i, b := range uname.Version { + if b == '\n' || b == '\t' { + if i == len(uname.Version)-1 { + uname.Version[i] = 0 + } else { + uname.Version[i] = ' ' + } + } + } + + mib = []_C_int{CTL_HW, HW_MACHINE} + n = unsafe.Sizeof(uname.Machine) + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + return err + } + + return nil +} + /* * Exposed directly */ @@ -431,9 +478,11 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) +//sys Getdents(fd int, buf []byte) (n int, err error) //sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) //sys Getdtablesize() (size int) //sysnb Getegid() (egid int) @@ -461,11 +510,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) -//sys Mlock(b []byte) (err error) -//sys Mlockall(flags int) (err error) -//sys Mprotect(b []byte, prot int) (err error) -//sys Munlock(b []byte) (err error) -//sys Munlockall() (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) @@ -512,6 +556,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) +//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) /* * Unimplemented @@ -545,9 +590,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Add_profil // Kdebug_trace // Sigreturn -// Mmap -// Mlock -// Munlock // Atsocket // Kqueue_from_portset_np // Kqueue_portset @@ -557,7 +599,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Searchfs // Delete // Copyfile -// Poll // Watchevent // Waitevent // Modwatch @@ -640,8 +681,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Lio_listio // __pthread_cond_wait // Iopolicysys -// Mlockall -// Munlockall // __pthread_kill // __pthread_sigmask // __sigwait @@ -694,7 +733,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { // Sendmsg_nocancel // Recvfrom_nocancel // Accept_nocancel -// Msync_nocancel // Fcntl_nocancel // Select_nocancel // Fsync_nocancel diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go index 6a0cd804d..21e03958c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go @@ -11,21 +11,12 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int32(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: int32(sec), Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int32(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: int32(sec), Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go index e142540ef..9c945a657 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go @@ -11,21 +11,12 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = nsec % 1e9 / 1e3 - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go index 5504cb125..5cd6243f2 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go @@ -11,21 +11,12 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return ts.Sec*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = nsec / 1e9 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index bb9022571..76cf81f57 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -255,7 +255,7 @@ func Getgroups() (gids []int, err error) { return nil, nil } - // Sanity check group count. Max is 1<<16 on Linux. + // Sanity check group count. Max is 1<<16 on Linux. if n < 0 || n > 1<<20 { return nil, EINVAL } @@ -290,8 +290,8 @@ type WaitStatus uint32 // 0x7F (stopped), or a signal number that caused an exit. // The 0x80 bit is whether there was a core dump. // An extra number (exit code, signal causing a stop) -// is in the high bits. At least that's the idea. -// There are various irregularities. For example, the +// is in the high bits. At least that's the idea. +// There are various irregularities. For example, the // "continued" status is 0xFFFF, distinguishing itself // from stopped via the core dump bit. @@ -413,6 +413,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), sl, nil } +// SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets. type SockaddrLinklayer struct { Protocol uint16 Ifindex int @@ -439,6 +440,7 @@ func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil } +// SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets. type SockaddrNetlink struct { Family uint16 Pad uint16 @@ -455,6 +457,8 @@ func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil } +// SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets +// using the HCI protocol. type SockaddrHCI struct { Dev uint16 Channel uint16 @@ -468,6 +472,31 @@ func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil } +// SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets +// using the L2CAP protocol. +type SockaddrL2 struct { + PSM uint16 + CID uint16 + Addr [6]uint8 + AddrType uint8 + raw RawSockaddrL2 +} + +func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { + sa.raw.Family = AF_BLUETOOTH + psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) + psm[0] = byte(sa.PSM) + psm[1] = byte(sa.PSM >> 8) + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] + } + cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) + cid[0] = byte(sa.CID) + cid[1] = byte(sa.CID >> 8) + sa.raw.Bdaddr_type = sa.AddrType + return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil +} + // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets. // The RxID and TxID fields are used for transport protocol addressing in // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with @@ -808,6 +837,24 @@ func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { return &value, err } +// GetsockoptString returns the string value of the socket option opt for the +// socket associated with fd at the given socket level. +func GetsockoptString(fd, level, opt int) (string, error) { + buf := make([]byte, 256) + vallen := _Socklen(len(buf)) + err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) + if err != nil { + if err == ERANGE { + buf = make([]byte, vallen) + err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) + } + if err != nil { + return "", err + } + } + return string(buf[:vallen-1]), nil +} + func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) } @@ -926,17 +973,22 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from msg.Namelen = uint32(SizeofSockaddrAny) var iov Iovec if len(p) > 0 { - iov.Base = (*byte)(unsafe.Pointer(&p[0])) + iov.Base = &p[0] iov.SetLen(len(p)) } var dummy byte if len(oob) > 0 { + var sockType int + sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) + if err != nil { + return + } // receive at least one normal byte - if len(p) == 0 { + if sockType != SOCK_DGRAM && len(p) == 0 { iov.Base = &dummy iov.SetLen(1) } - msg.Control = (*byte)(unsafe.Pointer(&oob[0])) + msg.Control = &oob[0] msg.SetControllen(len(oob)) } msg.Iov = &iov @@ -969,21 +1021,26 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) } } var msg Msghdr - msg.Name = (*byte)(unsafe.Pointer(ptr)) + msg.Name = (*byte)(ptr) msg.Namelen = uint32(salen) var iov Iovec if len(p) > 0 { - iov.Base = (*byte)(unsafe.Pointer(&p[0])) + iov.Base = &p[0] iov.SetLen(len(p)) } var dummy byte if len(oob) > 0 { + var sockType int + sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) + if err != nil { + return 0, err + } // send at least one normal byte - if len(p) == 0 { + if sockType != SOCK_DGRAM && len(p) == 0 { iov.Base = &dummy iov.SetLen(1) } - msg.Control = (*byte)(unsafe.Pointer(&oob[0])) + msg.Control = &oob[0] msg.SetControllen(len(oob)) } msg.Iov = &iov @@ -1013,7 +1070,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro var buf [sizeofPtr]byte - // Leading edge. PEEKTEXT/PEEKDATA don't require aligned + // Leading edge. PEEKTEXT/PEEKDATA don't require aligned // access (PEEKUSER warns that it might), but if we don't // align our reads, we might straddle an unmapped page // boundary and not get the bytes leading up to the page @@ -1115,6 +1172,10 @@ func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) } +func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { + return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) +} + func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) } @@ -1158,22 +1219,6 @@ func ReadDirent(fd int, buf []byte) (n int, err error) { return Getdents(fd, buf) } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - reclen, ok := direntReclen(buf) - if !ok { - return 0, false - } - return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true -} - //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { @@ -1252,6 +1297,7 @@ func Getpgrp() (pid int) { //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) +//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) @@ -1278,6 +1324,7 @@ func Setgid(uid int) (err error) { //sys Setpriority(which int, who int, prio int) (err error) //sys Setxattr(path string, attr string, data []byte, flags int) (err error) +//sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) //sys Sync() //sys Syncfs(fd int) (err error) //sysnb Sysinfo(info *Sysinfo_t) (err error) @@ -1314,9 +1361,9 @@ func Munmap(b []byte) (err error) { //sys Madvise(b []byte, advice int) (err error) //sys Mprotect(b []byte, prot int) (err error) //sys Mlock(b []byte) (err error) -//sys Munlock(b []byte) (err error) //sys Mlockall(flags int) (err error) //sys Msync(b []byte, flags int) (err error) +//sys Munlock(b []byte) (err error) //sys Munlockall() (err error) // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, @@ -1384,7 +1431,6 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { // ModifyLdt // Mount // MovePages -// Mprotect // MqGetsetattr // MqNotify // MqOpen @@ -1396,7 +1442,6 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { // Msgget // Msgrcv // Msgsnd -// Newfstatat // Nfsservctl // Personality // Pselect6 @@ -1417,11 +1462,9 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { // RtSigtimedwait // SchedGetPriorityMax // SchedGetPriorityMin -// SchedGetaffinity // SchedGetparam // SchedGetscheduler // SchedRrGetInterval -// SchedSetaffinity // SchedSetparam // SchedYield // Security diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_386.go index 2b881b979..bb8e4fbd8 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_386.go @@ -14,21 +14,12 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int32(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: int32(sec), Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = int32(nsec / 1e9) - tv.Usec = int32(nsec % 1e9 / 1e3) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: int32(sec), Usec: int32(usec)} } //sysnb pipe(p *[2]_C_int) (err error) @@ -63,6 +54,7 @@ func Pipe2(p []int, flags int) (err error) { //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sysnb Getegid() (egid int) = SYS_GETEGID32 //sysnb Geteuid() (euid int) = SYS_GETEUID32 @@ -185,9 +177,9 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { // On x86 Linux, all the socket calls go through an extra indirection, // I think because the 5-register system call interface can't handle -// the 6-argument calls like sendto and recvfrom. Instead the +// the 6-argument calls like sendto and recvfrom. Instead the // arguments to the underlying system call are the number below -// and a pointer to an array of uintptr. We hide the pointer in the +// and a pointer to an array of uintptr. We hide the pointer in the // socketcall assembly to avoid allocation on every system call. const ( diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go index 9516a3fd7..53d38a534 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go @@ -11,6 +11,7 @@ package unix //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -69,8 +70,6 @@ func Gettimeofday(tv *Timeval) (err error) { return nil } -func Getpagesize() int { return 4096 } - func Time(t *Time_t) (tt Time_t, err error) { var tv Timeval errno := gettimeofday(&tv) @@ -85,19 +84,12 @@ func Time(t *Time_t) (tt Time_t, err error) { //sys Utime(path string, buf *Utimbuf) (err error) -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = nsec / 1e9 - tv.Usec = nsec % 1e9 / 1e3 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } //sysnb pipe(p *[2]_C_int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go index 71d870228..c59f8588f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go @@ -11,21 +11,12 @@ import ( "unsafe" ) -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int32(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: int32(sec), Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = int32(nsec / 1e9) - tv.Usec = int32(nsec % 1e9 / 1e3) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: int32(sec), Usec: int32(usec)} } func Pipe(p []int) (err error) { @@ -86,6 +77,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { //sys Dup2(oldfd int, newfd int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sysnb Getegid() (egid int) = SYS_GETEGID32 //sysnb Geteuid() (euid int) = SYS_GETEUID32 //sysnb Getgid() (gid int) = SYS_GETGID32 diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index 4a136396c..a1e8a609b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -7,6 +7,7 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) @@ -21,7 +22,15 @@ package unix //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK -//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS_PSELECT6 + +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + var ts *Timespec + if timeout != nil { + ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} + } + return Pselect(nfd, r, w, e, ts, nil) +} + //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys Setfsgid(gid int) (err error) //sys Setfsuid(uid int) (err error) @@ -66,23 +75,14 @@ func Lstat(path string, stat *Stat_t) (err error) { //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) -func Getpagesize() int { return 65536 } - //sysnb Gettimeofday(tv *Timeval) (err error) -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = nsec / 1e9 - tv.Usec = nsec % 1e9 / 1e3 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func Time(t *Time_t) (Time_t, error) { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gc.go b/vendor/golang.org/x/sys/unix/syscall_linux_gc.go new file mode 100644 index 000000000..c26e6ec23 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gc.go @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux,!gccgo + +package unix + +// SyscallNoError may be used instead of Syscall for syscalls that don't fail. +func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) + +// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't +// fail. +func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go new file mode 100644 index 000000000..df9c12371 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go @@ -0,0 +1,21 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux +// +build gccgo +// +build 386 arm + +package unix + +import ( + "syscall" + "unsafe" +) + +func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) { + offsetLow := uint32(offset & 0xffffffff) + offsetHigh := uint32((offset >> 32) & 0xffffffff) + _, _, err = Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0) + return newoffset, err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index 73318e5c6..090ed404a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -9,7 +9,9 @@ package unix //sys Dup2(oldfd int, newfd int) (err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -23,7 +25,15 @@ package unix //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK -//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS_PSELECT6 + +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + var ts *Timespec + if timeout != nil { + ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} + } + return Pselect(nfd, r, w, e, ts, nil) +} + //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys Setfsgid(gid int) (err error) //sys Setfsuid(uid int) (err error) @@ -55,8 +65,6 @@ package unix //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) -func Getpagesize() int { return 65536 } - //sysnb Gettimeofday(tv *Timeval) (err error) func Time(t *Time_t) (tt Time_t, err error) { @@ -73,19 +81,12 @@ func Time(t *Time_t) (tt Time_t, err error) { //sys Utime(path string, buf *Utimbuf) (err error) -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = nsec / 1e9 - tv.Usec = nsec % 1e9 / 1e3 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func Pipe(p []int) (err error) { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go index b83d93fdf..3d5817f66 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go @@ -15,6 +15,7 @@ import ( func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) //sys Dup2(oldfd int, newfd int) (err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sysnb Getegid() (egid int) @@ -65,6 +66,7 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Utime(path string, buf *Utimbuf) (err error) @@ -99,19 +101,12 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { return } -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int32(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: int32(sec), Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = int32(nsec / 1e9) - tv.Usec = int32(nsec % 1e9 / 1e3) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: int32(sec), Usec: int32(usec)} } //sysnb pipe2(p *[2]_C_int, flags int) (err error) @@ -235,5 +230,3 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { } return poll(&fds[0], len(fds), timeout) } - -func Getpagesize() int { return 4096 } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go index 60770f627..6fb8733d6 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go @@ -9,8 +9,10 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Dup2(oldfd int, newfd int) (err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -28,7 +30,7 @@ package unix //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK -//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) +//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys Setfsgid(gid int) (err error) //sys Setfsuid(uid int) (err error) @@ -61,26 +63,17 @@ package unix //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) -func Getpagesize() int { return 65536 } - //sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Time(t *Time_t) (tt Time_t, err error) //sys Utime(path string, buf *Utimbuf) (err error) -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = nsec / 1e9 - tv.Usec = nsec % 1e9 / 1e3 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func (r *PtraceRegs) PC() uint64 { return r.Nip } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go index 1708a4bbf..c0d86e722 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go @@ -15,6 +15,7 @@ import ( //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -46,8 +47,6 @@ import ( //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) //sysnb setgroups(n int, list *_Gid_t) (err error) -func Getpagesize() int { return 4096 } - //sysnb Gettimeofday(tv *Timeval) (err error) func Time(t *Time_t) (tt Time_t, err error) { @@ -64,19 +63,12 @@ func Time(t *Time_t) (tt Time_t, err error) { //sys Utime(path string, buf *Utimbuf) (err error) -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = nsec / 1e9 - tv.Usec = nsec % 1e9 / 1e3 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } //sysnb pipe2(p *[2]_C_int, flags int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go index 20b7454d7..78c1e0df1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go @@ -6,15 +6,12 @@ package unix -import ( - "sync/atomic" - "syscall" -) - //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Dup2(oldfd int, newfd int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -63,21 +60,6 @@ import ( //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) -func sysconf(name int) (n int64, err syscall.Errno) - -// pageSize caches the value of Getpagesize, since it can't change -// once the system is booted. -var pageSize int64 // accessed atomically - -func Getpagesize() int { - n := atomic.LoadInt64(&pageSize) - if n == 0 { - n, _ = sysconf(_SC_PAGESIZE) - atomic.StoreInt64(&pageSize, n) - } - return int(n) -} - func Ioperm(from int, num int, on int) (err error) { return ENOSYS } @@ -102,19 +84,12 @@ func Time(t *Time_t) (tt Time_t, err error) { //sys Utime(path string, buf *Utimbuf) (err error) -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = nsec / 1e9 - tv.Usec = int32(nsec % 1e9 / 1e3) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func (r *PtraceRegs) PC() uint64 { return r.Tpc } diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 01f6a48c8..e1a3baa23 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -17,6 +17,7 @@ import ( "unsafe" ) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -55,7 +56,6 @@ func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) { } func nametomib(name string) (mib []_C_int, err error) { - // Split name into components. var parts []string last := 0 @@ -93,18 +93,6 @@ func nametomib(name string) (mib []_C_int, err error) { return mib, nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (fd1 int, fd2 int, err error) func Pipe(p []int) (err error) { if len(p) != 2 { @@ -119,11 +107,118 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { return getdents(fd, buf) } +const ImplementsGetwd = true + +//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD + +func Getwd() (string, error) { + var buf [PathMax]byte + _, err := Getcwd(buf[0:]) + if err != nil { + return "", err + } + n := clen(buf[:]) + if n < 1 { + return "", EINVAL + } + return string(buf[:n]), nil +} + // TODO func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { return -1, ENOSYS } +func setattrlistTimes(path string, times []Timespec, flags int) error { + // used on Darwin for UtimesNano + return ENOSYS +} + +//sys ioctl(fd int, req uint, arg uintptr) (err error) + +// ioctl itself should not be exposed directly, but additional get/set +// functions for specific types are permissible. + +// IoctlSetInt performs an ioctl operation which sets an integer value +// on fd, using the specified request number. +func IoctlSetInt(fd int, req uint, value int) error { + return ioctl(fd, req, uintptr(value)) +} + +func IoctlSetWinsize(fd int, req uint, value *Winsize) error { + return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +} + +func IoctlSetTermios(fd int, req uint, value *Termios) error { + return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +} + +// IoctlGetInt performs an ioctl operation which gets an integer value +// from fd, using the specified request number. +func IoctlGetInt(fd int, req uint) (int, error) { + var value int + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return value, err +} + +func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { + var value Winsize + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func IoctlGetTermios(fd int, req uint) (*Termios, error) { + var value Termios + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func Uname(uname *Utsname) error { + mib := []_C_int{CTL_KERN, KERN_OSTYPE} + n := unsafe.Sizeof(uname.Sysname) + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_HOSTNAME} + n = unsafe.Sizeof(uname.Nodename) + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_OSRELEASE} + n = unsafe.Sizeof(uname.Release) + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_VERSION} + n = unsafe.Sizeof(uname.Version) + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + return err + } + + // The version might have newlines or tabs in it, convert them to + // spaces. + for i, b := range uname.Version { + if b == '\n' || b == '\t' { + if i == len(uname.Version)-1 { + uname.Version[i] = 0 + } else { + uname.Version[i] = ' ' + } + } + } + + mib = []_C_int{CTL_HW, HW_MACHINE} + n = unsafe.Sizeof(uname.Machine) + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + return err + } + + return nil +} + /* * Exposed directly */ @@ -138,13 +233,16 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to int) (err error) //sys Exit(code int) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -170,11 +268,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Mkdir(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) -//sys Mlock(b []byte) (err error) -//sys Mlockall(flags int) (err error) -//sys Mprotect(b []byte, prot int) (err error) -//sys Munlock(b []byte) (err error) -//sys Munlockall() (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Pathconf(path string, name int) (val int, err error) @@ -210,6 +303,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys munmap(addr uintptr, length uintptr) (err error) //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE +//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) /* * Unimplemented @@ -229,7 +323,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e // __msync13 // __ntp_gettime30 // __posix_chown -// __posix_fadvise50 // __posix_fchown // __posix_lchown // __posix_rename @@ -388,7 +481,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e // getitimer // getvfsstat // getxattr -// ioctl // ktrace // lchflags // lchmod @@ -426,7 +518,6 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e // ntp_adjtime // pmc_control // pmc_get_info -// poll // pollts // preadv // profil diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go index afaca0983..24f74e58c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go @@ -6,21 +6,12 @@ package unix -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go index a6ff04ce5..6878bf7ff 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go @@ -6,21 +6,12 @@ package unix -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int64(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go index 68a6969b2..dbbfcf71d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go @@ -6,21 +6,12 @@ package unix -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_no_getwd.go b/vendor/golang.org/x/sys/unix/syscall_no_getwd.go deleted file mode 100644 index 530792ea9..000000000 --- a/vendor/golang.org/x/sys/unix/syscall_no_getwd.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build dragonfly freebsd netbsd openbsd - -package unix - -const ImplementsGetwd = false - -func Getwd() (string, error) { return "", ENOTSUP } diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index c0d2b6c80..387e1cfcf 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -13,10 +13,12 @@ package unix import ( + "sort" "syscall" "unsafe" ) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Len uint8 Family uint8 @@ -32,39 +34,15 @@ type SockaddrDatalink struct { func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func nametomib(name string) (mib []_C_int, err error) { - - // Perform lookup via a binary search - left := 0 - right := len(sysctlMib) - 1 - for { - idx := left + (right-left)/2 - switch { - case name == sysctlMib[idx].ctlname: - return sysctlMib[idx].ctloid, nil - case name > sysctlMib[idx].ctlname: - left = idx + 1 - default: - right = idx - 1 - } - if left > right { - break - } + i := sort.Search(len(sysctlMib), func(i int) bool { + return sysctlMib[i].ctlname >= name + }) + if i < len(sysctlMib) && sysctlMib[i].ctlname == name { + return sysctlMib[i].ctloid, nil } return nil, EINVAL } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe(p *[2]_C_int) (err error) func Pipe(p []int) (err error) { if len(p) != 2 { @@ -82,6 +60,23 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { return getdents(fd, buf) } +const ImplementsGetwd = true + +//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD + +func Getwd() (string, error) { + var buf [PathMax]byte + _, err := Getcwd(buf[0:]) + if err != nil { + return "", err + } + n := clen(buf[:]) + if n < 1 { + return "", EINVAL + } + return string(buf[:n]), nil +} + // TODO func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { return -1, ENOSYS @@ -102,6 +97,96 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } +func setattrlistTimes(path string, times []Timespec, flags int) error { + // used on Darwin for UtimesNano + return ENOSYS +} + +//sys ioctl(fd int, req uint, arg uintptr) (err error) + +// ioctl itself should not be exposed directly, but additional get/set +// functions for specific types are permissible. + +// IoctlSetInt performs an ioctl operation which sets an integer value +// on fd, using the specified request number. +func IoctlSetInt(fd int, req uint, value int) error { + return ioctl(fd, req, uintptr(value)) +} + +func IoctlSetWinsize(fd int, req uint, value *Winsize) error { + return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +} + +func IoctlSetTermios(fd int, req uint, value *Termios) error { + return ioctl(fd, req, uintptr(unsafe.Pointer(value))) +} + +// IoctlGetInt performs an ioctl operation which gets an integer value +// from fd, using the specified request number. +func IoctlGetInt(fd int, req uint) (int, error) { + var value int + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return value, err +} + +func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { + var value Winsize + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func IoctlGetTermios(fd int, req uint) (*Termios, error) { + var value Termios + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func Uname(uname *Utsname) error { + mib := []_C_int{CTL_KERN, KERN_OSTYPE} + n := unsafe.Sizeof(uname.Sysname) + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_HOSTNAME} + n = unsafe.Sizeof(uname.Nodename) + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_OSRELEASE} + n = unsafe.Sizeof(uname.Release) + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + return err + } + + mib = []_C_int{CTL_KERN, KERN_VERSION} + n = unsafe.Sizeof(uname.Version) + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + return err + } + + // The version might have newlines or tabs in it, convert them to + // spaces. + for i, b := range uname.Version { + if b == '\n' || b == '\t' { + if i == len(uname.Version)-1 { + uname.Version[i] = 0 + } else { + uname.Version[i] = ' ' + } + } + } + + mib = []_C_int{CTL_HW, HW_MACHINE} + n = unsafe.Sizeof(uname.Machine) + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + return err + } + + return nil +} + /* * Exposed directly */ @@ -119,10 +204,12 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) @@ -149,11 +236,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { //sys Mkdir(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) -//sys Mlock(b []byte) (err error) -//sys Mlockall(flags int) (err error) -//sys Mprotect(b []byte, prot int) (err error) -//sys Munlock(b []byte) (err error) -//sys Munlockall() (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Pathconf(path string, name int) (val int, err error) @@ -193,6 +275,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { //sys munmap(addr uintptr, length uintptr) (err error) //sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE +//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) /* * Unimplemented @@ -226,7 +309,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // getresuid // getrtable // getthrid -// ioctl // ktrace // lfs_bmapv // lfs_markv @@ -247,7 +329,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // nfssvc // nnpfspioctl // openat -// poll // preadv // profil // pwritev @@ -282,6 +363,5 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { // thrsleep // thrwakeup // unlinkat -// utimensat // vfork // writev diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go index a66ddc59c..994964a91 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go @@ -6,21 +6,12 @@ package unix -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go index 0776c1faf..649e67fcc 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go @@ -6,21 +6,12 @@ package unix -func Getpagesize() int { return 4096 } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = nsec % 1e9 / 1e3 - tv.Sec = nsec / 1e9 - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go index 14ddaf3f3..59844f504 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go @@ -6,23 +6,12 @@ package unix -import "syscall" - -func Getpagesize() int { return syscall.Getpagesize() } - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: int32(nsec)} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: int32(usec)} } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 0d4e5c4e6..f4d2a3451 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -13,7 +13,6 @@ package unix import ( - "sync/atomic" "syscall" "unsafe" ) @@ -24,6 +23,7 @@ type syscallFunc uintptr func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. type SockaddrDatalink struct { Family uint16 Index uint16 @@ -35,31 +35,6 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } -func clen(n []byte) int { - for i := 0; i < len(n); i++ { - if n[i] == 0 { - return i - } - } - return len(n) -} - -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - reclen, ok := direntReclen(buf) - if !ok { - return 0, false - } - return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true -} - //sysnb pipe(p *[2]_C_int) (n int, err error) func Pipe(p []int) (err error) { @@ -140,6 +115,18 @@ func Getsockname(fd int) (sa Sockaddr, err error) { return anyToSockaddr(&rsa) } +// GetsockoptString returns the string value of the socket option opt for the +// socket associated with fd at the given socket level. +func GetsockoptString(fd, level, opt int) (string, error) { + buf := make([]byte, 256) + vallen := _Socklen(len(buf)) + err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) + if err != nil { + return "", err + } + return string(buf[:vallen-1]), nil +} + const ImplementsGetwd = true //sys Getcwd(buf []byte) (n int, err error) @@ -167,7 +154,7 @@ func Getwd() (wd string, err error) { func Getgroups() (gids []int, err error) { n, err := getgroups(0, nil) - // Check for error and sanity check group count. Newer versions of + // Check for error and sanity check group count. Newer versions of // Solaris allow up to 1024 (NGROUPS_MAX). if n < 0 || n > 1024 { if err != nil { @@ -351,7 +338,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error { } // Solaris doesn't have an futimes function because it allows NULL to be -// specified as the path for futimesat. However, Go doesn't like +// specified as the path for futimesat. However, Go doesn't like // NULL-style string interfaces, so this simple wrapper is provided. func Futimes(fd int, tv []Timeval) error { if tv == nil { @@ -515,6 +502,24 @@ func Acct(path string) (err error) { return acct(pathp) } +//sys __makedev(version int, major uint, minor uint) (val uint64) + +func Mkdev(major, minor uint32) uint64 { + return __makedev(NEWDEV, uint(major), uint(minor)) +} + +//sys __major(version int, dev uint64) (val uint) + +func Major(dev uint64) uint32 { + return uint32(__major(NEWDEV, dev)) +} + +//sys __minor(version int, dev uint64) (val uint) + +func Minor(dev uint64) uint32 { + return uint32(__minor(NEWDEV, dev)) +} + /* * Expose the ioctl function */ @@ -561,6 +566,15 @@ func IoctlGetTermio(fd int, req uint) (*Termio, error) { return &value, err } +//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) + +func Poll(fds []PollFd, timeout int) (n int, err error) { + if len(fds) == 0 { + return poll(nil, 0, timeout) + } + return poll(&fds[0], len(fds), timeout) +} + /* * Exposed directly */ @@ -581,9 +595,10 @@ func IoctlGetTermio(fd int, req uint) (*Termio, error) { //sys Fchown(fd int, uid int, gid int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fdatasync(fd int) (err error) -//sys Flock(fd int, how int) (err error) +//sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) //sysnb Getgid() (gid int) @@ -613,6 +628,7 @@ func IoctlGetTermio(fd int, req uint) (*Termio, error) { //sys Mlock(b []byte) (err error) //sys Mlockall(flags int) (err error) //sys Mprotect(b []byte, prot int) (err error) +//sys Msync(b []byte, flags int) (err error) //sys Munlock(b []byte) (err error) //sys Munlockall() (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) @@ -628,6 +644,7 @@ func IoctlGetTermio(fd int, req uint) (*Termio, error) { //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Rmdir(path string) (err error) //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek +//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) //sysnb Setegid(egid int) (err error) //sysnb Seteuid(euid int) (err error) //sysnb Setgid(gid int) (err error) @@ -699,18 +716,3 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e func Munmap(b []byte) (err error) { return mapper.Munmap(b) } - -//sys sysconf(name int) (n int64, err error) - -// pageSize caches the value of Getpagesize, since it can't change -// once the system is booted. -var pageSize int64 // accessed atomically - -func Getpagesize() int { - n := atomic.LoadInt64(&pageSize) - if n == 0 { - n, _ = sysconf(_SC_PAGESIZE) - atomic.StoreInt64(&pageSize, n) - } - return int(n) -} diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go index 5aff62c3b..9d4e7a678 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go @@ -6,19 +6,12 @@ package unix -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = nsec / 1e9 - ts.Nsec = nsec % 1e9 - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} } -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = nsec % 1e9 / 1e3 - tv.Sec = int64(nsec / 1e9) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} } func (iov *Iovec) SetLen(length int) { diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 3ed8a91f5..8c66ae518 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -7,6 +7,7 @@ package unix import ( + "bytes" "runtime" "sync" "syscall" @@ -50,6 +51,15 @@ func errnoErr(e syscall.Errno) error { return e } +// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. +func clen(n []byte) int { + i := bytes.IndexByte(n, 0) + if i == -1 { + i = len(n) + } + return i +} + // Mmap manager, for use by operating system-specific implementations. type mmapper struct { @@ -138,16 +148,19 @@ func Write(fd int, p []byte) (n int, err error) { // creation of IPv6 sockets to return EAFNOSUPPORT. var SocketDisableIPv6 bool +// Sockaddr represents a socket address. type Sockaddr interface { sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs } +// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets. type SockaddrInet4 struct { Port int Addr [4]byte raw RawSockaddrInet4 } +// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets. type SockaddrInet6 struct { Port int ZoneId uint32 @@ -155,6 +168,7 @@ type SockaddrInet6 struct { raw RawSockaddrInet6 } +// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets. type SockaddrUnix struct { Name string raw RawSockaddrUnix @@ -192,6 +206,20 @@ func GetsockoptInt(fd, level, opt int) (value int, err error) { return int(n), err } +func GetsockoptLinger(fd, level, opt int) (*Linger, error) { + var linger Linger + vallen := _Socklen(SizeofLinger) + err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen) + return &linger, err +} + +func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) { + var tv Timeval + vallen := _Socklen(unsafe.Sizeof(tv)) + err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen) + return &tv, err +} + func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { var rsa RawSockaddrAny var len _Socklen = SizeofSockaddrAny @@ -291,3 +319,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) { _, err = fcntl(fd, F_SETFL, flag) return err } + +// Exec calls execve(2), which replaces the calling executable in the process +// tree. argv0 should be the full path to an executable ("/bin/ls") and the +// executable name should also be the first argument in argv (["ls", "-l"]). +// envv are the environment variables that should be passed to the new +// process (["USER=go", "PWD=/tmp"]). +func Exec(argv0 string, argv []string, envv []string) error { + return syscall.Exec(argv0, argv, envv) +} diff --git a/vendor/golang.org/x/sys/unix/timestruct.go b/vendor/golang.org/x/sys/unix/timestruct.go new file mode 100644 index 000000000..47b9011ee --- /dev/null +++ b/vendor/golang.org/x/sys/unix/timestruct.go @@ -0,0 +1,82 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +package unix + +import "time" + +// TimespecToNsec converts a Timespec value into a number of +// nanoseconds since the Unix epoch. +func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } + +// NsecToTimespec takes a number of nanoseconds since the Unix epoch +// and returns the corresponding Timespec value. +func NsecToTimespec(nsec int64) Timespec { + sec := nsec / 1e9 + nsec = nsec % 1e9 + if nsec < 0 { + nsec += 1e9 + sec-- + } + return setTimespec(sec, nsec) +} + +// TimeToTimespec converts t into a Timespec. +// On some 32-bit systems the range of valid Timespec values are smaller +// than that of time.Time values. So if t is out of the valid range of +// Timespec, it returns a zero Timespec and ERANGE. +func TimeToTimespec(t time.Time) (Timespec, error) { + sec := t.Unix() + nsec := int64(t.Nanosecond()) + ts := setTimespec(sec, nsec) + + // Currently all targets have either int32 or int64 for Timespec.Sec. + // If there were a new target with floating point type for it, we have + // to consider the rounding error. + if int64(ts.Sec) != sec { + return Timespec{}, ERANGE + } + return ts, nil +} + +// TimevalToNsec converts a Timeval value into a number of nanoseconds +// since the Unix epoch. +func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } + +// NsecToTimeval takes a number of nanoseconds since the Unix epoch +// and returns the corresponding Timeval value. +func NsecToTimeval(nsec int64) Timeval { + nsec += 999 // round up to microsecond + usec := nsec % 1e9 / 1e3 + sec := nsec / 1e9 + if usec < 0 { + usec += 1e6 + sec-- + } + return setTimeval(sec, usec) +} + +// Unix returns ts as the number of seconds and nanoseconds elapsed since the +// Unix epoch. +func (ts *Timespec) Unix() (sec int64, nsec int64) { + return int64(ts.Sec), int64(ts.Nsec) +} + +// Unix returns tv as the number of seconds and nanoseconds elapsed since the +// Unix epoch. +func (tv *Timeval) Unix() (sec int64, nsec int64) { + return int64(tv.Sec), int64(tv.Usec) * 1000 +} + +// Nano returns ts as the number of nanoseconds elapsed since the Unix epoch. +func (ts *Timespec) Nano() int64 { + return int64(ts.Sec)*1e9 + int64(ts.Nsec) +} + +// Nano returns tv as the number of nanoseconds elapsed since the Unix epoch. +func (tv *Timeval) Nano() int64 { + return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go index 1c68758b6..dcba88424 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go @@ -49,6 +49,86 @@ const ( AF_UNSPEC = 0x0 AF_UTUN = 0x26 ALTWERASE = 0x200 + ATTR_BIT_MAP_COUNT = 0x5 + ATTR_CMN_ACCESSMASK = 0x20000 + ATTR_CMN_ACCTIME = 0x1000 + ATTR_CMN_ADDEDTIME = 0x10000000 + ATTR_CMN_BKUPTIME = 0x2000 + ATTR_CMN_CHGTIME = 0x800 + ATTR_CMN_CRTIME = 0x200 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 + ATTR_CMN_DEVID = 0x2 + ATTR_CMN_DOCUMENT_ID = 0x100000 + ATTR_CMN_ERROR = 0x20000000 + ATTR_CMN_EXTENDED_SECURITY = 0x400000 + ATTR_CMN_FILEID = 0x2000000 + ATTR_CMN_FLAGS = 0x40000 + ATTR_CMN_FNDRINFO = 0x4000 + ATTR_CMN_FSID = 0x4 + ATTR_CMN_FULLPATH = 0x8000000 + ATTR_CMN_GEN_COUNT = 0x80000 + ATTR_CMN_GRPID = 0x10000 + ATTR_CMN_GRPUUID = 0x1000000 + ATTR_CMN_MODTIME = 0x400 + ATTR_CMN_NAME = 0x1 + ATTR_CMN_NAMEDATTRCOUNT = 0x80000 + ATTR_CMN_NAMEDATTRLIST = 0x100000 + ATTR_CMN_OBJID = 0x20 + ATTR_CMN_OBJPERMANENTID = 0x40 + ATTR_CMN_OBJTAG = 0x10 + ATTR_CMN_OBJTYPE = 0x8 + ATTR_CMN_OWNERID = 0x8000 + ATTR_CMN_PARENTID = 0x4000000 + ATTR_CMN_PAROBJID = 0x80 + ATTR_CMN_RETURNED_ATTRS = 0x80000000 + ATTR_CMN_SCRIPT = 0x100 + ATTR_CMN_SETMASK = 0x41c7ff00 + ATTR_CMN_USERACCESS = 0x200000 + ATTR_CMN_UUID = 0x800000 + ATTR_CMN_VALIDMASK = 0xffffffff + ATTR_CMN_VOLSETMASK = 0x6700 + ATTR_FILE_ALLOCSIZE = 0x4 + ATTR_FILE_CLUMPSIZE = 0x10 + ATTR_FILE_DATAALLOCSIZE = 0x400 + ATTR_FILE_DATAEXTENTS = 0x800 + ATTR_FILE_DATALENGTH = 0x200 + ATTR_FILE_DEVTYPE = 0x20 + ATTR_FILE_FILETYPE = 0x40 + ATTR_FILE_FORKCOUNT = 0x80 + ATTR_FILE_FORKLIST = 0x100 + ATTR_FILE_IOBLOCKSIZE = 0x8 + ATTR_FILE_LINKCOUNT = 0x1 + ATTR_FILE_RSRCALLOCSIZE = 0x2000 + ATTR_FILE_RSRCEXTENTS = 0x4000 + ATTR_FILE_RSRCLENGTH = 0x1000 + ATTR_FILE_SETMASK = 0x20 + ATTR_FILE_TOTALSIZE = 0x2 + ATTR_FILE_VALIDMASK = 0x37ff + ATTR_VOL_ALLOCATIONCLUMP = 0x40 + ATTR_VOL_ATTRIBUTES = 0x40000000 + ATTR_VOL_CAPABILITIES = 0x20000 + ATTR_VOL_DIRCOUNT = 0x400 + ATTR_VOL_ENCODINGSUSED = 0x10000 + ATTR_VOL_FILECOUNT = 0x200 + ATTR_VOL_FSTYPE = 0x1 + ATTR_VOL_INFO = 0x80000000 + ATTR_VOL_IOBLOCKSIZE = 0x80 + ATTR_VOL_MAXOBJCOUNT = 0x800 + ATTR_VOL_MINALLOCATION = 0x20 + ATTR_VOL_MOUNTEDDEVICE = 0x8000 + ATTR_VOL_MOUNTFLAGS = 0x4000 + ATTR_VOL_MOUNTPOINT = 0x1000 + ATTR_VOL_NAME = 0x2000 + ATTR_VOL_OBJCOUNT = 0x100 + ATTR_VOL_QUOTA_SIZE = 0x10000000 + ATTR_VOL_RESERVED_SIZE = 0x20000000 + ATTR_VOL_SETMASK = 0x80002000 + ATTR_VOL_SIGNATURE = 0x2 + ATTR_VOL_SIZE = 0x4 + ATTR_VOL_SPACEAVAIL = 0x10 + ATTR_VOL_SPACEFREE = 0x8 + ATTR_VOL_UUID = 0x40000 + ATTR_VOL_VALIDMASK = 0xf007ffff B0 = 0x0 B110 = 0x6e B115200 = 0x1c200 @@ -169,6 +249,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -390,6 +472,11 @@ const ( FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FSOPT_ATTR_CMN_EXTENDED = 0x20 + FSOPT_NOFOLLOW = 0x1 + FSOPT_NOINMEMUPDATE = 0x2 + FSOPT_PACK_INVAL_ATTRS = 0x8 + FSOPT_REPORT_FULLSIZE = 0x4 F_ADDFILESIGS = 0x3d F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 F_ADDFILESIGS_RETURN = 0x61 @@ -425,6 +512,7 @@ const ( F_PATHPKG_CHECK = 0x34 F_PEOFPOSMODE = 0x3 F_PREALLOCATE = 0x2a + F_PUNCHHOLE = 0x63 F_RDADVISE = 0x2c F_RDAHEAD = 0x2d F_RDLCK = 0x1 @@ -441,10 +529,12 @@ const ( F_SINGLE_WRITER = 0x4c F_THAW_FS = 0x36 F_TRANSCODEKEY = 0x4b + F_TRIM_ACTIVE_FILE = 0x64 F_UNLCK = 0x2 F_VOLPOSMODE = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -681,6 +771,7 @@ const ( IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOW_ECN_MASK = 0x300 IPV6_FRAGTTL = 0x3c IPV6_FW_ADD = 0x1e IPV6_FW_DEL = 0x1f @@ -771,6 +862,7 @@ const ( IP_RECVOPTS = 0x5 IP_RECVPKTINFO = 0x1a IP_RECVRETOPTS = 0x6 + IP_RECVTOS = 0x1b IP_RECVTTL = 0x18 IP_RETOPTS = 0x8 IP_RF = 0x8000 @@ -789,6 +881,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index 48f63d4f0..1a51c963c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -49,6 +49,86 @@ const ( AF_UNSPEC = 0x0 AF_UTUN = 0x26 ALTWERASE = 0x200 + ATTR_BIT_MAP_COUNT = 0x5 + ATTR_CMN_ACCESSMASK = 0x20000 + ATTR_CMN_ACCTIME = 0x1000 + ATTR_CMN_ADDEDTIME = 0x10000000 + ATTR_CMN_BKUPTIME = 0x2000 + ATTR_CMN_CHGTIME = 0x800 + ATTR_CMN_CRTIME = 0x200 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 + ATTR_CMN_DEVID = 0x2 + ATTR_CMN_DOCUMENT_ID = 0x100000 + ATTR_CMN_ERROR = 0x20000000 + ATTR_CMN_EXTENDED_SECURITY = 0x400000 + ATTR_CMN_FILEID = 0x2000000 + ATTR_CMN_FLAGS = 0x40000 + ATTR_CMN_FNDRINFO = 0x4000 + ATTR_CMN_FSID = 0x4 + ATTR_CMN_FULLPATH = 0x8000000 + ATTR_CMN_GEN_COUNT = 0x80000 + ATTR_CMN_GRPID = 0x10000 + ATTR_CMN_GRPUUID = 0x1000000 + ATTR_CMN_MODTIME = 0x400 + ATTR_CMN_NAME = 0x1 + ATTR_CMN_NAMEDATTRCOUNT = 0x80000 + ATTR_CMN_NAMEDATTRLIST = 0x100000 + ATTR_CMN_OBJID = 0x20 + ATTR_CMN_OBJPERMANENTID = 0x40 + ATTR_CMN_OBJTAG = 0x10 + ATTR_CMN_OBJTYPE = 0x8 + ATTR_CMN_OWNERID = 0x8000 + ATTR_CMN_PARENTID = 0x4000000 + ATTR_CMN_PAROBJID = 0x80 + ATTR_CMN_RETURNED_ATTRS = 0x80000000 + ATTR_CMN_SCRIPT = 0x100 + ATTR_CMN_SETMASK = 0x41c7ff00 + ATTR_CMN_USERACCESS = 0x200000 + ATTR_CMN_UUID = 0x800000 + ATTR_CMN_VALIDMASK = 0xffffffff + ATTR_CMN_VOLSETMASK = 0x6700 + ATTR_FILE_ALLOCSIZE = 0x4 + ATTR_FILE_CLUMPSIZE = 0x10 + ATTR_FILE_DATAALLOCSIZE = 0x400 + ATTR_FILE_DATAEXTENTS = 0x800 + ATTR_FILE_DATALENGTH = 0x200 + ATTR_FILE_DEVTYPE = 0x20 + ATTR_FILE_FILETYPE = 0x40 + ATTR_FILE_FORKCOUNT = 0x80 + ATTR_FILE_FORKLIST = 0x100 + ATTR_FILE_IOBLOCKSIZE = 0x8 + ATTR_FILE_LINKCOUNT = 0x1 + ATTR_FILE_RSRCALLOCSIZE = 0x2000 + ATTR_FILE_RSRCEXTENTS = 0x4000 + ATTR_FILE_RSRCLENGTH = 0x1000 + ATTR_FILE_SETMASK = 0x20 + ATTR_FILE_TOTALSIZE = 0x2 + ATTR_FILE_VALIDMASK = 0x37ff + ATTR_VOL_ALLOCATIONCLUMP = 0x40 + ATTR_VOL_ATTRIBUTES = 0x40000000 + ATTR_VOL_CAPABILITIES = 0x20000 + ATTR_VOL_DIRCOUNT = 0x400 + ATTR_VOL_ENCODINGSUSED = 0x10000 + ATTR_VOL_FILECOUNT = 0x200 + ATTR_VOL_FSTYPE = 0x1 + ATTR_VOL_INFO = 0x80000000 + ATTR_VOL_IOBLOCKSIZE = 0x80 + ATTR_VOL_MAXOBJCOUNT = 0x800 + ATTR_VOL_MINALLOCATION = 0x20 + ATTR_VOL_MOUNTEDDEVICE = 0x8000 + ATTR_VOL_MOUNTFLAGS = 0x4000 + ATTR_VOL_MOUNTPOINT = 0x1000 + ATTR_VOL_NAME = 0x2000 + ATTR_VOL_OBJCOUNT = 0x100 + ATTR_VOL_QUOTA_SIZE = 0x10000000 + ATTR_VOL_RESERVED_SIZE = 0x20000000 + ATTR_VOL_SETMASK = 0x80002000 + ATTR_VOL_SIGNATURE = 0x2 + ATTR_VOL_SIZE = 0x4 + ATTR_VOL_SPACEAVAIL = 0x10 + ATTR_VOL_SPACEFREE = 0x8 + ATTR_VOL_UUID = 0x40000 + ATTR_VOL_VALIDMASK = 0xf007ffff B0 = 0x0 B110 = 0x6e B115200 = 0x1c200 @@ -169,6 +249,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -390,6 +472,11 @@ const ( FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FSOPT_ATTR_CMN_EXTENDED = 0x20 + FSOPT_NOFOLLOW = 0x1 + FSOPT_NOINMEMUPDATE = 0x2 + FSOPT_PACK_INVAL_ATTRS = 0x8 + FSOPT_REPORT_FULLSIZE = 0x4 F_ADDFILESIGS = 0x3d F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 F_ADDFILESIGS_RETURN = 0x61 @@ -425,6 +512,7 @@ const ( F_PATHPKG_CHECK = 0x34 F_PEOFPOSMODE = 0x3 F_PREALLOCATE = 0x2a + F_PUNCHHOLE = 0x63 F_RDADVISE = 0x2c F_RDAHEAD = 0x2d F_RDLCK = 0x1 @@ -441,10 +529,12 @@ const ( F_SINGLE_WRITER = 0x4c F_THAW_FS = 0x36 F_TRANSCODEKEY = 0x4b + F_TRIM_ACTIVE_FILE = 0x64 F_UNLCK = 0x2 F_VOLPOSMODE = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -681,6 +771,7 @@ const ( IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOW_ECN_MASK = 0x300 IPV6_FRAGTTL = 0x3c IPV6_FW_ADD = 0x1e IPV6_FW_DEL = 0x1f @@ -771,6 +862,7 @@ const ( IP_RECVOPTS = 0x5 IP_RECVPKTINFO = 0x1a IP_RECVRETOPTS = 0x6 + IP_RECVTOS = 0x1b IP_RECVTTL = 0x18 IP_RETOPTS = 0x8 IP_RF = 0x8000 @@ -789,6 +881,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go index 24cb522d9..fa135b17c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go @@ -49,6 +49,86 @@ const ( AF_UNSPEC = 0x0 AF_UTUN = 0x26 ALTWERASE = 0x200 + ATTR_BIT_MAP_COUNT = 0x5 + ATTR_CMN_ACCESSMASK = 0x20000 + ATTR_CMN_ACCTIME = 0x1000 + ATTR_CMN_ADDEDTIME = 0x10000000 + ATTR_CMN_BKUPTIME = 0x2000 + ATTR_CMN_CHGTIME = 0x800 + ATTR_CMN_CRTIME = 0x200 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 + ATTR_CMN_DEVID = 0x2 + ATTR_CMN_DOCUMENT_ID = 0x100000 + ATTR_CMN_ERROR = 0x20000000 + ATTR_CMN_EXTENDED_SECURITY = 0x400000 + ATTR_CMN_FILEID = 0x2000000 + ATTR_CMN_FLAGS = 0x40000 + ATTR_CMN_FNDRINFO = 0x4000 + ATTR_CMN_FSID = 0x4 + ATTR_CMN_FULLPATH = 0x8000000 + ATTR_CMN_GEN_COUNT = 0x80000 + ATTR_CMN_GRPID = 0x10000 + ATTR_CMN_GRPUUID = 0x1000000 + ATTR_CMN_MODTIME = 0x400 + ATTR_CMN_NAME = 0x1 + ATTR_CMN_NAMEDATTRCOUNT = 0x80000 + ATTR_CMN_NAMEDATTRLIST = 0x100000 + ATTR_CMN_OBJID = 0x20 + ATTR_CMN_OBJPERMANENTID = 0x40 + ATTR_CMN_OBJTAG = 0x10 + ATTR_CMN_OBJTYPE = 0x8 + ATTR_CMN_OWNERID = 0x8000 + ATTR_CMN_PARENTID = 0x4000000 + ATTR_CMN_PAROBJID = 0x80 + ATTR_CMN_RETURNED_ATTRS = 0x80000000 + ATTR_CMN_SCRIPT = 0x100 + ATTR_CMN_SETMASK = 0x41c7ff00 + ATTR_CMN_USERACCESS = 0x200000 + ATTR_CMN_UUID = 0x800000 + ATTR_CMN_VALIDMASK = 0xffffffff + ATTR_CMN_VOLSETMASK = 0x6700 + ATTR_FILE_ALLOCSIZE = 0x4 + ATTR_FILE_CLUMPSIZE = 0x10 + ATTR_FILE_DATAALLOCSIZE = 0x400 + ATTR_FILE_DATAEXTENTS = 0x800 + ATTR_FILE_DATALENGTH = 0x200 + ATTR_FILE_DEVTYPE = 0x20 + ATTR_FILE_FILETYPE = 0x40 + ATTR_FILE_FORKCOUNT = 0x80 + ATTR_FILE_FORKLIST = 0x100 + ATTR_FILE_IOBLOCKSIZE = 0x8 + ATTR_FILE_LINKCOUNT = 0x1 + ATTR_FILE_RSRCALLOCSIZE = 0x2000 + ATTR_FILE_RSRCEXTENTS = 0x4000 + ATTR_FILE_RSRCLENGTH = 0x1000 + ATTR_FILE_SETMASK = 0x20 + ATTR_FILE_TOTALSIZE = 0x2 + ATTR_FILE_VALIDMASK = 0x37ff + ATTR_VOL_ALLOCATIONCLUMP = 0x40 + ATTR_VOL_ATTRIBUTES = 0x40000000 + ATTR_VOL_CAPABILITIES = 0x20000 + ATTR_VOL_DIRCOUNT = 0x400 + ATTR_VOL_ENCODINGSUSED = 0x10000 + ATTR_VOL_FILECOUNT = 0x200 + ATTR_VOL_FSTYPE = 0x1 + ATTR_VOL_INFO = 0x80000000 + ATTR_VOL_IOBLOCKSIZE = 0x80 + ATTR_VOL_MAXOBJCOUNT = 0x800 + ATTR_VOL_MINALLOCATION = 0x20 + ATTR_VOL_MOUNTEDDEVICE = 0x8000 + ATTR_VOL_MOUNTFLAGS = 0x4000 + ATTR_VOL_MOUNTPOINT = 0x1000 + ATTR_VOL_NAME = 0x2000 + ATTR_VOL_OBJCOUNT = 0x100 + ATTR_VOL_QUOTA_SIZE = 0x10000000 + ATTR_VOL_RESERVED_SIZE = 0x20000000 + ATTR_VOL_SETMASK = 0x80002000 + ATTR_VOL_SIGNATURE = 0x2 + ATTR_VOL_SIZE = 0x4 + ATTR_VOL_SPACEAVAIL = 0x10 + ATTR_VOL_SPACEFREE = 0x8 + ATTR_VOL_UUID = 0x40000 + ATTR_VOL_VALIDMASK = 0xf007ffff B0 = 0x0 B110 = 0x6e B115200 = 0x1c200 @@ -169,6 +249,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -390,6 +472,11 @@ const ( FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FSOPT_ATTR_CMN_EXTENDED = 0x20 + FSOPT_NOFOLLOW = 0x1 + FSOPT_NOINMEMUPDATE = 0x2 + FSOPT_PACK_INVAL_ATTRS = 0x8 + FSOPT_REPORT_FULLSIZE = 0x4 F_ADDFILESIGS = 0x3d F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 F_ADDFILESIGS_RETURN = 0x61 @@ -425,6 +512,7 @@ const ( F_PATHPKG_CHECK = 0x34 F_PEOFPOSMODE = 0x3 F_PREALLOCATE = 0x2a + F_PUNCHHOLE = 0x63 F_RDADVISE = 0x2c F_RDAHEAD = 0x2d F_RDLCK = 0x1 @@ -441,10 +529,12 @@ const ( F_SINGLE_WRITER = 0x4c F_THAW_FS = 0x36 F_TRANSCODEKEY = 0x4b + F_TRIM_ACTIVE_FILE = 0x64 F_UNLCK = 0x2 F_VOLPOSMODE = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -681,6 +771,7 @@ const ( IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOW_ECN_MASK = 0x300 IPV6_FRAGTTL = 0x3c IPV6_FW_ADD = 0x1e IPV6_FW_DEL = 0x1f @@ -771,6 +862,7 @@ const ( IP_RECVOPTS = 0x5 IP_RECVPKTINFO = 0x1a IP_RECVRETOPTS = 0x6 + IP_RECVTOS = 0x1b IP_RECVTTL = 0x18 IP_RETOPTS = 0x8 IP_RF = 0x8000 @@ -789,6 +881,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index cc8cc5b57..6419c65e1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -49,6 +49,86 @@ const ( AF_UNSPEC = 0x0 AF_UTUN = 0x26 ALTWERASE = 0x200 + ATTR_BIT_MAP_COUNT = 0x5 + ATTR_CMN_ACCESSMASK = 0x20000 + ATTR_CMN_ACCTIME = 0x1000 + ATTR_CMN_ADDEDTIME = 0x10000000 + ATTR_CMN_BKUPTIME = 0x2000 + ATTR_CMN_CHGTIME = 0x800 + ATTR_CMN_CRTIME = 0x200 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 + ATTR_CMN_DEVID = 0x2 + ATTR_CMN_DOCUMENT_ID = 0x100000 + ATTR_CMN_ERROR = 0x20000000 + ATTR_CMN_EXTENDED_SECURITY = 0x400000 + ATTR_CMN_FILEID = 0x2000000 + ATTR_CMN_FLAGS = 0x40000 + ATTR_CMN_FNDRINFO = 0x4000 + ATTR_CMN_FSID = 0x4 + ATTR_CMN_FULLPATH = 0x8000000 + ATTR_CMN_GEN_COUNT = 0x80000 + ATTR_CMN_GRPID = 0x10000 + ATTR_CMN_GRPUUID = 0x1000000 + ATTR_CMN_MODTIME = 0x400 + ATTR_CMN_NAME = 0x1 + ATTR_CMN_NAMEDATTRCOUNT = 0x80000 + ATTR_CMN_NAMEDATTRLIST = 0x100000 + ATTR_CMN_OBJID = 0x20 + ATTR_CMN_OBJPERMANENTID = 0x40 + ATTR_CMN_OBJTAG = 0x10 + ATTR_CMN_OBJTYPE = 0x8 + ATTR_CMN_OWNERID = 0x8000 + ATTR_CMN_PARENTID = 0x4000000 + ATTR_CMN_PAROBJID = 0x80 + ATTR_CMN_RETURNED_ATTRS = 0x80000000 + ATTR_CMN_SCRIPT = 0x100 + ATTR_CMN_SETMASK = 0x41c7ff00 + ATTR_CMN_USERACCESS = 0x200000 + ATTR_CMN_UUID = 0x800000 + ATTR_CMN_VALIDMASK = 0xffffffff + ATTR_CMN_VOLSETMASK = 0x6700 + ATTR_FILE_ALLOCSIZE = 0x4 + ATTR_FILE_CLUMPSIZE = 0x10 + ATTR_FILE_DATAALLOCSIZE = 0x400 + ATTR_FILE_DATAEXTENTS = 0x800 + ATTR_FILE_DATALENGTH = 0x200 + ATTR_FILE_DEVTYPE = 0x20 + ATTR_FILE_FILETYPE = 0x40 + ATTR_FILE_FORKCOUNT = 0x80 + ATTR_FILE_FORKLIST = 0x100 + ATTR_FILE_IOBLOCKSIZE = 0x8 + ATTR_FILE_LINKCOUNT = 0x1 + ATTR_FILE_RSRCALLOCSIZE = 0x2000 + ATTR_FILE_RSRCEXTENTS = 0x4000 + ATTR_FILE_RSRCLENGTH = 0x1000 + ATTR_FILE_SETMASK = 0x20 + ATTR_FILE_TOTALSIZE = 0x2 + ATTR_FILE_VALIDMASK = 0x37ff + ATTR_VOL_ALLOCATIONCLUMP = 0x40 + ATTR_VOL_ATTRIBUTES = 0x40000000 + ATTR_VOL_CAPABILITIES = 0x20000 + ATTR_VOL_DIRCOUNT = 0x400 + ATTR_VOL_ENCODINGSUSED = 0x10000 + ATTR_VOL_FILECOUNT = 0x200 + ATTR_VOL_FSTYPE = 0x1 + ATTR_VOL_INFO = 0x80000000 + ATTR_VOL_IOBLOCKSIZE = 0x80 + ATTR_VOL_MAXOBJCOUNT = 0x800 + ATTR_VOL_MINALLOCATION = 0x20 + ATTR_VOL_MOUNTEDDEVICE = 0x8000 + ATTR_VOL_MOUNTFLAGS = 0x4000 + ATTR_VOL_MOUNTPOINT = 0x1000 + ATTR_VOL_NAME = 0x2000 + ATTR_VOL_OBJCOUNT = 0x100 + ATTR_VOL_QUOTA_SIZE = 0x10000000 + ATTR_VOL_RESERVED_SIZE = 0x20000000 + ATTR_VOL_SETMASK = 0x80002000 + ATTR_VOL_SIGNATURE = 0x2 + ATTR_VOL_SIZE = 0x4 + ATTR_VOL_SPACEAVAIL = 0x10 + ATTR_VOL_SPACEFREE = 0x8 + ATTR_VOL_UUID = 0x40000 + ATTR_VOL_VALIDMASK = 0xf007ffff B0 = 0x0 B110 = 0x6e B115200 = 0x1c200 @@ -169,6 +249,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -390,6 +472,11 @@ const ( FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FSOPT_ATTR_CMN_EXTENDED = 0x20 + FSOPT_NOFOLLOW = 0x1 + FSOPT_NOINMEMUPDATE = 0x2 + FSOPT_PACK_INVAL_ATTRS = 0x8 + FSOPT_REPORT_FULLSIZE = 0x4 F_ADDFILESIGS = 0x3d F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 F_ADDFILESIGS_RETURN = 0x61 @@ -425,6 +512,7 @@ const ( F_PATHPKG_CHECK = 0x34 F_PEOFPOSMODE = 0x3 F_PREALLOCATE = 0x2a + F_PUNCHHOLE = 0x63 F_RDADVISE = 0x2c F_RDAHEAD = 0x2d F_RDLCK = 0x1 @@ -441,10 +529,12 @@ const ( F_SINGLE_WRITER = 0x4c F_THAW_FS = 0x36 F_TRANSCODEKEY = 0x4b + F_TRIM_ACTIVE_FILE = 0x64 F_UNLCK = 0x2 F_VOLPOSMODE = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -681,6 +771,7 @@ const ( IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOW_ECN_MASK = 0x300 IPV6_FRAGTTL = 0x3c IPV6_FW_ADD = 0x1e IPV6_FW_DEL = 0x1f @@ -771,6 +862,7 @@ const ( IP_RECVOPTS = 0x5 IP_RECVPKTINFO = 0x1a IP_RECVRETOPTS = 0x6 + IP_RECVTOS = 0x1b IP_RECVTTL = 0x18 IP_RETOPTS = 0x8 IP_RF = 0x8000 @@ -789,6 +881,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go index 8f40598bb..474441b80 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go @@ -168,6 +168,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -353,6 +355,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -835,6 +838,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -973,7 +980,10 @@ const ( RLIMIT_CPU = 0x0 RLIMIT_DATA = 0x2 RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 RLIMIT_STACK = 0x3 RLIM_INFINITY = 0x7fffffffffffffff RTAX_AUTHOR = 0x6 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go index 1d3eec44d..a8b05878e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go @@ -351,6 +351,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0x18 CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -608,6 +610,7 @@ const ( F_UNLCKSYS = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -944,6 +947,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -981,6 +988,49 @@ const ( MAP_STACK = 0x400 MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 + MNT_ACLS = 0x8000000 + MNT_ASYNC = 0x40 + MNT_AUTOMOUNTED = 0x200000000 + MNT_BYFSID = 0x8000000 + MNT_CMDFLAGS = 0xd0f0000 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_EXKERB = 0x800 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXPUBLIC = 0x20000000 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_GJOURNAL = 0x2000000 + MNT_IGNORE = 0x800000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_MULTILABEL = 0x4000000 + MNT_NFS4ACLS = 0x10 + MNT_NOATIME = 0x10000000 + MNT_NOCLUSTERR = 0x40000000 + MNT_NOCLUSTERW = 0x80000000 + MNT_NOEXEC = 0x4 + MNT_NONBUSY = 0x4000000 + MNT_NOSUID = 0x8 + MNT_NOSYMFOLLOW = 0x400000 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SNAPSHOT = 0x1000000 + MNT_SOFTDEP = 0x200000 + MNT_SUIDDIR = 0x100000 + MNT_SUJ = 0x100000000 + MNT_SUSPEND = 0x4 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UPDATE = 0x10000 + MNT_UPDATEMASK = 0x2d8d0807e + MNT_USER = 0x8000 + MNT_VISFLAGMASK = 0x3fef0ffff + MNT_WAIT = 0x1 MSG_CMSG_CLOEXEC = 0x40000 MSG_COMPAT = 0x8000 MSG_CTRUNC = 0x20 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go index ac094f9cf..cf5f01260 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go @@ -351,6 +351,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0x18 CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -608,6 +610,7 @@ const ( F_UNLCKSYS = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -944,6 +947,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -982,6 +989,49 @@ const ( MAP_STACK = 0x400 MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 + MNT_ACLS = 0x8000000 + MNT_ASYNC = 0x40 + MNT_AUTOMOUNTED = 0x200000000 + MNT_BYFSID = 0x8000000 + MNT_CMDFLAGS = 0xd0f0000 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_EXKERB = 0x800 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXPUBLIC = 0x20000000 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_GJOURNAL = 0x2000000 + MNT_IGNORE = 0x800000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_MULTILABEL = 0x4000000 + MNT_NFS4ACLS = 0x10 + MNT_NOATIME = 0x10000000 + MNT_NOCLUSTERR = 0x40000000 + MNT_NOCLUSTERW = 0x80000000 + MNT_NOEXEC = 0x4 + MNT_NONBUSY = 0x4000000 + MNT_NOSUID = 0x8 + MNT_NOSYMFOLLOW = 0x400000 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SNAPSHOT = 0x1000000 + MNT_SOFTDEP = 0x200000 + MNT_SUIDDIR = 0x100000 + MNT_SUJ = 0x100000000 + MNT_SUSPEND = 0x4 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UPDATE = 0x10000 + MNT_UPDATEMASK = 0x2d8d0807e + MNT_USER = 0x8000 + MNT_VISFLAGMASK = 0x3fef0ffff + MNT_WAIT = 0x1 MSG_CMSG_CLOEXEC = 0x40000 MSG_COMPAT = 0x8000 MSG_CTRUNC = 0x20 diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go index c5c6f13e5..9bbb90ad8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go @@ -351,6 +351,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0x18 CTL_NET = 0x4 DLT_A429 = 0xb8 @@ -615,6 +617,7 @@ const ( F_UNLCKSYS = 0x4 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -951,6 +954,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -989,6 +996,49 @@ const ( MAP_STACK = 0x400 MCL_CURRENT = 0x1 MCL_FUTURE = 0x2 + MNT_ACLS = 0x8000000 + MNT_ASYNC = 0x40 + MNT_AUTOMOUNTED = 0x200000000 + MNT_BYFSID = 0x8000000 + MNT_CMDFLAGS = 0xd0f0000 + MNT_DEFEXPORTED = 0x200 + MNT_DELEXPORT = 0x20000 + MNT_EXKERB = 0x800 + MNT_EXPORTANON = 0x400 + MNT_EXPORTED = 0x100 + MNT_EXPUBLIC = 0x20000000 + MNT_EXRDONLY = 0x80 + MNT_FORCE = 0x80000 + MNT_GJOURNAL = 0x2000000 + MNT_IGNORE = 0x800000 + MNT_LAZY = 0x3 + MNT_LOCAL = 0x1000 + MNT_MULTILABEL = 0x4000000 + MNT_NFS4ACLS = 0x10 + MNT_NOATIME = 0x10000000 + MNT_NOCLUSTERR = 0x40000000 + MNT_NOCLUSTERW = 0x80000000 + MNT_NOEXEC = 0x4 + MNT_NONBUSY = 0x4000000 + MNT_NOSUID = 0x8 + MNT_NOSYMFOLLOW = 0x400000 + MNT_NOWAIT = 0x2 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_ROOTFS = 0x4000 + MNT_SNAPSHOT = 0x1000000 + MNT_SOFTDEP = 0x200000 + MNT_SUIDDIR = 0x100000 + MNT_SUJ = 0x100000000 + MNT_SUSPEND = 0x4 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UPDATE = 0x10000 + MNT_UPDATEMASK = 0x2d8d0807e + MNT_USER = 0x8000 + MNT_VISFLAGMASK = 0x3fef0ffff + MNT_WAIT = 0x1 MSG_CMSG_CLOEXEC = 0x40000 MSG_COMPAT = 0x8000 MSG_CTRUNC = 0x20 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index a6b3b5f14..fa0637408 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_32BIT = 0x40 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 @@ -870,6 +918,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +951,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +966,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +985,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1006,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1018,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1067,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1161,6 +1217,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1243,10 +1304,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1257,7 +1319,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1268,7 +1330,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1312,6 +1374,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1320,6 +1383,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1341,10 +1405,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1359,8 +1424,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1371,6 +1436,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1401,6 +1467,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1526,6 +1593,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1539,6 +1607,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1547,11 +1616,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1559,6 +1630,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1590,10 +1662,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1626,6 +1720,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -1649,6 +1749,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1658,6 +1759,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1678,6 +1781,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1708,6 +1812,7 @@ const ( TIOCGPKT = 0x80045438 TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 + TIOCGPTPEER = 0x5441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1765,6 +1870,7 @@ const ( TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 TOSTOP = 0x100 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x400854d5 TUNDETACHFILTER = 0x400854d6 TUNGETFEATURES = 0x800454cf @@ -1790,6 +1896,8 @@ const ( TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1819,6 +1927,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x80045702 + WDIOC_GETPRETIMEOUT = 0x80045709 + WDIOC_GETSTATUS = 0x80045701 + WDIOC_GETSUPPORT = 0x80285700 + WDIOC_GETTEMP = 0x80045703 + WDIOC_GETTIMELEFT = 0x8004570a + WDIOC_GETTIMEOUT = 0x80045707 + WDIOC_KEEPALIVE = 0x80045705 + WDIOC_SETOPTIONS = 0x80045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -1999,7 +2118,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 4ffc8d29c..eb2a22f65 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_32BIT = 0x40 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 @@ -870,6 +918,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +951,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +966,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +985,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1006,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1018,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1067,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1153,7 +1209,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1161,6 +1217,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1244,10 +1305,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1258,7 +1320,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1269,7 +1331,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1313,6 +1375,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1321,6 +1384,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1342,10 +1406,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1360,8 +1425,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1372,6 +1437,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1402,6 +1468,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1527,6 +1594,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1540,6 +1608,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1548,11 +1617,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1560,6 +1631,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1591,10 +1663,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1627,6 +1721,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -1650,6 +1750,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1659,6 +1760,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1679,6 +1782,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1709,6 +1813,7 @@ const ( TIOCGPKT = 0x80045438 TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 + TIOCGPTPEER = 0x5441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1766,6 +1871,7 @@ const ( TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 TOSTOP = 0x100 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 TUNGETFEATURES = 0x800454cf @@ -1791,6 +1897,8 @@ const ( TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1820,6 +1928,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x80045702 + WDIOC_GETPRETIMEOUT = 0x80045709 + WDIOC_GETSTATUS = 0x80045701 + WDIOC_GETSUPPORT = 0x80285700 + WDIOC_GETTEMP = 0x80045703 + WDIOC_GETTIMELEFT = 0x8004570a + WDIOC_GETTIMEOUT = 0x80045707 + WDIOC_KEEPALIVE = 0x80045705 + WDIOC_SETOPTIONS = 0x80045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -2000,7 +2119,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index f4b178ef1..37d212ca4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 @@ -869,6 +917,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -901,6 +950,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -915,6 +965,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -933,6 +984,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -953,8 +1005,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -963,6 +1017,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1011,6 +1066,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1160,6 +1216,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1181,6 +1242,9 @@ const ( PTRACE_EVENT_VFORK_DONE = 0x5 PTRACE_GETCRUNCHREGS = 0x19 PTRACE_GETEVENTMSG = 0x4201 + PTRACE_GETFDPIC = 0x1f + PTRACE_GETFDPIC_EXEC = 0x0 + PTRACE_GETFDPIC_INTERP = 0x1 PTRACE_GETFPREGS = 0xe PTRACE_GETHBPREGS = 0x1d PTRACE_GETREGS = 0xc @@ -1248,10 +1312,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1262,7 +1327,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1273,7 +1338,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1317,6 +1382,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1325,6 +1391,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1346,10 +1413,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1364,8 +1432,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1376,6 +1444,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1406,6 +1475,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1531,6 +1601,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1544,6 +1615,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1552,11 +1624,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1564,6 +1638,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1595,10 +1670,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1631,6 +1728,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -1654,6 +1757,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1663,6 +1767,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1683,6 +1789,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1713,6 +1820,7 @@ const ( TIOCGPKT = 0x80045438 TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 + TIOCGPTPEER = 0x5441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1770,6 +1878,7 @@ const ( TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 TOSTOP = 0x100 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x400854d5 TUNDETACHFILTER = 0x400854d6 TUNGETFEATURES = 0x800454cf @@ -1795,6 +1904,8 @@ const ( TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1824,6 +1935,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x80045702 + WDIOC_GETPRETIMEOUT = 0x80045709 + WDIOC_GETSTATUS = 0x80045701 + WDIOC_GETSUPPORT = 0x80285700 + WDIOC_GETTEMP = 0x80045703 + WDIOC_GETTIMELEFT = 0x8004570a + WDIOC_GETTIMEOUT = 0x80045707 + WDIOC_KEEPALIVE = 0x80045705 + WDIOC_SETOPTIONS = 0x80045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -2004,7 +2126,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 495f13b61..51d84a35c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -389,13 +392,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -406,11 +412,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -441,6 +449,7 @@ const ( EXTA = 0xe EXTB = 0xf EXTPROC = 0x10000 + EXTRA_MAGIC = 0x45585401 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -454,6 +463,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -472,6 +483,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -484,6 +496,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -491,6 +506,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -502,12 +521,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -544,6 +578,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -606,6 +642,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -645,8 +682,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -659,12 +698,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -675,8 +716,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -690,7 +733,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -733,6 +778,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -770,6 +816,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -817,6 +864,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -825,6 +873,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 @@ -870,6 +919,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +952,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +967,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +986,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1007,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1019,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1068,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1153,7 +1210,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1161,6 +1218,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1233,10 +1295,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1247,7 +1310,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1258,7 +1321,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1302,6 +1365,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1310,6 +1374,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1331,10 +1396,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1349,8 +1415,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1361,6 +1427,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1391,6 +1458,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1516,6 +1584,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1529,6 +1598,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1537,11 +1607,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1549,6 +1621,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1580,10 +1653,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1616,6 +1711,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -1639,6 +1740,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1648,6 +1750,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1668,6 +1772,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1698,6 +1803,7 @@ const ( TIOCGPKT = 0x80045438 TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 + TIOCGPTPEER = 0x5441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1755,6 +1861,7 @@ const ( TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 TOSTOP = 0x100 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 TUNGETFEATURES = 0x800454cf @@ -1780,6 +1887,8 @@ const ( TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1809,6 +1918,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x80045702 + WDIOC_GETPRETIMEOUT = 0x80045709 + WDIOC_GETSTATUS = 0x80045701 + WDIOC_GETSUPPORT = 0x80285700 + WDIOC_GETTEMP = 0x80045703 + WDIOC_GETTIMELEFT = 0x8004570a + WDIOC_GETTIMEOUT = 0x80045707 + WDIOC_KEEPALIVE = 0x80045705 + WDIOC_SETOPTIONS = 0x80045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -1989,7 +2109,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 59651e415..8aec95d6c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 @@ -870,6 +918,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +951,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +966,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +985,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1006,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1018,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1067,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1161,6 +1217,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1245,10 +1306,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1259,7 +1321,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1270,7 +1332,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1314,6 +1376,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1322,6 +1385,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1343,10 +1407,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1361,8 +1426,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1373,6 +1438,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1403,6 +1469,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1528,6 +1595,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1541,6 +1609,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1549,11 +1618,13 @@ const ( SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x8 SO_LINGER = 0x80 SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0x100 @@ -1561,6 +1632,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1e SO_PRIORITY = 0xc @@ -1593,10 +1665,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1629,6 +1723,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -1651,6 +1751,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1660,6 +1761,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1680,6 +1783,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1709,6 +1813,7 @@ const ( TIOCGPKT = 0x40045438 TIOCGPTLCK = 0x40045439 TIOCGPTN = 0x40045430 + TIOCGPTPEER = 0x20005441 TIOCGRS485 = 0x4020542e TIOCGSERIAL = 0x5484 TIOCGSID = 0x7416 @@ -1769,6 +1874,7 @@ const ( TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 TOSTOP = 0x8000 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x800854d5 TUNDETACHFILTER = 0x800854d6 TUNGETFEATURES = 0x400454cf @@ -1794,6 +1900,8 @@ const ( TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1824,6 +1932,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x40045702 + WDIOC_GETPRETIMEOUT = 0x40045709 + WDIOC_GETSTATUS = 0x40045701 + WDIOC_GETSUPPORT = 0x40285700 + WDIOC_GETTEMP = 0x40045703 + WDIOC_GETTIMELEFT = 0x4004570a + WDIOC_GETTIMEOUT = 0x40045707 + WDIOC_KEEPALIVE = 0x40045705 + WDIOC_SETOPTIONS = 0x40045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index a09bf9b18..423f48ae0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 @@ -870,6 +918,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +951,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +966,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +985,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1006,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1018,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1067,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1153,7 +1209,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1161,6 +1217,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1245,10 +1306,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1259,7 +1321,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1270,7 +1332,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1314,6 +1376,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1322,6 +1385,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1343,10 +1407,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1361,8 +1426,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1373,6 +1438,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1403,6 +1469,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1528,6 +1595,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1541,6 +1609,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1549,11 +1618,13 @@ const ( SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x8 SO_LINGER = 0x80 SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0x100 @@ -1561,6 +1632,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1e SO_PRIORITY = 0xc @@ -1593,10 +1665,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1629,6 +1723,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -1651,6 +1751,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1660,6 +1761,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1680,6 +1783,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1709,6 +1813,7 @@ const ( TIOCGPKT = 0x40045438 TIOCGPTLCK = 0x40045439 TIOCGPTN = 0x40045430 + TIOCGPTPEER = 0x20005441 TIOCGRS485 = 0x4020542e TIOCGSERIAL = 0x5484 TIOCGSID = 0x7416 @@ -1769,6 +1874,7 @@ const ( TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 TOSTOP = 0x8000 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 TUNGETFEATURES = 0x400454cf @@ -1794,6 +1900,8 @@ const ( TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1824,6 +1932,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x40045702 + WDIOC_GETPRETIMEOUT = 0x40045709 + WDIOC_GETSTATUS = 0x40045701 + WDIOC_GETSUPPORT = 0x40285700 + WDIOC_GETTEMP = 0x40045703 + WDIOC_GETTIMELEFT = 0x4004570a + WDIOC_GETTIMEOUT = 0x40045707 + WDIOC_KEEPALIVE = 0x40045705 + WDIOC_SETOPTIONS = 0x40045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 72a0083c4..5e4060701 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 @@ -870,6 +918,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +951,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +966,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +985,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1006,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1018,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1067,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1153,7 +1209,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1161,6 +1217,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1245,10 +1306,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1259,7 +1321,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1270,7 +1332,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1314,6 +1376,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1322,6 +1385,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1343,10 +1407,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1361,8 +1426,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1373,6 +1438,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1403,6 +1469,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1528,6 +1595,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1541,6 +1609,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1549,11 +1618,13 @@ const ( SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x8 SO_LINGER = 0x80 SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0x100 @@ -1561,6 +1632,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1e SO_PRIORITY = 0xc @@ -1593,10 +1665,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1629,6 +1723,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -1651,6 +1751,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1660,6 +1761,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1680,6 +1783,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1709,6 +1813,7 @@ const ( TIOCGPKT = 0x40045438 TIOCGPTLCK = 0x40045439 TIOCGPTN = 0x40045430 + TIOCGPTPEER = 0x20005441 TIOCGRS485 = 0x4020542e TIOCGSERIAL = 0x5484 TIOCGSID = 0x7416 @@ -1769,6 +1874,7 @@ const ( TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 TOSTOP = 0x8000 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 TUNGETFEATURES = 0x400454cf @@ -1794,6 +1900,8 @@ const ( TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1824,6 +1932,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x40045702 + WDIOC_GETPRETIMEOUT = 0x40045709 + WDIOC_GETSTATUS = 0x40045701 + WDIOC_GETSUPPORT = 0x40285700 + WDIOC_GETTEMP = 0x40045703 + WDIOC_GETTIMELEFT = 0x4004570a + WDIOC_GETTIMEOUT = 0x40045707 + WDIOC_KEEPALIVE = 0x40045705 + WDIOC_SETOPTIONS = 0x40045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 84c0e3cc1..b9b9d6374 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x2000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x800 MAP_ANONYMOUS = 0x800 MAP_DENYWRITE = 0x2000 @@ -870,6 +918,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -902,6 +951,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -916,6 +966,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -934,6 +985,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -954,8 +1006,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -964,6 +1018,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1012,6 +1067,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1161,6 +1217,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1245,10 +1306,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1259,7 +1321,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1270,7 +1332,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1314,6 +1376,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1322,6 +1385,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1343,10 +1407,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1361,8 +1426,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1373,6 +1438,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1403,6 +1469,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1528,6 +1595,7 @@ const ( SOL_SOCKET = 0xffff SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1009 @@ -1541,6 +1609,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1549,11 +1618,13 @@ const ( SO_ERROR = 0x1007 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x8 SO_LINGER = 0x80 SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0x100 @@ -1561,6 +1632,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1e SO_PRIORITY = 0xc @@ -1593,10 +1665,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1629,6 +1723,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x5407 TCGETA = 0x5401 TCGETS = 0x540d @@ -1651,6 +1751,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1660,6 +1761,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1680,6 +1783,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x5410 @@ -1709,6 +1813,7 @@ const ( TIOCGPKT = 0x40045438 TIOCGPTLCK = 0x40045439 TIOCGPTN = 0x40045430 + TIOCGPTPEER = 0x20005441 TIOCGRS485 = 0x4020542e TIOCGSERIAL = 0x5484 TIOCGSID = 0x7416 @@ -1769,6 +1874,7 @@ const ( TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 TOSTOP = 0x8000 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x800854d5 TUNDETACHFILTER = 0x800854d6 TUNGETFEATURES = 0x400454cf @@ -1794,6 +1900,8 @@ const ( TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x10 VEOL = 0x11 @@ -1824,6 +1932,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x40045702 + WDIOC_GETPRETIMEOUT = 0x40045709 + WDIOC_GETSTATUS = 0x40045701 + WDIOC_GETSUPPORT = 0x40285700 + WDIOC_GETTEMP = 0x40045703 + WDIOC_GETTIMELEFT = 0x4004570a + WDIOC_GETTIMEOUT = 0x40045707 + WDIOC_KEEPALIVE = 0x40045705 + WDIOC_SETOPTIONS = 0x40045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 8e4606e06..509418ef2 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x17 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x4000 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 @@ -869,6 +917,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -901,6 +950,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -915,6 +965,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -933,6 +984,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -955,8 +1007,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -965,6 +1019,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1013,6 +1068,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1155,7 +1211,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1163,6 +1219,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1301,10 +1362,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1315,7 +1377,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1326,7 +1388,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1370,6 +1432,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1378,6 +1441,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1399,10 +1463,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1417,8 +1482,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1429,6 +1494,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1459,6 +1525,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1584,6 +1651,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1597,6 +1665,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1605,11 +1674,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1617,6 +1688,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1648,10 +1720,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1684,6 +1778,12 @@ const ( TAB2 = 0x800 TAB3 = 0xc00 TABDLY = 0xc00 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x2000741f TCGETA = 0x40147417 TCGETS = 0x402c7413 @@ -1705,6 +1805,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1714,6 +1815,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1734,6 +1837,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1761,6 +1865,7 @@ const ( TIOCGPKT = 0x40045438 TIOCGPTLCK = 0x40045439 TIOCGPTN = 0x40045430 + TIOCGPTPEER = 0x20005441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1827,6 +1932,7 @@ const ( TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 TOSTOP = 0x400000 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 TUNGETFEATURES = 0x400454cf @@ -1852,6 +1958,8 @@ const ( TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0x10 VEOF = 0x4 VEOL = 0x6 @@ -1881,6 +1989,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x40045702 + WDIOC_GETPRETIMEOUT = 0x40045709 + WDIOC_GETSTATUS = 0x40045701 + WDIOC_GETSUPPORT = 0x40285700 + WDIOC_GETTEMP = 0x40045703 + WDIOC_GETTIMELEFT = 0x4004570a + WDIOC_GETTIMEOUT = 0x40045707 + WDIOC_KEEPALIVE = 0x40045705 + WDIOC_SETOPTIONS = 0x40045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -2061,7 +2180,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 16ed19311..26afbb8de 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x17 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x4000 FFDLY = 0x4000 FLUSHO = 0x800000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x4000 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 @@ -869,6 +917,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -901,6 +950,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -915,6 +965,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -933,6 +984,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -955,8 +1007,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -965,6 +1019,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1013,6 +1068,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1155,7 +1211,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1163,6 +1219,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1301,10 +1362,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1315,7 +1377,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1326,7 +1388,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1370,6 +1432,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1378,6 +1441,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1399,10 +1463,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1417,8 +1482,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1429,6 +1494,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1459,6 +1525,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1584,6 +1651,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1597,6 +1665,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1605,11 +1674,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1617,6 +1688,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1648,10 +1720,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1684,6 +1778,12 @@ const ( TAB2 = 0x800 TAB3 = 0xc00 TABDLY = 0xc00 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x2000741f TCGETA = 0x40147417 TCGETS = 0x402c7413 @@ -1705,6 +1805,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1714,6 +1815,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1734,6 +1837,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1761,6 +1865,7 @@ const ( TIOCGPKT = 0x40045438 TIOCGPTLCK = 0x40045439 TIOCGPTN = 0x40045430 + TIOCGPTPEER = 0x20005441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1827,6 +1932,7 @@ const ( TIOCSWINSZ = 0x80087467 TIOCVHANGUP = 0x5437 TOSTOP = 0x400000 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x801054d5 TUNDETACHFILTER = 0x801054d6 TUNGETFEATURES = 0x400454cf @@ -1852,6 +1958,8 @@ const ( TUNSETVNETHDRSZ = 0x800454d8 TUNSETVNETLE = 0x800454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0x10 VEOF = 0x4 VEOL = 0x6 @@ -1881,6 +1989,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x40045702 + WDIOC_GETPRETIMEOUT = 0x40045709 + WDIOC_GETSTATUS = 0x40045701 + WDIOC_GETSUPPORT = 0x40285700 + WDIOC_GETTEMP = 0x40045703 + WDIOC_GETTIMELEFT = 0x4004570a + WDIOC_GETTIMEOUT = 0x40045707 + WDIOC_KEEPALIVE = 0x40045705 + WDIOC_SETOPTIONS = 0x40045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -2061,7 +2180,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index bd385f809..eeb9941de 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -36,7 +36,7 @@ const ( AF_KEY = 0xf AF_LLC = 0x1a AF_LOCAL = 0x1 - AF_MAX = 0x2b + AF_MAX = 0x2c AF_MPLS = 0x1c AF_NETBEUI = 0xd AF_NETLINK = 0x10 @@ -51,6 +51,7 @@ const ( AF_ROUTE = 0x10 AF_RXRPC = 0x21 AF_SECURITY = 0xe + AF_SMC = 0x2b AF_SNA = 0x16 AF_TIPC = 0x1e AF_UNIX = 0x1 @@ -120,6 +121,7 @@ const ( ARPHRD_PPP = 0x200 ARPHRD_PRONET = 0x4 ARPHRD_RAWHDLC = 0x206 + ARPHRD_RAWIP = 0x207 ARPHRD_ROSE = 0x10e ARPHRD_RSRVD = 0x104 ARPHRD_SIT = 0x308 @@ -129,6 +131,7 @@ const ( ARPHRD_TUNNEL = 0x300 ARPHRD_TUNNEL6 = 0x301 ARPHRD_VOID = 0xffff + ARPHRD_VSOCKMON = 0x33a ARPHRD_X25 = 0x10f B0 = 0x0 B1000000 = 0x1008 @@ -388,13 +391,16 @@ const ( ETH_P_DSA = 0x1b ETH_P_ECONET = 0x18 ETH_P_EDSA = 0xdada + ETH_P_ERSPAN = 0x88be ETH_P_FCOE = 0x8906 ETH_P_FIP = 0x8914 ETH_P_HDLC = 0x19 ETH_P_HSR = 0x892f + ETH_P_IBOE = 0x8915 ETH_P_IEEE802154 = 0xf6 ETH_P_IEEEPUP = 0xa00 ETH_P_IEEEPUPAT = 0xa01 + ETH_P_IFE = 0xed3e ETH_P_IP = 0x800 ETH_P_IPV6 = 0x86dd ETH_P_IPX = 0x8137 @@ -405,11 +411,13 @@ const ( ETH_P_LOOP = 0x60 ETH_P_LOOPBACK = 0x9000 ETH_P_MACSEC = 0x88e5 + ETH_P_MAP = 0xf9 ETH_P_MOBITEX = 0x15 ETH_P_MPLS_MC = 0x8848 ETH_P_MPLS_UC = 0x8847 ETH_P_MVRP = 0x88f5 ETH_P_NCSI = 0x88f8 + ETH_P_NSH = 0x894f ETH_P_PAE = 0x888e ETH_P_PAUSE = 0x8808 ETH_P_PHONET = 0xf5 @@ -453,6 +461,8 @@ const ( FF1 = 0x8000 FFDLY = 0x8000 FLUSHO = 0x1000 + FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 + FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 @@ -471,6 +481,7 @@ const ( FS_POLICY_FLAGS_PAD_8 = 0x1 FS_POLICY_FLAGS_PAD_MASK = 0x3 FS_POLICY_FLAGS_VALID = 0x3 + F_ADD_SEALS = 0x409 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 F_EXLCK = 0x4 @@ -483,6 +494,9 @@ const ( F_GETOWN_EX = 0x10 F_GETPIPE_SZ = 0x408 F_GETSIG = 0xb + F_GET_FILE_RW_HINT = 0x40d + F_GET_RW_HINT = 0x40b + F_GET_SEALS = 0x40a F_LOCK = 0x1 F_NOTIFY = 0x402 F_OFD_GETLK = 0x24 @@ -490,6 +504,10 @@ const ( F_OFD_SETLKW = 0x26 F_OK = 0x0 F_RDLCK = 0x0 + F_SEAL_GROW = 0x4 + F_SEAL_SEAL = 0x1 + F_SEAL_SHRINK = 0x2 + F_SEAL_WRITE = 0x8 F_SETFD = 0x2 F_SETFL = 0x4 F_SETLEASE = 0x400 @@ -501,12 +519,27 @@ const ( F_SETOWN_EX = 0xf F_SETPIPE_SZ = 0x407 F_SETSIG = 0xa + F_SET_FILE_RW_HINT = 0x40e + F_SET_RW_HINT = 0x40c F_SHLCK = 0x8 F_TEST = 0x3 F_TLOCK = 0x2 F_ULOCK = 0x0 F_UNLCK = 0x2 F_WRLCK = 0x1 + GENL_ADMIN_PERM = 0x1 + GENL_CMD_CAP_DO = 0x2 + GENL_CMD_CAP_DUMP = 0x4 + GENL_CMD_CAP_HASPOL = 0x8 + GENL_HDRLEN = 0x4 + GENL_ID_CTRL = 0x10 + GENL_ID_PMCRAID = 0x12 + GENL_ID_VFS_DQUOT = 0x11 + GENL_MAX_ID = 0x3ff + GENL_MIN_ID = 0x10 + GENL_NAMSIZ = 0x10 + GENL_START_ALLOC = 0x13 + GENL_UNS_ADMIN_PERM = 0x10 GRND_NONBLOCK = 0x1 GRND_RANDOM = 0x2 HUPCL = 0x400 @@ -543,6 +576,8 @@ const ( IFF_MASTER = 0x400 IFF_MULTICAST = 0x1000 IFF_MULTI_QUEUE = 0x100 + IFF_NAPI = 0x10 + IFF_NAPI_FRAGS = 0x20 IFF_NOARP = 0x80 IFF_NOFILTER = 0x1000 IFF_NOTRAILERS = 0x20 @@ -605,6 +640,7 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -644,8 +680,10 @@ const ( IPV6_2292PKTOPTIONS = 0x6 IPV6_2292RTHDR = 0x5 IPV6_ADDRFORM = 0x1 + IPV6_ADDR_PREFERENCES = 0x48 IPV6_ADD_MEMBERSHIP = 0x14 IPV6_AUTHHDR = 0xa + IPV6_AUTOFLOWLABEL = 0x46 IPV6_CHECKSUM = 0x7 IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 @@ -658,12 +696,14 @@ const ( IPV6_JOIN_GROUP = 0x14 IPV6_LEAVE_ANYCAST = 0x1c IPV6_LEAVE_GROUP = 0x15 + IPV6_MINHOPCOUNT = 0x49 IPV6_MTU = 0x18 IPV6_MTU_DISCOVER = 0x17 IPV6_MULTICAST_HOPS = 0x12 IPV6_MULTICAST_IF = 0x11 IPV6_MULTICAST_LOOP = 0x13 IPV6_NEXTHOP = 0x9 + IPV6_ORIGDSTADDR = 0x4a IPV6_PATHMTU = 0x3d IPV6_PKTINFO = 0x32 IPV6_PMTUDISC_DO = 0x2 @@ -674,8 +714,10 @@ const ( IPV6_PMTUDISC_WANT = 0x1 IPV6_RECVDSTOPTS = 0x3a IPV6_RECVERR = 0x19 + IPV6_RECVFRAGSIZE = 0x4d IPV6_RECVHOPLIMIT = 0x33 IPV6_RECVHOPOPTS = 0x35 + IPV6_RECVORIGDSTADDR = 0x4a IPV6_RECVPATHMTU = 0x3c IPV6_RECVPKTINFO = 0x31 IPV6_RECVRTHDR = 0x38 @@ -689,7 +731,9 @@ const ( IPV6_RXDSTOPTS = 0x3b IPV6_RXHOPOPTS = 0x36 IPV6_TCLASS = 0x43 + IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 + IPV6_UNICAST_IF = 0x4c IPV6_V6ONLY = 0x1a IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 @@ -732,6 +776,7 @@ const ( IP_PMTUDISC_PROBE = 0x3 IP_PMTUDISC_WANT = 0x1 IP_RECVERR = 0xb + IP_RECVFRAGSIZE = 0x19 IP_RECVOPTS = 0x6 IP_RECVORIGDSTADDR = 0x14 IP_RECVRETOPTS = 0x7 @@ -769,6 +814,7 @@ const ( KEYCTL_NEGATE = 0xd KEYCTL_READ = 0xb KEYCTL_REJECT = 0x13 + KEYCTL_RESTRICT_KEYRING = 0x1d KEYCTL_REVOKE = 0x3 KEYCTL_SEARCH = 0xa KEYCTL_SESSION_TO_PARENT = 0x12 @@ -816,6 +862,7 @@ const ( MADV_FREE = 0x8 MADV_HUGEPAGE = 0xe MADV_HWPOISON = 0x64 + MADV_KEEPONFORK = 0x13 MADV_MERGEABLE = 0xc MADV_NOHUGEPAGE = 0xf MADV_NORMAL = 0x0 @@ -824,6 +871,7 @@ const ( MADV_SEQUENTIAL = 0x2 MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 + MADV_WIPEONFORK = 0x12 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 @@ -869,6 +917,7 @@ const ( MSG_TRYHARD = 0x4 MSG_WAITALL = 0x100 MSG_WAITFORONE = 0x10000 + MSG_ZEROCOPY = 0x4000000 MS_ACTIVE = 0x40000000 MS_ASYNC = 0x1 MS_BIND = 0x1000 @@ -901,6 +950,7 @@ const ( MS_SILENT = 0x8000 MS_SLAVE = 0x80000 MS_STRICTATIME = 0x1000000 + MS_SUBMOUNT = 0x4000000 MS_SYNC = 0x4 MS_SYNCHRONOUS = 0x10 MS_UNBINDABLE = 0x20000 @@ -915,6 +965,7 @@ const ( NETLINK_DNRTMSG = 0xe NETLINK_DROP_MEMBERSHIP = 0x2 NETLINK_ECRYPTFS = 0x13 + NETLINK_EXT_ACK = 0xb NETLINK_FIB_LOOKUP = 0xa NETLINK_FIREWALL = 0x3 NETLINK_GENERIC = 0x10 @@ -933,6 +984,7 @@ const ( NETLINK_RX_RING = 0x6 NETLINK_SCSITRANSPORT = 0x12 NETLINK_SELINUX = 0x7 + NETLINK_SMC = 0x16 NETLINK_SOCK_DIAG = 0x4 NETLINK_TX_RING = 0x7 NETLINK_UNUSED = 0x1 @@ -953,8 +1005,10 @@ const ( NLMSG_NOOP = 0x1 NLMSG_OVERRUN = 0x4 NLM_F_ACK = 0x4 + NLM_F_ACK_TLVS = 0x200 NLM_F_APPEND = 0x800 NLM_F_ATOMIC = 0x400 + NLM_F_CAPPED = 0x100 NLM_F_CREATE = 0x400 NLM_F_DUMP = 0x300 NLM_F_DUMP_FILTERED = 0x20 @@ -963,6 +1017,7 @@ const ( NLM_F_EXCL = 0x200 NLM_F_MATCH = 0x200 NLM_F_MULTI = 0x2 + NLM_F_NONREC = 0x100 NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 @@ -1011,6 +1066,7 @@ const ( PACKET_FANOUT_EBPF = 0x7 PACKET_FANOUT_FLAG_DEFRAG = 0x8000 PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 + PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 PACKET_FANOUT_HASH = 0x0 PACKET_FANOUT_LB = 0x1 PACKET_FANOUT_QM = 0x5 @@ -1152,7 +1208,7 @@ const ( PR_SET_NO_NEW_PRIVS = 0x26 PR_SET_PDEATHSIG = 0x1 PR_SET_PTRACER = 0x59616d61 - PR_SET_PTRACER_ANY = -0x1 + PR_SET_PTRACER_ANY = 0xffffffffffffffff PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c PR_SET_THP_DISABLE = 0x29 @@ -1160,6 +1216,11 @@ const ( PR_SET_TIMING = 0xe PR_SET_TSC = 0x1a PR_SET_UNALIGN = 0x6 + PR_SVE_GET_VL = 0x33 + PR_SVE_SET_VL = 0x32 + PR_SVE_SET_VL_ONEXEC = 0x40000 + PR_SVE_VL_INHERIT = 0x20000 + PR_SVE_VL_LEN_MASK = 0xffff PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 PR_TIMING_STATISTICAL = 0x0 @@ -1305,10 +1366,11 @@ const ( RLIMIT_RTTIME = 0xf RLIMIT_SIGPENDING = 0xb RLIMIT_STACK = 0x3 - RLIM_INFINITY = -0x1 + RLIM_INFINITY = 0xffffffffffffffff RTAX_ADVMSS = 0x8 RTAX_CC_ALGO = 0x10 RTAX_CWND = 0x7 + RTAX_FASTOPEN_NO_COOKIE = 0x11 RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 @@ -1319,7 +1381,7 @@ const ( RTAX_INITCWND = 0xb RTAX_INITRWND = 0xe RTAX_LOCK = 0x1 - RTAX_MAX = 0x10 + RTAX_MAX = 0x11 RTAX_MTU = 0x2 RTAX_QUICKACK = 0xf RTAX_REORDERING = 0x9 @@ -1330,7 +1392,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x19 + RTA_MAX = 0x1a RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -1374,6 +1436,7 @@ const ( RTM_DELLINK = 0x11 RTM_DELMDB = 0x55 RTM_DELNEIGH = 0x1d + RTM_DELNETCONF = 0x51 RTM_DELNSID = 0x59 RTM_DELQDISC = 0x25 RTM_DELROUTE = 0x19 @@ -1382,6 +1445,7 @@ const ( RTM_DELTFILTER = 0x2d RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 + RTM_F_FIB_MATCH = 0x2000 RTM_F_LOOKUP_TABLE = 0x1000 RTM_F_NOTIFY = 0x100 RTM_F_PREFIX = 0x800 @@ -1403,10 +1467,11 @@ const ( RTM_GETSTATS = 0x5e RTM_GETTCLASS = 0x2a RTM_GETTFILTER = 0x2e - RTM_MAX = 0x5f + RTM_MAX = 0x63 RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWCACHEREPORT = 0x60 RTM_NEWLINK = 0x10 RTM_NEWMDB = 0x54 RTM_NEWNDUSEROPT = 0x44 @@ -1421,8 +1486,8 @@ const ( RTM_NEWSTATS = 0x5c RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c - RTM_NR_FAMILIES = 0x14 - RTM_NR_MSGTYPES = 0x50 + RTM_NR_FAMILIES = 0x15 + RTM_NR_MSGTYPES = 0x54 RTM_SETDCB = 0x4f RTM_SETLINK = 0x13 RTM_SETNEIGHTBL = 0x43 @@ -1433,6 +1498,7 @@ const ( RTNH_F_OFFLOAD = 0x8 RTNH_F_ONLINK = 0x4 RTNH_F_PERVASIVE = 0x2 + RTNH_F_UNRESOLVED = 0x20 RTN_MAX = 0xb RTPROT_BABEL = 0x2a RTPROT_BIRD = 0xc @@ -1463,6 +1529,7 @@ const ( SCM_TIMESTAMP = 0x1d SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 + SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 SCM_WIFI_STATUS = 0x29 SECCOMP_MODE_DISABLED = 0x0 @@ -1588,6 +1655,7 @@ const ( SOL_SOCKET = 0x1 SOL_TCP = 0x6 SOL_TIPC = 0x10f + SOL_TLS = 0x11a SOL_X25 = 0x106 SOMAXCONN = 0x80 SO_ACCEPTCONN = 0x1e @@ -1601,6 +1669,7 @@ const ( SO_BSDCOMPAT = 0xe SO_BUSY_POLL = 0x2e SO_CNX_ADVICE = 0x35 + SO_COOKIE = 0x39 SO_DEBUG = 0x1 SO_DETACH_BPF = 0x1b SO_DETACH_FILTER = 0x1b @@ -1609,11 +1678,13 @@ const ( SO_ERROR = 0x4 SO_GET_FILTER = 0x1a SO_INCOMING_CPU = 0x31 + SO_INCOMING_NAPI_ID = 0x38 SO_KEEPALIVE = 0x9 SO_LINGER = 0xd SO_LOCK_FILTER = 0x2c SO_MARK = 0x24 SO_MAX_PACING_RATE = 0x2f + SO_MEMINFO = 0x37 SO_NOFCS = 0x2b SO_NO_CHECK = 0xb SO_OOBINLINE = 0xa @@ -1621,6 +1692,7 @@ const ( SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 + SO_PEERGROUPS = 0x3b SO_PEERNAME = 0x1c SO_PEERSEC = 0x1f SO_PRIORITY = 0xc @@ -1652,10 +1724,32 @@ const ( SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 SO_VM_SOCKETS_TRUSTED = 0x5 SO_WIFI_STATUS = 0x29 + SO_ZEROCOPY = 0x3c SPLICE_F_GIFT = 0x8 SPLICE_F_MORE = 0x4 SPLICE_F_MOVE = 0x1 SPLICE_F_NONBLOCK = 0x2 + STATX_ALL = 0xfff + STATX_ATIME = 0x20 + STATX_ATTR_APPEND = 0x20 + STATX_ATTR_AUTOMOUNT = 0x1000 + STATX_ATTR_COMPRESSED = 0x4 + STATX_ATTR_ENCRYPTED = 0x800 + STATX_ATTR_IMMUTABLE = 0x10 + STATX_ATTR_NODUMP = 0x40 + STATX_BASIC_STATS = 0x7ff + STATX_BLOCKS = 0x400 + STATX_BTIME = 0x800 + STATX_CTIME = 0x80 + STATX_GID = 0x10 + STATX_INO = 0x100 + STATX_MODE = 0x2 + STATX_MTIME = 0x40 + STATX_NLINK = 0x4 + STATX_SIZE = 0x200 + STATX_TYPE = 0x1 + STATX_UID = 0x8 + STATX__RESERVED = 0x80000000 S_BLKSIZE = 0x200 S_IEXEC = 0x40 S_IFBLK = 0x6000 @@ -1688,6 +1782,12 @@ const ( TAB2 = 0x1000 TAB3 = 0x1800 TABDLY = 0x1800 + TASKSTATS_CMD_ATTR_MAX = 0x4 + TASKSTATS_CMD_MAX = 0x2 + TASKSTATS_GENL_NAME = "TASKSTATS" + TASKSTATS_GENL_VERSION = 0x1 + TASKSTATS_TYPE_MAX = 0x6 + TASKSTATS_VERSION = 0x8 TCFLSH = 0x540b TCGETA = 0x5405 TCGETS = 0x5401 @@ -1711,6 +1811,7 @@ const ( TCP_CORK = 0x3 TCP_DEFER_ACCEPT = 0x9 TCP_FASTOPEN = 0x17 + TCP_FASTOPEN_CONNECT = 0x1e TCP_INFO = 0xb TCP_KEEPCNT = 0x6 TCP_KEEPIDLE = 0x4 @@ -1720,6 +1821,8 @@ const ( TCP_MAXWIN = 0xffff TCP_MAX_WINSHIFT = 0xe TCP_MD5SIG = 0xe + TCP_MD5SIG_EXT = 0x20 + TCP_MD5SIG_FLAG_PREFIX = 0x1 TCP_MD5SIG_MAXKEYLEN = 0x50 TCP_MSS = 0x200 TCP_MSS_DEFAULT = 0x218 @@ -1740,6 +1843,7 @@ const ( TCP_THIN_DUPACK = 0x11 TCP_THIN_LINEAR_TIMEOUTS = 0x10 TCP_TIMESTAMP = 0x18 + TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 TCP_WINDOW_CLAMP = 0xa TCSAFLUSH = 0x2 @@ -1770,6 +1874,7 @@ const ( TIOCGPKT = 0x80045438 TIOCGPTLCK = 0x80045439 TIOCGPTN = 0x80045430 + TIOCGPTPEER = 0x5441 TIOCGRS485 = 0x542e TIOCGSERIAL = 0x541e TIOCGSID = 0x5429 @@ -1827,6 +1932,7 @@ const ( TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 TOSTOP = 0x100 + TS_COMM_LEN = 0x20 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 TUNGETFEATURES = 0x800454cf @@ -1852,6 +1958,8 @@ const ( TUNSETVNETHDRSZ = 0x400454d8 TUNSETVNETLE = 0x400454dc UMOUNT_NOFOLLOW = 0x8 + UTIME_NOW = 0x3fffffff + UTIME_OMIT = 0x3ffffffe VDISCARD = 0xd VEOF = 0x4 VEOL = 0xb @@ -1881,6 +1989,17 @@ const ( WALL = 0x40000000 WCLONE = 0x80000000 WCONTINUED = 0x8 + WDIOC_GETBOOTSTATUS = 0x80045702 + WDIOC_GETPRETIMEOUT = 0x80045709 + WDIOC_GETSTATUS = 0x80045701 + WDIOC_GETSUPPORT = 0x80285700 + WDIOC_GETTEMP = 0x80045703 + WDIOC_GETTIMELEFT = 0x8004570a + WDIOC_GETTIMEOUT = 0x80045707 + WDIOC_KEEPALIVE = 0x80045705 + WDIOC_SETOPTIONS = 0x80045704 + WDIOC_SETPRETIMEOUT = 0xc0045708 + WDIOC_SETTIMEOUT = 0xc0045706 WEXITED = 0x4 WNOHANG = 0x1 WNOTHREAD = 0x20000000 @@ -2061,7 +2180,6 @@ const ( SIGTSTP = syscall.Signal(0x14) SIGTTIN = syscall.Signal(0x15) SIGTTOU = syscall.Signal(0x16) - SIGUNUSED = syscall.Signal(0x1f) SIGURG = syscall.Signal(0x17) SIGUSR1 = syscall.Signal(0xa) SIGUSR2 = syscall.Signal(0xc) diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go index b4338d5f2..1612b6609 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go @@ -1,5 +1,5 @@ // mkerrors.sh -m32 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,netbsd @@ -169,6 +169,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 CTL_QUERY = -0x2 @@ -581,6 +583,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -970,6 +973,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go index 4994437b6..c994ab610 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go @@ -1,5 +1,5 @@ // mkerrors.sh -m64 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,netbsd @@ -169,6 +169,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 CTL_QUERY = -0x2 @@ -571,6 +573,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -960,6 +963,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go index ac85ca645..a8f9efede 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go @@ -1,5 +1,5 @@ // mkerrors.sh -marm -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,netbsd @@ -161,6 +161,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 CTL_QUERY = -0x2 @@ -563,6 +565,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -952,6 +955,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LOCK_EX = 0x2 LOCK_NB = 0x4 LOCK_SH = 0x1 @@ -1006,6 +1013,9 @@ const ( MSG_TRUNC = 0x10 MSG_USERFLAGS = 0xffffff MSG_WAITALL = 0x40 + MS_ASYNC = 0x1 + MS_INVALIDATE = 0x2 + MS_SYNC = 0x4 NAME_MAX = 0x1ff NET_RT_DUMP = 0x1 NET_RT_FLAGS = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go index 3322e998d..04e4f3319 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go @@ -1,5 +1,5 @@ // mkerrors.sh -m32 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,openbsd @@ -157,6 +157,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DIOCOSFPFLUSH = 0x2000444e @@ -442,6 +444,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -860,6 +863,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LCNT_OVERLOAD_FLUSH = 0x6 LOCK_EX = 0x2 LOCK_NB = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go index 1758ecca9..c80ff9812 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go @@ -1,5 +1,5 @@ // mkerrors.sh -m64 -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,openbsd @@ -157,6 +157,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DIOCOSFPFLUSH = 0x2000444e @@ -442,6 +444,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -860,6 +863,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LCNT_OVERLOAD_FLUSH = 0x6 LOCK_EX = 0x2 LOCK_NB = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go index 3ed0b2602..4c320495c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go @@ -1,5 +1,5 @@ // mkerrors.sh -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // Created by cgo -godefs - DO NOT EDIT // cgo -godefs -- _const.go @@ -157,6 +157,8 @@ const ( CSTOP = 0x13 CSTOPB = 0x400 CSUSP = 0x1a + CTL_HW = 0x6 + CTL_KERN = 0x1 CTL_MAXNAME = 0xc CTL_NET = 0x4 DIOCOSFPFLUSH = 0x2000444e @@ -441,6 +443,7 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -859,6 +862,10 @@ const ( IXANY = 0x800 IXOFF = 0x400 IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 LCNT_OVERLOAD_FLUSH = 0x6 LOCK_EX = 0x2 LOCK_NB = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go index 81e83d78f..09eedb009 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go @@ -664,6 +664,8 @@ const ( MS_OLDSYNC = 0x0 MS_SYNC = 0x4 M_FLUSH = 0x86 + NAME_MAX = 0xff + NEWDEV = 0x1 NL0 = 0x0 NL1 = 0x100 NLDLY = 0x100 @@ -672,6 +674,9 @@ const ( OFDEL = 0x80 OFILL = 0x40 OLCUC = 0x2 + OLDDEV = 0x0 + ONBITSMAJOR = 0x7 + ONBITSMINOR = 0x8 ONLCR = 0x4 ONLRET = 0x20 ONOCR = 0x10 @@ -1105,6 +1110,7 @@ const ( VEOL = 0x5 VEOL2 = 0x6 VERASE = 0x2 + VERASE2 = 0x11 VINTR = 0x0 VKILL = 0x3 VLNEXT = 0xf diff --git a/vendor/golang.org/x/sys/unix/zptrace386_linux.go b/vendor/golang.org/x/sys/unix/zptrace386_linux.go new file mode 100644 index 000000000..2d21c49e1 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zptrace386_linux.go @@ -0,0 +1,80 @@ +// Code generated by linux/mkall.go generatePtracePair(386, amd64). DO NOT EDIT. + +// +build linux +// +build 386 amd64 + +package unix + +import "unsafe" + +// PtraceRegs386 is the registers used by 386 binaries. +type PtraceRegs386 struct { + Ebx int32 + Ecx int32 + Edx int32 + Esi int32 + Edi int32 + Ebp int32 + Eax int32 + Xds int32 + Xes int32 + Xfs int32 + Xgs int32 + Orig_eax int32 + Eip int32 + Xcs int32 + Eflags int32 + Esp int32 + Xss int32 +} + +// PtraceGetRegs386 fetches the registers used by 386 binaries. +func PtraceGetRegs386(pid int, regsout *PtraceRegs386) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegs386 sets the registers used by 386 binaries. +func PtraceSetRegs386(pid int, regs *PtraceRegs386) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} + +// PtraceRegsAmd64 is the registers used by amd64 binaries. +type PtraceRegsAmd64 struct { + R15 uint64 + R14 uint64 + R13 uint64 + R12 uint64 + Rbp uint64 + Rbx uint64 + R11 uint64 + R10 uint64 + R9 uint64 + R8 uint64 + Rax uint64 + Rcx uint64 + Rdx uint64 + Rsi uint64 + Rdi uint64 + Orig_rax uint64 + Rip uint64 + Cs uint64 + Eflags uint64 + Rsp uint64 + Ss uint64 + Fs_base uint64 + Gs_base uint64 + Ds uint64 + Es uint64 + Fs uint64 + Gs uint64 +} + +// PtraceGetRegsAmd64 fetches the registers used by amd64 binaries. +func PtraceGetRegsAmd64(pid int, regsout *PtraceRegsAmd64) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsAmd64 sets the registers used by amd64 binaries. +func PtraceSetRegsAmd64(pid int, regs *PtraceRegsAmd64) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} diff --git a/vendor/golang.org/x/sys/unix/zptracearm_linux.go b/vendor/golang.org/x/sys/unix/zptracearm_linux.go new file mode 100644 index 000000000..faf23bbed --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zptracearm_linux.go @@ -0,0 +1,41 @@ +// Code generated by linux/mkall.go generatePtracePair(arm, arm64). DO NOT EDIT. + +// +build linux +// +build arm arm64 + +package unix + +import "unsafe" + +// PtraceRegsArm is the registers used by arm binaries. +type PtraceRegsArm struct { + Uregs [18]uint32 +} + +// PtraceGetRegsArm fetches the registers used by arm binaries. +func PtraceGetRegsArm(pid int, regsout *PtraceRegsArm) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsArm sets the registers used by arm binaries. +func PtraceSetRegsArm(pid int, regs *PtraceRegsArm) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} + +// PtraceRegsArm64 is the registers used by arm64 binaries. +type PtraceRegsArm64 struct { + Regs [31]uint64 + Sp uint64 + Pc uint64 + Pstate uint64 +} + +// PtraceGetRegsArm64 fetches the registers used by arm64 binaries. +func PtraceGetRegsArm64(pid int, regsout *PtraceRegsArm64) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsArm64 sets the registers used by arm64 binaries. +func PtraceSetRegsArm64(pid int, regs *PtraceRegsArm64) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} diff --git a/vendor/golang.org/x/sys/unix/zptracemips_linux.go b/vendor/golang.org/x/sys/unix/zptracemips_linux.go new file mode 100644 index 000000000..c431131e6 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zptracemips_linux.go @@ -0,0 +1,50 @@ +// Code generated by linux/mkall.go generatePtracePair(mips, mips64). DO NOT EDIT. + +// +build linux +// +build mips mips64 + +package unix + +import "unsafe" + +// PtraceRegsMips is the registers used by mips binaries. +type PtraceRegsMips struct { + Regs [32]uint64 + Lo uint64 + Hi uint64 + Epc uint64 + Badvaddr uint64 + Status uint64 + Cause uint64 +} + +// PtraceGetRegsMips fetches the registers used by mips binaries. +func PtraceGetRegsMips(pid int, regsout *PtraceRegsMips) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsMips sets the registers used by mips binaries. +func PtraceSetRegsMips(pid int, regs *PtraceRegsMips) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} + +// PtraceRegsMips64 is the registers used by mips64 binaries. +type PtraceRegsMips64 struct { + Regs [32]uint64 + Lo uint64 + Hi uint64 + Epc uint64 + Badvaddr uint64 + Status uint64 + Cause uint64 +} + +// PtraceGetRegsMips64 fetches the registers used by mips64 binaries. +func PtraceGetRegsMips64(pid int, regsout *PtraceRegsMips64) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsMips64 sets the registers used by mips64 binaries. +func PtraceSetRegsMips64(pid int, regs *PtraceRegsMips64) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} diff --git a/vendor/golang.org/x/sys/unix/zptracemipsle_linux.go b/vendor/golang.org/x/sys/unix/zptracemipsle_linux.go new file mode 100644 index 000000000..dc3d6d373 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zptracemipsle_linux.go @@ -0,0 +1,50 @@ +// Code generated by linux/mkall.go generatePtracePair(mipsle, mips64le). DO NOT EDIT. + +// +build linux +// +build mipsle mips64le + +package unix + +import "unsafe" + +// PtraceRegsMipsle is the registers used by mipsle binaries. +type PtraceRegsMipsle struct { + Regs [32]uint64 + Lo uint64 + Hi uint64 + Epc uint64 + Badvaddr uint64 + Status uint64 + Cause uint64 +} + +// PtraceGetRegsMipsle fetches the registers used by mipsle binaries. +func PtraceGetRegsMipsle(pid int, regsout *PtraceRegsMipsle) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsMipsle sets the registers used by mipsle binaries. +func PtraceSetRegsMipsle(pid int, regs *PtraceRegsMipsle) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} + +// PtraceRegsMips64le is the registers used by mips64le binaries. +type PtraceRegsMips64le struct { + Regs [32]uint64 + Lo uint64 + Hi uint64 + Epc uint64 + Badvaddr uint64 + Status uint64 + Cause uint64 +} + +// PtraceGetRegsMips64le fetches the registers used by mips64le binaries. +func PtraceGetRegsMips64le(pid int, regsout *PtraceRegsMips64le) error { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +// PtraceSetRegsMips64le sets the registers used by mips64le binaries. +func PtraceSetRegsMips64le(pid int, regs *PtraceRegsMips64le) error { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go index 92708acc3..4c9f72756 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) if e1 != 0 { @@ -582,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -905,90 +1031,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Msync(b []byte, flags int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Open(path string, mode int, perm uint32) (fd int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 44fc14f8a..256237773 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) if e1 != 0 { @@ -582,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -905,90 +1031,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Msync(b []byte, flags int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Open(path string, mode int, perm uint32) (fd int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go index 6e5bd7532..4ae787e49 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go @@ -221,7 +221,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) } else { _p0 = unsafe.Pointer(&_zero) } - _, _, e1 := Syscall6(SYS_SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) if e1 != 0 { err = errnoErr(e1) } @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) if e1 != 0 { @@ -582,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -905,74 +1031,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Open(path string, mode int, perm uint32) (fd int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 7005b8dd4..14ed6886c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) if e1 != 0 { @@ -582,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -905,74 +1031,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Open(path string, mode int, perm uint32) (fd int, err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index eafceb8e8..91f36e9ec 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (r int, w int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) r = int(r0) @@ -312,6 +423,33 @@ func extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -480,6 +618,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -521,6 +674,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -829,74 +997,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1391,3 +1491,18 @@ func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go index 24de0a06f..a86434a7b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (r int, w int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) r = int(r0) @@ -278,6 +389,23 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -796,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -826,6 +969,23 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -1139,74 +1299,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1828,3 +1920,18 @@ func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go index 0b61521d2..040e2f760 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (r int, w int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) r = int(r0) @@ -278,6 +389,23 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -796,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -826,6 +969,23 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -1139,74 +1299,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1828,3 +1920,18 @@ func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go index bf9a8c9b2..cddc5e86b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (r int, w int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) r = int(r0) @@ -278,6 +389,23 @@ func pipe() (r int, w int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -796,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -826,6 +969,23 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getdents(fd int, buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { @@ -1139,74 +1299,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1828,3 +1920,18 @@ func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go index 38c1bbdf9..ef9602c1e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1558,6 +1584,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Ftruncate(fd int, length int64) (err error) { _, _, e1 := Syscall(SYS_FTRUNCATE64, uintptr(fd), uintptr(length), uintptr(length>>32)) if e1 != 0 { @@ -1569,7 +1610,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID32, 0, 0, 0) egid = int(r0) return } @@ -1577,7 +1618,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID32, 0, 0, 0) euid = int(r0) return } @@ -1585,7 +1626,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID32, 0, 0, 0) gid = int(r0) return } @@ -1593,7 +1634,7 @@ func Getgid() (gid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID32, 0, 0, 0) uid = int(r0) return } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go index dc8fe0a84..63054b358 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1555,6 +1581,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1576,7 +1617,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1584,7 +1625,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1592,7 +1633,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1610,7 +1651,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go index 4d2804278..8b10ee144 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1717,8 +1743,23 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID32, 0, 0, 0) egid = int(r0) return } @@ -1726,7 +1767,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID32, 0, 0, 0) euid = int(r0) return } @@ -1734,7 +1775,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID32, 0, 0, 0) gid = int(r0) return } @@ -1742,7 +1783,7 @@ func Getgid() (gid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID32, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID32, 0, 0, 0) uid = int(r0) return } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index 20ad4b6c9..8c9e26a0a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1515,6 +1541,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1571,7 +1607,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1579,7 +1615,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1587,7 +1623,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1605,7 +1641,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -1667,17 +1703,6 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go index 9f194dc4a..8dc2b58f5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1508,6 +1534,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset>>32), uintptr(offset), uintptr(length>>32), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1529,7 +1565,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1537,7 +1573,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1545,7 +1581,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1553,7 +1589,7 @@ func Getgid() (gid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -2003,6 +2039,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Stat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go index 4fde3ef08..e8beef850 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1525,6 +1551,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1535,6 +1571,21 @@ func Fchown(fd int, uid int, gid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1556,7 +1607,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1564,7 +1615,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1572,7 +1623,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1590,7 +1641,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -1677,17 +1728,6 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go index f6463423c..899e4403a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1525,6 +1551,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1535,6 +1571,21 @@ func Fchown(fd int, uid int, gid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1556,7 +1607,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1564,7 +1615,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1572,7 +1623,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1590,7 +1641,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -1677,17 +1728,6 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go index 964591e5e..7a477cbde 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1508,6 +1534,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1529,7 +1565,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1537,7 +1573,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1545,7 +1581,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1553,7 +1589,7 @@ func Getgid() (gid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -2003,6 +2039,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Stat(path string, stat *Stat_t) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index 204ab1ae3..9dc4c7d6d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1525,6 +1551,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1545,6 +1581,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1566,7 +1617,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1574,7 +1625,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1582,7 +1633,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1600,7 +1651,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -1734,7 +1785,7 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index a8a2b0b0a..f0d1ee125 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1525,6 +1551,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -1545,6 +1581,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1566,7 +1617,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1574,7 +1625,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1582,7 +1633,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1600,7 +1651,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } @@ -1734,7 +1785,7 @@ func Seek(fd int, offset int64, whence int) (off int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { - r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go index b6ff9e392..c443baf63 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go @@ -538,7 +538,7 @@ func Eventfd(initval uint, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Exit(code int) { - Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0) + SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) return } @@ -674,7 +674,7 @@ func Getpgid(pid int) (pgid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getpid() (pid int) { - r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) pid = int(r0) return } @@ -682,7 +682,7 @@ func Getpid() (pid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getppid() (ppid int) { - r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) ppid = int(r0) return } @@ -739,7 +739,7 @@ func Getsid(pid int) (sid int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Gettid() (tid int) { - r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) tid = int(r0) return } @@ -1035,6 +1035,17 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func read(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { @@ -1227,8 +1238,23 @@ func Setxattr(path string, attr string, data []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Sync() { - Syscall(SYS_SYNC, 0, 0, 0) + SyscallNoError(SYS_SYNC, 0, 0, 0) return } @@ -1287,7 +1313,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Umask(mask int) (oldmask int) { - r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) + r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) oldmask = int(r0) return } @@ -1446,22 +1472,6 @@ func Mlock(b []byte) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Mlockall(flags int) (err error) { _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) if e1 != 0 { @@ -1488,6 +1498,22 @@ func Msync(b []byte, flags int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Munlockall() (err error) { _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) if e1 != 0 { @@ -1555,6 +1581,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, buf *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) if e1 != 0 { @@ -1576,7 +1617,7 @@ func Ftruncate(fd int, length int64) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getegid() (egid int) { - r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) egid = int(r0) return } @@ -1584,7 +1625,7 @@ func Getegid() (egid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Geteuid() (euid int) { - r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) euid = int(r0) return } @@ -1592,7 +1633,7 @@ func Geteuid() (euid int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getgid() (gid int) { - r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) gid = int(r0) return } @@ -1610,7 +1651,7 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Getuid() (uid int) { - r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0) + r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) uid = int(r0) return } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go index 2dd98434e..c01b3b6ba 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go @@ -1222,6 +1222,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index 3182345ec..fb4b96278 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -1,5 +1,5 @@ // mksyscall.pl -l32 -netbsd -tags netbsd,386 syscall_bsd.go syscall_netbsd.go syscall_netbsd_386.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build netbsd,386 @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (fd1 int, fd2 int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) fd1 = int(r0) @@ -295,6 +406,33 @@ func getdents(fd int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -433,6 +571,16 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), 0, uintptr(length), uintptr(length>>32), uintptr(advice), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -463,6 +611,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -504,6 +667,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -777,74 +955,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1297,3 +1407,18 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 74ba8189a..beac82ef8 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -1,5 +1,5 @@ // mksyscall.pl -netbsd -tags netbsd,amd64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_amd64.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build netbsd,amd64 @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (fd1 int, fd2 int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) fd1 = int(r0) @@ -295,6 +406,33 @@ func getdents(fd int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -433,6 +571,16 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), 0, uintptr(length), uintptr(advice)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -463,6 +611,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -504,6 +667,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -777,74 +955,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1297,3 +1407,18 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index 1f346e2f5..7bd5f60b0 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -1,5 +1,5 @@ -// mksyscall.pl -l32 -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// mksyscall.pl -l32 -netbsd -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build netbsd,arm @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (fd1 int, fd2 int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) fd1 = int(r0) @@ -295,6 +406,33 @@ func getdents(fd int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -433,6 +571,16 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), 0, uintptr(length), uintptr(length>>32), uintptr(advice), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -463,6 +611,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -504,6 +667,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { @@ -777,74 +955,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1297,3 +1407,18 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index ca3e81392..5c09c0758 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -1,5 +1,5 @@ // mksyscall.pl -l32 -openbsd -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build openbsd,386 @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -293,6 +404,33 @@ func getdents(fd int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -461,6 +599,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -502,6 +655,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -785,74 +953,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1355,3 +1455,18 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index bf63d552e..54ccc935d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -1,5 +1,5 @@ // mksyscall.pl -openbsd -tags openbsd,amd64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build openbsd,amd64 @@ -266,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -293,6 +404,33 @@ func getdents(fd int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -461,6 +599,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -502,6 +655,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -785,74 +953,6 @@ func Mknod(path string, mode uint32, dev int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Mlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mlockall(flags int) (err error) { - _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Mprotect(b []byte, prot int) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlock(b []byte) (err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Munlockall() (err error) { - _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) if e1 != 0 { @@ -1355,3 +1455,18 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index 9cabf577c..59258b0a4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -1,5 +1,5 @@ // mksyscall.pl -l32 -openbsd -arm -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; see README.md. DO NOT EDIT. // +build openbsd,arm @@ -10,6 +10,8 @@ import ( "unsafe" ) +var _ syscall.Errno + // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func getgroups(ngid int, gid *_Gid_t) (n int, err error) { @@ -264,6 +266,117 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout)) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Madvise(b []byte, behav int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mlockall(flags int) (err error) { + _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Mprotect(b []byte, prot int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Msync(b []byte, flags int) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlock(b []byte) (err error) { + var _p0 unsafe.Pointer + if len(b) > 0 { + _p0 = unsafe.Pointer(&b[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Munlockall() (err error) { + _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe(p *[2]_C_int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) if e1 != 0 { @@ -291,6 +404,33 @@ func getdents(fd int, buf []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Getcwd(buf []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -459,6 +599,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -500,6 +655,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -1054,6 +1224,26 @@ func Setreuid(ruid int, euid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setresgid(rgid int, egid int, sgid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Setresuid(ruid int, euid int, suid int) (err error) { + _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setrlimit(which int, lim *Rlimit) (err error) { _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) if e1 != 0 { @@ -1265,3 +1455,18 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 4287133d0..5e88619c4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -25,7 +25,11 @@ import ( //go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so" //go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so" //go:cgo_import_dynamic libc_acct acct "libc.so" +//go:cgo_import_dynamic libc___makedev __makedev "libc.so" +//go:cgo_import_dynamic libc___major __major "libc.so" +//go:cgo_import_dynamic libc___minor __minor "libc.so" //go:cgo_import_dynamic libc_ioctl ioctl "libc.so" +//go:cgo_import_dynamic libc_poll poll "libc.so" //go:cgo_import_dynamic libc_access access "libc.so" //go:cgo_import_dynamic libc_adjtime adjtime "libc.so" //go:cgo_import_dynamic libc_chdir chdir "libc.so" @@ -46,6 +50,7 @@ import ( //go:cgo_import_dynamic libc_flock flock "libc.so" //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" //go:cgo_import_dynamic libc_fstat fstat "libc.so" +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" //go:cgo_import_dynamic libc_fstatvfs fstatvfs "libc.so" //go:cgo_import_dynamic libc_getdents getdents "libc.so" //go:cgo_import_dynamic libc_getgid getgid "libc.so" @@ -75,6 +80,7 @@ import ( //go:cgo_import_dynamic libc_mlock mlock "libc.so" //go:cgo_import_dynamic libc_mlockall mlockall "libc.so" //go:cgo_import_dynamic libc_mprotect mprotect "libc.so" +//go:cgo_import_dynamic libc_msync msync "libc.so" //go:cgo_import_dynamic libc_munlock munlock "libc.so" //go:cgo_import_dynamic libc_munlockall munlockall "libc.so" //go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so" @@ -90,6 +96,7 @@ import ( //go:cgo_import_dynamic libc_renameat renameat "libc.so" //go:cgo_import_dynamic libc_rmdir rmdir "libc.so" //go:cgo_import_dynamic libc_lseek lseek "libc.so" +//go:cgo_import_dynamic libc_select select "libc.so" //go:cgo_import_dynamic libc_setegid setegid "libc.so" //go:cgo_import_dynamic libc_seteuid seteuid "libc.so" //go:cgo_import_dynamic libc_setgid setgid "libc.so" @@ -129,7 +136,6 @@ import ( //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" -//go:cgo_import_dynamic libc_sysconf sysconf "libc.so" //go:linkname procpipe libc_pipe //go:linkname procgetsockname libc_getsockname @@ -146,7 +152,11 @@ import ( //go:linkname proc__xnet_recvmsg libc___xnet_recvmsg //go:linkname proc__xnet_sendmsg libc___xnet_sendmsg //go:linkname procacct libc_acct +//go:linkname proc__makedev libc___makedev +//go:linkname proc__major libc___major +//go:linkname proc__minor libc___minor //go:linkname procioctl libc_ioctl +//go:linkname procpoll libc_poll //go:linkname procAccess libc_access //go:linkname procAdjtime libc_adjtime //go:linkname procChdir libc_chdir @@ -167,6 +177,7 @@ import ( //go:linkname procFlock libc_flock //go:linkname procFpathconf libc_fpathconf //go:linkname procFstat libc_fstat +//go:linkname procFstatat libc_fstatat //go:linkname procFstatvfs libc_fstatvfs //go:linkname procGetdents libc_getdents //go:linkname procGetgid libc_getgid @@ -196,6 +207,7 @@ import ( //go:linkname procMlock libc_mlock //go:linkname procMlockall libc_mlockall //go:linkname procMprotect libc_mprotect +//go:linkname procMsync libc_msync //go:linkname procMunlock libc_munlock //go:linkname procMunlockall libc_munlockall //go:linkname procNanosleep libc_nanosleep @@ -211,6 +223,7 @@ import ( //go:linkname procRenameat libc_renameat //go:linkname procRmdir libc_rmdir //go:linkname proclseek libc_lseek +//go:linkname procSelect libc_select //go:linkname procSetegid libc_setegid //go:linkname procSeteuid libc_seteuid //go:linkname procSetgid libc_setgid @@ -250,7 +263,6 @@ import ( //go:linkname procgetpeername libc_getpeername //go:linkname procsetsockopt libc_setsockopt //go:linkname procrecvfrom libc_recvfrom -//go:linkname procsysconf libc_sysconf var ( procpipe, @@ -268,7 +280,11 @@ var ( proc__xnet_recvmsg, proc__xnet_sendmsg, procacct, + proc__makedev, + proc__major, + proc__minor, procioctl, + procpoll, procAccess, procAdjtime, procChdir, @@ -289,6 +305,7 @@ var ( procFlock, procFpathconf, procFstat, + procFstatat, procFstatvfs, procGetdents, procGetgid, @@ -318,6 +335,7 @@ var ( procMlock, procMlockall, procMprotect, + procMsync, procMunlock, procMunlockall, procNanosleep, @@ -333,6 +351,7 @@ var ( procRenameat, procRmdir, proclseek, + procSelect, procSetegid, procSeteuid, procSetgid, @@ -371,8 +390,7 @@ var ( proc__xnet_getsockopt, procgetpeername, procsetsockopt, - procrecvfrom, - procsysconf syscallFunc + procrecvfrom syscallFunc ) func pipe(p *[2]_C_int) (n int, err error) { @@ -522,6 +540,24 @@ func acct(path *byte) (err error) { return } +func __makedev(version int, major uint, minor uint) (val uint64) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&proc__makedev)), 3, uintptr(version), uintptr(major), uintptr(minor), 0, 0, 0) + val = uint64(r0) + return +} + +func __major(version int, dev uint64) (val uint) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&proc__major)), 2, uintptr(version), uintptr(dev), 0, 0, 0, 0) + val = uint(r0) + return +} + +func __minor(version int, dev uint64) (val uint) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&proc__minor)), 2, uintptr(version), uintptr(dev), 0, 0, 0, 0) + val = uint(r0) + return +} + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) if e1 != 0 { @@ -530,6 +566,15 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpoll)), 3, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout), 0, 0, 0) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) @@ -730,6 +775,19 @@ func Fstat(fd int, stat *Stat_t) (err error) { return } +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatat)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + func Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatvfs)), 2, uintptr(fd), uintptr(unsafe.Pointer(vfsstat)), 0, 0, 0, 0) if e1 != 0 { @@ -1020,6 +1078,18 @@ func Mprotect(b []byte, prot int) (err error) { return } +func Msync(b []byte, flags int) (err error) { + var _p0 *byte + if len(b) > 0 { + _p0 = &b[0] + } + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMsync)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(flags), 0, 0, 0) + if e1 != 0 { + err = e1 + } + return +} + func Munlock(b []byte) (err error) { var _p0 *byte if len(b) > 0 { @@ -1213,6 +1283,14 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { return } +func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSelect)), 5, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + if e1 != 0 { + err = e1 + } + return +} + func Setegid(egid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetegid)), 1, uintptr(egid), 0, 0, 0, 0, 0) if e1 != 0 { @@ -1589,12 +1667,3 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl } return } - -func sysconf(name int) (n int64, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsysconf)), 1, uintptr(name), 0, 0, 0, 0, 0) - n = int64(r0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go similarity index 100% rename from vendor/golang.org/x/sys/unix/zsysctl_openbsd.go rename to vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go new file mode 100644 index 000000000..83bb935b9 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go @@ -0,0 +1,270 @@ +// mksysctl_openbsd.pl +// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry{ + {"ddb.console", []_C_int{9, 6}}, + {"ddb.log", []_C_int{9, 7}}, + {"ddb.max_line", []_C_int{9, 3}}, + {"ddb.max_width", []_C_int{9, 2}}, + {"ddb.panic", []_C_int{9, 5}}, + {"ddb.radix", []_C_int{9, 1}}, + {"ddb.tab_stop_width", []_C_int{9, 4}}, + {"ddb.trigger", []_C_int{9, 8}}, + {"fs.posix.setuid", []_C_int{3, 1, 1}}, + {"hw.allowpowerdown", []_C_int{6, 22}}, + {"hw.byteorder", []_C_int{6, 4}}, + {"hw.cpuspeed", []_C_int{6, 12}}, + {"hw.diskcount", []_C_int{6, 10}}, + {"hw.disknames", []_C_int{6, 8}}, + {"hw.diskstats", []_C_int{6, 9}}, + {"hw.machine", []_C_int{6, 1}}, + {"hw.model", []_C_int{6, 2}}, + {"hw.ncpu", []_C_int{6, 3}}, + {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.pagesize", []_C_int{6, 7}}, + {"hw.physmem", []_C_int{6, 19}}, + {"hw.product", []_C_int{6, 15}}, + {"hw.serialno", []_C_int{6, 17}}, + {"hw.setperf", []_C_int{6, 13}}, + {"hw.usermem", []_C_int{6, 20}}, + {"hw.uuid", []_C_int{6, 18}}, + {"hw.vendor", []_C_int{6, 14}}, + {"hw.version", []_C_int{6, 16}}, + {"kern.arandom", []_C_int{1, 37}}, + {"kern.argmax", []_C_int{1, 8}}, + {"kern.boottime", []_C_int{1, 21}}, + {"kern.bufcachepercent", []_C_int{1, 72}}, + {"kern.ccpu", []_C_int{1, 45}}, + {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consdev", []_C_int{1, 75}}, + {"kern.cp_time", []_C_int{1, 40}}, + {"kern.cp_time2", []_C_int{1, 71}}, + {"kern.cryptodevallowsoft", []_C_int{1, 53}}, + {"kern.domainname", []_C_int{1, 22}}, + {"kern.file", []_C_int{1, 73}}, + {"kern.forkstat", []_C_int{1, 42}}, + {"kern.fscale", []_C_int{1, 46}}, + {"kern.fsync", []_C_int{1, 33}}, + {"kern.hostid", []_C_int{1, 11}}, + {"kern.hostname", []_C_int{1, 10}}, + {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, + {"kern.job_control", []_C_int{1, 19}}, + {"kern.malloc.buckets", []_C_int{1, 39, 1}}, + {"kern.malloc.kmemnames", []_C_int{1, 39, 3}}, + {"kern.maxclusters", []_C_int{1, 67}}, + {"kern.maxfiles", []_C_int{1, 7}}, + {"kern.maxlocksperuid", []_C_int{1, 70}}, + {"kern.maxpartitions", []_C_int{1, 23}}, + {"kern.maxproc", []_C_int{1, 6}}, + {"kern.maxthread", []_C_int{1, 25}}, + {"kern.maxvnodes", []_C_int{1, 5}}, + {"kern.mbstat", []_C_int{1, 59}}, + {"kern.msgbuf", []_C_int{1, 48}}, + {"kern.msgbufsize", []_C_int{1, 38}}, + {"kern.nchstats", []_C_int{1, 41}}, + {"kern.netlivelocks", []_C_int{1, 76}}, + {"kern.nfiles", []_C_int{1, 56}}, + {"kern.ngroups", []_C_int{1, 18}}, + {"kern.nosuidcoredump", []_C_int{1, 32}}, + {"kern.nprocs", []_C_int{1, 47}}, + {"kern.nselcoll", []_C_int{1, 43}}, + {"kern.nthreads", []_C_int{1, 26}}, + {"kern.numvnodes", []_C_int{1, 58}}, + {"kern.osrelease", []_C_int{1, 2}}, + {"kern.osrevision", []_C_int{1, 3}}, + {"kern.ostype", []_C_int{1, 1}}, + {"kern.osversion", []_C_int{1, 27}}, + {"kern.pool_debug", []_C_int{1, 77}}, + {"kern.posix1version", []_C_int{1, 17}}, + {"kern.proc", []_C_int{1, 66}}, + {"kern.random", []_C_int{1, 31}}, + {"kern.rawpartition", []_C_int{1, 24}}, + {"kern.saved_ids", []_C_int{1, 20}}, + {"kern.securelevel", []_C_int{1, 9}}, + {"kern.seminfo", []_C_int{1, 61}}, + {"kern.shminfo", []_C_int{1, 62}}, + {"kern.somaxconn", []_C_int{1, 28}}, + {"kern.sominconn", []_C_int{1, 29}}, + {"kern.splassert", []_C_int{1, 54}}, + {"kern.stackgap_random", []_C_int{1, 50}}, + {"kern.sysvipc_info", []_C_int{1, 51}}, + {"kern.sysvmsg", []_C_int{1, 34}}, + {"kern.sysvsem", []_C_int{1, 35}}, + {"kern.sysvshm", []_C_int{1, 36}}, + {"kern.timecounter.choice", []_C_int{1, 69, 4}}, + {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, + {"kern.timecounter.tick", []_C_int{1, 69, 1}}, + {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.tty.maxptys", []_C_int{1, 44, 6}}, + {"kern.tty.nptys", []_C_int{1, 44, 7}}, + {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, + {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, + {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, + {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, + {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, + {"kern.ttycount", []_C_int{1, 57}}, + {"kern.userasymcrypto", []_C_int{1, 60}}, + {"kern.usercrypto", []_C_int{1, 52}}, + {"kern.usermount", []_C_int{1, 30}}, + {"kern.version", []_C_int{1, 4}}, + {"kern.vnode", []_C_int{1, 13}}, + {"kern.watchdog.auto", []_C_int{1, 64, 2}}, + {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"net.bpf.bufsize", []_C_int{4, 31, 1}}, + {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, + {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, + {"net.inet.ah.stats", []_C_int{4, 2, 51, 2}}, + {"net.inet.carp.allow", []_C_int{4, 2, 112, 1}}, + {"net.inet.carp.log", []_C_int{4, 2, 112, 3}}, + {"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}}, + {"net.inet.carp.stats", []_C_int{4, 2, 112, 4}}, + {"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}}, + {"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}}, + {"net.inet.divert.stats", []_C_int{4, 2, 258, 3}}, + {"net.inet.esp.enable", []_C_int{4, 2, 50, 1}}, + {"net.inet.esp.stats", []_C_int{4, 2, 50, 4}}, + {"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}}, + {"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}}, + {"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}}, + {"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}}, + {"net.inet.gre.allow", []_C_int{4, 2, 47, 1}}, + {"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}}, + {"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}}, + {"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}}, + {"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}}, + {"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}}, + {"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}}, + {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, + {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, + {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, + {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, + {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, + {"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}}, + {"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}}, + {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, + {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, + {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, + {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, + {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, + {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, + {"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}}, + {"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}}, + {"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}}, + {"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}}, + {"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}}, + {"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}}, + {"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}}, + {"net.inet.ip.stats", []_C_int{4, 2, 0, 33}}, + {"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}}, + {"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}}, + {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, + {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, + {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, + {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, + {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, + {"net.inet.pim.stats", []_C_int{4, 2, 103, 1}}, + {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, + {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, + {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, + {"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}}, + {"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}}, + {"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}}, + {"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}}, + {"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}}, + {"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}}, + {"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}}, + {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, + {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, + {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, + {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, + {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, + {"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}}, + {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, + {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, + {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, + {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, + {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, + {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, + {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, + {"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}}, + {"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}}, + {"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}}, + {"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}}, + {"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}}, + {"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}}, + {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, + {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, + {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, + {"net.inet6.icmp6.nd6_prune", []_C_int{4, 24, 30, 6}}, + {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, + {"net.inet6.icmp6.nd6_useloopback", []_C_int{4, 24, 30, 11}}, + {"net.inet6.icmp6.nodeinfo", []_C_int{4, 24, 30, 13}}, + {"net.inet6.icmp6.rediraccept", []_C_int{4, 24, 30, 2}}, + {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, + {"net.inet6.ip6.accept_rtadv", []_C_int{4, 24, 17, 12}}, + {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, + {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, + {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, + {"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}}, + {"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}}, + {"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}}, + {"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}}, + {"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}}, + {"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}}, + {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, + {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, + {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, + {"net.inet6.ip6.maxifdefrouters", []_C_int{4, 24, 17, 47}}, + {"net.inet6.ip6.maxifprefixes", []_C_int{4, 24, 17, 46}}, + {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, + {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, + {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, + {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, + {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, + {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, + {"net.inet6.ip6.rr_prune", []_C_int{4, 24, 17, 22}}, + {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, + {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, + {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, + {"net.inet6.ip6.v6only", []_C_int{4, 24, 17, 24}}, + {"net.key.sadb_dump", []_C_int{4, 30, 1}}, + {"net.key.spd_dump", []_C_int{4, 30, 2}}, + {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, + {"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}}, + {"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}}, + {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, + {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, + {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, + {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, + {"net.mpls.ttl", []_C_int{4, 33, 2}}, + {"net.pflow.stats", []_C_int{4, 34, 1}}, + {"net.pipex.enable", []_C_int{4, 35, 1}}, + {"vm.anonmin", []_C_int{2, 7}}, + {"vm.loadavg", []_C_int{2, 2}}, + {"vm.maxslp", []_C_int{2, 10}}, + {"vm.nkmempages", []_C_int{2, 6}}, + {"vm.psstrings", []_C_int{2, 3}}, + {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, + {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, + {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, + {"vm.uspace", []_C_int{2, 11}}, + {"vm.uvmexp", []_C_int{2, 4}}, + {"vm.vmmeter", []_C_int{2, 1}}, + {"vm.vnodemin", []_C_int{2, 9}}, + {"vm.vtextmin", []_C_int{2, 8}}, +} diff --git a/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go new file mode 100644 index 000000000..83bb935b9 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go @@ -0,0 +1,270 @@ +// mksysctl_openbsd.pl +// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT + +package unix + +type mibentry struct { + ctlname string + ctloid []_C_int +} + +var sysctlMib = []mibentry{ + {"ddb.console", []_C_int{9, 6}}, + {"ddb.log", []_C_int{9, 7}}, + {"ddb.max_line", []_C_int{9, 3}}, + {"ddb.max_width", []_C_int{9, 2}}, + {"ddb.panic", []_C_int{9, 5}}, + {"ddb.radix", []_C_int{9, 1}}, + {"ddb.tab_stop_width", []_C_int{9, 4}}, + {"ddb.trigger", []_C_int{9, 8}}, + {"fs.posix.setuid", []_C_int{3, 1, 1}}, + {"hw.allowpowerdown", []_C_int{6, 22}}, + {"hw.byteorder", []_C_int{6, 4}}, + {"hw.cpuspeed", []_C_int{6, 12}}, + {"hw.diskcount", []_C_int{6, 10}}, + {"hw.disknames", []_C_int{6, 8}}, + {"hw.diskstats", []_C_int{6, 9}}, + {"hw.machine", []_C_int{6, 1}}, + {"hw.model", []_C_int{6, 2}}, + {"hw.ncpu", []_C_int{6, 3}}, + {"hw.ncpufound", []_C_int{6, 21}}, + {"hw.pagesize", []_C_int{6, 7}}, + {"hw.physmem", []_C_int{6, 19}}, + {"hw.product", []_C_int{6, 15}}, + {"hw.serialno", []_C_int{6, 17}}, + {"hw.setperf", []_C_int{6, 13}}, + {"hw.usermem", []_C_int{6, 20}}, + {"hw.uuid", []_C_int{6, 18}}, + {"hw.vendor", []_C_int{6, 14}}, + {"hw.version", []_C_int{6, 16}}, + {"kern.arandom", []_C_int{1, 37}}, + {"kern.argmax", []_C_int{1, 8}}, + {"kern.boottime", []_C_int{1, 21}}, + {"kern.bufcachepercent", []_C_int{1, 72}}, + {"kern.ccpu", []_C_int{1, 45}}, + {"kern.clockrate", []_C_int{1, 12}}, + {"kern.consdev", []_C_int{1, 75}}, + {"kern.cp_time", []_C_int{1, 40}}, + {"kern.cp_time2", []_C_int{1, 71}}, + {"kern.cryptodevallowsoft", []_C_int{1, 53}}, + {"kern.domainname", []_C_int{1, 22}}, + {"kern.file", []_C_int{1, 73}}, + {"kern.forkstat", []_C_int{1, 42}}, + {"kern.fscale", []_C_int{1, 46}}, + {"kern.fsync", []_C_int{1, 33}}, + {"kern.hostid", []_C_int{1, 11}}, + {"kern.hostname", []_C_int{1, 10}}, + {"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}}, + {"kern.job_control", []_C_int{1, 19}}, + {"kern.malloc.buckets", []_C_int{1, 39, 1}}, + {"kern.malloc.kmemnames", []_C_int{1, 39, 3}}, + {"kern.maxclusters", []_C_int{1, 67}}, + {"kern.maxfiles", []_C_int{1, 7}}, + {"kern.maxlocksperuid", []_C_int{1, 70}}, + {"kern.maxpartitions", []_C_int{1, 23}}, + {"kern.maxproc", []_C_int{1, 6}}, + {"kern.maxthread", []_C_int{1, 25}}, + {"kern.maxvnodes", []_C_int{1, 5}}, + {"kern.mbstat", []_C_int{1, 59}}, + {"kern.msgbuf", []_C_int{1, 48}}, + {"kern.msgbufsize", []_C_int{1, 38}}, + {"kern.nchstats", []_C_int{1, 41}}, + {"kern.netlivelocks", []_C_int{1, 76}}, + {"kern.nfiles", []_C_int{1, 56}}, + {"kern.ngroups", []_C_int{1, 18}}, + {"kern.nosuidcoredump", []_C_int{1, 32}}, + {"kern.nprocs", []_C_int{1, 47}}, + {"kern.nselcoll", []_C_int{1, 43}}, + {"kern.nthreads", []_C_int{1, 26}}, + {"kern.numvnodes", []_C_int{1, 58}}, + {"kern.osrelease", []_C_int{1, 2}}, + {"kern.osrevision", []_C_int{1, 3}}, + {"kern.ostype", []_C_int{1, 1}}, + {"kern.osversion", []_C_int{1, 27}}, + {"kern.pool_debug", []_C_int{1, 77}}, + {"kern.posix1version", []_C_int{1, 17}}, + {"kern.proc", []_C_int{1, 66}}, + {"kern.random", []_C_int{1, 31}}, + {"kern.rawpartition", []_C_int{1, 24}}, + {"kern.saved_ids", []_C_int{1, 20}}, + {"kern.securelevel", []_C_int{1, 9}}, + {"kern.seminfo", []_C_int{1, 61}}, + {"kern.shminfo", []_C_int{1, 62}}, + {"kern.somaxconn", []_C_int{1, 28}}, + {"kern.sominconn", []_C_int{1, 29}}, + {"kern.splassert", []_C_int{1, 54}}, + {"kern.stackgap_random", []_C_int{1, 50}}, + {"kern.sysvipc_info", []_C_int{1, 51}}, + {"kern.sysvmsg", []_C_int{1, 34}}, + {"kern.sysvsem", []_C_int{1, 35}}, + {"kern.sysvshm", []_C_int{1, 36}}, + {"kern.timecounter.choice", []_C_int{1, 69, 4}}, + {"kern.timecounter.hardware", []_C_int{1, 69, 3}}, + {"kern.timecounter.tick", []_C_int{1, 69, 1}}, + {"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}}, + {"kern.tty.maxptys", []_C_int{1, 44, 6}}, + {"kern.tty.nptys", []_C_int{1, 44, 7}}, + {"kern.tty.tk_cancc", []_C_int{1, 44, 4}}, + {"kern.tty.tk_nin", []_C_int{1, 44, 1}}, + {"kern.tty.tk_nout", []_C_int{1, 44, 2}}, + {"kern.tty.tk_rawcc", []_C_int{1, 44, 3}}, + {"kern.tty.ttyinfo", []_C_int{1, 44, 5}}, + {"kern.ttycount", []_C_int{1, 57}}, + {"kern.userasymcrypto", []_C_int{1, 60}}, + {"kern.usercrypto", []_C_int{1, 52}}, + {"kern.usermount", []_C_int{1, 30}}, + {"kern.version", []_C_int{1, 4}}, + {"kern.vnode", []_C_int{1, 13}}, + {"kern.watchdog.auto", []_C_int{1, 64, 2}}, + {"kern.watchdog.period", []_C_int{1, 64, 1}}, + {"net.bpf.bufsize", []_C_int{4, 31, 1}}, + {"net.bpf.maxbufsize", []_C_int{4, 31, 2}}, + {"net.inet.ah.enable", []_C_int{4, 2, 51, 1}}, + {"net.inet.ah.stats", []_C_int{4, 2, 51, 2}}, + {"net.inet.carp.allow", []_C_int{4, 2, 112, 1}}, + {"net.inet.carp.log", []_C_int{4, 2, 112, 3}}, + {"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}}, + {"net.inet.carp.stats", []_C_int{4, 2, 112, 4}}, + {"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}}, + {"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}}, + {"net.inet.divert.stats", []_C_int{4, 2, 258, 3}}, + {"net.inet.esp.enable", []_C_int{4, 2, 50, 1}}, + {"net.inet.esp.stats", []_C_int{4, 2, 50, 4}}, + {"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}}, + {"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}}, + {"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}}, + {"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}}, + {"net.inet.gre.allow", []_C_int{4, 2, 47, 1}}, + {"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}}, + {"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}}, + {"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}}, + {"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}}, + {"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}}, + {"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}}, + {"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}}, + {"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}}, + {"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}}, + {"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}}, + {"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}}, + {"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}}, + {"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}}, + {"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}}, + {"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}}, + {"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}}, + {"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}}, + {"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}}, + {"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}}, + {"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}}, + {"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}}, + {"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}}, + {"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}}, + {"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}}, + {"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}}, + {"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}}, + {"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}}, + {"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}}, + {"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}}, + {"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}}, + {"net.inet.ip.stats", []_C_int{4, 2, 0, 33}}, + {"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}}, + {"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}}, + {"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}}, + {"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}}, + {"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}}, + {"net.inet.mobileip.allow", []_C_int{4, 2, 55, 1}}, + {"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}}, + {"net.inet.pim.stats", []_C_int{4, 2, 103, 1}}, + {"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}}, + {"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}}, + {"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}}, + {"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}}, + {"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}}, + {"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}}, + {"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}}, + {"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}}, + {"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}}, + {"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}}, + {"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}}, + {"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}}, + {"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}}, + {"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}}, + {"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}}, + {"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}}, + {"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}}, + {"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}}, + {"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}}, + {"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}}, + {"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}}, + {"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}}, + {"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}}, + {"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}}, + {"net.inet.udp.stats", []_C_int{4, 2, 17, 5}}, + {"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}}, + {"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}}, + {"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}}, + {"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}}, + {"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}}, + {"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}}, + {"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}}, + {"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}}, + {"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}}, + {"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}}, + {"net.inet6.icmp6.nd6_prune", []_C_int{4, 24, 30, 6}}, + {"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}}, + {"net.inet6.icmp6.nd6_useloopback", []_C_int{4, 24, 30, 11}}, + {"net.inet6.icmp6.nodeinfo", []_C_int{4, 24, 30, 13}}, + {"net.inet6.icmp6.rediraccept", []_C_int{4, 24, 30, 2}}, + {"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}}, + {"net.inet6.ip6.accept_rtadv", []_C_int{4, 24, 17, 12}}, + {"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}}, + {"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}}, + {"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}}, + {"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}}, + {"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}}, + {"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}}, + {"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}}, + {"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}}, + {"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}}, + {"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}}, + {"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}}, + {"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}}, + {"net.inet6.ip6.maxifdefrouters", []_C_int{4, 24, 17, 47}}, + {"net.inet6.ip6.maxifprefixes", []_C_int{4, 24, 17, 46}}, + {"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}}, + {"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}}, + {"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}}, + {"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}}, + {"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}}, + {"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}}, + {"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}}, + {"net.inet6.ip6.rr_prune", []_C_int{4, 24, 17, 22}}, + {"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}}, + {"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}}, + {"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}}, + {"net.inet6.ip6.v6only", []_C_int{4, 24, 17, 24}}, + {"net.key.sadb_dump", []_C_int{4, 30, 1}}, + {"net.key.spd_dump", []_C_int{4, 30, 2}}, + {"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}}, + {"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}}, + {"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}}, + {"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}}, + {"net.mpls.mapttl_ip", []_C_int{4, 33, 5}}, + {"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}}, + {"net.mpls.maxloop_inkernel", []_C_int{4, 33, 4}}, + {"net.mpls.ttl", []_C_int{4, 33, 2}}, + {"net.pflow.stats", []_C_int{4, 34, 1}}, + {"net.pipex.enable", []_C_int{4, 35, 1}}, + {"vm.anonmin", []_C_int{2, 7}}, + {"vm.loadavg", []_C_int{2, 2}}, + {"vm.maxslp", []_C_int{2, 10}}, + {"vm.nkmempages", []_C_int{2, 6}}, + {"vm.psstrings", []_C_int{2, 3}}, + {"vm.swapencrypt.enable", []_C_int{2, 5, 0}}, + {"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}}, + {"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}}, + {"vm.uspace", []_C_int{2, 11}}, + {"vm.uvmexp", []_C_int{2, 4}}, + {"vm.vmmeter", []_C_int{2, 1}}, + {"vm.vnodemin", []_C_int{2, 9}}, + {"vm.vtextmin", []_C_int{2, 8}}, +} diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go index 2786773ba..d1d36da3f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go @@ -1,5 +1,5 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/sys/syscall.h -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h +// Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,darwin @@ -121,13 +121,15 @@ const ( SYS_CSOPS = 169 SYS_CSOPS_AUDITTOKEN = 170 SYS_WAITID = 173 + SYS_KDEBUG_TYPEFILTER = 177 + SYS_KDEBUG_TRACE_STRING = 178 SYS_KDEBUG_TRACE64 = 179 SYS_KDEBUG_TRACE = 180 SYS_SETGID = 181 SYS_SETEGID = 182 SYS_SETEUID = 183 SYS_SIGRETURN = 184 - SYS_CHUD = 185 + SYS_THREAD_SELFCOUNTS = 186 SYS_FDATASYNC = 187 SYS_STAT = 188 SYS_FSTAT = 189 @@ -278,7 +280,6 @@ const ( SYS_KQUEUE = 362 SYS_KEVENT = 363 SYS_LCHOWN = 364 - SYS_STACK_SNAPSHOT = 365 SYS_BSDTHREAD_REGISTER = 366 SYS_WORKQ_OPEN = 367 SYS_WORKQ_KERNRETURN = 368 @@ -287,6 +288,8 @@ const ( SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL = 371 SYS_THREAD_SELFID = 372 SYS_LEDGER = 373 + SYS_KEVENT_QOS = 374 + SYS_KEVENT_ID = 375 SYS___MAC_EXECVE = 380 SYS___MAC_SYSCALL = 381 SYS___MAC_GET_FILE = 382 @@ -298,11 +301,8 @@ const ( SYS___MAC_GET_FD = 388 SYS___MAC_SET_FD = 389 SYS___MAC_GET_PID = 390 - SYS___MAC_GET_LCID = 391 - SYS___MAC_GET_LCTX = 392 - SYS___MAC_SET_LCTX = 393 - SYS_SETLCID = 394 - SYS_GETLCID = 395 + SYS_PSELECT = 394 + SYS_PSELECT_NOCANCEL = 395 SYS_READ_NOCANCEL = 396 SYS_WRITE_NOCANCEL = 397 SYS_OPEN_NOCANCEL = 398 @@ -351,6 +351,7 @@ const ( SYS_GUARDED_CLOSE_NP = 442 SYS_GUARDED_KQUEUE_NP = 443 SYS_CHANGE_FDGUARD_NP = 444 + SYS_USRCTL = 445 SYS_PROC_RLIMIT_CONTROL = 446 SYS_CONNECTX = 447 SYS_DISCONNECTX = 448 @@ -367,6 +368,7 @@ const ( SYS_COALITION_INFO = 459 SYS_NECP_MATCH_POLICY = 460 SYS_GETATTRLISTBULK = 461 + SYS_CLONEFILEAT = 462 SYS_OPENAT = 463 SYS_OPENAT_NOCANCEL = 464 SYS_RENAMEAT = 465 @@ -392,7 +394,43 @@ const ( SYS_GUARDED_WRITE_NP = 485 SYS_GUARDED_PWRITE_NP = 486 SYS_GUARDED_WRITEV_NP = 487 - SYS_RENAME_EXT = 488 + SYS_RENAMEATX_NP = 488 SYS_MREMAP_ENCRYPTED = 489 - SYS_MAXSYSCALL = 490 + SYS_NETAGENT_TRIGGER = 490 + SYS_STACK_SNAPSHOT_WITH_CONFIG = 491 + SYS_MICROSTACKSHOT = 492 + SYS_GRAB_PGO_DATA = 493 + SYS_PERSONA = 494 + SYS_WORK_INTERVAL_CTL = 499 + SYS_GETENTROPY = 500 + SYS_NECP_OPEN = 501 + SYS_NECP_CLIENT_ACTION = 502 + SYS___NEXUS_OPEN = 503 + SYS___NEXUS_REGISTER = 504 + SYS___NEXUS_DEREGISTER = 505 + SYS___NEXUS_CREATE = 506 + SYS___NEXUS_DESTROY = 507 + SYS___NEXUS_GET_OPT = 508 + SYS___NEXUS_SET_OPT = 509 + SYS___CHANNEL_OPEN = 510 + SYS___CHANNEL_GET_INFO = 511 + SYS___CHANNEL_SYNC = 512 + SYS___CHANNEL_GET_OPT = 513 + SYS___CHANNEL_SET_OPT = 514 + SYS_ULOCK_WAIT = 515 + SYS_ULOCK_WAKE = 516 + SYS_FCLONEFILEAT = 517 + SYS_FS_SNAPSHOT = 518 + SYS_TERMINATE_WITH_PAYLOAD = 520 + SYS_ABORT_WITH_PAYLOAD = 521 + SYS_NECP_SESSION_OPEN = 522 + SYS_NECP_SESSION_ACTION = 523 + SYS_SETATTRLISTAT = 524 + SYS_NET_QOS_GUIDELINE = 525 + SYS_FMOUNT = 526 + SYS_NTP_ADJTIME = 527 + SYS_NTP_GETTIME = 528 + SYS_OS_FAULT_WITH_PAYLOAD = 529 + SYS_MAXSYSCALL = 530 + SYS_INVALID = 63 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go index 09de240c8..e35de4145 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go @@ -1,5 +1,5 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/sys/syscall.h -// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT +// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,darwin @@ -121,13 +121,15 @@ const ( SYS_CSOPS = 169 SYS_CSOPS_AUDITTOKEN = 170 SYS_WAITID = 173 + SYS_KDEBUG_TYPEFILTER = 177 + SYS_KDEBUG_TRACE_STRING = 178 SYS_KDEBUG_TRACE64 = 179 SYS_KDEBUG_TRACE = 180 SYS_SETGID = 181 SYS_SETEGID = 182 SYS_SETEUID = 183 SYS_SIGRETURN = 184 - SYS_CHUD = 185 + SYS_THREAD_SELFCOUNTS = 186 SYS_FDATASYNC = 187 SYS_STAT = 188 SYS_FSTAT = 189 @@ -278,7 +280,6 @@ const ( SYS_KQUEUE = 362 SYS_KEVENT = 363 SYS_LCHOWN = 364 - SYS_STACK_SNAPSHOT = 365 SYS_BSDTHREAD_REGISTER = 366 SYS_WORKQ_OPEN = 367 SYS_WORKQ_KERNRETURN = 368 @@ -287,6 +288,8 @@ const ( SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL = 371 SYS_THREAD_SELFID = 372 SYS_LEDGER = 373 + SYS_KEVENT_QOS = 374 + SYS_KEVENT_ID = 375 SYS___MAC_EXECVE = 380 SYS___MAC_SYSCALL = 381 SYS___MAC_GET_FILE = 382 @@ -298,11 +301,8 @@ const ( SYS___MAC_GET_FD = 388 SYS___MAC_SET_FD = 389 SYS___MAC_GET_PID = 390 - SYS___MAC_GET_LCID = 391 - SYS___MAC_GET_LCTX = 392 - SYS___MAC_SET_LCTX = 393 - SYS_SETLCID = 394 - SYS_GETLCID = 395 + SYS_PSELECT = 394 + SYS_PSELECT_NOCANCEL = 395 SYS_READ_NOCANCEL = 396 SYS_WRITE_NOCANCEL = 397 SYS_OPEN_NOCANCEL = 398 @@ -351,6 +351,7 @@ const ( SYS_GUARDED_CLOSE_NP = 442 SYS_GUARDED_KQUEUE_NP = 443 SYS_CHANGE_FDGUARD_NP = 444 + SYS_USRCTL = 445 SYS_PROC_RLIMIT_CONTROL = 446 SYS_CONNECTX = 447 SYS_DISCONNECTX = 448 @@ -367,6 +368,7 @@ const ( SYS_COALITION_INFO = 459 SYS_NECP_MATCH_POLICY = 460 SYS_GETATTRLISTBULK = 461 + SYS_CLONEFILEAT = 462 SYS_OPENAT = 463 SYS_OPENAT_NOCANCEL = 464 SYS_RENAMEAT = 465 @@ -392,7 +394,43 @@ const ( SYS_GUARDED_WRITE_NP = 485 SYS_GUARDED_PWRITE_NP = 486 SYS_GUARDED_WRITEV_NP = 487 - SYS_RENAME_EXT = 488 + SYS_RENAMEATX_NP = 488 SYS_MREMAP_ENCRYPTED = 489 - SYS_MAXSYSCALL = 490 + SYS_NETAGENT_TRIGGER = 490 + SYS_STACK_SNAPSHOT_WITH_CONFIG = 491 + SYS_MICROSTACKSHOT = 492 + SYS_GRAB_PGO_DATA = 493 + SYS_PERSONA = 494 + SYS_WORK_INTERVAL_CTL = 499 + SYS_GETENTROPY = 500 + SYS_NECP_OPEN = 501 + SYS_NECP_CLIENT_ACTION = 502 + SYS___NEXUS_OPEN = 503 + SYS___NEXUS_REGISTER = 504 + SYS___NEXUS_DEREGISTER = 505 + SYS___NEXUS_CREATE = 506 + SYS___NEXUS_DESTROY = 507 + SYS___NEXUS_GET_OPT = 508 + SYS___NEXUS_SET_OPT = 509 + SYS___CHANNEL_OPEN = 510 + SYS___CHANNEL_GET_INFO = 511 + SYS___CHANNEL_SYNC = 512 + SYS___CHANNEL_GET_OPT = 513 + SYS___CHANNEL_SET_OPT = 514 + SYS_ULOCK_WAIT = 515 + SYS_ULOCK_WAKE = 516 + SYS_FCLONEFILEAT = 517 + SYS_FS_SNAPSHOT = 518 + SYS_TERMINATE_WITH_PAYLOAD = 520 + SYS_ABORT_WITH_PAYLOAD = 521 + SYS_NECP_SESSION_OPEN = 522 + SYS_NECP_SESSION_ACTION = 523 + SYS_SETATTRLISTAT = 524 + SYS_NET_QOS_GUIDELINE = 525 + SYS_FMOUNT = 526 + SYS_NTP_ADJTIME = 527 + SYS_NTP_GETTIME = 528 + SYS_OS_FAULT_WITH_PAYLOAD = 529 + SYS_MAXSYSCALL = 530 + SYS_INVALID = 63 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go index 41cb6ed39..f2df27db2 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk/usr/include/sys/syscall.h +// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h // Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,darwin @@ -129,6 +129,7 @@ const ( SYS_SETEGID = 182 SYS_SETEUID = 183 SYS_SIGRETURN = 184 + SYS_THREAD_SELFCOUNTS = 186 SYS_FDATASYNC = 187 SYS_STAT = 188 SYS_FSTAT = 189 @@ -288,6 +289,7 @@ const ( SYS_THREAD_SELFID = 372 SYS_LEDGER = 373 SYS_KEVENT_QOS = 374 + SYS_KEVENT_ID = 375 SYS___MAC_EXECVE = 380 SYS___MAC_SYSCALL = 381 SYS___MAC_GET_FILE = 382 @@ -421,6 +423,14 @@ const ( SYS_FS_SNAPSHOT = 518 SYS_TERMINATE_WITH_PAYLOAD = 520 SYS_ABORT_WITH_PAYLOAD = 521 - SYS_MAXSYSCALL = 522 + SYS_NECP_SESSION_OPEN = 522 + SYS_NECP_SESSION_ACTION = 523 + SYS_SETATTRLISTAT = 524 + SYS_NET_QOS_GUIDELINE = 525 + SYS_FMOUNT = 526 + SYS_NTP_ADJTIME = 527 + SYS_NTP_GETTIME = 528 + SYS_OS_FAULT_WITH_PAYLOAD = 529 + SYS_MAXSYSCALL = 530 SYS_INVALID = 63 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go index 075816c34..969463023 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go @@ -1,4 +1,4 @@ -// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk/usr/include/sys/syscall.h +// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.1.sdk/usr/include/sys/syscall.h // Code generated by the command above; see README.md. DO NOT EDIT. // +build arm64,darwin @@ -129,6 +129,7 @@ const ( SYS_SETEGID = 182 SYS_SETEUID = 183 SYS_SIGRETURN = 184 + SYS_THREAD_SELFCOUNTS = 186 SYS_FDATASYNC = 187 SYS_STAT = 188 SYS_FSTAT = 189 @@ -288,6 +289,7 @@ const ( SYS_THREAD_SELFID = 372 SYS_LEDGER = 373 SYS_KEVENT_QOS = 374 + SYS_KEVENT_ID = 375 SYS___MAC_EXECVE = 380 SYS___MAC_SYSCALL = 381 SYS___MAC_GET_FILE = 382 @@ -421,6 +423,14 @@ const ( SYS_FS_SNAPSHOT = 518 SYS_TERMINATE_WITH_PAYLOAD = 520 SYS_ABORT_WITH_PAYLOAD = 521 - SYS_MAXSYSCALL = 522 + SYS_NECP_SESSION_OPEN = 522 + SYS_NECP_SESSION_ACTION = 523 + SYS_SETATTRLISTAT = 524 + SYS_NET_QOS_GUIDELINE = 525 + SYS_FMOUNT = 526 + SYS_NTP_ADJTIME = 527 + SYS_NTP_GETTIME = 528 + SYS_OS_FAULT_WITH_PAYLOAD = 529 + SYS_MAXSYSCALL = 530 SYS_INVALID = 63 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index cef4fed02..95ab12903 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -385,4 +385,6 @@ const ( SYS_PKEY_MPROTECT = 380 SYS_PKEY_ALLOC = 381 SYS_PKEY_FREE = 382 + SYS_STATX = 383 + SYS_ARCH_PRCTL = 384 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 49bfa1270..c5dabf2e4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -338,4 +338,5 @@ const ( SYS_PKEY_MPROTECT = 329 SYS_PKEY_ALLOC = 330 SYS_PKEY_FREE = 331 + SYS_STATX = 332 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 97b182ef5..ab7fa5fd3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -358,4 +358,5 @@ const ( SYS_PKEY_MPROTECT = 394 SYS_PKEY_ALLOC = 395 SYS_PKEY_FREE = 396 + SYS_STATX = 397 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 640784357..b1c6b4bd3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -282,4 +282,5 @@ const ( SYS_PKEY_MPROTECT = 288 SYS_PKEY_ALLOC = 289 SYS_PKEY_FREE = 290 + SYS_STATX = 291 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 939567c09..2e9aa7a3e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -371,4 +371,5 @@ const ( SYS_PKEY_MPROTECT = 4363 SYS_PKEY_ALLOC = 4364 SYS_PKEY_FREE = 4365 + SYS_STATX = 4366 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 09db95969..92827635a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -331,4 +331,5 @@ const ( SYS_PKEY_MPROTECT = 5323 SYS_PKEY_ALLOC = 5324 SYS_PKEY_FREE = 5325 + SYS_STATX = 5326 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index d1b872a09..45bd3fd6c 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -331,4 +331,5 @@ const ( SYS_PKEY_MPROTECT = 5323 SYS_PKEY_ALLOC = 5324 SYS_PKEY_FREE = 5325 + SYS_STATX = 5326 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 82ba20f28..62ccac4b7 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -371,4 +371,5 @@ const ( SYS_PKEY_MPROTECT = 4363 SYS_PKEY_ALLOC = 4364 SYS_PKEY_FREE = 4365 + SYS_STATX = 4366 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index 8944448ae..dfe5dab67 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -366,4 +366,5 @@ const ( SYS_PREADV2 = 380 SYS_PWRITEV2 = 381 SYS_KEXEC_FILE_LOAD = 382 + SYS_STATX = 383 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 90a039be4..eca97f738 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -366,4 +366,5 @@ const ( SYS_PREADV2 = 380 SYS_PWRITEV2 = 381 SYS_KEXEC_FILE_LOAD = 382 + SYS_STATX = 383 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index aab0cdb18..8bf50c8d4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -306,6 +306,9 @@ const ( SYS_COPY_FILE_RANGE = 375 SYS_PREADV2 = 376 SYS_PWRITEV2 = 377 + SYS_S390_GUARDED_STORAGE = 378 + SYS_STATX = 379 + SYS_S390_STHYI = 380 SYS_SELECT = 142 SYS_GETRLIMIT = 191 SYS_LCHOWN = 198 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go index f60d8f988..8afda9c45 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go @@ -134,6 +134,7 @@ const ( SYS_MINHERIT = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); } SYS_LCHMOD = 274 // { int|sys||lchmod(const char *path, mode_t mode); } SYS_LCHOWN = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); } + SYS_MSYNC = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); } SYS___POSIX_CHOWN = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); } SYS___POSIX_FCHOWN = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); } SYS___POSIX_LCHOWN = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go index 48a91d464..aea8dbec4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go @@ -134,6 +134,7 @@ const ( SYS_MINHERIT = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); } SYS_LCHMOD = 274 // { int|sys||lchmod(const char *path, mode_t mode); } SYS_LCHOWN = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); } + SYS_MSYNC = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); } SYS___POSIX_CHOWN = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); } SYS___POSIX_FCHOWN = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); } SYS___POSIX_LCHOWN = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go index 612ba662c..c6158a7ef 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go @@ -134,6 +134,7 @@ const ( SYS_MINHERIT = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); } SYS_LCHMOD = 274 // { int|sys||lchmod(const char *path, mode_t mode); } SYS_LCHOWN = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); } + SYS_MSYNC = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); } SYS___POSIX_CHOWN = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); } SYS___POSIX_FCHOWN = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); } SYS___POSIX_LCHOWN = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go deleted file mode 100644 index c70865985..000000000 --- a/vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build amd64,solaris - -package unix - -// TODO(aram): remove these before Go 1.3. -const ( - SYS_EXECVE = 59 - SYS_FCNTL = 62 -) diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go index e61d78a54..327af5fba 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go @@ -136,13 +136,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -295,14 +295,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -338,51 +338,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -430,11 +430,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { @@ -460,3 +460,30 @@ const ( AT_SYMLINK_FOLLOW = 0x40 AT_SYMLINK_NOFOLLOW = 0x20 ) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 2619155ff..116e6e075 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -26,9 +26,9 @@ type Timespec struct { } type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte + Sec int64 + Usec int32 + _ [4]byte } type Timeval32 struct { @@ -70,7 +70,7 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev int32 - Pad_cgo_0 [4]byte + _ [4]byte Atimespec Timespec Mtimespec Timespec Ctimespec Timespec @@ -120,9 +120,9 @@ type Fstore_t struct { } type Radvisory_t struct { - Offset int64 - Count int32 - Pad_cgo_0 [4]byte + Offset int64 + Count int32 + _ [4]byte } type Fbootstraptransfer_t struct { @@ -132,9 +132,9 @@ type Fbootstraptransfer_t struct { } type Log2phys_t struct { - Flags uint32 - Pad_cgo_0 [8]byte - Pad_cgo_1 [8]byte + Flags uint32 + _ [8]byte + _ [8]byte } type Fsid struct { @@ -142,13 +142,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -221,10 +221,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -303,14 +303,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -346,51 +346,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -426,9 +426,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -439,22 +439,22 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval32 - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval32 + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { - Iflag uint64 - Oflag uint64 - Cflag uint64 - Lflag uint64 - Cc [20]uint8 - Pad_cgo_0 [4]byte - Ispeed uint64 - Ospeed uint64 + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]uint8 + _ [4]byte + Ispeed uint64 + Ospeed uint64 } type Winsize struct { @@ -470,3 +470,30 @@ const ( AT_SYMLINK_FOLLOW = 0x40 AT_SYMLINK_NOFOLLOW = 0x20 ) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go index 4dca0d4db..2750ad760 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go @@ -137,13 +137,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -296,14 +296,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -339,51 +339,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -431,11 +431,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { @@ -461,3 +461,30 @@ const ( AT_SYMLINK_FOLLOW = 0x40 AT_SYMLINK_NOFOLLOW = 0x20 ) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index f2881fd14..8cead0996 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -1,6 +1,7 @@ +// cgo -godefs types_darwin.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + // +build arm64,darwin -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_darwin.go package unix @@ -25,9 +26,9 @@ type Timespec struct { } type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte + Sec int64 + Usec int32 + _ [4]byte } type Timeval32 struct { @@ -69,7 +70,7 @@ type Stat_t struct { Uid uint32 Gid uint32 Rdev int32 - Pad_cgo_0 [4]byte + _ [4]byte Atimespec Timespec Mtimespec Timespec Ctimespec Timespec @@ -119,9 +120,9 @@ type Fstore_t struct { } type Radvisory_t struct { - Offset int64 - Count int32 - Pad_cgo_0 [4]byte + Offset int64 + Count int32 + _ [4]byte } type Fbootstraptransfer_t struct { @@ -131,9 +132,9 @@ type Fbootstraptransfer_t struct { } type Log2phys_t struct { - Flags uint32 - Pad_cgo_0 [8]byte - Pad_cgo_1 [8]byte + Flags uint32 + _ [8]byte + _ [8]byte } type Fsid struct { @@ -141,13 +142,13 @@ type Fsid struct { } type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte + Ino uint64 + Seekoff uint64 + Reclen uint16 + Namlen uint16 + Type uint8 + Name [1024]int8 + _ [3]byte } type RawSockaddrInet4 struct { @@ -220,10 +221,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -302,14 +303,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -345,51 +346,51 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfmaMsghdr2 struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Refcount int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Refcount int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -425,9 +426,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -438,22 +439,22 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval32 - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp Timeval32 + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { - Iflag uint64 - Oflag uint64 - Cflag uint64 - Lflag uint64 - Cc [20]uint8 - Pad_cgo_0 [4]byte - Ispeed uint64 - Ospeed uint64 + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]uint8 + _ [4]byte + Ispeed uint64 + Ospeed uint64 } type Winsize struct { @@ -469,3 +470,30 @@ const ( AT_SYMLINK_FOLLOW = 0x40 AT_SYMLINK_NOFOLLOW = 0x20 ) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go index e585c893a..315a553bd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go @@ -108,7 +108,7 @@ type Statfs_t struct { Owner uint32 Type int32 Flags int32 - Pad_cgo_0 [4]byte + _ [4]byte Syncwrites int64 Asyncwrites int64 Fstypename [16]int8 @@ -118,7 +118,7 @@ type Statfs_t struct { Spares1 int16 Mntfromname [80]int8 Spares2 int16 - Pad_cgo_1 [4]byte + _ [4]byte Spare [2]int64 } @@ -143,6 +143,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -215,10 +219,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -290,14 +294,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -307,7 +311,7 @@ type IfData struct { Hdrlen uint8 Recvquota uint8 Xmitquota uint8 - Pad_cgo_0 [2]byte + _ [2]byte Mtu uint64 Metric uint64 Link_state uint64 @@ -329,24 +333,24 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfAnnounceMsghdr struct { @@ -359,19 +363,19 @@ type IfAnnounceMsghdr struct { } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint64 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint64 + Rmx RtMetrics } type RtMetrics struct { @@ -387,7 +391,7 @@ type RtMetrics struct { Hopcount uint64 Mssopt uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Msl uint64 Iwmaxsegs uint64 Iwcapsegs uint64 @@ -412,9 +416,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -425,11 +429,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [6]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [6]byte } type Termios struct { @@ -441,3 +445,42 @@ type Termios struct { Ispeed uint32 Ospeed uint32 } + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = 0xfffafdcd + AT_SYMLINK_NOFOLLOW = 0x1 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [32]byte + Nodename [32]byte + Release [32]byte + Version [32]byte + Machine [32]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index 5b28bcbba..878a21ad6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -140,6 +140,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + const ( FADV_NORMAL = 0x0 FADV_RANDOM = 0x1 @@ -516,6 +520,34 @@ const ( AT_SYMLINK_NOFOLLOW = 0x200 ) +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLINIGNEOF = 0x2000 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + type CapRights struct { Rights [2]uint64 } + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index c65d89e49..8408af125 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -140,6 +140,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + const ( FADV_NORMAL = 0x0 FADV_RANDOM = 0x1 @@ -519,6 +523,34 @@ const ( AT_SYMLINK_NOFOLLOW = 0x200 ) +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLINIGNEOF = 0x2000 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + type CapRights struct { Rights [2]uint64 } + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 42c0a502c..4b2d9a483 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -142,6 +142,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + const ( FADV_NORMAL = 0x0 FADV_RANDOM = 0x1 @@ -519,6 +523,34 @@ const ( AT_SYMLINK_NOFOLLOW = 0x200 ) +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLINIGNEOF = 0x2000 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + type CapRights struct { Rights [2]uint64 } + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 0dcebb50b..f9a99358a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -98,7 +98,7 @@ type _Gid_t uint32 type Stat_t struct { Dev uint64 X__pad1 uint16 - Pad_cgo_0 [2]byte + _ [2]byte X__st_ino uint32 Mode uint32 Nlink uint32 @@ -106,7 +106,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 X__pad2 uint16 - Pad_cgo_1 [2]byte + _ [2]byte Size int64 Blksize int32 Blocks int64 @@ -131,13 +131,43 @@ type Statfs_t struct { Spare [4]int32 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [1]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [1]byte } type Fsid struct { @@ -224,11 +254,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -341,7 +380,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -376,6 +415,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -396,97 +436,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -565,9 +631,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -621,12 +687,12 @@ type Sysinfo_t struct { } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { @@ -643,8 +709,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -673,8 +746,6 @@ const RNDGETENTCNT = 0x80045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -692,3 +763,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint32 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x20 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index d70e54348..4df7088d4 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -131,13 +131,43 @@ type Statfs_t struct { Spare [4]int64 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { @@ -145,13 +175,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -226,11 +256,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -297,13 +336,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -345,7 +384,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -380,6 +419,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -400,97 +440,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -569,9 +635,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -628,30 +694,30 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 X_f [0]int8 - Pad_cgo_1 [4]byte + _ [4]byte } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -661,8 +727,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -691,8 +764,6 @@ const RNDGETENTCNT = 0x80045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -710,3 +781,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index 497f56319..a181469ca 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -98,7 +98,7 @@ type _Gid_t uint32 type Stat_t struct { Dev uint64 X__pad1 uint16 - Pad_cgo_0 [2]byte + _ [2]byte X__st_ino uint32 Mode uint32 Nlink uint32 @@ -106,10 +106,10 @@ type Stat_t struct { Gid uint32 Rdev uint64 X__pad2 uint16 - Pad_cgo_1 [6]byte + _ [6]byte Size int64 Blksize int32 - Pad_cgo_2 [4]byte + _ [4]byte Blocks int64 Atim Timespec Mtim Timespec @@ -118,28 +118,58 @@ type Stat_t struct { } type Statfs_t struct { - Type int32 - Bsize int32 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid Fsid - Namelen int32 - Frsize int32 - Flags int32 - Spare [4]int32 - Pad_cgo_0 [4]byte + Type int32 + Bsize int32 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Namelen int32 + Frsize int32 + Flags int32 + Spare [4]int32 + _ [4]byte +} + +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]uint8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte } type Fsid struct { @@ -147,13 +177,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -228,11 +258,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -345,7 +384,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -380,6 +419,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -400,97 +440,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -569,9 +635,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -609,12 +675,12 @@ type Sysinfo_t struct { } type Utsname struct { - Sysname [65]uint8 - Nodename [65]uint8 - Release [65]uint8 - Version [65]uint8 - Machine [65]uint8 - Domainname [65]uint8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { @@ -632,8 +698,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -662,8 +735,6 @@ const RNDGETENTCNT = 0x80045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -681,3 +752,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]uint8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint32 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x20 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index f0bdaede6..cff50c3d3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -132,13 +132,43 @@ type Statfs_t struct { Spare [4]int64 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { @@ -146,13 +176,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -227,11 +257,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -298,13 +337,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -346,7 +385,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -381,6 +420,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -401,97 +441,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -570,9 +636,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -606,30 +672,30 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 X_f [0]int8 - Pad_cgo_1 [4]byte + _ [4]byte } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -640,8 +706,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -670,8 +743,6 @@ const RNDGETENTCNT = 0x80045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -689,3 +760,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 850a68cb2..87d0a8b1b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -116,29 +116,59 @@ type Stat_t struct { } type Statfs_t struct { - Type int32 - Bsize int32 - Frsize int32 - Pad_cgo_0 [4]byte - Blocks uint64 - Bfree uint64 - Files uint64 - Ffree uint64 - Bavail uint64 - Fsid Fsid - Namelen int32 - Flags int32 - Spare [5]int32 - Pad_cgo_1 [4]byte + Type int32 + Bsize int32 + Frsize int32 + _ [4]byte + Blocks uint64 + Bfree uint64 + Files uint64 + Ffree uint64 + Bavail uint64 + Fsid Fsid + Namelen int32 + Flags int32 + Spare [5]int32 + _ [4]byte +} + +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { @@ -146,13 +176,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -227,11 +257,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -344,7 +383,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -379,6 +418,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -399,97 +439,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -568,9 +634,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -614,12 +680,12 @@ type Sysinfo_t struct { } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { @@ -637,8 +703,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -667,8 +740,6 @@ const RNDGETENTCNT = 0x40045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -686,3 +757,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint32 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x20 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 92aac5d93..cf4e2bd29 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -132,13 +132,43 @@ type Statfs_t struct { Spare [5]int64 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { @@ -146,13 +176,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -227,11 +257,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -298,13 +337,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -346,7 +385,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -381,6 +420,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -401,97 +441,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -570,9 +636,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -609,30 +675,30 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 X_f [0]int8 - Pad_cgo_1 [4]byte + _ [4]byte } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -642,8 +708,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -672,8 +745,6 @@ const RNDGETENTCNT = 0x40045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -691,3 +762,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index 623f58127..b8da482ca 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -132,13 +132,43 @@ type Statfs_t struct { Spare [5]int64 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { @@ -146,13 +176,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -227,11 +257,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -298,13 +337,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -346,7 +385,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -381,6 +420,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -401,97 +441,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -570,9 +636,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -609,30 +675,30 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 X_f [0]int8 - Pad_cgo_1 [4]byte + _ [4]byte } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } type EpollEvent struct { @@ -642,8 +708,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -672,8 +745,6 @@ const RNDGETENTCNT = 0x40045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -691,3 +762,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 56598a1bf..7106b512d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -52,7 +52,7 @@ type Timex struct { Errcnt int32 Stbcnt int32 Tai int32 - Pad_cgo_0 [44]byte + _ [44]byte } type Time_t int32 @@ -116,29 +116,59 @@ type Stat_t struct { } type Statfs_t struct { - Type int32 - Bsize int32 - Frsize int32 - Pad_cgo_0 [4]byte - Blocks uint64 - Bfree uint64 - Files uint64 - Ffree uint64 - Bavail uint64 - Fsid Fsid - Namelen int32 - Flags int32 - Spare [5]int32 - Pad_cgo_1 [4]byte + Type int32 + Bsize int32 + Frsize int32 + _ [4]byte + Blocks uint64 + Bfree uint64 + Files uint64 + Ffree uint64 + Bavail uint64 + Fsid Fsid + Namelen int32 + Flags int32 + Spare [5]int32 + _ [4]byte +} + +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]int8 + _ [5]byte } type Fsid struct { @@ -146,13 +176,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -227,11 +257,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -344,7 +383,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -379,6 +418,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -399,97 +439,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -568,9 +634,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [2]byte - Filter *SockFilter + Len uint16 + _ [2]byte + Filter *SockFilter } type InotifyEvent struct { @@ -614,12 +680,12 @@ type Sysinfo_t struct { } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { @@ -637,8 +703,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -667,8 +740,6 @@ const RNDGETENTCNT = 0x40045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -686,3 +757,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint32 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x20 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index acc7c819d..319071c8b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -133,13 +133,43 @@ type Statfs_t struct { Spare [4]int64 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]uint8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte } type Fsid struct { @@ -147,13 +177,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -228,11 +258,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -299,13 +338,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -347,7 +386,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -382,6 +421,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -402,97 +442,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -571,9 +637,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -616,30 +682,30 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 X_f [0]uint8 - Pad_cgo_1 [4]byte + _ [4]byte } type Utsname struct { - Sysname [65]uint8 - Nodename [65]uint8 - Release [65]uint8 - Version [65]uint8 - Machine [65]uint8 - Domainname [65]uint8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]uint8 - Fpack [6]uint8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]uint8 + Fpack [6]uint8 + _ [4]byte } type EpollEvent struct { @@ -650,8 +716,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -680,8 +753,6 @@ const RNDGETENTCNT = 0x40045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -699,3 +770,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]uint8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index b348885c8..ef00ed498 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -33,13 +33,13 @@ type Timeval struct { type Timex struct { Modes uint32 - Pad_cgo_0 [4]byte + _ [4]byte Offset int64 Freq int64 Maxerror int64 Esterror int64 Status int32 - Pad_cgo_1 [4]byte + _ [4]byte Constant int64 Precision int64 Tolerance int64 @@ -48,14 +48,14 @@ type Timex struct { Ppsfreq int64 Jitter int64 Shift int32 - Pad_cgo_2 [4]byte + _ [4]byte Stabil int64 Jitcnt int64 Calcnt int64 Errcnt int64 Stbcnt int64 Tai int32 - Pad_cgo_3 [44]byte + _ [44]byte } type Time_t int64 @@ -133,13 +133,43 @@ type Statfs_t struct { Spare [4]int64 } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + X__reserved int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Type uint8 - Name [256]uint8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Type uint8 + Name [256]uint8 + _ [5]byte } type Fsid struct { @@ -147,13 +177,13 @@ type Fsid struct { } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Pid int32 - Pad_cgo_1 [4]byte + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Pid int32 + _ [4]byte } type FscryptPolicy struct { @@ -228,11 +258,20 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { - Family uint16 - Pad_cgo_0 [2]byte - Ifindex int32 - Addr [8]byte + Family uint16 + _ [2]byte + Ifindex int32 + Addr [8]byte } type RawSockaddrALG struct { @@ -299,13 +338,13 @@ type PacketMreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen uint64 Control *byte Controllen uint64 Flags int32 - Pad_cgo_1 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -347,7 +386,7 @@ type TCPInfo struct { Probes uint8 Backoff uint8 Options uint8 - Pad_cgo_0 [2]byte + _ [2]byte Rto uint32 Ato uint32 Snd_mss uint32 @@ -382,6 +421,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -402,97 +442,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -571,9 +637,9 @@ type SockFilter struct { } type SockFprog struct { - Len uint16 - Pad_cgo_0 [6]byte - Filter *SockFilter + Len uint16 + _ [6]byte + Filter *SockFilter } type InotifyEvent struct { @@ -616,30 +682,30 @@ type Sysinfo_t struct { Freeswap uint64 Procs uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Totalhigh uint64 Freehigh uint64 Unit uint32 X_f [0]uint8 - Pad_cgo_1 [4]byte + _ [4]byte } type Utsname struct { - Sysname [65]uint8 - Nodename [65]uint8 - Release [65]uint8 - Version [65]uint8 - Machine [65]uint8 - Domainname [65]uint8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { - Tfree int32 - Pad_cgo_0 [4]byte - Tinode uint64 - Fname [6]uint8 - Fpack [6]uint8 - Pad_cgo_1 [4]byte + Tfree int32 + _ [4]byte + Tinode uint64 + Fname [6]uint8 + Fpack [6]uint8 + _ [4]byte } type EpollEvent struct { @@ -650,8 +716,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -680,8 +753,6 @@ const RNDGETENTCNT = 0x40045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -699,3 +770,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]uint8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index a706e2f8c..e9ee49706 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -132,6 +132,36 @@ type Statfs_t struct { _ [4]byte } +type StatxTimestamp struct { + Sec int64 + Nsec uint32 + _ int32 +} + +type Statx_t struct { + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + _ [14]uint64 +} + type Dirent struct { Ino uint64 Off int64 @@ -227,6 +257,15 @@ type RawSockaddrHCI struct { Channel uint16 } +type RawSockaddrL2 struct { + Family uint16 + Psm uint16 + Bdaddr [6]uint8 + Cid uint16 + Bdaddr_type uint8 + _ [1]byte +} + type RawSockaddrCAN struct { Family uint16 _ [2]byte @@ -381,6 +420,7 @@ const ( SizeofSockaddrLinklayer = 0x14 SizeofSockaddrNetlink = 0xc SizeofSockaddrHCI = 0x6 + SizeofSockaddrL2 = 0xe SizeofSockaddrCAN = 0x10 SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 @@ -401,97 +441,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2b - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -642,12 +708,12 @@ type Sysinfo_t struct { } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { @@ -667,8 +733,15 @@ type EpollEvent struct { } const ( - AT_FDCWD = -0x64 - AT_REMOVEDIR = 0x200 + AT_EMPTY_PATH = 0x1000 + AT_FDCWD = -0x64 + AT_NO_AUTOMOUNT = 0x800 + AT_REMOVEDIR = 0x200 + + AT_STATX_SYNC_AS_STAT = 0x0 + AT_STATX_FORCE_SYNC = 0x2000 + AT_STATX_DONT_SYNC = 0x4000 + AT_SYMLINK_FOLLOW = 0x400 AT_SYMLINK_NOFOLLOW = 0x100 ) @@ -697,8 +770,6 @@ const RNDGETENTCNT = 0x80045200 const PERF_IOC_FLAG_GROUP = 0x1 -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 @@ -716,3 +787,135 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type Taskstats struct { + Version uint16 + _ [2]byte + Ac_exitcode uint32 + Ac_flag uint8 + Ac_nice uint8 + _ [6]byte + Cpu_count uint64 + Cpu_delay_total uint64 + Blkio_count uint64 + Blkio_delay_total uint64 + Swapin_count uint64 + Swapin_delay_total uint64 + Cpu_run_real_total uint64 + Cpu_run_virtual_total uint64 + Ac_comm [32]int8 + Ac_sched uint8 + Ac_pad [3]uint8 + _ [4]byte + Ac_uid uint32 + Ac_gid uint32 + Ac_pid uint32 + Ac_ppid uint32 + Ac_btime uint32 + _ [4]byte + Ac_etime uint64 + Ac_utime uint64 + Ac_stime uint64 + Ac_minflt uint64 + Ac_majflt uint64 + Coremem uint64 + Virtmem uint64 + Hiwater_rss uint64 + Hiwater_vm uint64 + Read_char uint64 + Write_char uint64 + Read_syscalls uint64 + Write_syscalls uint64 + Read_bytes uint64 + Write_bytes uint64 + Cancelled_write_bytes uint64 + Nvcsw uint64 + Nivcsw uint64 + Ac_utimescaled uint64 + Ac_stimescaled uint64 + Cpu_scaled_run_real_total uint64 + Freepages_count uint64 + Freepages_delay_total uint64 +} + +const ( + TASKSTATS_CMD_UNSPEC = 0x0 + TASKSTATS_CMD_GET = 0x1 + TASKSTATS_CMD_NEW = 0x2 + TASKSTATS_TYPE_UNSPEC = 0x0 + TASKSTATS_TYPE_PID = 0x1 + TASKSTATS_TYPE_TGID = 0x2 + TASKSTATS_TYPE_STATS = 0x3 + TASKSTATS_TYPE_AGGR_PID = 0x4 + TASKSTATS_TYPE_AGGR_TGID = 0x5 + TASKSTATS_TYPE_NULL = 0x6 + TASKSTATS_CMD_ATTR_UNSPEC = 0x0 + TASKSTATS_CMD_ATTR_PID = 0x1 + TASKSTATS_CMD_ATTR_TGID = 0x2 + TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 + TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 +) + +type CGroupStats struct { + Sleeping uint64 + Running uint64 + Stopped uint64 + Uninterruptible uint64 + Io_wait uint64 +} + +const ( + CGROUPSTATS_CMD_UNSPEC = 0x3 + CGROUPSTATS_CMD_GET = 0x4 + CGROUPSTATS_CMD_NEW = 0x5 + CGROUPSTATS_TYPE_UNSPEC = 0x0 + CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 + CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 + CGROUPSTATS_CMD_ATTR_FD = 0x1 +) + +type Genlmsghdr struct { + Cmd uint8 + Version uint8 + Reserved uint16 +} + +const ( + CTRL_CMD_UNSPEC = 0x0 + CTRL_CMD_NEWFAMILY = 0x1 + CTRL_CMD_DELFAMILY = 0x2 + CTRL_CMD_GETFAMILY = 0x3 + CTRL_CMD_NEWOPS = 0x4 + CTRL_CMD_DELOPS = 0x5 + CTRL_CMD_GETOPS = 0x6 + CTRL_CMD_NEWMCAST_GRP = 0x7 + CTRL_CMD_DELMCAST_GRP = 0x8 + CTRL_CMD_GETMCAST_GRP = 0x9 + CTRL_ATTR_UNSPEC = 0x0 + CTRL_ATTR_FAMILY_ID = 0x1 + CTRL_ATTR_FAMILY_NAME = 0x2 + CTRL_ATTR_VERSION = 0x3 + CTRL_ATTR_HDRSIZE = 0x4 + CTRL_ATTR_MAXATTR = 0x5 + CTRL_ATTR_OPS = 0x6 + CTRL_ATTR_MCAST_GROUPS = 0x7 + CTRL_ATTR_OP_UNSPEC = 0x0 + CTRL_ATTR_OP_ID = 0x1 + CTRL_ATTR_OP_FLAGS = 0x2 + CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 + CTRL_ATTR_MCAST_GRP_NAME = 0x1 + CTRL_ATTR_MCAST_GRP_ID = 0x2 +) + +type cpuMask uint64 + +const ( + _CPU_SETSIZE = 0x400 + _NCPUBITS = 0x40 +) + +const ( + BDADDR_BREDR = 0x0 + BDADDR_LE_PUBLIC = 0x1 + BDADDR_LE_RANDOM = 0x2 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 22bdab961..8e7384b89 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -376,97 +376,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2a - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { @@ -601,12 +627,12 @@ type Sysinfo_t struct { } type Utsname struct { - Sysname [65]int8 - Nodename [65]int8 - Release [65]int8 - Version [65]int8 - Machine [65]int8 - Domainname [65]int8 + Sysname [65]byte + Nodename [65]byte + Release [65]byte + Version [65]byte + Machine [65]byte + Domainname [65]byte } type Ustat_t struct { @@ -652,8 +678,6 @@ type Sigset_t struct { X__val [16]uint64 } -const _SC_PAGESIZE = 0x1e - type Termios struct { Iflag uint32 Oflag uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go index caf755fb8..4b86fb2b3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go @@ -1,5 +1,5 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_netbsd.go +// cgo -godefs types_netbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,netbsd @@ -99,6 +99,19 @@ type Fsid struct { X__fsid_val [2]int32 } +const ( + PathMax = 0x400 +) + +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -382,6 +395,37 @@ type Termios struct { Ospeed int32 } +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x200 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + type Sysctlnode struct { Flags uint32 Num int32 @@ -394,3 +438,11 @@ type Sysctlnode struct { X_sysctl_parent [8]byte X_sysctl_desc [8]byte } + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go index 91b4a5305..9048a509d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go @@ -1,5 +1,5 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_netbsd.go +// cgo -godefs types_netbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,netbsd @@ -103,6 +103,19 @@ type Fsid struct { X__fsid_val [2]int32 } +const ( + PathMax = 0x400 +) + +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -389,6 +402,37 @@ type Termios struct { Ospeed int32 } +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x200 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + type Sysctlnode struct { Flags uint32 Num int32 @@ -401,3 +445,11 @@ type Sysctlnode struct { X_sysctl_parent [8]byte X_sysctl_desc [8]byte } + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index c0758f9d3..00525e7b0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -1,5 +1,5 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_netbsd.go +// cgo -godefs types_netbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,netbsd @@ -104,6 +104,19 @@ type Fsid struct { X__fsid_val [2]int32 } +const ( + PathMax = 0x400 +) + +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -387,6 +400,37 @@ type Termios struct { Ospeed int32 } +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x200 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + type Sysctlnode struct { Flags uint32 Num int32 @@ -399,3 +443,11 @@ type Sysctlnode struct { X_sysctl_parent [8]byte X_sysctl_desc [8]byte } + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go index 860a46979..d5a2d75da 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go @@ -1,5 +1,5 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go +// cgo -godefs types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build 386,openbsd @@ -140,6 +140,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -439,3 +443,42 @@ type Termios struct { Ispeed int32 Ospeed int32 } + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x2 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go index 23c52727f..d53141085 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go @@ -1,5 +1,5 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go +// cgo -godefs types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build amd64,openbsd @@ -142,6 +142,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -446,3 +450,42 @@ type Termios struct { Ispeed int32 Ospeed int32 } + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x2 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go index f960f6c0d..e35b13b6f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go @@ -1,5 +1,5 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go +// cgo -godefs types_openbsd.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. // +build arm,openbsd @@ -140,6 +140,10 @@ type Fsid struct { Val [2]int32 } +const ( + PathMax = 0x400 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 @@ -432,3 +436,42 @@ type Termios struct { Ispeed int32 Ospeed int32 } + +type Winsize struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +const ( + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x2 +) + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) + +type Utsname struct { + Sysname [256]byte + Nodename [256]byte + Release [256]byte + Version [256]byte + Machine [256]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index 92336f9f9..2248598d0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -93,40 +93,40 @@ const ( ) type Stat_t struct { - Dev uint64 - Ino uint64 - Mode uint32 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev uint64 - Size int64 - Atim Timespec - Mtim Timespec - Ctim Timespec - Blksize int32 - Pad_cgo_0 [4]byte - Blocks int64 - Fstype [16]int8 + Dev uint64 + Ino uint64 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint64 + Size int64 + Atim Timespec + Mtim Timespec + Ctim Timespec + Blksize int32 + _ [4]byte + Blocks int64 + Fstype [16]int8 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Sysid int32 - Pid int32 - Pad [4]int64 + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Sysid int32 + Pid int32 + Pad [4]int64 } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Name [1]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Name [1]int8 + _ [5]byte } type _Fsblkcnt_t uint64 @@ -213,13 +213,13 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Accrights *int8 Accrightslen int32 - Pad_cgo_2 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -263,19 +263,19 @@ type FdSet struct { } type Utsname struct { - Sysname [257]int8 - Nodename [257]int8 - Release [257]int8 - Version [257]int8 - Machine [257]int8 + Sysname [257]byte + Nodename [257]byte + Release [257]byte + Version [257]byte + Machine [257]byte } type Ustat_t struct { - Tfree int64 - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_0 [4]byte + Tfree int64 + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } const ( @@ -295,21 +295,21 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { Type uint8 Addrlen uint8 Hdrlen uint8 - Pad_cgo_0 [1]byte + _ [1]byte Mtu uint32 Metric uint32 Baudrate uint32 @@ -328,30 +328,30 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -388,9 +388,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -406,32 +406,30 @@ type BpfTimeval struct { } type BpfHdr struct { - Tstamp BpfTimeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } -const _SC_PAGESIZE = 0xb - type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [19]uint8 - Pad_cgo_0 [1]byte + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [19]uint8 + _ [1]byte } type Termio struct { - Iflag uint16 - Oflag uint16 - Cflag uint16 - Lflag uint16 - Line int8 - Cc [8]uint8 - Pad_cgo_0 [1]byte + Iflag uint16 + Oflag uint16 + Cflag uint16 + Lflag uint16 + Line int8 + Cc [8]uint8 + _ [1]byte } type Winsize struct { @@ -440,3 +438,22 @@ type Winsize struct { Xpixel uint16 Ypixel uint16 } + +type PollFd struct { + Fd int32 + Events int16 + Revents int16 +} + +const ( + POLLERR = 0x8 + POLLHUP = 0x10 + POLLIN = 0x1 + POLLNVAL = 0x20 + POLLOUT = 0x4 + POLLPRI = 0x2 + POLLRDBAND = 0x80 + POLLRDNORM = 0x40 + POLLWRBAND = 0x100 + POLLWRNORM = 0x4 +) diff --git a/vendor/golang.org/x/sys/windows/asm_windows_386.s b/vendor/golang.org/x/sys/windows/asm_windows_386.s new file mode 100644 index 000000000..1c20dd2f8 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/asm_windows_386.s @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +// System calls for 386, Windows are implemented in runtime/syscall_windows.goc +// + +TEXT ·getprocaddress(SB), 7, $0-8 + JMP syscall·getprocaddress(SB) + +TEXT ·loadlibrary(SB), 7, $0-4 + JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/asm_windows_amd64.s b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s new file mode 100644 index 000000000..4d025ab55 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/asm_windows_amd64.s @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +// System calls for amd64, Windows are implemented in runtime/syscall_windows.goc +// + +TEXT ·getprocaddress(SB), 7, $0-32 + JMP syscall·getprocaddress(SB) + +TEXT ·loadlibrary(SB), 7, $0-8 + JMP syscall·loadlibrary(SB) diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go new file mode 100644 index 000000000..e92c05b21 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -0,0 +1,378 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "sync" + "sync/atomic" + "syscall" + "unsafe" +) + +// DLLError describes reasons for DLL load failures. +type DLLError struct { + Err error + ObjName string + Msg string +} + +func (e *DLLError) Error() string { return e.Msg } + +// Implemented in runtime/syscall_windows.goc; we provide jumps to them in our assembly file. +func loadlibrary(filename *uint16) (handle uintptr, err syscall.Errno) +func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err syscall.Errno) + +// A DLL implements access to a single DLL. +type DLL struct { + Name string + Handle Handle +} + +// LoadDLL loads DLL file into memory. +// +// Warning: using LoadDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use LazyDLL +// with System set to true, or use LoadLibraryEx directly. +func LoadDLL(name string) (dll *DLL, err error) { + namep, err := UTF16PtrFromString(name) + if err != nil { + return nil, err + } + h, e := loadlibrary(namep) + if e != 0 { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to load " + name + ": " + e.Error(), + } + } + d := &DLL{ + Name: name, + Handle: Handle(h), + } + return d, nil +} + +// MustLoadDLL is like LoadDLL but panics if load operation failes. +func MustLoadDLL(name string) *DLL { + d, e := LoadDLL(name) + if e != nil { + panic(e) + } + return d +} + +// FindProc searches DLL d for procedure named name and returns *Proc +// if found. It returns an error if search fails. +func (d *DLL) FindProc(name string) (proc *Proc, err error) { + namep, err := BytePtrFromString(name) + if err != nil { + return nil, err + } + a, e := getprocaddress(uintptr(d.Handle), namep) + if e != 0 { + return nil, &DLLError{ + Err: e, + ObjName: name, + Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(), + } + } + p := &Proc{ + Dll: d, + Name: name, + addr: a, + } + return p, nil +} + +// MustFindProc is like FindProc but panics if search fails. +func (d *DLL) MustFindProc(name string) *Proc { + p, e := d.FindProc(name) + if e != nil { + panic(e) + } + return p +} + +// Release unloads DLL d from memory. +func (d *DLL) Release() (err error) { + return FreeLibrary(d.Handle) +} + +// A Proc implements access to a procedure inside a DLL. +type Proc struct { + Dll *DLL + Name string + addr uintptr +} + +// Addr returns the address of the procedure represented by p. +// The return value can be passed to Syscall to run the procedure. +func (p *Proc) Addr() uintptr { + return p.addr +} + +//go:uintptrescapes + +// Call executes procedure p with arguments a. It will panic, if more than 15 arguments +// are supplied. +// +// The returned error is always non-nil, constructed from the result of GetLastError. +// Callers must inspect the primary return value to decide whether an error occurred +// (according to the semantics of the specific function being called) before consulting +// the error. The error will be guaranteed to contain windows.Errno. +func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { + switch len(a) { + case 0: + return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0) + case 1: + return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0) + case 2: + return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0) + case 3: + return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2]) + case 4: + return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0) + case 5: + return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0) + case 6: + return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5]) + case 7: + return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) + case 8: + return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) + case 9: + return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) + case 10: + return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) + case 11: + return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) + case 12: + return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) + case 13: + return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) + case 14: + return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) + case 15: + return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) + default: + panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".") + } +} + +// A LazyDLL implements access to a single DLL. +// It will delay the load of the DLL until the first +// call to its Handle method or to one of its +// LazyProc's Addr method. +type LazyDLL struct { + Name string + + // System determines whether the DLL must be loaded from the + // Windows System directory, bypassing the normal DLL search + // path. + System bool + + mu sync.Mutex + dll *DLL // non nil once DLL is loaded +} + +// Load loads DLL file d.Name into memory. It returns an error if fails. +// Load will not try to load DLL, if it is already loaded into memory. +func (d *LazyDLL) Load() error { + // Non-racy version of: + // if d.dll != nil { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) != nil { + return nil + } + d.mu.Lock() + defer d.mu.Unlock() + if d.dll != nil { + return nil + } + + // kernel32.dll is special, since it's where LoadLibraryEx comes from. + // The kernel already special-cases its name, so it's always + // loaded from system32. + var dll *DLL + var err error + if d.Name == "kernel32.dll" { + dll, err = LoadDLL(d.Name) + } else { + dll, err = loadLibraryEx(d.Name, d.System) + } + if err != nil { + return err + } + + // Non-racy version of: + // d.dll = dll + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll)) + return nil +} + +// mustLoad is like Load but panics if search fails. +func (d *LazyDLL) mustLoad() { + e := d.Load() + if e != nil { + panic(e) + } +} + +// Handle returns d's module handle. +func (d *LazyDLL) Handle() uintptr { + d.mustLoad() + return uintptr(d.dll.Handle) +} + +// NewProc returns a LazyProc for accessing the named procedure in the DLL d. +func (d *LazyDLL) NewProc(name string) *LazyProc { + return &LazyProc{l: d, Name: name} +} + +// NewLazyDLL creates new LazyDLL associated with DLL file. +func NewLazyDLL(name string) *LazyDLL { + return &LazyDLL{Name: name} +} + +// NewLazySystemDLL is like NewLazyDLL, but will only +// search Windows System directory for the DLL if name is +// a base name (like "advapi32.dll"). +func NewLazySystemDLL(name string) *LazyDLL { + return &LazyDLL{Name: name, System: true} +} + +// A LazyProc implements access to a procedure inside a LazyDLL. +// It delays the lookup until the Addr method is called. +type LazyProc struct { + Name string + + mu sync.Mutex + l *LazyDLL + proc *Proc +} + +// Find searches DLL for procedure named p.Name. It returns +// an error if search fails. Find will not search procedure, +// if it is already found and loaded into memory. +func (p *LazyProc) Find() error { + // Non-racy version of: + // if p.proc == nil { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil { + p.mu.Lock() + defer p.mu.Unlock() + if p.proc == nil { + e := p.l.Load() + if e != nil { + return e + } + proc, e := p.l.dll.FindProc(p.Name) + if e != nil { + return e + } + // Non-racy version of: + // p.proc = proc + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc)) + } + } + return nil +} + +// mustFind is like Find but panics if search fails. +func (p *LazyProc) mustFind() { + e := p.Find() + if e != nil { + panic(e) + } +} + +// Addr returns the address of the procedure represented by p. +// The return value can be passed to Syscall to run the procedure. +// It will panic if the procedure cannot be found. +func (p *LazyProc) Addr() uintptr { + p.mustFind() + return p.proc.Addr() +} + +//go:uintptrescapes + +// Call executes procedure p with arguments a. It will panic, if more than 15 arguments +// are supplied. It will also panic if the procedure cannot be found. +// +// The returned error is always non-nil, constructed from the result of GetLastError. +// Callers must inspect the primary return value to decide whether an error occurred +// (according to the semantics of the specific function being called) before consulting +// the error. The error will be guaranteed to contain windows.Errno. +func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { + p.mustFind() + return p.proc.Call(a...) +} + +var canDoSearchSystem32Once struct { + sync.Once + v bool +} + +func initCanDoSearchSystem32() { + // https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: + // "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows + // Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on + // systems that have KB2533623 installed. To determine whether the + // flags are available, use GetProcAddress to get the address of the + // AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories + // function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* + // flags can be used with LoadLibraryEx." + canDoSearchSystem32Once.v = (modkernel32.NewProc("AddDllDirectory").Find() == nil) +} + +func canDoSearchSystem32() bool { + canDoSearchSystem32Once.Do(initCanDoSearchSystem32) + return canDoSearchSystem32Once.v +} + +func isBaseName(name string) bool { + for _, c := range name { + if c == ':' || c == '/' || c == '\\' { + return false + } + } + return true +} + +// loadLibraryEx wraps the Windows LoadLibraryEx function. +// +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx +// +// If name is not an absolute path, LoadLibraryEx searches for the DLL +// in a variety of automatic locations unless constrained by flags. +// See: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx +func loadLibraryEx(name string, system bool) (*DLL, error) { + loadDLL := name + var flags uintptr + if system { + if canDoSearchSystem32() { + const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + flags = LOAD_LIBRARY_SEARCH_SYSTEM32 + } else if isBaseName(name) { + // WindowsXP or unpatched Windows machine + // trying to load "foo.dll" out of the system + // folder, but LoadLibraryEx doesn't support + // that yet on their system, so emulate it. + windir, _ := Getenv("WINDIR") // old var; apparently works on XP + if windir == "" { + return nil, errString("%WINDIR% not defined") + } + loadDLL = windir + "\\System32\\" + name + } + } + h, err := LoadLibraryEx(loadDLL, 0, flags) + if err != nil { + return nil, err + } + return &DLL{Name: name, Handle: h}, nil +} + +type errString string + +func (s errString) Error() string { return string(s) } diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go new file mode 100644 index 000000000..bdc71e241 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -0,0 +1,29 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Windows environment variables. + +package windows + +import "syscall" + +func Getenv(key string) (value string, found bool) { + return syscall.Getenv(key) +} + +func Setenv(key, value string) error { + return syscall.Setenv(key, value) +} + +func Clearenv() { + syscall.Clearenv() +} + +func Environ() []string { + return syscall.Environ() +} + +func Unsetenv(key string) error { + return syscall.Unsetenv(key) +} diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go new file mode 100644 index 000000000..40af946e1 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/eventlog.go @@ -0,0 +1,20 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package windows + +const ( + EVENTLOG_SUCCESS = 0 + EVENTLOG_ERROR_TYPE = 1 + EVENTLOG_WARNING_TYPE = 2 + EVENTLOG_INFORMATION_TYPE = 4 + EVENTLOG_AUDIT_SUCCESS = 8 + EVENTLOG_AUDIT_FAILURE = 16 +) + +//sys RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW +//sys DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource +//sys ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go new file mode 100644 index 000000000..3606c3a8b --- /dev/null +++ b/vendor/golang.org/x/sys/windows/exec_windows.go @@ -0,0 +1,97 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Fork, exec, wait, etc. + +package windows + +// EscapeArg rewrites command line argument s as prescribed +// in http://msdn.microsoft.com/en-us/library/ms880421. +// This function returns "" (2 double quotes) if s is empty. +// Alternatively, these transformations are done: +// - every back slash (\) is doubled, but only if immediately +// followed by double quote ("); +// - every double quote (") is escaped by back slash (\); +// - finally, s is wrapped with double quotes (arg -> "arg"), +// but only if there is space or tab inside s. +func EscapeArg(s string) string { + if len(s) == 0 { + return "\"\"" + } + n := len(s) + hasSpace := false + for i := 0; i < len(s); i++ { + switch s[i] { + case '"', '\\': + n++ + case ' ', '\t': + hasSpace = true + } + } + if hasSpace { + n += 2 + } + if n == len(s) { + return s + } + + qs := make([]byte, n) + j := 0 + if hasSpace { + qs[j] = '"' + j++ + } + slashes := 0 + for i := 0; i < len(s); i++ { + switch s[i] { + default: + slashes = 0 + qs[j] = s[i] + case '\\': + slashes++ + qs[j] = s[i] + case '"': + for ; slashes > 0; slashes-- { + qs[j] = '\\' + j++ + } + qs[j] = '\\' + j++ + qs[j] = s[i] + } + j++ + } + if hasSpace { + for ; slashes > 0; slashes-- { + qs[j] = '\\' + j++ + } + qs[j] = '"' + j++ + } + return string(qs[:j]) +} + +func CloseOnExec(fd Handle) { + SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0) +} + +// FullPath retrieves the full path of the specified file. +func FullPath(name string) (path string, err error) { + p, err := UTF16PtrFromString(name) + if err != nil { + return "", err + } + n := uint32(100) + for { + buf := make([]uint16, n) + n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil) + if err != nil { + return "", err + } + if n <= uint32(len(buf)) { + return UTF16ToString(buf[:n]), nil + } + } +} diff --git a/vendor/golang.org/x/sys/windows/memory_windows.go b/vendor/golang.org/x/sys/windows/memory_windows.go new file mode 100644 index 000000000..f80a4204f --- /dev/null +++ b/vendor/golang.org/x/sys/windows/memory_windows.go @@ -0,0 +1,26 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +const ( + MEM_COMMIT = 0x00001000 + MEM_RESERVE = 0x00002000 + MEM_DECOMMIT = 0x00004000 + MEM_RELEASE = 0x00008000 + MEM_RESET = 0x00080000 + MEM_TOP_DOWN = 0x00100000 + MEM_WRITE_WATCH = 0x00200000 + MEM_PHYSICAL = 0x00400000 + MEM_RESET_UNDO = 0x01000000 + MEM_LARGE_PAGES = 0x20000000 + + PAGE_NOACCESS = 0x01 + PAGE_READONLY = 0x02 + PAGE_READWRITE = 0x04 + PAGE_WRITECOPY = 0x08 + PAGE_EXECUTE_READ = 0x20 + PAGE_EXECUTE_READWRITE = 0x40 + PAGE_EXECUTE_WRITECOPY = 0x80 +) diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go new file mode 100644 index 000000000..fb7db0ef8 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/mksyscall.go @@ -0,0 +1,7 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go new file mode 100644 index 000000000..a74e3e24b --- /dev/null +++ b/vendor/golang.org/x/sys/windows/race.go @@ -0,0 +1,30 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows,race + +package windows + +import ( + "runtime" + "unsafe" +) + +const raceenabled = true + +func raceAcquire(addr unsafe.Pointer) { + runtime.RaceAcquire(addr) +} + +func raceReleaseMerge(addr unsafe.Pointer) { + runtime.RaceReleaseMerge(addr) +} + +func raceReadRange(addr unsafe.Pointer, len int) { + runtime.RaceReadRange(addr, len) +} + +func raceWriteRange(addr unsafe.Pointer, len int) { + runtime.RaceWriteRange(addr, len) +} diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go new file mode 100644 index 000000000..e44a3cbf6 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/race0.go @@ -0,0 +1,25 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows,!race + +package windows + +import ( + "unsafe" +) + +const raceenabled = false + +func raceAcquire(addr unsafe.Pointer) { +} + +func raceReleaseMerge(addr unsafe.Pointer) { +} + +func raceReadRange(addr unsafe.Pointer, len int) { +} + +func raceWriteRange(addr unsafe.Pointer, len int) { +} diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go new file mode 100644 index 000000000..f1ec5dc4e --- /dev/null +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -0,0 +1,476 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import ( + "syscall" + "unsafe" +) + +const ( + STANDARD_RIGHTS_REQUIRED = 0xf0000 + STANDARD_RIGHTS_READ = 0x20000 + STANDARD_RIGHTS_WRITE = 0x20000 + STANDARD_RIGHTS_EXECUTE = 0x20000 + STANDARD_RIGHTS_ALL = 0x1F0000 +) + +const ( + NameUnknown = 0 + NameFullyQualifiedDN = 1 + NameSamCompatible = 2 + NameDisplay = 3 + NameUniqueId = 6 + NameCanonical = 7 + NameUserPrincipal = 8 + NameCanonicalEx = 9 + NameServicePrincipal = 10 + NameDnsDomain = 12 +) + +// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. +// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx +//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW +//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW + +// TranslateAccountName converts a directory service +// object name from one format to another. +func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) { + u, e := UTF16PtrFromString(username) + if e != nil { + return "", e + } + n := uint32(50) + for { + b := make([]uint16, n) + e = TranslateName(u, from, to, &b[0], &n) + if e == nil { + return UTF16ToString(b[:n]), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", e + } + if n <= uint32(len(b)) { + return "", e + } + } +} + +const ( + // do not reorder + NetSetupUnknownStatus = iota + NetSetupUnjoined + NetSetupWorkgroupName + NetSetupDomainName +) + +type UserInfo10 struct { + Name *uint16 + Comment *uint16 + UsrComment *uint16 + FullName *uint16 +} + +//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo +//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation +//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree + +const ( + // do not reorder + SidTypeUser = 1 + iota + SidTypeGroup + SidTypeDomain + SidTypeAlias + SidTypeWellKnownGroup + SidTypeDeletedAccount + SidTypeInvalid + SidTypeUnknown + SidTypeComputer + SidTypeLabel +) + +type SidIdentifierAuthority struct { + Value [6]byte +} + +var ( + SECURITY_NULL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}} + SECURITY_WORLD_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}} + SECURITY_LOCAL_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}} + SECURITY_CREATOR_SID_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}} + SECURITY_NON_UNIQUE_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}} + SECURITY_NT_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}} + SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}} +) + +const ( + SECURITY_NULL_RID = 0 + SECURITY_WORLD_RID = 0 + SECURITY_LOCAL_RID = 0 + SECURITY_CREATOR_OWNER_RID = 0 + SECURITY_CREATOR_GROUP_RID = 1 + SECURITY_DIALUP_RID = 1 + SECURITY_NETWORK_RID = 2 + SECURITY_BATCH_RID = 3 + SECURITY_INTERACTIVE_RID = 4 + SECURITY_LOGON_IDS_RID = 5 + SECURITY_SERVICE_RID = 6 + SECURITY_LOCAL_SYSTEM_RID = 18 + SECURITY_BUILTIN_DOMAIN_RID = 32 + SECURITY_PRINCIPAL_SELF_RID = 10 + SECURITY_CREATOR_OWNER_SERVER_RID = 0x2 + SECURITY_CREATOR_GROUP_SERVER_RID = 0x3 + SECURITY_LOGON_IDS_RID_COUNT = 0x3 + SECURITY_ANONYMOUS_LOGON_RID = 0x7 + SECURITY_PROXY_RID = 0x8 + SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9 + SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID + SECURITY_AUTHENTICATED_USER_RID = 0xb + SECURITY_RESTRICTED_CODE_RID = 0xc + SECURITY_NT_NON_UNIQUE_RID = 0x15 +) + +// Predefined domain-relative RIDs for local groups. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx +const ( + DOMAIN_ALIAS_RID_ADMINS = 0x220 + DOMAIN_ALIAS_RID_USERS = 0x221 + DOMAIN_ALIAS_RID_GUESTS = 0x222 + DOMAIN_ALIAS_RID_POWER_USERS = 0x223 + DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224 + DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225 + DOMAIN_ALIAS_RID_PRINT_OPS = 0x226 + DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227 + DOMAIN_ALIAS_RID_REPLICATOR = 0x228 + DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229 + DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a + DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b + DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c + DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d + DOMAIN_ALIAS_RID_MONITORING_USERS = 0X22e + DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f + DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230 + DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231 + DOMAIN_ALIAS_RID_DCOM_USERS = 0x232 + DOMAIN_ALIAS_RID_IUSERS = 0x238 + DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x239 + DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x23b + DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c + DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x23d + DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x23e +) + +//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW +//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW +//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW +//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW +//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid +//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid +//sys AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid +//sys FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid +//sys EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid + +// The security identifier (SID) structure is a variable-length +// structure used to uniquely identify users or groups. +type SID struct{} + +// StringToSid converts a string-format security identifier +// sid into a valid, functional sid. +func StringToSid(s string) (*SID, error) { + var sid *SID + p, e := UTF16PtrFromString(s) + if e != nil { + return nil, e + } + e = ConvertStringSidToSid(p, &sid) + if e != nil { + return nil, e + } + defer LocalFree((Handle)(unsafe.Pointer(sid))) + return sid.Copy() +} + +// LookupSID retrieves a security identifier sid for the account +// and the name of the domain on which the account was found. +// System specify target computer to search. +func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) { + if len(account) == 0 { + return nil, "", 0, syscall.EINVAL + } + acc, e := UTF16PtrFromString(account) + if e != nil { + return nil, "", 0, e + } + var sys *uint16 + if len(system) > 0 { + sys, e = UTF16PtrFromString(system) + if e != nil { + return nil, "", 0, e + } + } + n := uint32(50) + dn := uint32(50) + for { + b := make([]byte, n) + db := make([]uint16, dn) + sid = (*SID)(unsafe.Pointer(&b[0])) + e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType) + if e == nil { + return sid, UTF16ToString(db), accType, nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return nil, "", 0, e + } + if n <= uint32(len(b)) { + return nil, "", 0, e + } + } +} + +// String converts sid to a string format +// suitable for display, storage, or transmission. +func (sid *SID) String() (string, error) { + var s *uint16 + e := ConvertSidToStringSid(sid, &s) + if e != nil { + return "", e + } + defer LocalFree((Handle)(unsafe.Pointer(s))) + return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil +} + +// Len returns the length, in bytes, of a valid security identifier sid. +func (sid *SID) Len() int { + return int(GetLengthSid(sid)) +} + +// Copy creates a duplicate of security identifier sid. +func (sid *SID) Copy() (*SID, error) { + b := make([]byte, sid.Len()) + sid2 := (*SID)(unsafe.Pointer(&b[0])) + e := CopySid(uint32(len(b)), sid2, sid) + if e != nil { + return nil, e + } + return sid2, nil +} + +// LookupAccount retrieves the name of the account for this sid +// and the name of the first domain on which this sid is found. +// System specify target computer to search for. +func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) { + var sys *uint16 + if len(system) > 0 { + sys, err = UTF16PtrFromString(system) + if err != nil { + return "", "", 0, err + } + } + n := uint32(50) + dn := uint32(50) + for { + b := make([]uint16, n) + db := make([]uint16, dn) + e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType) + if e == nil { + return UTF16ToString(b), UTF16ToString(db), accType, nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", "", 0, e + } + if n <= uint32(len(b)) { + return "", "", 0, e + } + } +} + +const ( + // do not reorder + TOKEN_ASSIGN_PRIMARY = 1 << iota + TOKEN_DUPLICATE + TOKEN_IMPERSONATE + TOKEN_QUERY + TOKEN_QUERY_SOURCE + TOKEN_ADJUST_PRIVILEGES + TOKEN_ADJUST_GROUPS + TOKEN_ADJUST_DEFAULT + + TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + TOKEN_ASSIGN_PRIMARY | + TOKEN_DUPLICATE | + TOKEN_IMPERSONATE | + TOKEN_QUERY | + TOKEN_QUERY_SOURCE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT + TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY + TOKEN_WRITE = STANDARD_RIGHTS_WRITE | + TOKEN_ADJUST_PRIVILEGES | + TOKEN_ADJUST_GROUPS | + TOKEN_ADJUST_DEFAULT + TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE +) + +const ( + // do not reorder + TokenUser = 1 + iota + TokenGroups + TokenPrivileges + TokenOwner + TokenPrimaryGroup + TokenDefaultDacl + TokenSource + TokenType + TokenImpersonationLevel + TokenStatistics + TokenRestrictedSids + TokenSessionId + TokenGroupsAndPrivileges + TokenSessionReference + TokenSandBoxInert + TokenAuditPolicy + TokenOrigin + TokenElevationType + TokenLinkedToken + TokenElevation + TokenHasRestrictions + TokenAccessInformation + TokenVirtualizationAllowed + TokenVirtualizationEnabled + TokenIntegrityLevel + TokenUIAccess + TokenMandatoryPolicy + TokenLogonSid + MaxTokenInfoClass +) + +type SIDAndAttributes struct { + Sid *SID + Attributes uint32 +} + +type Tokenuser struct { + User SIDAndAttributes +} + +type Tokenprimarygroup struct { + PrimaryGroup *SID +} + +type Tokengroups struct { + GroupCount uint32 + Groups [1]SIDAndAttributes +} + +// Authorization Functions +//sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership +//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken +//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation +//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW + +// An access token contains the security information for a logon session. +// The system creates an access token when a user logs on, and every +// process executed on behalf of the user has a copy of the token. +// The token identifies the user, the user's groups, and the user's +// privileges. The system uses the token to control access to securable +// objects and to control the ability of the user to perform various +// system-related operations on the local computer. +type Token Handle + +// OpenCurrentProcessToken opens the access token +// associated with current process. +func OpenCurrentProcessToken() (Token, error) { + p, e := GetCurrentProcess() + if e != nil { + return 0, e + } + var t Token + e = OpenProcessToken(p, TOKEN_QUERY, &t) + if e != nil { + return 0, e + } + return t, nil +} + +// Close releases access to access token. +func (t Token) Close() error { + return CloseHandle(Handle(t)) +} + +// getInfo retrieves a specified type of information about an access token. +func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) { + n := uint32(initSize) + for { + b := make([]byte, n) + e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n) + if e == nil { + return unsafe.Pointer(&b[0]), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return nil, e + } + if n <= uint32(len(b)) { + return nil, e + } + } +} + +// GetTokenUser retrieves access token t user account information. +func (t Token) GetTokenUser() (*Tokenuser, error) { + i, e := t.getInfo(TokenUser, 50) + if e != nil { + return nil, e + } + return (*Tokenuser)(i), nil +} + +// GetTokenGroups retrieves group accounts associated with access token t. +func (t Token) GetTokenGroups() (*Tokengroups, error) { + i, e := t.getInfo(TokenGroups, 50) + if e != nil { + return nil, e + } + return (*Tokengroups)(i), nil +} + +// GetTokenPrimaryGroup retrieves access token t primary group information. +// A pointer to a SID structure representing a group that will become +// the primary group of any objects created by a process using this access token. +func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) { + i, e := t.getInfo(TokenPrimaryGroup, 50) + if e != nil { + return nil, e + } + return (*Tokenprimarygroup)(i), nil +} + +// GetUserProfileDirectory retrieves path to the +// root directory of the access token t user's profile. +func (t Token) GetUserProfileDirectory() (string, error) { + n := uint32(100) + for { + b := make([]uint16, n) + e := GetUserProfileDirectory(t, &b[0], &n) + if e == nil { + return UTF16ToString(b), nil + } + if e != ERROR_INSUFFICIENT_BUFFER { + return "", e + } + if n <= uint32(len(b)) { + return "", e + } + } +} + +// IsMember reports whether the access token t is a member of the provided SID. +func (t Token) IsMember(sid *SID) (bool, error) { + var b int32 + if e := checkTokenMembership(t, sid, &b); e != nil { + return false, e + } + return b != 0, nil +} diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go new file mode 100644 index 000000000..a500dd7df --- /dev/null +++ b/vendor/golang.org/x/sys/windows/service.go @@ -0,0 +1,164 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package windows + +const ( + SC_MANAGER_CONNECT = 1 + SC_MANAGER_CREATE_SERVICE = 2 + SC_MANAGER_ENUMERATE_SERVICE = 4 + SC_MANAGER_LOCK = 8 + SC_MANAGER_QUERY_LOCK_STATUS = 16 + SC_MANAGER_MODIFY_BOOT_CONFIG = 32 + SC_MANAGER_ALL_ACCESS = 0xf003f +) + +//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW + +const ( + SERVICE_KERNEL_DRIVER = 1 + SERVICE_FILE_SYSTEM_DRIVER = 2 + SERVICE_ADAPTER = 4 + SERVICE_RECOGNIZER_DRIVER = 8 + SERVICE_WIN32_OWN_PROCESS = 16 + SERVICE_WIN32_SHARE_PROCESS = 32 + SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS + SERVICE_INTERACTIVE_PROCESS = 256 + SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER + SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS + + SERVICE_BOOT_START = 0 + SERVICE_SYSTEM_START = 1 + SERVICE_AUTO_START = 2 + SERVICE_DEMAND_START = 3 + SERVICE_DISABLED = 4 + + SERVICE_ERROR_IGNORE = 0 + SERVICE_ERROR_NORMAL = 1 + SERVICE_ERROR_SEVERE = 2 + SERVICE_ERROR_CRITICAL = 3 + + SC_STATUS_PROCESS_INFO = 0 + + SERVICE_STOPPED = 1 + SERVICE_START_PENDING = 2 + SERVICE_STOP_PENDING = 3 + SERVICE_RUNNING = 4 + SERVICE_CONTINUE_PENDING = 5 + SERVICE_PAUSE_PENDING = 6 + SERVICE_PAUSED = 7 + SERVICE_NO_CHANGE = 0xffffffff + + SERVICE_ACCEPT_STOP = 1 + SERVICE_ACCEPT_PAUSE_CONTINUE = 2 + SERVICE_ACCEPT_SHUTDOWN = 4 + SERVICE_ACCEPT_PARAMCHANGE = 8 + SERVICE_ACCEPT_NETBINDCHANGE = 16 + SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32 + SERVICE_ACCEPT_POWEREVENT = 64 + SERVICE_ACCEPT_SESSIONCHANGE = 128 + + SERVICE_CONTROL_STOP = 1 + SERVICE_CONTROL_PAUSE = 2 + SERVICE_CONTROL_CONTINUE = 3 + SERVICE_CONTROL_INTERROGATE = 4 + SERVICE_CONTROL_SHUTDOWN = 5 + SERVICE_CONTROL_PARAMCHANGE = 6 + SERVICE_CONTROL_NETBINDADD = 7 + SERVICE_CONTROL_NETBINDREMOVE = 8 + SERVICE_CONTROL_NETBINDENABLE = 9 + SERVICE_CONTROL_NETBINDDISABLE = 10 + SERVICE_CONTROL_DEVICEEVENT = 11 + SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12 + SERVICE_CONTROL_POWEREVENT = 13 + SERVICE_CONTROL_SESSIONCHANGE = 14 + + SERVICE_ACTIVE = 1 + SERVICE_INACTIVE = 2 + SERVICE_STATE_ALL = 3 + + SERVICE_QUERY_CONFIG = 1 + SERVICE_CHANGE_CONFIG = 2 + SERVICE_QUERY_STATUS = 4 + SERVICE_ENUMERATE_DEPENDENTS = 8 + SERVICE_START = 16 + SERVICE_STOP = 32 + SERVICE_PAUSE_CONTINUE = 64 + SERVICE_INTERROGATE = 128 + SERVICE_USER_DEFINED_CONTROL = 256 + SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL + SERVICE_RUNS_IN_SYSTEM_PROCESS = 1 + SERVICE_CONFIG_DESCRIPTION = 1 + SERVICE_CONFIG_FAILURE_ACTIONS = 2 + + NO_ERROR = 0 + + SC_ENUM_PROCESS_INFO = 0 +) + +type SERVICE_STATUS struct { + ServiceType uint32 + CurrentState uint32 + ControlsAccepted uint32 + Win32ExitCode uint32 + ServiceSpecificExitCode uint32 + CheckPoint uint32 + WaitHint uint32 +} + +type SERVICE_TABLE_ENTRY struct { + ServiceName *uint16 + ServiceProc uintptr +} + +type QUERY_SERVICE_CONFIG struct { + ServiceType uint32 + StartType uint32 + ErrorControl uint32 + BinaryPathName *uint16 + LoadOrderGroup *uint16 + TagId uint32 + Dependencies *uint16 + ServiceStartName *uint16 + DisplayName *uint16 +} + +type SERVICE_DESCRIPTION struct { + Description *uint16 +} + +type SERVICE_STATUS_PROCESS struct { + ServiceType uint32 + CurrentState uint32 + ControlsAccepted uint32 + Win32ExitCode uint32 + ServiceSpecificExitCode uint32 + CheckPoint uint32 + WaitHint uint32 + ProcessId uint32 + ServiceFlags uint32 +} + +type ENUM_SERVICE_STATUS_PROCESS struct { + ServiceName *uint16 + DisplayName *uint16 + ServiceStatusProcess SERVICE_STATUS_PROCESS +} + +//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle +//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW +//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW +//sys DeleteService(service Handle) (err error) = advapi32.DeleteService +//sys StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW +//sys QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus +//sys ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService +//sys StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW +//sys SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus +//sys ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW +//sys QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW +//sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W +//sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W +//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go new file mode 100644 index 000000000..917cc2aae --- /dev/null +++ b/vendor/golang.org/x/sys/windows/str.go @@ -0,0 +1,22 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package windows + +func itoa(val int) string { // do it here rather than with fmt to avoid dependency + if val < 0 { + return "-" + itoa(-val) + } + var buf [32]byte // big enough for int64 + i := len(buf) - 1 + for val >= 10 { + buf[i] = byte(val%10 + '0') + i-- + val /= 10 + } + buf[i] = byte(val + '0') + return string(buf[i:]) +} diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go new file mode 100644 index 000000000..af828a91b --- /dev/null +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -0,0 +1,74 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +// Package windows contains an interface to the low-level operating system +// primitives. OS details vary depending on the underlying system, and +// by default, godoc will display the OS-specific documentation for the current +// system. If you want godoc to display syscall documentation for another +// system, set $GOOS and $GOARCH to the desired system. For example, if +// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS +// to freebsd and $GOARCH to arm. +// +// The primary use of this package is inside other packages that provide a more +// portable interface to the system, such as "os", "time" and "net". Use +// those packages rather than this one if you can. +// +// For details of the functions and data types in this package consult +// the manuals for the appropriate operating system. +// +// These calls return err == nil to indicate success; otherwise +// err represents an operating system error describing the failure and +// holds a value of type syscall.Errno. +package windows // import "golang.org/x/sys/windows" + +import ( + "syscall" +) + +// ByteSliceFromString returns a NUL-terminated slice of bytes +// containing the text of s. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func ByteSliceFromString(s string) ([]byte, error) { + for i := 0; i < len(s); i++ { + if s[i] == 0 { + return nil, syscall.EINVAL + } + } + a := make([]byte, len(s)+1) + copy(a, s) + return a, nil +} + +// BytePtrFromString returns a pointer to a NUL-terminated array of +// bytes containing the text of s. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func BytePtrFromString(s string) (*byte, error) { + a, err := ByteSliceFromString(s) + if err != nil { + return nil, err + } + return &a[0], nil +} + +// Single-word zero for use when we need a valid pointer to 0 bytes. +// See mksyscall.pl. +var _zero uintptr + +func (ts *Timespec) Unix() (sec int64, nsec int64) { + return int64(ts.Sec), int64(ts.Nsec) +} + +func (tv *Timeval) Unix() (sec int64, nsec int64) { + return int64(tv.Sec), int64(tv.Usec) * 1000 +} + +func (ts *Timespec) Nano() int64 { + return int64(ts.Sec)*1e9 + int64(ts.Nsec) +} + +func (tv *Timeval) Nano() int64 { + return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 +} diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go new file mode 100644 index 000000000..1e9f4bb4a --- /dev/null +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -0,0 +1,1153 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Windows system calls. + +package windows + +import ( + errorspkg "errors" + "sync" + "syscall" + "unicode/utf16" + "unsafe" +) + +type Handle uintptr + +const ( + InvalidHandle = ^Handle(0) + + // Flags for DefineDosDevice. + DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 + DDD_NO_BROADCAST_SYSTEM = 0x00000008 + DDD_RAW_TARGET_PATH = 0x00000001 + DDD_REMOVE_DEFINITION = 0x00000002 + + // Return values for GetDriveType. + DRIVE_UNKNOWN = 0 + DRIVE_NO_ROOT_DIR = 1 + DRIVE_REMOVABLE = 2 + DRIVE_FIXED = 3 + DRIVE_REMOTE = 4 + DRIVE_CDROM = 5 + DRIVE_RAMDISK = 6 + + // File system flags from GetVolumeInformation and GetVolumeInformationByHandle. + FILE_CASE_SENSITIVE_SEARCH = 0x00000001 + FILE_CASE_PRESERVED_NAMES = 0x00000002 + FILE_FILE_COMPRESSION = 0x00000010 + FILE_DAX_VOLUME = 0x20000000 + FILE_NAMED_STREAMS = 0x00040000 + FILE_PERSISTENT_ACLS = 0x00000008 + FILE_READ_ONLY_VOLUME = 0x00080000 + FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000 + FILE_SUPPORTS_ENCRYPTION = 0x00020000 + FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000 + FILE_SUPPORTS_HARD_LINKS = 0x00400000 + FILE_SUPPORTS_OBJECT_IDS = 0x00010000 + FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000 + FILE_SUPPORTS_REPARSE_POINTS = 0x00000080 + FILE_SUPPORTS_SPARSE_FILES = 0x00000040 + FILE_SUPPORTS_TRANSACTIONS = 0x00200000 + FILE_SUPPORTS_USN_JOURNAL = 0x02000000 + FILE_UNICODE_ON_DISK = 0x00000004 + FILE_VOLUME_IS_COMPRESSED = 0x00008000 + FILE_VOLUME_QUOTAS = 0x00000020 +) + +// StringToUTF16 is deprecated. Use UTF16FromString instead. +// If s contains a NUL byte this function panics instead of +// returning an error. +func StringToUTF16(s string) []uint16 { + a, err := UTF16FromString(s) + if err != nil { + panic("windows: string with NUL passed to StringToUTF16") + } + return a +} + +// UTF16FromString returns the UTF-16 encoding of the UTF-8 string +// s, with a terminating NUL added. If s contains a NUL byte at any +// location, it returns (nil, syscall.EINVAL). +func UTF16FromString(s string) ([]uint16, error) { + for i := 0; i < len(s); i++ { + if s[i] == 0 { + return nil, syscall.EINVAL + } + } + return utf16.Encode([]rune(s + "\x00")), nil +} + +// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, +// with a terminating NUL removed. +func UTF16ToString(s []uint16) string { + for i, v := range s { + if v == 0 { + s = s[0:i] + break + } + } + return string(utf16.Decode(s)) +} + +// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead. +// If s contains a NUL byte this function panics instead of +// returning an error. +func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] } + +// UTF16PtrFromString returns pointer to the UTF-16 encoding of +// the UTF-8 string s, with a terminating NUL added. If s +// contains a NUL byte at any location, it returns (nil, syscall.EINVAL). +func UTF16PtrFromString(s string) (*uint16, error) { + a, err := UTF16FromString(s) + if err != nil { + return nil, err + } + return &a[0], nil +} + +func Getpagesize() int { return 4096 } + +// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. +// This is useful when interoperating with Windows code requiring callbacks. +func NewCallback(fn interface{}) uintptr { + return syscall.NewCallback(fn) +} + +// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. +// This is useful when interoperating with Windows code requiring callbacks. +func NewCallbackCDecl(fn interface{}) uintptr { + return syscall.NewCallbackCDecl(fn) +} + +// windows api calls + +//sys GetLastError() (lasterr error) +//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW +//sys LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) = LoadLibraryExW +//sys FreeLibrary(handle Handle) (err error) +//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) +//sys GetVersion() (ver uint32, err error) +//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW +//sys ExitProcess(exitcode uint32) +//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW +//sys ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) +//sys WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) +//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff] +//sys CloseHandle(handle Handle) (err error) +//sys GetStdHandle(stdhandle uint32) (handle Handle, err error) [failretval==InvalidHandle] +//sys SetStdHandle(stdhandle uint32, handle Handle) (err error) +//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW +//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW +//sys FindClose(handle Handle) (err error) +//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) +//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW +//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW +//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW +//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW +//sys DeleteFile(path *uint16) (err error) = DeleteFileW +//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW +//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW +//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW +//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW +//sys SetEndOfFile(handle Handle) (err error) +//sys GetSystemTimeAsFileTime(time *Filetime) +//sys GetSystemTimePreciseAsFileTime(time *Filetime) +//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] +//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) +//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) +//sys PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) +//sys CancelIo(s Handle) (err error) +//sys CancelIoEx(s Handle, o *Overlapped) (err error) +//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW +//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) +//sys TerminateProcess(handle Handle, exitcode uint32) (err error) +//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) +//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW +//sys GetCurrentProcess() (pseudoHandle Handle, err error) +//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) +//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) +//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] +//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW +//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) +//sys GetFileType(filehandle Handle) (n uint32, err error) +//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW +//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext +//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom +//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW +//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW +//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW +//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW +//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) +//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW +//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW +//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW +//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW +//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW +//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] +//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) +//sys FlushFileBuffers(handle Handle) (err error) +//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW +//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW +//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW +//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW +//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) +//sys UnmapViewOfFile(addr uintptr) (err error) +//sys FlushViewOfFile(addr uintptr, length uintptr) (err error) +//sys VirtualLock(addr uintptr, length uintptr) (err error) +//sys VirtualUnlock(addr uintptr, length uintptr) (err error) +//sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc +//sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree +//sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect +//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile +//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW +//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW +//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore +//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore +//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore +//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore +//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain +//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain +//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext +//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext +//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy +//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW +//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey +//sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW +//sys RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW +//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW +//sys getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId +//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode +//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode +//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo +//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW +//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot +//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW +//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW +//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) +// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. +//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW +//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW +//sys GetCurrentThreadId() (id uint32) +//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW +//sys CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW +//sys OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW +//sys SetEvent(event Handle) (err error) = kernel32.SetEvent +//sys ResetEvent(event Handle) (err error) = kernel32.ResetEvent +//sys PulseEvent(event Handle) (err error) = kernel32.PulseEvent + +// Volume Management Functions +//sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW +//sys DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) = DeleteVolumeMountPointW +//sys FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeW +//sys FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeMountPointW +//sys FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) = FindNextVolumeW +//sys FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW +//sys FindVolumeClose(findVolume Handle) (err error) +//sys FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) +//sys GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW +//sys GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0] +//sys GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW +//sys GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationW +//sys GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW +//sys GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW +//sys GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) = GetVolumePathNameW +//sys GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) = GetVolumePathNamesForVolumeNameW +//sys QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW +//sys SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW +//sys SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW + +// syscall interface implementation for other packages + +// GetProcAddressByOrdinal retrieves the address of the exported +// function from module by ordinal. +func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) { + r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0) + proc = uintptr(r0) + if proc == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Exit(code int) { ExitProcess(uint32(code)) } + +func makeInheritSa() *SecurityAttributes { + var sa SecurityAttributes + sa.Length = uint32(unsafe.Sizeof(sa)) + sa.InheritHandle = 1 + return &sa +} + +func Open(path string, mode int, perm uint32) (fd Handle, err error) { + if len(path) == 0 { + return InvalidHandle, ERROR_FILE_NOT_FOUND + } + pathp, err := UTF16PtrFromString(path) + if err != nil { + return InvalidHandle, err + } + var access uint32 + switch mode & (O_RDONLY | O_WRONLY | O_RDWR) { + case O_RDONLY: + access = GENERIC_READ + case O_WRONLY: + access = GENERIC_WRITE + case O_RDWR: + access = GENERIC_READ | GENERIC_WRITE + } + if mode&O_CREAT != 0 { + access |= GENERIC_WRITE + } + if mode&O_APPEND != 0 { + access &^= GENERIC_WRITE + access |= FILE_APPEND_DATA + } + sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE) + var sa *SecurityAttributes + if mode&O_CLOEXEC == 0 { + sa = makeInheritSa() + } + var createmode uint32 + switch { + case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): + createmode = CREATE_NEW + case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC): + createmode = CREATE_ALWAYS + case mode&O_CREAT == O_CREAT: + createmode = OPEN_ALWAYS + case mode&O_TRUNC == O_TRUNC: + createmode = TRUNCATE_EXISTING + default: + createmode = OPEN_EXISTING + } + h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0) + return h, e +} + +func Read(fd Handle, p []byte) (n int, err error) { + var done uint32 + e := ReadFile(fd, p, &done, nil) + if e != nil { + if e == ERROR_BROKEN_PIPE { + // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin + return 0, nil + } + return 0, e + } + if raceenabled { + if done > 0 { + raceWriteRange(unsafe.Pointer(&p[0]), int(done)) + } + raceAcquire(unsafe.Pointer(&ioSync)) + } + return int(done), nil +} + +func Write(fd Handle, p []byte) (n int, err error) { + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + var done uint32 + e := WriteFile(fd, p, &done, nil) + if e != nil { + return 0, e + } + if raceenabled && done > 0 { + raceReadRange(unsafe.Pointer(&p[0]), int(done)) + } + return int(done), nil +} + +var ioSync int64 + +func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) { + var w uint32 + switch whence { + case 0: + w = FILE_BEGIN + case 1: + w = FILE_CURRENT + case 2: + w = FILE_END + } + hi := int32(offset >> 32) + lo := int32(offset) + // use GetFileType to check pipe, pipe can't do seek + ft, _ := GetFileType(fd) + if ft == FILE_TYPE_PIPE { + return 0, syscall.EPIPE + } + rlo, e := SetFilePointer(fd, lo, &hi, w) + if e != nil { + return 0, e + } + return int64(hi)<<32 + int64(rlo), nil +} + +func Close(fd Handle) (err error) { + return CloseHandle(fd) +} + +var ( + Stdin = getStdHandle(STD_INPUT_HANDLE) + Stdout = getStdHandle(STD_OUTPUT_HANDLE) + Stderr = getStdHandle(STD_ERROR_HANDLE) +) + +func getStdHandle(stdhandle uint32) (fd Handle) { + r, _ := GetStdHandle(stdhandle) + CloseOnExec(r) + return r +} + +const ImplementsGetwd = true + +func Getwd() (wd string, err error) { + b := make([]uint16, 300) + n, e := GetCurrentDirectory(uint32(len(b)), &b[0]) + if e != nil { + return "", e + } + return string(utf16.Decode(b[0:n])), nil +} + +func Chdir(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return SetCurrentDirectory(pathp) +} + +func Mkdir(path string, mode uint32) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return CreateDirectory(pathp, nil) +} + +func Rmdir(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return RemoveDirectory(pathp) +} + +func Unlink(path string) (err error) { + pathp, err := UTF16PtrFromString(path) + if err != nil { + return err + } + return DeleteFile(pathp) +} + +func Rename(oldpath, newpath string) (err error) { + from, err := UTF16PtrFromString(oldpath) + if err != nil { + return err + } + to, err := UTF16PtrFromString(newpath) + if err != nil { + return err + } + return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) +} + +func ComputerName() (name string, err error) { + var n uint32 = MAX_COMPUTERNAME_LENGTH + 1 + b := make([]uint16, n) + e := GetComputerName(&b[0], &n) + if e != nil { + return "", e + } + return string(utf16.Decode(b[0:n])), nil +} + +func Ftruncate(fd Handle, length int64) (err error) { + curoffset, e := Seek(fd, 0, 1) + if e != nil { + return e + } + defer Seek(fd, curoffset, 0) + _, e = Seek(fd, length, 0) + if e != nil { + return e + } + e = SetEndOfFile(fd) + if e != nil { + return e + } + return nil +} + +func Gettimeofday(tv *Timeval) (err error) { + var ft Filetime + GetSystemTimeAsFileTime(&ft) + *tv = NsecToTimeval(ft.Nanoseconds()) + return nil +} + +func Pipe(p []Handle) (err error) { + if len(p) != 2 { + return syscall.EINVAL + } + var r, w Handle + e := CreatePipe(&r, &w, makeInheritSa(), 0) + if e != nil { + return e + } + p[0] = r + p[1] = w + return nil +} + +func Utimes(path string, tv []Timeval) (err error) { + if len(tv) != 2 { + return syscall.EINVAL + } + pathp, e := UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := CreateFile(pathp, + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer Close(h) + a := NsecToFiletime(tv[0].Nanoseconds()) + w := NsecToFiletime(tv[1].Nanoseconds()) + return SetFileTime(h, nil, &a, &w) +} + +func UtimesNano(path string, ts []Timespec) (err error) { + if len(ts) != 2 { + return syscall.EINVAL + } + pathp, e := UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := CreateFile(pathp, + FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer Close(h) + a := NsecToFiletime(TimespecToNsec(ts[0])) + w := NsecToFiletime(TimespecToNsec(ts[1])) + return SetFileTime(h, nil, &a, &w) +} + +func Fsync(fd Handle) (err error) { + return FlushFileBuffers(fd) +} + +func Chmod(path string, mode uint32) (err error) { + if mode == 0 { + return syscall.EINVAL + } + p, e := UTF16PtrFromString(path) + if e != nil { + return e + } + attrs, e := GetFileAttributes(p) + if e != nil { + return e + } + if mode&S_IWRITE != 0 { + attrs &^= FILE_ATTRIBUTE_READONLY + } else { + attrs |= FILE_ATTRIBUTE_READONLY + } + return SetFileAttributes(p, attrs) +} + +func LoadGetSystemTimePreciseAsFileTime() error { + return procGetSystemTimePreciseAsFileTime.Find() +} + +func LoadCancelIoEx() error { + return procCancelIoEx.Find() +} + +func LoadSetFileCompletionNotificationModes() error { + return procSetFileCompletionNotificationModes.Find() +} + +// net api calls + +const socket_error = uintptr(^uint32(0)) + +//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup +//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup +//sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl +//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket +//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt +//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt +//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind +//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect +//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname +//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername +//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen +//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown +//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket +//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx +//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs +//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv +//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend +//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom +//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo +//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname +//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname +//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs +//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname +//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W +//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree +//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W +//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW +//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW +//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry +//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo +//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes +//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW +//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses +//sys GetACP() (acp uint32) = kernel32.GetACP +//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar + +// For testing: clients can set this flag to force +// creation of IPv6 sockets to return EAFNOSUPPORT. +var SocketDisableIPv6 bool + +type RawSockaddrInet4 struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +type RawSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type RawSockaddr struct { + Family uint16 + Data [14]int8 +} + +type RawSockaddrAny struct { + Addr RawSockaddr + Pad [96]int8 +} + +type Sockaddr interface { + sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs +} + +type SockaddrInet4 struct { + Port int + Addr [4]byte + raw RawSockaddrInet4 +} + +func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_INET + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Addr[i] = sa.Addr[i] + } + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +type SockaddrInet6 struct { + Port int + ZoneId uint32 + Addr [16]byte + raw RawSockaddrInet6 +} + +func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { + if sa.Port < 0 || sa.Port > 0xFFFF { + return nil, 0, syscall.EINVAL + } + sa.raw.Family = AF_INET6 + p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) + p[0] = byte(sa.Port >> 8) + p[1] = byte(sa.Port) + sa.raw.Scope_id = sa.ZoneId + for i := 0; i < len(sa.Addr); i++ { + sa.raw.Addr[i] = sa.Addr[i] + } + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + +type SockaddrUnix struct { + Name string +} + +func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { + // TODO(brainman): implement SockaddrUnix.sockaddr() + return nil, 0, syscall.EWINDOWS +} + +func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { + switch rsa.Addr.Family { + case AF_UNIX: + return nil, syscall.EWINDOWS + + case AF_INET: + pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) + sa := new(SockaddrInet4) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i] + } + return sa, nil + + case AF_INET6: + pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) + sa := new(SockaddrInet6) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.ZoneId = pp.Scope_id + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i] + } + return sa, nil + } + return nil, syscall.EAFNOSUPPORT +} + +func Socket(domain, typ, proto int) (fd Handle, err error) { + if domain == AF_INET6 && SocketDisableIPv6 { + return InvalidHandle, syscall.EAFNOSUPPORT + } + return socket(int32(domain), int32(typ), int32(proto)) +} + +func SetsockoptInt(fd Handle, level, opt int, value int) (err error) { + v := int32(value) + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))) +} + +func Bind(fd Handle, sa Sockaddr) (err error) { + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return bind(fd, ptr, n) +} + +func Connect(fd Handle, sa Sockaddr) (err error) { + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return connect(fd, ptr, n) +} + +func Getsockname(fd Handle) (sa Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + if err = getsockname(fd, &rsa, &l); err != nil { + return + } + return rsa.Sockaddr() +} + +func Getpeername(fd Handle) (sa Sockaddr, err error) { + var rsa RawSockaddrAny + l := int32(unsafe.Sizeof(rsa)) + if err = getpeername(fd, &rsa, &l); err != nil { + return + } + return rsa.Sockaddr() +} + +func Listen(s Handle, n int) (err error) { + return listen(s, int32(n)) +} + +func Shutdown(fd Handle, how int) (err error) { + return shutdown(fd, int32(how)) +} + +func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { + rsa, l, err := to.sockaddr() + if err != nil { + return err + } + return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine) +} + +func LoadGetAddrInfo() error { + return procGetAddrInfoW.Find() +} + +var connectExFunc struct { + once sync.Once + addr uintptr + err error +} + +func LoadConnectEx() error { + connectExFunc.once.Do(func() { + var s Handle + s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + if connectExFunc.err != nil { + return + } + defer CloseHandle(s) + var n uint32 + connectExFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)), + uint32(unsafe.Sizeof(WSAID_CONNECTEX)), + (*byte)(unsafe.Pointer(&connectExFunc.addr)), + uint32(unsafe.Sizeof(connectExFunc.addr)), + &n, nil, 0) + }) + return connectExFunc.err +} + +func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error { + err := LoadConnectEx() + if err != nil { + return errorspkg.New("failed to find ConnectEx: " + err.Error()) + } + ptr, n, err := sa.sockaddr() + if err != nil { + return err + } + return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) +} + +var sendRecvMsgFunc struct { + once sync.Once + sendAddr uintptr + recvAddr uintptr + err error +} + +func loadWSASendRecvMsg() error { + sendRecvMsgFunc.once.Do(func() { + var s Handle + s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) + if sendRecvMsgFunc.err != nil { + return + } + defer CloseHandle(s) + var n uint32 + sendRecvMsgFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), + uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), + (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), + uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), + &n, nil, 0) + if sendRecvMsgFunc.err != nil { + return + } + sendRecvMsgFunc.err = WSAIoctl(s, + SIO_GET_EXTENSION_FUNCTION_POINTER, + (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), + uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), + (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), + uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), + &n, nil, 0) + }) + return sendRecvMsgFunc.err +} + +func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error { + err := loadWSASendRecvMsg() + if err != nil { + return err + } + r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return err +} + +func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error { + err := loadWSASendRecvMsg() + if err != nil { + return err + } + r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return err +} + +// Invented structures to support what package os expects. +type Rusage struct { + CreationTime Filetime + ExitTime Filetime + KernelTime Filetime + UserTime Filetime +} + +type WaitStatus struct { + ExitCode uint32 +} + +func (w WaitStatus) Exited() bool { return true } + +func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) } + +func (w WaitStatus) Signal() Signal { return -1 } + +func (w WaitStatus) CoreDump() bool { return false } + +func (w WaitStatus) Stopped() bool { return false } + +func (w WaitStatus) Continued() bool { return false } + +func (w WaitStatus) StopSignal() Signal { return -1 } + +func (w WaitStatus) Signaled() bool { return false } + +func (w WaitStatus) TrapCause() int { return -1 } + +// Timespec is an invented structure on Windows, but here for +// consistency with the corresponding package for other operating systems. +type Timespec struct { + Sec int64 + Nsec int64 +} + +func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } + +func NsecToTimespec(nsec int64) (ts Timespec) { + ts.Sec = nsec / 1e9 + ts.Nsec = nsec % 1e9 + return +} + +// TODO(brainman): fix all needed for net + +func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS } +func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) { + return 0, nil, syscall.EWINDOWS +} +func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return syscall.EWINDOWS } +func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS } + +// The Linger struct is wrong but we only noticed after Go 1. +// sysLinger is the real system call structure. + +// BUG(brainman): The definition of Linger is not appropriate for direct use +// with Setsockopt and Getsockopt. +// Use SetsockoptLinger instead. + +type Linger struct { + Onoff int32 + Linger int32 +} + +type sysLinger struct { + Onoff uint16 + Linger uint16 +} + +type IPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type IPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS } + +func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { + sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) +} + +func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) +} +func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) +} +func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { + return syscall.EWINDOWS +} + +func Getpid() (pid int) { return int(getCurrentProcessId()) } + +func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { + // NOTE(rsc): The Win32finddata struct is wrong for the system call: + // the two paths are each one uint16 short. Use the correct struct, + // a win32finddata1, and then copy the results out. + // There is no loss of expressivity here, because the final + // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that. + // For Go 1.1, we might avoid the allocation of win32finddata1 here + // by adding a final Bug [2]uint16 field to the struct and then + // adjusting the fields in the result directly. + var data1 win32finddata1 + handle, err = findFirstFile1(name, &data1) + if err == nil { + copyFindData(data, &data1) + } + return +} + +func FindNextFile(handle Handle, data *Win32finddata) (err error) { + var data1 win32finddata1 + err = findNextFile1(handle, &data1) + if err == nil { + copyFindData(data, &data1) + } + return +} + +func getProcessEntry(pid int) (*ProcessEntry32, error) { + snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err + } + defer CloseHandle(snapshot) + var procEntry ProcessEntry32 + procEntry.Size = uint32(unsafe.Sizeof(procEntry)) + if err = Process32First(snapshot, &procEntry); err != nil { + return nil, err + } + for { + if procEntry.ProcessID == uint32(pid) { + return &procEntry, nil + } + err = Process32Next(snapshot, &procEntry) + if err != nil { + return nil, err + } + } +} + +func Getppid() (ppid int) { + pe, err := getProcessEntry(Getpid()) + if err != nil { + return -1 + } + return int(pe.ParentProcessID) +} + +// TODO(brainman): fix all needed for os +func Fchdir(fd Handle) (err error) { return syscall.EWINDOWS } +func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS } +func Symlink(path, link string) (err error) { return syscall.EWINDOWS } + +func Fchmod(fd Handle, mode uint32) (err error) { return syscall.EWINDOWS } +func Chown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } +func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } +func Fchown(fd Handle, uid int, gid int) (err error) { return syscall.EWINDOWS } + +func Getuid() (uid int) { return -1 } +func Geteuid() (euid int) { return -1 } +func Getgid() (gid int) { return -1 } +func Getegid() (egid int) { return -1 } +func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS } + +type Signal int + +func (s Signal) Signal() {} + +func (s Signal) String() string { + if 0 <= s && int(s) < len(signals) { + str := signals[s] + if str != "" { + return str + } + } + return "signal " + itoa(int(s)) +} + +func LoadCreateSymbolicLink() error { + return procCreateSymbolicLinkW.Find() +} + +// Readlink returns the destination of the named symbolic link. +func Readlink(path string, buf []byte) (n int, err error) { + fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0) + if err != nil { + return -1, err + } + defer CloseHandle(fd) + + rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) + var bytesReturned uint32 + err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) + if err != nil { + return -1, err + } + + rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0])) + var s string + switch rdb.ReparseTag { + case IO_REPARSE_TAG_SYMLINK: + data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) + p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) + s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + case IO_REPARSE_TAG_MOUNT_POINT: + data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) + p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) + s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) + default: + // the path is not a symlink or junction but another type of reparse + // point + return -1, syscall.ENOENT + } + n = copy(buf, []byte(s)) + + return n, nil +} diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go new file mode 100644 index 000000000..52c2037b6 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -0,0 +1,1333 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +import "syscall" + +const ( + // Windows errors. + ERROR_FILE_NOT_FOUND syscall.Errno = 2 + ERROR_PATH_NOT_FOUND syscall.Errno = 3 + ERROR_ACCESS_DENIED syscall.Errno = 5 + ERROR_NO_MORE_FILES syscall.Errno = 18 + ERROR_HANDLE_EOF syscall.Errno = 38 + ERROR_NETNAME_DELETED syscall.Errno = 64 + ERROR_FILE_EXISTS syscall.Errno = 80 + ERROR_BROKEN_PIPE syscall.Errno = 109 + ERROR_BUFFER_OVERFLOW syscall.Errno = 111 + ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122 + ERROR_MOD_NOT_FOUND syscall.Errno = 126 + ERROR_PROC_NOT_FOUND syscall.Errno = 127 + ERROR_ALREADY_EXISTS syscall.Errno = 183 + ERROR_ENVVAR_NOT_FOUND syscall.Errno = 203 + ERROR_MORE_DATA syscall.Errno = 234 + ERROR_OPERATION_ABORTED syscall.Errno = 995 + ERROR_IO_PENDING syscall.Errno = 997 + ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066 + ERROR_NOT_FOUND syscall.Errno = 1168 + ERROR_PRIVILEGE_NOT_HELD syscall.Errno = 1314 + WSAEACCES syscall.Errno = 10013 + WSAEMSGSIZE syscall.Errno = 10040 + WSAECONNRESET syscall.Errno = 10054 +) + +const ( + // Invented values to support what package os expects. + O_RDONLY = 0x00000 + O_WRONLY = 0x00001 + O_RDWR = 0x00002 + O_CREAT = 0x00040 + O_EXCL = 0x00080 + O_NOCTTY = 0x00100 + O_TRUNC = 0x00200 + O_NONBLOCK = 0x00800 + O_APPEND = 0x00400 + O_SYNC = 0x01000 + O_ASYNC = 0x02000 + O_CLOEXEC = 0x80000 +) + +const ( + // More invented values for signals + SIGHUP = Signal(0x1) + SIGINT = Signal(0x2) + SIGQUIT = Signal(0x3) + SIGILL = Signal(0x4) + SIGTRAP = Signal(0x5) + SIGABRT = Signal(0x6) + SIGBUS = Signal(0x7) + SIGFPE = Signal(0x8) + SIGKILL = Signal(0x9) + SIGSEGV = Signal(0xb) + SIGPIPE = Signal(0xd) + SIGALRM = Signal(0xe) + SIGTERM = Signal(0xf) +) + +var signals = [...]string{ + 1: "hangup", + 2: "interrupt", + 3: "quit", + 4: "illegal instruction", + 5: "trace/breakpoint trap", + 6: "aborted", + 7: "bus error", + 8: "floating point exception", + 9: "killed", + 10: "user defined signal 1", + 11: "segmentation fault", + 12: "user defined signal 2", + 13: "broken pipe", + 14: "alarm clock", + 15: "terminated", +} + +const ( + GENERIC_READ = 0x80000000 + GENERIC_WRITE = 0x40000000 + GENERIC_EXECUTE = 0x20000000 + GENERIC_ALL = 0x10000000 + + FILE_LIST_DIRECTORY = 0x00000001 + FILE_APPEND_DATA = 0x00000004 + FILE_WRITE_ATTRIBUTES = 0x00000100 + + FILE_SHARE_READ = 0x00000001 + FILE_SHARE_WRITE = 0x00000002 + FILE_SHARE_DELETE = 0x00000004 + FILE_ATTRIBUTE_READONLY = 0x00000001 + FILE_ATTRIBUTE_HIDDEN = 0x00000002 + FILE_ATTRIBUTE_SYSTEM = 0x00000004 + FILE_ATTRIBUTE_DIRECTORY = 0x00000010 + FILE_ATTRIBUTE_ARCHIVE = 0x00000020 + FILE_ATTRIBUTE_NORMAL = 0x00000080 + FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 + + INVALID_FILE_ATTRIBUTES = 0xffffffff + + CREATE_NEW = 1 + CREATE_ALWAYS = 2 + OPEN_EXISTING = 3 + OPEN_ALWAYS = 4 + TRUNCATE_EXISTING = 5 + + FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 + FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 + FILE_FLAG_OVERLAPPED = 0x40000000 + + HANDLE_FLAG_INHERIT = 0x00000001 + STARTF_USESTDHANDLES = 0x00000100 + STARTF_USESHOWWINDOW = 0x00000001 + DUPLICATE_CLOSE_SOURCE = 0x00000001 + DUPLICATE_SAME_ACCESS = 0x00000002 + + STD_INPUT_HANDLE = -10 & (1<<32 - 1) + STD_OUTPUT_HANDLE = -11 & (1<<32 - 1) + STD_ERROR_HANDLE = -12 & (1<<32 - 1) + + FILE_BEGIN = 0 + FILE_CURRENT = 1 + FILE_END = 2 + + LANG_ENGLISH = 0x09 + SUBLANG_ENGLISH_US = 0x01 + + FORMAT_MESSAGE_ALLOCATE_BUFFER = 256 + FORMAT_MESSAGE_IGNORE_INSERTS = 512 + FORMAT_MESSAGE_FROM_STRING = 1024 + FORMAT_MESSAGE_FROM_HMODULE = 2048 + FORMAT_MESSAGE_FROM_SYSTEM = 4096 + FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192 + FORMAT_MESSAGE_MAX_WIDTH_MASK = 255 + + MAX_PATH = 260 + MAX_LONG_PATH = 32768 + + MAX_COMPUTERNAME_LENGTH = 15 + + TIME_ZONE_ID_UNKNOWN = 0 + TIME_ZONE_ID_STANDARD = 1 + + TIME_ZONE_ID_DAYLIGHT = 2 + IGNORE = 0 + INFINITE = 0xffffffff + + WAIT_TIMEOUT = 258 + WAIT_ABANDONED = 0x00000080 + WAIT_OBJECT_0 = 0x00000000 + WAIT_FAILED = 0xFFFFFFFF + + PROCESS_TERMINATE = 1 + PROCESS_QUERY_INFORMATION = 0x00000400 + SYNCHRONIZE = 0x00100000 + + FILE_MAP_COPY = 0x01 + FILE_MAP_WRITE = 0x02 + FILE_MAP_READ = 0x04 + FILE_MAP_EXECUTE = 0x20 + + CTRL_C_EVENT = 0 + CTRL_BREAK_EVENT = 1 + + // Windows reserves errors >= 1<<29 for application use. + APPLICATION_ERROR = 1 << 29 +) + +const ( + // Process creation flags. + CREATE_BREAKAWAY_FROM_JOB = 0x01000000 + CREATE_DEFAULT_ERROR_MODE = 0x04000000 + CREATE_NEW_CONSOLE = 0x00000010 + CREATE_NEW_PROCESS_GROUP = 0x00000200 + CREATE_NO_WINDOW = 0x08000000 + CREATE_PROTECTED_PROCESS = 0x00040000 + CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 + CREATE_SEPARATE_WOW_VDM = 0x00000800 + CREATE_SHARED_WOW_VDM = 0x00001000 + CREATE_SUSPENDED = 0x00000004 + CREATE_UNICODE_ENVIRONMENT = 0x00000400 + DEBUG_ONLY_THIS_PROCESS = 0x00000002 + DEBUG_PROCESS = 0x00000001 + DETACHED_PROCESS = 0x00000008 + EXTENDED_STARTUPINFO_PRESENT = 0x00080000 + INHERIT_PARENT_AFFINITY = 0x00010000 +) + +const ( + // flags for CreateToolhelp32Snapshot + TH32CS_SNAPHEAPLIST = 0x01 + TH32CS_SNAPPROCESS = 0x02 + TH32CS_SNAPTHREAD = 0x04 + TH32CS_SNAPMODULE = 0x08 + TH32CS_SNAPMODULE32 = 0x10 + TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD + TH32CS_INHERIT = 0x80000000 +) + +const ( + // filters for ReadDirectoryChangesW + FILE_NOTIFY_CHANGE_FILE_NAME = 0x001 + FILE_NOTIFY_CHANGE_DIR_NAME = 0x002 + FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x004 + FILE_NOTIFY_CHANGE_SIZE = 0x008 + FILE_NOTIFY_CHANGE_LAST_WRITE = 0x010 + FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020 + FILE_NOTIFY_CHANGE_CREATION = 0x040 + FILE_NOTIFY_CHANGE_SECURITY = 0x100 +) + +const ( + // do not reorder + FILE_ACTION_ADDED = iota + 1 + FILE_ACTION_REMOVED + FILE_ACTION_MODIFIED + FILE_ACTION_RENAMED_OLD_NAME + FILE_ACTION_RENAMED_NEW_NAME +) + +const ( + // wincrypt.h + PROV_RSA_FULL = 1 + PROV_RSA_SIG = 2 + PROV_DSS = 3 + PROV_FORTEZZA = 4 + PROV_MS_EXCHANGE = 5 + PROV_SSL = 6 + PROV_RSA_SCHANNEL = 12 + PROV_DSS_DH = 13 + PROV_EC_ECDSA_SIG = 14 + PROV_EC_ECNRA_SIG = 15 + PROV_EC_ECDSA_FULL = 16 + PROV_EC_ECNRA_FULL = 17 + PROV_DH_SCHANNEL = 18 + PROV_SPYRUS_LYNKS = 20 + PROV_RNG = 21 + PROV_INTEL_SEC = 22 + PROV_REPLACE_OWF = 23 + PROV_RSA_AES = 24 + CRYPT_VERIFYCONTEXT = 0xF0000000 + CRYPT_NEWKEYSET = 0x00000008 + CRYPT_DELETEKEYSET = 0x00000010 + CRYPT_MACHINE_KEYSET = 0x00000020 + CRYPT_SILENT = 0x00000040 + CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080 + + USAGE_MATCH_TYPE_AND = 0 + USAGE_MATCH_TYPE_OR = 1 + + X509_ASN_ENCODING = 0x00000001 + PKCS_7_ASN_ENCODING = 0x00010000 + + CERT_STORE_PROV_MEMORY = 2 + + CERT_STORE_ADD_ALWAYS = 4 + + CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004 + + CERT_TRUST_NO_ERROR = 0x00000000 + CERT_TRUST_IS_NOT_TIME_VALID = 0x00000001 + CERT_TRUST_IS_REVOKED = 0x00000004 + CERT_TRUST_IS_NOT_SIGNATURE_VALID = 0x00000008 + CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 0x00000010 + CERT_TRUST_IS_UNTRUSTED_ROOT = 0x00000020 + CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 0x00000040 + CERT_TRUST_IS_CYCLIC = 0x00000080 + CERT_TRUST_INVALID_EXTENSION = 0x00000100 + CERT_TRUST_INVALID_POLICY_CONSTRAINTS = 0x00000200 + CERT_TRUST_INVALID_BASIC_CONSTRAINTS = 0x00000400 + CERT_TRUST_INVALID_NAME_CONSTRAINTS = 0x00000800 + CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000 + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT = 0x00002000 + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000 + CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT = 0x00008000 + CERT_TRUST_IS_OFFLINE_REVOCATION = 0x01000000 + CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY = 0x02000000 + CERT_TRUST_IS_EXPLICIT_DISTRUST = 0x04000000 + CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT = 0x08000000 + + CERT_CHAIN_POLICY_BASE = 1 + CERT_CHAIN_POLICY_AUTHENTICODE = 2 + CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3 + CERT_CHAIN_POLICY_SSL = 4 + CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5 + CERT_CHAIN_POLICY_NT_AUTH = 6 + CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7 + CERT_CHAIN_POLICY_EV = 8 + + CERT_E_EXPIRED = 0x800B0101 + CERT_E_ROLE = 0x800B0103 + CERT_E_PURPOSE = 0x800B0106 + CERT_E_UNTRUSTEDROOT = 0x800B0109 + CERT_E_CN_NO_MATCH = 0x800B010F + + AUTHTYPE_CLIENT = 1 + AUTHTYPE_SERVER = 2 +) + +var ( + OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00") + OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00") + OID_SGC_NETSCAPE = []byte("2.16.840.1.113730.4.1\x00") +) + +// Invented values to support what package os expects. +type Timeval struct { + Sec int32 + Usec int32 +} + +func (tv *Timeval) Nanoseconds() int64 { + return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3 +} + +func NsecToTimeval(nsec int64) (tv Timeval) { + tv.Sec = int32(nsec / 1e9) + tv.Usec = int32(nsec % 1e9 / 1e3) + return +} + +type SecurityAttributes struct { + Length uint32 + SecurityDescriptor uintptr + InheritHandle uint32 +} + +type Overlapped struct { + Internal uintptr + InternalHigh uintptr + Offset uint32 + OffsetHigh uint32 + HEvent Handle +} + +type FileNotifyInformation struct { + NextEntryOffset uint32 + Action uint32 + FileNameLength uint32 + FileName uint16 +} + +type Filetime struct { + LowDateTime uint32 + HighDateTime uint32 +} + +// Nanoseconds returns Filetime ft in nanoseconds +// since Epoch (00:00:00 UTC, January 1, 1970). +func (ft *Filetime) Nanoseconds() int64 { + // 100-nanosecond intervals since January 1, 1601 + nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) + // change starting time to the Epoch (00:00:00 UTC, January 1, 1970) + nsec -= 116444736000000000 + // convert into nanoseconds + nsec *= 100 + return nsec +} + +func NsecToFiletime(nsec int64) (ft Filetime) { + // convert into 100-nanosecond + nsec /= 100 + // change starting time to January 1, 1601 + nsec += 116444736000000000 + // split into high / low + ft.LowDateTime = uint32(nsec & 0xffffffff) + ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff) + return ft +} + +type Win32finddata struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 + Reserved0 uint32 + Reserved1 uint32 + FileName [MAX_PATH - 1]uint16 + AlternateFileName [13]uint16 +} + +// This is the actual system call structure. +// Win32finddata is what we committed to in Go 1. +type win32finddata1 struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 + Reserved0 uint32 + Reserved1 uint32 + FileName [MAX_PATH]uint16 + AlternateFileName [14]uint16 +} + +func copyFindData(dst *Win32finddata, src *win32finddata1) { + dst.FileAttributes = src.FileAttributes + dst.CreationTime = src.CreationTime + dst.LastAccessTime = src.LastAccessTime + dst.LastWriteTime = src.LastWriteTime + dst.FileSizeHigh = src.FileSizeHigh + dst.FileSizeLow = src.FileSizeLow + dst.Reserved0 = src.Reserved0 + dst.Reserved1 = src.Reserved1 + + // The src is 1 element bigger than dst, but it must be NUL. + copy(dst.FileName[:], src.FileName[:]) + copy(dst.AlternateFileName[:], src.AlternateFileName[:]) +} + +type ByHandleFileInformation struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + VolumeSerialNumber uint32 + FileSizeHigh uint32 + FileSizeLow uint32 + NumberOfLinks uint32 + FileIndexHigh uint32 + FileIndexLow uint32 +} + +const ( + GetFileExInfoStandard = 0 + GetFileExMaxInfoLevel = 1 +) + +type Win32FileAttributeData struct { + FileAttributes uint32 + CreationTime Filetime + LastAccessTime Filetime + LastWriteTime Filetime + FileSizeHigh uint32 + FileSizeLow uint32 +} + +// ShowWindow constants +const ( + // winuser.h + SW_HIDE = 0 + SW_NORMAL = 1 + SW_SHOWNORMAL = 1 + SW_SHOWMINIMIZED = 2 + SW_SHOWMAXIMIZED = 3 + SW_MAXIMIZE = 3 + SW_SHOWNOACTIVATE = 4 + SW_SHOW = 5 + SW_MINIMIZE = 6 + SW_SHOWMINNOACTIVE = 7 + SW_SHOWNA = 8 + SW_RESTORE = 9 + SW_SHOWDEFAULT = 10 + SW_FORCEMINIMIZE = 11 +) + +type StartupInfo struct { + Cb uint32 + _ *uint16 + Desktop *uint16 + Title *uint16 + X uint32 + Y uint32 + XSize uint32 + YSize uint32 + XCountChars uint32 + YCountChars uint32 + FillAttribute uint32 + Flags uint32 + ShowWindow uint16 + _ uint16 + _ *byte + StdInput Handle + StdOutput Handle + StdErr Handle +} + +type ProcessInformation struct { + Process Handle + Thread Handle + ProcessId uint32 + ThreadId uint32 +} + +type ProcessEntry32 struct { + Size uint32 + Usage uint32 + ProcessID uint32 + DefaultHeapID uintptr + ModuleID uint32 + Threads uint32 + ParentProcessID uint32 + PriClassBase int32 + Flags uint32 + ExeFile [MAX_PATH]uint16 +} + +type Systemtime struct { + Year uint16 + Month uint16 + DayOfWeek uint16 + Day uint16 + Hour uint16 + Minute uint16 + Second uint16 + Milliseconds uint16 +} + +type Timezoneinformation struct { + Bias int32 + StandardName [32]uint16 + StandardDate Systemtime + StandardBias int32 + DaylightName [32]uint16 + DaylightDate Systemtime + DaylightBias int32 +} + +// Socket related. + +const ( + AF_UNSPEC = 0 + AF_UNIX = 1 + AF_INET = 2 + AF_INET6 = 23 + AF_NETBIOS = 17 + + SOCK_STREAM = 1 + SOCK_DGRAM = 2 + SOCK_RAW = 3 + SOCK_SEQPACKET = 5 + + IPPROTO_IP = 0 + IPPROTO_IPV6 = 0x29 + IPPROTO_TCP = 6 + IPPROTO_UDP = 17 + + SOL_SOCKET = 0xffff + SO_REUSEADDR = 4 + SO_KEEPALIVE = 8 + SO_DONTROUTE = 16 + SO_BROADCAST = 32 + SO_LINGER = 128 + SO_RCVBUF = 0x1002 + SO_SNDBUF = 0x1001 + SO_UPDATE_ACCEPT_CONTEXT = 0x700b + SO_UPDATE_CONNECT_CONTEXT = 0x7010 + + IOC_OUT = 0x40000000 + IOC_IN = 0x80000000 + IOC_VENDOR = 0x18000000 + IOC_INOUT = IOC_IN | IOC_OUT + IOC_WS2 = 0x08000000 + SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 + SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 + SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 + + // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 + + IP_TOS = 0x3 + IP_TTL = 0x4 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_LOOP = 0xb + IP_ADD_MEMBERSHIP = 0xc + IP_DROP_MEMBERSHIP = 0xd + + IPV6_V6ONLY = 0x1b + IPV6_UNICAST_HOPS = 0x4 + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_LOOP = 0xb + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_DONTROUTE = 0x4 + MSG_WAITALL = 0x8 + + MSG_TRUNC = 0x0100 + MSG_CTRUNC = 0x0200 + MSG_BCAST = 0x0400 + MSG_MCAST = 0x0800 + + SOMAXCONN = 0x7fffffff + + TCP_NODELAY = 1 + + SHUT_RD = 0 + SHUT_WR = 1 + SHUT_RDWR = 2 + + WSADESCRIPTION_LEN = 256 + WSASYS_STATUS_LEN = 128 +) + +type WSABuf struct { + Len uint32 + Buf *byte +} + +type WSAMsg struct { + Name *syscall.RawSockaddrAny + Namelen int32 + Buffers *WSABuf + BufferCount uint32 + Control WSABuf + Flags uint32 +} + +// Invented values to support what package os expects. +const ( + S_IFMT = 0x1f000 + S_IFIFO = 0x1000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFBLK = 0x6000 + S_IFREG = 0x8000 + S_IFLNK = 0xa000 + S_IFSOCK = 0xc000 + S_ISUID = 0x800 + S_ISGID = 0x400 + S_ISVTX = 0x200 + S_IRUSR = 0x100 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXUSR = 0x40 +) + +const ( + FILE_TYPE_CHAR = 0x0002 + FILE_TYPE_DISK = 0x0001 + FILE_TYPE_PIPE = 0x0003 + FILE_TYPE_REMOTE = 0x8000 + FILE_TYPE_UNKNOWN = 0x0000 +) + +type Hostent struct { + Name *byte + Aliases **byte + AddrType uint16 + Length uint16 + AddrList **byte +} + +type Protoent struct { + Name *byte + Aliases **byte + Proto uint16 +} + +const ( + DNS_TYPE_A = 0x0001 + DNS_TYPE_NS = 0x0002 + DNS_TYPE_MD = 0x0003 + DNS_TYPE_MF = 0x0004 + DNS_TYPE_CNAME = 0x0005 + DNS_TYPE_SOA = 0x0006 + DNS_TYPE_MB = 0x0007 + DNS_TYPE_MG = 0x0008 + DNS_TYPE_MR = 0x0009 + DNS_TYPE_NULL = 0x000a + DNS_TYPE_WKS = 0x000b + DNS_TYPE_PTR = 0x000c + DNS_TYPE_HINFO = 0x000d + DNS_TYPE_MINFO = 0x000e + DNS_TYPE_MX = 0x000f + DNS_TYPE_TEXT = 0x0010 + DNS_TYPE_RP = 0x0011 + DNS_TYPE_AFSDB = 0x0012 + DNS_TYPE_X25 = 0x0013 + DNS_TYPE_ISDN = 0x0014 + DNS_TYPE_RT = 0x0015 + DNS_TYPE_NSAP = 0x0016 + DNS_TYPE_NSAPPTR = 0x0017 + DNS_TYPE_SIG = 0x0018 + DNS_TYPE_KEY = 0x0019 + DNS_TYPE_PX = 0x001a + DNS_TYPE_GPOS = 0x001b + DNS_TYPE_AAAA = 0x001c + DNS_TYPE_LOC = 0x001d + DNS_TYPE_NXT = 0x001e + DNS_TYPE_EID = 0x001f + DNS_TYPE_NIMLOC = 0x0020 + DNS_TYPE_SRV = 0x0021 + DNS_TYPE_ATMA = 0x0022 + DNS_TYPE_NAPTR = 0x0023 + DNS_TYPE_KX = 0x0024 + DNS_TYPE_CERT = 0x0025 + DNS_TYPE_A6 = 0x0026 + DNS_TYPE_DNAME = 0x0027 + DNS_TYPE_SINK = 0x0028 + DNS_TYPE_OPT = 0x0029 + DNS_TYPE_DS = 0x002B + DNS_TYPE_RRSIG = 0x002E + DNS_TYPE_NSEC = 0x002F + DNS_TYPE_DNSKEY = 0x0030 + DNS_TYPE_DHCID = 0x0031 + DNS_TYPE_UINFO = 0x0064 + DNS_TYPE_UID = 0x0065 + DNS_TYPE_GID = 0x0066 + DNS_TYPE_UNSPEC = 0x0067 + DNS_TYPE_ADDRS = 0x00f8 + DNS_TYPE_TKEY = 0x00f9 + DNS_TYPE_TSIG = 0x00fa + DNS_TYPE_IXFR = 0x00fb + DNS_TYPE_AXFR = 0x00fc + DNS_TYPE_MAILB = 0x00fd + DNS_TYPE_MAILA = 0x00fe + DNS_TYPE_ALL = 0x00ff + DNS_TYPE_ANY = 0x00ff + DNS_TYPE_WINS = 0xff01 + DNS_TYPE_WINSR = 0xff02 + DNS_TYPE_NBSTAT = 0xff01 +) + +const ( + DNS_INFO_NO_RECORDS = 0x251D +) + +const ( + // flags inside DNSRecord.Dw + DnsSectionQuestion = 0x0000 + DnsSectionAnswer = 0x0001 + DnsSectionAuthority = 0x0002 + DnsSectionAdditional = 0x0003 +) + +type DNSSRVData struct { + Target *uint16 + Priority uint16 + Weight uint16 + Port uint16 + Pad uint16 +} + +type DNSPTRData struct { + Host *uint16 +} + +type DNSMXData struct { + NameExchange *uint16 + Preference uint16 + Pad uint16 +} + +type DNSTXTData struct { + StringCount uint16 + StringArray [1]*uint16 +} + +type DNSRecord struct { + Next *DNSRecord + Name *uint16 + Type uint16 + Length uint16 + Dw uint32 + Ttl uint32 + Reserved uint32 + Data [40]byte +} + +const ( + TF_DISCONNECT = 1 + TF_REUSE_SOCKET = 2 + TF_WRITE_BEHIND = 4 + TF_USE_DEFAULT_WORKER = 0 + TF_USE_SYSTEM_THREAD = 16 + TF_USE_KERNEL_APC = 32 +) + +type TransmitFileBuffers struct { + Head uintptr + HeadLength uint32 + Tail uintptr + TailLength uint32 +} + +const ( + IFF_UP = 1 + IFF_BROADCAST = 2 + IFF_LOOPBACK = 4 + IFF_POINTTOPOINT = 8 + IFF_MULTICAST = 16 +) + +const SIO_GET_INTERFACE_LIST = 0x4004747F + +// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old. +// will be fixed to change variable type as suitable. + +type SockaddrGen [24]byte + +type InterfaceInfo struct { + Flags uint32 + Address SockaddrGen + BroadcastAddress SockaddrGen + Netmask SockaddrGen +} + +type IpAddressString struct { + String [16]byte +} + +type IpMaskString IpAddressString + +type IpAddrString struct { + Next *IpAddrString + IpAddress IpAddressString + IpMask IpMaskString + Context uint32 +} + +const MAX_ADAPTER_NAME_LENGTH = 256 +const MAX_ADAPTER_DESCRIPTION_LENGTH = 128 +const MAX_ADAPTER_ADDRESS_LENGTH = 8 + +type IpAdapterInfo struct { + Next *IpAdapterInfo + ComboIndex uint32 + AdapterName [MAX_ADAPTER_NAME_LENGTH + 4]byte + Description [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte + AddressLength uint32 + Address [MAX_ADAPTER_ADDRESS_LENGTH]byte + Index uint32 + Type uint32 + DhcpEnabled uint32 + CurrentIpAddress *IpAddrString + IpAddressList IpAddrString + GatewayList IpAddrString + DhcpServer IpAddrString + HaveWins bool + PrimaryWinsServer IpAddrString + SecondaryWinsServer IpAddrString + LeaseObtained int64 + LeaseExpires int64 +} + +const MAXLEN_PHYSADDR = 8 +const MAX_INTERFACE_NAME_LEN = 256 +const MAXLEN_IFDESCR = 256 + +type MibIfRow struct { + Name [MAX_INTERFACE_NAME_LEN]uint16 + Index uint32 + Type uint32 + Mtu uint32 + Speed uint32 + PhysAddrLen uint32 + PhysAddr [MAXLEN_PHYSADDR]byte + AdminStatus uint32 + OperStatus uint32 + LastChange uint32 + InOctets uint32 + InUcastPkts uint32 + InNUcastPkts uint32 + InDiscards uint32 + InErrors uint32 + InUnknownProtos uint32 + OutOctets uint32 + OutUcastPkts uint32 + OutNUcastPkts uint32 + OutDiscards uint32 + OutErrors uint32 + OutQLen uint32 + DescrLen uint32 + Descr [MAXLEN_IFDESCR]byte +} + +type CertContext struct { + EncodingType uint32 + EncodedCert *byte + Length uint32 + CertInfo uintptr + Store Handle +} + +type CertChainContext struct { + Size uint32 + TrustStatus CertTrustStatus + ChainCount uint32 + Chains **CertSimpleChain + LowerQualityChainCount uint32 + LowerQualityChains **CertChainContext + HasRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 +} + +type CertSimpleChain struct { + Size uint32 + TrustStatus CertTrustStatus + NumElements uint32 + Elements **CertChainElement + TrustListInfo uintptr + HasRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 +} + +type CertChainElement struct { + Size uint32 + CertContext *CertContext + TrustStatus CertTrustStatus + RevocationInfo *CertRevocationInfo + IssuanceUsage *CertEnhKeyUsage + ApplicationUsage *CertEnhKeyUsage + ExtendedErrorInfo *uint16 +} + +type CertRevocationInfo struct { + Size uint32 + RevocationResult uint32 + RevocationOid *byte + OidSpecificInfo uintptr + HasFreshnessTime uint32 + FreshnessTime uint32 + CrlInfo uintptr // *CertRevocationCrlInfo +} + +type CertTrustStatus struct { + ErrorStatus uint32 + InfoStatus uint32 +} + +type CertUsageMatch struct { + Type uint32 + Usage CertEnhKeyUsage +} + +type CertEnhKeyUsage struct { + Length uint32 + UsageIdentifiers **byte +} + +type CertChainPara struct { + Size uint32 + RequestedUsage CertUsageMatch + RequstedIssuancePolicy CertUsageMatch + URLRetrievalTimeout uint32 + CheckRevocationFreshnessTime uint32 + RevocationFreshnessTime uint32 + CacheResync *Filetime +} + +type CertChainPolicyPara struct { + Size uint32 + Flags uint32 + ExtraPolicyPara uintptr +} + +type SSLExtraCertChainPolicyPara struct { + Size uint32 + AuthType uint32 + Checks uint32 + ServerName *uint16 +} + +type CertChainPolicyStatus struct { + Size uint32 + Error uint32 + ChainIndex uint32 + ElementIndex uint32 + ExtraPolicyStatus uintptr +} + +const ( + // do not reorder + HKEY_CLASSES_ROOT = 0x80000000 + iota + HKEY_CURRENT_USER + HKEY_LOCAL_MACHINE + HKEY_USERS + HKEY_PERFORMANCE_DATA + HKEY_CURRENT_CONFIG + HKEY_DYN_DATA + + KEY_QUERY_VALUE = 1 + KEY_SET_VALUE = 2 + KEY_CREATE_SUB_KEY = 4 + KEY_ENUMERATE_SUB_KEYS = 8 + KEY_NOTIFY = 16 + KEY_CREATE_LINK = 32 + KEY_WRITE = 0x20006 + KEY_EXECUTE = 0x20019 + KEY_READ = 0x20019 + KEY_WOW64_64KEY = 0x0100 + KEY_WOW64_32KEY = 0x0200 + KEY_ALL_ACCESS = 0xf003f +) + +const ( + // do not reorder + REG_NONE = iota + REG_SZ + REG_EXPAND_SZ + REG_BINARY + REG_DWORD_LITTLE_ENDIAN + REG_DWORD_BIG_ENDIAN + REG_LINK + REG_MULTI_SZ + REG_RESOURCE_LIST + REG_FULL_RESOURCE_DESCRIPTOR + REG_RESOURCE_REQUIREMENTS_LIST + REG_QWORD_LITTLE_ENDIAN + REG_DWORD = REG_DWORD_LITTLE_ENDIAN + REG_QWORD = REG_QWORD_LITTLE_ENDIAN +) + +type AddrinfoW struct { + Flags int32 + Family int32 + Socktype int32 + Protocol int32 + Addrlen uintptr + Canonname *uint16 + Addr uintptr + Next *AddrinfoW +} + +const ( + AI_PASSIVE = 1 + AI_CANONNAME = 2 + AI_NUMERICHOST = 4 +) + +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +var WSAID_CONNECTEX = GUID{ + 0x25a207b9, + 0xddf3, + 0x4660, + [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}, +} + +var WSAID_WSASENDMSG = GUID{ + 0xa441e712, + 0x754f, + 0x43ca, + [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, +} + +var WSAID_WSARECVMSG = GUID{ + 0xf689d7c8, + 0x6f1f, + 0x436b, + [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, +} + +const ( + FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 + FILE_SKIP_SET_EVENT_ON_HANDLE = 2 +) + +const ( + WSAPROTOCOL_LEN = 255 + MAX_PROTOCOL_CHAIN = 7 + BASE_PROTOCOL = 1 + LAYERED_PROTOCOL = 0 + + XP1_CONNECTIONLESS = 0x00000001 + XP1_GUARANTEED_DELIVERY = 0x00000002 + XP1_GUARANTEED_ORDER = 0x00000004 + XP1_MESSAGE_ORIENTED = 0x00000008 + XP1_PSEUDO_STREAM = 0x00000010 + XP1_GRACEFUL_CLOSE = 0x00000020 + XP1_EXPEDITED_DATA = 0x00000040 + XP1_CONNECT_DATA = 0x00000080 + XP1_DISCONNECT_DATA = 0x00000100 + XP1_SUPPORT_BROADCAST = 0x00000200 + XP1_SUPPORT_MULTIPOINT = 0x00000400 + XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800 + XP1_MULTIPOINT_DATA_PLANE = 0x00001000 + XP1_QOS_SUPPORTED = 0x00002000 + XP1_UNI_SEND = 0x00008000 + XP1_UNI_RECV = 0x00010000 + XP1_IFS_HANDLES = 0x00020000 + XP1_PARTIAL_MESSAGE = 0x00040000 + XP1_SAN_SUPPORT_SDP = 0x00080000 + + PFL_MULTIPLE_PROTO_ENTRIES = 0x00000001 + PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002 + PFL_HIDDEN = 0x00000004 + PFL_MATCHES_PROTOCOL_ZERO = 0x00000008 + PFL_NETWORKDIRECT_PROVIDER = 0x00000010 +) + +type WSAProtocolInfo struct { + ServiceFlags1 uint32 + ServiceFlags2 uint32 + ServiceFlags3 uint32 + ServiceFlags4 uint32 + ProviderFlags uint32 + ProviderId GUID + CatalogEntryId uint32 + ProtocolChain WSAProtocolChain + Version int32 + AddressFamily int32 + MaxSockAddr int32 + MinSockAddr int32 + SocketType int32 + Protocol int32 + ProtocolMaxOffset int32 + NetworkByteOrder int32 + SecurityScheme int32 + MessageSize uint32 + ProviderReserved uint32 + ProtocolName [WSAPROTOCOL_LEN + 1]uint16 +} + +type WSAProtocolChain struct { + ChainLen int32 + ChainEntries [MAX_PROTOCOL_CHAIN]uint32 +} + +type TCPKeepalive struct { + OnOff uint32 + Time uint32 + Interval uint32 +} + +type symbolicLinkReparseBuffer struct { + SubstituteNameOffset uint16 + SubstituteNameLength uint16 + PrintNameOffset uint16 + PrintNameLength uint16 + Flags uint32 + PathBuffer [1]uint16 +} + +type mountPointReparseBuffer struct { + SubstituteNameOffset uint16 + SubstituteNameLength uint16 + PrintNameOffset uint16 + PrintNameLength uint16 + PathBuffer [1]uint16 +} + +type reparseDataBuffer struct { + ReparseTag uint32 + ReparseDataLength uint16 + Reserved uint16 + + // GenericReparseBuffer + reparseBuffer byte +} + +const ( + FSCTL_GET_REPARSE_POINT = 0x900A8 + MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024 + IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 + IO_REPARSE_TAG_SYMLINK = 0xA000000C + SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 +) + +const ( + ComputerNameNetBIOS = 0 + ComputerNameDnsHostname = 1 + ComputerNameDnsDomain = 2 + ComputerNameDnsFullyQualified = 3 + ComputerNamePhysicalNetBIOS = 4 + ComputerNamePhysicalDnsHostname = 5 + ComputerNamePhysicalDnsDomain = 6 + ComputerNamePhysicalDnsFullyQualified = 7 + ComputerNameMax = 8 +) + +const ( + MOVEFILE_REPLACE_EXISTING = 0x1 + MOVEFILE_COPY_ALLOWED = 0x2 + MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 + MOVEFILE_WRITE_THROUGH = 0x8 + MOVEFILE_CREATE_HARDLINK = 0x10 + MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 +) + +const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 + +const ( + IF_TYPE_OTHER = 1 + IF_TYPE_ETHERNET_CSMACD = 6 + IF_TYPE_ISO88025_TOKENRING = 9 + IF_TYPE_PPP = 23 + IF_TYPE_SOFTWARE_LOOPBACK = 24 + IF_TYPE_ATM = 37 + IF_TYPE_IEEE80211 = 71 + IF_TYPE_TUNNEL = 131 + IF_TYPE_IEEE1394 = 144 +) + +type SocketAddress struct { + Sockaddr *syscall.RawSockaddrAny + SockaddrLength int32 +} + +type IpAdapterUnicastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterUnicastAddress + Address SocketAddress + PrefixOrigin int32 + SuffixOrigin int32 + DadState int32 + ValidLifetime uint32 + PreferredLifetime uint32 + LeaseLifetime uint32 + OnLinkPrefixLength uint8 +} + +type IpAdapterAnycastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterAnycastAddress + Address SocketAddress +} + +type IpAdapterMulticastAddress struct { + Length uint32 + Flags uint32 + Next *IpAdapterMulticastAddress + Address SocketAddress +} + +type IpAdapterDnsServerAdapter struct { + Length uint32 + Reserved uint32 + Next *IpAdapterDnsServerAdapter + Address SocketAddress +} + +type IpAdapterPrefix struct { + Length uint32 + Flags uint32 + Next *IpAdapterPrefix + Address SocketAddress + PrefixLength uint32 +} + +type IpAdapterAddresses struct { + Length uint32 + IfIndex uint32 + Next *IpAdapterAddresses + AdapterName *byte + FirstUnicastAddress *IpAdapterUnicastAddress + FirstAnycastAddress *IpAdapterAnycastAddress + FirstMulticastAddress *IpAdapterMulticastAddress + FirstDnsServerAddress *IpAdapterDnsServerAdapter + DnsSuffix *uint16 + Description *uint16 + FriendlyName *uint16 + PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte + PhysicalAddressLength uint32 + Flags uint32 + Mtu uint32 + IfType uint32 + OperStatus uint32 + Ipv6IfIndex uint32 + ZoneIndices [16]uint32 + FirstPrefix *IpAdapterPrefix + /* more fields might be present here. */ +} + +const ( + IfOperStatusUp = 1 + IfOperStatusDown = 2 + IfOperStatusTesting = 3 + IfOperStatusUnknown = 4 + IfOperStatusDormant = 5 + IfOperStatusNotPresent = 6 + IfOperStatusLowerLayerDown = 7 +) + +// Console related constants used for the mode parameter to SetConsoleMode. See +// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details. + +const ( + ENABLE_PROCESSED_INPUT = 0x1 + ENABLE_LINE_INPUT = 0x2 + ENABLE_ECHO_INPUT = 0x4 + ENABLE_WINDOW_INPUT = 0x8 + ENABLE_MOUSE_INPUT = 0x10 + ENABLE_INSERT_MODE = 0x20 + ENABLE_QUICK_EDIT_MODE = 0x40 + ENABLE_EXTENDED_FLAGS = 0x80 + ENABLE_AUTO_POSITION = 0x100 + ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200 + + ENABLE_PROCESSED_OUTPUT = 0x1 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x2 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 + DISABLE_NEWLINE_AUTO_RETURN = 0x8 + ENABLE_LVB_GRID_WORLDWIDE = 0x10 +) + +type Coord struct { + X int16 + Y int16 +} + +type SmallRect struct { + Left int16 + Top int16 + Right int16 + Bottom int16 +} + +// Used with GetConsoleScreenBuffer to retreive information about a console +// screen buffer. See +// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str +// for details. + +type ConsoleScreenBufferInfo struct { + Size Coord + CursorPosition Coord + Attributes uint16 + Window SmallRect + MaximumWindowSize Coord +} diff --git a/vendor/golang.org/x/sys/windows/types_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go new file mode 100644 index 000000000..fe0ddd031 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_386.go @@ -0,0 +1,22 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte +} + +type Servent struct { + Name *byte + Aliases **byte + Port uint16 + Proto *byte +} diff --git a/vendor/golang.org/x/sys/windows/types_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go new file mode 100644 index 000000000..7e154c2df --- /dev/null +++ b/vendor/golang.org/x/sys/windows/types_windows_amd64.go @@ -0,0 +1,22 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package windows + +type WSAData struct { + Version uint16 + HighVersion uint16 + MaxSockets uint16 + MaxUdpDg uint16 + VendorInfo *byte + Description [WSADESCRIPTION_LEN + 1]byte + SystemStatus [WSASYS_STATUS_LEN + 1]byte +} + +type Servent struct { + Name *byte + Aliases **byte + Proto *byte + Port uint16 +} diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go new file mode 100644 index 000000000..c7b3b15ea --- /dev/null +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -0,0 +1,2687 @@ +// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT + +package windows + +import ( + "syscall" + "unsafe" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modadvapi32 = NewLazySystemDLL("advapi32.dll") + modkernel32 = NewLazySystemDLL("kernel32.dll") + modshell32 = NewLazySystemDLL("shell32.dll") + modmswsock = NewLazySystemDLL("mswsock.dll") + modcrypt32 = NewLazySystemDLL("crypt32.dll") + modws2_32 = NewLazySystemDLL("ws2_32.dll") + moddnsapi = NewLazySystemDLL("dnsapi.dll") + modiphlpapi = NewLazySystemDLL("iphlpapi.dll") + modsecur32 = NewLazySystemDLL("secur32.dll") + modnetapi32 = NewLazySystemDLL("netapi32.dll") + moduserenv = NewLazySystemDLL("userenv.dll") + + procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") + procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") + procReportEventW = modadvapi32.NewProc("ReportEventW") + procOpenSCManagerW = modadvapi32.NewProc("OpenSCManagerW") + procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") + procCreateServiceW = modadvapi32.NewProc("CreateServiceW") + procOpenServiceW = modadvapi32.NewProc("OpenServiceW") + procDeleteService = modadvapi32.NewProc("DeleteService") + procStartServiceW = modadvapi32.NewProc("StartServiceW") + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procControlService = modadvapi32.NewProc("ControlService") + procStartServiceCtrlDispatcherW = modadvapi32.NewProc("StartServiceCtrlDispatcherW") + procSetServiceStatus = modadvapi32.NewProc("SetServiceStatus") + procChangeServiceConfigW = modadvapi32.NewProc("ChangeServiceConfigW") + procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW") + procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W") + procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W") + procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") + procGetLastError = modkernel32.NewProc("GetLastError") + procLoadLibraryW = modkernel32.NewProc("LoadLibraryW") + procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") + procFreeLibrary = modkernel32.NewProc("FreeLibrary") + procGetProcAddress = modkernel32.NewProc("GetProcAddress") + procGetVersion = modkernel32.NewProc("GetVersion") + procFormatMessageW = modkernel32.NewProc("FormatMessageW") + procExitProcess = modkernel32.NewProc("ExitProcess") + procCreateFileW = modkernel32.NewProc("CreateFileW") + procReadFile = modkernel32.NewProc("ReadFile") + procWriteFile = modkernel32.NewProc("WriteFile") + procSetFilePointer = modkernel32.NewProc("SetFilePointer") + procCloseHandle = modkernel32.NewProc("CloseHandle") + procGetStdHandle = modkernel32.NewProc("GetStdHandle") + procSetStdHandle = modkernel32.NewProc("SetStdHandle") + procFindFirstFileW = modkernel32.NewProc("FindFirstFileW") + procFindNextFileW = modkernel32.NewProc("FindNextFileW") + procFindClose = modkernel32.NewProc("FindClose") + procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle") + procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") + procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") + procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") + procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") + procDeleteFileW = modkernel32.NewProc("DeleteFileW") + procMoveFileW = modkernel32.NewProc("MoveFileW") + procMoveFileExW = modkernel32.NewProc("MoveFileExW") + procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") + procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime") + procGetSystemTimePreciseAsFileTime = modkernel32.NewProc("GetSystemTimePreciseAsFileTime") + procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus") + procCancelIo = modkernel32.NewProc("CancelIo") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procCreateProcessW = modkernel32.NewProc("CreateProcessW") + procOpenProcess = modkernel32.NewProc("OpenProcess") + procTerminateProcess = modkernel32.NewProc("TerminateProcess") + procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") + procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW") + procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") + procDuplicateHandle = modkernel32.NewProc("DuplicateHandle") + procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") + procGetTempPathW = modkernel32.NewProc("GetTempPathW") + procCreatePipe = modkernel32.NewProc("CreatePipe") + procGetFileType = modkernel32.NewProc("GetFileType") + procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW") + procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext") + procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom") + procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW") + procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW") + procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW") + procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") + procSetFileTime = modkernel32.NewProc("SetFileTime") + procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW") + procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW") + procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW") + procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") + procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW") + procLocalFree = modkernel32.NewProc("LocalFree") + procSetHandleInformation = modkernel32.NewProc("SetHandleInformation") + procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") + procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW") + procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW") + procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW") + procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW") + procMapViewOfFile = modkernel32.NewProc("MapViewOfFile") + procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile") + procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") + procVirtualLock = modkernel32.NewProc("VirtualLock") + procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") + procVirtualAlloc = modkernel32.NewProc("VirtualAlloc") + procVirtualFree = modkernel32.NewProc("VirtualFree") + procVirtualProtect = modkernel32.NewProc("VirtualProtect") + procTransmitFile = modmswsock.NewProc("TransmitFile") + procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") + procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") + procCertOpenStore = modcrypt32.NewProc("CertOpenStore") + procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") + procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore") + procCertCloseStore = modcrypt32.NewProc("CertCloseStore") + procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain") + procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") + procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext") + procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") + procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") + procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW") + procRegCloseKey = modadvapi32.NewProc("RegCloseKey") + procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") + procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW") + procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") + procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") + procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") + procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") + procReadConsoleW = modkernel32.NewProc("ReadConsoleW") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") + procDeviceIoControl = modkernel32.NewProc("DeviceIoControl") + procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") + procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW") + procGetCurrentThreadId = modkernel32.NewProc("GetCurrentThreadId") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateEventExW = modkernel32.NewProc("CreateEventExW") + procOpenEventW = modkernel32.NewProc("OpenEventW") + procSetEvent = modkernel32.NewProc("SetEvent") + procResetEvent = modkernel32.NewProc("ResetEvent") + procPulseEvent = modkernel32.NewProc("PulseEvent") + procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW") + procDeleteVolumeMountPointW = modkernel32.NewProc("DeleteVolumeMountPointW") + procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindFirstVolumeMountPointW = modkernel32.NewProc("FindFirstVolumeMountPointW") + procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") + procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") + procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") + procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") + procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") + procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") + procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") + procGetVolumeInformationByHandleW = modkernel32.NewProc("GetVolumeInformationByHandleW") + procGetVolumeNameForVolumeMountPointW = modkernel32.NewProc("GetVolumeNameForVolumeMountPointW") + procGetVolumePathNameW = modkernel32.NewProc("GetVolumePathNameW") + procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procQueryDosDeviceW = modkernel32.NewProc("QueryDosDeviceW") + procSetVolumeLabelW = modkernel32.NewProc("SetVolumeLabelW") + procSetVolumeMountPointW = modkernel32.NewProc("SetVolumeMountPointW") + procWSAStartup = modws2_32.NewProc("WSAStartup") + procWSACleanup = modws2_32.NewProc("WSACleanup") + procWSAIoctl = modws2_32.NewProc("WSAIoctl") + procsocket = modws2_32.NewProc("socket") + procsetsockopt = modws2_32.NewProc("setsockopt") + procgetsockopt = modws2_32.NewProc("getsockopt") + procbind = modws2_32.NewProc("bind") + procconnect = modws2_32.NewProc("connect") + procgetsockname = modws2_32.NewProc("getsockname") + procgetpeername = modws2_32.NewProc("getpeername") + proclisten = modws2_32.NewProc("listen") + procshutdown = modws2_32.NewProc("shutdown") + procclosesocket = modws2_32.NewProc("closesocket") + procAcceptEx = modmswsock.NewProc("AcceptEx") + procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") + procWSARecv = modws2_32.NewProc("WSARecv") + procWSASend = modws2_32.NewProc("WSASend") + procWSARecvFrom = modws2_32.NewProc("WSARecvFrom") + procWSASendTo = modws2_32.NewProc("WSASendTo") + procgethostbyname = modws2_32.NewProc("gethostbyname") + procgetservbyname = modws2_32.NewProc("getservbyname") + procntohs = modws2_32.NewProc("ntohs") + procgetprotobyname = modws2_32.NewProc("getprotobyname") + procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") + procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") + procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") + procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") + procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") + procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procGetACP = modkernel32.NewProc("GetACP") + procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") + procTranslateNameW = modsecur32.NewProc("TranslateNameW") + procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") + procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") + procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation") + procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree") + procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") + procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") + procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") + procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") + procGetLengthSid = modadvapi32.NewProc("GetLengthSid") + procCopySid = modadvapi32.NewProc("CopySid") + procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid") + procFreeSid = modadvapi32.NewProc("FreeSid") + procEqualSid = modadvapi32.NewProc("EqualSid") + procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership") + procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken") + procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation") + procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") +) + +func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeregisterEventSource(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CloseServiceHandle(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeleteService(service Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { + r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { + r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { + r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { + r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { + r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { + r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLastError() (lasterr error) { + r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) + if r0 != 0 { + lasterr = syscall.Errno(r0) + } + return +} + +func LoadLibrary(libname string) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return + } + return _LoadLibrary(_p0) +} + +func _LoadLibrary(libname *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(libname) + if err != nil { + return + } + return _LoadLibraryEx(_p0, zero, flags) +} + +func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FreeLibrary(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(procname) + if err != nil { + return + } + return _GetProcAddress(module, _p0) +} + +func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { + r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) + proc = uintptr(r0) + if proc == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVersion() (ver uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) + ver = uint32(r0) + if ver == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { + var _p0 *uint16 + if len(buf) > 0 { + _p0 = &buf[0] + } + r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ExitProcess(exitcode uint32) { + syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) + return +} + +func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } + r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { + r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) + newlowoffset = uint32(r0) + if newlowoffset == 0xffffffff { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CloseHandle(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetStdHandle(stdhandle uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetStdHandle(stdhandle uint32, handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func findNextFile1(handle Handle, data *win32finddata1) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindClose(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { + r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetCurrentDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { + r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func RemoveDirectory(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeleteFile(path *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func MoveFile(from *uint16, to *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetComputerName(buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetEndOfFile(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetSystemTimeAsFileTime(time *Filetime) { + syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + return +} + +func GetSystemTimePreciseAsFileTime(time *Filetime) { + syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + return +} + +func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) + rc = uint32(r0) + if rc == 0xffffffff { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CancelIo(s Handle) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CancelIoEx(s Handle, o *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { + var _p0 uint32 + if inheritHandles { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } else { + _p0 = 0 + } + r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid)) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func TerminateProcess(handle Handle, exitcode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetStartupInfo(startupInfo *StartupInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCurrentProcess() (pseudoHandle Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0) + pseudoHandle = Handle(r0) + if pseudoHandle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) { + var _p0 uint32 + if bInheritHandle { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { + r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) + event = uint32(r0) + if event == 0xffffffff { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileType(filehandle Handle) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { + r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetEnvironmentStrings() (envs *uint16, err error) { + r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) + envs = (*uint16)(unsafe.Pointer(r0)) + if envs == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FreeEnvironmentStrings(envs *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { + r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileAttributes(name *uint16) (attrs uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + attrs = uint32(r0) + if attrs == INVALID_FILE_ATTRIBUTES { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetFileAttributes(name *uint16, attrs uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { + r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCommandLine() (cmd *uint16) { + r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) + cmd = (*uint16)(unsafe.Pointer(r0)) + return +} + +func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { + r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) + argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0)) + if argv == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func LocalFree(hmem Handle) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) + handle = Handle(r0) + if handle != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FlushFileBuffers(handle Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) + addr = uintptr(r0) + if addr == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func UnmapViewOfFile(addr uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FlushViewOfFile(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualLock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualUnlock(addr uintptr, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) + value = uintptr(r0) + if value == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + var _p0 uint32 + if watchSubTree { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { + r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) + store = Handle(r0) + if store == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { + r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertCloseStore(store Handle, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { + r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertFreeCertificateChain(ctx *CertChainContext) { + syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + return +} + +func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) + context = (*CertContext)(unsafe.Pointer(r0)) + if context == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertFreeCertificateContext(ctx *CertContext) (err error) { + r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { + r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegCloseKey(key Handle) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func getCurrentProcessId() (pid uint32) { + r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + pid = uint32(r0) + return +} + +func GetConsoleMode(console Handle, mode *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetConsoleMode(console Handle, mode uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { + r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetCurrentThreadId() (id uint32) { + r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0) + id = uint32(r0) + return +} + +func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) { + var _p0 uint32 + if inheritHandle { + _p0 = 1 + } else { + _p0 = 0 + } + r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + handle = Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ResetEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func PulseEvent(event Handle) (err error) { + r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindVolumeClose(findVolume Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetDriveType(rootPathName *uint16) (driveType uint32) { + r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + driveType = uint32(r0) + return +} + +func GetLogicalDrives() (drivesBitMask uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) + drivesBitMask = uint32(r0) + if drivesBitMask == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { + r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) + if r0 != 0 { + sockerr = syscall.Errno(r0) + } + return +} + +func WSACleanup() (err error) { + r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { + r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) + handle = Handle(r0) + if handle == InvalidHandle { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { + r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { + r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { + r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func listen(s Handle, backlog int32) (err error) { + r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func shutdown(s Handle, how int32) (err error) { + r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Closesocket(s Handle) (err error) { + r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { + r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { + syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) + return +} + +func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { + r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + if r1 == socket_error { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetHostByName(name string) (h *Hostent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + return _GetHostByName(_p0) +} + +func _GetHostByName(name *byte) (h *Hostent, err error) { + r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + h = (*Hostent)(unsafe.Pointer(r0)) + if h == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetServByName(name string, proto string) (s *Servent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + var _p1 *byte + _p1, err = syscall.BytePtrFromString(proto) + if err != nil { + return + } + return _GetServByName(_p0, _p1) +} + +func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { + r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) + s = (*Servent)(unsafe.Pointer(r0)) + if s == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func Ntohs(netshort uint16) (u uint16) { + r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) + u = uint16(r0) + return +} + +func GetProtoByName(name string) (p *Protoent, err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(name) + if err != nil { + return + } + return _GetProtoByName(_p0) +} + +func _GetProtoByName(name *byte) (p *Protoent, err error) { + r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + p = (*Protoent)(unsafe.Pointer(r0)) + if p == nil { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + var _p0 *uint16 + _p0, status = syscall.UTF16PtrFromString(name) + if status != nil { + return + } + return _DnsQuery(_p0, qtype, options, extra, qrs, pr) +} + +func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { + r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) + if r0 != 0 { + status = syscall.Errno(r0) + } + return +} + +func DnsRecordListFree(rl *DNSRecord, freetype uint32) { + syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) + return +} + +func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { + r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) + same = r0 != 0 + return +} + +func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { + r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) + if r0 != 0 { + sockerr = syscall.Errno(r0) + } + return +} + +func FreeAddrInfoW(addrinfo *AddrinfoW) { + syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) + return +} + +func GetIfEntry(pIfRow *MibIfRow) (errcode error) { + r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { + r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { + r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) + n = int32(r0) + if n == -1 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { + r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetACP() (acp uint32) { + r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) + acp = uint32(r0) + return +} + +func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { + r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + nwrite = int32(r0) + if nwrite == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) + if r1&0xff == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { + r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { + r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func NetApiBufferFree(buf *byte) (neterr error) { + r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { + r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { + r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetLengthSid(sid *SID) (len uint32) { + r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + len = uint32(r0) + return +} + +func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { + r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { + r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func FreeSid(sid *SID) (err error) { + r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + if r1 != 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { + r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) + isEqual = r0 != 0 + return +} + +func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { + r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func OpenProcessToken(h Handle, access uint32, token *Token) (err error) { + r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} diff --git a/vendor/vendor.json b/vendor/vendor.json index b48f00557..40f4077af 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -233,12 +233,6 @@ "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", "revisionTime": "2018-01-10T05:50:12Z" }, - { - "checksumSHA1": "8dVO3L8yAdQ17X3lAhIziyF3OFk=", - "path": "github.com/Sirupsen/logrus", - "revision": "10f801ebc38b33738c9d17d50860f484a0988ff5", - "revisionTime": "2017-03-17T14:32:14Z" - }, { "checksumSHA1": "HttiPj314X1a0i2Jen1p6lRH/vE=", "path": "github.com/aliyun/aliyun-oss-go-sdk/oss", @@ -1075,10 +1069,10 @@ "revisionTime": "2016-02-22T16:21:17Z" }, { - "checksumSHA1": "WcXDSYIAP73RAvy22iD57nE/peI=", + "checksumSHA1": "nlJWlZ8NlDeKDaXoSFq1UM56RCs=", "path": "github.com/moul/gotty-client", - "revision": "99224eea3278d662fce9124bb2bf6c2bb39f5160", - "revisionTime": "2017-02-05T09:54:39Z" + "revision": "b26a57ebc215d2d68945184bb7e88886dfd9c66c", + "revisionTime": "2018-03-27T18:02:12Z" }, { "checksumSHA1": "gcLub3oB+u4QrOJZcYmk/y2AP4k=", @@ -1184,22 +1178,28 @@ "revisionTime": "2017-03-21T23:07:31Z" }, { - "checksumSHA1": "FFhSGe3Y3J1laR/6rwSS7U2esrk=", + "checksumSHA1": "UvMjUbtTEF0wskLTpV8grtBUh7Q=", "path": "github.com/scaleway/scaleway-cli/pkg/api", - "revision": "e50cb485747a4f25a361c90ef3ba05be79944c56", - "revisionTime": "2017-04-03T16:01:47Z" + "revision": "51d0290d9434dc6139dd89001236cfd989521a79", + "revisionTime": "2018-03-05T22:44:21Z" }, { "checksumSHA1": "kveaAmNlnvmIIuEkFcMlB+N7TqY=", "path": "github.com/scaleway/scaleway-cli/pkg/sshcommand", - "revision": "e50cb485747a4f25a361c90ef3ba05be79944c56", - "revisionTime": "2017-04-03T16:01:47Z" + "revision": "51d0290d9434dc6139dd89001236cfd989521a79", + "revisionTime": "2018-03-05T22:44:21Z" }, { - "checksumSHA1": "xM3G5ct9YYYnVIL3XMRrcf41xVw=", + "checksumSHA1": "elO1R+B5Ym3ZNA5Zht4cIE/8b0c=", "path": "github.com/scaleway/scaleway-cli/pkg/utils", - "revision": "e50cb485747a4f25a361c90ef3ba05be79944c56", - "revisionTime": "2017-04-03T16:01:47Z" + "revision": "51d0290d9434dc6139dd89001236cfd989521a79", + "revisionTime": "2018-03-05T22:44:21Z" + }, + { + "checksumSHA1": "ByFN6xh/YGP/D3DM9c8p0D9D1XM=", + "path": "github.com/sirupsen/logrus", + "revision": "90150a8ed11b6ce285e77e8af2b0109559ce4777", + "revisionTime": "2018-03-15T01:07:03Z" }, { "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", @@ -1354,10 +1354,10 @@ "revisionTime": "2017-02-08T20:51:15Z" }, { - "checksumSHA1": "xiderUuvye8Kpn7yX3niiJg32bE=", + "checksumSHA1": "BGm8lKZmvJbf/YOJLeL1rw2WVjA=", "path": "golang.org/x/crypto/ssh/terminal", - "revision": "c2303dcbe84172e0c0da4c9f083eeca54c06f298", - "revisionTime": "2017-01-17T19:20:27Z" + "revision": "88942b9c40a4c9d203b82b3731787b672d6e809b", + "revisionTime": "2018-03-21T23:38:19Z" }, { "checksumSHA1": "GtamqiJoL7PGHsN454AoffBFMa8=", @@ -1427,10 +1427,16 @@ "revisionTime": "2017-03-17T17:13:11Z" }, { - "checksumSHA1": "NzQ3QYllWwK+3GZliu11jMU6xwo=", + "checksumSHA1": "HUsOCUBC1i9oPZo0VvmawbuhGa4=", "path": "golang.org/x/sys/unix", - "revision": "c84c1ab9fd18cdd4c23dd021c10f5f46dea95e46", - "revisionTime": "2017-08-11T22:05:22Z" + "revision": "13d03a9a82fba647c21a0ef8fba44a795d0f0835", + "revisionTime": "2018-03-26T12:16:02Z" + }, + { + "checksumSHA1": "Dfz4tGItokMvHZENCsBmPPB8FGQ=", + "path": "golang.org/x/sys/windows", + "revision": "13d03a9a82fba647c21a0ef8fba44a795d0f0835", + "revisionTime": "2018-03-26T12:16:02Z" }, { "checksumSHA1": "Mr4ur60bgQJnQFfJY0dGtwWwMPE=", From 14e1c4ebee1883d8e7aa7b1d6656796d28859e2b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 28 Mar 2018 09:04:06 -0700 Subject: [PATCH 0867/1007] fix json formatting issue --- website/source/docs/builders/oracle-classic.html.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/source/docs/builders/oracle-classic.html.md b/website/source/docs/builders/oracle-classic.html.md index 30f5bfd5e..383d15409 100644 --- a/website/source/docs/builders/oracle-classic.html.md +++ b/website/source/docs/builders/oracle-classic.html.md @@ -148,6 +148,7 @@ Save this file as `windows_attributes.json`: Following is a minimal but working Packer config that references this attributes file: + ```{.json} { "variables": { @@ -163,7 +164,7 @@ file: "password": "{{ user `opc_password`}}", "identity_domain": "{{ user `opc_identity_domain`}}", "api_endpoint": "{{ user `opc_api_endpoint`}}", - "source_image_list": "/Compute-{{ user `opc_identity_domain` }}/{{ user opc_username`}}/Microsoft_Windows_Server_2012_R2-17.3.6-20170930-124649", + "source_image_list": "/Compute-{{ user `opc_identity_domain` }}/{{ user `opc_username`}}/Microsoft_Windows_Server_2012_R2-17.3.6-20170930-124649", "attributes_file": "./windows_attributes.json", "shape": "oc3", "image_name": "Packer_Windows_Demo_{{timestamp}}", From 58ecd3228994b0bd95e21a4bd2d3f21a99a7a893 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 28 Mar 2018 10:54:06 -0700 Subject: [PATCH 0868/1007] remove redundant security_protocol code from the winrm implementation of the oracle-classic provisioner --- builder/oracle/classic/step_security.go | 32 ------------------------- 1 file changed, 32 deletions(-) diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index a4b547d27..34b0d6544 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -52,26 +52,6 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste if commType == "SSH" { application = "/oracle/public/ssh" } else if commType == "WINRM" { - // Check to see whether a winRM security protocol is already defined; - // don't need to do this for SSH because it is built into the Oracle API. - protocolClient := client.SecurityProtocols() - winrmProtocol := fmt.Sprintf("WINRM_%s", runUUID) - input := compute.CreateSecurityProtocolInput{ - Name: winrmProtocol, - Description: "packer-generated protocol to allow winRM communicator", - DstPortSet: []string{"5985", "5986", "443"}, // TODO make configurable - IPProtocol: "tcp", - } - _, err = protocolClient.CreateSecurityProtocol(&input) - if err != nil { - err = fmt.Errorf("Error creating security protocol to"+ - " allow Packer to connect to Oracle instance via %s: %s", commType, err) - ui.Error(err.Error()) - state.Put("error", err) - return multistep.ActionHalt - } - state.Put("winrm_protocol", winrmProtocol) - // Check to see whether a winRM security application is already defined applicationClient := client.SecurityApplications() application = fmt.Sprintf("packer_winRM_%s", runUUID) @@ -146,18 +126,6 @@ func (s *stepSecurity) Cleanup(state multistep.StateBag) { // Some extra cleanup if we used the winRM communicator if config.Comm.Type == "winrm" { - // Delete the packer-generated protocol - protocol := state.Get("winrm_protocol").(string) - protocolClient := client.SecurityProtocols() - deleteProtocolInput := compute.DeleteSecurityProtocolInput{ - Name: namePrefix + protocol, - } - err = protocolClient.DeleteSecurityProtocol(&deleteProtocolInput) - if err != nil { - ui.Say(fmt.Sprintf("Error deleting the packer-generated winrm security protocol %s; "+ - "please delete manually. (error : %s)", protocol, err.Error())) - } - // Delete the packer-generated application application := state.Get("winrm_application").(string) applicationClient := client.SecurityApplications() From 091ac8fa5907bf47dd9d3603617b026390ee06dc Mon Sep 17 00:00:00 2001 From: "Elijah Caine M. Voigt" <Elijah.Caine.MV@gmail.com> Date: Wed, 28 Mar 2018 11:22:20 -0700 Subject: [PATCH 0869/1007] Update qemu basic example Referenced `iso_url` was a dud. Added updated iso url and md5 checksum. --- website/source/docs/builders/qemu.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index ac15772a0..91b0e09a2 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -30,8 +30,8 @@ to files, URLS for ISOs and checksums. [ { "type": "qemu", - "iso_url": "http://mirror.raystedman.net/centos/6/isos/x86_64/CentOS-6.8-x86_64-minimal.iso", - "iso_checksum": "0ca12fe5f28c2ceed4f4084b41ff8a0b", + "iso_url": "http://mirror.raystedman.net/centos/6/isos/x86_64/CentOS-6.9-x86_64-minimal.iso", + "iso_checksum": "af4a1640c0c6f348c6c41f1ea9e192a2", "iso_checksum_type": "md5", "output_directory": "output_centos_tdhtest", "shutdown_command": "shutdown -P now", From 16d044b3987f3bd91bb7dfe5f9e5455e75e3b75a Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 28 Mar 2018 13:27:41 -0700 Subject: [PATCH 0870/1007] add user data and user data file to oracle oci builder --- builder/oracle/oci/config.go | 30 ++++++++++++++++++++++++++++++ builder/oracle/oci/driver_oci.go | 3 +++ 2 files changed, 33 insertions(+) diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 881ed1e35..3af6dcbdf 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -1,8 +1,11 @@ package oci import ( + "encoding/base64" "errors" "fmt" + "io/ioutil" + "log" "os" "path/filepath" @@ -41,6 +44,9 @@ type Config struct { BaseImageID string `mapstructure:"base_image_ocid"` Shape string `mapstructure:"shape"` ImageName string `mapstructure:"image_name"` + // UserData and UserDataFile file are both optional and mutually exclusive. + UserData string `mapstructure:"user_data"` + UserDataFile string `mapstructure:"user_data_file"` // Networking SubnetID string `mapstructure:"subnet_ocid"` @@ -195,6 +201,30 @@ func NewConfig(raws ...interface{}) (*Config, error) { } } + // Optional UserData config + if c.UserData != "" && c.UserDataFile != "" { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) + } else if c.UserDataFile != "" { + if _, err := os.Stat(c.UserDataFile); err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile)) + } + } + // read UserDataFile into string. + if c.UserDataFile != "" { + fiData, err := ioutil.ReadFile(c.UserDataFile) + if err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("Problem reading user_data_file: %s", err)) + } + c.UserData = string(fiData) + } + // Test if UserData is encoded already, and if not, encode it + if c.UserData != "" { + if _, err := base64.StdEncoding.DecodeString(c.UserData); err != nil { + log.Printf("[DEBUG] base64 encoding user data...") + c.UserData = base64.StdEncoding.EncodeToString([]byte(c.UserData)) + } + } + if errs != nil && len(errs.Errors) > 0 { return nil, errs } diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index ead05a12d..1b6b0a3f9 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -35,6 +35,9 @@ func (d *driverOCI) CreateInstance(publicKey string) (string, error) { "ssh_authorized_keys": publicKey, }, } + if d.cfg.UserData != "" { + params.Metadata["user_data"] = d.cfg.UserData + } instance, err := d.client.Compute.Instances.Launch(params) if err != nil { return "", err From 56af8852124685066fc3976606d6b10b470ee2ea Mon Sep 17 00:00:00 2001 From: Omer Katz <omer.drow@gmail.com> Date: Thu, 29 Mar 2018 14:51:02 +0300 Subject: [PATCH 0871/1007] Avoid warning when using raw format. When using the raw image format and attempting to resize it we get the following error message: ``` WARNING: Image format was not specified for 'test.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. ``` Specifying the format will remove this warning. --- builder/qemu/step_resize_disk.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/qemu/step_resize_disk.go b/builder/qemu/step_resize_disk.go index 8ffab5931..f4f44ec34 100644 --- a/builder/qemu/step_resize_disk.go +++ b/builder/qemu/step_resize_disk.go @@ -21,6 +21,7 @@ func (s *stepResizeDisk) Run(_ context.Context, state multistep.StateBag) multis command := []string{ "resize", + "-f", config.Format, path, fmt.Sprintf("%vM", config.DiskSize), } From 3ffaf551c08b69dd0e00715bbb37199e4e6482b4 Mon Sep 17 00:00:00 2001 From: Hannu Piki <hannu.piki@sympa.com> Date: Thu, 29 Mar 2018 18:31:19 +0300 Subject: [PATCH 0872/1007] Fixing Hyper-V ISO builder CopyExportedVirtualMachine PowerShell Script wasn't able to handle path that Packer used to create VM in the first place: "==> hyperv-iso: Copying to output dir... ==> hyperv-iso: Error exporting vm: PowerShell error: Move-Item : An object at the specified path C:\Users\HANNU~1.PIK does not exist. ==> hyperv-iso: At C:\Users\hannu.piki\AppData\Local\Temp\ps520830935.ps1:13 char:1 ==> hyperv-iso: + Move-Item -Path "$srcPath/$vhdDirName" -Destination $dstPath -Verbose ==> hyperv-iso: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ==> hyperv-iso: + CategoryInfo : InvalidArgument: (:) [Move-Item], PSArgumentException ==> hyperv-iso: + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.MoveItemCommand" Used path was: C:\Users\HANNU~1.PIK\AppData\Local\Temp\packerhv616791918\export253729206\2016min Real path was: C:\Users\hannu.piki\AppData\Local\Temp\packerhv616791918\export253729206\2016min --- common/powershell/hyperv/hyperv.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index d5b58f5db..f1dfc940c 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -649,9 +649,9 @@ func CopyExportedVirtualMachine(expPath string, outputPath string, vhdDir string var script = ` param([string]$srcPath, [string]$dstPath, [string]$vhdDirName, [string]$vmDir) -Move-Item -Path $srcPath/*.* -Destination $dstPath -Move-Item -Path $srcPath/$vhdDirName -Destination $dstPath -Move-Item -Path $srcPath/$vmDir -Destination $dstPath +Move-Item -Path (Join-Path (Get-Item $srcPath).FullName "*.*") -Destination $dstPath +Move-Item -Path (Join-Path (Get-Item $srcPath).FullName $vhdDirName) -Destination $dstPath +Move-Item -Path (Join-Path (Get-Item $srcPath).FullName $vmDir) -Destination $dstPath ` var ps powershell.PowerShellCmd From 646523c5f4e2dd1791160434df557b7427288a09 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 29 Mar 2018 13:04:25 -0500 Subject: [PATCH 0873/1007] Replaced the call to os.Open and ReadNetworkMap to just a single call to ReadNetmapConfig in both the Workstation9 and Player5 VMware drivers. --- builder/vmware/common/driver_player5.go | 9 ++------- builder/vmware/common/driver_workstation9.go | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/builder/vmware/common/driver_player5.go b/builder/vmware/common/driver_player5.go index fb14dcb52..5f492e6be 100644 --- a/builder/vmware/common/driver_player5.go +++ b/builder/vmware/common/driver_player5.go @@ -201,14 +201,9 @@ func (d *Player5Driver) Verify() error { if _, err := os.Stat(pathNetmap); err != nil { return nil, fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } + log.Printf("Located networkmapper configuration file using Player: %s", pathNetmap) - fd, err := os.Open(pathNetmap) - if err != nil { - return nil, err - } - defer fd.Close() - - return ReadNetworkMap(fd) + return ReadNetmapConfig(pathNetmap) } return nil } diff --git a/builder/vmware/common/driver_workstation9.go b/builder/vmware/common/driver_workstation9.go index 25b4ddd2c..8186ac83f 100644 --- a/builder/vmware/common/driver_workstation9.go +++ b/builder/vmware/common/driver_workstation9.go @@ -162,14 +162,9 @@ func (d *Workstation9Driver) Verify() error { if _, err := os.Stat(pathNetmap); err != nil { return nil, fmt.Errorf("Could not find netmap conf file: %s", pathNetmap) } + log.Printf("Located networkmapper configuration file using Workstation: %s", pathNetmap) - fd, err := os.Open(pathNetmap) - if err != nil { - return nil, err - } - defer fd.Close() - - return ReadNetworkMap(fd) + return ReadNetmapConfig(pathNetmap) } return nil } From 6e176f97a0dfb6666023a36c2549f9f8d728a57a Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Thu, 29 Mar 2018 13:06:41 -0500 Subject: [PATCH 0874/1007] Added logs to all of the VMware drivers that emits each detected network device that gets enumerated for a network. --- builder/vmware/common/driver.go | 19 +++++++++++++++++++ builder/vmware/common/driver_fusion5.go | 2 ++ builder/vmware/common/driver_fusion6.go | 1 + 3 files changed, 22 insertions(+) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index 47dc6e8b6..fb69b015d 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -296,6 +296,7 @@ func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string, error) { return "", errors.New("couldn't find MAC address in VMX") } } + log.Printf("GuestAddress: Found MAC address in VMX: %s", macAddress) res, err := net.ParseMAC(macAddress) if err != nil { @@ -317,6 +318,11 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { network := state.Get("vmnetwork").(string) devices, err := netmap.NameIntoDevices(network) + // log them to see what was detected + for _, device := range devices { + log.Printf("GuestIP(%s): Discovered device: %s", network, device) + } + // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration if err != nil || network == "custom" { @@ -332,6 +338,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { if err != nil { return "", err } + log.Printf("GuestIP(%s): Discovered custom device: %s", network, device) } // figure out our MAC address for looking up the guest address @@ -415,6 +422,11 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { network := state.Get("vmnetwork").(string) devices, err := netmap.NameIntoDevices(network) + // log them to see what was detected + for _, device := range devices { + log.Printf("HostAddress(%s): Discovered device: %s", network, device) + } + // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration if err != nil || network == "custom" { @@ -430,6 +442,7 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { if err != nil { return "", err } + log.Printf("HostAddress(%s): Discovered custom device: %s", network, device) } var lastError error @@ -488,6 +501,11 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { network := state.Get("vmnetwork").(string) devices, err := netmap.NameIntoDevices(network) + // log them to see what was detected + for _, device := range devices { + log.Printf("HostIP(%s): Discovered device: %s", network, device) + } + // we were unable to find the device, maybe it's a custom one... // so, check to see if it's in the .vmx configuration if err != nil || network == "custom" { @@ -503,6 +521,7 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { if err != nil { return "", err } + log.Printf("HostIP(%s): Discovered custom device: %s", network, device) } var lastError error diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index 9c81efd4a..bfc7803e7 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -3,6 +3,7 @@ package common import ( "errors" "fmt" + "log" "io/ioutil" "os" "os/exec" @@ -157,6 +158,7 @@ func (d *Fusion5Driver) Verify() error { if _, err := os.Stat(pathNetworking); err != nil { return nil, fmt.Errorf("Could not find networking conf file: %s", pathNetworking) } + log.Printf("Located networkmapper configuration file using Fusion5: %s", pathNetworking) fd, err := os.Open(pathNetworking) if err != nil { diff --git a/builder/vmware/common/driver_fusion6.go b/builder/vmware/common/driver_fusion6.go index 1f959d35d..002d4227a 100644 --- a/builder/vmware/common/driver_fusion6.go +++ b/builder/vmware/common/driver_fusion6.go @@ -83,6 +83,7 @@ func (d *Fusion6Driver) Verify() error { if _, err := os.Stat(pathNetworking); err != nil { return nil, fmt.Errorf("Could not find networking conf file: %s", pathNetworking) } + log.Printf("Located networkmapper configuration file using Fusion6: %s", pathNetworking) fd, err := os.Open(pathNetworking) if err != nil { From 832f390733348766340603630c46821d1c0e8a4a Mon Sep 17 00:00:00 2001 From: Stefan Scherer <scherer_stefan@icloud.com> Date: Thu, 29 Mar 2018 22:46:59 +0200 Subject: [PATCH 0875/1007] Set tar header format to tar.FormatGNU --- post-processor/vagrant/util.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index de80912bb..d7597f74a 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -126,6 +126,11 @@ func DirToBox(dst, dir string, ui packer.Ui, level int) error { return err } + // We have to set the Format explicitly because of a bug in + // libarchive. This affects eg. the tar in macOS listing huge + // files with zero byte length. + header.Format = tar.FormatGNU + // We have to set the Name explicitly because it is supposed to // be a relative path to the root. Otherwise, the tar ends up // being a bunch of files in the root, even if they're actually From 742e366367f13946554310d54e406f9ca231e4ee Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 29 Mar 2018 14:21:54 -0700 Subject: [PATCH 0876/1007] conditionally set tar header on go >= 1.10 --- post-processor/vagrant/tar_fix.go | 9 +++++++++ post-processor/vagrant/tar_fix_go110.go | 12 ++++++++++++ post-processor/vagrant/util.go | 6 ++---- 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 post-processor/vagrant/tar_fix.go create mode 100644 post-processor/vagrant/tar_fix_go110.go diff --git a/post-processor/vagrant/tar_fix.go b/post-processor/vagrant/tar_fix.go new file mode 100644 index 000000000..32f05d933 --- /dev/null +++ b/post-processor/vagrant/tar_fix.go @@ -0,0 +1,9 @@ +// +build !go1.10 + +package vagrant + +import "archive/tar" + +func setHeaderFormat(header *tar.Header) { + // no-op +} diff --git a/post-processor/vagrant/tar_fix_go110.go b/post-processor/vagrant/tar_fix_go110.go new file mode 100644 index 000000000..e9092ac08 --- /dev/null +++ b/post-processor/vagrant/tar_fix_go110.go @@ -0,0 +1,12 @@ +// +build go1.10 + +package vagrant + +import "archive/tar" + +func setHeaderFormat(header *tar.Header) { + // We have to set the Format explicitly because of a bug in + // libarchive. This affects eg. the tar in macOS listing huge + // files with zero byte length. + header.Format = tar.FormatGNU +} diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index d7597f74a..defc3e302 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -126,10 +126,8 @@ func DirToBox(dst, dir string, ui packer.Ui, level int) error { return err } - // We have to set the Format explicitly because of a bug in - // libarchive. This affects eg. the tar in macOS listing huge - // files with zero byte length. - header.Format = tar.FormatGNU + // workaround for large archive formats on go >=1.10 + setHeaderFormat(header) // We have to set the Name explicitly because it is supposed to // be a relative path to the root. Otherwise, the tar ends up From 60986ae6826e9582a8b6b6931498eb6f7d81a527 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 29 Mar 2018 16:18:55 -0700 Subject: [PATCH 0877/1007] better comment about why gnu tar --- post-processor/vagrant/util.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index defc3e302..55c89ae5c 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -126,7 +126,8 @@ func DirToBox(dst, dir string, ui packer.Ui, level int) error { return err } - // workaround for large archive formats on go >=1.10 + // go >=1.10 wants to use GNU tar format to workaround issues in + // libarchive < 3.3.2 setHeaderFormat(header) // We have to set the Name explicitly because it is supposed to From 3f94a49b7026765de7596ed059fb3496e729ef25 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 29 Mar 2018 16:21:49 -0700 Subject: [PATCH 0878/1007] update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e66d470f7..6aabaee88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## (UNRELEASED) + +### BUG FIXES: +* post-processor/vagrant: Large VMDKs should no longer show a 0-byte size on OS X. [GH-6084] + ## 1.2.2 (March 26, 2018) ### BUG FIXES: From 3cfbec623a149da5e3c24e2301bcad89583bca4d Mon Sep 17 00:00:00 2001 From: Mykola Marzhan <mykola.marzhan@percona.com> Date: Fri, 30 Mar 2018 09:23:31 +0300 Subject: [PATCH 0879/1007] handle multiple Azure accounts correctly --- contrib/azure-setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 8ccd0cbc0..6149b38d0 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -85,9 +85,9 @@ askSubscription() { if [ "$azure_subscription_id" != "" ]; then az account set --subscription $azure_subscription_id else - azure_subscription_id=$(az account list | jq -r .[].id) + azure_subscription_id=$(az account list | jq -r '.[] | select(.isDefault==true) | .id') fi - azure_tenant_id=$(az account list | jq -r '.[] | select(.tenantId) | .tenantId') + azure_tenant_id=$(az account list | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') echo "Using subscription_id: $azure_subscription_id" echo "Using tenant_id: $azure_tenant_id" } From 507b3619e7ef8c62c4be4cda09149890e8236b98 Mon Sep 17 00:00:00 2001 From: ADO <ado@oxalide.com> Date: Fri, 30 Mar 2018 10:47:11 +0200 Subject: [PATCH 0880/1007] Expose more source ami data in the template --- .../amazon/common/interpolate_build_info.go | 34 +++++++++++++++++-- builder/amazon/common/step_create_tags.go | 11 ++---- .../common/step_modify_ami_attributes.go | 12 +------ .../amazon/common/step_run_source_instance.go | 6 ++-- .../amazon/common/step_run_spot_instance.go | 4 +-- builder/amazon/common/tags.go | 9 +++-- .../amazon/ebsvolume/step_tag_ebs_volumes.go | 3 +- 7 files changed, 45 insertions(+), 34 deletions(-) diff --git a/builder/amazon/common/interpolate_build_info.go b/builder/amazon/common/interpolate_build_info.go index a279a2f72..b141bc9d4 100644 --- a/builder/amazon/common/interpolate_build_info.go +++ b/builder/amazon/common/interpolate_build_info.go @@ -1,6 +1,36 @@ package common +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" +) + type BuildInfoTemplate struct { - SourceAMI string - BuildRegion string + BuildRegion string + SourceAMI string + SourceAMIName string + SourceAMITags map[string]string +} + +func extractBuildInfo(region string, state multistep.StateBag) *BuildInfoTemplate { + rawSourceAMI, hasSourceAMI := state.GetOk("source_image") + if !hasSourceAMI { + return &BuildInfoTemplate{ + BuildRegion: region, + } + } + + sourceAMI := rawSourceAMI.(*ec2.Image) + sourceAMITags := make(map[string]string, len(sourceAMI.Tags)) + for _, tag := range sourceAMI.Tags { + sourceAMITags[aws.StringValue(tag.Key)] = aws.StringValue(tag.Value) + } + + return &BuildInfoTemplate{ + BuildRegion: region, + SourceAMI: aws.StringValue(sourceAMI.ImageId), + SourceAMIName: aws.StringValue(sourceAMI.Name), + SourceAMITags: sourceAMITags, + } } diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 96177c8a8..95a736a6b 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -26,13 +26,6 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) - var sourceAMI string - if rawSourceAMI, hasSourceAMI := state.GetOk("source_image"); hasSourceAMI { - sourceAMI = *rawSourceAMI.(*ec2.Image).ImageId - } else { - sourceAMI = "" - } - if !s.Tags.IsSet() && !s.SnapshotTags.IsSet() { return multistep.ActionContinue } @@ -79,7 +72,7 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis // Convert tags to ec2.Tag format ui.Say("Creating AMI tags") - amiTags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, sourceAMI) + amiTags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -88,7 +81,7 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis amiTags.Report(ui) ui.Say("Creating snapshot tags") - snapshotTags, err := s.SnapshotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, sourceAMI) + snapshotTags, err := s.SnapshotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index 26ab31986..234e1762a 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -27,13 +27,6 @@ func (s *StepModifyAMIAttributes) Run(_ context.Context, state multistep.StateBa session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) - - var sourceAMI string - if rawSourceAMI, hasSourceAMI := state.GetOk("source_image"); hasSourceAMI { - sourceAMI = *rawSourceAMI.(*ec2.Image).ImageId - } else { - sourceAMI = "" - } snapshots := state.Get("snapshots").(map[string][]string) // Determine if there is any work to do. @@ -50,10 +43,7 @@ func (s *StepModifyAMIAttributes) Run(_ context.Context, state multistep.StateBa } var err error - s.Ctx.Data = &BuildInfoTemplate{ - SourceAMI: sourceAMI, - BuildRegion: *ec2conn.Config.Region, - } + s.Ctx.Data = extractBuildInfo(*ec2conn.Config.Region, state) s.Description, err = interpolate.Render(s.Description, &s.Ctx) if err != nil { err = fmt.Errorf("Error interpolating AMI description: %s", err) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 761e6f09c..8542e9387 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -88,7 +88,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) s.Tags["Name"] = "Packer Builder" } - ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source instance: %s", err) state.Put("error", err) @@ -96,7 +96,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) return multistep.ActionHalt } - volTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + volTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging volumes: %s", err) state.Put("error", err) @@ -259,7 +259,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) if len(volumeIds) > 0 && s.VolumeTags.IsSet() { ui.Say("Adding tags to source EBS Volumes") - volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) state.Put("error", err) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 0f08ea90b..d90dd391a 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -143,7 +143,7 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m s.Tags["Name"] = "Packer Builder" } - ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source instance: %s", err) state.Put("error", err) @@ -287,7 +287,7 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m if len(volumeIds) > 0 && s.VolumeTags.IsSet() { ui.Say("Adding tags to source EBS Volumes") - volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) state.Put("error", err) diff --git a/builder/amazon/common/tags.go b/builder/amazon/common/tags.go index 3c257e10f..918269f91 100644 --- a/builder/amazon/common/tags.go +++ b/builder/amazon/common/tags.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" ) @@ -23,12 +24,10 @@ func (t TagMap) IsSet() bool { return len(t) > 0 } -func (t TagMap) EC2Tags(ctx interpolate.Context, region, sourceAMIID string) (EC2Tags, error) { +func (t TagMap) EC2Tags(ctx interpolate.Context, region string, state multistep.StateBag) (EC2Tags, error) { var ec2Tags []*ec2.Tag - ctx.Data = &BuildInfoTemplate{ - SourceAMI: sourceAMIID, - BuildRegion: region, - } + ctx.Data = extractBuildInfo(region, state) + for key, value := range t { interpolatedKey, err := interpolate.Render(key, &ctx) if err != nil { diff --git a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go index 31e6799b1..62a84146c 100644 --- a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go +++ b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go @@ -18,7 +18,6 @@ type stepTagEBSVolumes struct { func (s *stepTagEBSVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) - sourceAMI := state.Get("source_image").(*ec2.Image) ui := state.Get("ui").(packer.Ui) volumes := make(EbsVolumes) @@ -43,7 +42,7 @@ func (s *stepTagEBSVolumes) Run(_ context.Context, state multistep.StateBag) mul continue } - tags, err := mapping.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, *sourceAMI.ImageId) + tags, err := mapping.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging device %s with %s", mapping.DeviceName, err) state.Put("error", err) From 04790695e6bee55ab3368e4b2fd069c365da06fa Mon Sep 17 00:00:00 2001 From: ADO <ado@oxalide.com> Date: Fri, 30 Mar 2018 16:46:35 +0200 Subject: [PATCH 0881/1007] Add interpolate_build_info_test tests --- .../common/interpolate_build_info_test.go | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 builder/amazon/common/interpolate_build_info_test.go diff --git a/builder/amazon/common/interpolate_build_info_test.go b/builder/amazon/common/interpolate_build_info_test.go new file mode 100644 index 000000000..7391fcd5d --- /dev/null +++ b/builder/amazon/common/interpolate_build_info_test.go @@ -0,0 +1,63 @@ +package common + +import ( + "reflect" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" +) + +func testImage() *ec2.Image { + return &ec2.Image{ + ImageId: aws.String("ami-abcd1234"), + Name: aws.String("ami_test_name"), + Tags: []*ec2.Tag{ + { + Key: aws.String("key-1"), + Value: aws.String("value-1"), + }, + { + Key: aws.String("key-2"), + Value: aws.String("value-2"), + }, + }, + } +} + +func testState() multistep.StateBag { + state := new(multistep.BasicStateBag) + return state +} + +func TestInterpolateBuildInfo_extractBuildInfo_noSourceImage(t *testing.T) { + state := testState() + buildInfo := extractBuildInfo("foo", state) + + expected := BuildInfoTemplate{ + BuildRegion: "foo", + } + if !reflect.DeepEqual(*buildInfo, expected) { + t.Fatalf("Unexpected BuildInfoTemplate: expected %#v got %#v\n", expected, *buildInfo) + } +} + +func TestInterpolateBuildInfo_extractBuildInfo_withSourceImage(t *testing.T) { + state := testState() + state.Put("source_image", testImage()) + buildInfo := extractBuildInfo("foo", state) + + expected := BuildInfoTemplate{ + BuildRegion: "foo", + SourceAMI: "ami-abcd1234", + SourceAMIName: "ami_test_name", + SourceAMITags: map[string]string{ + "key-1": "value-1", + "key-2": "value-2", + }, + } + if !reflect.DeepEqual(*buildInfo, expected) { + t.Fatalf("Unexpected BuildInfoTemplate: expected %#v got %#v\n", expected, *buildInfo) + } +} From ec5eba82cc27e380820b80e664eb6fcff3127d8f Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Fri, 30 Mar 2018 10:57:40 -0700 Subject: [PATCH 0882/1007] add docs for user_data_file and user_data to oracle-oci builder page --- website/source/docs/builders/oracle-oci.html.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/website/source/docs/builders/oracle-oci.html.md b/website/source/docs/builders/oracle-oci.html.md index ea4b08404..4329a56f5 100644 --- a/website/source/docs/builders/oracle-oci.html.md +++ b/website/source/docs/builders/oracle-oci.html.md @@ -125,6 +125,15 @@ builder. - `use_private_ip` (boolean) - Use private ip addresses to connect to the instance via ssh. + - `user_data` (string) - user_data to be used by cloud + init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Generally speaking, it is easier to use the `user_data_file`, + but you can use this option to put either the platintext data or the base64 + encoded data directly into your Packer config. + + - `user_data_file` (string) - Path to a file to be used as user_data by cloud + init. See [the Oracle docs](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/LaunchInstanceDetails) for more details. Example: + `"user_data_file": "./boot_config/myscript.sh"` + ## Basic Example From 0533e1ad9c24262bcdafc17d6800c8005555e71b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 30 Mar 2018 13:01:48 -0700 Subject: [PATCH 0883/1007] Validate destination image name. --- builder/oracle/classic/config.go | 7 +++++++ builder/oracle/classic/config_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index a483c8e50..78fb42085 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/url" "os" + "regexp" "time" "github.com/hashicorp/packer/common" @@ -94,6 +95,12 @@ func NewConfig(raws ...interface{}) (*Config, error) { } } + // Object names can contain only alphanumeric characters, hyphens, underscores, and periods + reValidObject := regexp.MustCompile("^[a-zA-Z0-9-._/]+$") + if !reValidObject.MatchString(c.DestImageList) { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("dest_image_list can contain only alphanumeric characters, hyphens, underscores, and periods.")) + } + if c.Attributes != "" && c.AttributesFile != "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) } else if c.AttributesFile != "" { diff --git a/builder/oracle/classic/config_test.go b/builder/oracle/classic/config_test.go index 214365731..7351af0d3 100644 --- a/builder/oracle/classic/config_test.go +++ b/builder/oracle/classic/config_test.go @@ -2,6 +2,8 @@ package classic import ( "testing" + + "github.com/stretchr/testify/assert" ) func testConfig() map[string]interface{} { @@ -59,3 +61,25 @@ func TestValidationsIgnoresOptional(t *testing.T) { t.Fatalf("Shouldn't care if ssh_username is missing: err: %#v", err.Error()) } } + +func TestConfigValidatesObjects(t *testing.T) { + var objectTests = []struct { + object string + valid bool + }{ + {"foo-BAR.0_9", true}, + {"%", false}, + {"Matt...?", false}, + {"/Config-thing/myuser/myimage", true}, + } + for _, tt := range objectTests { + tc := testConfig() + tc["dest_image_list"] = tt.object + _, err := NewConfig(tc) + if tt.valid { + assert.NoError(t, err, tt.object) + } else { + assert.Error(t, err, tt.object) + } + } +} From 7e9699675f45b1b5a241e4821c61d49c24525222 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 30 Mar 2018 18:13:02 -0500 Subject: [PATCH 0884/1007] Modified device matching logs to look more consistent. --- builder/vmware/common/driver.go | 14 +++++++------- builder/vmware/common/driver_fusion5.go | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/builder/vmware/common/driver.go b/builder/vmware/common/driver.go index fb69b015d..8ceb393ff 100644 --- a/builder/vmware/common/driver.go +++ b/builder/vmware/common/driver.go @@ -296,7 +296,7 @@ func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string, error) { return "", errors.New("couldn't find MAC address in VMX") } } - log.Printf("GuestAddress: Found MAC address in VMX: %s", macAddress) + log.Printf("GuestAddress found MAC address in VMX: %s", macAddress) res, err := net.ParseMAC(macAddress) if err != nil { @@ -320,7 +320,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { // log them to see what was detected for _, device := range devices { - log.Printf("GuestIP(%s): Discovered device: %s", network, device) + log.Printf("GuestIP discovered device matching %s: %s", network, device) } // we were unable to find the device, maybe it's a custom one... @@ -338,7 +338,7 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) { if err != nil { return "", err } - log.Printf("GuestIP(%s): Discovered custom device: %s", network, device) + log.Printf("GuestIP discovered custom device matching %s: %s", network, device) } // figure out our MAC address for looking up the guest address @@ -424,7 +424,7 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { // log them to see what was detected for _, device := range devices { - log.Printf("HostAddress(%s): Discovered device: %s", network, device) + log.Printf("HostAddress discovered device matching %s: %s", network, device) } // we were unable to find the device, maybe it's a custom one... @@ -442,7 +442,7 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) { if err != nil { return "", err } - log.Printf("HostAddress(%s): Discovered custom device: %s", network, device) + log.Printf("HostAddress discovered custom device matching %s: %s", network, device) } var lastError error @@ -503,7 +503,7 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { // log them to see what was detected for _, device := range devices { - log.Printf("HostIP(%s): Discovered device: %s", network, device) + log.Printf("HostIP discovered device matching %s: %s", network, device) } // we were unable to find the device, maybe it's a custom one... @@ -521,7 +521,7 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) { if err != nil { return "", err } - log.Printf("HostIP(%s): Discovered custom device: %s", network, device) + log.Printf("HostIP discovered custom device matching %s: %s", network, device) } var lastError error diff --git a/builder/vmware/common/driver_fusion5.go b/builder/vmware/common/driver_fusion5.go index bfc7803e7..63211f99a 100644 --- a/builder/vmware/common/driver_fusion5.go +++ b/builder/vmware/common/driver_fusion5.go @@ -3,8 +3,8 @@ package common import ( "errors" "fmt" - "log" "io/ioutil" + "log" "os" "os/exec" "path/filepath" From 2c2904c0958be0dfb9ef800480685dcf01a3be9d Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago <arizvisa@gmail.com> Date: Fri, 30 Mar 2018 18:19:25 -0500 Subject: [PATCH 0885/1007] Modified the path finders for the Player driver in the vmware-builders to search through all the possible variations for dhcp configuration and leases.. --- builder/vmware/common/driver_player_unix.go | 39 +++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/builder/vmware/common/driver_player_unix.go b/builder/vmware/common/driver_player_unix.go index 068720a6c..a963c60fa 100644 --- a/builder/vmware/common/driver_player_unix.go +++ b/builder/vmware/common/driver_player_unix.go @@ -7,6 +7,7 @@ import ( "bytes" "fmt" "log" + "os" "os/exec" "path/filepath" "regexp" @@ -44,7 +45,24 @@ func playerDhcpLeasesPath(device string) string { log.Printf("Error finding VMware root: %s", err) return "" } - return filepath.Join(base, device, "dhcpd/dhcpd.leases") + + // Build the base path to VMware configuration for specified device: `/etc/vmware/${device}` + devicebase := filepath.Join(base, device) + + // Walk through a list of paths searching for the correct permutation... + // ...as it appears that in >= WS14 and < WS14, the leases file may be labelled differently. + + // Docs say we should expect: dhcpd/dhcpd.leases + paths := []string{"dhcpd/dhcpd.leases", "dhcpd/dhcp.leases", "dhcp/dhcpd.leases", "dhcp/dhcp.leases"} + for _, p := range paths { + fp := filepath.Join(devicebase, p) + if _, err := os.Stat(fp); !os.IsNotExist(err) { + return fp + } + } + + log.Printf("Error finding VMWare DHCP Server Leases (dhcpd.leases) under device path: %s", devicebase) + return "" } func playerVmDhcpConfPath(device string) string { @@ -53,7 +71,24 @@ func playerVmDhcpConfPath(device string) string { log.Printf("Error finding VMware root: %s", err) return "" } - return filepath.Join(base, device, "dhcp/dhcp.conf") + + // Build the base path to VMware configuration for specified device: `/etc/vmware/${device}` + devicebase := filepath.Join(base, device) + + // Walk through a list of paths searching for the correct permutation... + // ...as it appears that in >= WS14 and < WS14, the dhcp config may be labelled differently. + + // Docs say we should expect: dhcp/dhcp.conf + paths := []string{"dhcp/dhcp.conf", "dhcp/dhcpd.conf", "dhcpd/dhcp.conf", "dhcpd/dhcpd.conf"} + for _, p := range paths { + fp := filepath.Join(devicebase, p) + if _, err := os.Stat(fp); !os.IsNotExist(err) { + return fp + } + } + + log.Printf("Error finding VMWare DHCP Server Configuration (dhcp.conf) under device path: %s", devicebase) + return "" } func playerVmnetnatConfPath(device string) string { From a952148800a53857da1aaebab8cbd64fa9522d58 Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Mon, 2 Apr 2018 12:30:15 -0400 Subject: [PATCH 0886/1007] adjustments to analytics scripts - remove existing GTM tag from head to prevent double tracking - adjust selector to not include non-download links - send a cleaner breakdown of download parameters for easier analysis --- website/source/assets/javascripts/analytics.js | 9 +++++++-- website/source/layouts/layout.erb | 7 ------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/website/source/assets/javascripts/analytics.js b/website/source/assets/javascripts/analytics.js index 33342909a..0e7dff179 100644 --- a/website/source/assets/javascripts/analytics.js +++ b/website/source/assets/javascripts/analytics.js @@ -1,9 +1,14 @@ document.addEventListener('DOMContentLoaded', function() { - track('.downloads .download a', function(el) { + track('.downloads .download .details li a', function(el) { + var m = el.href.match(/packer_(\d+\.\d+\.\d+)_(.*?)_(.*?)\.zip/) return { event: 'Download', category: 'Button', - label: 'Packer | v' + el.href.match(/\/(\d+\.\d+\.\d+)\//)[1] + label: 'Packer | v' + m[1] + ' | ' + m[2] + ' | ' + m[3], + version: m[1], + os: m[2], + architecture: m[3], + product: 'packer' } }) }) diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index a632d884e..768ea0a83 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -34,13 +34,6 @@ <![endif]--> <%= javascript_include_tag "application" %> - <!-- Google Tag Manager --> - <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': - new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], - j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= - 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); - })(window,document,'script','dataLayer','GTM-NR2SD7C');</script> - <!-- Typekit script to import Klavika font --> <script src="https://use.typekit.net/wxf7mfi.js"></script> <script>try{Typekit.load({ async: true });}catch(e){}</script> From 5b7e058d0a8278e4a2c76d98034de76266dcd120 Mon Sep 17 00:00:00 2001 From: Anthony Dong <adongy@users.noreply.github.com> Date: Mon, 2 Apr 2018 19:32:14 +0200 Subject: [PATCH 0887/1007] Add documentation for template variables available for tagging --- .../docs/builders/amazon-chroot.html.md | 27 +++++++------ .../source/docs/builders/amazon-ebs.html.md | 38 +++++++++++-------- .../docs/builders/amazon-ebssurrogate.html.md | 35 +++++++++-------- .../docs/builders/amazon-ebsvolume.html.md | 21 ++++++---- .../docs/builders/amazon-instance.html.md | 24 +++++++----- 5 files changed, 86 insertions(+), 59 deletions(-) diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index c9612d3b8..3738d4e7d 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -77,10 +77,8 @@ each category, the available configuration keys are alphabetized. - `ami_description` (string) - The description to set for the resulting AMI(s). By default this description is empty. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with name of the region where this - is built. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `ami_groups` (array of strings) - A list of groups that have access to launch the resulting AMI(s). By default no groups have permission to launch @@ -251,10 +249,8 @@ each category, the available configuration keys are alphabetized. - `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. They will override AMI tags if already applied to snapshot. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with name of the region where this - is built. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `snapshot_groups` (array of strings) - A list of groups that have access to create volumes from the snapshot(s). By default no groups have permission to create @@ -307,10 +303,8 @@ each category, the available configuration keys are alphabetized. Default `false`. - `tags` (object of key/value strings) - Tags applied to the AMI. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with name of the region where this - is built. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. ## Basic Example @@ -432,3 +426,12 @@ provisioning commands to install the os and bootloader. ] } ``` + +## Build template data + +The available variables are: + +- `BuildRegion` - The region (for example `eu-central-1`) where Packer is building the AMI. +- `SourceAMI` - The source AMI ID (for example `ami-a2412fcd`) used to build the AMI. +- `SourceAMIName` - The source AMI Name (for example `ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306`) used to build the AMI. +- `SourceAMITags` - The source AMI Tags, as a `map[string]string` object. diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 400eb7ecb..fce12b678 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -114,9 +114,8 @@ builder. - `ami_description` (string) - The description to set for the resulting AMI(s). By default this description is empty. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `ami_groups` (array of strings) - A list of groups that have access to launch the resulting AMI(s). By default no groups have permission to launch @@ -221,16 +220,14 @@ builder. - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `run_volume_tags` (object of key/value strings) - Tags to apply to the volumes that are *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `security_group_id` (string) - The ID (*not* the name) of the security group to assign to the instance. By default this is not set and Packer will @@ -264,9 +261,8 @@ builder. - `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. They will override AMI tags if already applied to snapshot. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `source_ami_filter` (object) - Filters used to populate the `source_ami` field. Example: @@ -361,9 +357,8 @@ builder. - `tags` (object of key/value strings) - Tags applied to the AMI and relevant snapshots. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `temporary_key_pair_name` (string) - The name of the temporary key pair to generate. By default, Packer generates a name that looks like @@ -462,6 +457,15 @@ configuration of `launch_block_device_mappings` will expand the root volume } ``` +## Build template data + +The available variables are: + +- `BuildRegion` - The region (for example `eu-central-1`) where Packer is building the AMI. +- `SourceAMI` - The source AMI ID (for example `ami-a2412fcd`) used to build the AMI. +- `SourceAMIName` - The source AMI Name (for example `ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306`) used to build the AMI. +- `SourceAMITags` - The source AMI Tags, as a `map[string]string` object. + ## Tag Example Here is an example using the optional AMI tags. This will add the tags @@ -481,7 +485,9 @@ images exist when this template is run: "ami_name": "packer-quick-start {{timestamp}}", "tags": { "OS_Version": "Ubuntu", - "Release": "Latest" + "Release": "Latest", + "Base_AMI_Name": "{{ .SourceAMIName }}", + "Extra": "{{ .SourceAMITags.TagName }}" } } ``` diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index 1d3724533..98781a94d 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -107,9 +107,8 @@ builder. - `ami_description` (string) - The description to set for the resulting AMI(s). By default this description is empty. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `ami_groups` (array of strings) - A list of groups that have access to launch the resulting AMI(s). By default no groups have permission to launch @@ -214,16 +213,14 @@ builder. - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `run_volume_tags` (object of key/value strings) - Tags to apply to the volumes that are *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `security_group_id` (string) - The ID (*not* the name) of the security group to assign to the instance. By default this is not set and Packer will @@ -257,9 +254,8 @@ builder. - `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot. They will override AMI tags if already applied to snapshot. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `source_ami_filter` (object) - Filters used to populate the `source_ami` field. Example: @@ -354,9 +350,8 @@ builder. - `tags` (object of key/value strings) - Tags applied to the AMI and relevant snapshots. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `temporary_key_pair_name` (string) - The name of the temporary keypair to generate. By default, Packer generates a name with a UUID. @@ -426,6 +421,16 @@ with the `-debug` flag. In debug mode, the Amazon builder will save the private key in the current directory and will output the DNS or IP information as well. You can use this information to access the instance as it is running. +## Build template data + +The available variables are: + +- `BuildRegion` - The region (for example `eu-central-1`) where Packer is building the AMI. +- `SourceAMI` - The source AMI ID (for example `ami-a2412fcd`) used to build the AMI. +- `SourceAMIName` - The source AMI Name (for example `ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306`) used to build the AMI. +- `SourceAMITags` - The source AMI Tags, as a `map[string]string` object. + + -&gt; **Note:** Packer uses pre-built AMIs as the source for building images. These source AMIs may include volumes that are not flagged to be destroyed on termination of the instance building the new image. In addition to those volumes diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 5a3ee9830..3c277920f 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -86,10 +86,9 @@ builder. volumes, `io1` for Provisioned IOPS (SSD) volumes, and `standard` for Magnetic volumes - `tags` (map) - Tags to apply to the volume. These are retained after the - builder completes. This is a \[template engine\] - (/docs/templates/engine.html) where the `SourceAMI` - variable is replaced with the source AMI ID and `BuildRegion` variable - is replaced with the value of `region`. + builder completes. This is a + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `associate_public_ip_address` (boolean) - If using a non-default VPC, public IP addresses are not provided by default. If this is toggled, your new @@ -126,9 +125,8 @@ builder. - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `security_group_id` (string) - The ID (*not* the name) of the security group to assign to the instance. By default this is not set and Packer will @@ -328,6 +326,15 @@ with the `-debug` flag. In debug mode, the Amazon builder will save the private key in the current directory and will output the DNS or IP information as well. You can use this information to access the instance as it is running. +## Build template data + +The available variables are: + +- `BuildRegion` - The region (for example `eu-central-1`) where Packer is building the AMI. +- `SourceAMI` - The source AMI ID (for example `ami-a2412fcd`) used to build the AMI. +- `SourceAMIName` - The source AMI Name (for example `ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306`) used to build the AMI. +- `SourceAMITags` - The source AMI Tags, as a `map[string]string` object. + -&gt; **Note:** Packer uses pre-built AMIs as the source for building images. These source AMIs may include volumes that are not flagged to be destroyed on termination of the instance building the new image. In addition to those volumes diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 58ac7088b..e6e40535c 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -136,9 +136,8 @@ builder. - `ami_description` (string) - The description to set for the resulting AMI(s). By default this description is empty. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `ami_groups` (array of strings) - A list of groups that have access to launch the resulting AMI(s). By default no groups have permission to launch @@ -236,9 +235,8 @@ builder. - `run_tags` (object of key/value strings) - Tags to apply to the instance that is *launched* to create the AMI. These tags are *not* applied to the resulting AMI unless they're duplicated in `tags`. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `security_group_id` (string) - The ID (*not* the name) of the security group to assign to the instance. By default this is not set and Packer will @@ -361,9 +359,8 @@ builder. required if you are using an non-default VPC. - `tags` (object of key/value strings) - Tags applied to the AMI. This is a - [template engine](/docs/templates/engine.html) - where the `SourceAMI` variable is replaced with the source AMI ID and - `BuildRegion` variable is replaced with the value of `region`. + [template engine](/docs/templates/engine.html), + see [Build template data](#build-template-data) for more information. - `temporary_key_pair_name` (string) - The name of the temporary key pair to generate. By default, Packer generates a name that looks like @@ -425,6 +422,15 @@ with the `-debug` flag. In debug mode, the Amazon builder will save the private key in the current directory and will output the DNS or IP information as well. You can use this information to access the instance as it is running. +## Build template data + +The available variables are: + +- `BuildRegion` - The region (for example `eu-central-1`) where Packer is building the AMI. +- `SourceAMI` - The source AMI ID (for example `ami-a2412fcd`) used to build the AMI. +- `SourceAMIName` - The source AMI Name (for example `ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306`) used to build the AMI. +- `SourceAMITags` - The source AMI Tags, as a `map[string]string` object. + ## Custom Bundle Commands A lot of the process required for creating an instance-store backed AMI involves From c0bd4fdafe2ddd7822d0fdcb1b1cc7e996737020 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 10:52:05 -0700 Subject: [PATCH 0888/1007] Add PR lifecycle to contributing doc. --- CONTRIBUTING.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ae5b39fd..e0c51bc78 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,9 +91,10 @@ export PATH=$PATH:$GOPATH/bin ### Opening an Pull Request -When you are ready to open a pull-request, you will need to -[fork Packer](https://github.com/hashicorp/packer#fork-destination-box), push -your changes to your fork, and then open a pull-request. +Thank you for contributing! When you are ready to open a pull-request, you will +need to [fork +Packer](https://github.com/hashicorp/packer#fork-destination-box), push your +changes to your fork, and then open a pull-request. For example, my github username is `cbednarski`, so I would do the following: @@ -109,6 +110,29 @@ From there, open your fork in your browser to open a new pull-request. will break if you `git clone` your fork instead of using `go get` on the main Packer project. +### Pull Request Lifecycle + +1. You are welcome to submit your pull request for commentary or review before + it is fully completed. Please prefix the title of your pull request with + "[WIP]" to indicate this. It's also a good idea to include specific questions + or items you'd like feedback on. + +1. Once you believe your pull request is ready to be merged, you can remove any + "[WIP]" prefix from the title and a core team member will review. + +1. One of Packer's core team members will look over your contribution and + either provide comments letting you know if there is anything left to do. We + do our best to provide feedback in a timely manner, but it may take some time + for us to respond. + +1. Once all outstanding comments and checklist items have been addressed, your + contribution will be merged! Merged PRs will be included in the next + Packer release. The core team takes care of updating the CHANGELOG as they + merge. + +1. In rare cases, we might decide that a PR should be closed. We'll make sure to + provide clear reasoning when this happens. + ### Tips for Working on Packer #### Working on forks From 6f7044c0f663e2d7c7a9cb13dd1a71bebc37b346 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 10:52:27 -0700 Subject: [PATCH 0889/1007] move contributing doc out of root --- CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md From ce0447693120ff159897b8529b4cd4b29b7e813f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 10:55:13 -0700 Subject: [PATCH 0890/1007] update contributing link --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d6b01c47a..d7b2186c9 100644 --- a/README.md +++ b/README.md @@ -92,4 +92,7 @@ https://www.packer.io/docs ## Developing Packer -See [CONTRIBUTING.md](https://github.com/hashicorp/packer/blob/master/CONTRIBUTING.md) for best practices and instructions on setting up your development environment to work on Packer. +See +[CONTRIBUTING.md](https://github.com/hashicorp/packer/blob/master/.github/CONTRIBUTING.md) +for best practices and instructions on setting up your development environment +to work on Packer. From 70426af4ebccb4e7066e264f0c5126fd916962e0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 10:59:59 -0700 Subject: [PATCH 0891/1007] update contributing link --- Makefile | 2 +- README.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 3a68f0ba5..54852ce26 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ testrace: deps ## Test for race conditions @go test -race $(TEST) $(TESTARGS) -timeout=2m updatedeps: - @echo "INFO: Packer deps are managed by govendor. See CONTRIBUTING.md" + @echo "INFO: Packer deps are managed by govendor. See .github/CONTRIBUTING.md" help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/README.md b/README.md index d7b2186c9..dcb0af7f4 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,10 @@ for those with a bit more patience. Otherwise, the quick start below will get you up and running quickly, at the sacrifice of not explaining some key points. -First, [download a pre-built Packer binary](https://www.packer.io/downloads.html) -for your operating system or [compile Packer yourself](CONTRIBUTING.md#setting-up-go-to-work-on-packer). +First, [download a pre-built Packer +binary](https://www.packer.io/downloads.html) for your operating system or +[compile Packer +yourself](https://github.com/hashicorp/packer/blob/master/.github/CONTRIBUTING.md#setting-up-go-to-work-on-packer). After Packer is installed, create your first template, which tells Packer what platforms to build images for and how you want to build them. In our From 52f69cd91a749bc90ac9fc817c6e7a3cf4eb7a25 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 11:12:07 -0700 Subject: [PATCH 0892/1007] Validate image name. --- builder/oracle/classic/config.go | 13 +++++++++++-- builder/oracle/classic/config_test.go | 18 ++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/builder/oracle/classic/config.go b/builder/oracle/classic/config.go index 78fb42085..da3a76460 100644 --- a/builder/oracle/classic/config.go +++ b/builder/oracle/classic/config.go @@ -97,8 +97,17 @@ func NewConfig(raws ...interface{}) (*Config, error) { // Object names can contain only alphanumeric characters, hyphens, underscores, and periods reValidObject := regexp.MustCompile("^[a-zA-Z0-9-._/]+$") - if !reValidObject.MatchString(c.DestImageList) { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("dest_image_list can contain only alphanumeric characters, hyphens, underscores, and periods.")) + var objectValidation = []struct { + name string + value string + }{ + {"dest_image_list", c.DestImageList}, + {"image_name", c.ImageName}, + } + for _, ov := range objectValidation { + if !reValidObject.MatchString(ov.value) { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("%s can contain only alphanumeric characters, hyphens, underscores, and periods.", ov.name)) + } } if c.Attributes != "" && c.AttributesFile != "" { diff --git a/builder/oracle/classic/config_test.go b/builder/oracle/classic/config_test.go index 7351af0d3..ff6bf2a00 100644 --- a/builder/oracle/classic/config_test.go +++ b/builder/oracle/classic/config_test.go @@ -72,14 +72,16 @@ func TestConfigValidatesObjects(t *testing.T) { {"Matt...?", false}, {"/Config-thing/myuser/myimage", true}, } - for _, tt := range objectTests { - tc := testConfig() - tc["dest_image_list"] = tt.object - _, err := NewConfig(tc) - if tt.valid { - assert.NoError(t, err, tt.object) - } else { - assert.Error(t, err, tt.object) + for _, s := range []string{"dest_image_list", "image_name"} { + for _, tt := range objectTests { + tc := testConfig() + tc[s] = tt.object + _, err := NewConfig(tc) + if tt.valid { + assert.NoError(t, err, tt.object) + } else { + assert.Error(t, err, tt.object) + } } } } From 7e13b5c62aad42cb4976bfe1032c78744b0097eb Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 11:56:11 -0700 Subject: [PATCH 0893/1007] prevent panics when cleaning up resources that haven't been created. --- .../oracle/classic/step_create_instance.go | 8 ++++-- .../classic/step_create_ip_reservation.go | 8 ++++-- builder/oracle/classic/step_security.go | 28 +++++++++++++------ builder/oracle/classic/step_snapshot.go | 11 ++++---- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/builder/oracle/classic/step_create_instance.go b/builder/oracle/classic/step_create_instance.go index d9d26b3e3..d52500e09 100644 --- a/builder/oracle/classic/step_create_instance.go +++ b/builder/oracle/classic/step_create_instance.go @@ -57,18 +57,22 @@ func (s *stepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu } func (s *stepCreateInstance) Cleanup(state multistep.StateBag) { + instanceID, ok := state.GetOk("instance_id") + if !ok { + return + } + // terminate instance ui := state.Get("ui").(packer.Ui) client := state.Get("client").(*compute.ComputeClient) config := state.Get("config").(*Config) - imID := state.Get("instance_id").(string) ui.Say("Terminating source instance...") instanceClient := client.Instances() input := &compute.DeleteInstanceInput{ Name: config.ImageName, - ID: imID, + ID: instanceID.(string), } err := instanceClient.DeleteInstance(input) diff --git a/builder/oracle/classic/step_create_ip_reservation.go b/builder/oracle/classic/step_create_ip_reservation.go index 74466a39f..5d400e746 100644 --- a/builder/oracle/classic/step_create_ip_reservation.go +++ b/builder/oracle/classic/step_create_ip_reservation.go @@ -42,12 +42,16 @@ func (s *stepCreateIPReservation) Run(_ context.Context, state multistep.StateBa } func (s *stepCreateIPReservation) Cleanup(state multistep.StateBag) { + ipResName, ok := state.GetOk("ipres_name") + if !ok { + return + } + ui := state.Get("ui").(packer.Ui) ui.Say("Cleaning up IP reservations...") client := state.Get("client").(*compute.ComputeClient) - ipResName := state.Get("ipres_name").(string) - input := compute.DeleteIPReservationInput{Name: ipResName} + input := compute.DeleteIPReservationInput{Name: ipResName.(string)} ipClient := client.IPReservations() err := ipClient.DeleteIPReservation(&input) if err != nil { diff --git a/builder/oracle/classic/step_security.go b/builder/oracle/classic/step_security.go index 34b0d6544..a5b04418b 100644 --- a/builder/oracle/classic/step_security.go +++ b/builder/oracle/classic/step_security.go @@ -97,6 +97,15 @@ func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multiste } func (s *stepSecurity) Cleanup(state multistep.StateBag) { + secRuleName, ok := state.GetOk("security_rule_name") + if !ok { + return + } + secListName, ok := state.GetOk("security_list") + if !ok { + return + } + client := state.Get("client").(*compute.ComputeClient) ui := state.Get("ui").(packer.Ui) config := state.Get("config").(*Config) @@ -105,37 +114,38 @@ func (s *stepSecurity) Cleanup(state multistep.StateBag) { namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username) // delete security rules that Packer generated - secRuleName := state.Get("security_rule_name").(string) secRulesClient := client.SecRules() - ruleInput := compute.DeleteSecRuleInput{Name: namePrefix + secRuleName} + ruleInput := compute.DeleteSecRuleInput{Name: namePrefix + secRuleName.(string)} err := secRulesClient.DeleteSecRule(&ruleInput) if err != nil { ui.Say(fmt.Sprintf("Error deleting the packer-generated security rule %s; "+ - "please delete manually. (error: %s)", secRuleName, err.Error())) + "please delete manually. (error: %s)", secRuleName.(string), err.Error())) } // delete security list that Packer generated - secListName := state.Get("security_list").(string) secListClient := client.SecurityLists() - input := compute.DeleteSecurityListInput{Name: namePrefix + secListName} + input := compute.DeleteSecurityListInput{Name: namePrefix + secListName.(string)} err = secListClient.DeleteSecurityList(&input) if err != nil { ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+ - "please delete manually. (error : %s)", secListName, err.Error())) + "please delete manually. (error : %s)", secListName.(string), err.Error())) } // Some extra cleanup if we used the winRM communicator if config.Comm.Type == "winrm" { // Delete the packer-generated application - application := state.Get("winrm_application").(string) + application, ok := state.GetOk("winrm_application") + if !ok { + return + } applicationClient := client.SecurityApplications() deleteApplicationInput := compute.DeleteSecurityApplicationInput{ - Name: namePrefix + application, + Name: namePrefix + application.(string), } err = applicationClient.DeleteSecurityApplication(&deleteApplicationInput) if err != nil { ui.Say(fmt.Sprintf("Error deleting the packer-generated winrm security application %s; "+ - "please delete manually. (error : %s)", application, err.Error())) + "please delete manually. (error : %s)", application.(string), err.Error())) } } diff --git a/builder/oracle/classic/step_snapshot.go b/builder/oracle/classic/step_snapshot.go index e0ebf3091..64058966d 100644 --- a/builder/oracle/classic/step_snapshot.go +++ b/builder/oracle/classic/step_snapshot.go @@ -15,7 +15,6 @@ type stepSnapshot struct { func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // get variables from state - s.cleanupSnap = false ui := state.Get("ui").(packer.Ui) ui.Say("Creating Snapshot...") config := state.Get("config").(*Config) @@ -39,7 +38,6 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste state.Put("error", err) return multistep.ActionHalt } - s.cleanupSnap = true state.Put("snapshot", snap) ui.Message(fmt.Sprintf("Created snapshot: %s.", snap.Name)) return multistep.ActionContinue @@ -47,13 +45,16 @@ func (s *stepSnapshot) Run(_ context.Context, state multistep.StateBag) multiste func (s *stepSnapshot) Cleanup(state multistep.StateBag) { // Delete the snapshot - ui := state.Get("ui").(packer.Ui) - if !s.cleanupSnap { + var snap *compute.Snapshot + if snapshot, ok := state.GetOk("snapshot"); ok { + snap = snapshot.(*compute.Snapshot) + } else { return } + + ui := state.Get("ui").(packer.Ui) ui.Say("Deleting Snapshot...") client := state.Get("client").(*compute.ComputeClient) - snap := state.Get("snapshot").(*compute.Snapshot) snapClient := client.Snapshots() snapInput := compute.DeleteSnapshotInput{ Snapshot: snap.Name, From bc5cf25d69bf74623d87a6520a7165c460d036ca Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 20:09:32 -0700 Subject: [PATCH 0894/1007] update github link to point to hashicorp --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dcb0af7f4..b031d542e 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ [travis]: https://travis-ci.org/hashicorp/packer [appveyor-badge]: https://ci.appveyor.com/api/projects/status/miavlgnp989e5obc/branch/master?svg=true [appveyor]: https://ci.appveyor.com/project/hashicorp/packer -[godoc-badge]: https://godoc.org/github.com/mitchellh/packer?status.svg -[godoc]: https://godoc.org/github.com/mitchellh/packer -[report-badge]: https://goreportcard.com/badge/github.com/mitchellh/packer -[report]: https://goreportcard.com/report/github.com/mitchellh/packer +[godoc-badge]: https://godoc.org/github.com/hashicorp/packer?status.svg +[godoc]: https://godoc.org/github.com/hashicorp/packer +[report-badge]: https://goreportcard.com/badge/github.com/hashicorp/packer +[report]: https://goreportcard.com/report/github.com/hashicorp/packer * Website: https://www.packer.io * IRC: `#packer-tool` on Freenode From 5206427a47a7d638fed6cef3aeeeefba0c2d21e8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 2 Apr 2018 20:13:07 -0700 Subject: [PATCH 0895/1007] Update go-fs. Closes #6083 --- .../github.com/mitchellh/go-fs/fat/boot_sector.go | 13 +++++++------ .../github.com/mitchellh/go-fs/fat/cluster_chain.go | 3 ++- vendor/github.com/mitchellh/go-fs/fat/directory.go | 9 +++++---- .../mitchellh/go-fs/fat/directory_cluster.go | 7 ++++--- vendor/github.com/mitchellh/go-fs/fat/fat.go | 3 ++- vendor/github.com/mitchellh/go-fs/fat/short_name.go | 9 ++++++--- .../github.com/mitchellh/go-fs/fat/super_floppy.go | 3 ++- vendor/vendor.json | 10 +++++----- 8 files changed, 33 insertions(+), 24 deletions(-) diff --git a/vendor/github.com/mitchellh/go-fs/fat/boot_sector.go b/vendor/github.com/mitchellh/go-fs/fat/boot_sector.go index 689a6b75c..f62df9283 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/boot_sector.go +++ b/vendor/github.com/mitchellh/go-fs/fat/boot_sector.go @@ -4,8 +4,9 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/mitchellh/go-fs" "unicode" + + "github.com/mitchellh/go-fs" ) type MediaType uint8 @@ -99,7 +100,7 @@ func (b *BootSectorCommon) Bytes() ([]byte, error) { for i, r := range b.OEMName { if r > unicode.MaxASCII { - return nil, fmt.Errorf("'%s' in OEM name not a valid ASCII char. Must be ASCII.", r) + return nil, fmt.Errorf("%#U in OEM name not a valid ASCII char. Must be ASCII.", r) } sector[0x3+i] = byte(r) @@ -245,7 +246,7 @@ func (b *BootSectorFat16) Bytes() ([]byte, error) { for i, r := range b.VolumeLabel { if r > unicode.MaxASCII { - return nil, fmt.Errorf("'%s' in VolumeLabel not a valid ASCII char. Must be ASCII.", r) + return nil, fmt.Errorf("%#U in VolumeLabel not a valid ASCII char. Must be ASCII.", r) } sector[43+i] = byte(r) @@ -258,7 +259,7 @@ func (b *BootSectorFat16) Bytes() ([]byte, error) { for i, r := range b.FileSystemTypeLabel { if r > unicode.MaxASCII { - return nil, fmt.Errorf("'%s' in FileSystemTypeLabel not a valid ASCII char. Must be ASCII.", r) + return nil, fmt.Errorf("%#U in FileSystemTypeLabel not a valid ASCII char. Must be ASCII.", r) } sector[54+i] = byte(r) @@ -324,7 +325,7 @@ func (b *BootSectorFat32) Bytes() ([]byte, error) { for i, r := range b.VolumeLabel { if r > unicode.MaxASCII { - return nil, fmt.Errorf("'%s' in VolumeLabel not a valid ASCII char. Must be ASCII.", r) + return nil, fmt.Errorf("%#U in VolumeLabel not a valid ASCII char. Must be ASCII.", r) } sector[71+i] = byte(r) @@ -337,7 +338,7 @@ func (b *BootSectorFat32) Bytes() ([]byte, error) { for i, r := range b.FileSystemTypeLabel { if r > unicode.MaxASCII { - return nil, fmt.Errorf("'%s' in FileSystemTypeLabel not a valid ASCII char. Must be ASCII.", r) + return nil, fmt.Errorf("%#U in FileSystemTypeLabel not a valid ASCII char. Must be ASCII.", r) } sector[82+i] = byte(r) diff --git a/vendor/github.com/mitchellh/go-fs/fat/cluster_chain.go b/vendor/github.com/mitchellh/go-fs/fat/cluster_chain.go index a1f9161d7..344f12e7c 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/cluster_chain.go +++ b/vendor/github.com/mitchellh/go-fs/fat/cluster_chain.go @@ -1,9 +1,10 @@ package fat import ( - "github.com/mitchellh/go-fs" "io" "math" + + "github.com/mitchellh/go-fs" ) type ClusterChain struct { diff --git a/vendor/github.com/mitchellh/go-fs/fat/directory.go b/vendor/github.com/mitchellh/go-fs/fat/directory.go index ff62319fd..2dec26ad2 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/directory.go +++ b/vendor/github.com/mitchellh/go-fs/fat/directory.go @@ -2,9 +2,10 @@ package fat import ( "fmt" - "github.com/mitchellh/go-fs" "strings" "time" + + "github.com/mitchellh/go-fs" ) // Directory implements fs.Directory and is used to interface with @@ -16,9 +17,9 @@ type Directory struct { } // DirectoryEntry implements fs.DirectoryEntry and represents a single -// file/folder within a directory in a FAT filesystem. Note that the -// underlying directory entry data structures on the disk may be more -// than one to accomodate for long filenames. +// file/folder within a directory in a FAT filesystem. Note that there may be +// more than one underlying directory entry data structure on the disk to +// account for long filenames. type DirectoryEntry struct { dir *Directory lfnEntries []*DirectoryClusterEntry diff --git a/vendor/github.com/mitchellh/go-fs/fat/directory_cluster.go b/vendor/github.com/mitchellh/go-fs/fat/directory_cluster.go index b822e82db..691710636 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/directory_cluster.go +++ b/vendor/github.com/mitchellh/go-fs/fat/directory_cluster.go @@ -5,11 +5,12 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/mitchellh/go-fs" "math" "strings" "time" "unicode/utf16" + + "github.com/mitchellh/go-fs" ) type DirectoryAttr uint8 @@ -126,7 +127,7 @@ func NewDirectoryCluster(start uint32, parent uint32, t time.Time) *DirectoryClu // Create the "." and ".." entries cluster.entries = []*DirectoryClusterEntry{ - &DirectoryClusterEntry{ + { accessTime: t, attr: AttrDirectory, cluster: start, @@ -134,7 +135,7 @@ func NewDirectoryCluster(start uint32, parent uint32, t time.Time) *DirectoryClu name: ".", writeTime: t, }, - &DirectoryClusterEntry{ + { accessTime: t, attr: AttrDirectory, cluster: parent, diff --git a/vendor/github.com/mitchellh/go-fs/fat/fat.go b/vendor/github.com/mitchellh/go-fs/fat/fat.go index 8597986f6..3b6ceb16a 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/fat.go +++ b/vendor/github.com/mitchellh/go-fs/fat/fat.go @@ -3,8 +3,9 @@ package fat import ( "errors" "fmt" - "github.com/mitchellh/go-fs" "math" + + "github.com/mitchellh/go-fs" ) // The first cluster that can really hold user data is always 2 diff --git a/vendor/github.com/mitchellh/go-fs/fat/short_name.go b/vendor/github.com/mitchellh/go-fs/fat/short_name.go index df03a2aaf..c91c161f5 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/short_name.go +++ b/vendor/github.com/mitchellh/go-fs/fat/short_name.go @@ -30,11 +30,11 @@ func generateShortName(longName string, used []string) (string, error) { if dotIdx == -1 { dotIdx = len(longName) } else { - ext = longName[dotIdx+1 : len(longName)] + ext = longName[dotIdx+1:] } ext = cleanShortString(ext) - ext = ext[0:len(ext)] + ext = ext[0:] rawName := longName[0:dotIdx] name := cleanShortString(rawName) simpleName := fmt.Sprintf("%s.%s", name, ext) @@ -42,7 +42,7 @@ func generateShortName(longName string, used []string) (string, error) { simpleName = simpleName[0 : len(simpleName)-1] } - doSuffix := name != rawName || len(name) > 8 + doSuffix := name != rawName || len(name) > 8 || len(ext) > 3 if !doSuffix { for _, usedSingle := range used { if strings.ToUpper(usedSingle) == simpleName { @@ -53,6 +53,9 @@ func generateShortName(longName string, used []string) (string, error) { } if doSuffix { + if len(ext) > 3 { + ext = ext[:3] + } found := false for i := 1; i < 99999; i++ { serial := fmt.Sprintf("~%d", i) diff --git a/vendor/github.com/mitchellh/go-fs/fat/super_floppy.go b/vendor/github.com/mitchellh/go-fs/fat/super_floppy.go index 16ad2caeb..ceaf4926a 100644 --- a/vendor/github.com/mitchellh/go-fs/fat/super_floppy.go +++ b/vendor/github.com/mitchellh/go-fs/fat/super_floppy.go @@ -3,8 +3,9 @@ package fat import ( "errors" "fmt" - "github.com/mitchellh/go-fs" "time" + + "github.com/mitchellh/go-fs" ) // SuperFloppyConfig is the configuration for various properties of diff --git a/vendor/vendor.json b/vendor/vendor.json index b48f00557..3f24598df 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1022,14 +1022,14 @@ { "checksumSHA1": "mVqDwKcibat0IKAdzAhfGIHPwI8=", "path": "github.com/mitchellh/go-fs", - "revision": "7bae45d9a684750e82b97ff320c82556614e621b", - "revisionTime": "2016-11-08T19:11:23Z" + "revision": "7b48fa161ea73ce54566b233d6fba8750b2faf47", + "revisionTime": "2018-04-02T23:40:41Z" }, { - "checksumSHA1": "B5dy+Lg6jFPgHYhozztz88z3b4A=", + "checksumSHA1": "i+3acspzTbQODW3dWX2JKydHVAo=", "path": "github.com/mitchellh/go-fs/fat", - "revision": "7bae45d9a684750e82b97ff320c82556614e621b", - "revisionTime": "2016-11-08T19:11:23Z" + "revision": "7b48fa161ea73ce54566b233d6fba8750b2faf47", + "revisionTime": "2018-04-02T23:40:41Z" }, { "checksumSHA1": "z235fRXw4+SW4xWgLTYc8SwkM2M=", From 8fdd20ec2d390ba1e72261ccd957317b479525b5 Mon Sep 17 00:00:00 2001 From: vkatsikaros <vkatsikaros@gmail.com> Date: Tue, 3 Apr 2018 16:29:51 +0300 Subject: [PATCH 0896/1007] Add simpler example for chef client in local mode The existing documentation example looks intimidating as it includes: * variable interpolation * configuration of the chef provisioner * and it misses the `config_template` file In the issue comments, [simpler and complete example](https://github.com/hashicorp/packer/issues/3355#issuecomment-198134727) exists already and works out of the box. This change adds the simpler and complete example, while leaving the more complicated example intact. --- .../docs/provisioners/chef-client.html.md | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/chef-client.html.md b/website/source/docs/provisioners/chef-client.html.md index c40f41034..d634b5c6f 100644 --- a/website/source/docs/provisioners/chef-client.html.md +++ b/website/source/docs/provisioners/chef-client.html.md @@ -286,7 +286,65 @@ directories, append a shell provisioner after Chef to modify them. ## Examples -### Chef Client Local Mode +### Chef Client Local Mode - Simple + +The following example shows how to run the `chef-client` provisioner in local +mode. + +**Packer variables** + +Set the necessary Packer variables using environment variables or provide a [var +file](/docs/templates/user-variables.html). + +``` json +"variables": { + "chef_dir": "/tmp/packer-chef-client" +} +``` + +**Setup the** `chef-client` **provisioner** + +Make sure we have the correct directories and permissions for the `chef-client` +provisioner. You will need to bootstrap the Chef run by providing the necessary +cookbooks using Berkshelf or some other means. + +``` json + "provisioners": [ + ... + { "type": "shell", "inline": [ "mkdir -p {{user `chef_dir`}}" ] }, + { "type": "file", "source": "./roles", "destination": "{{user `chef_dir`}}" }, + { "type": "file", "source": "./cookbooks", "destination": "{{user `chef_dir`}}" }, + { "type": "file", "source": "./data_bags", "destination": "{{user `chef_dir`}}" }, + { "type": "file", "source": "./environments", "destination": "{{user `chef_dir`}}" }, + { "type": "file", "source": "./scripts/install_chef.sh", "destination": "{{user `chef_dir`}}/install_chef.sh" }, + { + "type": "chef-client", + "install_command": "sudo bash {{user `chef_dir`}}/install_chef.sh", + "server_url": "http://localhost:8889", + "config_template": "./config/client.rb.template", + "run_list": [ "role[testing]" ], + "skip_clean_node": true, + "skip_clean_client": true + } + ... + ] +``` + +And ./config/client.rb.template referenced by the above configuration: + +```ruby +log_level :info +log_location STDOUT +local_mode true +chef_zero.enabled true +ssl_verify_mode "verify_peer" +role_path "{{user `chef_dir`}}/roles" +data_bag_path "{{user `chef_dir`}}/data_bags" +environment_path "{{user `chef_dir`}}/environments" +cookbook_path [ "{{user `chef_dir`}}/cookbooks" ] +``` + +### Chef Client Local Mode - Passing variables The following example shows how to run the `chef-client` provisioner in local mode, while passing a `run_list` using a variable. From c0719a359087b3c91d823dd52c91fb87718da663 Mon Sep 17 00:00:00 2001 From: Omer Katz <omer.drow@gmail.com> Date: Thu, 5 Apr 2018 12:56:07 +0300 Subject: [PATCH 0897/1007] Allow using a custom inventory file. --- provisioner/ansible/provisioner.go | 10 +++++----- website/source/docs/provisioners/ansible.html.md | 7 ++++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index bc24044b3..d6e785c70 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -56,7 +56,7 @@ type Config struct { SkipVersionCheck bool `mapstructure:"skip_version_check"` UseSFTP bool `mapstructure:"use_sftp"` InventoryDirectory string `mapstructure:"inventory_directory"` - inventoryFile string + InventoryFile string `mapstructure:"inventory_file"` } type Provisioner struct { @@ -266,7 +266,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { go p.adapter.Serve() - if len(p.config.inventoryFile) == 0 { + if len(p.config.InventoryFile) == 0 { tf, err := ioutil.TempFile(p.config.InventoryDirectory, "packer-provisioner-ansible") if err != nil { return fmt.Errorf("Error preparing inventory file: %s", err) @@ -295,9 +295,9 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { return fmt.Errorf("Error preparing inventory file: %s", err) } tf.Close() - p.config.inventoryFile = tf.Name() + p.config.InventoryFile = tf.Name() defer func() { - p.config.inventoryFile = "" + p.config.InventoryFile = "" }() } @@ -320,7 +320,7 @@ func (p *Provisioner) Cancel() { func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, privKeyFile string) error { playbook, _ := filepath.Abs(p.config.PlaybookFile) - inventory := p.config.inventoryFile + inventory := p.config.InventoryFile if len(p.config.InventoryDirectory) > 0 { inventory = p.config.InventoryDirectory } diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 5c9f1c31c..0f9aa5908 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -81,8 +81,13 @@ Optional Parameters: should be placed. When unspecified, the host is not associated with any groups. +- `inventory_file` (string) - The inventory file to use during provisioning. + When unspecified, Packer will create a temporary inventory file and will + use the `host_alias`. + - `host_alias` (string) - The alias by which the Ansible host should be known. - Defaults to `default`. + Defaults to `default`. This setting is ignored when using a custom inventory + file. - `inventory_directory` (string) - The directory in which to place the temporary generated Ansible inventory file. By default, this is the From b17b333e298e0fadc7d42b5370c725ce2be69144 Mon Sep 17 00:00:00 2001 From: Seth Vargo <seth@sethvargo.com> Date: Wed, 4 Apr 2018 19:24:21 -0700 Subject: [PATCH 0898/1007] Add a common package for specifying useragent and adopt that everywhere There were 5 different formats for the Packer useragent string. This fixes that and unifies it into a helper package. I did not touch oracle's user-agent, because it looked kinda special. --- builder/azure/arm/azure_client.go | 33 ++++++++++++----------------- builder/azure/common/devicelogin.go | 6 ++---- builder/googlecompute/driver_gce.go | 11 ++++------ builder/scaleway/config.go | 3 ++- common/step_download.go | 3 ++- helper/useragent/useragent.go | 29 +++++++++++++++++++++++++ helper/useragent/useragent_test.go | 18 ++++++++++++++++ 7 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 helper/useragent/useragent.go create mode 100644 helper/useragent/useragent_test.go diff --git a/builder/azure/arm/azure_client.go b/builder/azure/arm/azure_client.go index c4d8b544d..faa0a4766 100644 --- a/builder/azure/arm/azure_client.go +++ b/builder/azure/arm/azure_client.go @@ -2,7 +2,6 @@ package arm import ( "encoding/json" - "fmt" "math" "net/http" "net/url" @@ -19,17 +18,13 @@ import ( "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/packer/builder/azure/common" - "github.com/hashicorp/packer/version" + "github.com/hashicorp/packer/helper/useragent" ) const ( EnvPackerLogAzureMaxLen = "PACKER_LOG_AZURE_MAXLEN" ) -var ( - packerUserAgent = fmt.Sprintf(";packer/%s", version.FormattedVersion()) -) - type AzureClient struct { storage.BlobStorageClient resources.DeploymentsClient @@ -137,67 +132,67 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.DeploymentsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DeploymentsClient.RequestInspector = withInspection(maxlen) azureClient.DeploymentsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DeploymentsClient.UserAgent += packerUserAgent + azureClient.DeploymentsClient.UserAgent = useragent.String() azureClient.DeploymentOperationsClient = resources.NewDeploymentOperationsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.DeploymentOperationsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DeploymentOperationsClient.RequestInspector = withInspection(maxlen) azureClient.DeploymentOperationsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DeploymentOperationsClient.UserAgent += packerUserAgent + azureClient.DeploymentOperationsClient.UserAgent = useragent.String() azureClient.DisksClient = disk.NewDisksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.DisksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DisksClient.RequestInspector = withInspection(maxlen) azureClient.DisksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DisksClient.UserAgent += packerUserAgent + azureClient.DisksClient.UserAgent = useragent.String() azureClient.GroupsClient = resources.NewGroupsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.GroupsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.GroupsClient.RequestInspector = withInspection(maxlen) azureClient.GroupsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.GroupsClient.UserAgent += packerUserAgent + azureClient.GroupsClient.UserAgent = useragent.String() azureClient.ImagesClient = compute.NewImagesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.ImagesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.ImagesClient.RequestInspector = withInspection(maxlen) azureClient.ImagesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.ImagesClient.UserAgent += packerUserAgent + azureClient.ImagesClient.UserAgent = useragent.String() azureClient.InterfacesClient = network.NewInterfacesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.InterfacesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.InterfacesClient.RequestInspector = withInspection(maxlen) azureClient.InterfacesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.InterfacesClient.UserAgent += packerUserAgent + azureClient.InterfacesClient.UserAgent = useragent.String() azureClient.SubnetsClient = network.NewSubnetsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.SubnetsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.SubnetsClient.RequestInspector = withInspection(maxlen) azureClient.SubnetsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.SubnetsClient.UserAgent += packerUserAgent + azureClient.SubnetsClient.UserAgent = useragent.String() azureClient.VirtualNetworksClient = network.NewVirtualNetworksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.VirtualNetworksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VirtualNetworksClient.RequestInspector = withInspection(maxlen) azureClient.VirtualNetworksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VirtualNetworksClient.UserAgent += packerUserAgent + azureClient.VirtualNetworksClient.UserAgent = useragent.String() azureClient.PublicIPAddressesClient = network.NewPublicIPAddressesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.PublicIPAddressesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.PublicIPAddressesClient.RequestInspector = withInspection(maxlen) azureClient.PublicIPAddressesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.PublicIPAddressesClient.UserAgent += packerUserAgent + azureClient.PublicIPAddressesClient.UserAgent = useragent.String() azureClient.VirtualMachinesClient = compute.NewVirtualMachinesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.VirtualMachinesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VirtualMachinesClient.RequestInspector = withInspection(maxlen) azureClient.VirtualMachinesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), templateCapture(azureClient), errorCapture(azureClient)) - azureClient.VirtualMachinesClient.UserAgent += packerUserAgent + azureClient.VirtualMachinesClient.UserAgent = useragent.String() azureClient.AccountsClient = armStorage.NewAccountsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.AccountsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.AccountsClient.RequestInspector = withInspection(maxlen) azureClient.AccountsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.AccountsClient.UserAgent += packerUserAgent + azureClient.AccountsClient.UserAgent = useragent.String() keyVaultURL, err := url.Parse(cloud.KeyVaultEndpoint) if err != nil { @@ -208,7 +203,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalTokenVault) azureClient.VaultClient.RequestInspector = withInspection(maxlen) azureClient.VaultClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VaultClient.UserAgent += packerUserAgent + azureClient.VaultClient.UserAgent = useragent.String() // TODO(boumenot) - SDK still does not have a full KeyVault client. // There are two ways that KeyVault has to be accessed, and each one has their own SPN. An authenticated SPN @@ -222,7 +217,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClientDelete.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VaultClientDelete.RequestInspector = withInspection(maxlen) azureClient.VaultClientDelete.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VaultClientDelete.UserAgent += packerUserAgent + azureClient.VaultClientDelete.UserAgent = useragent.String() // If this is a managed disk build, this should be ignored. if resourceGroupName != "" && storageAccountName != "" { diff --git a/builder/azure/common/devicelogin.go b/builder/azure/common/devicelogin.go index 904bd157f..8cf689600 100644 --- a/builder/azure/common/devicelogin.go +++ b/builder/azure/common/devicelogin.go @@ -12,7 +12,7 @@ import ( "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" - "github.com/hashicorp/packer/version" + "github.com/hashicorp/packer/helper/useragent" "github.com/mitchellh/go-homedir" ) @@ -21,8 +21,6 @@ var ( clientIDs = map[string]string{ azure.PublicCloud.Name: "04cc58ec-51ab-4833-ac0d-ce3a7912414b", } - - userAgent = fmt.Sprintf("packer/%s", version.FormattedVersion()) ) // NOTE(ahmetalpbalkan): Azure Active Directory implements OAuth 2.0 Device Flow @@ -138,7 +136,7 @@ func tokenFromFile(say func(string), oauthCfg adal.OAuthConfig, tokenPath, clien // endpoint is polled until user gives consent, denies or the flow times out. // Returned token must be saved. func tokenFromDeviceFlow(say func(string), oauthCfg adal.OAuthConfig, clientID, resource string) (*adal.ServicePrincipalToken, error) { - cl := autorest.NewClientWithUserAgent(userAgent) + cl := autorest.NewClientWithUserAgent(useragent.String()) deviceCode, err := adal.InitiateDeviceAuth(&cl, oauthCfg, clientID, resource) if err != nil { return nil, fmt.Errorf("Failed to start device auth: %v", err) diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 8adbd833e..91f20a58a 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -10,15 +10,14 @@ import ( "fmt" "log" "net/http" - "runtime" "strings" "time" "google.golang.org/api/compute/v1" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/useragent" "github.com/hashicorp/packer/packer" - "github.com/hashicorp/packer/version" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -81,15 +80,13 @@ func NewDriverGCE(ui packer.Ui, p string, a *AccountFile) (Driver, error) { log.Printf("[INFO] Instantiating GCE client...") service, err := compute.New(client) - // Set UserAgent - versionString := version.FormattedVersion() - service.UserAgent = fmt.Sprintf( - "(%s %s) Packer/%s", runtime.GOOS, runtime.GOARCH, versionString) - if err != nil { return nil, err } + // Set UserAgent + service.UserAgent = useragent.String() + return &driverGCE{ projectId: p, service: service, diff --git a/builder/scaleway/config.go b/builder/scaleway/config.go index f965e1ce0..d658e1dad 100644 --- a/builder/scaleway/config.go +++ b/builder/scaleway/config.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/useragent" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/mapstructure" @@ -51,7 +52,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { return nil, nil, err } - c.UserAgent = "Packer - Scaleway builder" + c.UserAgent = useragent.String() if c.Organization == "" { c.Organization = os.Getenv("SCALEWAY_API_ACCESS_KEY") diff --git a/common/step_download.go b/common/step_download.go index 5f5bb7dfe..03340b974 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -9,6 +9,7 @@ import ( "time" "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/helper/useragent" "github.com/hashicorp/packer/packer" ) @@ -91,7 +92,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste CopyFile: false, Hash: HashForType(s.ChecksumType), Checksum: checksum, - UserAgent: "Packer", + UserAgent: useragent.String(), } downloadConfigs[i] = config diff --git a/helper/useragent/useragent.go b/helper/useragent/useragent.go new file mode 100644 index 000000000..bd433d0cb --- /dev/null +++ b/helper/useragent/useragent.go @@ -0,0 +1,29 @@ +package useragent + +import ( + "fmt" + "runtime" + + "github.com/hashicorp/packer/version" +) + +var ( + // projectURL is the project URL. + projectURL = "https://www.packer.io/" + + // rt is the runtime - variable for tests. + rt = runtime.Version() + + // versionFunc is the func that returns the current version. This is a + // function to take into account the different build processes and distinguish + // between enterprise and oss builds. + versionFunc = func() string { + return version.FormattedVersion() + } +) + +// String returns the consistent user-agent string for Packer. +func String() string { + return fmt.Sprintf("Packer/%s (+%s; %s)", + versionFunc(), projectURL, rt) +} diff --git a/helper/useragent/useragent_test.go b/helper/useragent/useragent_test.go new file mode 100644 index 000000000..b193f77eb --- /dev/null +++ b/helper/useragent/useragent_test.go @@ -0,0 +1,18 @@ +package useragent + +import ( + "testing" +) + +func TestUserAgent(t *testing.T) { + projectURL = "https://packer-test.com" + rt = "go5.0" + versionFunc = func() string { return "1.2.3" } + + act := String() + + exp := "Packer/1.2.3 (+https://packer-test.com; go5.0)" + if exp != act { + t.Errorf("expected %q to be %q", act, exp) + } +} From b193b96f76818fc431cef346c6e8c056823d451c Mon Sep 17 00:00:00 2001 From: Seth Vargo <seth@sethvargo.com> Date: Thu, 5 Apr 2018 14:25:11 -0400 Subject: [PATCH 0899/1007] Include arch and os --- helper/useragent/useragent.go | 10 ++++++++-- helper/useragent/useragent_test.go | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/helper/useragent/useragent.go b/helper/useragent/useragent.go index bd433d0cb..575d77aba 100644 --- a/helper/useragent/useragent.go +++ b/helper/useragent/useragent.go @@ -14,6 +14,12 @@ var ( // rt is the runtime - variable for tests. rt = runtime.Version() + // goos is the os - variable for tests. + goos = runtime.GOOS + + // goarch is the architecture - variable for tests. + goarch = runtime.GOARCH + // versionFunc is the func that returns the current version. This is a // function to take into account the different build processes and distinguish // between enterprise and oss builds. @@ -24,6 +30,6 @@ var ( // String returns the consistent user-agent string for Packer. func String() string { - return fmt.Sprintf("Packer/%s (+%s; %s)", - versionFunc(), projectURL, rt) + return fmt.Sprintf("Packer/%s (+%s; %s; %s/%s)", + versionFunc(), projectURL, rt, goos, goarch) } diff --git a/helper/useragent/useragent_test.go b/helper/useragent/useragent_test.go index b193f77eb..b792753c6 100644 --- a/helper/useragent/useragent_test.go +++ b/helper/useragent/useragent_test.go @@ -7,11 +7,13 @@ import ( func TestUserAgent(t *testing.T) { projectURL = "https://packer-test.com" rt = "go5.0" + goos = "linux" + goarch = "amd64" versionFunc = func() string { return "1.2.3" } act := String() - exp := "Packer/1.2.3 (+https://packer-test.com; go5.0)" + exp := "Packer/1.2.3 (+https://packer-test.com; go5.0; linux/amd64)" if exp != act { t.Errorf("expected %q to be %q", act, exp) } From 5eeac07b6327121ea3210b6520346b9bc067aac8 Mon Sep 17 00:00:00 2001 From: Seth Vargo <seth@sethvargo.com> Date: Thu, 5 Apr 2018 14:28:46 -0400 Subject: [PATCH 0900/1007] Include existing azure user agent --- builder/azure/arm/azure_client.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/builder/azure/arm/azure_client.go b/builder/azure/arm/azure_client.go index faa0a4766..bb272435e 100644 --- a/builder/azure/arm/azure_client.go +++ b/builder/azure/arm/azure_client.go @@ -2,6 +2,7 @@ package arm import ( "encoding/json" + "fmt" "math" "net/http" "net/url" @@ -132,67 +133,67 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.DeploymentsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DeploymentsClient.RequestInspector = withInspection(maxlen) azureClient.DeploymentsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DeploymentsClient.UserAgent = useragent.String() + azureClient.DeploymentsClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.DeploymentsClient.UserAgent) azureClient.DeploymentOperationsClient = resources.NewDeploymentOperationsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.DeploymentOperationsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DeploymentOperationsClient.RequestInspector = withInspection(maxlen) azureClient.DeploymentOperationsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DeploymentOperationsClient.UserAgent = useragent.String() + azureClient.DeploymentOperationsClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.DeploymentOperationsClient.UserAgent) azureClient.DisksClient = disk.NewDisksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.DisksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DisksClient.RequestInspector = withInspection(maxlen) azureClient.DisksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DisksClient.UserAgent = useragent.String() + azureClient.DisksClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.DisksClient.UserAgent) azureClient.GroupsClient = resources.NewGroupsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.GroupsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.GroupsClient.RequestInspector = withInspection(maxlen) azureClient.GroupsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.GroupsClient.UserAgent = useragent.String() + azureClient.GroupsClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.GroupsClient.UserAgent) azureClient.ImagesClient = compute.NewImagesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.ImagesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.ImagesClient.RequestInspector = withInspection(maxlen) azureClient.ImagesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.ImagesClient.UserAgent = useragent.String() + azureClient.ImagesClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.ImagesClient.UserAgent) azureClient.InterfacesClient = network.NewInterfacesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.InterfacesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.InterfacesClient.RequestInspector = withInspection(maxlen) azureClient.InterfacesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.InterfacesClient.UserAgent = useragent.String() + azureClient.InterfacesClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.InterfacesClient.UserAgent) azureClient.SubnetsClient = network.NewSubnetsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.SubnetsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.SubnetsClient.RequestInspector = withInspection(maxlen) azureClient.SubnetsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.SubnetsClient.UserAgent = useragent.String() + azureClient.SubnetsClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.SubnetsClient.UserAgent) azureClient.VirtualNetworksClient = network.NewVirtualNetworksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.VirtualNetworksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VirtualNetworksClient.RequestInspector = withInspection(maxlen) azureClient.VirtualNetworksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VirtualNetworksClient.UserAgent = useragent.String() + azureClient.VirtualNetworksClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.VirtualNetworksClient.UserAgent) azureClient.PublicIPAddressesClient = network.NewPublicIPAddressesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.PublicIPAddressesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.PublicIPAddressesClient.RequestInspector = withInspection(maxlen) azureClient.PublicIPAddressesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.PublicIPAddressesClient.UserAgent = useragent.String() + azureClient.PublicIPAddressesClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.PublicIPAddressesClient.UserAgent) azureClient.VirtualMachinesClient = compute.NewVirtualMachinesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.VirtualMachinesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VirtualMachinesClient.RequestInspector = withInspection(maxlen) azureClient.VirtualMachinesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), templateCapture(azureClient), errorCapture(azureClient)) - azureClient.VirtualMachinesClient.UserAgent = useragent.String() + azureClient.VirtualMachinesClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.VirtualMachinesClient.UserAgent) azureClient.AccountsClient = armStorage.NewAccountsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.AccountsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.AccountsClient.RequestInspector = withInspection(maxlen) azureClient.AccountsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.AccountsClient.UserAgent = useragent.String() + azureClient.AccountsClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.AccountsClient.UserAgent) keyVaultURL, err := url.Parse(cloud.KeyVaultEndpoint) if err != nil { @@ -203,7 +204,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalTokenVault) azureClient.VaultClient.RequestInspector = withInspection(maxlen) azureClient.VaultClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VaultClient.UserAgent = useragent.String() + azureClient.VaultClient.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.VaultClient.UserAgent) // TODO(boumenot) - SDK still does not have a full KeyVault client. // There are two ways that KeyVault has to be accessed, and each one has their own SPN. An authenticated SPN @@ -217,7 +218,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClientDelete.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VaultClientDelete.RequestInspector = withInspection(maxlen) azureClient.VaultClientDelete.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VaultClientDelete.UserAgent = useragent.String() + azureClient.VaultClientDelete.UserAgent = fmt.Sprintf("%s %s", useragent.String(), azureClient.VaultClientDelete.UserAgent) // If this is a managed disk build, this should be ignored. if resourceGroupName != "" && storageAccountName != "" { From 302b1988a5a4e7c90589c898f1120b06875384e8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 5 Apr 2018 13:29:32 -0700 Subject: [PATCH 0901/1007] Restrict deregistered AMIs to those owned by self. --- builder/amazon/common/step_deregister_ami.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index 9c176d3c7..eb8b957b5 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -41,6 +41,7 @@ func (s *StepDeregisterAMI) Run(_ context.Context, state multistep.StateBag) mul )) resp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ + Owners: aws.StringSlice([]string{"self"}), Filters: []*ec2.Filter{{ Name: aws.String("name"), Values: []*string{aws.String(s.AMIName)}, From d236f26439f22df68c4aecb46c260c88387e6018 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 5 Apr 2018 15:24:54 -0700 Subject: [PATCH 0902/1007] allow users to access winrm password in powershell and elevated powershell provisioners --- builder/azure/arm/builder.go | 3 +++ builder/azure/arm/config.go | 4 ++++ builder/azure/arm/step_save_winrm_password.go | 22 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 builder/azure/arm/step_save_winrm_password.go diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index b81ccf94f..8fb4389ad 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -176,6 +176,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepValidateTemplate(azureClient, ui, b.config, GetVirtualMachineDeployment), NewStepDeployTemplate(azureClient, ui, b.config, deploymentName, GetVirtualMachineDeployment), NewStepGetIPAddress(azureClient, ui, endpointConnectType), + &StepSaveWinRMPassword{ + Password: b.config.tmpAdminPassword, + }, &communicator.StepConnectWinRM{ Config: &b.config.Comm, Host: func(stateBag multistep.StateBag) (string, error) { diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 8f795f353..5d789708d 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/packer/builder/azure/common/constants" "github.com/hashicorp/packer/builder/azure/pkcs12" "github.com/hashicorp/packer/common" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" @@ -357,6 +358,9 @@ func setRuntimeValues(c *Config) { var tempName = NewTempName() c.tmpAdminPassword = tempName.AdminPassword + // store so that we can access this later during provisioning + commonhelper.SetSharedState("winrm_password", c.tmpAdminPassword) + c.tmpCertificatePassword = tempName.CertificatePassword if c.TempComputeName == "" { c.tmpComputeName = tempName.ComputeName diff --git a/builder/azure/arm/step_save_winrm_password.go b/builder/azure/arm/step_save_winrm_password.go new file mode 100644 index 000000000..e28fcd771 --- /dev/null +++ b/builder/azure/arm/step_save_winrm_password.go @@ -0,0 +1,22 @@ +package arm + +import ( + "context" + + commonhelper "github.com/hashicorp/packer/helper/common" + "github.com/hashicorp/packer/helper/multistep" +) + +type StepSaveWinRMPassword struct { + Password string +} + +func (s *StepSaveWinRMPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { + // store so that we can access this later during provisioning + commonhelper.SetSharedState("winrm_password", s.Password) + return multistep.ActionContinue +} + +func (s *StepSaveWinRMPassword) Cleanup(multistep.StateBag) { + commonhelper.RemoveSharedStateFile("winrm_password") +} From bb53d5f6ccb6e6a4e762876415e88b1e0715dc84 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 5 Apr 2018 15:26:19 -0700 Subject: [PATCH 0903/1007] update docs to include Azure. --- website/source/docs/provisioners/powershell.html.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index 2051efff3..0a97d41ac 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -72,10 +72,9 @@ Optional parameters: - `environment_vars` (array of strings) - An array of key/value pairs to inject prior to the execute\_command. The format should be `key=value`. Packer injects some environmental variables by default into the - environment, as well, which are covered in the section below. If you are - using AWS and would like to use the randomly-generated unique - If you are running on AWS and would like to access the AWS-generated - Administrator password that Packer uses to connect to the instance via + environment, as well, which are covered in the section below. + If you are running on AWS or Azure and would like to access the generated + password that Packer uses to connect to the instance via WinRM, you can use the template variable `{{.WinRMPassword}}` to set this as an environment variable. For example: From 6da6ea74de37e1be37fd3ef99424ef6c79c41d92 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 5 Apr 2018 16:12:20 -0700 Subject: [PATCH 0904/1007] add warning to generated feature in file provisioner --- website/source/docs/provisioners/file.html.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/source/docs/provisioners/file.html.md b/website/source/docs/provisioners/file.html.md index 0dc2e1d01..d2baa868b 100644 --- a/website/source/docs/provisioners/file.html.md +++ b/website/source/docs/provisioners/file.html.md @@ -48,8 +48,13 @@ The available configuration options are listed below. All elements are required. "upload". If it is set to "download" then the file "source" in the machine will be downloaded locally to "destination" -- `generated` (boolean) - If true, check the file existence only before uploading. - This allows to upload files created on-the-fly. This defaults to false. +- `generated` (boolean) - For advanced users only. If true, check the file + existence only before uploading, rather than upon pre-build validation. + This allows to upload files created on-the-fly. This defaults to false. We + don't recommend using this feature, since it can cause Packer to become + dependent on system state. We would prefer you generate your files before + the Packer run, but realize that there are situations where this may be + unavoidable. ## Directory Uploads From f094b3be8506ba98dd00811ce50dc99774e83f1b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 5 Apr 2018 16:32:03 -0700 Subject: [PATCH 0905/1007] update changelog --- CHANGELOG.md | 7 +++++++ builder/amazon/common/step_deregister_ami.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aabaee88..1d20a9f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,15 @@ ## (UNRELEASED) ### BUG FIXES: + * post-processor/vagrant: Large VMDKs should no longer show a 0-byte size on OS X. [GH-6084] +### IMPROVEMENTS: + +* builder/amazon: Setting `force_delete` will only delete AMIs owned by the + user. This should prevent failures where we try to delete an AMI with + a matching name, but owned by someone else. [GH-6111] + ## 1.2.2 (March 26, 2018) ### BUG FIXES: diff --git a/builder/amazon/common/step_deregister_ami.go b/builder/amazon/common/step_deregister_ami.go index eb8b957b5..8a82d7c7e 100644 --- a/builder/amazon/common/step_deregister_ami.go +++ b/builder/amazon/common/step_deregister_ami.go @@ -44,7 +44,7 @@ func (s *StepDeregisterAMI) Run(_ context.Context, state multistep.StateBag) mul Owners: aws.StringSlice([]string{"self"}), Filters: []*ec2.Filter{{ Name: aws.String("name"), - Values: []*string{aws.String(s.AMIName)}, + Values: aws.StringSlice([]string{s.AMIName}), }}}) if err != nil { From 6855216387594566f37672a0962b6e7d18b192d9 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Thu, 5 Apr 2018 10:04:12 -0700 Subject: [PATCH 0906/1007] force QueryEscape to escape spaces as %20 instead of as + for ovftool. --- post-processor/vsphere/post-processor.go | 13 ++++++-- post-processor/vsphere/post-processor_test.go | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/post-processor/vsphere/post-processor.go b/post-processor/vsphere/post-processor.go index b9702fe82..fcf209ea7 100644 --- a/post-processor/vsphere/post-processor.go +++ b/post-processor/vsphere/post-processor.go @@ -110,9 +110,9 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, fmt.Errorf("VMX, OVF or OVA file not found") } - password := url.QueryEscape(p.config.Password) + password := escapeWithSpaces(p.config.Password) ovftool_uri := fmt.Sprintf("vi://%s:%s@%s/%s/host/%s", - url.QueryEscape(p.config.Username), + escapeWithSpaces(p.config.Username), password, p.config.Host, p.config.Datacenter, @@ -146,7 +146,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac } func (p *PostProcessor) filterLog(s string) string { - password := url.QueryEscape(p.config.Password) + password := escapeWithSpaces(p.config.Password) return strings.Replace(s, password, "<password>", -1) } @@ -186,3 +186,10 @@ func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) return args, nil } + +// Encode everything except for + signs +func escapeWithSpaces(stringToEscape string) string { + escapedString := url.QueryEscape(stringToEscape) + escapedString = strings.Replace(escapedString, "+", `%20`, -1) + return escapedString +} diff --git a/post-processor/vsphere/post-processor_test.go b/post-processor/vsphere/post-processor_test.go index 61b58789b..65b99f9a7 100644 --- a/post-processor/vsphere/post-processor_test.go +++ b/post-processor/vsphere/post-processor_test.go @@ -40,3 +40,34 @@ func TestArgs(t *testing.T) { t.Logf("ovftool %s", strings.Join(args, " ")) } + +func TestEscaping(t *testing.T) { + type escapeCases struct { + Input string + Expected string + } + + cases := []escapeCases{ + {`this has spaces`, `this%20has%20spaces`}, + {`exclaimation_!`, `exclaimation_%21`}, + {`hash_#_dollar_$`, `hash_%23_dollar_%24`}, + {`ampersand_&awesome`, `ampersand_%26awesome`}, + {`single_quote_'_and_another_'`, `single_quote_%27_and_another_%27`}, + {`open_paren_(_close_paren_)`, `open_paren_%28_close_paren_%29`}, + {`asterisk_*_plus_+`, `asterisk_%2A_plus_%2B`}, + {`comma_,slash_/`, `comma_%2Cslash_%2F`}, + {`colon_:semicolon_;`, `colon_%3Asemicolon_%3B`}, + {`equal_=question_?`, `equal_%3Dquestion_%3F`}, + {`at_@`, `at_%40`}, + {`open_bracket_[closed_bracket]`, `open_bracket_%5Bclosed_bracket%5D`}, + {`user:password with $paces@host/name.foo`, `user%3Apassword%20with%20%24paces%40host%2Fname.foo`}, + } + for _, escapeCase := range cases { + received := escapeWithSpaces(escapeCase.Input) + + if escapeCase.Expected != received { + t.Errorf("Error escaping URL; expected %s got %s", escapeCase.Expected, received) + } + } + +} From 6bb173045a3c42059aa5609bf8021b198857a69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Fortunato?= <mfortunato@online.net> Date: Sat, 7 Apr 2018 22:07:49 +0200 Subject: [PATCH 0907/1007] fix: documentation scaleway - update commercial type name --- website/source/docs/builders/scaleway.html.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/source/docs/builders/scaleway.html.md b/website/source/docs/builders/scaleway.html.md index b1864bdb0..c712ce2c6 100644 --- a/website/source/docs/builders/scaleway.html.md +++ b/website/source/docs/builders/scaleway.html.md @@ -56,10 +56,10 @@ builder. or `ams1`). Consequently, this is the region where the snapshot will be available. -- `commercial_type` (string) - The name of the server commercial type: `C1`, - `C2S`, `C2M`, `C2L`, `X64-2GB`, `X64-4GB`, `X64-8GB`, `X64-15GB`, - `X64-30GB`, `X64-60GB`, `X64-120GB`, `ARM64-2GB`, `ARM64-4GB`, `ARM64-8GB`, - `ARM64-16GB`, `ARM64-32GB`, `ARM64-64GB`, `ARM64-128GB` +- `commercial_type` (string) - The name of the server commercial type: + `ARM64-128GB`,`ARM64-16GB`,`ARM64-2GB`,`ARM64-32GB`,`ARM64-4GB`, `ARM64-64GB`, + `ARM64-8GB`,`C1`,`C2L`,`C2M`,`C2S`,`VC1L`,`VC1M`,`VC1S`, + `X64-120GB`,`X64-15GB`,`X64-30GB`,`X64-60GB` ### Optional: @@ -84,7 +84,7 @@ access tokens: "api_token": "YOUR TOKEN", "image": "UUID OF THE BASE IMAGE", "region": "par1", - "commercial_type": "X64-2GB", + "commercial_type": "VC1S", "ssh_username": "root", "ssh_private_key_file": "~/.ssh/id_rsa" } From ee1ff3132d22035faeefefb81797f61421b963bd Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 10 Apr 2018 08:13:06 -0700 Subject: [PATCH 0908/1007] remove attempt to discover whether destination is a directory from upload function in various communicators --- builder/docker/communicator.go | 16 ----------- communicator/ssh/communicator.go | 49 -------------------------------- 2 files changed, 65 deletions(-) diff --git a/builder/docker/communicator.go b/builder/docker/communicator.go index 7b0ecae07..e898ecd1c 100644 --- a/builder/docker/communicator.go +++ b/builder/docker/communicator.go @@ -105,22 +105,6 @@ func (c *Communicator) uploadReader(dst string, src io.Reader) error { // uploadFile uses docker cp to copy the file from the host to the container func (c *Communicator) uploadFile(dst string, src io.Reader, fi *os.FileInfo) error { - // find out if it's a directory - testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, dst) - cmd := &packer.RemoteCmd{Command: testDirectoryCommand} - - err := c.Start(cmd) - - if err != nil { - log.Printf("Unable to check whether remote path is a dir: %s", err) - return err - } - cmd.Wait() - if cmd.ExitStatus == 0 { - log.Printf("path is a directory; copying file into directory.") - dst = filepath.Join(dst, filepath.Base((*fi).Name())) - } - // command format: docker cp /path/to/infile containerid:/path/to/outfile log.Printf("Copying to %s on container %s.", dst, c.ContainerID) diff --git a/communicator/ssh/communicator.go b/communicator/ssh/communicator.go index 218c11be6..6545d1d5c 100644 --- a/communicator/ssh/communicator.go +++ b/communicator/ssh/communicator.go @@ -410,27 +410,6 @@ func (c *comm) sftpUploadSession(path string, input io.Reader, fi *os.FileInfo) func (c *comm) sftpUploadFile(path string, input io.Reader, client *sftp.Client, fi *os.FileInfo) error { log.Printf("[DEBUG] sftp: uploading %s", path) - - // find out if destination is a directory (this is to replicate rsync behavior) - testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) - - cmd := &packer.RemoteCmd{ - Command: testDirectoryCommand, - } - - err := c.Start(cmd) - - if err != nil { - log.Printf("[ERROR] Unable to check whether remote path is a dir: %s", err) - return err - } - cmd.Wait() - if cmd.ExitStatus == 0 { - return fmt.Errorf( - "Destination path (%s) is a directory that already exists. "+ - "Please ensure the destination is writable.", path) - } - f, err := client.Create(path) if err != nil { return err @@ -586,34 +565,6 @@ func (c *comm) scpUploadSession(path string, input io.Reader, fi *os.FileInfo) e target_dir := filepath.Dir(path) target_file := filepath.Base(path) - // find out if destination is a directory (this is to replicate rsync behavior) - testDirectoryCommand := fmt.Sprintf(`test -d "%s"`, path) - var stdout, stderr bytes.Buffer - cmd := &packer.RemoteCmd{ - Command: testDirectoryCommand, - Stdout: &stdout, - Stderr: &stderr, - } - - err := c.Start(cmd) - - if err != nil { - log.Printf("[ERROR] Unable to check whether remote path is a dir: %s", err) - return err - } - cmd.Wait() - if stdout.Len() > 0 { - return fmt.Errorf("%s", stdout.Bytes()) - } - if stderr.Len() > 0 { - return fmt.Errorf("%s", stderr.Bytes()) - } - if cmd.ExitStatus == 0 { - return fmt.Errorf( - "Destination path (%s) is a directory that already exists. "+ - "Please ensure the destination is writable.", path) - } - // On windows, filepath.Dir uses backslash separators (ie. "\tmp"). // This does not work when the target host is unix. Switch to forward slash // which works for unix and windows From 545b2c4e0f251545a94708289c1d66cbd709e20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Carr?= <lcarr@online.net> Date: Thu, 12 Apr 2018 09:35:46 +0200 Subject: [PATCH 0909/1007] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d20a9f6d..9e5e744e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### BUG FIXES: * post-processor/vagrant: Large VMDKs should no longer show a 0-byte size on OS X. [GH-6084] +* builder/scaleway: Fix compilation issues on solaris/amd64. [GH-6069] ### IMPROVEMENTS: From 0f0fc1b99c29cae5f12ef0c56cadb8fe8d59ae52 Mon Sep 17 00:00:00 2001 From: andrew-best-diaxion <abest@diaxion.com> Date: Fri, 13 Apr 2018 14:02:55 +1000 Subject: [PATCH 0910/1007] azure-cli output config check added Adds a check to contrib/azure-setup.sh which ensure the users azure-cli is configured to output json. --- contrib/azure-setup.sh | 394 +++++++++++++++++++++-------------------- 1 file changed, 202 insertions(+), 192 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 6149b38d0..40ad49697 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -12,257 +12,267 @@ azure_tenant_id= # Derived from the account after login location= azure_object_id= azureversion= +azurecliconfig= create_sleep=10 showhelp() { - echo "azure-setup" - echo "" - echo " azure-setup helps you generate packer credentials for azure" - echo "" - echo " The script creates a resource group, storage account, application" - echo " (client), service principal, and permissions and displays a snippet" - echo " for use in your packer templates." - echo "" - echo " For simplicity we make a lot of assumptions and choose reasonable" - echo " defaults. If you want more control over what happens, please use" - echo " the azure-cli directly." - echo "" - echo " Note that you must already have an Azure account, username," - echo " password, and subscription. You can create those here:" - echo "" - echo " - https://account.windowsazure.com/" - echo "" - echo "REQUIREMENTS" - echo "" - echo " - azure-cli" - echo " - jq" - echo "" - echo " Use the requirements command (below) for more info." - echo "" - echo "USAGE" - echo "" - echo " ./azure-setup.sh requirements" - echo " ./azure-setup.sh setup" - echo "" + echo "azure-setup" + echo "" + echo " azure-setup helps you generate packer credentials for azure" + echo "" + echo " The script creates a resource group, storage account, application" + echo " (client), service principal, and permissions and displays a snippet" + echo " for use in your packer templates." + echo "" + echo " For simplicity we make a lot of assumptions and choose reasonable" + echo " defaults. If you want more control over what happens, please use" + echo " the azure-cli directly." + echo "" + echo " Note that you must already have an Azure account, username," + echo " password, and subscription. You can create those here:" + echo "" + echo " - https://account.windowsazure.com/" + echo "" + echo "REQUIREMENTS" + echo "" + echo " - azure-cli" + echo " - jq" + echo "" + echo " Use the requirements command (below) for more info." + echo "" + echo "USAGE" + echo "" + echo " ./azure-setup.sh requirements" + echo " ./azure-setup.sh setup" + echo "" } requirements() { - found=0 + found=0 - azureversion=$(az --version) - if [ $? -eq 0 ]; then - found=$((found + 1)) - echo "Found azure-cli version: $azureversion" - else - echo "azure-cli is missing. Please install azure-cli from" - echo "https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" - echo "Alternatively, you can use the Cloud Shell https://docs.microsoft.com/en-us/azure/cloud-shell/overview right from the Azure Portal or even VS Code." - fi + azureversion=$(az --version) + if [ $? -eq 0 ]; then + found=$((found + 1)) + echo "Found azure-cli version: $azureversion" + else + echo "azure-cli is missing. Please install azure-cli from" + echo "https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" + echo "Alternatively, you can use the Cloud Shell https://docs.microsoft.com/en-us/azure/cloud-shell/overview right from the Azure Portal or even VS Code." + fi - jqversion=$(jq --version) - if [ $? -eq 0 ]; then - found=$((found + 1)) - echo "Found jq version: $jqversion" - else - echo "jq is missing. Please install jq from" - echo "https://stedolan.github.io/jq/" - fi + azurecliconfig=$(cat $HOME/.azure/config | grep output | awk -F'[ ]' '{print $3}') + if [ "$azurecliconfig" == "json" ]; then + found=$((found +1)) + echo "Found correct azure-cli output configuration: output = $azurecliconfig." + else + echo "azure-cli is configured for $azurecliconfig output." + echo "Please reconfigure your azure-cli client to output using json." + fi - if [ $found -lt 2 ]; then - exit 1 - fi + jqversion=$(jq --version) + if [ $? -eq 0 ]; then + found=$((found + 1)) + echo "Found jq version: $jqversion" + else + echo "jq is missing. Please install jq from" + echo "https://stedolan.github.io/jq/" + fi + + if [ $found -lt 3 ]; then + exit 1 + fi } askSubscription() { - az account list -otable - echo "" - echo "Please enter the Id of the account you wish to use. If you do not see" - echo "a valid account in the list press Ctrl+C to abort and create one." - echo "If you leave this blank we will use the Current account." - echo -n "> " - read azure_subscription_id + az account list -otable + echo "" + echo "Please enter the Id of the account you wish to use. If you do not see" + echo "a valid account in the list press Ctrl+C to abort and create one." + echo "If you leave this blank we will use the Current account." + echo -n "> " + read azure_subscription_id - if [ "$azure_subscription_id" != "" ]; then - az account set --subscription $azure_subscription_id - else - azure_subscription_id=$(az account list | jq -r '.[] | select(.isDefault==true) | .id') - fi - azure_tenant_id=$(az account list | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') - echo "Using subscription_id: $azure_subscription_id" - echo "Using tenant_id: $azure_tenant_id" + if [ "$azure_subscription_id" != "" ]; then + az account set --subscription $azure_subscription_id + else + azure_subscription_id=$(az account list | jq -r '.[] | select(.isDefault==true) | .id') + fi + azure_tenant_id=$(az account list | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') + echo "Using subscription_id: $azure_subscription_id" + echo "Using tenant_id: $azure_tenant_id" } askName() { - echo "" - echo "Choose a name for your resource group, storage account and client" - echo "client. This is arbitrary, but it must not already be in use by" - echo "any of those resources. ALPHANUMERIC ONLY. Ex: mypackerbuild" - echo -n "> " - read meta_name + echo "" + echo "Choose a name for your resource group, storage account and client" + echo "client. This is arbitrary, but it must not already be in use by" + echo "any of those resources. ALPHANUMERIC ONLY. Ex: mypackerbuild" + echo -n "> " + read meta_name } askSecret() { - echo "" - echo "Enter a secret for your application. We recommend generating one with" - echo "openssl rand -base64 24. If you leave this blank we will attempt to" - echo "generate one for you using openssl. THIS WILL BE SHOWN IN PLAINTEXT." - echo "Ex: mypackersecret8734" - echo -n "> " - read azure_client_secret - if [ "$azure_client_secret" = "" ]; then - azure_client_secret=$(openssl rand -base64 24) - if [ $? -ne 0 ]; then - echo "Error generating secret" - exit 1 - fi - echo "Generated client_secret: $azure_client_secret" + echo "" + echo "Enter a secret for your application. We recommend generating one with" + echo "openssl rand -base64 24. If you leave this blank we will attempt to" + echo "generate one for you using openssl. THIS WILL BE SHOWN IN PLAINTEXT." + echo "Ex: mypackersecret8734" + echo -n "> " + read azure_client_secret + if [ "$azure_client_secret" = "" ]; then + azure_client_secret=$(openssl rand -base64 24) + if [ $? -ne 0 ]; then + echo "Error generating secret" + exit 1 fi + echo "Generated client_secret: $azure_client_secret" + fi } askLocation() { - az account list-locations -otable - echo "" - echo "Choose which region your resource group and storage account will be created. example: westus" - echo -n "> " - read location + az account list-locations -otable + echo "" + echo "Choose which region your resource group and storage account will be created. example: westus" + echo -n "> " + read location } createResourceGroup() { - echo "==> Creating resource group" - az group create -n $meta_name -l $location - if [ $? -eq 0 ]; then - azure_group_name=$meta_name - else - echo "Error creating resource group: $meta_name" - return 1 - fi + echo "==> Creating resource group" + az group create -n $meta_name -l $location + if [ $? -eq 0 ]; then + azure_group_name=$meta_name + else + echo "Error creating resource group: $meta_name" + return 1 + fi } createStorageAccount() { - echo "==> Creating storage account" - az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage --sku Standard_LRS - if [ $? -eq 0 ]; then - azure_storage_name=$meta_name - else - echo "Error creating storage account: $meta_name" - return 1 - fi + echo "==> Creating storage account" + az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage --sku Standard_LRS + if [ $? -eq 0 ]; then + azure_storage_name=$meta_name + else + echo "Error creating storage account: $meta_name" + return 1 + fi } createApplication() { - echo "==> Creating application" - echo "==> Does application exist?" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') - - if [ "$azure_client_id" != "" ]; then - echo "==> application already exist, grab appId" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') - else - echo "==> application does not exist" - azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) - fi + echo "==> Creating application" + echo "==> Does application exist?" + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') - if [ $? -ne 0 ]; then - echo "Error creating application: $meta_name @ http://$meta_name" - return 1 - fi + if [ "$azure_client_id" != "" ]; then + echo "==> application already exist, grab appId" + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') + else + echo "==> application does not exist" + azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) + fi + + if [ $? -ne 0 ]; then + echo "Error creating application: $meta_name @ http://$meta_name" + return 1 + fi } createServicePrincipal() { - echo "==> Creating service principal" - azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) - echo $azure_object_id "was selected." + echo "==> Creating service principal" + azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) + echo $azure_object_id "was selected." - if [ $? -ne 0 ]; then - echo "Error creating service principal: $azure_client_id" - return 1 - fi + if [ $? -ne 0 ]; then + echo "Error creating service principal: $azure_client_id" + return 1 + fi } createPermissions() { - echo "==> Creating permissions" - az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id - # If the user wants to use a more conservative scope, she can. She must - # configure the Azure builder to use build_resource_group_name. The - # easiest solution is subscription wide permission. - # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" - if [ $? -ne 0 ]; then - echo "Error creating permissions for: http://$meta_name" - return 1 - fi + echo "==> Creating permissions" + az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id + # If the user wants to use a more conservative scope, she can. She must + # configure the Azure builder to use build_resource_group_name. The + # easiest solution is subscription wide permission. + # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" + if [ $? -ne 0 ]; then + echo "Error creating permissions for: http://$meta_name" + return 1 + fi } showConfigs() { - echo "" - echo "Use the following configuration for your packer template:" - echo "" - echo "{" - echo " \"client_id\": \"$azure_client_id\"," - echo " \"client_secret\": \"$azure_client_secret\"," - echo " \"object_id\": \"$azure_object_id\"," - echo " \"subscription_id\": \"$azure_subscription_id\"," - echo " \"tenant_id\": \"$azure_tenant_id\"," - echo " \"resource_group_name\": \"$azure_group_name\"," - echo " \"storage_account\": \"$azure_storage_name\"," - echo "}" - echo "" + echo "" + echo "Use the following configuration for your packer template:" + echo "" + echo "{" + echo " \"client_id\": \"$azure_client_id\"," + echo " \"client_secret\": \"$azure_client_secret\"," + echo " \"object_id\": \"$azure_object_id\"," + echo " \"subscription_id\": \"$azure_subscription_id\"," + echo " \"tenant_id\": \"$azure_tenant_id\"," + echo " \"resource_group_name\": \"$azure_group_name\"," + echo " \"storage_account\": \"$azure_storage_name\"," + echo "}" + echo "" } doSleep() { - local sleep_time=${PACKER_SLEEP_TIME-$create_sleep} - echo "" - echo "Sleeping for ${sleep_time} seconds to wait for resources to be " - echo "created. If you get an error about a resource not existing, you can " - echo "try increasing the amount of time we wait after creating resources " - echo "by setting PACKER_SLEEP_TIME to something higher than the default." - echo "" - sleep $sleep_time + local sleep_time=${PACKER_SLEEP_TIME-$create_sleep} + echo "" + echo "Sleeping for ${sleep_time} seconds to wait for resources to be " + echo "created. If you get an error about a resource not existing, you can " + echo "try increasing the amount of time we wait after creating resources " + echo "by setting PACKER_SLEEP_TIME to something higher than the default." + echo "" + sleep $sleep_time } retryable() { - n=0 - until [ $n -ge $1 ] - do - $2 && return 0 - echo "$2 failed. Retrying..." - n=$[$n+1] - doSleep - done - echo "$2 failed after $1 tries. Exiting." - exit 1 + n=0 + until [ $n -ge $1 ] + do + $2 && return 0 + echo "$2 failed. Retrying..." + n=$[$n+1] + doSleep + done + echo "$2 failed after $1 tries. Exiting." + exit 1 } setup() { - requirements + requirements - az login + az login - askSubscription - askName - askSecret - askLocation + askSubscription + askName + askSecret + askLocation - # Some of the resources take a while to converge in the API. To make the - # script more reliable we'll add a sleep after we create each resource. + # Some of the resources take a while to converge in the API. To make the + # script more reliable we'll add a sleep after we create each resource. - retryable 3 createResourceGroup - retryable 3 createStorageAccount - retryable 3 createApplication - retryable 3 createServicePrincipal - retryable 3 createPermissions + retryable 3 createResourceGroup + retryable 3 createStorageAccount + retryable 3 createApplication + retryable 3 createServicePrincipal + retryable 3 createPermissions - showConfigs + showConfigs } case "$1" in - requirements) - requirements - ;; - setup) - setup - ;; - *) - showhelp - ;; + requirements) + requirements + ;; + setup) + setup + ;; + *) + showhelp + ;; esac From 5e22942f3002c423267cfbe186721d6698e7acaf Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Fri, 13 Apr 2018 17:59:14 -0400 Subject: [PATCH 0911/1007] analytics script adjustments --- website/source/layouts/layout.erb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index 768ea0a83..a6c615b72 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -112,23 +112,24 @@ </div> <script> - // ga async load - window['GoogleAnalyticsObject'] = 'ga'; - window['ga'] = window['ga'] || function() { - (window['ga'].q = window['ga'].q || []).push(arguments) - }; // analytics.js !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; analytics.load("<%= segmentId %>"); analytics.page(); }}(); - </script> - <script> // optinmonster var om597a24292a958,om597a24292a958_poll=function(){var b=0;return function(d,c){clearInterval(b);b=setInterval(d,c)}}(); !function(b,d,c){if(b.getElementById(c))om597a24292a958_poll(function(){if(window.om_loaded&&!om597a24292a958)return om597a24292a958=new OptinMonsterApp,om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0})},25);else{var e=!1,a=b.createElement(d);a.id=c;a.src="//a.optnmstr.com/app/js/api.min.js";a.async=!0;a.onload=a.onreadystatechange=function(){if(!(e||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState))try{e=om_loaded=!0,om597a24292a958=new OptinMonsterApp, om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0}),a.onload=a.onreadystatechange=null}catch(f){}};(document.getElementsByTagName("head")[0]||document.documentElement).appendChild(a)}}(document,"script","omapi-script"); </script> + <!-- temporary test --> + <script async src="https://www.googletagmanager.com/gtag/js?id=UA-43075859-2"></script> + <script> + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', 'UA-43075859-2'); + </script> <script type="application/ld+json"> { "@context": "http://schema.org", From b5ec42e62f5304d9c1b4ec3b62f06ac018b9a360 Mon Sep 17 00:00:00 2001 From: John Morrissey <jwm@horde.net> Date: Sat, 14 Apr 2018 09:15:21 -0400 Subject: [PATCH 0912/1007] fix missing comma in docs for lxd builder --- website/source/docs/builders/lxd.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/lxd.html.md b/website/source/docs/builders/lxd.html.md index 019b97534..4f8cf9c84 100644 --- a/website/source/docs/builders/lxd.html.md +++ b/website/source/docs/builders/lxd.html.md @@ -30,7 +30,7 @@ Below is a fully functioning example. "type": "lxd", "name": "lxd-xenial", "image": "ubuntu-daily:xenial", - "output_image": "ubuntu-xenial" + "output_image": "ubuntu-xenial", "publish_properties": { "description": "Trivial repackage with Packer" } From e911f03b6d695f7222817fe465120bba5a6996ac Mon Sep 17 00:00:00 2001 From: andrew-best-diaxion <abest@diaxion.com> Date: Mon, 16 Apr 2018 07:45:17 +1000 Subject: [PATCH 0913/1007] Revert "azure-cli output config check added" This reverts commit 0f0fc1b99c29cae5f12ef0c56cadb8fe8d59ae52. --- contrib/azure-setup.sh | 394 ++++++++++++++++++++--------------------- 1 file changed, 192 insertions(+), 202 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 40ad49697..6149b38d0 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -12,267 +12,257 @@ azure_tenant_id= # Derived from the account after login location= azure_object_id= azureversion= -azurecliconfig= create_sleep=10 showhelp() { - echo "azure-setup" - echo "" - echo " azure-setup helps you generate packer credentials for azure" - echo "" - echo " The script creates a resource group, storage account, application" - echo " (client), service principal, and permissions and displays a snippet" - echo " for use in your packer templates." - echo "" - echo " For simplicity we make a lot of assumptions and choose reasonable" - echo " defaults. If you want more control over what happens, please use" - echo " the azure-cli directly." - echo "" - echo " Note that you must already have an Azure account, username," - echo " password, and subscription. You can create those here:" - echo "" - echo " - https://account.windowsazure.com/" - echo "" - echo "REQUIREMENTS" - echo "" - echo " - azure-cli" - echo " - jq" - echo "" - echo " Use the requirements command (below) for more info." - echo "" - echo "USAGE" - echo "" - echo " ./azure-setup.sh requirements" - echo " ./azure-setup.sh setup" - echo "" + echo "azure-setup" + echo "" + echo " azure-setup helps you generate packer credentials for azure" + echo "" + echo " The script creates a resource group, storage account, application" + echo " (client), service principal, and permissions and displays a snippet" + echo " for use in your packer templates." + echo "" + echo " For simplicity we make a lot of assumptions and choose reasonable" + echo " defaults. If you want more control over what happens, please use" + echo " the azure-cli directly." + echo "" + echo " Note that you must already have an Azure account, username," + echo " password, and subscription. You can create those here:" + echo "" + echo " - https://account.windowsazure.com/" + echo "" + echo "REQUIREMENTS" + echo "" + echo " - azure-cli" + echo " - jq" + echo "" + echo " Use the requirements command (below) for more info." + echo "" + echo "USAGE" + echo "" + echo " ./azure-setup.sh requirements" + echo " ./azure-setup.sh setup" + echo "" } requirements() { - found=0 + found=0 - azureversion=$(az --version) - if [ $? -eq 0 ]; then - found=$((found + 1)) - echo "Found azure-cli version: $azureversion" - else - echo "azure-cli is missing. Please install azure-cli from" - echo "https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" - echo "Alternatively, you can use the Cloud Shell https://docs.microsoft.com/en-us/azure/cloud-shell/overview right from the Azure Portal or even VS Code." - fi + azureversion=$(az --version) + if [ $? -eq 0 ]; then + found=$((found + 1)) + echo "Found azure-cli version: $azureversion" + else + echo "azure-cli is missing. Please install azure-cli from" + echo "https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest" + echo "Alternatively, you can use the Cloud Shell https://docs.microsoft.com/en-us/azure/cloud-shell/overview right from the Azure Portal or even VS Code." + fi - azurecliconfig=$(cat $HOME/.azure/config | grep output | awk -F'[ ]' '{print $3}') - if [ "$azurecliconfig" == "json" ]; then - found=$((found +1)) - echo "Found correct azure-cli output configuration: output = $azurecliconfig." - else - echo "azure-cli is configured for $azurecliconfig output." - echo "Please reconfigure your azure-cli client to output using json." - fi + jqversion=$(jq --version) + if [ $? -eq 0 ]; then + found=$((found + 1)) + echo "Found jq version: $jqversion" + else + echo "jq is missing. Please install jq from" + echo "https://stedolan.github.io/jq/" + fi - jqversion=$(jq --version) - if [ $? -eq 0 ]; then - found=$((found + 1)) - echo "Found jq version: $jqversion" - else - echo "jq is missing. Please install jq from" - echo "https://stedolan.github.io/jq/" - fi - - if [ $found -lt 3 ]; then - exit 1 - fi + if [ $found -lt 2 ]; then + exit 1 + fi } askSubscription() { - az account list -otable - echo "" - echo "Please enter the Id of the account you wish to use. If you do not see" - echo "a valid account in the list press Ctrl+C to abort and create one." - echo "If you leave this blank we will use the Current account." - echo -n "> " - read azure_subscription_id + az account list -otable + echo "" + echo "Please enter the Id of the account you wish to use. If you do not see" + echo "a valid account in the list press Ctrl+C to abort and create one." + echo "If you leave this blank we will use the Current account." + echo -n "> " + read azure_subscription_id - if [ "$azure_subscription_id" != "" ]; then - az account set --subscription $azure_subscription_id - else - azure_subscription_id=$(az account list | jq -r '.[] | select(.isDefault==true) | .id') - fi - azure_tenant_id=$(az account list | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') - echo "Using subscription_id: $azure_subscription_id" - echo "Using tenant_id: $azure_tenant_id" + if [ "$azure_subscription_id" != "" ]; then + az account set --subscription $azure_subscription_id + else + azure_subscription_id=$(az account list | jq -r '.[] | select(.isDefault==true) | .id') + fi + azure_tenant_id=$(az account list | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') + echo "Using subscription_id: $azure_subscription_id" + echo "Using tenant_id: $azure_tenant_id" } askName() { - echo "" - echo "Choose a name for your resource group, storage account and client" - echo "client. This is arbitrary, but it must not already be in use by" - echo "any of those resources. ALPHANUMERIC ONLY. Ex: mypackerbuild" - echo -n "> " - read meta_name + echo "" + echo "Choose a name for your resource group, storage account and client" + echo "client. This is arbitrary, but it must not already be in use by" + echo "any of those resources. ALPHANUMERIC ONLY. Ex: mypackerbuild" + echo -n "> " + read meta_name } askSecret() { - echo "" - echo "Enter a secret for your application. We recommend generating one with" - echo "openssl rand -base64 24. If you leave this blank we will attempt to" - echo "generate one for you using openssl. THIS WILL BE SHOWN IN PLAINTEXT." - echo "Ex: mypackersecret8734" - echo -n "> " - read azure_client_secret - if [ "$azure_client_secret" = "" ]; then - azure_client_secret=$(openssl rand -base64 24) - if [ $? -ne 0 ]; then - echo "Error generating secret" - exit 1 + echo "" + echo "Enter a secret for your application. We recommend generating one with" + echo "openssl rand -base64 24. If you leave this blank we will attempt to" + echo "generate one for you using openssl. THIS WILL BE SHOWN IN PLAINTEXT." + echo "Ex: mypackersecret8734" + echo -n "> " + read azure_client_secret + if [ "$azure_client_secret" = "" ]; then + azure_client_secret=$(openssl rand -base64 24) + if [ $? -ne 0 ]; then + echo "Error generating secret" + exit 1 + fi + echo "Generated client_secret: $azure_client_secret" fi - echo "Generated client_secret: $azure_client_secret" - fi } askLocation() { - az account list-locations -otable - echo "" - echo "Choose which region your resource group and storage account will be created. example: westus" - echo -n "> " - read location + az account list-locations -otable + echo "" + echo "Choose which region your resource group and storage account will be created. example: westus" + echo -n "> " + read location } createResourceGroup() { - echo "==> Creating resource group" - az group create -n $meta_name -l $location - if [ $? -eq 0 ]; then - azure_group_name=$meta_name - else - echo "Error creating resource group: $meta_name" - return 1 - fi + echo "==> Creating resource group" + az group create -n $meta_name -l $location + if [ $? -eq 0 ]; then + azure_group_name=$meta_name + else + echo "Error creating resource group: $meta_name" + return 1 + fi } createStorageAccount() { - echo "==> Creating storage account" - az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage --sku Standard_LRS - if [ $? -eq 0 ]; then - azure_storage_name=$meta_name - else - echo "Error creating storage account: $meta_name" - return 1 - fi + echo "==> Creating storage account" + az storage account create --name $meta_name --resource-group $meta_name --location $location --kind Storage --sku Standard_LRS + if [ $? -eq 0 ]; then + azure_storage_name=$meta_name + else + echo "Error creating storage account: $meta_name" + return 1 + fi } createApplication() { - echo "==> Creating application" - echo "==> Does application exist?" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') + echo "==> Creating application" + echo "==> Does application exist?" + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') + + if [ "$azure_client_id" != "" ]; then + echo "==> application already exist, grab appId" + azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') + else + echo "==> application does not exist" + azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) + fi - if [ "$azure_client_id" != "" ]; then - echo "==> application already exist, grab appId" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') - else - echo "==> application does not exist" - azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) - fi - - if [ $? -ne 0 ]; then - echo "Error creating application: $meta_name @ http://$meta_name" - return 1 - fi + if [ $? -ne 0 ]; then + echo "Error creating application: $meta_name @ http://$meta_name" + return 1 + fi } createServicePrincipal() { - echo "==> Creating service principal" - azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) - echo $azure_object_id "was selected." + echo "==> Creating service principal" + azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) + echo $azure_object_id "was selected." - if [ $? -ne 0 ]; then - echo "Error creating service principal: $azure_client_id" - return 1 - fi + if [ $? -ne 0 ]; then + echo "Error creating service principal: $azure_client_id" + return 1 + fi } createPermissions() { - echo "==> Creating permissions" - az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id - # If the user wants to use a more conservative scope, she can. She must - # configure the Azure builder to use build_resource_group_name. The - # easiest solution is subscription wide permission. - # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" - if [ $? -ne 0 ]; then - echo "Error creating permissions for: http://$meta_name" - return 1 - fi + echo "==> Creating permissions" + az role assignment create --assignee $azure_object_id --role "Owner" --scope /subscriptions/$azure_subscription_id + # If the user wants to use a more conservative scope, she can. She must + # configure the Azure builder to use build_resource_group_name. The + # easiest solution is subscription wide permission. + # az role assignment create --spn http://$meta_name -g $azure_group_name -o "API Management Service Contributor" + if [ $? -ne 0 ]; then + echo "Error creating permissions for: http://$meta_name" + return 1 + fi } showConfigs() { - echo "" - echo "Use the following configuration for your packer template:" - echo "" - echo "{" - echo " \"client_id\": \"$azure_client_id\"," - echo " \"client_secret\": \"$azure_client_secret\"," - echo " \"object_id\": \"$azure_object_id\"," - echo " \"subscription_id\": \"$azure_subscription_id\"," - echo " \"tenant_id\": \"$azure_tenant_id\"," - echo " \"resource_group_name\": \"$azure_group_name\"," - echo " \"storage_account\": \"$azure_storage_name\"," - echo "}" - echo "" + echo "" + echo "Use the following configuration for your packer template:" + echo "" + echo "{" + echo " \"client_id\": \"$azure_client_id\"," + echo " \"client_secret\": \"$azure_client_secret\"," + echo " \"object_id\": \"$azure_object_id\"," + echo " \"subscription_id\": \"$azure_subscription_id\"," + echo " \"tenant_id\": \"$azure_tenant_id\"," + echo " \"resource_group_name\": \"$azure_group_name\"," + echo " \"storage_account\": \"$azure_storage_name\"," + echo "}" + echo "" } doSleep() { - local sleep_time=${PACKER_SLEEP_TIME-$create_sleep} - echo "" - echo "Sleeping for ${sleep_time} seconds to wait for resources to be " - echo "created. If you get an error about a resource not existing, you can " - echo "try increasing the amount of time we wait after creating resources " - echo "by setting PACKER_SLEEP_TIME to something higher than the default." - echo "" - sleep $sleep_time + local sleep_time=${PACKER_SLEEP_TIME-$create_sleep} + echo "" + echo "Sleeping for ${sleep_time} seconds to wait for resources to be " + echo "created. If you get an error about a resource not existing, you can " + echo "try increasing the amount of time we wait after creating resources " + echo "by setting PACKER_SLEEP_TIME to something higher than the default." + echo "" + sleep $sleep_time } retryable() { - n=0 - until [ $n -ge $1 ] - do - $2 && return 0 - echo "$2 failed. Retrying..." - n=$[$n+1] - doSleep - done - echo "$2 failed after $1 tries. Exiting." - exit 1 + n=0 + until [ $n -ge $1 ] + do + $2 && return 0 + echo "$2 failed. Retrying..." + n=$[$n+1] + doSleep + done + echo "$2 failed after $1 tries. Exiting." + exit 1 } setup() { - requirements + requirements - az login + az login - askSubscription - askName - askSecret - askLocation + askSubscription + askName + askSecret + askLocation - # Some of the resources take a while to converge in the API. To make the - # script more reliable we'll add a sleep after we create each resource. + # Some of the resources take a while to converge in the API. To make the + # script more reliable we'll add a sleep after we create each resource. - retryable 3 createResourceGroup - retryable 3 createStorageAccount - retryable 3 createApplication - retryable 3 createServicePrincipal - retryable 3 createPermissions + retryable 3 createResourceGroup + retryable 3 createStorageAccount + retryable 3 createApplication + retryable 3 createServicePrincipal + retryable 3 createPermissions - showConfigs + showConfigs } case "$1" in - requirements) - requirements - ;; - setup) - setup - ;; - *) - showhelp - ;; + requirements) + requirements + ;; + setup) + setup + ;; + *) + showhelp + ;; esac From d2e8fd4952d09ecb77dea169feea2511bb297c49 Mon Sep 17 00:00:00 2001 From: andrew-best-diaxion <abest@diaxion.com> Date: Mon, 16 Apr 2018 08:01:31 +1000 Subject: [PATCH 0914/1007] forces az cli to output in JSON where required This check in forces the scipt to output in JSON when that output is being piped to jq. --- contrib/azure-setup.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/azure-setup.sh b/contrib/azure-setup.sh index 6149b38d0..6473c5a08 100755 --- a/contrib/azure-setup.sh +++ b/contrib/azure-setup.sh @@ -85,9 +85,9 @@ askSubscription() { if [ "$azure_subscription_id" != "" ]; then az account set --subscription $azure_subscription_id else - azure_subscription_id=$(az account list | jq -r '.[] | select(.isDefault==true) | .id') + azure_subscription_id=$(az account list --output json | jq -r '.[] | select(.isDefault==true) | .id') fi - azure_tenant_id=$(az account list | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') + azure_tenant_id=$(az account list --output json | jq -r '.[] | select(.id=="'$azure_subscription_id'") | .tenantId') echo "Using subscription_id: $azure_subscription_id" echo "Using tenant_id: $azure_tenant_id" } @@ -152,14 +152,14 @@ createStorageAccount() { createApplication() { echo "==> Creating application" echo "==> Does application exist?" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') - + azure_client_id=$(az ad app list --output json | jq -r '.[] | select(.displayName | contains("'$meta_name'")) ') + if [ "$azure_client_id" != "" ]; then echo "==> application already exist, grab appId" - azure_client_id=$(az ad app list | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') + azure_client_id=$(az ad app list az ad app list --output json | jq -r '.[] | select(.displayName | contains("'$meta_name'")) .appId') else echo "==> application does not exist" - azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret | jq -r .appId) + azure_client_id=$(az ad app create --display-name $meta_name --identifier-uris http://$meta_name --homepage http://$meta_name --password $azure_client_secret --output json | jq -r .appId) fi if [ $? -ne 0 ]; then @@ -170,7 +170,7 @@ createApplication() { createServicePrincipal() { echo "==> Creating service principal" - azure_object_id=$(az ad sp create --id $azure_client_id | jq -r .objectId) + azure_object_id=$(az ad sp create --id $azure_client_id --output json | jq -r .objectId) echo $azure_object_id "was selected." if [ $? -ne 0 ]; then From ec6f8264bf84f139369e782312dbd8a7f7925e3f Mon Sep 17 00:00:00 2001 From: Richard Nienaber <rnienaber@salesforce.com> Date: Mon, 16 Apr 2018 10:56:26 +0100 Subject: [PATCH 0915/1007] fix winrm password access in google compute --- builder/googlecompute/step_create_windows_password.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builder/googlecompute/step_create_windows_password.go b/builder/googlecompute/step_create_windows_password.go index 3386f6fbc..a389ad97a 100644 --- a/builder/googlecompute/step_create_windows_password.go +++ b/builder/googlecompute/step_create_windows_password.go @@ -13,6 +13,7 @@ import ( "os" "time" + commonhelper "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -112,6 +113,7 @@ func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.State } state.Put("winrm_password", data.password) + commonhelper.SetSharedState("winrm_password", data.password) return multistep.ActionContinue } From 747d1eba273a9d7a2cefc4b6aab318f7f1dfd507 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 16 Apr 2018 10:38:59 -0700 Subject: [PATCH 0916/1007] add a note about sdl errors and how to fix. --- website/source/docs/builders/qemu.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index 91b0e09a2..bdd39410b 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -312,7 +312,7 @@ default port of `5985` or whatever value you have the service set to listen on. - `use_default_display` (boolean) - If true, do not pass a `-display` option to qemu, allowing it to choose the default. This may be needed when running - under OS X. + under OS X, and getting errors about `sdl` not being available. - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty From 3afb243f118af760bb312c2c77d95b63eefacd97 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 16 Apr 2018 11:51:04 -0700 Subject: [PATCH 0917/1007] use build name to ensure that winrm password and other shared state is not overwritten if two builders need the password in the same packer run. --- builder/amazon/common/step_get_password.go | 11 ++++++----- builder/amazon/ebs/builder.go | 7 ++++--- builder/amazon/ebssurrogate/builder.go | 7 ++++--- builder/amazon/ebsvolume/builder.go | 7 ++++--- builder/amazon/instance/builder.go | 7 ++++--- builder/azure/arm/builder.go | 3 ++- builder/azure/arm/config.go | 2 +- builder/azure/arm/step_save_winrm_password.go | 7 ++++--- common/step_http_server.go | 12 ++++++------ helper/common/shared_state.go | 16 ++++++++-------- provisioner/powershell/provisioner.go | 12 ++++++------ 11 files changed, 49 insertions(+), 42 deletions(-) diff --git a/builder/amazon/common/step_get_password.go b/builder/amazon/common/step_get_password.go index c9011d930..8b0d0c74c 100644 --- a/builder/amazon/common/step_get_password.go +++ b/builder/amazon/common/step_get_password.go @@ -21,9 +21,10 @@ import ( // StepGetPassword reads the password from a Windows server and sets it // on the WinRM config. type StepGetPassword struct { - Debug bool - Comm *communicator.Config - Timeout time.Duration + Debug bool + Comm *communicator.Config + Timeout time.Duration + BuildName string } func (s *StepGetPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { @@ -94,13 +95,13 @@ WaitLoop: "Password (since debug is enabled): %s", s.Comm.WinRMPassword)) } // store so that we can access this later during provisioning - commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword) + commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword, s.BuildName) return multistep.ActionContinue } func (s *StepGetPassword) Cleanup(multistep.StateBag) { - commonhelper.RemoveSharedStateFile("winrm_password") + commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName) } func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) { diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 87354223c..5e63b05c8 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -193,9 +193,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, instanceStep, &awscommon.StepGetPassword{ - Debug: b.config.PackerDebug, - Comm: &b.config.RunConfig.Comm, - Timeout: b.config.WindowsPasswordTimeout, + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 002560602..31f47164f 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -207,9 +207,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, instanceStep, &awscommon.StepGetPassword{ - Debug: b.config.PackerDebug, - Comm: &b.config.RunConfig.Comm, - Timeout: b.config.WindowsPasswordTimeout, + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index cdfda8e14..a1cc1fd2a 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -186,9 +186,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &awscommon.StepGetPassword{ - Debug: b.config.PackerDebug, - Comm: &b.config.RunConfig.Comm, - Timeout: b.config.WindowsPasswordTimeout, + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index 98d9dc24d..eb3ecdbda 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -269,9 +269,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, instanceStep, &awscommon.StepGetPassword{ - Debug: b.config.PackerDebug, - Comm: &b.config.RunConfig.Comm, - Timeout: b.config.WindowsPasswordTimeout, + Debug: b.config.PackerDebug, + Comm: &b.config.RunConfig.Comm, + Timeout: b.config.WindowsPasswordTimeout, + BuildName: b.config.PackerBuildName, }, &communicator.StepConnect{ Config: &b.config.RunConfig.Comm, diff --git a/builder/azure/arm/builder.go b/builder/azure/arm/builder.go index 8fb4389ad..efaf228e7 100644 --- a/builder/azure/arm/builder.go +++ b/builder/azure/arm/builder.go @@ -177,7 +177,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe NewStepDeployTemplate(azureClient, ui, b.config, deploymentName, GetVirtualMachineDeployment), NewStepGetIPAddress(azureClient, ui, endpointConnectType), &StepSaveWinRMPassword{ - Password: b.config.tmpAdminPassword, + Password: b.config.tmpAdminPassword, + BuildName: b.config.PackerBuildName, }, &communicator.StepConnectWinRM{ Config: &b.config.Comm, diff --git a/builder/azure/arm/config.go b/builder/azure/arm/config.go index 5d789708d..6d41fc7dc 100644 --- a/builder/azure/arm/config.go +++ b/builder/azure/arm/config.go @@ -359,7 +359,7 @@ func setRuntimeValues(c *Config) { c.tmpAdminPassword = tempName.AdminPassword // store so that we can access this later during provisioning - commonhelper.SetSharedState("winrm_password", c.tmpAdminPassword) + commonhelper.SetSharedState("winrm_password", c.tmpAdminPassword, c.PackerConfig.PackerBuildName) c.tmpCertificatePassword = tempName.CertificatePassword if c.TempComputeName == "" { diff --git a/builder/azure/arm/step_save_winrm_password.go b/builder/azure/arm/step_save_winrm_password.go index e28fcd771..700a4b048 100644 --- a/builder/azure/arm/step_save_winrm_password.go +++ b/builder/azure/arm/step_save_winrm_password.go @@ -8,15 +8,16 @@ import ( ) type StepSaveWinRMPassword struct { - Password string + Password string + BuildName string } func (s *StepSaveWinRMPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { // store so that we can access this later during provisioning - commonhelper.SetSharedState("winrm_password", s.Password) + commonhelper.SetSharedState("winrm_password", s.Password, s.BuildName) return multistep.ActionContinue } func (s *StepSaveWinRMPassword) Cleanup(multistep.StateBag) { - commonhelper.RemoveSharedStateFile("winrm_password") + commonhelper.RemoveSharedStateFile("winrm_password", s.BuildName) } diff --git a/common/step_http_server.go b/common/step_http_server.go index 953ef38c1..394042961 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -76,20 +76,20 @@ func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multis } func SetHTTPPort(port string) error { - return common.SetSharedState("port", port) + return common.SetSharedState("port", port, "") } func SetHTTPIP(ip string) error { - return common.SetSharedState("ip", ip) + return common.SetSharedState("ip", ip, "") } func GetHTTPAddr() string { - ip, err := common.RetrieveSharedState("ip") + ip, err := common.RetrieveSharedState("ip", "") if err != nil { return "" } - port, err := common.RetrieveSharedState("port") + port, err := common.RetrieveSharedState("port", "") if err != nil { return "" } @@ -101,6 +101,6 @@ func (s *StepHTTPServer) Cleanup(multistep.StateBag) { // Close the listener so that the HTTP server stops s.l.Close() } - common.RemoveSharedStateFile("port") - common.RemoveSharedStateFile("ip") + common.RemoveSharedStateFile("port", "") + common.RemoveSharedStateFile("ip", "") } diff --git a/helper/common/shared_state.go b/helper/common/shared_state.go index 92ffbaeaf..87e111cfb 100644 --- a/helper/common/shared_state.go +++ b/helper/common/shared_state.go @@ -9,23 +9,23 @@ import ( // Used to set variables which we need to access later in the build, where // state bag and config information won't work -func sharedStateFilename(suffix string) string { +func sharedStateFilename(suffix string, buildName string) string { uuid := os.Getenv("PACKER_RUN_UUID") - return filepath.Join(os.TempDir(), fmt.Sprintf("packer-%s-%s", uuid, suffix)) + return filepath.Join(os.TempDir(), fmt.Sprintf("packer-%s-%s-%s", uuid, suffix, buildName)) } -func SetSharedState(key string, value string) error { - return ioutil.WriteFile(sharedStateFilename(key), []byte(value), 0600) +func SetSharedState(key string, value string, buildName string) error { + return ioutil.WriteFile(sharedStateFilename(key, buildName), []byte(value), 0600) } -func RetrieveSharedState(key string) (string, error) { - value, err := ioutil.ReadFile(sharedStateFilename(key)) +func RetrieveSharedState(key string, buildName string) (string, error) { + value, err := ioutil.ReadFile(sharedStateFilename(key, buildName)) if err != nil { return "", err } return string(value), nil } -func RemoveSharedStateFile(key string) { - os.Remove(sharedStateFilename(key)) +func RemoveSharedStateFile(key string, buildName string) { + os.Remove(sharedStateFilename(key, buildName)) } diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index e28becef0..c5a4845f7 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -377,7 +377,7 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // interpolate environment variables p.config.ctx.Data = &EnvVarsTemplate{ - WinRMPassword: getWinRMPassword(), + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } // Split vars into key/value components for _, envVar := range p.config.Vars { @@ -445,7 +445,7 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro p.config.ctx.Data = &ExecuteCommandTemplate{ Path: p.config.RemotePath, Vars: envVarPath, - WinRMPassword: getWinRMPassword(), + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -457,8 +457,8 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro return command, nil } -func getWinRMPassword() string { - winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password") +func getWinRMPassword(buildName string) string { + winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName) return winRMPass } @@ -472,7 +472,7 @@ func (p *Provisioner) createCommandTextPrivileged() (command string, err error) p.config.ctx.Data = &ExecuteCommandTemplate{ Path: p.config.RemotePath, Vars: envVarPath, - WinRMPassword: getWinRMPassword(), + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } command, err = interpolate.Render(p.config.ElevatedExecuteCommand, &p.config.ctx) if err != nil { @@ -530,7 +530,7 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } // Replace ElevatedPassword for winrm users who used this feature p.config.ctx.Data = &EnvVarsTemplate{ - WinRMPassword: getWinRMPassword(), + WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } p.config.ElevatedPassword, _ = interpolate.Render(p.config.ElevatedPassword, &p.config.ctx) From fd670e779905de4f2018eea30a41a52c6c8285f2 Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Mon, 16 Apr 2018 17:34:27 -0400 Subject: [PATCH 0918/1007] move analytics.js to the head --- website/source/layouts/layout.erb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index a6c615b72..1eeb97e08 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -39,6 +39,14 @@ <script>try{Typekit.load({ async: true });}catch(e){}</script> <%= yield_content :head %> + + <script> + // analytics.js + !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; + analytics.load("<%= segmentId %>"); + analytics.page(); + }}(); + </script> </head> <body id="<%= body_id_for(current_page) %>" class="<%= body_classes_for(current_page) %>"> @@ -112,11 +120,6 @@ </div> <script> - // analytics.js - !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; - analytics.load("<%= segmentId %>"); - analytics.page(); - }}(); // optinmonster var om597a24292a958,om597a24292a958_poll=function(){var b=0;return function(d,c){clearInterval(b);b=setInterval(d,c)}}(); !function(b,d,c){if(b.getElementById(c))om597a24292a958_poll(function(){if(window.om_loaded&&!om597a24292a958)return om597a24292a958=new OptinMonsterApp,om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0})},25);else{var e=!1,a=b.createElement(d);a.id=c;a.src="//a.optnmstr.com/app/js/api.min.js";a.async=!0;a.onload=a.onreadystatechange=function(){if(!(e||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState))try{e=om_loaded=!0,om597a24292a958=new OptinMonsterApp, From e7db66faf728a84070be588c757dfe86e577a138 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 16 Apr 2018 15:31:00 -0700 Subject: [PATCH 0919/1007] update middleman docker version --- website/packer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/packer.json b/website/packer.json index 4ac70d626..21e2316e9 100644 --- a/website/packer.json +++ b/website/packer.json @@ -9,7 +9,7 @@ "builders": [ { "type": "docker", - "image": "hashicorp/middleman-hashicorp:0.3.32", + "image": "hashicorp/middleman-hashicorp:0.3.34", "discard": "true", "volumes": { "{{ pwd }}": "/website" From 31973d9f8b45f17c3988580e8b37da4d15e23851 Mon Sep 17 00:00:00 2001 From: Harvey Lowndes <harvey.lowndes@oracle.com> Date: Wed, 11 Apr 2018 10:20:07 +0100 Subject: [PATCH 0920/1007] Add OCI Go SDK dependency --- .../github.com/oracle/oci-go-sdk/CHANGELOG.md | 15 + .../oracle/oci-go-sdk/CONTRIBUTING.md | 24 + .../github.com/oracle/oci-go-sdk/LICENSE.txt | 82 + vendor/github.com/oracle/oci-go-sdk/Makefile | 55 + vendor/github.com/oracle/oci-go-sdk/README.md | 153 ++ .../oracle/oci-go-sdk/audit/audit_client.go | 113 + .../oracle/oci-go-sdk/audit/audit_event.go | 78 + .../oracle/oci-go-sdk/audit/configuration.go | 24 + .../get_configuration_request_response.go | 34 + .../audit/list_events_request_response.go | 60 + .../audit/update_configuration_details.go | 24 + .../update_configuration_request_response.go | 41 + .../oci-go-sdk/cmd/genver/version_template.go | 42 + .../common/auth/certificate_retriever.go | 154 ++ .../oci-go-sdk/common/auth/configuration.go | 61 + .../common/auth/federation_client.go | 288 +++ .../auth/instance_principal_key_provider.go | 95 + .../oracle/oci-go-sdk/common/auth/jwt.go | 61 + .../oracle/oci-go-sdk/common/auth/utils.go | 64 + .../oracle/oci-go-sdk/common/client.go | 253 +++ .../oracle/oci-go-sdk/common/common.go | 39 + .../oracle/oci-go-sdk/common/configuration.go | 487 ++++ .../oracle/oci-go-sdk/common/errors.go | 80 + .../oracle/oci-go-sdk/common/helpers.go | 168 ++ .../oracle/oci-go-sdk/common/http.go | 863 +++++++ .../oracle/oci-go-sdk/common/http_signer.go | 230 ++ .../oracle/oci-go-sdk/common/log.go | 67 + .../oracle/oci-go-sdk/common/version.go | 36 + .../core/attach_boot_volume_details.go | 30 + .../attach_boot_volume_request_response.go | 48 + .../core/attach_i_scsi_volume_details.go | 63 + .../oci-go-sdk/core/attach_vnic_details.go | 37 + .../core/attach_vnic_request_response.go | 48 + .../oci-go-sdk/core/attach_volume_details.go | 86 + .../core/attach_volume_request_response.go | 48 + .../oracle/oci-go-sdk/core/boot_volume.go | 86 + .../oci-go-sdk/core/boot_volume_attachment.go | 76 + ...virtual_circuit_public_prefixes_details.go | 24 + ...ircuit_public_prefixes_request_response.go | 34 + ...virtual_circuit_public_prefixes_details.go | 24 + ...ircuit_public_prefixes_request_response.go | 34 + .../core/capture_console_history_details.go | 27 + ...apture_console_history_request_response.go | 48 + .../connect_local_peering_gateways_details.go | 24 + ...local_peering_gateways_request_response.go | 38 + .../oracle/oci-go-sdk/core/console_history.go | 75 + .../core/core_blockstorage_client.go | 334 +++ .../oci-go-sdk/core/core_compute_client.go | 833 +++++++ .../core/core_virtualnetwork_client.go | 2009 +++++++++++++++++ .../github.com/oracle/oci-go-sdk/core/cpe.go | 45 + .../oci-go-sdk/core/create_cpe_details.go | 31 + .../core/create_cpe_request_response.go | 48 + .../core/create_cross_connect_details.go | 53 + .../create_cross_connect_group_details.go | 28 + ...te_cross_connect_group_request_response.go | 48 + .../create_cross_connect_request_response.go | 48 + .../oci-go-sdk/core/create_dhcp_details.go | 61 + .../create_dhcp_options_request_response.go | 48 + .../core/create_drg_attachment_details.go | 30 + .../create_drg_attachment_request_response.go | 48 + .../oci-go-sdk/core/create_drg_details.go | 27 + .../core/create_drg_request_response.go | 48 + ...ate_i_p_sec_connection_request_response.go | 48 + .../oci-go-sdk/core/create_image_details.go | 61 + .../core/create_image_request_response.go | 48 + ...ate_instance_console_connection_details.go | 28 + ...nce_console_connection_request_response.go | 48 + .../core/create_internet_gateway_details.go | 33 + ...reate_internet_gateway_request_response.go | 48 + .../core/create_ip_sec_connection_details.go | 38 + .../create_local_peering_gateway_details.go | 31 + ..._local_peering_gateway_request_response.go | 48 + .../core/create_private_ip_details.go | 46 + .../create_private_ip_request_response.go | 48 + .../core/create_route_table_details.go | 33 + .../create_route_table_request_response.go | 48 + .../core/create_security_list_details.go | 36 + .../create_security_list_request_response.go | 48 + .../oci-go-sdk/core/create_subnet_details.go | 76 + .../core/create_subnet_request_response.go | 48 + .../oci-go-sdk/core/create_vcn_details.go | 45 + .../core/create_vcn_request_response.go | 48 + .../core/create_virtual_circuit_details.go | 98 + ...e_virtual_circuit_public_prefix_details.go | 25 + ...create_virtual_circuit_request_response.go | 48 + .../oci-go-sdk/core/create_vnic_details.go | 85 + .../core/create_volume_backup_details.go | 28 + .../create_volume_backup_request_response.go | 48 + .../oci-go-sdk/core/create_volume_details.go | 80 + .../core/create_volume_request_response.go | 48 + .../oracle/oci-go-sdk/core/cross_connect.go | 94 + .../oci-go-sdk/core/cross_connect_group.go | 77 + .../oci-go-sdk/core/cross_connect_location.go | 28 + .../oci-go-sdk/core/cross_connect_mapping.go | 76 + .../core/cross_connect_port_speed_shape.go | 29 + .../oci-go-sdk/core/cross_connect_status.go | 91 + .../delete_boot_volume_request_response.go | 40 + ...delete_console_history_request_response.go | 40 + .../core/delete_cpe_request_response.go | 40 + ...te_cross_connect_group_request_response.go | 40 + .../delete_cross_connect_request_response.go | 40 + .../delete_dhcp_options_request_response.go | 40 + .../delete_drg_attachment_request_response.go | 40 + .../core/delete_drg_request_response.go | 40 + ...ete_i_p_sec_connection_request_response.go | 40 + .../core/delete_image_request_response.go | 40 + ...nce_console_connection_request_response.go | 40 + ...elete_internet_gateway_request_response.go | 40 + ..._local_peering_gateway_request_response.go | 40 + .../delete_private_ip_request_response.go | 40 + .../delete_route_table_request_response.go | 40 + .../delete_security_list_request_response.go | 40 + .../core/delete_subnet_request_response.go | 40 + .../core/delete_vcn_request_response.go | 40 + ...e_virtual_circuit_public_prefix_details.go | 24 + ...delete_virtual_circuit_request_response.go | 40 + .../delete_volume_backup_request_response.go | 40 + .../core/delete_volume_request_response.go | 40 + .../detach_boot_volume_request_response.go | 40 + .../core/detach_vnic_request_response.go | 40 + .../core/detach_volume_request_response.go | 40 + .../oracle/oci-go-sdk/core/dhcp_dns_option.go | 81 + .../oracle/oci-go-sdk/core/dhcp_option.go | 64 + .../oracle/oci-go-sdk/core/dhcp_options.go | 115 + .../core/dhcp_search_domain_option.go | 50 + .../github.com/oracle/oci-go-sdk/core/drg.go | 72 + .../oracle/oci-go-sdk/core/drg_attachment.go | 72 + .../oci-go-sdk/core/egress_security_rule.go | 56 + .../oci-go-sdk/core/export_image_details.go | 66 + .../core/export_image_request_response.go | 56 + ..._image_via_object_storage_tuple_details.go | 45 + ...rt_image_via_object_storage_uri_details.go | 40 + .../core/fast_connect_provider_service.go | 142 ++ ...boot_volume_attachment_request_response.go | 41 + .../core/get_boot_volume_request_response.go | 41 + ...onsole_history_content_request_response.go | 47 + .../get_console_history_request_response.go | 41 + .../core/get_cpe_request_response.go | 41 + ...et_cross_connect_group_request_response.go | 41 + ...ct_letter_of_authority_request_response.go | 38 + .../get_cross_connect_request_response.go | 41 + ...t_cross_connect_status_request_response.go | 38 + .../core/get_dhcp_options_request_response.go | 41 + .../get_drg_attachment_request_response.go | 41 + .../core/get_drg_request_response.go | 41 + ...nnect_provider_service_request_response.go | 38 + ...nnection_device_config_request_response.go | 41 + ...nnection_device_status_request_response.go | 41 + ...get_i_p_sec_connection_request_response.go | 41 + .../core/get_image_request_response.go | 41 + ...nce_console_connection_request_response.go | 38 + .../core/get_instance_request_response.go | 41 + .../get_internet_gateway_request_response.go | 41 + ..._local_peering_gateway_request_response.go | 41 + .../core/get_private_ip_request_response.go | 41 + .../core/get_route_table_request_response.go | 41 + .../get_security_list_request_response.go | 41 + .../core/get_subnet_request_response.go | 41 + .../core/get_vcn_request_response.go | 41 + .../get_virtual_circuit_request_response.go | 41 + .../get_vnic_attachment_request_response.go | 41 + .../core/get_vnic_request_response.go | 41 + .../get_volume_attachment_request_response.go | 41 + .../get_volume_backup_request_response.go | 41 + .../core/get_volume_request_response.go | 41 + ...ce_initial_credentials_request_response.go | 38 + .../core/i_scsi_volume_attachment.go | 125 + .../oracle/oci-go-sdk/core/icmp_options.go | 33 + .../oracle/oci-go-sdk/core/image.go | 90 + .../oci-go-sdk/core/image_source_details.go | 60 + ...source_via_object_storage_tuple_details.go | 45 + ...e_source_via_object_storage_uri_details.go | 39 + .../oci-go-sdk/core/ingress_security_rule.go | 56 + .../oracle/oci-go-sdk/core/instance.go | 170 ++ .../core/instance_action_request_response.go | 83 + .../core/instance_console_connection.go | 71 + .../oci-go-sdk/core/instance_credentials.go | 27 + .../core/instance_source_details.go | 60 + ...instance_source_via_boot_volume_details.go | 39 + .../core/instance_source_via_image_details.go | 39 + .../oci-go-sdk/core/internet_gateway.go | 77 + .../oci-go-sdk/core/ip_sec_connection.go | 82 + .../core/ip_sec_connection_device_config.go | 33 + .../core/ip_sec_connection_device_status.go | 34 + .../core/launch_instance_details.go | 172 ++ .../core/launch_instance_request_response.go | 48 + .../oci-go-sdk/core/letter_of_authority.go | 67 + ...oot_volume_attachments_request_response.go | 60 + .../list_boot_volumes_request_response.go | 54 + ...list_console_histories_request_response.go | 119 + .../core/list_cpes_request_response.go | 50 + ...t_cross_connect_groups_request_response.go | 115 + ...ross_connect_locations_request_response.go | 50 + .../list_cross_connects_request_response.go | 118 + ...nect_port_speed_shapes_request_response.go | 50 + .../list_dhcp_options_request_response.go | 118 + .../list_drg_attachments_request_response.go | 56 + .../core/list_drgs_request_response.go | 50 + ...nect_provider_services_request_response.go | 50 + ...rcuit_bandwidth_shapes_request_response.go | 50 + ...st_i_p_sec_connections_request_response.go | 56 + .../core/list_images_request_response.go | 123 + ...ce_console_connections_request_response.go | 53 + .../core/list_instances_request_response.go | 119 + ...list_internet_gateways_request_response.go | 118 + ...local_peering_gateways_request_response.go | 53 + .../core/list_private_ips_request_response.go | 57 + .../list_route_tables_request_response.go | 118 + .../list_security_lists_request_response.go | 118 + .../core/list_shapes_request_response.go | 57 + .../core/list_subnets_request_response.go | 118 + .../core/list_vcns_request_response.go | 115 + ...rcuit_bandwidth_shapes_request_response.go | 50 + ...ircuit_public_prefixes_request_response.go | 42 + .../list_virtual_circuits_request_response.go | 115 + .../list_vnic_attachments_request_response.go | 60 + ...ist_volume_attachments_request_response.go | 60 + .../list_volume_backups_request_response.go | 118 + .../core/list_volumes_request_response.go | 119 + .../oci-go-sdk/core/local_peering_gateway.go | 123 + .../oracle/oci-go-sdk/core/port_range.go | 28 + .../oracle/oci-go-sdk/core/private_ip.go | 89 + .../oracle/oci-go-sdk/core/route_rule.go | 32 + .../oracle/oci-go-sdk/core/route_table.go | 76 + .../oracle/oci-go-sdk/core/security_list.go | 84 + .../oracle/oci-go-sdk/core/shape.go | 26 + .../oracle/oci-go-sdk/core/subnet.go | 131 ++ .../oracle/oci-go-sdk/core/tcp_options.go | 30 + .../terminate_instance_request_response.go | 44 + .../oracle/oci-go-sdk/core/tunnel_config.go | 33 + .../oracle/oci-go-sdk/core/tunnel_status.go | 61 + .../oracle/oci-go-sdk/core/udp_options.go | 30 + .../core/update_boot_volume_details.go | 25 + .../update_boot_volume_request_response.go | 49 + .../core/update_console_history_details.go | 24 + ...update_console_history_request_response.go | 49 + .../oci-go-sdk/core/update_cpe_details.go | 25 + .../core/update_cpe_request_response.go | 49 + .../core/update_cross_connect_details.go | 31 + .../update_cross_connect_group_details.go | 25 + ...te_cross_connect_group_request_response.go | 49 + .../update_cross_connect_request_response.go | 49 + .../oci-go-sdk/core/update_dhcp_details.go | 51 + .../update_dhcp_options_request_response.go | 49 + .../core/update_drg_attachment_details.go | 25 + .../update_drg_attachment_request_response.go | 49 + .../oci-go-sdk/core/update_drg_details.go | 25 + .../core/update_drg_request_response.go | 49 + ...ate_i_p_sec_connection_request_response.go | 49 + .../oci-go-sdk/core/update_image_details.go | 26 + .../core/update_image_request_response.go | 56 + .../core/update_instance_details.go | 26 + .../core/update_instance_request_response.go | 56 + .../core/update_internet_gateway_details.go | 28 + ...pdate_internet_gateway_request_response.go | 49 + .../core/update_ip_sec_connection_details.go | 25 + .../update_local_peering_gateway_details.go | 25 + ..._local_peering_gateway_request_response.go | 49 + .../core/update_private_ip_details.go | 40 + .../update_private_ip_request_response.go | 49 + .../core/update_route_table_details.go | 28 + .../update_route_table_request_response.go | 49 + .../core/update_security_list_details.go | 31 + .../update_security_list_request_response.go | 49 + .../oci-go-sdk/core/update_subnet_details.go | 25 + .../core/update_subnet_request_response.go | 49 + .../oci-go-sdk/core/update_vcn_details.go | 25 + .../core/update_vcn_request_response.go | 49 + .../core/update_virtual_circuit_details.go | 90 + ...update_virtual_circuit_request_response.go | 49 + .../oci-go-sdk/core/update_vnic_details.go | 45 + .../core/update_vnic_request_response.go | 49 + .../core/update_volume_backup_details.go | 25 + .../update_volume_backup_request_response.go | 45 + .../oci-go-sdk/core/update_volume_details.go | 25 + .../core/update_volume_request_response.go | 49 + .../github.com/oracle/oci-go-sdk/core/vcn.go | 101 + .../oracle/oci-go-sdk/core/virtual_circuit.go | 273 +++ .../core/virtual_circuit_bandwidth_shape.go | 29 + .../core/virtual_circuit_public_prefix.go | 58 + .../github.com/oracle/oci-go-sdk/core/vnic.go | 118 + .../oracle/oci-go-sdk/core/vnic_attachment.go | 92 + .../oracle/oci-go-sdk/core/volume.go | 127 ++ .../oci-go-sdk/core/volume_attachment.go | 171 ++ .../oracle/oci-go-sdk/core/volume_backup.go | 96 + .../oci-go-sdk/core/volume_source_details.go | 60 + ...olume_source_from_volume_backup_details.go | 39 + .../core/volume_source_from_volume_details.go | 39 + .../oracle/oci-go-sdk/database/backup.go | 106 + .../oci-go-sdk/database/backup_summary.go | 106 + .../database/create_backup_details.go | 27 + .../create_backup_request_response.go | 48 + .../create_data_guard_association_details.go | 158 ++ ...data_guard_association_request_response.go | 51 + ...sociation_to_existing_db_system_details.go | 79 + .../database/create_database_details.go | 66 + .../create_database_from_backup_details.go | 30 + .../database/create_db_home_details.go | 28 + .../create_db_home_request_response.go | 48 + .../create_db_home_with_db_system_id_base.go | 80 + ...reate_db_home_with_db_system_id_details.go | 57 + ...e_with_db_system_id_from_backup_details.go | 54 + .../database/data_guard_association.go | 211 ++ .../data_guard_association_summary.go | 211 ++ .../oracle/oci-go-sdk/database/database.go | 95 + .../oci-go-sdk/database/database_client.go | 753 ++++++ .../oci-go-sdk/database/database_summary.go | 95 + .../oci-go-sdk/database/db_backup_config.go | 25 + .../oracle/oci-go-sdk/database/db_home.go | 82 + .../oci-go-sdk/database/db_home_summary.go | 82 + .../oracle/oci-go-sdk/database/db_node.go | 83 + .../db_node_action_request_response.go | 83 + .../oci-go-sdk/database/db_node_summary.go | 83 + .../oracle/oci-go-sdk/database/db_system.go | 236 ++ .../database/db_system_shape_summary.go | 34 + .../oci-go-sdk/database/db_system_summary.go | 236 ++ .../oci-go-sdk/database/db_version_summary.go | 28 + .../delete_backup_request_response.go | 40 + .../delete_db_home_request_response.go | 43 + ...failover_data_guard_association_details.go | 24 + ...data_guard_association_request_response.go | 52 + .../database/get_backup_request_response.go | 41 + ...data_guard_association_request_response.go | 44 + .../database/get_database_request_response.go | 41 + ...me_patch_history_entry_request_response.go | 44 + .../get_db_home_patch_request_response.go | 41 + .../database/get_db_home_request_response.go | 41 + .../database/get_db_node_request_response.go | 41 + ...em_patch_history_entry_request_response.go | 44 + .../get_db_system_patch_request_response.go | 41 + .../get_db_system_request_response.go | 41 + .../database/launch_db_system_details.go | 171 ++ .../launch_db_system_request_response.go | 48 + .../database/list_backups_request_response.go | 53 + ...ata_guard_associations_request_response.go | 50 + .../list_databases_request_response.go | 53 + ..._patch_history_entries_request_response.go | 50 + .../list_db_home_patches_request_response.go | 50 + .../list_db_homes_request_response.go | 53 + .../list_db_nodes_request_response.go | 53 + ..._patch_history_entries_request_response.go | 50 + ...list_db_system_patches_request_response.go | 50 + .../list_db_system_shapes_request_response.go | 53 + .../list_db_systems_request_response.go | 50 + .../list_db_versions_request_response.go | 53 + .../oracle/oci-go-sdk/database/patch.go | 122 + .../oci-go-sdk/database/patch_details.go | 52 + .../database/patch_history_entry.go | 91 + .../database/patch_history_entry_summary.go | 91 + .../oci-go-sdk/database/patch_summary.go | 122 + ...einstate_data_guard_association_details.go | 24 + ...data_guard_association_request_response.go | 52 + .../database/restore_database_details.go | 30 + .../restore_database_request_response.go | 49 + ...itchover_data_guard_association_details.go | 24 + ...data_guard_association_request_response.go | 52 + .../terminate_db_system_request_response.go | 40 + .../database/update_database_details.go | 22 + .../update_database_request_response.go | 49 + .../database/update_db_home_details.go | 22 + .../update_db_home_request_response.go | 49 + .../database/update_db_system_details.go | 32 + .../update_db_system_request_response.go | 49 + .../oracle/oci-go-sdk/example/helpers/args.go | 46 + .../oci-go-sdk/example/helpers/helper.go | 111 + .../identity/add_user_to_group_details.go | 27 + .../add_user_to_group_request_response.go | 48 + .../oracle/oci-go-sdk/identity/api_key.go | 80 + .../identity/availability_domain.go | 29 + .../oracle/oci-go-sdk/identity/compartment.go | 88 + .../identity/create_api_key_details.go | 24 + .../identity/create_compartment_details.go | 31 + .../create_compartment_request_response.go | 48 + .../create_customer_secret_key_details.go | 24 + ...te_customer_secret_key_request_response.go | 51 + .../identity/create_group_details.go | 31 + .../identity/create_group_request_response.go | 48 + .../create_identity_provider_details.go | 125 + ...eate_identity_provider_request_response.go | 48 + .../create_idp_group_mapping_details.go | 28 + ...eate_idp_group_mapping_request_response.go | 51 + ..._or_reset_u_i_password_request_response.go | 48 + .../identity/create_policy_details.go | 41 + .../create_policy_request_response.go | 48 + .../create_region_subscription_details.go | 29 + ...te_region_subscription_request_response.go | 48 + .../create_saml2_identity_provider_details.go | 81 + .../identity/create_swift_password_details.go | 24 + .../create_swift_password_request_response.go | 51 + .../identity/create_user_details.go | 31 + .../identity/create_user_request_response.go | 48 + .../identity/customer_secret_key.go | 82 + .../identity/customer_secret_key_summary.go | 76 + .../delete_api_key_request_response.go | 43 + ...te_customer_secret_key_request_response.go | 43 + .../identity/delete_group_request_response.go | 40 + ...lete_identity_provider_request_response.go | 40 + ...lete_idp_group_mapping_request_response.go | 43 + .../delete_policy_request_response.go | 40 + .../delete_swift_password_request_response.go | 43 + .../identity/delete_user_request_response.go | 40 + .../oci-go-sdk/identity/fault_domain.go | 32 + .../get_compartment_request_response.go | 41 + .../identity/get_group_request_response.go | 41 + .../get_identity_provider_request_response.go | 41 + .../get_idp_group_mapping_request_response.go | 44 + .../identity/get_policy_request_response.go | 41 + .../identity/get_tenancy_request_response.go | 38 + ..._user_group_membership_request_response.go | 41 + .../identity/get_user_request_response.go | 41 + .../oracle/oci-go-sdk/identity/group.go | 84 + .../oci-go-sdk/identity/identity_client.go | 1167 ++++++++++ .../oci-go-sdk/identity/identity_provider.go | 185 ++ .../oci-go-sdk/identity/idp_group_mapping.go | 84 + .../list_api_keys_request_response.go | 43 + ...t_availability_domains_request_response.go | 43 + .../list_compartments_request_response.go | 49 + ...t_customer_secret_keys_request_response.go | 43 + .../list_fault_domains_request_response.go | 41 + .../identity/list_groups_request_response.go | 49 + ...ist_identity_providers_request_response.go | 73 + ...ist_idp_group_mappings_request_response.go | 49 + .../list_policies_request_response.go | 49 + ...t_region_subscriptions_request_response.go | 38 + .../identity/list_regions_request_response.go | 35 + .../list_swift_passwords_request_response.go | 43 + ...user_group_memberships_request_response.go | 55 + .../identity/list_users_request_response.go | 49 + .../oracle/oci-go-sdk/identity/policy.go | 91 + .../oracle/oci-go-sdk/identity/region.go | 40 + .../identity/region_subscription.go | 68 + ...remove_user_from_group_request_response.go | 40 + .../identity/saml2_identity_provider.go | 127 ++ .../oci-go-sdk/identity/swift_password.go | 83 + .../oracle/oci-go-sdk/identity/tenancy.go | 43 + .../oracle/oci-go-sdk/identity/ui_password.go | 69 + .../identity/update_compartment_details.go | 27 + .../update_compartment_request_response.go | 49 + .../update_customer_secret_key_details.go | 24 + ...te_customer_secret_key_request_response.go | 52 + .../identity/update_group_details.go | 24 + .../identity/update_group_request_response.go | 49 + .../update_identity_provider_details.go | 67 + ...date_identity_provider_request_response.go | 49 + .../update_idp_group_mapping_details.go | 27 + ...date_idp_group_mapping_request_response.go | 52 + .../identity/update_policy_details.go | 34 + .../update_policy_request_response.go | 49 + .../update_saml2_identity_provider_details.go | 52 + .../identity/update_state_details.go | 24 + .../identity/update_swift_password_details.go | 24 + .../update_swift_password_request_response.go | 52 + .../identity/update_user_details.go | 24 + .../identity/update_user_request_response.go | 49 + .../update_user_state_request_response.go | 49 + .../upload_api_key_request_response.go | 51 + .../oracle/oci-go-sdk/identity/user.go | 91 + .../identity/user_group_membership.go | 74 + .../oracle/oci-go-sdk/loadbalancer/backend.go | 57 + .../loadbalancer/backend_details.go | 52 + .../oci-go-sdk/loadbalancer/backend_health.go | 58 + .../oci-go-sdk/loadbalancer/backend_set.go | 41 + .../loadbalancer/backend_set_details.go | 35 + .../loadbalancer/backend_set_health.go | 78 + .../oci-go-sdk/loadbalancer/certificate.go | 51 + .../loadbalancer/certificate_details.go | 66 + .../loadbalancer/create_backend_details.go | 54 + .../create_backend_request_response.go | 56 + .../create_backend_set_details.go | 41 + .../create_backend_set_request_response.go | 52 + .../create_certificate_details.go | 66 + .../create_certificate_request_response.go | 52 + .../loadbalancer/create_listener_details.go | 43 + .../create_listener_request_response.go | 52 + .../create_load_balancer_details.go | 57 + .../create_load_balancer_request_response.go | 49 + .../delete_backend_request_response.go | 50 + .../delete_backend_set_request_response.go | 46 + .../delete_certificate_request_response.go | 46 + .../delete_listener_request_response.go | 46 + .../delete_load_balancer_request_response.go | 42 + .../get_backend_health_request_response.go | 50 + .../get_backend_request_response.go | 50 + ...get_backend_set_health_request_response.go | 46 + .../get_backend_set_request_response.go | 46 + .../get_health_checker_request_response.go | 46 + ...t_load_balancer_health_request_response.go | 42 + .../get_load_balancer_request_response.go | 42 + .../get_work_request_request_response.go | 42 + .../loadbalancer/health_check_result.go | 71 + .../oci-go-sdk/loadbalancer/health_checker.go | 57 + .../loadbalancer/health_checker_details.go | 55 + .../oci-go-sdk/loadbalancer/ip_address.go | 30 + .../list_backend_sets_request_response.go | 42 + .../list_backends_request_response.go | 46 + .../list_certificates_request_response.go | 42 + ..._load_balancer_healths_request_response.go | 55 + .../list_load_balancers_request_response.go | 117 + .../list_policies_request_response.go | 55 + .../list_protocols_request_response.go | 55 + .../list_shapes_request_response.go | 55 + .../list_work_requests_request_response.go | 55 + .../oci-go-sdk/loadbalancer/listener.go | 42 + .../loadbalancer/listener_details.go | 36 + .../oci-go-sdk/loadbalancer/load_balancer.go | 104 + .../loadbalancer/load_balancer_health.go | 82 + .../load_balancer_health_summary.go | 64 + .../loadbalancer/load_balancer_policy.go | 26 + .../loadbalancer/load_balancer_protocol.go | 24 + .../loadbalancer/load_balancer_shape.go | 27 + .../loadbalancer/loadbalancer_client.go | 656 ++++++ ...ssion_persistence_configuration_details.go | 37 + .../loadbalancer/ssl_configuration.go | 36 + .../loadbalancer/ssl_configuration_details.go | 35 + .../loadbalancer/update_backend_details.go | 44 + .../update_backend_request_response.go | 60 + .../update_backend_set_details.go | 35 + .../update_backend_set_request_response.go | 56 + .../update_health_checker_details.go | 54 + .../update_health_checker_request_response.go | 56 + .../loadbalancer/update_listener_details.go | 36 + .../update_listener_request_response.go | 56 + .../update_load_balancer_details.go | 26 + .../update_load_balancer_request_response.go | 52 + .../oci-go-sdk/loadbalancer/work_request.go | 82 + .../loadbalancer/work_request_error.go | 48 + ...abort_multipart_upload_request_response.go | 52 + .../oracle/oci-go-sdk/objectstorage/bucket.go | 73 + .../objectstorage/bucket_summary.go | 41 + .../commit_multipart_upload_details.go | 30 + .../commit_multipart_upload_part_details.go | 29 + ...ommit_multipart_upload_request_response.go | 76 + .../objectstorage/create_bucket_details.go | 62 + .../create_bucket_request_response.go | 53 + .../create_multipart_upload_details.go | 39 + ...reate_multipart_upload_request_response.go | 63 + ...create_preauthenticated_request_details.go | 61 + ...eauthenticated_request_request_response.go | 51 + .../delete_bucket_request_response.go | 49 + .../delete_object_request_response.go | 56 + ...eauthenticated_request_request_response.go | 49 + .../get_bucket_request_response.go | 66 + .../get_namespace_request_response.go | 34 + .../get_object_request_response.go | 107 + ...eauthenticated_request_request_response.go | 52 + .../head_bucket_request_response.go | 63 + .../head_object_request_response.go | 96 + .../list_buckets_request_response.go | 59 + ...multipart_upload_parts_request_response.go | 67 + ...list_multipart_uploads_request_response.go | 60 + .../oci-go-sdk/objectstorage/list_objects.go | 33 + .../list_objects_request_response.go | 73 + ...authenticated_requests_request_response.go | 63 + .../objectstorage/multipart_upload.go | 38 + .../multipart_upload_part_summary.go | 35 + .../objectstorage/object_summary.go | 35 + .../objectstorage/objectstorage_client.go | 478 ++++ .../objectstorage/preauthenticated_request.go | 71 + .../preauthenticated_request_summary.go | 68 + .../put_object_request_response.go | 92 + .../objectstorage/update_bucket_details.go | 61 + .../update_bucket_request_response.go | 58 + .../upload_part_request_response.go | 83 + vendor/github.com/oracle/oci-go-sdk/oci.go | 232 ++ .../github.com/oracle/oci-go-sdk/wercker.yml | 26 + vendor/vendor.json | 9 +- 566 files changed, 39598 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/oracle/oci-go-sdk/CHANGELOG.md create mode 100644 vendor/github.com/oracle/oci-go-sdk/CONTRIBUTING.md create mode 100644 vendor/github.com/oracle/oci-go-sdk/LICENSE.txt create mode 100644 vendor/github.com/oracle/oci-go-sdk/Makefile create mode 100644 vendor/github.com/oracle/oci-go-sdk/README.md create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/audit_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/audit_event.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/configuration.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/get_configuration_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/list_events_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/cmd/genver/version_template.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/auth/certificate_retriever.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/auth/configuration.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/auth/federation_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/auth/instance_principal_key_provider.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/auth/jwt.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/auth/utils.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/common.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/configuration.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/errors.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/helpers.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/http.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/http_signer.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/log.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/version.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_i_scsi_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/attach_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/boot_volume.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/boot_volume_attachment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/console_history.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/core_blockstorage_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/core_compute_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/core_virtualnetwork_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cpe.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_cpe_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_cpe_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_options_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_drg_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_drg_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_i_p_sec_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_image_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_image_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_ip_sec_connection_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_route_table_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_route_table_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_security_list_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_security_list_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_subnet_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_subnet_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_vcn_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_vcn_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_public_prefix_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_vnic_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/create_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cross_connect.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cross_connect_group.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cross_connect_location.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cross_connect_mapping.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cross_connect_port_speed_shape.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/cross_connect_status.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_boot_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_console_history_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_cpe_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_dhcp_options_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_drg_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_drg_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_i_p_sec_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_image_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_instance_console_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_internet_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_local_peering_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_private_ip_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_route_table_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_security_list_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_subnet_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_vcn_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_public_prefix_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_volume_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/delete_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/detach_boot_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/detach_vnic_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/detach_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/dhcp_dns_option.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/dhcp_option.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/dhcp_options.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/dhcp_search_domain_option.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/drg.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/drg_attachment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/egress_security_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/export_image_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/export_image_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_tuple_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_uri_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/fast_connect_provider_service.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_console_history_content_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_console_history_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_cpe_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_letter_of_authority_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_status_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_dhcp_options_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_drg_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_drg_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_fast_connect_provider_service_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_config_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_status_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_image_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_instance_console_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_instance_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_internet_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_local_peering_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_private_ip_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_route_table_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_security_list_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_subnet_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_vcn_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_virtual_circuit_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_vnic_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_vnic_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_volume_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_volume_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/get_windows_instance_initial_credentials_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/i_scsi_volume_attachment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/icmp_options.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/image.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/image_source_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_tuple_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_uri_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/ingress_security_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance_action_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance_console_connection.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance_credentials.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance_source_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_boot_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_image_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/internet_gateway.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_config.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_status.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/launch_instance_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/launch_instance_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/letter_of_authority.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_boot_volume_attachments_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_boot_volumes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_console_histories_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_cpes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_groups_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_locations_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_cross_connects_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_crossconnect_port_speed_shapes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_dhcp_options_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_drg_attachments_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_drgs_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_services_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_virtual_circuit_bandwidth_shapes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_i_p_sec_connections_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_images_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_instance_console_connections_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_instances_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_internet_gateways_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_local_peering_gateways_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_private_ips_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_route_tables_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_security_lists_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_shapes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_subnets_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_vcns_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_bandwidth_shapes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_public_prefixes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuits_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_vnic_attachments_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_volume_attachments_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_volume_backups_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/list_volumes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/local_peering_gateway.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/port_range.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/private_ip.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/route_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/route_table.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/security_list.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/shape.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/subnet.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/tcp_options.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/terminate_instance_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/tunnel_config.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/tunnel_status.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/udp_options.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_console_history_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_console_history_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_cpe_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_cpe_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_options_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_drg_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_drg_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_i_p_sec_connection_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_image_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_image_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_instance_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_instance_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_ip_sec_connection_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_route_table_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_route_table_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_security_list_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_security_list_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_subnet_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_subnet_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_vcn_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_vcn_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_vnic_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_vnic_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/update_volume_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/vcn.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_bandwidth_shape.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_public_prefix.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/vnic.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/vnic_attachment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/volume.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/volume_attachment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/volume_backup.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/volume_source_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_backup_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/backup.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/backup_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_backup_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_to_existing_db_system_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_database_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_database_from_backup_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_db_home_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_db_home_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_base.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_from_backup_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/data_guard_association.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/data_guard_association_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/database.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/database_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/database_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_backup_config.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_home.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_home_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_node.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_node_action_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_node_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_system.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_system_shape_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_system_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/db_version_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/delete_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/delete_db_home_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_backup_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_data_guard_association_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_database_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_history_entry_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_home_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_node_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_history_entry_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/get_db_system_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_backups_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_data_guard_associations_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_databases_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patch_history_entries_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patches_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_homes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_nodes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patch_history_entries_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patches_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_system_shapes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_systems_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/list_db_versions_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/patch.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/patch_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/patch_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/restore_database_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/restore_database_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/terminate_db_system_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/update_database_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/update_database_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/update_db_home_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/update_db_home_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/update_db_system_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/database/update_db_system_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/example/helpers/args.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/example/helpers/helper.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/api_key.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/availability_domain.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/compartment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_api_key_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_group_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_or_reset_u_i_password_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_policy_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_saml2_identity_provider_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_user_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/create_user_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_api_key_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_customer_secret_key_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_identity_provider_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_idp_group_mapping_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_swift_password_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/delete_user_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/fault_domain.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_compartment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_identity_provider_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_idp_group_mapping_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_tenancy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_user_group_membership_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/get_user_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/group.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/identity_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/identity_provider.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/idp_group_mapping.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_api_keys_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_availability_domains_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_compartments_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_customer_secret_keys_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_fault_domains_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_groups_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_identity_providers_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_idp_group_mappings_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_policies_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_region_subscriptions_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_regions_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_swift_passwords_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_user_group_memberships_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/list_users_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/policy.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/region.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/region_subscription.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/remove_user_from_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/saml2_identity_provider.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/swift_password.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/tenancy.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/ui_password.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_group_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_group_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_policy_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_saml2_identity_provider_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_state_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_user_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_user_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/update_user_state_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/upload_api_key_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/user.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/identity/user_group_membership.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_health.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_health.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_certificate_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_listener_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_load_balancer_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_health_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_health_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_health_checker_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_health_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_work_request_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_check_result.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/ip_address.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backend_sets_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backends_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_certificates_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancer_healths_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancers_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_policies_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_protocols_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_shapes_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_work_requests_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_policy.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_protocol.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_shape.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/loadbalancer_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/session_persistence_configuration_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request_error.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/abort_multipart_upload_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_part_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_bucket_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_object_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_preauthenticated_request_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/get_bucket_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/get_namespace_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/get_object_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/get_preauthenticated_request_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/head_bucket_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/head_object_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/list_buckets_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_upload_parts_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_uploads_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/list_preauthenticated_requests_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload_part_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/object_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/objectstorage_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/put_object_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/objectstorage/upload_part_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/oci.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/wercker.yml diff --git a/vendor/github.com/oracle/oci-go-sdk/CHANGELOG.md b/vendor/github.com/oracle/oci-go-sdk/CHANGELOG.md new file mode 100644 index 000000000..e1a29e257 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/CHANGELOG.md @@ -0,0 +1,15 @@ +# CHANGELOG + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) + + +## 1.0.0 - 2018-02-28 Initial Release +### Added +- Support for Audit service +- Support for Core Services (Networking, Compute, Block Volume) +- Support for Database service +- Support for IAM service +- Support for Load Balancing service +- Suport for Object Storage service diff --git a/vendor/github.com/oracle/oci-go-sdk/CONTRIBUTING.md b/vendor/github.com/oracle/oci-go-sdk/CONTRIBUTING.md new file mode 100644 index 000000000..31e4b6c60 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing to the Oracle Cloud Infrastructure Go SDK + +*Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.* + +Pull requests can be made under +[The Oracle Contributor Agreement](https://www.oracle.com/technetwork/community/oca-486395.html) +(OCA). + +For pull requests to be accepted, the bottom of +your commit message must have the following line using your name and +e-mail address as it appears in the OCA Signatories list. + +``` +Signed-off-by: Your Name <you@example.org> +``` + +This can be automatically added to pull requests by committing with: + +``` +git commit --signoff +```` + +Only pull requests from committers that can be verified as having +signed the OCA can be accepted. \ No newline at end of file diff --git a/vendor/github.com/oracle/oci-go-sdk/LICENSE.txt b/vendor/github.com/oracle/oci-go-sdk/LICENSE.txt new file mode 100644 index 000000000..63bc0c882 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/LICENSE.txt @@ -0,0 +1,82 @@ +Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +This software is dual-licensed to you under the Universal Permissive License (UPL) and Apache License 2.0.  See below for license terms.  You may choose either license, or both. + ____________________________ +The Universal Permissive License (UPL), Version 1.0 +Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software (each a "Larger Work" to which the Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. + +This license is subject to the following condition: + +The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +The Apache Software License, Version 2.0 +Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); You may not use this product except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. A copy of the license is also reproduced below. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +1. Definitions. +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. +END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/oracle/oci-go-sdk/Makefile b/vendor/github.com/oracle/oci-go-sdk/Makefile new file mode 100644 index 000000000..d69dfd999 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/Makefile @@ -0,0 +1,55 @@ +DOC_SERVER_URL=https:\/\/docs.us-phoenix-1.oraclecloud.com + +GEN_TARGETS = identity core objectstorage loadbalancer database audit +NON_GEN_TARGETS = common common/auth +TARGETS = $(NON_GEN_TARGETS) $(GEN_TARGETS) + +TARGETS_WITH_TESTS = common common/auth +TARGETS_BUILD = $(patsubst %,build-%, $(TARGETS)) +TARGETS_CLEAN = $(patsubst %,clean-%, $(GEN_TARGETS)) +TARGETS_LINT = $(patsubst %,lint-%, $(TARGETS)) +TARGETS_TEST = $(patsubst %,test-%, $(TARGETS_WITH_TESTS)) +TARGETS_RELEASE= $(patsubst %,release-%, $(TARGETS)) +GOLINT=$(GOPATH)/bin/golint +LINT_FLAGS=-min_confidence 0.9 -set_exit_status + + +.PHONY: $(TARGETS_BUILD) $(TARGET_TEST) + +build: lint $(TARGETS_BUILD) + +test: build $(TARGETS_TEST) + +lint: $(TARGETS_LINT) + +clean: $(TARGETS_CLEAN) + +$(TARGETS_LINT): lint-%:% + @echo "linting and formatting: $<" + @(cd $< && gofmt -s -w .) + @if [ \( $< = common \) -o \( $< = common/auth \) ]; then\ + (cd $< && $(GOLINT) -set_exit_status .);\ + else\ + (cd $< && $(GOLINT) $(LINT_FLAGS) .);\ + fi + +$(TARGETS_BUILD): build-%:% + @echo "building: $<" + @(cd $< && find . -name '*_integ_test.go' | xargs -I{} mv {} ../integtest) + @(cd $< && go build -v) + +$(TARGETS_TEST): test-%:% + @(cd $< && go test -v) + +$(TARGETS_CLEAN): clean-%:% + @echo "cleaning $<" + @-rm -rf $< + +pre-doc: + @echo "Rendering doc server to ${DOC_SERVER_URL}" + find . -name \*.go |xargs sed -i '' 's/{{DOC_SERVER_URL}}/${DOC_SERVER_URL}/g' + +gen-version: + go generate -x + +release: gen-version build pre-doc diff --git a/vendor/github.com/oracle/oci-go-sdk/README.md b/vendor/github.com/oracle/oci-go-sdk/README.md new file mode 100644 index 000000000..4065a1529 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/README.md @@ -0,0 +1,153 @@ +# Oracle Cloud Infrastructure Golang SDK +[![wercker status](https://app.wercker.com/status/09bc4818e7b1d70b04285331a9bdbc41/s/master "wercker status")](https://app.wercker.com/project/byKey/09bc4818e7b1d70b04285331a9bdbc41) + +This is the Go SDK for Oracle Cloud Infrastructure. This project is open source and maintained by Oracle Corp. +The home page for the project is [here](https://godoc.org/github.com/oracle/oci-go-sdk/). +>***WARNING:***: To avoid automatically consuming breaking changes if we have to rev the major version of the Go SDK, +please consider using the [Go dependency management tool](https://github.com/golang/dep), or vendoring the SDK. +This will allow you to pin to a specific version of the Go SDK in your project, letting you control how and when you move to the next major version. + +## Dependencies +- Install [Go programming language](https://golang.org/dl/). +- Install [GNU Make](https://www.gnu.org/software/make/), using the package manager or binary distribution tool appropriate for your platform. + + + +## Installing +Use the following command to install this SDK: + +``` +go get -u github.com/oracle/oci-go-sdk +``` +Alternatively you can git clone this repo. + +## Working with the Go SDK +To start working with the Go SDK, you import the service package, create a client, and then use that client to make calls. + +### Configuring +Before using the SDK, set up a config file with the required credentials. See [SDK and Tool Configuration](https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdkconfig.htm) for instructions. + +Once a config file has been setup, call `common.DefaultConfigProvider()` function as follows: + + ```go + // Import necessary packages + import ( + "github.com/oracle/oci-go-sdk/common" + "github.com/oracle/oci-go-sdk/identity" // Identity or any other service you wish to make requests to +) + + //... + +configProvider := common.DefaultConfigProvider() +``` + + Or, to configure the SDK programmatically instead, implement the `ConfigurationProvider` interface shown below: + ```go +// ConfigurationProvider wraps information about the account owner +type ConfigurationProvider interface { + KeyProvider + TenancyOCID() (string, error) + UserOCID() (string, error) + KeyFingerprint() (string, error) + Region() (string, error) +} +``` + +### Making a request +To make a request to an OCI service, create a client for the service and then use the client to call a function from the service. + +- *Creating a client*: All packages provide a function to create clients, using the naming convention `New<ServiceName>ClientWithConfigurationProvider`, +such as `NewVirtualNetworkClientWithConfigurationProvider` or `NewIdentityClientWithConfigurationProvider`. To create a new client, +pass a struct that conforms to the `ConfigurationProvider` interface, or use the `DefaultConfigProvider()` function in the common package. + +For example: +```go +config := common.DefaultConfigProvider() +client, err := identity.NewIdentityClientWithConfigurationProvider(config) +if err != nil { + panic(err) +} +``` + +- *Making calls*: After successfully creating a client, requests can now be made to the service. Generally all functions associated with an operation +accept [`context.Context`](https://golang.org/pkg/context/) and a struct that wraps all input parameters. The functions then return a response struct +that contains the desired data, and an error struct that describes the error if an error occurs. + +For example: +```go +id := "your_group_id" +response, err := client.GetGroup(context.Background(), identity.GetGroupRequest{GroupId:&id}) +if err != nil { + //Something happened + panic(err) +} +//Process the data in response struct +fmt.Println("Group's name is:", response.Name) +``` + +## Organization of the SDK +The `oci-go-sdk` contains the following: +- **Service packages**: All packages except `common` and any other package found inside `cmd`. These packages represent +the Oracle Cloud Infrastructure services supported by the Go SDK. Each package represents a service. +These packages include methods to interact with the service, structs that model +input and output parameters, and a client struct that acts as receiver for the above methods. + +- **Common package**: Found in the `common` directory. The common package provides supporting functions and structs used by service packages. +Includes HTTP request/response (de)serialization, request signing, JSON parsing, pointer to reference and other helper functions. Most of the functions +in this package are meant to be used by the service packages. + +- **cmd**: Internal tools used by the `oci-go-sdk`. + +## Examples +Examples can be found [here](https://github.com/oracle/oci-go-sdk/tree/master/example) + +## Documentation +Full documentation can be found [on the godocs site](https://godoc.org/github.com/oracle/oci-go-sdk/). + +## Help +* The [Issues](https://github.com/oracle/oci-go-sdk/issues) page of this GitHub repository. +* [Stack Overflow](https://stackoverflow.com/), use the [oracle-cloud-infrastructure](https://stackoverflow.com/questions/tagged/oracle-cloud-infrastructure) and [oci-go-sdk](https://stackoverflow.com/questions/tagged/oci-go-sdk) tags in your post. +* [Developer Tools](https://community.oracle.com/community/cloud_computing/bare-metal/content?filterID=contentstatus%5Bpublished%5D~category%5Bdeveloper-tools%5D&filterID=contentstatus%5Bpublished%5D~objecttype~objecttype%5Bthread%5D) of the Oracle Cloud forums. +* [My Oracle Support](https://support.oracle.com). + + +## Contributing +`oci-go-sdk` is an open source project. See [CONTRIBUTING](/CONTRIBUTING.md) for details. + +Oracle gratefully acknowledges the contributions to oci-go-sdk that have been made by the community. + + +## License +Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +This SDK and sample is dual licensed under the Universal Permissive License 1.0 and the Apache License 2.0. + +See [LICENSE](/LICENSE.txt) for more details. + +## Changes +See [CHANGELOG](/CHANGELOG.md). + +## Known Issues +You can find information on any known issues with the SDK here and under the [Issues](https://github.com/oracle/oci-go-sdk/issues) tab of this project's GitHub repository. + +## Building and testing +### Dev dependencies +- Install [Testify](https://github.com/stretchr/testify) with the command: +```sh +go get github.com/stretchr/testify +``` +- Install [go lint](https://github.com/golang/lint) with the command: +``` +go get -u github.com/golang/lint/golint +``` +### Build +Building is provided by the make file at the root of the project. To build the project execute. + +``` +make build +``` + +To run the tests: +``` +make test +``` diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/audit_client.go b/vendor/github.com/oracle/oci-go-sdk/audit/audit_client.go new file mode 100644 index 000000000..ce0ad0c55 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/audit_client.go @@ -0,0 +1,113 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Audit API +// +// API for the Audit Service. You can use this API for queries, but not bulk-export operations. +// + +package audit + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//AuditClient a client for Audit +type AuditClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewAuditClientWithConfigurationProvider Creates a new default Audit client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewAuditClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client AuditClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = AuditClient{BaseClient: baseClient} + client.BasePath = "20160918" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *AuditClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "audit", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *AuditClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *AuditClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// GetConfiguration Get the configuration +func (client AuditClient) GetConfiguration(ctx context.Context, request GetConfigurationRequest) (response GetConfigurationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/configuration", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListEvents Returns all audit events for the specified compartment that were processed within the specified time range. +func (client AuditClient) ListEvents(ctx context.Context, request ListEventsRequest) (response ListEventsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/auditEvents", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateConfiguration Update the configuration +func (client AuditClient) UpdateConfiguration(ctx context.Context, request UpdateConfigurationRequest) (response UpdateConfigurationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/configuration", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/audit_event.go b/vendor/github.com/oracle/oci-go-sdk/audit/audit_event.go new file mode 100644 index 000000000..bc0012c6d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/audit_event.go @@ -0,0 +1,78 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Audit API +// +// API for the Audit Service. You can use this API for queries, but not bulk-export operations. +// + +package audit + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// AuditEvent The representation of AuditEvent +type AuditEvent struct { + + // The OCID of the tenant. + TenantId *string `mandatory:"false" json:"tenantId"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The GUID of the event. + EventId *string `mandatory:"false" json:"eventId"` + + // The source of the event. + EventSource *string `mandatory:"false" json:"eventSource"` + + // The type of the event. + EventType *string `mandatory:"false" json:"eventType"` + + // The time the event occurred, expressed in RFC 3339 (https://tools.ietf.org/html/rfc3339) timestamp format. + EventTime *common.SDKTime `mandatory:"false" json:"eventTime"` + + // The OCID of the user whose action triggered the event. + PrincipalId *string `mandatory:"false" json:"principalId"` + + // The credential ID of the user. This value is extracted from the HTTP 'Authorization' request header. It consists of the tenantId, userId, and user fingerprint, all delimited by a slash (/). + CredentialId *string `mandatory:"false" json:"credentialId"` + + // The HTTP method of the request. + RequestAction *string `mandatory:"false" json:"requestAction"` + + // The opc-request-id of the request. + RequestId *string `mandatory:"false" json:"requestId"` + + // The user agent of the client that made the request. + RequestAgent *string `mandatory:"false" json:"requestAgent"` + + // The HTTP header fields and values in the request. + RequestHeaders map[string][]string `mandatory:"false" json:"requestHeaders"` + + // The IP address of the source of the request. + RequestOrigin *string `mandatory:"false" json:"requestOrigin"` + + // The query parameter fields and values for the request. + RequestParameters map[string][]string `mandatory:"false" json:"requestParameters"` + + // The resource targeted by the request. + RequestResource *string `mandatory:"false" json:"requestResource"` + + // The headers of the response. + ResponseHeaders map[string][]string `mandatory:"false" json:"responseHeaders"` + + // The status code of the response. + ResponseStatus *string `mandatory:"false" json:"responseStatus"` + + // The time of the response to the audited request, expressed in RFC 3339 (https://tools.ietf.org/html/rfc3339) timestamp format. + ResponseTime *common.SDKTime `mandatory:"false" json:"responseTime"` + + // Metadata of interest from the response payload. For example, the OCID of a resource. + ResponsePayload map[string]interface{} `mandatory:"false" json:"responsePayload"` +} + +func (m AuditEvent) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/configuration.go b/vendor/github.com/oracle/oci-go-sdk/audit/configuration.go new file mode 100644 index 000000000..35d0c9b07 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/configuration.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Audit API +// +// API for the Audit Service. You can use this API for queries, but not bulk-export operations. +// + +package audit + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Configuration The representation of Configuration +type Configuration struct { + + // The retention period days + RetentionPeriodDays *int `mandatory:"false" json:"retentionPeriodDays"` +} + +func (m Configuration) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/get_configuration_request_response.go b/vendor/github.com/oracle/oci-go-sdk/audit/get_configuration_request_response.go new file mode 100644 index 000000000..684d790b0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/get_configuration_request_response.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package audit + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetConfigurationRequest wrapper for the GetConfiguration operation +type GetConfigurationRequest struct { + + // ID of the root compartment (tenancy) + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` +} + +func (request GetConfigurationRequest) String() string { + return common.PointerString(request) +} + +// GetConfigurationResponse wrapper for the GetConfiguration operation +type GetConfigurationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Configuration instance + Configuration `presentIn:"body"` +} + +func (response GetConfigurationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/list_events_request_response.go b/vendor/github.com/oracle/oci-go-sdk/audit/list_events_request_response.go new file mode 100644 index 000000000..e8c6b8d6b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/list_events_request_response.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package audit + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListEventsRequest wrapper for the ListEvents operation +type ListEventsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // Returns events that were processed at or after this start date and time, expressed in RFC 3339 (https://tools.ietf.org/html/rfc3339) timestamp format. + // For example, a start value of `2017-01-15T11:30:00Z` will retrieve a list of all events processed since 30 minutes after the 11th hour of January 15, 2017, in Coordinated Universal Time (UTC). + // You can specify a value with granularity to the minute. Seconds (and milliseconds, if included) must be set to `0`. + StartTime *common.SDKTime `mandatory:"true" contributesTo:"query" name:"startTime"` + + // Returns events that were processed before this end date and time, expressed in RFC 3339 (https://tools.ietf.org/html/rfc3339) timestamp format. For example, a start value of `2017-01-01T00:00:00Z` and an end value of `2017-01-02T00:00:00Z` will retrieve a list of all events processed on January 1, 2017. + // Similarly, a start value of `2017-01-01T00:00:00Z` and an end value of `2017-02-01T00:00:00Z` will result in a list of all events processed between January 1, 2017 and January 31, 2017. + // You can specify a value with granularity to the minute. Seconds (and milliseconds, if included) must be set to `0`. + EndTime *common.SDKTime `mandatory:"true" contributesTo:"query" name:"endTime"` + + // The value of the `opc-next-page` response header from the previous list query. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // Unique Oracle-assigned identifier for the request. + // If you need to contact Oracle about a particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request ListEventsRequest) String() string { + return common.PointerString(request) +} + +// ListEventsResponse wrapper for the ListEvents operation +type ListEventsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []AuditEvent instance + Items []AuditEvent `presentIn:"body"` + + // For pagination of a list of audit events. When this header appears in the response, + // it means you received a partial list and there are more results. + // Include this value as the `page` parameter for the subsequent ListEvents request to get the next batch of events. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListEventsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_details.go b/vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_details.go new file mode 100644 index 000000000..a1129293b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Audit API +// +// API for the Audit Service. You can use this API for queries, but not bulk-export operations. +// + +package audit + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateConfigurationDetails The representation of UpdateConfigurationDetails +type UpdateConfigurationDetails struct { + + // The retention period days + RetentionPeriodDays *int `mandatory:"false" json:"retentionPeriodDays"` +} + +func (m UpdateConfigurationDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_request_response.go b/vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_request_response.go new file mode 100644 index 000000000..2d709a8a8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/audit/update_configuration_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package audit + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateConfigurationRequest wrapper for the UpdateConfiguration operation +type UpdateConfigurationRequest struct { + + // ID of the root compartment (tenancy) + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The configuration properties + UpdateConfigurationDetails `contributesTo:"body"` +} + +func (request UpdateConfigurationRequest) String() string { + return common.PointerString(request) +} + +// UpdateConfigurationResponse wrapper for the UpdateConfiguration operation +type UpdateConfigurationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response UpdateConfigurationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/cmd/genver/version_template.go b/vendor/github.com/oracle/oci-go-sdk/cmd/genver/version_template.go new file mode 100644 index 000000000..5c684fd5e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/cmd/genver/version_template.go @@ -0,0 +1,42 @@ +package main + + +const versionTemplate = ` +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated by go generate; DO NOT EDIT + +package common + +import ( + "bytes" + "fmt" + "sync" +) + +const ( + major = "{{.Major}}" + minor = "{{.Minor}}" + patch = "{{.Patch}}" + tag = "{{.Tag}}" +) + +var once sync.Once +var version string + +// Version returns semantic version of the sdk +func Version() string { + once.Do(func() { + ver := fmt.Sprintf("%s.%s.%s", major, minor, patch) + verBuilder := bytes.NewBufferString(ver) + if tag != "" && tag != "-" { + _, err := verBuilder.WriteString(tag) + if err == nil { + verBuilder = bytes.NewBufferString(ver) + } + } + version = verBuilder.String() + }) + return version +} +` + diff --git a/vendor/github.com/oracle/oci-go-sdk/common/auth/certificate_retriever.go b/vendor/github.com/oracle/oci-go-sdk/common/auth/certificate_retriever.go new file mode 100644 index 000000000..e2e04ee7a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/auth/certificate_retriever.go @@ -0,0 +1,154 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package auth + +import ( + "bytes" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "sync" +) + +// x509CertificateRetriever provides an X509 certificate with the RSA private key +type x509CertificateRetriever interface { + Refresh() error + CertificatePemRaw() []byte + Certificate() *x509.Certificate + PrivateKeyPemRaw() []byte + PrivateKey() *rsa.PrivateKey +} + +// urlBasedX509CertificateRetriever retrieves PEM-encoded X509 certificates from the given URLs. +type urlBasedX509CertificateRetriever struct { + certURL string + privateKeyURL string + passphrase string + certificatePemRaw []byte + certificate *x509.Certificate + privateKeyPemRaw []byte + privateKey *rsa.PrivateKey + mux sync.Mutex +} + +func newURLBasedX509CertificateRetriever(certURL, privateKeyURL, passphrase string) x509CertificateRetriever { + return &urlBasedX509CertificateRetriever{ + certURL: certURL, + privateKeyURL: privateKeyURL, + passphrase: passphrase, + mux: sync.Mutex{}, + } +} + +// Refresh() is failure atomic, i.e., CertificatePemRaw(), Certificate(), PrivateKeyPemRaw(), and PrivateKey() would +// return their previous values if Refresh() fails. +func (r *urlBasedX509CertificateRetriever) Refresh() error { + common.Debugln("Refreshing certificate") + + r.mux.Lock() + defer r.mux.Unlock() + + var err error + + var certificatePemRaw []byte + var certificate *x509.Certificate + if certificatePemRaw, certificate, err = r.renewCertificate(r.certURL); err != nil { + return fmt.Errorf("failed to renew certificate: %s", err.Error()) + } + + var privateKeyPemRaw []byte + var privateKey *rsa.PrivateKey + if r.privateKeyURL != "" { + if privateKeyPemRaw, privateKey, err = r.renewPrivateKey(r.privateKeyURL, r.passphrase); err != nil { + return fmt.Errorf("failed to renew private key: %s", err.Error()) + } + } + + r.certificatePemRaw = certificatePemRaw + r.certificate = certificate + r.privateKeyPemRaw = privateKeyPemRaw + r.privateKey = privateKey + return nil +} + +func (r *urlBasedX509CertificateRetriever) renewCertificate(url string) (certificatePemRaw []byte, certificate *x509.Certificate, err error) { + var body bytes.Buffer + if body, err = httpGet(url); err != nil { + return nil, nil, fmt.Errorf("failed to get certificate from %s: %s", url, err.Error()) + } + + certificatePemRaw = body.Bytes() + var block *pem.Block + block, _ = pem.Decode(certificatePemRaw) + if certificate, err = x509.ParseCertificate(block.Bytes); err != nil { + return nil, nil, fmt.Errorf("failed to parse the new certificate: %s", err.Error()) + } + + return certificatePemRaw, certificate, nil +} + +func (r *urlBasedX509CertificateRetriever) renewPrivateKey(url, passphrase string) (privateKeyPemRaw []byte, privateKey *rsa.PrivateKey, err error) { + var body bytes.Buffer + if body, err = httpGet(url); err != nil { + return nil, nil, fmt.Errorf("failed to get private key from %s: %s", url, err.Error()) + } + + privateKeyPemRaw = body.Bytes() + if privateKey, err = common.PrivateKeyFromBytes(privateKeyPemRaw, &passphrase); err != nil { + return nil, nil, fmt.Errorf("failed to parse the new private key: %s", err.Error()) + } + + return privateKeyPemRaw, privateKey, nil +} + +func (r *urlBasedX509CertificateRetriever) CertificatePemRaw() []byte { + r.mux.Lock() + defer r.mux.Unlock() + + if r.certificatePemRaw == nil { + return nil + } + + c := make([]byte, len(r.certificatePemRaw)) + copy(c, r.certificatePemRaw) + return c +} + +func (r *urlBasedX509CertificateRetriever) Certificate() *x509.Certificate { + r.mux.Lock() + defer r.mux.Unlock() + + if r.certificate == nil { + return nil + } + + c := *r.certificate + return &c +} + +func (r *urlBasedX509CertificateRetriever) PrivateKeyPemRaw() []byte { + r.mux.Lock() + defer r.mux.Unlock() + + if r.privateKeyPemRaw == nil { + return nil + } + + c := make([]byte, len(r.privateKeyPemRaw)) + copy(c, r.privateKeyPemRaw) + return c +} + +func (r *urlBasedX509CertificateRetriever) PrivateKey() *rsa.PrivateKey { + r.mux.Lock() + defer r.mux.Unlock() + + if r.privateKey == nil { + return nil + } + + c := *r.privateKey + return &c +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/auth/configuration.go b/vendor/github.com/oracle/oci-go-sdk/common/auth/configuration.go new file mode 100644 index 000000000..b0f455e9b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/auth/configuration.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package auth + +import ( + "crypto/rsa" + "fmt" + "github.com/oracle/oci-go-sdk/common" +) + +type instancePrincipalConfigurationProvider struct { + keyProvider *instancePrincipalKeyProvider + region *common.Region +} + +//InstancePrincipalConfigurationProvider returns a configuration for instance principals +func InstancePrincipalConfigurationProvider() (common.ConfigurationProvider, error) { + var err error + var keyProvider *instancePrincipalKeyProvider + if keyProvider, err = newInstancePrincipalKeyProvider(); err != nil { + return nil, fmt.Errorf("failed to create a new key provider for instance principal: %s", err.Error()) + } + return instancePrincipalConfigurationProvider{keyProvider: keyProvider, region: nil}, nil +} + +//InstancePrincipalConfigurationProviderForRegion returns a configuration for instance principals with a given region +func InstancePrincipalConfigurationProviderForRegion(region common.Region) (common.ConfigurationProvider, error) { + var err error + var keyProvider *instancePrincipalKeyProvider + if keyProvider, err = newInstancePrincipalKeyProvider(); err != nil { + return nil, fmt.Errorf("failed to create a new key provider for instance principal: %s", err.Error()) + } + return instancePrincipalConfigurationProvider{keyProvider: keyProvider, region: &region}, nil +} + +func (p instancePrincipalConfigurationProvider) PrivateRSAKey() (*rsa.PrivateKey, error) { + return p.keyProvider.PrivateRSAKey() +} + +func (p instancePrincipalConfigurationProvider) KeyID() (string, error) { + return p.keyProvider.KeyID() +} + +func (p instancePrincipalConfigurationProvider) TenancyOCID() (string, error) { + return "", nil +} + +func (p instancePrincipalConfigurationProvider) UserOCID() (string, error) { + return "", nil +} + +func (p instancePrincipalConfigurationProvider) KeyFingerprint() (string, error) { + return "", nil +} + +func (p instancePrincipalConfigurationProvider) Region() (string, error) { + if p.region == nil { + return string(p.keyProvider.RegionForFederationClient()), nil + } + return string(*p.region), nil +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/auth/federation_client.go b/vendor/github.com/oracle/oci-go-sdk/common/auth/federation_client.go new file mode 100644 index 000000000..f15aff82d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/auth/federation_client.go @@ -0,0 +1,288 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +// Package auth provides supporting functions and structs for authentication +package auth + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" + "strings" + "sync" +) + +// federationClient is a client to retrieve the security token for an instance principal necessary to sign a request. +// It also provides the private key whose corresponding public key is used to retrieve the security token. +type federationClient interface { + PrivateKey() (*rsa.PrivateKey, error) + SecurityToken() (string, error) +} + +// x509FederationClient retrieves a security token from Auth service. +type x509FederationClient struct { + tenancyID string + sessionKeySupplier sessionKeySupplier + leafCertificateRetriever x509CertificateRetriever + intermediateCertificateRetrievers []x509CertificateRetriever + securityToken securityToken + authClient *common.BaseClient + mux sync.Mutex +} + +func newX509FederationClient(region common.Region, tenancyID string, leafCertificateRetriever x509CertificateRetriever, intermediateCertificateRetrievers []x509CertificateRetriever) federationClient { + client := &x509FederationClient{ + tenancyID: tenancyID, + leafCertificateRetriever: leafCertificateRetriever, + intermediateCertificateRetrievers: intermediateCertificateRetrievers, + } + client.sessionKeySupplier = newSessionKeySupplier() + client.authClient = newAuthClient(region, client) + return client +} + +var ( + genericHeaders = []string{"date", "(request-target)"} // "host" is not needed for the federation endpoint. Don't ask me why. + bodyHeaders = []string{"content-length", "content-type", "x-content-sha256"} +) + +func newAuthClient(region common.Region, provider common.KeyProvider) *common.BaseClient { + signer := common.RequestSigner(provider, genericHeaders, bodyHeaders) + client := common.DefaultBaseClientWithSigner(signer) + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "auth", string(region)) + client.BasePath = "v1/x509" + return &client +} + +// For authClient to sign requests to X509 Federation Endpoint +func (c *x509FederationClient) KeyID() (string, error) { + tenancy := c.tenancyID + fingerprint := fingerprint(c.leafCertificateRetriever.Certificate()) + return fmt.Sprintf("%s/fed-x509/%s", tenancy, fingerprint), nil +} + +// For authClient to sign requests to X509 Federation Endpoint +func (c *x509FederationClient) PrivateRSAKey() (*rsa.PrivateKey, error) { + return c.leafCertificateRetriever.PrivateKey(), nil +} + +func (c *x509FederationClient) PrivateKey() (*rsa.PrivateKey, error) { + c.mux.Lock() + defer c.mux.Unlock() + + if err := c.renewSecurityTokenIfNotValid(); err != nil { + return nil, err + } + return c.sessionKeySupplier.PrivateKey(), nil +} + +func (c *x509FederationClient) SecurityToken() (token string, err error) { + c.mux.Lock() + defer c.mux.Unlock() + + if err = c.renewSecurityTokenIfNotValid(); err != nil { + return "", err + } + return c.securityToken.String(), nil +} + +func (c *x509FederationClient) renewSecurityTokenIfNotValid() (err error) { + if c.securityToken == nil || !c.securityToken.Valid() { + if err = c.renewSecurityToken(); err != nil { + return fmt.Errorf("failed to renew security token: %s", err.Error()) + } + } + return nil +} + +func (c *x509FederationClient) renewSecurityToken() (err error) { + if err = c.sessionKeySupplier.Refresh(); err != nil { + return fmt.Errorf("failed to refresh session key: %s", err.Error()) + } + + if err = c.leafCertificateRetriever.Refresh(); err != nil { + return fmt.Errorf("failed to refresh leaf certificate: %s", err.Error()) + } + + updatedTenancyID := extractTenancyIDFromCertificate(c.leafCertificateRetriever.Certificate()) + if c.tenancyID != updatedTenancyID { + err = fmt.Errorf("unexpected update of tenancy OCID in the leaf certificate. Previous tenancy: %s, Updated: %s", c.tenancyID, updatedTenancyID) + return + } + + for _, retriever := range c.intermediateCertificateRetrievers { + if err = retriever.Refresh(); err != nil { + return fmt.Errorf("failed to refresh intermediate certificate: %s", err.Error()) + } + } + + if c.securityToken, err = c.getSecurityToken(); err != nil { + return fmt.Errorf("failed to get security token: %s", err.Error()) + } + + return nil +} + +func (c *x509FederationClient) getSecurityToken() (securityToken, error) { + request := c.makeX509FederationRequest() + + var err error + var httpRequest http.Request + if httpRequest, err = common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "", request); err != nil { + return nil, fmt.Errorf("failed to make http request: %s", err.Error()) + } + + var httpResponse *http.Response + defer common.CloseBodyIfValid(httpResponse) + if httpResponse, err = c.authClient.Call(context.Background(), &httpRequest); err != nil { + return nil, fmt.Errorf("failed to call: %s", err.Error()) + } + + response := x509FederationResponse{} + if err = common.UnmarshalResponse(httpResponse, &response); err != nil { + return nil, fmt.Errorf("failed to unmarshal the response: %s", err.Error()) + } + + return newInstancePrincipalToken(response.Token.Token) +} + +type x509FederationRequest struct { + X509FederationDetails `contributesTo:"body"` +} + +// X509FederationDetails x509 federation details +type X509FederationDetails struct { + Certificate string `mandatory:"true" json:"certificate,omitempty"` + PublicKey string `mandatory:"true" json:"publicKey,omitempty"` + IntermediateCertificates []string `mandatory:"false" json:"intermediateCertificates,omitempty"` +} + +type x509FederationResponse struct { + Token `presentIn:"body"` +} + +// Token token +type Token struct { + Token string `mandatory:"true" json:"token,omitempty"` +} + +func (c *x509FederationClient) makeX509FederationRequest() *x509FederationRequest { + certificate := c.sanitizeCertificateString(string(c.leafCertificateRetriever.CertificatePemRaw())) + publicKey := c.sanitizeCertificateString(string(c.sessionKeySupplier.PublicKeyPemRaw())) + var intermediateCertificates []string + for _, retriever := range c.intermediateCertificateRetrievers { + intermediateCertificates = append(intermediateCertificates, c.sanitizeCertificateString(string(retriever.CertificatePemRaw()))) + } + + details := X509FederationDetails{ + Certificate: certificate, + PublicKey: publicKey, + IntermediateCertificates: intermediateCertificates, + } + return &x509FederationRequest{details} +} + +func (c *x509FederationClient) sanitizeCertificateString(certString string) string { + certString = strings.Replace(certString, "-----BEGIN CERTIFICATE-----", "", -1) + certString = strings.Replace(certString, "-----END CERTIFICATE-----", "", -1) + certString = strings.Replace(certString, "-----BEGIN PUBLIC KEY-----", "", -1) + certString = strings.Replace(certString, "-----END PUBLIC KEY-----", "", -1) + certString = strings.Replace(certString, "\n", "", -1) + return certString +} + +// sessionKeySupplier provides an RSA keypair which can be re-generated by calling Refresh(). +type sessionKeySupplier interface { + Refresh() error + PrivateKey() *rsa.PrivateKey + PublicKeyPemRaw() []byte +} + +// inMemorySessionKeySupplier implements sessionKeySupplier to vend an RSA keypair. +// Refresh() generates a new RSA keypair with a random source, and keeps it in memory. +// +// inMemorySessionKeySupplier is not thread-safe. +type inMemorySessionKeySupplier struct { + keySize int + privateKey *rsa.PrivateKey + publicKeyPemRaw []byte +} + +// newSessionKeySupplier creates and returns a sessionKeySupplier instance which generates key pairs of size 2048. +func newSessionKeySupplier() sessionKeySupplier { + return &inMemorySessionKeySupplier{keySize: 2048} +} + +// Refresh() is failure atomic, i.e., PrivateKey() and PublicKeyPemRaw() would return their previous values +// if Refresh() fails. +func (s *inMemorySessionKeySupplier) Refresh() (err error) { + common.Debugln("Refreshing session key") + + var privateKey *rsa.PrivateKey + privateKey, err = rsa.GenerateKey(rand.Reader, s.keySize) + if err != nil { + return fmt.Errorf("failed to generate a new keypair: %s", err) + } + + var publicKeyAsnBytes []byte + if publicKeyAsnBytes, err = x509.MarshalPKIXPublicKey(privateKey.Public()); err != nil { + return fmt.Errorf("failed to marshal the public part of the new keypair: %s", err.Error()) + } + publicKeyPemRaw := pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: publicKeyAsnBytes, + }) + + s.privateKey = privateKey + s.publicKeyPemRaw = publicKeyPemRaw + return nil +} + +func (s *inMemorySessionKeySupplier) PrivateKey() *rsa.PrivateKey { + if s.privateKey == nil { + return nil + } + + c := *s.privateKey + return &c +} + +func (s *inMemorySessionKeySupplier) PublicKeyPemRaw() []byte { + if s.publicKeyPemRaw == nil { + return nil + } + + c := make([]byte, len(s.publicKeyPemRaw)) + copy(c, s.publicKeyPemRaw) + return c +} + +type securityToken interface { + fmt.Stringer + Valid() bool +} + +type instancePrincipalToken struct { + tokenString string + jwtToken *jwtToken +} + +func newInstancePrincipalToken(tokenString string) (newToken securityToken, err error) { + var jwtToken *jwtToken + if jwtToken, err = parseJwt(tokenString); err != nil { + return nil, fmt.Errorf("failed to parse the token string \"%s\": %s", tokenString, err.Error()) + } + return &instancePrincipalToken{tokenString, jwtToken}, nil +} + +func (t *instancePrincipalToken) String() string { + return t.tokenString +} + +func (t *instancePrincipalToken) Valid() bool { + return !t.jwtToken.expired() +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/auth/instance_principal_key_provider.go b/vendor/github.com/oracle/oci-go-sdk/common/auth/instance_principal_key_provider.go new file mode 100644 index 000000000..ecf14b072 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/auth/instance_principal_key_provider.go @@ -0,0 +1,95 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package auth + +import ( + "bytes" + "crypto/rsa" + "fmt" + "github.com/oracle/oci-go-sdk/common" +) + +const ( + regionURL = `http://169.254.169.254/opc/v1/instance/region` + leafCertificateURL = `http://169.254.169.254/opc/v1/identity/cert.pem` + leafCertificateKeyURL = `http://169.254.169.254/opc/v1/identity/key.pem` + leafCertificateKeyPassphrase = `` // No passphrase for the private key for Compute instances + intermediateCertificateURL = `http://169.254.169.254/opc/v1/identity/intermediate.pem` + intermediateCertificateKeyURL = `` + intermediateCertificateKeyPassphrase = `` // No passphrase for the private key for Compute instances +) + +// instancePrincipalKeyProvider implements KeyProvider to provide a key ID and its corresponding private key +// for an instance principal by getting a security token via x509FederationClient. +// +// The region name of the endpoint for x509FederationClient is obtained from the metadata service on the compute +// instance. +type instancePrincipalKeyProvider struct { + regionForFederationClient common.Region + federationClient federationClient +} + +// newInstancePrincipalKeyProvider creates and returns an instancePrincipalKeyProvider instance based on +// x509FederationClient. +// +// NOTE: There is a race condition between PrivateRSAKey() and KeyID(). These two pieces are tightly coupled; KeyID +// includes a security token obtained from Auth service by giving a public key which is paired with PrivateRSAKey. +// The x509FederationClient caches the security token in memory until it is expired. Thus, even if a client obtains a +// KeyID that is not expired at the moment, the PrivateRSAKey that the client acquires at a next moment could be +// invalid because the KeyID could be already expired. +func newInstancePrincipalKeyProvider() (provider *instancePrincipalKeyProvider, err error) { + var region common.Region + if region, err = getRegionForFederationClient(regionURL); err != nil { + err = fmt.Errorf("failed to get the region name from %s: %s", regionURL, err.Error()) + common.Logln(err) + return nil, err + } + + leafCertificateRetriever := newURLBasedX509CertificateRetriever( + leafCertificateURL, leafCertificateKeyURL, leafCertificateKeyPassphrase) + intermediateCertificateRetrievers := []x509CertificateRetriever{ + newURLBasedX509CertificateRetriever( + intermediateCertificateURL, intermediateCertificateKeyURL, intermediateCertificateKeyPassphrase), + } + + if err = leafCertificateRetriever.Refresh(); err != nil { + err = fmt.Errorf("failed to refresh the leaf certificate: %s", err.Error()) + return nil, err + } + tenancyID := extractTenancyIDFromCertificate(leafCertificateRetriever.Certificate()) + + federationClient := newX509FederationClient( + region, tenancyID, leafCertificateRetriever, intermediateCertificateRetrievers) + + provider = &instancePrincipalKeyProvider{regionForFederationClient: region, federationClient: federationClient} + return +} + +func getRegionForFederationClient(url string) (r common.Region, err error) { + var body bytes.Buffer + if body, err = httpGet(url); err != nil { + return + } + return common.StringToRegion(body.String()), nil +} + +func (p *instancePrincipalKeyProvider) RegionForFederationClient() common.Region { + return p.regionForFederationClient +} + +func (p *instancePrincipalKeyProvider) PrivateRSAKey() (privateKey *rsa.PrivateKey, err error) { + if privateKey, err = p.federationClient.PrivateKey(); err != nil { + err = fmt.Errorf("failed to get private key: %s", err.Error()) + return nil, err + } + return privateKey, nil +} + +func (p *instancePrincipalKeyProvider) KeyID() (string, error) { + var securityToken string + var err error + if securityToken, err = p.federationClient.SecurityToken(); err != nil { + return "", fmt.Errorf("failed to get security token: %s", err.Error()) + } + return fmt.Sprintf("ST$%s", securityToken), nil +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/auth/jwt.go b/vendor/github.com/oracle/oci-go-sdk/common/auth/jwt.go new file mode 100644 index 000000000..b199a4d68 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/auth/jwt.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package auth + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "strings" + "time" +) + +type jwtToken struct { + raw string + header map[string]interface{} + payload map[string]interface{} +} + +func (t *jwtToken) expired() bool { + exp := int64(t.payload["exp"].(float64)) + return exp <= time.Now().Unix() +} + +func parseJwt(tokenString string) (*jwtToken, error) { + parts := strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, fmt.Errorf("the given token string contains an invalid number of parts") + } + + token := &jwtToken{raw: tokenString} + var err error + + // Parse Header part + var headerBytes []byte + if headerBytes, err = decodePart(parts[0]); err != nil { + return nil, fmt.Errorf("failed to decode the header bytes: %s", err.Error()) + } + if err = json.Unmarshal(headerBytes, &token.header); err != nil { + return nil, err + } + + // Parse Payload part + var payloadBytes []byte + if payloadBytes, err = decodePart(parts[1]); err != nil { + return nil, fmt.Errorf("failed to decode the payload bytes: %s", err.Error()) + } + decoder := json.NewDecoder(bytes.NewBuffer(payloadBytes)) + if err = decoder.Decode(&token.payload); err != nil { + return nil, fmt.Errorf("failed to decode the payload json: %s", err.Error()) + } + + return token, nil +} + +func decodePart(partString string) ([]byte, error) { + if l := len(partString) % 4; 0 < l { + partString += strings.Repeat("=", 4-l) + } + return base64.URLEncoding.DecodeString(partString) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/auth/utils.go b/vendor/github.com/oracle/oci-go-sdk/common/auth/utils.go new file mode 100644 index 000000000..f84490c7d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/auth/utils.go @@ -0,0 +1,64 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package auth + +import ( + "bytes" + "crypto/sha1" + "crypto/x509" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" + "net/http/httputil" + "strings" +) + +// httpGet makes a simple HTTP GET request to the given URL, expecting only "200 OK" status code. +// This is basically for the Instance Metadata Service. +func httpGet(url string) (body bytes.Buffer, err error) { + var response *http.Response + if response, err = http.Get(url); err != nil { + return + } + + common.IfDebug(func() { + if dump, e := httputil.DumpResponse(response, true); e == nil { + common.Logf("Dump Response %v", string(dump)) + } else { + common.Debugln(e) + } + }) + + defer response.Body.Close() + if _, err = body.ReadFrom(response.Body); err != nil { + return + } + + if response.StatusCode != http.StatusOK { + err = fmt.Errorf("HTTP Get failed: URL: %s, Status: %s, Message: %s", + url, response.Status, body.String()) + return + } + + return +} + +func extractTenancyIDFromCertificate(cert *x509.Certificate) string { + for _, nameAttr := range cert.Subject.Names { + value := nameAttr.Value.(string) + if strings.HasPrefix(value, "opc-tenant:") { + return value[len("opc-tenant:"):] + } + } + return "" +} + +func fingerprint(certificate *x509.Certificate) string { + fingerprint := sha1.Sum(certificate.Raw) + return colonSeparatedString(fingerprint) +} + +func colonSeparatedString(fingerprint [sha1.Size]byte) string { + spaceSeparated := fmt.Sprintf("% x", fingerprint) + return strings.Replace(spaceSeparated, " ", ":", -1) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/client.go b/vendor/github.com/oracle/oci-go-sdk/common/client.go new file mode 100644 index 000000000..d67e99777 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/client.go @@ -0,0 +1,253 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +// Package common provides supporting functions and structs used by service packages +package common + +import ( + "context" + "fmt" + "net/http" + "net/http/httputil" + "net/url" + "os" + "os/user" + "path" + "runtime" + "strings" + "time" +) + +const ( + // DefaultHostURLTemplate The default url template for service hosts + DefaultHostURLTemplate = "%s.%s.oraclecloud.com" + defaultScheme = "https" + defaultSDKMarker = "Oracle-GoSDK" + defaultUserAgentTemplate = "%s/%s (%s/%s; go/%s)" //SDK/SDKVersion (OS/OSVersion; Lang/LangVersion) + defaultTimeout = time.Second * 30 + defaultConfigFileName = "config" + defaultConfigDirName = ".oci" + secondaryConfigDirName = ".oraclebmc" + maxBodyLenForDebug = 1024 * 1000 +) + +// RequestInterceptor function used to customize the request before calling the underlying service +type RequestInterceptor func(*http.Request) error + +// HTTPRequestDispatcher wraps the execution of a http request, it is generally implemented by +// http.Client.Do, but can be customized for testing +type HTTPRequestDispatcher interface { + Do(req *http.Request) (*http.Response, error) +} + +// BaseClient struct implements all basic operations to call oci web services. +type BaseClient struct { + //HTTPClient performs the http network operations + HTTPClient HTTPRequestDispatcher + + //Signer performs auth operation + Signer HTTPRequestSigner + + //A request interceptor can be used to customize the request before signing and dispatching + Interceptor RequestInterceptor + + //The host of the service + Host string + + //The user agent + UserAgent string + + //Base path for all operations of this client + BasePath string +} + +func defaultUserAgent() string { + userAgent := fmt.Sprintf(defaultUserAgentTemplate, defaultSDKMarker, Version(), runtime.GOOS, runtime.GOARCH, runtime.Version()) + return userAgent +} + +func newBaseClient(signer HTTPRequestSigner, dispatcher HTTPRequestDispatcher) BaseClient { + return BaseClient{ + UserAgent: defaultUserAgent(), + Interceptor: nil, + Signer: signer, + HTTPClient: dispatcher, + } +} + +func defaultHTTPDispatcher() http.Client { + httpClient := http.Client{ + Timeout: defaultTimeout, + } + return httpClient +} + +func defaultBaseClient(provider KeyProvider) BaseClient { + dispatcher := defaultHTTPDispatcher() + signer := DefaultRequestSigner(provider) + return newBaseClient(signer, &dispatcher) +} + +//DefaultBaseClientWithSigner creates a default base client with a given signer +func DefaultBaseClientWithSigner(signer HTTPRequestSigner) BaseClient { + dispatcher := defaultHTTPDispatcher() + return newBaseClient(signer, &dispatcher) +} + +// NewClientWithConfig Create a new client with a configuration provider, the configuration provider +// will be used for the default signer as well as reading the region +// This function does not check for valid regions to implement forward compatibility +func NewClientWithConfig(configProvider ConfigurationProvider) (client BaseClient, err error) { + var ok bool + if ok, err = IsConfigurationProviderValid(configProvider); !ok { + err = fmt.Errorf("can not create client, bad configuration: %s", err.Error()) + return + } + + client = defaultBaseClient(configProvider) + return +} + +func getHomeFolder() string { + current, e := user.Current() + if e != nil { + //Give up and try to return something sensible + home := os.Getenv("HOME") + if home == "" { + home = os.Getenv("USERPROFILE") + } + return home + } + return current.HomeDir +} + +// DefaultConfigProvider returns the default config provider. The default config provider +// will look for configurations in 3 places: file in $HOME/.oci/config, HOME/.obmcs/config and +// variables names starting with the string TF_VAR. If the same configuration is found in multiple +// places the provider will prefer the first one. +func DefaultConfigProvider() ConfigurationProvider { + homeFolder := getHomeFolder() + defaultConfigFile := path.Join(homeFolder, defaultConfigDirName, defaultConfigFileName) + secondaryConfigFile := path.Join(homeFolder, secondaryConfigDirName, defaultConfigFileName) + + defaultFileProvider, _ := ConfigurationProviderFromFile(defaultConfigFile, "") + secondaryFileProvider, _ := ConfigurationProviderFromFile(secondaryConfigFile, "") + environmentProvider := environmentConfigurationProvider{EnvironmentVariablePrefix: "TF_VAR"} + + provider, _ := ComposingConfigurationProvider([]ConfigurationProvider{defaultFileProvider, secondaryFileProvider, environmentProvider}) + Debugf("Configuration provided by: %s", provider) + return provider +} + +func (client *BaseClient) prepareRequest(request *http.Request) (err error) { + if client.UserAgent == "" { + return fmt.Errorf("user agent can not be blank") + } + + if request.Header == nil { + request.Header = http.Header{} + } + request.Header.Set("User-Agent", client.UserAgent) + + if !strings.Contains(client.Host, "http") && + !strings.Contains(client.Host, "https") { + client.Host = fmt.Sprintf("%s://%s", defaultScheme, client.Host) + } + + clientURL, err := url.Parse(client.Host) + if err != nil { + return fmt.Errorf("host is invalid. %s", err.Error()) + } + request.URL.Host = clientURL.Host + request.URL.Scheme = clientURL.Scheme + currentPath := request.URL.Path + request.URL.Path = path.Clean(fmt.Sprintf("/%s/%s", client.BasePath, currentPath)) + return +} + +func (client BaseClient) intercept(request *http.Request) (err error) { + if client.Interceptor != nil { + err = client.Interceptor(request) + } + return +} + +func checkForSuccessfulResponse(res *http.Response) error { + familyStatusCode := res.StatusCode / 100 + if familyStatusCode == 4 || familyStatusCode == 5 { + return newServiceFailureFromResponse(res) + } + return nil + +} + +//Call executes the underlying http requrest with the given context +func (client BaseClient) Call(ctx context.Context, request *http.Request) (response *http.Response, err error) { + Debugln("Atempting to call downstream service") + request = request.WithContext(ctx) + + err = client.prepareRequest(request) + if err != nil { + return + } + + //Intercept + err = client.intercept(request) + if err != nil { + return + } + + //Sign the request + err = client.Signer.Sign(request) + if err != nil { + return + } + + IfDebug(func() { + dumpBody := true + if request.ContentLength > maxBodyLenForDebug { + Logln("not dumping body too big") + dumpBody = false + } + if dump, e := httputil.DumpRequest(request, dumpBody); e == nil { + Logf("Dump Request %v", string(dump)) + } else { + Debugln(e) + } + }) + + //Execute the http request + response, err = client.HTTPClient.Do(request) + + IfDebug(func() { + if err != nil { + Logln(err) + return + } + + dumpBody := true + if response.ContentLength > maxBodyLenForDebug { + Logln("not dumping body too big") + dumpBody = false + } + + if dump, e := httputil.DumpResponse(response, dumpBody); e == nil { + Logf("Dump Response %v", string(dump)) + } else { + Debugln(e) + } + }) + + if err != nil { + return + } + + err = checkForSuccessfulResponse(response) + return +} + +//CloseBodyIfValid closes the body of an http response if the response and the body are valid +func CloseBodyIfValid(httpResponse *http.Response) { + if httpResponse != nil && httpResponse.Body != nil { + httpResponse.Body.Close() + } +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/common.go b/vendor/github.com/oracle/oci-go-sdk/common/common.go new file mode 100644 index 000000000..9164562b4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/common.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "strings" +) + +//Region type for regions +type Region string + +const ( + //RegionSEA region SEA + RegionSEA Region = "sea" + //RegionPHX region PHX + RegionPHX Region = "us-phoenix-1" + //RegionIAD region IAD + RegionIAD Region = "us-ashburn-1" + //RegionFRA region FRA + RegionFRA Region = "eu-frankfurt-1" +) + +//StringToRegion convert a string to Region type +func StringToRegion(stringRegion string) (r Region) { + switch strings.ToLower(stringRegion) { + case "sea": + r = RegionSEA + case "phx", "us-phoenix-1": + r = RegionPHX + case "iad", "us-ashburn-1": + r = RegionIAD + case "fra", "eu-frankfurt-1": + r = RegionFRA + default: + r = Region(stringRegion) + Debugf("region named: %s, is not recognized", stringRegion) + } + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/configuration.go b/vendor/github.com/oracle/oci-go-sdk/common/configuration.go new file mode 100644 index 000000000..d2292bb9d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/configuration.go @@ -0,0 +1,487 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "crypto/rsa" + "errors" + "fmt" + "io/ioutil" + "os" + "regexp" + "strings" +) + +// ConfigurationProvider wraps information about the account owner +type ConfigurationProvider interface { + KeyProvider + TenancyOCID() (string, error) + UserOCID() (string, error) + KeyFingerprint() (string, error) + Region() (string, error) +} + +// IsConfigurationProviderValid Tests all parts of the configuration provider do not return an error +func IsConfigurationProviderValid(conf ConfigurationProvider) (ok bool, err error) { + baseFn := []func() (string, error){conf.TenancyOCID, conf.UserOCID, conf.KeyFingerprint, conf.Region, conf.KeyID} + for _, fn := range baseFn { + _, err = fn() + ok = err == nil + if err != nil { + return + } + } + + _, err = conf.PrivateRSAKey() + ok = err == nil + if err != nil { + return + } + return true, nil +} + +// rawConfigurationProvider allows a user to simply construct a configuration provider from raw values. +type rawConfigurationProvider struct { + tenancy string + user string + region string + fingerprint string + privateKey string + privateKeyPassphrase *string +} + +// NewRawConfigurationProvider will create a rawConfigurationProvider +func NewRawConfigurationProvider(tenancy, user, region, fingerprint, privateKey string, privateKeyPassphrase *string) ConfigurationProvider { + return rawConfigurationProvider{tenancy, user, region, fingerprint, privateKey, privateKeyPassphrase} +} + +func (p rawConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) { + return PrivateKeyFromBytes([]byte(p.privateKey), p.privateKeyPassphrase) +} + +func (p rawConfigurationProvider) KeyID() (keyID string, err error) { + tenancy, err := p.TenancyOCID() + if err != nil { + return + } + + user, err := p.UserOCID() + if err != nil { + return + } + + fingerprint, err := p.KeyFingerprint() + if err != nil { + return + } + + return fmt.Sprintf("%s/%s/%s", tenancy, user, fingerprint), nil +} + +func (p rawConfigurationProvider) TenancyOCID() (string, error) { + return p.tenancy, nil +} + +func (p rawConfigurationProvider) UserOCID() (string, error) { + return p.user, nil +} + +func (p rawConfigurationProvider) KeyFingerprint() (string, error) { + return p.fingerprint, nil +} + +func (p rawConfigurationProvider) Region() (string, error) { + return p.region, nil +} + +// environmentConfigurationProvider reads configuration from environment variables +type environmentConfigurationProvider struct { // TODO: Support Instance Principal + PrivateKeyPassword string + EnvironmentVariablePrefix string +} + +// ConfigurationProviderEnvironmentVariables creates a ConfigurationProvider from a uniform set of environment variables starting with a prefix +// The env variables should look like: [prefix]_private_key_path, [prefix]_tenancy_ocid, [prefix]_user_ocid, [prefix]_fingerprint +// [prefix]_region +func ConfigurationProviderEnvironmentVariables(environmentVariablePrefix, privateKeyPassword string) ConfigurationProvider { + return environmentConfigurationProvider{EnvironmentVariablePrefix: environmentVariablePrefix, + PrivateKeyPassword: privateKeyPassword} +} + +func (p environmentConfigurationProvider) String() string { + return fmt.Sprintf("Configuration provided by environment variables prefixed with: %s", p.EnvironmentVariablePrefix) +} + +func (p environmentConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) { + environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "private_key_path") + var ok bool + var value string + if value, ok = os.LookupEnv(environmentVariable); !ok { + return nil, fmt.Errorf("can not read PrivateKey from env variable: %s", environmentVariable) + } + + pemFileContent, err := ioutil.ReadFile(value) + if err != nil { + Debugln("Can not read PrivateKey location from environment variable: " + environmentVariable) + return + } + + key, err = PrivateKeyFromBytes(pemFileContent, &p.PrivateKeyPassword) + return +} + +func (p environmentConfigurationProvider) KeyID() (keyID string, err error) { + ocid, err := p.TenancyOCID() + if err != nil { + return + } + + userocid, err := p.UserOCID() + if err != nil { + return + } + + fingerprint, err := p.KeyFingerprint() + if err != nil { + return + } + + return fmt.Sprintf("%s/%s/%s", ocid, userocid, fingerprint), nil +} + +func (p environmentConfigurationProvider) TenancyOCID() (value string, err error) { + environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "tenancy_ocid") + var ok bool + if value, ok = os.LookupEnv(environmentVariable); !ok { + err = fmt.Errorf("can not read Tenancy from environment variable %s", environmentVariable) + } + return +} + +func (p environmentConfigurationProvider) UserOCID() (value string, err error) { + environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "user_ocid") + var ok bool + if value, ok = os.LookupEnv(environmentVariable); !ok { + err = fmt.Errorf("can not read user id from environment variable %s", environmentVariable) + } + return +} + +func (p environmentConfigurationProvider) KeyFingerprint() (value string, err error) { + environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "fingerprint") + var ok bool + if value, ok = os.LookupEnv(environmentVariable); !ok { + err = fmt.Errorf("can not read fingerprint from environment variable %s", environmentVariable) + } + return +} + +func (p environmentConfigurationProvider) Region() (value string, err error) { + environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "region") + var ok bool + if value, ok = os.LookupEnv(environmentVariable); !ok { + err = fmt.Errorf("can not read region from environment variable %s", environmentVariable) + } + return +} + +// fileConfigurationProvider. reads configuration information from a file +type fileConfigurationProvider struct { // TODO: Support Instance Principal + //The path to the configuration file + ConfigPath string + + //The password for the private key + PrivateKeyPassword string + + //The profile for the configuration + Profile string + + //ConfigFileInfo + FileInfo *configFileInfo +} + +// ConfigurationProviderFromFile creates a configuration provider from a configuration file +// by reading the "DEFAULT" profile +func ConfigurationProviderFromFile(configFilePath, privateKeyPassword string) (ConfigurationProvider, error) { + if configFilePath == "" { + return nil, fmt.Errorf("config file path can not be empty") + } + + return fileConfigurationProvider{ + ConfigPath: configFilePath, + PrivateKeyPassword: privateKeyPassword, + Profile: "DEFAULT"}, nil +} + +// ConfigurationProviderFromFileWithProfile creates a configuration provider from a configuration file +// and the given profile +func ConfigurationProviderFromFileWithProfile(configFilePath, profile, privateKeyPassword string) (ConfigurationProvider, error) { + if configFilePath == "" { + return nil, fmt.Errorf("config file path can not be empty") + } + + return fileConfigurationProvider{ + ConfigPath: configFilePath, + PrivateKeyPassword: privateKeyPassword, + Profile: profile}, nil +} + +type configFileInfo struct { + UserOcid, Fingerprint, KeyFilePath, TenancyOcid, Region string + PresentConfiguration byte +} + +const ( + hasTenancy = 1 << iota + hasUser + hasFingerprint + hasRegion + hasKeyFile + none +) + +var profileRegex = regexp.MustCompile(`^\[(.*)\]`) + +func parseConfigFile(data []byte, profile string) (info *configFileInfo, err error) { + + if len(data) == 0 { + return nil, fmt.Errorf("configuration file content is empty") + } + + content := string(data) + splitContent := strings.Split(content, "\n") + + //Look for profile + for i, line := range splitContent { + if match := profileRegex.FindStringSubmatch(line); match != nil && len(match) > 1 && match[1] == profile { + start := i + 1 + return parseConfigAtLine(start, splitContent) + } + } + + return nil, fmt.Errorf("configuration file did not contain profile: %s", profile) +} + +func parseConfigAtLine(start int, content []string) (info *configFileInfo, err error) { + var configurationPresent byte + info = &configFileInfo{} + for i := start; i < len(content); i++ { + line := content[i] + if profileRegex.MatchString(line) { + break + } + + if !strings.Contains(line, "=") { + continue + } + + splits := strings.Split(line, "=") + switch key, value := strings.TrimSpace(splits[0]), strings.TrimSpace(splits[1]); strings.ToLower(key) { + case "user": + configurationPresent = configurationPresent | hasUser + info.UserOcid = value + case "fingerprint": + configurationPresent = configurationPresent | hasFingerprint + info.Fingerprint = value + case "key_file": + configurationPresent = configurationPresent | hasKeyFile + info.KeyFilePath = value + case "tenancy": + configurationPresent = configurationPresent | hasTenancy + info.TenancyOcid = value + case "region": + configurationPresent = configurationPresent | hasRegion + info.Region = value + } + } + info.PresentConfiguration = configurationPresent + return + +} + +func openConfigFile(configFilePath string) (data []byte, err error) { + data, err = ioutil.ReadFile(configFilePath) + if err != nil { + err = fmt.Errorf("can not read config file: %s due to: %s", configFilePath, err.Error()) + } + + return +} + +func (p fileConfigurationProvider) String() string { + return fmt.Sprintf("Configuration provided by file: %s", p.ConfigPath) +} + +func (p fileConfigurationProvider) readAndParseConfigFile() (info *configFileInfo, err error) { + if p.FileInfo != nil { + return p.FileInfo, nil + } + + if p.ConfigPath == "" { + return nil, fmt.Errorf("configuration path can not be empty") + } + + data, err := openConfigFile(p.ConfigPath) + if err != nil { + err = fmt.Errorf("error while parsing config file: %s. Due to: %s", p.ConfigPath, err.Error()) + return + } + + p.FileInfo, err = parseConfigFile(data, p.Profile) + return p.FileInfo, err +} + +func presentOrError(value string, expectedConf, presentConf byte, confMissing string) (string, error) { + if presentConf&expectedConf == expectedConf { + return value, nil + } + return "", errors.New(confMissing + " configuration is missing from file") +} + +func (p fileConfigurationProvider) TenancyOCID() (value string, err error) { + info, err := p.readAndParseConfigFile() + if err != nil { + err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error()) + return + } + + value, err = presentOrError(info.TenancyOcid, hasTenancy, info.PresentConfiguration, "tenancy") + return +} + +func (p fileConfigurationProvider) UserOCID() (value string, err error) { + info, err := p.readAndParseConfigFile() + if err != nil { + err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error()) + return + } + + value, err = presentOrError(info.UserOcid, hasUser, info.PresentConfiguration, "user") + return +} + +func (p fileConfigurationProvider) KeyFingerprint() (value string, err error) { + info, err := p.readAndParseConfigFile() + if err != nil { + err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error()) + return + } + value, err = presentOrError(info.Fingerprint, hasFingerprint, info.PresentConfiguration, "fingerprint") + return +} + +func (p fileConfigurationProvider) KeyID() (keyID string, err error) { + info, err := p.readAndParseConfigFile() + if err != nil { + err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error()) + return + } + + return fmt.Sprintf("%s/%s/%s", info.TenancyOcid, info.UserOcid, info.Fingerprint), nil +} + +func (p fileConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) { + info, err := p.readAndParseConfigFile() + if err != nil { + err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error()) + return + } + + filePath, err := presentOrError(info.KeyFilePath, hasKeyFile, info.PresentConfiguration, "key file path") + if err != nil { + return + } + pemFileContent, err := ioutil.ReadFile(filePath) + if err != nil { + err = fmt.Errorf("can not read PrivateKey from configuration file due to: %s", err.Error()) + return + } + + key, err = PrivateKeyFromBytes(pemFileContent, &p.PrivateKeyPassword) + return +} + +func (p fileConfigurationProvider) Region() (value string, err error) { + info, err := p.readAndParseConfigFile() + if err != nil { + err = fmt.Errorf("can not read region configuration due to: %s", err.Error()) + return + } + + value, err = presentOrError(info.Region, hasRegion, info.PresentConfiguration, "region") + return +} + +// A configuration provider that look for information in multiple configuration providers +type composingConfigurationProvider struct { + Providers []ConfigurationProvider +} + +// ComposingConfigurationProvider creates a composing configuration provider with the given slice of configuration providers +// A composing provider will return the configuration of the first provider that has the required property +// if no provider has the property it will return an error. +func ComposingConfigurationProvider(providers []ConfigurationProvider) (ConfigurationProvider, error) { + if len(providers) == 0 { + return nil, fmt.Errorf("providers can not be an empty slice") + } + return composingConfigurationProvider{Providers: providers}, nil +} + +func (c composingConfigurationProvider) TenancyOCID() (string, error) { + for _, p := range c.Providers { + val, err := p.TenancyOCID() + if err == nil { + return val, nil + } + } + return "", fmt.Errorf("did not find a proper configuration for tenancy") +} + +func (c composingConfigurationProvider) UserOCID() (string, error) { + for _, p := range c.Providers { + val, err := p.UserOCID() + if err == nil { + return val, nil + } + } + return "", fmt.Errorf("did not find a proper configuration for user") +} + +func (c composingConfigurationProvider) KeyFingerprint() (string, error) { + for _, p := range c.Providers { + val, err := p.KeyFingerprint() + if err == nil { + return val, nil + } + } + return "", fmt.Errorf("did not find a proper configuration for keyFingerprint") +} +func (c composingConfigurationProvider) Region() (string, error) { + for _, p := range c.Providers { + val, err := p.Region() + if err == nil { + return val, nil + } + } + return "", fmt.Errorf("did not find a proper configuration for region") +} + +func (c composingConfigurationProvider) KeyID() (string, error) { + for _, p := range c.Providers { + val, err := p.KeyID() + if err == nil { + return val, nil + } + } + return "", fmt.Errorf("did not find a proper configuration for key id") +} + +func (c composingConfigurationProvider) PrivateRSAKey() (*rsa.PrivateKey, error) { + for _, p := range c.Providers { + val, err := p.PrivateRSAKey() + if err == nil { + return val, nil + } + } + return nil, fmt.Errorf("did not find a proper configuration for private key") +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/errors.go b/vendor/github.com/oracle/oci-go-sdk/common/errors.go new file mode 100644 index 000000000..290bd08bf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/errors.go @@ -0,0 +1,80 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +// ServiceError models all potential errors generated the service call +type ServiceError interface { + // The http status code of the error + GetHTTPStatusCode() int + + // The human-readable error string as sent by the service + GetMessage() string + + // A short error code that defines the error, meant for programmatic parsing. + // See https://docs.us-phoenix-1.oraclecloud.com/Content/API/References/apierrors.htm + GetCode() string +} + +type servicefailure struct { + StatusCode int + Code string `json:"code,omitempty"` + Message string `json:"message,omitempty"` +} + +func newServiceFailureFromResponse(response *http.Response) error { + var err error + + //If there is an error consume the body, entirely + body, err := ioutil.ReadAll(response.Body) + if err != nil { + return servicefailure{ + StatusCode: response.StatusCode, + Code: "BadErrorResponse", + Message: fmt.Sprintf("The body of the response was not readable, due to :%s", err.Error()), + } + } + + se := servicefailure{StatusCode: response.StatusCode} + err = json.Unmarshal(body, &se) + if err != nil { + Debugf("Error response could not be parsed due to: %s", err.Error()) + return servicefailure{ + StatusCode: response.StatusCode, + Code: "BadErrorResponse", + Message: fmt.Sprintf("Error while parsing failure from response"), + } + } + return se +} + +func (se servicefailure) Error() string { + return fmt.Sprintf("Service error:%s. %s. http status code: %d", + se.Code, se.Message, se.StatusCode) +} + +func (se servicefailure) GetHTTPStatusCode() int { + return se.StatusCode + +} + +func (se servicefailure) GetMessage() string { + return se.Message +} + +func (se servicefailure) GetCode() string { + return se.Code +} + +// IsServiceError returns false if the error is not service side, otherwise true +// additionally it returns an interface representing the ServiceError +func IsServiceError(err error) (failure ServiceError, ok bool) { + failure, ok = err.(servicefailure) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/helpers.go b/vendor/github.com/oracle/oci-go-sdk/common/helpers.go new file mode 100644 index 000000000..554436944 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/helpers.go @@ -0,0 +1,168 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "reflect" + "strings" + "time" +) + +// String returns a pointer to the provided string +func String(value string) *string { + return &value +} + +// Int returns a pointer to the provided int +func Int(value int) *int { + return &value +} + +// Uint returns a pointer to the provided uint +func Uint(value uint) *uint { + return &value +} + +//Float32 returns a pointer to the provided float32 +func Float32(value float32) *float32 { + return &value +} + +//Float64 returns a pointer to the provided float64 +func Float64(value float64) *float64 { + return &value +} + +//Bool returns a pointer to the provided bool +func Bool(value bool) *bool { + return &value +} + +//PointerString prints the values of pointers in a struct +//Producing a human friendly string for an struct with pointers. +//useful when debugging the values of a struct +func PointerString(datastruct interface{}) (representation string) { + val := reflect.ValueOf(datastruct) + typ := reflect.TypeOf(datastruct) + all := make([]string, 2) + all = append(all, "{") + for i := 0; i < typ.NumField(); i++ { + sf := typ.Field(i) + + //unexported + if sf.PkgPath != "" && !sf.Anonymous { + continue + } + + sv := val.Field(i) + stringValue := "" + if isNil(sv) { + stringValue = fmt.Sprintf("%s=<nil>", sf.Name) + } else { + if sv.Type().Kind() == reflect.Ptr { + sv = sv.Elem() + } + stringValue = fmt.Sprintf("%s=%v", sf.Name, sv) + } + all = append(all, stringValue) + } + all = append(all, "}") + representation = strings.TrimSpace(strings.Join(all, " ")) + return +} + +// SDKTime a time struct, which renders to/from json using RFC339 +type SDKTime struct { + time.Time +} + +func sdkTimeFromTime(t time.Time) SDKTime { + return SDKTime{t} +} + +func now() *SDKTime { + t := SDKTime{time.Now()} + return &t +} + +var timeType = reflect.TypeOf(SDKTime{}) +var timeTypePtr = reflect.TypeOf(&SDKTime{}) + +const sdkTimeFormat = time.RFC3339 + +const rfc1123OptionalLeadingDigitsInDay = "Mon, _2 Jan 2006 15:04:05 MST" + +func formatTime(t SDKTime) string { + return t.Format(sdkTimeFormat) +} + +func tryParsingTimeWithValidFormatsForHeaders(data []byte, headerName string) (t time.Time, err error) { + header := strings.ToLower(headerName) + switch header { + case "lastmodified", "date": + t, err = tryParsing(data, time.RFC3339, time.RFC1123, rfc1123OptionalLeadingDigitsInDay, time.RFC850, time.ANSIC) + return + default: //By default we parse with RFC3339 + t, err = time.Parse(sdkTimeFormat, string(data)) + return + } +} + +func tryParsing(data []byte, layouts ...string) (tm time.Time, err error) { + datestring := string(data) + for _, l := range layouts { + tm, err = time.Parse(l, datestring) + if err == nil { + return + } + } + err = fmt.Errorf("Could not parse time: %s with formats: %s", datestring, layouts[:]) + return +} + +// UnmarshalJSON unmarshals from json +func (t *SDKTime) UnmarshalJSON(data []byte) (e error) { + s := string(data) + if s == "null" { + t.Time = time.Time{} + } else { + //Try parsing with RFC3339 + t.Time, e = time.Parse(`"`+sdkTimeFormat+`"`, string(data)) + } + return +} + +// MarshalJSON marshals to JSON +func (t *SDKTime) MarshalJSON() (buff []byte, e error) { + s := t.Format(sdkTimeFormat) + buff = []byte(`"` + s + `"`) + return +} + +// PrivateKeyFromBytes is a helper function that will produce a RSA private +// key from bytes. +func PrivateKeyFromBytes(pemData []byte, password *string) (key *rsa.PrivateKey, e error) { + if pemBlock, _ := pem.Decode(pemData); pemBlock != nil { + decrypted := pemBlock.Bytes + if x509.IsEncryptedPEMBlock(pemBlock) { + if password == nil { + e = fmt.Errorf("private_key_password is required for encrypted private keys") + return + } + if decrypted, e = x509.DecryptPEMBlock(pemBlock, []byte(*password)); e != nil { + return + } + } + + key, e = x509.ParsePKCS1PrivateKey(decrypted) + + } else { + e = fmt.Errorf("PEM data was not found in buffer") + return + } + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/http.go b/vendor/github.com/oracle/oci-go-sdk/common/http.go new file mode 100644 index 000000000..5e75ed4b3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/http.go @@ -0,0 +1,863 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "path" + "reflect" + "regexp" + "strconv" + "strings" + "time" +) + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Request Marshaling +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +func isNil(v reflect.Value) bool { + return v.Kind() == reflect.Ptr && v.IsNil() +} + +// Returns the string representation of a reflect.Value +// Only transforms primitive values +func toStringValue(v reflect.Value, field reflect.StructField) (string, error) { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + return "", fmt.Errorf("can not marshal a nil pointer") + } + v = v.Elem() + } + + if v.Type() == timeType { + t := v.Interface().(SDKTime) + return formatTime(t), nil + } + + switch v.Kind() { + case reflect.Bool: + return strconv.FormatBool(v.Bool()), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(v.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(v.Uint(), 10), nil + case reflect.String: + return v.String(), nil + case reflect.Float32: + return strconv.FormatFloat(v.Float(), 'f', 6, 32), nil + case reflect.Float64: + return strconv.FormatFloat(v.Float(), 'f', 6, 64), nil + default: + return "", fmt.Errorf("marshaling structure to a http.Request does not support field named: %s of type: %v", + field.Name, v.Type().String()) + } +} + +func addBinaryBody(request *http.Request, value reflect.Value) (e error) { + readCloser, ok := value.Interface().(io.ReadCloser) + if !ok { + e = fmt.Errorf("body of the request needs to be an io.ReadCloser interface. Can not marshal body of binary request") + return + } + + request.Body = readCloser + + //Set the default content type to application/octet-stream if not set + if request.Header.Get("Content-Type") == "" { + request.Header.Set("Content-Type", "application/octet-stream") + } + return nil +} + +// getTaggedNilFieldNameOrError, evaluates if a field with json and non mandatory tags is nil +// returns the json tag name, or an error if the tags are incorrectly present +func getTaggedNilFieldNameOrError(field reflect.StructField, fieldValue reflect.Value) (bool, string, error) { + currentTag := field.Tag + jsonTag := currentTag.Get("json") + + if jsonTag == "" { + return false, "", fmt.Errorf("json tag is not valid for field %s", field.Name) + } + + partsJSONTag := strings.Split(jsonTag, ",") + nameJSONField := partsJSONTag[0] + + if _, ok := currentTag.Lookup("mandatory"); !ok { + //No mandatory field set, no-op + return false, nameJSONField, nil + } + isMandatory, err := strconv.ParseBool(currentTag.Get("mandatory")) + if err != nil { + return false, "", fmt.Errorf("mandatory tag is not valid for field %s", field.Name) + } + + // If the field is marked as mandatory, no-op + if isMandatory { + return false, nameJSONField, nil + } + + Debugf("Adjusting tag: mandatory is false and json tag is valid on field: %s", field.Name) + + // If the field can not be nil, then no-op + if !isNillableType(&fieldValue) { + Debugf("WARNING json field is tagged with mandatory flags, but the type can not be nil, field name: %s", field.Name) + return false, nameJSONField, nil + } + + // If field value is nil, tag it as omitEmpty + return fieldValue.IsNil(), nameJSONField, nil + +} + +// isNillableType returns true if the filed can be nil +func isNillableType(value *reflect.Value) bool { + k := value.Kind() + switch k { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice: + return true + } + return false +} + +// omitNilFieldsInJSON, removes json keys whose struct value is nil, and the field is tag with the json and +// mandatory:false tags +func omitNilFieldsInJSON(data interface{}, value reflect.Value) (interface{}, error) { + switch value.Kind() { + case reflect.Struct: + jsonMap := data.(map[string]interface{}) + fieldType := value.Type() + for i := 0; i < fieldType.NumField(); i++ { + currentField := fieldType.Field(i) + //unexported skip + if currentField.PkgPath != "" { + continue + } + + //Does not have json tag, no-op + if _, ok := currentField.Tag.Lookup("json"); !ok { + continue + } + + currentFieldValue := value.Field(i) + ok, jsonFieldName, err := getTaggedNilFieldNameOrError(currentField, currentFieldValue) + if err != nil { + return nil, fmt.Errorf("can not omit nil fields for field: %s, due to: %s", + currentField.Name, err.Error()) + } + + //Delete the struct field from the json representation + if ok { + delete(jsonMap, jsonFieldName) + continue + } + + if currentFieldValue.Type() == timeType || currentFieldValue.Type() == timeTypePtr { + continue + } + // does it need to be adjusted? + var adjustedValue interface{} + adjustedValue, err = omitNilFieldsInJSON(jsonMap[jsonFieldName], currentFieldValue) + if err != nil { + return nil, fmt.Errorf("can not omit nil fields for field: %s, due to: %s", + currentField.Name, err.Error()) + } + jsonMap[jsonFieldName] = adjustedValue + } + return jsonMap, nil + case reflect.Slice, reflect.Array: + jsonList := data.([]interface{}) + newList := make([]interface{}, len(jsonList)) + var err error + for i, val := range jsonList { + newList[i], err = omitNilFieldsInJSON(val, value.Index(i)) + if err != nil { + return nil, err + } + } + return newList, nil + case reflect.Map: + jsonMap := data.(map[string]interface{}) + newMap := make(map[string]interface{}, len(jsonMap)) + var err error + for key, val := range jsonMap { + newMap[key], err = omitNilFieldsInJSON(val, value.MapIndex(reflect.ValueOf(key))) + if err != nil { + return nil, err + } + } + return newMap, nil + case reflect.Ptr, reflect.Interface: + valPtr := value.Elem() + return omitNilFieldsInJSON(data, valPtr) + default: + //Otherwise no-op + return data, nil + } +} + +// removeNilFieldsInJSONWithTaggedStruct remove struct fields tagged with json and mandatory false +// that are nil +func removeNilFieldsInJSONWithTaggedStruct(rawJSON []byte, value reflect.Value) ([]byte, error) { + rawMap := make(map[string]interface{}) + json.Unmarshal(rawJSON, &rawMap) + fixedMap, err := omitNilFieldsInJSON(rawMap, value) + if err != nil { + return nil, err + } + return json.Marshal(fixedMap) +} + +func addToBody(request *http.Request, value reflect.Value, field reflect.StructField) (e error) { + Debugln("Marshaling to body from field:", field.Name) + if request.Body != nil { + Logln("The body of the request is already set. Structure: ", field.Name, " will overwrite it") + } + tag := field.Tag + encoding := tag.Get("encoding") + + if encoding == "binary" { + return addBinaryBody(request, value) + } + + rawJSON, e := json.Marshal(value.Interface()) + if e != nil { + return + } + marshaled, e := removeNilFieldsInJSONWithTaggedStruct(rawJSON, value) + if e != nil { + return + } + Debugf("Marshaled body is: %s", string(marshaled)) + bodyBytes := bytes.NewReader(marshaled) + request.ContentLength = int64(bodyBytes.Len()) + request.Header.Set("Content-Length", strconv.FormatInt(request.ContentLength, 10)) + request.Header.Set("Content-Type", "application/json") + request.Body = ioutil.NopCloser(bodyBytes) + request.GetBody = func() (io.ReadCloser, error) { + return ioutil.NopCloser(bodyBytes), nil + } + return +} + +func addToQuery(request *http.Request, value reflect.Value, field reflect.StructField) (e error) { + Debugln("Marshaling to query from field:", field.Name) + if request.URL == nil { + request.URL = &url.URL{} + } + query := request.URL.Query() + var queryParameterValue, queryParameterName string + + if queryParameterName = field.Tag.Get("name"); queryParameterName == "" { + return fmt.Errorf("marshaling request to a query requires the 'name' tag for field: %s ", field.Name) + } + + mandatory, _ := strconv.ParseBool(strings.ToLower(field.Tag.Get("mandatory"))) + + //If mandatory and nil. Error out + if mandatory && isNil(value) { + return fmt.Errorf("marshaling request to a header requires not nil pointer for field: %s", field.Name) + } + + //if not mandatory and nil. Omit + if !mandatory && isNil(value) { + Debugf("Query parameter value is not mandatory and is nil pointer in field: %s. Skipping header", field.Name) + return + } + + if queryParameterValue, e = toStringValue(value, field); e != nil { + return + } + + //check for tag "omitEmpty", this is done to accomodate unset fields that do not + //support an empty string: enums in query params + if omitEmpty, present := field.Tag.Lookup("omitEmpty"); present { + omitEmptyBool, _ := strconv.ParseBool(strings.ToLower(omitEmpty)) + if queryParameterValue != "" || !omitEmptyBool { + query.Set(queryParameterName, queryParameterValue) + } else { + Debugf("Omitting %s, is empty and omitEmpty tag is set", field.Name) + } + } else { + query.Set(queryParameterName, queryParameterValue) + } + + request.URL.RawQuery = query.Encode() + return +} + +// Adds to the path of the url in the order they appear in the structure +func addToPath(request *http.Request, value reflect.Value, field reflect.StructField) (e error) { + var additionalURLPathPart string + if additionalURLPathPart, e = toStringValue(value, field); e != nil { + return fmt.Errorf("can not marshal to path in request for field %s. Due to %s", field.Name, e.Error()) + } + + if request.URL == nil { + request.URL = &url.URL{} + request.URL.Path = "" + } + var currentURLPath = request.URL.Path + + var templatedPathRegex, _ = regexp.Compile(".*{.+}.*") + if !templatedPathRegex.MatchString(currentURLPath) { + Debugln("Marshaling request to path by appending field:", field.Name) + allPath := []string{currentURLPath, additionalURLPathPart} + newPath := strings.Join(allPath, "/") + request.URL.Path = path.Clean(newPath) + } else { + var fieldName string + if fieldName = field.Tag.Get("name"); fieldName == "" { + e = fmt.Errorf("marshaling request to path name and template requires a 'name' tag for field: %s", field.Name) + return + } + urlTemplate := currentURLPath + Debugln("Marshaling to path from field:", field.Name, "in template:", urlTemplate) + request.URL.Path = path.Clean(strings.Replace(urlTemplate, "{"+fieldName+"}", additionalURLPathPart, -1)) + } + return +} + +func setWellKnownHeaders(request *http.Request, headerName, headerValue string) (e error) { + switch strings.ToLower(headerName) { + case "content-length": + var len int + len, e = strconv.Atoi(headerValue) + if e != nil { + return + } + request.ContentLength = int64(len) + } + return nil +} + +func addToHeader(request *http.Request, value reflect.Value, field reflect.StructField) (e error) { + Debugln("Marshaling to header from field:", field.Name) + if request.Header == nil { + request.Header = http.Header{} + } + + var headerName, headerValue string + if headerName = field.Tag.Get("name"); headerName == "" { + return fmt.Errorf("marshaling request to a header requires the 'name' tag for field: %s", field.Name) + } + + mandatory, _ := strconv.ParseBool(strings.ToLower(field.Tag.Get("mandatory"))) + //If mandatory and nil. Error out + if mandatory && isNil(value) { + return fmt.Errorf("marshaling request to a header requires not nil pointer for field: %s", field.Name) + } + + //if not mandatory and nil. Omit + if !mandatory && isNil(value) { + Debugf("Header value is not mandatory and is nil pointer in field: %s. Skipping header", field.Name) + return + } + + //Otherwise get value and set header + if headerValue, e = toStringValue(value, field); e != nil { + return + } + + if e = setWellKnownHeaders(request, headerName, headerValue); e != nil { + return + } + + request.Header.Set(headerName, headerValue) + return +} + +// Header collection is a map of string to string that gets rendered as individual headers with a given prefix +func addToHeaderCollection(request *http.Request, value reflect.Value, field reflect.StructField) (e error) { + Debugln("Marshaling to header-collection from field:", field.Name) + if request.Header == nil { + request.Header = http.Header{} + } + + var headerPrefix string + if headerPrefix = field.Tag.Get("prefix"); headerPrefix == "" { + return fmt.Errorf("marshaling request to a header requires the 'prefix' tag for field: %s", field.Name) + } + + mandatory, _ := strconv.ParseBool(strings.ToLower(field.Tag.Get("mandatory"))) + //If mandatory and nil. Error out + if mandatory && isNil(value) { + return fmt.Errorf("marshaling request to a header requires not nil pointer for field: %s", field.Name) + } + + //if not mandatory and nil. Omit + if !mandatory && isNil(value) { + Debugf("Header value is not mandatory and is nil pointer in field: %s. Skipping header", field.Name) + return + } + + //cast to map + headerValues, ok := value.Interface().(map[string]string) + if !ok { + e = fmt.Errorf("header fields need to be of type map[string]string") + return + } + + for k, v := range headerValues { + headerName := fmt.Sprintf("%s%s", headerPrefix, k) + request.Header.Set(headerName, v) + } + return +} + +// Makes sure the incoming structure is able to be marshalled +// to a request +func checkForValidRequestStruct(s interface{}) (*reflect.Value, error) { + val := reflect.ValueOf(s) + for val.Kind() == reflect.Ptr { + if val.IsNil() { + return nil, fmt.Errorf("can not marshal to request a pointer to structure") + } + val = val.Elem() + } + + if s == nil { + return nil, fmt.Errorf("can not marshal to request a nil structure") + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("can not marshal to request, expects struct input. Got %v", val.Kind()) + } + + return &val, nil +} + +// Populates the parts of a request by reading tags in the passed structure +// nested structs are followed recursively depth-first. +func structToRequestPart(request *http.Request, val reflect.Value) (err error) { + typ := val.Type() + for i := 0; i < typ.NumField(); i++ { + if err != nil { + return + } + + sf := typ.Field(i) + //unexported + if sf.PkgPath != "" && !sf.Anonymous { + continue + } + + sv := val.Field(i) + tag := sf.Tag.Get("contributesTo") + switch tag { + case "header": + err = addToHeader(request, sv, sf) + case "header-collection": + err = addToHeaderCollection(request, sv, sf) + case "path": + err = addToPath(request, sv, sf) + case "query": + err = addToQuery(request, sv, sf) + case "body": + err = addToBody(request, sv, sf) + case "": + Debugln(sf.Name, "does not contain contributes tag. Skipping.") + default: + err = fmt.Errorf("can not marshal field: %s. It needs to contain valid contributesTo tag", sf.Name) + } + } + + //If headers are and the content type was not set, we default to application/json + if request.Header != nil && request.Header.Get("Content-Type") == "" { + request.Header.Set("Content-Type", "application/json") + } + + return +} + +// HTTPRequestMarshaller marshals a structure to an http request using tag values in the struct +// The marshaller tag should like the following +// type A struct { +// ANumber string `contributesTo="query" name="number"` +// TheBody `contributesTo="body"` +// } +// where the contributesTo tag can be: header, path, query, body +// and the 'name' tag is the name of the value used in the http request(not applicable for path) +// If path is specified as part of the tag, the values are appened to the url path +// in the order they appear in the structure +// The current implementation only supports primitive types, except for the body tag, which needs a struct type. +// The body of a request will be marshaled using the tags of the structure +func HTTPRequestMarshaller(requestStruct interface{}, httpRequest *http.Request) (err error) { + var val *reflect.Value + if val, err = checkForValidRequestStruct(requestStruct); err != nil { + return + } + + Debugln("Marshaling to Request:", val.Type().Name()) + err = structToRequestPart(httpRequest, *val) + return +} + +// MakeDefaultHTTPRequest creates the basic http request with the necessary headers set +func MakeDefaultHTTPRequest(method, path string) (httpRequest http.Request) { + httpRequest = http.Request{ + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + URL: &url.URL{}, + } + + httpRequest.Header.Set("Content-Length", "0") + httpRequest.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) + httpRequest.Header.Set("Opc-Client-Info", strings.Join([]string{defaultSDKMarker, Version()}, "/")) + httpRequest.Header.Set("Accept", "*/*") + httpRequest.Method = method + httpRequest.URL.Path = path + return +} + +// MakeDefaultHTTPRequestWithTaggedStruct creates an http request from an struct with tagged fields, see HTTPRequestMarshaller +// for more information +func MakeDefaultHTTPRequestWithTaggedStruct(method, path string, requestStruct interface{}) (httpRequest http.Request, err error) { + httpRequest = MakeDefaultHTTPRequest(method, path) + err = HTTPRequestMarshaller(requestStruct, &httpRequest) + return +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Request UnMarshaling +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Makes sure the incoming structure is able to be unmarshaled +// to a request +func checkForValidResponseStruct(s interface{}) (*reflect.Value, error) { + val := reflect.ValueOf(s) + for val.Kind() == reflect.Ptr { + if val.IsNil() { + return nil, fmt.Errorf("can not unmarshal to response a pointer to nil structure") + } + val = val.Elem() + } + + if s == nil { + return nil, fmt.Errorf("can not unmarshal to response a nil structure") + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("can not unmarshal to response, expects struct input. Got %v", val.Kind()) + } + + return &val, nil +} + +func intSizeFromKind(kind reflect.Kind) int { + switch kind { + case reflect.Int8, reflect.Uint8: + return 8 + case reflect.Int16, reflect.Uint16: + return 16 + case reflect.Int32, reflect.Uint32: + return 32 + case reflect.Int64, reflect.Uint64: + return 64 + case reflect.Int, reflect.Uint: + return strconv.IntSize + default: + Debugln("The type is not valid: %v. Returing int size for arch", kind.String()) + return strconv.IntSize + } + +} + +func analyzeValue(stringValue string, kind reflect.Kind, field reflect.StructField) (val reflect.Value, valPointer reflect.Value, err error) { + switch kind { + case timeType.Kind(): + var t time.Time + t, err = tryParsingTimeWithValidFormatsForHeaders([]byte(stringValue), field.Name) + if err != nil { + return + } + sdkTime := sdkTimeFromTime(t) + val = reflect.ValueOf(sdkTime) + valPointer = reflect.ValueOf(&sdkTime) + return + case reflect.Bool: + var bVal bool + if bVal, err = strconv.ParseBool(stringValue); err != nil { + return + } + val = reflect.ValueOf(bVal) + valPointer = reflect.ValueOf(&bVal) + return + case reflect.Int: + size := intSizeFromKind(kind) + var iVal int64 + if iVal, err = strconv.ParseInt(stringValue, 10, size); err != nil { + return + } + var iiVal int + iiVal = int(iVal) + val = reflect.ValueOf(iiVal) + valPointer = reflect.ValueOf(&iiVal) + return + case reflect.Int64: + size := intSizeFromKind(kind) + var iVal int64 + if iVal, err = strconv.ParseInt(stringValue, 10, size); err != nil { + return + } + val = reflect.ValueOf(iVal) + valPointer = reflect.ValueOf(&iVal) + return + case reflect.Uint: + size := intSizeFromKind(kind) + var iVal uint64 + if iVal, err = strconv.ParseUint(stringValue, 10, size); err != nil { + return + } + var uiVal uint + uiVal = uint(iVal) + val = reflect.ValueOf(uiVal) + valPointer = reflect.ValueOf(&uiVal) + return + case reflect.String: + val = reflect.ValueOf(stringValue) + valPointer = reflect.ValueOf(&stringValue) + case reflect.Float32: + var fVal float64 + if fVal, err = strconv.ParseFloat(stringValue, 32); err != nil { + return + } + var ffVal float32 + ffVal = float32(fVal) + val = reflect.ValueOf(ffVal) + valPointer = reflect.ValueOf(&ffVal) + return + case reflect.Float64: + var fVal float64 + if fVal, err = strconv.ParseFloat(stringValue, 64); err != nil { + return + } + val = reflect.ValueOf(fVal) + valPointer = reflect.ValueOf(&fVal) + return + default: + err = fmt.Errorf("value for kind: %s not supported", kind) + } + return +} + +// Sets the field of a struct, with the appropiate value of the string +// Only sets basic types +func fromStringValue(newValue string, val *reflect.Value, field reflect.StructField) (err error) { + + if !val.CanSet() { + err = fmt.Errorf("can not set field name: %s of type: %v", field.Name, val.Type().String()) + return + } + + kind := val.Kind() + isPointer := false + if val.Kind() == reflect.Ptr { + isPointer = true + kind = field.Type.Elem().Kind() + } + + value, valPtr, err := analyzeValue(newValue, kind, field) + if err != nil { + return + } + if !isPointer { + val.Set(value) + } else { + val.Set(valPtr) + } + return +} + +// PolymorphicJSONUnmarshaler is the interface to unmarshal polymorphic json payloads +type PolymorphicJSONUnmarshaler interface { + UnmarshalPolymorphicJSON(data []byte) (interface{}, error) +} + +func valueFromPolymorphicJSON(content []byte, unmarshaler PolymorphicJSONUnmarshaler) (val interface{}, err error) { + err = json.Unmarshal(content, unmarshaler) + if err != nil { + return + } + val, err = unmarshaler.UnmarshalPolymorphicJSON(content) + return +} + +func valueFromJSONBody(response *http.Response, value *reflect.Value, unmarshaler PolymorphicJSONUnmarshaler) (val interface{}, err error) { + //Consumes the body, consider implementing it + //without body consumption + var content []byte + content, err = ioutil.ReadAll(response.Body) + if err != nil { + return + } + + if unmarshaler != nil { + val, err = valueFromPolymorphicJSON(content, unmarshaler) + return + } + + val = reflect.New(value.Type()).Interface() + err = json.Unmarshal(content, &val) + return +} + +func addFromBody(response *http.Response, value *reflect.Value, field reflect.StructField, unmarshaler PolymorphicJSONUnmarshaler) (err error) { + Debugln("Unmarshaling from body to field:", field.Name) + if response.Body == nil { + Debugln("Unmarshaling body skipped due to nil body content for field: ", field.Name) + return nil + } + + tag := field.Tag + encoding := tag.Get("encoding") + var iVal interface{} + switch encoding { + case "binary": + value.Set(reflect.ValueOf(response.Body)) + return + case "plain-text": + //Expects UTF-8 + byteArr, e := ioutil.ReadAll(response.Body) + if e != nil { + return e + } + str := string(byteArr) + value.Set(reflect.ValueOf(&str)) + return + default: //If the encoding is not set. we'll decode with json + iVal, err = valueFromJSONBody(response, value, unmarshaler) + if err != nil { + return + } + + newVal := reflect.ValueOf(iVal) + if newVal.Kind() == reflect.Ptr { + newVal = newVal.Elem() + } + value.Set(newVal) + return + } +} + +func addFromHeader(response *http.Response, value *reflect.Value, field reflect.StructField) (err error) { + Debugln("Unmarshaling from header to field:", field.Name) + var headerName string + if headerName = field.Tag.Get("name"); headerName == "" { + return fmt.Errorf("unmarshaling response to a header requires the 'name' tag for field: %s", field.Name) + } + + headerValue := response.Header.Get(headerName) + if headerValue == "" { + Debugf("Unmarshalling did not find header with name:%s", headerName) + return nil + } + + if err = fromStringValue(headerValue, value, field); err != nil { + return fmt.Errorf("unmarshaling response to a header failed for field %s, due to %s", field.Name, + err.Error()) + } + return +} + +func addFromHeaderCollection(response *http.Response, value *reflect.Value, field reflect.StructField) error { + Debugln("Unmarshaling from header-collection to field:", field.Name) + var headerPrefix string + if headerPrefix = field.Tag.Get("prefix"); headerPrefix == "" { + return fmt.Errorf("Unmarshaling response to a header-collection requires the 'prefix' tag for field: %s", field.Name) + } + + mapCollection := make(map[string]string) + for name, value := range response.Header { + nameLowerCase := strings.ToLower(name) + if strings.HasPrefix(nameLowerCase, headerPrefix) { + headerNoPrefix := strings.TrimPrefix(nameLowerCase, headerPrefix) + mapCollection[headerNoPrefix] = value[0] + } + } + + Debugln("Marshalled header collection is:", mapCollection) + value.Set(reflect.ValueOf(mapCollection)) + return nil +} + +// Populates a struct from parts of a request by reading tags of the struct +func responseToStruct(response *http.Response, val *reflect.Value, unmarshaler PolymorphicJSONUnmarshaler) (err error) { + typ := val.Type() + for i := 0; i < typ.NumField(); i++ { + if err != nil { + return + } + + sf := typ.Field(i) + + //unexported + if sf.PkgPath != "" { + continue + } + + sv := val.Field(i) + tag := sf.Tag.Get("presentIn") + switch tag { + case "header": + err = addFromHeader(response, &sv, sf) + case "header-collection": + err = addFromHeaderCollection(response, &sv, sf) + case "body": + err = addFromBody(response, &sv, sf, unmarshaler) + case "": + Debugln(sf.Name, "does not contain presentIn tag. Skipping") + default: + err = fmt.Errorf("can not unmarshal field: %s. It needs to contain valid presentIn tag", sf.Name) + } + } + return +} + +// UnmarshalResponse hydrates the fields of a struct with the values of a http response, guided +// by the field tags. The directive tag is "presentIn" and it can be either +// - "header": Will look for the header tagged as "name" in the headers of the struct and set it value to that +// - "body": It will try to marshal the body from a json string to a struct tagged with 'presentIn: "body"'. +// Further this method will consume the body it should be safe to close it after this function +// Notice the current implementation only supports native types:int, strings, floats, bool as the field types +func UnmarshalResponse(httpResponse *http.Response, responseStruct interface{}) (err error) { + + var val *reflect.Value + if val, err = checkForValidResponseStruct(responseStruct); err != nil { + return + } + + if err = responseToStruct(httpResponse, val, nil); err != nil { + return + } + + return nil +} + +// UnmarshalResponseWithPolymorphicBody similar to UnmarshalResponse but assumes the body of the response +// contains polymorphic json. This function will use the unmarshaler argument to unmarshal json content +func UnmarshalResponseWithPolymorphicBody(httpResponse *http.Response, responseStruct interface{}, unmarshaler PolymorphicJSONUnmarshaler) (err error) { + + var val *reflect.Value + if val, err = checkForValidResponseStruct(responseStruct); err != nil { + return + } + + if err = responseToStruct(httpResponse, val, unmarshaler); err != nil { + return + } + + return nil +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/http_signer.go b/vendor/github.com/oracle/oci-go-sdk/common/http_signer.go new file mode 100644 index 000000000..3e82931aa --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/http_signer.go @@ -0,0 +1,230 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "bytes" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "strings" +) + +// HTTPRequestSigner the interface to sign a request +type HTTPRequestSigner interface { + Sign(r *http.Request) error +} + +// KeyProvider interface that wraps information about the key's account owner +type KeyProvider interface { + PrivateRSAKey() (*rsa.PrivateKey, error) + KeyID() (string, error) +} + +const signerVersion = "1" + +// SignerBodyHashPredicate a function that allows to disable/enable body hashing +// of requests and headers associated with body content +type SignerBodyHashPredicate func(r *http.Request) bool + +// ociRequestSigner implements the http-signatures-draft spec +// as described in https://tools.ietf.org/html/draft-cavage-http-signatures-08 +type ociRequestSigner struct { + KeyProvider KeyProvider + GenericHeaders []string + BodyHeaders []string + ShouldHashBody SignerBodyHashPredicate +} + +var ( + defaultGenericHeaders = []string{"date", "(request-target)", "host"} + defaultBodyHeaders = []string{"content-length", "content-type", "x-content-sha256"} + defaultBodyHashPredicate = func(r *http.Request) bool { + return r.Method == http.MethodPost || r.Method == http.MethodPut + } +) + +// DefaultRequestSigner creates a signer with default parameters. +func DefaultRequestSigner(provider KeyProvider) HTTPRequestSigner { + return RequestSigner(provider, defaultGenericHeaders, defaultBodyHeaders) +} + +// RequestSigner creates a signer that utilizes the specified headers for signing +// and the default predicate for using the body of the request as part of the signature +func RequestSigner(provider KeyProvider, genericHeaders, bodyHeaders []string) HTTPRequestSigner { + return ociRequestSigner{ + KeyProvider: provider, + GenericHeaders: genericHeaders, + BodyHeaders: bodyHeaders, + ShouldHashBody: defaultBodyHashPredicate} +} + +// RequestSignerWithBodyHashingPredicate creates a signer that utilizes the specified headers for signing, as well as a predicate for using +// the body of the request and bodyHeaders parameter as part of the signature +func RequestSignerWithBodyHashingPredicate(provider KeyProvider, genericHeaders, bodyHeaders []string, shouldHashBody SignerBodyHashPredicate) HTTPRequestSigner { + return ociRequestSigner{ + KeyProvider: provider, + GenericHeaders: genericHeaders, + BodyHeaders: bodyHeaders, + ShouldHashBody: shouldHashBody} +} + +func (signer ociRequestSigner) getSigningHeaders(r *http.Request) []string { + var result []string + result = append(result, signer.GenericHeaders...) + + if signer.ShouldHashBody(r) { + result = append(result, signer.BodyHeaders...) + } + + return result +} + +func (signer ociRequestSigner) getSigningString(request *http.Request) string { + signingHeaders := signer.getSigningHeaders(request) + signingParts := make([]string, len(signingHeaders)) + for i, part := range signingHeaders { + var value string + switch part { + case "(request-target)": + value = getRequestTarget(request) + case "host": + value = request.URL.Host + if len(value) == 0 { + value = request.Host + } + default: + value = request.Header.Get(part) + } + signingParts[i] = fmt.Sprintf("%s: %s", part, value) + } + + signingString := strings.Join(signingParts, "\n") + return signingString + +} + +func getRequestTarget(request *http.Request) string { + lowercaseMethod := strings.ToLower(request.Method) + return fmt.Sprintf("%s %s", lowercaseMethod, request.URL.RequestURI()) +} + +func calculateHashOfBody(request *http.Request) (err error) { + var hash string + if request.ContentLength > 0 { + hash, err = GetBodyHash(request) + if err != nil { + return + } + } else { + hash = hashAndEncode([]byte("")) + } + request.Header.Set("X-Content-Sha256", hash) + return +} + +// drainBody reads all of b to memory and then returns two equivalent +// ReadClosers yielding the same bytes. +// +// It returns an error if the initial slurp of all bytes fails. It does not attempt +// to make the returned ReadClosers have identical error-matching behavior. +func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) { + if b == http.NoBody { + // No copying needed. Preserve the magic sentinel meaning of NoBody. + return http.NoBody, http.NoBody, nil + } + var buf bytes.Buffer + if _, err = buf.ReadFrom(b); err != nil { + return nil, b, err + } + if err = b.Close(); err != nil { + return nil, b, err + } + return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil +} + +func hashAndEncode(data []byte) string { + hashedContent := sha256.Sum256(data) + hash := base64.StdEncoding.EncodeToString(hashedContent[:]) + return hash +} + +// GetBodyHash creates a base64 string from the hash of body the request +func GetBodyHash(request *http.Request) (hashString string, err error) { + if request.Body == nil { + return "", fmt.Errorf("can not read body of request while calculating body hash, nil body?") + } + + var data []byte + bReader := request.Body + bReader, request.Body, err = drainBody(request.Body) + if err != nil { + return "", fmt.Errorf("can not read body of request while calculating body hash: %s", err.Error()) + } + + data, err = ioutil.ReadAll(bReader) + if err != nil { + return "", fmt.Errorf("can not read body of request while calculating body hash: %s", err.Error()) + } + hashString = hashAndEncode(data) + return +} + +func (signer ociRequestSigner) computeSignature(request *http.Request) (signature string, err error) { + signingString := signer.getSigningString(request) + hasher := sha256.New() + hasher.Write([]byte(signingString)) + hashed := hasher.Sum(nil) + + privateKey, err := signer.KeyProvider.PrivateRSAKey() + if err != nil { + return + } + + var unencodedSig []byte + unencodedSig, e := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed) + if e != nil { + err = fmt.Errorf("can not compute signature while signing the request %s: ", e.Error()) + return + } + + signature = base64.StdEncoding.EncodeToString(unencodedSig) + return +} + +// Sign signs the http request, by inspecting the necessary headers. Once signed +// the request will have the proper 'Authorization' header set, otherwise +// and error is returned +func (signer ociRequestSigner) Sign(request *http.Request) (err error) { + if signer.ShouldHashBody(request) { + err = calculateHashOfBody(request) + if err != nil { + return + } + } + + var signature string + if signature, err = signer.computeSignature(request); err != nil { + return + } + + signingHeaders := strings.Join(signer.getSigningHeaders(request), " ") + + var keyID string + if keyID, err = signer.KeyProvider.KeyID(); err != nil { + return + } + + authValue := fmt.Sprintf("Signature version=\"%s\",headers=\"%s\",keyId=\"%s\",algorithm=\"rsa-sha256\",signature=\"%s\"", + signerVersion, signingHeaders, keyID, signature) + + request.Header.Set("Authorization", authValue) + + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/log.go b/vendor/github.com/oracle/oci-go-sdk/common/log.go new file mode 100644 index 000000000..328485fdd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/log.go @@ -0,0 +1,67 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + +package common + +import ( + "fmt" + "io" + "io/ioutil" + "log" + "os" + "sync" +) + +// Simple logging proxy to distinguish control for logging messages +// Debug logging is turned on/off by the presence of the environment variable "OCI_GO_SDK_DEBUG" +var debugLog = log.New(os.Stderr, "DEBUG ", log.Ldate|log.Ltime|log.Lshortfile) +var mainLog = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile) +var isDebugLogEnabled bool +var checkDebug sync.Once + +func getOutputForEnv() (writer io.Writer) { + checkDebug.Do(func() { + isDebugLogEnabled = *new(bool) + _, isDebugLogEnabled = os.LookupEnv("OCI_GO_SDK_DEBUG") + }) + + writer = ioutil.Discard + if isDebugLogEnabled { + writer = os.Stderr + } + return +} + +// Debugf logs v with the provided format if debug mode is set +func Debugf(format string, v ...interface{}) { + debugLog.SetOutput(getOutputForEnv()) + debugLog.Output(3, fmt.Sprintf(format, v...)) +} + +// Debug logs v if debug mode is set +func Debug(v ...interface{}) { + debugLog.SetOutput(getOutputForEnv()) + debugLog.Output(3, fmt.Sprint(v...)) +} + +// Debugln logs v appending a new line if debug mode is set +func Debugln(v ...interface{}) { + debugLog.SetOutput(getOutputForEnv()) + debugLog.Output(3, fmt.Sprintln(v...)) +} + +// IfDebug executes closure if debug is enabled +func IfDebug(fn func()) { + if isDebugLogEnabled { + fn() + } +} + +// Logln logs v appending a new line at the end +func Logln(v ...interface{}) { + mainLog.Output(3, fmt.Sprintln(v...)) +} + +// Logf logs v with the provided format +func Logf(format string, v ...interface{}) { + mainLog.Output(3, fmt.Sprintf(format, v...)) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/common/version.go b/vendor/github.com/oracle/oci-go-sdk/common/version.go new file mode 100644 index 000000000..be610d170 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/common/version.go @@ -0,0 +1,36 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated by go generate; DO NOT EDIT + +package common + +import ( + "bytes" + "fmt" + "sync" +) + +const ( + major = "1" + minor = "0" + patch = "0" + tag = "" +) + +var once sync.Once +var version string + +// Version returns semantic version of the sdk +func Version() string { + once.Do(func() { + ver := fmt.Sprintf("%s.%s.%s", major, minor, patch) + verBuilder := bytes.NewBufferString(ver) + if tag != "" && tag != "-" { + _, err := verBuilder.WriteString(tag) + if err == nil { + verBuilder = bytes.NewBufferString(ver) + } + } + version = verBuilder.String() + }) + return version +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_details.go new file mode 100644 index 000000000..7dc403a4c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_details.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// AttachBootVolumeDetails The representation of AttachBootVolumeDetails +type AttachBootVolumeDetails struct { + + // The OCID of the boot volume. + BootVolumeId *string `mandatory:"true" json:"bootVolumeId"` + + // The OCID of the instance. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // A user-friendly name. Does not have to be unique, and it cannot be changed. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m AttachBootVolumeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_request_response.go new file mode 100644 index 000000000..f52a01930 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_boot_volume_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// AttachBootVolumeRequest wrapper for the AttachBootVolume operation +type AttachBootVolumeRequest struct { + + // Attach boot volume request + AttachBootVolumeDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request AttachBootVolumeRequest) String() string { + return common.PointerString(request) +} + +// AttachBootVolumeResponse wrapper for the AttachBootVolume operation +type AttachBootVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BootVolumeAttachment instance + BootVolumeAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response AttachBootVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_i_scsi_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_i_scsi_volume_details.go new file mode 100644 index 000000000..827108d2f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_i_scsi_volume_details.go @@ -0,0 +1,63 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// AttachIScsiVolumeDetails The representation of AttachIScsiVolumeDetails +type AttachIScsiVolumeDetails struct { + + // The OCID of the instance. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // The OCID of the volume. + VolumeId *string `mandatory:"true" json:"volumeId"` + + // A user-friendly name. Does not have to be unique, and it cannot be changed. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Whether to use CHAP authentication for the volume attachment. Defaults to false. + UseChap *bool `mandatory:"false" json:"useChap"` +} + +//GetDisplayName returns DisplayName +func (m AttachIScsiVolumeDetails) GetDisplayName() *string { + return m.DisplayName +} + +//GetInstanceId returns InstanceId +func (m AttachIScsiVolumeDetails) GetInstanceId() *string { + return m.InstanceId +} + +//GetVolumeId returns VolumeId +func (m AttachIScsiVolumeDetails) GetVolumeId() *string { + return m.VolumeId +} + +func (m AttachIScsiVolumeDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m AttachIScsiVolumeDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeAttachIScsiVolumeDetails AttachIScsiVolumeDetails + s := struct { + DiscriminatorParam string `json:"type"` + MarshalTypeAttachIScsiVolumeDetails + }{ + "iscsi", + (MarshalTypeAttachIScsiVolumeDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_details.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_details.go new file mode 100644 index 000000000..a6e978940 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_details.go @@ -0,0 +1,37 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// AttachVnicDetails The representation of AttachVnicDetails +type AttachVnicDetails struct { + + // Details for creating a new VNIC. + CreateVnicDetails *CreateVnicDetails `mandatory:"true" json:"createVnicDetails"` + + // The OCID of the instance. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // A user-friendly name for the attachment. Does not have to be unique, and it cannot be changed. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Which physical network interface card (NIC) the VNIC will use. Defaults to 0. + // Certain bare metal instance shapes have two active physical NICs (0 and 1). If + // you add a secondary VNIC to one of these instances, you can specify which NIC + // the VNIC will use. For more information, see + // Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). + NicIndex *int `mandatory:"false" json:"nicIndex"` +} + +func (m AttachVnicDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_request_response.go new file mode 100644 index 000000000..3f04c241a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_vnic_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// AttachVnicRequest wrapper for the AttachVnic operation +type AttachVnicRequest struct { + + // Attach VNIC details. + AttachVnicDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request AttachVnicRequest) String() string { + return common.PointerString(request) +} + +// AttachVnicResponse wrapper for the AttachVnic operation +type AttachVnicResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VnicAttachment instance + VnicAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response AttachVnicResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_volume_details.go new file mode 100644 index 000000000..414fc9c3a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_volume_details.go @@ -0,0 +1,86 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// AttachVolumeDetails The representation of AttachVolumeDetails +type AttachVolumeDetails interface { + + // The OCID of the instance. + GetInstanceId() *string + + // The OCID of the volume. + GetVolumeId() *string + + // A user-friendly name. Does not have to be unique, and it cannot be changed. Avoid entering confidential information. + GetDisplayName() *string +} + +type attachvolumedetails struct { + JsonData []byte + InstanceId *string `mandatory:"true" json:"instanceId"` + VolumeId *string `mandatory:"true" json:"volumeId"` + DisplayName *string `mandatory:"false" json:"displayName"` + Type string `json:"type"` +} + +// UnmarshalJSON unmarshals json +func (m *attachvolumedetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalerattachvolumedetails attachvolumedetails + s := struct { + Model Unmarshalerattachvolumedetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.InstanceId = s.Model.InstanceId + m.VolumeId = s.Model.VolumeId + m.DisplayName = s.Model.DisplayName + m.Type = s.Model.Type + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *attachvolumedetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Type { + case "iscsi": + mm := AttachIScsiVolumeDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetInstanceId returns InstanceId +func (m attachvolumedetails) GetInstanceId() *string { + return m.InstanceId +} + +//GetVolumeId returns VolumeId +func (m attachvolumedetails) GetVolumeId() *string { + return m.VolumeId +} + +//GetDisplayName returns DisplayName +func (m attachvolumedetails) GetDisplayName() *string { + return m.DisplayName +} + +func (m attachvolumedetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/attach_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/attach_volume_request_response.go new file mode 100644 index 000000000..d2f7076f8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/attach_volume_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// AttachVolumeRequest wrapper for the AttachVolume operation +type AttachVolumeRequest struct { + + // Attach volume request + AttachVolumeDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request AttachVolumeRequest) String() string { + return common.PointerString(request) +} + +// AttachVolumeResponse wrapper for the AttachVolume operation +type AttachVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VolumeAttachment instance + VolumeAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response AttachVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/boot_volume.go b/vendor/github.com/oracle/oci-go-sdk/core/boot_volume.go new file mode 100644 index 000000000..1f57aca45 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/boot_volume.go @@ -0,0 +1,86 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BootVolume A detachable boot volume device that contains the image used to boot an Compute instance. For more information, see +// Overview of Boot Volumes (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/bootvolumes.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type BootVolume struct { + + // The Availability Domain of the boot volume. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment that contains the boot volume. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The boot volume's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The current state of a boot volume. + LifecycleState BootVolumeLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The size of the volume in MBs. The value must be a multiple of 1024. + // This field is deprecated. Please use sizeInGBs. + SizeInMBs *int `mandatory:"true" json:"sizeInMBs"` + + // The date and time the boot volume was created. Format defined by RFC3339. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The image OCID used to create the boot volume. + ImageId *string `mandatory:"false" json:"imageId"` + + // The size of the boot volume in GBs. + SizeInGBs *int `mandatory:"false" json:"sizeInGBs"` +} + +func (m BootVolume) String() string { + return common.PointerString(m) +} + +// BootVolumeLifecycleStateEnum Enum with underlying type: string +type BootVolumeLifecycleStateEnum string + +// Set of constants representing the allowable values for BootVolumeLifecycleState +const ( + BootVolumeLifecycleStateProvisioning BootVolumeLifecycleStateEnum = "PROVISIONING" + BootVolumeLifecycleStateRestoring BootVolumeLifecycleStateEnum = "RESTORING" + BootVolumeLifecycleStateAvailable BootVolumeLifecycleStateEnum = "AVAILABLE" + BootVolumeLifecycleStateTerminating BootVolumeLifecycleStateEnum = "TERMINATING" + BootVolumeLifecycleStateTerminated BootVolumeLifecycleStateEnum = "TERMINATED" + BootVolumeLifecycleStateFaulty BootVolumeLifecycleStateEnum = "FAULTY" +) + +var mappingBootVolumeLifecycleState = map[string]BootVolumeLifecycleStateEnum{ + "PROVISIONING": BootVolumeLifecycleStateProvisioning, + "RESTORING": BootVolumeLifecycleStateRestoring, + "AVAILABLE": BootVolumeLifecycleStateAvailable, + "TERMINATING": BootVolumeLifecycleStateTerminating, + "TERMINATED": BootVolumeLifecycleStateTerminated, + "FAULTY": BootVolumeLifecycleStateFaulty, +} + +// GetBootVolumeLifecycleStateEnumValues Enumerates the set of values for BootVolumeLifecycleState +func GetBootVolumeLifecycleStateEnumValues() []BootVolumeLifecycleStateEnum { + values := make([]BootVolumeLifecycleStateEnum, 0) + for _, v := range mappingBootVolumeLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/boot_volume_attachment.go b/vendor/github.com/oracle/oci-go-sdk/core/boot_volume_attachment.go new file mode 100644 index 000000000..2c24059fc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/boot_volume_attachment.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BootVolumeAttachment Represents an attachment between a boot volume and an instance. +type BootVolumeAttachment struct { + + // The Availability Domain of an instance. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the boot volume. + BootVolumeId *string `mandatory:"true" json:"bootVolumeId"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the boot volume attachment. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the instance the boot volume is attached to. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // The current state of the boot volume attachment. + LifecycleState BootVolumeAttachmentLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The date and time the boot volume was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // A user-friendly name. Does not have to be unique, and it cannot be changed. + // Avoid entering confidential information. + // Example: `My boot volume` + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m BootVolumeAttachment) String() string { + return common.PointerString(m) +} + +// BootVolumeAttachmentLifecycleStateEnum Enum with underlying type: string +type BootVolumeAttachmentLifecycleStateEnum string + +// Set of constants representing the allowable values for BootVolumeAttachmentLifecycleState +const ( + BootVolumeAttachmentLifecycleStateAttaching BootVolumeAttachmentLifecycleStateEnum = "ATTACHING" + BootVolumeAttachmentLifecycleStateAttached BootVolumeAttachmentLifecycleStateEnum = "ATTACHED" + BootVolumeAttachmentLifecycleStateDetaching BootVolumeAttachmentLifecycleStateEnum = "DETACHING" + BootVolumeAttachmentLifecycleStateDetached BootVolumeAttachmentLifecycleStateEnum = "DETACHED" +) + +var mappingBootVolumeAttachmentLifecycleState = map[string]BootVolumeAttachmentLifecycleStateEnum{ + "ATTACHING": BootVolumeAttachmentLifecycleStateAttaching, + "ATTACHED": BootVolumeAttachmentLifecycleStateAttached, + "DETACHING": BootVolumeAttachmentLifecycleStateDetaching, + "DETACHED": BootVolumeAttachmentLifecycleStateDetached, +} + +// GetBootVolumeAttachmentLifecycleStateEnumValues Enumerates the set of values for BootVolumeAttachmentLifecycleState +func GetBootVolumeAttachmentLifecycleStateEnumValues() []BootVolumeAttachmentLifecycleStateEnum { + values := make([]BootVolumeAttachmentLifecycleStateEnum, 0) + for _, v := range mappingBootVolumeAttachmentLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_details.go b/vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_details.go new file mode 100644 index 000000000..bf8afbbf2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BulkAddVirtualCircuitPublicPrefixesDetails The representation of BulkAddVirtualCircuitPublicPrefixesDetails +type BulkAddVirtualCircuitPublicPrefixesDetails struct { + + // The public IP prefixes (CIDRs) to add to the public virtual circuit. + PublicPrefixes []CreateVirtualCircuitPublicPrefixDetails `mandatory:"true" json:"publicPrefixes"` +} + +func (m BulkAddVirtualCircuitPublicPrefixesDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_request_response.go new file mode 100644 index 000000000..749adc891 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/bulk_add_virtual_circuit_public_prefixes_request_response.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// BulkAddVirtualCircuitPublicPrefixesRequest wrapper for the BulkAddVirtualCircuitPublicPrefixes operation +type BulkAddVirtualCircuitPublicPrefixesRequest struct { + + // The OCID of the virtual circuit. + VirtualCircuitId *string `mandatory:"true" contributesTo:"path" name:"virtualCircuitId"` + + // Request with publix prefixes to be added to the virtual circuit + BulkAddVirtualCircuitPublicPrefixesDetails `contributesTo:"body"` +} + +func (request BulkAddVirtualCircuitPublicPrefixesRequest) String() string { + return common.PointerString(request) +} + +// BulkAddVirtualCircuitPublicPrefixesResponse wrapper for the BulkAddVirtualCircuitPublicPrefixes operation +type BulkAddVirtualCircuitPublicPrefixesResponse struct { + + // The underlying http response + RawResponse *http.Response +} + +func (response BulkAddVirtualCircuitPublicPrefixesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_details.go b/vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_details.go new file mode 100644 index 000000000..031eea71b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BulkDeleteVirtualCircuitPublicPrefixesDetails The representation of BulkDeleteVirtualCircuitPublicPrefixesDetails +type BulkDeleteVirtualCircuitPublicPrefixesDetails struct { + + // The public IP prefixes (CIDRs) to remove from the public virtual circuit. + PublicPrefixes []DeleteVirtualCircuitPublicPrefixDetails `mandatory:"true" json:"publicPrefixes"` +} + +func (m BulkDeleteVirtualCircuitPublicPrefixesDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_request_response.go new file mode 100644 index 000000000..a57afa64e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/bulk_delete_virtual_circuit_public_prefixes_request_response.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// BulkDeleteVirtualCircuitPublicPrefixesRequest wrapper for the BulkDeleteVirtualCircuitPublicPrefixes operation +type BulkDeleteVirtualCircuitPublicPrefixesRequest struct { + + // The OCID of the virtual circuit. + VirtualCircuitId *string `mandatory:"true" contributesTo:"path" name:"virtualCircuitId"` + + // Request with publix prefixes to be deleted from the virtual circuit + BulkDeleteVirtualCircuitPublicPrefixesDetails `contributesTo:"body"` +} + +func (request BulkDeleteVirtualCircuitPublicPrefixesRequest) String() string { + return common.PointerString(request) +} + +// BulkDeleteVirtualCircuitPublicPrefixesResponse wrapper for the BulkDeleteVirtualCircuitPublicPrefixes operation +type BulkDeleteVirtualCircuitPublicPrefixesResponse struct { + + // The underlying http response + RawResponse *http.Response +} + +func (response BulkDeleteVirtualCircuitPublicPrefixesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_details.go b/vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_details.go new file mode 100644 index 000000000..9fb153ec6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_details.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CaptureConsoleHistoryDetails The representation of CaptureConsoleHistoryDetails +type CaptureConsoleHistoryDetails struct { + + // The OCID of the instance to get the console history from. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CaptureConsoleHistoryDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_request_response.go new file mode 100644 index 000000000..8e2919b70 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/capture_console_history_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CaptureConsoleHistoryRequest wrapper for the CaptureConsoleHistory operation +type CaptureConsoleHistoryRequest struct { + + // Console history details + CaptureConsoleHistoryDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CaptureConsoleHistoryRequest) String() string { + return common.PointerString(request) +} + +// CaptureConsoleHistoryResponse wrapper for the CaptureConsoleHistory operation +type CaptureConsoleHistoryResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The ConsoleHistory instance + ConsoleHistory `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CaptureConsoleHistoryResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_details.go b/vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_details.go new file mode 100644 index 000000000..6a2d06c2a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ConnectLocalPeeringGatewaysDetails Information about the other local peering gateway (LPG). +type ConnectLocalPeeringGatewaysDetails struct { + + // The OCID of the LPG you want to peer with. + PeerId *string `mandatory:"true" json:"peerId"` +} + +func (m ConnectLocalPeeringGatewaysDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_request_response.go new file mode 100644 index 000000000..084abbe5d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/connect_local_peering_gateways_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ConnectLocalPeeringGatewaysRequest wrapper for the ConnectLocalPeeringGateways operation +type ConnectLocalPeeringGatewaysRequest struct { + + // The OCID of the local peering gateway. + LocalPeeringGatewayId *string `mandatory:"true" contributesTo:"path" name:"localPeeringGatewayId"` + + // Details regarding the local peering gateway to connect. + ConnectLocalPeeringGatewaysDetails `contributesTo:"body"` +} + +func (request ConnectLocalPeeringGatewaysRequest) String() string { + return common.PointerString(request) +} + +// ConnectLocalPeeringGatewaysResponse wrapper for the ConnectLocalPeeringGateways operation +type ConnectLocalPeeringGatewaysResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ConnectLocalPeeringGatewaysResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/console_history.go b/vendor/github.com/oracle/oci-go-sdk/core/console_history.go new file mode 100644 index 000000000..27b9d760a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/console_history.go @@ -0,0 +1,75 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ConsoleHistory An instance's serial console data. It includes configuration messages that occur when the +// instance boots, such as kernel and BIOS messages, and is useful for checking the status of +// the instance or diagnosing problems. The console data is minimally formatted ASCII text. +type ConsoleHistory struct { + + // The Availability Domain of an instance. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the console history metadata object. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the instance this console history was fetched from. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // The current state of the console history. + LifecycleState ConsoleHistoryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The date and time the history was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // Example: `My console history metadata` + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m ConsoleHistory) String() string { + return common.PointerString(m) +} + +// ConsoleHistoryLifecycleStateEnum Enum with underlying type: string +type ConsoleHistoryLifecycleStateEnum string + +// Set of constants representing the allowable values for ConsoleHistoryLifecycleState +const ( + ConsoleHistoryLifecycleStateRequested ConsoleHistoryLifecycleStateEnum = "REQUESTED" + ConsoleHistoryLifecycleStateGettingHistory ConsoleHistoryLifecycleStateEnum = "GETTING-HISTORY" + ConsoleHistoryLifecycleStateSucceeded ConsoleHistoryLifecycleStateEnum = "SUCCEEDED" + ConsoleHistoryLifecycleStateFailed ConsoleHistoryLifecycleStateEnum = "FAILED" +) + +var mappingConsoleHistoryLifecycleState = map[string]ConsoleHistoryLifecycleStateEnum{ + "REQUESTED": ConsoleHistoryLifecycleStateRequested, + "GETTING-HISTORY": ConsoleHistoryLifecycleStateGettingHistory, + "SUCCEEDED": ConsoleHistoryLifecycleStateSucceeded, + "FAILED": ConsoleHistoryLifecycleStateFailed, +} + +// GetConsoleHistoryLifecycleStateEnumValues Enumerates the set of values for ConsoleHistoryLifecycleState +func GetConsoleHistoryLifecycleStateEnumValues() []ConsoleHistoryLifecycleStateEnum { + values := make([]ConsoleHistoryLifecycleStateEnum, 0) + for _, v := range mappingConsoleHistoryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/core_blockstorage_client.go b/vendor/github.com/oracle/oci-go-sdk/core/core_blockstorage_client.go new file mode 100644 index 000000000..4b49fcaff --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/core_blockstorage_client.go @@ -0,0 +1,334 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//BlockstorageClient a client for Blockstorage +type BlockstorageClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewBlockstorageClientWithConfigurationProvider Creates a new default Blockstorage client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewBlockstorageClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client BlockstorageClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = BlockstorageClient{BaseClient: baseClient} + client.BasePath = "20160918" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *BlockstorageClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "iaas", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *BlockstorageClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *BlockstorageClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// CreateVolume Creates a new volume in the specified compartment. Volumes can be created in sizes ranging from +// 50 GB (51200 MB) to 16 TB (16777216 MB), in 1 GB (1024 MB) increments. By default, volumes are 1 TB (1048576 MB). +// For general information about block volumes, see +// Overview of Block Volume Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/overview.htm). +// A volume and instance can be in separate compartments but must be in the same Availability Domain. +// For information about access control and compartments, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about +// Availability Domains, see Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +// To get a list of Availability Domains, use the `ListAvailabilityDomains` operation +// in the Identity and Access Management Service API. +// You may optionally specify a *display name* for the volume, which is simply a friendly name or +// description. It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client BlockstorageClient) CreateVolume(ctx context.Context, request CreateVolumeRequest) (response CreateVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/volumes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateVolumeBackup Creates a new backup of the specified volume. For general information about volume backups, +// see Overview of Block Volume Service Backups (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/blockvolumebackups.htm) +// When the request is received, the backup object is in a REQUEST_RECEIVED state. +// When the data is imaged, it goes into a CREATING state. +// After the backup is fully uploaded to the cloud, it goes into an AVAILABLE state. +func (client BlockstorageClient) CreateVolumeBackup(ctx context.Context, request CreateVolumeBackupRequest) (response CreateVolumeBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/volumeBackups", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteBootVolume Deletes the specified boot volume. The volume cannot have an active connection to an instance. +// To disconnect the boot volume from a connected instance, see +// Disconnecting From a Boot Volume (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Tasks/deletingbootvolume.htm). +// **Warning:** All data on the boot volume will be permanently lost when the boot volume is deleted. +func (client BlockstorageClient) DeleteBootVolume(ctx context.Context, request DeleteBootVolumeRequest) (response DeleteBootVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/bootVolumes/{bootVolumeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteVolume Deletes the specified volume. The volume cannot have an active connection to an instance. +// To disconnect the volume from a connected instance, see +// Disconnecting From a Volume (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Tasks/disconnectingfromavolume.htm). +// **Warning:** All data on the volume will be permanently lost when the volume is deleted. +func (client BlockstorageClient) DeleteVolume(ctx context.Context, request DeleteVolumeRequest) (response DeleteVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/volumes/{volumeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteVolumeBackup Deletes a volume backup. +func (client BlockstorageClient) DeleteVolumeBackup(ctx context.Context, request DeleteVolumeBackupRequest) (response DeleteVolumeBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/volumeBackups/{volumeBackupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBootVolume Gets information for the specified boot volume. +func (client BlockstorageClient) GetBootVolume(ctx context.Context, request GetBootVolumeRequest) (response GetBootVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/bootVolumes/{bootVolumeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVolume Gets information for the specified volume. +func (client BlockstorageClient) GetVolume(ctx context.Context, request GetVolumeRequest) (response GetVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/volumes/{volumeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVolumeBackup Gets information for the specified volume backup. +func (client BlockstorageClient) GetVolumeBackup(ctx context.Context, request GetVolumeBackupRequest) (response GetVolumeBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/volumeBackups/{volumeBackupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListBootVolumes Lists the boot volumes in the specified compartment and Availability Domain. +func (client BlockstorageClient) ListBootVolumes(ctx context.Context, request ListBootVolumesRequest) (response ListBootVolumesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/bootVolumes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVolumeBackups Lists the volume backups in the specified compartment. You can filter the results by volume. +func (client BlockstorageClient) ListVolumeBackups(ctx context.Context, request ListVolumeBackupsRequest) (response ListVolumeBackupsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/volumeBackups", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVolumes Lists the volumes in the specified compartment and Availability Domain. +func (client BlockstorageClient) ListVolumes(ctx context.Context, request ListVolumesRequest) (response ListVolumesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/volumes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateBootVolume Updates the specified boot volume's display name. +func (client BlockstorageClient) UpdateBootVolume(ctx context.Context, request UpdateBootVolumeRequest) (response UpdateBootVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/bootVolumes/{bootVolumeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateVolume Updates the specified volume's display name. +// Avoid entering confidential information. +func (client BlockstorageClient) UpdateVolume(ctx context.Context, request UpdateVolumeRequest) (response UpdateVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/volumes/{volumeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateVolumeBackup Updates the display name for the specified volume backup. +// Avoid entering confidential information. +func (client BlockstorageClient) UpdateVolumeBackup(ctx context.Context, request UpdateVolumeBackupRequest) (response UpdateVolumeBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/volumeBackups/{volumeBackupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/core_compute_client.go b/vendor/github.com/oracle/oci-go-sdk/core/core_compute_client.go new file mode 100644 index 000000000..34b17d7b9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/core_compute_client.go @@ -0,0 +1,833 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//ComputeClient a client for Compute +type ComputeClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewComputeClientWithConfigurationProvider Creates a new default Compute client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewComputeClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client ComputeClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = ComputeClient{BaseClient: baseClient} + client.BasePath = "20160918" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *ComputeClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "iaas", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *ComputeClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *ComputeClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// AttachBootVolume Attaches the specified boot volume to the specified instance. +func (client ComputeClient) AttachBootVolume(ctx context.Context, request AttachBootVolumeRequest) (response AttachBootVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/bootVolumeAttachments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// AttachVnic Creates a secondary VNIC and attaches it to the specified instance. +// For more information about secondary VNICs, see +// Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). +func (client ComputeClient) AttachVnic(ctx context.Context, request AttachVnicRequest) (response AttachVnicResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/vnicAttachments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// AttachVolume Attaches the specified storage volume to the specified instance. +func (client ComputeClient) AttachVolume(ctx context.Context, request AttachVolumeRequest) (response AttachVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/volumeAttachments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &volumeattachment{}) + return +} + +// CaptureConsoleHistory Captures the most recent serial console data (up to a megabyte) for the +// specified instance. +// The `CaptureConsoleHistory` operation works with the other console history operations +// as described below. +// 1. Use `CaptureConsoleHistory` to request the capture of up to a megabyte of the +// most recent console history. This call returns a `ConsoleHistory` +// object. The object will have a state of REQUESTED. +// 2. Wait for the capture operation to succeed by polling `GetConsoleHistory` with +// the identifier of the console history metadata. The state of the +// `ConsoleHistory` object will go from REQUESTED to GETTING-HISTORY and +// then SUCCEEDED (or FAILED). +// 3. Use `GetConsoleHistoryContent` to get the actual console history data (not the +// metadata). +// 4. Optionally, use `DeleteConsoleHistory` to delete the console history metadata +// and the console history data. +func (client ComputeClient) CaptureConsoleHistory(ctx context.Context, request CaptureConsoleHistoryRequest) (response CaptureConsoleHistoryResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/instanceConsoleHistories/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateImage Creates a boot disk image for the specified instance or imports an exported image from the Oracle Cloud Infrastructure Object Storage service. +// When creating a new image, you must provide the OCID of the instance you want to use as the basis for the image, and +// the OCID of the compartment containing that instance. For more information about images, +// see Managing Custom Images (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/managingcustomimages.htm). +// When importing an exported image from Object Storage, you specify the source information +// in ImageSourceDetails. +// When importing an image based on the namespace, bucket name, and object name, +// use ImageSourceViaObjectStorageTupleDetails. +// When importing an image based on the Object Storage URL, use +// ImageSourceViaObjectStorageUriDetails. +// See Object Storage URLs (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/imageimportexport.htm#URLs) and pre-authenticated requests (https://docs.us-phoenix-1.oraclecloud.com/Content/Object/Tasks/managingaccess.htm#pre-auth) +// for constructing URLs for image import/export. +// For more information about importing exported images, see +// Image Import/Export (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/imageimportexport.htm). +// You may optionally specify a *display name* for the image, which is simply a friendly name or description. +// It does not have to be unique, and you can change it. See UpdateImage. +// Avoid entering confidential information. +func (client ComputeClient) CreateImage(ctx context.Context, request CreateImageRequest) (response CreateImageResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/images/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateInstanceConsoleConnection Creates a new console connection to the specified instance. +// Once the console connection has been created and is available, +// you connect to the console using SSH. +// For more information about console access, see Accessing the Console (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/serialconsole.htm). +func (client ComputeClient) CreateInstanceConsoleConnection(ctx context.Context, request CreateInstanceConsoleConnectionRequest) (response CreateInstanceConsoleConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/instanceConsoleConnections", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteConsoleHistory Deletes the specified console history metadata and the console history data. +func (client ComputeClient) DeleteConsoleHistory(ctx context.Context, request DeleteConsoleHistoryRequest) (response DeleteConsoleHistoryResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/instanceConsoleHistories/{instanceConsoleHistoryId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteImage Deletes an image. +func (client ComputeClient) DeleteImage(ctx context.Context, request DeleteImageRequest) (response DeleteImageResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/images/{imageId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteInstanceConsoleConnection Deletes the specified instance console connection. +func (client ComputeClient) DeleteInstanceConsoleConnection(ctx context.Context, request DeleteInstanceConsoleConnectionRequest) (response DeleteInstanceConsoleConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/instanceConsoleConnections/{instanceConsoleConnectionId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DetachBootVolume Detaches a boot volume from an instance. You must specify the OCID of the boot volume attachment. +// This is an asynchronous operation. The attachment's `lifecycleState` will change to DETACHING temporarily +// until the attachment is completely removed. +func (client ComputeClient) DetachBootVolume(ctx context.Context, request DetachBootVolumeRequest) (response DetachBootVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/bootVolumeAttachments/{bootVolumeAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DetachVnic Detaches and deletes the specified secondary VNIC. +// This operation cannot be used on the instance's primary VNIC. +// When you terminate an instance, all attached VNICs (primary +// and secondary) are automatically detached and deleted. +// **Important:** If the VNIC has a +// PrivateIp that is the +// target of a route rule (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm#privateip), +// deleting the VNIC causes that route rule to blackhole and the traffic +// will be dropped. +func (client ComputeClient) DetachVnic(ctx context.Context, request DetachVnicRequest) (response DetachVnicResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/vnicAttachments/{vnicAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DetachVolume Detaches a storage volume from an instance. You must specify the OCID of the volume attachment. +// This is an asynchronous operation. The attachment's `lifecycleState` will change to DETACHING temporarily +// until the attachment is completely removed. +func (client ComputeClient) DetachVolume(ctx context.Context, request DetachVolumeRequest) (response DetachVolumeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/volumeAttachments/{volumeAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ExportImage Exports the specified image to the Oracle Cloud Infrastructure Object Storage service. You can use the Object Storage URL, +// or the namespace, bucket name, and object name when specifying the location to export to. +// For more information about exporting images, see Image Import/Export (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/imageimportexport.htm). +// To perform an image export, you need write access to the Object Storage bucket for the image, +// see Let Users Write Objects to Object Storage Buckets (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm#Let4). +// See Object Storage URLs (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/imageimportexport.htm#URLs) and pre-authenticated requests (https://docs.us-phoenix-1.oraclecloud.com/Content/Object/Tasks/managingaccess.htm#pre-auth) +// for constructing URLs for image import/export. +func (client ComputeClient) ExportImage(ctx context.Context, request ExportImageRequest) (response ExportImageResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/images/{imageId}/actions/export", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBootVolumeAttachment Gets information about the specified boot volume attachment. +func (client ComputeClient) GetBootVolumeAttachment(ctx context.Context, request GetBootVolumeAttachmentRequest) (response GetBootVolumeAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/bootVolumeAttachments/{bootVolumeAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetConsoleHistory Shows the metadata for the specified console history. +// See CaptureConsoleHistory +// for details about using the console history operations. +func (client ComputeClient) GetConsoleHistory(ctx context.Context, request GetConsoleHistoryRequest) (response GetConsoleHistoryResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instanceConsoleHistories/{instanceConsoleHistoryId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetConsoleHistoryContent Gets the actual console history data (not the metadata). +// See CaptureConsoleHistory +// for details about using the console history operations. +func (client ComputeClient) GetConsoleHistoryContent(ctx context.Context, request GetConsoleHistoryContentRequest) (response GetConsoleHistoryContentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instanceConsoleHistories/{instanceConsoleHistoryId}/data", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetImage Gets the specified image. +func (client ComputeClient) GetImage(ctx context.Context, request GetImageRequest) (response GetImageResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/images/{imageId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetInstance Gets information about the specified instance. +func (client ComputeClient) GetInstance(ctx context.Context, request GetInstanceRequest) (response GetInstanceResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instances/{instanceId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetInstanceConsoleConnection Gets the specified instance console connection's information. +func (client ComputeClient) GetInstanceConsoleConnection(ctx context.Context, request GetInstanceConsoleConnectionRequest) (response GetInstanceConsoleConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instanceConsoleConnections/{instanceConsoleConnectionId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVnicAttachment Gets the information for the specified VNIC attachment. +func (client ComputeClient) GetVnicAttachment(ctx context.Context, request GetVnicAttachmentRequest) (response GetVnicAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/vnicAttachments/{vnicAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVolumeAttachment Gets information about the specified volume attachment. +func (client ComputeClient) GetVolumeAttachment(ctx context.Context, request GetVolumeAttachmentRequest) (response GetVolumeAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/volumeAttachments/{volumeAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &volumeattachment{}) + return +} + +// GetWindowsInstanceInitialCredentials Gets the generated credentials for the instance. Only works for Windows instances. The returned credentials +// are only valid for the initial login. +func (client ComputeClient) GetWindowsInstanceInitialCredentials(ctx context.Context, request GetWindowsInstanceInitialCredentialsRequest) (response GetWindowsInstanceInitialCredentialsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instances/{instanceId}/initialCredentials", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// InstanceAction Performs one of the power actions (start, stop, softreset, or reset) +// on the specified instance. +// **start** - power on +// **stop** - power off +// **softreset** - ACPI shutdown and power on +// **reset** - power off and power on +// Note that the **stop** state has no effect on the resources you consume. +// Billing continues for instances that you stop, and related resources continue +// to apply against any relevant quotas. You must terminate an instance +// (TerminateInstance) +// to remove its resources from billing and quotas. +func (client ComputeClient) InstanceAction(ctx context.Context, request InstanceActionRequest) (response InstanceActionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/instances/{instanceId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// LaunchInstance Creates a new instance in the specified compartment and the specified Availability Domain. +// For general information about instances, see +// Overview of the Compute Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Concepts/computeoverview.htm). +// For information about access control and compartments, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about Availability Domains, see +// Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +// To get a list of Availability Domains, use the `ListAvailabilityDomains` operation +// in the Identity and Access Management Service API. +// All Oracle Cloud Infrastructure resources, including instances, get an Oracle-assigned, +// unique ID called an Oracle Cloud Identifier (OCID). +// When you create a resource, you can find its OCID in the response. You can +// also retrieve a resource's OCID by using a List API operation +// on that resource type, or by viewing the resource in the Console. +// When you launch an instance, it is automatically attached to a virtual +// network interface card (VNIC), called the *primary VNIC*. The VNIC +// has a private IP address from the subnet's CIDR. You can either assign a +// private IP address of your choice or let Oracle automatically assign one. +// You can choose whether the instance has a public IP address. To retrieve the +// addresses, use the ListVnicAttachments +// operation to get the VNIC ID for the instance, and then call +// GetVnic with the VNIC ID. +// You can later add secondary VNICs to an instance. For more information, see +// Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). +func (client ComputeClient) LaunchInstance(ctx context.Context, request LaunchInstanceRequest) (response LaunchInstanceResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/instances/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListBootVolumeAttachments Lists the boot volume attachments in the specified compartment. You can filter the +// list by specifying an instance OCID, boot volume OCID, or both. +func (client ComputeClient) ListBootVolumeAttachments(ctx context.Context, request ListBootVolumeAttachmentsRequest) (response ListBootVolumeAttachmentsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/bootVolumeAttachments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListConsoleHistories Lists the console history metadata for the specified compartment or instance. +func (client ComputeClient) ListConsoleHistories(ctx context.Context, request ListConsoleHistoriesRequest) (response ListConsoleHistoriesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instanceConsoleHistories/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListImages Lists the available images in the specified compartment. +// If you specify a value for the `sortBy` parameter, Oracle-provided images appear first in the list, followed by custom images. +// For more +// information about images, see +// Managing Custom Images (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/managingcustomimages.htm). +func (client ComputeClient) ListImages(ctx context.Context, request ListImagesRequest) (response ListImagesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/images/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListInstanceConsoleConnections Lists the console connections for the specified compartment or instance. +// For more information about console access, see Accessing the Instance Console (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/serialconsole.htm). +func (client ComputeClient) ListInstanceConsoleConnections(ctx context.Context, request ListInstanceConsoleConnectionsRequest) (response ListInstanceConsoleConnectionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instanceConsoleConnections", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListInstances Lists the instances in the specified compartment and the specified Availability Domain. +// You can filter the results by specifying an instance name (the list will include all the identically-named +// instances in the compartment). +func (client ComputeClient) ListInstances(ctx context.Context, request ListInstancesRequest) (response ListInstancesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/instances/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListShapes Lists the shapes that can be used to launch an instance within the specified compartment. You can +// filter the list by compatibility with a specific image. +func (client ComputeClient) ListShapes(ctx context.Context, request ListShapesRequest) (response ListShapesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/shapes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVnicAttachments Lists the VNIC attachments in the specified compartment. A VNIC attachment +// resides in the same compartment as the attached instance. The list can be +// filtered by instance, VNIC, or Availability Domain. +func (client ComputeClient) ListVnicAttachments(ctx context.Context, request ListVnicAttachmentsRequest) (response ListVnicAttachmentsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/vnicAttachments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +//listvolumeattachment allows to unmarshal list of polymorphic VolumeAttachment +type listvolumeattachment []volumeattachment + +//UnmarshalPolymorphicJSON unmarshals polymorphic json list of items +func (m *listvolumeattachment) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + res := make([]VolumeAttachment, len(*m)) + for i, v := range *m { + nn, err := v.UnmarshalPolymorphicJSON(v.JsonData) + if err != nil { + return nil, err + } + res[i] = nn.(VolumeAttachment) + } + return res, nil +} + +// ListVolumeAttachments Lists the volume attachments in the specified compartment. You can filter the +// list by specifying an instance OCID, volume OCID, or both. +// Currently, the only supported volume attachment type is IScsiVolumeAttachment. +func (client ComputeClient) ListVolumeAttachments(ctx context.Context, request ListVolumeAttachmentsRequest) (response ListVolumeAttachmentsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/volumeAttachments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &listvolumeattachment{}) + return +} + +// TerminateInstance Terminates the specified instance. Any attached VNICs and volumes are automatically detached +// when the instance terminates. +// To preserve the boot volume associated with the instance, specify `true` for `PreserveBootVolumeQueryParam`. +// To delete the boot volume when the instance is deleted, specify `false` or do not specify a value for `PreserveBootVolumeQueryParam`. +// This is an asynchronous operation. The instance's `lifecycleState` will change to TERMINATING temporarily +// until the instance is completely removed. +func (client ComputeClient) TerminateInstance(ctx context.Context, request TerminateInstanceRequest) (response TerminateInstanceResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/instances/{instanceId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateConsoleHistory Updates the specified console history metadata. +func (client ComputeClient) UpdateConsoleHistory(ctx context.Context, request UpdateConsoleHistoryRequest) (response UpdateConsoleHistoryResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/instanceConsoleHistories/{instanceConsoleHistoryId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateImage Updates the display name of the image. Avoid entering confidential information. +func (client ComputeClient) UpdateImage(ctx context.Context, request UpdateImageRequest) (response UpdateImageResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/images/{imageId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateInstance Updates the display name of the specified instance. Avoid entering confidential information. +// The OCID of the instance remains the same. +func (client ComputeClient) UpdateInstance(ctx context.Context, request UpdateInstanceRequest) (response UpdateInstanceResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/instances/{instanceId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/core_virtualnetwork_client.go b/vendor/github.com/oracle/oci-go-sdk/core/core_virtualnetwork_client.go new file mode 100644 index 000000000..2888effff --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/core_virtualnetwork_client.go @@ -0,0 +1,2009 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//VirtualNetworkClient a client for VirtualNetwork +type VirtualNetworkClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewVirtualNetworkClientWithConfigurationProvider Creates a new default VirtualNetwork client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewVirtualNetworkClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client VirtualNetworkClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = VirtualNetworkClient{BaseClient: baseClient} + client.BasePath = "20160918" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *VirtualNetworkClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "iaas", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *VirtualNetworkClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *VirtualNetworkClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// BulkAddVirtualCircuitPublicPrefixes Adds one or more customer public IP prefixes to the specified public virtual circuit. +// Use this operation (and not UpdateVirtualCircuit) +// to add prefixes to the virtual circuit. Oracle must verify the customer's ownership +// of each prefix before traffic for that prefix will flow across the virtual circuit. +func (client VirtualNetworkClient) BulkAddVirtualCircuitPublicPrefixes(ctx context.Context, request BulkAddVirtualCircuitPublicPrefixesRequest) (err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/virtualCircuits/{virtualCircuitId}/actions/bulkAddPublicPrefixes", request) + if err != nil { + return + } + + _, err = client.Call(ctx, &httpRequest) + return +} + +// BulkDeleteVirtualCircuitPublicPrefixes Removes one or more customer public IP prefixes from the specified public virtual circuit. +// Use this operation (and not UpdateVirtualCircuit) +// to remove prefixes from the virtual circuit. When the virtual circuit's state switches +// back to PROVISIONED, Oracle stops advertising the specified prefixes across the connection. +func (client VirtualNetworkClient) BulkDeleteVirtualCircuitPublicPrefixes(ctx context.Context, request BulkDeleteVirtualCircuitPublicPrefixesRequest) (err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/virtualCircuits/{virtualCircuitId}/actions/bulkDeletePublicPrefixes", request) + if err != nil { + return + } + + _, err = client.Call(ctx, &httpRequest) + return +} + +// ConnectLocalPeeringGateways Connects this local peering gateway (LPG) to another one in the same region. +// This operation must be called by the VCN administrator who is designated as +// the *requestor* in the peering relationship. The *acceptor* must implement +// an Identity and Access Management (IAM) policy that gives the requestor permission +// to connect to LPGs in the acceptor's compartment. Without that permission, this +// operation will fail. For more information, see +// VCN Peering (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/VCNpeering.htm). +func (client VirtualNetworkClient) ConnectLocalPeeringGateways(ctx context.Context, request ConnectLocalPeeringGatewaysRequest) (response ConnectLocalPeeringGatewaysResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/localPeeringGateways/{localPeeringGatewayId}/actions/connect", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateCpe Creates a new virtual Customer-Premises Equipment (CPE) object in the specified compartment. For +// more information, see IPSec VPNs (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPsec.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want +// the CPE to reside. Notice that the CPE doesn't have to be in the same compartment as the IPSec +// connection or other Networking Service components. If you're not sure which compartment to +// use, put the CPE in the same compartment as the DRG. For more information about +// compartments and access control, see Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about OCIDs, see Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You must provide the public IP address of your on-premises router. See +// Configuring Your On-Premises Router for an IPSec VPN (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/configuringCPE.htm). +// You may optionally specify a *display name* for the CPE, otherwise a default is provided. It does not have to +// be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateCpe(ctx context.Context, request CreateCpeRequest) (response CreateCpeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/cpes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateCrossConnect Creates a new cross-connect. Oracle recommends you create each cross-connect in a +// CrossConnectGroup so you can use link aggregation +// with the connection. +// After creating the `CrossConnect` object, you need to go the FastConnect location +// and request to have the physical cable installed. For more information, see +// FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// For the purposes of access control, you must provide the OCID of the +// compartment where you want the cross-connect to reside. If you're +// not sure which compartment to use, put the cross-connect in the +// same compartment with your VCN. For more information about +// compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the cross-connect. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateCrossConnect(ctx context.Context, request CreateCrossConnectRequest) (response CreateCrossConnectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/crossConnects", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateCrossConnectGroup Creates a new cross-connect group to use with Oracle Cloud Infrastructure +// FastConnect. For more information, see +// FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// For the purposes of access control, you must provide the OCID of the +// compartment where you want the cross-connect group to reside. If you're +// not sure which compartment to use, put the cross-connect group in the +// same compartment with your VCN. For more information about +// compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the cross-connect group. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateCrossConnectGroup(ctx context.Context, request CreateCrossConnectGroupRequest) (response CreateCrossConnectGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/crossConnectGroups", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateDhcpOptions Creates a new set of DHCP options for the specified VCN. For more information, see +// DhcpOptions. +// For the purposes of access control, you must provide the OCID of the compartment where you want the set of +// DHCP options to reside. Notice that the set of options doesn't have to be in the same compartment as the VCN, +// subnets, or other Networking Service components. If you're not sure which compartment to use, put the set +// of DHCP options in the same compartment as the VCN. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the set of DHCP options, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateDhcpOptions(ctx context.Context, request CreateDhcpOptionsRequest) (response CreateDhcpOptionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/dhcps", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateDrg Creates a new Dynamic Routing Gateway (DRG) in the specified compartment. For more information, +// see Dynamic Routing Gateways (DRGs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDRGs.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want +// the DRG to reside. Notice that the DRG doesn't have to be in the same compartment as the VCN, +// the DRG attachment, or other Networking Service components. If you're not sure which compartment +// to use, put the DRG in the same compartment as the VCN. For more information about compartments +// and access control, see Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about OCIDs, see Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the DRG, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateDrg(ctx context.Context, request CreateDrgRequest) (response CreateDrgResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/drgs", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateDrgAttachment Attaches the specified DRG to the specified VCN. A VCN can be attached to only one DRG at a time, +// and vice versa. The response includes a `DrgAttachment` object with its own OCID. For more +// information about DRGs, see +// Dynamic Routing Gateways (DRGs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDRGs.htm). +// You may optionally specify a *display name* for the attachment, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +// For the purposes of access control, the DRG attachment is automatically placed into the same compartment +// as the VCN. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +func (client VirtualNetworkClient) CreateDrgAttachment(ctx context.Context, request CreateDrgAttachmentRequest) (response CreateDrgAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/drgAttachments", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateIPSecConnection Creates a new IPSec connection between the specified DRG and CPE. For more information, see +// IPSec VPNs (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPsec.htm). +// In the request, you must include at least one static route to the CPE object (you're allowed a maximum +// of 10). For example: 10.0.8.0/16. +// For the purposes of access control, you must provide the OCID of the compartment where you want the +// IPSec connection to reside. Notice that the IPSec connection doesn't have to be in the same compartment +// as the DRG, CPE, or other Networking Service components. If you're not sure which compartment to +// use, put the IPSec connection in the same compartment as the DRG. For more information about +// compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about OCIDs, see Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the IPSec connection, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +// After creating the IPSec connection, you need to configure your on-premises router +// with tunnel-specific information returned by +// GetIPSecConnectionDeviceConfig. +// For each tunnel, that operation gives you the IP address of Oracle's VPN headend and the shared secret +// (that is, the pre-shared key). For more information, see +// Configuring Your On-Premises Router for an IPSec VPN (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/configuringCPE.htm). +// To get the status of the tunnels (whether they're up or down), use +// GetIPSecConnectionDeviceStatus. +func (client VirtualNetworkClient) CreateIPSecConnection(ctx context.Context, request CreateIPSecConnectionRequest) (response CreateIPSecConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/ipsecConnections", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateInternetGateway Creates a new Internet Gateway for the specified VCN. For more information, see +// Connectivity to the Internet (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIGs.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want the Internet +// Gateway to reside. Notice that the Internet Gateway doesn't have to be in the same compartment as the VCN or +// other Networking Service components. If you're not sure which compartment to use, put the Internet +// Gateway in the same compartment with the VCN. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the Internet Gateway, otherwise a default is provided. It +// does not have to be unique, and you can change it. Avoid entering confidential information. +// For traffic to flow between a subnet and an Internet Gateway, you must create a route rule accordingly in +// the subnet's route table (for example, 0.0.0.0/0 > Internet Gateway). See +// UpdateRouteTable. +// You must specify whether the Internet Gateway is enabled when you create it. If it's disabled, that means no +// traffic will flow to/from the internet even if there's a route rule that enables that traffic. You can later +// use UpdateInternetGateway to easily disable/enable +// the gateway without changing the route rule. +func (client VirtualNetworkClient) CreateInternetGateway(ctx context.Context, request CreateInternetGatewayRequest) (response CreateInternetGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/internetGateways", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateLocalPeeringGateway Creates a new local peering gateway (LPG) for the specified VCN. +func (client VirtualNetworkClient) CreateLocalPeeringGateway(ctx context.Context, request CreateLocalPeeringGatewayRequest) (response CreateLocalPeeringGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/localPeeringGateways", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreatePrivateIp Creates a secondary private IP for the specified VNIC. +// For more information about secondary private IPs, see +// IP Addresses (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPaddresses.htm). +func (client VirtualNetworkClient) CreatePrivateIp(ctx context.Context, request CreatePrivateIpRequest) (response CreatePrivateIpResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/privateIps", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateRouteTable Creates a new route table for the specified VCN. In the request you must also include at least one route +// rule for the new route table. For information on the number of rules you can have in a route table, see +// Service Limits (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/servicelimits.htm). For general information about route +// tables in your VCN and the types of targets you can use in route rules, +// see Route Tables (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want the route +// table to reside. Notice that the route table doesn't have to be in the same compartment as the VCN, subnets, +// or other Networking Service components. If you're not sure which compartment to use, put the route +// table in the same compartment as the VCN. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the route table, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateRouteTable(ctx context.Context, request CreateRouteTableRequest) (response CreateRouteTableResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/routeTables", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateSecurityList Creates a new security list for the specified VCN. For more information +// about security lists, see Security Lists (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm). +// For information on the number of rules you can have in a security list, see +// Service Limits (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/servicelimits.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want the security +// list to reside. Notice that the security list doesn't have to be in the same compartment as the VCN, subnets, +// or other Networking Service components. If you're not sure which compartment to use, put the security +// list in the same compartment as the VCN. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the security list, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +func (client VirtualNetworkClient) CreateSecurityList(ctx context.Context, request CreateSecurityListRequest) (response CreateSecurityListResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/securityLists", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateSubnet Creates a new subnet in the specified VCN. You can't change the size of the subnet after creation, +// so it's important to think about the size of subnets you need before creating them. +// For more information, see VCNs and Subnets (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVCNs.htm). +// For information on the number of subnets you can have in a VCN, see +// Service Limits (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/servicelimits.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want the subnet +// to reside. Notice that the subnet doesn't have to be in the same compartment as the VCN, route tables, or +// other Networking Service components. If you're not sure which compartment to use, put the subnet in +// the same compartment as the VCN. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about OCIDs, +// see Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally associate a route table with the subnet. If you don't, the subnet will use the +// VCN's default route table. For more information about route tables, see +// Route Tables (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm). +// You may optionally associate a security list with the subnet. If you don't, the subnet will use the +// VCN's default security list. For more information about security lists, see +// Security Lists (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm). +// You may optionally associate a set of DHCP options with the subnet. If you don't, the subnet will use the +// VCN's default set. For more information about DHCP options, see +// DHCP Options (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDHCP.htm). +// You may optionally specify a *display name* for the subnet, otherwise a default is provided. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +// You can also add a DNS label for the subnet, which is required if you want the Internet and +// VCN Resolver to resolve hostnames for instances in the subnet. For more information, see +// DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). +func (client VirtualNetworkClient) CreateSubnet(ctx context.Context, request CreateSubnetRequest) (response CreateSubnetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/subnets", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateVcn Creates a new Virtual Cloud Network (VCN). For more information, see +// VCNs and Subnets (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVCNs.htm). +// For the VCN you must specify a single, contiguous IPv4 CIDR block. Oracle recommends using one of the +// private IP address ranges specified in RFC 1918 (https://tools.ietf.org/html/rfc1918) (10.0.0.0/8, +// 172.16/12, and 192.168/16). Example: 172.16.0.0/16. The CIDR block can range from /16 to /30, and it +// must not overlap with your on-premises network. You can't change the size of the VCN after creation. +// For the purposes of access control, you must provide the OCID of the compartment where you want the VCN to +// reside. Consult an Oracle Cloud Infrastructure administrator in your organization if you're not sure which +// compartment to use. Notice that the VCN doesn't have to be in the same compartment as the subnets or other +// Networking Service components. For more information about compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the VCN, otherwise a default is provided. It does not have to +// be unique, and you can change it. Avoid entering confidential information. +// You can also add a DNS label for the VCN, which is required if you want the instances to use the +// Interent and VCN Resolver option for DNS in the VCN. For more information, see +// DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). +// The VCN automatically comes with a default route table, default security list, and default set of DHCP options. +// The OCID for each is returned in the response. You can't delete these default objects, but you can change their +// contents (that is, change the route rules, security list rules, and so on). +// The VCN and subnets you create are not accessible until you attach an Internet Gateway or set up an IPSec VPN +// or FastConnect. For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +func (client VirtualNetworkClient) CreateVcn(ctx context.Context, request CreateVcnRequest) (response CreateVcnResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/vcns", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateVirtualCircuit Creates a new virtual circuit to use with Oracle Cloud +// Infrastructure FastConnect. For more information, see +// FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// For the purposes of access control, you must provide the OCID of the +// compartment where you want the virtual circuit to reside. If you're +// not sure which compartment to use, put the virtual circuit in the +// same compartment with the DRG it's using. For more information about +// compartments and access control, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You may optionally specify a *display name* for the virtual circuit. +// It does not have to be unique, and you can change it. Avoid entering confidential information. +// **Important:** When creating a virtual circuit, you specify a DRG for +// the traffic to flow through. Make sure you attach the DRG to your +// VCN and confirm the VCN's routing sends traffic to the DRG. Otherwise +// traffic will not flow. For more information, see +// Route Tables (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm). +func (client VirtualNetworkClient) CreateVirtualCircuit(ctx context.Context, request CreateVirtualCircuitRequest) (response CreateVirtualCircuitResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/virtualCircuits", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteCpe Deletes the specified CPE object. The CPE must not be connected to a DRG. This is an asynchronous +// operation. The CPE's `lifecycleState` will change to TERMINATING temporarily until the CPE is completely +// removed. +func (client VirtualNetworkClient) DeleteCpe(ctx context.Context, request DeleteCpeRequest) (response DeleteCpeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/cpes/{cpeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteCrossConnect Deletes the specified cross-connect. It must not be mapped to a +// VirtualCircuit. +func (client VirtualNetworkClient) DeleteCrossConnect(ctx context.Context, request DeleteCrossConnectRequest) (response DeleteCrossConnectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/crossConnects/{crossConnectId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteCrossConnectGroup Deletes the specified cross-connect group. It must not contain any +// cross-connects, and it cannot be mapped to a +// VirtualCircuit. +func (client VirtualNetworkClient) DeleteCrossConnectGroup(ctx context.Context, request DeleteCrossConnectGroupRequest) (response DeleteCrossConnectGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/crossConnectGroups/{crossConnectGroupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteDhcpOptions Deletes the specified set of DHCP options, but only if it's not associated with a subnet. You can't delete a +// VCN's default set of DHCP options. +// This is an asynchronous operation. The state of the set of options will switch to TERMINATING temporarily +// until the set is completely removed. +func (client VirtualNetworkClient) DeleteDhcpOptions(ctx context.Context, request DeleteDhcpOptionsRequest) (response DeleteDhcpOptionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/dhcps/{dhcpId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteDrg Deletes the specified DRG. The DRG must not be attached to a VCN or be connected to your on-premise +// network. Also, there must not be a route table that lists the DRG as a target. This is an asynchronous +// operation. The DRG's `lifecycleState` will change to TERMINATING temporarily until the DRG is completely +// removed. +func (client VirtualNetworkClient) DeleteDrg(ctx context.Context, request DeleteDrgRequest) (response DeleteDrgResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/drgs/{drgId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteDrgAttachment Detaches a DRG from a VCN by deleting the corresponding `DrgAttachment`. This is an asynchronous +// operation. The attachment's `lifecycleState` will change to DETACHING temporarily until the attachment +// is completely removed. +func (client VirtualNetworkClient) DeleteDrgAttachment(ctx context.Context, request DeleteDrgAttachmentRequest) (response DeleteDrgAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/drgAttachments/{drgAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteIPSecConnection Deletes the specified IPSec connection. If your goal is to disable the IPSec VPN between your VCN and +// on-premises network, it's easiest to simply detach the DRG but keep all the IPSec VPN components intact. +// If you were to delete all the components and then later need to create an IPSec VPN again, you would +// need to configure your on-premises router again with the new information returned from +// CreateIPSecConnection. +// This is an asynchronous operation. The connection's `lifecycleState` will change to TERMINATING temporarily +// until the connection is completely removed. +func (client VirtualNetworkClient) DeleteIPSecConnection(ctx context.Context, request DeleteIPSecConnectionRequest) (response DeleteIPSecConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/ipsecConnections/{ipscId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteInternetGateway Deletes the specified Internet Gateway. The Internet Gateway does not have to be disabled, but +// there must not be a route table that lists it as a target. +// This is an asynchronous operation. The gateway's `lifecycleState` will change to TERMINATING temporarily +// until the gateway is completely removed. +func (client VirtualNetworkClient) DeleteInternetGateway(ctx context.Context, request DeleteInternetGatewayRequest) (response DeleteInternetGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/internetGateways/{igId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteLocalPeeringGateway Deletes the specified local peering gateway (LPG). +// This is an asynchronous operation; the local peering gateway's `lifecycleState` changes to TERMINATING temporarily +// until the local peering gateway is completely removed. +func (client VirtualNetworkClient) DeleteLocalPeeringGateway(ctx context.Context, request DeleteLocalPeeringGatewayRequest) (response DeleteLocalPeeringGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/localPeeringGateways/{localPeeringGatewayId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeletePrivateIp Unassigns and deletes the specified private IP. You must +// specify the object's OCID. The private IP address is returned to +// the subnet's pool of available addresses. +// This operation cannot be used with primary private IPs, which are +// automatically unassigned and deleted when the VNIC is terminated. +// **Important:** If a secondary private IP is the +// target of a route rule (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm#privateip), +// unassigning it from the VNIC causes that route rule to blackhole and the traffic +// will be dropped. +func (client VirtualNetworkClient) DeletePrivateIp(ctx context.Context, request DeletePrivateIpRequest) (response DeletePrivateIpResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/privateIps/{privateIpId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteRouteTable Deletes the specified route table, but only if it's not associated with a subnet. You can't delete a +// VCN's default route table. +// This is an asynchronous operation. The route table's `lifecycleState` will change to TERMINATING temporarily +// until the route table is completely removed. +func (client VirtualNetworkClient) DeleteRouteTable(ctx context.Context, request DeleteRouteTableRequest) (response DeleteRouteTableResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/routeTables/{rtId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteSecurityList Deletes the specified security list, but only if it's not associated with a subnet. You can't delete +// a VCN's default security list. +// This is an asynchronous operation. The security list's `lifecycleState` will change to TERMINATING temporarily +// until the security list is completely removed. +func (client VirtualNetworkClient) DeleteSecurityList(ctx context.Context, request DeleteSecurityListRequest) (response DeleteSecurityListResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/securityLists/{securityListId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteSubnet Deletes the specified subnet, but only if there are no instances in the subnet. This is an asynchronous +// operation. The subnet's `lifecycleState` will change to TERMINATING temporarily. If there are any +// instances in the subnet, the state will instead change back to AVAILABLE. +func (client VirtualNetworkClient) DeleteSubnet(ctx context.Context, request DeleteSubnetRequest) (response DeleteSubnetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/subnets/{subnetId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteVcn Deletes the specified VCN. The VCN must be empty and have no attached gateways. This is an asynchronous +// operation. The VCN's `lifecycleState` will change to TERMINATING temporarily until the VCN is completely +// removed. +func (client VirtualNetworkClient) DeleteVcn(ctx context.Context, request DeleteVcnRequest) (response DeleteVcnResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/vcns/{vcnId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteVirtualCircuit Deletes the specified virtual circuit. +// **Important:** If you're using FastConnect via a provider, +// make sure to also terminate the connection with +// the provider, or else the provider may continue to bill you. +func (client VirtualNetworkClient) DeleteVirtualCircuit(ctx context.Context, request DeleteVirtualCircuitRequest) (response DeleteVirtualCircuitResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/virtualCircuits/{virtualCircuitId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetCpe Gets the specified CPE's information. +func (client VirtualNetworkClient) GetCpe(ctx context.Context, request GetCpeRequest) (response GetCpeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/cpes/{cpeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetCrossConnect Gets the specified cross-connect's information. +func (client VirtualNetworkClient) GetCrossConnect(ctx context.Context, request GetCrossConnectRequest) (response GetCrossConnectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnects/{crossConnectId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetCrossConnectGroup Gets the specified cross-connect group's information. +func (client VirtualNetworkClient) GetCrossConnectGroup(ctx context.Context, request GetCrossConnectGroupRequest) (response GetCrossConnectGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnectGroups/{crossConnectGroupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetCrossConnectLetterOfAuthority Gets the Letter of Authority for the specified cross-connect. +func (client VirtualNetworkClient) GetCrossConnectLetterOfAuthority(ctx context.Context, request GetCrossConnectLetterOfAuthorityRequest) (response GetCrossConnectLetterOfAuthorityResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnects/{crossConnectId}/letterOfAuthority", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetCrossConnectStatus Gets the status of the specified cross-connect. +func (client VirtualNetworkClient) GetCrossConnectStatus(ctx context.Context, request GetCrossConnectStatusRequest) (response GetCrossConnectStatusResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnects/{crossConnectId}/status", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDhcpOptions Gets the specified set of DHCP options. +func (client VirtualNetworkClient) GetDhcpOptions(ctx context.Context, request GetDhcpOptionsRequest) (response GetDhcpOptionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dhcps/{dhcpId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDrg Gets the specified DRG's information. +func (client VirtualNetworkClient) GetDrg(ctx context.Context, request GetDrgRequest) (response GetDrgResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/drgs/{drgId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDrgAttachment Gets the information for the specified `DrgAttachment`. +func (client VirtualNetworkClient) GetDrgAttachment(ctx context.Context, request GetDrgAttachmentRequest) (response GetDrgAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/drgAttachments/{drgAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetFastConnectProviderService Gets the specified provider service. +// For more information, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +func (client VirtualNetworkClient) GetFastConnectProviderService(ctx context.Context, request GetFastConnectProviderServiceRequest) (response GetFastConnectProviderServiceResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/fastConnectProviderServices/{providerServiceId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetIPSecConnection Gets the specified IPSec connection's basic information, including the static routes for the +// on-premises router. If you want the status of the connection (whether it's up or down), use +// GetIPSecConnectionDeviceStatus. +func (client VirtualNetworkClient) GetIPSecConnection(ctx context.Context, request GetIPSecConnectionRequest) (response GetIPSecConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/ipsecConnections/{ipscId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetIPSecConnectionDeviceConfig Gets the configuration information for the specified IPSec connection. For each tunnel, the +// response includes the IP address of Oracle's VPN headend and the shared secret. +func (client VirtualNetworkClient) GetIPSecConnectionDeviceConfig(ctx context.Context, request GetIPSecConnectionDeviceConfigRequest) (response GetIPSecConnectionDeviceConfigResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/ipsecConnections/{ipscId}/deviceConfig", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetIPSecConnectionDeviceStatus Gets the status of the specified IPSec connection (whether it's up or down). +func (client VirtualNetworkClient) GetIPSecConnectionDeviceStatus(ctx context.Context, request GetIPSecConnectionDeviceStatusRequest) (response GetIPSecConnectionDeviceStatusResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/ipsecConnections/{ipscId}/deviceStatus", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetInternetGateway Gets the specified Internet Gateway's information. +func (client VirtualNetworkClient) GetInternetGateway(ctx context.Context, request GetInternetGatewayRequest) (response GetInternetGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/internetGateways/{igId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetLocalPeeringGateway Gets the specified local peering gateway's information. +func (client VirtualNetworkClient) GetLocalPeeringGateway(ctx context.Context, request GetLocalPeeringGatewayRequest) (response GetLocalPeeringGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/localPeeringGateways/{localPeeringGatewayId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetPrivateIp Gets the specified private IP. You must specify the object's OCID. +// Alternatively, you can get the object by using +// ListPrivateIps +// with the private IP address (for example, 10.0.3.3) and subnet OCID. +func (client VirtualNetworkClient) GetPrivateIp(ctx context.Context, request GetPrivateIpRequest) (response GetPrivateIpResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/privateIps/{privateIpId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetRouteTable Gets the specified route table's information. +func (client VirtualNetworkClient) GetRouteTable(ctx context.Context, request GetRouteTableRequest) (response GetRouteTableResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/routeTables/{rtId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetSecurityList Gets the specified security list's information. +func (client VirtualNetworkClient) GetSecurityList(ctx context.Context, request GetSecurityListRequest) (response GetSecurityListResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/securityLists/{securityListId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetSubnet Gets the specified subnet's information. +func (client VirtualNetworkClient) GetSubnet(ctx context.Context, request GetSubnetRequest) (response GetSubnetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/subnets/{subnetId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVcn Gets the specified VCN's information. +func (client VirtualNetworkClient) GetVcn(ctx context.Context, request GetVcnRequest) (response GetVcnResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/vcns/{vcnId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVirtualCircuit Gets the specified virtual circuit's information. +func (client VirtualNetworkClient) GetVirtualCircuit(ctx context.Context, request GetVirtualCircuitRequest) (response GetVirtualCircuitResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/virtualCircuits/{virtualCircuitId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetVnic Gets the information for the specified virtual network interface card (VNIC). +// You can get the VNIC OCID from the +// ListVnicAttachments +// operation. +func (client VirtualNetworkClient) GetVnic(ctx context.Context, request GetVnicRequest) (response GetVnicResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/vnics/{vnicId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCpes Lists the Customer-Premises Equipment objects (CPEs) in the specified compartment. +func (client VirtualNetworkClient) ListCpes(ctx context.Context, request ListCpesRequest) (response ListCpesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/cpes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCrossConnectGroups Lists the cross-connect groups in the specified compartment. +func (client VirtualNetworkClient) ListCrossConnectGroups(ctx context.Context, request ListCrossConnectGroupsRequest) (response ListCrossConnectGroupsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnectGroups", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCrossConnectLocations Lists the available FastConnect locations for cross-connect installation. You need +// this information so you can specify your desired location when you create a cross-connect. +func (client VirtualNetworkClient) ListCrossConnectLocations(ctx context.Context, request ListCrossConnectLocationsRequest) (response ListCrossConnectLocationsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnectLocations", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCrossConnects Lists the cross-connects in the specified compartment. You can filter the list +// by specifying the OCID of a cross-connect group. +func (client VirtualNetworkClient) ListCrossConnects(ctx context.Context, request ListCrossConnectsRequest) (response ListCrossConnectsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnects", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCrossconnectPortSpeedShapes Lists the available port speeds for cross-connects. You need this information +// so you can specify your desired port speed (that is, shape) when you create a +// cross-connect. +func (client VirtualNetworkClient) ListCrossconnectPortSpeedShapes(ctx context.Context, request ListCrossconnectPortSpeedShapesRequest) (response ListCrossconnectPortSpeedShapesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/crossConnectPortSpeedShapes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDhcpOptions Lists the sets of DHCP options in the specified VCN and specified compartment. +// The response includes the default set of options that automatically comes with each VCN, +// plus any other sets you've created. +func (client VirtualNetworkClient) ListDhcpOptions(ctx context.Context, request ListDhcpOptionsRequest) (response ListDhcpOptionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dhcps", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDrgAttachments Lists the `DrgAttachment` objects for the specified compartment. You can filter the +// results by VCN or DRG. +func (client VirtualNetworkClient) ListDrgAttachments(ctx context.Context, request ListDrgAttachmentsRequest) (response ListDrgAttachmentsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/drgAttachments", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDrgs Lists the DRGs in the specified compartment. +func (client VirtualNetworkClient) ListDrgs(ctx context.Context, request ListDrgsRequest) (response ListDrgsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/drgs", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListFastConnectProviderServices Lists the service offerings from supported providers. You need this +// information so you can specify your desired provider and service +// offering when you create a virtual circuit. +// For the compartment ID, provide the OCID of your tenancy (the root compartment). +// For more information, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +func (client VirtualNetworkClient) ListFastConnectProviderServices(ctx context.Context, request ListFastConnectProviderServicesRequest) (response ListFastConnectProviderServicesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/fastConnectProviderServices", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListFastConnectProviderVirtualCircuitBandwidthShapes Gets the list of available virtual circuit bandwidth levels for a provider. +// You need this information so you can specify your desired bandwidth level (shape) when you create a virtual circuit. +// For more information about virtual circuits, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +func (client VirtualNetworkClient) ListFastConnectProviderVirtualCircuitBandwidthShapes(ctx context.Context, request ListFastConnectProviderVirtualCircuitBandwidthShapesRequest) (response ListFastConnectProviderVirtualCircuitBandwidthShapesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/fastConnectProviderServices/{providerServiceId}/virtualCircuitBandwidthShapes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListIPSecConnections Lists the IPSec connections for the specified compartment. You can filter the +// results by DRG or CPE. +func (client VirtualNetworkClient) ListIPSecConnections(ctx context.Context, request ListIPSecConnectionsRequest) (response ListIPSecConnectionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/ipsecConnections", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListInternetGateways Lists the Internet Gateways in the specified VCN and the specified compartment. +func (client VirtualNetworkClient) ListInternetGateways(ctx context.Context, request ListInternetGatewaysRequest) (response ListInternetGatewaysResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/internetGateways", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListLocalPeeringGateways Lists the local peering gateways (LPGs) for the specified VCN and compartment +// (the LPG's compartment). +func (client VirtualNetworkClient) ListLocalPeeringGateways(ctx context.Context, request ListLocalPeeringGatewaysRequest) (response ListLocalPeeringGatewaysResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/localPeeringGateways", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListPrivateIps Lists the PrivateIp objects based +// on one of these filters: +// - Subnet OCID. +// - VNIC OCID. +// - Both private IP address and subnet OCID: This lets +// you get a `privateIP` object based on its private IP +// address (for example, 10.0.3.3) and not its OCID. For comparison, +// GetPrivateIp +// requires the OCID. +// If you're listing all the private IPs associated with a given subnet +// or VNIC, the response includes both primary and secondary private IPs. +func (client VirtualNetworkClient) ListPrivateIps(ctx context.Context, request ListPrivateIpsRequest) (response ListPrivateIpsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/privateIps", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListRouteTables Lists the route tables in the specified VCN and specified compartment. The response +// includes the default route table that automatically comes with each VCN, plus any route tables +// you've created. +func (client VirtualNetworkClient) ListRouteTables(ctx context.Context, request ListRouteTablesRequest) (response ListRouteTablesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/routeTables", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListSecurityLists Lists the security lists in the specified VCN and compartment. +func (client VirtualNetworkClient) ListSecurityLists(ctx context.Context, request ListSecurityListsRequest) (response ListSecurityListsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/securityLists", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListSubnets Lists the subnets in the specified VCN and the specified compartment. +func (client VirtualNetworkClient) ListSubnets(ctx context.Context, request ListSubnetsRequest) (response ListSubnetsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/subnets", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVcns Lists the Virtual Cloud Networks (VCNs) in the specified compartment. +func (client VirtualNetworkClient) ListVcns(ctx context.Context, request ListVcnsRequest) (response ListVcnsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/vcns", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVirtualCircuitBandwidthShapes The deprecated operation lists available bandwidth levels for virtual circuits. For the compartment ID, provide the OCID of your tenancy (the root compartment). +func (client VirtualNetworkClient) ListVirtualCircuitBandwidthShapes(ctx context.Context, request ListVirtualCircuitBandwidthShapesRequest) (response ListVirtualCircuitBandwidthShapesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/virtualCircuitBandwidthShapes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVirtualCircuitPublicPrefixes Lists the public IP prefixes and their details for the specified +// public virtual circuit. +func (client VirtualNetworkClient) ListVirtualCircuitPublicPrefixes(ctx context.Context, request ListVirtualCircuitPublicPrefixesRequest) (response ListVirtualCircuitPublicPrefixesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/virtualCircuits/{virtualCircuitId}/publicPrefixes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListVirtualCircuits Lists the virtual circuits in the specified compartment. +func (client VirtualNetworkClient) ListVirtualCircuits(ctx context.Context, request ListVirtualCircuitsRequest) (response ListVirtualCircuitsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/virtualCircuits", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateCpe Updates the specified CPE's display name. +// Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateCpe(ctx context.Context, request UpdateCpeRequest) (response UpdateCpeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/cpes/{cpeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateCrossConnect Updates the specified cross-connect. +func (client VirtualNetworkClient) UpdateCrossConnect(ctx context.Context, request UpdateCrossConnectRequest) (response UpdateCrossConnectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/crossConnects/{crossConnectId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateCrossConnectGroup Updates the specified cross-connect group's display name. +// Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateCrossConnectGroup(ctx context.Context, request UpdateCrossConnectGroupRequest) (response UpdateCrossConnectGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/crossConnectGroups/{crossConnectGroupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateDhcpOptions Updates the specified set of DHCP options. You can update the display name or the options +// themselves. Avoid entering confidential information. +// Note that the `options` object you provide replaces the entire existing set of options. +func (client VirtualNetworkClient) UpdateDhcpOptions(ctx context.Context, request UpdateDhcpOptionsRequest) (response UpdateDhcpOptionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/dhcps/{dhcpId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateDrg Updates the specified DRG's display name. Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateDrg(ctx context.Context, request UpdateDrgRequest) (response UpdateDrgResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/drgs/{drgId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateDrgAttachment Updates the display name for the specified `DrgAttachment`. +// Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateDrgAttachment(ctx context.Context, request UpdateDrgAttachmentRequest) (response UpdateDrgAttachmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/drgAttachments/{drgAttachmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateIPSecConnection Updates the display name for the specified IPSec connection. +// Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateIPSecConnection(ctx context.Context, request UpdateIPSecConnectionRequest) (response UpdateIPSecConnectionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/ipsecConnections/{ipscId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateInternetGateway Updates the specified Internet Gateway. You can disable/enable it, or change its display name. +// Avoid entering confidential information. +// If the gateway is disabled, that means no traffic will flow to/from the internet even if there's +// a route rule that enables that traffic. +func (client VirtualNetworkClient) UpdateInternetGateway(ctx context.Context, request UpdateInternetGatewayRequest) (response UpdateInternetGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/internetGateways/{igId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateLocalPeeringGateway Updates the specified local peering gateway (LPG). +func (client VirtualNetworkClient) UpdateLocalPeeringGateway(ctx context.Context, request UpdateLocalPeeringGatewayRequest) (response UpdateLocalPeeringGatewayResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/localPeeringGateways/{localPeeringGatewayId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdatePrivateIp Updates the specified private IP. You must specify the object's OCID. +// Use this operation if you want to: +// - Move a secondary private IP to a different VNIC in the same subnet. +// - Change the display name for a secondary private IP. +// - Change the hostname for a secondary private IP. +// This operation cannot be used with primary private IPs. +// To update the hostname for the primary IP on a VNIC, use +// UpdateVnic. +func (client VirtualNetworkClient) UpdatePrivateIp(ctx context.Context, request UpdatePrivateIpRequest) (response UpdatePrivateIpResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/privateIps/{privateIpId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateRouteTable Updates the specified route table's display name or route rules. +// Avoid entering confidential information. +// Note that the `routeRules` object you provide replaces the entire existing set of rules. +func (client VirtualNetworkClient) UpdateRouteTable(ctx context.Context, request UpdateRouteTableRequest) (response UpdateRouteTableResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/routeTables/{rtId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateSecurityList Updates the specified security list's display name or rules. +// Avoid entering confidential information. +// Note that the `egressSecurityRules` or `ingressSecurityRules` objects you provide replace the entire +// existing objects. +func (client VirtualNetworkClient) UpdateSecurityList(ctx context.Context, request UpdateSecurityListRequest) (response UpdateSecurityListResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/securityLists/{securityListId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateSubnet Updates the specified subnet's display name. Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateSubnet(ctx context.Context, request UpdateSubnetRequest) (response UpdateSubnetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/subnets/{subnetId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateVcn Updates the specified VCN's display name. +// Avoid entering confidential information. +func (client VirtualNetworkClient) UpdateVcn(ctx context.Context, request UpdateVcnRequest) (response UpdateVcnResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/vcns/{vcnId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateVirtualCircuit Updates the specified virtual circuit. This can be called by +// either the customer who owns the virtual circuit, or the +// provider (when provisioning or de-provisioning the virtual +// circuit from their end). The documentation for +// UpdateVirtualCircuitDetails +// indicates who can update each property of the virtual circuit. +// **Important:** If the virtual circuit is working and in the +// PROVISIONED state, updating any of the network-related properties +// (such as the DRG being used, the BGP ASN, and so on) will cause the virtual +// circuit's state to switch to PROVISIONING and the related BGP +// session to go down. After Oracle re-provisions the virtual circuit, +// its state will return to PROVISIONED. Make sure you confirm that +// the associated BGP session is back up. For more information +// about the various states and how to test connectivity, see +// FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// To change the list of public IP prefixes for a public virtual circuit, +// use BulkAddVirtualCircuitPublicPrefixes +// and +// BulkDeleteVirtualCircuitPublicPrefixes. +// Updating the list of prefixes does NOT cause the BGP session to go down. However, +// Oracle must verify the customer's ownership of each added prefix before +// traffic for that prefix will flow across the virtual circuit. +func (client VirtualNetworkClient) UpdateVirtualCircuit(ctx context.Context, request UpdateVirtualCircuitRequest) (response UpdateVirtualCircuitResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/virtualCircuits/{virtualCircuitId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateVnic Updates the specified VNIC. +func (client VirtualNetworkClient) UpdateVnic(ctx context.Context, request UpdateVnicRequest) (response UpdateVnicResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/vnics/{vnicId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cpe.go b/vendor/github.com/oracle/oci-go-sdk/core/cpe.go new file mode 100644 index 000000000..9759c8cbf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cpe.go @@ -0,0 +1,45 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Cpe An object you create when setting up an IPSec VPN between your on-premises network +// and VCN. The `Cpe` is a virtual representation of your Customer-Premises Equipment, +// which is the actual router on-premises at your site at your end of the IPSec VPN connection. +// For more information, +// see Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Cpe struct { + + // The OCID of the compartment containing the CPE. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The CPE's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The public IP address of the on-premises router. + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The date and time the CPE was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m Cpe) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_cpe_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_cpe_details.go new file mode 100644 index 000000000..0dff34734 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_cpe_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateCpeDetails The representation of CreateCpeDetails +type CreateCpeDetails struct { + + // The OCID of the compartment to contain the CPE. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The public IP address of the on-premises router. + // Example: `143.19.23.16` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateCpeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_cpe_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_cpe_request_response.go new file mode 100644 index 000000000..c4a5314a8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_cpe_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateCpeRequest wrapper for the CreateCpe operation +type CreateCpeRequest struct { + + // Details for creating a CPE. + CreateCpeDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateCpeRequest) String() string { + return common.PointerString(request) +} + +// CreateCpeResponse wrapper for the CreateCpe operation +type CreateCpeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Cpe instance + Cpe `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateCpeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_details.go new file mode 100644 index 000000000..6a17ea194 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_details.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateCrossConnectDetails The representation of CreateCrossConnectDetails +type CreateCrossConnectDetails struct { + + // The OCID of the compartment to contain the cross-connect. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name of the FastConnect location where this cross-connect will be installed. + // To get a list of the available locations, see + // ListCrossConnectLocations. + // Example: `CyrusOne, Chandler, AZ` + LocationName *string `mandatory:"true" json:"locationName"` + + // The port speed for this cross-connect. To get a list of the available port speeds, see + // ListCrossconnectPortSpeedShapes. + // Example: `10 Gbps` + PortSpeedShapeName *string `mandatory:"true" json:"portSpeedShapeName"` + + // The OCID of the cross-connect group to put this cross-connect in. + CrossConnectGroupId *string `mandatory:"false" json:"crossConnectGroupId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // If you already have an existing cross-connect or cross-connect group at this FastConnect + // location, and you want this new cross-connect to be on a different router (for the + // purposes of redundancy), provide the OCID of that existing cross-connect or + // cross-connect group. + FarCrossConnectOrCrossConnectGroupId *string `mandatory:"false" json:"farCrossConnectOrCrossConnectGroupId"` + + // If you already have an existing cross-connect or cross-connect group at this FastConnect + // location, and you want this new cross-connect to be on the same router, provide the + // OCID of that existing cross-connect or cross-connect group. + NearCrossConnectOrCrossConnectGroupId *string `mandatory:"false" json:"nearCrossConnectOrCrossConnectGroupId"` +} + +func (m CreateCrossConnectDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_details.go new file mode 100644 index 000000000..c1232cfca --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateCrossConnectGroupDetails The representation of CreateCrossConnectGroupDetails +type CreateCrossConnectGroupDetails struct { + + // The OCID of the compartment to contain the cross-connect group. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateCrossConnectGroupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_request_response.go new file mode 100644 index 000000000..33cdec7e9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_group_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateCrossConnectGroupRequest wrapper for the CreateCrossConnectGroup operation +type CreateCrossConnectGroupRequest struct { + + // Details to create a CrossConnectGroup + CreateCrossConnectGroupDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateCrossConnectGroupRequest) String() string { + return common.PointerString(request) +} + +// CreateCrossConnectGroupResponse wrapper for the CreateCrossConnectGroup operation +type CreateCrossConnectGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnectGroup instance + CrossConnectGroup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateCrossConnectGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_request_response.go new file mode 100644 index 000000000..b9bf4a46e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_cross_connect_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateCrossConnectRequest wrapper for the CreateCrossConnect operation +type CreateCrossConnectRequest struct { + + // Details to create a CrossConnect + CreateCrossConnectDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateCrossConnectRequest) String() string { + return common.PointerString(request) +} + +// CreateCrossConnectResponse wrapper for the CreateCrossConnect operation +type CreateCrossConnectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnect instance + CrossConnect `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateCrossConnectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_details.go new file mode 100644 index 000000000..a29660b37 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_details.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDhcpDetails The representation of CreateDhcpDetails +type CreateDhcpDetails struct { + + // The OCID of the compartment to contain the set of DHCP options. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A set of DHCP options. + Options []DhcpOption `mandatory:"true" json:"options"` + + // The OCID of the VCN the set of DHCP options belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateDhcpDetails) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *CreateDhcpDetails) UnmarshalJSON(data []byte) (e error) { + model := struct { + DisplayName *string `json:"displayName"` + CompartmentId *string `json:"compartmentId"` + Options []dhcpoption `json:"options"` + VcnId *string `json:"vcnId"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.DisplayName = model.DisplayName + m.CompartmentId = model.CompartmentId + m.Options = make([]DhcpOption, len(model.Options)) + for i, n := range model.Options { + nn, err := n.UnmarshalPolymorphicJSON(n.JsonData) + if err != nil { + return err + } + m.Options[i] = nn + } + m.VcnId = model.VcnId + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_options_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_options_request_response.go new file mode 100644 index 000000000..6fed1770d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_dhcp_options_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateDhcpOptionsRequest wrapper for the CreateDhcpOptions operation +type CreateDhcpOptionsRequest struct { + + // Request object for creating a new set of DHCP options. + CreateDhcpDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateDhcpOptionsRequest) String() string { + return common.PointerString(request) +} + +// CreateDhcpOptionsResponse wrapper for the CreateDhcpOptions operation +type CreateDhcpOptionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DhcpOptions instance + DhcpOptions `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateDhcpOptionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_details.go new file mode 100644 index 000000000..d76431fc9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_details.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDrgAttachmentDetails The representation of CreateDrgAttachmentDetails +type CreateDrgAttachmentDetails struct { + + // The OCID of the DRG. + DrgId *string `mandatory:"true" json:"drgId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateDrgAttachmentDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_request_response.go new file mode 100644 index 000000000..4e50c9bd6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_attachment_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateDrgAttachmentRequest wrapper for the CreateDrgAttachment operation +type CreateDrgAttachmentRequest struct { + + // Details for creating a `DrgAttachment`. + CreateDrgAttachmentDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateDrgAttachmentRequest) String() string { + return common.PointerString(request) +} + +// CreateDrgAttachmentResponse wrapper for the CreateDrgAttachment operation +type CreateDrgAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DrgAttachment instance + DrgAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateDrgAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_drg_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_details.go new file mode 100644 index 000000000..a4a7d6f65 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_details.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDrgDetails The representation of CreateDrgDetails +type CreateDrgDetails struct { + + // The OCID of the compartment to contain the DRG. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateDrgDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_drg_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_request_response.go new file mode 100644 index 000000000..a1fa6bae0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_drg_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateDrgRequest wrapper for the CreateDrg operation +type CreateDrgRequest struct { + + // Details for creating a DRG. + CreateDrgDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateDrgRequest) String() string { + return common.PointerString(request) +} + +// CreateDrgResponse wrapper for the CreateDrg operation +type CreateDrgResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Drg instance + Drg `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateDrgResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_i_p_sec_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_i_p_sec_connection_request_response.go new file mode 100644 index 000000000..877bcc9c8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_i_p_sec_connection_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateIPSecConnectionRequest wrapper for the CreateIPSecConnection operation +type CreateIPSecConnectionRequest struct { + + // Details for creating an `IPSecConnection`. + CreateIpSecConnectionDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateIPSecConnectionRequest) String() string { + return common.PointerString(request) +} + +// CreateIPSecConnectionResponse wrapper for the CreateIPSecConnection operation +type CreateIPSecConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IpSecConnection instance + IpSecConnection `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateIPSecConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_image_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_image_details.go new file mode 100644 index 000000000..6a482ea01 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_image_details.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateImageDetails Either instanceId or imageSourceDetails must be provided in addition to other required parameters. +type CreateImageDetails struct { + + // The OCID of the compartment containing the instance you want to use as the basis for the image. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name for the image. It does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // You cannot use an Oracle-provided image name as a custom image name. + // Example: `My Oracle Linux image` + DisplayName *string `mandatory:"false" json:"displayName"` + + // Details for creating an image through import + ImageSourceDetails ImageSourceDetails `mandatory:"false" json:"imageSourceDetails"` + + // The OCID of the instance you want to use as the basis for the image. + InstanceId *string `mandatory:"false" json:"instanceId"` +} + +func (m CreateImageDetails) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *CreateImageDetails) UnmarshalJSON(data []byte) (e error) { + model := struct { + DisplayName *string `json:"displayName"` + ImageSourceDetails imagesourcedetails `json:"imageSourceDetails"` + InstanceId *string `json:"instanceId"` + CompartmentId *string `json:"compartmentId"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.DisplayName = model.DisplayName + nn, e := model.ImageSourceDetails.UnmarshalPolymorphicJSON(model.ImageSourceDetails.JsonData) + if e != nil { + return + } + m.ImageSourceDetails = nn + m.InstanceId = model.InstanceId + m.CompartmentId = model.CompartmentId + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_image_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_image_request_response.go new file mode 100644 index 000000000..0481d6924 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_image_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateImageRequest wrapper for the CreateImage operation +type CreateImageRequest struct { + + // Image creation details + CreateImageDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateImageRequest) String() string { + return common.PointerString(request) +} + +// CreateImageResponse wrapper for the CreateImage operation +type CreateImageResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Image instance + Image `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateImageResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_details.go new file mode 100644 index 000000000..3d3225bf7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateInstanceConsoleConnectionDetails The details for creating a instance console connection. +// The instance console connection is created in the same compartment as the instance. +type CreateInstanceConsoleConnectionDetails struct { + + // The OCID of the instance to create the console connection to. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // The SSH public key used to authenticate the console connection. + PublicKey *string `mandatory:"true" json:"publicKey"` +} + +func (m CreateInstanceConsoleConnectionDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_request_response.go new file mode 100644 index 000000000..456bd9b78 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_instance_console_connection_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateInstanceConsoleConnectionRequest wrapper for the CreateInstanceConsoleConnection operation +type CreateInstanceConsoleConnectionRequest struct { + + // Request object for creating an InstanceConsoleConnection + CreateInstanceConsoleConnectionDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateInstanceConsoleConnectionRequest) String() string { + return common.PointerString(request) +} + +// CreateInstanceConsoleConnectionResponse wrapper for the CreateInstanceConsoleConnection operation +type CreateInstanceConsoleConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The InstanceConsoleConnection instance + InstanceConsoleConnection `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateInstanceConsoleConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_details.go new file mode 100644 index 000000000..df49670c6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_details.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateInternetGatewayDetails The representation of CreateInternetGatewayDetails +type CreateInternetGatewayDetails struct { + + // The OCID of the compartment to contain the Internet Gateway. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Whether the gateway is enabled upon creation. + IsEnabled *bool `mandatory:"true" json:"isEnabled"` + + // The OCID of the VCN the Internet Gateway is attached to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateInternetGatewayDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_request_response.go new file mode 100644 index 000000000..767747486 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_internet_gateway_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateInternetGatewayRequest wrapper for the CreateInternetGateway operation +type CreateInternetGatewayRequest struct { + + // Details for creating a new Internet Gateway. + CreateInternetGatewayDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateInternetGatewayRequest) String() string { + return common.PointerString(request) +} + +// CreateInternetGatewayResponse wrapper for the CreateInternetGateway operation +type CreateInternetGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The InternetGateway instance + InternetGateway `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateInternetGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_ip_sec_connection_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_ip_sec_connection_details.go new file mode 100644 index 000000000..31cf23fa8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_ip_sec_connection_details.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateIpSecConnectionDetails The representation of CreateIpSecConnectionDetails +type CreateIpSecConnectionDetails struct { + + // The OCID of the compartment to contain the IPSec connection. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the CPE. + CpeId *string `mandatory:"true" json:"cpeId"` + + // The OCID of the DRG. + DrgId *string `mandatory:"true" json:"drgId"` + + // Static routes to the CPE. At least one route must be included. The CIDR must not be a + // multicast address or class E address. + // Example: `10.0.1.0/24` + StaticRoutes []string `mandatory:"true" json:"staticRoutes"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateIpSecConnectionDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_details.go new file mode 100644 index 000000000..6e0b45439 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateLocalPeeringGatewayDetails The representation of CreateLocalPeeringGatewayDetails +type CreateLocalPeeringGatewayDetails struct { + + // The OCID of the compartment containing the local peering gateway (LPG). + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the VCN the LPG belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid + // entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateLocalPeeringGatewayDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_request_response.go new file mode 100644 index 000000000..4f72bdb5c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_local_peering_gateway_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateLocalPeeringGatewayRequest wrapper for the CreateLocalPeeringGateway operation +type CreateLocalPeeringGatewayRequest struct { + + // Details for creating a new local peering gateway. + CreateLocalPeeringGatewayDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateLocalPeeringGatewayRequest) String() string { + return common.PointerString(request) +} + +// CreateLocalPeeringGatewayResponse wrapper for the CreateLocalPeeringGateway operation +type CreateLocalPeeringGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The LocalPeeringGateway instance + LocalPeeringGateway `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateLocalPeeringGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_details.go new file mode 100644 index 000000000..b9da8cc51 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_details.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreatePrivateIpDetails The representation of CreatePrivateIpDetails +type CreatePrivateIpDetails struct { + + // The OCID of the VNIC to assign the private IP to. The VNIC and private IP + // must be in the same subnet. + VnicId *string `mandatory:"true" json:"vnicId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid + // entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The hostname for the private IP. Used for DNS. The value + // is the hostname portion of the private IP's fully qualified domain name (FQDN) + // (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be unique across all VNICs in the subnet and comply with + // RFC 952 (https://tools.ietf.org/html/rfc952) and + // RFC 1123 (https://tools.ietf.org/html/rfc1123). + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `bminstance-1` + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // A private IP address of your choice. Must be an available IP address within + // the subnet's CIDR. If you don't specify a value, Oracle automatically + // assigns a private IP address from the subnet. + // Example: `10.0.3.3` + IpAddress *string `mandatory:"false" json:"ipAddress"` +} + +func (m CreatePrivateIpDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_request_response.go new file mode 100644 index 000000000..941d3a3ed --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_private_ip_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreatePrivateIpRequest wrapper for the CreatePrivateIp operation +type CreatePrivateIpRequest struct { + + // Create private IP details. + CreatePrivateIpDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreatePrivateIpRequest) String() string { + return common.PointerString(request) +} + +// CreatePrivateIpResponse wrapper for the CreatePrivateIp operation +type CreatePrivateIpResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PrivateIp instance + PrivateIp `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreatePrivateIpResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_route_table_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_route_table_details.go new file mode 100644 index 000000000..8f3005acd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_route_table_details.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateRouteTableDetails The representation of CreateRouteTableDetails +type CreateRouteTableDetails struct { + + // The OCID of the compartment to contain the route table. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The collection of rules used for routing destination IPs to network devices. + RouteRules []RouteRule `mandatory:"true" json:"routeRules"` + + // The OCID of the VCN the route table belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateRouteTableDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_route_table_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_route_table_request_response.go new file mode 100644 index 000000000..7e70b4de8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_route_table_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateRouteTableRequest wrapper for the CreateRouteTable operation +type CreateRouteTableRequest struct { + + // Details for creating a new route table. + CreateRouteTableDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateRouteTableRequest) String() string { + return common.PointerString(request) +} + +// CreateRouteTableResponse wrapper for the CreateRouteTable operation +type CreateRouteTableResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The RouteTable instance + RouteTable `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateRouteTableResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_security_list_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_security_list_details.go new file mode 100644 index 000000000..06d4c4ec9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_security_list_details.go @@ -0,0 +1,36 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateSecurityListDetails The representation of CreateSecurityListDetails +type CreateSecurityListDetails struct { + + // The OCID of the compartment to contain the security list. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Rules for allowing egress IP packets. + EgressSecurityRules []EgressSecurityRule `mandatory:"true" json:"egressSecurityRules"` + + // Rules for allowing ingress IP packets. + IngressSecurityRules []IngressSecurityRule `mandatory:"true" json:"ingressSecurityRules"` + + // The OCID of the VCN the security list belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateSecurityListDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_security_list_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_security_list_request_response.go new file mode 100644 index 000000000..e652c644b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_security_list_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateSecurityListRequest wrapper for the CreateSecurityList operation +type CreateSecurityListRequest struct { + + // Details regarding the security list to create. + CreateSecurityListDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateSecurityListRequest) String() string { + return common.PointerString(request) +} + +// CreateSecurityListResponse wrapper for the CreateSecurityList operation +type CreateSecurityListResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The SecurityList instance + SecurityList `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateSecurityListResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_subnet_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_subnet_details.go new file mode 100644 index 000000000..bc50b2add --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_subnet_details.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateSubnetDetails The representation of CreateSubnetDetails +type CreateSubnetDetails struct { + + // The Availability Domain to contain the subnet. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The CIDR IP address range of the subnet. + // Example: `172.16.1.0/24` + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + // The OCID of the compartment to contain the subnet. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the VCN to contain the subnet. + VcnId *string `mandatory:"true" json:"vcnId"` + + // The OCID of the set of DHCP options the subnet will use. If you don't + // provide a value, the subnet will use the VCN's default set of DHCP options. + DhcpOptionsId *string `mandatory:"false" json:"dhcpOptionsId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // A DNS label for the subnet, used in conjunction with the VNIC's hostname and + // VCN's DNS label to form a fully qualified domain name (FQDN) for each VNIC + // within this subnet (for example, `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be an alphanumeric string that begins with a letter and is unique within the VCN. + // The value cannot be changed. + // This value must be set if you want to use the Internet and VCN Resolver to resolve the + // hostnames of instances in the subnet. It can only be set if the VCN itself + // was created with a DNS label. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `subnet123` + DnsLabel *string `mandatory:"false" json:"dnsLabel"` + + // Whether VNICs within this subnet can have public IP addresses. + // Defaults to false, which means VNICs created in this subnet will + // automatically be assigned public IP addresses unless specified + // otherwise during instance launch or VNIC creation (with the + // `assignPublicIp` flag in CreateVnicDetails). + // If `prohibitPublicIpOnVnic` is set to true, VNICs created in this + // subnet cannot have public IP addresses (that is, it's a private + // subnet). + // Example: `true` + ProhibitPublicIpOnVnic *bool `mandatory:"false" json:"prohibitPublicIpOnVnic"` + + // The OCID of the route table the subnet will use. If you don't provide a value, + // the subnet will use the VCN's default route table. + RouteTableId *string `mandatory:"false" json:"routeTableId"` + + // OCIDs for the security lists to associate with the subnet. If you don't + // provide a value, the VCN's default security list will be associated with + // the subnet. Remember that security lists are associated at the subnet + // level, but the rules are applied to the individual VNICs in the subnet. + SecurityListIds []string `mandatory:"false" json:"securityListIds"` +} + +func (m CreateSubnetDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_subnet_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_subnet_request_response.go new file mode 100644 index 000000000..8d5818ec7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_subnet_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateSubnetRequest wrapper for the CreateSubnet operation +type CreateSubnetRequest struct { + + // Details for creating a subnet. + CreateSubnetDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateSubnetRequest) String() string { + return common.PointerString(request) +} + +// CreateSubnetResponse wrapper for the CreateSubnet operation +type CreateSubnetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Subnet instance + Subnet `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateSubnetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_vcn_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_vcn_details.go new file mode 100644 index 000000000..70eb2c240 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_vcn_details.go @@ -0,0 +1,45 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateVcnDetails The representation of CreateVcnDetails +type CreateVcnDetails struct { + + // The CIDR IP address block of the VCN. + // Example: `172.16.0.0/16` + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + // The OCID of the compartment to contain the VCN. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // A DNS label for the VCN, used in conjunction with the VNIC's hostname and + // subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC + // within this subnet (for example, `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Not required to be unique, but it's a best practice to set unique DNS labels + // for VCNs in your tenancy. Must be an alphanumeric string that begins with a letter. + // The value cannot be changed. + // You must set this value if you want instances to be able to use hostnames to + // resolve other instances in the VCN. Otherwise the Internet and VCN Resolver + // will not work. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `vcn1` + DnsLabel *string `mandatory:"false" json:"dnsLabel"` +} + +func (m CreateVcnDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_vcn_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_vcn_request_response.go new file mode 100644 index 000000000..99cd907af --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_vcn_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateVcnRequest wrapper for the CreateVcn operation +type CreateVcnRequest struct { + + // Details for creating a new VCN. + CreateVcnDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateVcnRequest) String() string { + return common.PointerString(request) +} + +// CreateVcnResponse wrapper for the CreateVcn operation +type CreateVcnResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Vcn instance + Vcn `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateVcnResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_details.go new file mode 100644 index 000000000..f663f9854 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_details.go @@ -0,0 +1,98 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateVirtualCircuitDetails The representation of CreateVirtualCircuitDetails +type CreateVirtualCircuitDetails struct { + + // The OCID of the compartment to contain the virtual circuit. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The type of IP addresses used in this virtual circuit. PRIVATE + // means RFC 1918 (https://tools.ietf.org/html/rfc1918) addresses + // (10.0.0.0/8, 172.16/12, and 192.168/16). Only PRIVATE is supported. + Type CreateVirtualCircuitDetailsTypeEnum `mandatory:"true" json:"type"` + + // The provisioned data rate of the connection. To get a list of the + // available bandwidth levels (that is, shapes), see + // ListFastConnectProviderVirtualCircuitBandwidthShapes. + // Example: `10 Gbps` + BandwidthShapeName *string `mandatory:"false" json:"bandwidthShapeName"` + + // Create a `CrossConnectMapping` for each cross-connect or cross-connect + // group this virtual circuit will run on. + CrossConnectMappings []CrossConnectMapping `mandatory:"false" json:"crossConnectMappings"` + + // Your BGP ASN (either public or private). Provide this value only if + // there's a BGP session that goes from your edge router to Oracle. + // Otherwise, leave this empty or null. + CustomerBgpAsn *int `mandatory:"false" json:"customerBgpAsn"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // For private virtual circuits only. The OCID of the Drg + // that this virtual circuit uses. + GatewayId *string `mandatory:"false" json:"gatewayId"` + + // Deprecated. Instead use `providerServiceId`. + // To get a list of the provider names, see + // ListFastConnectProviderServices. + ProviderName *string `mandatory:"false" json:"providerName"` + + // The OCID of the service offered by the provider (if you're connecting + // via a provider). To get a list of the available service offerings, see + // ListFastConnectProviderServices. + ProviderServiceId *string `mandatory:"false" json:"providerServiceId"` + + // Deprecated. Instead use `providerServiceId`. + // To get a list of the provider names, see + // ListFastConnectProviderServices. + ProviderServiceName *string `mandatory:"false" json:"providerServiceName"` + + // For a public virtual circuit. The public IP prefixes (CIDRs) the customer wants to + // advertise across the connection. + PublicPrefixes []CreateVirtualCircuitPublicPrefixDetails `mandatory:"false" json:"publicPrefixes"` + + // The Oracle Cloud Infrastructure region where this virtual + // circuit is located. + // Example: `phx` + Region *string `mandatory:"false" json:"region"` +} + +func (m CreateVirtualCircuitDetails) String() string { + return common.PointerString(m) +} + +// CreateVirtualCircuitDetailsTypeEnum Enum with underlying type: string +type CreateVirtualCircuitDetailsTypeEnum string + +// Set of constants representing the allowable values for CreateVirtualCircuitDetailsType +const ( + CreateVirtualCircuitDetailsTypePublic CreateVirtualCircuitDetailsTypeEnum = "PUBLIC" + CreateVirtualCircuitDetailsTypePrivate CreateVirtualCircuitDetailsTypeEnum = "PRIVATE" +) + +var mappingCreateVirtualCircuitDetailsType = map[string]CreateVirtualCircuitDetailsTypeEnum{ + "PUBLIC": CreateVirtualCircuitDetailsTypePublic, + "PRIVATE": CreateVirtualCircuitDetailsTypePrivate, +} + +// GetCreateVirtualCircuitDetailsTypeEnumValues Enumerates the set of values for CreateVirtualCircuitDetailsType +func GetCreateVirtualCircuitDetailsTypeEnumValues() []CreateVirtualCircuitDetailsTypeEnum { + values := make([]CreateVirtualCircuitDetailsTypeEnum, 0) + for _, v := range mappingCreateVirtualCircuitDetailsType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_public_prefix_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_public_prefix_details.go new file mode 100644 index 000000000..10e13c8f5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_public_prefix_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateVirtualCircuitPublicPrefixDetails The representation of CreateVirtualCircuitPublicPrefixDetails +type CreateVirtualCircuitPublicPrefixDetails struct { + + // An individual public IP prefix (CIDR) to add to the public virtual circuit. + // Must be /24 or less specific. + CidrBlock *string `mandatory:"true" json:"cidrBlock"` +} + +func (m CreateVirtualCircuitPublicPrefixDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_request_response.go new file mode 100644 index 000000000..629fc3e8a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_virtual_circuit_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateVirtualCircuitRequest wrapper for the CreateVirtualCircuit operation +type CreateVirtualCircuitRequest struct { + + // Details to create a VirtualCircuit. + CreateVirtualCircuitDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateVirtualCircuitRequest) String() string { + return common.PointerString(request) +} + +// CreateVirtualCircuitResponse wrapper for the CreateVirtualCircuit operation +type CreateVirtualCircuitResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VirtualCircuit instance + VirtualCircuit `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateVirtualCircuitResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_vnic_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_vnic_details.go new file mode 100644 index 000000000..c92cd1a5c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_vnic_details.go @@ -0,0 +1,85 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateVnicDetails Contains properties for a VNIC. You use this object when creating the +// primary VNIC during instance launch or when creating a secondary VNIC. +// For more information about VNICs, see +// Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). +type CreateVnicDetails struct { + + // The OCID of the subnet to create the VNIC in. When launching an instance, + // use this `subnetId` instead of the deprecated `subnetId` in + // LaunchInstanceDetails. + // At least one of them is required; if you provide both, the values must match. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // Whether the VNIC should be assigned a public IP address. Defaults to whether + // the subnet is public or private. If not set and the VNIC is being created + // in a private subnet (that is, where `prohibitPublicIpOnVnic` = true in the + // Subnet), then no public IP address is assigned. + // If not set and the subnet is public (`prohibitPublicIpOnVnic` = false), then + // a public IP address is assigned. If set to true and + // `prohibitPublicIpOnVnic` = true, an error is returned. + // **Note:** This public IP address is associated with the primary private IP + // on the VNIC. Secondary private IPs cannot have public IP + // addresses associated with them. For more information, see + // IP Addresses (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPaddresses.htm). + // Example: `false` + AssignPublicIp *bool `mandatory:"false" json:"assignPublicIp"` + + // A user-friendly name for the VNIC. Does not have to be unique. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The hostname for the VNIC's primary private IP. Used for DNS. The value is the hostname + // portion of the primary private IP's fully qualified domain name (FQDN) + // (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be unique across all VNICs in the subnet and comply with + // RFC 952 (https://tools.ietf.org/html/rfc952) and + // RFC 1123 (https://tools.ietf.org/html/rfc1123). + // The value appears in the Vnic object and also the + // PrivateIp object returned by + // ListPrivateIps and + // GetPrivateIp. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // When launching an instance, use this `hostnameLabel` instead + // of the deprecated `hostnameLabel` in + // LaunchInstanceDetails. + // If you provide both, the values must match. + // Example: `bminstance-1` + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // A private IP address of your choice to assign to the VNIC. Must be an + // available IP address within the subnet's CIDR. If you don't specify a + // value, Oracle automatically assigns a private IP address from the subnet. + // This is the VNIC's *primary* private IP address. The value appears in + // the Vnic object and also the + // PrivateIp object returned by + // ListPrivateIps and + // GetPrivateIp. + // Example: `10.0.3.3` + PrivateIp *string `mandatory:"false" json:"privateIp"` + + // Whether the source/destination check is disabled on the VNIC. + // Defaults to `false`, which means the check is performed. For information + // about why you would skip the source/destination check, see + // Using a Private IP as a Route Target (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm#privateip). + // Example: `true` + SkipSourceDestCheck *bool `mandatory:"false" json:"skipSourceDestCheck"` +} + +func (m CreateVnicDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_details.go new file mode 100644 index 000000000..8a1907cb0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateVolumeBackupDetails The representation of CreateVolumeBackupDetails +type CreateVolumeBackupDetails struct { + + // The OCID of the volume that needs to be backed up. + VolumeId *string `mandatory:"true" json:"volumeId"` + + // A user-friendly name for the volume backup. Does not have to be unique and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateVolumeBackupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_request_response.go new file mode 100644 index 000000000..44e47b735 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_backup_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateVolumeBackupRequest wrapper for the CreateVolumeBackup operation +type CreateVolumeBackupRequest struct { + + // Request to create a new backup of given volume. + CreateVolumeBackupDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateVolumeBackupRequest) String() string { + return common.PointerString(request) +} + +// CreateVolumeBackupResponse wrapper for the CreateVolumeBackup operation +type CreateVolumeBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VolumeBackup instance + VolumeBackup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateVolumeBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_details.go new file mode 100644 index 000000000..492c815fb --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_details.go @@ -0,0 +1,80 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateVolumeDetails The representation of CreateVolumeDetails +type CreateVolumeDetails struct { + + // The Availability Domain of the volume. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment that contains the volume. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The size of the volume in GBs. + SizeInGBs *int `mandatory:"false" json:"sizeInGBs"` + + // The size of the volume in MBs. The value must be a multiple of 1024. + // This field is deprecated. Use sizeInGBs instead. + SizeInMBs *int `mandatory:"false" json:"sizeInMBs"` + + // Specifies the volume source details for a new Block volume. The volume source is either another Block volume in the same Availability Domain or a Block volume backup. + // This is an optional field. If not specified or set to null, the new Block volume will be empty. + // When specified, the new Block volume will contain data from the source volume or backup. + SourceDetails VolumeSourceDetails `mandatory:"false" json:"sourceDetails"` + + // The OCID of the volume backup from which the data should be restored on the newly created volume. + // This field is deprecated. Use the sourceDetails field instead to specify the + // backup for the volume. + VolumeBackupId *string `mandatory:"false" json:"volumeBackupId"` +} + +func (m CreateVolumeDetails) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *CreateVolumeDetails) UnmarshalJSON(data []byte) (e error) { + model := struct { + DisplayName *string `json:"displayName"` + SizeInGBs *int `json:"sizeInGBs"` + SizeInMBs *int `json:"sizeInMBs"` + SourceDetails volumesourcedetails `json:"sourceDetails"` + VolumeBackupId *string `json:"volumeBackupId"` + AvailabilityDomain *string `json:"availabilityDomain"` + CompartmentId *string `json:"compartmentId"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.DisplayName = model.DisplayName + m.SizeInGBs = model.SizeInGBs + m.SizeInMBs = model.SizeInMBs + nn, e := model.SourceDetails.UnmarshalPolymorphicJSON(model.SourceDetails.JsonData) + if e != nil { + return + } + m.SourceDetails = nn + m.VolumeBackupId = model.VolumeBackupId + m.AvailabilityDomain = model.AvailabilityDomain + m.CompartmentId = model.CompartmentId + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/create_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_request_response.go new file mode 100644 index 000000000..d505805f4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/create_volume_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateVolumeRequest wrapper for the CreateVolume operation +type CreateVolumeRequest struct { + + // Request to create a new volume. + CreateVolumeDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateVolumeRequest) String() string { + return common.PointerString(request) +} + +// CreateVolumeResponse wrapper for the CreateVolume operation +type CreateVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Volume instance + Volume `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cross_connect.go b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect.go new file mode 100644 index 000000000..67f43bf74 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect.go @@ -0,0 +1,94 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CrossConnect For use with Oracle Cloud Infrastructure FastConnect. A cross-connect represents a +// physical connection between an existing network and Oracle. Customers who are colocated +// with Oracle in a FastConnect location create and use cross-connects. For more +// information, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// Oracle recommends you create each cross-connect in a +// CrossConnectGroup so you can use link aggregation +// with the connection. +// **Note:** If you're a provider who is setting up a physical connection to Oracle so customers +// can use FastConnect over the connection, be aware that your connection is modeled the +// same way as a colocated customer's (with `CrossConnect` and `CrossConnectGroup` objects, and so on). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type CrossConnect struct { + + // The OCID of the compartment containing the cross-connect group. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The OCID of the cross-connect group this cross-connect belongs to (if any). + CrossConnectGroupId *string `mandatory:"false" json:"crossConnectGroupId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The cross-connect's Oracle ID (OCID). + Id *string `mandatory:"false" json:"id"` + + // The cross-connect's current state. + LifecycleState CrossConnectLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The name of the FastConnect location where this cross-connect is installed. + LocationName *string `mandatory:"false" json:"locationName"` + + // A string identifying the meet-me room port for this cross-connect. + PortName *string `mandatory:"false" json:"portName"` + + // The port speed for this cross-connect. + // Example: `10 Gbps` + PortSpeedShapeName *string `mandatory:"false" json:"portSpeedShapeName"` + + // The date and time the cross-connect was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m CrossConnect) String() string { + return common.PointerString(m) +} + +// CrossConnectLifecycleStateEnum Enum with underlying type: string +type CrossConnectLifecycleStateEnum string + +// Set of constants representing the allowable values for CrossConnectLifecycleState +const ( + CrossConnectLifecycleStatePendingCustomer CrossConnectLifecycleStateEnum = "PENDING_CUSTOMER" + CrossConnectLifecycleStateProvisioning CrossConnectLifecycleStateEnum = "PROVISIONING" + CrossConnectLifecycleStateProvisioned CrossConnectLifecycleStateEnum = "PROVISIONED" + CrossConnectLifecycleStateInactive CrossConnectLifecycleStateEnum = "INACTIVE" + CrossConnectLifecycleStateTerminating CrossConnectLifecycleStateEnum = "TERMINATING" + CrossConnectLifecycleStateTerminated CrossConnectLifecycleStateEnum = "TERMINATED" +) + +var mappingCrossConnectLifecycleState = map[string]CrossConnectLifecycleStateEnum{ + "PENDING_CUSTOMER": CrossConnectLifecycleStatePendingCustomer, + "PROVISIONING": CrossConnectLifecycleStateProvisioning, + "PROVISIONED": CrossConnectLifecycleStateProvisioned, + "INACTIVE": CrossConnectLifecycleStateInactive, + "TERMINATING": CrossConnectLifecycleStateTerminating, + "TERMINATED": CrossConnectLifecycleStateTerminated, +} + +// GetCrossConnectLifecycleStateEnumValues Enumerates the set of values for CrossConnectLifecycleState +func GetCrossConnectLifecycleStateEnumValues() []CrossConnectLifecycleStateEnum { + values := make([]CrossConnectLifecycleStateEnum, 0) + for _, v := range mappingCrossConnectLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_group.go b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_group.go new file mode 100644 index 000000000..2193bf7e7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_group.go @@ -0,0 +1,77 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CrossConnectGroup For use with Oracle Cloud Infrastructure FastConnect. A cross-connect group +// is a link aggregation group (LAG), which can contain one or more +// CrossConnect. Customers who are colocated with +// Oracle in a FastConnect location create and use cross-connect groups. For more +// information, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// **Note:** If you're a provider who is setting up a physical connection to Oracle so customers +// can use FastConnect over the connection, be aware that your connection is modeled the +// same way as a colocated customer's (with `CrossConnect` and `CrossConnectGroup` objects, and so on). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type CrossConnectGroup struct { + + // The OCID of the compartment containing the cross-connect group. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The display name of A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The cross-connect group's Oracle ID (OCID). + Id *string `mandatory:"false" json:"id"` + + // The cross-connect group's current state. + LifecycleState CrossConnectGroupLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The date and time the cross-connect group was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m CrossConnectGroup) String() string { + return common.PointerString(m) +} + +// CrossConnectGroupLifecycleStateEnum Enum with underlying type: string +type CrossConnectGroupLifecycleStateEnum string + +// Set of constants representing the allowable values for CrossConnectGroupLifecycleState +const ( + CrossConnectGroupLifecycleStateProvisioning CrossConnectGroupLifecycleStateEnum = "PROVISIONING" + CrossConnectGroupLifecycleStateProvisioned CrossConnectGroupLifecycleStateEnum = "PROVISIONED" + CrossConnectGroupLifecycleStateInactive CrossConnectGroupLifecycleStateEnum = "INACTIVE" + CrossConnectGroupLifecycleStateTerminating CrossConnectGroupLifecycleStateEnum = "TERMINATING" + CrossConnectGroupLifecycleStateTerminated CrossConnectGroupLifecycleStateEnum = "TERMINATED" +) + +var mappingCrossConnectGroupLifecycleState = map[string]CrossConnectGroupLifecycleStateEnum{ + "PROVISIONING": CrossConnectGroupLifecycleStateProvisioning, + "PROVISIONED": CrossConnectGroupLifecycleStateProvisioned, + "INACTIVE": CrossConnectGroupLifecycleStateInactive, + "TERMINATING": CrossConnectGroupLifecycleStateTerminating, + "TERMINATED": CrossConnectGroupLifecycleStateTerminated, +} + +// GetCrossConnectGroupLifecycleStateEnumValues Enumerates the set of values for CrossConnectGroupLifecycleState +func GetCrossConnectGroupLifecycleStateEnumValues() []CrossConnectGroupLifecycleStateEnum { + values := make([]CrossConnectGroupLifecycleStateEnum, 0) + for _, v := range mappingCrossConnectGroupLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_location.go b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_location.go new file mode 100644 index 000000000..3a291556b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_location.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CrossConnectLocation An individual FastConnect location. +type CrossConnectLocation struct { + + // A description of the location. + Description *string `mandatory:"true" json:"description"` + + // The name of the location. + // Example: `CyrusOne, Chandler, AZ` + Name *string `mandatory:"true" json:"name"` +} + +func (m CrossConnectLocation) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_mapping.go b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_mapping.go new file mode 100644 index 000000000..43ec7d68e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_mapping.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CrossConnectMapping For use with Oracle Cloud Infrastructure FastConnect. Each +// VirtualCircuit runs on one or +// more cross-connects or cross-connect groups. A `CrossConnectMapping` +// contains the properties for an individual cross-connect or cross-connect group +// associated with a given virtual circuit. +// The mapping includes information about the cross-connect or +// cross-connect group, the VLAN, and the BGP peering session. +// If you're a customer who is colocated with Oracle, that means you own both +// the virtual circuit and the physical connection it runs on (cross-connect or +// cross-connect group), so you specify all the information in the mapping. There's +// one exception: for a public virtual circuit, Oracle specifies the BGP IP +// addresses. +// If you're a provider, then you own the physical connection that the customer's +// virtual circuit runs on, so you contribute information about the cross-connect +// or cross-connect group and VLAN. +// Who specifies the BGP peering information in the case of customer connection via +// provider? If the BGP session goes from Oracle to the provider's edge router, then +// the provider also specifies the BGP peering information. If the BGP session instead +// goes from Oracle to the customer's edge router, then the customer specifies the BGP +// peering information. There's one exception: for a public virtual circuit, Oracle +// specifies the BGP IP addresses. +type CrossConnectMapping struct { + + // The key for BGP MD5 authentication. Only applicable if your system + // requires MD5 authentication. If empty or not set (null), that + // means you don't use BGP MD5 authentication. + BgpMd5AuthKey *string `mandatory:"false" json:"bgpMd5AuthKey"` + + // The OCID of the cross-connect or cross-connect group for this mapping. + // Specified by the owner of the cross-connect or cross-connect group (the + // customer if the customer is colocated with Oracle, or the provider if the + // customer is connecting via provider). + CrossConnectOrCrossConnectGroupId *string `mandatory:"false" json:"crossConnectOrCrossConnectGroupId"` + + // The BGP IP address for the router on the other end of the BGP session from + // Oracle. Specified by the owner of that router. If the session goes from Oracle + // to a customer, this is the BGP IP address of the customer's edge router. If the + // session goes from Oracle to a provider, this is the BGP IP address of the + // provider's edge router. Must use a /30 or /31 subnet mask. + // There's one exception: for a public virtual circuit, Oracle specifies the BGP IP addresses. + // Example: `10.0.0.18/31` + CustomerBgpPeeringIp *string `mandatory:"false" json:"customerBgpPeeringIp"` + + // The IP address for Oracle's end of the BGP session. Must use a /30 or /31 + // subnet mask. If the session goes from Oracle to a customer's edge router, + // the customer specifies this information. If the session goes from Oracle to + // a provider's edge router, the provider specifies this. + // There's one exception: for a public virtual circuit, Oracle specifies the BGP IP addresses. + // Example: `10.0.0.19/31` + OracleBgpPeeringIp *string `mandatory:"false" json:"oracleBgpPeeringIp"` + + // The number of the specific VLAN (on the cross-connect or cross-connect group) + // that is assigned to this virtual circuit. Specified by the owner of the cross-connect + // or cross-connect group (the customer if the customer is colocated with Oracle, or + // the provider if the customer is connecting via provider). + // Example: `200` + Vlan *int `mandatory:"false" json:"vlan"` +} + +func (m CrossConnectMapping) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_port_speed_shape.go b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_port_speed_shape.go new file mode 100644 index 000000000..3e854fa23 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_port_speed_shape.go @@ -0,0 +1,29 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CrossConnectPortSpeedShape An individual port speed level for cross-connects. +type CrossConnectPortSpeedShape struct { + + // The name of the port speed shape. + // Example: `10 Gbps` + Name *string `mandatory:"true" json:"name"` + + // The port speed in Gbps. + // Example: `10` + PortSpeedInGbps *int `mandatory:"true" json:"portSpeedInGbps"` +} + +func (m CrossConnectPortSpeedShape) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_status.go b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_status.go new file mode 100644 index 000000000..608ab9c80 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/cross_connect_status.go @@ -0,0 +1,91 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CrossConnectStatus The status of the cross-connect. +type CrossConnectStatus struct { + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"true" json:"crossConnectId"` + + // Whether Oracle's side of the interface is up or down. + InterfaceState CrossConnectStatusInterfaceStateEnum `mandatory:"false" json:"interfaceState,omitempty"` + + // The light level of the cross-connect (in dBm). + // Example: `14.0` + LightLevelIndBm *float32 `mandatory:"false" json:"lightLevelIndBm"` + + // Status indicator corresponding to the light level. + // * **NO_LIGHT:** No measurable light + // * **LOW_WARN:** There's measurable light but it's too low + // * **HIGH_WARN:** Light level is too high + // * **BAD:** There's measurable light but the signal-to-noise ratio is bad + // * **GOOD:** Good light level + LightLevelIndicator CrossConnectStatusLightLevelIndicatorEnum `mandatory:"false" json:"lightLevelIndicator,omitempty"` +} + +func (m CrossConnectStatus) String() string { + return common.PointerString(m) +} + +// CrossConnectStatusInterfaceStateEnum Enum with underlying type: string +type CrossConnectStatusInterfaceStateEnum string + +// Set of constants representing the allowable values for CrossConnectStatusInterfaceState +const ( + CrossConnectStatusInterfaceStateUp CrossConnectStatusInterfaceStateEnum = "UP" + CrossConnectStatusInterfaceStateDown CrossConnectStatusInterfaceStateEnum = "DOWN" +) + +var mappingCrossConnectStatusInterfaceState = map[string]CrossConnectStatusInterfaceStateEnum{ + "UP": CrossConnectStatusInterfaceStateUp, + "DOWN": CrossConnectStatusInterfaceStateDown, +} + +// GetCrossConnectStatusInterfaceStateEnumValues Enumerates the set of values for CrossConnectStatusInterfaceState +func GetCrossConnectStatusInterfaceStateEnumValues() []CrossConnectStatusInterfaceStateEnum { + values := make([]CrossConnectStatusInterfaceStateEnum, 0) + for _, v := range mappingCrossConnectStatusInterfaceState { + values = append(values, v) + } + return values +} + +// CrossConnectStatusLightLevelIndicatorEnum Enum with underlying type: string +type CrossConnectStatusLightLevelIndicatorEnum string + +// Set of constants representing the allowable values for CrossConnectStatusLightLevelIndicator +const ( + CrossConnectStatusLightLevelIndicatorNoLight CrossConnectStatusLightLevelIndicatorEnum = "NO_LIGHT" + CrossConnectStatusLightLevelIndicatorLowWarn CrossConnectStatusLightLevelIndicatorEnum = "LOW_WARN" + CrossConnectStatusLightLevelIndicatorHighWarn CrossConnectStatusLightLevelIndicatorEnum = "HIGH_WARN" + CrossConnectStatusLightLevelIndicatorBad CrossConnectStatusLightLevelIndicatorEnum = "BAD" + CrossConnectStatusLightLevelIndicatorGood CrossConnectStatusLightLevelIndicatorEnum = "GOOD" +) + +var mappingCrossConnectStatusLightLevelIndicator = map[string]CrossConnectStatusLightLevelIndicatorEnum{ + "NO_LIGHT": CrossConnectStatusLightLevelIndicatorNoLight, + "LOW_WARN": CrossConnectStatusLightLevelIndicatorLowWarn, + "HIGH_WARN": CrossConnectStatusLightLevelIndicatorHighWarn, + "BAD": CrossConnectStatusLightLevelIndicatorBad, + "GOOD": CrossConnectStatusLightLevelIndicatorGood, +} + +// GetCrossConnectStatusLightLevelIndicatorEnumValues Enumerates the set of values for CrossConnectStatusLightLevelIndicator +func GetCrossConnectStatusLightLevelIndicatorEnumValues() []CrossConnectStatusLightLevelIndicatorEnum { + values := make([]CrossConnectStatusLightLevelIndicatorEnum, 0) + for _, v := range mappingCrossConnectStatusLightLevelIndicator { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_boot_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_boot_volume_request_response.go new file mode 100644 index 000000000..1f5d59d9a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_boot_volume_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteBootVolumeRequest wrapper for the DeleteBootVolume operation +type DeleteBootVolumeRequest struct { + + // The OCID of the boot volume. + BootVolumeId *string `mandatory:"true" contributesTo:"path" name:"bootVolumeId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteBootVolumeRequest) String() string { + return common.PointerString(request) +} + +// DeleteBootVolumeResponse wrapper for the DeleteBootVolume operation +type DeleteBootVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteBootVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_console_history_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_console_history_request_response.go new file mode 100644 index 000000000..e964e9bf4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_console_history_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteConsoleHistoryRequest wrapper for the DeleteConsoleHistory operation +type DeleteConsoleHistoryRequest struct { + + // The OCID of the console history. + InstanceConsoleHistoryId *string `mandatory:"true" contributesTo:"path" name:"instanceConsoleHistoryId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteConsoleHistoryRequest) String() string { + return common.PointerString(request) +} + +// DeleteConsoleHistoryResponse wrapper for the DeleteConsoleHistory operation +type DeleteConsoleHistoryResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteConsoleHistoryResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_cpe_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_cpe_request_response.go new file mode 100644 index 000000000..6a398d922 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_cpe_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteCpeRequest wrapper for the DeleteCpe operation +type DeleteCpeRequest struct { + + // The OCID of the CPE. + CpeId *string `mandatory:"true" contributesTo:"path" name:"cpeId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteCpeRequest) String() string { + return common.PointerString(request) +} + +// DeleteCpeResponse wrapper for the DeleteCpe operation +type DeleteCpeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteCpeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_group_request_response.go new file mode 100644 index 000000000..fbfaf81e1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_group_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteCrossConnectGroupRequest wrapper for the DeleteCrossConnectGroup operation +type DeleteCrossConnectGroupRequest struct { + + // The OCID of the cross-connect group. + CrossConnectGroupId *string `mandatory:"true" contributesTo:"path" name:"crossConnectGroupId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteCrossConnectGroupRequest) String() string { + return common.PointerString(request) +} + +// DeleteCrossConnectGroupResponse wrapper for the DeleteCrossConnectGroup operation +type DeleteCrossConnectGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteCrossConnectGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_request_response.go new file mode 100644 index 000000000..f3641dfd2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_cross_connect_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteCrossConnectRequest wrapper for the DeleteCrossConnect operation +type DeleteCrossConnectRequest struct { + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"true" contributesTo:"path" name:"crossConnectId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteCrossConnectRequest) String() string { + return common.PointerString(request) +} + +// DeleteCrossConnectResponse wrapper for the DeleteCrossConnect operation +type DeleteCrossConnectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteCrossConnectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_dhcp_options_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_dhcp_options_request_response.go new file mode 100644 index 000000000..e89249eec --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_dhcp_options_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteDhcpOptionsRequest wrapper for the DeleteDhcpOptions operation +type DeleteDhcpOptionsRequest struct { + + // The OCID for the set of DHCP options. + DhcpId *string `mandatory:"true" contributesTo:"path" name:"dhcpId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteDhcpOptionsRequest) String() string { + return common.PointerString(request) +} + +// DeleteDhcpOptionsResponse wrapper for the DeleteDhcpOptions operation +type DeleteDhcpOptionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteDhcpOptionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_drg_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_drg_attachment_request_response.go new file mode 100644 index 000000000..a921056e5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_drg_attachment_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteDrgAttachmentRequest wrapper for the DeleteDrgAttachment operation +type DeleteDrgAttachmentRequest struct { + + // The OCID of the DRG attachment. + DrgAttachmentId *string `mandatory:"true" contributesTo:"path" name:"drgAttachmentId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteDrgAttachmentRequest) String() string { + return common.PointerString(request) +} + +// DeleteDrgAttachmentResponse wrapper for the DeleteDrgAttachment operation +type DeleteDrgAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteDrgAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_drg_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_drg_request_response.go new file mode 100644 index 000000000..225db2c44 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_drg_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteDrgRequest wrapper for the DeleteDrg operation +type DeleteDrgRequest struct { + + // The OCID of the DRG. + DrgId *string `mandatory:"true" contributesTo:"path" name:"drgId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteDrgRequest) String() string { + return common.PointerString(request) +} + +// DeleteDrgResponse wrapper for the DeleteDrg operation +type DeleteDrgResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteDrgResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_i_p_sec_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_i_p_sec_connection_request_response.go new file mode 100644 index 000000000..47a19acff --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_i_p_sec_connection_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteIPSecConnectionRequest wrapper for the DeleteIPSecConnection operation +type DeleteIPSecConnectionRequest struct { + + // The OCID of the IPSec connection. + IpscId *string `mandatory:"true" contributesTo:"path" name:"ipscId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteIPSecConnectionRequest) String() string { + return common.PointerString(request) +} + +// DeleteIPSecConnectionResponse wrapper for the DeleteIPSecConnection operation +type DeleteIPSecConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteIPSecConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_image_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_image_request_response.go new file mode 100644 index 000000000..f7c0a2b7f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_image_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteImageRequest wrapper for the DeleteImage operation +type DeleteImageRequest struct { + + // The OCID of the image. + ImageId *string `mandatory:"true" contributesTo:"path" name:"imageId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteImageRequest) String() string { + return common.PointerString(request) +} + +// DeleteImageResponse wrapper for the DeleteImage operation +type DeleteImageResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteImageResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_instance_console_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_instance_console_connection_request_response.go new file mode 100644 index 000000000..126d52c84 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_instance_console_connection_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteInstanceConsoleConnectionRequest wrapper for the DeleteInstanceConsoleConnection operation +type DeleteInstanceConsoleConnectionRequest struct { + + // The OCID of the intance console connection + InstanceConsoleConnectionId *string `mandatory:"true" contributesTo:"path" name:"instanceConsoleConnectionId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteInstanceConsoleConnectionRequest) String() string { + return common.PointerString(request) +} + +// DeleteInstanceConsoleConnectionResponse wrapper for the DeleteInstanceConsoleConnection operation +type DeleteInstanceConsoleConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteInstanceConsoleConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_internet_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_internet_gateway_request_response.go new file mode 100644 index 000000000..e1c2fcf27 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_internet_gateway_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteInternetGatewayRequest wrapper for the DeleteInternetGateway operation +type DeleteInternetGatewayRequest struct { + + // The OCID of the Internet Gateway. + IgId *string `mandatory:"true" contributesTo:"path" name:"igId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteInternetGatewayRequest) String() string { + return common.PointerString(request) +} + +// DeleteInternetGatewayResponse wrapper for the DeleteInternetGateway operation +type DeleteInternetGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteInternetGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_local_peering_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_local_peering_gateway_request_response.go new file mode 100644 index 000000000..312cd7485 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_local_peering_gateway_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteLocalPeeringGatewayRequest wrapper for the DeleteLocalPeeringGateway operation +type DeleteLocalPeeringGatewayRequest struct { + + // The OCID of the local peering gateway. + LocalPeeringGatewayId *string `mandatory:"true" contributesTo:"path" name:"localPeeringGatewayId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteLocalPeeringGatewayRequest) String() string { + return common.PointerString(request) +} + +// DeleteLocalPeeringGatewayResponse wrapper for the DeleteLocalPeeringGateway operation +type DeleteLocalPeeringGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteLocalPeeringGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_private_ip_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_private_ip_request_response.go new file mode 100644 index 000000000..6994c1320 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_private_ip_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeletePrivateIpRequest wrapper for the DeletePrivateIp operation +type DeletePrivateIpRequest struct { + + // The private IP's OCID. + PrivateIpId *string `mandatory:"true" contributesTo:"path" name:"privateIpId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeletePrivateIpRequest) String() string { + return common.PointerString(request) +} + +// DeletePrivateIpResponse wrapper for the DeletePrivateIp operation +type DeletePrivateIpResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeletePrivateIpResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_route_table_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_route_table_request_response.go new file mode 100644 index 000000000..79cf5fee0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_route_table_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteRouteTableRequest wrapper for the DeleteRouteTable operation +type DeleteRouteTableRequest struct { + + // The OCID of the route table. + RtId *string `mandatory:"true" contributesTo:"path" name:"rtId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteRouteTableRequest) String() string { + return common.PointerString(request) +} + +// DeleteRouteTableResponse wrapper for the DeleteRouteTable operation +type DeleteRouteTableResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteRouteTableResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_security_list_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_security_list_request_response.go new file mode 100644 index 000000000..6fccea27e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_security_list_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteSecurityListRequest wrapper for the DeleteSecurityList operation +type DeleteSecurityListRequest struct { + + // The OCID of the security list. + SecurityListId *string `mandatory:"true" contributesTo:"path" name:"securityListId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteSecurityListRequest) String() string { + return common.PointerString(request) +} + +// DeleteSecurityListResponse wrapper for the DeleteSecurityList operation +type DeleteSecurityListResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteSecurityListResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_subnet_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_subnet_request_response.go new file mode 100644 index 000000000..cd198d893 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_subnet_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteSubnetRequest wrapper for the DeleteSubnet operation +type DeleteSubnetRequest struct { + + // The OCID of the subnet. + SubnetId *string `mandatory:"true" contributesTo:"path" name:"subnetId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteSubnetRequest) String() string { + return common.PointerString(request) +} + +// DeleteSubnetResponse wrapper for the DeleteSubnet operation +type DeleteSubnetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteSubnetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_vcn_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_vcn_request_response.go new file mode 100644 index 000000000..9e30cccc4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_vcn_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteVcnRequest wrapper for the DeleteVcn operation +type DeleteVcnRequest struct { + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"path" name:"vcnId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteVcnRequest) String() string { + return common.PointerString(request) +} + +// DeleteVcnResponse wrapper for the DeleteVcn operation +type DeleteVcnResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteVcnResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_public_prefix_details.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_public_prefix_details.go new file mode 100644 index 000000000..cea9aca23 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_public_prefix_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DeleteVirtualCircuitPublicPrefixDetails The representation of DeleteVirtualCircuitPublicPrefixDetails +type DeleteVirtualCircuitPublicPrefixDetails struct { + + // An individual public IP prefix (CIDR) to remove from the public virtual circuit. + CidrBlock *string `mandatory:"true" json:"cidrBlock"` +} + +func (m DeleteVirtualCircuitPublicPrefixDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_request_response.go new file mode 100644 index 000000000..55caa0d27 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_virtual_circuit_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteVirtualCircuitRequest wrapper for the DeleteVirtualCircuit operation +type DeleteVirtualCircuitRequest struct { + + // The OCID of the virtual circuit. + VirtualCircuitId *string `mandatory:"true" contributesTo:"path" name:"virtualCircuitId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteVirtualCircuitRequest) String() string { + return common.PointerString(request) +} + +// DeleteVirtualCircuitResponse wrapper for the DeleteVirtualCircuit operation +type DeleteVirtualCircuitResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteVirtualCircuitResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_volume_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_volume_backup_request_response.go new file mode 100644 index 000000000..4c1e30354 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_volume_backup_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteVolumeBackupRequest wrapper for the DeleteVolumeBackup operation +type DeleteVolumeBackupRequest struct { + + // The OCID of the volume backup. + VolumeBackupId *string `mandatory:"true" contributesTo:"path" name:"volumeBackupId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteVolumeBackupRequest) String() string { + return common.PointerString(request) +} + +// DeleteVolumeBackupResponse wrapper for the DeleteVolumeBackup operation +type DeleteVolumeBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteVolumeBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/delete_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/delete_volume_request_response.go new file mode 100644 index 000000000..e9bfd8a60 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/delete_volume_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteVolumeRequest wrapper for the DeleteVolume operation +type DeleteVolumeRequest struct { + + // The OCID of the volume. + VolumeId *string `mandatory:"true" contributesTo:"path" name:"volumeId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteVolumeRequest) String() string { + return common.PointerString(request) +} + +// DeleteVolumeResponse wrapper for the DeleteVolume operation +type DeleteVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/detach_boot_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/detach_boot_volume_request_response.go new file mode 100644 index 000000000..5820949e9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/detach_boot_volume_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DetachBootVolumeRequest wrapper for the DetachBootVolume operation +type DetachBootVolumeRequest struct { + + // The OCID of the boot volume attachment. + BootVolumeAttachmentId *string `mandatory:"true" contributesTo:"path" name:"bootVolumeAttachmentId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DetachBootVolumeRequest) String() string { + return common.PointerString(request) +} + +// DetachBootVolumeResponse wrapper for the DetachBootVolume operation +type DetachBootVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DetachBootVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/detach_vnic_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/detach_vnic_request_response.go new file mode 100644 index 000000000..7f4bf5e93 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/detach_vnic_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DetachVnicRequest wrapper for the DetachVnic operation +type DetachVnicRequest struct { + + // The OCID of the VNIC attachment. + VnicAttachmentId *string `mandatory:"true" contributesTo:"path" name:"vnicAttachmentId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DetachVnicRequest) String() string { + return common.PointerString(request) +} + +// DetachVnicResponse wrapper for the DetachVnic operation +type DetachVnicResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DetachVnicResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/detach_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/detach_volume_request_response.go new file mode 100644 index 000000000..59188b434 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/detach_volume_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DetachVolumeRequest wrapper for the DetachVolume operation +type DetachVolumeRequest struct { + + // The OCID of the volume attachment. + VolumeAttachmentId *string `mandatory:"true" contributesTo:"path" name:"volumeAttachmentId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DetachVolumeRequest) String() string { + return common.PointerString(request) +} + +// DetachVolumeResponse wrapper for the DetachVolume operation +type DetachVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DetachVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/dhcp_dns_option.go b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_dns_option.go new file mode 100644 index 000000000..51237ca28 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_dns_option.go @@ -0,0 +1,81 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// DhcpDnsOption DHCP option for specifying how DNS (hostname resolution) is handled in the subnets in the VCN. +// For more information, see +// DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). +type DhcpDnsOption struct { + + // If you set `serverType` to `CustomDnsServer`, specify the IP address + // of at least one DNS server of your choice (three maximum). + CustomDnsServers []string `mandatory:"false" json:"customDnsServers"` + + // - **VcnLocal:** Reserved for future use. + // - **VcnLocalPlusInternet:** Also referred to as "Internet and VCN Resolver". + // Instances can resolve internet hostnames (no Internet Gateway is required), + // and can resolve hostnames of instances in the VCN. This is the default + // value in the default set of DHCP options in the VCN. For the Internet and + // VCN Resolver to work across the VCN, there must also be a DNS label set for + // the VCN, a DNS label set for each subnet, and a hostname for each instance. + // The Internet and VCN Resolver also enables reverse DNS lookup, which lets + // you determine the hostname corresponding to the private IP address. For more + // information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // - **CustomDnsServer:** Instances use a DNS server of your choice (three maximum). + ServerType DhcpDnsOptionServerTypeEnum `mandatory:"true" json:"serverType"` +} + +func (m DhcpDnsOption) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m DhcpDnsOption) MarshalJSON() (buff []byte, e error) { + type MarshalTypeDhcpDnsOption DhcpDnsOption + s := struct { + DiscriminatorParam string `json:"type"` + MarshalTypeDhcpDnsOption + }{ + "DomainNameServer", + (MarshalTypeDhcpDnsOption)(m), + } + + return json.Marshal(&s) +} + +// DhcpDnsOptionServerTypeEnum Enum with underlying type: string +type DhcpDnsOptionServerTypeEnum string + +// Set of constants representing the allowable values for DhcpDnsOptionServerType +const ( + DhcpDnsOptionServerTypeVcnlocal DhcpDnsOptionServerTypeEnum = "VcnLocal" + DhcpDnsOptionServerTypeVcnlocalplusinternet DhcpDnsOptionServerTypeEnum = "VcnLocalPlusInternet" + DhcpDnsOptionServerTypeCustomdnsserver DhcpDnsOptionServerTypeEnum = "CustomDnsServer" +) + +var mappingDhcpDnsOptionServerType = map[string]DhcpDnsOptionServerTypeEnum{ + "VcnLocal": DhcpDnsOptionServerTypeVcnlocal, + "VcnLocalPlusInternet": DhcpDnsOptionServerTypeVcnlocalplusinternet, + "CustomDnsServer": DhcpDnsOptionServerTypeCustomdnsserver, +} + +// GetDhcpDnsOptionServerTypeEnumValues Enumerates the set of values for DhcpDnsOptionServerType +func GetDhcpDnsOptionServerTypeEnumValues() []DhcpDnsOptionServerTypeEnum { + values := make([]DhcpDnsOptionServerTypeEnum, 0) + for _, v := range mappingDhcpDnsOptionServerType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/dhcp_option.go b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_option.go new file mode 100644 index 000000000..742f3411b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_option.go @@ -0,0 +1,64 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// DhcpOption A single DHCP option according to RFC 1533 (https://tools.ietf.org/html/rfc1533). +// The two options available to use are DhcpDnsOption +// and DhcpSearchDomainOption. For more +// information, see DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm) +// and DHCP Options (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDHCP.htm). +type DhcpOption interface { +} + +type dhcpoption struct { + JsonData []byte + Type string `json:"type"` +} + +// UnmarshalJSON unmarshals json +func (m *dhcpoption) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalerdhcpoption dhcpoption + s := struct { + Model Unmarshalerdhcpoption + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.Type = s.Model.Type + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *dhcpoption) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Type { + case "DomainNameServer": + mm := DhcpDnsOption{} + err = json.Unmarshal(data, &mm) + return mm, err + case "SearchDomain": + mm := DhcpSearchDomainOption{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +func (m dhcpoption) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/dhcp_options.go b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_options.go new file mode 100644 index 000000000..f96edd995 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_options.go @@ -0,0 +1,115 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// DhcpOptions A set of DHCP options. Used by the VCN to automatically provide configuration +// information to the instances when they boot up. There are two options you can set: +// - DhcpDnsOption: Lets you specify how DNS (hostname resolution) is +// handled in the subnets in your VCN. +// - DhcpSearchDomainOption: Lets you specify +// a search domain name to use for DNS queries. +// For more information, see DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm) +// and DHCP Options (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingDHCP.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DhcpOptions struct { + + // The OCID of the compartment containing the set of DHCP options. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Oracle ID (OCID) for the set of DHCP options. + Id *string `mandatory:"true" json:"id"` + + // The current state of the set of DHCP options. + LifecycleState DhcpOptionsLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The collection of individual DHCP options. + Options []DhcpOption `mandatory:"true" json:"options"` + + // Date and time the set of DHCP options was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the VCN the set of DHCP options belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m DhcpOptions) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *DhcpOptions) UnmarshalJSON(data []byte) (e error) { + model := struct { + DisplayName *string `json:"displayName"` + CompartmentId *string `json:"compartmentId"` + Id *string `json:"id"` + LifecycleState DhcpOptionsLifecycleStateEnum `json:"lifecycleState"` + Options []dhcpoption `json:"options"` + TimeCreated *common.SDKTime `json:"timeCreated"` + VcnId *string `json:"vcnId"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.DisplayName = model.DisplayName + m.CompartmentId = model.CompartmentId + m.Id = model.Id + m.LifecycleState = model.LifecycleState + m.Options = make([]DhcpOption, len(model.Options)) + for i, n := range model.Options { + nn, err := n.UnmarshalPolymorphicJSON(n.JsonData) + if err != nil { + return err + } + m.Options[i] = nn + } + m.TimeCreated = model.TimeCreated + m.VcnId = model.VcnId + return +} + +// DhcpOptionsLifecycleStateEnum Enum with underlying type: string +type DhcpOptionsLifecycleStateEnum string + +// Set of constants representing the allowable values for DhcpOptionsLifecycleState +const ( + DhcpOptionsLifecycleStateProvisioning DhcpOptionsLifecycleStateEnum = "PROVISIONING" + DhcpOptionsLifecycleStateAvailable DhcpOptionsLifecycleStateEnum = "AVAILABLE" + DhcpOptionsLifecycleStateTerminating DhcpOptionsLifecycleStateEnum = "TERMINATING" + DhcpOptionsLifecycleStateTerminated DhcpOptionsLifecycleStateEnum = "TERMINATED" +) + +var mappingDhcpOptionsLifecycleState = map[string]DhcpOptionsLifecycleStateEnum{ + "PROVISIONING": DhcpOptionsLifecycleStateProvisioning, + "AVAILABLE": DhcpOptionsLifecycleStateAvailable, + "TERMINATING": DhcpOptionsLifecycleStateTerminating, + "TERMINATED": DhcpOptionsLifecycleStateTerminated, +} + +// GetDhcpOptionsLifecycleStateEnumValues Enumerates the set of values for DhcpOptionsLifecycleState +func GetDhcpOptionsLifecycleStateEnumValues() []DhcpOptionsLifecycleStateEnum { + values := make([]DhcpOptionsLifecycleStateEnum, 0) + for _, v := range mappingDhcpOptionsLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/dhcp_search_domain_option.go b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_search_domain_option.go new file mode 100644 index 000000000..58968eb53 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/dhcp_search_domain_option.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// DhcpSearchDomainOption DHCP option for specifying a search domain name for DNS queries. For more information, see +// DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). +type DhcpSearchDomainOption struct { + + // A single search domain name according to RFC 952 (https://tools.ietf.org/html/rfc952) + // and RFC 1123 (https://tools.ietf.org/html/rfc1123). During a DNS query, + // the OS will append this search domain name to the value being queried. + // If you set DhcpDnsOption to `VcnLocalPlusInternet`, + // and you assign a DNS label to the VCN during creation, the search domain name in the + // VCN's default set of DHCP options is automatically set to the VCN domain + // (for example, `vcn1.oraclevcn.com`). + // If you don't want to use a search domain name, omit this option from the + // set of DHCP options. Do not include this option with an empty list + // of search domain names, or with an empty string as the value for any search + // domain name. + SearchDomainNames []string `mandatory:"true" json:"searchDomainNames"` +} + +func (m DhcpSearchDomainOption) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m DhcpSearchDomainOption) MarshalJSON() (buff []byte, e error) { + type MarshalTypeDhcpSearchDomainOption DhcpSearchDomainOption + s := struct { + DiscriminatorParam string `json:"type"` + MarshalTypeDhcpSearchDomainOption + }{ + "SearchDomain", + (MarshalTypeDhcpSearchDomainOption)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/drg.go b/vendor/github.com/oracle/oci-go-sdk/core/drg.go new file mode 100644 index 000000000..b87673bba --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/drg.go @@ -0,0 +1,72 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Drg A Dynamic Routing Gateway (DRG), which is a virtual router that provides a path for private +// network traffic between your VCN and your existing network. You use it with other Networking +// Service components to create an IPSec VPN or a connection that uses +// Oracle Cloud Infrastructure FastConnect. For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Drg struct { + + // The OCID of the compartment containing the DRG. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The DRG's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The DRG's current state. + LifecycleState DrgLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The date and time the DRG was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m Drg) String() string { + return common.PointerString(m) +} + +// DrgLifecycleStateEnum Enum with underlying type: string +type DrgLifecycleStateEnum string + +// Set of constants representing the allowable values for DrgLifecycleState +const ( + DrgLifecycleStateProvisioning DrgLifecycleStateEnum = "PROVISIONING" + DrgLifecycleStateAvailable DrgLifecycleStateEnum = "AVAILABLE" + DrgLifecycleStateTerminating DrgLifecycleStateEnum = "TERMINATING" + DrgLifecycleStateTerminated DrgLifecycleStateEnum = "TERMINATED" +) + +var mappingDrgLifecycleState = map[string]DrgLifecycleStateEnum{ + "PROVISIONING": DrgLifecycleStateProvisioning, + "AVAILABLE": DrgLifecycleStateAvailable, + "TERMINATING": DrgLifecycleStateTerminating, + "TERMINATED": DrgLifecycleStateTerminated, +} + +// GetDrgLifecycleStateEnumValues Enumerates the set of values for DrgLifecycleState +func GetDrgLifecycleStateEnumValues() []DrgLifecycleStateEnum { + values := make([]DrgLifecycleStateEnum, 0) + for _, v := range mappingDrgLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/drg_attachment.go b/vendor/github.com/oracle/oci-go-sdk/core/drg_attachment.go new file mode 100644 index 000000000..108763457 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/drg_attachment.go @@ -0,0 +1,72 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DrgAttachment A link between a DRG and VCN. For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +type DrgAttachment struct { + + // The OCID of the compartment containing the DRG attachment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the DRG. + DrgId *string `mandatory:"true" json:"drgId"` + + // The DRG attachment's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The DRG attachment's current state. + LifecycleState DrgAttachmentLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The date and time the DRG attachment was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m DrgAttachment) String() string { + return common.PointerString(m) +} + +// DrgAttachmentLifecycleStateEnum Enum with underlying type: string +type DrgAttachmentLifecycleStateEnum string + +// Set of constants representing the allowable values for DrgAttachmentLifecycleState +const ( + DrgAttachmentLifecycleStateAttaching DrgAttachmentLifecycleStateEnum = "ATTACHING" + DrgAttachmentLifecycleStateAttached DrgAttachmentLifecycleStateEnum = "ATTACHED" + DrgAttachmentLifecycleStateDetaching DrgAttachmentLifecycleStateEnum = "DETACHING" + DrgAttachmentLifecycleStateDetached DrgAttachmentLifecycleStateEnum = "DETACHED" +) + +var mappingDrgAttachmentLifecycleState = map[string]DrgAttachmentLifecycleStateEnum{ + "ATTACHING": DrgAttachmentLifecycleStateAttaching, + "ATTACHED": DrgAttachmentLifecycleStateAttached, + "DETACHING": DrgAttachmentLifecycleStateDetaching, + "DETACHED": DrgAttachmentLifecycleStateDetached, +} + +// GetDrgAttachmentLifecycleStateEnumValues Enumerates the set of values for DrgAttachmentLifecycleState +func GetDrgAttachmentLifecycleStateEnumValues() []DrgAttachmentLifecycleStateEnum { + values := make([]DrgAttachmentLifecycleStateEnum, 0) + for _, v := range mappingDrgAttachmentLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/egress_security_rule.go b/vendor/github.com/oracle/oci-go-sdk/core/egress_security_rule.go new file mode 100644 index 000000000..313470a2f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/egress_security_rule.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// EgressSecurityRule A rule for allowing outbound IP packets. +type EgressSecurityRule struct { + + // The destination CIDR block for the egress rule. This is the range of IP addresses that a + // packet originating from the instance can go to. + Destination *string `mandatory:"true" json:"destination"` + + // The transport protocol. Specify either `all` or an IPv4 protocol number as + // defined in + // Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). + // Options are supported only for ICMP ("1"), TCP ("6"), and UDP ("17"). + Protocol *string `mandatory:"true" json:"protocol"` + + // Optional and valid only for ICMP. Use to specify a particular ICMP type and code + // as defined in + // ICMP Parameters (http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml). + // If you specify ICMP as the protocol but omit this object, then all ICMP types and + // codes are allowed. If you do provide this object, the type is required and the code is optional. + // To enable MTU negotiation for ingress internet traffic, make sure to allow type 3 ("Destination + // Unreachable") code 4 ("Fragmentation Needed and Don't Fragment was Set"). If you need to specify + // multiple codes for a single type, create a separate security list rule for each. + IcmpOptions *IcmpOptions `mandatory:"false" json:"icmpOptions"` + + // A stateless rule allows traffic in one direction. Remember to add a corresponding + // stateless rule in the other direction if you need to support bidirectional traffic. For + // example, if egress traffic allows TCP destination port 80, there should be an ingress + // rule to allow TCP source port 80. Defaults to false, which means the rule is stateful + // and a corresponding rule is not necessary for bidirectional traffic. + IsStateless *bool `mandatory:"false" json:"isStateless"` + + // Optional and valid only for TCP. Use to specify particular destination ports for TCP rules. + // If you specify TCP as the protocol but omit this object, then all destination ports are allowed. + TcpOptions *TcpOptions `mandatory:"false" json:"tcpOptions"` + + // Optional and valid only for UDP. Use to specify particular destination ports for UDP rules. + // If you specify UDP as the protocol but omit this object, then all destination ports are allowed. + UdpOptions *UdpOptions `mandatory:"false" json:"udpOptions"` +} + +func (m EgressSecurityRule) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/export_image_details.go b/vendor/github.com/oracle/oci-go-sdk/core/export_image_details.go new file mode 100644 index 000000000..f066a58a7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/export_image_details.go @@ -0,0 +1,66 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// ExportImageDetails The destination details for the image export. +// Set `destinationType` to `objectStorageTuple` +// and use ExportImageViaObjectStorageTupleDetails +// when specifying the namespace, bucket name, and object name. +// Set `destinationType` to `objectStorageUri` and +// use ExportImageViaObjectStorageUriDetails +// when specifying the Object Storage URL. +type ExportImageDetails interface { +} + +type exportimagedetails struct { + JsonData []byte + DestinationType string `json:"destinationType"` +} + +// UnmarshalJSON unmarshals json +func (m *exportimagedetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalerexportimagedetails exportimagedetails + s := struct { + Model Unmarshalerexportimagedetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.DestinationType = s.Model.DestinationType + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *exportimagedetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.DestinationType { + case "objectStorageUri": + mm := ExportImageViaObjectStorageUriDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + case "objectStorageTuple": + mm := ExportImageViaObjectStorageTupleDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +func (m exportimagedetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/export_image_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/export_image_request_response.go new file mode 100644 index 000000000..4ecb1a3ce --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/export_image_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ExportImageRequest wrapper for the ExportImage operation +type ExportImageRequest struct { + + // The OCID of the image. + ImageId *string `mandatory:"true" contributesTo:"path" name:"imageId"` + + // Details for the image export. + ExportImageDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request ExportImageRequest) String() string { + return common.PointerString(request) +} + +// ExportImageResponse wrapper for the ExportImage operation +type ExportImageResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Image instance + Image `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ExportImageResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_tuple_details.go b/vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_tuple_details.go new file mode 100644 index 000000000..39d08873f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_tuple_details.go @@ -0,0 +1,45 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// ExportImageViaObjectStorageTupleDetails The representation of ExportImageViaObjectStorageTupleDetails +type ExportImageViaObjectStorageTupleDetails struct { + + // The Object Storage bucket to export the image to. + BucketName *string `mandatory:"false" json:"bucketName"` + + // The Object Storage namespace to export the image to. + NamespaceName *string `mandatory:"false" json:"namespaceName"` + + // The Object Storage object name for the exported image. + ObjectName *string `mandatory:"false" json:"objectName"` +} + +func (m ExportImageViaObjectStorageTupleDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m ExportImageViaObjectStorageTupleDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeExportImageViaObjectStorageTupleDetails ExportImageViaObjectStorageTupleDetails + s := struct { + DiscriminatorParam string `json:"destinationType"` + MarshalTypeExportImageViaObjectStorageTupleDetails + }{ + "objectStorageTuple", + (MarshalTypeExportImageViaObjectStorageTupleDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_uri_details.go b/vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_uri_details.go new file mode 100644 index 000000000..5a44a21a6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/export_image_via_object_storage_uri_details.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// ExportImageViaObjectStorageUriDetails The representation of ExportImageViaObjectStorageUriDetails +type ExportImageViaObjectStorageUriDetails struct { + + // The Object Storage URL to export the image to. See Object Storage URLs (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/imageimportexport.htm#URLs) + // and pre-authenticated requests (https://docs.us-phoenix-1.oraclecloud.com/Content/Object/Tasks/managingaccess.htm#pre-auth) for constructing URLs for image import/export. + DestinationUri *string `mandatory:"true" json:"destinationUri"` +} + +func (m ExportImageViaObjectStorageUriDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m ExportImageViaObjectStorageUriDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeExportImageViaObjectStorageUriDetails ExportImageViaObjectStorageUriDetails + s := struct { + DiscriminatorParam string `json:"destinationType"` + MarshalTypeExportImageViaObjectStorageUriDetails + }{ + "objectStorageUri", + (MarshalTypeExportImageViaObjectStorageUriDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/fast_connect_provider_service.go b/vendor/github.com/oracle/oci-go-sdk/core/fast_connect_provider_service.go new file mode 100644 index 000000000..1b8dcca1d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/fast_connect_provider_service.go @@ -0,0 +1,142 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// FastConnectProviderService A service offering from a supported provider. For more information, +// see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +type FastConnectProviderService struct { + + // The OCID of the service offered by the provider. + Id *string `mandatory:"true" json:"id"` + + // Private peering BGP management. + PrivatePeeringBgpManagement FastConnectProviderServicePrivatePeeringBgpManagementEnum `mandatory:"true" json:"privatePeeringBgpManagement"` + + // The name of the provider. + ProviderName *string `mandatory:"true" json:"providerName"` + + // The name of the service offered by the provider. + ProviderServiceName *string `mandatory:"true" json:"providerServiceName"` + + // Public peering BGP management. + PublicPeeringBgpManagement FastConnectProviderServicePublicPeeringBgpManagementEnum `mandatory:"true" json:"publicPeeringBgpManagement"` + + // Provider service type. + Type FastConnectProviderServiceTypeEnum `mandatory:"true" json:"type"` + + // A description of the service offered by the provider. + Description *string `mandatory:"false" json:"description"` + + // An array of virtual circuit types supported by this service. + SupportedVirtualCircuitTypes []FastConnectProviderServiceSupportedVirtualCircuitTypesEnum `mandatory:"false" json:"supportedVirtualCircuitTypes,omitempty"` +} + +func (m FastConnectProviderService) String() string { + return common.PointerString(m) +} + +// FastConnectProviderServicePrivatePeeringBgpManagementEnum Enum with underlying type: string +type FastConnectProviderServicePrivatePeeringBgpManagementEnum string + +// Set of constants representing the allowable values for FastConnectProviderServicePrivatePeeringBgpManagement +const ( + FastConnectProviderServicePrivatePeeringBgpManagementCustomerManaged FastConnectProviderServicePrivatePeeringBgpManagementEnum = "CUSTOMER_MANAGED" + FastConnectProviderServicePrivatePeeringBgpManagementProviderManaged FastConnectProviderServicePrivatePeeringBgpManagementEnum = "PROVIDER_MANAGED" + FastConnectProviderServicePrivatePeeringBgpManagementOracleManaged FastConnectProviderServicePrivatePeeringBgpManagementEnum = "ORACLE_MANAGED" +) + +var mappingFastConnectProviderServicePrivatePeeringBgpManagement = map[string]FastConnectProviderServicePrivatePeeringBgpManagementEnum{ + "CUSTOMER_MANAGED": FastConnectProviderServicePrivatePeeringBgpManagementCustomerManaged, + "PROVIDER_MANAGED": FastConnectProviderServicePrivatePeeringBgpManagementProviderManaged, + "ORACLE_MANAGED": FastConnectProviderServicePrivatePeeringBgpManagementOracleManaged, +} + +// GetFastConnectProviderServicePrivatePeeringBgpManagementEnumValues Enumerates the set of values for FastConnectProviderServicePrivatePeeringBgpManagement +func GetFastConnectProviderServicePrivatePeeringBgpManagementEnumValues() []FastConnectProviderServicePrivatePeeringBgpManagementEnum { + values := make([]FastConnectProviderServicePrivatePeeringBgpManagementEnum, 0) + for _, v := range mappingFastConnectProviderServicePrivatePeeringBgpManagement { + values = append(values, v) + } + return values +} + +// FastConnectProviderServicePublicPeeringBgpManagementEnum Enum with underlying type: string +type FastConnectProviderServicePublicPeeringBgpManagementEnum string + +// Set of constants representing the allowable values for FastConnectProviderServicePublicPeeringBgpManagement +const ( + FastConnectProviderServicePublicPeeringBgpManagementCustomerManaged FastConnectProviderServicePublicPeeringBgpManagementEnum = "CUSTOMER_MANAGED" + FastConnectProviderServicePublicPeeringBgpManagementProviderManaged FastConnectProviderServicePublicPeeringBgpManagementEnum = "PROVIDER_MANAGED" + FastConnectProviderServicePublicPeeringBgpManagementOracleManaged FastConnectProviderServicePublicPeeringBgpManagementEnum = "ORACLE_MANAGED" +) + +var mappingFastConnectProviderServicePublicPeeringBgpManagement = map[string]FastConnectProviderServicePublicPeeringBgpManagementEnum{ + "CUSTOMER_MANAGED": FastConnectProviderServicePublicPeeringBgpManagementCustomerManaged, + "PROVIDER_MANAGED": FastConnectProviderServicePublicPeeringBgpManagementProviderManaged, + "ORACLE_MANAGED": FastConnectProviderServicePublicPeeringBgpManagementOracleManaged, +} + +// GetFastConnectProviderServicePublicPeeringBgpManagementEnumValues Enumerates the set of values for FastConnectProviderServicePublicPeeringBgpManagement +func GetFastConnectProviderServicePublicPeeringBgpManagementEnumValues() []FastConnectProviderServicePublicPeeringBgpManagementEnum { + values := make([]FastConnectProviderServicePublicPeeringBgpManagementEnum, 0) + for _, v := range mappingFastConnectProviderServicePublicPeeringBgpManagement { + values = append(values, v) + } + return values +} + +// FastConnectProviderServiceSupportedVirtualCircuitTypesEnum Enum with underlying type: string +type FastConnectProviderServiceSupportedVirtualCircuitTypesEnum string + +// Set of constants representing the allowable values for FastConnectProviderServiceSupportedVirtualCircuitTypes +const ( + FastConnectProviderServiceSupportedVirtualCircuitTypesPublic FastConnectProviderServiceSupportedVirtualCircuitTypesEnum = "PUBLIC" + FastConnectProviderServiceSupportedVirtualCircuitTypesPrivate FastConnectProviderServiceSupportedVirtualCircuitTypesEnum = "PRIVATE" +) + +var mappingFastConnectProviderServiceSupportedVirtualCircuitTypes = map[string]FastConnectProviderServiceSupportedVirtualCircuitTypesEnum{ + "PUBLIC": FastConnectProviderServiceSupportedVirtualCircuitTypesPublic, + "PRIVATE": FastConnectProviderServiceSupportedVirtualCircuitTypesPrivate, +} + +// GetFastConnectProviderServiceSupportedVirtualCircuitTypesEnumValues Enumerates the set of values for FastConnectProviderServiceSupportedVirtualCircuitTypes +func GetFastConnectProviderServiceSupportedVirtualCircuitTypesEnumValues() []FastConnectProviderServiceSupportedVirtualCircuitTypesEnum { + values := make([]FastConnectProviderServiceSupportedVirtualCircuitTypesEnum, 0) + for _, v := range mappingFastConnectProviderServiceSupportedVirtualCircuitTypes { + values = append(values, v) + } + return values +} + +// FastConnectProviderServiceTypeEnum Enum with underlying type: string +type FastConnectProviderServiceTypeEnum string + +// Set of constants representing the allowable values for FastConnectProviderServiceType +const ( + FastConnectProviderServiceTypeLayer2 FastConnectProviderServiceTypeEnum = "LAYER2" + FastConnectProviderServiceTypeLayer3 FastConnectProviderServiceTypeEnum = "LAYER3" +) + +var mappingFastConnectProviderServiceType = map[string]FastConnectProviderServiceTypeEnum{ + "LAYER2": FastConnectProviderServiceTypeLayer2, + "LAYER3": FastConnectProviderServiceTypeLayer3, +} + +// GetFastConnectProviderServiceTypeEnumValues Enumerates the set of values for FastConnectProviderServiceType +func GetFastConnectProviderServiceTypeEnumValues() []FastConnectProviderServiceTypeEnum { + values := make([]FastConnectProviderServiceTypeEnum, 0) + for _, v := range mappingFastConnectProviderServiceType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_attachment_request_response.go new file mode 100644 index 000000000..e14e9201b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_attachment_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBootVolumeAttachmentRequest wrapper for the GetBootVolumeAttachment operation +type GetBootVolumeAttachmentRequest struct { + + // The OCID of the boot volume attachment. + BootVolumeAttachmentId *string `mandatory:"true" contributesTo:"path" name:"bootVolumeAttachmentId"` +} + +func (request GetBootVolumeAttachmentRequest) String() string { + return common.PointerString(request) +} + +// GetBootVolumeAttachmentResponse wrapper for the GetBootVolumeAttachment operation +type GetBootVolumeAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BootVolumeAttachment instance + BootVolumeAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBootVolumeAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_request_response.go new file mode 100644 index 000000000..95c3d0909 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_boot_volume_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBootVolumeRequest wrapper for the GetBootVolume operation +type GetBootVolumeRequest struct { + + // The OCID of the boot volume. + BootVolumeId *string `mandatory:"true" contributesTo:"path" name:"bootVolumeId"` +} + +func (request GetBootVolumeRequest) String() string { + return common.PointerString(request) +} + +// GetBootVolumeResponse wrapper for the GetBootVolume operation +type GetBootVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BootVolume instance + BootVolume `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBootVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_console_history_content_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_console_history_content_request_response.go new file mode 100644 index 000000000..4fc8e50ba --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_console_history_content_request_response.go @@ -0,0 +1,47 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetConsoleHistoryContentRequest wrapper for the GetConsoleHistoryContent operation +type GetConsoleHistoryContentRequest struct { + + // The OCID of the console history. + InstanceConsoleHistoryId *string `mandatory:"true" contributesTo:"path" name:"instanceConsoleHistoryId"` + + // Offset of the snapshot data to retrieve. + Offset *int `mandatory:"false" contributesTo:"query" name:"offset"` + + // Length of the snapshot data to retrieve. + Length *int `mandatory:"false" contributesTo:"query" name:"length"` +} + +func (request GetConsoleHistoryContentRequest) String() string { + return common.PointerString(request) +} + +// GetConsoleHistoryContentResponse wrapper for the GetConsoleHistoryContent operation +type GetConsoleHistoryContentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The string instance + Value *string `presentIn:"body" encoding:"plain-text"` + + // The number of bytes remaining in the snapshot. + OpcBytesRemaining *int `presentIn:"header" name:"opc-bytes-remaining"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetConsoleHistoryContentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_console_history_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_console_history_request_response.go new file mode 100644 index 000000000..b5aa9eb38 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_console_history_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetConsoleHistoryRequest wrapper for the GetConsoleHistory operation +type GetConsoleHistoryRequest struct { + + // The OCID of the console history. + InstanceConsoleHistoryId *string `mandatory:"true" contributesTo:"path" name:"instanceConsoleHistoryId"` +} + +func (request GetConsoleHistoryRequest) String() string { + return common.PointerString(request) +} + +// GetConsoleHistoryResponse wrapper for the GetConsoleHistory operation +type GetConsoleHistoryResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The ConsoleHistory instance + ConsoleHistory `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetConsoleHistoryResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_cpe_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_cpe_request_response.go new file mode 100644 index 000000000..0ed76a7f9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_cpe_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetCpeRequest wrapper for the GetCpe operation +type GetCpeRequest struct { + + // The OCID of the CPE. + CpeId *string `mandatory:"true" contributesTo:"path" name:"cpeId"` +} + +func (request GetCpeRequest) String() string { + return common.PointerString(request) +} + +// GetCpeResponse wrapper for the GetCpe operation +type GetCpeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Cpe instance + Cpe `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetCpeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_group_request_response.go new file mode 100644 index 000000000..fd3d8803e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_group_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetCrossConnectGroupRequest wrapper for the GetCrossConnectGroup operation +type GetCrossConnectGroupRequest struct { + + // The OCID of the cross-connect group. + CrossConnectGroupId *string `mandatory:"true" contributesTo:"path" name:"crossConnectGroupId"` +} + +func (request GetCrossConnectGroupRequest) String() string { + return common.PointerString(request) +} + +// GetCrossConnectGroupResponse wrapper for the GetCrossConnectGroup operation +type GetCrossConnectGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnectGroup instance + CrossConnectGroup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetCrossConnectGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_letter_of_authority_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_letter_of_authority_request_response.go new file mode 100644 index 000000000..674ea1f19 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_letter_of_authority_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetCrossConnectLetterOfAuthorityRequest wrapper for the GetCrossConnectLetterOfAuthority operation +type GetCrossConnectLetterOfAuthorityRequest struct { + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"true" contributesTo:"path" name:"crossConnectId"` +} + +func (request GetCrossConnectLetterOfAuthorityRequest) String() string { + return common.PointerString(request) +} + +// GetCrossConnectLetterOfAuthorityResponse wrapper for the GetCrossConnectLetterOfAuthority operation +type GetCrossConnectLetterOfAuthorityResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The LetterOfAuthority instance + LetterOfAuthority `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetCrossConnectLetterOfAuthorityResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_request_response.go new file mode 100644 index 000000000..b505c6ad5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetCrossConnectRequest wrapper for the GetCrossConnect operation +type GetCrossConnectRequest struct { + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"true" contributesTo:"path" name:"crossConnectId"` +} + +func (request GetCrossConnectRequest) String() string { + return common.PointerString(request) +} + +// GetCrossConnectResponse wrapper for the GetCrossConnect operation +type GetCrossConnectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnect instance + CrossConnect `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetCrossConnectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_status_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_status_request_response.go new file mode 100644 index 000000000..cf826242e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_cross_connect_status_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetCrossConnectStatusRequest wrapper for the GetCrossConnectStatus operation +type GetCrossConnectStatusRequest struct { + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"true" contributesTo:"path" name:"crossConnectId"` +} + +func (request GetCrossConnectStatusRequest) String() string { + return common.PointerString(request) +} + +// GetCrossConnectStatusResponse wrapper for the GetCrossConnectStatus operation +type GetCrossConnectStatusResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnectStatus instance + CrossConnectStatus `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetCrossConnectStatusResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_dhcp_options_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_dhcp_options_request_response.go new file mode 100644 index 000000000..72f46761c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_dhcp_options_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDhcpOptionsRequest wrapper for the GetDhcpOptions operation +type GetDhcpOptionsRequest struct { + + // The OCID for the set of DHCP options. + DhcpId *string `mandatory:"true" contributesTo:"path" name:"dhcpId"` +} + +func (request GetDhcpOptionsRequest) String() string { + return common.PointerString(request) +} + +// GetDhcpOptionsResponse wrapper for the GetDhcpOptions operation +type GetDhcpOptionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DhcpOptions instance + DhcpOptions `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDhcpOptionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_drg_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_drg_attachment_request_response.go new file mode 100644 index 000000000..b485721ae --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_drg_attachment_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDrgAttachmentRequest wrapper for the GetDrgAttachment operation +type GetDrgAttachmentRequest struct { + + // The OCID of the DRG attachment. + DrgAttachmentId *string `mandatory:"true" contributesTo:"path" name:"drgAttachmentId"` +} + +func (request GetDrgAttachmentRequest) String() string { + return common.PointerString(request) +} + +// GetDrgAttachmentResponse wrapper for the GetDrgAttachment operation +type GetDrgAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DrgAttachment instance + DrgAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDrgAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_drg_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_drg_request_response.go new file mode 100644 index 000000000..4488accfc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_drg_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDrgRequest wrapper for the GetDrg operation +type GetDrgRequest struct { + + // The OCID of the DRG. + DrgId *string `mandatory:"true" contributesTo:"path" name:"drgId"` +} + +func (request GetDrgRequest) String() string { + return common.PointerString(request) +} + +// GetDrgResponse wrapper for the GetDrg operation +type GetDrgResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Drg instance + Drg `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDrgResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_fast_connect_provider_service_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_fast_connect_provider_service_request_response.go new file mode 100644 index 000000000..28b352403 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_fast_connect_provider_service_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetFastConnectProviderServiceRequest wrapper for the GetFastConnectProviderService operation +type GetFastConnectProviderServiceRequest struct { + + // The OCID of the provider service. + ProviderServiceId *string `mandatory:"true" contributesTo:"path" name:"providerServiceId"` +} + +func (request GetFastConnectProviderServiceRequest) String() string { + return common.PointerString(request) +} + +// GetFastConnectProviderServiceResponse wrapper for the GetFastConnectProviderService operation +type GetFastConnectProviderServiceResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The FastConnectProviderService instance + FastConnectProviderService `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetFastConnectProviderServiceResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_config_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_config_request_response.go new file mode 100644 index 000000000..a41b69aed --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_config_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetIPSecConnectionDeviceConfigRequest wrapper for the GetIPSecConnectionDeviceConfig operation +type GetIPSecConnectionDeviceConfigRequest struct { + + // The OCID of the IPSec connection. + IpscId *string `mandatory:"true" contributesTo:"path" name:"ipscId"` +} + +func (request GetIPSecConnectionDeviceConfigRequest) String() string { + return common.PointerString(request) +} + +// GetIPSecConnectionDeviceConfigResponse wrapper for the GetIPSecConnectionDeviceConfig operation +type GetIPSecConnectionDeviceConfigResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IpSecConnectionDeviceConfig instance + IpSecConnectionDeviceConfig `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetIPSecConnectionDeviceConfigResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_status_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_status_request_response.go new file mode 100644 index 000000000..c3fbde11d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_device_status_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetIPSecConnectionDeviceStatusRequest wrapper for the GetIPSecConnectionDeviceStatus operation +type GetIPSecConnectionDeviceStatusRequest struct { + + // The OCID of the IPSec connection. + IpscId *string `mandatory:"true" contributesTo:"path" name:"ipscId"` +} + +func (request GetIPSecConnectionDeviceStatusRequest) String() string { + return common.PointerString(request) +} + +// GetIPSecConnectionDeviceStatusResponse wrapper for the GetIPSecConnectionDeviceStatus operation +type GetIPSecConnectionDeviceStatusResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IpSecConnectionDeviceStatus instance + IpSecConnectionDeviceStatus `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetIPSecConnectionDeviceStatusResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_request_response.go new file mode 100644 index 000000000..1ba8d86d0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_i_p_sec_connection_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetIPSecConnectionRequest wrapper for the GetIPSecConnection operation +type GetIPSecConnectionRequest struct { + + // The OCID of the IPSec connection. + IpscId *string `mandatory:"true" contributesTo:"path" name:"ipscId"` +} + +func (request GetIPSecConnectionRequest) String() string { + return common.PointerString(request) +} + +// GetIPSecConnectionResponse wrapper for the GetIPSecConnection operation +type GetIPSecConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IpSecConnection instance + IpSecConnection `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetIPSecConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_image_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_image_request_response.go new file mode 100644 index 000000000..9c64a2429 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_image_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetImageRequest wrapper for the GetImage operation +type GetImageRequest struct { + + // The OCID of the image. + ImageId *string `mandatory:"true" contributesTo:"path" name:"imageId"` +} + +func (request GetImageRequest) String() string { + return common.PointerString(request) +} + +// GetImageResponse wrapper for the GetImage operation +type GetImageResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Image instance + Image `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetImageResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_instance_console_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_instance_console_connection_request_response.go new file mode 100644 index 000000000..c90d9c464 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_instance_console_connection_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetInstanceConsoleConnectionRequest wrapper for the GetInstanceConsoleConnection operation +type GetInstanceConsoleConnectionRequest struct { + + // The OCID of the intance console connection + InstanceConsoleConnectionId *string `mandatory:"true" contributesTo:"path" name:"instanceConsoleConnectionId"` +} + +func (request GetInstanceConsoleConnectionRequest) String() string { + return common.PointerString(request) +} + +// GetInstanceConsoleConnectionResponse wrapper for the GetInstanceConsoleConnection operation +type GetInstanceConsoleConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The InstanceConsoleConnection instance + InstanceConsoleConnection `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetInstanceConsoleConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_instance_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_instance_request_response.go new file mode 100644 index 000000000..8619c5ade --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_instance_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetInstanceRequest wrapper for the GetInstance operation +type GetInstanceRequest struct { + + // The OCID of the instance. + InstanceId *string `mandatory:"true" contributesTo:"path" name:"instanceId"` +} + +func (request GetInstanceRequest) String() string { + return common.PointerString(request) +} + +// GetInstanceResponse wrapper for the GetInstance operation +type GetInstanceResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Instance instance + Instance `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetInstanceResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_internet_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_internet_gateway_request_response.go new file mode 100644 index 000000000..61423dffb --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_internet_gateway_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetInternetGatewayRequest wrapper for the GetInternetGateway operation +type GetInternetGatewayRequest struct { + + // The OCID of the Internet Gateway. + IgId *string `mandatory:"true" contributesTo:"path" name:"igId"` +} + +func (request GetInternetGatewayRequest) String() string { + return common.PointerString(request) +} + +// GetInternetGatewayResponse wrapper for the GetInternetGateway operation +type GetInternetGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The InternetGateway instance + InternetGateway `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetInternetGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_local_peering_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_local_peering_gateway_request_response.go new file mode 100644 index 000000000..3a04a7c17 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_local_peering_gateway_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetLocalPeeringGatewayRequest wrapper for the GetLocalPeeringGateway operation +type GetLocalPeeringGatewayRequest struct { + + // The OCID of the local peering gateway. + LocalPeeringGatewayId *string `mandatory:"true" contributesTo:"path" name:"localPeeringGatewayId"` +} + +func (request GetLocalPeeringGatewayRequest) String() string { + return common.PointerString(request) +} + +// GetLocalPeeringGatewayResponse wrapper for the GetLocalPeeringGateway operation +type GetLocalPeeringGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The LocalPeeringGateway instance + LocalPeeringGateway `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetLocalPeeringGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_private_ip_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_private_ip_request_response.go new file mode 100644 index 000000000..778c771bf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_private_ip_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetPrivateIpRequest wrapper for the GetPrivateIp operation +type GetPrivateIpRequest struct { + + // The private IP's OCID. + PrivateIpId *string `mandatory:"true" contributesTo:"path" name:"privateIpId"` +} + +func (request GetPrivateIpRequest) String() string { + return common.PointerString(request) +} + +// GetPrivateIpResponse wrapper for the GetPrivateIp operation +type GetPrivateIpResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PrivateIp instance + PrivateIp `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetPrivateIpResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_route_table_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_route_table_request_response.go new file mode 100644 index 000000000..f74bee61b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_route_table_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetRouteTableRequest wrapper for the GetRouteTable operation +type GetRouteTableRequest struct { + + // The OCID of the route table. + RtId *string `mandatory:"true" contributesTo:"path" name:"rtId"` +} + +func (request GetRouteTableRequest) String() string { + return common.PointerString(request) +} + +// GetRouteTableResponse wrapper for the GetRouteTable operation +type GetRouteTableResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The RouteTable instance + RouteTable `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetRouteTableResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_security_list_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_security_list_request_response.go new file mode 100644 index 000000000..a62a52d89 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_security_list_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetSecurityListRequest wrapper for the GetSecurityList operation +type GetSecurityListRequest struct { + + // The OCID of the security list. + SecurityListId *string `mandatory:"true" contributesTo:"path" name:"securityListId"` +} + +func (request GetSecurityListRequest) String() string { + return common.PointerString(request) +} + +// GetSecurityListResponse wrapper for the GetSecurityList operation +type GetSecurityListResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The SecurityList instance + SecurityList `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetSecurityListResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_subnet_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_subnet_request_response.go new file mode 100644 index 000000000..a8ffa4c10 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_subnet_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetSubnetRequest wrapper for the GetSubnet operation +type GetSubnetRequest struct { + + // The OCID of the subnet. + SubnetId *string `mandatory:"true" contributesTo:"path" name:"subnetId"` +} + +func (request GetSubnetRequest) String() string { + return common.PointerString(request) +} + +// GetSubnetResponse wrapper for the GetSubnet operation +type GetSubnetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Subnet instance + Subnet `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetSubnetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_vcn_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_vcn_request_response.go new file mode 100644 index 000000000..5696f7c3f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_vcn_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVcnRequest wrapper for the GetVcn operation +type GetVcnRequest struct { + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"path" name:"vcnId"` +} + +func (request GetVcnRequest) String() string { + return common.PointerString(request) +} + +// GetVcnResponse wrapper for the GetVcn operation +type GetVcnResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Vcn instance + Vcn `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVcnResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_virtual_circuit_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_virtual_circuit_request_response.go new file mode 100644 index 000000000..85ac11259 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_virtual_circuit_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVirtualCircuitRequest wrapper for the GetVirtualCircuit operation +type GetVirtualCircuitRequest struct { + + // The OCID of the virtual circuit. + VirtualCircuitId *string `mandatory:"true" contributesTo:"path" name:"virtualCircuitId"` +} + +func (request GetVirtualCircuitRequest) String() string { + return common.PointerString(request) +} + +// GetVirtualCircuitResponse wrapper for the GetVirtualCircuit operation +type GetVirtualCircuitResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VirtualCircuit instance + VirtualCircuit `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVirtualCircuitResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_vnic_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_vnic_attachment_request_response.go new file mode 100644 index 000000000..3c0e62d0e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_vnic_attachment_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVnicAttachmentRequest wrapper for the GetVnicAttachment operation +type GetVnicAttachmentRequest struct { + + // The OCID of the VNIC attachment. + VnicAttachmentId *string `mandatory:"true" contributesTo:"path" name:"vnicAttachmentId"` +} + +func (request GetVnicAttachmentRequest) String() string { + return common.PointerString(request) +} + +// GetVnicAttachmentResponse wrapper for the GetVnicAttachment operation +type GetVnicAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VnicAttachment instance + VnicAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVnicAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_vnic_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_vnic_request_response.go new file mode 100644 index 000000000..6f52d96c5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_vnic_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVnicRequest wrapper for the GetVnic operation +type GetVnicRequest struct { + + // The OCID of the VNIC. + VnicId *string `mandatory:"true" contributesTo:"path" name:"vnicId"` +} + +func (request GetVnicRequest) String() string { + return common.PointerString(request) +} + +// GetVnicResponse wrapper for the GetVnic operation +type GetVnicResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Vnic instance + Vnic `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVnicResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_volume_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_volume_attachment_request_response.go new file mode 100644 index 000000000..e9492439f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_volume_attachment_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVolumeAttachmentRequest wrapper for the GetVolumeAttachment operation +type GetVolumeAttachmentRequest struct { + + // The OCID of the volume attachment. + VolumeAttachmentId *string `mandatory:"true" contributesTo:"path" name:"volumeAttachmentId"` +} + +func (request GetVolumeAttachmentRequest) String() string { + return common.PointerString(request) +} + +// GetVolumeAttachmentResponse wrapper for the GetVolumeAttachment operation +type GetVolumeAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VolumeAttachment instance + VolumeAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVolumeAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_volume_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_volume_backup_request_response.go new file mode 100644 index 000000000..6ca44c977 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_volume_backup_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVolumeBackupRequest wrapper for the GetVolumeBackup operation +type GetVolumeBackupRequest struct { + + // The OCID of the volume backup. + VolumeBackupId *string `mandatory:"true" contributesTo:"path" name:"volumeBackupId"` +} + +func (request GetVolumeBackupRequest) String() string { + return common.PointerString(request) +} + +// GetVolumeBackupResponse wrapper for the GetVolumeBackup operation +type GetVolumeBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VolumeBackup instance + VolumeBackup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVolumeBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_volume_request_response.go new file mode 100644 index 000000000..57e71a0f2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_volume_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetVolumeRequest wrapper for the GetVolume operation +type GetVolumeRequest struct { + + // The OCID of the volume. + VolumeId *string `mandatory:"true" contributesTo:"path" name:"volumeId"` +} + +func (request GetVolumeRequest) String() string { + return common.PointerString(request) +} + +// GetVolumeResponse wrapper for the GetVolume operation +type GetVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Volume instance + Volume `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/get_windows_instance_initial_credentials_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/get_windows_instance_initial_credentials_request_response.go new file mode 100644 index 000000000..98d138e2b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/get_windows_instance_initial_credentials_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetWindowsInstanceInitialCredentialsRequest wrapper for the GetWindowsInstanceInitialCredentials operation +type GetWindowsInstanceInitialCredentialsRequest struct { + + // The OCID of the instance. + InstanceId *string `mandatory:"true" contributesTo:"path" name:"instanceId"` +} + +func (request GetWindowsInstanceInitialCredentialsRequest) String() string { + return common.PointerString(request) +} + +// GetWindowsInstanceInitialCredentialsResponse wrapper for the GetWindowsInstanceInitialCredentials operation +type GetWindowsInstanceInitialCredentialsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The InstanceCredentials instance + InstanceCredentials `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetWindowsInstanceInitialCredentialsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/i_scsi_volume_attachment.go b/vendor/github.com/oracle/oci-go-sdk/core/i_scsi_volume_attachment.go new file mode 100644 index 000000000..107ab34f3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/i_scsi_volume_attachment.go @@ -0,0 +1,125 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// IScsiVolumeAttachment An ISCSI volume attachment. +type IScsiVolumeAttachment struct { + + // The Availability Domain of an instance. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the volume attachment. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the instance the volume is attached to. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // The date and time the volume was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the volume. + VolumeId *string `mandatory:"true" json:"volumeId"` + + // The volume's iSCSI IP address. + // Example: `169.254.0.2` + Ipv4 *string `mandatory:"true" json:"ipv4"` + + // The target volume's iSCSI Qualified Name in the format defined by RFC 3720. + // Example: `iqn.2015-12.us.oracle.com:456b0391-17b8-4122-bbf1-f85fc0bb97d9` + Iqn *string `mandatory:"true" json:"iqn"` + + // The volume's iSCSI port. + // Example: `3260` + Port *int `mandatory:"true" json:"port"` + + // A user-friendly name. Does not have to be unique, and it cannot be changed. + // Avoid entering confidential information. + // Example: `My volume attachment` + DisplayName *string `mandatory:"false" json:"displayName"` + + // The Challenge-Handshake-Authentication-Protocol (CHAP) secret valid for the associated CHAP user name. + // (Also called the "CHAP password".) + // Example: `d6866c0d-298b-48ba-95af-309b4faux45e` + ChapSecret *string `mandatory:"false" json:"chapSecret"` + + // The volume's system-generated Challenge-Handshake-Authentication-Protocol (CHAP) user name. + // Example: `ocid1.volume.oc1.phx.abyhqljrgvttnlx73nmrwfaux7kcvzfs3s66izvxf2h4lgvyndsdsnoiwr5q` + ChapUsername *string `mandatory:"false" json:"chapUsername"` + + // The current state of the volume attachment. + LifecycleState VolumeAttachmentLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` +} + +//GetAvailabilityDomain returns AvailabilityDomain +func (m IScsiVolumeAttachment) GetAvailabilityDomain() *string { + return m.AvailabilityDomain +} + +//GetCompartmentId returns CompartmentId +func (m IScsiVolumeAttachment) GetCompartmentId() *string { + return m.CompartmentId +} + +//GetDisplayName returns DisplayName +func (m IScsiVolumeAttachment) GetDisplayName() *string { + return m.DisplayName +} + +//GetId returns Id +func (m IScsiVolumeAttachment) GetId() *string { + return m.Id +} + +//GetInstanceId returns InstanceId +func (m IScsiVolumeAttachment) GetInstanceId() *string { + return m.InstanceId +} + +//GetLifecycleState returns LifecycleState +func (m IScsiVolumeAttachment) GetLifecycleState() VolumeAttachmentLifecycleStateEnum { + return m.LifecycleState +} + +//GetTimeCreated returns TimeCreated +func (m IScsiVolumeAttachment) GetTimeCreated() *common.SDKTime { + return m.TimeCreated +} + +//GetVolumeId returns VolumeId +func (m IScsiVolumeAttachment) GetVolumeId() *string { + return m.VolumeId +} + +func (m IScsiVolumeAttachment) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m IScsiVolumeAttachment) MarshalJSON() (buff []byte, e error) { + type MarshalTypeIScsiVolumeAttachment IScsiVolumeAttachment + s := struct { + DiscriminatorParam string `json:"attachmentType"` + MarshalTypeIScsiVolumeAttachment + }{ + "iscsi", + (MarshalTypeIScsiVolumeAttachment)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/icmp_options.go b/vendor/github.com/oracle/oci-go-sdk/core/icmp_options.go new file mode 100644 index 000000000..79b841e78 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/icmp_options.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IcmpOptions Optional object to specify a particular ICMP type and code. If you specify ICMP as the protocol +// but do not provide this object, then all ICMP types and codes are allowed. If you do provide +// this object, the type is required and the code is optional. +// See ICMP Parameters (http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml) +// for allowed values. To enable MTU negotiation for ingress internet traffic, make sure to allow +// type 3 ("Destination Unreachable") code 4 ("Fragmentation Needed and Don't Fragment was Set"). +// If you need to specify multiple codes for a single type, create a separate security list rule for each. +type IcmpOptions struct { + + // The ICMP type. + Type *int `mandatory:"true" json:"type"` + + // The ICMP code (optional). + Code *int `mandatory:"false" json:"code"` +} + +func (m IcmpOptions) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/image.go b/vendor/github.com/oracle/oci-go-sdk/core/image.go new file mode 100644 index 000000000..250a1af1c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/image.go @@ -0,0 +1,90 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Image A boot disk image for launching an instance. For more information, see +// Overview of the Compute Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Concepts/computeoverview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Image struct { + + // The OCID of the compartment containing the instance you want to use as the basis for the image. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Whether instances launched with this image can be used to create new images. + // For example, you cannot create an image of an Oracle Database instance. + // Example: `true` + CreateImageAllowed *bool `mandatory:"true" json:"createImageAllowed"` + + // The OCID of the image. + Id *string `mandatory:"true" json:"id"` + + LifecycleState ImageLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The image's operating system. + // Example: `Oracle Linux` + OperatingSystem *string `mandatory:"true" json:"operatingSystem"` + + // The image's operating system version. + // Example: `7.2` + OperatingSystemVersion *string `mandatory:"true" json:"operatingSystemVersion"` + + // The date and time the image was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the image originally used to launch the instance. + BaseImageId *string `mandatory:"false" json:"baseImageId"` + + // A user-friendly name for the image. It does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // You cannot use an Oracle-provided image name as a custom image name. + // Example: `My custom Oracle Linux image` + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m Image) String() string { + return common.PointerString(m) +} + +// ImageLifecycleStateEnum Enum with underlying type: string +type ImageLifecycleStateEnum string + +// Set of constants representing the allowable values for ImageLifecycleState +const ( + ImageLifecycleStateProvisioning ImageLifecycleStateEnum = "PROVISIONING" + ImageLifecycleStateImporting ImageLifecycleStateEnum = "IMPORTING" + ImageLifecycleStateAvailable ImageLifecycleStateEnum = "AVAILABLE" + ImageLifecycleStateExporting ImageLifecycleStateEnum = "EXPORTING" + ImageLifecycleStateDisabled ImageLifecycleStateEnum = "DISABLED" + ImageLifecycleStateDeleted ImageLifecycleStateEnum = "DELETED" +) + +var mappingImageLifecycleState = map[string]ImageLifecycleStateEnum{ + "PROVISIONING": ImageLifecycleStateProvisioning, + "IMPORTING": ImageLifecycleStateImporting, + "AVAILABLE": ImageLifecycleStateAvailable, + "EXPORTING": ImageLifecycleStateExporting, + "DISABLED": ImageLifecycleStateDisabled, + "DELETED": ImageLifecycleStateDeleted, +} + +// GetImageLifecycleStateEnumValues Enumerates the set of values for ImageLifecycleState +func GetImageLifecycleStateEnumValues() []ImageLifecycleStateEnum { + values := make([]ImageLifecycleStateEnum, 0) + for _, v := range mappingImageLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/image_source_details.go b/vendor/github.com/oracle/oci-go-sdk/core/image_source_details.go new file mode 100644 index 000000000..ae8d32acb --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/image_source_details.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// ImageSourceDetails The representation of ImageSourceDetails +type ImageSourceDetails interface { +} + +type imagesourcedetails struct { + JsonData []byte + SourceType string `json:"sourceType"` +} + +// UnmarshalJSON unmarshals json +func (m *imagesourcedetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalerimagesourcedetails imagesourcedetails + s := struct { + Model Unmarshalerimagesourcedetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.SourceType = s.Model.SourceType + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *imagesourcedetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.SourceType { + case "objectStorageTuple": + mm := ImageSourceViaObjectStorageTupleDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + case "objectStorageUri": + mm := ImageSourceViaObjectStorageUriDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +func (m imagesourcedetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_tuple_details.go b/vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_tuple_details.go new file mode 100644 index 000000000..61eddb488 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_tuple_details.go @@ -0,0 +1,45 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// ImageSourceViaObjectStorageTupleDetails The representation of ImageSourceViaObjectStorageTupleDetails +type ImageSourceViaObjectStorageTupleDetails struct { + + // The Object Storage bucket for the image. + BucketName *string `mandatory:"true" json:"bucketName"` + + // The Object Storage namespace for the image. + NamespaceName *string `mandatory:"true" json:"namespaceName"` + + // The Object Storage name for the image. + ObjectName *string `mandatory:"true" json:"objectName"` +} + +func (m ImageSourceViaObjectStorageTupleDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m ImageSourceViaObjectStorageTupleDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeImageSourceViaObjectStorageTupleDetails ImageSourceViaObjectStorageTupleDetails + s := struct { + DiscriminatorParam string `json:"sourceType"` + MarshalTypeImageSourceViaObjectStorageTupleDetails + }{ + "objectStorageTuple", + (MarshalTypeImageSourceViaObjectStorageTupleDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_uri_details.go b/vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_uri_details.go new file mode 100644 index 000000000..e65376d4d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/image_source_via_object_storage_uri_details.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// ImageSourceViaObjectStorageUriDetails The representation of ImageSourceViaObjectStorageUriDetails +type ImageSourceViaObjectStorageUriDetails struct { + + // The Object Storage URL for the image. + SourceUri *string `mandatory:"true" json:"sourceUri"` +} + +func (m ImageSourceViaObjectStorageUriDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m ImageSourceViaObjectStorageUriDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeImageSourceViaObjectStorageUriDetails ImageSourceViaObjectStorageUriDetails + s := struct { + DiscriminatorParam string `json:"sourceType"` + MarshalTypeImageSourceViaObjectStorageUriDetails + }{ + "objectStorageUri", + (MarshalTypeImageSourceViaObjectStorageUriDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/ingress_security_rule.go b/vendor/github.com/oracle/oci-go-sdk/core/ingress_security_rule.go new file mode 100644 index 000000000..fbd7d7561 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/ingress_security_rule.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IngressSecurityRule A rule for allowing inbound IP packets. +type IngressSecurityRule struct { + + // The transport protocol. Specify either `all` or an IPv4 protocol number as + // defined in + // Protocol Numbers (http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). + // Options are supported only for ICMP ("1"), TCP ("6"), and UDP ("17"). + Protocol *string `mandatory:"true" json:"protocol"` + + // The source CIDR block for the ingress rule. This is the range of IP addresses that a + // packet coming into the instance can come from. + Source *string `mandatory:"true" json:"source"` + + // Optional and valid only for ICMP. Use to specify a particular ICMP type and code + // as defined in + // ICMP Parameters (http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml). + // If you specify ICMP as the protocol but omit this object, then all ICMP types and + // codes are allowed. If you do provide this object, the type is required and the code is optional. + // To enable MTU negotiation for ingress internet traffic, make sure to allow type 3 ("Destination + // Unreachable") code 4 ("Fragmentation Needed and Don't Fragment was Set"). If you need to specify + // multiple codes for a single type, create a separate security list rule for each. + IcmpOptions *IcmpOptions `mandatory:"false" json:"icmpOptions"` + + // A stateless rule allows traffic in one direction. Remember to add a corresponding + // stateless rule in the other direction if you need to support bidirectional traffic. For + // example, if ingress traffic allows TCP destination port 80, there should be an egress + // rule to allow TCP source port 80. Defaults to false, which means the rule is stateful + // and a corresponding rule is not necessary for bidirectional traffic. + IsStateless *bool `mandatory:"false" json:"isStateless"` + + // Optional and valid only for TCP. Use to specify particular destination ports for TCP rules. + // If you specify TCP as the protocol but omit this object, then all destination ports are allowed. + TcpOptions *TcpOptions `mandatory:"false" json:"tcpOptions"` + + // Optional and valid only for UDP. Use to specify particular destination ports for UDP rules. + // If you specify UDP as the protocol but omit this object, then all destination ports are allowed. + UdpOptions *UdpOptions `mandatory:"false" json:"udpOptions"` +} + +func (m IngressSecurityRule) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance.go b/vendor/github.com/oracle/oci-go-sdk/core/instance.go new file mode 100644 index 000000000..afad7986f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance.go @@ -0,0 +1,170 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// Instance A compute host. The image used to launch the instance determines its operating system and other +// software. The shape specified during the launch process determines the number of CPUs and memory +// allocated to the instance. For more information, see +// Overview of the Compute Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Concepts/computeoverview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Instance struct { + + // The Availability Domain the instance is running in. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment that contains the instance. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the instance. + Id *string `mandatory:"true" json:"id"` + + // The current state of the instance. + LifecycleState InstanceLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The region that contains the Availability Domain the instance is running in. + // Example: `phx` + Region *string `mandatory:"true" json:"region"` + + // The shape of the instance. The shape determines the number of CPUs and the amount of memory + // allocated to the instance. You can enumerate all available shapes by calling + // ListShapes. + Shape *string `mandatory:"true" json:"shape"` + + // The date and time the instance was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // Example: `My bare metal instance` + DisplayName *string `mandatory:"false" json:"displayName"` + + // Additional metadata key/value pairs that you provide. They serve a similar purpose and functionality from fields in the 'metadata' object. + // They are distinguished from 'metadata' fields in that these can be nested JSON objects (whereas 'metadata' fields are string/string maps only). + // If you don't need nested metadata values, it is strongly advised to avoid using this object and use the Metadata object instead. + ExtendedMetadata map[string]interface{} `mandatory:"false" json:"extendedMetadata"` + + // Deprecated. Use `sourceDetails` instead. + ImageId *string `mandatory:"false" json:"imageId"` + + // When a bare metal or virtual machine + // instance boots, the iPXE firmware that runs on the instance is + // configured to run an iPXE script to continue the boot process. + // If you want more control over the boot process, you can provide + // your own custom iPXE script that will run when the instance boots; + // however, you should be aware that the same iPXE script will run + // every time an instance boots; not only after the initial + // LaunchInstance call. + // The default iPXE script connects to the instance's local boot + // volume over iSCSI and performs a network boot. If you use a custom iPXE + // script and want to network-boot from the instance's local boot volume + // over iSCSI the same way as the default iPXE script, you should use the + // following iSCSI IP address: 169.254.0.2, and boot volume IQN: + // iqn.2015-02.oracle.boot. + // For more information about the Bring Your Own Image feature of + // Oracle Cloud Infrastructure, see + // Bring Your Own Image (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/bringyourownimage.htm). + // For more information about iPXE, see http://ipxe.org. + IpxeScript *string `mandatory:"false" json:"ipxeScript"` + + // Custom metadata that you provide. + Metadata map[string]string `mandatory:"false" json:"metadata"` + + // Details for creating an instance + SourceDetails InstanceSourceDetails `mandatory:"false" json:"sourceDetails"` +} + +func (m Instance) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *Instance) UnmarshalJSON(data []byte) (e error) { + model := struct { + DisplayName *string `json:"displayName"` + ExtendedMetadata map[string]interface{} `json:"extendedMetadata"` + ImageId *string `json:"imageId"` + IpxeScript *string `json:"ipxeScript"` + Metadata map[string]string `json:"metadata"` + SourceDetails instancesourcedetails `json:"sourceDetails"` + AvailabilityDomain *string `json:"availabilityDomain"` + CompartmentId *string `json:"compartmentId"` + Id *string `json:"id"` + LifecycleState InstanceLifecycleStateEnum `json:"lifecycleState"` + Region *string `json:"region"` + Shape *string `json:"shape"` + TimeCreated *common.SDKTime `json:"timeCreated"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.DisplayName = model.DisplayName + m.ExtendedMetadata = model.ExtendedMetadata + m.ImageId = model.ImageId + m.IpxeScript = model.IpxeScript + m.Metadata = model.Metadata + nn, e := model.SourceDetails.UnmarshalPolymorphicJSON(model.SourceDetails.JsonData) + if e != nil { + return + } + m.SourceDetails = nn + m.AvailabilityDomain = model.AvailabilityDomain + m.CompartmentId = model.CompartmentId + m.Id = model.Id + m.LifecycleState = model.LifecycleState + m.Region = model.Region + m.Shape = model.Shape + m.TimeCreated = model.TimeCreated + return +} + +// InstanceLifecycleStateEnum Enum with underlying type: string +type InstanceLifecycleStateEnum string + +// Set of constants representing the allowable values for InstanceLifecycleState +const ( + InstanceLifecycleStateProvisioning InstanceLifecycleStateEnum = "PROVISIONING" + InstanceLifecycleStateRunning InstanceLifecycleStateEnum = "RUNNING" + InstanceLifecycleStateStarting InstanceLifecycleStateEnum = "STARTING" + InstanceLifecycleStateStopping InstanceLifecycleStateEnum = "STOPPING" + InstanceLifecycleStateStopped InstanceLifecycleStateEnum = "STOPPED" + InstanceLifecycleStateCreatingImage InstanceLifecycleStateEnum = "CREATING_IMAGE" + InstanceLifecycleStateTerminating InstanceLifecycleStateEnum = "TERMINATING" + InstanceLifecycleStateTerminated InstanceLifecycleStateEnum = "TERMINATED" +) + +var mappingInstanceLifecycleState = map[string]InstanceLifecycleStateEnum{ + "PROVISIONING": InstanceLifecycleStateProvisioning, + "RUNNING": InstanceLifecycleStateRunning, + "STARTING": InstanceLifecycleStateStarting, + "STOPPING": InstanceLifecycleStateStopping, + "STOPPED": InstanceLifecycleStateStopped, + "CREATING_IMAGE": InstanceLifecycleStateCreatingImage, + "TERMINATING": InstanceLifecycleStateTerminating, + "TERMINATED": InstanceLifecycleStateTerminated, +} + +// GetInstanceLifecycleStateEnumValues Enumerates the set of values for InstanceLifecycleState +func GetInstanceLifecycleStateEnumValues() []InstanceLifecycleStateEnum { + values := make([]InstanceLifecycleStateEnum, 0) + for _, v := range mappingInstanceLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance_action_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/instance_action_request_response.go new file mode 100644 index 000000000..37faf1966 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance_action_request_response.go @@ -0,0 +1,83 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// InstanceActionRequest wrapper for the InstanceAction operation +type InstanceActionRequest struct { + + // The OCID of the instance. + InstanceId *string `mandatory:"true" contributesTo:"path" name:"instanceId"` + + // The action to perform on the instance. + Action InstanceActionActionEnum `mandatory:"true" contributesTo:"query" name:"action" omitEmpty:"true"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request InstanceActionRequest) String() string { + return common.PointerString(request) +} + +// InstanceActionResponse wrapper for the InstanceAction operation +type InstanceActionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Instance instance + Instance `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response InstanceActionResponse) String() string { + return common.PointerString(response) +} + +// InstanceActionActionEnum Enum with underlying type: string +type InstanceActionActionEnum string + +// Set of constants representing the allowable values for InstanceActionAction +const ( + InstanceActionActionStop InstanceActionActionEnum = "STOP" + InstanceActionActionStart InstanceActionActionEnum = "START" + InstanceActionActionSoftreset InstanceActionActionEnum = "SOFTRESET" + InstanceActionActionReset InstanceActionActionEnum = "RESET" +) + +var mappingInstanceActionAction = map[string]InstanceActionActionEnum{ + "STOP": InstanceActionActionStop, + "START": InstanceActionActionStart, + "SOFTRESET": InstanceActionActionSoftreset, + "RESET": InstanceActionActionReset, +} + +// GetInstanceActionActionEnumValues Enumerates the set of values for InstanceActionAction +func GetInstanceActionActionEnumValues() []InstanceActionActionEnum { + values := make([]InstanceActionActionEnum, 0) + for _, v := range mappingInstanceActionAction { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance_console_connection.go b/vendor/github.com/oracle/oci-go-sdk/core/instance_console_connection.go new file mode 100644 index 000000000..3dd2f61a4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance_console_connection.go @@ -0,0 +1,71 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// InstanceConsoleConnection The `InstanceConsoleConnection` API provides you with console access to virtual machine (VM) instances, +// enabling you to troubleshoot malfunctioning instances remotely. +// For more information about console access, see +// Accessing the Console (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/serialconsole.htm). +type InstanceConsoleConnection struct { + + // The OCID of the compartment to contain the console connection. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The SSH connection string for the console connection. + ConnectionString *string `mandatory:"false" json:"connectionString"` + + // The SSH public key fingerprint for the console connection. + Fingerprint *string `mandatory:"false" json:"fingerprint"` + + // The OCID of the console connection. + Id *string `mandatory:"false" json:"id"` + + // The OCID of the instance the console connection connects to. + InstanceId *string `mandatory:"false" json:"instanceId"` + + // The current state of the console connection. + LifecycleState InstanceConsoleConnectionLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` +} + +func (m InstanceConsoleConnection) String() string { + return common.PointerString(m) +} + +// InstanceConsoleConnectionLifecycleStateEnum Enum with underlying type: string +type InstanceConsoleConnectionLifecycleStateEnum string + +// Set of constants representing the allowable values for InstanceConsoleConnectionLifecycleState +const ( + InstanceConsoleConnectionLifecycleStateActive InstanceConsoleConnectionLifecycleStateEnum = "ACTIVE" + InstanceConsoleConnectionLifecycleStateCreating InstanceConsoleConnectionLifecycleStateEnum = "CREATING" + InstanceConsoleConnectionLifecycleStateDeleted InstanceConsoleConnectionLifecycleStateEnum = "DELETED" + InstanceConsoleConnectionLifecycleStateDeleting InstanceConsoleConnectionLifecycleStateEnum = "DELETING" + InstanceConsoleConnectionLifecycleStateFailed InstanceConsoleConnectionLifecycleStateEnum = "FAILED" +) + +var mappingInstanceConsoleConnectionLifecycleState = map[string]InstanceConsoleConnectionLifecycleStateEnum{ + "ACTIVE": InstanceConsoleConnectionLifecycleStateActive, + "CREATING": InstanceConsoleConnectionLifecycleStateCreating, + "DELETED": InstanceConsoleConnectionLifecycleStateDeleted, + "DELETING": InstanceConsoleConnectionLifecycleStateDeleting, + "FAILED": InstanceConsoleConnectionLifecycleStateFailed, +} + +// GetInstanceConsoleConnectionLifecycleStateEnumValues Enumerates the set of values for InstanceConsoleConnectionLifecycleState +func GetInstanceConsoleConnectionLifecycleStateEnumValues() []InstanceConsoleConnectionLifecycleStateEnum { + values := make([]InstanceConsoleConnectionLifecycleStateEnum, 0) + for _, v := range mappingInstanceConsoleConnectionLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance_credentials.go b/vendor/github.com/oracle/oci-go-sdk/core/instance_credentials.go new file mode 100644 index 000000000..62f78e935 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance_credentials.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// InstanceCredentials The credentials for a particular instance. +type InstanceCredentials struct { + + // The password for the username. + Password *string `mandatory:"true" json:"password"` + + // The username. + Username *string `mandatory:"true" json:"username"` +} + +func (m InstanceCredentials) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance_source_details.go b/vendor/github.com/oracle/oci-go-sdk/core/instance_source_details.go new file mode 100644 index 000000000..c9dffbd34 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance_source_details.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// InstanceSourceDetails The representation of InstanceSourceDetails +type InstanceSourceDetails interface { +} + +type instancesourcedetails struct { + JsonData []byte + SourceType string `json:"sourceType"` +} + +// UnmarshalJSON unmarshals json +func (m *instancesourcedetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalerinstancesourcedetails instancesourcedetails + s := struct { + Model Unmarshalerinstancesourcedetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.SourceType = s.Model.SourceType + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *instancesourcedetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.SourceType { + case "image": + mm := InstanceSourceViaImageDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + case "bootVolume": + mm := InstanceSourceViaBootVolumeDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +func (m instancesourcedetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_boot_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_boot_volume_details.go new file mode 100644 index 000000000..9dc4b2326 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_boot_volume_details.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// InstanceSourceViaBootVolumeDetails The representation of InstanceSourceViaBootVolumeDetails +type InstanceSourceViaBootVolumeDetails struct { + + // The OCID of the boot volume used to boot the instance. + BootVolumeId *string `mandatory:"true" json:"bootVolumeId"` +} + +func (m InstanceSourceViaBootVolumeDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m InstanceSourceViaBootVolumeDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeInstanceSourceViaBootVolumeDetails InstanceSourceViaBootVolumeDetails + s := struct { + DiscriminatorParam string `json:"sourceType"` + MarshalTypeInstanceSourceViaBootVolumeDetails + }{ + "bootVolume", + (MarshalTypeInstanceSourceViaBootVolumeDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_image_details.go b/vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_image_details.go new file mode 100644 index 000000000..3327d9ecf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/instance_source_via_image_details.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// InstanceSourceViaImageDetails The representation of InstanceSourceViaImageDetails +type InstanceSourceViaImageDetails struct { + + // The OCID of the image used to boot the instance. + ImageId *string `mandatory:"true" json:"imageId"` +} + +func (m InstanceSourceViaImageDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m InstanceSourceViaImageDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeInstanceSourceViaImageDetails InstanceSourceViaImageDetails + s := struct { + DiscriminatorParam string `json:"sourceType"` + MarshalTypeInstanceSourceViaImageDetails + }{ + "image", + (MarshalTypeInstanceSourceViaImageDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/internet_gateway.go b/vendor/github.com/oracle/oci-go-sdk/core/internet_gateway.go new file mode 100644 index 000000000..a9b8f1c0b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/internet_gateway.go @@ -0,0 +1,77 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// InternetGateway Represents a router that connects the edge of a VCN with the Internet. For an example scenario +// that uses an Internet Gateway, see +// Typical Networking Service Scenarios (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm#scenarios). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type InternetGateway struct { + + // The OCID of the compartment containing the Internet Gateway. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The Internet Gateway's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The Internet Gateway's current state. + LifecycleState InternetGatewayLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the VCN the Internet Gateway belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Whether the gateway is enabled. When the gateway is disabled, traffic is not + // routed to/from the Internet, regardless of route rules. + IsEnabled *bool `mandatory:"false" json:"isEnabled"` + + // The date and time the Internet Gateway was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m InternetGateway) String() string { + return common.PointerString(m) +} + +// InternetGatewayLifecycleStateEnum Enum with underlying type: string +type InternetGatewayLifecycleStateEnum string + +// Set of constants representing the allowable values for InternetGatewayLifecycleState +const ( + InternetGatewayLifecycleStateProvisioning InternetGatewayLifecycleStateEnum = "PROVISIONING" + InternetGatewayLifecycleStateAvailable InternetGatewayLifecycleStateEnum = "AVAILABLE" + InternetGatewayLifecycleStateTerminating InternetGatewayLifecycleStateEnum = "TERMINATING" + InternetGatewayLifecycleStateTerminated InternetGatewayLifecycleStateEnum = "TERMINATED" +) + +var mappingInternetGatewayLifecycleState = map[string]InternetGatewayLifecycleStateEnum{ + "PROVISIONING": InternetGatewayLifecycleStateProvisioning, + "AVAILABLE": InternetGatewayLifecycleStateAvailable, + "TERMINATING": InternetGatewayLifecycleStateTerminating, + "TERMINATED": InternetGatewayLifecycleStateTerminated, +} + +// GetInternetGatewayLifecycleStateEnumValues Enumerates the set of values for InternetGatewayLifecycleState +func GetInternetGatewayLifecycleStateEnumValues() []InternetGatewayLifecycleStateEnum { + values := make([]InternetGatewayLifecycleStateEnum, 0) + for _, v := range mappingInternetGatewayLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection.go b/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection.go new file mode 100644 index 000000000..c57e74559 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection.go @@ -0,0 +1,82 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IpSecConnection A connection between a DRG and CPE. This connection consists of multiple IPSec +// tunnels. Creating this connection is one of the steps required when setting up +// an IPSec VPN. For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type IpSecConnection struct { + + // The OCID of the compartment containing the IPSec connection. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the CPE. + CpeId *string `mandatory:"true" json:"cpeId"` + + // The OCID of the DRG. + DrgId *string `mandatory:"true" json:"drgId"` + + // The IPSec connection's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The IPSec connection's current state. + LifecycleState IpSecConnectionLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // Static routes to the CPE. At least one route must be included. The CIDR must not be a + // multicast address or class E address. + // Example: `10.0.1.0/24` + StaticRoutes []string `mandatory:"true" json:"staticRoutes"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The date and time the IPSec connection was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m IpSecConnection) String() string { + return common.PointerString(m) +} + +// IpSecConnectionLifecycleStateEnum Enum with underlying type: string +type IpSecConnectionLifecycleStateEnum string + +// Set of constants representing the allowable values for IpSecConnectionLifecycleState +const ( + IpSecConnectionLifecycleStateProvisioning IpSecConnectionLifecycleStateEnum = "PROVISIONING" + IpSecConnectionLifecycleStateAvailable IpSecConnectionLifecycleStateEnum = "AVAILABLE" + IpSecConnectionLifecycleStateTerminating IpSecConnectionLifecycleStateEnum = "TERMINATING" + IpSecConnectionLifecycleStateTerminated IpSecConnectionLifecycleStateEnum = "TERMINATED" +) + +var mappingIpSecConnectionLifecycleState = map[string]IpSecConnectionLifecycleStateEnum{ + "PROVISIONING": IpSecConnectionLifecycleStateProvisioning, + "AVAILABLE": IpSecConnectionLifecycleStateAvailable, + "TERMINATING": IpSecConnectionLifecycleStateTerminating, + "TERMINATED": IpSecConnectionLifecycleStateTerminated, +} + +// GetIpSecConnectionLifecycleStateEnumValues Enumerates the set of values for IpSecConnectionLifecycleState +func GetIpSecConnectionLifecycleStateEnumValues() []IpSecConnectionLifecycleStateEnum { + values := make([]IpSecConnectionLifecycleStateEnum, 0) + for _, v := range mappingIpSecConnectionLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_config.go b/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_config.go new file mode 100644 index 000000000..5572af637 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_config.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IpSecConnectionDeviceConfig Information about the IPSecConnection device configuration. +type IpSecConnectionDeviceConfig struct { + + // The OCID of the compartment containing the IPSec connection. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The IPSec connection's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The date and time the IPSec connection was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // Two TunnelConfig objects. + Tunnels []TunnelConfig `mandatory:"false" json:"tunnels"` +} + +func (m IpSecConnectionDeviceConfig) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_status.go b/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_status.go new file mode 100644 index 000000000..5f5a4d3c9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/ip_sec_connection_device_status.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IpSecConnectionDeviceStatus Status of the IPSec connection. +type IpSecConnectionDeviceStatus struct { + + // The OCID of the compartment containing the IPSec connection. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The IPSec connection's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The date and time the IPSec connection was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // Two TunnelStatus objects. + Tunnels []TunnelStatus `mandatory:"false" json:"tunnels"` +} + +func (m IpSecConnectionDeviceStatus) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/launch_instance_details.go b/vendor/github.com/oracle/oci-go-sdk/core/launch_instance_details.go new file mode 100644 index 000000000..c40c778ca --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/launch_instance_details.go @@ -0,0 +1,172 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// LaunchInstanceDetails Instance launch details. +// Use the sourceDetails parameter to specify whether a boot volume should be used for a new instance launch. +type LaunchInstanceDetails struct { + + // The Availability Domain of the instance. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The shape of an instance. The shape determines the number of CPUs, amount of memory, + // and other resources allocated to the instance. + // You can enumerate all available shapes by calling ListShapes. + Shape *string `mandatory:"true" json:"shape"` + + // Details for the primary VNIC, which is automatically created and attached when + // the instance is launched. + CreateVnicDetails *CreateVnicDetails `mandatory:"false" json:"createVnicDetails"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // Example: `My bare metal instance` + DisplayName *string `mandatory:"false" json:"displayName"` + + // Additional metadata key/value pairs that you provide. They serve a similar purpose and functionality from fields in the 'metadata' object. + // They are distinguished from 'metadata' fields in that these can be nested JSON objects (whereas 'metadata' fields are string/string maps only). + // If you don't need nested metadata values, it is strongly advised to avoid using this object and use the Metadata object instead. + ExtendedMetadata map[string]interface{} `mandatory:"false" json:"extendedMetadata"` + + // Deprecated. Instead Use `hostnameLabel` in + // CreateVnicDetails. + // If you provide both, the values must match. + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // Deprecated. Use `sourceDetails` with InstanceSourceViaImageDetails + // source type instead. If you specify values for both, the values must match. + ImageId *string `mandatory:"false" json:"imageId"` + + // This is an advanced option. + // When a bare metal or virtual machine + // instance boots, the iPXE firmware that runs on the instance is + // configured to run an iPXE script to continue the boot process. + // If you want more control over the boot process, you can provide + // your own custom iPXE script that will run when the instance boots; + // however, you should be aware that the same iPXE script will run + // every time an instance boots; not only after the initial + // LaunchInstance call. + // The default iPXE script connects to the instance's local boot + // volume over iSCSI and performs a network boot. If you use a custom iPXE + // script and want to network-boot from the instance's local boot volume + // over iSCSI the same way as the default iPXE script, you should use the + // following iSCSI IP address: 169.254.0.2, and boot volume IQN: + // iqn.2015-02.oracle.boot. + // For more information about the Bring Your Own Image feature of + // Oracle Cloud Infrastructure, see + // Bring Your Own Image (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/References/bringyourownimage.htm). + // For more information about iPXE, see http://ipxe.org. + IpxeScript *string `mandatory:"false" json:"ipxeScript"` + + // Custom metadata key/value pairs that you provide, such as the SSH public key + // required to connect to the instance. + // A metadata service runs on every launched instance. The service is an HTTP + // endpoint listening on 169.254.169.254. You can use the service to: + // * Provide information to Cloud-Init (https://cloudinit.readthedocs.org/en/latest/) + // to be used for various system initialization tasks. + // * Get information about the instance, including the custom metadata that you + // provide when you launch the instance. + // **Providing Cloud-Init Metadata** + // You can use the following metadata key names to provide information to + // Cloud-Init: + // **"ssh_authorized_keys"** - Provide one or more public SSH keys to be + // included in the `~/.ssh/authorized_keys` file for the default user on the + // instance. Use a newline character to separate multiple keys. The SSH + // keys must be in the format necessary for the `authorized_keys` file, as shown + // in the example below. + // **"user_data"** - Provide your own base64-encoded data to be used by + // Cloud-Init to run custom scripts or provide custom Cloud-Init configuration. For + // information about how to take advantage of user data, see the + // Cloud-Init Documentation (http://cloudinit.readthedocs.org/en/latest/topics/format.html). + // **Note:** Cloud-Init does not pull this data from the `http://169.254.169.254/opc/v1/instance/metadata/` + // path. When the instance launches and either of these keys are provided, the key values are formatted as + // OpenStack metadata and copied to the following locations, which are recognized by Cloud-Init: + // `http://169.254.169.254/openstack/latest/meta_data.json` - This JSON blob + // contains, among other things, the SSH keys that you provided for + // **"ssh_authorized_keys"**. + // `http://169.254.169.254/openstack/latest/user_data` - Contains the + // base64-decoded data that you provided for **"user_data"**. + // **Metadata Example** + // "metadata" : { + // "quake_bot_level" : "Severe", + // "ssh_authorized_keys" : "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCZ06fccNTQfq+xubFlJ5ZR3kt+uzspdH9tXL+lAejSM1NXM+CFZev7MIxfEjas06y80ZBZ7DUTQO0GxJPeD8NCOb1VorF8M4xuLwrmzRtkoZzU16umt4y1W0Q4ifdp3IiiU0U8/WxczSXcUVZOLqkz5dc6oMHdMVpkimietWzGZ4LBBsH/LjEVY7E0V+a0sNchlVDIZcm7ErReBLcdTGDq0uLBiuChyl6RUkX1PNhusquTGwK7zc8OBXkRuubn5UKXhI3Ul9Nyk4XESkVWIGNKmw8mSpoJSjR8P9ZjRmcZVo8S+x4KVPMZKQEor== ryan.smith@company.com + // ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAzJSAtwEPoB3Jmr58IXrDGzLuDYkWAYg8AsLYlo6JZvKpjY1xednIcfEVQJm4T2DhVmdWhRrwQ8DmayVZvBkLt+zs2LdoAJEVimKwXcJFD/7wtH8Lnk17HiglbbbNXsemjDY0hea4JUE5CfvkIdZBITuMrfqSmA4n3VNoorXYdvtTMoGG8fxMub46RPtuxtqi9bG9Zqenordkg5FJt2mVNfQRqf83CWojcOkklUWq4CjyxaeLf5i9gv1fRoBo4QhiA8I6NCSppO8GnoV/6Ox6TNoh9BiifqGKC9VGYuC89RvUajRBTZSK2TK4DPfaT+2R+slPsFrwiT/oPEhhEK1S5Q== rsa-key-20160227", + // "user_data" : "SWYgeW91IGNhbiBzZWUgdGhpcywgdGhlbiBpdCB3b3JrZWQgbWF5YmUuCg==" + // } + // **Getting Metadata on the Instance** + // To get information about your instance, connect to the instance using SSH and issue any of the + // following GET requests: + // curl http://169.254.169.254/opc/v1/instance/ + // curl http://169.254.169.254/opc/v1/instance/metadata/ + // curl http://169.254.169.254/opc/v1/instance/metadata/<any-key-name> + // You'll get back a response that includes all the instance information; only the metadata information; or + // the metadata information for the specified key name, respectively. + Metadata map[string]string `mandatory:"false" json:"metadata"` + + // Details for creating an instance. + SourceDetails InstanceSourceDetails `mandatory:"false" json:"sourceDetails"` + + // Deprecated. Instead use `subnetId` in + // CreateVnicDetails. + // At least one of them is required; if you provide both, the values must match. + SubnetId *string `mandatory:"false" json:"subnetId"` +} + +func (m LaunchInstanceDetails) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *LaunchInstanceDetails) UnmarshalJSON(data []byte) (e error) { + model := struct { + CreateVnicDetails *CreateVnicDetails `json:"createVnicDetails"` + DisplayName *string `json:"displayName"` + ExtendedMetadata map[string]interface{} `json:"extendedMetadata"` + HostnameLabel *string `json:"hostnameLabel"` + ImageId *string `json:"imageId"` + IpxeScript *string `json:"ipxeScript"` + Metadata map[string]string `json:"metadata"` + SourceDetails instancesourcedetails `json:"sourceDetails"` + SubnetId *string `json:"subnetId"` + AvailabilityDomain *string `json:"availabilityDomain"` + CompartmentId *string `json:"compartmentId"` + Shape *string `json:"shape"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.CreateVnicDetails = model.CreateVnicDetails + m.DisplayName = model.DisplayName + m.ExtendedMetadata = model.ExtendedMetadata + m.HostnameLabel = model.HostnameLabel + m.ImageId = model.ImageId + m.IpxeScript = model.IpxeScript + m.Metadata = model.Metadata + nn, e := model.SourceDetails.UnmarshalPolymorphicJSON(model.SourceDetails.JsonData) + if e != nil { + return + } + m.SourceDetails = nn + m.SubnetId = model.SubnetId + m.AvailabilityDomain = model.AvailabilityDomain + m.CompartmentId = model.CompartmentId + m.Shape = model.Shape + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/launch_instance_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/launch_instance_request_response.go new file mode 100644 index 000000000..dfccbc48b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/launch_instance_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// LaunchInstanceRequest wrapper for the LaunchInstance operation +type LaunchInstanceRequest struct { + + // Instance details + LaunchInstanceDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request LaunchInstanceRequest) String() string { + return common.PointerString(request) +} + +// LaunchInstanceResponse wrapper for the LaunchInstance operation +type LaunchInstanceResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Instance instance + Instance `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response LaunchInstanceResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/letter_of_authority.go b/vendor/github.com/oracle/oci-go-sdk/core/letter_of_authority.go new file mode 100644 index 000000000..3b24abade --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/letter_of_authority.go @@ -0,0 +1,67 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LetterOfAuthority The Letter of Authority for the cross-connect. You must submit this letter when +// requesting cabling for the cross-connect at the FastConnect location. +type LetterOfAuthority struct { + + // The name of the entity authorized by this Letter of Authority. + AuthorizedEntityName *string `mandatory:"false" json:"authorizedEntityName"` + + // The type of cross-connect fiber, termination, and optical specification. + CircuitType LetterOfAuthorityCircuitTypeEnum `mandatory:"false" json:"circuitType,omitempty"` + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"false" json:"crossConnectId"` + + // The address of the FastConnect location. + FacilityLocation *string `mandatory:"false" json:"facilityLocation"` + + // The meet-me room port for this cross-connect. + PortName *string `mandatory:"false" json:"portName"` + + // The date and time when the Letter of Authority expires, in the format defined by RFC3339. + TimeExpires *common.SDKTime `mandatory:"false" json:"timeExpires"` + + // The date and time the Letter of Authority was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeIssued *common.SDKTime `mandatory:"false" json:"timeIssued"` +} + +func (m LetterOfAuthority) String() string { + return common.PointerString(m) +} + +// LetterOfAuthorityCircuitTypeEnum Enum with underlying type: string +type LetterOfAuthorityCircuitTypeEnum string + +// Set of constants representing the allowable values for LetterOfAuthorityCircuitType +const ( + LetterOfAuthorityCircuitTypeLc LetterOfAuthorityCircuitTypeEnum = "Single_mode_LC" + LetterOfAuthorityCircuitTypeSc LetterOfAuthorityCircuitTypeEnum = "Single_mode_SC" +) + +var mappingLetterOfAuthorityCircuitType = map[string]LetterOfAuthorityCircuitTypeEnum{ + "Single_mode_LC": LetterOfAuthorityCircuitTypeLc, + "Single_mode_SC": LetterOfAuthorityCircuitTypeSc, +} + +// GetLetterOfAuthorityCircuitTypeEnumValues Enumerates the set of values for LetterOfAuthorityCircuitType +func GetLetterOfAuthorityCircuitTypeEnumValues() []LetterOfAuthorityCircuitTypeEnum { + values := make([]LetterOfAuthorityCircuitTypeEnum, 0) + for _, v := range mappingLetterOfAuthorityCircuitType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_boot_volume_attachments_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_boot_volume_attachments_request_response.go new file mode 100644 index 000000000..51669f7e1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_boot_volume_attachments_request_response.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListBootVolumeAttachmentsRequest wrapper for the ListBootVolumeAttachments operation +type ListBootVolumeAttachmentsRequest struct { + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" contributesTo:"query" name:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The OCID of the instance. + InstanceId *string `mandatory:"false" contributesTo:"query" name:"instanceId"` + + // The OCID of the boot volume. + BootVolumeId *string `mandatory:"false" contributesTo:"query" name:"bootVolumeId"` +} + +func (request ListBootVolumeAttachmentsRequest) String() string { + return common.PointerString(request) +} + +// ListBootVolumeAttachmentsResponse wrapper for the ListBootVolumeAttachments operation +type ListBootVolumeAttachmentsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []BootVolumeAttachment instance + Items []BootVolumeAttachment `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListBootVolumeAttachmentsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_boot_volumes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_boot_volumes_request_response.go new file mode 100644 index 000000000..20370d315 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_boot_volumes_request_response.go @@ -0,0 +1,54 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListBootVolumesRequest wrapper for the ListBootVolumes operation +type ListBootVolumesRequest struct { + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" contributesTo:"query" name:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListBootVolumesRequest) String() string { + return common.PointerString(request) +} + +// ListBootVolumesResponse wrapper for the ListBootVolumes operation +type ListBootVolumesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []BootVolume instance + Items []BootVolume `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListBootVolumesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_console_histories_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_console_histories_request_response.go new file mode 100644 index 000000000..e47d04333 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_console_histories_request_response.go @@ -0,0 +1,119 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListConsoleHistoriesRequest wrapper for the ListConsoleHistories operation +type ListConsoleHistoriesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" contributesTo:"query" name:"availabilityDomain"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The OCID of the instance. + InstanceId *string `mandatory:"false" contributesTo:"query" name:"instanceId"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListConsoleHistoriesSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListConsoleHistoriesSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState ConsoleHistoryLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListConsoleHistoriesRequest) String() string { + return common.PointerString(request) +} + +// ListConsoleHistoriesResponse wrapper for the ListConsoleHistories operation +type ListConsoleHistoriesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []ConsoleHistory instance + Items []ConsoleHistory `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListConsoleHistoriesResponse) String() string { + return common.PointerString(response) +} + +// ListConsoleHistoriesSortByEnum Enum with underlying type: string +type ListConsoleHistoriesSortByEnum string + +// Set of constants representing the allowable values for ListConsoleHistoriesSortBy +const ( + ListConsoleHistoriesSortByTimecreated ListConsoleHistoriesSortByEnum = "TIMECREATED" + ListConsoleHistoriesSortByDisplayname ListConsoleHistoriesSortByEnum = "DISPLAYNAME" +) + +var mappingListConsoleHistoriesSortBy = map[string]ListConsoleHistoriesSortByEnum{ + "TIMECREATED": ListConsoleHistoriesSortByTimecreated, + "DISPLAYNAME": ListConsoleHistoriesSortByDisplayname, +} + +// GetListConsoleHistoriesSortByEnumValues Enumerates the set of values for ListConsoleHistoriesSortBy +func GetListConsoleHistoriesSortByEnumValues() []ListConsoleHistoriesSortByEnum { + values := make([]ListConsoleHistoriesSortByEnum, 0) + for _, v := range mappingListConsoleHistoriesSortBy { + values = append(values, v) + } + return values +} + +// ListConsoleHistoriesSortOrderEnum Enum with underlying type: string +type ListConsoleHistoriesSortOrderEnum string + +// Set of constants representing the allowable values for ListConsoleHistoriesSortOrder +const ( + ListConsoleHistoriesSortOrderAsc ListConsoleHistoriesSortOrderEnum = "ASC" + ListConsoleHistoriesSortOrderDesc ListConsoleHistoriesSortOrderEnum = "DESC" +) + +var mappingListConsoleHistoriesSortOrder = map[string]ListConsoleHistoriesSortOrderEnum{ + "ASC": ListConsoleHistoriesSortOrderAsc, + "DESC": ListConsoleHistoriesSortOrderDesc, +} + +// GetListConsoleHistoriesSortOrderEnumValues Enumerates the set of values for ListConsoleHistoriesSortOrder +func GetListConsoleHistoriesSortOrderEnumValues() []ListConsoleHistoriesSortOrderEnum { + values := make([]ListConsoleHistoriesSortOrderEnum, 0) + for _, v := range mappingListConsoleHistoriesSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_cpes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_cpes_request_response.go new file mode 100644 index 000000000..5a0ce9fb3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_cpes_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCpesRequest wrapper for the ListCpes operation +type ListCpesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListCpesRequest) String() string { + return common.PointerString(request) +} + +// ListCpesResponse wrapper for the ListCpes operation +type ListCpesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Cpe instance + Items []Cpe `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListCpesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_groups_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_groups_request_response.go new file mode 100644 index 000000000..221747c68 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_groups_request_response.go @@ -0,0 +1,115 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCrossConnectGroupsRequest wrapper for the ListCrossConnectGroups operation +type ListCrossConnectGroupsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListCrossConnectGroupsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListCrossConnectGroupsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to return only resources that match the specified lifecycle state. The value is case insensitive. + LifecycleState CrossConnectGroupLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListCrossConnectGroupsRequest) String() string { + return common.PointerString(request) +} + +// ListCrossConnectGroupsResponse wrapper for the ListCrossConnectGroups operation +type ListCrossConnectGroupsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []CrossConnectGroup instance + Items []CrossConnectGroup `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListCrossConnectGroupsResponse) String() string { + return common.PointerString(response) +} + +// ListCrossConnectGroupsSortByEnum Enum with underlying type: string +type ListCrossConnectGroupsSortByEnum string + +// Set of constants representing the allowable values for ListCrossConnectGroupsSortBy +const ( + ListCrossConnectGroupsSortByTimecreated ListCrossConnectGroupsSortByEnum = "TIMECREATED" + ListCrossConnectGroupsSortByDisplayname ListCrossConnectGroupsSortByEnum = "DISPLAYNAME" +) + +var mappingListCrossConnectGroupsSortBy = map[string]ListCrossConnectGroupsSortByEnum{ + "TIMECREATED": ListCrossConnectGroupsSortByTimecreated, + "DISPLAYNAME": ListCrossConnectGroupsSortByDisplayname, +} + +// GetListCrossConnectGroupsSortByEnumValues Enumerates the set of values for ListCrossConnectGroupsSortBy +func GetListCrossConnectGroupsSortByEnumValues() []ListCrossConnectGroupsSortByEnum { + values := make([]ListCrossConnectGroupsSortByEnum, 0) + for _, v := range mappingListCrossConnectGroupsSortBy { + values = append(values, v) + } + return values +} + +// ListCrossConnectGroupsSortOrderEnum Enum with underlying type: string +type ListCrossConnectGroupsSortOrderEnum string + +// Set of constants representing the allowable values for ListCrossConnectGroupsSortOrder +const ( + ListCrossConnectGroupsSortOrderAsc ListCrossConnectGroupsSortOrderEnum = "ASC" + ListCrossConnectGroupsSortOrderDesc ListCrossConnectGroupsSortOrderEnum = "DESC" +) + +var mappingListCrossConnectGroupsSortOrder = map[string]ListCrossConnectGroupsSortOrderEnum{ + "ASC": ListCrossConnectGroupsSortOrderAsc, + "DESC": ListCrossConnectGroupsSortOrderDesc, +} + +// GetListCrossConnectGroupsSortOrderEnumValues Enumerates the set of values for ListCrossConnectGroupsSortOrder +func GetListCrossConnectGroupsSortOrderEnumValues() []ListCrossConnectGroupsSortOrderEnum { + values := make([]ListCrossConnectGroupsSortOrderEnum, 0) + for _, v := range mappingListCrossConnectGroupsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_locations_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_locations_request_response.go new file mode 100644 index 000000000..4200b32ac --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connect_locations_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCrossConnectLocationsRequest wrapper for the ListCrossConnectLocations operation +type ListCrossConnectLocationsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListCrossConnectLocationsRequest) String() string { + return common.PointerString(request) +} + +// ListCrossConnectLocationsResponse wrapper for the ListCrossConnectLocations operation +type ListCrossConnectLocationsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []CrossConnectLocation instance + Items []CrossConnectLocation `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListCrossConnectLocationsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connects_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connects_request_response.go new file mode 100644 index 000000000..e10f72d55 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_cross_connects_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCrossConnectsRequest wrapper for the ListCrossConnects operation +type ListCrossConnectsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the cross-connect group. + CrossConnectGroupId *string `mandatory:"false" contributesTo:"query" name:"crossConnectGroupId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListCrossConnectsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListCrossConnectsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to return only resources that match the specified lifecycle state. The value is case insensitive. + LifecycleState CrossConnectLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListCrossConnectsRequest) String() string { + return common.PointerString(request) +} + +// ListCrossConnectsResponse wrapper for the ListCrossConnects operation +type ListCrossConnectsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []CrossConnect instance + Items []CrossConnect `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListCrossConnectsResponse) String() string { + return common.PointerString(response) +} + +// ListCrossConnectsSortByEnum Enum with underlying type: string +type ListCrossConnectsSortByEnum string + +// Set of constants representing the allowable values for ListCrossConnectsSortBy +const ( + ListCrossConnectsSortByTimecreated ListCrossConnectsSortByEnum = "TIMECREATED" + ListCrossConnectsSortByDisplayname ListCrossConnectsSortByEnum = "DISPLAYNAME" +) + +var mappingListCrossConnectsSortBy = map[string]ListCrossConnectsSortByEnum{ + "TIMECREATED": ListCrossConnectsSortByTimecreated, + "DISPLAYNAME": ListCrossConnectsSortByDisplayname, +} + +// GetListCrossConnectsSortByEnumValues Enumerates the set of values for ListCrossConnectsSortBy +func GetListCrossConnectsSortByEnumValues() []ListCrossConnectsSortByEnum { + values := make([]ListCrossConnectsSortByEnum, 0) + for _, v := range mappingListCrossConnectsSortBy { + values = append(values, v) + } + return values +} + +// ListCrossConnectsSortOrderEnum Enum with underlying type: string +type ListCrossConnectsSortOrderEnum string + +// Set of constants representing the allowable values for ListCrossConnectsSortOrder +const ( + ListCrossConnectsSortOrderAsc ListCrossConnectsSortOrderEnum = "ASC" + ListCrossConnectsSortOrderDesc ListCrossConnectsSortOrderEnum = "DESC" +) + +var mappingListCrossConnectsSortOrder = map[string]ListCrossConnectsSortOrderEnum{ + "ASC": ListCrossConnectsSortOrderAsc, + "DESC": ListCrossConnectsSortOrderDesc, +} + +// GetListCrossConnectsSortOrderEnumValues Enumerates the set of values for ListCrossConnectsSortOrder +func GetListCrossConnectsSortOrderEnumValues() []ListCrossConnectsSortOrderEnum { + values := make([]ListCrossConnectsSortOrderEnum, 0) + for _, v := range mappingListCrossConnectsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_crossconnect_port_speed_shapes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_crossconnect_port_speed_shapes_request_response.go new file mode 100644 index 000000000..b60655348 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_crossconnect_port_speed_shapes_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCrossconnectPortSpeedShapesRequest wrapper for the ListCrossconnectPortSpeedShapes operation +type ListCrossconnectPortSpeedShapesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListCrossconnectPortSpeedShapesRequest) String() string { + return common.PointerString(request) +} + +// ListCrossconnectPortSpeedShapesResponse wrapper for the ListCrossconnectPortSpeedShapes operation +type ListCrossconnectPortSpeedShapesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []CrossConnectPortSpeedShape instance + Items []CrossConnectPortSpeedShape `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListCrossconnectPortSpeedShapesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_dhcp_options_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_dhcp_options_request_response.go new file mode 100644 index 000000000..f06466fc6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_dhcp_options_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDhcpOptionsRequest wrapper for the ListDhcpOptions operation +type ListDhcpOptionsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"query" name:"vcnId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListDhcpOptionsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListDhcpOptionsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState DhcpOptionsLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListDhcpOptionsRequest) String() string { + return common.PointerString(request) +} + +// ListDhcpOptionsResponse wrapper for the ListDhcpOptions operation +type ListDhcpOptionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DhcpOptions instance + Items []DhcpOptions `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDhcpOptionsResponse) String() string { + return common.PointerString(response) +} + +// ListDhcpOptionsSortByEnum Enum with underlying type: string +type ListDhcpOptionsSortByEnum string + +// Set of constants representing the allowable values for ListDhcpOptionsSortBy +const ( + ListDhcpOptionsSortByTimecreated ListDhcpOptionsSortByEnum = "TIMECREATED" + ListDhcpOptionsSortByDisplayname ListDhcpOptionsSortByEnum = "DISPLAYNAME" +) + +var mappingListDhcpOptionsSortBy = map[string]ListDhcpOptionsSortByEnum{ + "TIMECREATED": ListDhcpOptionsSortByTimecreated, + "DISPLAYNAME": ListDhcpOptionsSortByDisplayname, +} + +// GetListDhcpOptionsSortByEnumValues Enumerates the set of values for ListDhcpOptionsSortBy +func GetListDhcpOptionsSortByEnumValues() []ListDhcpOptionsSortByEnum { + values := make([]ListDhcpOptionsSortByEnum, 0) + for _, v := range mappingListDhcpOptionsSortBy { + values = append(values, v) + } + return values +} + +// ListDhcpOptionsSortOrderEnum Enum with underlying type: string +type ListDhcpOptionsSortOrderEnum string + +// Set of constants representing the allowable values for ListDhcpOptionsSortOrder +const ( + ListDhcpOptionsSortOrderAsc ListDhcpOptionsSortOrderEnum = "ASC" + ListDhcpOptionsSortOrderDesc ListDhcpOptionsSortOrderEnum = "DESC" +) + +var mappingListDhcpOptionsSortOrder = map[string]ListDhcpOptionsSortOrderEnum{ + "ASC": ListDhcpOptionsSortOrderAsc, + "DESC": ListDhcpOptionsSortOrderDesc, +} + +// GetListDhcpOptionsSortOrderEnumValues Enumerates the set of values for ListDhcpOptionsSortOrder +func GetListDhcpOptionsSortOrderEnumValues() []ListDhcpOptionsSortOrderEnum { + values := make([]ListDhcpOptionsSortOrderEnum, 0) + for _, v := range mappingListDhcpOptionsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_drg_attachments_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_drg_attachments_request_response.go new file mode 100644 index 000000000..d526209d5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_drg_attachments_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDrgAttachmentsRequest wrapper for the ListDrgAttachments operation +type ListDrgAttachmentsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"false" contributesTo:"query" name:"vcnId"` + + // The OCID of the DRG. + DrgId *string `mandatory:"false" contributesTo:"query" name:"drgId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDrgAttachmentsRequest) String() string { + return common.PointerString(request) +} + +// ListDrgAttachmentsResponse wrapper for the ListDrgAttachments operation +type ListDrgAttachmentsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DrgAttachment instance + Items []DrgAttachment `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDrgAttachmentsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_drgs_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_drgs_request_response.go new file mode 100644 index 000000000..6577f9c2f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_drgs_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDrgsRequest wrapper for the ListDrgs operation +type ListDrgsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDrgsRequest) String() string { + return common.PointerString(request) +} + +// ListDrgsResponse wrapper for the ListDrgs operation +type ListDrgsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Drg instance + Items []Drg `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDrgsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_services_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_services_request_response.go new file mode 100644 index 000000000..27614fd85 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_services_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListFastConnectProviderServicesRequest wrapper for the ListFastConnectProviderServices operation +type ListFastConnectProviderServicesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListFastConnectProviderServicesRequest) String() string { + return common.PointerString(request) +} + +// ListFastConnectProviderServicesResponse wrapper for the ListFastConnectProviderServices operation +type ListFastConnectProviderServicesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []FastConnectProviderService instance + Items []FastConnectProviderService `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListFastConnectProviderServicesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_virtual_circuit_bandwidth_shapes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_virtual_circuit_bandwidth_shapes_request_response.go new file mode 100644 index 000000000..6197b9b54 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_fast_connect_provider_virtual_circuit_bandwidth_shapes_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListFastConnectProviderVirtualCircuitBandwidthShapesRequest wrapper for the ListFastConnectProviderVirtualCircuitBandwidthShapes operation +type ListFastConnectProviderVirtualCircuitBandwidthShapesRequest struct { + + // The OCID of the provider service. + ProviderServiceId *string `mandatory:"true" contributesTo:"path" name:"providerServiceId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListFastConnectProviderVirtualCircuitBandwidthShapesRequest) String() string { + return common.PointerString(request) +} + +// ListFastConnectProviderVirtualCircuitBandwidthShapesResponse wrapper for the ListFastConnectProviderVirtualCircuitBandwidthShapes operation +type ListFastConnectProviderVirtualCircuitBandwidthShapesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VirtualCircuitBandwidthShape instance + Items []VirtualCircuitBandwidthShape `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListFastConnectProviderVirtualCircuitBandwidthShapesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_i_p_sec_connections_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_i_p_sec_connections_request_response.go new file mode 100644 index 000000000..c1b346754 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_i_p_sec_connections_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListIPSecConnectionsRequest wrapper for the ListIPSecConnections operation +type ListIPSecConnectionsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the DRG. + DrgId *string `mandatory:"false" contributesTo:"query" name:"drgId"` + + // The OCID of the CPE. + CpeId *string `mandatory:"false" contributesTo:"query" name:"cpeId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListIPSecConnectionsRequest) String() string { + return common.PointerString(request) +} + +// ListIPSecConnectionsResponse wrapper for the ListIPSecConnections operation +type ListIPSecConnectionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []IpSecConnection instance + Items []IpSecConnection `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListIPSecConnectionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_images_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_images_request_response.go new file mode 100644 index 000000000..5ac886860 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_images_request_response.go @@ -0,0 +1,123 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListImagesRequest wrapper for the ListImages operation +type ListImagesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The image's operating system. + // Example: `Oracle Linux` + OperatingSystem *string `mandatory:"false" contributesTo:"query" name:"operatingSystem"` + + // The image's operating system version. + // Example: `7.2` + OperatingSystemVersion *string `mandatory:"false" contributesTo:"query" name:"operatingSystemVersion"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListImagesSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListImagesSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState ImageLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListImagesRequest) String() string { + return common.PointerString(request) +} + +// ListImagesResponse wrapper for the ListImages operation +type ListImagesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Image instance + Items []Image `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListImagesResponse) String() string { + return common.PointerString(response) +} + +// ListImagesSortByEnum Enum with underlying type: string +type ListImagesSortByEnum string + +// Set of constants representing the allowable values for ListImagesSortBy +const ( + ListImagesSortByTimecreated ListImagesSortByEnum = "TIMECREATED" + ListImagesSortByDisplayname ListImagesSortByEnum = "DISPLAYNAME" +) + +var mappingListImagesSortBy = map[string]ListImagesSortByEnum{ + "TIMECREATED": ListImagesSortByTimecreated, + "DISPLAYNAME": ListImagesSortByDisplayname, +} + +// GetListImagesSortByEnumValues Enumerates the set of values for ListImagesSortBy +func GetListImagesSortByEnumValues() []ListImagesSortByEnum { + values := make([]ListImagesSortByEnum, 0) + for _, v := range mappingListImagesSortBy { + values = append(values, v) + } + return values +} + +// ListImagesSortOrderEnum Enum with underlying type: string +type ListImagesSortOrderEnum string + +// Set of constants representing the allowable values for ListImagesSortOrder +const ( + ListImagesSortOrderAsc ListImagesSortOrderEnum = "ASC" + ListImagesSortOrderDesc ListImagesSortOrderEnum = "DESC" +) + +var mappingListImagesSortOrder = map[string]ListImagesSortOrderEnum{ + "ASC": ListImagesSortOrderAsc, + "DESC": ListImagesSortOrderDesc, +} + +// GetListImagesSortOrderEnumValues Enumerates the set of values for ListImagesSortOrder +func GetListImagesSortOrderEnumValues() []ListImagesSortOrderEnum { + values := make([]ListImagesSortOrderEnum, 0) + for _, v := range mappingListImagesSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_instance_console_connections_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_instance_console_connections_request_response.go new file mode 100644 index 000000000..012b2a77b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_instance_console_connections_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListInstanceConsoleConnectionsRequest wrapper for the ListInstanceConsoleConnections operation +type ListInstanceConsoleConnectionsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the instance. + InstanceId *string `mandatory:"false" contributesTo:"query" name:"instanceId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListInstanceConsoleConnectionsRequest) String() string { + return common.PointerString(request) +} + +// ListInstanceConsoleConnectionsResponse wrapper for the ListInstanceConsoleConnections operation +type ListInstanceConsoleConnectionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []InstanceConsoleConnection instance + Items []InstanceConsoleConnection `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListInstanceConsoleConnectionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_instances_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_instances_request_response.go new file mode 100644 index 000000000..f687890c4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_instances_request_response.go @@ -0,0 +1,119 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListInstancesRequest wrapper for the ListInstances operation +type ListInstancesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" contributesTo:"query" name:"availabilityDomain"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListInstancesSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListInstancesSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState InstanceLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListInstancesRequest) String() string { + return common.PointerString(request) +} + +// ListInstancesResponse wrapper for the ListInstances operation +type ListInstancesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Instance instance + Items []Instance `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListInstancesResponse) String() string { + return common.PointerString(response) +} + +// ListInstancesSortByEnum Enum with underlying type: string +type ListInstancesSortByEnum string + +// Set of constants representing the allowable values for ListInstancesSortBy +const ( + ListInstancesSortByTimecreated ListInstancesSortByEnum = "TIMECREATED" + ListInstancesSortByDisplayname ListInstancesSortByEnum = "DISPLAYNAME" +) + +var mappingListInstancesSortBy = map[string]ListInstancesSortByEnum{ + "TIMECREATED": ListInstancesSortByTimecreated, + "DISPLAYNAME": ListInstancesSortByDisplayname, +} + +// GetListInstancesSortByEnumValues Enumerates the set of values for ListInstancesSortBy +func GetListInstancesSortByEnumValues() []ListInstancesSortByEnum { + values := make([]ListInstancesSortByEnum, 0) + for _, v := range mappingListInstancesSortBy { + values = append(values, v) + } + return values +} + +// ListInstancesSortOrderEnum Enum with underlying type: string +type ListInstancesSortOrderEnum string + +// Set of constants representing the allowable values for ListInstancesSortOrder +const ( + ListInstancesSortOrderAsc ListInstancesSortOrderEnum = "ASC" + ListInstancesSortOrderDesc ListInstancesSortOrderEnum = "DESC" +) + +var mappingListInstancesSortOrder = map[string]ListInstancesSortOrderEnum{ + "ASC": ListInstancesSortOrderAsc, + "DESC": ListInstancesSortOrderDesc, +} + +// GetListInstancesSortOrderEnumValues Enumerates the set of values for ListInstancesSortOrder +func GetListInstancesSortOrderEnumValues() []ListInstancesSortOrderEnum { + values := make([]ListInstancesSortOrderEnum, 0) + for _, v := range mappingListInstancesSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_internet_gateways_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_internet_gateways_request_response.go new file mode 100644 index 000000000..b37985a4d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_internet_gateways_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListInternetGatewaysRequest wrapper for the ListInternetGateways operation +type ListInternetGatewaysRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"query" name:"vcnId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListInternetGatewaysSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListInternetGatewaysSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState InternetGatewayLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListInternetGatewaysRequest) String() string { + return common.PointerString(request) +} + +// ListInternetGatewaysResponse wrapper for the ListInternetGateways operation +type ListInternetGatewaysResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []InternetGateway instance + Items []InternetGateway `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListInternetGatewaysResponse) String() string { + return common.PointerString(response) +} + +// ListInternetGatewaysSortByEnum Enum with underlying type: string +type ListInternetGatewaysSortByEnum string + +// Set of constants representing the allowable values for ListInternetGatewaysSortBy +const ( + ListInternetGatewaysSortByTimecreated ListInternetGatewaysSortByEnum = "TIMECREATED" + ListInternetGatewaysSortByDisplayname ListInternetGatewaysSortByEnum = "DISPLAYNAME" +) + +var mappingListInternetGatewaysSortBy = map[string]ListInternetGatewaysSortByEnum{ + "TIMECREATED": ListInternetGatewaysSortByTimecreated, + "DISPLAYNAME": ListInternetGatewaysSortByDisplayname, +} + +// GetListInternetGatewaysSortByEnumValues Enumerates the set of values for ListInternetGatewaysSortBy +func GetListInternetGatewaysSortByEnumValues() []ListInternetGatewaysSortByEnum { + values := make([]ListInternetGatewaysSortByEnum, 0) + for _, v := range mappingListInternetGatewaysSortBy { + values = append(values, v) + } + return values +} + +// ListInternetGatewaysSortOrderEnum Enum with underlying type: string +type ListInternetGatewaysSortOrderEnum string + +// Set of constants representing the allowable values for ListInternetGatewaysSortOrder +const ( + ListInternetGatewaysSortOrderAsc ListInternetGatewaysSortOrderEnum = "ASC" + ListInternetGatewaysSortOrderDesc ListInternetGatewaysSortOrderEnum = "DESC" +) + +var mappingListInternetGatewaysSortOrder = map[string]ListInternetGatewaysSortOrderEnum{ + "ASC": ListInternetGatewaysSortOrderAsc, + "DESC": ListInternetGatewaysSortOrderDesc, +} + +// GetListInternetGatewaysSortOrderEnumValues Enumerates the set of values for ListInternetGatewaysSortOrder +func GetListInternetGatewaysSortOrderEnumValues() []ListInternetGatewaysSortOrderEnum { + values := make([]ListInternetGatewaysSortOrderEnum, 0) + for _, v := range mappingListInternetGatewaysSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_local_peering_gateways_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_local_peering_gateways_request_response.go new file mode 100644 index 000000000..071ec59af --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_local_peering_gateways_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListLocalPeeringGatewaysRequest wrapper for the ListLocalPeeringGateways operation +type ListLocalPeeringGatewaysRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"query" name:"vcnId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListLocalPeeringGatewaysRequest) String() string { + return common.PointerString(request) +} + +// ListLocalPeeringGatewaysResponse wrapper for the ListLocalPeeringGateways operation +type ListLocalPeeringGatewaysResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []LocalPeeringGateway instance + Items []LocalPeeringGateway `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListLocalPeeringGatewaysResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_private_ips_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_private_ips_request_response.go new file mode 100644 index 000000000..7054edfc3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_private_ips_request_response.go @@ -0,0 +1,57 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListPrivateIpsRequest wrapper for the ListPrivateIps operation +type ListPrivateIpsRequest struct { + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The private IP address of the `privateIp` object. + // Example: `10.0.3.3` + IpAddress *string `mandatory:"false" contributesTo:"query" name:"ipAddress"` + + // The OCID of the subnet. + SubnetId *string `mandatory:"false" contributesTo:"query" name:"subnetId"` + + // The OCID of the VNIC. + VnicId *string `mandatory:"false" contributesTo:"query" name:"vnicId"` +} + +func (request ListPrivateIpsRequest) String() string { + return common.PointerString(request) +} + +// ListPrivateIpsResponse wrapper for the ListPrivateIps operation +type ListPrivateIpsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []PrivateIp instance + Items []PrivateIp `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListPrivateIpsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_route_tables_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_route_tables_request_response.go new file mode 100644 index 000000000..88cc414c2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_route_tables_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListRouteTablesRequest wrapper for the ListRouteTables operation +type ListRouteTablesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"query" name:"vcnId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListRouteTablesSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListRouteTablesSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState RouteTableLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListRouteTablesRequest) String() string { + return common.PointerString(request) +} + +// ListRouteTablesResponse wrapper for the ListRouteTables operation +type ListRouteTablesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []RouteTable instance + Items []RouteTable `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListRouteTablesResponse) String() string { + return common.PointerString(response) +} + +// ListRouteTablesSortByEnum Enum with underlying type: string +type ListRouteTablesSortByEnum string + +// Set of constants representing the allowable values for ListRouteTablesSortBy +const ( + ListRouteTablesSortByTimecreated ListRouteTablesSortByEnum = "TIMECREATED" + ListRouteTablesSortByDisplayname ListRouteTablesSortByEnum = "DISPLAYNAME" +) + +var mappingListRouteTablesSortBy = map[string]ListRouteTablesSortByEnum{ + "TIMECREATED": ListRouteTablesSortByTimecreated, + "DISPLAYNAME": ListRouteTablesSortByDisplayname, +} + +// GetListRouteTablesSortByEnumValues Enumerates the set of values for ListRouteTablesSortBy +func GetListRouteTablesSortByEnumValues() []ListRouteTablesSortByEnum { + values := make([]ListRouteTablesSortByEnum, 0) + for _, v := range mappingListRouteTablesSortBy { + values = append(values, v) + } + return values +} + +// ListRouteTablesSortOrderEnum Enum with underlying type: string +type ListRouteTablesSortOrderEnum string + +// Set of constants representing the allowable values for ListRouteTablesSortOrder +const ( + ListRouteTablesSortOrderAsc ListRouteTablesSortOrderEnum = "ASC" + ListRouteTablesSortOrderDesc ListRouteTablesSortOrderEnum = "DESC" +) + +var mappingListRouteTablesSortOrder = map[string]ListRouteTablesSortOrderEnum{ + "ASC": ListRouteTablesSortOrderAsc, + "DESC": ListRouteTablesSortOrderDesc, +} + +// GetListRouteTablesSortOrderEnumValues Enumerates the set of values for ListRouteTablesSortOrder +func GetListRouteTablesSortOrderEnumValues() []ListRouteTablesSortOrderEnum { + values := make([]ListRouteTablesSortOrderEnum, 0) + for _, v := range mappingListRouteTablesSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_security_lists_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_security_lists_request_response.go new file mode 100644 index 000000000..883452ce7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_security_lists_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListSecurityListsRequest wrapper for the ListSecurityLists operation +type ListSecurityListsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"query" name:"vcnId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListSecurityListsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListSecurityListsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState SecurityListLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListSecurityListsRequest) String() string { + return common.PointerString(request) +} + +// ListSecurityListsResponse wrapper for the ListSecurityLists operation +type ListSecurityListsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []SecurityList instance + Items []SecurityList `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListSecurityListsResponse) String() string { + return common.PointerString(response) +} + +// ListSecurityListsSortByEnum Enum with underlying type: string +type ListSecurityListsSortByEnum string + +// Set of constants representing the allowable values for ListSecurityListsSortBy +const ( + ListSecurityListsSortByTimecreated ListSecurityListsSortByEnum = "TIMECREATED" + ListSecurityListsSortByDisplayname ListSecurityListsSortByEnum = "DISPLAYNAME" +) + +var mappingListSecurityListsSortBy = map[string]ListSecurityListsSortByEnum{ + "TIMECREATED": ListSecurityListsSortByTimecreated, + "DISPLAYNAME": ListSecurityListsSortByDisplayname, +} + +// GetListSecurityListsSortByEnumValues Enumerates the set of values for ListSecurityListsSortBy +func GetListSecurityListsSortByEnumValues() []ListSecurityListsSortByEnum { + values := make([]ListSecurityListsSortByEnum, 0) + for _, v := range mappingListSecurityListsSortBy { + values = append(values, v) + } + return values +} + +// ListSecurityListsSortOrderEnum Enum with underlying type: string +type ListSecurityListsSortOrderEnum string + +// Set of constants representing the allowable values for ListSecurityListsSortOrder +const ( + ListSecurityListsSortOrderAsc ListSecurityListsSortOrderEnum = "ASC" + ListSecurityListsSortOrderDesc ListSecurityListsSortOrderEnum = "DESC" +) + +var mappingListSecurityListsSortOrder = map[string]ListSecurityListsSortOrderEnum{ + "ASC": ListSecurityListsSortOrderAsc, + "DESC": ListSecurityListsSortOrderDesc, +} + +// GetListSecurityListsSortOrderEnumValues Enumerates the set of values for ListSecurityListsSortOrder +func GetListSecurityListsSortOrderEnumValues() []ListSecurityListsSortOrderEnum { + values := make([]ListSecurityListsSortOrderEnum, 0) + for _, v := range mappingListSecurityListsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_shapes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_shapes_request_response.go new file mode 100644 index 000000000..71c7a2dec --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_shapes_request_response.go @@ -0,0 +1,57 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListShapesRequest wrapper for the ListShapes operation +type ListShapesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" contributesTo:"query" name:"availabilityDomain"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The OCID of an image. + ImageId *string `mandatory:"false" contributesTo:"query" name:"imageId"` +} + +func (request ListShapesRequest) String() string { + return common.PointerString(request) +} + +// ListShapesResponse wrapper for the ListShapes operation +type ListShapesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Shape instance + Items []Shape `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListShapesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_subnets_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_subnets_request_response.go new file mode 100644 index 000000000..a74e9e134 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_subnets_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListSubnetsRequest wrapper for the ListSubnets operation +type ListSubnetsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"query" name:"vcnId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListSubnetsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListSubnetsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState SubnetLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListSubnetsRequest) String() string { + return common.PointerString(request) +} + +// ListSubnetsResponse wrapper for the ListSubnets operation +type ListSubnetsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Subnet instance + Items []Subnet `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListSubnetsResponse) String() string { + return common.PointerString(response) +} + +// ListSubnetsSortByEnum Enum with underlying type: string +type ListSubnetsSortByEnum string + +// Set of constants representing the allowable values for ListSubnetsSortBy +const ( + ListSubnetsSortByTimecreated ListSubnetsSortByEnum = "TIMECREATED" + ListSubnetsSortByDisplayname ListSubnetsSortByEnum = "DISPLAYNAME" +) + +var mappingListSubnetsSortBy = map[string]ListSubnetsSortByEnum{ + "TIMECREATED": ListSubnetsSortByTimecreated, + "DISPLAYNAME": ListSubnetsSortByDisplayname, +} + +// GetListSubnetsSortByEnumValues Enumerates the set of values for ListSubnetsSortBy +func GetListSubnetsSortByEnumValues() []ListSubnetsSortByEnum { + values := make([]ListSubnetsSortByEnum, 0) + for _, v := range mappingListSubnetsSortBy { + values = append(values, v) + } + return values +} + +// ListSubnetsSortOrderEnum Enum with underlying type: string +type ListSubnetsSortOrderEnum string + +// Set of constants representing the allowable values for ListSubnetsSortOrder +const ( + ListSubnetsSortOrderAsc ListSubnetsSortOrderEnum = "ASC" + ListSubnetsSortOrderDesc ListSubnetsSortOrderEnum = "DESC" +) + +var mappingListSubnetsSortOrder = map[string]ListSubnetsSortOrderEnum{ + "ASC": ListSubnetsSortOrderAsc, + "DESC": ListSubnetsSortOrderDesc, +} + +// GetListSubnetsSortOrderEnumValues Enumerates the set of values for ListSubnetsSortOrder +func GetListSubnetsSortOrderEnumValues() []ListSubnetsSortOrderEnum { + values := make([]ListSubnetsSortOrderEnum, 0) + for _, v := range mappingListSubnetsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_vcns_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_vcns_request_response.go new file mode 100644 index 000000000..b1e5b0edd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_vcns_request_response.go @@ -0,0 +1,115 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVcnsRequest wrapper for the ListVcns operation +type ListVcnsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListVcnsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListVcnsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState VcnLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListVcnsRequest) String() string { + return common.PointerString(request) +} + +// ListVcnsResponse wrapper for the ListVcns operation +type ListVcnsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Vcn instance + Items []Vcn `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVcnsResponse) String() string { + return common.PointerString(response) +} + +// ListVcnsSortByEnum Enum with underlying type: string +type ListVcnsSortByEnum string + +// Set of constants representing the allowable values for ListVcnsSortBy +const ( + ListVcnsSortByTimecreated ListVcnsSortByEnum = "TIMECREATED" + ListVcnsSortByDisplayname ListVcnsSortByEnum = "DISPLAYNAME" +) + +var mappingListVcnsSortBy = map[string]ListVcnsSortByEnum{ + "TIMECREATED": ListVcnsSortByTimecreated, + "DISPLAYNAME": ListVcnsSortByDisplayname, +} + +// GetListVcnsSortByEnumValues Enumerates the set of values for ListVcnsSortBy +func GetListVcnsSortByEnumValues() []ListVcnsSortByEnum { + values := make([]ListVcnsSortByEnum, 0) + for _, v := range mappingListVcnsSortBy { + values = append(values, v) + } + return values +} + +// ListVcnsSortOrderEnum Enum with underlying type: string +type ListVcnsSortOrderEnum string + +// Set of constants representing the allowable values for ListVcnsSortOrder +const ( + ListVcnsSortOrderAsc ListVcnsSortOrderEnum = "ASC" + ListVcnsSortOrderDesc ListVcnsSortOrderEnum = "DESC" +) + +var mappingListVcnsSortOrder = map[string]ListVcnsSortOrderEnum{ + "ASC": ListVcnsSortOrderAsc, + "DESC": ListVcnsSortOrderDesc, +} + +// GetListVcnsSortOrderEnumValues Enumerates the set of values for ListVcnsSortOrder +func GetListVcnsSortOrderEnumValues() []ListVcnsSortOrderEnum { + values := make([]ListVcnsSortOrderEnum, 0) + for _, v := range mappingListVcnsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_bandwidth_shapes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_bandwidth_shapes_request_response.go new file mode 100644 index 000000000..3d0ac6253 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_bandwidth_shapes_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVirtualCircuitBandwidthShapesRequest wrapper for the ListVirtualCircuitBandwidthShapes operation +type ListVirtualCircuitBandwidthShapesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListVirtualCircuitBandwidthShapesRequest) String() string { + return common.PointerString(request) +} + +// ListVirtualCircuitBandwidthShapesResponse wrapper for the ListVirtualCircuitBandwidthShapes operation +type ListVirtualCircuitBandwidthShapesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VirtualCircuitBandwidthShape instance + Items []VirtualCircuitBandwidthShape `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVirtualCircuitBandwidthShapesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_public_prefixes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_public_prefixes_request_response.go new file mode 100644 index 000000000..0e885eb36 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuit_public_prefixes_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVirtualCircuitPublicPrefixesRequest wrapper for the ListVirtualCircuitPublicPrefixes operation +type ListVirtualCircuitPublicPrefixesRequest struct { + + // The OCID of the virtual circuit. + VirtualCircuitId *string `mandatory:"true" contributesTo:"path" name:"virtualCircuitId"` + + // A filter to only return resources that match the given verification state. + // The state value is case-insensitive. + VerificationState VirtualCircuitPublicPrefixVerificationStateEnum `mandatory:"false" contributesTo:"query" name:"verificationState" omitEmpty:"true"` +} + +func (request ListVirtualCircuitPublicPrefixesRequest) String() string { + return common.PointerString(request) +} + +// ListVirtualCircuitPublicPrefixesResponse wrapper for the ListVirtualCircuitPublicPrefixes operation +type ListVirtualCircuitPublicPrefixesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VirtualCircuitPublicPrefix instance + Items []VirtualCircuitPublicPrefix `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVirtualCircuitPublicPrefixesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuits_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuits_request_response.go new file mode 100644 index 000000000..65dc99414 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_virtual_circuits_request_response.go @@ -0,0 +1,115 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVirtualCircuitsRequest wrapper for the ListVirtualCircuits operation +type ListVirtualCircuitsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListVirtualCircuitsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListVirtualCircuitsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to return only resources that match the specified lifecycle state. The value is case insensitive. + LifecycleState VirtualCircuitLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListVirtualCircuitsRequest) String() string { + return common.PointerString(request) +} + +// ListVirtualCircuitsResponse wrapper for the ListVirtualCircuits operation +type ListVirtualCircuitsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VirtualCircuit instance + Items []VirtualCircuit `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVirtualCircuitsResponse) String() string { + return common.PointerString(response) +} + +// ListVirtualCircuitsSortByEnum Enum with underlying type: string +type ListVirtualCircuitsSortByEnum string + +// Set of constants representing the allowable values for ListVirtualCircuitsSortBy +const ( + ListVirtualCircuitsSortByTimecreated ListVirtualCircuitsSortByEnum = "TIMECREATED" + ListVirtualCircuitsSortByDisplayname ListVirtualCircuitsSortByEnum = "DISPLAYNAME" +) + +var mappingListVirtualCircuitsSortBy = map[string]ListVirtualCircuitsSortByEnum{ + "TIMECREATED": ListVirtualCircuitsSortByTimecreated, + "DISPLAYNAME": ListVirtualCircuitsSortByDisplayname, +} + +// GetListVirtualCircuitsSortByEnumValues Enumerates the set of values for ListVirtualCircuitsSortBy +func GetListVirtualCircuitsSortByEnumValues() []ListVirtualCircuitsSortByEnum { + values := make([]ListVirtualCircuitsSortByEnum, 0) + for _, v := range mappingListVirtualCircuitsSortBy { + values = append(values, v) + } + return values +} + +// ListVirtualCircuitsSortOrderEnum Enum with underlying type: string +type ListVirtualCircuitsSortOrderEnum string + +// Set of constants representing the allowable values for ListVirtualCircuitsSortOrder +const ( + ListVirtualCircuitsSortOrderAsc ListVirtualCircuitsSortOrderEnum = "ASC" + ListVirtualCircuitsSortOrderDesc ListVirtualCircuitsSortOrderEnum = "DESC" +) + +var mappingListVirtualCircuitsSortOrder = map[string]ListVirtualCircuitsSortOrderEnum{ + "ASC": ListVirtualCircuitsSortOrderAsc, + "DESC": ListVirtualCircuitsSortOrderDesc, +} + +// GetListVirtualCircuitsSortOrderEnumValues Enumerates the set of values for ListVirtualCircuitsSortOrder +func GetListVirtualCircuitsSortOrderEnumValues() []ListVirtualCircuitsSortOrderEnum { + values := make([]ListVirtualCircuitsSortOrderEnum, 0) + for _, v := range mappingListVirtualCircuitsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_vnic_attachments_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_vnic_attachments_request_response.go new file mode 100644 index 000000000..6746850b4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_vnic_attachments_request_response.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVnicAttachmentsRequest wrapper for the ListVnicAttachments operation +type ListVnicAttachmentsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" contributesTo:"query" name:"availabilityDomain"` + + // The OCID of the instance. + InstanceId *string `mandatory:"false" contributesTo:"query" name:"instanceId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The OCID of the VNIC. + VnicId *string `mandatory:"false" contributesTo:"query" name:"vnicId"` +} + +func (request ListVnicAttachmentsRequest) String() string { + return common.PointerString(request) +} + +// ListVnicAttachmentsResponse wrapper for the ListVnicAttachments operation +type ListVnicAttachmentsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VnicAttachment instance + Items []VnicAttachment `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVnicAttachmentsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_volume_attachments_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_volume_attachments_request_response.go new file mode 100644 index 000000000..5bc7ffdf4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_volume_attachments_request_response.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVolumeAttachmentsRequest wrapper for the ListVolumeAttachments operation +type ListVolumeAttachmentsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" contributesTo:"query" name:"availabilityDomain"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The OCID of the instance. + InstanceId *string `mandatory:"false" contributesTo:"query" name:"instanceId"` + + // The OCID of the volume. + VolumeId *string `mandatory:"false" contributesTo:"query" name:"volumeId"` +} + +func (request ListVolumeAttachmentsRequest) String() string { + return common.PointerString(request) +} + +// ListVolumeAttachmentsResponse wrapper for the ListVolumeAttachments operation +type ListVolumeAttachmentsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VolumeAttachment instance + Items []VolumeAttachment `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVolumeAttachmentsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_volume_backups_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_volume_backups_request_response.go new file mode 100644 index 000000000..19bdff08c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_volume_backups_request_response.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVolumeBackupsRequest wrapper for the ListVolumeBackups operation +type ListVolumeBackupsRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the volume. + VolumeId *string `mandatory:"false" contributesTo:"query" name:"volumeId"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListVolumeBackupsSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListVolumeBackupsSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState VolumeBackupLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListVolumeBackupsRequest) String() string { + return common.PointerString(request) +} + +// ListVolumeBackupsResponse wrapper for the ListVolumeBackups operation +type ListVolumeBackupsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []VolumeBackup instance + Items []VolumeBackup `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVolumeBackupsResponse) String() string { + return common.PointerString(response) +} + +// ListVolumeBackupsSortByEnum Enum with underlying type: string +type ListVolumeBackupsSortByEnum string + +// Set of constants representing the allowable values for ListVolumeBackupsSortBy +const ( + ListVolumeBackupsSortByTimecreated ListVolumeBackupsSortByEnum = "TIMECREATED" + ListVolumeBackupsSortByDisplayname ListVolumeBackupsSortByEnum = "DISPLAYNAME" +) + +var mappingListVolumeBackupsSortBy = map[string]ListVolumeBackupsSortByEnum{ + "TIMECREATED": ListVolumeBackupsSortByTimecreated, + "DISPLAYNAME": ListVolumeBackupsSortByDisplayname, +} + +// GetListVolumeBackupsSortByEnumValues Enumerates the set of values for ListVolumeBackupsSortBy +func GetListVolumeBackupsSortByEnumValues() []ListVolumeBackupsSortByEnum { + values := make([]ListVolumeBackupsSortByEnum, 0) + for _, v := range mappingListVolumeBackupsSortBy { + values = append(values, v) + } + return values +} + +// ListVolumeBackupsSortOrderEnum Enum with underlying type: string +type ListVolumeBackupsSortOrderEnum string + +// Set of constants representing the allowable values for ListVolumeBackupsSortOrder +const ( + ListVolumeBackupsSortOrderAsc ListVolumeBackupsSortOrderEnum = "ASC" + ListVolumeBackupsSortOrderDesc ListVolumeBackupsSortOrderEnum = "DESC" +) + +var mappingListVolumeBackupsSortOrder = map[string]ListVolumeBackupsSortOrderEnum{ + "ASC": ListVolumeBackupsSortOrderAsc, + "DESC": ListVolumeBackupsSortOrderDesc, +} + +// GetListVolumeBackupsSortOrderEnumValues Enumerates the set of values for ListVolumeBackupsSortOrder +func GetListVolumeBackupsSortOrderEnumValues() []ListVolumeBackupsSortOrderEnum { + values := make([]ListVolumeBackupsSortOrderEnum, 0) + for _, v := range mappingListVolumeBackupsSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/list_volumes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/list_volumes_request_response.go new file mode 100644 index 000000000..20bb4c553 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/list_volumes_request_response.go @@ -0,0 +1,119 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListVolumesRequest wrapper for the ListVolumes operation +type ListVolumesRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" contributesTo:"query" name:"availabilityDomain"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // A filter to return only resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // The field to sort by. You can provide one sort order (`sortOrder`). Default order for + // TIMECREATED is descending. Default order for DISPLAYNAME is ascending. The DISPLAYNAME + // sort order is case sensitive. + // **Note:** In general, some "List" operations (for example, `ListInstances`) let you + // optionally filter by Availability Domain if the scope of the resource type is within a + // single Availability Domain. If you call one of these "List" operations without specifying + // an Availability Domain, the resources are grouped by Availability Domain, then sorted. + SortBy ListVolumesSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either ascending (`ASC`) or descending (`DESC`). The DISPLAYNAME sort order + // is case sensitive. + SortOrder ListVolumesSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given lifecycle state. The state value is case-insensitive. + LifecycleState VolumeLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListVolumesRequest) String() string { + return common.PointerString(request) +} + +// ListVolumesResponse wrapper for the ListVolumes operation +type ListVolumesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Volume instance + Items []Volume `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListVolumesResponse) String() string { + return common.PointerString(response) +} + +// ListVolumesSortByEnum Enum with underlying type: string +type ListVolumesSortByEnum string + +// Set of constants representing the allowable values for ListVolumesSortBy +const ( + ListVolumesSortByTimecreated ListVolumesSortByEnum = "TIMECREATED" + ListVolumesSortByDisplayname ListVolumesSortByEnum = "DISPLAYNAME" +) + +var mappingListVolumesSortBy = map[string]ListVolumesSortByEnum{ + "TIMECREATED": ListVolumesSortByTimecreated, + "DISPLAYNAME": ListVolumesSortByDisplayname, +} + +// GetListVolumesSortByEnumValues Enumerates the set of values for ListVolumesSortBy +func GetListVolumesSortByEnumValues() []ListVolumesSortByEnum { + values := make([]ListVolumesSortByEnum, 0) + for _, v := range mappingListVolumesSortBy { + values = append(values, v) + } + return values +} + +// ListVolumesSortOrderEnum Enum with underlying type: string +type ListVolumesSortOrderEnum string + +// Set of constants representing the allowable values for ListVolumesSortOrder +const ( + ListVolumesSortOrderAsc ListVolumesSortOrderEnum = "ASC" + ListVolumesSortOrderDesc ListVolumesSortOrderEnum = "DESC" +) + +var mappingListVolumesSortOrder = map[string]ListVolumesSortOrderEnum{ + "ASC": ListVolumesSortOrderAsc, + "DESC": ListVolumesSortOrderDesc, +} + +// GetListVolumesSortOrderEnumValues Enumerates the set of values for ListVolumesSortOrder +func GetListVolumesSortOrderEnumValues() []ListVolumesSortOrderEnum { + values := make([]ListVolumesSortOrderEnum, 0) + for _, v := range mappingListVolumesSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/local_peering_gateway.go b/vendor/github.com/oracle/oci-go-sdk/core/local_peering_gateway.go new file mode 100644 index 000000000..61242c667 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/local_peering_gateway.go @@ -0,0 +1,123 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LocalPeeringGateway A local peering gateway (LPG) is an object on a VCN that lets that VCN peer +// with another VCN in the same region. *Peering* means that the two VCNs can +// communicate using private IP addresses, but without the traffic traversing the +// internet or routing through your on-premises network. For more information, +// see VCN Peering (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/VCNpeering.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type LocalPeeringGateway struct { + + // The OCID of the compartment containing the LPG. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid + // entering confidential information. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The LPG's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // Whether the VCN at the other end of the peering is in a different tenancy. + // Example: `false` + IsCrossTenancyPeering *bool `mandatory:"true" json:"isCrossTenancyPeering"` + + // The LPG's current lifecycle state. + LifecycleState LocalPeeringGatewayLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // Whether the LPG is peered with another LPG. `NEW` means the LPG has not yet been + // peered. `PENDING` means the peering is being established. `REVOKED` means the + // LPG at the other end of the peering has been deleted. + PeeringStatus LocalPeeringGatewayPeeringStatusEnum `mandatory:"true" json:"peeringStatus"` + + // The date and time the LPG was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the VCN the LPG belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // The range of IP addresses available on the VCN at the other + // end of the peering from this LPG. The value is `null` if the LPG is not peered. + // You can use this as the destination CIDR for a route rule to route a subnet's + // traffic to this LPG. + // Example: `192.168.0.0/16` + PeerAdvertisedCidr *string `mandatory:"false" json:"peerAdvertisedCidr"` + + // Additional information regarding the peering status, if applicable. + PeeringStatusDetails *string `mandatory:"false" json:"peeringStatusDetails"` +} + +func (m LocalPeeringGateway) String() string { + return common.PointerString(m) +} + +// LocalPeeringGatewayLifecycleStateEnum Enum with underlying type: string +type LocalPeeringGatewayLifecycleStateEnum string + +// Set of constants representing the allowable values for LocalPeeringGatewayLifecycleState +const ( + LocalPeeringGatewayLifecycleStateProvisioning LocalPeeringGatewayLifecycleStateEnum = "PROVISIONING" + LocalPeeringGatewayLifecycleStateAvailable LocalPeeringGatewayLifecycleStateEnum = "AVAILABLE" + LocalPeeringGatewayLifecycleStateTerminating LocalPeeringGatewayLifecycleStateEnum = "TERMINATING" + LocalPeeringGatewayLifecycleStateTerminated LocalPeeringGatewayLifecycleStateEnum = "TERMINATED" +) + +var mappingLocalPeeringGatewayLifecycleState = map[string]LocalPeeringGatewayLifecycleStateEnum{ + "PROVISIONING": LocalPeeringGatewayLifecycleStateProvisioning, + "AVAILABLE": LocalPeeringGatewayLifecycleStateAvailable, + "TERMINATING": LocalPeeringGatewayLifecycleStateTerminating, + "TERMINATED": LocalPeeringGatewayLifecycleStateTerminated, +} + +// GetLocalPeeringGatewayLifecycleStateEnumValues Enumerates the set of values for LocalPeeringGatewayLifecycleState +func GetLocalPeeringGatewayLifecycleStateEnumValues() []LocalPeeringGatewayLifecycleStateEnum { + values := make([]LocalPeeringGatewayLifecycleStateEnum, 0) + for _, v := range mappingLocalPeeringGatewayLifecycleState { + values = append(values, v) + } + return values +} + +// LocalPeeringGatewayPeeringStatusEnum Enum with underlying type: string +type LocalPeeringGatewayPeeringStatusEnum string + +// Set of constants representing the allowable values for LocalPeeringGatewayPeeringStatus +const ( + LocalPeeringGatewayPeeringStatusInvalid LocalPeeringGatewayPeeringStatusEnum = "INVALID" + LocalPeeringGatewayPeeringStatusNew LocalPeeringGatewayPeeringStatusEnum = "NEW" + LocalPeeringGatewayPeeringStatusPeered LocalPeeringGatewayPeeringStatusEnum = "PEERED" + LocalPeeringGatewayPeeringStatusPending LocalPeeringGatewayPeeringStatusEnum = "PENDING" + LocalPeeringGatewayPeeringStatusRevoked LocalPeeringGatewayPeeringStatusEnum = "REVOKED" +) + +var mappingLocalPeeringGatewayPeeringStatus = map[string]LocalPeeringGatewayPeeringStatusEnum{ + "INVALID": LocalPeeringGatewayPeeringStatusInvalid, + "NEW": LocalPeeringGatewayPeeringStatusNew, + "PEERED": LocalPeeringGatewayPeeringStatusPeered, + "PENDING": LocalPeeringGatewayPeeringStatusPending, + "REVOKED": LocalPeeringGatewayPeeringStatusRevoked, +} + +// GetLocalPeeringGatewayPeeringStatusEnumValues Enumerates the set of values for LocalPeeringGatewayPeeringStatus +func GetLocalPeeringGatewayPeeringStatusEnumValues() []LocalPeeringGatewayPeeringStatusEnum { + values := make([]LocalPeeringGatewayPeeringStatusEnum, 0) + for _, v := range mappingLocalPeeringGatewayPeeringStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/port_range.go b/vendor/github.com/oracle/oci-go-sdk/core/port_range.go new file mode 100644 index 000000000..f01332769 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/port_range.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PortRange The representation of PortRange +type PortRange struct { + + // The maximum port number. Must not be lower than the minimum port number. To specify + // a single port number, set both the min and max to the same value. + Max *int `mandatory:"true" json:"max"` + + // The minimum port number. Must not be greater than the maximum port number. + Min *int `mandatory:"true" json:"min"` +} + +func (m PortRange) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/private_ip.go b/vendor/github.com/oracle/oci-go-sdk/core/private_ip.go new file mode 100644 index 000000000..7ae7b37a0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/private_ip.go @@ -0,0 +1,89 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PrivateIp A *private IP* is a conceptual term that refers to a private IP address and related properties. +// The `privateIp` object is the API representation of a private IP. +// Each instance has a *primary private IP* that is automatically created and +// assigned to the primary VNIC during instance launch. If you add a secondary +// VNIC to the instance, it also automatically gets a primary private IP. You +// can't remove a primary private IP from its VNIC. The primary private IP is +// automatically deleted when the VNIC is terminated. +// You can add *secondary private IPs* to a VNIC after it's created. For more +// information, see the `privateIp` operations and also +// IP Addresses (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPaddresses.htm). +// **Note:** Only +// ListPrivateIps and +// GetPrivateIp work with +// *primary* private IPs. To create and update primary private IPs, you instead +// work with instance and VNIC operations. For example, a primary private IP's +// properties come from the values you specify in +// CreateVnicDetails when calling either +// LaunchInstance or +// AttachVnic. To update the hostname +// for a primary private IP, you use UpdateVnic. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type PrivateIp struct { + + // The private IP's Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"false" json:"availabilityDomain"` + + // The OCID of the compartment containing the private IP. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid + // entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The hostname for the private IP. Used for DNS. The value is the hostname + // portion of the private IP's fully qualified domain name (FQDN) + // (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be unique across all VNICs in the subnet and comply with + // RFC 952 (https://tools.ietf.org/html/rfc952) and + // RFC 1123 (https://tools.ietf.org/html/rfc1123). + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `bminstance-1` + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // The private IP's Oracle ID (OCID). + Id *string `mandatory:"false" json:"id"` + + // The private IP address of the `privateIp` object. The address is within the CIDR + // of the VNIC's subnet. + // Example: `10.0.3.3` + IpAddress *string `mandatory:"false" json:"ipAddress"` + + // Whether this private IP is the primary one on the VNIC. Primary private IPs + // are unassigned and deleted automatically when the VNIC is terminated. + // Example: `true` + IsPrimary *bool `mandatory:"false" json:"isPrimary"` + + // The OCID of the subnet the VNIC is in. + SubnetId *string `mandatory:"false" json:"subnetId"` + + // The date and time the private IP was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The OCID of the VNIC the private IP is assigned to. The VNIC and private IP + // must be in the same subnet. + VnicId *string `mandatory:"false" json:"vnicId"` +} + +func (m PrivateIp) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/route_rule.go b/vendor/github.com/oracle/oci-go-sdk/core/route_rule.go new file mode 100644 index 000000000..11b0e1b2a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/route_rule.go @@ -0,0 +1,32 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// RouteRule A mapping between a destination IP address range and a virtual device to route matching +// packets to (a target). +type RouteRule struct { + + // A destination IP address range in CIDR notation. Matching packets will + // be routed to the indicated network entity (the target). + // Example: `0.0.0.0/0` + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + // The OCID for the route rule's target. For information about the type of + // targets you can specify, see + // Route Tables (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm). + NetworkEntityId *string `mandatory:"true" json:"networkEntityId"` +} + +func (m RouteRule) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/route_table.go b/vendor/github.com/oracle/oci-go-sdk/core/route_table.go new file mode 100644 index 000000000..f255d131c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/route_table.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// RouteTable A collection of `RouteRule` objects, which are used to route packets +// based on destination IP to a particular network entity. For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type RouteTable struct { + + // The OCID of the compartment containing the route table. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The route table's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The route table's current state. + LifecycleState RouteTableLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The collection of rules for routing destination IPs to network devices. + RouteRules []RouteRule `mandatory:"true" json:"routeRules"` + + // The OCID of the VCN the route table list belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The date and time the route table was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m RouteTable) String() string { + return common.PointerString(m) +} + +// RouteTableLifecycleStateEnum Enum with underlying type: string +type RouteTableLifecycleStateEnum string + +// Set of constants representing the allowable values for RouteTableLifecycleState +const ( + RouteTableLifecycleStateProvisioning RouteTableLifecycleStateEnum = "PROVISIONING" + RouteTableLifecycleStateAvailable RouteTableLifecycleStateEnum = "AVAILABLE" + RouteTableLifecycleStateTerminating RouteTableLifecycleStateEnum = "TERMINATING" + RouteTableLifecycleStateTerminated RouteTableLifecycleStateEnum = "TERMINATED" +) + +var mappingRouteTableLifecycleState = map[string]RouteTableLifecycleStateEnum{ + "PROVISIONING": RouteTableLifecycleStateProvisioning, + "AVAILABLE": RouteTableLifecycleStateAvailable, + "TERMINATING": RouteTableLifecycleStateTerminating, + "TERMINATED": RouteTableLifecycleStateTerminated, +} + +// GetRouteTableLifecycleStateEnumValues Enumerates the set of values for RouteTableLifecycleState +func GetRouteTableLifecycleStateEnumValues() []RouteTableLifecycleStateEnum { + values := make([]RouteTableLifecycleStateEnum, 0) + for _, v := range mappingRouteTableLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/security_list.go b/vendor/github.com/oracle/oci-go-sdk/core/security_list.go new file mode 100644 index 000000000..d55bcd206 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/security_list.go @@ -0,0 +1,84 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// SecurityList A set of virtual firewall rules for your VCN. Security lists are configured at the subnet +// level, but the rules are applied to the ingress and egress traffic for the individual instances +// in the subnet. The rules can be stateful or stateless. For more information, see +// Security Lists (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm). +// **Important:** Oracle Cloud Infrastructure Compute service images automatically include firewall rules (for example, +// Linux iptables, Windows firewall). If there are issues with some type of access to an instance, +// make sure both the security lists associated with the instance's subnet and the instance's +// firewall rules are set correctly. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type SecurityList struct { + + // The OCID of the compartment containing the security list. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"true" json:"displayName"` + + // Rules for allowing egress IP packets. + EgressSecurityRules []EgressSecurityRule `mandatory:"true" json:"egressSecurityRules"` + + // The security list's Oracle Cloud ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // Rules for allowing ingress IP packets. + IngressSecurityRules []IngressSecurityRule `mandatory:"true" json:"ingressSecurityRules"` + + // The security list's current state. + LifecycleState SecurityListLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The date and time the security list was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the VCN the security list belongs to. + VcnId *string `mandatory:"true" json:"vcnId"` +} + +func (m SecurityList) String() string { + return common.PointerString(m) +} + +// SecurityListLifecycleStateEnum Enum with underlying type: string +type SecurityListLifecycleStateEnum string + +// Set of constants representing the allowable values for SecurityListLifecycleState +const ( + SecurityListLifecycleStateProvisioning SecurityListLifecycleStateEnum = "PROVISIONING" + SecurityListLifecycleStateAvailable SecurityListLifecycleStateEnum = "AVAILABLE" + SecurityListLifecycleStateTerminating SecurityListLifecycleStateEnum = "TERMINATING" + SecurityListLifecycleStateTerminated SecurityListLifecycleStateEnum = "TERMINATED" +) + +var mappingSecurityListLifecycleState = map[string]SecurityListLifecycleStateEnum{ + "PROVISIONING": SecurityListLifecycleStateProvisioning, + "AVAILABLE": SecurityListLifecycleStateAvailable, + "TERMINATING": SecurityListLifecycleStateTerminating, + "TERMINATED": SecurityListLifecycleStateTerminated, +} + +// GetSecurityListLifecycleStateEnumValues Enumerates the set of values for SecurityListLifecycleState +func GetSecurityListLifecycleStateEnumValues() []SecurityListLifecycleStateEnum { + values := make([]SecurityListLifecycleStateEnum, 0) + for _, v := range mappingSecurityListLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/shape.go b/vendor/github.com/oracle/oci-go-sdk/core/shape.go new file mode 100644 index 000000000..7cb572cff --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/shape.go @@ -0,0 +1,26 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Shape A compute instance shape that can be used in LaunchInstance. +// For more information, see Overview of the Compute Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Concepts/computeoverview.htm). +type Shape struct { + + // The name of the shape. You can enumerate all available shapes by calling + // ListShapes. + Shape *string `mandatory:"true" json:"shape"` +} + +func (m Shape) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/subnet.go b/vendor/github.com/oracle/oci-go-sdk/core/subnet.go new file mode 100644 index 000000000..d765cefce --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/subnet.go @@ -0,0 +1,131 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Subnet A logical subdivision of a VCN. Each subnet exists in a single Availability Domain and +// consists of a contiguous range of IP addresses that do not overlap with +// other subnets in the VCN. Example: 172.16.1.0/24. For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm) and +// VCNs and Subnets (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVCNs.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Subnet struct { + + // The subnet's Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The subnet's CIDR block. + // Example: `172.16.1.0/24` + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + // The OCID of the compartment containing the subnet. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The subnet's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The subnet's current state. + LifecycleState SubnetLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the route table the subnet is using. + RouteTableId *string `mandatory:"true" json:"routeTableId"` + + // The OCID of the VCN the subnet is in. + VcnId *string `mandatory:"true" json:"vcnId"` + + // The IP address of the virtual router. + // Example: `10.0.14.1` + VirtualRouterIp *string `mandatory:"true" json:"virtualRouterIp"` + + // The MAC address of the virtual router. + // Example: `00:00:17:B6:4D:DD` + VirtualRouterMac *string `mandatory:"true" json:"virtualRouterMac"` + + // The OCID of the set of DHCP options associated with the subnet. + DhcpOptionsId *string `mandatory:"false" json:"dhcpOptionsId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // A DNS label for the subnet, used in conjunction with the VNIC's hostname and + // VCN's DNS label to form a fully qualified domain name (FQDN) for each VNIC + // within this subnet (for example, `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be an alphanumeric string that begins with a letter and is unique within the VCN. + // The value cannot be changed. + // The absence of this parameter means the Internet and VCN Resolver + // will not resolve hostnames of instances in this subnet. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `subnet123` + DnsLabel *string `mandatory:"false" json:"dnsLabel"` + + // Whether VNICs within this subnet can have public IP addresses. + // Defaults to false, which means VNICs created in this subnet will + // automatically be assigned public IP addresses unless specified + // otherwise during instance launch or VNIC creation (with the + // `assignPublicIp` flag in + // CreateVnicDetails). + // If `prohibitPublicIpOnVnic` is set to true, VNICs created in this + // subnet cannot have public IP addresses (that is, it's a private + // subnet). + // Example: `true` + ProhibitPublicIpOnVnic *bool `mandatory:"false" json:"prohibitPublicIpOnVnic"` + + // OCIDs for the security lists to use for VNICs in this subnet. + SecurityListIds []string `mandatory:"false" json:"securityListIds"` + + // The subnet's domain name, which consists of the subnet's DNS label, + // the VCN's DNS label, and the `oraclevcn.com` domain. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `subnet123.vcn1.oraclevcn.com` + SubnetDomainName *string `mandatory:"false" json:"subnetDomainName"` + + // The date and time the subnet was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m Subnet) String() string { + return common.PointerString(m) +} + +// SubnetLifecycleStateEnum Enum with underlying type: string +type SubnetLifecycleStateEnum string + +// Set of constants representing the allowable values for SubnetLifecycleState +const ( + SubnetLifecycleStateProvisioning SubnetLifecycleStateEnum = "PROVISIONING" + SubnetLifecycleStateAvailable SubnetLifecycleStateEnum = "AVAILABLE" + SubnetLifecycleStateTerminating SubnetLifecycleStateEnum = "TERMINATING" + SubnetLifecycleStateTerminated SubnetLifecycleStateEnum = "TERMINATED" +) + +var mappingSubnetLifecycleState = map[string]SubnetLifecycleStateEnum{ + "PROVISIONING": SubnetLifecycleStateProvisioning, + "AVAILABLE": SubnetLifecycleStateAvailable, + "TERMINATING": SubnetLifecycleStateTerminating, + "TERMINATED": SubnetLifecycleStateTerminated, +} + +// GetSubnetLifecycleStateEnumValues Enumerates the set of values for SubnetLifecycleState +func GetSubnetLifecycleStateEnumValues() []SubnetLifecycleStateEnum { + values := make([]SubnetLifecycleStateEnum, 0) + for _, v := range mappingSubnetLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/tcp_options.go b/vendor/github.com/oracle/oci-go-sdk/core/tcp_options.go new file mode 100644 index 000000000..4037afbe8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/tcp_options.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// TcpOptions Optional object to specify ports for a TCP rule. If you specify TCP as the +// protocol but omit this object, then all ports are allowed. +type TcpOptions struct { + + // An inclusive range of allowed destination ports. Use the same number for the min and max + // to indicate a single port. Defaults to all ports if not specified. + DestinationPortRange *PortRange `mandatory:"false" json:"destinationPortRange"` + + // An inclusive range of allowed source ports. Use the same number for the min and max to + // indicate a single port. Defaults to all ports if not specified. + SourcePortRange *PortRange `mandatory:"false" json:"sourcePortRange"` +} + +func (m TcpOptions) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/terminate_instance_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/terminate_instance_request_response.go new file mode 100644 index 000000000..085b4c5d8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/terminate_instance_request_response.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// TerminateInstanceRequest wrapper for the TerminateInstance operation +type TerminateInstanceRequest struct { + + // The OCID of the instance. + InstanceId *string `mandatory:"true" contributesTo:"path" name:"instanceId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // Specifies whether to delete or preserve the boot volume when terminating an instance. + // The default value is false. + PreserveBootVolume *bool `mandatory:"false" contributesTo:"query" name:"preserveBootVolume"` +} + +func (request TerminateInstanceRequest) String() string { + return common.PointerString(request) +} + +// TerminateInstanceResponse wrapper for the TerminateInstance operation +type TerminateInstanceResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response TerminateInstanceResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/tunnel_config.go b/vendor/github.com/oracle/oci-go-sdk/core/tunnel_config.go new file mode 100644 index 000000000..fe12d0997 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/tunnel_config.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// TunnelConfig Specific connection details for an IPSec tunnel. +type TunnelConfig struct { + + // The IP address of Oracle's VPN headend. + // Example: `129.146.17.50` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // The shared secret of the IPSec tunnel. + // Example: `vFG2IF6TWq4UToUiLSRDoJEUs6j1c.p8G.dVQxiMfMO0yXMLi.lZTbYIWhGu4V8o` + SharedSecret *string `mandatory:"true" json:"sharedSecret"` + + // The date and time the IPSec connection was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m TunnelConfig) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/tunnel_status.go b/vendor/github.com/oracle/oci-go-sdk/core/tunnel_status.go new file mode 100644 index 000000000..c2655abc8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/tunnel_status.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// TunnelStatus Specific connection details for an IPSec tunnel. +type TunnelStatus struct { + + // The IP address of Oracle's VPN headend. + // Example: `129.146.17.50` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // The tunnel's current state. + LifecycleState TunnelStatusLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The date and time the IPSec connection was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // When the state of the tunnel last changed, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeStateModified *common.SDKTime `mandatory:"false" json:"timeStateModified"` +} + +func (m TunnelStatus) String() string { + return common.PointerString(m) +} + +// TunnelStatusLifecycleStateEnum Enum with underlying type: string +type TunnelStatusLifecycleStateEnum string + +// Set of constants representing the allowable values for TunnelStatusLifecycleState +const ( + TunnelStatusLifecycleStateUp TunnelStatusLifecycleStateEnum = "UP" + TunnelStatusLifecycleStateDown TunnelStatusLifecycleStateEnum = "DOWN" + TunnelStatusLifecycleStateDownForMaintenance TunnelStatusLifecycleStateEnum = "DOWN_FOR_MAINTENANCE" +) + +var mappingTunnelStatusLifecycleState = map[string]TunnelStatusLifecycleStateEnum{ + "UP": TunnelStatusLifecycleStateUp, + "DOWN": TunnelStatusLifecycleStateDown, + "DOWN_FOR_MAINTENANCE": TunnelStatusLifecycleStateDownForMaintenance, +} + +// GetTunnelStatusLifecycleStateEnumValues Enumerates the set of values for TunnelStatusLifecycleState +func GetTunnelStatusLifecycleStateEnumValues() []TunnelStatusLifecycleStateEnum { + values := make([]TunnelStatusLifecycleStateEnum, 0) + for _, v := range mappingTunnelStatusLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/udp_options.go b/vendor/github.com/oracle/oci-go-sdk/core/udp_options.go new file mode 100644 index 000000000..c68886ee2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/udp_options.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UdpOptions Optional object to specify ports for a UDP rule. If you specify UDP as the +// protocol but omit this object, then all ports are allowed. +type UdpOptions struct { + + // An inclusive range of allowed destination ports. Use the same number for the min and max + // to indicate a single port. Defaults to all ports if not specified. + DestinationPortRange *PortRange `mandatory:"false" json:"destinationPortRange"` + + // An inclusive range of allowed source ports. Use the same number for the min and max to + // indicate a single port. Defaults to all ports if not specified. + SourcePortRange *PortRange `mandatory:"false" json:"sourcePortRange"` +} + +func (m UdpOptions) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_details.go new file mode 100644 index 000000000..ead6727c7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateBootVolumeDetails The representation of UpdateBootVolumeDetails +type UpdateBootVolumeDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateBootVolumeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_request_response.go new file mode 100644 index 000000000..08ea32ad4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_boot_volume_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateBootVolumeRequest wrapper for the UpdateBootVolume operation +type UpdateBootVolumeRequest struct { + + // The OCID of the boot volume. + BootVolumeId *string `mandatory:"true" contributesTo:"path" name:"bootVolumeId"` + + // Update boot volume's display name. + UpdateBootVolumeDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateBootVolumeRequest) String() string { + return common.PointerString(request) +} + +// UpdateBootVolumeResponse wrapper for the UpdateBootVolume operation +type UpdateBootVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BootVolume instance + BootVolume `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateBootVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_console_history_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_console_history_details.go new file mode 100644 index 000000000..cfecb4ead --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_console_history_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateConsoleHistoryDetails The representation of UpdateConsoleHistoryDetails +type UpdateConsoleHistoryDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateConsoleHistoryDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_console_history_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_console_history_request_response.go new file mode 100644 index 000000000..c9bc64732 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_console_history_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateConsoleHistoryRequest wrapper for the UpdateConsoleHistory operation +type UpdateConsoleHistoryRequest struct { + + // The OCID of the console history. + InstanceConsoleHistoryId *string `mandatory:"true" contributesTo:"path" name:"instanceConsoleHistoryId"` + + // Update instance fields + UpdateConsoleHistoryDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateConsoleHistoryRequest) String() string { + return common.PointerString(request) +} + +// UpdateConsoleHistoryResponse wrapper for the UpdateConsoleHistory operation +type UpdateConsoleHistoryResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The ConsoleHistory instance + ConsoleHistory `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateConsoleHistoryResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_cpe_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_cpe_details.go new file mode 100644 index 000000000..bd0daa6ef --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_cpe_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateCpeDetails The representation of UpdateCpeDetails +type UpdateCpeDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateCpeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_cpe_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_cpe_request_response.go new file mode 100644 index 000000000..a87170834 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_cpe_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateCpeRequest wrapper for the UpdateCpe operation +type UpdateCpeRequest struct { + + // The OCID of the CPE. + CpeId *string `mandatory:"true" contributesTo:"path" name:"cpeId"` + + // Details object for updating a CPE. + UpdateCpeDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateCpeRequest) String() string { + return common.PointerString(request) +} + +// UpdateCpeResponse wrapper for the UpdateCpe operation +type UpdateCpeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Cpe instance + Cpe `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateCpeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_details.go new file mode 100644 index 000000000..4cfa19004 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateCrossConnectDetails Update a CrossConnect +type UpdateCrossConnectDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Set to true to activate the cross-connect. You activate it after the physical cabling + // is complete, and you've confirmed the cross-connect's light levels are good and your side + // of the interface is up. Activation indicates to Oracle that the physical connection is ready. + // Example: `true` + IsActive *bool `mandatory:"false" json:"isActive"` +} + +func (m UpdateCrossConnectDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_details.go new file mode 100644 index 000000000..97a424d29 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateCrossConnectGroupDetails The representation of UpdateCrossConnectGroupDetails +type UpdateCrossConnectGroupDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateCrossConnectGroupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_request_response.go new file mode 100644 index 000000000..23164788c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_group_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateCrossConnectGroupRequest wrapper for the UpdateCrossConnectGroup operation +type UpdateCrossConnectGroupRequest struct { + + // The OCID of the cross-connect group. + CrossConnectGroupId *string `mandatory:"true" contributesTo:"path" name:"crossConnectGroupId"` + + // Update CrossConnectGroup fields + UpdateCrossConnectGroupDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateCrossConnectGroupRequest) String() string { + return common.PointerString(request) +} + +// UpdateCrossConnectGroupResponse wrapper for the UpdateCrossConnectGroup operation +type UpdateCrossConnectGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnectGroup instance + CrossConnectGroup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateCrossConnectGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_request_response.go new file mode 100644 index 000000000..8af219a51 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_cross_connect_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateCrossConnectRequest wrapper for the UpdateCrossConnect operation +type UpdateCrossConnectRequest struct { + + // The OCID of the cross-connect. + CrossConnectId *string `mandatory:"true" contributesTo:"path" name:"crossConnectId"` + + // Update CrossConnect fields. + UpdateCrossConnectDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateCrossConnectRequest) String() string { + return common.PointerString(request) +} + +// UpdateCrossConnectResponse wrapper for the UpdateCrossConnect operation +type UpdateCrossConnectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CrossConnect instance + CrossConnect `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateCrossConnectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_details.go new file mode 100644 index 000000000..b2e221a13 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_details.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateDhcpDetails The representation of UpdateDhcpDetails +type UpdateDhcpDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + Options []DhcpOption `mandatory:"false" json:"options"` +} + +func (m UpdateDhcpDetails) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *UpdateDhcpDetails) UnmarshalJSON(data []byte) (e error) { + model := struct { + DisplayName *string `json:"displayName"` + Options []dhcpoption `json:"options"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.DisplayName = model.DisplayName + m.Options = make([]DhcpOption, len(model.Options)) + for i, n := range model.Options { + nn, err := n.UnmarshalPolymorphicJSON(n.JsonData) + if err != nil { + return err + } + m.Options[i] = nn + } + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_options_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_options_request_response.go new file mode 100644 index 000000000..c8b6e542d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_dhcp_options_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateDhcpOptionsRequest wrapper for the UpdateDhcpOptions operation +type UpdateDhcpOptionsRequest struct { + + // The OCID for the set of DHCP options. + DhcpId *string `mandatory:"true" contributesTo:"path" name:"dhcpId"` + + // Request object for updating a set of DHCP options. + UpdateDhcpDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateDhcpOptionsRequest) String() string { + return common.PointerString(request) +} + +// UpdateDhcpOptionsResponse wrapper for the UpdateDhcpOptions operation +type UpdateDhcpOptionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DhcpOptions instance + DhcpOptions `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateDhcpOptionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_details.go new file mode 100644 index 000000000..876f22c9d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateDrgAttachmentDetails The representation of UpdateDrgAttachmentDetails +type UpdateDrgAttachmentDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateDrgAttachmentDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_request_response.go new file mode 100644 index 000000000..c0580c97c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_attachment_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateDrgAttachmentRequest wrapper for the UpdateDrgAttachment operation +type UpdateDrgAttachmentRequest struct { + + // The OCID of the DRG attachment. + DrgAttachmentId *string `mandatory:"true" contributesTo:"path" name:"drgAttachmentId"` + + // Details object for updating a `DrgAttachment`. + UpdateDrgAttachmentDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateDrgAttachmentRequest) String() string { + return common.PointerString(request) +} + +// UpdateDrgAttachmentResponse wrapper for the UpdateDrgAttachment operation +type UpdateDrgAttachmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DrgAttachment instance + DrgAttachment `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateDrgAttachmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_drg_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_details.go new file mode 100644 index 000000000..2e64240b5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateDrgDetails The representation of UpdateDrgDetails +type UpdateDrgDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateDrgDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_drg_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_request_response.go new file mode 100644 index 000000000..0aba53e12 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_drg_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateDrgRequest wrapper for the UpdateDrg operation +type UpdateDrgRequest struct { + + // The OCID of the DRG. + DrgId *string `mandatory:"true" contributesTo:"path" name:"drgId"` + + // Details object for updating a DRG. + UpdateDrgDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateDrgRequest) String() string { + return common.PointerString(request) +} + +// UpdateDrgResponse wrapper for the UpdateDrg operation +type UpdateDrgResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Drg instance + Drg `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateDrgResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_i_p_sec_connection_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_i_p_sec_connection_request_response.go new file mode 100644 index 000000000..ad809bea8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_i_p_sec_connection_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateIPSecConnectionRequest wrapper for the UpdateIPSecConnection operation +type UpdateIPSecConnectionRequest struct { + + // The OCID of the IPSec connection. + IpscId *string `mandatory:"true" contributesTo:"path" name:"ipscId"` + + // Details object for updating a IPSec connection. + UpdateIpSecConnectionDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateIPSecConnectionRequest) String() string { + return common.PointerString(request) +} + +// UpdateIPSecConnectionResponse wrapper for the UpdateIPSecConnection operation +type UpdateIPSecConnectionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IpSecConnection instance + IpSecConnection `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateIPSecConnectionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_image_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_image_details.go new file mode 100644 index 000000000..f3c35d5fa --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_image_details.go @@ -0,0 +1,26 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateImageDetails The representation of UpdateImageDetails +type UpdateImageDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // Example: `My custom Oracle Linux image` + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateImageDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_image_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_image_request_response.go new file mode 100644 index 000000000..6757b1d1a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_image_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateImageRequest wrapper for the UpdateImage operation +type UpdateImageRequest struct { + + // The OCID of the image. + ImageId *string `mandatory:"true" contributesTo:"path" name:"imageId"` + + // Updates the image display name field. Avoid entering confidential information. + UpdateImageDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateImageRequest) String() string { + return common.PointerString(request) +} + +// UpdateImageResponse wrapper for the UpdateImage operation +type UpdateImageResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Image instance + Image `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateImageResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_instance_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_instance_details.go new file mode 100644 index 000000000..e18c8c402 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_instance_details.go @@ -0,0 +1,26 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateInstanceDetails The representation of UpdateInstanceDetails +type UpdateInstanceDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + // Example: `My bare metal instance` + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateInstanceDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_instance_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_instance_request_response.go new file mode 100644 index 000000000..3705804cd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_instance_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateInstanceRequest wrapper for the UpdateInstance operation +type UpdateInstanceRequest struct { + + // The OCID of the instance. + InstanceId *string `mandatory:"true" contributesTo:"path" name:"instanceId"` + + // Update instance fields + UpdateInstanceDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateInstanceRequest) String() string { + return common.PointerString(request) +} + +// UpdateInstanceResponse wrapper for the UpdateInstance operation +type UpdateInstanceResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Instance instance + Instance `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateInstanceResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_details.go new file mode 100644 index 000000000..9410eeef1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateInternetGatewayDetails The representation of UpdateInternetGatewayDetails +type UpdateInternetGatewayDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Whether the gateway is enabled. + IsEnabled *bool `mandatory:"false" json:"isEnabled"` +} + +func (m UpdateInternetGatewayDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_request_response.go new file mode 100644 index 000000000..a81ca3093 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_internet_gateway_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateInternetGatewayRequest wrapper for the UpdateInternetGateway operation +type UpdateInternetGatewayRequest struct { + + // The OCID of the Internet Gateway. + IgId *string `mandatory:"true" contributesTo:"path" name:"igId"` + + // Details for updating the Internet Gateway. + UpdateInternetGatewayDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateInternetGatewayRequest) String() string { + return common.PointerString(request) +} + +// UpdateInternetGatewayResponse wrapper for the UpdateInternetGateway operation +type UpdateInternetGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The InternetGateway instance + InternetGateway `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateInternetGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_ip_sec_connection_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_ip_sec_connection_details.go new file mode 100644 index 000000000..b6834690b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_ip_sec_connection_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateIpSecConnectionDetails The representation of UpdateIpSecConnectionDetails +type UpdateIpSecConnectionDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateIpSecConnectionDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_details.go new file mode 100644 index 000000000..7b9d10083 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateLocalPeeringGatewayDetails The representation of UpdateLocalPeeringGatewayDetails +type UpdateLocalPeeringGatewayDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid + // entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateLocalPeeringGatewayDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_request_response.go new file mode 100644 index 000000000..093c48638 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_local_peering_gateway_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateLocalPeeringGatewayRequest wrapper for the UpdateLocalPeeringGateway operation +type UpdateLocalPeeringGatewayRequest struct { + + // The OCID of the local peering gateway. + LocalPeeringGatewayId *string `mandatory:"true" contributesTo:"path" name:"localPeeringGatewayId"` + + // Details object for updating a local peering gateway. + UpdateLocalPeeringGatewayDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateLocalPeeringGatewayRequest) String() string { + return common.PointerString(request) +} + +// UpdateLocalPeeringGatewayResponse wrapper for the UpdateLocalPeeringGateway operation +type UpdateLocalPeeringGatewayResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The LocalPeeringGateway instance + LocalPeeringGateway `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateLocalPeeringGatewayResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_details.go new file mode 100644 index 000000000..96c7a2a74 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_details.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdatePrivateIpDetails The representation of UpdatePrivateIpDetails +type UpdatePrivateIpDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. Avoid + // entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The hostname for the private IP. Used for DNS. The value + // is the hostname portion of the private IP's fully qualified domain name (FQDN) + // (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be unique across all VNICs in the subnet and comply with + // RFC 952 (https://tools.ietf.org/html/rfc952) and + // RFC 1123 (https://tools.ietf.org/html/rfc1123). + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `bminstance-1` + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // The OCID of the VNIC to reassign the private IP to. The VNIC must + // be in the same subnet as the current VNIC. + VnicId *string `mandatory:"false" json:"vnicId"` +} + +func (m UpdatePrivateIpDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_request_response.go new file mode 100644 index 000000000..ae74cf5c7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_private_ip_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdatePrivateIpRequest wrapper for the UpdatePrivateIp operation +type UpdatePrivateIpRequest struct { + + // The private IP's OCID. + PrivateIpId *string `mandatory:"true" contributesTo:"path" name:"privateIpId"` + + // Private IP details. + UpdatePrivateIpDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdatePrivateIpRequest) String() string { + return common.PointerString(request) +} + +// UpdatePrivateIpResponse wrapper for the UpdatePrivateIp operation +type UpdatePrivateIpResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PrivateIp instance + PrivateIp `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdatePrivateIpResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_route_table_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_route_table_details.go new file mode 100644 index 000000000..547a1b2b9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_route_table_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateRouteTableDetails The representation of UpdateRouteTableDetails +type UpdateRouteTableDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The collection of rules used for routing destination IPs to network devices. + RouteRules []RouteRule `mandatory:"false" json:"routeRules"` +} + +func (m UpdateRouteTableDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_route_table_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_route_table_request_response.go new file mode 100644 index 000000000..5323576a9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_route_table_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateRouteTableRequest wrapper for the UpdateRouteTable operation +type UpdateRouteTableRequest struct { + + // The OCID of the route table. + RtId *string `mandatory:"true" contributesTo:"path" name:"rtId"` + + // Details object for updating a route table. + UpdateRouteTableDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateRouteTableRequest) String() string { + return common.PointerString(request) +} + +// UpdateRouteTableResponse wrapper for the UpdateRouteTable operation +type UpdateRouteTableResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The RouteTable instance + RouteTable `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateRouteTableResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_security_list_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_security_list_details.go new file mode 100644 index 000000000..d23a3f75c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_security_list_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateSecurityListDetails The representation of UpdateSecurityListDetails +type UpdateSecurityListDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Rules for allowing egress IP packets. + EgressSecurityRules []EgressSecurityRule `mandatory:"false" json:"egressSecurityRules"` + + // Rules for allowing ingress IP packets. + IngressSecurityRules []IngressSecurityRule `mandatory:"false" json:"ingressSecurityRules"` +} + +func (m UpdateSecurityListDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_security_list_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_security_list_request_response.go new file mode 100644 index 000000000..d9e7b468d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_security_list_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateSecurityListRequest wrapper for the UpdateSecurityList operation +type UpdateSecurityListRequest struct { + + // The OCID of the security list. + SecurityListId *string `mandatory:"true" contributesTo:"path" name:"securityListId"` + + // Updated details for the security list. + UpdateSecurityListDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateSecurityListRequest) String() string { + return common.PointerString(request) +} + +// UpdateSecurityListResponse wrapper for the UpdateSecurityList operation +type UpdateSecurityListResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The SecurityList instance + SecurityList `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateSecurityListResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_subnet_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_subnet_details.go new file mode 100644 index 000000000..e15eaa013 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_subnet_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateSubnetDetails The representation of UpdateSubnetDetails +type UpdateSubnetDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateSubnetDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_subnet_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_subnet_request_response.go new file mode 100644 index 000000000..1dec9a727 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_subnet_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateSubnetRequest wrapper for the UpdateSubnet operation +type UpdateSubnetRequest struct { + + // The OCID of the subnet. + SubnetId *string `mandatory:"true" contributesTo:"path" name:"subnetId"` + + // Details object for updating a subnet. + UpdateSubnetDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateSubnetRequest) String() string { + return common.PointerString(request) +} + +// UpdateSubnetResponse wrapper for the UpdateSubnet operation +type UpdateSubnetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Subnet instance + Subnet `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateSubnetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_vcn_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_vcn_details.go new file mode 100644 index 000000000..e4dca15cd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_vcn_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateVcnDetails The representation of UpdateVcnDetails +type UpdateVcnDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateVcnDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_vcn_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_vcn_request_response.go new file mode 100644 index 000000000..37e483eb0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_vcn_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateVcnRequest wrapper for the UpdateVcn operation +type UpdateVcnRequest struct { + + // The OCID of the VCN. + VcnId *string `mandatory:"true" contributesTo:"path" name:"vcnId"` + + // Details object for updating a VCN. + UpdateVcnDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateVcnRequest) String() string { + return common.PointerString(request) +} + +// UpdateVcnResponse wrapper for the UpdateVcn operation +type UpdateVcnResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Vcn instance + Vcn `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateVcnResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_details.go new file mode 100644 index 000000000..cbfaf178f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_details.go @@ -0,0 +1,90 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateVirtualCircuitDetails The representation of UpdateVirtualCircuitDetails +type UpdateVirtualCircuitDetails struct { + + // The provisioned data rate of the connection. To get a list of the + // available bandwidth levels (that is, shapes), see + // ListFastConnectProviderVirtualCircuitBandwidthShapes. + // To be updated only by the customer who owns the virtual circuit. + BandwidthShapeName *string `mandatory:"false" json:"bandwidthShapeName"` + + // An array of mappings, each containing properties for a cross-connect or + // cross-connect group associated with this virtual circuit. + // The customer and provider can update different properties in the mapping + // depending on the situation. See the description of the + // CrossConnectMapping. + CrossConnectMappings []CrossConnectMapping `mandatory:"false" json:"crossConnectMappings"` + + // The BGP ASN of the network at the other end of the BGP + // session from Oracle. + // If the BGP session is from the customer's edge router to Oracle, the + // required value is the customer's ASN, and it can be updated only + // by the customer. + // If the BGP session is from the provider's edge router to Oracle, the + // required value is the provider's ASN, and it can be updated only + // by the provider. + CustomerBgpAsn *int `mandatory:"false" json:"customerBgpAsn"` + + // A user-friendly name. Does not have to be unique. + // Avoid entering confidential information. + // To be updated only by the customer who owns the virtual circuit. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The OCID of the Drg + // that this private virtual circuit uses. + // To be updated only by the customer who owns the virtual circuit. + GatewayId *string `mandatory:"false" json:"gatewayId"` + + // The provider's state in relation to this virtual circuit. Relevant only + // if the customer is using FastConnect via a provider. ACTIVE + // means the provider has provisioned the virtual circuit from their + // end. INACTIVE means the provider has not yet provisioned the virtual + // circuit, or has de-provisioned it. + // To be updated only by the provider. + ProviderState UpdateVirtualCircuitDetailsProviderStateEnum `mandatory:"false" json:"providerState,omitempty"` + + // Provider-supplied reference information about this virtual circuit. + // Relevant only if the customer is using FastConnect via a provider. + // To be updated only by the provider. + ReferenceComment *string `mandatory:"false" json:"referenceComment"` +} + +func (m UpdateVirtualCircuitDetails) String() string { + return common.PointerString(m) +} + +// UpdateVirtualCircuitDetailsProviderStateEnum Enum with underlying type: string +type UpdateVirtualCircuitDetailsProviderStateEnum string + +// Set of constants representing the allowable values for UpdateVirtualCircuitDetailsProviderState +const ( + UpdateVirtualCircuitDetailsProviderStateActive UpdateVirtualCircuitDetailsProviderStateEnum = "ACTIVE" + UpdateVirtualCircuitDetailsProviderStateInactive UpdateVirtualCircuitDetailsProviderStateEnum = "INACTIVE" +) + +var mappingUpdateVirtualCircuitDetailsProviderState = map[string]UpdateVirtualCircuitDetailsProviderStateEnum{ + "ACTIVE": UpdateVirtualCircuitDetailsProviderStateActive, + "INACTIVE": UpdateVirtualCircuitDetailsProviderStateInactive, +} + +// GetUpdateVirtualCircuitDetailsProviderStateEnumValues Enumerates the set of values for UpdateVirtualCircuitDetailsProviderState +func GetUpdateVirtualCircuitDetailsProviderStateEnumValues() []UpdateVirtualCircuitDetailsProviderStateEnum { + values := make([]UpdateVirtualCircuitDetailsProviderStateEnum, 0) + for _, v := range mappingUpdateVirtualCircuitDetailsProviderState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_request_response.go new file mode 100644 index 000000000..7f2a8df15 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_virtual_circuit_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateVirtualCircuitRequest wrapper for the UpdateVirtualCircuit operation +type UpdateVirtualCircuitRequest struct { + + // The OCID of the virtual circuit. + VirtualCircuitId *string `mandatory:"true" contributesTo:"path" name:"virtualCircuitId"` + + // Update VirtualCircuit fields. + UpdateVirtualCircuitDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateVirtualCircuitRequest) String() string { + return common.PointerString(request) +} + +// UpdateVirtualCircuitResponse wrapper for the UpdateVirtualCircuit operation +type UpdateVirtualCircuitResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VirtualCircuit instance + VirtualCircuit `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateVirtualCircuitResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_vnic_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_vnic_details.go new file mode 100644 index 000000000..6eb74fde7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_vnic_details.go @@ -0,0 +1,45 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateVnicDetails The representation of UpdateVnicDetails +type UpdateVnicDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The hostname for the VNIC's primary private IP. Used for DNS. The value is the hostname + // portion of the primary private IP's fully qualified domain name (FQDN) + // (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be unique across all VNICs in the subnet and comply with + // RFC 952 (https://tools.ietf.org/html/rfc952) and + // RFC 1123 (https://tools.ietf.org/html/rfc1123). + // The value appears in the Vnic object and also the + // PrivateIp object returned by + // ListPrivateIps and + // GetPrivateIp. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // Whether the source/destination check is disabled on the VNIC. + // Defaults to `false`, which means the check is performed. For information + // about why you would skip the source/destination check, see + // Using a Private IP as a Route Target (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm#privateip). + // Example: `true` + SkipSourceDestCheck *bool `mandatory:"false" json:"skipSourceDestCheck"` +} + +func (m UpdateVnicDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_vnic_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_vnic_request_response.go new file mode 100644 index 000000000..9bacd4eb5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_vnic_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateVnicRequest wrapper for the UpdateVnic operation +type UpdateVnicRequest struct { + + // The OCID of the VNIC. + VnicId *string `mandatory:"true" contributesTo:"path" name:"vnicId"` + + // Details object for updating a VNIC. + UpdateVnicDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateVnicRequest) String() string { + return common.PointerString(request) +} + +// UpdateVnicResponse wrapper for the UpdateVnic operation +type UpdateVnicResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Vnic instance + Vnic `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateVnicResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_details.go new file mode 100644 index 000000000..05be76e2b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateVolumeBackupDetails The representation of UpdateVolumeBackupDetails +type UpdateVolumeBackupDetails struct { + + // A friendly user-specified name for the volume backup. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateVolumeBackupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_request_response.go new file mode 100644 index 000000000..e98d05109 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_backup_request_response.go @@ -0,0 +1,45 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateVolumeBackupRequest wrapper for the UpdateVolumeBackup operation +type UpdateVolumeBackupRequest struct { + + // The OCID of the volume backup. + VolumeBackupId *string `mandatory:"true" contributesTo:"path" name:"volumeBackupId"` + + // Update volume backup fields + UpdateVolumeBackupDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateVolumeBackupRequest) String() string { + return common.PointerString(request) +} + +// UpdateVolumeBackupResponse wrapper for the UpdateVolumeBackup operation +type UpdateVolumeBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The VolumeBackup instance + VolumeBackup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateVolumeBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_details.go new file mode 100644 index 000000000..e0b642bd7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_details.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateVolumeDetails The representation of UpdateVolumeDetails +type UpdateVolumeDetails struct { + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateVolumeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/update_volume_request_response.go b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_request_response.go new file mode 100644 index 000000000..b8b044f97 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/update_volume_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateVolumeRequest wrapper for the UpdateVolume operation +type UpdateVolumeRequest struct { + + // The OCID of the volume. + VolumeId *string `mandatory:"true" contributesTo:"path" name:"volumeId"` + + // Update volume's display name. Avoid entering confidential information. + UpdateVolumeDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateVolumeRequest) String() string { + return common.PointerString(request) +} + +// UpdateVolumeResponse wrapper for the UpdateVolume operation +type UpdateVolumeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Volume instance + Volume `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateVolumeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/vcn.go b/vendor/github.com/oracle/oci-go-sdk/core/vcn.go new file mode 100644 index 000000000..8077a531d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/vcn.go @@ -0,0 +1,101 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Vcn A Virtual Cloud Network (VCN). For more information, see +// Overview of the Networking Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Vcn struct { + + // The CIDR IP address block of the VCN. + // Example: `172.16.0.0/16` + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + // The OCID of the compartment containing the VCN. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The VCN's Oracle ID (OCID). + Id *string `mandatory:"true" json:"id"` + + // The VCN's current state. + LifecycleState VcnLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID for the VCN's default set of DHCP options. + DefaultDhcpOptionsId *string `mandatory:"false" json:"defaultDhcpOptionsId"` + + // The OCID for the VCN's default route table. + DefaultRouteTableId *string `mandatory:"false" json:"defaultRouteTableId"` + + // The OCID for the VCN's default security list. + DefaultSecurityListId *string `mandatory:"false" json:"defaultSecurityListId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // A DNS label for the VCN, used in conjunction with the VNIC's hostname and + // subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC + // within this subnet (for example, `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be an alphanumeric string that begins with a letter. + // The value cannot be changed. + // The absence of this parameter means the Internet and VCN Resolver will + // not work for this VCN. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `vcn1` + DnsLabel *string `mandatory:"false" json:"dnsLabel"` + + // The date and time the VCN was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The VCN's domain name, which consists of the VCN's DNS label, and the + // `oraclevcn.com` domain. + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `vcn1.oraclevcn.com` + VcnDomainName *string `mandatory:"false" json:"vcnDomainName"` +} + +func (m Vcn) String() string { + return common.PointerString(m) +} + +// VcnLifecycleStateEnum Enum with underlying type: string +type VcnLifecycleStateEnum string + +// Set of constants representing the allowable values for VcnLifecycleState +const ( + VcnLifecycleStateProvisioning VcnLifecycleStateEnum = "PROVISIONING" + VcnLifecycleStateAvailable VcnLifecycleStateEnum = "AVAILABLE" + VcnLifecycleStateTerminating VcnLifecycleStateEnum = "TERMINATING" + VcnLifecycleStateTerminated VcnLifecycleStateEnum = "TERMINATED" +) + +var mappingVcnLifecycleState = map[string]VcnLifecycleStateEnum{ + "PROVISIONING": VcnLifecycleStateProvisioning, + "AVAILABLE": VcnLifecycleStateAvailable, + "TERMINATING": VcnLifecycleStateTerminating, + "TERMINATED": VcnLifecycleStateTerminated, +} + +// GetVcnLifecycleStateEnumValues Enumerates the set of values for VcnLifecycleState +func GetVcnLifecycleStateEnumValues() []VcnLifecycleStateEnum { + values := make([]VcnLifecycleStateEnum, 0) + for _, v := range mappingVcnLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit.go b/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit.go new file mode 100644 index 000000000..492c84bf4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit.go @@ -0,0 +1,273 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// VirtualCircuit For use with Oracle Cloud Infrastructure FastConnect. +// A virtual circuit is an isolated network path that runs over one or more physical +// network connections to provide a single, logical connection between the edge router +// on the customer's existing network and Oracle Cloud Infrastructure. *Private* +// virtual circuits support private peering, and *public* virtual circuits support +// public peering. For more information, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +// Each virtual circuit is made up of information shared between a customer, Oracle, +// and a provider (if the customer is using FastConnect via a provider). Who fills in +// a given property of a virtual circuit depends on whether the BGP session related to +// that virtual circuit goes from the customer's edge router to Oracle, or from the provider's +// edge router to Oracle. Also, in the case where the customer is using a provider, values +// for some of the properties may not be present immediately, but may get filled in as the +// provider and Oracle each do their part to provision the virtual circuit. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type VirtualCircuit struct { + + // The provisioned data rate of the connection. + BandwidthShapeName *string `mandatory:"false" json:"bandwidthShapeName"` + + // BGP management option. + BgpManagement VirtualCircuitBgpManagementEnum `mandatory:"false" json:"bgpManagement,omitempty"` + + // The state of the BGP session associated with the virtual circuit. + BgpSessionState VirtualCircuitBgpSessionStateEnum `mandatory:"false" json:"bgpSessionState,omitempty"` + + // The OCID of the compartment containing the virtual circuit. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // An array of mappings, each containing properties for a + // cross-connect or cross-connect group that is associated with this + // virtual circuit. + CrossConnectMappings []CrossConnectMapping `mandatory:"false" json:"crossConnectMappings"` + + // The BGP ASN of the network at the other end of the BGP + // session from Oracle. If the session is between the customer's + // edge router and Oracle, the value is the customer's ASN. If the BGP + // session is between the provider's edge router and Oracle, the value + // is the provider's ASN. + CustomerBgpAsn *int `mandatory:"false" json:"customerBgpAsn"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The OCID of the customer's Drg + // that this virtual circuit uses. Applicable only to private virtual circuits. + GatewayId *string `mandatory:"false" json:"gatewayId"` + + // The virtual circuit's Oracle ID (OCID). + Id *string `mandatory:"false" json:"id"` + + // The virtual circuit's current state. For information about + // the different states, see + // FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). + LifecycleState VirtualCircuitLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The Oracle BGP ASN. + OracleBgpAsn *int `mandatory:"false" json:"oracleBgpAsn"` + + // Deprecated. Instead use `providerServiceId`. + ProviderName *string `mandatory:"false" json:"providerName"` + + // The OCID of the service offered by the provider (if the customer is connecting via a provider). + ProviderServiceId *string `mandatory:"false" json:"providerServiceId"` + + // Deprecated. Instead use `providerServiceId`. + ProviderServiceName *string `mandatory:"false" json:"providerServiceName"` + + // The provider's state in relation to this virtual circuit (if the + // customer is connecting via a provider). ACTIVE means + // the provider has provisioned the virtual circuit from their end. + // INACTIVE means the provider has not yet provisioned the virtual + // circuit, or has de-provisioned it. + ProviderState VirtualCircuitProviderStateEnum `mandatory:"false" json:"providerState,omitempty"` + + // For a public virtual circuit. The public IP prefixes (CIDRs) the customer wants to + // advertise across the connection. Each prefix must be /24 or less specific. + PublicPrefixes []string `mandatory:"false" json:"publicPrefixes"` + + // Provider-supplied reference information about this virtual circuit + // (if the customer is connecting via a provider). + ReferenceComment *string `mandatory:"false" json:"referenceComment"` + + // The Oracle Cloud Infrastructure region where this virtual + // circuit is located. + Region *string `mandatory:"false" json:"region"` + + // Provider service type. + ServiceType VirtualCircuitServiceTypeEnum `mandatory:"false" json:"serviceType,omitempty"` + + // The date and time the virtual circuit was created, + // in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // Whether the virtual circuit supports private or public peering. For more information, + // see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). + Type VirtualCircuitTypeEnum `mandatory:"false" json:"type,omitempty"` +} + +func (m VirtualCircuit) String() string { + return common.PointerString(m) +} + +// VirtualCircuitBgpManagementEnum Enum with underlying type: string +type VirtualCircuitBgpManagementEnum string + +// Set of constants representing the allowable values for VirtualCircuitBgpManagement +const ( + VirtualCircuitBgpManagementCustomerManaged VirtualCircuitBgpManagementEnum = "CUSTOMER_MANAGED" + VirtualCircuitBgpManagementProviderManaged VirtualCircuitBgpManagementEnum = "PROVIDER_MANAGED" + VirtualCircuitBgpManagementOracleManaged VirtualCircuitBgpManagementEnum = "ORACLE_MANAGED" +) + +var mappingVirtualCircuitBgpManagement = map[string]VirtualCircuitBgpManagementEnum{ + "CUSTOMER_MANAGED": VirtualCircuitBgpManagementCustomerManaged, + "PROVIDER_MANAGED": VirtualCircuitBgpManagementProviderManaged, + "ORACLE_MANAGED": VirtualCircuitBgpManagementOracleManaged, +} + +// GetVirtualCircuitBgpManagementEnumValues Enumerates the set of values for VirtualCircuitBgpManagement +func GetVirtualCircuitBgpManagementEnumValues() []VirtualCircuitBgpManagementEnum { + values := make([]VirtualCircuitBgpManagementEnum, 0) + for _, v := range mappingVirtualCircuitBgpManagement { + values = append(values, v) + } + return values +} + +// VirtualCircuitBgpSessionStateEnum Enum with underlying type: string +type VirtualCircuitBgpSessionStateEnum string + +// Set of constants representing the allowable values for VirtualCircuitBgpSessionState +const ( + VirtualCircuitBgpSessionStateUp VirtualCircuitBgpSessionStateEnum = "UP" + VirtualCircuitBgpSessionStateDown VirtualCircuitBgpSessionStateEnum = "DOWN" +) + +var mappingVirtualCircuitBgpSessionState = map[string]VirtualCircuitBgpSessionStateEnum{ + "UP": VirtualCircuitBgpSessionStateUp, + "DOWN": VirtualCircuitBgpSessionStateDown, +} + +// GetVirtualCircuitBgpSessionStateEnumValues Enumerates the set of values for VirtualCircuitBgpSessionState +func GetVirtualCircuitBgpSessionStateEnumValues() []VirtualCircuitBgpSessionStateEnum { + values := make([]VirtualCircuitBgpSessionStateEnum, 0) + for _, v := range mappingVirtualCircuitBgpSessionState { + values = append(values, v) + } + return values +} + +// VirtualCircuitLifecycleStateEnum Enum with underlying type: string +type VirtualCircuitLifecycleStateEnum string + +// Set of constants representing the allowable values for VirtualCircuitLifecycleState +const ( + VirtualCircuitLifecycleStatePendingProvider VirtualCircuitLifecycleStateEnum = "PENDING_PROVIDER" + VirtualCircuitLifecycleStateVerifying VirtualCircuitLifecycleStateEnum = "VERIFYING" + VirtualCircuitLifecycleStateProvisioning VirtualCircuitLifecycleStateEnum = "PROVISIONING" + VirtualCircuitLifecycleStateProvisioned VirtualCircuitLifecycleStateEnum = "PROVISIONED" + VirtualCircuitLifecycleStateFailed VirtualCircuitLifecycleStateEnum = "FAILED" + VirtualCircuitLifecycleStateInactive VirtualCircuitLifecycleStateEnum = "INACTIVE" + VirtualCircuitLifecycleStateTerminating VirtualCircuitLifecycleStateEnum = "TERMINATING" + VirtualCircuitLifecycleStateTerminated VirtualCircuitLifecycleStateEnum = "TERMINATED" +) + +var mappingVirtualCircuitLifecycleState = map[string]VirtualCircuitLifecycleStateEnum{ + "PENDING_PROVIDER": VirtualCircuitLifecycleStatePendingProvider, + "VERIFYING": VirtualCircuitLifecycleStateVerifying, + "PROVISIONING": VirtualCircuitLifecycleStateProvisioning, + "PROVISIONED": VirtualCircuitLifecycleStateProvisioned, + "FAILED": VirtualCircuitLifecycleStateFailed, + "INACTIVE": VirtualCircuitLifecycleStateInactive, + "TERMINATING": VirtualCircuitLifecycleStateTerminating, + "TERMINATED": VirtualCircuitLifecycleStateTerminated, +} + +// GetVirtualCircuitLifecycleStateEnumValues Enumerates the set of values for VirtualCircuitLifecycleState +func GetVirtualCircuitLifecycleStateEnumValues() []VirtualCircuitLifecycleStateEnum { + values := make([]VirtualCircuitLifecycleStateEnum, 0) + for _, v := range mappingVirtualCircuitLifecycleState { + values = append(values, v) + } + return values +} + +// VirtualCircuitProviderStateEnum Enum with underlying type: string +type VirtualCircuitProviderStateEnum string + +// Set of constants representing the allowable values for VirtualCircuitProviderState +const ( + VirtualCircuitProviderStateActive VirtualCircuitProviderStateEnum = "ACTIVE" + VirtualCircuitProviderStateInactive VirtualCircuitProviderStateEnum = "INACTIVE" +) + +var mappingVirtualCircuitProviderState = map[string]VirtualCircuitProviderStateEnum{ + "ACTIVE": VirtualCircuitProviderStateActive, + "INACTIVE": VirtualCircuitProviderStateInactive, +} + +// GetVirtualCircuitProviderStateEnumValues Enumerates the set of values for VirtualCircuitProviderState +func GetVirtualCircuitProviderStateEnumValues() []VirtualCircuitProviderStateEnum { + values := make([]VirtualCircuitProviderStateEnum, 0) + for _, v := range mappingVirtualCircuitProviderState { + values = append(values, v) + } + return values +} + +// VirtualCircuitServiceTypeEnum Enum with underlying type: string +type VirtualCircuitServiceTypeEnum string + +// Set of constants representing the allowable values for VirtualCircuitServiceType +const ( + VirtualCircuitServiceTypeColocated VirtualCircuitServiceTypeEnum = "COLOCATED" + VirtualCircuitServiceTypeLayer2 VirtualCircuitServiceTypeEnum = "LAYER2" + VirtualCircuitServiceTypeLayer3 VirtualCircuitServiceTypeEnum = "LAYER3" +) + +var mappingVirtualCircuitServiceType = map[string]VirtualCircuitServiceTypeEnum{ + "COLOCATED": VirtualCircuitServiceTypeColocated, + "LAYER2": VirtualCircuitServiceTypeLayer2, + "LAYER3": VirtualCircuitServiceTypeLayer3, +} + +// GetVirtualCircuitServiceTypeEnumValues Enumerates the set of values for VirtualCircuitServiceType +func GetVirtualCircuitServiceTypeEnumValues() []VirtualCircuitServiceTypeEnum { + values := make([]VirtualCircuitServiceTypeEnum, 0) + for _, v := range mappingVirtualCircuitServiceType { + values = append(values, v) + } + return values +} + +// VirtualCircuitTypeEnum Enum with underlying type: string +type VirtualCircuitTypeEnum string + +// Set of constants representing the allowable values for VirtualCircuitType +const ( + VirtualCircuitTypePublic VirtualCircuitTypeEnum = "PUBLIC" + VirtualCircuitTypePrivate VirtualCircuitTypeEnum = "PRIVATE" +) + +var mappingVirtualCircuitType = map[string]VirtualCircuitTypeEnum{ + "PUBLIC": VirtualCircuitTypePublic, + "PRIVATE": VirtualCircuitTypePrivate, +} + +// GetVirtualCircuitTypeEnumValues Enumerates the set of values for VirtualCircuitType +func GetVirtualCircuitTypeEnumValues() []VirtualCircuitTypeEnum { + values := make([]VirtualCircuitTypeEnum, 0) + for _, v := range mappingVirtualCircuitType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_bandwidth_shape.go b/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_bandwidth_shape.go new file mode 100644 index 000000000..e237448d5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_bandwidth_shape.go @@ -0,0 +1,29 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// VirtualCircuitBandwidthShape An individual bandwidth level for virtual circuits. +type VirtualCircuitBandwidthShape struct { + + // The name of the bandwidth shape. + // Example: `10 Gbps` + Name *string `mandatory:"true" json:"name"` + + // The bandwidth in Mbps. + // Example: `10000` + BandwidthInMbps *int `mandatory:"false" json:"bandwidthInMbps"` +} + +func (m VirtualCircuitBandwidthShape) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_public_prefix.go b/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_public_prefix.go new file mode 100644 index 000000000..62c1f41f3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/virtual_circuit_public_prefix.go @@ -0,0 +1,58 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// VirtualCircuitPublicPrefix A public IP prefix and its details. With a public virtual circuit, the customer +// specifies the customer-owned public IP prefixes to advertise across the connection. +// For more information, see FastConnect Overview (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/fastconnect.htm). +type VirtualCircuitPublicPrefix struct { + + // Publix IP prefix (CIDR) that the customer specified. + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + // Oracle must verify that the customer owns the public IP prefix before traffic + // for that prefix can flow across the virtual circuit. Verification can take a + // few business days. `IN_PROGRESS` means Oracle is verifying the prefix. `COMPLETED` + // means verification succeeded. `FAILED` means verification failed and traffic for + // this prefix will not flow across the connection. + VerificationState VirtualCircuitPublicPrefixVerificationStateEnum `mandatory:"true" json:"verificationState"` +} + +func (m VirtualCircuitPublicPrefix) String() string { + return common.PointerString(m) +} + +// VirtualCircuitPublicPrefixVerificationStateEnum Enum with underlying type: string +type VirtualCircuitPublicPrefixVerificationStateEnum string + +// Set of constants representing the allowable values for VirtualCircuitPublicPrefixVerificationState +const ( + VirtualCircuitPublicPrefixVerificationStateInProgress VirtualCircuitPublicPrefixVerificationStateEnum = "IN_PROGRESS" + VirtualCircuitPublicPrefixVerificationStateCompleted VirtualCircuitPublicPrefixVerificationStateEnum = "COMPLETED" + VirtualCircuitPublicPrefixVerificationStateFailed VirtualCircuitPublicPrefixVerificationStateEnum = "FAILED" +) + +var mappingVirtualCircuitPublicPrefixVerificationState = map[string]VirtualCircuitPublicPrefixVerificationStateEnum{ + "IN_PROGRESS": VirtualCircuitPublicPrefixVerificationStateInProgress, + "COMPLETED": VirtualCircuitPublicPrefixVerificationStateCompleted, + "FAILED": VirtualCircuitPublicPrefixVerificationStateFailed, +} + +// GetVirtualCircuitPublicPrefixVerificationStateEnumValues Enumerates the set of values for VirtualCircuitPublicPrefixVerificationState +func GetVirtualCircuitPublicPrefixVerificationStateEnumValues() []VirtualCircuitPublicPrefixVerificationStateEnum { + values := make([]VirtualCircuitPublicPrefixVerificationStateEnum, 0) + for _, v := range mappingVirtualCircuitPublicPrefixVerificationState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/vnic.go b/vendor/github.com/oracle/oci-go-sdk/core/vnic.go new file mode 100644 index 000000000..d7eb9d053 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/vnic.go @@ -0,0 +1,118 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Vnic A virtual network interface card. Each VNIC resides in a subnet in a VCN. +// An instance attaches to a VNIC to obtain a network connection into the VCN +// through that subnet. Each instance has a *primary VNIC* that is automatically +// created and attached during launch. You can add *secondary VNICs* to an +// instance after it's launched. For more information, see +// Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). +// Each VNIC has a *primary private IP* that is automatically assigned during launch. +// You can add *secondary private IPs* to a VNIC after it's created. For more +// information, see CreatePrivateIp and +// IP Addresses (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingIPaddresses.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Vnic struct { + + // The VNIC's Availability Domain. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment containing the VNIC. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the VNIC. + Id *string `mandatory:"true" json:"id"` + + // The current state of the VNIC. + LifecycleState VnicLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The private IP address of the primary `privateIp` object on the VNIC. + // The address is within the CIDR of the VNIC's subnet. + // Example: `10.0.3.3` + PrivateIp *string `mandatory:"true" json:"privateIp"` + + // The OCID of the subnet the VNIC is in. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // The date and time the VNIC was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // A user-friendly name. Does not have to be unique. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The hostname for the VNIC's primary private IP. Used for DNS. The value is the hostname + // portion of the primary private IP's fully qualified domain name (FQDN) + // (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). + // Must be unique across all VNICs in the subnet and comply with + // RFC 952 (https://tools.ietf.org/html/rfc952) and + // RFC 1123 (https://tools.ietf.org/html/rfc1123). + // For more information, see + // DNS in Your Virtual Cloud Network (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/dns.htm). + // Example: `bminstance-1` + HostnameLabel *string `mandatory:"false" json:"hostnameLabel"` + + // Whether the VNIC is the primary VNIC (the VNIC that is automatically created + // and attached during instance launch). + IsPrimary *bool `mandatory:"false" json:"isPrimary"` + + // The MAC address of the VNIC. + // Example: `00:00:17:B6:4D:DD` + MacAddress *string `mandatory:"false" json:"macAddress"` + + // The public IP address of the VNIC, if one is assigned. + PublicIp *string `mandatory:"false" json:"publicIp"` + + // Whether the source/destination check is disabled on the VNIC. + // Defaults to `false`, which means the check is performed. For information + // about why you would skip the source/destination check, see + // Using a Private IP as a Route Target (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingroutetables.htm#privateip). + // Example: `true` + SkipSourceDestCheck *bool `mandatory:"false" json:"skipSourceDestCheck"` +} + +func (m Vnic) String() string { + return common.PointerString(m) +} + +// VnicLifecycleStateEnum Enum with underlying type: string +type VnicLifecycleStateEnum string + +// Set of constants representing the allowable values for VnicLifecycleState +const ( + VnicLifecycleStateProvisioning VnicLifecycleStateEnum = "PROVISIONING" + VnicLifecycleStateAvailable VnicLifecycleStateEnum = "AVAILABLE" + VnicLifecycleStateTerminating VnicLifecycleStateEnum = "TERMINATING" + VnicLifecycleStateTerminated VnicLifecycleStateEnum = "TERMINATED" +) + +var mappingVnicLifecycleState = map[string]VnicLifecycleStateEnum{ + "PROVISIONING": VnicLifecycleStateProvisioning, + "AVAILABLE": VnicLifecycleStateAvailable, + "TERMINATING": VnicLifecycleStateTerminating, + "TERMINATED": VnicLifecycleStateTerminated, +} + +// GetVnicLifecycleStateEnumValues Enumerates the set of values for VnicLifecycleState +func GetVnicLifecycleStateEnumValues() []VnicLifecycleStateEnum { + values := make([]VnicLifecycleStateEnum, 0) + for _, v := range mappingVnicLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/vnic_attachment.go b/vendor/github.com/oracle/oci-go-sdk/core/vnic_attachment.go new file mode 100644 index 000000000..f08db683f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/vnic_attachment.go @@ -0,0 +1,92 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// VnicAttachment Represents an attachment between a VNIC and an instance. For more information, see +// Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). +type VnicAttachment struct { + + // The Availability Domain of the instance. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment the VNIC attachment is in, which is the same + // compartment the instance is in. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the VNIC attachment. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the instance. + InstanceId *string `mandatory:"true" json:"instanceId"` + + // The current state of the VNIC attachment. + LifecycleState VnicAttachmentLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the VNIC's subnet. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // The date and time the VNIC attachment was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // A user-friendly name. Does not have to be unique. + // Avoid entering confidential information. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Which physical network interface card (NIC) the VNIC uses. + // Certain bare metal instance shapes have two active physical NICs (0 and 1). If + // you add a secondary VNIC to one of these instances, you can specify which NIC + // the VNIC will use. For more information, see + // Virtual Network Interface Cards (VNICs) (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Tasks/managingVNICs.htm). + NicIndex *int `mandatory:"false" json:"nicIndex"` + + // The Oracle-assigned VLAN tag of the attached VNIC. Available after the + // attachment process is complete. + // Example: `0` + VlanTag *int `mandatory:"false" json:"vlanTag"` + + // The OCID of the VNIC. Available after the attachment process is complete. + VnicId *string `mandatory:"false" json:"vnicId"` +} + +func (m VnicAttachment) String() string { + return common.PointerString(m) +} + +// VnicAttachmentLifecycleStateEnum Enum with underlying type: string +type VnicAttachmentLifecycleStateEnum string + +// Set of constants representing the allowable values for VnicAttachmentLifecycleState +const ( + VnicAttachmentLifecycleStateAttaching VnicAttachmentLifecycleStateEnum = "ATTACHING" + VnicAttachmentLifecycleStateAttached VnicAttachmentLifecycleStateEnum = "ATTACHED" + VnicAttachmentLifecycleStateDetaching VnicAttachmentLifecycleStateEnum = "DETACHING" + VnicAttachmentLifecycleStateDetached VnicAttachmentLifecycleStateEnum = "DETACHED" +) + +var mappingVnicAttachmentLifecycleState = map[string]VnicAttachmentLifecycleStateEnum{ + "ATTACHING": VnicAttachmentLifecycleStateAttaching, + "ATTACHED": VnicAttachmentLifecycleStateAttached, + "DETACHING": VnicAttachmentLifecycleStateDetaching, + "DETACHED": VnicAttachmentLifecycleStateDetached, +} + +// GetVnicAttachmentLifecycleStateEnumValues Enumerates the set of values for VnicAttachmentLifecycleState +func GetVnicAttachmentLifecycleStateEnumValues() []VnicAttachmentLifecycleStateEnum { + values := make([]VnicAttachmentLifecycleStateEnum, 0) + for _, v := range mappingVnicAttachmentLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/volume.go b/vendor/github.com/oracle/oci-go-sdk/core/volume.go new file mode 100644 index 000000000..85c7394c5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/volume.go @@ -0,0 +1,127 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// Volume A detachable block volume device that allows you to dynamically expand +// the storage capacity of an instance. For more information, see +// Overview of Cloud Volume Storage (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Volume struct { + + // The Availability Domain of the volume. + // Example: `Uocm:PHX-AD-1` + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment that contains the volume. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. Does not have to be unique, and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The OCID of the volume. + Id *string `mandatory:"true" json:"id"` + + // The current state of a volume. + LifecycleState VolumeLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The size of the volume in MBs. This field is deprecated. Use sizeInGBs instead. + SizeInMBs *int `mandatory:"true" json:"sizeInMBs"` + + // The date and time the volume was created. Format defined by RFC3339. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // Specifies whether the cloned volume's data has finished copying from the source volume or backup. + IsHydrated *bool `mandatory:"false" json:"isHydrated"` + + // The size of the volume in GBs. + SizeInGBs *int `mandatory:"false" json:"sizeInGBs"` + + // The volume source, either an existing volume in the same Availability Domain or a volume backup. + // If null, an empty volume is created. + SourceDetails VolumeSourceDetails `mandatory:"false" json:"sourceDetails"` +} + +func (m Volume) String() string { + return common.PointerString(m) +} + +// UnmarshalJSON unmarshals from json +func (m *Volume) UnmarshalJSON(data []byte) (e error) { + model := struct { + IsHydrated *bool `json:"isHydrated"` + SizeInGBs *int `json:"sizeInGBs"` + SourceDetails volumesourcedetails `json:"sourceDetails"` + AvailabilityDomain *string `json:"availabilityDomain"` + CompartmentId *string `json:"compartmentId"` + DisplayName *string `json:"displayName"` + Id *string `json:"id"` + LifecycleState VolumeLifecycleStateEnum `json:"lifecycleState"` + SizeInMBs *int `json:"sizeInMBs"` + TimeCreated *common.SDKTime `json:"timeCreated"` + }{} + + e = json.Unmarshal(data, &model) + if e != nil { + return + } + m.IsHydrated = model.IsHydrated + m.SizeInGBs = model.SizeInGBs + nn, e := model.SourceDetails.UnmarshalPolymorphicJSON(model.SourceDetails.JsonData) + if e != nil { + return + } + m.SourceDetails = nn + m.AvailabilityDomain = model.AvailabilityDomain + m.CompartmentId = model.CompartmentId + m.DisplayName = model.DisplayName + m.Id = model.Id + m.LifecycleState = model.LifecycleState + m.SizeInMBs = model.SizeInMBs + m.TimeCreated = model.TimeCreated + return +} + +// VolumeLifecycleStateEnum Enum with underlying type: string +type VolumeLifecycleStateEnum string + +// Set of constants representing the allowable values for VolumeLifecycleState +const ( + VolumeLifecycleStateProvisioning VolumeLifecycleStateEnum = "PROVISIONING" + VolumeLifecycleStateRestoring VolumeLifecycleStateEnum = "RESTORING" + VolumeLifecycleStateAvailable VolumeLifecycleStateEnum = "AVAILABLE" + VolumeLifecycleStateTerminating VolumeLifecycleStateEnum = "TERMINATING" + VolumeLifecycleStateTerminated VolumeLifecycleStateEnum = "TERMINATED" + VolumeLifecycleStateFaulty VolumeLifecycleStateEnum = "FAULTY" +) + +var mappingVolumeLifecycleState = map[string]VolumeLifecycleStateEnum{ + "PROVISIONING": VolumeLifecycleStateProvisioning, + "RESTORING": VolumeLifecycleStateRestoring, + "AVAILABLE": VolumeLifecycleStateAvailable, + "TERMINATING": VolumeLifecycleStateTerminating, + "TERMINATED": VolumeLifecycleStateTerminated, + "FAULTY": VolumeLifecycleStateFaulty, +} + +// GetVolumeLifecycleStateEnumValues Enumerates the set of values for VolumeLifecycleState +func GetVolumeLifecycleStateEnumValues() []VolumeLifecycleStateEnum { + values := make([]VolumeLifecycleStateEnum, 0) + for _, v := range mappingVolumeLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/volume_attachment.go b/vendor/github.com/oracle/oci-go-sdk/core/volume_attachment.go new file mode 100644 index 000000000..d8942c4e9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/volume_attachment.go @@ -0,0 +1,171 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// VolumeAttachment A base object for all types of attachments between a storage volume and an instance. +// For specific details about iSCSI attachments, see +// IScsiVolumeAttachment. +// For general information about volume attachments, see +// Overview of Block Volume Storage (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/overview.htm). +type VolumeAttachment interface { + + // The Availability Domain of an instance. + // Example: `Uocm:PHX-AD-1` + GetAvailabilityDomain() *string + + // The OCID of the compartment. + GetCompartmentId() *string + + // The OCID of the volume attachment. + GetId() *string + + // The OCID of the instance the volume is attached to. + GetInstanceId() *string + + // The current state of the volume attachment. + GetLifecycleState() VolumeAttachmentLifecycleStateEnum + + // The date and time the volume was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + GetTimeCreated() *common.SDKTime + + // The OCID of the volume. + GetVolumeId() *string + + // A user-friendly name. Does not have to be unique, and it cannot be changed. + // Avoid entering confidential information. + // Example: `My volume attachment` + GetDisplayName() *string +} + +type volumeattachment struct { + JsonData []byte + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + CompartmentId *string `mandatory:"true" json:"compartmentId"` + Id *string `mandatory:"true" json:"id"` + InstanceId *string `mandatory:"true" json:"instanceId"` + LifecycleState VolumeAttachmentLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + VolumeId *string `mandatory:"true" json:"volumeId"` + DisplayName *string `mandatory:"false" json:"displayName"` + AttachmentType string `json:"attachmentType"` +} + +// UnmarshalJSON unmarshals json +func (m *volumeattachment) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalervolumeattachment volumeattachment + s := struct { + Model Unmarshalervolumeattachment + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.AvailabilityDomain = s.Model.AvailabilityDomain + m.CompartmentId = s.Model.CompartmentId + m.Id = s.Model.Id + m.InstanceId = s.Model.InstanceId + m.LifecycleState = s.Model.LifecycleState + m.TimeCreated = s.Model.TimeCreated + m.VolumeId = s.Model.VolumeId + m.DisplayName = s.Model.DisplayName + m.AttachmentType = s.Model.AttachmentType + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *volumeattachment) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.AttachmentType { + case "iscsi": + mm := IScsiVolumeAttachment{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetAvailabilityDomain returns AvailabilityDomain +func (m volumeattachment) GetAvailabilityDomain() *string { + return m.AvailabilityDomain +} + +//GetCompartmentId returns CompartmentId +func (m volumeattachment) GetCompartmentId() *string { + return m.CompartmentId +} + +//GetId returns Id +func (m volumeattachment) GetId() *string { + return m.Id +} + +//GetInstanceId returns InstanceId +func (m volumeattachment) GetInstanceId() *string { + return m.InstanceId +} + +//GetLifecycleState returns LifecycleState +func (m volumeattachment) GetLifecycleState() VolumeAttachmentLifecycleStateEnum { + return m.LifecycleState +} + +//GetTimeCreated returns TimeCreated +func (m volumeattachment) GetTimeCreated() *common.SDKTime { + return m.TimeCreated +} + +//GetVolumeId returns VolumeId +func (m volumeattachment) GetVolumeId() *string { + return m.VolumeId +} + +//GetDisplayName returns DisplayName +func (m volumeattachment) GetDisplayName() *string { + return m.DisplayName +} + +func (m volumeattachment) String() string { + return common.PointerString(m) +} + +// VolumeAttachmentLifecycleStateEnum Enum with underlying type: string +type VolumeAttachmentLifecycleStateEnum string + +// Set of constants representing the allowable values for VolumeAttachmentLifecycleState +const ( + VolumeAttachmentLifecycleStateAttaching VolumeAttachmentLifecycleStateEnum = "ATTACHING" + VolumeAttachmentLifecycleStateAttached VolumeAttachmentLifecycleStateEnum = "ATTACHED" + VolumeAttachmentLifecycleStateDetaching VolumeAttachmentLifecycleStateEnum = "DETACHING" + VolumeAttachmentLifecycleStateDetached VolumeAttachmentLifecycleStateEnum = "DETACHED" +) + +var mappingVolumeAttachmentLifecycleState = map[string]VolumeAttachmentLifecycleStateEnum{ + "ATTACHING": VolumeAttachmentLifecycleStateAttaching, + "ATTACHED": VolumeAttachmentLifecycleStateAttached, + "DETACHING": VolumeAttachmentLifecycleStateDetaching, + "DETACHED": VolumeAttachmentLifecycleStateDetached, +} + +// GetVolumeAttachmentLifecycleStateEnumValues Enumerates the set of values for VolumeAttachmentLifecycleState +func GetVolumeAttachmentLifecycleStateEnumValues() []VolumeAttachmentLifecycleStateEnum { + values := make([]VolumeAttachmentLifecycleStateEnum, 0) + for _, v := range mappingVolumeAttachmentLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/volume_backup.go b/vendor/github.com/oracle/oci-go-sdk/core/volume_backup.go new file mode 100644 index 000000000..6fd52b878 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/volume_backup.go @@ -0,0 +1,96 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// VolumeBackup A point-in-time copy of a volume that can then be used to create a new block volume +// or recover a block volume. For more information, see +// Overview of Cloud Volume Storage (https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type VolumeBackup struct { + + // The OCID of the compartment that contains the volume backup. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name for the volume backup. Does not have to be unique and it's changeable. + // Avoid entering confidential information. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The OCID of the volume backup. + Id *string `mandatory:"true" json:"id"` + + // The current state of a volume backup. + LifecycleState VolumeBackupLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The date and time the volume backup was created. This is the time the actual point-in-time image + // of the volume data was taken. Format defined by RFC3339. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The size of the volume, in GBs. + SizeInGBs *int `mandatory:"false" json:"sizeInGBs"` + + // The size of the volume in MBs. The value must be a multiple of 1024. + // This field is deprecated. Please use sizeInGBs. + SizeInMBs *int `mandatory:"false" json:"sizeInMBs"` + + // The date and time the request to create the volume backup was received. Format defined by RFC3339. + TimeRequestReceived *common.SDKTime `mandatory:"false" json:"timeRequestReceived"` + + // The size used by the backup, in GBs. It is typically smaller than sizeInGBs, depending on the space + // consumed on the volume and whether the backup is full or incremental. + UniqueSizeInGBs *int `mandatory:"false" json:"uniqueSizeInGBs"` + + // The size used by the backup, in MBs. It is typically smaller than sizeInMBs, depending on the space + // consumed on the volume and whether the backup is full or incremental. + // This field is deprecated. Please use uniqueSizeInGBs. + UniqueSizeInMbs *int `mandatory:"false" json:"uniqueSizeInMbs"` + + // The OCID of the volume. + VolumeId *string `mandatory:"false" json:"volumeId"` +} + +func (m VolumeBackup) String() string { + return common.PointerString(m) +} + +// VolumeBackupLifecycleStateEnum Enum with underlying type: string +type VolumeBackupLifecycleStateEnum string + +// Set of constants representing the allowable values for VolumeBackupLifecycleState +const ( + VolumeBackupLifecycleStateCreating VolumeBackupLifecycleStateEnum = "CREATING" + VolumeBackupLifecycleStateAvailable VolumeBackupLifecycleStateEnum = "AVAILABLE" + VolumeBackupLifecycleStateTerminating VolumeBackupLifecycleStateEnum = "TERMINATING" + VolumeBackupLifecycleStateTerminated VolumeBackupLifecycleStateEnum = "TERMINATED" + VolumeBackupLifecycleStateFaulty VolumeBackupLifecycleStateEnum = "FAULTY" + VolumeBackupLifecycleStateRequestReceived VolumeBackupLifecycleStateEnum = "REQUEST_RECEIVED" +) + +var mappingVolumeBackupLifecycleState = map[string]VolumeBackupLifecycleStateEnum{ + "CREATING": VolumeBackupLifecycleStateCreating, + "AVAILABLE": VolumeBackupLifecycleStateAvailable, + "TERMINATING": VolumeBackupLifecycleStateTerminating, + "TERMINATED": VolumeBackupLifecycleStateTerminated, + "FAULTY": VolumeBackupLifecycleStateFaulty, + "REQUEST_RECEIVED": VolumeBackupLifecycleStateRequestReceived, +} + +// GetVolumeBackupLifecycleStateEnumValues Enumerates the set of values for VolumeBackupLifecycleState +func GetVolumeBackupLifecycleStateEnumValues() []VolumeBackupLifecycleStateEnum { + values := make([]VolumeBackupLifecycleStateEnum, 0) + for _, v := range mappingVolumeBackupLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/volume_source_details.go b/vendor/github.com/oracle/oci-go-sdk/core/volume_source_details.go new file mode 100644 index 000000000..336c21e8b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/volume_source_details.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// VolumeSourceDetails The representation of VolumeSourceDetails +type VolumeSourceDetails interface { +} + +type volumesourcedetails struct { + JsonData []byte + Type string `json:"type"` +} + +// UnmarshalJSON unmarshals json +func (m *volumesourcedetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalervolumesourcedetails volumesourcedetails + s := struct { + Model Unmarshalervolumesourcedetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.Type = s.Model.Type + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *volumesourcedetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Type { + case "volume": + mm := VolumeSourceFromVolumeDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + case "volumeBackup": + mm := VolumeSourceFromVolumeBackupDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +func (m volumesourcedetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_backup_details.go b/vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_backup_details.go new file mode 100644 index 000000000..5c6d57af3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_backup_details.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// VolumeSourceFromVolumeBackupDetails Specifies the volume backup. +type VolumeSourceFromVolumeBackupDetails struct { + + // The OCID of the volume backup. + Id *string `mandatory:"true" json:"id"` +} + +func (m VolumeSourceFromVolumeBackupDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m VolumeSourceFromVolumeBackupDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeVolumeSourceFromVolumeBackupDetails VolumeSourceFromVolumeBackupDetails + s := struct { + DiscriminatorParam string `json:"type"` + MarshalTypeVolumeSourceFromVolumeBackupDetails + }{ + "volumeBackup", + (MarshalTypeVolumeSourceFromVolumeBackupDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_details.go b/vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_details.go new file mode 100644 index 000000000..bb1ed162a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/core/volume_source_from_volume_details.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Core Services API +// +// APIs for Networking Service, Compute Service, and Block Volume Service. +// + +package core + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// VolumeSourceFromVolumeDetails Specifies the source volume. +type VolumeSourceFromVolumeDetails struct { + + // The OCID of the volume. + Id *string `mandatory:"true" json:"id"` +} + +func (m VolumeSourceFromVolumeDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m VolumeSourceFromVolumeDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeVolumeSourceFromVolumeDetails VolumeSourceFromVolumeDetails + s := struct { + DiscriminatorParam string `json:"type"` + MarshalTypeVolumeSourceFromVolumeDetails + }{ + "volume", + (MarshalTypeVolumeSourceFromVolumeDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/backup.go b/vendor/github.com/oracle/oci-go-sdk/database/backup.go new file mode 100644 index 000000000..f898387ef --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/backup.go @@ -0,0 +1,106 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Backup A database backup +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Backup struct { + + // The name of the Availability Domain that the backup is located in. + AvailabilityDomain *string `mandatory:"false" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The OCID of the database. + DatabaseId *string `mandatory:"false" json:"databaseId"` + + // The user-friendly name for the backup. It does not have to be unique. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The OCID of the backup. + Id *string `mandatory:"false" json:"id"` + + // Additional information about the current lifecycleState. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The current state of the backup. + LifecycleState BackupLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The date and time the backup was completed. + TimeEnded *common.SDKTime `mandatory:"false" json:"timeEnded"` + + // The date and time the backup starts. + TimeStarted *common.SDKTime `mandatory:"false" json:"timeStarted"` + + // The type of backup. + Type BackupTypeEnum `mandatory:"false" json:"type,omitempty"` +} + +func (m Backup) String() string { + return common.PointerString(m) +} + +// BackupLifecycleStateEnum Enum with underlying type: string +type BackupLifecycleStateEnum string + +// Set of constants representing the allowable values for BackupLifecycleState +const ( + BackupLifecycleStateCreating BackupLifecycleStateEnum = "CREATING" + BackupLifecycleStateActive BackupLifecycleStateEnum = "ACTIVE" + BackupLifecycleStateDeleting BackupLifecycleStateEnum = "DELETING" + BackupLifecycleStateDeleted BackupLifecycleStateEnum = "DELETED" + BackupLifecycleStateFailed BackupLifecycleStateEnum = "FAILED" + BackupLifecycleStateRestoring BackupLifecycleStateEnum = "RESTORING" +) + +var mappingBackupLifecycleState = map[string]BackupLifecycleStateEnum{ + "CREATING": BackupLifecycleStateCreating, + "ACTIVE": BackupLifecycleStateActive, + "DELETING": BackupLifecycleStateDeleting, + "DELETED": BackupLifecycleStateDeleted, + "FAILED": BackupLifecycleStateFailed, + "RESTORING": BackupLifecycleStateRestoring, +} + +// GetBackupLifecycleStateEnumValues Enumerates the set of values for BackupLifecycleState +func GetBackupLifecycleStateEnumValues() []BackupLifecycleStateEnum { + values := make([]BackupLifecycleStateEnum, 0) + for _, v := range mappingBackupLifecycleState { + values = append(values, v) + } + return values +} + +// BackupTypeEnum Enum with underlying type: string +type BackupTypeEnum string + +// Set of constants representing the allowable values for BackupType +const ( + BackupTypeIncremental BackupTypeEnum = "INCREMENTAL" + BackupTypeFull BackupTypeEnum = "FULL" +) + +var mappingBackupType = map[string]BackupTypeEnum{ + "INCREMENTAL": BackupTypeIncremental, + "FULL": BackupTypeFull, +} + +// GetBackupTypeEnumValues Enumerates the set of values for BackupType +func GetBackupTypeEnumValues() []BackupTypeEnum { + values := make([]BackupTypeEnum, 0) + for _, v := range mappingBackupType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/backup_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/backup_summary.go new file mode 100644 index 000000000..5e12d1c60 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/backup_summary.go @@ -0,0 +1,106 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BackupSummary A database backup +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type BackupSummary struct { + + // The name of the Availability Domain that the backup is located in. + AvailabilityDomain *string `mandatory:"false" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The OCID of the database. + DatabaseId *string `mandatory:"false" json:"databaseId"` + + // The user-friendly name for the backup. It does not have to be unique. + DisplayName *string `mandatory:"false" json:"displayName"` + + // The OCID of the backup. + Id *string `mandatory:"false" json:"id"` + + // Additional information about the current lifecycleState. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The current state of the backup. + LifecycleState BackupSummaryLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The date and time the backup was completed. + TimeEnded *common.SDKTime `mandatory:"false" json:"timeEnded"` + + // The date and time the backup starts. + TimeStarted *common.SDKTime `mandatory:"false" json:"timeStarted"` + + // The type of backup. + Type BackupSummaryTypeEnum `mandatory:"false" json:"type,omitempty"` +} + +func (m BackupSummary) String() string { + return common.PointerString(m) +} + +// BackupSummaryLifecycleStateEnum Enum with underlying type: string +type BackupSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for BackupSummaryLifecycleState +const ( + BackupSummaryLifecycleStateCreating BackupSummaryLifecycleStateEnum = "CREATING" + BackupSummaryLifecycleStateActive BackupSummaryLifecycleStateEnum = "ACTIVE" + BackupSummaryLifecycleStateDeleting BackupSummaryLifecycleStateEnum = "DELETING" + BackupSummaryLifecycleStateDeleted BackupSummaryLifecycleStateEnum = "DELETED" + BackupSummaryLifecycleStateFailed BackupSummaryLifecycleStateEnum = "FAILED" + BackupSummaryLifecycleStateRestoring BackupSummaryLifecycleStateEnum = "RESTORING" +) + +var mappingBackupSummaryLifecycleState = map[string]BackupSummaryLifecycleStateEnum{ + "CREATING": BackupSummaryLifecycleStateCreating, + "ACTIVE": BackupSummaryLifecycleStateActive, + "DELETING": BackupSummaryLifecycleStateDeleting, + "DELETED": BackupSummaryLifecycleStateDeleted, + "FAILED": BackupSummaryLifecycleStateFailed, + "RESTORING": BackupSummaryLifecycleStateRestoring, +} + +// GetBackupSummaryLifecycleStateEnumValues Enumerates the set of values for BackupSummaryLifecycleState +func GetBackupSummaryLifecycleStateEnumValues() []BackupSummaryLifecycleStateEnum { + values := make([]BackupSummaryLifecycleStateEnum, 0) + for _, v := range mappingBackupSummaryLifecycleState { + values = append(values, v) + } + return values +} + +// BackupSummaryTypeEnum Enum with underlying type: string +type BackupSummaryTypeEnum string + +// Set of constants representing the allowable values for BackupSummaryType +const ( + BackupSummaryTypeIncremental BackupSummaryTypeEnum = "INCREMENTAL" + BackupSummaryTypeFull BackupSummaryTypeEnum = "FULL" +) + +var mappingBackupSummaryType = map[string]BackupSummaryTypeEnum{ + "INCREMENTAL": BackupSummaryTypeIncremental, + "FULL": BackupSummaryTypeFull, +} + +// GetBackupSummaryTypeEnumValues Enumerates the set of values for BackupSummaryType +func GetBackupSummaryTypeEnumValues() []BackupSummaryTypeEnum { + values := make([]BackupSummaryTypeEnum, 0) + for _, v := range mappingBackupSummaryType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_backup_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_backup_details.go new file mode 100644 index 000000000..6faa74c49 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_backup_details.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateBackupDetails The representation of CreateBackupDetails +type CreateBackupDetails struct { + + // The OCID of the database. + DatabaseId *string `mandatory:"true" json:"databaseId"` + + // The user-friendly name for the backup. It does not have to be unique. + DisplayName *string `mandatory:"true" json:"displayName"` +} + +func (m CreateBackupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/create_backup_request_response.go new file mode 100644 index 000000000..9cd01036e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_backup_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateBackupRequest wrapper for the CreateBackup operation +type CreateBackupRequest struct { + + // Request to create a new database backup. + CreateBackupDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateBackupRequest) String() string { + return common.PointerString(request) +} + +// CreateBackupResponse wrapper for the CreateBackup operation +type CreateBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Backup instance + Backup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_details.go new file mode 100644 index 000000000..dc92eb654 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_details.go @@ -0,0 +1,158 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDataGuardAssociationDetails The configuration details for creating a Data Guard association between databases. +// **NOTE:** +// "ExistingDbSystem" is the only supported `creationType` value. Therefore, all +// CreateDataGuardAssociation +// requests must include the `peerDbSystemId` parameter found in the +// CreateDataGuardAssociationToExistingDbSystemDetails +// object. +type CreateDataGuardAssociationDetails interface { + + // A strong password for the `SYS`, `SYSTEM`, and `PDB Admin` users to apply during standby creation. + // The password must contain no fewer than nine characters and include: + // * At least two uppercase characters. + // * At least two lowercase characters. + // * At least two numeric characters. + // * At least two special characters. Valid special characters include "_", "#", and "-" only. + // **The password MUST be the same as the primary admin password.** + GetDatabaseAdminPassword() *string + + // The protection mode to set up between the primary and standby databases. For more information, see + // Oracle Data Guard Protection Modes (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-protection-modes.htm#SBYDB02000) + // in the Oracle Data Guard documentation. + // **IMPORTANT** - The only protection mode currently supported by the Database Service is MAXIMUM_PERFORMANCE. + GetProtectionMode() CreateDataGuardAssociationDetailsProtectionModeEnum + + // The redo transport type to use for this Data Guard association. Valid values depend on the specified `protectionMode`: + // * MAXIMUM_AVAILABILITY - SYNC or FASTSYNC + // * MAXIMUM_PERFORMANCE - ASYNC + // * MAXIMUM_PROTECTION - SYNC + // For more information, see + // Redo Transport Services (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-redo-transport-services.htm#SBYDB00400) + // in the Oracle Data Guard documentation. + // **IMPORTANT** - The only transport type currently supported by the Database Service is ASYNC. + GetTransportType() CreateDataGuardAssociationDetailsTransportTypeEnum +} + +type createdataguardassociationdetails struct { + JsonData []byte + DatabaseAdminPassword *string `mandatory:"true" json:"databaseAdminPassword"` + ProtectionMode CreateDataGuardAssociationDetailsProtectionModeEnum `mandatory:"true" json:"protectionMode"` + TransportType CreateDataGuardAssociationDetailsTransportTypeEnum `mandatory:"true" json:"transportType"` + CreationType string `json:"creationType"` +} + +// UnmarshalJSON unmarshals json +func (m *createdataguardassociationdetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalercreatedataguardassociationdetails createdataguardassociationdetails + s := struct { + Model Unmarshalercreatedataguardassociationdetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.DatabaseAdminPassword = s.Model.DatabaseAdminPassword + m.ProtectionMode = s.Model.ProtectionMode + m.TransportType = s.Model.TransportType + m.CreationType = s.Model.CreationType + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *createdataguardassociationdetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.CreationType { + case "ExistingDbSystem": + mm := CreateDataGuardAssociationToExistingDbSystemDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetDatabaseAdminPassword returns DatabaseAdminPassword +func (m createdataguardassociationdetails) GetDatabaseAdminPassword() *string { + return m.DatabaseAdminPassword +} + +//GetProtectionMode returns ProtectionMode +func (m createdataguardassociationdetails) GetProtectionMode() CreateDataGuardAssociationDetailsProtectionModeEnum { + return m.ProtectionMode +} + +//GetTransportType returns TransportType +func (m createdataguardassociationdetails) GetTransportType() CreateDataGuardAssociationDetailsTransportTypeEnum { + return m.TransportType +} + +func (m createdataguardassociationdetails) String() string { + return common.PointerString(m) +} + +// CreateDataGuardAssociationDetailsProtectionModeEnum Enum with underlying type: string +type CreateDataGuardAssociationDetailsProtectionModeEnum string + +// Set of constants representing the allowable values for CreateDataGuardAssociationDetailsProtectionMode +const ( + CreateDataGuardAssociationDetailsProtectionModeAvailability CreateDataGuardAssociationDetailsProtectionModeEnum = "MAXIMUM_AVAILABILITY" + CreateDataGuardAssociationDetailsProtectionModePerformance CreateDataGuardAssociationDetailsProtectionModeEnum = "MAXIMUM_PERFORMANCE" + CreateDataGuardAssociationDetailsProtectionModeProtection CreateDataGuardAssociationDetailsProtectionModeEnum = "MAXIMUM_PROTECTION" +) + +var mappingCreateDataGuardAssociationDetailsProtectionMode = map[string]CreateDataGuardAssociationDetailsProtectionModeEnum{ + "MAXIMUM_AVAILABILITY": CreateDataGuardAssociationDetailsProtectionModeAvailability, + "MAXIMUM_PERFORMANCE": CreateDataGuardAssociationDetailsProtectionModePerformance, + "MAXIMUM_PROTECTION": CreateDataGuardAssociationDetailsProtectionModeProtection, +} + +// GetCreateDataGuardAssociationDetailsProtectionModeEnumValues Enumerates the set of values for CreateDataGuardAssociationDetailsProtectionMode +func GetCreateDataGuardAssociationDetailsProtectionModeEnumValues() []CreateDataGuardAssociationDetailsProtectionModeEnum { + values := make([]CreateDataGuardAssociationDetailsProtectionModeEnum, 0) + for _, v := range mappingCreateDataGuardAssociationDetailsProtectionMode { + values = append(values, v) + } + return values +} + +// CreateDataGuardAssociationDetailsTransportTypeEnum Enum with underlying type: string +type CreateDataGuardAssociationDetailsTransportTypeEnum string + +// Set of constants representing the allowable values for CreateDataGuardAssociationDetailsTransportType +const ( + CreateDataGuardAssociationDetailsTransportTypeSync CreateDataGuardAssociationDetailsTransportTypeEnum = "SYNC" + CreateDataGuardAssociationDetailsTransportTypeAsync CreateDataGuardAssociationDetailsTransportTypeEnum = "ASYNC" + CreateDataGuardAssociationDetailsTransportTypeFastsync CreateDataGuardAssociationDetailsTransportTypeEnum = "FASTSYNC" +) + +var mappingCreateDataGuardAssociationDetailsTransportType = map[string]CreateDataGuardAssociationDetailsTransportTypeEnum{ + "SYNC": CreateDataGuardAssociationDetailsTransportTypeSync, + "ASYNC": CreateDataGuardAssociationDetailsTransportTypeAsync, + "FASTSYNC": CreateDataGuardAssociationDetailsTransportTypeFastsync, +} + +// GetCreateDataGuardAssociationDetailsTransportTypeEnumValues Enumerates the set of values for CreateDataGuardAssociationDetailsTransportType +func GetCreateDataGuardAssociationDetailsTransportTypeEnumValues() []CreateDataGuardAssociationDetailsTransportTypeEnum { + values := make([]CreateDataGuardAssociationDetailsTransportTypeEnum, 0) + for _, v := range mappingCreateDataGuardAssociationDetailsTransportType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_request_response.go new file mode 100644 index 000000000..b65888e01 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_request_response.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateDataGuardAssociationRequest wrapper for the CreateDataGuardAssociation operation +type CreateDataGuardAssociationRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // A request to create a Data Guard association. + CreateDataGuardAssociationDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateDataGuardAssociationRequest) String() string { + return common.PointerString(request) +} + +// CreateDataGuardAssociationResponse wrapper for the CreateDataGuardAssociation operation +type CreateDataGuardAssociationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DataGuardAssociation instance + DataGuardAssociation `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateDataGuardAssociationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_to_existing_db_system_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_to_existing_db_system_details.go new file mode 100644 index 000000000..0badd6d50 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_data_guard_association_to_existing_db_system_details.go @@ -0,0 +1,79 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDataGuardAssociationToExistingDbSystemDetails The configuration details for creating a Data Guard association to an existing database. +type CreateDataGuardAssociationToExistingDbSystemDetails struct { + + // A strong password for the `SYS`, `SYSTEM`, and `PDB Admin` users to apply during standby creation. + // The password must contain no fewer than nine characters and include: + // * At least two uppercase characters. + // * At least two lowercase characters. + // * At least two numeric characters. + // * At least two special characters. Valid special characters include "_", "#", and "-" only. + // **The password MUST be the same as the primary admin password.** + DatabaseAdminPassword *string `mandatory:"true" json:"databaseAdminPassword"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the DB System to create the standby database on. + PeerDbSystemId *string `mandatory:"false" json:"peerDbSystemId"` + + // The protection mode to set up between the primary and standby databases. For more information, see + // Oracle Data Guard Protection Modes (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-protection-modes.htm#SBYDB02000) + // in the Oracle Data Guard documentation. + // **IMPORTANT** - The only protection mode currently supported by the Database Service is MAXIMUM_PERFORMANCE. + ProtectionMode CreateDataGuardAssociationDetailsProtectionModeEnum `mandatory:"true" json:"protectionMode"` + + // The redo transport type to use for this Data Guard association. Valid values depend on the specified `protectionMode`: + // * MAXIMUM_AVAILABILITY - SYNC or FASTSYNC + // * MAXIMUM_PERFORMANCE - ASYNC + // * MAXIMUM_PROTECTION - SYNC + // For more information, see + // Redo Transport Services (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-redo-transport-services.htm#SBYDB00400) + // in the Oracle Data Guard documentation. + // **IMPORTANT** - The only transport type currently supported by the Database Service is ASYNC. + TransportType CreateDataGuardAssociationDetailsTransportTypeEnum `mandatory:"true" json:"transportType"` +} + +//GetDatabaseAdminPassword returns DatabaseAdminPassword +func (m CreateDataGuardAssociationToExistingDbSystemDetails) GetDatabaseAdminPassword() *string { + return m.DatabaseAdminPassword +} + +//GetProtectionMode returns ProtectionMode +func (m CreateDataGuardAssociationToExistingDbSystemDetails) GetProtectionMode() CreateDataGuardAssociationDetailsProtectionModeEnum { + return m.ProtectionMode +} + +//GetTransportType returns TransportType +func (m CreateDataGuardAssociationToExistingDbSystemDetails) GetTransportType() CreateDataGuardAssociationDetailsTransportTypeEnum { + return m.TransportType +} + +func (m CreateDataGuardAssociationToExistingDbSystemDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m CreateDataGuardAssociationToExistingDbSystemDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeCreateDataGuardAssociationToExistingDbSystemDetails CreateDataGuardAssociationToExistingDbSystemDetails + s := struct { + DiscriminatorParam string `json:"creationType"` + MarshalTypeCreateDataGuardAssociationToExistingDbSystemDetails + }{ + "ExistingDbSystem", + (MarshalTypeCreateDataGuardAssociationToExistingDbSystemDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_database_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_database_details.go new file mode 100644 index 000000000..0565459d5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_database_details.go @@ -0,0 +1,66 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDatabaseDetails The representation of CreateDatabaseDetails +type CreateDatabaseDetails struct { + + // A strong password for SYS, SYSTEM, and PDB Admin. The password must be at least nine characters and contain at least two uppercase, two lowercase, two numbers, and two special characters. The special characters must be _, \#, or -. + AdminPassword *string `mandatory:"true" json:"adminPassword"` + + // The database name. It must begin with an alphabetic character and can contain a maximum of eight alphanumeric characters. Special characters are not permitted. + DbName *string `mandatory:"true" json:"dbName"` + + // The character set for the database. The default is AL32UTF8. Allowed values are: + // AL32UTF8, AR8ADOS710, AR8ADOS720, AR8APTEC715, AR8ARABICMACS, AR8ASMO8X, AR8ISO8859P6, AR8MSWIN1256, AR8MUSSAD768, AR8NAFITHA711, AR8NAFITHA721, AR8SAKHR706, AR8SAKHR707, AZ8ISO8859P9E, BG8MSWIN, BG8PC437S, BLT8CP921, BLT8ISO8859P13, BLT8MSWIN1257, BLT8PC775, BN8BSCII, CDN8PC863, CEL8ISO8859P14, CL8ISO8859P5, CL8ISOIR111, CL8KOI8R, CL8KOI8U, CL8MACCYRILLICS, CL8MSWIN1251, EE8ISO8859P2, EE8MACCES, EE8MACCROATIANS, EE8MSWIN1250, EE8PC852, EL8DEC, EL8ISO8859P7, EL8MACGREEKS, EL8MSWIN1253, EL8PC437S, EL8PC851, EL8PC869, ET8MSWIN923, HU8ABMOD, HU8CWI2, IN8ISCII, IS8PC861, IW8ISO8859P8, IW8MACHEBREWS, IW8MSWIN1255, IW8PC1507, JA16EUC, JA16EUCTILDE, JA16SJIS, JA16SJISTILDE, JA16VMS, KO16KSCCS, KO16MSWIN949, LA8ISO6937, LA8PASSPORT, LT8MSWIN921, LT8PC772, LT8PC774, LV8PC1117, LV8PC8LR, LV8RST104090, N8PC865, NE8ISO8859P10, NEE8ISO8859P4, RU8BESTA, RU8PC855, RU8PC866, SE8ISO8859P3, TH8MACTHAIS, TH8TISASCII, TR8DEC, TR8MACTURKISHS, TR8MSWIN1254, TR8PC857, US7ASCII, US8PC437, UTF8, VN8MSWIN1258, VN8VN3, WE8DEC, WE8DG, WE8ISO8859P15, WE8ISO8859P9, WE8MACROMAN8S, WE8MSWIN1252, WE8NCR4970, WE8NEXTSTEP, WE8PC850, WE8PC858, WE8PC860, WE8ROMAN8, ZHS16CGB231280, ZHS16GBK, ZHT16BIG5, ZHT16CCDC, ZHT16DBT, ZHT16HKSCS, ZHT16MSWIN950, ZHT32EUC, ZHT32SOPS, ZHT32TRIS + CharacterSet *string `mandatory:"false" json:"characterSet"` + + DbBackupConfig *DbBackupConfig `mandatory:"false" json:"dbBackupConfig"` + + // Database workload type. + DbWorkload CreateDatabaseDetailsDbWorkloadEnum `mandatory:"false" json:"dbWorkload,omitempty"` + + // National character set for the database. The default is AL16UTF16. Allowed values are: + // AL16UTF16 or UTF8. + NcharacterSet *string `mandatory:"false" json:"ncharacterSet"` + + // Pluggable database name. It must begin with an alphabetic character and can contain a maximum of eight alphanumeric characters. Special characters are not permitted. Pluggable database should not be same as database name. + PdbName *string `mandatory:"false" json:"pdbName"` +} + +func (m CreateDatabaseDetails) String() string { + return common.PointerString(m) +} + +// CreateDatabaseDetailsDbWorkloadEnum Enum with underlying type: string +type CreateDatabaseDetailsDbWorkloadEnum string + +// Set of constants representing the allowable values for CreateDatabaseDetailsDbWorkload +const ( + CreateDatabaseDetailsDbWorkloadOltp CreateDatabaseDetailsDbWorkloadEnum = "OLTP" + CreateDatabaseDetailsDbWorkloadDss CreateDatabaseDetailsDbWorkloadEnum = "DSS" +) + +var mappingCreateDatabaseDetailsDbWorkload = map[string]CreateDatabaseDetailsDbWorkloadEnum{ + "OLTP": CreateDatabaseDetailsDbWorkloadOltp, + "DSS": CreateDatabaseDetailsDbWorkloadDss, +} + +// GetCreateDatabaseDetailsDbWorkloadEnumValues Enumerates the set of values for CreateDatabaseDetailsDbWorkload +func GetCreateDatabaseDetailsDbWorkloadEnumValues() []CreateDatabaseDetailsDbWorkloadEnum { + values := make([]CreateDatabaseDetailsDbWorkloadEnum, 0) + for _, v := range mappingCreateDatabaseDetailsDbWorkload { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_database_from_backup_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_database_from_backup_details.go new file mode 100644 index 000000000..9c25aadc4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_database_from_backup_details.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDatabaseFromBackupDetails The representation of CreateDatabaseFromBackupDetails +type CreateDatabaseFromBackupDetails struct { + + // A strong password for SYS, SYSTEM, PDB Admin and TDE Wallet. The password must be at least nine characters and contain at least two uppercase, two lowercase, two numbers, and two special characters. The special characters must be _, \#, or -. + AdminPassword *string `mandatory:"true" json:"adminPassword"` + + // The backup OCID. + BackupId *string `mandatory:"true" json:"backupId"` + + // The password to open the TDE wallet. + BackupTDEPassword *string `mandatory:"true" json:"backupTDEPassword"` +} + +func (m CreateDatabaseFromBackupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_details.go new file mode 100644 index 000000000..93eb4c928 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDbHomeDetails The representation of CreateDbHomeDetails +type CreateDbHomeDetails struct { + Database *CreateDatabaseDetails `mandatory:"true" json:"database"` + + // A valid Oracle database version. To get a list of supported versions, use the ListDbVersions operation. + DbVersion *string `mandatory:"true" json:"dbVersion"` + + // The user-provided name of the database home. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m CreateDbHomeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_request_response.go new file mode 100644 index 000000000..6df0ab66c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateDbHomeRequest wrapper for the CreateDbHome operation +type CreateDbHomeRequest struct { + + // Request to create a new DB Home. + CreateDbHomeWithDbSystemIdBase `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateDbHomeRequest) String() string { + return common.PointerString(request) +} + +// CreateDbHomeResponse wrapper for the CreateDbHome operation +type CreateDbHomeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbHome instance + DbHome `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateDbHomeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_base.go b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_base.go new file mode 100644 index 000000000..670c00026 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_base.go @@ -0,0 +1,80 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDbHomeWithDbSystemIdBase The representation of CreateDbHomeWithDbSystemIdBase +type CreateDbHomeWithDbSystemIdBase interface { + + // The OCID of the DB System. + GetDbSystemId() *string + + // The user-provided name of the database home. + GetDisplayName() *string +} + +type createdbhomewithdbsystemidbase struct { + JsonData []byte + DbSystemId *string `mandatory:"true" json:"dbSystemId"` + DisplayName *string `mandatory:"false" json:"displayName"` + Source string `json:"source"` +} + +// UnmarshalJSON unmarshals json +func (m *createdbhomewithdbsystemidbase) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalercreatedbhomewithdbsystemidbase createdbhomewithdbsystemidbase + s := struct { + Model Unmarshalercreatedbhomewithdbsystemidbase + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.DbSystemId = s.Model.DbSystemId + m.DisplayName = s.Model.DisplayName + m.Source = s.Model.Source + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *createdbhomewithdbsystemidbase) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Source { + case "DB_BACKUP": + mm := CreateDbHomeWithDbSystemIdFromBackupDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + case "NONE": + mm := CreateDbHomeWithDbSystemIdDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetDbSystemId returns DbSystemId +func (m createdbhomewithdbsystemidbase) GetDbSystemId() *string { + return m.DbSystemId +} + +//GetDisplayName returns DisplayName +func (m createdbhomewithdbsystemidbase) GetDisplayName() *string { + return m.DisplayName +} + +func (m createdbhomewithdbsystemidbase) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_details.go new file mode 100644 index 000000000..92795f765 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_details.go @@ -0,0 +1,57 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDbHomeWithDbSystemIdDetails The representation of CreateDbHomeWithDbSystemIdDetails +type CreateDbHomeWithDbSystemIdDetails struct { + + // The OCID of the DB System. + DbSystemId *string `mandatory:"true" json:"dbSystemId"` + + Database *CreateDatabaseDetails `mandatory:"true" json:"database"` + + // A valid Oracle database version. To get a list of supported versions, use the ListDbVersions operation. + DbVersion *string `mandatory:"true" json:"dbVersion"` + + // The user-provided name of the database home. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +//GetDbSystemId returns DbSystemId +func (m CreateDbHomeWithDbSystemIdDetails) GetDbSystemId() *string { + return m.DbSystemId +} + +//GetDisplayName returns DisplayName +func (m CreateDbHomeWithDbSystemIdDetails) GetDisplayName() *string { + return m.DisplayName +} + +func (m CreateDbHomeWithDbSystemIdDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m CreateDbHomeWithDbSystemIdDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeCreateDbHomeWithDbSystemIdDetails CreateDbHomeWithDbSystemIdDetails + s := struct { + DiscriminatorParam string `json:"source"` + MarshalTypeCreateDbHomeWithDbSystemIdDetails + }{ + "NONE", + (MarshalTypeCreateDbHomeWithDbSystemIdDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_from_backup_details.go b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_from_backup_details.go new file mode 100644 index 000000000..98f9fc305 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/create_db_home_with_db_system_id_from_backup_details.go @@ -0,0 +1,54 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateDbHomeWithDbSystemIdFromBackupDetails The representation of CreateDbHomeWithDbSystemIdFromBackupDetails +type CreateDbHomeWithDbSystemIdFromBackupDetails struct { + + // The OCID of the DB System. + DbSystemId *string `mandatory:"true" json:"dbSystemId"` + + Database *CreateDatabaseFromBackupDetails `mandatory:"true" json:"database"` + + // The user-provided name of the database home. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +//GetDbSystemId returns DbSystemId +func (m CreateDbHomeWithDbSystemIdFromBackupDetails) GetDbSystemId() *string { + return m.DbSystemId +} + +//GetDisplayName returns DisplayName +func (m CreateDbHomeWithDbSystemIdFromBackupDetails) GetDisplayName() *string { + return m.DisplayName +} + +func (m CreateDbHomeWithDbSystemIdFromBackupDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m CreateDbHomeWithDbSystemIdFromBackupDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeCreateDbHomeWithDbSystemIdFromBackupDetails CreateDbHomeWithDbSystemIdFromBackupDetails + s := struct { + DiscriminatorParam string `json:"source"` + MarshalTypeCreateDbHomeWithDbSystemIdFromBackupDetails + }{ + "DB_BACKUP", + (MarshalTypeCreateDbHomeWithDbSystemIdFromBackupDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/data_guard_association.go b/vendor/github.com/oracle/oci-go-sdk/database/data_guard_association.go new file mode 100644 index 000000000..d572feb42 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/data_guard_association.go @@ -0,0 +1,211 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DataGuardAssociation The properties that define a Data Guard association. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an +// administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// For information about endpoints and signing API requests, see +// About the API (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm). For information about available SDKs and tools, see +// SDKS and Other Tools (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdks.htm). +type DataGuardAssociation struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the reporting database. + DatabaseId *string `mandatory:"true" json:"databaseId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the Data Guard association. + Id *string `mandatory:"true" json:"id"` + + // The current state of the Data Guard association. + LifecycleState DataGuardAssociationLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the DB System containing the associated + // peer database. + PeerDbSystemId *string `mandatory:"true" json:"peerDbSystemId"` + + // The role of the peer database in this Data Guard association. + PeerRole DataGuardAssociationPeerRoleEnum `mandatory:"true" json:"peerRole"` + + // The protection mode of this Data Guard association. For more information, see + // Oracle Data Guard Protection Modes (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-protection-modes.htm#SBYDB02000) + // in the Oracle Data Guard documentation. + ProtectionMode DataGuardAssociationProtectionModeEnum `mandatory:"true" json:"protectionMode"` + + // The role of the reporting database in this Data Guard association. + Role DataGuardAssociationRoleEnum `mandatory:"true" json:"role"` + + // The lag time between updates to the primary database and application of the redo data on the standby database, + // as computed by the reporting database. + // Example: `9 seconds` + ApplyLag *string `mandatory:"false" json:"applyLag"` + + // The rate at which redo logs are synced between the associated databases. + // Example: `180 Mb per second` + ApplyRate *string `mandatory:"false" json:"applyRate"` + + // Additional information about the current lifecycleState, if available. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the peer database's Data Guard association. + PeerDataGuardAssociationId *string `mandatory:"false" json:"peerDataGuardAssociationId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the associated peer database. + PeerDatabaseId *string `mandatory:"false" json:"peerDatabaseId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the database home containing the associated peer database. + PeerDbHomeId *string `mandatory:"false" json:"peerDbHomeId"` + + // The date and time the Data Guard Association was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The redo transport type used by this Data Guard association. For more information, see + // Redo Transport Services (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-redo-transport-services.htm#SBYDB00400) + // in the Oracle Data Guard documentation. + TransportType DataGuardAssociationTransportTypeEnum `mandatory:"false" json:"transportType,omitempty"` +} + +func (m DataGuardAssociation) String() string { + return common.PointerString(m) +} + +// DataGuardAssociationLifecycleStateEnum Enum with underlying type: string +type DataGuardAssociationLifecycleStateEnum string + +// Set of constants representing the allowable values for DataGuardAssociationLifecycleState +const ( + DataGuardAssociationLifecycleStateProvisioning DataGuardAssociationLifecycleStateEnum = "PROVISIONING" + DataGuardAssociationLifecycleStateAvailable DataGuardAssociationLifecycleStateEnum = "AVAILABLE" + DataGuardAssociationLifecycleStateUpdating DataGuardAssociationLifecycleStateEnum = "UPDATING" + DataGuardAssociationLifecycleStateTerminating DataGuardAssociationLifecycleStateEnum = "TERMINATING" + DataGuardAssociationLifecycleStateTerminated DataGuardAssociationLifecycleStateEnum = "TERMINATED" + DataGuardAssociationLifecycleStateFailed DataGuardAssociationLifecycleStateEnum = "FAILED" +) + +var mappingDataGuardAssociationLifecycleState = map[string]DataGuardAssociationLifecycleStateEnum{ + "PROVISIONING": DataGuardAssociationLifecycleStateProvisioning, + "AVAILABLE": DataGuardAssociationLifecycleStateAvailable, + "UPDATING": DataGuardAssociationLifecycleStateUpdating, + "TERMINATING": DataGuardAssociationLifecycleStateTerminating, + "TERMINATED": DataGuardAssociationLifecycleStateTerminated, + "FAILED": DataGuardAssociationLifecycleStateFailed, +} + +// GetDataGuardAssociationLifecycleStateEnumValues Enumerates the set of values for DataGuardAssociationLifecycleState +func GetDataGuardAssociationLifecycleStateEnumValues() []DataGuardAssociationLifecycleStateEnum { + values := make([]DataGuardAssociationLifecycleStateEnum, 0) + for _, v := range mappingDataGuardAssociationLifecycleState { + values = append(values, v) + } + return values +} + +// DataGuardAssociationPeerRoleEnum Enum with underlying type: string +type DataGuardAssociationPeerRoleEnum string + +// Set of constants representing the allowable values for DataGuardAssociationPeerRole +const ( + DataGuardAssociationPeerRolePrimary DataGuardAssociationPeerRoleEnum = "PRIMARY" + DataGuardAssociationPeerRoleStandby DataGuardAssociationPeerRoleEnum = "STANDBY" + DataGuardAssociationPeerRoleDisabledStandby DataGuardAssociationPeerRoleEnum = "DISABLED_STANDBY" +) + +var mappingDataGuardAssociationPeerRole = map[string]DataGuardAssociationPeerRoleEnum{ + "PRIMARY": DataGuardAssociationPeerRolePrimary, + "STANDBY": DataGuardAssociationPeerRoleStandby, + "DISABLED_STANDBY": DataGuardAssociationPeerRoleDisabledStandby, +} + +// GetDataGuardAssociationPeerRoleEnumValues Enumerates the set of values for DataGuardAssociationPeerRole +func GetDataGuardAssociationPeerRoleEnumValues() []DataGuardAssociationPeerRoleEnum { + values := make([]DataGuardAssociationPeerRoleEnum, 0) + for _, v := range mappingDataGuardAssociationPeerRole { + values = append(values, v) + } + return values +} + +// DataGuardAssociationProtectionModeEnum Enum with underlying type: string +type DataGuardAssociationProtectionModeEnum string + +// Set of constants representing the allowable values for DataGuardAssociationProtectionMode +const ( + DataGuardAssociationProtectionModeAvailability DataGuardAssociationProtectionModeEnum = "MAXIMUM_AVAILABILITY" + DataGuardAssociationProtectionModePerformance DataGuardAssociationProtectionModeEnum = "MAXIMUM_PERFORMANCE" + DataGuardAssociationProtectionModeProtection DataGuardAssociationProtectionModeEnum = "MAXIMUM_PROTECTION" +) + +var mappingDataGuardAssociationProtectionMode = map[string]DataGuardAssociationProtectionModeEnum{ + "MAXIMUM_AVAILABILITY": DataGuardAssociationProtectionModeAvailability, + "MAXIMUM_PERFORMANCE": DataGuardAssociationProtectionModePerformance, + "MAXIMUM_PROTECTION": DataGuardAssociationProtectionModeProtection, +} + +// GetDataGuardAssociationProtectionModeEnumValues Enumerates the set of values for DataGuardAssociationProtectionMode +func GetDataGuardAssociationProtectionModeEnumValues() []DataGuardAssociationProtectionModeEnum { + values := make([]DataGuardAssociationProtectionModeEnum, 0) + for _, v := range mappingDataGuardAssociationProtectionMode { + values = append(values, v) + } + return values +} + +// DataGuardAssociationRoleEnum Enum with underlying type: string +type DataGuardAssociationRoleEnum string + +// Set of constants representing the allowable values for DataGuardAssociationRole +const ( + DataGuardAssociationRolePrimary DataGuardAssociationRoleEnum = "PRIMARY" + DataGuardAssociationRoleStandby DataGuardAssociationRoleEnum = "STANDBY" + DataGuardAssociationRoleDisabledStandby DataGuardAssociationRoleEnum = "DISABLED_STANDBY" +) + +var mappingDataGuardAssociationRole = map[string]DataGuardAssociationRoleEnum{ + "PRIMARY": DataGuardAssociationRolePrimary, + "STANDBY": DataGuardAssociationRoleStandby, + "DISABLED_STANDBY": DataGuardAssociationRoleDisabledStandby, +} + +// GetDataGuardAssociationRoleEnumValues Enumerates the set of values for DataGuardAssociationRole +func GetDataGuardAssociationRoleEnumValues() []DataGuardAssociationRoleEnum { + values := make([]DataGuardAssociationRoleEnum, 0) + for _, v := range mappingDataGuardAssociationRole { + values = append(values, v) + } + return values +} + +// DataGuardAssociationTransportTypeEnum Enum with underlying type: string +type DataGuardAssociationTransportTypeEnum string + +// Set of constants representing the allowable values for DataGuardAssociationTransportType +const ( + DataGuardAssociationTransportTypeSync DataGuardAssociationTransportTypeEnum = "SYNC" + DataGuardAssociationTransportTypeAsync DataGuardAssociationTransportTypeEnum = "ASYNC" + DataGuardAssociationTransportTypeFastsync DataGuardAssociationTransportTypeEnum = "FASTSYNC" +) + +var mappingDataGuardAssociationTransportType = map[string]DataGuardAssociationTransportTypeEnum{ + "SYNC": DataGuardAssociationTransportTypeSync, + "ASYNC": DataGuardAssociationTransportTypeAsync, + "FASTSYNC": DataGuardAssociationTransportTypeFastsync, +} + +// GetDataGuardAssociationTransportTypeEnumValues Enumerates the set of values for DataGuardAssociationTransportType +func GetDataGuardAssociationTransportTypeEnumValues() []DataGuardAssociationTransportTypeEnum { + values := make([]DataGuardAssociationTransportTypeEnum, 0) + for _, v := range mappingDataGuardAssociationTransportType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/data_guard_association_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/data_guard_association_summary.go new file mode 100644 index 000000000..ebfc69c62 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/data_guard_association_summary.go @@ -0,0 +1,211 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DataGuardAssociationSummary The properties that define a Data Guard association. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an +// administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// For information about endpoints and signing API requests, see +// About the API (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm). For information about available SDKs and tools, see +// SDKS and Other Tools (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdks.htm). +type DataGuardAssociationSummary struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the reporting database. + DatabaseId *string `mandatory:"true" json:"databaseId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the Data Guard association. + Id *string `mandatory:"true" json:"id"` + + // The current state of the Data Guard association. + LifecycleState DataGuardAssociationSummaryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the DB System containing the associated + // peer database. + PeerDbSystemId *string `mandatory:"true" json:"peerDbSystemId"` + + // The role of the peer database in this Data Guard association. + PeerRole DataGuardAssociationSummaryPeerRoleEnum `mandatory:"true" json:"peerRole"` + + // The protection mode of this Data Guard association. For more information, see + // Oracle Data Guard Protection Modes (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-protection-modes.htm#SBYDB02000) + // in the Oracle Data Guard documentation. + ProtectionMode DataGuardAssociationSummaryProtectionModeEnum `mandatory:"true" json:"protectionMode"` + + // The role of the reporting database in this Data Guard association. + Role DataGuardAssociationSummaryRoleEnum `mandatory:"true" json:"role"` + + // The lag time between updates to the primary database and application of the redo data on the standby database, + // as computed by the reporting database. + // Example: `9 seconds` + ApplyLag *string `mandatory:"false" json:"applyLag"` + + // The rate at which redo logs are synced between the associated databases. + // Example: `180 Mb per second` + ApplyRate *string `mandatory:"false" json:"applyRate"` + + // Additional information about the current lifecycleState, if available. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the peer database's Data Guard association. + PeerDataGuardAssociationId *string `mandatory:"false" json:"peerDataGuardAssociationId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the associated peer database. + PeerDatabaseId *string `mandatory:"false" json:"peerDatabaseId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the database home containing the associated peer database. + PeerDbHomeId *string `mandatory:"false" json:"peerDbHomeId"` + + // The date and time the Data Guard Association was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The redo transport type used by this Data Guard association. For more information, see + // Redo Transport Services (http://docs.oracle.com/database/122/SBYDB/oracle-data-guard-redo-transport-services.htm#SBYDB00400) + // in the Oracle Data Guard documentation. + TransportType DataGuardAssociationSummaryTransportTypeEnum `mandatory:"false" json:"transportType,omitempty"` +} + +func (m DataGuardAssociationSummary) String() string { + return common.PointerString(m) +} + +// DataGuardAssociationSummaryLifecycleStateEnum Enum with underlying type: string +type DataGuardAssociationSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for DataGuardAssociationSummaryLifecycleState +const ( + DataGuardAssociationSummaryLifecycleStateProvisioning DataGuardAssociationSummaryLifecycleStateEnum = "PROVISIONING" + DataGuardAssociationSummaryLifecycleStateAvailable DataGuardAssociationSummaryLifecycleStateEnum = "AVAILABLE" + DataGuardAssociationSummaryLifecycleStateUpdating DataGuardAssociationSummaryLifecycleStateEnum = "UPDATING" + DataGuardAssociationSummaryLifecycleStateTerminating DataGuardAssociationSummaryLifecycleStateEnum = "TERMINATING" + DataGuardAssociationSummaryLifecycleStateTerminated DataGuardAssociationSummaryLifecycleStateEnum = "TERMINATED" + DataGuardAssociationSummaryLifecycleStateFailed DataGuardAssociationSummaryLifecycleStateEnum = "FAILED" +) + +var mappingDataGuardAssociationSummaryLifecycleState = map[string]DataGuardAssociationSummaryLifecycleStateEnum{ + "PROVISIONING": DataGuardAssociationSummaryLifecycleStateProvisioning, + "AVAILABLE": DataGuardAssociationSummaryLifecycleStateAvailable, + "UPDATING": DataGuardAssociationSummaryLifecycleStateUpdating, + "TERMINATING": DataGuardAssociationSummaryLifecycleStateTerminating, + "TERMINATED": DataGuardAssociationSummaryLifecycleStateTerminated, + "FAILED": DataGuardAssociationSummaryLifecycleStateFailed, +} + +// GetDataGuardAssociationSummaryLifecycleStateEnumValues Enumerates the set of values for DataGuardAssociationSummaryLifecycleState +func GetDataGuardAssociationSummaryLifecycleStateEnumValues() []DataGuardAssociationSummaryLifecycleStateEnum { + values := make([]DataGuardAssociationSummaryLifecycleStateEnum, 0) + for _, v := range mappingDataGuardAssociationSummaryLifecycleState { + values = append(values, v) + } + return values +} + +// DataGuardAssociationSummaryPeerRoleEnum Enum with underlying type: string +type DataGuardAssociationSummaryPeerRoleEnum string + +// Set of constants representing the allowable values for DataGuardAssociationSummaryPeerRole +const ( + DataGuardAssociationSummaryPeerRolePrimary DataGuardAssociationSummaryPeerRoleEnum = "PRIMARY" + DataGuardAssociationSummaryPeerRoleStandby DataGuardAssociationSummaryPeerRoleEnum = "STANDBY" + DataGuardAssociationSummaryPeerRoleDisabledStandby DataGuardAssociationSummaryPeerRoleEnum = "DISABLED_STANDBY" +) + +var mappingDataGuardAssociationSummaryPeerRole = map[string]DataGuardAssociationSummaryPeerRoleEnum{ + "PRIMARY": DataGuardAssociationSummaryPeerRolePrimary, + "STANDBY": DataGuardAssociationSummaryPeerRoleStandby, + "DISABLED_STANDBY": DataGuardAssociationSummaryPeerRoleDisabledStandby, +} + +// GetDataGuardAssociationSummaryPeerRoleEnumValues Enumerates the set of values for DataGuardAssociationSummaryPeerRole +func GetDataGuardAssociationSummaryPeerRoleEnumValues() []DataGuardAssociationSummaryPeerRoleEnum { + values := make([]DataGuardAssociationSummaryPeerRoleEnum, 0) + for _, v := range mappingDataGuardAssociationSummaryPeerRole { + values = append(values, v) + } + return values +} + +// DataGuardAssociationSummaryProtectionModeEnum Enum with underlying type: string +type DataGuardAssociationSummaryProtectionModeEnum string + +// Set of constants representing the allowable values for DataGuardAssociationSummaryProtectionMode +const ( + DataGuardAssociationSummaryProtectionModeAvailability DataGuardAssociationSummaryProtectionModeEnum = "MAXIMUM_AVAILABILITY" + DataGuardAssociationSummaryProtectionModePerformance DataGuardAssociationSummaryProtectionModeEnum = "MAXIMUM_PERFORMANCE" + DataGuardAssociationSummaryProtectionModeProtection DataGuardAssociationSummaryProtectionModeEnum = "MAXIMUM_PROTECTION" +) + +var mappingDataGuardAssociationSummaryProtectionMode = map[string]DataGuardAssociationSummaryProtectionModeEnum{ + "MAXIMUM_AVAILABILITY": DataGuardAssociationSummaryProtectionModeAvailability, + "MAXIMUM_PERFORMANCE": DataGuardAssociationSummaryProtectionModePerformance, + "MAXIMUM_PROTECTION": DataGuardAssociationSummaryProtectionModeProtection, +} + +// GetDataGuardAssociationSummaryProtectionModeEnumValues Enumerates the set of values for DataGuardAssociationSummaryProtectionMode +func GetDataGuardAssociationSummaryProtectionModeEnumValues() []DataGuardAssociationSummaryProtectionModeEnum { + values := make([]DataGuardAssociationSummaryProtectionModeEnum, 0) + for _, v := range mappingDataGuardAssociationSummaryProtectionMode { + values = append(values, v) + } + return values +} + +// DataGuardAssociationSummaryRoleEnum Enum with underlying type: string +type DataGuardAssociationSummaryRoleEnum string + +// Set of constants representing the allowable values for DataGuardAssociationSummaryRole +const ( + DataGuardAssociationSummaryRolePrimary DataGuardAssociationSummaryRoleEnum = "PRIMARY" + DataGuardAssociationSummaryRoleStandby DataGuardAssociationSummaryRoleEnum = "STANDBY" + DataGuardAssociationSummaryRoleDisabledStandby DataGuardAssociationSummaryRoleEnum = "DISABLED_STANDBY" +) + +var mappingDataGuardAssociationSummaryRole = map[string]DataGuardAssociationSummaryRoleEnum{ + "PRIMARY": DataGuardAssociationSummaryRolePrimary, + "STANDBY": DataGuardAssociationSummaryRoleStandby, + "DISABLED_STANDBY": DataGuardAssociationSummaryRoleDisabledStandby, +} + +// GetDataGuardAssociationSummaryRoleEnumValues Enumerates the set of values for DataGuardAssociationSummaryRole +func GetDataGuardAssociationSummaryRoleEnumValues() []DataGuardAssociationSummaryRoleEnum { + values := make([]DataGuardAssociationSummaryRoleEnum, 0) + for _, v := range mappingDataGuardAssociationSummaryRole { + values = append(values, v) + } + return values +} + +// DataGuardAssociationSummaryTransportTypeEnum Enum with underlying type: string +type DataGuardAssociationSummaryTransportTypeEnum string + +// Set of constants representing the allowable values for DataGuardAssociationSummaryTransportType +const ( + DataGuardAssociationSummaryTransportTypeSync DataGuardAssociationSummaryTransportTypeEnum = "SYNC" + DataGuardAssociationSummaryTransportTypeAsync DataGuardAssociationSummaryTransportTypeEnum = "ASYNC" + DataGuardAssociationSummaryTransportTypeFastsync DataGuardAssociationSummaryTransportTypeEnum = "FASTSYNC" +) + +var mappingDataGuardAssociationSummaryTransportType = map[string]DataGuardAssociationSummaryTransportTypeEnum{ + "SYNC": DataGuardAssociationSummaryTransportTypeSync, + "ASYNC": DataGuardAssociationSummaryTransportTypeAsync, + "FASTSYNC": DataGuardAssociationSummaryTransportTypeFastsync, +} + +// GetDataGuardAssociationSummaryTransportTypeEnumValues Enumerates the set of values for DataGuardAssociationSummaryTransportType +func GetDataGuardAssociationSummaryTransportTypeEnumValues() []DataGuardAssociationSummaryTransportTypeEnum { + values := make([]DataGuardAssociationSummaryTransportTypeEnum, 0) + for _, v := range mappingDataGuardAssociationSummaryTransportType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/database.go b/vendor/github.com/oracle/oci-go-sdk/database/database.go new file mode 100644 index 000000000..be33ef1a8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/database.go @@ -0,0 +1,95 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Database An Oracle database on a DB System. For more information, see Managing Oracle Databases (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Database struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The database name. + DbName *string `mandatory:"true" json:"dbName"` + + // A system-generated name for the database to ensure uniqueness within an Oracle Data Guard group (a primary database and its standby databases). The unique name cannot be changed. + DbUniqueName *string `mandatory:"true" json:"dbUniqueName"` + + // The OCID of the database. + Id *string `mandatory:"true" json:"id"` + + // The current state of the database. + LifecycleState DatabaseLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The character set for the database. + CharacterSet *string `mandatory:"false" json:"characterSet"` + + DbBackupConfig *DbBackupConfig `mandatory:"false" json:"dbBackupConfig"` + + // The OCID of the database home. + DbHomeId *string `mandatory:"false" json:"dbHomeId"` + + // Database workload type. + DbWorkload *string `mandatory:"false" json:"dbWorkload"` + + // Additional information about the current lifecycleState. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The national character set for the database. + NcharacterSet *string `mandatory:"false" json:"ncharacterSet"` + + // Pluggable database name. It must begin with an alphabetic character and can contain a maximum of eight alphanumeric characters. Special characters are not permitted. Pluggable database should not be same as database name. + PdbName *string `mandatory:"false" json:"pdbName"` + + // The date and time the database was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m Database) String() string { + return common.PointerString(m) +} + +// DatabaseLifecycleStateEnum Enum with underlying type: string +type DatabaseLifecycleStateEnum string + +// Set of constants representing the allowable values for DatabaseLifecycleState +const ( + DatabaseLifecycleStateProvisioning DatabaseLifecycleStateEnum = "PROVISIONING" + DatabaseLifecycleStateAvailable DatabaseLifecycleStateEnum = "AVAILABLE" + DatabaseLifecycleStateUpdating DatabaseLifecycleStateEnum = "UPDATING" + DatabaseLifecycleStateBackupInProgress DatabaseLifecycleStateEnum = "BACKUP_IN_PROGRESS" + DatabaseLifecycleStateTerminating DatabaseLifecycleStateEnum = "TERMINATING" + DatabaseLifecycleStateTerminated DatabaseLifecycleStateEnum = "TERMINATED" + DatabaseLifecycleStateRestoreFailed DatabaseLifecycleStateEnum = "RESTORE_FAILED" + DatabaseLifecycleStateFailed DatabaseLifecycleStateEnum = "FAILED" +) + +var mappingDatabaseLifecycleState = map[string]DatabaseLifecycleStateEnum{ + "PROVISIONING": DatabaseLifecycleStateProvisioning, + "AVAILABLE": DatabaseLifecycleStateAvailable, + "UPDATING": DatabaseLifecycleStateUpdating, + "BACKUP_IN_PROGRESS": DatabaseLifecycleStateBackupInProgress, + "TERMINATING": DatabaseLifecycleStateTerminating, + "TERMINATED": DatabaseLifecycleStateTerminated, + "RESTORE_FAILED": DatabaseLifecycleStateRestoreFailed, + "FAILED": DatabaseLifecycleStateFailed, +} + +// GetDatabaseLifecycleStateEnumValues Enumerates the set of values for DatabaseLifecycleState +func GetDatabaseLifecycleStateEnumValues() []DatabaseLifecycleStateEnum { + values := make([]DatabaseLifecycleStateEnum, 0) + for _, v := range mappingDatabaseLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/database_client.go b/vendor/github.com/oracle/oci-go-sdk/database/database_client.go new file mode 100644 index 000000000..d666cc5f0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/database_client.go @@ -0,0 +1,753 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//DatabaseClient a client for Database +type DatabaseClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewDatabaseClientWithConfigurationProvider Creates a new default Database client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewDatabaseClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client DatabaseClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = DatabaseClient{BaseClient: baseClient} + client.BasePath = "20160918" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *DatabaseClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "database", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *DatabaseClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *DatabaseClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// CreateBackup Creates a new backup in the specified database based on the request parameters you provide. If you previously used RMAN or dbcli to configure backups and then you switch to using the Console or the API for backups, a new backup configuration is created and associated with your database. This means that you can no longer rely on your previously configured unmanaged backups to work. +func (client DatabaseClient) CreateBackup(ctx context.Context, request CreateBackupRequest) (response CreateBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/backups", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateDataGuardAssociation Creates a new Data Guard association. A Data Guard association represents the replication relationship between the +// specified database and a peer database. For more information, see Using Oracle Data Guard (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Tasks/usingdataguard.htm). +// All Oracle Cloud Infrastructure resources, including Data Guard associations, get an Oracle-assigned, unique ID +// called an Oracle Cloud Identifier (OCID). When you create a resource, you can find its OCID in the response. +// You can also retrieve a resource's OCID by using a List API operation on that resource type, or by viewing the +// resource in the Console. Fore more information, see +// Resource Identifiers (http://localhost:8000/Content/General/Concepts/identifiers.htm). +func (client DatabaseClient) CreateDataGuardAssociation(ctx context.Context, request CreateDataGuardAssociationRequest) (response CreateDataGuardAssociationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/databases/{databaseId}/dataGuardAssociations", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateDbHome Creates a new DB Home in the specified DB System based on the request parameters you provide. +func (client DatabaseClient) CreateDbHome(ctx context.Context, request CreateDbHomeRequest) (response CreateDbHomeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/dbHomes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DbNodeAction Performs an action, such as one of the power actions (start, stop, softreset, or reset), on the specified DB Node. +// **start** - power on +// **stop** - power off +// **softreset** - ACPI shutdown and power on +// **reset** - power off and power on +// Note that the **stop** state has no effect on the resources you consume. +// Billing continues for DB Nodes that you stop, and related resources continue +// to apply against any relevant quotas. You must terminate the DB System +// (TerminateDbSystem) +// to remove its resources from billing and quotas. +func (client DatabaseClient) DbNodeAction(ctx context.Context, request DbNodeActionRequest) (response DbNodeActionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/dbNodes/{dbNodeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteBackup Deletes a full backup. You cannot delete automatic backups using this API. +func (client DatabaseClient) DeleteBackup(ctx context.Context, request DeleteBackupRequest) (response DeleteBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/backups/{backupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteDbHome Deletes a DB Home. The DB Home and its database data are local to the DB System and will be lost when it is deleted. Oracle recommends that you back up any data in the DB System prior to deleting it. +func (client DatabaseClient) DeleteDbHome(ctx context.Context, request DeleteDbHomeRequest) (response DeleteDbHomeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/dbHomes/{dbHomeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// FailoverDataGuardAssociation Performs a failover to transition the standby database identified by the `databaseId` parameter into the +// specified Data Guard association's primary role after the existing primary database fails or becomes unreachable. +// A failover might result in data loss depending on the protection mode in effect at the time of the primary +// database failure. +func (client DatabaseClient) FailoverDataGuardAssociation(ctx context.Context, request FailoverDataGuardAssociationRequest) (response FailoverDataGuardAssociationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/databases/{databaseId}/dataGuardAssociations/{dataGuardAssociationId}/actions/failover", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBackup Gets information about the specified backup. +func (client DatabaseClient) GetBackup(ctx context.Context, request GetBackupRequest) (response GetBackupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/backups/{backupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDataGuardAssociation Gets the specified Data Guard association's configuration information. +func (client DatabaseClient) GetDataGuardAssociation(ctx context.Context, request GetDataGuardAssociationRequest) (response GetDataGuardAssociationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/databases/{databaseId}/dataGuardAssociations/{dataGuardAssociationId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDatabase Gets information about a specific database. +func (client DatabaseClient) GetDatabase(ctx context.Context, request GetDatabaseRequest) (response GetDatabaseResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/databases/{databaseId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbHome Gets information about the specified database home. +func (client DatabaseClient) GetDbHome(ctx context.Context, request GetDbHomeRequest) (response GetDbHomeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbHomes/{dbHomeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbHomePatch Gets information about a specified patch package. +func (client DatabaseClient) GetDbHomePatch(ctx context.Context, request GetDbHomePatchRequest) (response GetDbHomePatchResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbHomes/{dbHomeId}/patches/{patchId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbHomePatchHistoryEntry Gets the patch history details for the specified patchHistoryEntryId +func (client DatabaseClient) GetDbHomePatchHistoryEntry(ctx context.Context, request GetDbHomePatchHistoryEntryRequest) (response GetDbHomePatchHistoryEntryResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbHomes/{dbHomeId}/patchHistoryEntries/{patchHistoryEntryId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbNode Gets information about the specified database node. +func (client DatabaseClient) GetDbNode(ctx context.Context, request GetDbNodeRequest) (response GetDbNodeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbNodes/{dbNodeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbSystem Gets information about the specified DB System. +func (client DatabaseClient) GetDbSystem(ctx context.Context, request GetDbSystemRequest) (response GetDbSystemResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystems/{dbSystemId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbSystemPatch Gets information about a specified patch package. +func (client DatabaseClient) GetDbSystemPatch(ctx context.Context, request GetDbSystemPatchRequest) (response GetDbSystemPatchResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystems/{dbSystemId}/patches/{patchId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetDbSystemPatchHistoryEntry Gets the patch history details for the specified patchHistoryEntryId. +func (client DatabaseClient) GetDbSystemPatchHistoryEntry(ctx context.Context, request GetDbSystemPatchHistoryEntryRequest) (response GetDbSystemPatchHistoryEntryResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystems/{dbSystemId}/patchHistoryEntries/{patchHistoryEntryId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// LaunchDbSystem Launches a new DB System in the specified compartment and Availability Domain. You'll specify a single Oracle +// Database Edition that applies to all the databases on that DB System. The selected edition cannot be changed. +// An initial database is created on the DB System based on the request parameters you provide and some default +// options. For more information, +// see Default Options for the Initial Database (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Tasks/launchingDB.htm#Default_Options_for_the_Initial_Database). +// The DB System will include a command line interface (CLI) that you can use to create additional databases and +// manage existing databases. For more information, see the +// Oracle Database CLI Reference (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/References/odacli.htm#Oracle_Database_CLI_Reference). +func (client DatabaseClient) LaunchDbSystem(ctx context.Context, request LaunchDbSystemRequest) (response LaunchDbSystemResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/dbSystems", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListBackups Gets a list of backups based on the databaseId or compartmentId specified. Either one of the query parameters must be provided. +func (client DatabaseClient) ListBackups(ctx context.Context, request ListBackupsRequest) (response ListBackupsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/backups", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDataGuardAssociations Lists all Data Guard associations for the specified database. +func (client DatabaseClient) ListDataGuardAssociations(ctx context.Context, request ListDataGuardAssociationsRequest) (response ListDataGuardAssociationsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/databases/{databaseId}/dataGuardAssociations", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDatabases Gets a list of the databases in the specified database home. +func (client DatabaseClient) ListDatabases(ctx context.Context, request ListDatabasesRequest) (response ListDatabasesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/databases", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbHomePatchHistoryEntries Gets history of the actions taken for patches for the specified database home. +func (client DatabaseClient) ListDbHomePatchHistoryEntries(ctx context.Context, request ListDbHomePatchHistoryEntriesRequest) (response ListDbHomePatchHistoryEntriesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbHomes/{dbHomeId}/patchHistoryEntries", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbHomePatches Lists patches applicable to the requested database home. +func (client DatabaseClient) ListDbHomePatches(ctx context.Context, request ListDbHomePatchesRequest) (response ListDbHomePatchesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbHomes/{dbHomeId}/patches", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbHomes Gets a list of database homes in the specified DB System and compartment. A database home is a directory where Oracle database software is installed. +func (client DatabaseClient) ListDbHomes(ctx context.Context, request ListDbHomesRequest) (response ListDbHomesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbHomes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbNodes Gets a list of database nodes in the specified DB System and compartment. A database node is a server running database software. +func (client DatabaseClient) ListDbNodes(ctx context.Context, request ListDbNodesRequest) (response ListDbNodesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbNodes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbSystemPatchHistoryEntries Gets the history of the patch actions performed on the specified DB System. +func (client DatabaseClient) ListDbSystemPatchHistoryEntries(ctx context.Context, request ListDbSystemPatchHistoryEntriesRequest) (response ListDbSystemPatchHistoryEntriesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystems/{dbSystemId}/patchHistoryEntries", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbSystemPatches Lists the patches applicable to the requested DB System. +func (client DatabaseClient) ListDbSystemPatches(ctx context.Context, request ListDbSystemPatchesRequest) (response ListDbSystemPatchesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystems/{dbSystemId}/patches", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbSystemShapes Gets a list of the shapes that can be used to launch a new DB System. The shape determines resources to allocate to the DB system - CPU cores and memory for VM shapes; CPU cores, memory and storage for non-VM (or bare metal) shapes. +func (client DatabaseClient) ListDbSystemShapes(ctx context.Context, request ListDbSystemShapesRequest) (response ListDbSystemShapesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystemShapes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbSystems Gets a list of the DB Systems in the specified compartment. +// +func (client DatabaseClient) ListDbSystems(ctx context.Context, request ListDbSystemsRequest) (response ListDbSystemsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbSystems", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListDbVersions Gets a list of supported Oracle database versions. +func (client DatabaseClient) ListDbVersions(ctx context.Context, request ListDbVersionsRequest) (response ListDbVersionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/dbVersions", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ReinstateDataGuardAssociation Reinstates the database identified by the `databaseId` parameter into the standby role in a Data Guard association. +func (client DatabaseClient) ReinstateDataGuardAssociation(ctx context.Context, request ReinstateDataGuardAssociationRequest) (response ReinstateDataGuardAssociationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/databases/{databaseId}/dataGuardAssociations/{dataGuardAssociationId}/actions/reinstate", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// RestoreDatabase Restore a Database based on the request parameters you provide. +func (client DatabaseClient) RestoreDatabase(ctx context.Context, request RestoreDatabaseRequest) (response RestoreDatabaseResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/databases/{databaseId}/actions/restore", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// SwitchoverDataGuardAssociation Performs a switchover to transition the primary database of a Data Guard association into a standby role. The +// standby database associated with the `dataGuardAssociationId` assumes the primary database role. +// A switchover guarantees no data loss. +func (client DatabaseClient) SwitchoverDataGuardAssociation(ctx context.Context, request SwitchoverDataGuardAssociationRequest) (response SwitchoverDataGuardAssociationResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/databases/{databaseId}/dataGuardAssociations/{dataGuardAssociationId}/actions/switchover", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// TerminateDbSystem Terminates a DB System and permanently deletes it and any databases running on it, and any storage volumes attached to it. The database data is local to the DB System and will be lost when the system is terminated. Oracle recommends that you back up any data in the DB System prior to terminating it. +func (client DatabaseClient) TerminateDbSystem(ctx context.Context, request TerminateDbSystemRequest) (response TerminateDbSystemResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/dbSystems/{dbSystemId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateDatabase Update a Database based on the request parameters you provide. +func (client DatabaseClient) UpdateDatabase(ctx context.Context, request UpdateDatabaseRequest) (response UpdateDatabaseResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/databases/{databaseId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateDbHome Patches the specified dbHome. +func (client DatabaseClient) UpdateDbHome(ctx context.Context, request UpdateDbHomeRequest) (response UpdateDbHomeResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/dbHomes/{dbHomeId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateDbSystem Updates the properties of a DB System, such as the CPU core count. +func (client DatabaseClient) UpdateDbSystem(ctx context.Context, request UpdateDbSystemRequest) (response UpdateDbSystemResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/dbSystems/{dbSystemId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/database_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/database_summary.go new file mode 100644 index 000000000..6191d850f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/database_summary.go @@ -0,0 +1,95 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DatabaseSummary An Oracle database on a DB System. For more information, see Managing Oracle Databases (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DatabaseSummary struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The database name. + DbName *string `mandatory:"true" json:"dbName"` + + // A system-generated name for the database to ensure uniqueness within an Oracle Data Guard group (a primary database and its standby databases). The unique name cannot be changed. + DbUniqueName *string `mandatory:"true" json:"dbUniqueName"` + + // The OCID of the database. + Id *string `mandatory:"true" json:"id"` + + // The current state of the database. + LifecycleState DatabaseSummaryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The character set for the database. + CharacterSet *string `mandatory:"false" json:"characterSet"` + + DbBackupConfig *DbBackupConfig `mandatory:"false" json:"dbBackupConfig"` + + // The OCID of the database home. + DbHomeId *string `mandatory:"false" json:"dbHomeId"` + + // Database workload type. + DbWorkload *string `mandatory:"false" json:"dbWorkload"` + + // Additional information about the current lifecycleState. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The national character set for the database. + NcharacterSet *string `mandatory:"false" json:"ncharacterSet"` + + // Pluggable database name. It must begin with an alphabetic character and can contain a maximum of eight alphanumeric characters. Special characters are not permitted. Pluggable database should not be same as database name. + PdbName *string `mandatory:"false" json:"pdbName"` + + // The date and time the database was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m DatabaseSummary) String() string { + return common.PointerString(m) +} + +// DatabaseSummaryLifecycleStateEnum Enum with underlying type: string +type DatabaseSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for DatabaseSummaryLifecycleState +const ( + DatabaseSummaryLifecycleStateProvisioning DatabaseSummaryLifecycleStateEnum = "PROVISIONING" + DatabaseSummaryLifecycleStateAvailable DatabaseSummaryLifecycleStateEnum = "AVAILABLE" + DatabaseSummaryLifecycleStateUpdating DatabaseSummaryLifecycleStateEnum = "UPDATING" + DatabaseSummaryLifecycleStateBackupInProgress DatabaseSummaryLifecycleStateEnum = "BACKUP_IN_PROGRESS" + DatabaseSummaryLifecycleStateTerminating DatabaseSummaryLifecycleStateEnum = "TERMINATING" + DatabaseSummaryLifecycleStateTerminated DatabaseSummaryLifecycleStateEnum = "TERMINATED" + DatabaseSummaryLifecycleStateRestoreFailed DatabaseSummaryLifecycleStateEnum = "RESTORE_FAILED" + DatabaseSummaryLifecycleStateFailed DatabaseSummaryLifecycleStateEnum = "FAILED" +) + +var mappingDatabaseSummaryLifecycleState = map[string]DatabaseSummaryLifecycleStateEnum{ + "PROVISIONING": DatabaseSummaryLifecycleStateProvisioning, + "AVAILABLE": DatabaseSummaryLifecycleStateAvailable, + "UPDATING": DatabaseSummaryLifecycleStateUpdating, + "BACKUP_IN_PROGRESS": DatabaseSummaryLifecycleStateBackupInProgress, + "TERMINATING": DatabaseSummaryLifecycleStateTerminating, + "TERMINATED": DatabaseSummaryLifecycleStateTerminated, + "RESTORE_FAILED": DatabaseSummaryLifecycleStateRestoreFailed, + "FAILED": DatabaseSummaryLifecycleStateFailed, +} + +// GetDatabaseSummaryLifecycleStateEnumValues Enumerates the set of values for DatabaseSummaryLifecycleState +func GetDatabaseSummaryLifecycleStateEnumValues() []DatabaseSummaryLifecycleStateEnum { + values := make([]DatabaseSummaryLifecycleStateEnum, 0) + for _, v := range mappingDatabaseSummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_backup_config.go b/vendor/github.com/oracle/oci-go-sdk/database/db_backup_config.go new file mode 100644 index 000000000..193a4a81c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_backup_config.go @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbBackupConfig Backup Options +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbBackupConfig struct { + + // If set to true, configures automatic backups. If you previously used RMAN or dbcli to configure backups and then you switch to using the Console or the API for backups, a new backup configuration is created and associated with your database. This means that you can no longer rely on your previously configured unmanaged backups to work. + AutoBackupEnabled *bool `mandatory:"false" json:"autoBackupEnabled"` +} + +func (m DbBackupConfig) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_home.go b/vendor/github.com/oracle/oci-go-sdk/database/db_home.go new file mode 100644 index 000000000..dc768b7cc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_home.go @@ -0,0 +1,82 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbHome A directory where Oracle database software is installed. Each DB System can have multiple database homes, +// and each database home can have multiple databases within it. All the databases within a single database home +// must be the same database version, but different database homes can run different versions. For more information, +// see Managing Oracle Databases (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an +// administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbHome struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The Oracle database version. + DbVersion *string `mandatory:"true" json:"dbVersion"` + + // The user-provided name for the database home. It does not need to be unique. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The OCID of the database home. + Id *string `mandatory:"true" json:"id"` + + // The current state of the database home. + LifecycleState DbHomeLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the DB System. + DbSystemId *string `mandatory:"false" json:"dbSystemId"` + + // The OCID of the last patch history. This is updated as soon as a patch operation is started. + LastPatchHistoryEntryId *string `mandatory:"false" json:"lastPatchHistoryEntryId"` + + // The date and time the database home was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m DbHome) String() string { + return common.PointerString(m) +} + +// DbHomeLifecycleStateEnum Enum with underlying type: string +type DbHomeLifecycleStateEnum string + +// Set of constants representing the allowable values for DbHomeLifecycleState +const ( + DbHomeLifecycleStateProvisioning DbHomeLifecycleStateEnum = "PROVISIONING" + DbHomeLifecycleStateAvailable DbHomeLifecycleStateEnum = "AVAILABLE" + DbHomeLifecycleStateUpdating DbHomeLifecycleStateEnum = "UPDATING" + DbHomeLifecycleStateTerminating DbHomeLifecycleStateEnum = "TERMINATING" + DbHomeLifecycleStateTerminated DbHomeLifecycleStateEnum = "TERMINATED" + DbHomeLifecycleStateFailed DbHomeLifecycleStateEnum = "FAILED" +) + +var mappingDbHomeLifecycleState = map[string]DbHomeLifecycleStateEnum{ + "PROVISIONING": DbHomeLifecycleStateProvisioning, + "AVAILABLE": DbHomeLifecycleStateAvailable, + "UPDATING": DbHomeLifecycleStateUpdating, + "TERMINATING": DbHomeLifecycleStateTerminating, + "TERMINATED": DbHomeLifecycleStateTerminated, + "FAILED": DbHomeLifecycleStateFailed, +} + +// GetDbHomeLifecycleStateEnumValues Enumerates the set of values for DbHomeLifecycleState +func GetDbHomeLifecycleStateEnumValues() []DbHomeLifecycleStateEnum { + values := make([]DbHomeLifecycleStateEnum, 0) + for _, v := range mappingDbHomeLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_home_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/db_home_summary.go new file mode 100644 index 000000000..b71dec836 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_home_summary.go @@ -0,0 +1,82 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbHomeSummary A directory where Oracle database software is installed. Each DB System can have multiple database homes, +// and each database home can have multiple databases within it. All the databases within a single database home +// must be the same database version, but different database homes can run different versions. For more information, +// see Managing Oracle Databases (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an +// administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbHomeSummary struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The Oracle database version. + DbVersion *string `mandatory:"true" json:"dbVersion"` + + // The user-provided name for the database home. It does not need to be unique. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The OCID of the database home. + Id *string `mandatory:"true" json:"id"` + + // The current state of the database home. + LifecycleState DbHomeSummaryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the DB System. + DbSystemId *string `mandatory:"false" json:"dbSystemId"` + + // The OCID of the last patch history. This is updated as soon as a patch operation is started. + LastPatchHistoryEntryId *string `mandatory:"false" json:"lastPatchHistoryEntryId"` + + // The date and time the database home was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m DbHomeSummary) String() string { + return common.PointerString(m) +} + +// DbHomeSummaryLifecycleStateEnum Enum with underlying type: string +type DbHomeSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for DbHomeSummaryLifecycleState +const ( + DbHomeSummaryLifecycleStateProvisioning DbHomeSummaryLifecycleStateEnum = "PROVISIONING" + DbHomeSummaryLifecycleStateAvailable DbHomeSummaryLifecycleStateEnum = "AVAILABLE" + DbHomeSummaryLifecycleStateUpdating DbHomeSummaryLifecycleStateEnum = "UPDATING" + DbHomeSummaryLifecycleStateTerminating DbHomeSummaryLifecycleStateEnum = "TERMINATING" + DbHomeSummaryLifecycleStateTerminated DbHomeSummaryLifecycleStateEnum = "TERMINATED" + DbHomeSummaryLifecycleStateFailed DbHomeSummaryLifecycleStateEnum = "FAILED" +) + +var mappingDbHomeSummaryLifecycleState = map[string]DbHomeSummaryLifecycleStateEnum{ + "PROVISIONING": DbHomeSummaryLifecycleStateProvisioning, + "AVAILABLE": DbHomeSummaryLifecycleStateAvailable, + "UPDATING": DbHomeSummaryLifecycleStateUpdating, + "TERMINATING": DbHomeSummaryLifecycleStateTerminating, + "TERMINATED": DbHomeSummaryLifecycleStateTerminated, + "FAILED": DbHomeSummaryLifecycleStateFailed, +} + +// GetDbHomeSummaryLifecycleStateEnumValues Enumerates the set of values for DbHomeSummaryLifecycleState +func GetDbHomeSummaryLifecycleStateEnumValues() []DbHomeSummaryLifecycleStateEnum { + values := make([]DbHomeSummaryLifecycleStateEnum, 0) + for _, v := range mappingDbHomeSummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_node.go b/vendor/github.com/oracle/oci-go-sdk/database/db_node.go new file mode 100644 index 000000000..3e052d092 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_node.go @@ -0,0 +1,83 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbNode A server where Oracle database software is running. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbNode struct { + + // The OCID of the DB System. + DbSystemId *string `mandatory:"true" json:"dbSystemId"` + + // The OCID of the DB Node. + Id *string `mandatory:"true" json:"id"` + + // The current state of the database node. + LifecycleState DbNodeLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The date and time that the DB Node was created. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the VNIC. + VnicId *string `mandatory:"true" json:"vnicId"` + + // The OCID of the backup VNIC. + BackupVnicId *string `mandatory:"false" json:"backupVnicId"` + + // The host name for the DB Node. + Hostname *string `mandatory:"false" json:"hostname"` + + // Storage size, in GBs, of the software volume that is allocated to the DB system. This is applicable only for VM-based DBs. + SoftwareStorageSizeInGB *int `mandatory:"false" json:"softwareStorageSizeInGB"` +} + +func (m DbNode) String() string { + return common.PointerString(m) +} + +// DbNodeLifecycleStateEnum Enum with underlying type: string +type DbNodeLifecycleStateEnum string + +// Set of constants representing the allowable values for DbNodeLifecycleState +const ( + DbNodeLifecycleStateProvisioning DbNodeLifecycleStateEnum = "PROVISIONING" + DbNodeLifecycleStateAvailable DbNodeLifecycleStateEnum = "AVAILABLE" + DbNodeLifecycleStateUpdating DbNodeLifecycleStateEnum = "UPDATING" + DbNodeLifecycleStateStopping DbNodeLifecycleStateEnum = "STOPPING" + DbNodeLifecycleStateStopped DbNodeLifecycleStateEnum = "STOPPED" + DbNodeLifecycleStateStarting DbNodeLifecycleStateEnum = "STARTING" + DbNodeLifecycleStateTerminating DbNodeLifecycleStateEnum = "TERMINATING" + DbNodeLifecycleStateTerminated DbNodeLifecycleStateEnum = "TERMINATED" + DbNodeLifecycleStateFailed DbNodeLifecycleStateEnum = "FAILED" +) + +var mappingDbNodeLifecycleState = map[string]DbNodeLifecycleStateEnum{ + "PROVISIONING": DbNodeLifecycleStateProvisioning, + "AVAILABLE": DbNodeLifecycleStateAvailable, + "UPDATING": DbNodeLifecycleStateUpdating, + "STOPPING": DbNodeLifecycleStateStopping, + "STOPPED": DbNodeLifecycleStateStopped, + "STARTING": DbNodeLifecycleStateStarting, + "TERMINATING": DbNodeLifecycleStateTerminating, + "TERMINATED": DbNodeLifecycleStateTerminated, + "FAILED": DbNodeLifecycleStateFailed, +} + +// GetDbNodeLifecycleStateEnumValues Enumerates the set of values for DbNodeLifecycleState +func GetDbNodeLifecycleStateEnumValues() []DbNodeLifecycleStateEnum { + values := make([]DbNodeLifecycleStateEnum, 0) + for _, v := range mappingDbNodeLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_node_action_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/db_node_action_request_response.go new file mode 100644 index 000000000..208e50489 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_node_action_request_response.go @@ -0,0 +1,83 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DbNodeActionRequest wrapper for the DbNodeAction operation +type DbNodeActionRequest struct { + + // The database node OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbNodeId *string `mandatory:"true" contributesTo:"path" name:"dbNodeId"` + + // The action to perform on the DB Node. + Action DbNodeActionActionEnum `mandatory:"true" contributesTo:"query" name:"action" omitEmpty:"true"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DbNodeActionRequest) String() string { + return common.PointerString(request) +} + +// DbNodeActionResponse wrapper for the DbNodeAction operation +type DbNodeActionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbNode instance + DbNode `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DbNodeActionResponse) String() string { + return common.PointerString(response) +} + +// DbNodeActionActionEnum Enum with underlying type: string +type DbNodeActionActionEnum string + +// Set of constants representing the allowable values for DbNodeActionAction +const ( + DbNodeActionActionStop DbNodeActionActionEnum = "STOP" + DbNodeActionActionStart DbNodeActionActionEnum = "START" + DbNodeActionActionSoftreset DbNodeActionActionEnum = "SOFTRESET" + DbNodeActionActionReset DbNodeActionActionEnum = "RESET" +) + +var mappingDbNodeActionAction = map[string]DbNodeActionActionEnum{ + "STOP": DbNodeActionActionStop, + "START": DbNodeActionActionStart, + "SOFTRESET": DbNodeActionActionSoftreset, + "RESET": DbNodeActionActionReset, +} + +// GetDbNodeActionActionEnumValues Enumerates the set of values for DbNodeActionAction +func GetDbNodeActionActionEnumValues() []DbNodeActionActionEnum { + values := make([]DbNodeActionActionEnum, 0) + for _, v := range mappingDbNodeActionAction { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_node_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/db_node_summary.go new file mode 100644 index 000000000..47e4ea0dc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_node_summary.go @@ -0,0 +1,83 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbNodeSummary A server where Oracle database software is running. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbNodeSummary struct { + + // The OCID of the DB System. + DbSystemId *string `mandatory:"true" json:"dbSystemId"` + + // The OCID of the DB Node. + Id *string `mandatory:"true" json:"id"` + + // The current state of the database node. + LifecycleState DbNodeSummaryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The date and time that the DB Node was created. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The OCID of the VNIC. + VnicId *string `mandatory:"true" json:"vnicId"` + + // The OCID of the backup VNIC. + BackupVnicId *string `mandatory:"false" json:"backupVnicId"` + + // The host name for the DB Node. + Hostname *string `mandatory:"false" json:"hostname"` + + // Storage size, in GBs, of the software volume that is allocated to the DB system. This is applicable only for VM-based DBs. + SoftwareStorageSizeInGB *int `mandatory:"false" json:"softwareStorageSizeInGB"` +} + +func (m DbNodeSummary) String() string { + return common.PointerString(m) +} + +// DbNodeSummaryLifecycleStateEnum Enum with underlying type: string +type DbNodeSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for DbNodeSummaryLifecycleState +const ( + DbNodeSummaryLifecycleStateProvisioning DbNodeSummaryLifecycleStateEnum = "PROVISIONING" + DbNodeSummaryLifecycleStateAvailable DbNodeSummaryLifecycleStateEnum = "AVAILABLE" + DbNodeSummaryLifecycleStateUpdating DbNodeSummaryLifecycleStateEnum = "UPDATING" + DbNodeSummaryLifecycleStateStopping DbNodeSummaryLifecycleStateEnum = "STOPPING" + DbNodeSummaryLifecycleStateStopped DbNodeSummaryLifecycleStateEnum = "STOPPED" + DbNodeSummaryLifecycleStateStarting DbNodeSummaryLifecycleStateEnum = "STARTING" + DbNodeSummaryLifecycleStateTerminating DbNodeSummaryLifecycleStateEnum = "TERMINATING" + DbNodeSummaryLifecycleStateTerminated DbNodeSummaryLifecycleStateEnum = "TERMINATED" + DbNodeSummaryLifecycleStateFailed DbNodeSummaryLifecycleStateEnum = "FAILED" +) + +var mappingDbNodeSummaryLifecycleState = map[string]DbNodeSummaryLifecycleStateEnum{ + "PROVISIONING": DbNodeSummaryLifecycleStateProvisioning, + "AVAILABLE": DbNodeSummaryLifecycleStateAvailable, + "UPDATING": DbNodeSummaryLifecycleStateUpdating, + "STOPPING": DbNodeSummaryLifecycleStateStopping, + "STOPPED": DbNodeSummaryLifecycleStateStopped, + "STARTING": DbNodeSummaryLifecycleStateStarting, + "TERMINATING": DbNodeSummaryLifecycleStateTerminating, + "TERMINATED": DbNodeSummaryLifecycleStateTerminated, + "FAILED": DbNodeSummaryLifecycleStateFailed, +} + +// GetDbNodeSummaryLifecycleStateEnumValues Enumerates the set of values for DbNodeSummaryLifecycleState +func GetDbNodeSummaryLifecycleStateEnumValues() []DbNodeSummaryLifecycleStateEnum { + values := make([]DbNodeSummaryLifecycleStateEnum, 0) + for _, v := range mappingDbNodeSummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_system.go b/vendor/github.com/oracle/oci-go-sdk/database/db_system.go new file mode 100644 index 000000000..04085ad17 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_system.go @@ -0,0 +1,236 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbSystem The Database Service supports several types of DB Systems, ranging in size, price, and performance. For details about each type of system, see: +// - Exadata DB Systems (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/exaoverview.htm) +// - Bare Metal or VM DB Systems (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm) +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// +// For information about access control and compartments, see +// Overview of the Identity Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about Availability Domains, see +// Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +// To get a list of Availability Domains, use the `ListAvailabilityDomains` operation +// in the Identity Service API. +type DbSystem struct { + + // The name of the Availability Domain that the DB System is located in. + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The number of CPU cores enabled on the DB System. + CpuCoreCount *int `mandatory:"true" json:"cpuCoreCount"` + + // The Oracle Database Edition that applies to all the databases on the DB System. + DatabaseEdition DbSystemDatabaseEditionEnum `mandatory:"true" json:"databaseEdition"` + + // The user-friendly name for the DB System. It does not have to be unique. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The domain name for the DB System. + Domain *string `mandatory:"true" json:"domain"` + + // The host name for the DB Node. + Hostname *string `mandatory:"true" json:"hostname"` + + // The OCID of the DB System. + Id *string `mandatory:"true" json:"id"` + + // The current state of the DB System. + LifecycleState DbSystemLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The shape of the DB System. The shape determines resources to allocate to the DB system - CPU cores and memory for VM shapes; CPU cores, memory and storage for non-VM (or bare metal) shapes. + Shape *string `mandatory:"true" json:"shape"` + + // The public key portion of one or more key pairs used for SSH access to the DB System. + SshPublicKeys []string `mandatory:"true" json:"sshPublicKeys"` + + // The OCID of the subnet the DB System is associated with. + // **Subnet Restrictions:** + // - For single node and 2-node (RAC) DB Systems, do not use a subnet that overlaps with 192.168.16.16/28 + // - For Exadata and VM-based RAC DB Systems, do not use a subnet that overlaps with 192.168.128.0/20 + // These subnets are used by the Oracle Clusterware private interconnect on the database instance. + // Specifying an overlapping subnet will cause the private interconnect to malfunction. + // This restriction applies to both the client subnet and backup subnet. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // The OCID of the backup network subnet the DB System is associated with. Applicable only to Exadata. + // **Subnet Restriction:** See above subnetId's 'Subnet Restriction'. + // to malfunction. + BackupSubnetId *string `mandatory:"false" json:"backupSubnetId"` + + // Cluster name for Exadata and 2-node RAC DB Systems. The cluster name must begin with an an alphabetic character, and may contain hyphens (-). Underscores (_) are not permitted. The cluster name can be no longer than 11 characters and is not case sensitive. + ClusterName *string `mandatory:"false" json:"clusterName"` + + // The percentage assigned to DATA storage (user data and database files). + // The remaining percentage is assigned to RECO storage (database redo logs, archive logs, and recovery manager backups). Accepted values are 40 and 80. + DataStoragePercentage *int `mandatory:"false" json:"dataStoragePercentage"` + + // Data storage size, in GBs, that is currently available to the DB system. This is applicable only for VM-based DBs. + DataStorageSizeInGBs *int `mandatory:"false" json:"dataStorageSizeInGBs"` + + // The type of redundancy configured for the DB System. + // Normal is 2-way redundancy. + // High is 3-way redundancy. + DiskRedundancy DbSystemDiskRedundancyEnum `mandatory:"false" json:"diskRedundancy,omitempty"` + + // The OCID of the last patch history. This is updated as soon as a patch operation is started. + LastPatchHistoryEntryId *string `mandatory:"false" json:"lastPatchHistoryEntryId"` + + // The Oracle license model that applies to all the databases on the DB System. The default is LICENSE_INCLUDED. + LicenseModel DbSystemLicenseModelEnum `mandatory:"false" json:"licenseModel,omitempty"` + + // Additional information about the current lifecycleState. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The port number configured for the listener on the DB System. + ListenerPort *int `mandatory:"false" json:"listenerPort"` + + // Number of nodes in this DB system. For RAC DBs, this will be greater than 1. + NodeCount *int `mandatory:"false" json:"nodeCount"` + + // RECO/REDO storage size, in GBs, that is currently allocated to the DB system. This is applicable only for VM-based DBs. + RecoStorageSizeInGB *int `mandatory:"false" json:"recoStorageSizeInGB"` + + // The OCID of the DNS record for the SCAN IP addresses that are associated with the DB System. + ScanDnsRecordId *string `mandatory:"false" json:"scanDnsRecordId"` + + // The OCID of the Single Client Access Name (SCAN) IP addresses associated with the DB System. + // SCAN IP addresses are typically used for load balancing and are not assigned to any interface. + // Clusterware directs the requests to the appropriate nodes in the cluster. + // - For a single-node DB System, this list is empty. + ScanIpIds []string `mandatory:"false" json:"scanIpIds"` + + // The date and time the DB System was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The version of the DB System. + Version *string `mandatory:"false" json:"version"` + + // The OCID of the virtual IP (VIP) addresses associated with the DB System. + // The Cluster Ready Services (CRS) creates and maintains one VIP address for each node in the DB System to + // enable failover. If one node fails, the VIP is reassigned to another active node in the cluster. + // - For a single-node DB System, this list is empty. + VipIds []string `mandatory:"false" json:"vipIds"` +} + +func (m DbSystem) String() string { + return common.PointerString(m) +} + +// DbSystemDatabaseEditionEnum Enum with underlying type: string +type DbSystemDatabaseEditionEnum string + +// Set of constants representing the allowable values for DbSystemDatabaseEdition +const ( + DbSystemDatabaseEditionStandardEdition DbSystemDatabaseEditionEnum = "STANDARD_EDITION" + DbSystemDatabaseEditionEnterpriseEdition DbSystemDatabaseEditionEnum = "ENTERPRISE_EDITION" + DbSystemDatabaseEditionEnterpriseEditionExtremePerformance DbSystemDatabaseEditionEnum = "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" + DbSystemDatabaseEditionEnterpriseEditionHighPerformance DbSystemDatabaseEditionEnum = "ENTERPRISE_EDITION_HIGH_PERFORMANCE" +) + +var mappingDbSystemDatabaseEdition = map[string]DbSystemDatabaseEditionEnum{ + "STANDARD_EDITION": DbSystemDatabaseEditionStandardEdition, + "ENTERPRISE_EDITION": DbSystemDatabaseEditionEnterpriseEdition, + "ENTERPRISE_EDITION_EXTREME_PERFORMANCE": DbSystemDatabaseEditionEnterpriseEditionExtremePerformance, + "ENTERPRISE_EDITION_HIGH_PERFORMANCE": DbSystemDatabaseEditionEnterpriseEditionHighPerformance, +} + +// GetDbSystemDatabaseEditionEnumValues Enumerates the set of values for DbSystemDatabaseEdition +func GetDbSystemDatabaseEditionEnumValues() []DbSystemDatabaseEditionEnum { + values := make([]DbSystemDatabaseEditionEnum, 0) + for _, v := range mappingDbSystemDatabaseEdition { + values = append(values, v) + } + return values +} + +// DbSystemDiskRedundancyEnum Enum with underlying type: string +type DbSystemDiskRedundancyEnum string + +// Set of constants representing the allowable values for DbSystemDiskRedundancy +const ( + DbSystemDiskRedundancyHigh DbSystemDiskRedundancyEnum = "HIGH" + DbSystemDiskRedundancyNormal DbSystemDiskRedundancyEnum = "NORMAL" +) + +var mappingDbSystemDiskRedundancy = map[string]DbSystemDiskRedundancyEnum{ + "HIGH": DbSystemDiskRedundancyHigh, + "NORMAL": DbSystemDiskRedundancyNormal, +} + +// GetDbSystemDiskRedundancyEnumValues Enumerates the set of values for DbSystemDiskRedundancy +func GetDbSystemDiskRedundancyEnumValues() []DbSystemDiskRedundancyEnum { + values := make([]DbSystemDiskRedundancyEnum, 0) + for _, v := range mappingDbSystemDiskRedundancy { + values = append(values, v) + } + return values +} + +// DbSystemLicenseModelEnum Enum with underlying type: string +type DbSystemLicenseModelEnum string + +// Set of constants representing the allowable values for DbSystemLicenseModel +const ( + DbSystemLicenseModelLicenseIncluded DbSystemLicenseModelEnum = "LICENSE_INCLUDED" + DbSystemLicenseModelBringYourOwnLicense DbSystemLicenseModelEnum = "BRING_YOUR_OWN_LICENSE" +) + +var mappingDbSystemLicenseModel = map[string]DbSystemLicenseModelEnum{ + "LICENSE_INCLUDED": DbSystemLicenseModelLicenseIncluded, + "BRING_YOUR_OWN_LICENSE": DbSystemLicenseModelBringYourOwnLicense, +} + +// GetDbSystemLicenseModelEnumValues Enumerates the set of values for DbSystemLicenseModel +func GetDbSystemLicenseModelEnumValues() []DbSystemLicenseModelEnum { + values := make([]DbSystemLicenseModelEnum, 0) + for _, v := range mappingDbSystemLicenseModel { + values = append(values, v) + } + return values +} + +// DbSystemLifecycleStateEnum Enum with underlying type: string +type DbSystemLifecycleStateEnum string + +// Set of constants representing the allowable values for DbSystemLifecycleState +const ( + DbSystemLifecycleStateProvisioning DbSystemLifecycleStateEnum = "PROVISIONING" + DbSystemLifecycleStateAvailable DbSystemLifecycleStateEnum = "AVAILABLE" + DbSystemLifecycleStateUpdating DbSystemLifecycleStateEnum = "UPDATING" + DbSystemLifecycleStateTerminating DbSystemLifecycleStateEnum = "TERMINATING" + DbSystemLifecycleStateTerminated DbSystemLifecycleStateEnum = "TERMINATED" + DbSystemLifecycleStateFailed DbSystemLifecycleStateEnum = "FAILED" +) + +var mappingDbSystemLifecycleState = map[string]DbSystemLifecycleStateEnum{ + "PROVISIONING": DbSystemLifecycleStateProvisioning, + "AVAILABLE": DbSystemLifecycleStateAvailable, + "UPDATING": DbSystemLifecycleStateUpdating, + "TERMINATING": DbSystemLifecycleStateTerminating, + "TERMINATED": DbSystemLifecycleStateTerminated, + "FAILED": DbSystemLifecycleStateFailed, +} + +// GetDbSystemLifecycleStateEnumValues Enumerates the set of values for DbSystemLifecycleState +func GetDbSystemLifecycleStateEnumValues() []DbSystemLifecycleStateEnum { + values := make([]DbSystemLifecycleStateEnum, 0) + for _, v := range mappingDbSystemLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_system_shape_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/db_system_shape_summary.go new file mode 100644 index 000000000..831411c16 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_system_shape_summary.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbSystemShapeSummary The shape of the DB System. The shape determines resources to allocate to the DB system - CPU cores and memory for VM shapes; CPU cores, memory and storage for non-VM (or bare metal) shapes. +// For a description of shapes, see DB System Launch Options (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/References/launchoptions.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. +// If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbSystemShapeSummary struct { + + // The maximum number of CPU cores that can be enabled on the DB System. + AvailableCoreCount *int `mandatory:"true" json:"availableCoreCount"` + + // The name of the shape used for the DB System. + Name *string `mandatory:"true" json:"name"` + + // Deprecated. Use `name` instead of `shape`. + Shape *string `mandatory:"false" json:"shape"` +} + +func (m DbSystemShapeSummary) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_system_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/db_system_summary.go new file mode 100644 index 000000000..7f8ba31a3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_system_summary.go @@ -0,0 +1,236 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbSystemSummary The Database Service supports several types of DB Systems, ranging in size, price, and performance. For details about each type of system, see: +// - Exadata DB Systems (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/exaoverview.htm) +// - Bare Metal or VM DB Systems (https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm) +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// +// For information about access control and compartments, see +// Overview of the Identity Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// For information about Availability Domains, see +// Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +// To get a list of Availability Domains, use the `ListAvailabilityDomains` operation +// in the Identity Service API. +type DbSystemSummary struct { + + // The name of the Availability Domain that the DB System is located in. + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The number of CPU cores enabled on the DB System. + CpuCoreCount *int `mandatory:"true" json:"cpuCoreCount"` + + // The Oracle Database Edition that applies to all the databases on the DB System. + DatabaseEdition DbSystemSummaryDatabaseEditionEnum `mandatory:"true" json:"databaseEdition"` + + // The user-friendly name for the DB System. It does not have to be unique. + DisplayName *string `mandatory:"true" json:"displayName"` + + // The domain name for the DB System. + Domain *string `mandatory:"true" json:"domain"` + + // The host name for the DB Node. + Hostname *string `mandatory:"true" json:"hostname"` + + // The OCID of the DB System. + Id *string `mandatory:"true" json:"id"` + + // The current state of the DB System. + LifecycleState DbSystemSummaryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The shape of the DB System. The shape determines resources to allocate to the DB system - CPU cores and memory for VM shapes; CPU cores, memory and storage for non-VM (or bare metal) shapes. + Shape *string `mandatory:"true" json:"shape"` + + // The public key portion of one or more key pairs used for SSH access to the DB System. + SshPublicKeys []string `mandatory:"true" json:"sshPublicKeys"` + + // The OCID of the subnet the DB System is associated with. + // **Subnet Restrictions:** + // - For single node and 2-node (RAC) DB Systems, do not use a subnet that overlaps with 192.168.16.16/28 + // - For Exadata and VM-based RAC DB Systems, do not use a subnet that overlaps with 192.168.128.0/20 + // These subnets are used by the Oracle Clusterware private interconnect on the database instance. + // Specifying an overlapping subnet will cause the private interconnect to malfunction. + // This restriction applies to both the client subnet and backup subnet. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // The OCID of the backup network subnet the DB System is associated with. Applicable only to Exadata. + // **Subnet Restriction:** See above subnetId's 'Subnet Restriction'. + // to malfunction. + BackupSubnetId *string `mandatory:"false" json:"backupSubnetId"` + + // Cluster name for Exadata and 2-node RAC DB Systems. The cluster name must begin with an an alphabetic character, and may contain hyphens (-). Underscores (_) are not permitted. The cluster name can be no longer than 11 characters and is not case sensitive. + ClusterName *string `mandatory:"false" json:"clusterName"` + + // The percentage assigned to DATA storage (user data and database files). + // The remaining percentage is assigned to RECO storage (database redo logs, archive logs, and recovery manager backups). Accepted values are 40 and 80. + DataStoragePercentage *int `mandatory:"false" json:"dataStoragePercentage"` + + // Data storage size, in GBs, that is currently available to the DB system. This is applicable only for VM-based DBs. + DataStorageSizeInGBs *int `mandatory:"false" json:"dataStorageSizeInGBs"` + + // The type of redundancy configured for the DB System. + // Normal is 2-way redundancy. + // High is 3-way redundancy. + DiskRedundancy DbSystemSummaryDiskRedundancyEnum `mandatory:"false" json:"diskRedundancy,omitempty"` + + // The OCID of the last patch history. This is updated as soon as a patch operation is started. + LastPatchHistoryEntryId *string `mandatory:"false" json:"lastPatchHistoryEntryId"` + + // The Oracle license model that applies to all the databases on the DB System. The default is LICENSE_INCLUDED. + LicenseModel DbSystemSummaryLicenseModelEnum `mandatory:"false" json:"licenseModel,omitempty"` + + // Additional information about the current lifecycleState. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The port number configured for the listener on the DB System. + ListenerPort *int `mandatory:"false" json:"listenerPort"` + + // Number of nodes in this DB system. For RAC DBs, this will be greater than 1. + NodeCount *int `mandatory:"false" json:"nodeCount"` + + // RECO/REDO storage size, in GBs, that is currently allocated to the DB system. This is applicable only for VM-based DBs. + RecoStorageSizeInGB *int `mandatory:"false" json:"recoStorageSizeInGB"` + + // The OCID of the DNS record for the SCAN IP addresses that are associated with the DB System. + ScanDnsRecordId *string `mandatory:"false" json:"scanDnsRecordId"` + + // The OCID of the Single Client Access Name (SCAN) IP addresses associated with the DB System. + // SCAN IP addresses are typically used for load balancing and are not assigned to any interface. + // Clusterware directs the requests to the appropriate nodes in the cluster. + // - For a single-node DB System, this list is empty. + ScanIpIds []string `mandatory:"false" json:"scanIpIds"` + + // The date and time the DB System was created. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The version of the DB System. + Version *string `mandatory:"false" json:"version"` + + // The OCID of the virtual IP (VIP) addresses associated with the DB System. + // The Cluster Ready Services (CRS) creates and maintains one VIP address for each node in the DB System to + // enable failover. If one node fails, the VIP is reassigned to another active node in the cluster. + // - For a single-node DB System, this list is empty. + VipIds []string `mandatory:"false" json:"vipIds"` +} + +func (m DbSystemSummary) String() string { + return common.PointerString(m) +} + +// DbSystemSummaryDatabaseEditionEnum Enum with underlying type: string +type DbSystemSummaryDatabaseEditionEnum string + +// Set of constants representing the allowable values for DbSystemSummaryDatabaseEdition +const ( + DbSystemSummaryDatabaseEditionStandardEdition DbSystemSummaryDatabaseEditionEnum = "STANDARD_EDITION" + DbSystemSummaryDatabaseEditionEnterpriseEdition DbSystemSummaryDatabaseEditionEnum = "ENTERPRISE_EDITION" + DbSystemSummaryDatabaseEditionEnterpriseEditionExtremePerformance DbSystemSummaryDatabaseEditionEnum = "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" + DbSystemSummaryDatabaseEditionEnterpriseEditionHighPerformance DbSystemSummaryDatabaseEditionEnum = "ENTERPRISE_EDITION_HIGH_PERFORMANCE" +) + +var mappingDbSystemSummaryDatabaseEdition = map[string]DbSystemSummaryDatabaseEditionEnum{ + "STANDARD_EDITION": DbSystemSummaryDatabaseEditionStandardEdition, + "ENTERPRISE_EDITION": DbSystemSummaryDatabaseEditionEnterpriseEdition, + "ENTERPRISE_EDITION_EXTREME_PERFORMANCE": DbSystemSummaryDatabaseEditionEnterpriseEditionExtremePerformance, + "ENTERPRISE_EDITION_HIGH_PERFORMANCE": DbSystemSummaryDatabaseEditionEnterpriseEditionHighPerformance, +} + +// GetDbSystemSummaryDatabaseEditionEnumValues Enumerates the set of values for DbSystemSummaryDatabaseEdition +func GetDbSystemSummaryDatabaseEditionEnumValues() []DbSystemSummaryDatabaseEditionEnum { + values := make([]DbSystemSummaryDatabaseEditionEnum, 0) + for _, v := range mappingDbSystemSummaryDatabaseEdition { + values = append(values, v) + } + return values +} + +// DbSystemSummaryDiskRedundancyEnum Enum with underlying type: string +type DbSystemSummaryDiskRedundancyEnum string + +// Set of constants representing the allowable values for DbSystemSummaryDiskRedundancy +const ( + DbSystemSummaryDiskRedundancyHigh DbSystemSummaryDiskRedundancyEnum = "HIGH" + DbSystemSummaryDiskRedundancyNormal DbSystemSummaryDiskRedundancyEnum = "NORMAL" +) + +var mappingDbSystemSummaryDiskRedundancy = map[string]DbSystemSummaryDiskRedundancyEnum{ + "HIGH": DbSystemSummaryDiskRedundancyHigh, + "NORMAL": DbSystemSummaryDiskRedundancyNormal, +} + +// GetDbSystemSummaryDiskRedundancyEnumValues Enumerates the set of values for DbSystemSummaryDiskRedundancy +func GetDbSystemSummaryDiskRedundancyEnumValues() []DbSystemSummaryDiskRedundancyEnum { + values := make([]DbSystemSummaryDiskRedundancyEnum, 0) + for _, v := range mappingDbSystemSummaryDiskRedundancy { + values = append(values, v) + } + return values +} + +// DbSystemSummaryLicenseModelEnum Enum with underlying type: string +type DbSystemSummaryLicenseModelEnum string + +// Set of constants representing the allowable values for DbSystemSummaryLicenseModel +const ( + DbSystemSummaryLicenseModelLicenseIncluded DbSystemSummaryLicenseModelEnum = "LICENSE_INCLUDED" + DbSystemSummaryLicenseModelBringYourOwnLicense DbSystemSummaryLicenseModelEnum = "BRING_YOUR_OWN_LICENSE" +) + +var mappingDbSystemSummaryLicenseModel = map[string]DbSystemSummaryLicenseModelEnum{ + "LICENSE_INCLUDED": DbSystemSummaryLicenseModelLicenseIncluded, + "BRING_YOUR_OWN_LICENSE": DbSystemSummaryLicenseModelBringYourOwnLicense, +} + +// GetDbSystemSummaryLicenseModelEnumValues Enumerates the set of values for DbSystemSummaryLicenseModel +func GetDbSystemSummaryLicenseModelEnumValues() []DbSystemSummaryLicenseModelEnum { + values := make([]DbSystemSummaryLicenseModelEnum, 0) + for _, v := range mappingDbSystemSummaryLicenseModel { + values = append(values, v) + } + return values +} + +// DbSystemSummaryLifecycleStateEnum Enum with underlying type: string +type DbSystemSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for DbSystemSummaryLifecycleState +const ( + DbSystemSummaryLifecycleStateProvisioning DbSystemSummaryLifecycleStateEnum = "PROVISIONING" + DbSystemSummaryLifecycleStateAvailable DbSystemSummaryLifecycleStateEnum = "AVAILABLE" + DbSystemSummaryLifecycleStateUpdating DbSystemSummaryLifecycleStateEnum = "UPDATING" + DbSystemSummaryLifecycleStateTerminating DbSystemSummaryLifecycleStateEnum = "TERMINATING" + DbSystemSummaryLifecycleStateTerminated DbSystemSummaryLifecycleStateEnum = "TERMINATED" + DbSystemSummaryLifecycleStateFailed DbSystemSummaryLifecycleStateEnum = "FAILED" +) + +var mappingDbSystemSummaryLifecycleState = map[string]DbSystemSummaryLifecycleStateEnum{ + "PROVISIONING": DbSystemSummaryLifecycleStateProvisioning, + "AVAILABLE": DbSystemSummaryLifecycleStateAvailable, + "UPDATING": DbSystemSummaryLifecycleStateUpdating, + "TERMINATING": DbSystemSummaryLifecycleStateTerminating, + "TERMINATED": DbSystemSummaryLifecycleStateTerminated, + "FAILED": DbSystemSummaryLifecycleStateFailed, +} + +// GetDbSystemSummaryLifecycleStateEnumValues Enumerates the set of values for DbSystemSummaryLifecycleState +func GetDbSystemSummaryLifecycleStateEnumValues() []DbSystemSummaryLifecycleStateEnum { + values := make([]DbSystemSummaryLifecycleStateEnum, 0) + for _, v := range mappingDbSystemSummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/db_version_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/db_version_summary.go new file mode 100644 index 000000000..5920cb4b9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/db_version_summary.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// DbVersionSummary The Oracle database software version. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, talk to an administrator. If you're an administrator who needs to write policies to give users access, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type DbVersionSummary struct { + + // A valid Oracle database version. + Version *string `mandatory:"true" json:"version"` + + // True if this version of the Oracle database software supports pluggable dbs. + SupportsPdb *bool `mandatory:"false" json:"supportsPdb"` +} + +func (m DbVersionSummary) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/delete_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/delete_backup_request_response.go new file mode 100644 index 000000000..ff0446bbb --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/delete_backup_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteBackupRequest wrapper for the DeleteBackup operation +type DeleteBackupRequest struct { + + // The backup OCID. + BackupId *string `mandatory:"true" contributesTo:"path" name:"backupId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteBackupRequest) String() string { + return common.PointerString(request) +} + +// DeleteBackupResponse wrapper for the DeleteBackup operation +type DeleteBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/delete_db_home_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/delete_db_home_request_response.go new file mode 100644 index 000000000..d50d313f0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/delete_db_home_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteDbHomeRequest wrapper for the DeleteDbHome operation +type DeleteDbHomeRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // Whether to perform a final backup of the database or not. Default is false. If you previously used RMAN or dbcli to configure backups and then you switch to using the Console or the API for backups, a new backup configuration is created and associated with your database. This means that you can no longer rely on your previously configured unmanaged backups to work. + PerformFinalBackup *bool `mandatory:"false" contributesTo:"query" name:"performFinalBackup"` +} + +func (request DeleteDbHomeRequest) String() string { + return common.PointerString(request) +} + +// DeleteDbHomeResponse wrapper for the DeleteDbHome operation +type DeleteDbHomeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteDbHomeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_details.go b/vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_details.go new file mode 100644 index 000000000..40e8bc76b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// FailoverDataGuardAssociationDetails The Data Guard association failover parameters. +type FailoverDataGuardAssociationDetails struct { + + // The DB System administrator password. + DatabaseAdminPassword *string `mandatory:"true" json:"databaseAdminPassword"` +} + +func (m FailoverDataGuardAssociationDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_request_response.go new file mode 100644 index 000000000..265c73f00 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/failover_data_guard_association_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// FailoverDataGuardAssociationRequest wrapper for the FailoverDataGuardAssociation operation +type FailoverDataGuardAssociationRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // The Data Guard association's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DataGuardAssociationId *string `mandatory:"true" contributesTo:"path" name:"dataGuardAssociationId"` + + // A request to perform a failover, transitioning a standby database into a primary database. + FailoverDataGuardAssociationDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request FailoverDataGuardAssociationRequest) String() string { + return common.PointerString(request) +} + +// FailoverDataGuardAssociationResponse wrapper for the FailoverDataGuardAssociation operation +type FailoverDataGuardAssociationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DataGuardAssociation instance + DataGuardAssociation `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response FailoverDataGuardAssociationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_backup_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_backup_request_response.go new file mode 100644 index 000000000..8a7ce1835 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_backup_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBackupRequest wrapper for the GetBackup operation +type GetBackupRequest struct { + + // The backup OCID. + BackupId *string `mandatory:"true" contributesTo:"path" name:"backupId"` +} + +func (request GetBackupRequest) String() string { + return common.PointerString(request) +} + +// GetBackupResponse wrapper for the GetBackup operation +type GetBackupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Backup instance + Backup `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBackupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_data_guard_association_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_data_guard_association_request_response.go new file mode 100644 index 000000000..2b2f55456 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_data_guard_association_request_response.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDataGuardAssociationRequest wrapper for the GetDataGuardAssociation operation +type GetDataGuardAssociationRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // The Data Guard association's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DataGuardAssociationId *string `mandatory:"true" contributesTo:"path" name:"dataGuardAssociationId"` +} + +func (request GetDataGuardAssociationRequest) String() string { + return common.PointerString(request) +} + +// GetDataGuardAssociationResponse wrapper for the GetDataGuardAssociation operation +type GetDataGuardAssociationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DataGuardAssociation instance + DataGuardAssociation `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDataGuardAssociationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_database_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_database_request_response.go new file mode 100644 index 000000000..8b3a5701b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_database_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDatabaseRequest wrapper for the GetDatabase operation +type GetDatabaseRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` +} + +func (request GetDatabaseRequest) String() string { + return common.PointerString(request) +} + +// GetDatabaseResponse wrapper for the GetDatabase operation +type GetDatabaseResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Database instance + Database `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDatabaseResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_history_entry_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_history_entry_request_response.go new file mode 100644 index 000000000..c129a3119 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_history_entry_request_response.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbHomePatchHistoryEntryRequest wrapper for the GetDbHomePatchHistoryEntry operation +type GetDbHomePatchHistoryEntryRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` + + // The OCID of the patch history entry. + PatchHistoryEntryId *string `mandatory:"true" contributesTo:"path" name:"patchHistoryEntryId"` +} + +func (request GetDbHomePatchHistoryEntryRequest) String() string { + return common.PointerString(request) +} + +// GetDbHomePatchHistoryEntryResponse wrapper for the GetDbHomePatchHistoryEntry operation +type GetDbHomePatchHistoryEntryResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PatchHistoryEntry instance + PatchHistoryEntry `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbHomePatchHistoryEntryResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_request_response.go new file mode 100644 index 000000000..74b389688 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_patch_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbHomePatchRequest wrapper for the GetDbHomePatch operation +type GetDbHomePatchRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` + + // The OCID of the patch. + PatchId *string `mandatory:"true" contributesTo:"path" name:"patchId"` +} + +func (request GetDbHomePatchRequest) String() string { + return common.PointerString(request) +} + +// GetDbHomePatchResponse wrapper for the GetDbHomePatch operation +type GetDbHomePatchResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Patch instance + Patch `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbHomePatchResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_request_response.go new file mode 100644 index 000000000..795c4f4bc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_home_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbHomeRequest wrapper for the GetDbHome operation +type GetDbHomeRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` +} + +func (request GetDbHomeRequest) String() string { + return common.PointerString(request) +} + +// GetDbHomeResponse wrapper for the GetDbHome operation +type GetDbHomeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbHome instance + DbHome `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbHomeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_node_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_node_request_response.go new file mode 100644 index 000000000..3f5e1fc2a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_node_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbNodeRequest wrapper for the GetDbNode operation +type GetDbNodeRequest struct { + + // The database node OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbNodeId *string `mandatory:"true" contributesTo:"path" name:"dbNodeId"` +} + +func (request GetDbNodeRequest) String() string { + return common.PointerString(request) +} + +// GetDbNodeResponse wrapper for the GetDbNode operation +type GetDbNodeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbNode instance + DbNode `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbNodeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_history_entry_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_history_entry_request_response.go new file mode 100644 index 000000000..4891a2df8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_history_entry_request_response.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbSystemPatchHistoryEntryRequest wrapper for the GetDbSystemPatchHistoryEntry operation +type GetDbSystemPatchHistoryEntryRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` + + // The OCID of the patch history entry. + PatchHistoryEntryId *string `mandatory:"true" contributesTo:"path" name:"patchHistoryEntryId"` +} + +func (request GetDbSystemPatchHistoryEntryRequest) String() string { + return common.PointerString(request) +} + +// GetDbSystemPatchHistoryEntryResponse wrapper for the GetDbSystemPatchHistoryEntry operation +type GetDbSystemPatchHistoryEntryResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PatchHistoryEntry instance + PatchHistoryEntry `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbSystemPatchHistoryEntryResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_request_response.go new file mode 100644 index 000000000..916b6aafc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_patch_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbSystemPatchRequest wrapper for the GetDbSystemPatch operation +type GetDbSystemPatchRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` + + // The OCID of the patch. + PatchId *string `mandatory:"true" contributesTo:"path" name:"patchId"` +} + +func (request GetDbSystemPatchRequest) String() string { + return common.PointerString(request) +} + +// GetDbSystemPatchResponse wrapper for the GetDbSystemPatch operation +type GetDbSystemPatchResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Patch instance + Patch `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbSystemPatchResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_request_response.go new file mode 100644 index 000000000..9a1dc670f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/get_db_system_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetDbSystemRequest wrapper for the GetDbSystem operation +type GetDbSystemRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` +} + +func (request GetDbSystemRequest) String() string { + return common.PointerString(request) +} + +// GetDbSystemResponse wrapper for the GetDbSystem operation +type GetDbSystemResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbSystem instance + DbSystem `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetDbSystemResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_details.go b/vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_details.go new file mode 100644 index 000000000..2ba66b6f7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_details.go @@ -0,0 +1,171 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LaunchDbSystemDetails The representation of LaunchDbSystemDetails +type LaunchDbSystemDetails struct { + + // The Availability Domain where the DB System is located. + AvailabilityDomain *string `mandatory:"true" json:"availabilityDomain"` + + // The Oracle Cloud ID (OCID) of the compartment the DB System belongs in. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The number of CPU cores to enable. The valid values depend on the specified shape: + // - BM.DenseIO1.36 and BM.HighIO1.36 - Specify a multiple of 2, from 2 to 36. + // - BM.RACLocalStorage1.72 - Specify a multiple of 4, from 4 to 72. + // - Exadata.Quarter1.84 - Specify a multiple of 2, from 22 to 84. + // - Exadata.Half1.168 - Specify a multiple of 4, from 44 to 168. + // - Exadata.Full1.336 - Specify a multiple of 8, from 88 to 336. + // For VM DB systems, the core count is inferred from the specific VM shape chosen, so this parameter is not used. + CpuCoreCount *int `mandatory:"true" json:"cpuCoreCount"` + + // The Oracle Database Edition that applies to all the databases on the DB System. + // Exadata DB Systems and 2-node RAC DB Systems require ENTERPRISE_EDITION_EXTREME_PERFORMANCE. + DatabaseEdition LaunchDbSystemDetailsDatabaseEditionEnum `mandatory:"true" json:"databaseEdition"` + + DbHome *CreateDbHomeDetails `mandatory:"true" json:"dbHome"` + + // The host name for the DB System. The host name must begin with an alphabetic character and + // can contain a maximum of 30 alphanumeric characters, including hyphens (-). + // The maximum length of the combined hostname and domain is 63 characters. + // **Note:** The hostname must be unique within the subnet. If it is not unique, + // the DB System will fail to provision. + Hostname *string `mandatory:"true" json:"hostname"` + + // The shape of the DB System. The shape determines resources allocated to the DB System - CPU cores and memory for VM shapes; CPU cores, memory and storage for non-VM (or bare metal) shapes. To get a list of shapes, use the ListDbSystemShapes operation. + Shape *string `mandatory:"true" json:"shape"` + + // The public key portion of the key pair to use for SSH access to the DB System. Multiple public keys can be provided. The length of the combined keys cannot exceed 10,000 characters. + SshPublicKeys []string `mandatory:"true" json:"sshPublicKeys"` + + // The OCID of the subnet the DB System is associated with. + // **Subnet Restrictions:** + // - For single node and 2-node (RAC) DB Systems, do not use a subnet that overlaps with 192.168.16.16/28 + // - For Exadata and VM-based RAC DB Systems, do not use a subnet that overlaps with 192.168.128.0/20 + // These subnets are used by the Oracle Clusterware private interconnect on the database instance. + // Specifying an overlapping subnet will cause the private interconnect to malfunction. + // This restriction applies to both the client subnet and backup subnet. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // The OCID of the backup network subnet the DB System is associated with. Applicable only to Exadata. + // **Subnet Restrictions:** See above subnetId's **Subnet Restriction**. + BackupSubnetId *string `mandatory:"false" json:"backupSubnetId"` + + // Cluster name for Exadata and 2-node RAC DB Systems. The cluster name must begin with an an alphabetic character, and may contain hyphens (-). Underscores (_) are not permitted. The cluster name can be no longer than 11 characters and is not case sensitive. + ClusterName *string `mandatory:"false" json:"clusterName"` + + // The percentage assigned to DATA storage (user data and database files). + // The remaining percentage is assigned to RECO storage (database redo logs, archive logs, and recovery manager backups). + // Specify 80 or 40. The default is 80 percent assigned to DATA storage. This is not applicable for VM based DB systems. + DataStoragePercentage *int `mandatory:"false" json:"dataStoragePercentage"` + + // The type of redundancy configured for the DB System. + // Normal is 2-way redundancy, recommended for test and development systems. + // High is 3-way redundancy, recommended for production systems. + DiskRedundancy LaunchDbSystemDetailsDiskRedundancyEnum `mandatory:"false" json:"diskRedundancy,omitempty"` + + // The user-friendly name for the DB System. It does not have to be unique. + DisplayName *string `mandatory:"false" json:"displayName"` + + // A domain name used for the DB System. If the Oracle-provided Internet and VCN + // Resolver is enabled for the specified subnet, the domain name for the subnet is used + // (don't provide one). Otherwise, provide a valid DNS domain name. Hyphens (-) are not permitted. + Domain *string `mandatory:"false" json:"domain"` + + // Size, in GBs, of the initial data volume that will be created and attached to VM-shape based DB system. This storage can later be scaled up if needed. Note that the total storage size attached will be more than what is requested, to account for REDO/RECO space and software volume. + InitialDataStorageSizeInGB *int `mandatory:"false" json:"initialDataStorageSizeInGB"` + + // The Oracle license model that applies to all the databases on the DB System. The default is LICENSE_INCLUDED. + LicenseModel LaunchDbSystemDetailsLicenseModelEnum `mandatory:"false" json:"licenseModel,omitempty"` + + // Number of nodes to launch for a VM-shape based RAC DB system. + NodeCount *int `mandatory:"false" json:"nodeCount"` +} + +func (m LaunchDbSystemDetails) String() string { + return common.PointerString(m) +} + +// LaunchDbSystemDetailsDatabaseEditionEnum Enum with underlying type: string +type LaunchDbSystemDetailsDatabaseEditionEnum string + +// Set of constants representing the allowable values for LaunchDbSystemDetailsDatabaseEdition +const ( + LaunchDbSystemDetailsDatabaseEditionStandardEdition LaunchDbSystemDetailsDatabaseEditionEnum = "STANDARD_EDITION" + LaunchDbSystemDetailsDatabaseEditionEnterpriseEdition LaunchDbSystemDetailsDatabaseEditionEnum = "ENTERPRISE_EDITION" + LaunchDbSystemDetailsDatabaseEditionEnterpriseEditionExtremePerformance LaunchDbSystemDetailsDatabaseEditionEnum = "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" + LaunchDbSystemDetailsDatabaseEditionEnterpriseEditionHighPerformance LaunchDbSystemDetailsDatabaseEditionEnum = "ENTERPRISE_EDITION_HIGH_PERFORMANCE" +) + +var mappingLaunchDbSystemDetailsDatabaseEdition = map[string]LaunchDbSystemDetailsDatabaseEditionEnum{ + "STANDARD_EDITION": LaunchDbSystemDetailsDatabaseEditionStandardEdition, + "ENTERPRISE_EDITION": LaunchDbSystemDetailsDatabaseEditionEnterpriseEdition, + "ENTERPRISE_EDITION_EXTREME_PERFORMANCE": LaunchDbSystemDetailsDatabaseEditionEnterpriseEditionExtremePerformance, + "ENTERPRISE_EDITION_HIGH_PERFORMANCE": LaunchDbSystemDetailsDatabaseEditionEnterpriseEditionHighPerformance, +} + +// GetLaunchDbSystemDetailsDatabaseEditionEnumValues Enumerates the set of values for LaunchDbSystemDetailsDatabaseEdition +func GetLaunchDbSystemDetailsDatabaseEditionEnumValues() []LaunchDbSystemDetailsDatabaseEditionEnum { + values := make([]LaunchDbSystemDetailsDatabaseEditionEnum, 0) + for _, v := range mappingLaunchDbSystemDetailsDatabaseEdition { + values = append(values, v) + } + return values +} + +// LaunchDbSystemDetailsDiskRedundancyEnum Enum with underlying type: string +type LaunchDbSystemDetailsDiskRedundancyEnum string + +// Set of constants representing the allowable values for LaunchDbSystemDetailsDiskRedundancy +const ( + LaunchDbSystemDetailsDiskRedundancyHigh LaunchDbSystemDetailsDiskRedundancyEnum = "HIGH" + LaunchDbSystemDetailsDiskRedundancyNormal LaunchDbSystemDetailsDiskRedundancyEnum = "NORMAL" +) + +var mappingLaunchDbSystemDetailsDiskRedundancy = map[string]LaunchDbSystemDetailsDiskRedundancyEnum{ + "HIGH": LaunchDbSystemDetailsDiskRedundancyHigh, + "NORMAL": LaunchDbSystemDetailsDiskRedundancyNormal, +} + +// GetLaunchDbSystemDetailsDiskRedundancyEnumValues Enumerates the set of values for LaunchDbSystemDetailsDiskRedundancy +func GetLaunchDbSystemDetailsDiskRedundancyEnumValues() []LaunchDbSystemDetailsDiskRedundancyEnum { + values := make([]LaunchDbSystemDetailsDiskRedundancyEnum, 0) + for _, v := range mappingLaunchDbSystemDetailsDiskRedundancy { + values = append(values, v) + } + return values +} + +// LaunchDbSystemDetailsLicenseModelEnum Enum with underlying type: string +type LaunchDbSystemDetailsLicenseModelEnum string + +// Set of constants representing the allowable values for LaunchDbSystemDetailsLicenseModel +const ( + LaunchDbSystemDetailsLicenseModelLicenseIncluded LaunchDbSystemDetailsLicenseModelEnum = "LICENSE_INCLUDED" + LaunchDbSystemDetailsLicenseModelBringYourOwnLicense LaunchDbSystemDetailsLicenseModelEnum = "BRING_YOUR_OWN_LICENSE" +) + +var mappingLaunchDbSystemDetailsLicenseModel = map[string]LaunchDbSystemDetailsLicenseModelEnum{ + "LICENSE_INCLUDED": LaunchDbSystemDetailsLicenseModelLicenseIncluded, + "BRING_YOUR_OWN_LICENSE": LaunchDbSystemDetailsLicenseModelBringYourOwnLicense, +} + +// GetLaunchDbSystemDetailsLicenseModelEnumValues Enumerates the set of values for LaunchDbSystemDetailsLicenseModel +func GetLaunchDbSystemDetailsLicenseModelEnumValues() []LaunchDbSystemDetailsLicenseModelEnum { + values := make([]LaunchDbSystemDetailsLicenseModelEnum, 0) + for _, v := range mappingLaunchDbSystemDetailsLicenseModel { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_request_response.go new file mode 100644 index 000000000..d1d6b45e6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/launch_db_system_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// LaunchDbSystemRequest wrapper for the LaunchDbSystem operation +type LaunchDbSystemRequest struct { + + // Request to launch a DB System. + LaunchDbSystemDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (for example, if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request LaunchDbSystemRequest) String() string { + return common.PointerString(request) +} + +// LaunchDbSystemResponse wrapper for the LaunchDbSystem operation +type LaunchDbSystemResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbSystem instance + DbSystem `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response LaunchDbSystemResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_backups_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_backups_request_response.go new file mode 100644 index 000000000..6bb089016 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_backups_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListBackupsRequest wrapper for the ListBackups operation +type ListBackupsRequest struct { + + // The OCID of the database. + DatabaseId *string `mandatory:"false" contributesTo:"query" name:"databaseId"` + + // The compartment OCID. + CompartmentId *string `mandatory:"false" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListBackupsRequest) String() string { + return common.PointerString(request) +} + +// ListBackupsResponse wrapper for the ListBackups operation +type ListBackupsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []BackupSummary instance + Items []BackupSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListBackupsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_data_guard_associations_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_data_guard_associations_request_response.go new file mode 100644 index 000000000..7f2f123d7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_data_guard_associations_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDataGuardAssociationsRequest wrapper for the ListDataGuardAssociations operation +type ListDataGuardAssociationsRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDataGuardAssociationsRequest) String() string { + return common.PointerString(request) +} + +// ListDataGuardAssociationsResponse wrapper for the ListDataGuardAssociations operation +type ListDataGuardAssociationsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DataGuardAssociationSummary instance + Items []DataGuardAssociationSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDataGuardAssociationsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_databases_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_databases_request_response.go new file mode 100644 index 000000000..73e357018 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_databases_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDatabasesRequest wrapper for the ListDatabases operation +type ListDatabasesRequest struct { + + // The compartment OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // A database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"query" name:"dbHomeId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDatabasesRequest) String() string { + return common.PointerString(request) +} + +// ListDatabasesResponse wrapper for the ListDatabases operation +type ListDatabasesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DatabaseSummary instance + Items []DatabaseSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDatabasesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patch_history_entries_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patch_history_entries_request_response.go new file mode 100644 index 000000000..841a4a809 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patch_history_entries_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbHomePatchHistoryEntriesRequest wrapper for the ListDbHomePatchHistoryEntries operation +type ListDbHomePatchHistoryEntriesRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbHomePatchHistoryEntriesRequest) String() string { + return common.PointerString(request) +} + +// ListDbHomePatchHistoryEntriesResponse wrapper for the ListDbHomePatchHistoryEntries operation +type ListDbHomePatchHistoryEntriesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []PatchHistoryEntrySummary instance + Items []PatchHistoryEntrySummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbHomePatchHistoryEntriesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patches_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patches_request_response.go new file mode 100644 index 000000000..5dd89d1a6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_home_patches_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbHomePatchesRequest wrapper for the ListDbHomePatches operation +type ListDbHomePatchesRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbHomePatchesRequest) String() string { + return common.PointerString(request) +} + +// ListDbHomePatchesResponse wrapper for the ListDbHomePatches operation +type ListDbHomePatchesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []PatchSummary instance + Items []PatchSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbHomePatchesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_homes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_homes_request_response.go new file mode 100644 index 000000000..363b60972 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_homes_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbHomesRequest wrapper for the ListDbHomes operation +type ListDbHomesRequest struct { + + // The compartment OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the DB System. + DbSystemId *string `mandatory:"true" contributesTo:"query" name:"dbSystemId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbHomesRequest) String() string { + return common.PointerString(request) +} + +// ListDbHomesResponse wrapper for the ListDbHomes operation +type ListDbHomesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DbHomeSummary instance + Items []DbHomeSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbHomesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_nodes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_nodes_request_response.go new file mode 100644 index 000000000..ae02ae583 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_nodes_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbNodesRequest wrapper for the ListDbNodes operation +type ListDbNodesRequest struct { + + // The compartment OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the DB System. + DbSystemId *string `mandatory:"true" contributesTo:"query" name:"dbSystemId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbNodesRequest) String() string { + return common.PointerString(request) +} + +// ListDbNodesResponse wrapper for the ListDbNodes operation +type ListDbNodesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DbNodeSummary instance + Items []DbNodeSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbNodesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patch_history_entries_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patch_history_entries_request_response.go new file mode 100644 index 000000000..2a4c1aba1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patch_history_entries_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbSystemPatchHistoryEntriesRequest wrapper for the ListDbSystemPatchHistoryEntries operation +type ListDbSystemPatchHistoryEntriesRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbSystemPatchHistoryEntriesRequest) String() string { + return common.PointerString(request) +} + +// ListDbSystemPatchHistoryEntriesResponse wrapper for the ListDbSystemPatchHistoryEntries operation +type ListDbSystemPatchHistoryEntriesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []PatchHistoryEntrySummary instance + Items []PatchHistoryEntrySummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbSystemPatchHistoryEntriesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patches_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patches_request_response.go new file mode 100644 index 000000000..46ae8fc10 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_patches_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbSystemPatchesRequest wrapper for the ListDbSystemPatches operation +type ListDbSystemPatchesRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbSystemPatchesRequest) String() string { + return common.PointerString(request) +} + +// ListDbSystemPatchesResponse wrapper for the ListDbSystemPatches operation +type ListDbSystemPatchesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []PatchSummary instance + Items []PatchSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbSystemPatchesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_shapes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_shapes_request_response.go new file mode 100644 index 000000000..8f3d8b470 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_system_shapes_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbSystemShapesRequest wrapper for the ListDbSystemShapes operation +type ListDbSystemShapesRequest struct { + + // The name of the Availability Domain. + AvailabilityDomain *string `mandatory:"true" contributesTo:"query" name:"availabilityDomain"` + + // The compartment OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbSystemShapesRequest) String() string { + return common.PointerString(request) +} + +// ListDbSystemShapesResponse wrapper for the ListDbSystemShapes operation +type ListDbSystemShapesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DbSystemShapeSummary instance + Items []DbSystemShapeSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbSystemShapesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_systems_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_systems_request_response.go new file mode 100644 index 000000000..96a4693e5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_systems_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbSystemsRequest wrapper for the ListDbSystems operation +type ListDbSystemsRequest struct { + + // The compartment OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListDbSystemsRequest) String() string { + return common.PointerString(request) +} + +// ListDbSystemsResponse wrapper for the ListDbSystems operation +type ListDbSystemsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DbSystemSummary instance + Items []DbSystemSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbSystemsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/list_db_versions_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/list_db_versions_request_response.go new file mode 100644 index 000000000..e6a77b7bb --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/list_db_versions_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListDbVersionsRequest wrapper for the ListDbVersions operation +type ListDbVersionsRequest struct { + + // The compartment OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The pagination token to continue listing from. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // If provided, filters the results to the set of database versions which are supported for the given shape. + DbSystemShape *string `mandatory:"false" contributesTo:"query" name:"dbSystemShape"` +} + +func (request ListDbVersionsRequest) String() string { + return common.PointerString(request) +} + +// ListDbVersionsResponse wrapper for the ListDbVersions operation +type ListDbVersionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []DbVersionSummary instance + Items []DbVersionSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then there are additional items still to get. Include this value as the `page` parameter for the + // subsequent GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#List_Pagination). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListDbVersionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/patch.go b/vendor/github.com/oracle/oci-go-sdk/database/patch.go new file mode 100644 index 000000000..7ed8a3398 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/patch.go @@ -0,0 +1,122 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Patch A Patch for a DB System or DB Home. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Patch struct { + + // The text describing this patch package. + Description *string `mandatory:"true" json:"description"` + + // The OCID of the patch. + Id *string `mandatory:"true" json:"id"` + + // The date and time that the patch was released. + TimeReleased *common.SDKTime `mandatory:"true" json:"timeReleased"` + + // The version of this patch package. + Version *string `mandatory:"true" json:"version"` + + // Actions that can possibly be performed using this patch. + AvailableActions []PatchAvailableActionsEnum `mandatory:"false" json:"availableActions,omitempty"` + + // Action that is currently being performed or was completed last. + LastAction PatchLastActionEnum `mandatory:"false" json:"lastAction,omitempty"` + + // A descriptive text associated with the lifecycleState. + // Typically can contain additional displayable text. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The current state of the patch as a result of lastAction. + LifecycleState PatchLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` +} + +func (m Patch) String() string { + return common.PointerString(m) +} + +// PatchAvailableActionsEnum Enum with underlying type: string +type PatchAvailableActionsEnum string + +// Set of constants representing the allowable values for PatchAvailableActions +const ( + PatchAvailableActionsApply PatchAvailableActionsEnum = "APPLY" + PatchAvailableActionsPrecheck PatchAvailableActionsEnum = "PRECHECK" +) + +var mappingPatchAvailableActions = map[string]PatchAvailableActionsEnum{ + "APPLY": PatchAvailableActionsApply, + "PRECHECK": PatchAvailableActionsPrecheck, +} + +// GetPatchAvailableActionsEnumValues Enumerates the set of values for PatchAvailableActions +func GetPatchAvailableActionsEnumValues() []PatchAvailableActionsEnum { + values := make([]PatchAvailableActionsEnum, 0) + for _, v := range mappingPatchAvailableActions { + values = append(values, v) + } + return values +} + +// PatchLastActionEnum Enum with underlying type: string +type PatchLastActionEnum string + +// Set of constants representing the allowable values for PatchLastAction +const ( + PatchLastActionApply PatchLastActionEnum = "APPLY" + PatchLastActionPrecheck PatchLastActionEnum = "PRECHECK" +) + +var mappingPatchLastAction = map[string]PatchLastActionEnum{ + "APPLY": PatchLastActionApply, + "PRECHECK": PatchLastActionPrecheck, +} + +// GetPatchLastActionEnumValues Enumerates the set of values for PatchLastAction +func GetPatchLastActionEnumValues() []PatchLastActionEnum { + values := make([]PatchLastActionEnum, 0) + for _, v := range mappingPatchLastAction { + values = append(values, v) + } + return values +} + +// PatchLifecycleStateEnum Enum with underlying type: string +type PatchLifecycleStateEnum string + +// Set of constants representing the allowable values for PatchLifecycleState +const ( + PatchLifecycleStateAvailable PatchLifecycleStateEnum = "AVAILABLE" + PatchLifecycleStateSuccess PatchLifecycleStateEnum = "SUCCESS" + PatchLifecycleStateInProgress PatchLifecycleStateEnum = "IN_PROGRESS" + PatchLifecycleStateFailed PatchLifecycleStateEnum = "FAILED" +) + +var mappingPatchLifecycleState = map[string]PatchLifecycleStateEnum{ + "AVAILABLE": PatchLifecycleStateAvailable, + "SUCCESS": PatchLifecycleStateSuccess, + "IN_PROGRESS": PatchLifecycleStateInProgress, + "FAILED": PatchLifecycleStateFailed, +} + +// GetPatchLifecycleStateEnumValues Enumerates the set of values for PatchLifecycleState +func GetPatchLifecycleStateEnumValues() []PatchLifecycleStateEnum { + values := make([]PatchLifecycleStateEnum, 0) + for _, v := range mappingPatchLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/patch_details.go b/vendor/github.com/oracle/oci-go-sdk/database/patch_details.go new file mode 100644 index 000000000..1dab6a67a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/patch_details.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PatchDetails The details about what actions to perform and using what patch to the specified target. +// This is part of an update request that is applied to a version field on the target such +// as DB System, database home, etc. +type PatchDetails struct { + + // The action to perform on the patch. + Action PatchDetailsActionEnum `mandatory:"false" json:"action,omitempty"` + + // The OCID of the patch. + PatchId *string `mandatory:"false" json:"patchId"` +} + +func (m PatchDetails) String() string { + return common.PointerString(m) +} + +// PatchDetailsActionEnum Enum with underlying type: string +type PatchDetailsActionEnum string + +// Set of constants representing the allowable values for PatchDetailsAction +const ( + PatchDetailsActionApply PatchDetailsActionEnum = "APPLY" + PatchDetailsActionPrecheck PatchDetailsActionEnum = "PRECHECK" +) + +var mappingPatchDetailsAction = map[string]PatchDetailsActionEnum{ + "APPLY": PatchDetailsActionApply, + "PRECHECK": PatchDetailsActionPrecheck, +} + +// GetPatchDetailsActionEnumValues Enumerates the set of values for PatchDetailsAction +func GetPatchDetailsActionEnumValues() []PatchDetailsActionEnum { + values := make([]PatchDetailsActionEnum, 0) + for _, v := range mappingPatchDetailsAction { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry.go b/vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry.go new file mode 100644 index 000000000..21fa02767 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry.go @@ -0,0 +1,91 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PatchHistoryEntry The record of a patch action on a specified target. +type PatchHistoryEntry struct { + + // The OCID of the patch history entry. + Id *string `mandatory:"true" json:"id"` + + // The current state of the action. + LifecycleState PatchHistoryEntryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the patch. + PatchId *string `mandatory:"true" json:"patchId"` + + // The date and time when the patch action started. + TimeStarted *common.SDKTime `mandatory:"true" json:"timeStarted"` + + // The action being performed or was completed. + Action PatchHistoryEntryActionEnum `mandatory:"false" json:"action,omitempty"` + + // A descriptive text associated with the lifecycleState. + // Typically contains additional displayable text. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The date and time when the patch action completed. + TimeEnded *common.SDKTime `mandatory:"false" json:"timeEnded"` +} + +func (m PatchHistoryEntry) String() string { + return common.PointerString(m) +} + +// PatchHistoryEntryActionEnum Enum with underlying type: string +type PatchHistoryEntryActionEnum string + +// Set of constants representing the allowable values for PatchHistoryEntryAction +const ( + PatchHistoryEntryActionApply PatchHistoryEntryActionEnum = "APPLY" + PatchHistoryEntryActionPrecheck PatchHistoryEntryActionEnum = "PRECHECK" +) + +var mappingPatchHistoryEntryAction = map[string]PatchHistoryEntryActionEnum{ + "APPLY": PatchHistoryEntryActionApply, + "PRECHECK": PatchHistoryEntryActionPrecheck, +} + +// GetPatchHistoryEntryActionEnumValues Enumerates the set of values for PatchHistoryEntryAction +func GetPatchHistoryEntryActionEnumValues() []PatchHistoryEntryActionEnum { + values := make([]PatchHistoryEntryActionEnum, 0) + for _, v := range mappingPatchHistoryEntryAction { + values = append(values, v) + } + return values +} + +// PatchHistoryEntryLifecycleStateEnum Enum with underlying type: string +type PatchHistoryEntryLifecycleStateEnum string + +// Set of constants representing the allowable values for PatchHistoryEntryLifecycleState +const ( + PatchHistoryEntryLifecycleStateInProgress PatchHistoryEntryLifecycleStateEnum = "IN_PROGRESS" + PatchHistoryEntryLifecycleStateSucceeded PatchHistoryEntryLifecycleStateEnum = "SUCCEEDED" + PatchHistoryEntryLifecycleStateFailed PatchHistoryEntryLifecycleStateEnum = "FAILED" +) + +var mappingPatchHistoryEntryLifecycleState = map[string]PatchHistoryEntryLifecycleStateEnum{ + "IN_PROGRESS": PatchHistoryEntryLifecycleStateInProgress, + "SUCCEEDED": PatchHistoryEntryLifecycleStateSucceeded, + "FAILED": PatchHistoryEntryLifecycleStateFailed, +} + +// GetPatchHistoryEntryLifecycleStateEnumValues Enumerates the set of values for PatchHistoryEntryLifecycleState +func GetPatchHistoryEntryLifecycleStateEnumValues() []PatchHistoryEntryLifecycleStateEnum { + values := make([]PatchHistoryEntryLifecycleStateEnum, 0) + for _, v := range mappingPatchHistoryEntryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry_summary.go new file mode 100644 index 000000000..ddb964f93 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/patch_history_entry_summary.go @@ -0,0 +1,91 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PatchHistoryEntrySummary The record of a patch action on a specified target. +type PatchHistoryEntrySummary struct { + + // The OCID of the patch history entry. + Id *string `mandatory:"true" json:"id"` + + // The current state of the action. + LifecycleState PatchHistoryEntrySummaryLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID of the patch. + PatchId *string `mandatory:"true" json:"patchId"` + + // The date and time when the patch action started. + TimeStarted *common.SDKTime `mandatory:"true" json:"timeStarted"` + + // The action being performed or was completed. + Action PatchHistoryEntrySummaryActionEnum `mandatory:"false" json:"action,omitempty"` + + // A descriptive text associated with the lifecycleState. + // Typically contains additional displayable text. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The date and time when the patch action completed. + TimeEnded *common.SDKTime `mandatory:"false" json:"timeEnded"` +} + +func (m PatchHistoryEntrySummary) String() string { + return common.PointerString(m) +} + +// PatchHistoryEntrySummaryActionEnum Enum with underlying type: string +type PatchHistoryEntrySummaryActionEnum string + +// Set of constants representing the allowable values for PatchHistoryEntrySummaryAction +const ( + PatchHistoryEntrySummaryActionApply PatchHistoryEntrySummaryActionEnum = "APPLY" + PatchHistoryEntrySummaryActionPrecheck PatchHistoryEntrySummaryActionEnum = "PRECHECK" +) + +var mappingPatchHistoryEntrySummaryAction = map[string]PatchHistoryEntrySummaryActionEnum{ + "APPLY": PatchHistoryEntrySummaryActionApply, + "PRECHECK": PatchHistoryEntrySummaryActionPrecheck, +} + +// GetPatchHistoryEntrySummaryActionEnumValues Enumerates the set of values for PatchHistoryEntrySummaryAction +func GetPatchHistoryEntrySummaryActionEnumValues() []PatchHistoryEntrySummaryActionEnum { + values := make([]PatchHistoryEntrySummaryActionEnum, 0) + for _, v := range mappingPatchHistoryEntrySummaryAction { + values = append(values, v) + } + return values +} + +// PatchHistoryEntrySummaryLifecycleStateEnum Enum with underlying type: string +type PatchHistoryEntrySummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for PatchHistoryEntrySummaryLifecycleState +const ( + PatchHistoryEntrySummaryLifecycleStateInProgress PatchHistoryEntrySummaryLifecycleStateEnum = "IN_PROGRESS" + PatchHistoryEntrySummaryLifecycleStateSucceeded PatchHistoryEntrySummaryLifecycleStateEnum = "SUCCEEDED" + PatchHistoryEntrySummaryLifecycleStateFailed PatchHistoryEntrySummaryLifecycleStateEnum = "FAILED" +) + +var mappingPatchHistoryEntrySummaryLifecycleState = map[string]PatchHistoryEntrySummaryLifecycleStateEnum{ + "IN_PROGRESS": PatchHistoryEntrySummaryLifecycleStateInProgress, + "SUCCEEDED": PatchHistoryEntrySummaryLifecycleStateSucceeded, + "FAILED": PatchHistoryEntrySummaryLifecycleStateFailed, +} + +// GetPatchHistoryEntrySummaryLifecycleStateEnumValues Enumerates the set of values for PatchHistoryEntrySummaryLifecycleState +func GetPatchHistoryEntrySummaryLifecycleStateEnumValues() []PatchHistoryEntrySummaryLifecycleStateEnum { + values := make([]PatchHistoryEntrySummaryLifecycleStateEnum, 0) + for _, v := range mappingPatchHistoryEntrySummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/patch_summary.go b/vendor/github.com/oracle/oci-go-sdk/database/patch_summary.go new file mode 100644 index 000000000..e803c53fb --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/patch_summary.go @@ -0,0 +1,122 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PatchSummary A Patch for a DB System or DB Home. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type PatchSummary struct { + + // The text describing this patch package. + Description *string `mandatory:"true" json:"description"` + + // The OCID of the patch. + Id *string `mandatory:"true" json:"id"` + + // The date and time that the patch was released. + TimeReleased *common.SDKTime `mandatory:"true" json:"timeReleased"` + + // The version of this patch package. + Version *string `mandatory:"true" json:"version"` + + // Actions that can possibly be performed using this patch. + AvailableActions []PatchSummaryAvailableActionsEnum `mandatory:"false" json:"availableActions,omitempty"` + + // Action that is currently being performed or was completed last. + LastAction PatchSummaryLastActionEnum `mandatory:"false" json:"lastAction,omitempty"` + + // A descriptive text associated with the lifecycleState. + // Typically can contain additional displayable text. + LifecycleDetails *string `mandatory:"false" json:"lifecycleDetails"` + + // The current state of the patch as a result of lastAction. + LifecycleState PatchSummaryLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` +} + +func (m PatchSummary) String() string { + return common.PointerString(m) +} + +// PatchSummaryAvailableActionsEnum Enum with underlying type: string +type PatchSummaryAvailableActionsEnum string + +// Set of constants representing the allowable values for PatchSummaryAvailableActions +const ( + PatchSummaryAvailableActionsApply PatchSummaryAvailableActionsEnum = "APPLY" + PatchSummaryAvailableActionsPrecheck PatchSummaryAvailableActionsEnum = "PRECHECK" +) + +var mappingPatchSummaryAvailableActions = map[string]PatchSummaryAvailableActionsEnum{ + "APPLY": PatchSummaryAvailableActionsApply, + "PRECHECK": PatchSummaryAvailableActionsPrecheck, +} + +// GetPatchSummaryAvailableActionsEnumValues Enumerates the set of values for PatchSummaryAvailableActions +func GetPatchSummaryAvailableActionsEnumValues() []PatchSummaryAvailableActionsEnum { + values := make([]PatchSummaryAvailableActionsEnum, 0) + for _, v := range mappingPatchSummaryAvailableActions { + values = append(values, v) + } + return values +} + +// PatchSummaryLastActionEnum Enum with underlying type: string +type PatchSummaryLastActionEnum string + +// Set of constants representing the allowable values for PatchSummaryLastAction +const ( + PatchSummaryLastActionApply PatchSummaryLastActionEnum = "APPLY" + PatchSummaryLastActionPrecheck PatchSummaryLastActionEnum = "PRECHECK" +) + +var mappingPatchSummaryLastAction = map[string]PatchSummaryLastActionEnum{ + "APPLY": PatchSummaryLastActionApply, + "PRECHECK": PatchSummaryLastActionPrecheck, +} + +// GetPatchSummaryLastActionEnumValues Enumerates the set of values for PatchSummaryLastAction +func GetPatchSummaryLastActionEnumValues() []PatchSummaryLastActionEnum { + values := make([]PatchSummaryLastActionEnum, 0) + for _, v := range mappingPatchSummaryLastAction { + values = append(values, v) + } + return values +} + +// PatchSummaryLifecycleStateEnum Enum with underlying type: string +type PatchSummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for PatchSummaryLifecycleState +const ( + PatchSummaryLifecycleStateAvailable PatchSummaryLifecycleStateEnum = "AVAILABLE" + PatchSummaryLifecycleStateSuccess PatchSummaryLifecycleStateEnum = "SUCCESS" + PatchSummaryLifecycleStateInProgress PatchSummaryLifecycleStateEnum = "IN_PROGRESS" + PatchSummaryLifecycleStateFailed PatchSummaryLifecycleStateEnum = "FAILED" +) + +var mappingPatchSummaryLifecycleState = map[string]PatchSummaryLifecycleStateEnum{ + "AVAILABLE": PatchSummaryLifecycleStateAvailable, + "SUCCESS": PatchSummaryLifecycleStateSuccess, + "IN_PROGRESS": PatchSummaryLifecycleStateInProgress, + "FAILED": PatchSummaryLifecycleStateFailed, +} + +// GetPatchSummaryLifecycleStateEnumValues Enumerates the set of values for PatchSummaryLifecycleState +func GetPatchSummaryLifecycleStateEnumValues() []PatchSummaryLifecycleStateEnum { + values := make([]PatchSummaryLifecycleStateEnum, 0) + for _, v := range mappingPatchSummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_details.go b/vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_details.go new file mode 100644 index 000000000..b348fafb9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ReinstateDataGuardAssociationDetails The Data Guard association reinstate parameters. +type ReinstateDataGuardAssociationDetails struct { + + // The DB System administrator password. + DatabaseAdminPassword *string `mandatory:"true" json:"databaseAdminPassword"` +} + +func (m ReinstateDataGuardAssociationDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_request_response.go new file mode 100644 index 000000000..994fdb3c2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/reinstate_data_guard_association_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ReinstateDataGuardAssociationRequest wrapper for the ReinstateDataGuardAssociation operation +type ReinstateDataGuardAssociationRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // The Data Guard association's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DataGuardAssociationId *string `mandatory:"true" contributesTo:"path" name:"dataGuardAssociationId"` + + // A request to reinstate a database in a standby role. + ReinstateDataGuardAssociationDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request ReinstateDataGuardAssociationRequest) String() string { + return common.PointerString(request) +} + +// ReinstateDataGuardAssociationResponse wrapper for the ReinstateDataGuardAssociation operation +type ReinstateDataGuardAssociationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DataGuardAssociation instance + DataGuardAssociation `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ReinstateDataGuardAssociationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/restore_database_details.go b/vendor/github.com/oracle/oci-go-sdk/database/restore_database_details.go new file mode 100644 index 000000000..4322a35ad --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/restore_database_details.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// RestoreDatabaseDetails The representation of RestoreDatabaseDetails +type RestoreDatabaseDetails struct { + + // Restores using the backup with the System Change Number (SCN) specified. + DatabaseSCN *string `mandatory:"false" json:"databaseSCN"` + + // Restores to the last known good state with the least possible data loss. + Latest *bool `mandatory:"false" json:"latest"` + + // Restores to the timestamp specified. + Timestamp *common.SDKTime `mandatory:"false" json:"timestamp"` +} + +func (m RestoreDatabaseDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/restore_database_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/restore_database_request_response.go new file mode 100644 index 000000000..19873c923 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/restore_database_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// RestoreDatabaseRequest wrapper for the RestoreDatabase operation +type RestoreDatabaseRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // Request to perform database restore. + RestoreDatabaseDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request RestoreDatabaseRequest) String() string { + return common.PointerString(request) +} + +// RestoreDatabaseResponse wrapper for the RestoreDatabase operation +type RestoreDatabaseResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Database instance + Database `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response RestoreDatabaseResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_details.go b/vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_details.go new file mode 100644 index 000000000..087705923 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// SwitchoverDataGuardAssociationDetails The Data Guard association switchover parameters. +type SwitchoverDataGuardAssociationDetails struct { + + // The DB System administrator password. + DatabaseAdminPassword *string `mandatory:"true" json:"databaseAdminPassword"` +} + +func (m SwitchoverDataGuardAssociationDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_request_response.go new file mode 100644 index 000000000..0e3024715 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/switchover_data_guard_association_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// SwitchoverDataGuardAssociationRequest wrapper for the SwitchoverDataGuardAssociation operation +type SwitchoverDataGuardAssociationRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // The Data Guard association's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DataGuardAssociationId *string `mandatory:"true" contributesTo:"path" name:"dataGuardAssociationId"` + + // Request to swtichover a primary to a standby. + SwitchoverDataGuardAssociationDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request SwitchoverDataGuardAssociationRequest) String() string { + return common.PointerString(request) +} + +// SwitchoverDataGuardAssociationResponse wrapper for the SwitchoverDataGuardAssociation operation +type SwitchoverDataGuardAssociationResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DataGuardAssociation instance + DataGuardAssociation `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response SwitchoverDataGuardAssociationResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/terminate_db_system_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/terminate_db_system_request_response.go new file mode 100644 index 000000000..991b68b0f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/terminate_db_system_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// TerminateDbSystemRequest wrapper for the TerminateDbSystem operation +type TerminateDbSystemRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request TerminateDbSystemRequest) String() string { + return common.PointerString(request) +} + +// TerminateDbSystemResponse wrapper for the TerminateDbSystem operation +type TerminateDbSystemResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response TerminateDbSystemResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/update_database_details.go b/vendor/github.com/oracle/oci-go-sdk/database/update_database_details.go new file mode 100644 index 000000000..2d436d6d6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/update_database_details.go @@ -0,0 +1,22 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateDatabaseDetails The representation of UpdateDatabaseDetails +type UpdateDatabaseDetails struct { + DbBackupConfig *DbBackupConfig `mandatory:"false" json:"dbBackupConfig"` +} + +func (m UpdateDatabaseDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/update_database_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/update_database_request_response.go new file mode 100644 index 000000000..c43867603 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/update_database_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateDatabaseRequest wrapper for the UpdateDatabase operation +type UpdateDatabaseRequest struct { + + // The database OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DatabaseId *string `mandatory:"true" contributesTo:"path" name:"databaseId"` + + // Request to perform database update. + UpdateDatabaseDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateDatabaseRequest) String() string { + return common.PointerString(request) +} + +// UpdateDatabaseResponse wrapper for the UpdateDatabase operation +type UpdateDatabaseResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Database instance + Database `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateDatabaseResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/update_db_home_details.go b/vendor/github.com/oracle/oci-go-sdk/database/update_db_home_details.go new file mode 100644 index 000000000..741a7e36f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/update_db_home_details.go @@ -0,0 +1,22 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateDbHomeDetails Describes the modification parameters for the DB Home. +type UpdateDbHomeDetails struct { + DbVersion *PatchDetails `mandatory:"false" json:"dbVersion"` +} + +func (m UpdateDbHomeDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/update_db_home_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/update_db_home_request_response.go new file mode 100644 index 000000000..b02cd0fb8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/update_db_home_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateDbHomeRequest wrapper for the UpdateDbHome operation +type UpdateDbHomeRequest struct { + + // The database home OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbHomeId *string `mandatory:"true" contributesTo:"path" name:"dbHomeId"` + + // Request to update the properties of a DB Home. + UpdateDbHomeDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateDbHomeRequest) String() string { + return common.PointerString(request) +} + +// UpdateDbHomeResponse wrapper for the UpdateDbHome operation +type UpdateDbHomeResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbHome instance + DbHome `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateDbHomeResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/update_db_system_details.go b/vendor/github.com/oracle/oci-go-sdk/database/update_db_system_details.go new file mode 100644 index 000000000..eb03d5d10 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/update_db_system_details.go @@ -0,0 +1,32 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Database Service API +// +// The API for the Database Service. +// + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateDbSystemDetails Describes the modification parameters for the DB System. +type UpdateDbSystemDetails struct { + + // The number of CPU Cores to be set on the DB System. Applicable only for non-VM based DB systems. + CpuCoreCount *int `mandatory:"false" json:"cpuCoreCount"` + + // Size, in GBs, to which the currently attached storage needs to be scaled up to for VM based DB system. This must be greater than current storage size. Note that the total storage size attached will be more than what is requested, to account for REDO/RECO space and software volume. + DataStorageSizeInGBs *int `mandatory:"false" json:"dataStorageSizeInGBs"` + + // The public key portion of the key pair to use for SSH access to the DB System. Multiple public keys can be provided. The length of the combined keys cannot exceed 10,000 characters. + SshPublicKeys []string `mandatory:"false" json:"sshPublicKeys"` + + Version *PatchDetails `mandatory:"false" json:"version"` +} + +func (m UpdateDbSystemDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/database/update_db_system_request_response.go b/vendor/github.com/oracle/oci-go-sdk/database/update_db_system_request_response.go new file mode 100644 index 000000000..d9cd0493e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/database/update_db_system_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package database + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateDbSystemRequest wrapper for the UpdateDbSystem operation +type UpdateDbSystemRequest struct { + + // The DB System OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + DbSystemId *string `mandatory:"true" contributesTo:"path" name:"dbSystemId"` + + // Request to update the properties of a DB System. + UpdateDbSystemDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateDbSystemRequest) String() string { + return common.PointerString(request) +} + +// UpdateDbSystemResponse wrapper for the UpdateDbSystem operation +type UpdateDbSystemResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The DbSystem instance + DbSystem `presentIn:"body"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response UpdateDbSystemResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/example/helpers/args.go b/vendor/github.com/oracle/oci-go-sdk/example/helpers/args.go new file mode 100644 index 000000000..4f8b123f0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/example/helpers/args.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// +// Helper methods for OCI GOSDK Samples +// + +package helpers + +import ( + "os" + + "github.com/oracle/oci-go-sdk/common" + + "github.com/subosito/gotenv" +) + +var ( + availabilityDomain string + compartmentID string + rootCompartmentID string +) + +// ParseAgrs parse shared variables from environment variables, other samples should define their own +// viariables and call this function to initialize shared variables +func ParseAgrs() { + err := gotenv.Load(".env.sample") + LogIfError(err) + + availabilityDomain = os.Getenv("OCI_AVAILABILITY_DOMAIN") + compartmentID = os.Getenv("OCI_COMPARTMENT_ID") + rootCompartmentID = os.Getenv("OCI_ROOT_COMPARTMENT_ID") +} + +// AvailabilityDomain return the aviailability domain defined in .env.sample file +func AvailabilityDomain() *string { + return common.String(availabilityDomain) +} + +// CompartmentID return the compartment ID defined in .env.sample file +func CompartmentID() *string { + return common.String(compartmentID) +} + +// RootCompartmentID return the root compartment ID defined in .env.sample file +func RootCompartmentID() *string { + return common.String(rootCompartmentID) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/example/helpers/helper.go b/vendor/github.com/oracle/oci-go-sdk/example/helpers/helper.go new file mode 100644 index 000000000..71317387d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/example/helpers/helper.go @@ -0,0 +1,111 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// +// Helper methods for OCI GOSDK Samples +// + +package helpers + +import ( + "fmt" + "log" + "math/rand" + "reflect" + "strings" + "time" +) + +// LogIfError is equivalent to Println() followed by a call to os.Exit(1) if error is not nil +func LogIfError(err error) { + if err != nil { + log.Fatalln(err.Error()) + } +} + +// RetryUntilTrueOrError retries a function until the predicate is true or it reaches a timeout. +// The operation is retried at the give frequency +func RetryUntilTrueOrError(operation func() (interface{}, error), predicate func(interface{}) (bool, error), frequency, timeout <-chan time.Time) error { + for { + select { + case <-timeout: + return fmt.Errorf("timeout reached") + case <-frequency: + result, err := operation() + if err != nil { + return err + } + + isTrue, err := predicate(result) + if err != nil { + return err + } + + if isTrue { + return nil + } + } + } +} + +// FindLifecycleFieldValue finds lifecycle value inside the struct based on reflection +func FindLifecycleFieldValue(request interface{}) (string, error) { + val := reflect.ValueOf(request) + if val.Kind() == reflect.Ptr { + if val.IsNil() { + return "", fmt.Errorf("can not unmarshal to response a pointer to nil structure") + } + val = val.Elem() + } + + var err error + typ := val.Type() + for i := 0; i < typ.NumField(); i++ { + if err != nil { + return "", err + } + + sf := typ.Field(i) + + //unexported + if sf.PkgPath != "" { + continue + } + + sv := val.Field(i) + + if sv.Kind() == reflect.Struct { + lif, err := FindLifecycleFieldValue(sv.Interface()) + if err == nil { + return lif, nil + } + } + if !strings.Contains(strings.ToLower(sf.Name), "lifecyclestate") { + continue + } + return sv.String(), nil + } + return "", fmt.Errorf("request does not have a lifecycle field") +} + +// CheckLifecycleState returns a function that checks for that a struct has the given lifecycle +func CheckLifecycleState(lifecycleState string) func(interface{}) (bool, error) { + return func(request interface{}) (bool, error) { + fieldLifecycle, err := FindLifecycleFieldValue(request) + if err != nil { + return false, err + } + isEqual := fieldLifecycle == lifecycleState + log.Printf("Current lifecycle state is: %s, waiting for it becomes to: %s", fieldLifecycle, lifecycleState) + return isEqual, nil + } +} + +// GetRandomString returns a random string with length equals to n +func GetRandomString(n int) string { + letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_details.go new file mode 100644 index 000000000..03b811f24 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_details.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// AddUserToGroupDetails The representation of AddUserToGroupDetails +type AddUserToGroupDetails struct { + + // The OCID of the user. + UserId *string `mandatory:"true" json:"userId"` + + // The OCID of the group. + GroupId *string `mandatory:"true" json:"groupId"` +} + +func (m AddUserToGroupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_request_response.go new file mode 100644 index 000000000..34b121dd0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/add_user_to_group_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// AddUserToGroupRequest wrapper for the AddUserToGroup operation +type AddUserToGroupRequest struct { + + // Request object for adding a user to a group. + AddUserToGroupDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request AddUserToGroupRequest) String() string { + return common.PointerString(request) +} + +// AddUserToGroupResponse wrapper for the AddUserToGroup operation +type AddUserToGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The UserGroupMembership instance + UserGroupMembership `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response AddUserToGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/api_key.go b/vendor/github.com/oracle/oci-go-sdk/identity/api_key.go new file mode 100644 index 000000000..d5b9eed1d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/api_key.go @@ -0,0 +1,80 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ApiKey A PEM-format RSA credential for securing requests to the Oracle Cloud Infrastructure REST API. Also known +// as an *API signing key*. Specifically, this is the public key from the key pair. The private key remains with +// the user calling the API. For information about generating a key pair +// in the required PEM format, see Required Keys and OCIDs (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm). +// **Important:** This is **not** the SSH key for accessing compute instances. +// Each user can have a maximum of three API signing keys. +// For more information about user credentials, see User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/usercredentials.htm). +type ApiKey struct { + + // An Oracle-assigned identifier for the key, in this format: + // TENANCY_OCID/USER_OCID/KEY_FINGERPRINT. + KeyId *string `mandatory:"false" json:"keyId"` + + // The key's value. + KeyValue *string `mandatory:"false" json:"keyValue"` + + // The key's fingerprint (e.g., 12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef). + Fingerprint *string `mandatory:"false" json:"fingerprint"` + + // The OCID of the user the key belongs to. + UserId *string `mandatory:"false" json:"userId"` + + // Date and time the `ApiKey` object was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The API key's current state. After creating an `ApiKey` object, make sure its `lifecycleState` changes from + // CREATING to ACTIVE before using it. + LifecycleState ApiKeyLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m ApiKey) String() string { + return common.PointerString(m) +} + +// ApiKeyLifecycleStateEnum Enum with underlying type: string +type ApiKeyLifecycleStateEnum string + +// Set of constants representing the allowable values for ApiKeyLifecycleState +const ( + ApiKeyLifecycleStateCreating ApiKeyLifecycleStateEnum = "CREATING" + ApiKeyLifecycleStateActive ApiKeyLifecycleStateEnum = "ACTIVE" + ApiKeyLifecycleStateInactive ApiKeyLifecycleStateEnum = "INACTIVE" + ApiKeyLifecycleStateDeleting ApiKeyLifecycleStateEnum = "DELETING" + ApiKeyLifecycleStateDeleted ApiKeyLifecycleStateEnum = "DELETED" +) + +var mappingApiKeyLifecycleState = map[string]ApiKeyLifecycleStateEnum{ + "CREATING": ApiKeyLifecycleStateCreating, + "ACTIVE": ApiKeyLifecycleStateActive, + "INACTIVE": ApiKeyLifecycleStateInactive, + "DELETING": ApiKeyLifecycleStateDeleting, + "DELETED": ApiKeyLifecycleStateDeleted, +} + +// GetApiKeyLifecycleStateEnumValues Enumerates the set of values for ApiKeyLifecycleState +func GetApiKeyLifecycleStateEnumValues() []ApiKeyLifecycleStateEnum { + values := make([]ApiKeyLifecycleStateEnum, 0) + for _, v := range mappingApiKeyLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/availability_domain.go b/vendor/github.com/oracle/oci-go-sdk/identity/availability_domain.go new file mode 100644 index 000000000..7d5d03b95 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/availability_domain.go @@ -0,0 +1,29 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// AvailabilityDomain One or more isolated, fault-tolerant Oracle data centers that host cloud resources such as instances, volumes, +// and subnets. A region contains several Availability Domains. For more information, see +// Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +type AvailabilityDomain struct { + + // The name of the Availability Domain. + Name *string `mandatory:"false" json:"name"` + + // The OCID of the tenancy. + CompartmentId *string `mandatory:"false" json:"compartmentId"` +} + +func (m AvailabilityDomain) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/compartment.go b/vendor/github.com/oracle/oci-go-sdk/identity/compartment.go new file mode 100644 index 000000000..941523d22 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/compartment.go @@ -0,0 +1,88 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Compartment A collection of related resources. Compartments are a fundamental component of Oracle Cloud Infrastructure +// for organizing and isolating your cloud resources. You use them to clearly separate resources for the purposes +// of measuring usage and billing, access (through the use of IAM Service policies), and isolation (separating the +// resources for one project or business unit from another). A common approach is to create a compartment for each +// major part of your organization. For more information, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm) and also +// Setting Up Your Tenancy (https://docs.us-phoenix-1.oraclecloud.com/Content/GSG/Concepts/settinguptenancy.htm). +// +// To place a resource in a compartment, simply specify the compartment ID in the "Create" request object when +// initially creating the resource. For example, to launch an instance into a particular compartment, specify +// that compartment's OCID in the `LaunchInstance` request. You can't move an existing resource from one +// compartment to another. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Compartment struct { + + // The OCID of the compartment. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the tenancy containing the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the compartment during creation. The name must be unique across all + // compartments in the tenancy. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the compartment. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // Date and time the compartment was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The compartment's current state. After creating a compartment, make sure its `lifecycleState` changes from + // CREATING to ACTIVE before using it. + LifecycleState CompartmentLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m Compartment) String() string { + return common.PointerString(m) +} + +// CompartmentLifecycleStateEnum Enum with underlying type: string +type CompartmentLifecycleStateEnum string + +// Set of constants representing the allowable values for CompartmentLifecycleState +const ( + CompartmentLifecycleStateCreating CompartmentLifecycleStateEnum = "CREATING" + CompartmentLifecycleStateActive CompartmentLifecycleStateEnum = "ACTIVE" + CompartmentLifecycleStateInactive CompartmentLifecycleStateEnum = "INACTIVE" + CompartmentLifecycleStateDeleting CompartmentLifecycleStateEnum = "DELETING" + CompartmentLifecycleStateDeleted CompartmentLifecycleStateEnum = "DELETED" +) + +var mappingCompartmentLifecycleState = map[string]CompartmentLifecycleStateEnum{ + "CREATING": CompartmentLifecycleStateCreating, + "ACTIVE": CompartmentLifecycleStateActive, + "INACTIVE": CompartmentLifecycleStateInactive, + "DELETING": CompartmentLifecycleStateDeleting, + "DELETED": CompartmentLifecycleStateDeleted, +} + +// GetCompartmentLifecycleStateEnumValues Enumerates the set of values for CompartmentLifecycleState +func GetCompartmentLifecycleStateEnumValues() []CompartmentLifecycleStateEnum { + values := make([]CompartmentLifecycleStateEnum, 0) + for _, v := range mappingCompartmentLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_api_key_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_api_key_details.go new file mode 100644 index 000000000..b9d6157ab --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_api_key_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateApiKeyDetails The representation of CreateApiKeyDetails +type CreateApiKeyDetails struct { + + // The public key. Must be an RSA key in PEM format. + Key *string `mandatory:"true" json:"key"` +} + +func (m CreateApiKeyDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_details.go new file mode 100644 index 000000000..fb4813a61 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateCompartmentDetails The representation of CreateCompartmentDetails +type CreateCompartmentDetails struct { + + // The OCID of the tenancy containing the compartment. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the compartment during creation. The name must be unique across all compartments + // in the tenancy. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the compartment during creation. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` +} + +func (m CreateCompartmentDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_request_response.go new file mode 100644 index 000000000..5ae960ed6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_compartment_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateCompartmentRequest wrapper for the CreateCompartment operation +type CreateCompartmentRequest struct { + + // Request object for creating a new compartment. + CreateCompartmentDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateCompartmentRequest) String() string { + return common.PointerString(request) +} + +// CreateCompartmentResponse wrapper for the CreateCompartment operation +type CreateCompartmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Compartment instance + Compartment `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateCompartmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_details.go new file mode 100644 index 000000000..f61527dc9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateCustomerSecretKeyDetails The representation of CreateCustomerSecretKeyDetails +type CreateCustomerSecretKeyDetails struct { + + // The name you assign to the secret key during creation. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"true" json:"displayName"` +} + +func (m CreateCustomerSecretKeyDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_request_response.go new file mode 100644 index 000000000..db24ca7a8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_customer_secret_key_request_response.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateCustomerSecretKeyRequest wrapper for the CreateCustomerSecretKey operation +type CreateCustomerSecretKeyRequest struct { + + // Request object for creating a new secret key. + CreateCustomerSecretKeyDetails `contributesTo:"body"` + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateCustomerSecretKeyRequest) String() string { + return common.PointerString(request) +} + +// CreateCustomerSecretKeyResponse wrapper for the CreateCustomerSecretKey operation +type CreateCustomerSecretKeyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CustomerSecretKey instance + CustomerSecretKey `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateCustomerSecretKeyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_group_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_group_details.go new file mode 100644 index 000000000..98a265dc9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_group_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateGroupDetails The representation of CreateGroupDetails +type CreateGroupDetails struct { + + // The OCID of the tenancy containing the group. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the group during creation. The name must be unique across all groups + // in the tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the group during creation. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` +} + +func (m CreateGroupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_group_request_response.go new file mode 100644 index 000000000..882880cb9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_group_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateGroupRequest wrapper for the CreateGroup operation +type CreateGroupRequest struct { + + // Request object for creating a new group. + CreateGroupDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateGroupRequest) String() string { + return common.PointerString(request) +} + +// CreateGroupResponse wrapper for the CreateGroup operation +type CreateGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Group instance + Group `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_details.go new file mode 100644 index 000000000..35d7f594a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_details.go @@ -0,0 +1,125 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateIdentityProviderDetails The representation of CreateIdentityProviderDetails +type CreateIdentityProviderDetails interface { + + // The OCID of your tenancy. + GetCompartmentId() *string + + // The name you assign to the `IdentityProvider` during creation. + // The name must be unique across all `IdentityProvider` objects in the + // tenancy and cannot be changed. + GetName() *string + + // The description you assign to the `IdentityProvider` during creation. + // Does not have to be unique, and it's changeable. + GetDescription() *string + + // The identity provider service or product. + // Supported identity providers are Oracle Identity Cloud Service (IDCS) and Microsoft + // Active Directory Federation Services (ADFS). + // Example: `IDCS` + GetProductType() CreateIdentityProviderDetailsProductTypeEnum +} + +type createidentityproviderdetails struct { + JsonData []byte + CompartmentId *string `mandatory:"true" json:"compartmentId"` + Name *string `mandatory:"true" json:"name"` + Description *string `mandatory:"true" json:"description"` + ProductType CreateIdentityProviderDetailsProductTypeEnum `mandatory:"true" json:"productType"` + Protocol string `json:"protocol"` +} + +// UnmarshalJSON unmarshals json +func (m *createidentityproviderdetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalercreateidentityproviderdetails createidentityproviderdetails + s := struct { + Model Unmarshalercreateidentityproviderdetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.CompartmentId = s.Model.CompartmentId + m.Name = s.Model.Name + m.Description = s.Model.Description + m.ProductType = s.Model.ProductType + m.Protocol = s.Model.Protocol + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *createidentityproviderdetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Protocol { + case "SAML2": + mm := CreateSaml2IdentityProviderDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetCompartmentId returns CompartmentId +func (m createidentityproviderdetails) GetCompartmentId() *string { + return m.CompartmentId +} + +//GetName returns Name +func (m createidentityproviderdetails) GetName() *string { + return m.Name +} + +//GetDescription returns Description +func (m createidentityproviderdetails) GetDescription() *string { + return m.Description +} + +//GetProductType returns ProductType +func (m createidentityproviderdetails) GetProductType() CreateIdentityProviderDetailsProductTypeEnum { + return m.ProductType +} + +func (m createidentityproviderdetails) String() string { + return common.PointerString(m) +} + +// CreateIdentityProviderDetailsProductTypeEnum Enum with underlying type: string +type CreateIdentityProviderDetailsProductTypeEnum string + +// Set of constants representing the allowable values for CreateIdentityProviderDetailsProductType +const ( + CreateIdentityProviderDetailsProductTypeIdcs CreateIdentityProviderDetailsProductTypeEnum = "IDCS" + CreateIdentityProviderDetailsProductTypeAdfs CreateIdentityProviderDetailsProductTypeEnum = "ADFS" +) + +var mappingCreateIdentityProviderDetailsProductType = map[string]CreateIdentityProviderDetailsProductTypeEnum{ + "IDCS": CreateIdentityProviderDetailsProductTypeIdcs, + "ADFS": CreateIdentityProviderDetailsProductTypeAdfs, +} + +// GetCreateIdentityProviderDetailsProductTypeEnumValues Enumerates the set of values for CreateIdentityProviderDetailsProductType +func GetCreateIdentityProviderDetailsProductTypeEnumValues() []CreateIdentityProviderDetailsProductTypeEnum { + values := make([]CreateIdentityProviderDetailsProductTypeEnum, 0) + for _, v := range mappingCreateIdentityProviderDetailsProductType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_request_response.go new file mode 100644 index 000000000..a3ac552dd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_identity_provider_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateIdentityProviderRequest wrapper for the CreateIdentityProvider operation +type CreateIdentityProviderRequest struct { + + // Request object for creating a new SAML2 identity provider. + CreateIdentityProviderDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateIdentityProviderRequest) String() string { + return common.PointerString(request) +} + +// CreateIdentityProviderResponse wrapper for the CreateIdentityProvider operation +type CreateIdentityProviderResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IdentityProvider instance + IdentityProvider `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateIdentityProviderResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_details.go new file mode 100644 index 000000000..a6cb91192 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_details.go @@ -0,0 +1,28 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateIdpGroupMappingDetails The representation of CreateIdpGroupMappingDetails +type CreateIdpGroupMappingDetails struct { + + // The name of the IdP group you want to map. + IdpGroupName *string `mandatory:"true" json:"idpGroupName"` + + // The OCID of the IAM Service Group + // you want to map to the IdP group. + GroupId *string `mandatory:"true" json:"groupId"` +} + +func (m CreateIdpGroupMappingDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_request_response.go new file mode 100644 index 000000000..376d07bc3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_idp_group_mapping_request_response.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateIdpGroupMappingRequest wrapper for the CreateIdpGroupMapping operation +type CreateIdpGroupMappingRequest struct { + + // Add a mapping from an SAML2.0 identity provider group to a BMC group. + CreateIdpGroupMappingDetails `contributesTo:"body"` + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateIdpGroupMappingRequest) String() string { + return common.PointerString(request) +} + +// CreateIdpGroupMappingResponse wrapper for the CreateIdpGroupMapping operation +type CreateIdpGroupMappingResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IdpGroupMapping instance + IdpGroupMapping `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateIdpGroupMappingResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_or_reset_u_i_password_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_or_reset_u_i_password_request_response.go new file mode 100644 index 000000000..8d6de9aa8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_or_reset_u_i_password_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateOrResetUIPasswordRequest wrapper for the CreateOrResetUIPassword operation +type CreateOrResetUIPasswordRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateOrResetUIPasswordRequest) String() string { + return common.PointerString(request) +} + +// CreateOrResetUIPasswordResponse wrapper for the CreateOrResetUIPassword operation +type CreateOrResetUIPasswordResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The UiPassword instance + UiPassword `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateOrResetUIPasswordResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_policy_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_policy_details.go new file mode 100644 index 000000000..b25f8b649 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_policy_details.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreatePolicyDetails The representation of CreatePolicyDetails +type CreatePolicyDetails struct { + + // The OCID of the compartment containing the policy (either the tenancy or another compartment). + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the policy during creation. The name must be unique across all policies + // in the tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // An array of policy statements written in the policy language. See + // How Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm) and + // Common Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm). + Statements []string `mandatory:"true" json:"statements"` + + // The description you assign to the policy during creation. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // The version of the policy. If null or set to an empty string, when a request comes in for authorization, the + // policy will be evaluated according to the current behavior of the services at that moment. If set to a particular + // date (YYYY-MM-DD), the policy will be evaluated according to the behavior of the services on that date. + VersionDate *common.SDKTime `mandatory:"false" json:"versionDate"` +} + +func (m CreatePolicyDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_policy_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_policy_request_response.go new file mode 100644 index 000000000..b6d7e0028 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_policy_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreatePolicyRequest wrapper for the CreatePolicy operation +type CreatePolicyRequest struct { + + // Request object for creating a new policy. + CreatePolicyDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreatePolicyRequest) String() string { + return common.PointerString(request) +} + +// CreatePolicyResponse wrapper for the CreatePolicy operation +type CreatePolicyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Policy instance + Policy `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreatePolicyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_details.go new file mode 100644 index 000000000..78e866f7c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_details.go @@ -0,0 +1,29 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateRegionSubscriptionDetails The representation of CreateRegionSubscriptionDetails +type CreateRegionSubscriptionDetails struct { + + // The regions's key. + // Allowed values are: + // - `PHX` + // - `IAD` + // - `FRA` + // Example: `PHX` + RegionKey *string `mandatory:"true" json:"regionKey"` +} + +func (m CreateRegionSubscriptionDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_request_response.go new file mode 100644 index 000000000..66dc199d1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_region_subscription_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateRegionSubscriptionRequest wrapper for the CreateRegionSubscription operation +type CreateRegionSubscriptionRequest struct { + + // Request object for activate a new region. + CreateRegionSubscriptionDetails `contributesTo:"body"` + + // The OCID of the tenancy. + TenancyId *string `mandatory:"true" contributesTo:"path" name:"tenancyId"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateRegionSubscriptionRequest) String() string { + return common.PointerString(request) +} + +// CreateRegionSubscriptionResponse wrapper for the CreateRegionSubscription operation +type CreateRegionSubscriptionResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The RegionSubscription instance + RegionSubscription `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreateRegionSubscriptionResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_saml2_identity_provider_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_saml2_identity_provider_details.go new file mode 100644 index 000000000..f4eba6eee --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_saml2_identity_provider_details.go @@ -0,0 +1,81 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// CreateSaml2IdentityProviderDetails The representation of CreateSaml2IdentityProviderDetails +type CreateSaml2IdentityProviderDetails struct { + + // The OCID of your tenancy. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the `IdentityProvider` during creation. + // The name must be unique across all `IdentityProvider` objects in the + // tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the `IdentityProvider` during creation. + // Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // The URL for retrieving the identity provider's metadata, + // which contains information required for federating. + MetadataUrl *string `mandatory:"true" json:"metadataUrl"` + + // The XML that contains the information required for federating. + Metadata *string `mandatory:"true" json:"metadata"` + + // The identity provider service or product. + // Supported identity providers are Oracle Identity Cloud Service (IDCS) and Microsoft + // Active Directory Federation Services (ADFS). + // Example: `IDCS` + ProductType CreateIdentityProviderDetailsProductTypeEnum `mandatory:"true" json:"productType"` +} + +//GetCompartmentId returns CompartmentId +func (m CreateSaml2IdentityProviderDetails) GetCompartmentId() *string { + return m.CompartmentId +} + +//GetName returns Name +func (m CreateSaml2IdentityProviderDetails) GetName() *string { + return m.Name +} + +//GetDescription returns Description +func (m CreateSaml2IdentityProviderDetails) GetDescription() *string { + return m.Description +} + +//GetProductType returns ProductType +func (m CreateSaml2IdentityProviderDetails) GetProductType() CreateIdentityProviderDetailsProductTypeEnum { + return m.ProductType +} + +func (m CreateSaml2IdentityProviderDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m CreateSaml2IdentityProviderDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeCreateSaml2IdentityProviderDetails CreateSaml2IdentityProviderDetails + s := struct { + DiscriminatorParam string `json:"protocol"` + MarshalTypeCreateSaml2IdentityProviderDetails + }{ + "SAML2", + (MarshalTypeCreateSaml2IdentityProviderDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_details.go new file mode 100644 index 000000000..0182d9dc5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateSwiftPasswordDetails The representation of CreateSwiftPasswordDetails +type CreateSwiftPasswordDetails struct { + + // The description you assign to the Swift password during creation. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` +} + +func (m CreateSwiftPasswordDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_request_response.go new file mode 100644 index 000000000..696261df5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_swift_password_request_response.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateSwiftPasswordRequest wrapper for the CreateSwiftPassword operation +type CreateSwiftPasswordRequest struct { + + // Request object for creating a new swift password. + CreateSwiftPasswordDetails `contributesTo:"body"` + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateSwiftPasswordRequest) String() string { + return common.PointerString(request) +} + +// CreateSwiftPasswordResponse wrapper for the CreateSwiftPassword operation +type CreateSwiftPasswordResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The SwiftPassword instance + SwiftPassword `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateSwiftPasswordResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_user_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_user_details.go new file mode 100644 index 000000000..37ddd5857 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_user_details.go @@ -0,0 +1,31 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateUserDetails The representation of CreateUserDetails +type CreateUserDetails struct { + + // The OCID of the tenancy containing the user. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the user during creation. This is the user's login for the Console. + // The name must be unique across all users in the tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the user during creation. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` +} + +func (m CreateUserDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/create_user_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/create_user_request_response.go new file mode 100644 index 000000000..137de9446 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/create_user_request_response.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateUserRequest wrapper for the CreateUser operation +type CreateUserRequest struct { + + // Request object for creating a new user. + CreateUserDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateUserRequest) String() string { + return common.PointerString(request) +} + +// CreateUserResponse wrapper for the CreateUser operation +type CreateUserResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The User instance + User `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response CreateUserResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key.go b/vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key.go new file mode 100644 index 000000000..f3137bf6e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key.go @@ -0,0 +1,82 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CustomerSecretKey A `CustomerSecretKey` is an Oracle-provided key for using the Object Storage Service's +// Amazon S3 compatible API (https://docs.us-phoenix-1.oraclecloud.com/Content/Object/Tasks/s3compatibleapi.htm). +// A user can have up to two secret keys at a time. +// **Note:** The secret key is always an Oracle-generated string; you can't change it to a string of your choice. +// For more information, see Managing User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Tasks/managingcredentials.htm). +type CustomerSecretKey struct { + + // The secret key. + Key *string `mandatory:"false" json:"key"` + + // The OCID of the secret key. + Id *string `mandatory:"false" json:"id"` + + // The OCID of the user the password belongs to. + UserId *string `mandatory:"false" json:"userId"` + + // The display name you assign to the secret key. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Date and time the `CustomerSecretKey` object was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // Date and time when this password will expire, in the format defined by RFC3339. + // Null if it never expires. + // Example: `2016-08-25T21:10:29.600Z` + TimeExpires *common.SDKTime `mandatory:"false" json:"timeExpires"` + + // The secret key's current state. After creating a secret key, make sure its `lifecycleState` changes from + // CREATING to ACTIVE before using it. + LifecycleState CustomerSecretKeyLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m CustomerSecretKey) String() string { + return common.PointerString(m) +} + +// CustomerSecretKeyLifecycleStateEnum Enum with underlying type: string +type CustomerSecretKeyLifecycleStateEnum string + +// Set of constants representing the allowable values for CustomerSecretKeyLifecycleState +const ( + CustomerSecretKeyLifecycleStateCreating CustomerSecretKeyLifecycleStateEnum = "CREATING" + CustomerSecretKeyLifecycleStateActive CustomerSecretKeyLifecycleStateEnum = "ACTIVE" + CustomerSecretKeyLifecycleStateInactive CustomerSecretKeyLifecycleStateEnum = "INACTIVE" + CustomerSecretKeyLifecycleStateDeleting CustomerSecretKeyLifecycleStateEnum = "DELETING" + CustomerSecretKeyLifecycleStateDeleted CustomerSecretKeyLifecycleStateEnum = "DELETED" +) + +var mappingCustomerSecretKeyLifecycleState = map[string]CustomerSecretKeyLifecycleStateEnum{ + "CREATING": CustomerSecretKeyLifecycleStateCreating, + "ACTIVE": CustomerSecretKeyLifecycleStateActive, + "INACTIVE": CustomerSecretKeyLifecycleStateInactive, + "DELETING": CustomerSecretKeyLifecycleStateDeleting, + "DELETED": CustomerSecretKeyLifecycleStateDeleted, +} + +// GetCustomerSecretKeyLifecycleStateEnumValues Enumerates the set of values for CustomerSecretKeyLifecycleState +func GetCustomerSecretKeyLifecycleStateEnumValues() []CustomerSecretKeyLifecycleStateEnum { + values := make([]CustomerSecretKeyLifecycleStateEnum, 0) + for _, v := range mappingCustomerSecretKeyLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key_summary.go b/vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key_summary.go new file mode 100644 index 000000000..bc59eed42 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/customer_secret_key_summary.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CustomerSecretKeySummary As the name suggests, a `CustomerSecretKeySummary` object contains information about a `CustomerSecretKey`. +// A `CustomerSecretKey` is an Oracle-provided key for using the Object Storage Service's Amazon S3 compatible API. +type CustomerSecretKeySummary struct { + + // The OCID of the secret key. + Id *string `mandatory:"false" json:"id"` + + // The OCID of the user the password belongs to. + UserId *string `mandatory:"false" json:"userId"` + + // The displayName you assign to the secret key. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"false" json:"displayName"` + + // Date and time the `CustomerSecretKey` object was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // Date and time when this password will expire, in the format defined by RFC3339. + // Null if it never expires. + // Example: `2016-08-25T21:10:29.600Z` + TimeExpires *common.SDKTime `mandatory:"false" json:"timeExpires"` + + // The secret key's current state. After creating a secret key, make sure its `lifecycleState` changes from + // CREATING to ACTIVE before using it. + LifecycleState CustomerSecretKeySummaryLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m CustomerSecretKeySummary) String() string { + return common.PointerString(m) +} + +// CustomerSecretKeySummaryLifecycleStateEnum Enum with underlying type: string +type CustomerSecretKeySummaryLifecycleStateEnum string + +// Set of constants representing the allowable values for CustomerSecretKeySummaryLifecycleState +const ( + CustomerSecretKeySummaryLifecycleStateCreating CustomerSecretKeySummaryLifecycleStateEnum = "CREATING" + CustomerSecretKeySummaryLifecycleStateActive CustomerSecretKeySummaryLifecycleStateEnum = "ACTIVE" + CustomerSecretKeySummaryLifecycleStateInactive CustomerSecretKeySummaryLifecycleStateEnum = "INACTIVE" + CustomerSecretKeySummaryLifecycleStateDeleting CustomerSecretKeySummaryLifecycleStateEnum = "DELETING" + CustomerSecretKeySummaryLifecycleStateDeleted CustomerSecretKeySummaryLifecycleStateEnum = "DELETED" +) + +var mappingCustomerSecretKeySummaryLifecycleState = map[string]CustomerSecretKeySummaryLifecycleStateEnum{ + "CREATING": CustomerSecretKeySummaryLifecycleStateCreating, + "ACTIVE": CustomerSecretKeySummaryLifecycleStateActive, + "INACTIVE": CustomerSecretKeySummaryLifecycleStateInactive, + "DELETING": CustomerSecretKeySummaryLifecycleStateDeleting, + "DELETED": CustomerSecretKeySummaryLifecycleStateDeleted, +} + +// GetCustomerSecretKeySummaryLifecycleStateEnumValues Enumerates the set of values for CustomerSecretKeySummaryLifecycleState +func GetCustomerSecretKeySummaryLifecycleStateEnumValues() []CustomerSecretKeySummaryLifecycleStateEnum { + values := make([]CustomerSecretKeySummaryLifecycleStateEnum, 0) + for _, v := range mappingCustomerSecretKeySummaryLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_api_key_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_api_key_request_response.go new file mode 100644 index 000000000..e2beffe0a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_api_key_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteApiKeyRequest wrapper for the DeleteApiKey operation +type DeleteApiKeyRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // The key's fingerprint. + Fingerprint *string `mandatory:"true" contributesTo:"path" name:"fingerprint"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteApiKeyRequest) String() string { + return common.PointerString(request) +} + +// DeleteApiKeyResponse wrapper for the DeleteApiKey operation +type DeleteApiKeyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteApiKeyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_customer_secret_key_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_customer_secret_key_request_response.go new file mode 100644 index 000000000..02855f42b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_customer_secret_key_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteCustomerSecretKeyRequest wrapper for the DeleteCustomerSecretKey operation +type DeleteCustomerSecretKeyRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // The OCID of the secret key. + CustomerSecretKeyId *string `mandatory:"true" contributesTo:"path" name:"customerSecretKeyId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteCustomerSecretKeyRequest) String() string { + return common.PointerString(request) +} + +// DeleteCustomerSecretKeyResponse wrapper for the DeleteCustomerSecretKey operation +type DeleteCustomerSecretKeyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteCustomerSecretKeyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_group_request_response.go new file mode 100644 index 000000000..9b63b8bf4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_group_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteGroupRequest wrapper for the DeleteGroup operation +type DeleteGroupRequest struct { + + // The OCID of the group. + GroupId *string `mandatory:"true" contributesTo:"path" name:"groupId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteGroupRequest) String() string { + return common.PointerString(request) +} + +// DeleteGroupResponse wrapper for the DeleteGroup operation +type DeleteGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_identity_provider_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_identity_provider_request_response.go new file mode 100644 index 000000000..e0d82c0fa --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_identity_provider_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteIdentityProviderRequest wrapper for the DeleteIdentityProvider operation +type DeleteIdentityProviderRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteIdentityProviderRequest) String() string { + return common.PointerString(request) +} + +// DeleteIdentityProviderResponse wrapper for the DeleteIdentityProvider operation +type DeleteIdentityProviderResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteIdentityProviderResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_idp_group_mapping_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_idp_group_mapping_request_response.go new file mode 100644 index 000000000..02d2b8c50 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_idp_group_mapping_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteIdpGroupMappingRequest wrapper for the DeleteIdpGroupMapping operation +type DeleteIdpGroupMappingRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // The OCID of the group mapping. + MappingId *string `mandatory:"true" contributesTo:"path" name:"mappingId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteIdpGroupMappingRequest) String() string { + return common.PointerString(request) +} + +// DeleteIdpGroupMappingResponse wrapper for the DeleteIdpGroupMapping operation +type DeleteIdpGroupMappingResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteIdpGroupMappingResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_policy_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_policy_request_response.go new file mode 100644 index 000000000..905f97563 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_policy_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeletePolicyRequest wrapper for the DeletePolicy operation +type DeletePolicyRequest struct { + + // The OCID of the policy. + PolicyId *string `mandatory:"true" contributesTo:"path" name:"policyId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeletePolicyRequest) String() string { + return common.PointerString(request) +} + +// DeletePolicyResponse wrapper for the DeletePolicy operation +type DeletePolicyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeletePolicyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_swift_password_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_swift_password_request_response.go new file mode 100644 index 000000000..fac41a4f3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_swift_password_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteSwiftPasswordRequest wrapper for the DeleteSwiftPassword operation +type DeleteSwiftPasswordRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // The OCID of the Swift password. + SwiftPasswordId *string `mandatory:"true" contributesTo:"path" name:"swiftPasswordId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteSwiftPasswordRequest) String() string { + return common.PointerString(request) +} + +// DeleteSwiftPasswordResponse wrapper for the DeleteSwiftPassword operation +type DeleteSwiftPasswordResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteSwiftPasswordResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/delete_user_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/delete_user_request_response.go new file mode 100644 index 000000000..5dffac8f5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/delete_user_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteUserRequest wrapper for the DeleteUser operation +type DeleteUserRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request DeleteUserRequest) String() string { + return common.PointerString(request) +} + +// DeleteUserResponse wrapper for the DeleteUser operation +type DeleteUserResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteUserResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/fault_domain.go b/vendor/github.com/oracle/oci-go-sdk/identity/fault_domain.go new file mode 100644 index 000000000..4f596c95b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/fault_domain.go @@ -0,0 +1,32 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// FaultDomain A Fault Domain is a logical grouping of hardware and infrastructure within an Availability Domain that can become +// unavailable in its entirety either due to hardware failure such as Top-of-rack (TOR) switch failure or due to +// planned software maintenance such as security updates that reboot your instances. +type FaultDomain struct { + + // The name of the Fault Domain. + Name *string `mandatory:"false" json:"name"` + + // The OCID of the of the compartment. Currently only tenancy (root) compartment can be provided. + CompartmentId *string `mandatory:"false" json:"compartmentId"` + + // The name of the availabilityDomain where the Fault Domain belongs. + AvailabilityDomain *string `mandatory:"false" json:"availabilityDomain"` +} + +func (m FaultDomain) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_compartment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_compartment_request_response.go new file mode 100644 index 000000000..f85794587 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_compartment_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetCompartmentRequest wrapper for the GetCompartment operation +type GetCompartmentRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"path" name:"compartmentId"` +} + +func (request GetCompartmentRequest) String() string { + return common.PointerString(request) +} + +// GetCompartmentResponse wrapper for the GetCompartment operation +type GetCompartmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Compartment instance + Compartment `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetCompartmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_group_request_response.go new file mode 100644 index 000000000..90d97badc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_group_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetGroupRequest wrapper for the GetGroup operation +type GetGroupRequest struct { + + // The OCID of the group. + GroupId *string `mandatory:"true" contributesTo:"path" name:"groupId"` +} + +func (request GetGroupRequest) String() string { + return common.PointerString(request) +} + +// GetGroupResponse wrapper for the GetGroup operation +type GetGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Group instance + Group `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_identity_provider_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_identity_provider_request_response.go new file mode 100644 index 000000000..503c1687a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_identity_provider_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetIdentityProviderRequest wrapper for the GetIdentityProvider operation +type GetIdentityProviderRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` +} + +func (request GetIdentityProviderRequest) String() string { + return common.PointerString(request) +} + +// GetIdentityProviderResponse wrapper for the GetIdentityProvider operation +type GetIdentityProviderResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IdentityProvider instance + IdentityProvider `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetIdentityProviderResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_idp_group_mapping_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_idp_group_mapping_request_response.go new file mode 100644 index 000000000..b589e1e9f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_idp_group_mapping_request_response.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetIdpGroupMappingRequest wrapper for the GetIdpGroupMapping operation +type GetIdpGroupMappingRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // The OCID of the group mapping. + MappingId *string `mandatory:"true" contributesTo:"path" name:"mappingId"` +} + +func (request GetIdpGroupMappingRequest) String() string { + return common.PointerString(request) +} + +// GetIdpGroupMappingResponse wrapper for the GetIdpGroupMapping operation +type GetIdpGroupMappingResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IdpGroupMapping instance + IdpGroupMapping `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetIdpGroupMappingResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_policy_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_policy_request_response.go new file mode 100644 index 000000000..3bff5478c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_policy_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetPolicyRequest wrapper for the GetPolicy operation +type GetPolicyRequest struct { + + // The OCID of the policy. + PolicyId *string `mandatory:"true" contributesTo:"path" name:"policyId"` +} + +func (request GetPolicyRequest) String() string { + return common.PointerString(request) +} + +// GetPolicyResponse wrapper for the GetPolicy operation +type GetPolicyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Policy instance + Policy `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetPolicyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_tenancy_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_tenancy_request_response.go new file mode 100644 index 000000000..8ad0f641d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_tenancy_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetTenancyRequest wrapper for the GetTenancy operation +type GetTenancyRequest struct { + + // The OCID of the tenancy. + TenancyId *string `mandatory:"true" contributesTo:"path" name:"tenancyId"` +} + +func (request GetTenancyRequest) String() string { + return common.PointerString(request) +} + +// GetTenancyResponse wrapper for the GetTenancy operation +type GetTenancyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Tenancy instance + Tenancy `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetTenancyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_user_group_membership_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_user_group_membership_request_response.go new file mode 100644 index 000000000..492240dbf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_user_group_membership_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetUserGroupMembershipRequest wrapper for the GetUserGroupMembership operation +type GetUserGroupMembershipRequest struct { + + // The OCID of the userGroupMembership. + UserGroupMembershipId *string `mandatory:"true" contributesTo:"path" name:"userGroupMembershipId"` +} + +func (request GetUserGroupMembershipRequest) String() string { + return common.PointerString(request) +} + +// GetUserGroupMembershipResponse wrapper for the GetUserGroupMembership operation +type GetUserGroupMembershipResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The UserGroupMembership instance + UserGroupMembership `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetUserGroupMembershipResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/get_user_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/get_user_request_response.go new file mode 100644 index 000000000..980955dad --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/get_user_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetUserRequest wrapper for the GetUser operation +type GetUserRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` +} + +func (request GetUserRequest) String() string { + return common.PointerString(request) +} + +// GetUserResponse wrapper for the GetUser operation +type GetUserResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The User instance + User `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response GetUserResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/group.go b/vendor/github.com/oracle/oci-go-sdk/identity/group.go new file mode 100644 index 000000000..8029ba950 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/group.go @@ -0,0 +1,84 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Group A collection of users who all need the same type of access to a particular set of resources or compartment. +// For conceptual information about groups and other IAM Service components, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// If you're federating with an identity provider (IdP), you need to create mappings between the groups +// defined in the IdP and groups you define in the IAM service. For more information, see +// Identity Providers and Federation (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm). Also see +// IdentityProvider and +// IdpGroupMapping. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Group struct { + + // The OCID of the group. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the tenancy containing the group. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the group during creation. The name must be unique across all groups in + // the tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the group. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // Date and time the group was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The group's current state. After creating a group, make sure its `lifecycleState` changes from CREATING to + // ACTIVE before using it. + LifecycleState GroupLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m Group) String() string { + return common.PointerString(m) +} + +// GroupLifecycleStateEnum Enum with underlying type: string +type GroupLifecycleStateEnum string + +// Set of constants representing the allowable values for GroupLifecycleState +const ( + GroupLifecycleStateCreating GroupLifecycleStateEnum = "CREATING" + GroupLifecycleStateActive GroupLifecycleStateEnum = "ACTIVE" + GroupLifecycleStateInactive GroupLifecycleStateEnum = "INACTIVE" + GroupLifecycleStateDeleting GroupLifecycleStateEnum = "DELETING" + GroupLifecycleStateDeleted GroupLifecycleStateEnum = "DELETED" +) + +var mappingGroupLifecycleState = map[string]GroupLifecycleStateEnum{ + "CREATING": GroupLifecycleStateCreating, + "ACTIVE": GroupLifecycleStateActive, + "INACTIVE": GroupLifecycleStateInactive, + "DELETING": GroupLifecycleStateDeleting, + "DELETED": GroupLifecycleStateDeleted, +} + +// GetGroupLifecycleStateEnumValues Enumerates the set of values for GroupLifecycleState +func GetGroupLifecycleStateEnumValues() []GroupLifecycleStateEnum { + values := make([]GroupLifecycleStateEnum, 0) + for _, v := range mappingGroupLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/identity_client.go b/vendor/github.com/oracle/oci-go-sdk/identity/identity_client.go new file mode 100644 index 000000000..8bf0c90c5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/identity_client.go @@ -0,0 +1,1167 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//IdentityClient a client for Identity +type IdentityClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewIdentityClientWithConfigurationProvider Creates a new default Identity client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewIdentityClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client IdentityClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = IdentityClient{BaseClient: baseClient} + client.BasePath = "20160918" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *IdentityClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "identity", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *IdentityClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *IdentityClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// AddUserToGroup Adds the specified user to the specified group and returns a `UserGroupMembership` object with its own OCID. +// After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before using the +// object, first make sure its `lifecycleState` has changed to ACTIVE. +func (client IdentityClient) AddUserToGroup(ctx context.Context, request AddUserToGroupRequest) (response AddUserToGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/userGroupMemberships/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateCompartment Creates a new compartment in your tenancy. +// **Important:** Compartments cannot be deleted. +// You must specify your tenancy's OCID as the compartment ID in the request object. Remember that the tenancy +// is simply the root compartment. For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You must also specify a *name* for the compartment, which must be unique across all compartments in +// your tenancy. You can use this name or the OCID when writing policies that apply +// to the compartment. For more information about policies, see +// How Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm). +// You must also specify a *description* for the compartment (although it can be an empty string). It does +// not have to be unique, and you can change it anytime with +// UpdateCompartment. +// After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before using the +// object, first make sure its `lifecycleState` has changed to ACTIVE. +func (client IdentityClient) CreateCompartment(ctx context.Context, request CreateCompartmentRequest) (response CreateCompartmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/compartments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateCustomerSecretKey Creates a new secret key for the specified user. Secret keys are used for authentication with the Object Storage Service's Amazon S3 +// compatible API. For information, see +// Managing User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Tasks/managingcredentials.htm). +// You must specify a *description* for the secret key (although it can be an empty string). It does not +// have to be unique, and you can change it anytime with +// UpdateCustomerSecretKey. +// Every user has permission to create a secret key for *their own user ID*. An administrator in your organization +// does not need to write a policy to give users this ability. To compare, administrators who have permission to the +// tenancy can use this operation to create a secret key for any user, including themselves. +func (client IdentityClient) CreateCustomerSecretKey(ctx context.Context, request CreateCustomerSecretKeyRequest) (response CreateCustomerSecretKeyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/users/{userId}/customerSecretKeys/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateGroup Creates a new group in your tenancy. +// You must specify your tenancy's OCID as the compartment ID in the request object (remember that the tenancy +// is simply the root compartment). Notice that IAM resources (users, groups, compartments, and some policies) +// reside within the tenancy itself, unlike cloud resources such as compute instances, which typically +// reside within compartments inside the tenancy. For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You must also specify a *name* for the group, which must be unique across all groups in your tenancy and +// cannot be changed. You can use this name or the OCID when writing policies that apply to the group. For more +// information about policies, see How Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm). +// You must also specify a *description* for the group (although it can be an empty string). It does not +// have to be unique, and you can change it anytime with UpdateGroup. +// After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before using the +// object, first make sure its `lifecycleState` has changed to ACTIVE. +// After creating the group, you need to put users in it and write policies for it. +// See AddUserToGroup and +// CreatePolicy. +func (client IdentityClient) CreateGroup(ctx context.Context, request CreateGroupRequest) (response CreateGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/groups/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateIdentityProvider Creates a new identity provider in your tenancy. For more information, see +// Identity Providers and Federation (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm). +// You must specify your tenancy's OCID as the compartment ID in the request object. +// Remember that the tenancy is simply the root compartment. For information about +// OCIDs, see Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You must also specify a *name* for the `IdentityProvider`, which must be unique +// across all `IdentityProvider` objects in your tenancy and cannot be changed. +// You must also specify a *description* for the `IdentityProvider` (although +// it can be an empty string). It does not have to be unique, and you can change +// it anytime with +// UpdateIdentityProvider. +// After you send your request, the new object's `lifecycleState` will temporarily +// be CREATING. Before using the object, first make sure its `lifecycleState` has +// changed to ACTIVE. +func (client IdentityClient) CreateIdentityProvider(ctx context.Context, request CreateIdentityProviderRequest) (response CreateIdentityProviderResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/identityProviders/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &identityprovider{}) + return +} + +// CreateIdpGroupMapping Creates a single mapping between an IdP group and an IAM Service +// Group. +func (client IdentityClient) CreateIdpGroupMapping(ctx context.Context, request CreateIdpGroupMappingRequest) (response CreateIdpGroupMappingResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/identityProviders/{identityProviderId}/groupMappings/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateOrResetUIPassword Creates a new Console one-time password for the specified user. For more information about user +// credentials, see User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/usercredentials.htm). +// Use this operation after creating a new user, or if a user forgets their password. The new one-time +// password is returned to you in the response, and you must securely deliver it to the user. They'll +// be prompted to change this password the next time they sign in to the Console. If they don't change +// it within 7 days, the password will expire and you'll need to create a new one-time password for the +// user. +// **Note:** The user's Console login is the unique name you specified when you created the user +// (see CreateUser). +func (client IdentityClient) CreateOrResetUIPassword(ctx context.Context, request CreateOrResetUIPasswordRequest) (response CreateOrResetUIPasswordResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/users/{userId}/uiPassword", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreatePolicy Creates a new policy in the specified compartment (either the tenancy or another of your compartments). +// If you're new to policies, see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// You must specify a *name* for the policy, which must be unique across all policies in your tenancy +// and cannot be changed. +// You must also specify a *description* for the policy (although it can be an empty string). It does not +// have to be unique, and you can change it anytime with UpdatePolicy. +// You must specify one or more policy statements in the statements array. For information about writing +// policies, see How Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm) and +// Common Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm). +// After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before using the +// object, first make sure its `lifecycleState` has changed to ACTIVE. +// New policies take effect typically within 10 seconds. +func (client IdentityClient) CreatePolicy(ctx context.Context, request CreatePolicyRequest) (response CreatePolicyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/policies/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateRegionSubscription Creates a subscription to a region for a tenancy. +func (client IdentityClient) CreateRegionSubscription(ctx context.Context, request CreateRegionSubscriptionRequest) (response CreateRegionSubscriptionResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/tenancies/{tenancyId}/regionSubscriptions", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateSwiftPassword Creates a new Swift password for the specified user. For information about what Swift passwords are for, see +// Managing User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Tasks/managingcredentials.htm). +// You must specify a *description* for the Swift password (although it can be an empty string). It does not +// have to be unique, and you can change it anytime with +// UpdateSwiftPassword. +// Every user has permission to create a Swift password for *their own user ID*. An administrator in your organization +// does not need to write a policy to give users this ability. To compare, administrators who have permission to the +// tenancy can use this operation to create a Swift password for any user, including themselves. +func (client IdentityClient) CreateSwiftPassword(ctx context.Context, request CreateSwiftPasswordRequest) (response CreateSwiftPasswordResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/users/{userId}/swiftPasswords/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateUser Creates a new user in your tenancy. For conceptual information about users, your tenancy, and other +// IAM Service components, see Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// You must specify your tenancy's OCID as the compartment ID in the request object (remember that the +// tenancy is simply the root compartment). Notice that IAM resources (users, groups, compartments, and +// some policies) reside within the tenancy itself, unlike cloud resources such as compute instances, +// which typically reside within compartments inside the tenancy. For information about OCIDs, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// You must also specify a *name* for the user, which must be unique across all users in your tenancy +// and cannot be changed. Allowed characters: No spaces. Only letters, numerals, hyphens, periods, +// underscores, +, and @. If you specify a name that's already in use, you'll get a 409 error. +// This name will be the user's login to the Console. You might want to pick a +// name that your company's own identity system (e.g., Active Directory, LDAP, etc.) already uses. +// If you delete a user and then create a new user with the same name, they'll be considered different +// users because they have different OCIDs. +// You must also specify a *description* for the user (although it can be an empty string). +// It does not have to be unique, and you can change it anytime with +// UpdateUser. You can use the field to provide the user's +// full name, a description, a nickname, or other information to generally identify the user. +// After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before +// using the object, first make sure its `lifecycleState` has changed to ACTIVE. +// A new user has no permissions until you place the user in one or more groups (see +// AddUserToGroup). If the user needs to +// access the Console, you need to provide the user a password (see +// CreateOrResetUIPassword). +// If the user needs to access the Oracle Cloud Infrastructure REST API, you need to upload a +// public API signing key for that user (see +// Required Keys and OCIDs (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm) and also +// UploadApiKey). +// **Important:** Make sure to inform the new user which compartment(s) they have access to. +func (client IdentityClient) CreateUser(ctx context.Context, request CreateUserRequest) (response CreateUserResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/users/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteApiKey Deletes the specified API signing key for the specified user. +// Every user has permission to use this operation to delete a key for *their own user ID*. An +// administrator in your organization does not need to write a policy to give users this ability. +// To compare, administrators who have permission to the tenancy can use this operation to delete +// a key for any user, including themselves. +func (client IdentityClient) DeleteApiKey(ctx context.Context, request DeleteApiKeyRequest) (response DeleteApiKeyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/users/{userId}/apiKeys/{fingerprint}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteCustomerSecretKey Deletes the specified secret key for the specified user. +func (client IdentityClient) DeleteCustomerSecretKey(ctx context.Context, request DeleteCustomerSecretKeyRequest) (response DeleteCustomerSecretKeyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/users/{userId}/customerSecretKeys/{customerSecretKeyId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteGroup Deletes the specified group. The group must be empty. +func (client IdentityClient) DeleteGroup(ctx context.Context, request DeleteGroupRequest) (response DeleteGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/groups/{groupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteIdentityProvider Deletes the specified identity provider. The identity provider must not have +// any group mappings (see IdpGroupMapping). +func (client IdentityClient) DeleteIdentityProvider(ctx context.Context, request DeleteIdentityProviderRequest) (response DeleteIdentityProviderResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/identityProviders/{identityProviderId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteIdpGroupMapping Deletes the specified group mapping. +func (client IdentityClient) DeleteIdpGroupMapping(ctx context.Context, request DeleteIdpGroupMappingRequest) (response DeleteIdpGroupMappingResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/identityProviders/{identityProviderId}/groupMappings/{mappingId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeletePolicy Deletes the specified policy. The deletion takes effect typically within 10 seconds. +func (client IdentityClient) DeletePolicy(ctx context.Context, request DeletePolicyRequest) (response DeletePolicyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/policies/{policyId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteSwiftPassword Deletes the specified Swift password for the specified user. +func (client IdentityClient) DeleteSwiftPassword(ctx context.Context, request DeleteSwiftPasswordRequest) (response DeleteSwiftPasswordResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/users/{userId}/swiftPasswords/{swiftPasswordId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteUser Deletes the specified user. The user must not be in any groups. +func (client IdentityClient) DeleteUser(ctx context.Context, request DeleteUserRequest) (response DeleteUserResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/users/{userId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetCompartment Gets the specified compartment's information. +// This operation does not return a list of all the resources inside the compartment. There is no single +// API operation that does that. Compartments can contain multiple types of resources (instances, block +// storage volumes, etc.). To find out what's in a compartment, you must call the "List" operation for +// each resource type and specify the compartment's OCID as a query parameter in the request. For example, +// call the ListInstances operation in the Cloud Compute +// Service or the ListVolumes operation in Cloud Block Storage. +func (client IdentityClient) GetCompartment(ctx context.Context, request GetCompartmentRequest) (response GetCompartmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/compartments/{compartmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetGroup Gets the specified group's information. +// This operation does not return a list of all the users in the group. To do that, use +// ListUserGroupMemberships and +// provide the group's OCID as a query parameter in the request. +func (client IdentityClient) GetGroup(ctx context.Context, request GetGroupRequest) (response GetGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/groups/{groupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetIdentityProvider Gets the specified identity provider's information. +func (client IdentityClient) GetIdentityProvider(ctx context.Context, request GetIdentityProviderRequest) (response GetIdentityProviderResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/identityProviders/{identityProviderId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &identityprovider{}) + return +} + +// GetIdpGroupMapping Gets the specified group mapping. +func (client IdentityClient) GetIdpGroupMapping(ctx context.Context, request GetIdpGroupMappingRequest) (response GetIdpGroupMappingResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/identityProviders/{identityProviderId}/groupMappings/{mappingId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetPolicy Gets the specified policy's information. +func (client IdentityClient) GetPolicy(ctx context.Context, request GetPolicyRequest) (response GetPolicyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/policies/{policyId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetTenancy Get the specified tenancy's information. +func (client IdentityClient) GetTenancy(ctx context.Context, request GetTenancyRequest) (response GetTenancyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/tenancies/{tenancyId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetUser Gets the specified user's information. +func (client IdentityClient) GetUser(ctx context.Context, request GetUserRequest) (response GetUserResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/users/{userId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetUserGroupMembership Gets the specified UserGroupMembership's information. +func (client IdentityClient) GetUserGroupMembership(ctx context.Context, request GetUserGroupMembershipRequest) (response GetUserGroupMembershipResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/userGroupMemberships/{userGroupMembershipId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListApiKeys Lists the API signing keys for the specified user. A user can have a maximum of three keys. +// Every user has permission to use this API call for *their own user ID*. An administrator in your +// organization does not need to write a policy to give users this ability. +func (client IdentityClient) ListApiKeys(ctx context.Context, request ListApiKeysRequest) (response ListApiKeysResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/users/{userId}/apiKeys/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListAvailabilityDomains Lists the Availability Domains in your tenancy. Specify the OCID of either the tenancy or another +// of your compartments as the value for the compartment ID (remember that the tenancy is simply the root compartment). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +func (client IdentityClient) ListAvailabilityDomains(ctx context.Context, request ListAvailabilityDomainsRequest) (response ListAvailabilityDomainsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/availabilityDomains/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCompartments Lists the compartments in your tenancy. You must specify your tenancy's OCID as the value +// for the compartment ID (remember that the tenancy is simply the root compartment). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +func (client IdentityClient) ListCompartments(ctx context.Context, request ListCompartmentsRequest) (response ListCompartmentsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/compartments/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCustomerSecretKeys Lists the secret keys for the specified user. The returned object contains the secret key's OCID, but not +// the secret key itself. The actual secret key is returned only upon creation. +func (client IdentityClient) ListCustomerSecretKeys(ctx context.Context, request ListCustomerSecretKeysRequest) (response ListCustomerSecretKeysResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/users/{userId}/customerSecretKeys/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListFaultDomains Lists the Fault Domains in your tenancy. Specify the OCID of either the tenancy or another +// of your compartments as the value for the compartment ID (remember that the tenancy is simply the root compartment). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +func (client IdentityClient) ListFaultDomains(ctx context.Context, request ListFaultDomainsRequest) (response ListFaultDomainsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/faultDomains/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListGroups Lists the groups in your tenancy. You must specify your tenancy's OCID as the value for +// the compartment ID (remember that the tenancy is simply the root compartment). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +func (client IdentityClient) ListGroups(ctx context.Context, request ListGroupsRequest) (response ListGroupsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/groups/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +//listidentityprovider allows to unmarshal list of polymorphic IdentityProvider +type listidentityprovider []identityprovider + +//UnmarshalPolymorphicJSON unmarshals polymorphic json list of items +func (m *listidentityprovider) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + res := make([]IdentityProvider, len(*m)) + for i, v := range *m { + nn, err := v.UnmarshalPolymorphicJSON(v.JsonData) + if err != nil { + return nil, err + } + res[i] = nn.(IdentityProvider) + } + return res, nil +} + +// ListIdentityProviders Lists all the identity providers in your tenancy. You must specify the identity provider type (e.g., `SAML2` for +// identity providers using the SAML2.0 protocol). You must specify your tenancy's OCID as the value for the +// compartment ID (remember that the tenancy is simply the root compartment). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +func (client IdentityClient) ListIdentityProviders(ctx context.Context, request ListIdentityProvidersRequest) (response ListIdentityProvidersResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/identityProviders/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &listidentityprovider{}) + return +} + +// ListIdpGroupMappings Lists the group mappings for the specified identity provider. +func (client IdentityClient) ListIdpGroupMappings(ctx context.Context, request ListIdpGroupMappingsRequest) (response ListIdpGroupMappingsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/identityProviders/{identityProviderId}/groupMappings/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListPolicies Lists the policies in the specified compartment (either the tenancy or another of your compartments). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +// To determine which policies apply to a particular group or compartment, you must view the individual +// statements inside all your policies. There isn't a way to automatically obtain that information via the API. +func (client IdentityClient) ListPolicies(ctx context.Context, request ListPoliciesRequest) (response ListPoliciesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/policies/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListRegionSubscriptions Lists the region subscriptions for the specified tenancy. +func (client IdentityClient) ListRegionSubscriptions(ctx context.Context, request ListRegionSubscriptionsRequest) (response ListRegionSubscriptionsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/tenancies/{tenancyId}/regionSubscriptions", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListRegions Lists all the regions offered by Oracle Cloud Infrastructure. +func (client IdentityClient) ListRegions(ctx context.Context) (response ListRegionsResponse, err error) { + httpRequest := common.MakeDefaultHTTPRequest(http.MethodGet, "/regions") + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListSwiftPasswords Lists the Swift passwords for the specified user. The returned object contains the password's OCID, but not +// the password itself. The actual password is returned only upon creation. +func (client IdentityClient) ListSwiftPasswords(ctx context.Context, request ListSwiftPasswordsRequest) (response ListSwiftPasswordsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/users/{userId}/swiftPasswords/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListUserGroupMemberships Lists the `UserGroupMembership` objects in your tenancy. You must specify your tenancy's OCID +// as the value for the compartment ID +// (see Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five)). +// You must also then filter the list in one of these ways: +// - You can limit the results to just the memberships for a given user by specifying a `userId`. +// - Similarly, you can limit the results to just the memberships for a given group by specifying a `groupId`. +// - You can set both the `userId` and `groupId` to determine if the specified user is in the specified group. +// If the answer is no, the response is an empty list. +func (client IdentityClient) ListUserGroupMemberships(ctx context.Context, request ListUserGroupMembershipsRequest) (response ListUserGroupMembershipsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/userGroupMemberships/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListUsers Lists the users in your tenancy. You must specify your tenancy's OCID as the value for the +// compartment ID (remember that the tenancy is simply the root compartment). +// See Where to Get the Tenancy's OCID and User's OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm#five). +func (client IdentityClient) ListUsers(ctx context.Context, request ListUsersRequest) (response ListUsersResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/users/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// RemoveUserFromGroup Removes a user from a group by deleting the corresponding `UserGroupMembership`. +func (client IdentityClient) RemoveUserFromGroup(ctx context.Context, request RemoveUserFromGroupRequest) (response RemoveUserFromGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/userGroupMemberships/{userGroupMembershipId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateCompartment Updates the specified compartment's description or name. You can't update the root compartment. +func (client IdentityClient) UpdateCompartment(ctx context.Context, request UpdateCompartmentRequest) (response UpdateCompartmentResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/compartments/{compartmentId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateCustomerSecretKey Updates the specified secret key's description. +func (client IdentityClient) UpdateCustomerSecretKey(ctx context.Context, request UpdateCustomerSecretKeyRequest) (response UpdateCustomerSecretKeyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/users/{userId}/customerSecretKeys/{customerSecretKeyId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateGroup Updates the specified group. +func (client IdentityClient) UpdateGroup(ctx context.Context, request UpdateGroupRequest) (response UpdateGroupResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/groups/{groupId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateIdentityProvider Updates the specified identity provider. +func (client IdentityClient) UpdateIdentityProvider(ctx context.Context, request UpdateIdentityProviderRequest) (response UpdateIdentityProviderResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/identityProviders/{identityProviderId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponseWithPolymorphicBody(httpResponse, &response, &identityprovider{}) + return +} + +// UpdateIdpGroupMapping Updates the specified group mapping. +func (client IdentityClient) UpdateIdpGroupMapping(ctx context.Context, request UpdateIdpGroupMappingRequest) (response UpdateIdpGroupMappingResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/identityProviders/{identityProviderId}/groupMappings/{mappingId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdatePolicy Updates the specified policy. You can update the description or the policy statements themselves. +// Policy changes take effect typically within 10 seconds. +func (client IdentityClient) UpdatePolicy(ctx context.Context, request UpdatePolicyRequest) (response UpdatePolicyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/policies/{policyId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateSwiftPassword Updates the specified Swift password's description. +func (client IdentityClient) UpdateSwiftPassword(ctx context.Context, request UpdateSwiftPasswordRequest) (response UpdateSwiftPasswordResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/users/{userId}/swiftPasswords/{swiftPasswordId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateUser Updates the description of the specified user. +func (client IdentityClient) UpdateUser(ctx context.Context, request UpdateUserRequest) (response UpdateUserResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/users/{userId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateUserState Updates the state of the specified user. +func (client IdentityClient) UpdateUserState(ctx context.Context, request UpdateUserStateRequest) (response UpdateUserStateResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/users/{userId}/state/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UploadApiKey Uploads an API signing key for the specified user. +// Every user has permission to use this operation to upload a key for *their own user ID*. An +// administrator in your organization does not need to write a policy to give users this ability. +// To compare, administrators who have permission to the tenancy can use this operation to upload a +// key for any user, including themselves. +// **Important:** Even though you have permission to upload an API key, you might not yet +// have permission to do much else. If you try calling an operation unrelated to your own credential +// management (e.g., `ListUsers`, `LaunchInstance`) and receive an "unauthorized" error, +// check with an administrator to confirm which IAM Service group(s) you're in and what access +// you have. Also confirm you're working in the correct compartment. +// After you send your request, the new object's `lifecycleState` will temporarily be CREATING. Before using +// the object, first make sure its `lifecycleState` has changed to ACTIVE. +func (client IdentityClient) UploadApiKey(ctx context.Context, request UploadApiKeyRequest) (response UploadApiKeyResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/users/{userId}/apiKeys/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/identity_provider.go b/vendor/github.com/oracle/oci-go-sdk/identity/identity_provider.go new file mode 100644 index 000000000..170df8879 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/identity_provider.go @@ -0,0 +1,185 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// IdentityProvider The resulting base object when you add an identity provider to your tenancy. A +// Saml2IdentityProvider +// is a specific type of `IdentityProvider` that supports the SAML 2.0 protocol. Each +// `IdentityProvider` object has its own OCID. For more information, see +// Identity Providers and Federation (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type IdentityProvider interface { + + // The OCID of the `IdentityProvider`. + GetId() *string + + // The OCID of the tenancy containing the `IdentityProvider`. + GetCompartmentId() *string + + // The name you assign to the `IdentityProvider` during creation. The name + // must be unique across all `IdentityProvider` objects in the tenancy and + // cannot be changed. This is the name federated users see when choosing + // which identity provider to use when signing in to the Oracle Cloud Infrastructure + // Console. + GetName() *string + + // The description you assign to the `IdentityProvider` during creation. Does + // not have to be unique, and it's changeable. + GetDescription() *string + + // The identity provider service or product. + // Supported identity providers are Oracle Identity Cloud Service (IDCS) and Microsoft + // Active Directory Federation Services (ADFS). + // Allowed values are: + // - `ADFS` + // - `IDCS` + // Example: `IDCS` + GetProductType() *string + + // Date and time the `IdentityProvider` was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + GetTimeCreated() *common.SDKTime + + // The current state. After creating an `IdentityProvider`, make sure its + // `lifecycleState` changes from CREATING to ACTIVE before using it. + GetLifecycleState() IdentityProviderLifecycleStateEnum + + // The detailed status of INACTIVE lifecycleState. + GetInactiveStatus() *int +} + +type identityprovider struct { + JsonData []byte + Id *string `mandatory:"true" json:"id"` + CompartmentId *string `mandatory:"true" json:"compartmentId"` + Name *string `mandatory:"true" json:"name"` + Description *string `mandatory:"true" json:"description"` + ProductType *string `mandatory:"true" json:"productType"` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + LifecycleState IdentityProviderLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` + Protocol string `json:"protocol"` +} + +// UnmarshalJSON unmarshals json +func (m *identityprovider) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshaleridentityprovider identityprovider + s := struct { + Model Unmarshaleridentityprovider + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.Id = s.Model.Id + m.CompartmentId = s.Model.CompartmentId + m.Name = s.Model.Name + m.Description = s.Model.Description + m.ProductType = s.Model.ProductType + m.TimeCreated = s.Model.TimeCreated + m.LifecycleState = s.Model.LifecycleState + m.InactiveStatus = s.Model.InactiveStatus + m.Protocol = s.Model.Protocol + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *identityprovider) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Protocol { + case "SAML2": + mm := Saml2IdentityProvider{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetId returns Id +func (m identityprovider) GetId() *string { + return m.Id +} + +//GetCompartmentId returns CompartmentId +func (m identityprovider) GetCompartmentId() *string { + return m.CompartmentId +} + +//GetName returns Name +func (m identityprovider) GetName() *string { + return m.Name +} + +//GetDescription returns Description +func (m identityprovider) GetDescription() *string { + return m.Description +} + +//GetProductType returns ProductType +func (m identityprovider) GetProductType() *string { + return m.ProductType +} + +//GetTimeCreated returns TimeCreated +func (m identityprovider) GetTimeCreated() *common.SDKTime { + return m.TimeCreated +} + +//GetLifecycleState returns LifecycleState +func (m identityprovider) GetLifecycleState() IdentityProviderLifecycleStateEnum { + return m.LifecycleState +} + +//GetInactiveStatus returns InactiveStatus +func (m identityprovider) GetInactiveStatus() *int { + return m.InactiveStatus +} + +func (m identityprovider) String() string { + return common.PointerString(m) +} + +// IdentityProviderLifecycleStateEnum Enum with underlying type: string +type IdentityProviderLifecycleStateEnum string + +// Set of constants representing the allowable values for IdentityProviderLifecycleState +const ( + IdentityProviderLifecycleStateCreating IdentityProviderLifecycleStateEnum = "CREATING" + IdentityProviderLifecycleStateActive IdentityProviderLifecycleStateEnum = "ACTIVE" + IdentityProviderLifecycleStateInactive IdentityProviderLifecycleStateEnum = "INACTIVE" + IdentityProviderLifecycleStateDeleting IdentityProviderLifecycleStateEnum = "DELETING" + IdentityProviderLifecycleStateDeleted IdentityProviderLifecycleStateEnum = "DELETED" +) + +var mappingIdentityProviderLifecycleState = map[string]IdentityProviderLifecycleStateEnum{ + "CREATING": IdentityProviderLifecycleStateCreating, + "ACTIVE": IdentityProviderLifecycleStateActive, + "INACTIVE": IdentityProviderLifecycleStateInactive, + "DELETING": IdentityProviderLifecycleStateDeleting, + "DELETED": IdentityProviderLifecycleStateDeleted, +} + +// GetIdentityProviderLifecycleStateEnumValues Enumerates the set of values for IdentityProviderLifecycleState +func GetIdentityProviderLifecycleStateEnumValues() []IdentityProviderLifecycleStateEnum { + values := make([]IdentityProviderLifecycleStateEnum, 0) + for _, v := range mappingIdentityProviderLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/idp_group_mapping.go b/vendor/github.com/oracle/oci-go-sdk/identity/idp_group_mapping.go new file mode 100644 index 000000000..cf9c0100b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/idp_group_mapping.go @@ -0,0 +1,84 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IdpGroupMapping A mapping between a single group defined by the identity provider (IdP) you're federating with +// and a single IAM Service Group in Oracle Cloud Infrastructure. +// For more information about group mappings and what they're for, see +// Identity Providers and Federation (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm). +// A given IdP group can be mapped to zero, one, or multiple IAM Service groups, and vice versa. +// But each `IdPGroupMapping` object is between only a single IdP group and IAM Service group. +// Each `IdPGroupMapping` object has its own OCID. +// **Note:** Any users who are in more than 50 IdP groups cannot be authenticated to use the Oracle +// Cloud Infrastructure Console. +type IdpGroupMapping struct { + + // The OCID of the `IdpGroupMapping`. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the `IdentityProvider` this mapping belongs to. + IdpId *string `mandatory:"true" json:"idpId"` + + // The name of the IdP group that is mapped to the IAM Service group. + IdpGroupName *string `mandatory:"true" json:"idpGroupName"` + + // The OCID of the IAM Service group that is mapped to the IdP group. + GroupId *string `mandatory:"true" json:"groupId"` + + // The OCID of the tenancy containing the `IdentityProvider`. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Date and time the mapping was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The mapping's current state. After creating a mapping object, make sure its `lifecycleState` changes + // from CREATING to ACTIVE before using it. + LifecycleState IdpGroupMappingLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m IdpGroupMapping) String() string { + return common.PointerString(m) +} + +// IdpGroupMappingLifecycleStateEnum Enum with underlying type: string +type IdpGroupMappingLifecycleStateEnum string + +// Set of constants representing the allowable values for IdpGroupMappingLifecycleState +const ( + IdpGroupMappingLifecycleStateCreating IdpGroupMappingLifecycleStateEnum = "CREATING" + IdpGroupMappingLifecycleStateActive IdpGroupMappingLifecycleStateEnum = "ACTIVE" + IdpGroupMappingLifecycleStateInactive IdpGroupMappingLifecycleStateEnum = "INACTIVE" + IdpGroupMappingLifecycleStateDeleting IdpGroupMappingLifecycleStateEnum = "DELETING" + IdpGroupMappingLifecycleStateDeleted IdpGroupMappingLifecycleStateEnum = "DELETED" +) + +var mappingIdpGroupMappingLifecycleState = map[string]IdpGroupMappingLifecycleStateEnum{ + "CREATING": IdpGroupMappingLifecycleStateCreating, + "ACTIVE": IdpGroupMappingLifecycleStateActive, + "INACTIVE": IdpGroupMappingLifecycleStateInactive, + "DELETING": IdpGroupMappingLifecycleStateDeleting, + "DELETED": IdpGroupMappingLifecycleStateDeleted, +} + +// GetIdpGroupMappingLifecycleStateEnumValues Enumerates the set of values for IdpGroupMappingLifecycleState +func GetIdpGroupMappingLifecycleStateEnumValues() []IdpGroupMappingLifecycleStateEnum { + values := make([]IdpGroupMappingLifecycleStateEnum, 0) + for _, v := range mappingIdpGroupMappingLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_api_keys_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_api_keys_request_response.go new file mode 100644 index 000000000..62ce550f5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_api_keys_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListApiKeysRequest wrapper for the ListApiKeys operation +type ListApiKeysRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` +} + +func (request ListApiKeysRequest) String() string { + return common.PointerString(request) +} + +// ListApiKeysResponse wrapper for the ListApiKeys operation +type ListApiKeysResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []ApiKey instance + Items []ApiKey `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListApiKeysResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_availability_domains_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_availability_domains_request_response.go new file mode 100644 index 000000000..407c2a36a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_availability_domains_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListAvailabilityDomainsRequest wrapper for the ListAvailabilityDomains operation +type ListAvailabilityDomainsRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` +} + +func (request ListAvailabilityDomainsRequest) String() string { + return common.PointerString(request) +} + +// ListAvailabilityDomainsResponse wrapper for the ListAvailabilityDomains operation +type ListAvailabilityDomainsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []AvailabilityDomain instance + Items []AvailabilityDomain `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListAvailabilityDomainsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_compartments_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_compartments_request_response.go new file mode 100644 index 000000000..6d4338d3d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_compartments_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCompartmentsRequest wrapper for the ListCompartments operation +type ListCompartmentsRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListCompartmentsRequest) String() string { + return common.PointerString(request) +} + +// ListCompartmentsResponse wrapper for the ListCompartments operation +type ListCompartmentsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Compartment instance + Items []Compartment `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListCompartmentsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_customer_secret_keys_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_customer_secret_keys_request_response.go new file mode 100644 index 000000000..a1de6bb33 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_customer_secret_keys_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCustomerSecretKeysRequest wrapper for the ListCustomerSecretKeys operation +type ListCustomerSecretKeysRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` +} + +func (request ListCustomerSecretKeysRequest) String() string { + return common.PointerString(request) +} + +// ListCustomerSecretKeysResponse wrapper for the ListCustomerSecretKeys operation +type ListCustomerSecretKeysResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []CustomerSecretKeySummary instance + Items []CustomerSecretKeySummary `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListCustomerSecretKeysResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_fault_domains_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_fault_domains_request_response.go new file mode 100644 index 000000000..58e8cf4ed --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_fault_domains_request_response.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListFaultDomainsRequest wrapper for the ListFaultDomains operation +type ListFaultDomainsRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The name of the availibilityDomain. + AvailabilityDomain *string `mandatory:"true" contributesTo:"query" name:"availabilityDomain"` +} + +func (request ListFaultDomainsRequest) String() string { + return common.PointerString(request) +} + +// ListFaultDomainsResponse wrapper for the ListFaultDomains operation +type ListFaultDomainsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []FaultDomain instance + Items []FaultDomain `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListFaultDomainsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_groups_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_groups_request_response.go new file mode 100644 index 000000000..b466a566f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_groups_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListGroupsRequest wrapper for the ListGroups operation +type ListGroupsRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListGroupsRequest) String() string { + return common.PointerString(request) +} + +// ListGroupsResponse wrapper for the ListGroups operation +type ListGroupsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Group instance + Items []Group `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListGroupsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_identity_providers_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_identity_providers_request_response.go new file mode 100644 index 000000000..abebf6877 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_identity_providers_request_response.go @@ -0,0 +1,73 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListIdentityProvidersRequest wrapper for the ListIdentityProviders operation +type ListIdentityProvidersRequest struct { + + // The protocol used for federation. + Protocol ListIdentityProvidersProtocolEnum `mandatory:"true" contributesTo:"query" name:"protocol" omitEmpty:"true"` + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListIdentityProvidersRequest) String() string { + return common.PointerString(request) +} + +// ListIdentityProvidersResponse wrapper for the ListIdentityProviders operation +type ListIdentityProvidersResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []IdentityProvider instance + Items []IdentityProvider `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListIdentityProvidersResponse) String() string { + return common.PointerString(response) +} + +// ListIdentityProvidersProtocolEnum Enum with underlying type: string +type ListIdentityProvidersProtocolEnum string + +// Set of constants representing the allowable values for ListIdentityProvidersProtocol +const ( + ListIdentityProvidersProtocolSaml2 ListIdentityProvidersProtocolEnum = "SAML2" +) + +var mappingListIdentityProvidersProtocol = map[string]ListIdentityProvidersProtocolEnum{ + "SAML2": ListIdentityProvidersProtocolSaml2, +} + +// GetListIdentityProvidersProtocolEnumValues Enumerates the set of values for ListIdentityProvidersProtocol +func GetListIdentityProvidersProtocolEnumValues() []ListIdentityProvidersProtocolEnum { + values := make([]ListIdentityProvidersProtocolEnum, 0) + for _, v := range mappingListIdentityProvidersProtocol { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_idp_group_mappings_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_idp_group_mappings_request_response.go new file mode 100644 index 000000000..09323f659 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_idp_group_mappings_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListIdpGroupMappingsRequest wrapper for the ListIdpGroupMappings operation +type ListIdpGroupMappingsRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListIdpGroupMappingsRequest) String() string { + return common.PointerString(request) +} + +// ListIdpGroupMappingsResponse wrapper for the ListIdpGroupMappings operation +type ListIdpGroupMappingsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []IdpGroupMapping instance + Items []IdpGroupMapping `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListIdpGroupMappingsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_policies_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_policies_request_response.go new file mode 100644 index 000000000..6b6461d28 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_policies_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListPoliciesRequest wrapper for the ListPolicies operation +type ListPoliciesRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListPoliciesRequest) String() string { + return common.PointerString(request) +} + +// ListPoliciesResponse wrapper for the ListPolicies operation +type ListPoliciesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Policy instance + Items []Policy `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListPoliciesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_region_subscriptions_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_region_subscriptions_request_response.go new file mode 100644 index 000000000..a10917633 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_region_subscriptions_request_response.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListRegionSubscriptionsRequest wrapper for the ListRegionSubscriptions operation +type ListRegionSubscriptionsRequest struct { + + // The OCID of the tenancy. + TenancyId *string `mandatory:"true" contributesTo:"path" name:"tenancyId"` +} + +func (request ListRegionSubscriptionsRequest) String() string { + return common.PointerString(request) +} + +// ListRegionSubscriptionsResponse wrapper for the ListRegionSubscriptions operation +type ListRegionSubscriptionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []RegionSubscription instance + Items []RegionSubscription `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListRegionSubscriptionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_regions_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_regions_request_response.go new file mode 100644 index 000000000..528b6b863 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_regions_request_response.go @@ -0,0 +1,35 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListRegionsRequest wrapper for the ListRegions operation +type ListRegionsRequest struct { +} + +func (request ListRegionsRequest) String() string { + return common.PointerString(request) +} + +// ListRegionsResponse wrapper for the ListRegions operation +type ListRegionsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Region instance + Items []Region `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListRegionsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_swift_passwords_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_swift_passwords_request_response.go new file mode 100644 index 000000000..86d737c0f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_swift_passwords_request_response.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListSwiftPasswordsRequest wrapper for the ListSwiftPasswords operation +type ListSwiftPasswordsRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` +} + +func (request ListSwiftPasswordsRequest) String() string { + return common.PointerString(request) +} + +// ListSwiftPasswordsResponse wrapper for the ListSwiftPasswords operation +type ListSwiftPasswordsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []SwiftPassword instance + Items []SwiftPassword `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListSwiftPasswordsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_user_group_memberships_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_user_group_memberships_request_response.go new file mode 100644 index 000000000..3f6d406b8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_user_group_memberships_request_response.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListUserGroupMembershipsRequest wrapper for the ListUserGroupMemberships operation +type ListUserGroupMembershipsRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The OCID of the user. + UserId *string `mandatory:"false" contributesTo:"query" name:"userId"` + + // The OCID of the group. + GroupId *string `mandatory:"false" contributesTo:"query" name:"groupId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListUserGroupMembershipsRequest) String() string { + return common.PointerString(request) +} + +// ListUserGroupMembershipsResponse wrapper for the ListUserGroupMemberships operation +type ListUserGroupMembershipsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []UserGroupMembership instance + Items []UserGroupMembership `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListUserGroupMembershipsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/list_users_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/list_users_request_response.go new file mode 100644 index 000000000..905d7e8c5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/list_users_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListUsersRequest wrapper for the ListUsers operation +type ListUsersRequest struct { + + // The OCID of the compartment (remember that the tenancy is simply the root compartment). + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The value of the `opc-next-page` response header from the previous "List" call. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The maximum number of items to return in a paginated "List" call. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` +} + +func (request ListUsersRequest) String() string { + return common.PointerString(request) +} + +// ListUsersResponse wrapper for the ListUsers operation +type ListUsersResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []User instance + Items []User `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListUsersResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/policy.go b/vendor/github.com/oracle/oci-go-sdk/identity/policy.go new file mode 100644 index 000000000..39eacc77a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/policy.go @@ -0,0 +1,91 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Policy A document that specifies the type of access a group has to the resources in a compartment. For information about +// policies and other IAM Service components, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). If you're new to policies, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// The word "policy" is used by people in different ways: +// * An individual statement written in the policy language +// * A collection of statements in a single, named "policy" document (which has an Oracle Cloud ID (OCID) assigned to it) +// * The overall body of policies your organization uses to control access to resources +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. +type Policy struct { + + // The OCID of the policy. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the compartment containing the policy (either the tenancy or another compartment). + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the policy during creation. The name must be unique across all policies + // in the tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // An array of one or more policy statements written in the policy language. + Statements []string `mandatory:"true" json:"statements"` + + // The description you assign to the policy. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // Date and time the policy was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The policy's current state. After creating a policy, make sure its `lifecycleState` changes from CREATING to + // ACTIVE before using it. + LifecycleState PolicyLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` + + // The version of the policy. If null or set to an empty string, when a request comes in for authorization, the + // policy will be evaluated according to the current behavior of the services at that moment. If set to a particular + // date (YYYY-MM-DD), the policy will be evaluated according to the behavior of the services on that date. + VersionDate *common.SDKTime `mandatory:"false" json:"versionDate"` +} + +func (m Policy) String() string { + return common.PointerString(m) +} + +// PolicyLifecycleStateEnum Enum with underlying type: string +type PolicyLifecycleStateEnum string + +// Set of constants representing the allowable values for PolicyLifecycleState +const ( + PolicyLifecycleStateCreating PolicyLifecycleStateEnum = "CREATING" + PolicyLifecycleStateActive PolicyLifecycleStateEnum = "ACTIVE" + PolicyLifecycleStateInactive PolicyLifecycleStateEnum = "INACTIVE" + PolicyLifecycleStateDeleting PolicyLifecycleStateEnum = "DELETING" + PolicyLifecycleStateDeleted PolicyLifecycleStateEnum = "DELETED" +) + +var mappingPolicyLifecycleState = map[string]PolicyLifecycleStateEnum{ + "CREATING": PolicyLifecycleStateCreating, + "ACTIVE": PolicyLifecycleStateActive, + "INACTIVE": PolicyLifecycleStateInactive, + "DELETING": PolicyLifecycleStateDeleting, + "DELETED": PolicyLifecycleStateDeleted, +} + +// GetPolicyLifecycleStateEnumValues Enumerates the set of values for PolicyLifecycleState +func GetPolicyLifecycleStateEnumValues() []PolicyLifecycleStateEnum { + values := make([]PolicyLifecycleStateEnum, 0) + for _, v := range mappingPolicyLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/region.go b/vendor/github.com/oracle/oci-go-sdk/identity/region.go new file mode 100644 index 000000000..ba73a4453 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/region.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Region A localized geographic area, such as Phoenix, AZ. Oracle Cloud Infrastructure is hosted in regions and Availability +// Domains. A region is composed of several Availability Domains. An Availability Domain is one or more data centers +// located within a region. For more information, see Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Region struct { + + // The key of the region. + // Allowed values are: + // - `PHX` + // - `IAD` + // - `FRA` + Key *string `mandatory:"false" json:"key"` + + // The name of the region. + // Allowed values are: + // - `us-phoenix-1` + // - `us-ashburn-1` + // - `eu-frankfurt-1` + Name *string `mandatory:"false" json:"name"` +} + +func (m Region) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/region_subscription.go b/vendor/github.com/oracle/oci-go-sdk/identity/region_subscription.go new file mode 100644 index 000000000..dfa9f26b6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/region_subscription.go @@ -0,0 +1,68 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// RegionSubscription An object that represents your tenancy's access to a particular region (i.e., a subscription), the status of that +// access, and whether that region is the home region. For more information, see Managing Regions (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Tasks/managingregions.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type RegionSubscription struct { + + // The region's key. + // Allowed values are: + // - `PHX` + // - `IAD` + // - `FRA` + RegionKey *string `mandatory:"true" json:"regionKey"` + + // The region's name. + // Allowed values are: + // - `us-phoenix-1` + // - `us-ashburn-1` + // - `eu-frankurt-1` + RegionName *string `mandatory:"true" json:"regionName"` + + // The region subscription status. + Status RegionSubscriptionStatusEnum `mandatory:"true" json:"status"` + + // Indicates if the region is the home region or not. + IsHomeRegion *bool `mandatory:"true" json:"isHomeRegion"` +} + +func (m RegionSubscription) String() string { + return common.PointerString(m) +} + +// RegionSubscriptionStatusEnum Enum with underlying type: string +type RegionSubscriptionStatusEnum string + +// Set of constants representing the allowable values for RegionSubscriptionStatus +const ( + RegionSubscriptionStatusReady RegionSubscriptionStatusEnum = "READY" + RegionSubscriptionStatusInProgress RegionSubscriptionStatusEnum = "IN_PROGRESS" +) + +var mappingRegionSubscriptionStatus = map[string]RegionSubscriptionStatusEnum{ + "READY": RegionSubscriptionStatusReady, + "IN_PROGRESS": RegionSubscriptionStatusInProgress, +} + +// GetRegionSubscriptionStatusEnumValues Enumerates the set of values for RegionSubscriptionStatus +func GetRegionSubscriptionStatusEnumValues() []RegionSubscriptionStatusEnum { + values := make([]RegionSubscriptionStatusEnum, 0) + for _, v := range mappingRegionSubscriptionStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/remove_user_from_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/remove_user_from_group_request_response.go new file mode 100644 index 000000000..afed269d0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/remove_user_from_group_request_response.go @@ -0,0 +1,40 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// RemoveUserFromGroupRequest wrapper for the RemoveUserFromGroup operation +type RemoveUserFromGroupRequest struct { + + // The OCID of the userGroupMembership. + UserGroupMembershipId *string `mandatory:"true" contributesTo:"path" name:"userGroupMembershipId"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request RemoveUserFromGroupRequest) String() string { + return common.PointerString(request) +} + +// RemoveUserFromGroupResponse wrapper for the RemoveUserFromGroup operation +type RemoveUserFromGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response RemoveUserFromGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/saml2_identity_provider.go b/vendor/github.com/oracle/oci-go-sdk/identity/saml2_identity_provider.go new file mode 100644 index 000000000..0ef2511b3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/saml2_identity_provider.go @@ -0,0 +1,127 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// Saml2IdentityProvider A special type of IdentityProvider that +// supports the SAML 2.0 protocol. For more information, see +// Identity Providers and Federation (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm). +type Saml2IdentityProvider struct { + + // The OCID of the `IdentityProvider`. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the tenancy containing the `IdentityProvider`. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the `IdentityProvider` during creation. The name + // must be unique across all `IdentityProvider` objects in the tenancy and + // cannot be changed. This is the name federated users see when choosing + // which identity provider to use when signing in to the Oracle Cloud Infrastructure + // Console. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the `IdentityProvider` during creation. Does + // not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // The identity provider service or product. + // Supported identity providers are Oracle Identity Cloud Service (IDCS) and Microsoft + // Active Directory Federation Services (ADFS). + // Allowed values are: + // - `ADFS` + // - `IDCS` + // Example: `IDCS` + ProductType *string `mandatory:"true" json:"productType"` + + // Date and time the `IdentityProvider` was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The URL for retrieving the identity provider's metadata, which + // contains information required for federating. + MetadataUrl *string `mandatory:"true" json:"metadataUrl"` + + // The identity provider's signing certificate used by the IAM Service + // to validate the SAML2 token. + SigningCertificate *string `mandatory:"true" json:"signingCertificate"` + + // The URL to redirect federated users to for authentication with the + // identity provider. + RedirectUrl *string `mandatory:"true" json:"redirectUrl"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` + + // The current state. After creating an `IdentityProvider`, make sure its + // `lifecycleState` changes from CREATING to ACTIVE before using it. + LifecycleState IdentityProviderLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` +} + +//GetId returns Id +func (m Saml2IdentityProvider) GetId() *string { + return m.Id +} + +//GetCompartmentId returns CompartmentId +func (m Saml2IdentityProvider) GetCompartmentId() *string { + return m.CompartmentId +} + +//GetName returns Name +func (m Saml2IdentityProvider) GetName() *string { + return m.Name +} + +//GetDescription returns Description +func (m Saml2IdentityProvider) GetDescription() *string { + return m.Description +} + +//GetProductType returns ProductType +func (m Saml2IdentityProvider) GetProductType() *string { + return m.ProductType +} + +//GetTimeCreated returns TimeCreated +func (m Saml2IdentityProvider) GetTimeCreated() *common.SDKTime { + return m.TimeCreated +} + +//GetLifecycleState returns LifecycleState +func (m Saml2IdentityProvider) GetLifecycleState() IdentityProviderLifecycleStateEnum { + return m.LifecycleState +} + +//GetInactiveStatus returns InactiveStatus +func (m Saml2IdentityProvider) GetInactiveStatus() *int { + return m.InactiveStatus +} + +func (m Saml2IdentityProvider) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m Saml2IdentityProvider) MarshalJSON() (buff []byte, e error) { + type MarshalTypeSaml2IdentityProvider Saml2IdentityProvider + s := struct { + DiscriminatorParam string `json:"protocol"` + MarshalTypeSaml2IdentityProvider + }{ + "SAML2", + (MarshalTypeSaml2IdentityProvider)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/swift_password.go b/vendor/github.com/oracle/oci-go-sdk/identity/swift_password.go new file mode 100644 index 000000000..89a37c63c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/swift_password.go @@ -0,0 +1,83 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// SwiftPassword Swift is the OpenStack object storage service. A `SwiftPassword` is an Oracle-provided password for using a +// Swift client with the Oracle Cloud Infrastructure Object Storage Service. This password is associated with +// the user's Console login. Swift passwords never expire. A user can have up to two Swift passwords at a time. +// **Note:** The password is always an Oracle-generated string; you can't change it to a string of your choice. +// For more information, see Managing User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Tasks/managingcredentials.htm). +type SwiftPassword struct { + + // The Swift password. The value is available only in the response for `CreateSwiftPassword`, and not + // for `ListSwiftPasswords` or `UpdateSwiftPassword`. + Password *string `mandatory:"false" json:"password"` + + // The OCID of the Swift password. + Id *string `mandatory:"false" json:"id"` + + // The OCID of the user the password belongs to. + UserId *string `mandatory:"false" json:"userId"` + + // The description you assign to the Swift password. Does not have to be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` + + // Date and time the `SwiftPassword` object was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // Date and time when this password will expire, in the format defined by RFC3339. + // Null if it never expires. + // Example: `2016-08-25T21:10:29.600Z` + ExpiresOn *common.SDKTime `mandatory:"false" json:"expiresOn"` + + // The password's current state. After creating a password, make sure its `lifecycleState` changes from + // CREATING to ACTIVE before using it. + LifecycleState SwiftPasswordLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m SwiftPassword) String() string { + return common.PointerString(m) +} + +// SwiftPasswordLifecycleStateEnum Enum with underlying type: string +type SwiftPasswordLifecycleStateEnum string + +// Set of constants representing the allowable values for SwiftPasswordLifecycleState +const ( + SwiftPasswordLifecycleStateCreating SwiftPasswordLifecycleStateEnum = "CREATING" + SwiftPasswordLifecycleStateActive SwiftPasswordLifecycleStateEnum = "ACTIVE" + SwiftPasswordLifecycleStateInactive SwiftPasswordLifecycleStateEnum = "INACTIVE" + SwiftPasswordLifecycleStateDeleting SwiftPasswordLifecycleStateEnum = "DELETING" + SwiftPasswordLifecycleStateDeleted SwiftPasswordLifecycleStateEnum = "DELETED" +) + +var mappingSwiftPasswordLifecycleState = map[string]SwiftPasswordLifecycleStateEnum{ + "CREATING": SwiftPasswordLifecycleStateCreating, + "ACTIVE": SwiftPasswordLifecycleStateActive, + "INACTIVE": SwiftPasswordLifecycleStateInactive, + "DELETING": SwiftPasswordLifecycleStateDeleting, + "DELETED": SwiftPasswordLifecycleStateDeleted, +} + +// GetSwiftPasswordLifecycleStateEnumValues Enumerates the set of values for SwiftPasswordLifecycleState +func GetSwiftPasswordLifecycleStateEnumValues() []SwiftPasswordLifecycleStateEnum { + values := make([]SwiftPasswordLifecycleStateEnum, 0) + for _, v := range mappingSwiftPasswordLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/tenancy.go b/vendor/github.com/oracle/oci-go-sdk/identity/tenancy.go new file mode 100644 index 000000000..676b91b9a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/tenancy.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Tenancy The root compartment that contains all of your organization's compartments and other +// Oracle Cloud Infrastructure cloud resources. When you sign up for Oracle Cloud Infrastructure, +// Oracle creates a tenancy for your company, which is a secure and isolated partition +// where you can create, organize, and administer your cloud resources. +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Tenancy struct { + + // The OCID of the tenancy. + Id *string `mandatory:"false" json:"id"` + + // The name of the tenancy. + Name *string `mandatory:"false" json:"name"` + + // The description of the tenancy. + Description *string `mandatory:"false" json:"description"` + + // The region key for the tenancy's home region. + // Allowed values are: + // - `IAD` + // - `PHX` + // - `FRA` + HomeRegionKey *string `mandatory:"false" json:"homeRegionKey"` +} + +func (m Tenancy) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/ui_password.go b/vendor/github.com/oracle/oci-go-sdk/identity/ui_password.go new file mode 100644 index 000000000..d0ff89997 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/ui_password.go @@ -0,0 +1,69 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UiPassword A text password that enables a user to sign in to the Console, the user interface for interacting with Oracle +// Cloud Infrastructure. +// For more information about user credentials, see User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/usercredentials.htm). +type UiPassword struct { + + // The user's password for the Console. + Password *string `mandatory:"false" json:"password"` + + // The OCID of the user. + UserId *string `mandatory:"false" json:"userId"` + + // Date and time the password was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` + + // The password's current state. After creating a password, make sure its `lifecycleState` changes from + // CREATING to ACTIVE before using it. + LifecycleState UiPasswordLifecycleStateEnum `mandatory:"false" json:"lifecycleState,omitempty"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m UiPassword) String() string { + return common.PointerString(m) +} + +// UiPasswordLifecycleStateEnum Enum with underlying type: string +type UiPasswordLifecycleStateEnum string + +// Set of constants representing the allowable values for UiPasswordLifecycleState +const ( + UiPasswordLifecycleStateCreating UiPasswordLifecycleStateEnum = "CREATING" + UiPasswordLifecycleStateActive UiPasswordLifecycleStateEnum = "ACTIVE" + UiPasswordLifecycleStateInactive UiPasswordLifecycleStateEnum = "INACTIVE" + UiPasswordLifecycleStateDeleting UiPasswordLifecycleStateEnum = "DELETING" + UiPasswordLifecycleStateDeleted UiPasswordLifecycleStateEnum = "DELETED" +) + +var mappingUiPasswordLifecycleState = map[string]UiPasswordLifecycleStateEnum{ + "CREATING": UiPasswordLifecycleStateCreating, + "ACTIVE": UiPasswordLifecycleStateActive, + "INACTIVE": UiPasswordLifecycleStateInactive, + "DELETING": UiPasswordLifecycleStateDeleting, + "DELETED": UiPasswordLifecycleStateDeleted, +} + +// GetUiPasswordLifecycleStateEnumValues Enumerates the set of values for UiPasswordLifecycleState +func GetUiPasswordLifecycleStateEnumValues() []UiPasswordLifecycleStateEnum { + values := make([]UiPasswordLifecycleStateEnum, 0) + for _, v := range mappingUiPasswordLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_details.go new file mode 100644 index 000000000..0e064808c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_details.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateCompartmentDetails The representation of UpdateCompartmentDetails +type UpdateCompartmentDetails struct { + + // The description you assign to the compartment. Does not have to be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` + + // The new name you assign to the compartment. The name must be unique across all compartments in the tenancy. + Name *string `mandatory:"false" json:"name"` +} + +func (m UpdateCompartmentDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_request_response.go new file mode 100644 index 000000000..217bc6877 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_compartment_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateCompartmentRequest wrapper for the UpdateCompartment operation +type UpdateCompartmentRequest struct { + + // The OCID of the compartment. + CompartmentId *string `mandatory:"true" contributesTo:"path" name:"compartmentId"` + + // Request object for updating a compartment. + UpdateCompartmentDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateCompartmentRequest) String() string { + return common.PointerString(request) +} + +// UpdateCompartmentResponse wrapper for the UpdateCompartment operation +type UpdateCompartmentResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Compartment instance + Compartment `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateCompartmentResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_details.go new file mode 100644 index 000000000..397e18396 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateCustomerSecretKeyDetails The representation of UpdateCustomerSecretKeyDetails +type UpdateCustomerSecretKeyDetails struct { + + // The description you assign to the secret key. Does not have to be unique, and it's changeable. + DisplayName *string `mandatory:"false" json:"displayName"` +} + +func (m UpdateCustomerSecretKeyDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_request_response.go new file mode 100644 index 000000000..e722571e7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_customer_secret_key_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateCustomerSecretKeyRequest wrapper for the UpdateCustomerSecretKey operation +type UpdateCustomerSecretKeyRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // The OCID of the secret key. + CustomerSecretKeyId *string `mandatory:"true" contributesTo:"path" name:"customerSecretKeyId"` + + // Request object for updating a secret key. + UpdateCustomerSecretKeyDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateCustomerSecretKeyRequest) String() string { + return common.PointerString(request) +} + +// UpdateCustomerSecretKeyResponse wrapper for the UpdateCustomerSecretKey operation +type UpdateCustomerSecretKeyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The CustomerSecretKeySummary instance + CustomerSecretKeySummary `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateCustomerSecretKeyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_group_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_group_details.go new file mode 100644 index 000000000..35a082a90 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_group_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateGroupDetails The representation of UpdateGroupDetails +type UpdateGroupDetails struct { + + // The description you assign to the group. Does not have to be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` +} + +func (m UpdateGroupDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_group_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_group_request_response.go new file mode 100644 index 000000000..75840e1c0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_group_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateGroupRequest wrapper for the UpdateGroup operation +type UpdateGroupRequest struct { + + // The OCID of the group. + GroupId *string `mandatory:"true" contributesTo:"path" name:"groupId"` + + // Request object for updating a group. + UpdateGroupDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateGroupRequest) String() string { + return common.PointerString(request) +} + +// UpdateGroupResponse wrapper for the UpdateGroup operation +type UpdateGroupResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Group instance + Group `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateGroupResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_details.go new file mode 100644 index 000000000..976c40edf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_details.go @@ -0,0 +1,67 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateIdentityProviderDetails The representation of UpdateIdentityProviderDetails +type UpdateIdentityProviderDetails interface { + + // The description you assign to the `IdentityProvider`. Does not have to + // be unique, and it's changeable. + GetDescription() *string +} + +type updateidentityproviderdetails struct { + JsonData []byte + Description *string `mandatory:"false" json:"description"` + Protocol string `json:"protocol"` +} + +// UnmarshalJSON unmarshals json +func (m *updateidentityproviderdetails) UnmarshalJSON(data []byte) error { + m.JsonData = data + type Unmarshalerupdateidentityproviderdetails updateidentityproviderdetails + s := struct { + Model Unmarshalerupdateidentityproviderdetails + }{} + err := json.Unmarshal(data, &s.Model) + if err != nil { + return err + } + m.Description = s.Model.Description + m.Protocol = s.Model.Protocol + + return err +} + +// UnmarshalPolymorphicJSON unmarshals polymorphic json +func (m *updateidentityproviderdetails) UnmarshalPolymorphicJSON(data []byte) (interface{}, error) { + var err error + switch m.Protocol { + case "SAML2": + mm := UpdateSaml2IdentityProviderDetails{} + err = json.Unmarshal(data, &mm) + return mm, err + default: + return m, nil + } +} + +//GetDescription returns Description +func (m updateidentityproviderdetails) GetDescription() *string { + return m.Description +} + +func (m updateidentityproviderdetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_request_response.go new file mode 100644 index 000000000..e092b59f4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_identity_provider_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateIdentityProviderRequest wrapper for the UpdateIdentityProvider operation +type UpdateIdentityProviderRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // Request object for updating a identity provider. + UpdateIdentityProviderDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateIdentityProviderRequest) String() string { + return common.PointerString(request) +} + +// UpdateIdentityProviderResponse wrapper for the UpdateIdentityProvider operation +type UpdateIdentityProviderResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IdentityProvider instance + IdentityProvider `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateIdentityProviderResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_details.go new file mode 100644 index 000000000..bf7716f61 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_details.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateIdpGroupMappingDetails The representation of UpdateIdpGroupMappingDetails +type UpdateIdpGroupMappingDetails struct { + + // The idp group name. + IdpGroupName *string `mandatory:"false" json:"idpGroupName"` + + // The OCID of the group. + GroupId *string `mandatory:"false" json:"groupId"` +} + +func (m UpdateIdpGroupMappingDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_request_response.go new file mode 100644 index 000000000..be9dbd3df --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_idp_group_mapping_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateIdpGroupMappingRequest wrapper for the UpdateIdpGroupMapping operation +type UpdateIdpGroupMappingRequest struct { + + // The OCID of the identity provider. + IdentityProviderId *string `mandatory:"true" contributesTo:"path" name:"identityProviderId"` + + // The OCID of the group mapping. + MappingId *string `mandatory:"true" contributesTo:"path" name:"mappingId"` + + // Request object for updating an identity provider group mapping + UpdateIdpGroupMappingDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateIdpGroupMappingRequest) String() string { + return common.PointerString(request) +} + +// UpdateIdpGroupMappingResponse wrapper for the UpdateIdpGroupMapping operation +type UpdateIdpGroupMappingResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The IdpGroupMapping instance + IdpGroupMapping `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateIdpGroupMappingResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_policy_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_policy_details.go new file mode 100644 index 000000000..3fd45b64e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_policy_details.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdatePolicyDetails The representation of UpdatePolicyDetails +type UpdatePolicyDetails struct { + + // The description you assign to the policy. Does not have to be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` + + // An array of policy statements written in the policy language. See + // How Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policies.htm) and + // Common Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/commonpolicies.htm). + Statements []string `mandatory:"false" json:"statements"` + + // The version of the policy. If null or set to an empty string, when a request comes in for authorization, the + // policy will be evaluated according to the current behavior of the services at that moment. If set to a particular + // date (YYYY-MM-DD), the policy will be evaluated according to the behavior of the services on that date. + VersionDate *common.SDKTime `mandatory:"false" json:"versionDate"` +} + +func (m UpdatePolicyDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_policy_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_policy_request_response.go new file mode 100644 index 000000000..198afbecd --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_policy_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdatePolicyRequest wrapper for the UpdatePolicy operation +type UpdatePolicyRequest struct { + + // The OCID of the policy. + PolicyId *string `mandatory:"true" contributesTo:"path" name:"policyId"` + + // Request object for updating a policy. + UpdatePolicyDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdatePolicyRequest) String() string { + return common.PointerString(request) +} + +// UpdatePolicyResponse wrapper for the UpdatePolicy operation +type UpdatePolicyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Policy instance + Policy `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdatePolicyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_saml2_identity_provider_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_saml2_identity_provider_details.go new file mode 100644 index 000000000..f83217f2b --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_saml2_identity_provider_details.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "encoding/json" + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateSaml2IdentityProviderDetails The representation of UpdateSaml2IdentityProviderDetails +type UpdateSaml2IdentityProviderDetails struct { + + // The description you assign to the `IdentityProvider`. Does not have to + // be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` + + // The URL for retrieving the identity provider's metadata, + // which contains information required for federating. + MetadataUrl *string `mandatory:"false" json:"metadataUrl"` + + // The XML that contains the information required for federating. + Metadata *string `mandatory:"false" json:"metadata"` +} + +//GetDescription returns Description +func (m UpdateSaml2IdentityProviderDetails) GetDescription() *string { + return m.Description +} + +func (m UpdateSaml2IdentityProviderDetails) String() string { + return common.PointerString(m) +} + +// MarshalJSON marshals to json representation +func (m UpdateSaml2IdentityProviderDetails) MarshalJSON() (buff []byte, e error) { + type MarshalTypeUpdateSaml2IdentityProviderDetails UpdateSaml2IdentityProviderDetails + s := struct { + DiscriminatorParam string `json:"protocol"` + MarshalTypeUpdateSaml2IdentityProviderDetails + }{ + "SAML2", + (MarshalTypeUpdateSaml2IdentityProviderDetails)(m), + } + + return json.Marshal(&s) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_state_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_state_details.go new file mode 100644 index 000000000..3c920d786 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_state_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateStateDetails The representation of UpdateStateDetails +type UpdateStateDetails struct { + + // Update state to blocked or unblocked. Only "false" is supported (for changing the state to unblocked). + Blocked *bool `mandatory:"false" json:"blocked"` +} + +func (m UpdateStateDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_details.go new file mode 100644 index 000000000..7f987bf70 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateSwiftPasswordDetails The representation of UpdateSwiftPasswordDetails +type UpdateSwiftPasswordDetails struct { + + // The description you assign to the Swift password. Does not have to be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` +} + +func (m UpdateSwiftPasswordDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_request_response.go new file mode 100644 index 000000000..0ec212ff8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_swift_password_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateSwiftPasswordRequest wrapper for the UpdateSwiftPassword operation +type UpdateSwiftPasswordRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // The OCID of the Swift password. + SwiftPasswordId *string `mandatory:"true" contributesTo:"path" name:"swiftPasswordId"` + + // Request object for updating a Swift password. + UpdateSwiftPasswordDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateSwiftPasswordRequest) String() string { + return common.PointerString(request) +} + +// UpdateSwiftPasswordResponse wrapper for the UpdateSwiftPassword operation +type UpdateSwiftPasswordResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The SwiftPassword instance + SwiftPassword `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateSwiftPasswordResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_user_details.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_user_details.go new file mode 100644 index 000000000..07b2ce2a4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_user_details.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateUserDetails The representation of UpdateUserDetails +type UpdateUserDetails struct { + + // The description you assign to the user. Does not have to be unique, and it's changeable. + Description *string `mandatory:"false" json:"description"` +} + +func (m UpdateUserDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_user_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_user_request_response.go new file mode 100644 index 000000000..41565565e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_user_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateUserRequest wrapper for the UpdateUser operation +type UpdateUserRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // Request object for updating a user. + UpdateUserDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateUserRequest) String() string { + return common.PointerString(request) +} + +// UpdateUserResponse wrapper for the UpdateUser operation +type UpdateUserResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The User instance + User `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateUserResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/update_user_state_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/update_user_state_request_response.go new file mode 100644 index 000000000..f1e2c7514 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/update_user_state_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateUserStateRequest wrapper for the UpdateUserState operation +type UpdateUserStateRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // Request object for updating a user state. + UpdateStateDetails `contributesTo:"body"` + + // For optimistic concurrency control. In the PUT or DELETE call for a resource, set the `if-match` + // parameter to the value of the etag from a previous GET or POST response for that resource. The resource + // will be updated or deleted only if the etag you provide matches the resource's current etag value. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` +} + +func (request UpdateUserStateRequest) String() string { + return common.PointerString(request) +} + +// UpdateUserStateResponse wrapper for the UpdateUserState operation +type UpdateUserStateResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The User instance + User `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateUserStateResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/upload_api_key_request_response.go b/vendor/github.com/oracle/oci-go-sdk/identity/upload_api_key_request_response.go new file mode 100644 index 000000000..4a971b526 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/upload_api_key_request_response.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UploadApiKeyRequest wrapper for the UploadApiKey operation +type UploadApiKeyRequest struct { + + // The OCID of the user. + UserId *string `mandatory:"true" contributesTo:"path" name:"userId"` + + // Request object for uploading an API key for a user. + CreateApiKeyDetails `contributesTo:"body"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request UploadApiKeyRequest) String() string { + return common.PointerString(request) +} + +// UploadApiKeyResponse wrapper for the UploadApiKey operation +type UploadApiKeyResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The ApiKey instance + ApiKey `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For optimistic concurrency control. See `if-match`. + Etag *string `presentIn:"header" name:"etag"` +} + +func (response UploadApiKeyResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/user.go b/vendor/github.com/oracle/oci-go-sdk/identity/user.go new file mode 100644 index 000000000..945e672e4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/user.go @@ -0,0 +1,91 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// User An individual employee or system that needs to manage or use your company's Oracle Cloud Infrastructure +// resources. Users might need to launch instances, manage remote disks, work with your cloud network, etc. Users +// have one or more IAM Service credentials (ApiKey, +// UIPassword, and SwiftPassword). +// For more information, see User Credentials (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usercredentials.htm)). End users of your +// application are not typically IAM Service users. For conceptual information about users and other IAM Service +// components, see Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// These users are created directly within the Oracle Cloud Infrastructure system, via the IAM service. +// They are different from *federated users*, who authenticate themselves to the Oracle Cloud Infrastructure +// Console via an identity provider. For more information, see +// Identity Providers and Federation (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/federation.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, +// see Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type User struct { + + // The OCID of the user. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the tenancy containing the user. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The name you assign to the user during creation. This is the user's login for the Console. + // The name must be unique across all users in the tenancy and cannot be changed. + Name *string `mandatory:"true" json:"name"` + + // The description you assign to the user. Does not have to be unique, and it's changeable. + Description *string `mandatory:"true" json:"description"` + + // Date and time the user was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The user's current state. After creating a user, make sure its `lifecycleState` changes from CREATING to + // ACTIVE before using it. + LifecycleState UserLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // Returned only if the user's `lifecycleState` is INACTIVE. A 16-bit value showing the reason why the user + // is inactive: + // - bit 0: SUSPENDED (reserved for future use) + // - bit 1: DISABLED (reserved for future use) + // - bit 2: BLOCKED (the user has exceeded the maximum number of failed login attempts for the Console) + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m User) String() string { + return common.PointerString(m) +} + +// UserLifecycleStateEnum Enum with underlying type: string +type UserLifecycleStateEnum string + +// Set of constants representing the allowable values for UserLifecycleState +const ( + UserLifecycleStateCreating UserLifecycleStateEnum = "CREATING" + UserLifecycleStateActive UserLifecycleStateEnum = "ACTIVE" + UserLifecycleStateInactive UserLifecycleStateEnum = "INACTIVE" + UserLifecycleStateDeleting UserLifecycleStateEnum = "DELETING" + UserLifecycleStateDeleted UserLifecycleStateEnum = "DELETED" +) + +var mappingUserLifecycleState = map[string]UserLifecycleStateEnum{ + "CREATING": UserLifecycleStateCreating, + "ACTIVE": UserLifecycleStateActive, + "INACTIVE": UserLifecycleStateInactive, + "DELETING": UserLifecycleStateDeleting, + "DELETED": UserLifecycleStateDeleted, +} + +// GetUserLifecycleStateEnumValues Enumerates the set of values for UserLifecycleState +func GetUserLifecycleStateEnumValues() []UserLifecycleStateEnum { + values := make([]UserLifecycleStateEnum, 0) + for _, v := range mappingUserLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/identity/user_group_membership.go b/vendor/github.com/oracle/oci-go-sdk/identity/user_group_membership.go new file mode 100644 index 000000000..f2b1a3aee --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/identity/user_group_membership.go @@ -0,0 +1,74 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Identity and Access Management Service API +// +// APIs for managing users, groups, compartments, and policies. +// + +package identity + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UserGroupMembership An object that represents the membership of a user in a group. When you add a user to a group, the result is a +// `UserGroupMembership` with its own OCID. To remove a user from a group, you delete the `UserGroupMembership` object. +type UserGroupMembership struct { + + // The OCID of the membership. + Id *string `mandatory:"true" json:"id"` + + // The OCID of the tenancy containing the user, group, and membership object. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the group. + GroupId *string `mandatory:"true" json:"groupId"` + + // The OCID of the user. + UserId *string `mandatory:"true" json:"userId"` + + // Date and time the membership was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The membership's current state. After creating a membership object, make sure its `lifecycleState` changes + // from CREATING to ACTIVE before using it. + LifecycleState UserGroupMembershipLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The detailed status of INACTIVE lifecycleState. + InactiveStatus *int `mandatory:"false" json:"inactiveStatus"` +} + +func (m UserGroupMembership) String() string { + return common.PointerString(m) +} + +// UserGroupMembershipLifecycleStateEnum Enum with underlying type: string +type UserGroupMembershipLifecycleStateEnum string + +// Set of constants representing the allowable values for UserGroupMembershipLifecycleState +const ( + UserGroupMembershipLifecycleStateCreating UserGroupMembershipLifecycleStateEnum = "CREATING" + UserGroupMembershipLifecycleStateActive UserGroupMembershipLifecycleStateEnum = "ACTIVE" + UserGroupMembershipLifecycleStateInactive UserGroupMembershipLifecycleStateEnum = "INACTIVE" + UserGroupMembershipLifecycleStateDeleting UserGroupMembershipLifecycleStateEnum = "DELETING" + UserGroupMembershipLifecycleStateDeleted UserGroupMembershipLifecycleStateEnum = "DELETED" +) + +var mappingUserGroupMembershipLifecycleState = map[string]UserGroupMembershipLifecycleStateEnum{ + "CREATING": UserGroupMembershipLifecycleStateCreating, + "ACTIVE": UserGroupMembershipLifecycleStateActive, + "INACTIVE": UserGroupMembershipLifecycleStateInactive, + "DELETING": UserGroupMembershipLifecycleStateDeleting, + "DELETED": UserGroupMembershipLifecycleStateDeleted, +} + +// GetUserGroupMembershipLifecycleStateEnumValues Enumerates the set of values for UserGroupMembershipLifecycleState +func GetUserGroupMembershipLifecycleStateEnumValues() []UserGroupMembershipLifecycleStateEnum { + values := make([]UserGroupMembershipLifecycleStateEnum, 0) + for _, v := range mappingUserGroupMembershipLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend.go new file mode 100644 index 000000000..ecca968c3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend.go @@ -0,0 +1,57 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Backend The configuration of a backend server that is a member of a load balancer backend set. +// For more information, see Managing Backend Servers (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/managingbackendservers.htm). +type Backend struct { + + // Whether the load balancer should treat this server as a backup unit. If `true`, the load balancer forwards no ingress + // traffic to this backend server unless all other backend servers not marked as "backup" fail the health check policy. + // Example: `true` + Backup *bool `mandatory:"true" json:"backup"` + + // Whether the load balancer should drain this server. Servers marked "drain" receive no new + // incoming traffic. + // Example: `true` + Drain *bool `mandatory:"true" json:"drain"` + + // The IP address of the backend server. + // Example: `10.10.10.4` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // A read-only field showing the IP address and port that uniquely identify this backend server in the backend set. + // Example: `10.10.10.4:8080` + Name *string `mandatory:"true" json:"name"` + + // Whether the load balancer should treat this server as offline. Offline servers receive no incoming + // traffic. + // Example: `true` + Offline *bool `mandatory:"true" json:"offline"` + + // The communication port for the backend server. + // Example: `8080` + Port *int `mandatory:"true" json:"port"` + + // The load balancing policy weight assigned to the server. Backend servers with a higher weight receive a larger + // proportion of incoming traffic. For example, a server weighted '3' receives 3 times the number of new connections + // as a server weighted '1'. + // For more information on load balancing policies, see + // How Load Balancing Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Reference/lbpolicies.htm). + // Example: `3` + Weight *int `mandatory:"true" json:"weight"` +} + +func (m Backend) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_details.go new file mode 100644 index 000000000..a65e538e3 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_details.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BackendDetails The load balancing configuration details of a backend server. +type BackendDetails struct { + + // The IP address of the backend server. + // Example: `10.10.10.4` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // The communication port for the backend server. + // Example: `8080` + Port *int `mandatory:"true" json:"port"` + + // Whether the load balancer should treat this server as a backup unit. If `true`, the load balancer forwards no ingress + // traffic to this backend server unless all other backend servers not marked as "backup" fail the health check policy. + // Example: `true` + Backup *bool `mandatory:"false" json:"backup"` + + // Whether the load balancer should drain this server. Servers marked "drain" receive no new + // incoming traffic. + // Example: `true` + Drain *bool `mandatory:"false" json:"drain"` + + // Whether the load balancer should treat this server as offline. Offline servers receive no incoming + // traffic. + // Example: `true` + Offline *bool `mandatory:"false" json:"offline"` + + // The load balancing policy weight assigned to the server. Backend servers with a higher weight receive a larger + // proportion of incoming traffic. For example, a server weighted '3' receives 3 times the number of new connections + // as a server weighted '1'. + // For more information on load balancing policies, see + // How Load Balancing Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Reference/lbpolicies.htm). + // Example: `3` + Weight *int `mandatory:"false" json:"weight"` +} + +func (m BackendDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_health.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_health.go new file mode 100644 index 000000000..ca8cbc42c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_health.go @@ -0,0 +1,58 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BackendHealth The health status of the specified backend server as reported by the primary and standby load balancers. +type BackendHealth struct { + + // A list of the most recent health check results returned for the specified backend server. + HealthCheckResults []HealthCheckResult `mandatory:"true" json:"healthCheckResults"` + + // The general health status of the specified backend server as reported by the primary and standby load balancers. + // * **OK:** Both health checks returned `OK`. + // * **WARNING:** One health check returned `OK` and one did not. + // * **CRITICAL:** Neither health check returned `OK`. + // * **UNKNOWN:** One or both health checks returned `UNKNOWN`, or the system was unable to retrieve metrics at this time. + Status BackendHealthStatusEnum `mandatory:"true" json:"status"` +} + +func (m BackendHealth) String() string { + return common.PointerString(m) +} + +// BackendHealthStatusEnum Enum with underlying type: string +type BackendHealthStatusEnum string + +// Set of constants representing the allowable values for BackendHealthStatus +const ( + BackendHealthStatusOk BackendHealthStatusEnum = "OK" + BackendHealthStatusWarning BackendHealthStatusEnum = "WARNING" + BackendHealthStatusCritical BackendHealthStatusEnum = "CRITICAL" + BackendHealthStatusUnknown BackendHealthStatusEnum = "UNKNOWN" +) + +var mappingBackendHealthStatus = map[string]BackendHealthStatusEnum{ + "OK": BackendHealthStatusOk, + "WARNING": BackendHealthStatusWarning, + "CRITICAL": BackendHealthStatusCritical, + "UNKNOWN": BackendHealthStatusUnknown, +} + +// GetBackendHealthStatusEnumValues Enumerates the set of values for BackendHealthStatus +func GetBackendHealthStatusEnumValues() []BackendHealthStatusEnum { + values := make([]BackendHealthStatusEnum, 0) + for _, v := range mappingBackendHealthStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set.go new file mode 100644 index 000000000..c47097c7a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BackendSet The configuration of a load balancer backend set. +// For more information on backend set configuration, see +// Managing Backend Sets (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managingbackendsets.htm). +type BackendSet struct { + Backends []Backend `mandatory:"true" json:"backends"` + + HealthChecker *HealthChecker `mandatory:"true" json:"healthChecker"` + + // A friendly name for the backend set. It must be unique and it cannot be changed. + // Valid backend set names include only alphanumeric characters, dashes, and underscores. Backend set names cannot + // contain spaces. Avoid entering confidential information. + // Example: `My_backend_set` + Name *string `mandatory:"true" json:"name"` + + // The load balancer policy for the backend set. To get a list of available policies, use the + // ListPolicies operation. + // Example: `LEAST_CONNECTIONS` + Policy *string `mandatory:"true" json:"policy"` + + SessionPersistenceConfiguration *SessionPersistenceConfigurationDetails `mandatory:"false" json:"sessionPersistenceConfiguration"` + + SslConfiguration *SslConfiguration `mandatory:"false" json:"sslConfiguration"` +} + +func (m BackendSet) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_details.go new file mode 100644 index 000000000..dad4d6591 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_details.go @@ -0,0 +1,35 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BackendSetDetails The configuration details for a load balancer backend set. +// For more information on backend set configuration, see +// Managing Backend Sets (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managingbackendsets.htm). +type BackendSetDetails struct { + HealthChecker *HealthCheckerDetails `mandatory:"true" json:"healthChecker"` + + // The load balancer policy for the backend set. To get a list of available policies, use the + // ListPolicies operation. + // Example: `LEAST_CONNECTIONS` + Policy *string `mandatory:"true" json:"policy"` + + Backends []BackendDetails `mandatory:"false" json:"backends"` + + SessionPersistenceConfiguration *SessionPersistenceConfigurationDetails `mandatory:"false" json:"sessionPersistenceConfiguration"` + + SslConfiguration *SslConfigurationDetails `mandatory:"false" json:"sslConfiguration"` +} + +func (m BackendSetDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_health.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_health.go new file mode 100644 index 000000000..1ef062996 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/backend_set_health.go @@ -0,0 +1,78 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BackendSetHealth The health status details for a backend set. +// This object does not explicitly enumerate backend servers with a status of `OK`. However, they are included in the +// `totalBackendCount` sum. +type BackendSetHealth struct { + + // A list of backend servers that are currently in the `CRITICAL` health state. The list identifies each backend server by + // IP address and port. + // Example: `1.1.1.1:80` + CriticalStateBackendNames []string `mandatory:"true" json:"criticalStateBackendNames"` + + // Overall health status of the backend set. + // * **OK:** All backend servers in the backend set return a status of `OK`. + // * **WARNING:** Half or more of the backend set's backend servers return a status of `OK` and at least one backend + // server returns a status of `WARNING`, `CRITICAL`, or `UNKNOWN`. + // * **CRITICAL:** Fewer than half of the backend set's backend servers return a status of `OK`. + // * **UNKNOWN:** More than half of the backend set's backend servers return a status of `UNKNOWN`, the system was + // unable to retrieve metrics, or the backend set does not have a listener attached. + Status BackendSetHealthStatusEnum `mandatory:"true" json:"status"` + + // The total number of backend servers in this backend set. + // Example: `5` + TotalBackendCount *int `mandatory:"true" json:"totalBackendCount"` + + // A list of backend servers that are currently in the `UNKNOWN` health state. The list identifies each backend server by + // IP address and port. + // Example: `1.1.1.5:80` + UnknownStateBackendNames []string `mandatory:"true" json:"unknownStateBackendNames"` + + // A list of backend servers that are currently in the `WARNING` health state. The list identifies each backend server by + // IP address and port. + // Example: `1.1.1.7:42` + WarningStateBackendNames []string `mandatory:"true" json:"warningStateBackendNames"` +} + +func (m BackendSetHealth) String() string { + return common.PointerString(m) +} + +// BackendSetHealthStatusEnum Enum with underlying type: string +type BackendSetHealthStatusEnum string + +// Set of constants representing the allowable values for BackendSetHealthStatus +const ( + BackendSetHealthStatusOk BackendSetHealthStatusEnum = "OK" + BackendSetHealthStatusWarning BackendSetHealthStatusEnum = "WARNING" + BackendSetHealthStatusCritical BackendSetHealthStatusEnum = "CRITICAL" + BackendSetHealthStatusUnknown BackendSetHealthStatusEnum = "UNKNOWN" +) + +var mappingBackendSetHealthStatus = map[string]BackendSetHealthStatusEnum{ + "OK": BackendSetHealthStatusOk, + "WARNING": BackendSetHealthStatusWarning, + "CRITICAL": BackendSetHealthStatusCritical, + "UNKNOWN": BackendSetHealthStatusUnknown, +} + +// GetBackendSetHealthStatusEnumValues Enumerates the set of values for BackendSetHealthStatus +func GetBackendSetHealthStatusEnumValues() []BackendSetHealthStatusEnum { + values := make([]BackendSetHealthStatusEnum, 0) + for _, v := range mappingBackendSetHealthStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate.go new file mode 100644 index 000000000..e2d038de7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Certificate The configuration details of a listener certificate bundle. +// For more information on SSL certficate configuration, see +// Managing SSL Certificates (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/managingcertificates.htm). +type Certificate struct { + + // The Certificate Authority certificate, or any interim certificate, that you received from your SSL certificate provider. + // Example: + // -----BEGIN CERTIFICATE----- + // MIIEczCCA1ugAwIBAgIBADANBgkqhkiG9w0BAQQFAD..AkGA1UEBhMCR0Ix + // EzARBgNVBAgTClNvbWUtU3RhdGUxFDASBgNVBAoTC0..0EgTHRkMTcwNQYD + // VQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcn..XRpb24gQXV0aG9y + // aXR5MRQwEgYDVQQDEwtCZXN0IENBIEx0ZDAeFw0wMD..TUwMTZaFw0wMTAy + // ... + // -----END CERTIFICATE----- + CaCertificate *string `mandatory:"true" json:"caCertificate"` + + // A friendly name for the certificate bundle. It must be unique and it cannot be changed. + // Valid certificate bundle names include only alphanumeric characters, dashes, and underscores. + // Certificate bundle names cannot contain spaces. Avoid entering confidential information. + // Example: `My_certificate_bundle` + CertificateName *string `mandatory:"true" json:"certificateName"` + + // The public certificate, in PEM format, that you received from your SSL certificate provider. + // Example: + // -----BEGIN CERTIFICATE----- + // MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG + // A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE + // MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl + // YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw + // ... + // -----END CERTIFICATE----- + PublicCertificate *string `mandatory:"true" json:"publicCertificate"` +} + +func (m Certificate) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate_details.go new file mode 100644 index 000000000..d63af94d9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/certificate_details.go @@ -0,0 +1,66 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CertificateDetails The configuration details for a listener certificate bundle. +// For more information on SSL certficate configuration, see +// Managing SSL Certificates (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/managingcertificates.htm). +type CertificateDetails struct { + + // A friendly name for the certificate bundle. It must be unique and it cannot be changed. + // Valid certificate bundle names include only alphanumeric characters, dashes, and underscores. + // Certificate bundle names cannot contain spaces. Avoid entering confidential information. + // Example: `My_certificate_bundle` + CertificateName *string `mandatory:"true" json:"certificateName"` + + // The Certificate Authority certificate, or any interim certificate, that you received from your SSL certificate provider. + // Example: + // -----BEGIN CERTIFICATE----- + // MIIEczCCA1ugAwIBAgIBADANBgkqhkiG9w0BAQQFAD..AkGA1UEBhMCR0Ix + // EzARBgNVBAgTClNvbWUtU3RhdGUxFDASBgNVBAoTC0..0EgTHRkMTcwNQYD + // VQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcn..XRpb24gQXV0aG9y + // aXR5MRQwEgYDVQQDEwtCZXN0IENBIEx0ZDAeFw0wMD..TUwMTZaFw0wMTAy + // ... + // -----END CERTIFICATE----- + CaCertificate *string `mandatory:"false" json:"caCertificate"` + + // A passphrase for encrypted private keys. This is needed only if you created your certificate with a passphrase. + // Example: `Mysecretunlockingcode42!1!` + Passphrase *string `mandatory:"false" json:"passphrase"` + + // The SSL private key for your certificate, in PEM format. + // Example: + // -----BEGIN RSA PRIVATE KEY----- + // jO1O1v2ftXMsawM90tnXwc6xhOAT1gDBC9S8DKeca..JZNUgYYwNS0dP2UK + // tmyN+XqVcAKw4HqVmChXy5b5msu8eIq3uc2NqNVtR..2ksSLukP8pxXcHyb + // +sEwvM4uf8qbnHAqwnOnP9+KV9vds6BaH1eRA4CHz..n+NVZlzBsTxTlS16 + // /Umr7wJzVrMqK5sDiSu4WuaaBdqMGfL5hLsTjcBFD..Da2iyQmSKuVD4lIZ + // ... + // -----END RSA PRIVATE KEY----- + PrivateKey *string `mandatory:"false" json:"privateKey"` + + // The public certificate, in PEM format, that you received from your SSL certificate provider. + // Example: + // -----BEGIN CERTIFICATE----- + // MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG + // A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE + // MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl + // YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw + // ... + // -----END CERTIFICATE----- + PublicCertificate *string `mandatory:"false" json:"publicCertificate"` +} + +func (m CertificateDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_details.go new file mode 100644 index 000000000..b47a042c0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_details.go @@ -0,0 +1,54 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateBackendDetails The configuration details for creating a backend server in a backend set. +// For more information on backend server configuration, see +// Managing Backend Servers (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managingbackendservers.htm). +type CreateBackendDetails struct { + + // The IP address of the backend server. + // Example: `10.10.10.4` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // The communication port for the backend server. + // Example: `8080` + Port *int `mandatory:"true" json:"port"` + + // Whether the load balancer should treat this server as a backup unit. If `true`, the load balancer forwards no ingress + // traffic to this backend server unless all other backend servers not marked as "backup" fail the health check policy. + // Example: `true` + Backup *bool `mandatory:"false" json:"backup"` + + // Whether the load balancer should drain this server. Servers marked "drain" receive no new + // incoming traffic. + // Example: `true` + Drain *bool `mandatory:"false" json:"drain"` + + // Whether the load balancer should treat this server as offline. Offline servers receive no incoming + // traffic. + // Example: `true` + Offline *bool `mandatory:"false" json:"offline"` + + // The load balancing policy weight assigned to the server. Backend servers with a higher weight receive a larger + // proportion of incoming traffic. For example, a server weighted '3' receives 3 times the number of new connections + // as a server weighted '1'. + // For more information on load balancing policies, see + // How Load Balancing Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Reference/lbpolicies.htm). + // Example: `3` + Weight *int `mandatory:"false" json:"weight"` +} + +func (m CreateBackendDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_request_response.go new file mode 100644 index 000000000..3d14273ce --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateBackendRequest wrapper for the CreateBackend operation +type CreateBackendRequest struct { + + // The details to add a backend server to a backend set. + CreateBackendDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set and servers. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set to add the backend server to. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateBackendRequest) String() string { + return common.PointerString(request) +} + +// CreateBackendResponse wrapper for the CreateBackend operation +type CreateBackendResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response CreateBackendResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_details.go new file mode 100644 index 000000000..2bf3acb40 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_details.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateBackendSetDetails The configuration details for creating a backend set in a load balancer. +// For more information on backend set configuration, see +// Managing Backend Sets (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managingbackendsets.htm). +type CreateBackendSetDetails struct { + HealthChecker *HealthCheckerDetails `mandatory:"true" json:"healthChecker"` + + // A friendly name for the backend set. It must be unique and it cannot be changed. + // Valid backend set names include only alphanumeric characters, dashes, and underscores. Backend set names cannot + // contain spaces. Avoid entering confidential information. + // Example: `My_backend_set` + Name *string `mandatory:"true" json:"name"` + + // The load balancer policy for the backend set. To get a list of available policies, use the + // ListPolicies operation. + // Example: `LEAST_CONNECTIONS` + Policy *string `mandatory:"true" json:"policy"` + + Backends []BackendDetails `mandatory:"false" json:"backends"` + + SessionPersistenceConfiguration *SessionPersistenceConfigurationDetails `mandatory:"false" json:"sessionPersistenceConfiguration"` + + SslConfiguration *SslConfigurationDetails `mandatory:"false" json:"sslConfiguration"` +} + +func (m CreateBackendSetDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_request_response.go new file mode 100644 index 000000000..7617987a4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_backend_set_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateBackendSetRequest wrapper for the CreateBackendSet operation +type CreateBackendSetRequest struct { + + // The details for adding a backend set. + CreateBackendSetDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer on which to add a backend set. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateBackendSetRequest) String() string { + return common.PointerString(request) +} + +// CreateBackendSetResponse wrapper for the CreateBackendSet operation +type CreateBackendSetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response CreateBackendSetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_details.go new file mode 100644 index 000000000..c7f4789bf --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_details.go @@ -0,0 +1,66 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateCertificateDetails The configuration details for adding a certificate bundle to a listener. +// For more information on SSL certficate configuration, see +// Managing SSL Certificates (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/managingcertificates.htm). +type CreateCertificateDetails struct { + + // A friendly name for the certificate bundle. It must be unique and it cannot be changed. + // Valid certificate bundle names include only alphanumeric characters, dashes, and underscores. + // Certificate bundle names cannot contain spaces. Avoid entering confidential information. + // Example: `My_certificate_bundle` + CertificateName *string `mandatory:"true" json:"certificateName"` + + // The Certificate Authority certificate, or any interim certificate, that you received from your SSL certificate provider. + // Example: + // -----BEGIN CERTIFICATE----- + // MIIEczCCA1ugAwIBAgIBADANBgkqhkiG9w0BAQQFAD..AkGA1UEBhMCR0Ix + // EzARBgNVBAgTClNvbWUtU3RhdGUxFDASBgNVBAoTC0..0EgTHRkMTcwNQYD + // VQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcn..XRpb24gQXV0aG9y + // aXR5MRQwEgYDVQQDEwtCZXN0IENBIEx0ZDAeFw0wMD..TUwMTZaFw0wMTAy + // ... + // -----END CERTIFICATE----- + CaCertificate *string `mandatory:"false" json:"caCertificate"` + + // A passphrase for encrypted private keys. This is needed only if you created your certificate with a passphrase. + // Example: `Mysecretunlockingcode42!1!` + Passphrase *string `mandatory:"false" json:"passphrase"` + + // The SSL private key for your certificate, in PEM format. + // Example: + // -----BEGIN RSA PRIVATE KEY----- + // jO1O1v2ftXMsawM90tnXwc6xhOAT1gDBC9S8DKeca..JZNUgYYwNS0dP2UK + // tmyN+XqVcAKw4HqVmChXy5b5msu8eIq3uc2NqNVtR..2ksSLukP8pxXcHyb + // +sEwvM4uf8qbnHAqwnOnP9+KV9vds6BaH1eRA4CHz..n+NVZlzBsTxTlS16 + // /Umr7wJzVrMqK5sDiSu4WuaaBdqMGfL5hLsTjcBFD..Da2iyQmSKuVD4lIZ + // ... + // -----END RSA PRIVATE KEY----- + PrivateKey *string `mandatory:"false" json:"privateKey"` + + // The public certificate, in PEM format, that you received from your SSL certificate provider. + // Example: + // -----BEGIN CERTIFICATE----- + // MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG + // A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE + // MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl + // YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw + // ... + // -----END CERTIFICATE----- + PublicCertificate *string `mandatory:"false" json:"publicCertificate"` +} + +func (m CreateCertificateDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_request_response.go new file mode 100644 index 000000000..f92bd347e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_certificate_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateCertificateRequest wrapper for the CreateCertificate operation +type CreateCertificateRequest struct { + + // The details of the certificate to add. + CreateCertificateDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer on which to add the certificate. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateCertificateRequest) String() string { + return common.PointerString(request) +} + +// CreateCertificateResponse wrapper for the CreateCertificate operation +type CreateCertificateResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response CreateCertificateResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_details.go new file mode 100644 index 000000000..58e7b30d6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_details.go @@ -0,0 +1,43 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateListenerDetails The configuration details for adding a listener to a backend set. +// For more information on listener configuration, see +// Managing Load Balancer Listeners (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managinglisteners.htm). +type CreateListenerDetails struct { + + // The name of the associated backend set. + DefaultBackendSetName *string `mandatory:"true" json:"defaultBackendSetName"` + + // A friendly name for the listener. It must be unique and it cannot be changed. + // Avoid entering confidential information. + // Example: `My listener` + Name *string `mandatory:"true" json:"name"` + + // The communication port for the listener. + // Example: `80` + Port *int `mandatory:"true" json:"port"` + + // The protocol on which the listener accepts connection requests. + // To get a list of valid protocols, use the ListProtocols + // operation. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + SslConfiguration *SslConfigurationDetails `mandatory:"false" json:"sslConfiguration"` +} + +func (m CreateListenerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_request_response.go new file mode 100644 index 000000000..9c9c9f570 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_listener_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateListenerRequest wrapper for the CreateListener operation +type CreateListenerRequest struct { + + // Details to add a listener. + CreateListenerDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer on which to add a listener. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateListenerRequest) String() string { + return common.PointerString(request) +} + +// CreateListenerResponse wrapper for the CreateListener operation +type CreateListenerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response CreateListenerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_details.go new file mode 100644 index 000000000..5b08bf52a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_details.go @@ -0,0 +1,57 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateLoadBalancerDetails The configuration details for creating a load balancer. +type CreateLoadBalancerDetails struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment in which to create the load balancer. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. It does not have to be unique, and it is changeable. + // Avoid entering confidential information. + // Example: `My load balancer` + DisplayName *string `mandatory:"true" json:"displayName"` + + // A template that determines the total pre-provisioned bandwidth (ingress plus egress). + // To get a list of available shapes, use the ListShapes + // operation. + // Example: `100Mbps` + ShapeName *string `mandatory:"true" json:"shapeName"` + + // An array of subnet OCIDs (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + SubnetIds []string `mandatory:"true" json:"subnetIds"` + + BackendSets map[string]BackendSetDetails `mandatory:"false" json:"backendSets"` + + Certificates map[string]CertificateDetails `mandatory:"false" json:"certificates"` + + // Whether the load balancer has a VCN-local (private) IP address. + // If "true", the service assigns a private IP address to the load balancer. The load balancer requires only one subnet + // to host both the primary and secondary load balancers. The private IP address is local to the subnet. The load balancer + // is accessible only from within the VCN that contains the associated subnet, or as further restricted by your security + // list rules. The load balancer can route traffic to any backend server that is reachable from the VCN. + // For a private load balancer, both the primary and secondary load balancer hosts are within the same Availability Domain. + // If "false", the service assigns a public IP address to the load balancer. A load balancer with a public IP address + // requires two subnets, each in a different Availability Domain. One subnet hosts the primary load balancer and the other + // hosts the secondary (standby) load balancer. A public load balancer is accessible from the internet, depending on your + // VCN's security list rules (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm). + // Example: `false` + IsPrivate *bool `mandatory:"false" json:"isPrivate"` + + Listeners map[string]ListenerDetails `mandatory:"false" json:"listeners"` +} + +func (m CreateLoadBalancerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_request_response.go new file mode 100644 index 000000000..0ff053e4e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/create_load_balancer_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateLoadBalancerRequest wrapper for the CreateLoadBalancer operation +type CreateLoadBalancerRequest struct { + + // The configuration details for creating a load balancer. + CreateLoadBalancerDetails `contributesTo:"body"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request CreateLoadBalancerRequest) String() string { + return common.PointerString(request) +} + +// CreateLoadBalancerResponse wrapper for the CreateLoadBalancer operation +type CreateLoadBalancerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response CreateLoadBalancerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_request_response.go new file mode 100644 index 000000000..acc746c90 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteBackendRequest wrapper for the DeleteBackend operation +type DeleteBackendRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set and server. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set associated with the backend server. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The IP address and port of the backend server to remove. + // Example: `1.1.1.7:42` + BackendName *string `mandatory:"true" contributesTo:"path" name:"backendName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request DeleteBackendRequest) String() string { + return common.PointerString(request) +} + +// DeleteBackendResponse wrapper for the DeleteBackend operation +type DeleteBackendResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response DeleteBackendResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_set_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_set_request_response.go new file mode 100644 index 000000000..6a73967a2 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_backend_set_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteBackendSetRequest wrapper for the DeleteBackendSet operation +type DeleteBackendSetRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set to delete. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request DeleteBackendSetRequest) String() string { + return common.PointerString(request) +} + +// DeleteBackendSetResponse wrapper for the DeleteBackendSet operation +type DeleteBackendSetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response DeleteBackendSetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_certificate_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_certificate_request_response.go new file mode 100644 index 000000000..db86b0637 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_certificate_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteCertificateRequest wrapper for the DeleteCertificate operation +type DeleteCertificateRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the certificate to be deleted. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the certificate to delete. + // Example: `My_certificate_bundle` + CertificateName *string `mandatory:"true" contributesTo:"path" name:"certificateName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request DeleteCertificateRequest) String() string { + return common.PointerString(request) +} + +// DeleteCertificateResponse wrapper for the DeleteCertificate operation +type DeleteCertificateResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response DeleteCertificateResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_listener_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_listener_request_response.go new file mode 100644 index 000000000..b5496e029 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_listener_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteListenerRequest wrapper for the DeleteListener operation +type DeleteListenerRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the listener to delete. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the listener to delete. + // Example: `My listener` + ListenerName *string `mandatory:"true" contributesTo:"path" name:"listenerName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request DeleteListenerRequest) String() string { + return common.PointerString(request) +} + +// DeleteListenerResponse wrapper for the DeleteListener operation +type DeleteListenerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response DeleteListenerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_load_balancer_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_load_balancer_request_response.go new file mode 100644 index 000000000..3e39b143c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/delete_load_balancer_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteLoadBalancerRequest wrapper for the DeleteLoadBalancer operation +type DeleteLoadBalancerRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer to delete. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request DeleteLoadBalancerRequest) String() string { + return common.PointerString(request) +} + +// DeleteLoadBalancerResponse wrapper for the DeleteLoadBalancer operation +type DeleteLoadBalancerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response DeleteLoadBalancerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_health_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_health_request_response.go new file mode 100644 index 000000000..6216d7aa9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_health_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBackendHealthRequest wrapper for the GetBackendHealth operation +type GetBackendHealthRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend server health status to be retrieved. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set associated with the backend server to retrieve the health status for. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The IP address and port of the backend server to retrieve the health status for. + // Example: `1.1.1.7:42` + BackendName *string `mandatory:"true" contributesTo:"path" name:"backendName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetBackendHealthRequest) String() string { + return common.PointerString(request) +} + +// GetBackendHealthResponse wrapper for the GetBackendHealth operation +type GetBackendHealthResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BackendHealth instance + BackendHealth `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBackendHealthResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_request_response.go new file mode 100644 index 000000000..b795f0a4f --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_request_response.go @@ -0,0 +1,50 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBackendRequest wrapper for the GetBackend operation +type GetBackendRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set and server. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set that includes the backend server. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The IP address and port of the backend server to retrieve. + // Example: `1.1.1.7:42` + BackendName *string `mandatory:"true" contributesTo:"path" name:"backendName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetBackendRequest) String() string { + return common.PointerString(request) +} + +// GetBackendResponse wrapper for the GetBackend operation +type GetBackendResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Backend instance + Backend `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBackendResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_health_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_health_request_response.go new file mode 100644 index 000000000..9c1952f17 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_health_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBackendSetHealthRequest wrapper for the GetBackendSetHealth operation +type GetBackendSetHealthRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set health status to be retrieved. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set to retrieve the health status for. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetBackendSetHealthRequest) String() string { + return common.PointerString(request) +} + +// GetBackendSetHealthResponse wrapper for the GetBackendSetHealth operation +type GetBackendSetHealthResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BackendSetHealth instance + BackendSetHealth `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBackendSetHealthResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_request_response.go new file mode 100644 index 000000000..19b461368 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_backend_set_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBackendSetRequest wrapper for the GetBackendSet operation +type GetBackendSetRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the specified load balancer. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set to retrieve. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetBackendSetRequest) String() string { + return common.PointerString(request) +} + +// GetBackendSetResponse wrapper for the GetBackendSet operation +type GetBackendSetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The BackendSet instance + BackendSet `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetBackendSetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_health_checker_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_health_checker_request_response.go new file mode 100644 index 000000000..70cfdc6f6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_health_checker_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetHealthCheckerRequest wrapper for the GetHealthChecker operation +type GetHealthCheckerRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the health check policy to be retrieved. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set associated with the health check policy to be retrieved. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetHealthCheckerRequest) String() string { + return common.PointerString(request) +} + +// GetHealthCheckerResponse wrapper for the GetHealthChecker operation +type GetHealthCheckerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The HealthChecker instance + HealthChecker `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetHealthCheckerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_health_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_health_request_response.go new file mode 100644 index 000000000..03783ea3a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_health_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetLoadBalancerHealthRequest wrapper for the GetLoadBalancerHealth operation +type GetLoadBalancerHealthRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer to return health status for. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetLoadBalancerHealthRequest) String() string { + return common.PointerString(request) +} + +// GetLoadBalancerHealthResponse wrapper for the GetLoadBalancerHealth operation +type GetLoadBalancerHealthResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The LoadBalancerHealth instance + LoadBalancerHealth `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetLoadBalancerHealthResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_request_response.go new file mode 100644 index 000000000..4f6347794 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_load_balancer_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetLoadBalancerRequest wrapper for the GetLoadBalancer operation +type GetLoadBalancerRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer to retrieve. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetLoadBalancerRequest) String() string { + return common.PointerString(request) +} + +// GetLoadBalancerResponse wrapper for the GetLoadBalancer operation +type GetLoadBalancerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The LoadBalancer instance + LoadBalancer `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetLoadBalancerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_work_request_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_work_request_request_response.go new file mode 100644 index 000000000..5159bf9c7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/get_work_request_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetWorkRequestRequest wrapper for the GetWorkRequest operation +type GetWorkRequestRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request to retrieve. + WorkRequestId *string `mandatory:"true" contributesTo:"path" name:"workRequestId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request GetWorkRequestRequest) String() string { + return common.PointerString(request) +} + +// GetWorkRequestResponse wrapper for the GetWorkRequest operation +type GetWorkRequestResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The WorkRequest instance + WorkRequest `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetWorkRequestResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_check_result.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_check_result.go new file mode 100644 index 000000000..8c7a04152 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_check_result.go @@ -0,0 +1,71 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// HealthCheckResult Information about a single backend server health check result reported by a load balancer. +type HealthCheckResult struct { + + // The result of the most recent health check. + HealthCheckStatus HealthCheckResultHealthCheckStatusEnum `mandatory:"true" json:"healthCheckStatus"` + + // The IP address of the health check status report provider. This identifier helps you differentiate same-subnet + // (private) load balancers that report health check status. + // Example: `10.2.0.1` + SourceIpAddress *string `mandatory:"true" json:"sourceIpAddress"` + + // The OCID of the subnet hosting the load balancer that reported this health check status. + SubnetId *string `mandatory:"true" json:"subnetId"` + + // The date and time the data was retrieved, in the format defined by RFC3339. + // Example: `2017-06-02T18:28:11+00:00` + Timestamp *common.SDKTime `mandatory:"true" json:"timestamp"` +} + +func (m HealthCheckResult) String() string { + return common.PointerString(m) +} + +// HealthCheckResultHealthCheckStatusEnum Enum with underlying type: string +type HealthCheckResultHealthCheckStatusEnum string + +// Set of constants representing the allowable values for HealthCheckResultHealthCheckStatus +const ( + HealthCheckResultHealthCheckStatusOk HealthCheckResultHealthCheckStatusEnum = "OK" + HealthCheckResultHealthCheckStatusInvalidStatusCode HealthCheckResultHealthCheckStatusEnum = "INVALID_STATUS_CODE" + HealthCheckResultHealthCheckStatusTimedOut HealthCheckResultHealthCheckStatusEnum = "TIMED_OUT" + HealthCheckResultHealthCheckStatusRegexMismatch HealthCheckResultHealthCheckStatusEnum = "REGEX_MISMATCH" + HealthCheckResultHealthCheckStatusConnectFailed HealthCheckResultHealthCheckStatusEnum = "CONNECT_FAILED" + HealthCheckResultHealthCheckStatusIoError HealthCheckResultHealthCheckStatusEnum = "IO_ERROR" + HealthCheckResultHealthCheckStatusOffline HealthCheckResultHealthCheckStatusEnum = "OFFLINE" + HealthCheckResultHealthCheckStatusUnknown HealthCheckResultHealthCheckStatusEnum = "UNKNOWN" +) + +var mappingHealthCheckResultHealthCheckStatus = map[string]HealthCheckResultHealthCheckStatusEnum{ + "OK": HealthCheckResultHealthCheckStatusOk, + "INVALID_STATUS_CODE": HealthCheckResultHealthCheckStatusInvalidStatusCode, + "TIMED_OUT": HealthCheckResultHealthCheckStatusTimedOut, + "REGEX_MISMATCH": HealthCheckResultHealthCheckStatusRegexMismatch, + "CONNECT_FAILED": HealthCheckResultHealthCheckStatusConnectFailed, + "IO_ERROR": HealthCheckResultHealthCheckStatusIoError, + "OFFLINE": HealthCheckResultHealthCheckStatusOffline, + "UNKNOWN": HealthCheckResultHealthCheckStatusUnknown, +} + +// GetHealthCheckResultHealthCheckStatusEnumValues Enumerates the set of values for HealthCheckResultHealthCheckStatus +func GetHealthCheckResultHealthCheckStatusEnumValues() []HealthCheckResultHealthCheckStatusEnum { + values := make([]HealthCheckResultHealthCheckStatusEnum, 0) + for _, v := range mappingHealthCheckResultHealthCheckStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker.go new file mode 100644 index 000000000..5f5150076 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker.go @@ -0,0 +1,57 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// HealthChecker The health check policy configuration. +// For more information, see Editing Health Check Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/editinghealthcheck.htm). +type HealthChecker struct { + + // The backend server port against which to run the health check. If the port is not specified, the load balancer uses the + // port information from the `Backend` object. + // Example: `8080` + Port *int `mandatory:"true" json:"port"` + + // The protocol the health check must use; either HTTP or TCP. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + // A regular expression for parsing the response body from the backend server. + // Example: `^(500|40[1348])$` + ResponseBodyRegex *string `mandatory:"true" json:"responseBodyRegex"` + + // The status code a healthy backend server should return. If you configure the health check policy to use the HTTP protocol, + // you can use common HTTP status codes such as "200". + // Example: `200` + ReturnCode *int `mandatory:"true" json:"returnCode"` + + // The interval between health checks, in milliseconds. The default is 10000 (10 seconds). + // Example: `30000` + IntervalInMillis *int `mandatory:"false" json:"intervalInMillis"` + + // The number of retries to attempt before a backend server is considered "unhealthy". Defaults to 3. + // Example: `3` + Retries *int `mandatory:"false" json:"retries"` + + // The maximum time, in milliseconds, to wait for a reply to a health check. A health check is successful only if a reply + // returns within this timeout period. Defaults to 3000 (3 seconds). + // Example: `6000` + TimeoutInMillis *int `mandatory:"false" json:"timeoutInMillis"` + + // The path against which to run the health check. + // Example: `/healthcheck` + UrlPath *string `mandatory:"false" json:"urlPath"` +} + +func (m HealthChecker) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker_details.go new file mode 100644 index 000000000..29f9a90c8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/health_checker_details.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// HealthCheckerDetails The health check policy's configuration details. +type HealthCheckerDetails struct { + + // The protocol the health check must use; either HTTP or TCP. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + // The interval between health checks, in milliseconds. + // Example: `30000` + IntervalInMillis *int `mandatory:"false" json:"intervalInMillis"` + + // The backend server port against which to run the health check. If the port is not specified, the load balancer uses the + // port information from the `Backend` object. + // Example: `8080` + Port *int `mandatory:"false" json:"port"` + + // A regular expression for parsing the response body from the backend server. + // Example: `^(500|40[1348])$` + ResponseBodyRegex *string `mandatory:"false" json:"responseBodyRegex"` + + // The number of retries to attempt before a backend server is considered "unhealthy". + // Example: `3` + Retries *int `mandatory:"false" json:"retries"` + + // The status code a healthy backend server should return. + // Example: `200` + ReturnCode *int `mandatory:"false" json:"returnCode"` + + // The maximum time, in milliseconds, to wait for a reply to a health check. A health check is successful only if a reply + // returns within this timeout period. + // Example: `6000` + TimeoutInMillis *int `mandatory:"false" json:"timeoutInMillis"` + + // The path against which to run the health check. + // Example: `/healthcheck` + UrlPath *string `mandatory:"false" json:"urlPath"` +} + +func (m HealthCheckerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ip_address.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ip_address.go new file mode 100644 index 000000000..04892809e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ip_address.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// IpAddress A load balancer IP address. +type IpAddress struct { + + // An IP address. + // Example: `128.148.10.20` + IpAddress *string `mandatory:"true" json:"ipAddress"` + + // Whether the IP address is public or private. + // If "true", the IP address is public and accessible from the internet. + // If "false", the IP address is private and accessible only from within the associated VCN. + IsPublic *bool `mandatory:"false" json:"isPublic"` +} + +func (m IpAddress) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backend_sets_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backend_sets_request_response.go new file mode 100644 index 000000000..240a49811 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backend_sets_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListBackendSetsRequest wrapper for the ListBackendSets operation +type ListBackendSetsRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend sets to retrieve. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request ListBackendSetsRequest) String() string { + return common.PointerString(request) +} + +// ListBackendSetsResponse wrapper for the ListBackendSets operation +type ListBackendSetsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []BackendSet instance + Items []BackendSet `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListBackendSetsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backends_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backends_request_response.go new file mode 100644 index 000000000..dd68c498a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_backends_request_response.go @@ -0,0 +1,46 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListBackendsRequest wrapper for the ListBackends operation +type ListBackendsRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set and servers. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set associated with the backend servers. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request ListBackendsRequest) String() string { + return common.PointerString(request) +} + +// ListBackendsResponse wrapper for the ListBackends operation +type ListBackendsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Backend instance + Items []Backend `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListBackendsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_certificates_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_certificates_request_response.go new file mode 100644 index 000000000..b5e62bc07 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_certificates_request_response.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListCertificatesRequest wrapper for the ListCertificates operation +type ListCertificatesRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the certificates to be listed. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` +} + +func (request ListCertificatesRequest) String() string { + return common.PointerString(request) +} + +// ListCertificatesResponse wrapper for the ListCertificates operation +type ListCertificatesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []Certificate instance + Items []Certificate `presentIn:"body"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListCertificatesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancer_healths_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancer_healths_request_response.go new file mode 100644 index 000000000..959153da0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancer_healths_request_response.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListLoadBalancerHealthsRequest wrapper for the ListLoadBalancerHealths operation +type ListLoadBalancerHealthsRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment containing the load balancers to return health status information for. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + // Example: `3` + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListLoadBalancerHealthsRequest) String() string { + return common.PointerString(request) +} + +// ListLoadBalancerHealthsResponse wrapper for the ListLoadBalancerHealths operation +type ListLoadBalancerHealthsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []LoadBalancerHealthSummary instance + Items []LoadBalancerHealthSummary `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListLoadBalancerHealthsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancers_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancers_request_response.go new file mode 100644 index 000000000..608697685 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_load_balancers_request_response.go @@ -0,0 +1,117 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListLoadBalancersRequest wrapper for the ListLoadBalancers operation +type ListLoadBalancersRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment containing the load balancers to list. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + // Example: `3` + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The level of detail to return for each result. Can be `full` or `simple`. + // Example: `full` + Detail *string `mandatory:"false" contributesTo:"query" name:"detail"` + + // The field to sort by. Only one sort order may be provided. Time created is default ordered as descending. Display name is default ordered as ascending. + SortBy ListLoadBalancersSortByEnum `mandatory:"false" contributesTo:"query" name:"sortBy" omitEmpty:"true"` + + // The sort order to use, either 'asc' or 'desc' + SortOrder ListLoadBalancersSortOrderEnum `mandatory:"false" contributesTo:"query" name:"sortOrder" omitEmpty:"true"` + + // A filter to only return resources that match the given display name exactly. + DisplayName *string `mandatory:"false" contributesTo:"query" name:"displayName"` + + // A filter to only return resources that match the given lifecycle state. + LifecycleState LoadBalancerLifecycleStateEnum `mandatory:"false" contributesTo:"query" name:"lifecycleState" omitEmpty:"true"` +} + +func (request ListLoadBalancersRequest) String() string { + return common.PointerString(request) +} + +// ListLoadBalancersResponse wrapper for the ListLoadBalancers operation +type ListLoadBalancersResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []LoadBalancer instance + Items []LoadBalancer `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListLoadBalancersResponse) String() string { + return common.PointerString(response) +} + +// ListLoadBalancersSortByEnum Enum with underlying type: string +type ListLoadBalancersSortByEnum string + +// Set of constants representing the allowable values for ListLoadBalancersSortBy +const ( + ListLoadBalancersSortByTimecreated ListLoadBalancersSortByEnum = "TIMECREATED" + ListLoadBalancersSortByDisplayname ListLoadBalancersSortByEnum = "DISPLAYNAME" +) + +var mappingListLoadBalancersSortBy = map[string]ListLoadBalancersSortByEnum{ + "TIMECREATED": ListLoadBalancersSortByTimecreated, + "DISPLAYNAME": ListLoadBalancersSortByDisplayname, +} + +// GetListLoadBalancersSortByEnumValues Enumerates the set of values for ListLoadBalancersSortBy +func GetListLoadBalancersSortByEnumValues() []ListLoadBalancersSortByEnum { + values := make([]ListLoadBalancersSortByEnum, 0) + for _, v := range mappingListLoadBalancersSortBy { + values = append(values, v) + } + return values +} + +// ListLoadBalancersSortOrderEnum Enum with underlying type: string +type ListLoadBalancersSortOrderEnum string + +// Set of constants representing the allowable values for ListLoadBalancersSortOrder +const ( + ListLoadBalancersSortOrderAsc ListLoadBalancersSortOrderEnum = "ASC" + ListLoadBalancersSortOrderDesc ListLoadBalancersSortOrderEnum = "DESC" +) + +var mappingListLoadBalancersSortOrder = map[string]ListLoadBalancersSortOrderEnum{ + "ASC": ListLoadBalancersSortOrderAsc, + "DESC": ListLoadBalancersSortOrderDesc, +} + +// GetListLoadBalancersSortOrderEnumValues Enumerates the set of values for ListLoadBalancersSortOrder +func GetListLoadBalancersSortOrderEnumValues() []ListLoadBalancersSortOrderEnum { + values := make([]ListLoadBalancersSortOrderEnum, 0) + for _, v := range mappingListLoadBalancersSortOrder { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_policies_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_policies_request_response.go new file mode 100644 index 000000000..197f32e5a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_policies_request_response.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListPoliciesRequest wrapper for the ListPolicies operation +type ListPoliciesRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment containing the load balancer policies to list. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + // Example: `3` + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListPoliciesRequest) String() string { + return common.PointerString(request) +} + +// ListPoliciesResponse wrapper for the ListPolicies operation +type ListPoliciesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []LoadBalancerPolicy instance + Items []LoadBalancerPolicy `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListPoliciesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_protocols_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_protocols_request_response.go new file mode 100644 index 000000000..d6e9c4e30 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_protocols_request_response.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListProtocolsRequest wrapper for the ListProtocols operation +type ListProtocolsRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment containing the load balancer protocols to list. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + // Example: `3` + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListProtocolsRequest) String() string { + return common.PointerString(request) +} + +// ListProtocolsResponse wrapper for the ListProtocols operation +type ListProtocolsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []LoadBalancerProtocol instance + Items []LoadBalancerProtocol `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListProtocolsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_shapes_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_shapes_request_response.go new file mode 100644 index 000000000..0db13f617 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_shapes_request_response.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListShapesRequest wrapper for the ListShapes operation +type ListShapesRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment containing the load balancer shapes to list. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + // Example: `3` + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListShapesRequest) String() string { + return common.PointerString(request) +} + +// ListShapesResponse wrapper for the ListShapes operation +type ListShapesResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []LoadBalancerShape instance + Items []LoadBalancerShape `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListShapesResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_work_requests_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_work_requests_request_response.go new file mode 100644 index 000000000..13018c150 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/list_work_requests_request_response.go @@ -0,0 +1,55 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListWorkRequestsRequest wrapper for the ListWorkRequests operation +type ListWorkRequestsRequest struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the work requests to retrieve. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // The maximum number of items to return in a paginated "List" call. + // Example: `500` + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The value of the `opc-next-page` response header from the previous "List" call. + // Example: `3` + Page *string `mandatory:"false" contributesTo:"query" name:"page"` +} + +func (request ListWorkRequestsRequest) String() string { + return common.PointerString(request) +} + +// ListWorkRequestsResponse wrapper for the ListWorkRequests operation +type ListWorkRequestsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []WorkRequest instance + Items []WorkRequest `presentIn:"body"` + + // For pagination of a list of items. When paging through a list, if this header appears in the response, + // then a partial list might have been returned. Include this value as the `page` parameter for the + // subsequent GET request to get the next batch of items. + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListWorkRequestsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener.go new file mode 100644 index 000000000..31110fd5e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener.go @@ -0,0 +1,42 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Listener The listener's configuration. +// For more information on backend set configuration, see +// Managing Load Balancer Listeners (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managinglisteners.htm). +type Listener struct { + + // The name of the associated backend set. + DefaultBackendSetName *string `mandatory:"true" json:"defaultBackendSetName"` + + // A friendly name for the listener. It must be unique and it cannot be changed. + // Example: `My listener` + Name *string `mandatory:"true" json:"name"` + + // The communication port for the listener. + // Example: `80` + Port *int `mandatory:"true" json:"port"` + + // The protocol on which the listener accepts connection requests. + // To get a list of valid protocols, use the ListProtocols + // operation. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + SslConfiguration *SslConfiguration `mandatory:"false" json:"sslConfiguration"` +} + +func (m Listener) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener_details.go new file mode 100644 index 000000000..15b4e5d9a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/listener_details.go @@ -0,0 +1,36 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ListenerDetails The listener's configuration details. +type ListenerDetails struct { + + // The name of the associated backend set. + DefaultBackendSetName *string `mandatory:"true" json:"defaultBackendSetName"` + + // The communication port for the listener. + // Example: `80` + Port *int `mandatory:"true" json:"port"` + + // The protocol on which the listener accepts connection requests. + // To get a list of valid protocols, use the ListProtocols + // operation. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + SslConfiguration *SslConfigurationDetails `mandatory:"false" json:"sslConfiguration"` +} + +func (m ListenerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer.go new file mode 100644 index 000000000..bf621e4a9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer.go @@ -0,0 +1,104 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LoadBalancer The properties that define a load balancer. For more information, see +// Managing a Load Balancer (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/managingloadbalancer.htm). +// To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +// For information about endpoints and signing API requests, see +// About the API (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm). For information about available SDKs and tools, see +// SDKS and Other Tools (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdks.htm). +type LoadBalancer struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the compartment containing the load balancer. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // A user-friendly name. It does not have to be unique, and it is changeable. + // Example: `My load balancer` + DisplayName *string `mandatory:"true" json:"displayName"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer. + Id *string `mandatory:"true" json:"id"` + + // The current state of the load balancer. + LifecycleState LoadBalancerLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // A template that determines the total pre-provisioned bandwidth (ingress plus egress). + // To get a list of available shapes, use the ListShapes + // operation. + // Example: `100Mbps` + ShapeName *string `mandatory:"true" json:"shapeName"` + + // The date and time the load balancer was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + BackendSets map[string]BackendSet `mandatory:"false" json:"backendSets"` + + Certificates map[string]Certificate `mandatory:"false" json:"certificates"` + + // An array of IP addresses. + IpAddresses []IpAddress `mandatory:"false" json:"ipAddresses"` + + // Whether the load balancer has a VCN-local (private) IP address. + // If "true", the service assigns a private IP address to the load balancer. The load balancer requires only one subnet + // to host both the primary and secondary load balancers. The private IP address is local to the subnet. The load balancer + // is accessible only from within the VCN that contains the associated subnet, or as further restricted by your security + // list rules. The load balancer can route traffic to any backend server that is reachable from the VCN. + // For a private load balancer, both the primary and secondary load balancer hosts are within the same Availability Domain. + // If "false", the service assigns a public IP address to the load balancer. A load balancer with a public IP address + // requires two subnets, each in a different Availability Domain. One subnet hosts the primary load balancer and the other + // hosts the secondary (standby) load balancer. A public load balancer is accessible from the internet, depending on your + // VCN's security list rules (https://docs.us-phoenix-1.oraclecloud.com/Content/Network/Concepts/securitylists.htm). + IsPrivate *bool `mandatory:"false" json:"isPrivate"` + + Listeners map[string]Listener `mandatory:"false" json:"listeners"` + + // An array of subnet OCIDs (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). + SubnetIds []string `mandatory:"false" json:"subnetIds"` +} + +func (m LoadBalancer) String() string { + return common.PointerString(m) +} + +// LoadBalancerLifecycleStateEnum Enum with underlying type: string +type LoadBalancerLifecycleStateEnum string + +// Set of constants representing the allowable values for LoadBalancerLifecycleState +const ( + LoadBalancerLifecycleStateCreating LoadBalancerLifecycleStateEnum = "CREATING" + LoadBalancerLifecycleStateFailed LoadBalancerLifecycleStateEnum = "FAILED" + LoadBalancerLifecycleStateActive LoadBalancerLifecycleStateEnum = "ACTIVE" + LoadBalancerLifecycleStateDeleting LoadBalancerLifecycleStateEnum = "DELETING" + LoadBalancerLifecycleStateDeleted LoadBalancerLifecycleStateEnum = "DELETED" +) + +var mappingLoadBalancerLifecycleState = map[string]LoadBalancerLifecycleStateEnum{ + "CREATING": LoadBalancerLifecycleStateCreating, + "FAILED": LoadBalancerLifecycleStateFailed, + "ACTIVE": LoadBalancerLifecycleStateActive, + "DELETING": LoadBalancerLifecycleStateDeleting, + "DELETED": LoadBalancerLifecycleStateDeleted, +} + +// GetLoadBalancerLifecycleStateEnumValues Enumerates the set of values for LoadBalancerLifecycleState +func GetLoadBalancerLifecycleStateEnumValues() []LoadBalancerLifecycleStateEnum { + values := make([]LoadBalancerLifecycleStateEnum, 0) + for _, v := range mappingLoadBalancerLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health.go new file mode 100644 index 000000000..ab7de4a9d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health.go @@ -0,0 +1,82 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LoadBalancerHealth The health status details for the specified load balancer. +// This object does not explicitly enumerate backend sets with a status of `OK`. However, they are included in the +// `totalBackendSetCount` sum. +type LoadBalancerHealth struct { + + // A list of backend sets that are currently in the `CRITICAL` health state. The list identifies each backend set by the + // friendly name you assigned when you created it. + // Example: `My_backend_set` + CriticalStateBackendSetNames []string `mandatory:"true" json:"criticalStateBackendSetNames"` + + // The overall health status of the load balancer. + // * **OK:** All backend sets associated with the load balancer return a status of `OK`. + // * **WARNING:** At least one of the backend sets associated with the load balancer returns a status of `WARNING`, + // no backend sets return a status of `CRITICAL`, and the load balancer life cycle state is `ACTIVE`. + // * **CRITICAL:** One or more of the backend sets associated with the load balancer return a status of `CRITICAL`. + // * **UNKNOWN:** If any one of the following conditions is true: + // * The load balancer life cycle state is not `ACTIVE`. + // * No backend sets are defined for the load balancer. + // * More than half of the backend sets associated with the load balancer return a status of `UNKNOWN`, none of the backend + // sets return a status of `WARNING` or `CRITICAL`, and the load balancer life cycle state is `ACTIVE`. + // * The system could not retrieve metrics for any reason. + Status LoadBalancerHealthStatusEnum `mandatory:"true" json:"status"` + + // The total number of backend sets associated with this load balancer. + // Example: `4` + TotalBackendSetCount *int `mandatory:"true" json:"totalBackendSetCount"` + + // A list of backend sets that are currently in the `UNKNOWN` health state. The list identifies each backend set by the + // friendly name you assigned when you created it. + // Example: `Backend_set2` + UnknownStateBackendSetNames []string `mandatory:"true" json:"unknownStateBackendSetNames"` + + // A list of backend sets that are currently in the `WARNING` health state. The list identifies each backend set by the + // friendly name you assigned when you created it. + // Example: `Backend_set3` + WarningStateBackendSetNames []string `mandatory:"true" json:"warningStateBackendSetNames"` +} + +func (m LoadBalancerHealth) String() string { + return common.PointerString(m) +} + +// LoadBalancerHealthStatusEnum Enum with underlying type: string +type LoadBalancerHealthStatusEnum string + +// Set of constants representing the allowable values for LoadBalancerHealthStatus +const ( + LoadBalancerHealthStatusOk LoadBalancerHealthStatusEnum = "OK" + LoadBalancerHealthStatusWarning LoadBalancerHealthStatusEnum = "WARNING" + LoadBalancerHealthStatusCritical LoadBalancerHealthStatusEnum = "CRITICAL" + LoadBalancerHealthStatusUnknown LoadBalancerHealthStatusEnum = "UNKNOWN" +) + +var mappingLoadBalancerHealthStatus = map[string]LoadBalancerHealthStatusEnum{ + "OK": LoadBalancerHealthStatusOk, + "WARNING": LoadBalancerHealthStatusWarning, + "CRITICAL": LoadBalancerHealthStatusCritical, + "UNKNOWN": LoadBalancerHealthStatusUnknown, +} + +// GetLoadBalancerHealthStatusEnumValues Enumerates the set of values for LoadBalancerHealthStatus +func GetLoadBalancerHealthStatusEnumValues() []LoadBalancerHealthStatusEnum { + values := make([]LoadBalancerHealthStatusEnum, 0) + for _, v := range mappingLoadBalancerHealthStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health_summary.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health_summary.go new file mode 100644 index 000000000..0ff51e894 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_health_summary.go @@ -0,0 +1,64 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LoadBalancerHealthSummary A health status summary for the specified load balancer. +type LoadBalancerHealthSummary struct { + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer the health status is associated with. + LoadBalancerId *string `mandatory:"true" json:"loadBalancerId"` + + // The overall health status of the load balancer. + // * **OK:** All backend sets associated with the load balancer return a status of `OK`. + // * **WARNING:** At least one of the backend sets associated with the load balancer returns a status of `WARNING`, + // no backend sets return a status of `CRITICAL`, and the load balancer life cycle state is `ACTIVE`. + // * **CRITICAL:** One or more of the backend sets associated with the load balancer return a status of `CRITICAL`. + // * **UNKNOWN:** If any one of the following conditions is true: + // * The load balancer life cycle state is not `ACTIVE`. + // * No backend sets are defined for the load balancer. + // * More than half of the backend sets associated with the load balancer return a status of `UNKNOWN`, none of the backend + // sets return a status of `WARNING` or `CRITICAL`, and the load balancer life cycle state is `ACTIVE`. + // * The system could not retrieve metrics for any reason. + Status LoadBalancerHealthSummaryStatusEnum `mandatory:"true" json:"status"` +} + +func (m LoadBalancerHealthSummary) String() string { + return common.PointerString(m) +} + +// LoadBalancerHealthSummaryStatusEnum Enum with underlying type: string +type LoadBalancerHealthSummaryStatusEnum string + +// Set of constants representing the allowable values for LoadBalancerHealthSummaryStatus +const ( + LoadBalancerHealthSummaryStatusOk LoadBalancerHealthSummaryStatusEnum = "OK" + LoadBalancerHealthSummaryStatusWarning LoadBalancerHealthSummaryStatusEnum = "WARNING" + LoadBalancerHealthSummaryStatusCritical LoadBalancerHealthSummaryStatusEnum = "CRITICAL" + LoadBalancerHealthSummaryStatusUnknown LoadBalancerHealthSummaryStatusEnum = "UNKNOWN" +) + +var mappingLoadBalancerHealthSummaryStatus = map[string]LoadBalancerHealthSummaryStatusEnum{ + "OK": LoadBalancerHealthSummaryStatusOk, + "WARNING": LoadBalancerHealthSummaryStatusWarning, + "CRITICAL": LoadBalancerHealthSummaryStatusCritical, + "UNKNOWN": LoadBalancerHealthSummaryStatusUnknown, +} + +// GetLoadBalancerHealthSummaryStatusEnumValues Enumerates the set of values for LoadBalancerHealthSummaryStatus +func GetLoadBalancerHealthSummaryStatusEnumValues() []LoadBalancerHealthSummaryStatusEnum { + values := make([]LoadBalancerHealthSummaryStatusEnum, 0) + for _, v := range mappingLoadBalancerHealthSummaryStatus { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_policy.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_policy.go new file mode 100644 index 000000000..610a970b8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_policy.go @@ -0,0 +1,26 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LoadBalancerPolicy A policy that determines how traffic is distributed among backend servers. +// For more information on load balancing policies, see +// How Load Balancing Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Reference/lbpolicies.htm). +type LoadBalancerPolicy struct { + + // The name of the load balancing policy. + Name *string `mandatory:"true" json:"name"` +} + +func (m LoadBalancerPolicy) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_protocol.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_protocol.go new file mode 100644 index 000000000..91be70bb7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_protocol.go @@ -0,0 +1,24 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LoadBalancerProtocol The protocol that defines the type of traffic accepted by a listener. +type LoadBalancerProtocol struct { + + // The name of the protocol. + Name *string `mandatory:"true" json:"name"` +} + +func (m LoadBalancerProtocol) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_shape.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_shape.go new file mode 100644 index 000000000..de82ebb47 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/load_balancer_shape.go @@ -0,0 +1,27 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// LoadBalancerShape A shape is a template that determines the total pre-provisioned bandwidth (ingress plus egress) for the +// load balancer. +// Note that the pre-provisioned maximum capacity applies to aggregated connections, not to a single client +// attempting to use the full bandwidth. +type LoadBalancerShape struct { + + // The name of the shape. + Name *string `mandatory:"true" json:"name"` +} + +func (m LoadBalancerShape) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/loadbalancer_client.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/loadbalancer_client.go new file mode 100644 index 000000000..cb408565e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/loadbalancer_client.go @@ -0,0 +1,656 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//LoadBalancerClient a client for LoadBalancer +type LoadBalancerClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +// NewLoadBalancerClientWithConfigurationProvider Creates a new default LoadBalancer client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewLoadBalancerClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client LoadBalancerClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + + client = LoadBalancerClient{BaseClient: baseClient} + client.BasePath = "20170115" + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *LoadBalancerClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "iaas", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *LoadBalancerClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *LoadBalancerClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// CreateBackend Adds a backend server to a backend set. +func (client LoadBalancerClient) CreateBackend(ctx context.Context, request CreateBackendRequest) (response CreateBackendResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/backends", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateBackendSet Adds a backend set to a load balancer. +func (client LoadBalancerClient) CreateBackendSet(ctx context.Context, request CreateBackendSetRequest) (response CreateBackendSetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/loadBalancers/{loadBalancerId}/backendSets", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateCertificate Creates an asynchronous request to add an SSL certificate. +func (client LoadBalancerClient) CreateCertificate(ctx context.Context, request CreateCertificateRequest) (response CreateCertificateResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/loadBalancers/{loadBalancerId}/certificates", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateListener Adds a listener to a load balancer. +func (client LoadBalancerClient) CreateListener(ctx context.Context, request CreateListenerRequest) (response CreateListenerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/loadBalancers/{loadBalancerId}/listeners", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateLoadBalancer Creates a new load balancer in the specified compartment. For general information about load balancers, +// see Overview of the Load Balancing Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Concepts/balanceoverview.htm). +// For the purposes of access control, you must provide the OCID of the compartment where you want +// the load balancer to reside. Notice that the load balancer doesn't have to be in the same compartment as the VCN +// or backend set. If you're not sure which compartment to use, put the load balancer in the same compartment as the VCN. +// For information about access control and compartments, see +// Overview of the IAM Service (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/overview.htm). +// You must specify a display name for the load balancer. It does not have to be unique, and you can change it. +// For information about Availability Domains, see +// Regions and Availability Domains (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm). +// To get a list of Availability Domains, use the `ListAvailabilityDomains` operation +// in the Identity and Access Management Service API. +// All Oracle Cloud Infrastructure resources, including load balancers, get an Oracle-assigned, +// unique ID called an Oracle Cloud Identifier (OCID). When you create a resource, you can find its OCID +// in the response. You can also retrieve a resource's OCID by using a List API operation on that resource type, +// or by viewing the resource in the Console. Fore more information, see +// Resource Identifiers (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm). +// After you send your request, the new object's state will temporarily be PROVISIONING. Before using the +// object, first make sure its state has changed to RUNNING. +// When you create a load balancer, the system assigns an IP address. +// To get the IP address, use the GetLoadBalancer operation. +func (client LoadBalancerClient) CreateLoadBalancer(ctx context.Context, request CreateLoadBalancerRequest) (response CreateLoadBalancerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/loadBalancers", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteBackend Removes a backend server from a given load balancer and backend set. +func (client LoadBalancerClient) DeleteBackend(ctx context.Context, request DeleteBackendRequest) (response DeleteBackendResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/backends/{backendName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteBackendSet Deletes the specified backend set. Note that deleting a backend set removes its backend servers from the load balancer. +// Before you can delete a backend set, you must remove it from any active listeners. +func (client LoadBalancerClient) DeleteBackendSet(ctx context.Context, request DeleteBackendSetRequest) (response DeleteBackendSetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteCertificate Deletes an SSL certificate from a load balancer. +func (client LoadBalancerClient) DeleteCertificate(ctx context.Context, request DeleteCertificateRequest) (response DeleteCertificateResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/loadBalancers/{loadBalancerId}/certificates/{certificateName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteListener Deletes a listener from a load balancer. +func (client LoadBalancerClient) DeleteListener(ctx context.Context, request DeleteListenerRequest) (response DeleteListenerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/loadBalancers/{loadBalancerId}/listeners/{listenerName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteLoadBalancer Stops a load balancer and removes it from service. +func (client LoadBalancerClient) DeleteLoadBalancer(ctx context.Context, request DeleteLoadBalancerRequest) (response DeleteLoadBalancerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/loadBalancers/{loadBalancerId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBackend Gets the specified backend server's configuration information. +func (client LoadBalancerClient) GetBackend(ctx context.Context, request GetBackendRequest) (response GetBackendResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/backends/{backendName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBackendHealth Gets the current health status of the specified backend server. +func (client LoadBalancerClient) GetBackendHealth(ctx context.Context, request GetBackendHealthRequest) (response GetBackendHealthResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/backends/{backendName}/health", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBackendSet Gets the specified backend set's configuration information. +func (client LoadBalancerClient) GetBackendSet(ctx context.Context, request GetBackendSetRequest) (response GetBackendSetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBackendSetHealth Gets the health status for the specified backend set. +func (client LoadBalancerClient) GetBackendSetHealth(ctx context.Context, request GetBackendSetHealthRequest) (response GetBackendSetHealthResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/health", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetHealthChecker Gets the health check policy information for a given load balancer and backend set. +func (client LoadBalancerClient) GetHealthChecker(ctx context.Context, request GetHealthCheckerRequest) (response GetHealthCheckerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/healthChecker", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetLoadBalancer Gets the specified load balancer's configuration information. +func (client LoadBalancerClient) GetLoadBalancer(ctx context.Context, request GetLoadBalancerRequest) (response GetLoadBalancerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetLoadBalancerHealth Gets the health status for the specified load balancer. +func (client LoadBalancerClient) GetLoadBalancerHealth(ctx context.Context, request GetLoadBalancerHealthRequest) (response GetLoadBalancerHealthResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/health", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetWorkRequest Gets the details of a work request. +func (client LoadBalancerClient) GetWorkRequest(ctx context.Context, request GetWorkRequestRequest) (response GetWorkRequestResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancerWorkRequests/{workRequestId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListBackendSets Lists all backend sets associated with a given load balancer. +func (client LoadBalancerClient) ListBackendSets(ctx context.Context, request ListBackendSetsRequest) (response ListBackendSetsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListBackends Lists the backend servers for a given load balancer and backend set. +func (client LoadBalancerClient) ListBackends(ctx context.Context, request ListBackendsRequest) (response ListBackendsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/backends", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListCertificates Lists all SSL certificates associated with a given load balancer. +func (client LoadBalancerClient) ListCertificates(ctx context.Context, request ListCertificatesRequest) (response ListCertificatesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/certificates", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListLoadBalancerHealths Lists the summary health statuses for all load balancers in the specified compartment. +func (client LoadBalancerClient) ListLoadBalancerHealths(ctx context.Context, request ListLoadBalancerHealthsRequest) (response ListLoadBalancerHealthsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancerHealths", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListLoadBalancers Lists all load balancers in the specified compartment. +func (client LoadBalancerClient) ListLoadBalancers(ctx context.Context, request ListLoadBalancersRequest) (response ListLoadBalancersResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListPolicies Lists the available load balancer policies. +func (client LoadBalancerClient) ListPolicies(ctx context.Context, request ListPoliciesRequest) (response ListPoliciesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancerPolicies", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListProtocols Lists all supported traffic protocols. +func (client LoadBalancerClient) ListProtocols(ctx context.Context, request ListProtocolsRequest) (response ListProtocolsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancerProtocols", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListShapes Lists the valid load balancer shapes. +func (client LoadBalancerClient) ListShapes(ctx context.Context, request ListShapesRequest) (response ListShapesResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancerShapes", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListWorkRequests Lists the work requests for a given load balancer. +func (client LoadBalancerClient) ListWorkRequests(ctx context.Context, request ListWorkRequestsRequest) (response ListWorkRequestsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/loadBalancers/{loadBalancerId}/workRequests", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateBackend Updates the configuration of a backend server within the specified backend set. +func (client LoadBalancerClient) UpdateBackend(ctx context.Context, request UpdateBackendRequest) (response UpdateBackendResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/backends/{backendName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateBackendSet Updates a backend set. +func (client LoadBalancerClient) UpdateBackendSet(ctx context.Context, request UpdateBackendSetRequest) (response UpdateBackendSetResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateHealthChecker Updates the health check policy for a given load balancer and backend set. +func (client LoadBalancerClient) UpdateHealthChecker(ctx context.Context, request UpdateHealthCheckerRequest) (response UpdateHealthCheckerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/loadBalancers/{loadBalancerId}/backendSets/{backendSetName}/healthChecker", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateListener Updates a listener for a given load balancer. +func (client LoadBalancerClient) UpdateListener(ctx context.Context, request UpdateListenerRequest) (response UpdateListenerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/loadBalancers/{loadBalancerId}/listeners/{listenerName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateLoadBalancer Updates a load balancer's configuration. +func (client LoadBalancerClient) UpdateLoadBalancer(ctx context.Context, request UpdateLoadBalancerRequest) (response UpdateLoadBalancerResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/loadBalancers/{loadBalancerId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/session_persistence_configuration_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/session_persistence_configuration_details.go new file mode 100644 index 000000000..a83e81d99 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/session_persistence_configuration_details.go @@ -0,0 +1,37 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// SessionPersistenceConfigurationDetails The configuration details for implementing session persistence. Session persistence enables the Load Balancing +// Service to direct any number of requests that originate from a single logical client to a single backend web server. +// For more information, see Session Persistence (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Reference/sessionpersistence.htm). +// To disable session persistence on a running load balancer, use the +// UpdateBackendSet operation and specify "null" for the +// `SessionPersistenceConfigurationDetails` object. +// Example: `SessionPersistenceConfigurationDetails: null` +type SessionPersistenceConfigurationDetails struct { + + // The name of the cookie used to detect a session initiated by the backend server. Use '*' to specify + // that any cookie set by the backend causes the session to persist. + // Example: `myCookieName` + CookieName *string `mandatory:"true" json:"cookieName"` + + // Whether the load balancer is prevented from directing traffic from a persistent session client to + // a different backend server if the original server is unavailable. Defaults to false. + // Example: `true` + DisableFallback *bool `mandatory:"false" json:"disableFallback"` +} + +func (m SessionPersistenceConfigurationDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration.go new file mode 100644 index 000000000..5f9c102dc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration.go @@ -0,0 +1,36 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// SslConfiguration A listener's SSL handling configuration. +// To use SSL, a listener must be associated with a Certificate. +type SslConfiguration struct { + + // A friendly name for the certificate bundle. It must be unique and it cannot be changed. + // Valid certificate bundle names include only alphanumeric characters, dashes, and underscores. + // Certificate bundle names cannot contain spaces. Avoid entering confidential information. + // Example: `My_certificate_bundle` + CertificateName *string `mandatory:"true" json:"certificateName"` + + // The maximum depth for peer certificate chain verification. + // Example: `3` + VerifyDepth *int `mandatory:"true" json:"verifyDepth"` + + // Whether the load balancer listener should verify peer certificates. + // Example: `true` + VerifyPeerCertificate *bool `mandatory:"true" json:"verifyPeerCertificate"` +} + +func (m SslConfiguration) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration_details.go new file mode 100644 index 000000000..7b083fcf7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/ssl_configuration_details.go @@ -0,0 +1,35 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// SslConfigurationDetails The load balancer's SSL handling configuration details. +type SslConfigurationDetails struct { + + // A friendly name for the certificate bundle. It must be unique and it cannot be changed. + // Valid certificate bundle names include only alphanumeric characters, dashes, and underscores. + // Certificate bundle names cannot contain spaces. Avoid entering confidential information. + // Example: `My_certificate_bundle` + CertificateName *string `mandatory:"true" json:"certificateName"` + + // The maximum depth for peer certificate chain verification. + // Example: `3` + VerifyDepth *int `mandatory:"false" json:"verifyDepth"` + + // Whether the load balancer listener should verify peer certificates. + // Example: `true` + VerifyPeerCertificate *bool `mandatory:"false" json:"verifyPeerCertificate"` +} + +func (m SslConfigurationDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_details.go new file mode 100644 index 000000000..56efca6d9 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_details.go @@ -0,0 +1,44 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateBackendDetails The configuration details for updating a backend server. +type UpdateBackendDetails struct { + + // Whether the load balancer should treat this server as a backup unit. If `true`, the load balancer forwards no ingress + // traffic to this backend server unless all other backend servers not marked as "backup" fail the health check policy. + // Example: `true` + Backup *bool `mandatory:"true" json:"backup"` + + // Whether the load balancer should drain this server. Servers marked "drain" receive no new + // incoming traffic. + // Example: `true` + Drain *bool `mandatory:"true" json:"drain"` + + // Whether the load balancer should treat this server as offline. Offline servers receive no incoming + // traffic. + // Example: `true` + Offline *bool `mandatory:"true" json:"offline"` + + // The load balancing policy weight assigned to the server. Backend servers with a higher weight receive a larger + // proportion of incoming traffic. For example, a server weighted '3' receives 3 times the number of new connections + // as a server weighted '1'. + // For more information on load balancing policies, see + // How Load Balancing Policies Work (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Reference/lbpolicies.htm). + // Example: `3` + Weight *int `mandatory:"true" json:"weight"` +} + +func (m UpdateBackendDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_request_response.go new file mode 100644 index 000000000..0d9915a19 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_request_response.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateBackendRequest wrapper for the UpdateBackend operation +type UpdateBackendRequest struct { + + // Details for updating a backend server. + UpdateBackendDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set and server. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set associated with the backend server. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The IP address and port of the backend server to update. + // Example: `1.1.1.7:42` + BackendName *string `mandatory:"true" contributesTo:"path" name:"backendName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request UpdateBackendRequest) String() string { + return common.PointerString(request) +} + +// UpdateBackendResponse wrapper for the UpdateBackend operation +type UpdateBackendResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response UpdateBackendResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_details.go new file mode 100644 index 000000000..4da009e97 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_details.go @@ -0,0 +1,35 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateBackendSetDetails The configuration details for updating a load balancer backend set. +// For more information on backend set configuration, see +// Managing Backend Sets (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/tasks/managingbackendsets.htm). +type UpdateBackendSetDetails struct { + Backends []BackendDetails `mandatory:"true" json:"backends"` + + HealthChecker *HealthCheckerDetails `mandatory:"true" json:"healthChecker"` + + // The load balancer policy for the backend set. To get a list of available policies, use the + // ListPolicies operation. + // Example: `LEAST_CONNECTIONS` + Policy *string `mandatory:"true" json:"policy"` + + SessionPersistenceConfiguration *SessionPersistenceConfigurationDetails `mandatory:"false" json:"sessionPersistenceConfiguration"` + + SslConfiguration *SslConfigurationDetails `mandatory:"false" json:"sslConfiguration"` +} + +func (m UpdateBackendSetDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_request_response.go new file mode 100644 index 000000000..e099e1db4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_backend_set_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateBackendSetRequest wrapper for the UpdateBackendSet operation +type UpdateBackendSetRequest struct { + + // The details to update a backend set. + UpdateBackendSetDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the backend set. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set to update. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request UpdateBackendSetRequest) String() string { + return common.PointerString(request) +} + +// UpdateBackendSetResponse wrapper for the UpdateBackendSet operation +type UpdateBackendSetResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response UpdateBackendSetResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_details.go new file mode 100644 index 000000000..5e2e8cda8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_details.go @@ -0,0 +1,54 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateHealthCheckerDetails The health checker's configuration details. +type UpdateHealthCheckerDetails struct { + + // The interval between health checks, in milliseconds. + // Example: `30000` + IntervalInMillis *int `mandatory:"true" json:"intervalInMillis"` + + // The backend server port against which to run the health check. + // Example: `8080` + Port *int `mandatory:"true" json:"port"` + + // The protocol the health check must use; either HTTP or TCP. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + // A regular expression for parsing the response body from the backend server. + // Example: `^(500|40[1348])$` + ResponseBodyRegex *string `mandatory:"true" json:"responseBodyRegex"` + + // The number of retries to attempt before a backend server is considered "unhealthy". + // Example: `3` + Retries *int `mandatory:"true" json:"retries"` + + // The status code a healthy backend server should return. + // Example: `200` + ReturnCode *int `mandatory:"true" json:"returnCode"` + + // The maximum time, in milliseconds, to wait for a reply to a health check. A health check is successful only if a reply + // returns within this timeout period. + // Example: `6000` + TimeoutInMillis *int `mandatory:"true" json:"timeoutInMillis"` + + // The path against which to run the health check. + // Example: `/healthcheck` + UrlPath *string `mandatory:"false" json:"urlPath"` +} + +func (m UpdateHealthCheckerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_request_response.go new file mode 100644 index 000000000..54ddccbbe --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_health_checker_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateHealthCheckerRequest wrapper for the UpdateHealthChecker operation +type UpdateHealthCheckerRequest struct { + + // The health check policy configuration details. + UpdateHealthCheckerDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the health check policy to be updated. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the backend set associated with the health check policy to be retrieved. + // Example: `My_backend_set` + BackendSetName *string `mandatory:"true" contributesTo:"path" name:"backendSetName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request UpdateHealthCheckerRequest) String() string { + return common.PointerString(request) +} + +// UpdateHealthCheckerResponse wrapper for the UpdateHealthChecker operation +type UpdateHealthCheckerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response UpdateHealthCheckerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_details.go new file mode 100644 index 000000000..c935eac54 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_details.go @@ -0,0 +1,36 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateListenerDetails The configuration details for updating a listener. +type UpdateListenerDetails struct { + + // The name of the associated backend set. + DefaultBackendSetName *string `mandatory:"true" json:"defaultBackendSetName"` + + // The communication port for the listener. + // Example: `80` + Port *int `mandatory:"true" json:"port"` + + // The protocol on which the listener accepts connection requests. + // To get a list of valid protocols, use the ListProtocols + // operation. + // Example: `HTTP` + Protocol *string `mandatory:"true" json:"protocol"` + + SslConfiguration *SslConfigurationDetails `mandatory:"false" json:"sslConfiguration"` +} + +func (m UpdateListenerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_request_response.go new file mode 100644 index 000000000..b07a7a250 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_listener_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateListenerRequest wrapper for the UpdateListener operation +type UpdateListenerRequest struct { + + // Details to update a listener. + UpdateListenerDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer associated with the listener to update. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The name of the listener to update. + // Example: `My listener` + ListenerName *string `mandatory:"true" contributesTo:"path" name:"listenerName"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request UpdateListenerRequest) String() string { + return common.PointerString(request) +} + +// UpdateListenerResponse wrapper for the UpdateListener operation +type UpdateListenerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response UpdateListenerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_details.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_details.go new file mode 100644 index 000000000..8a66761f4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_details.go @@ -0,0 +1,26 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateLoadBalancerDetails Configuration details to update a load balancer. +type UpdateLoadBalancerDetails struct { + + // The user-friendly display name for the load balancer. It does not have to be unique, and it is changeable. + // Avoid entering confidential information. + // Example: `My load balancer` + DisplayName *string `mandatory:"true" json:"displayName"` +} + +func (m UpdateLoadBalancerDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_request_response.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_request_response.go new file mode 100644 index 000000000..15101ba1c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/update_load_balancer_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateLoadBalancerRequest wrapper for the UpdateLoadBalancer operation +type UpdateLoadBalancerRequest struct { + + // The details for updating a load balancer's configuration. + UpdateLoadBalancerDetails `contributesTo:"body"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer to update. + LoadBalancerId *string `mandatory:"true" contributesTo:"path" name:"loadBalancerId"` + + // The unique Oracle-assigned identifier for the request. If you need to contact Oracle about a + // particular request, please provide the request ID. + OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"` + + // A token that uniquely identifies a request so it can be retried in case of a timeout or + // server error without risk of executing that same action again. Retry tokens expire after 24 + // hours, but can be invalidated before then due to conflicting operations (e.g., if a resource + // has been deleted and purged from the system, then a retry of the original creation request + // may be rejected). + OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"` +} + +func (request UpdateLoadBalancerRequest) String() string { + return common.PointerString(request) +} + +// UpdateLoadBalancerResponse wrapper for the UpdateLoadBalancer operation +type UpdateLoadBalancerResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about + // a particular request, please provide the request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + OpcWorkRequestId *string `presentIn:"header" name:"opc-work-request-id"` +} + +func (response UpdateLoadBalancerResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request.go new file mode 100644 index 000000000..0a8a007f4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request.go @@ -0,0 +1,82 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// WorkRequest Many of the API requests you use to create and configure load balancing do not take effect immediately. +// In these cases, the request spawns an asynchronous work flow to fulfill the request. WorkRequest objects provide visibility +// for in-progress work flows. +// For more information about work requests, see Viewing the State of a Work Request (https://docs.us-phoenix-1.oraclecloud.com/Content/Balance/Tasks/viewingworkrequest.htm). +type WorkRequest struct { + ErrorDetails []WorkRequestError `mandatory:"true" json:"errorDetails"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the work request. + Id *string `mandatory:"true" json:"id"` + + // The current state of the work request. + LifecycleState WorkRequestLifecycleStateEnum `mandatory:"true" json:"lifecycleState"` + + // The OCID (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/identifiers.htm) of the load balancer with which the work request + // is associated. + LoadBalancerId *string `mandatory:"true" json:"loadBalancerId"` + + // A collection of data, related to the load balancer provisioning process, that helps with debugging in the event of failure. + // Possible data elements include: + // - workflow name + // - event ID + // - work request ID + // - load balancer ID + // - workflow completion message + Message *string `mandatory:"true" json:"message"` + + // The date and time the work request was created, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeAccepted *common.SDKTime `mandatory:"true" json:"timeAccepted"` + + // The type of action the work request represents. + Type *string `mandatory:"true" json:"type"` + + // The date and time the work request was completed, in the format defined by RFC3339. + // Example: `2016-08-25T21:10:29.600Z` + TimeFinished *common.SDKTime `mandatory:"false" json:"timeFinished"` +} + +func (m WorkRequest) String() string { + return common.PointerString(m) +} + +// WorkRequestLifecycleStateEnum Enum with underlying type: string +type WorkRequestLifecycleStateEnum string + +// Set of constants representing the allowable values for WorkRequestLifecycleState +const ( + WorkRequestLifecycleStateAccepted WorkRequestLifecycleStateEnum = "ACCEPTED" + WorkRequestLifecycleStateInProgress WorkRequestLifecycleStateEnum = "IN_PROGRESS" + WorkRequestLifecycleStateFailed WorkRequestLifecycleStateEnum = "FAILED" + WorkRequestLifecycleStateSucceeded WorkRequestLifecycleStateEnum = "SUCCEEDED" +) + +var mappingWorkRequestLifecycleState = map[string]WorkRequestLifecycleStateEnum{ + "ACCEPTED": WorkRequestLifecycleStateAccepted, + "IN_PROGRESS": WorkRequestLifecycleStateInProgress, + "FAILED": WorkRequestLifecycleStateFailed, + "SUCCEEDED": WorkRequestLifecycleStateSucceeded, +} + +// GetWorkRequestLifecycleStateEnumValues Enumerates the set of values for WorkRequestLifecycleState +func GetWorkRequestLifecycleStateEnumValues() []WorkRequestLifecycleStateEnum { + values := make([]WorkRequestLifecycleStateEnum, 0) + for _, v := range mappingWorkRequestLifecycleState { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request_error.go b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request_error.go new file mode 100644 index 000000000..6b755f4b1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/loadbalancer/work_request_error.go @@ -0,0 +1,48 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Load Balancing Service API +// +// API for the Load Balancing Service +// + +package loadbalancer + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// WorkRequestError An object returned in the event of a work request error. +type WorkRequestError struct { + ErrorCode WorkRequestErrorErrorCodeEnum `mandatory:"true" json:"errorCode"` + + // A human-readable error string. + Message *string `mandatory:"true" json:"message"` +} + +func (m WorkRequestError) String() string { + return common.PointerString(m) +} + +// WorkRequestErrorErrorCodeEnum Enum with underlying type: string +type WorkRequestErrorErrorCodeEnum string + +// Set of constants representing the allowable values for WorkRequestErrorErrorCode +const ( + WorkRequestErrorErrorCodeBadInput WorkRequestErrorErrorCodeEnum = "BAD_INPUT" + WorkRequestErrorErrorCodeInternalError WorkRequestErrorErrorCodeEnum = "INTERNAL_ERROR" +) + +var mappingWorkRequestErrorErrorCode = map[string]WorkRequestErrorErrorCodeEnum{ + "BAD_INPUT": WorkRequestErrorErrorCodeBadInput, + "INTERNAL_ERROR": WorkRequestErrorErrorCodeInternalError, +} + +// GetWorkRequestErrorErrorCodeEnumValues Enumerates the set of values for WorkRequestErrorErrorCode +func GetWorkRequestErrorErrorCodeEnumValues() []WorkRequestErrorErrorCodeEnum { + values := make([]WorkRequestErrorErrorCodeEnum, 0) + for _, v := range mappingWorkRequestErrorErrorCode { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/abort_multipart_upload_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/abort_multipart_upload_request_response.go new file mode 100644 index 000000000..8858e1066 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/abort_multipart_upload_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// AbortMultipartUploadRequest wrapper for the AbortMultipartUpload operation +type AbortMultipartUploadRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The upload ID for a multipart upload. + UploadId *string `mandatory:"true" contributesTo:"query" name:"uploadId"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request AbortMultipartUploadRequest) String() string { + return common.PointerString(request) +} + +// AbortMultipartUploadResponse wrapper for the AbortMultipartUpload operation +type AbortMultipartUploadResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response AbortMultipartUploadResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket.go new file mode 100644 index 000000000..81462ba1a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket.go @@ -0,0 +1,73 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// Bucket To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type Bucket struct { + + // The namespace in which the bucket lives. + Namespace *string `mandatory:"true" json:"namespace"` + + // The name of the bucket. + Name *string `mandatory:"true" json:"name"` + + // The compartment ID in which the bucket is authorized. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Arbitrary string keys and values for user-defined metadata. + Metadata map[string]string `mandatory:"true" json:"metadata"` + + // The OCID of the user who created the bucket. + CreatedBy *string `mandatory:"true" json:"createdBy"` + + // The date and time at which the bucket was created. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The entity tag for the bucket. + Etag *string `mandatory:"true" json:"etag"` + + // The type of public access available on this bucket. Allows authenticated caller to access the bucket or + // contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + // when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + // When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + PublicAccessType BucketPublicAccessTypeEnum `mandatory:"false" json:"publicAccessType,omitempty"` +} + +func (m Bucket) String() string { + return common.PointerString(m) +} + +// BucketPublicAccessTypeEnum Enum with underlying type: string +type BucketPublicAccessTypeEnum string + +// Set of constants representing the allowable values for BucketPublicAccessType +const ( + BucketPublicAccessTypeNopublicaccess BucketPublicAccessTypeEnum = "NoPublicAccess" + BucketPublicAccessTypeObjectread BucketPublicAccessTypeEnum = "ObjectRead" +) + +var mappingBucketPublicAccessType = map[string]BucketPublicAccessTypeEnum{ + "NoPublicAccess": BucketPublicAccessTypeNopublicaccess, + "ObjectRead": BucketPublicAccessTypeObjectread, +} + +// GetBucketPublicAccessTypeEnumValues Enumerates the set of values for BucketPublicAccessType +func GetBucketPublicAccessTypeEnumValues() []BucketPublicAccessTypeEnum { + values := make([]BucketPublicAccessTypeEnum, 0) + for _, v := range mappingBucketPublicAccessType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket_summary.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket_summary.go new file mode 100644 index 000000000..028177a52 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/bucket_summary.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// BucketSummary To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type BucketSummary struct { + + // The namespace in which the bucket lives. + Namespace *string `mandatory:"true" json:"namespace"` + + // The name of the bucket. + Name *string `mandatory:"true" json:"name"` + + // The compartment ID in which the bucket is authorized. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // The OCID of the user who created the bucket. + CreatedBy *string `mandatory:"true" json:"createdBy"` + + // The date and time at which the bucket was created. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // The entity tag for the bucket. + Etag *string `mandatory:"true" json:"etag"` +} + +func (m BucketSummary) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_details.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_details.go new file mode 100644 index 000000000..c285f7383 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_details.go @@ -0,0 +1,30 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CommitMultipartUploadDetails To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type CommitMultipartUploadDetails struct { + + // The part numbers and ETags for the parts to be committed. + PartsToCommit []CommitMultipartUploadPartDetails `mandatory:"true" json:"partsToCommit"` + + // The part numbers for the parts to be excluded from the completed object. + // Each part created for this upload must be in either partsToExclude or partsToCommit, but cannot be in both. + PartsToExclude []int `mandatory:"false" json:"partsToExclude"` +} + +func (m CommitMultipartUploadDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_part_details.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_part_details.go new file mode 100644 index 000000000..a4d053b37 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_part_details.go @@ -0,0 +1,29 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CommitMultipartUploadPartDetails To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type CommitMultipartUploadPartDetails struct { + + // The part number for this part. + PartNum *int `mandatory:"true" json:"partNum"` + + // The ETag returned when this part was uploaded. + Etag *string `mandatory:"true" json:"etag"` +} + +func (m CommitMultipartUploadPartDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_request_response.go new file mode 100644 index 000000000..101834254 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/commit_multipart_upload_request_response.go @@ -0,0 +1,76 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CommitMultipartUploadRequest wrapper for the CommitMultipartUpload operation +type CommitMultipartUploadRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The upload ID for a multipart upload. + UploadId *string `mandatory:"true" contributesTo:"query" name:"uploadId"` + + // The part numbers and ETags for the parts you want to commit. + CommitMultipartUploadDetails `contributesTo:"body"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request CommitMultipartUploadRequest) String() string { + return common.PointerString(request) +} + +// CommitMultipartUploadResponse wrapper for the CommitMultipartUpload operation +type CommitMultipartUploadResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // Base-64 representation of the multipart object hash. + // The multipart object hash is calculated by taking the MD5 hashes of the parts passed to this call, + // concatenating the binary representation of those hashes in order of their part numbers, + // and then calculating the MD5 hash of the concatenated values. + OpcMultipartMd5 *string `presentIn:"header" name:"opc-multipart-md5"` + + // The entity tag for the object. + ETag *string `presentIn:"header" name:"etag"` + + // The time the object was last modified, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.29. + LastModified *common.SDKTime `presentIn:"header" name:"last-modified"` +} + +func (response CommitMultipartUploadResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_details.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_details.go new file mode 100644 index 000000000..b6be2982c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_details.go @@ -0,0 +1,62 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateBucketDetails To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type CreateBucketDetails struct { + + // The name of the bucket. Valid characters are uppercase or lowercase letters, + // numbers, and dashes. Bucket names must be unique within the namespace. + Name *string `mandatory:"true" json:"name"` + + // The ID of the compartment in which to create the bucket. + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + // Arbitrary string, up to 4KB, of keys and values for user-defined metadata. + Metadata map[string]string `mandatory:"false" json:"metadata"` + + // The type of public access available on this bucket. Allows authenticated caller to access the bucket or + // contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + // when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + // When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + PublicAccessType CreateBucketDetailsPublicAccessTypeEnum `mandatory:"false" json:"publicAccessType,omitempty"` +} + +func (m CreateBucketDetails) String() string { + return common.PointerString(m) +} + +// CreateBucketDetailsPublicAccessTypeEnum Enum with underlying type: string +type CreateBucketDetailsPublicAccessTypeEnum string + +// Set of constants representing the allowable values for CreateBucketDetailsPublicAccessType +const ( + CreateBucketDetailsPublicAccessTypeNopublicaccess CreateBucketDetailsPublicAccessTypeEnum = "NoPublicAccess" + CreateBucketDetailsPublicAccessTypeObjectread CreateBucketDetailsPublicAccessTypeEnum = "ObjectRead" +) + +var mappingCreateBucketDetailsPublicAccessType = map[string]CreateBucketDetailsPublicAccessTypeEnum{ + "NoPublicAccess": CreateBucketDetailsPublicAccessTypeNopublicaccess, + "ObjectRead": CreateBucketDetailsPublicAccessTypeObjectread, +} + +// GetCreateBucketDetailsPublicAccessTypeEnumValues Enumerates the set of values for CreateBucketDetailsPublicAccessType +func GetCreateBucketDetailsPublicAccessTypeEnumValues() []CreateBucketDetailsPublicAccessTypeEnum { + values := make([]CreateBucketDetailsPublicAccessTypeEnum, 0) + for _, v := range mappingCreateBucketDetailsPublicAccessType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_request_response.go new file mode 100644 index 000000000..00a7aa13c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_bucket_request_response.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateBucketRequest wrapper for the CreateBucket operation +type CreateBucketRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // Request object for creating a bucket. + CreateBucketDetails `contributesTo:"body"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request CreateBucketRequest) String() string { + return common.PointerString(request) +} + +// CreateBucketResponse wrapper for the CreateBucket operation +type CreateBucketResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Bucket instance + Bucket `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The entity tag for the bucket that was created. + ETag *string `presentIn:"header" name:"etag"` + + // The full path to the bucket that was created. + Location *string `presentIn:"header" name:"location"` +} + +func (response CreateBucketResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_details.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_details.go new file mode 100644 index 000000000..f21262d54 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_details.go @@ -0,0 +1,39 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreateMultipartUploadDetails To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type CreateMultipartUploadDetails struct { + + // the name of the object to which this multi-part upload is targetted. + Object *string `mandatory:"true" json:"object"` + + // the content type of the object to upload. + ContentType *string `mandatory:"false" json:"contentType"` + + // the content language of the object to upload. + ContentLanguage *string `mandatory:"false" json:"contentLanguage"` + + // the content encoding of the object to upload. + ContentEncoding *string `mandatory:"false" json:"contentEncoding"` + + // Arbitrary string keys and values for the user-defined metadata for the object. + // Keys must be in "opc-meta-*" format. + Metadata map[string]string `mandatory:"false" json:"metadata"` +} + +func (m CreateMultipartUploadDetails) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_request_response.go new file mode 100644 index 000000000..ca790ade0 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_multipart_upload_request_response.go @@ -0,0 +1,63 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreateMultipartUploadRequest wrapper for the CreateMultipartUpload operation +type CreateMultipartUploadRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // Request object for creating a multi-part upload. + CreateMultipartUploadDetails `contributesTo:"body"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request CreateMultipartUploadRequest) String() string { + return common.PointerString(request) +} + +// CreateMultipartUploadResponse wrapper for the CreateMultipartUpload operation +type CreateMultipartUploadResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The MultipartUpload instance + MultipartUpload `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The full path to the new upload. + Location *string `presentIn:"header" name:"location"` +} + +func (response CreateMultipartUploadResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_details.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_details.go new file mode 100644 index 000000000..498dc6dd4 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_details.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// CreatePreauthenticatedRequestDetails The representation of CreatePreauthenticatedRequestDetails +type CreatePreauthenticatedRequestDetails struct { + + // user specified name for pre-authenticated request. Helpful for management purposes. + Name *string `mandatory:"true" json:"name"` + + // the operation that can be performed on this resource e.g PUT or GET. + AccessType CreatePreauthenticatedRequestDetailsAccessTypeEnum `mandatory:"true" json:"accessType"` + + // The expiration date after which the pre-authenticated request will no longer be valid per spec + // RFC 3339 (https://tools.ietf.org/rfc/rfc3339) + TimeExpires *common.SDKTime `mandatory:"true" json:"timeExpires"` + + // Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + ObjectName *string `mandatory:"false" json:"objectName"` +} + +func (m CreatePreauthenticatedRequestDetails) String() string { + return common.PointerString(m) +} + +// CreatePreauthenticatedRequestDetailsAccessTypeEnum Enum with underlying type: string +type CreatePreauthenticatedRequestDetailsAccessTypeEnum string + +// Set of constants representing the allowable values for CreatePreauthenticatedRequestDetailsAccessType +const ( + CreatePreauthenticatedRequestDetailsAccessTypeObjectread CreatePreauthenticatedRequestDetailsAccessTypeEnum = "ObjectRead" + CreatePreauthenticatedRequestDetailsAccessTypeObjectwrite CreatePreauthenticatedRequestDetailsAccessTypeEnum = "ObjectWrite" + CreatePreauthenticatedRequestDetailsAccessTypeObjectreadwrite CreatePreauthenticatedRequestDetailsAccessTypeEnum = "ObjectReadWrite" + CreatePreauthenticatedRequestDetailsAccessTypeAnyobjectwrite CreatePreauthenticatedRequestDetailsAccessTypeEnum = "AnyObjectWrite" +) + +var mappingCreatePreauthenticatedRequestDetailsAccessType = map[string]CreatePreauthenticatedRequestDetailsAccessTypeEnum{ + "ObjectRead": CreatePreauthenticatedRequestDetailsAccessTypeObjectread, + "ObjectWrite": CreatePreauthenticatedRequestDetailsAccessTypeObjectwrite, + "ObjectReadWrite": CreatePreauthenticatedRequestDetailsAccessTypeObjectreadwrite, + "AnyObjectWrite": CreatePreauthenticatedRequestDetailsAccessTypeAnyobjectwrite, +} + +// GetCreatePreauthenticatedRequestDetailsAccessTypeEnumValues Enumerates the set of values for CreatePreauthenticatedRequestDetailsAccessType +func GetCreatePreauthenticatedRequestDetailsAccessTypeEnumValues() []CreatePreauthenticatedRequestDetailsAccessTypeEnum { + values := make([]CreatePreauthenticatedRequestDetailsAccessTypeEnum, 0) + for _, v := range mappingCreatePreauthenticatedRequestDetailsAccessType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_request_response.go new file mode 100644 index 000000000..f0580b6d1 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/create_preauthenticated_request_request_response.go @@ -0,0 +1,51 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// CreatePreauthenticatedRequestRequest wrapper for the CreatePreauthenticatedRequest operation +type CreatePreauthenticatedRequestRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // details for creating the pre-authenticated request. + CreatePreauthenticatedRequestDetails `contributesTo:"body"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request CreatePreauthenticatedRequestRequest) String() string { + return common.PointerString(request) +} + +// CreatePreauthenticatedRequestResponse wrapper for the CreatePreauthenticatedRequest operation +type CreatePreauthenticatedRequestResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PreauthenticatedRequest instance + PreauthenticatedRequest `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response CreatePreauthenticatedRequestResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_bucket_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_bucket_request_response.go new file mode 100644 index 000000000..71385a147 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_bucket_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteBucketRequest wrapper for the DeleteBucket operation +type DeleteBucketRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request DeleteBucketRequest) String() string { + return common.PointerString(request) +} + +// DeleteBucketResponse wrapper for the DeleteBucket operation +type DeleteBucketResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeleteBucketResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_object_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_object_request_response.go new file mode 100644 index 000000000..ae33f3a61 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_object_request_response.go @@ -0,0 +1,56 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeleteObjectRequest wrapper for the DeleteObject operation +type DeleteObjectRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request DeleteObjectRequest) String() string { + return common.PointerString(request) +} + +// DeleteObjectResponse wrapper for the DeleteObject operation +type DeleteObjectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The time the object was deleted, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.29. + LastModified *common.SDKTime `presentIn:"header" name:"last-modified"` +} + +func (response DeleteObjectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_preauthenticated_request_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_preauthenticated_request_request_response.go new file mode 100644 index 000000000..675d24927 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/delete_preauthenticated_request_request_response.go @@ -0,0 +1,49 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// DeletePreauthenticatedRequestRequest wrapper for the DeletePreauthenticatedRequest operation +type DeletePreauthenticatedRequestRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The unique identifier for the pre-authenticated request (PAR). This can be used to manage the PAR + // such as GET or DELETE the PAR + ParId *string `mandatory:"true" contributesTo:"path" name:"parId"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request DeletePreauthenticatedRequestRequest) String() string { + return common.PointerString(request) +} + +// DeletePreauthenticatedRequestResponse wrapper for the DeletePreauthenticatedRequest operation +type DeletePreauthenticatedRequestResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response DeletePreauthenticatedRequestResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_bucket_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_bucket_request_response.go new file mode 100644 index 000000000..4284a4a56 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_bucket_request_response.go @@ -0,0 +1,66 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetBucketRequest wrapper for the GetBucket operation +type GetBucketRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request GetBucketRequest) String() string { + return common.PointerString(request) +} + +// GetBucketResponse wrapper for the GetBucket operation +type GetBucketResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Bucket instance + Bucket `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The current entity tag for the bucket. + ETag *string `presentIn:"header" name:"etag"` + + // Flag to indicate whether or not the object was modified. If this is true, + // the getter for the object itself will return null. Callers should check this + // if they specified one of the request params that might result in a conditional + // response (like 'if-match'/'if-none-match'). + IsNotModified bool +} + +func (response GetBucketResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_namespace_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_namespace_request_response.go new file mode 100644 index 000000000..043ae9c99 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_namespace_request_response.go @@ -0,0 +1,34 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetNamespaceRequest wrapper for the GetNamespace operation +type GetNamespaceRequest struct { + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request GetNamespaceRequest) String() string { + return common.PointerString(request) +} + +// GetNamespaceResponse wrapper for the GetNamespace operation +type GetNamespaceResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The string instance + Value *string `presentIn:"body"` +} + +func (response GetNamespaceResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_object_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_object_request_response.go new file mode 100644 index 000000000..f75e36b74 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_object_request_response.go @@ -0,0 +1,107 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "io" + "net/http" +) + +// GetObjectRequest wrapper for the GetObject operation +type GetObjectRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` + + // Optional byte range to fetch, as described in RFC 7233 (https://tools.ietf.org/rfc/rfc7233), section 2.1. + // Note, only a single range of bytes is supported. + Range *string `mandatory:"false" contributesTo:"header" name:"range"` +} + +func (request GetObjectRequest) String() string { + return common.PointerString(request) +} + +// GetObjectResponse wrapper for the GetObject operation +type GetObjectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The io.ReadCloser instance + Content io.ReadCloser `presentIn:"body" encoding:"binary"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The entity tag for the object. + ETag *string `presentIn:"header" name:"etag"` + + // The user-defined metadata for the object. + OpcMeta map[string]string `presentIn:"header-collection" prefix:"opc-meta-"` + + // The object size in bytes. + ContentLength *int `presentIn:"header" name:"content-length"` + + // Content-Range header for range requests, per RFC 7233 (https://tools.ietf.org/rfc/rfc7233), section 4.2. + ContentRange *string `presentIn:"header" name:"content-range"` + + // Content-MD5 header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.15. + // Unavailable for objects uploaded using multipart upload. + ContentMd5 *string `presentIn:"header" name:"content-md5"` + + // Only applicable to objects uploaded using multipart upload. + // Base-64 representation of the multipart object hash. + // The multipart object hash is calculated by taking the MD5 hashes of the parts, + // concatenating the binary representation of those hashes in order of their part numbers, + // and then calculating the MD5 hash of the concatenated values. + OpcMultipartMd5 *string `presentIn:"header" name:"opc-multipart-md5"` + + // Content-Type header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.17. + ContentType *string `presentIn:"header" name:"content-type"` + + // Content-Language header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.12. + ContentLanguage *string `presentIn:"header" name:"content-language"` + + // Content-Encoding header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.11. + ContentEncoding *string `presentIn:"header" name:"content-encoding"` + + // The object modification time, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.29. + LastModified *common.SDKTime `presentIn:"header" name:"last-modified"` + + // Flag to indicate whether or not the object was modified. If this is true, + // the getter for the object itself will return null. Callers should check this + // if they specified one of the request params that might result in a conditional + // response (like 'if-match'/'if-none-match'). + IsNotModified bool +} + +func (response GetObjectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_preauthenticated_request_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_preauthenticated_request_request_response.go new file mode 100644 index 000000000..0e41fff80 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/get_preauthenticated_request_request_response.go @@ -0,0 +1,52 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// GetPreauthenticatedRequestRequest wrapper for the GetPreauthenticatedRequest operation +type GetPreauthenticatedRequestRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The unique identifier for the pre-authenticated request (PAR). This can be used to manage the PAR + // such as GET or DELETE the PAR + ParId *string `mandatory:"true" contributesTo:"path" name:"parId"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request GetPreauthenticatedRequestRequest) String() string { + return common.PointerString(request) +} + +// GetPreauthenticatedRequestResponse wrapper for the GetPreauthenticatedRequest operation +type GetPreauthenticatedRequestResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The PreauthenticatedRequestSummary instance + PreauthenticatedRequestSummary `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response GetPreauthenticatedRequestResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/head_bucket_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/head_bucket_request_response.go new file mode 100644 index 000000000..cca2efc72 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/head_bucket_request_response.go @@ -0,0 +1,63 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// HeadBucketRequest wrapper for the HeadBucket operation +type HeadBucketRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request HeadBucketRequest) String() string { + return common.PointerString(request) +} + +// HeadBucketResponse wrapper for the HeadBucket operation +type HeadBucketResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The current entity tag for the bucket. + ETag *string `presentIn:"header" name:"etag"` + + // Flag to indicate whether or not the object was modified. If this is true, + // the getter for the object itself will return null. Callers should check this + // if they specified one of the request params that might result in a conditional + // response (like 'if-match'/'if-none-match'). + IsNotModified bool +} + +func (response HeadBucketResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/head_object_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/head_object_request_response.go new file mode 100644 index 000000000..b058a2d01 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/head_object_request_response.go @@ -0,0 +1,96 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// HeadObjectRequest wrapper for the HeadObject operation +type HeadObjectRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request HeadObjectRequest) String() string { + return common.PointerString(request) +} + +// HeadObjectResponse wrapper for the HeadObject operation +type HeadObjectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The entity tag for the object. + ETag *string `presentIn:"header" name:"etag"` + + // The user-defined metadata for the object. + OpcMeta map[string]string `presentIn:"header-collection" prefix:"opc-meta-"` + + // The object size in bytes. + ContentLength *int `presentIn:"header" name:"content-length"` + + // Content-MD5 header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.15. + // Unavailable for objects uploaded using multipart upload. + ContentMd5 *string `presentIn:"header" name:"content-md5"` + + // Only applicable to objects uploaded using multipart upload. + // Base-64 representation of the multipart object hash. + // The multipart object hash is calculated by taking the MD5 hashes of the parts, + // concatenating the binary representation of those hashes in order of their part numbers, + // and then calculating the MD5 hash of the concatenated values. + OpcMultipartMd5 *string `presentIn:"header" name:"opc-multipart-md5"` + + // Content-Type header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.17. + ContentType *string `presentIn:"header" name:"content-type"` + + // Content-Language header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.12. + ContentLanguage *string `presentIn:"header" name:"content-language"` + + // Content-Encoding header, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.11. + ContentEncoding *string `presentIn:"header" name:"content-encoding"` + + // The object modification time, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.29. + LastModified *common.SDKTime `presentIn:"header" name:"last-modified"` + + // Flag to indicate whether or not the object was modified. If this is true, + // the getter for the object itself will return null. Callers should check this + // if they specified one of the request params that might result in a conditional + // response (like 'if-match'/'if-none-match'). + IsNotModified bool +} + +func (response HeadObjectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_buckets_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_buckets_request_response.go new file mode 100644 index 000000000..09474ba93 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_buckets_request_response.go @@ -0,0 +1,59 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListBucketsRequest wrapper for the ListBuckets operation +type ListBucketsRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The ID of the compartment in which to create the bucket. + CompartmentId *string `mandatory:"true" contributesTo:"query" name:"compartmentId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The page at which to start retrieving results. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request ListBucketsRequest) String() string { + return common.PointerString(request) +} + +// ListBucketsResponse wrapper for the ListBuckets operation +type ListBucketsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []BucketSummary instance + Items []BucketSummary `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of `Bucket`s. If this header appears in the response, then this + // is a partial list of buckets. Include this value as the `page` parameter in a subsequent + // GET request to get the next batch of buckets. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#nine). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListBucketsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_upload_parts_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_upload_parts_request_response.go new file mode 100644 index 000000000..367ea7af7 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_upload_parts_request_response.go @@ -0,0 +1,67 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListMultipartUploadPartsRequest wrapper for the ListMultipartUploadParts operation +type ListMultipartUploadPartsRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The upload ID for a multipart upload. + UploadId *string `mandatory:"true" contributesTo:"query" name:"uploadId"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The page at which to start retrieving results. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request ListMultipartUploadPartsRequest) String() string { + return common.PointerString(request) +} + +// ListMultipartUploadPartsResponse wrapper for the ListMultipartUploadParts operation +type ListMultipartUploadPartsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []MultipartUploadPartSummary instance + Items []MultipartUploadPartSummary `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of `MultipartUploadPartSummary`s. If this header appears in the response, + // then this is a partial list of object parts. Include this value as the `page` parameter in a subsequent + // GET request to get the next batch of object parts. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListMultipartUploadPartsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_uploads_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_uploads_request_response.go new file mode 100644 index 000000000..259e0630e --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_multipart_uploads_request_response.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListMultipartUploadsRequest wrapper for the ListMultipartUploads operation +type ListMultipartUploadsRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The page at which to start retrieving results. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request ListMultipartUploadsRequest) String() string { + return common.PointerString(request) +} + +// ListMultipartUploadsResponse wrapper for the ListMultipartUploads operation +type ListMultipartUploadsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []MultipartUpload instance + Items []MultipartUpload `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of `MultipartUpload`s. If this header appears in the response, then + // this is a partial list of multipart uploads. Include this value as the `page` parameter in a subsequent + // GET request. For information about pagination, see + // List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListMultipartUploadsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects.go new file mode 100644 index 000000000..aa216e61d --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ListObjects To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type ListObjects struct { + + // An array of object summaries. + Objects []ObjectSummary `mandatory:"true" json:"objects"` + + // Prefixes that are common to the results returned by the request if the request specified a delimiter. + Prefixes []string `mandatory:"false" json:"prefixes"` + + // The name of the object to use in the 'startWith' parameter to obtain the next page of + // a truncated ListObjects response. + NextStartWith *string `mandatory:"false" json:"nextStartWith"` +} + +func (m ListObjects) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects_request_response.go new file mode 100644 index 000000000..0cca1b1c6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_objects_request_response.go @@ -0,0 +1,73 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListObjectsRequest wrapper for the ListObjects operation +type ListObjectsRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The string to use for matching against the start of object names in a list query. + Prefix *string `mandatory:"false" contributesTo:"query" name:"prefix"` + + // Object names returned by a list query must be greater or equal to this parameter. + Start *string `mandatory:"false" contributesTo:"query" name:"start"` + + // Object names returned by a list query must be strictly less than this parameter. + End *string `mandatory:"false" contributesTo:"query" name:"end"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // When this parameter is set, only objects whose names do not contain the delimiter character + // (after an optionally specified prefix) are returned. Scanned objects whose names contain the + // delimiter have part of their name up to the last occurrence of the delimiter (after the optional + // prefix) returned as a set of prefixes. Note that only '/' is a supported delimiter character at + // this time. + Delimiter *string `mandatory:"false" contributesTo:"query" name:"delimiter"` + + // Object summary in list of objects includes the 'name' field. This parameter can also include 'size' + // (object size in bytes), 'md5', and 'timeCreated' (object creation date and time) fields. + // Value of this parameter should be a comma-separated, case-insensitive list of those field names. + // For example 'name,timeCreated,md5'. + Fields *string `mandatory:"false" contributesTo:"query" name:"fields" omitEmpty:"true"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request ListObjectsRequest) String() string { + return common.PointerString(request) +} + +// ListObjectsResponse wrapper for the ListObjects operation +type ListObjectsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The ListObjects instance + ListObjects `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` +} + +func (response ListObjectsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_preauthenticated_requests_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_preauthenticated_requests_request_response.go new file mode 100644 index 000000000..4adcbe26a --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/list_preauthenticated_requests_request_response.go @@ -0,0 +1,63 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// ListPreauthenticatedRequestsRequest wrapper for the ListPreauthenticatedRequests operation +type ListPreauthenticatedRequestsRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // Pre-authenticated requests returned by the list must have object names starting with prefix + ObjectNamePrefix *string `mandatory:"false" contributesTo:"query" name:"objectNamePrefix"` + + // The maximum number of items to return. + Limit *int `mandatory:"false" contributesTo:"query" name:"limit"` + + // The page at which to start retrieving results. + Page *string `mandatory:"false" contributesTo:"query" name:"page"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request ListPreauthenticatedRequestsRequest) String() string { + return common.PointerString(request) +} + +// ListPreauthenticatedRequestsResponse wrapper for the ListPreauthenticatedRequests operation +type ListPreauthenticatedRequestsResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The []PreauthenticatedRequestSummary instance + Items []PreauthenticatedRequestSummary `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // For pagination of a list of pre-authenticated requests, if this header appears in the response, + // then this is a partial list. Include this value as the `page` parameter in a subsequent + // GET request to get the next batch of pre-authenticated requests. + // For information about pagination, see List Pagination (https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/usingapi.htm#nine). + OpcNextPage *string `presentIn:"header" name:"opc-next-page"` +} + +func (response ListPreauthenticatedRequestsResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload.go new file mode 100644 index 000000000..00cad6055 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload.go @@ -0,0 +1,38 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// MultipartUpload To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type MultipartUpload struct { + + // The namespace in which the in-progress multipart upload is stored. + Namespace *string `mandatory:"true" json:"namespace"` + + // The bucket in which the in-progress multipart upload is stored. + Bucket *string `mandatory:"true" json:"bucket"` + + // The object name of the in-progress multipart upload. + Object *string `mandatory:"true" json:"object"` + + // The unique identifier for the in-progress multipart upload. + UploadId *string `mandatory:"true" json:"uploadId"` + + // The date and time when the upload was created. + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` +} + +func (m MultipartUpload) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload_part_summary.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload_part_summary.go new file mode 100644 index 000000000..05f9aff44 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/multipart_upload_part_summary.go @@ -0,0 +1,35 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// MultipartUploadPartSummary To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type MultipartUploadPartSummary struct { + + // the current entity tag for the part. + Etag *string `mandatory:"true" json:"etag"` + + // the MD5 hash of the bytes of the part. + Md5 *string `mandatory:"true" json:"md5"` + + // the size of the part in bytes. + Size *int `mandatory:"true" json:"size"` + + // the part number for this part. + PartNumber *int `mandatory:"true" json:"partNumber"` +} + +func (m MultipartUploadPartSummary) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/object_summary.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/object_summary.go new file mode 100644 index 000000000..c1cf92ba8 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/object_summary.go @@ -0,0 +1,35 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// ObjectSummary To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type ObjectSummary struct { + + // The name of the object. + Name *string `mandatory:"true" json:"name"` + + // Size of the object in bytes. + Size *int `mandatory:"false" json:"size"` + + // Base64-encoded MD5 hash of the object data. + Md5 *string `mandatory:"false" json:"md5"` + + // Date and time of object creation. + TimeCreated *common.SDKTime `mandatory:"false" json:"timeCreated"` +} + +func (m ObjectSummary) String() string { + return common.PointerString(m) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/objectstorage_client.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/objectstorage_client.go new file mode 100644 index 000000000..eaf8bdfb6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/objectstorage_client.go @@ -0,0 +1,478 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "context" + "fmt" + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +//ObjectStorageClient a client for ObjectStorage +type ObjectStorageClient struct { + common.BaseClient + config *common.ConfigurationProvider +} + +func buildSigner(configProvider common.ConfigurationProvider) common.HTTPRequestSigner { + objStorageHeaders := []string{"date", "(request-target)", "host"} + defaultBodyHeaders := []string{"content-length", "content-type", "x-content-sha256"} + shouldHashBody := func(r *http.Request) bool { + return r.Method == http.MethodPost + } + signer := common.RequestSignerWithBodyHashingPredicate(configProvider, objStorageHeaders, defaultBodyHeaders, shouldHashBody) + return signer +} + +// NewObjectStorageClientWithConfigurationProvider Creates a new default ObjectStorage client with the given configuration provider. +// the configuration provider will be used for the default signer as well as reading the region +func NewObjectStorageClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (client ObjectStorageClient, err error) { + baseClient, err := common.NewClientWithConfig(configProvider) + if err != nil { + return + } + baseClient.Signer = buildSigner(configProvider) + + client = ObjectStorageClient{BaseClient: baseClient} + err = client.setConfigurationProvider(configProvider) + return +} + +// SetRegion overrides the region of this client. +func (client *ObjectStorageClient) SetRegion(region string) { + client.Host = fmt.Sprintf(common.DefaultHostURLTemplate, "objectstorage", region) +} + +// SetConfigurationProvider sets the configuration provider including the region, returns an error if is not valid +func (client *ObjectStorageClient) setConfigurationProvider(configProvider common.ConfigurationProvider) error { + if ok, err := common.IsConfigurationProviderValid(configProvider); !ok { + return err + } + + // Error has been checked already + region, _ := configProvider.Region() + client.config = &configProvider + client.SetRegion(region) + return nil +} + +// ConfigurationProvider the ConfigurationProvider used in this client, or null if none set +func (client *ObjectStorageClient) ConfigurationProvider() *common.ConfigurationProvider { + return client.config +} + +// AbortMultipartUpload Aborts an in-progress multipart upload and deletes all parts that have been uploaded. +func (client ObjectStorageClient) AbortMultipartUpload(ctx context.Context, request AbortMultipartUploadRequest) (response AbortMultipartUploadResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/n/{namespaceName}/b/{bucketName}/u/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CommitMultipartUpload Commits a multipart upload, which involves checking part numbers and ETags of the parts, to create an aggregate object. +func (client ObjectStorageClient) CommitMultipartUpload(ctx context.Context, request CommitMultipartUploadRequest) (response CommitMultipartUploadResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/n/{namespaceName}/b/{bucketName}/u/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateBucket Creates a bucket in the given namespace with a bucket name and optional user-defined metadata. +// To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +func (client ObjectStorageClient) CreateBucket(ctx context.Context, request CreateBucketRequest) (response CreateBucketResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/n/{namespaceName}/b/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreateMultipartUpload Starts a new multipart upload to a specific object in the given bucket in the given namespace. +func (client ObjectStorageClient) CreateMultipartUpload(ctx context.Context, request CreateMultipartUploadRequest) (response CreateMultipartUploadResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/n/{namespaceName}/b/{bucketName}/u", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// CreatePreauthenticatedRequest Create a pre-authenticated request specific to the bucket +func (client ObjectStorageClient) CreatePreauthenticatedRequest(ctx context.Context, request CreatePreauthenticatedRequestRequest) (response CreatePreauthenticatedRequestResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/n/{namespaceName}/b/{bucketName}/p/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteBucket Deletes a bucket if it is already empty. If the bucket is not empty, use DeleteObject first. +func (client ObjectStorageClient) DeleteBucket(ctx context.Context, request DeleteBucketRequest) (response DeleteBucketResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/n/{namespaceName}/b/{bucketName}/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeleteObject Deletes an object. +func (client ObjectStorageClient) DeleteObject(ctx context.Context, request DeleteObjectRequest) (response DeleteObjectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/n/{namespaceName}/b/{bucketName}/o/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// DeletePreauthenticatedRequest Deletes the bucket level pre-authenticateted request +func (client ObjectStorageClient) DeletePreauthenticatedRequest(ctx context.Context, request DeletePreauthenticatedRequestRequest) (response DeletePreauthenticatedRequestResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodDelete, "/n/{namespaceName}/b/{bucketName}/p/{parId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetBucket Gets the current representation of the given bucket in the given namespace. +func (client ObjectStorageClient) GetBucket(ctx context.Context, request GetBucketRequest) (response GetBucketResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetNamespace Gets the name of the namespace for the user making the request. An account name must be unique, must start with a +// letter, and can have up to 15 lowercase letters and numbers. You cannot use spaces or special characters. +func (client ObjectStorageClient) GetNamespace(ctx context.Context, request GetNamespaceRequest) (response GetNamespaceResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetObject Gets the metadata and body of an object. +func (client ObjectStorageClient) GetObject(ctx context.Context, request GetObjectRequest) (response GetObjectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/o/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// GetPreauthenticatedRequest Get the bucket level pre-authenticateted request +func (client ObjectStorageClient) GetPreauthenticatedRequest(ctx context.Context, request GetPreauthenticatedRequestRequest) (response GetPreauthenticatedRequestResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/p/{parId}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// HeadBucket Efficiently checks if a bucket exists and gets the current ETag for the bucket. +func (client ObjectStorageClient) HeadBucket(ctx context.Context, request HeadBucketRequest) (response HeadBucketResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodHead, "/n/{namespaceName}/b/{bucketName}/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// HeadObject Gets the user-defined metadata and entity tag for an object. +func (client ObjectStorageClient) HeadObject(ctx context.Context, request HeadObjectRequest) (response HeadObjectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodHead, "/n/{namespaceName}/b/{bucketName}/o/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListBuckets Gets a list of all `BucketSummary`s in a compartment. A `BucketSummary` contains only summary fields for the bucket +// and does not contain fields like the user-defined metadata. +// To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +func (client ObjectStorageClient) ListBuckets(ctx context.Context, request ListBucketsRequest) (response ListBucketsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListMultipartUploadParts Lists the parts of an in-progress multipart upload. +func (client ObjectStorageClient) ListMultipartUploadParts(ctx context.Context, request ListMultipartUploadPartsRequest) (response ListMultipartUploadPartsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/u/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListMultipartUploads Lists all in-progress multipart uploads for the given bucket in the given namespace. +func (client ObjectStorageClient) ListMultipartUploads(ctx context.Context, request ListMultipartUploadsRequest) (response ListMultipartUploadsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/u", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListObjects Lists the objects in a bucket. +// To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +func (client ObjectStorageClient) ListObjects(ctx context.Context, request ListObjectsRequest) (response ListObjectsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/o", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// ListPreauthenticatedRequests List pre-authenticated requests for the bucket +func (client ObjectStorageClient) ListPreauthenticatedRequests(ctx context.Context, request ListPreauthenticatedRequestsRequest) (response ListPreauthenticatedRequestsResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodGet, "/n/{namespaceName}/b/{bucketName}/p/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// PutObject Creates a new object or overwrites an existing one. +// To use this and other API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +func (client ObjectStorageClient) PutObject(ctx context.Context, request PutObjectRequest) (response PutObjectResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/n/{namespaceName}/b/{bucketName}/o/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UpdateBucket Performs a partial or full update of a bucket's user-defined metadata. +func (client ObjectStorageClient) UpdateBucket(ctx context.Context, request UpdateBucketRequest) (response UpdateBucketResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPost, "/n/{namespaceName}/b/{bucketName}/", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} + +// UploadPart Uploads a single part of a multipart upload. +func (client ObjectStorageClient) UploadPart(ctx context.Context, request UploadPartRequest) (response UploadPartResponse, err error) { + httpRequest, err := common.MakeDefaultHTTPRequestWithTaggedStruct(http.MethodPut, "/n/{namespaceName}/b/{bucketName}/u/{objectName}", request) + if err != nil { + return + } + + httpResponse, err := client.Call(ctx, &httpRequest) + defer common.CloseBodyIfValid(httpResponse) + response.RawResponse = httpResponse + if err != nil { + return + } + + err = common.UnmarshalResponse(httpResponse, &response) + return +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request.go new file mode 100644 index 000000000..54e4d2430 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request.go @@ -0,0 +1,71 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PreauthenticatedRequest The representation of PreauthenticatedRequest +type PreauthenticatedRequest struct { + + // the unique identifier to use when directly addressing the pre-authenticated request + Id *string `mandatory:"true" json:"id"` + + // the user supplied name of the pre-authenticated request. + Name *string `mandatory:"true" json:"name"` + + // the uri to embed in the url when using the pre-authenticated request. + AccessUri *string `mandatory:"true" json:"accessUri"` + + // the operation that can be performed on this resource e.g PUT or GET. + AccessType PreauthenticatedRequestAccessTypeEnum `mandatory:"true" json:"accessType"` + + // the expiration date after which the pre authenticated request will no longer be valid as per spec + // RFC 3339 (https://tools.ietf.org/rfc/rfc3339) + TimeExpires *common.SDKTime `mandatory:"true" json:"timeExpires"` + + // the date when the pre-authenticated request was created as per spec + // RFC 3339 (https://tools.ietf.org/rfc/rfc3339) + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + ObjectName *string `mandatory:"false" json:"objectName"` +} + +func (m PreauthenticatedRequest) String() string { + return common.PointerString(m) +} + +// PreauthenticatedRequestAccessTypeEnum Enum with underlying type: string +type PreauthenticatedRequestAccessTypeEnum string + +// Set of constants representing the allowable values for PreauthenticatedRequestAccessType +const ( + PreauthenticatedRequestAccessTypeObjectread PreauthenticatedRequestAccessTypeEnum = "ObjectRead" + PreauthenticatedRequestAccessTypeObjectwrite PreauthenticatedRequestAccessTypeEnum = "ObjectWrite" + PreauthenticatedRequestAccessTypeObjectreadwrite PreauthenticatedRequestAccessTypeEnum = "ObjectReadWrite" + PreauthenticatedRequestAccessTypeAnyobjectwrite PreauthenticatedRequestAccessTypeEnum = "AnyObjectWrite" +) + +var mappingPreauthenticatedRequestAccessType = map[string]PreauthenticatedRequestAccessTypeEnum{ + "ObjectRead": PreauthenticatedRequestAccessTypeObjectread, + "ObjectWrite": PreauthenticatedRequestAccessTypeObjectwrite, + "ObjectReadWrite": PreauthenticatedRequestAccessTypeObjectreadwrite, + "AnyObjectWrite": PreauthenticatedRequestAccessTypeAnyobjectwrite, +} + +// GetPreauthenticatedRequestAccessTypeEnumValues Enumerates the set of values for PreauthenticatedRequestAccessType +func GetPreauthenticatedRequestAccessTypeEnumValues() []PreauthenticatedRequestAccessTypeEnum { + values := make([]PreauthenticatedRequestAccessTypeEnum, 0) + for _, v := range mappingPreauthenticatedRequestAccessType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request_summary.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request_summary.go new file mode 100644 index 000000000..f293237bc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/preauthenticated_request_summary.go @@ -0,0 +1,68 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// PreauthenticatedRequestSummary The representation of PreauthenticatedRequestSummary +type PreauthenticatedRequestSummary struct { + + // the unique identifier to use when directly addressing the pre-authenticated request + Id *string `mandatory:"true" json:"id"` + + // the user supplied name of the pre-authenticated request + Name *string `mandatory:"true" json:"name"` + + // the operation that can be performed on this resource e.g PUT or GET. + AccessType PreauthenticatedRequestSummaryAccessTypeEnum `mandatory:"true" json:"accessType"` + + // the expiration date after which the pre authenticated request will no longer be valid as per spec + // RFC 3339 (https://tools.ietf.org/rfc/rfc3339) + TimeExpires *common.SDKTime `mandatory:"true" json:"timeExpires"` + + // the date when the pre-authenticated request was created as per spec + // RFC 3339 (https://tools.ietf.org/rfc/rfc3339) + TimeCreated *common.SDKTime `mandatory:"true" json:"timeCreated"` + + // Name of object that is being granted access to by the pre-authenticated request. This can be null and that would mean that the pre-authenticated request is granting access to the entire bucket + ObjectName *string `mandatory:"false" json:"objectName"` +} + +func (m PreauthenticatedRequestSummary) String() string { + return common.PointerString(m) +} + +// PreauthenticatedRequestSummaryAccessTypeEnum Enum with underlying type: string +type PreauthenticatedRequestSummaryAccessTypeEnum string + +// Set of constants representing the allowable values for PreauthenticatedRequestSummaryAccessType +const ( + PreauthenticatedRequestSummaryAccessTypeObjectread PreauthenticatedRequestSummaryAccessTypeEnum = "ObjectRead" + PreauthenticatedRequestSummaryAccessTypeObjectwrite PreauthenticatedRequestSummaryAccessTypeEnum = "ObjectWrite" + PreauthenticatedRequestSummaryAccessTypeObjectreadwrite PreauthenticatedRequestSummaryAccessTypeEnum = "ObjectReadWrite" + PreauthenticatedRequestSummaryAccessTypeAnyobjectwrite PreauthenticatedRequestSummaryAccessTypeEnum = "AnyObjectWrite" +) + +var mappingPreauthenticatedRequestSummaryAccessType = map[string]PreauthenticatedRequestSummaryAccessTypeEnum{ + "ObjectRead": PreauthenticatedRequestSummaryAccessTypeObjectread, + "ObjectWrite": PreauthenticatedRequestSummaryAccessTypeObjectwrite, + "ObjectReadWrite": PreauthenticatedRequestSummaryAccessTypeObjectreadwrite, + "AnyObjectWrite": PreauthenticatedRequestSummaryAccessTypeAnyobjectwrite, +} + +// GetPreauthenticatedRequestSummaryAccessTypeEnumValues Enumerates the set of values for PreauthenticatedRequestSummaryAccessType +func GetPreauthenticatedRequestSummaryAccessTypeEnumValues() []PreauthenticatedRequestSummaryAccessTypeEnum { + values := make([]PreauthenticatedRequestSummaryAccessTypeEnum, 0) + for _, v := range mappingPreauthenticatedRequestSummaryAccessType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/put_object_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/put_object_request_response.go new file mode 100644 index 000000000..3652da5fc --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/put_object_request_response.go @@ -0,0 +1,92 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "io" + "net/http" +) + +// PutObjectRequest wrapper for the PutObject operation +type PutObjectRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The content length of the body. + ContentLength *int `mandatory:"true" contributesTo:"header" name:"Content-Length"` + + // The object to upload to the object store. + PutObjectBody io.ReadCloser `mandatory:"true" contributesTo:"body" encoding:"binary"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` + + // 100-continue + Expect *string `mandatory:"false" contributesTo:"header" name:"Expect"` + + // The base-64 encoded MD5 hash of the body. + ContentMD5 *string `mandatory:"false" contributesTo:"header" name:"Content-MD5"` + + // The content type of the object. Defaults to 'application/octet-stream' if not overridden during the PutObject call. + ContentType *string `mandatory:"false" contributesTo:"header" name:"Content-Type"` + + // The content language of the object. + ContentLanguage *string `mandatory:"false" contributesTo:"header" name:"Content-Language"` + + // The content encoding of the object. + ContentEncoding *string `mandatory:"false" contributesTo:"header" name:"Content-Encoding"` + + // Optional user-defined metadata key and value. + OpcMeta map[string]string `mandatory:"false" contributesTo:"header-collection" prefix:"opc-meta-"` +} + +func (request PutObjectRequest) String() string { + return common.PointerString(request) +} + +// PutObjectResponse wrapper for the PutObject operation +type PutObjectResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The base-64 encoded MD5 hash of the request body as computed by the server. + OpcContentMd5 *string `presentIn:"header" name:"opc-content-md5"` + + // The entity tag for the object. + ETag *string `presentIn:"header" name:"etag"` + + // The time the object was modified, as described in RFC 2616 (https://tools.ietf.org/rfc/rfc2616), section 14.29. + LastModified *common.SDKTime `presentIn:"header" name:"last-modified"` +} + +func (response PutObjectResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_details.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_details.go new file mode 100644 index 000000000..a3cf083a5 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_details.go @@ -0,0 +1,61 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +// Object Storage Service API +// +// APIs for managing buckets and objects. +// + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" +) + +// UpdateBucketDetails To use any of the API operations, you must be authorized in an IAM policy. If you're not authorized, +// talk to an administrator. If you're an administrator who needs to write policies to give users access, see +// Getting Started with Policies (https://docs.us-phoenix-1.oraclecloud.com/Content/Identity/Concepts/policygetstarted.htm). +type UpdateBucketDetails struct { + + // The namespace in which the bucket lives. + Namespace *string `mandatory:"false" json:"namespace"` + + // The name of the bucket. + Name *string `mandatory:"false" json:"name"` + + // Arbitrary string, up to 4KB, of keys and values for user-defined metadata. + Metadata map[string]string `mandatory:"false" json:"metadata"` + + // The type of public access available on this bucket. Allows authenticated caller to access the bucket or + // contents of this bucket. By default a bucket is set to NoPublicAccess. It is treated as NoPublicAccess + // when this value is not specified. When the type is NoPublicAccess the bucket does not allow any public access. + // When the type is ObjectRead the bucket allows public access to the GetObject, HeadObject, ListObjects. + PublicAccessType UpdateBucketDetailsPublicAccessTypeEnum `mandatory:"false" json:"publicAccessType,omitempty"` +} + +func (m UpdateBucketDetails) String() string { + return common.PointerString(m) +} + +// UpdateBucketDetailsPublicAccessTypeEnum Enum with underlying type: string +type UpdateBucketDetailsPublicAccessTypeEnum string + +// Set of constants representing the allowable values for UpdateBucketDetailsPublicAccessType +const ( + UpdateBucketDetailsPublicAccessTypeNopublicaccess UpdateBucketDetailsPublicAccessTypeEnum = "NoPublicAccess" + UpdateBucketDetailsPublicAccessTypeObjectread UpdateBucketDetailsPublicAccessTypeEnum = "ObjectRead" +) + +var mappingUpdateBucketDetailsPublicAccessType = map[string]UpdateBucketDetailsPublicAccessTypeEnum{ + "NoPublicAccess": UpdateBucketDetailsPublicAccessTypeNopublicaccess, + "ObjectRead": UpdateBucketDetailsPublicAccessTypeObjectread, +} + +// GetUpdateBucketDetailsPublicAccessTypeEnumValues Enumerates the set of values for UpdateBucketDetailsPublicAccessType +func GetUpdateBucketDetailsPublicAccessTypeEnumValues() []UpdateBucketDetailsPublicAccessTypeEnum { + values := make([]UpdateBucketDetailsPublicAccessTypeEnum, 0) + for _, v := range mappingUpdateBucketDetailsPublicAccessType { + values = append(values, v) + } + return values +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_request_response.go new file mode 100644 index 000000000..a352d64fe --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/update_bucket_request_response.go @@ -0,0 +1,58 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "net/http" +) + +// UpdateBucketRequest wrapper for the UpdateBucket operation +type UpdateBucketRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // Request object for updating a bucket. + UpdateBucketDetails `contributesTo:"body"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` +} + +func (request UpdateBucketRequest) String() string { + return common.PointerString(request) +} + +// UpdateBucketResponse wrapper for the UpdateBucket operation +type UpdateBucketResponse struct { + + // The underlying http response + RawResponse *http.Response + + // The Bucket instance + Bucket `presentIn:"body"` + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The entity tag for the updated bucket. + ETag *string `presentIn:"header" name:"etag"` +} + +func (response UpdateBucketResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/objectstorage/upload_part_request_response.go b/vendor/github.com/oracle/oci-go-sdk/objectstorage/upload_part_request_response.go new file mode 100644 index 000000000..9a48fa05c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/objectstorage/upload_part_request_response.go @@ -0,0 +1,83 @@ +// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. +// Code generated. DO NOT EDIT. + +package objectstorage + +import ( + "github.com/oracle/oci-go-sdk/common" + "io" + "net/http" +) + +// UploadPartRequest wrapper for the UploadPart operation +type UploadPartRequest struct { + + // The top-level namespace used for the request. + NamespaceName *string `mandatory:"true" contributesTo:"path" name:"namespaceName"` + + // The name of the bucket. + // Example: `my-new-bucket1` + BucketName *string `mandatory:"true" contributesTo:"path" name:"bucketName"` + + // The name of the object. + // Example: `test/object1.log` + ObjectName *string `mandatory:"true" contributesTo:"path" name:"objectName"` + + // The upload ID for a multipart upload. + UploadId *string `mandatory:"true" contributesTo:"query" name:"uploadId"` + + // The part number that identifies the object part currently being uploaded. + UploadPartNum *int `mandatory:"true" contributesTo:"query" name:"uploadPartNum"` + + // The content length of the body. + ContentLength *int `mandatory:"true" contributesTo:"header" name:"Content-Length"` + + // The part being uploaded to the Object Storage Service. + UploadPartBody io.ReadCloser `mandatory:"true" contributesTo:"body" encoding:"binary"` + + // The client request ID for tracing. + OpcClientRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-client-request-id"` + + // The entity tag to match. For creating and committing a multipart upload to an object, this is the entity tag of the target object. + // For uploading a part, this is the entity tag of the target part. + IfMatch *string `mandatory:"false" contributesTo:"header" name:"if-match"` + + // The entity tag to avoid matching. The only valid value is ‘*’, which indicates that the request should fail if the object already exists. + // For creating and committing a multipart upload, this is the entity tag of the target object. For uploading a part, this is the entity tag + // of the target part. + IfNoneMatch *string `mandatory:"false" contributesTo:"header" name:"if-none-match"` + + // 100-continue + Expect *string `mandatory:"false" contributesTo:"header" name:"Expect"` + + // The base-64 encoded MD5 hash of the body. + ContentMD5 *string `mandatory:"false" contributesTo:"header" name:"Content-MD5"` +} + +func (request UploadPartRequest) String() string { + return common.PointerString(request) +} + +// UploadPartResponse wrapper for the UploadPart operation +type UploadPartResponse struct { + + // The underlying http response + RawResponse *http.Response + + // Echoes back the value passed in the opc-client-request-id header, for use by clients when debugging. + OpcClientRequestId *string `presentIn:"header" name:"opc-client-request-id"` + + // Unique Oracle-assigned identifier for the request. If you need to contact Oracle about a particular + // request, please provide this request ID. + OpcRequestId *string `presentIn:"header" name:"opc-request-id"` + + // The base64-encoded MD5 hash of the request body, as computed by the server. + OpcContentMd5 *string `presentIn:"header" name:"opc-content-md5"` + + // The entity tag for the object. + ETag *string `presentIn:"header" name:"etag"` +} + +func (response UploadPartResponse) String() string { + return common.PointerString(response) +} diff --git a/vendor/github.com/oracle/oci-go-sdk/oci.go b/vendor/github.com/oracle/oci-go-sdk/oci.go new file mode 100644 index 000000000..47fcef9c6 --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/oci.go @@ -0,0 +1,232 @@ + +/* +This is the official Go SDK for Oracle Cloud Infrastructure + +Installation + +Refer to https://github.com/oracle/oci-go-sdk/blob/master/README.md#installing for installation instructions. + +Configuration + +Refer to https://github.com/oracle/oci-go-sdk/blob/master/README.md#configuring for configuration instructions. + +Quickstart + +The following example shows how to get started with the SDK. The example belows creates an identityClient +struct with the default configuration. It then utilizes the identityClient to list availability domains and prints +them out to stdout + + import ( + "context" + "fmt" + + "github.com/oracle/oci-go-sdk/common" + "github.com/oracle/oci-go-sdk/identity" + ) + + func main() { + c, err := identity.NewIdentityClientWithConfigurationProvider(common.DefaultConfigProvider()) + if err != nil { + fmt.Println("Error:", err) + return + } + + // The OCID of the tenancy containing the compartment. + tenancyID, err := common.DefaultConfigProvider().TenancyOCID() + if err != nil { + fmt.Println("Error:", err) + return + } + + request := identity.ListAvailabilityDomainsRequest{ + CompartmentId: &tenancyID, + } + + r, err := c.ListAvailabilityDomains(context.Background(), request) + if err != nil { + fmt.Println("Error:", err) + return + } + + fmt.Printf("List of available domains: %v", r.Items) + return + } + +More examples can be found in the SDK Github repo: https://github.com/oracle/oci-go-sdk/tree/master/example + +Optional fields in the SDK + +Optional fields are represented with the `mandatory:"false"` tag on input structs. The SDK will omit all optional fields that are nil when making requests. +In the case of enum-type fields, the SDK will omit fields whose value is an empty string. + +Helper functions + +The SDK uses pointers for primitive types in many input structs. To aid in the construction of such structs, the SDK provides +functions that return a pointer for a given value. For example: + + // Given the struct + type CreateVcnDetails struct { + + // Example: `172.16.0.0/16` + CidrBlock *string `mandatory:"true" json:"cidrBlock"` + + CompartmentId *string `mandatory:"true" json:"compartmentId"` + + DisplayName *string `mandatory:"false" json:"displayName"` + + } + + // We can use the helper functions to build the struct + details := core.CreateVcnDetails{ + CidrBlock: common.String("172.16.0.0/16"), + CompartmentId: common.String("someOcid"), + DisplayName: common.String("myVcn"), + } + + +Signing custom requests + +The SDK exposes a stand-alone signer that can be used to signing custom requests. Related code can be found here: +https://github.com/oracle/oci-go-sdk/blob/master/common/http_signer.go. + +The example below shows how to create a default signer. + + client := http.Client{} + var request http.Request + request = ... // some custom request + + // Set the Date header + request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) + + // And a provider of cryptographic keys + provider := common.DefaultConfigProvider() + + // Build the signer + signer := common.DefaultSigner(provider) + + // Sign the request + signer.Sign(&request) + + // Execute the request + client.Do(request) + + + +The signer also allows more granular control on the headers used for signing. For example: + + client := http.Client{} + var request http.Request + request = ... // some custom request + + // Set the Date header + request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) + + // Mandatory headers to be used in the sign process + defaultGenericHeaders = []string{"date", "(request-target)", "host"} + + // Optional headers + optionalHeaders = []string{"content-length", "content-type", "x-content-sha256"} + + // A predicate that specifies when to use the optional signing headers + optionalHeadersPredicate := func (r *http.Request) bool { + return r.Method == http.MethodPost + } + + // And a provider of cryptographic keys + provider := common.DefaultConfigProvider() + + // Build the signer + signer := common.RequestSigner(provider, defaultGenericHeaders, optionalHeaders, optionalHeadersPredicate) + + // Sign the request + signer.Sign(&request) + + // Execute the request + c.Do(request) + +For more information on the signing algorithm refer to: https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/signingrequests.htm + +Polymorphic json requests and responses + +Some operations accept or return polymorphic json objects. The SDK models such objects as interfaces. Further the SDK provides +structs that implement such interfaces. Thus, for all operations that expect interfaces as input, pass the struct in the SDK that satisfies +such interface. For example: + + c, err := identity.NewIdentityClientWithConfigurationProvider(common.DefaultConfigProvider()) + if err != nil { + panic(err) + } + + // The CreateIdentityProviderRequest takes a CreateIdentityProviderDetails interface as input + rCreate := identity.CreateIdentityProviderRequest{} + + // The CreateSaml2IdentityProviderDetails struct implements the CreateIdentityProviderDetails interface + details := identity.CreateSaml2IdentityProviderDetails{} + details.CompartmentId = common.String(getTenancyID()) + details.Name = common.String("someName") + //... more setup if needed + // Use the above struct + rCreate.CreateIdentityProviderDetails = details + + // Make the call + rspCreate, createErr := c.CreateIdentityProvider(context.Background(), rCreate) + +In the case of a polymorphic response you can type assert the interface to the expected type. For example: + + rRead := identity.GetIdentityProviderRequest{} + rRead.IdentityProviderId = common.String("aValidId") + response, err := c.GetIdentityProvider(context.Background(), rRead) + + provider := response.IdentityProvider.(identity.Saml2IdentityProvider) + +An example of polymorphic json request handling can be found here: https://github.com/oracle/oci-go-sdk/blob/master/example/example_core_test.go#L63 + + +Pagination + +When calling a list operation, the operation will retrieve a page of results. To retrieve more data, call the list operation again, +passing in the value of the most recent response's OpcNextPage as the value of Page in the next list operation call. +When there is no more data the OpcNextPage field will be nil. An example of pagination using this logic can be found here: https://github.com/oracle/oci-go-sdk/blob/master/example/example_core_test.go#L86 + +Logging and Debugging + +The SDK has a built-in logging mechanism used internally. The internal logging logic is used to record the raw http +requests, responses and potential errors when (un)marshalling request and responses. + +To expose debugging logs, set the environment variable "OCI_GO_SDK_DEBUG" to "1", or some other non empty string. + + +Forward Compatibility + +Some response fields are enum-typed. In the future, individual services may return values not covered by existing enums +for that field. To address this possibility, every enum-type response field is a modeled as a type that supports any string. +Thus if a service returns a value that is not recognized by your version of the SDK, then the response field will be set to this value. + +When individual services return a polymorphic json response not available as a concrete struct, the SDK will return an implementation that only satisfies +the interface modeling the polymorphic json response. + + +Contributions + +Got a fix for a bug, or a new feature you'd like to contribute? The SDK is open source and accepting pull requests on GitHub +https://github.com/oracle/oci-go-sdk + +License + +Licensing information available at: https://github.com/oracle/oci-go-sdk/blob/master/LICENSE.txt + +Notifications + +To be notified when a new version of the Go SDK is released, subscribe to the following feed: https://github.com/oracle/oci-go-sdk/releases.atom + +Questions or Feedback + +Please refer to this link: https://github.com/oracle/oci-go-sdk#help + + + + + */ +package oci + +//go:generate go run cmd/genver/main.go cmd/genver/version_template.go --output common/version.go diff --git a/vendor/github.com/oracle/oci-go-sdk/wercker.yml b/vendor/github.com/oracle/oci-go-sdk/wercker.yml new file mode 100644 index 000000000..58255f22c --- /dev/null +++ b/vendor/github.com/oracle/oci-go-sdk/wercker.yml @@ -0,0 +1,26 @@ +box: + id: golang + ports: + - "5000" + +build: + steps: + - script: + name: golint-prepare + code: | + go get github.com/golang/lint/golint + go install github.com/golang/lint/golint + + - script: + name: symlinking src code + code: | + mkdir -p $GOPATH/src/github.com/oracle + ln -s $WERCKER_SOURCE_DIR $GOPATH/src/github.com/oracle/oci-go-sdk + ls -al $GOPATH/src/github.com/oracle/oci-go-sdk + + - script: + name: make-build + code: | + make build + + diff --git a/vendor/vendor.json b/vendor/vendor.json index 3f24598df..bb00a6f68 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1,6 +1,6 @@ { "comment": "", - "ignore": "test appengine", + "ignore": "test", "package": [ { "checksumSHA1": "aABATU51PlDHfGeSe5cc9udwSXg=", @@ -1091,6 +1091,13 @@ "revision": "96aac992fc8b1a4c83841a6c3e7178d20d989625", "revisionTime": "2018-01-05T11:11:33Z" }, + { + "checksumSHA1": "/LfGOK58LAN5bN/kVhyjw6prFuw=", + "path": "github.com/oracle/oci-go-sdk", + "revision": "36126af3da60f6d2053487efed8801aa794f7605", + "revisionTime": "2018-03-02T19:49:46Z", + "tree": true + }, { "checksumSHA1": "/NoE6t3UkW4/iKAtbf59GGv6tF8=", "path": "github.com/packer-community/winrmcp/winrmcp", From c442ba165e10a5f00ed3b8c4ae0079a7a83d1bc8 Mon Sep 17 00:00:00 2001 From: Harvey Lowndes <harvey.lowndes@oracle.com> Date: Wed, 11 Apr 2018 10:20:40 +0100 Subject: [PATCH 0921/1007] Migrate to official OCI Go SDK --- builder/oracle/oci/artifact.go | 15 +- builder/oracle/oci/builder.go | 11 +- builder/oracle/oci/client/base_client.go | 216 ------------- builder/oracle/oci/client/client.go | 31 -- builder/oracle/oci/client/client_test.go | 49 --- builder/oracle/oci/client/compute.go | 21 -- builder/oracle/oci/client/config.go | 240 --------------- builder/oracle/oci/client/config_test.go | 283 ------------------ builder/oracle/oci/client/error.go | 27 -- builder/oracle/oci/client/image.go | 122 -------- builder/oracle/oci/client/image_test.go | 115 ------- builder/oracle/oci/client/instance.go | 129 -------- builder/oracle/oci/client/instance_test.go | 96 ------ builder/oracle/oci/client/transport.go | 116 ------- builder/oracle/oci/client/transport_test.go | 156 ---------- builder/oracle/oci/client/vnic.go | 47 --- builder/oracle/oci/client/vnic_attachment.go | 52 ---- .../oracle/oci/client/vnic_attachment_test.go | 31 -- builder/oracle/oci/client/vnic_test.go | 29 -- builder/oracle/oci/client/waiters.go | 59 ---- builder/oracle/oci/client/waiters_test.go | 80 ----- builder/oracle/oci/config.go | 120 +++----- builder/oracle/oci/config_provider.go | 76 +++++ builder/oracle/oci/config_test.go | 211 ++++++++++--- builder/oracle/oci/driver.go | 6 +- builder/oracle/oci/driver_mock.go | 10 +- builder/oracle/oci/driver_oci.go | 158 +++++++--- builder/oracle/oci/step_image.go | 2 +- builder/oracle/oci/step_test.go | 17 +- 29 files changed, 433 insertions(+), 2092 deletions(-) delete mode 100644 builder/oracle/oci/client/base_client.go delete mode 100644 builder/oracle/oci/client/client.go delete mode 100644 builder/oracle/oci/client/client_test.go delete mode 100644 builder/oracle/oci/client/compute.go delete mode 100644 builder/oracle/oci/client/config.go delete mode 100644 builder/oracle/oci/client/config_test.go delete mode 100644 builder/oracle/oci/client/error.go delete mode 100644 builder/oracle/oci/client/image.go delete mode 100644 builder/oracle/oci/client/image_test.go delete mode 100644 builder/oracle/oci/client/instance.go delete mode 100644 builder/oracle/oci/client/instance_test.go delete mode 100644 builder/oracle/oci/client/transport.go delete mode 100644 builder/oracle/oci/client/transport_test.go delete mode 100644 builder/oracle/oci/client/vnic.go delete mode 100644 builder/oracle/oci/client/vnic_attachment.go delete mode 100644 builder/oracle/oci/client/vnic_attachment_test.go delete mode 100644 builder/oracle/oci/client/vnic_test.go delete mode 100644 builder/oracle/oci/client/waiters.go delete mode 100644 builder/oracle/oci/client/waiters_test.go create mode 100644 builder/oracle/oci/config_provider.go diff --git a/builder/oracle/oci/artifact.go b/builder/oracle/oci/artifact.go index e237d48e4..a454ff7c7 100644 --- a/builder/oracle/oci/artifact.go +++ b/builder/oracle/oci/artifact.go @@ -3,12 +3,12 @@ package oci import ( "fmt" - client "github.com/hashicorp/packer/builder/oracle/oci/client" + "github.com/oracle/oci-go-sdk/core" ) // Artifact is an artifact implementation that contains a built Custom Image. type Artifact struct { - Image client.Image + Image core.Image Region string driver Driver } @@ -26,13 +26,18 @@ func (a *Artifact) Files() []string { // Id returns the OCID of the associated Image. func (a *Artifact) Id() string { - return a.Image.ID + return *a.Image.Id } func (a *Artifact) String() string { + var displayName string + if a.Image.DisplayName != nil { + displayName = *a.Image.DisplayName + } + return fmt.Sprintf( "An image was created: '%v' (OCID: %v) in region '%v'", - a.Image.DisplayName, a.Image.ID, a.Region, + displayName, *a.Image.Id, a.Region, ) } @@ -42,5 +47,5 @@ func (a *Artifact) State(name string) interface{} { // Destroy deletes the custom image associated with the artifact. func (a *Artifact) Destroy() error { - return a.driver.DeleteImage(a.Image.ID) + return a.driver.DeleteImage(*a.Image.Id) } diff --git a/builder/oracle/oci/builder.go b/builder/oracle/oci/builder.go index 612fdf4f6..6ceaaf2d2 100644 --- a/builder/oracle/oci/builder.go +++ b/builder/oracle/oci/builder.go @@ -7,11 +7,11 @@ import ( "log" ocommon "github.com/hashicorp/packer/builder/oracle/common" - client "github.com/hashicorp/packer/builder/oracle/oci/client" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" + "github.com/oracle/oci-go-sdk/core" ) // BuilderId uniquely identifies the builder @@ -78,10 +78,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe return nil, rawErr.(error) } + region, err := b.config.ConfigProvider.Region() + if err != nil { + return nil, err + } + // Build the artifact and return it artifact := &Artifact{ - Image: state.Get("image").(client.Image), - Region: b.config.AccessCfg.Region, + Image: state.Get("image").(core.Image), + Region: region, driver: driver, } diff --git a/builder/oracle/oci/client/base_client.go b/builder/oracle/oci/client/base_client.go deleted file mode 100644 index 01d66215a..000000000 --- a/builder/oracle/oci/client/base_client.go +++ /dev/null @@ -1,216 +0,0 @@ -package oci - -import ( - "bytes" - "encoding/json" - "net/http" - "net/url" - - "github.com/google/go-querystring/query" -) - -const ( - contentType = "Content-Type" - jsonContentType = "application/json" -) - -// baseClient provides a basic (AND INTENTIONALLY INCOMPLETE) JSON REST client -// that abstracts away some of the repetitive code required in the OCI Client. -type baseClient struct { - httpClient *http.Client - method string - url string - queryStruct interface{} - header http.Header - body interface{} -} - -// newBaseClient constructs a default baseClient. -func newBaseClient() *baseClient { - return &baseClient{ - httpClient: http.DefaultClient, - method: "GET", - header: make(http.Header), - } -} - -// New creates a copy of an existing baseClient. -func (c *baseClient) New() *baseClient { - // Copy headers - header := make(http.Header) - for k, v := range c.header { - header[k] = v - } - - return &baseClient{ - httpClient: c.httpClient, - method: c.method, - url: c.url, - header: header, - } -} - -// Client sets the http Client used to perform requests. -func (c *baseClient) Client(httpClient *http.Client) *baseClient { - if httpClient == nil { - c.httpClient = http.DefaultClient - } else { - c.httpClient = httpClient - } - return c -} - -// Base sets the base client url. -func (c *baseClient) Base(path string) *baseClient { - c.url = path - return c -} - -// Path extends the client url. -func (c *baseClient) Path(path string) *baseClient { - baseURL, baseErr := url.Parse(c.url) - pathURL, pathErr := url.Parse(path) - // Bail on parsing error leaving the client's url unmodified - if baseErr != nil || pathErr != nil { - return c - } - - c.url = baseURL.ResolveReference(pathURL).String() - return c -} - -// QueryStruct sets the struct from which the request querystring is built. -func (c *baseClient) QueryStruct(params interface{}) *baseClient { - c.queryStruct = params - return c -} - -// SetBody wraps a given struct for serialisation and sets the client body. -func (c *baseClient) SetBody(params interface{}) *baseClient { - c.body = params - return c -} - -// Header - -// AddHeader adds a HTTP header to the client. Existing keys will be extended. -func (c *baseClient) AddHeader(key, value string) *baseClient { - c.header.Add(key, value) - return c -} - -// SetHeader sets a HTTP header on the client. Existing keys will be -// overwritten. -func (c *baseClient) SetHeader(key, value string) *baseClient { - c.header.Add(key, value) - return c -} - -// HTTP methods (subset) - -// Get sets the client's HTTP method to GET. -func (c *baseClient) Get(path string) *baseClient { - c.method = "GET" - return c.Path(path) -} - -// Post sets the client's HTTP method to POST. -func (c *baseClient) Post(path string) *baseClient { - c.method = "POST" - return c.Path(path) -} - -// Delete sets the client's HTTP method to DELETE. -func (c *baseClient) Delete(path string) *baseClient { - c.method = "DELETE" - return c.Path(path) -} - -// Do executes a HTTP request and returns the response encoded as either error -// or success values. -func (c *baseClient) Do(req *http.Request, successV, failureV interface{}) (*http.Response, error) { - resp, err := c.httpClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode >= 200 && resp.StatusCode < 300 { - if successV != nil { - err = json.NewDecoder(resp.Body).Decode(successV) - } - } else { - if failureV != nil { - err = json.NewDecoder(resp.Body).Decode(failureV) - } - } - - return resp, err -} - -// Request builds a http.Request from the baseClient instance. -func (c *baseClient) Request() (*http.Request, error) { - reqURL, err := url.Parse(c.url) - if err != nil { - return nil, err - } - - if c.queryStruct != nil { - err = addQueryStruct(reqURL, c.queryStruct) - if err != nil { - return nil, err - } - } - - body := &bytes.Buffer{} - if c.body != nil { - if err := json.NewEncoder(body).Encode(c.body); err != nil { - return nil, err - } - } - - req, err := http.NewRequest(c.method, reqURL.String(), body) - if err != nil { - return nil, err - } - - // Add headers to request - for k, vs := range c.header { - for _, v := range vs { - req.Header.Add(k, v) - } - } - - return req, nil -} - -// Receive creates a http request from the client and executes it returning the -// response. -func (c *baseClient) Receive(successV, failureV interface{}) (*http.Response, error) { - req, err := c.Request() - if err != nil { - return nil, err - } - return c.Do(req, successV, failureV) -} - -// addQueryStruct converts a struct to a querystring and merges any values -// provided in the URL itself. -func addQueryStruct(reqURL *url.URL, queryStruct interface{}) error { - urlValues, err := url.ParseQuery(reqURL.RawQuery) - if err != nil { - return err - } - queryValues, err := query.Values(queryStruct) - if err != nil { - return err - } - - for k, vs := range queryValues { - for _, v := range vs { - urlValues.Add(k, v) - } - } - reqURL.RawQuery = urlValues.Encode() - return nil -} diff --git a/builder/oracle/oci/client/client.go b/builder/oracle/oci/client/client.go deleted file mode 100644 index 8e6c1762d..000000000 --- a/builder/oracle/oci/client/client.go +++ /dev/null @@ -1,31 +0,0 @@ -package oci - -import ( - "net/http" -) - -const ( - apiVersion = "20160918" - userAgent = "go-oci/" + apiVersion - baseURLPattern = "https://%s.%s.oraclecloud.com/%s/" -) - -// Client is the main interface through which consumers interact with the OCI -// API. -type Client struct { - UserAgent string - Compute *ComputeClient - Config *Config -} - -// NewClient creates a new Client for communicating with the OCI API. -func NewClient(config *Config) (*Client, error) { - transport := NewTransport(http.DefaultTransport, config) - base := newBaseClient().Client(&http.Client{Transport: transport}) - - return &Client{ - UserAgent: userAgent, - Compute: NewComputeClient(base.New().Base(config.getBaseURL("iaas"))), - Config: config, - }, nil -} diff --git a/builder/oracle/oci/client/client_test.go b/builder/oracle/oci/client/client_test.go deleted file mode 100644 index f2ebd8f87..000000000 --- a/builder/oracle/oci/client/client_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package oci - -import ( - "net/http" - "net/http/httptest" - "net/url" - "os" - - "github.com/go-ini/ini" -) - -var ( - mux *http.ServeMux - client *Client - server *httptest.Server - keyFile *os.File -) - -// setup sets up a test HTTP server along with a oci.Client that is -// configured to talk to that test server. Tests should register handlers on -// mux which provide mock responses for the API method being tested. -func setup() { - mux = http.NewServeMux() - server = httptest.NewServer(mux) - parsedURL, _ := url.Parse(server.URL) - - config := &Config{} - config.baseURL = parsedURL.String() - - var cfg *ini.File - var err error - cfg, keyFile, err = BaseTestConfig() - - config, err = loadConfigSection(cfg, "DEFAULT", config) - if err != nil { - panic(err) - } - - client, err = NewClient(config) - if err != nil { - panic("Failed to instantiate test client") - } -} - -// teardown closes the test HTTP server -func teardown() { - server.Close() - os.Remove(keyFile.Name()) -} diff --git a/builder/oracle/oci/client/compute.go b/builder/oracle/oci/client/compute.go deleted file mode 100644 index 183a3794f..000000000 --- a/builder/oracle/oci/client/compute.go +++ /dev/null @@ -1,21 +0,0 @@ -package oci - -// ComputeClient is a client for the OCI Compute API. -type ComputeClient struct { - BaseURL string - Instances *InstanceService - Images *ImageService - VNICAttachments *VNICAttachmentService - VNICs *VNICService -} - -// NewComputeClient creates a new client for communicating with the OCI -// Compute API. -func NewComputeClient(s *baseClient) *ComputeClient { - return &ComputeClient{ - Instances: NewInstanceService(s), - Images: NewImageService(s), - VNICAttachments: NewVNICAttachmentService(s), - VNICs: NewVNICService(s), - } -} diff --git a/builder/oracle/oci/client/config.go b/builder/oracle/oci/client/config.go deleted file mode 100644 index 4df6b6a01..000000000 --- a/builder/oracle/oci/client/config.go +++ /dev/null @@ -1,240 +0,0 @@ -package oci - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" - "io/ioutil" - "os" - - "github.com/go-ini/ini" - "github.com/mitchellh/go-homedir" -) - -// Config API authentication and target configuration -type Config struct { - // User OCID e.g. ocid1.user.oc1..aaaaaaaadcshyehbkvxl7arse3lv7z5oknexjgfhnhwidtugsxhlm4247 - User string `ini:"user"` - - // User's Tenancy OCID e.g. ocid1.tenancy.oc1..aaaaaaaagtgvshv6opxzjyzkupkt64ymd32n6kbomadanpcg43d - Tenancy string `ini:"tenancy"` - - // Bare metal region identifier (e.g. us-phoenix-1) - Region string `ini:"region"` - - // Hex key fingerprint (e.g. b5:a0:62:57:28:0d:fd:c9:59:16:eb:d4:51:9f:70:e4) - Fingerprint string `ini:"fingerprint"` - - // Path to OCI config file (e.g. ~/.oci/config) - KeyFile string `ini:"key_file"` - - // Passphrase used for the key, if it is encrypted. - PassPhrase string `ini:"pass_phrase"` - - // Private key (loaded via LoadPrivateKey or ParsePrivateKey) - Key *rsa.PrivateKey - - // Used to override base API URL. - baseURL string -} - -// getBaseURL returns either the specified base URL or builds the appropriate -// URL based on service, region, and API version. -func (c *Config) getBaseURL(service string) string { - if c.baseURL != "" { - return c.baseURL - } - return fmt.Sprintf(baseURLPattern, service, c.Region, apiVersion) -} - -// LoadConfigsFromFile loads all oracle oci configurations from a file -// (generally ~/.oci/config). -func LoadConfigsFromFile(path string) (map[string]*Config, error) { - if _, err := os.Stat(path); err != nil { - return nil, fmt.Errorf("Oracle OCI config file is missing: %s", path) - } - - cfgFile, err := ini.Load(path) - if err != nil { - err := fmt.Errorf("Failed to parse config file %s: %s", path, err.Error()) - return nil, err - } - - configs := make(map[string]*Config) - - // Load DEFAULT section to populate defaults for all other configs - config, err := loadConfigSection(cfgFile, "DEFAULT", nil) - if err != nil { - return nil, err - } - configs["DEFAULT"] = config - - // Load other sections. - for _, sectionName := range cfgFile.SectionStrings() { - if sectionName == "DEFAULT" { - continue - } - - // Map to Config struct with defaults from DEFAULT section. - config, err := loadConfigSection(cfgFile, sectionName, configs["DEFAULT"]) - if err != nil { - return nil, err - } - configs[sectionName] = config - } - - return configs, nil -} - -// Loads an individual Config object from a ini.Section in the Oracle OCI config -// file. -func loadConfigSection(f *ini.File, sectionName string, config *Config) (*Config, error) { - if config == nil { - config = &Config{} - } - - section, err := f.GetSection(sectionName) - if err != nil { - return nil, fmt.Errorf("Config file does not contain a %s section", sectionName) - } - - if err := section.MapTo(config); err != nil { - return nil, err - } - - config.Key, err = LoadPrivateKey(config) - if err != nil { - return nil, err - } - - return config, err -} - -// LoadPrivateKey loads private key from disk and parses it. -func LoadPrivateKey(config *Config) (*rsa.PrivateKey, error) { - // Expand '~' to $HOME - path, err := homedir.Expand(config.KeyFile) - if err != nil { - return nil, err - } - - // Read and parse API signing key - keyContent, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - key, err := ParsePrivateKey(keyContent, []byte(config.PassPhrase)) - - return key, err -} - -// ParsePrivateKey parses a PEM encoded array of bytes into an rsa.PrivateKey. -// Attempts to decrypt the PEM encoded array of bytes with the given password -// if the PEM encoded byte array is encrypted. -func ParsePrivateKey(content, password []byte) (*rsa.PrivateKey, error) { - keyBlock, _ := pem.Decode(content) - - if keyBlock == nil { - return nil, errors.New("could not decode PEM private key") - } - - var der []byte - var err error - if x509.IsEncryptedPEMBlock(keyBlock) { - if len(password) < 1 { - return nil, errors.New("encrypted private key but no pass phrase provided") - } - der, err = x509.DecryptPEMBlock(keyBlock, password) - if err != nil { - return nil, err - } - } else { - der = keyBlock.Bytes - } - - if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { - return key, nil - } - - key, err := x509.ParsePKCS8PrivateKey(der) - if err == nil { - switch key := key.(type) { - case *rsa.PrivateKey: - return key, nil - default: - return nil, errors.New("Private key is not an RSA private key") - } - } - return nil, fmt.Errorf("Failed to parse private key :%s", err) -} - -// BaseTestConfig creates the base (DEFAULT) config including a temporary key -// file. -// NOTE: Caller is responsible for removing temporary key file. -func BaseTestConfig() (*ini.File, *os.File, error) { - keyFile, err := generateRSAKeyFile() - if err != nil { - return nil, keyFile, err - } - // Build ini - cfg := ini.Empty() - section, _ := cfg.NewSection("DEFAULT") - section.NewKey("region", "us-ashburn-1") - section.NewKey("tenancy", "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - section.NewKey("user", "ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - section.NewKey("fingerprint", "3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55") - section.NewKey("key_file", keyFile.Name()) - - return cfg, keyFile, nil -} - -// WriteTestConfig writes a ini.File to a temporary file for use in unit tests. -// NOTE: Caller is responsible for removing temporary file. -func WriteTestConfig(cfg *ini.File) (*os.File, error) { - confFile, err := ioutil.TempFile("", "config_file") - if err != nil { - return nil, err - } - - _, err = cfg.WriteTo(confFile) - if err != nil { - os.Remove(confFile.Name()) - return nil, err - } - - return confFile, nil -} - -// generateRSAKeyFile generates an RSA key file for use in unit tests. -// NOTE: The caller is responsible for deleting the temporary file. -func generateRSAKeyFile() (*os.File, error) { - // Create temporary file for the key - f, err := ioutil.TempFile("", "key") - if err != nil { - return nil, err - } - - // Generate key - priv, err := rsa.GenerateKey(rand.Reader, 2014) - if err != nil { - return nil, err - } - - // ASN.1 DER encoded form - privDer := x509.MarshalPKCS1PrivateKey(priv) - privBlk := pem.Block{ - Type: "RSA PRIVATE KEY", - Headers: nil, - Bytes: privDer, - } - - // Write the key out - if _, err := f.Write(pem.EncodeToMemory(&privBlk)); err != nil { - return nil, err - } - - return f, nil -} diff --git a/builder/oracle/oci/client/config_test.go b/builder/oracle/oci/client/config_test.go deleted file mode 100644 index 1be34c5f0..000000000 --- a/builder/oracle/oci/client/config_test.go +++ /dev/null @@ -1,283 +0,0 @@ -package oci - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/asn1" - "encoding/pem" - "os" - "reflect" - "strings" - "testing" -) - -func TestNewConfigMissingFile(t *testing.T) { - // WHEN - _, err := LoadConfigsFromFile("some/invalid/path") - - // THEN - - if err == nil { - t.Error("Expected missing file error") - } -} - -func TestNewConfigDefaultOnly(t *testing.T) { - // GIVEN - - // Get DEFAULT config - cfg, keyFile, err := BaseTestConfig() - defer os.Remove(keyFile.Name()) - - // Write test config to file - f, err := WriteTestConfig(cfg) - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) // clean up - - // WHEN - - // Load configs - cfgs, err := LoadConfigsFromFile(f.Name()) - if err != nil { - t.Fatal(err) - } - - // THEN - - if _, ok := cfgs["DEFAULT"]; !ok { - t.Fatal("Expected DEFAULT config to exist in map") - } -} - -func TestNewConfigDefaultsPopulated(t *testing.T) { - // GIVEN - - // Get DEFAULT config - cfg, keyFile, err := BaseTestConfig() - defer os.Remove(keyFile.Name()) - - admin := cfg.Section("ADMIN") - admin.NewKey("user", "ocid1.user.oc1..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") - admin.NewKey("fingerprint", "11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11") - - // Write test config to file - f, err := WriteTestConfig(cfg) - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) // clean up - - // WHEN - - cfgs, err := LoadConfigsFromFile(f.Name()) - adminConfig, ok := cfgs["ADMIN"] - - // THEN - - if !ok { - t.Fatal("Expected ADMIN config to exist in map") - } - - if adminConfig.Region != "us-ashburn-1" { - t.Errorf("Expected 'us-ashburn-1', got '%s'", adminConfig.Region) - } -} - -func TestNewConfigDefaultsOverridden(t *testing.T) { - // GIVEN - - // Get DEFAULT config - cfg, keyFile, err := BaseTestConfig() - defer os.Remove(keyFile.Name()) - - admin := cfg.Section("ADMIN") - admin.NewKey("user", "ocid1.user.oc1..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") - admin.NewKey("fingerprint", "11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11") - - // Write test config to file - f, err := WriteTestConfig(cfg) - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) // clean up - - // WHEN - - cfgs, err := LoadConfigsFromFile(f.Name()) - adminConfig, ok := cfgs["ADMIN"] - - // THEN - - if !ok { - t.Fatal("Expected ADMIN config to exist in map") - } - - if adminConfig.Fingerprint != "11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11" { - t.Errorf("Expected fingerprint '11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11', got '%s'", - adminConfig.Fingerprint) - } -} - -func TestParseEncryptedPrivateKeyValidPassword(t *testing.T) { - // Generate private key - priv, err := rsa.GenerateKey(rand.Reader, 2014) - if err != nil { - t.Fatalf("Unexpected generating RSA key: %+v", err) - } - publicKey := priv.PublicKey - - // ASN.1 DER encoded form - privDer := x509.MarshalPKCS1PrivateKey(priv) - - blockType := "RSA PRIVATE KEY" - password := []byte("password") - cipherType := x509.PEMCipherAES256 - - // Encrypt priv with password - encryptedPEMBlock, err := x509.EncryptPEMBlock( - rand.Reader, - blockType, - privDer, - password, - cipherType) - if err != nil { - t.Fatalf("Unexpected error encrypting PEM block: %+v", err) - } - - // Parse private key - key, err := ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), password) - if err != nil { - t.Fatalf("unexpected error: %+v", err) - } - - // Check we get the same key back - if !reflect.DeepEqual(publicKey, key.PublicKey) { - t.Errorf("expected public key of encrypted and decrypted key to match") - } -} - -func TestParseEncryptedPrivateKeyPKCS8(t *testing.T) { - // Generate private key - priv, err := rsa.GenerateKey(rand.Reader, 2014) - if err != nil { - t.Fatalf("Unexpected generating RSA key: %+v", err) - } - publicKey := priv.PublicKey - - // Implements x509.MarshalPKCS8PrivateKey which is not included in the - // standard library. - pkey := struct { - Version int - PrivateKeyAlgorithm []asn1.ObjectIdentifier - PrivateKey []byte - }{ - Version: 0, - PrivateKeyAlgorithm: []asn1.ObjectIdentifier{{1, 2, 840, 113549, 1, 1, 1}}, - PrivateKey: x509.MarshalPKCS1PrivateKey(priv), - } - privDer, err := asn1.Marshal(pkey) - if err != nil { - t.Fatalf("Unexpected marshaling RSA key: %+v", err) - } - - blockType := "RSA PRIVATE KEY" - password := []byte("password") - cipherType := x509.PEMCipherAES256 - - // Encrypt priv with password - encryptedPEMBlock, err := x509.EncryptPEMBlock( - rand.Reader, - blockType, - privDer, - password, - cipherType) - if err != nil { - t.Fatalf("Unexpected error encrypting PEM block: %+v", err) - } - - // Parse private key - key, err := ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), password) - if err != nil { - t.Fatalf("unexpected error: %+v", err) - } - - // Check we get the same key back - if !reflect.DeepEqual(publicKey, key.PublicKey) { - t.Errorf("expected public key of encrypted and decrypted key to match") - } -} - -func TestParseEncryptedPrivateKeyInvalidPassword(t *testing.T) { - // Generate private key - priv, err := rsa.GenerateKey(rand.Reader, 2014) - if err != nil { - t.Fatalf("Unexpected generating RSA key: %+v", err) - } - - // ASN.1 DER encoded form - privDer := x509.MarshalPKCS1PrivateKey(priv) - - blockType := "RSA PRIVATE KEY" - password := []byte("password") - cipherType := x509.PEMCipherAES256 - - // Encrypt priv with password - encryptedPEMBlock, err := x509.EncryptPEMBlock( - rand.Reader, - blockType, - privDer, - password, - cipherType) - if err != nil { - t.Fatalf("Unexpected error encrypting PEM block: %+v", err) - } - - // Parse private key (with wrong password) - _, err = ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), []byte("foo")) - if err == nil { - t.Fatalf("Expected error, got nil") - } - - if !strings.Contains(err.Error(), "decryption password incorrect") { - t.Errorf("Expected error to contain 'decryption password incorrect', got %+v", err) - } -} - -func TestParseEncryptedPrivateKeyInvalidNoPassword(t *testing.T) { - // Generate private key - priv, err := rsa.GenerateKey(rand.Reader, 2014) - if err != nil { - t.Fatalf("Unexpected generating RSA key: %+v", err) - } - - // ASN.1 DER encoded form - privDer := x509.MarshalPKCS1PrivateKey(priv) - - blockType := "RSA PRIVATE KEY" - password := []byte("password") - cipherType := x509.PEMCipherAES256 - - // Encrypt priv with password - encryptedPEMBlock, err := x509.EncryptPEMBlock( - rand.Reader, - blockType, - privDer, - password, - cipherType) - if err != nil { - t.Fatalf("Unexpected error encrypting PEM block: %+v", err) - } - - // Parse private key (with wrong password) - _, err = ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), []byte{}) - if err == nil { - t.Fatalf("Expected error, got nil") - } - - if !strings.Contains(err.Error(), "no pass phrase provided") { - t.Errorf("Expected error to contain 'no pass phrase provided', got %+v", err) - } -} diff --git a/builder/oracle/oci/client/error.go b/builder/oracle/oci/client/error.go deleted file mode 100644 index a97112f81..000000000 --- a/builder/oracle/oci/client/error.go +++ /dev/null @@ -1,27 +0,0 @@ -package oci - -import "fmt" - -// APIError encapsulates an error returned from the API -type APIError struct { - Code string `json:"code"` - Message string `json:"message"` -} - -func (e APIError) Error() string { - return fmt.Sprintf("OCI: [%s] '%s'", e.Code, e.Message) -} - -// firstError is a helper function to work out which error to return from calls -// to the API. -func firstError(err error, apiError *APIError) error { - if err != nil { - return err - } - - if apiError != nil && len(apiError.Code) > 0 { - return apiError - } - - return nil -} diff --git a/builder/oracle/oci/client/image.go b/builder/oracle/oci/client/image.go deleted file mode 100644 index 67ada02d5..000000000 --- a/builder/oracle/oci/client/image.go +++ /dev/null @@ -1,122 +0,0 @@ -package oci - -import ( - "time" -) - -// ImageService enables communicating with the OCI compute API's instance -// related endpoints. -type ImageService struct { - client *baseClient -} - -// NewImageService creates a new ImageService for communicating with the -// OCI compute API's instance related endpoints. -func NewImageService(s *baseClient) *ImageService { - return &ImageService{ - client: s.New().Path("images/"), - } -} - -// Image details a OCI boot disk image. -type Image struct { - // The OCID of the image originally used to launch the instance. - BaseImageID string `json:"baseImageId,omitempty"` - - // The OCID of the compartment containing the instance you want to use - // as the basis for the image. - CompartmentID string `json:"compartmentId"` - - // Whether instances launched with this image can be used to create new - // images. - CreateImageAllowed bool `json:"createImageAllowed"` - - // A user-friendly name for the image. It does not have to be unique, - // and it's changeable. You cannot use an Oracle-provided image name - // as a custom image name. - DisplayName string `json:"displayName,omitempty"` - - // The OCID of the image. - ID string `json:"id"` - - // Current state of the image. Allowed values are: - // - PROVISIONING - // - AVAILABLE - // - DISABLED - // - DELETED - LifecycleState string `json:"lifecycleState"` - - // The image's operating system (e.g. Oracle Linux). - OperatingSystem string `json:"operatingSystem"` - - // The image's operating system version (e.g. 7.2). - OperatingSystemVersion string `json:"operatingSystemVersion"` - - // The date and time the image was created. - TimeCreated time.Time `json:"timeCreated"` -} - -// GetImageParams are the parameters available when communicating with the -// GetImage API endpoint. -type GetImageParams struct { - ID string `url:"imageId"` -} - -// Get returns a single Image -func (s *ImageService) Get(params *GetImageParams) (Image, error) { - image := Image{} - e := &APIError{} - - _, err := s.client.New().Get(params.ID).Receive(&image, e) - err = firstError(err, e) - - return image, err -} - -// CreateImageParams are the parameters available when communicating with -// the CreateImage API endpoint. -type CreateImageParams struct { - CompartmentID string `json:"compartmentId"` - DisplayName string `json:"displayName,omitempty"` - InstanceID string `json:"instanceId"` -} - -// Create creates a new custom image based on a running compute instance. It -// does *not* wait for the imaging process to finish. -func (s *ImageService) Create(params *CreateImageParams) (Image, error) { - image := Image{} - e := &APIError{} - - _, err := s.client.New().Post("").SetBody(params).Receive(&image, &e) - err = firstError(err, e) - - return image, err -} - -// GetResourceState GETs the LifecycleState of the given image id. -func (s *ImageService) GetResourceState(id string) (string, error) { - image, err := s.Get(&GetImageParams{ID: id}) - if err != nil { - return "", err - } - return image.LifecycleState, nil - -} - -// DeleteImageParams are the parameters available when communicating with -// the DeleteImage API endpoint. -type DeleteImageParams struct { - ID string `url:"imageId"` -} - -// Delete deletes an existing custom image. -// NOTE: Deleting an image results in the API endpoint returning 404 on -// subsequent calls. As such deletion can't be waited on with a Waiter. -func (s *ImageService) Delete(params *DeleteImageParams) error { - e := &APIError{} - - _, err := s.client.New().Delete(params.ID).SetBody(params).Receive(nil, e) - err = firstError(err, e) - - return err -} diff --git a/builder/oracle/oci/client/image_test.go b/builder/oracle/oci/client/image_test.go deleted file mode 100644 index ef55cc552..000000000 --- a/builder/oracle/oci/client/image_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package oci - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestGetImage(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.image.oc1.phx.a" - path := fmt.Sprintf("/images/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, `{"id":"%s"}`, id) - }) - - image, err := client.Compute.Images.Get(&GetImageParams{ID: id}) - if err != nil { - t.Errorf("Client.Compute.Images.Get() returned error: %v", err) - } - - want := Image{ID: id} - - if !reflect.DeepEqual(image, want) { - t.Errorf("Client.Compute.Images.Get() returned %+v, want %+v", image, want) - } -} - -func TestCreateImage(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/images/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"displayName": "go-oci test"}`) - }) - - params := &CreateImageParams{ - CompartmentID: "ocid1.compartment.oc1..a", - DisplayName: "go-oci test image", - InstanceID: "ocid1.image.oc1.phx.a", - } - - image, err := client.Compute.Images.Create(params) - if err != nil { - t.Errorf("Client.Compute.Images.Create() returned error: %v", err) - } - - want := Image{DisplayName: "go-oci test"} - - if !reflect.DeepEqual(image, want) { - t.Errorf("Client.Compute.Images.Create() returned %+v, want %+v", image, want) - } -} - -func TestImageGetResourceState(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.image.oc1.phx.a" - path := fmt.Sprintf("/images/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"LifecycleState": "AVAILABLE"}`) - }) - - state, err := client.Compute.Images.GetResourceState(id) - if err != nil { - t.Errorf("Client.Compute.Images.GetResourceState() returned error: %v", err) - } - - want := "AVAILABLE" - if state != want { - t.Errorf("Client.Compute.Images.GetResourceState() returned %+v, want %+v", state, want) - } -} - -func TestImageGetResourceStateInvalidID(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.image.oc1.phx.a" - path := fmt.Sprintf("/images/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotFound) - fmt.Fprint(w, `{"code": "NotAuthorizedOrNotFound"}`) - }) - - state, err := client.Compute.Images.GetResourceState(id) - if err == nil { - t.Errorf("Client.Compute.Images.GetResourceState() expected error, got %v", state) - } - - want := &APIError{Code: "NotAuthorizedOrNotFound"} - if !reflect.DeepEqual(err, want) { - t.Errorf("Client.Compute.Images.GetResourceState() errored with %+v, want %+v", err, want) - } -} - -func TestDeleteInstance(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.image.oc1.phx.a" - path := fmt.Sprintf("/images/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNoContent) - }) - - err := client.Compute.Images.Delete(&DeleteImageParams{ID: id}) - if err != nil { - t.Errorf("Client.Compute.Images.Delete() returned error: %v", err) - } -} diff --git a/builder/oracle/oci/client/instance.go b/builder/oracle/oci/client/instance.go deleted file mode 100644 index e81ad3a44..000000000 --- a/builder/oracle/oci/client/instance.go +++ /dev/null @@ -1,129 +0,0 @@ -package oci - -import ( - "time" -) - -// InstanceService enables communicating with the OCI compute API's instance -// related endpoints. -type InstanceService struct { - client *baseClient -} - -// NewInstanceService creates a new InstanceService for communicating with the -// OCI compute API's instance related endpoints. -func NewInstanceService(s *baseClient) *InstanceService { - return &InstanceService{ - client: s.New().Path("instances/"), - } -} - -// Instance details a OCI compute instance. -type Instance struct { - // The Availability Domain the instance is running in. - AvailabilityDomain string `json:"availabilityDomain"` - - // The OCID of the compartment that contains the instance. - CompartmentID string `json:"compartmentId"` - - // A user-friendly name. Does not have to be unique, and it's changeable. - DisplayName string `json:"displayName,omitempty"` - - // The OCID of the instance. - ID string `json:"id"` - - // The image used to boot the instance. - ImageID string `json:"imageId,omitempty"` - - // The current state of the instance. Allowed values: - // - PROVISIONING - // - RUNNING - // - STARTING - // - STOPPING - // - STOPPED - // - CREATING_IMAGE - // - TERMINATING - // - TERMINATED - LifecycleState string `json:"lifecycleState"` - - // Custom metadata that you provide. - Metadata map[string]string `json:"metadata,omitempty"` - - // The region that contains the Availability Domain the instance is running in. - Region string `json:"region"` - - // The shape of the instance. The shape determines the number of CPUs - // and the amount of memory allocated to the instance. - Shape string `json:"shape"` - - // The date and time the instance was created. - TimeCreated time.Time `json:"timeCreated"` -} - -// GetInstanceParams are the parameters available when communicating with the -// GetInstance API endpoint. -type GetInstanceParams struct { - ID string `url:"instanceId,omitempty"` -} - -// Get returns a single Instance -func (s *InstanceService) Get(params *GetInstanceParams) (Instance, error) { - instance := Instance{} - e := &APIError{} - - _, err := s.client.New().Get(params.ID).Receive(&instance, e) - err = firstError(err, e) - - return instance, err -} - -// LaunchInstanceParams are the parameters available when communicating with -// the LunchInstance API endpoint. -type LaunchInstanceParams struct { - AvailabilityDomain string `json:"availabilityDomain,omitempty"` - CompartmentID string `json:"compartmentId,omitempty"` - DisplayName string `json:"displayName,omitempty"` - ImageID string `json:"imageId,omitempty"` - Metadata map[string]string `json:"metadata,omitempty"` - OPCiPXEScript string `json:"opcIpxeScript,omitempty"` - Shape string `json:"shape,omitempty"` - SubnetID string `json:"subnetId,omitempty"` -} - -// Launch creates a new OCI compute instance. It does *not* wait for the -// instance to boot. -func (s *InstanceService) Launch(params *LaunchInstanceParams) (Instance, error) { - instance := &Instance{} - e := &APIError{} - - _, err := s.client.New().Post("").SetBody(params).Receive(instance, e) - err = firstError(err, e) - - return *instance, err -} - -// TerminateInstanceParams are the parameters available when communicating with -// the TerminateInstance API endpoint. -type TerminateInstanceParams struct { - ID string `url:"instanceId,omitempty"` -} - -// Terminate terminates a running OCI compute instance. -// instance to boot. -func (s *InstanceService) Terminate(params *TerminateInstanceParams) error { - e := &APIError{} - - _, err := s.client.New().Delete(params.ID).SetBody(params).Receive(nil, e) - err = firstError(err, e) - - return err -} - -// GetResourceState GETs the LifecycleState of the given instance id. -func (s *InstanceService) GetResourceState(id string) (string, error) { - instance, err := s.Get(&GetInstanceParams{ID: id}) - if err != nil { - return "", err - } - return instance.LifecycleState, nil -} diff --git a/builder/oracle/oci/client/instance_test.go b/builder/oracle/oci/client/instance_test.go deleted file mode 100644 index e45b707af..000000000 --- a/builder/oracle/oci/client/instance_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package oci - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestGetInstance(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.instance.oc1.phx.a" - path := fmt.Sprintf("/instances/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, `{"id":"%s"}`, id) - }) - - instance, err := client.Compute.Instances.Get(&GetInstanceParams{ID: id}) - if err != nil { - t.Errorf("Client.Compute.Instances.Get() returned error: %v", err) - } - - want := Instance{ID: id} - - if !reflect.DeepEqual(instance, want) { - t.Errorf("Client.Compute.Instances.Get() returned %+v, want %+v", instance, want) - } -} - -func TestLaunchInstance(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc("/instances/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"displayName": "go-oci test"}`) - }) - - params := &LaunchInstanceParams{ - AvailabilityDomain: "aaaa:PHX-AD-1", - CompartmentID: "ocid1.compartment.oc1..a", - DisplayName: "go-oci test", - ImageID: "ocid1.image.oc1.phx.a", - Shape: "VM.Standard1.1", - SubnetID: "ocid1.subnet.oc1.phx.a", - } - - instance, err := client.Compute.Instances.Launch(params) - if err != nil { - t.Errorf("Client.Compute.Instances.Launch() returned error: %v", err) - } - - want := Instance{DisplayName: "go-oci test"} - - if !reflect.DeepEqual(instance, want) { - t.Errorf("Client.Compute.Instances.Launch() returned %+v, want %+v", instance, want) - } -} - -func TestTerminateInstance(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.instance.oc1.phx.a" - path := fmt.Sprintf("/instances/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNoContent) - }) - - err := client.Compute.Instances.Terminate(&TerminateInstanceParams{ID: id}) - if err != nil { - t.Errorf("Client.Compute.Instances.Terminate() returned error: %v", err) - } -} - -func TestInstanceGetResourceState(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.instance.oc1.phx.a" - path := fmt.Sprintf("/instances/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, `{"LifecycleState": "RUNNING"}`) - }) - - state, err := client.Compute.Instances.GetResourceState(id) - if err != nil { - t.Errorf("Client.Compute.Instances.GetResourceState() returned error: %v", err) - } - - want := "RUNNING" - if state != want { - t.Errorf("Client.Compute.Instances.GetResourceState() returned %+v, want %+v", state, want) - } -} diff --git a/builder/oracle/oci/client/transport.go b/builder/oracle/oci/client/transport.go deleted file mode 100644 index 79da20509..000000000 --- a/builder/oracle/oci/client/transport.go +++ /dev/null @@ -1,116 +0,0 @@ -package oci - -import ( - "bytes" - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "encoding/base64" - "fmt" - "io" - "net/http" - "strconv" - "strings" - "time" -) - -type nopCloser struct { - io.Reader -} - -func (nopCloser) Close() error { - return nil -} - -// Transport adds OCI signature authentication to each outgoing request. -type Transport struct { - transport http.RoundTripper - config *Config -} - -// NewTransport creates a new Transport to add OCI signature authentication -// to each outgoing request. -func NewTransport(transport http.RoundTripper, config *Config) *Transport { - return &Transport{ - transport: transport, - config: config, - } -} - -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - var buf *bytes.Buffer - - if req.Body != nil { - buf = new(bytes.Buffer) - buf.ReadFrom(req.Body) - req.Body = nopCloser{buf} - } - if req.Header.Get("date") == "" { - req.Header.Set("date", time.Now().UTC().Format(http.TimeFormat)) - } - if req.Header.Get("content-type") == "" { - req.Header.Set("content-type", "application/json") - } - if req.Header.Get("accept") == "" { - req.Header.Set("accept", "application/json") - } - if req.Header.Get("host") == "" { - req.Header.Set("host", req.URL.Host) - } - - var signheaders []string - if (req.Method == "PUT" || req.Method == "POST") && buf != nil { - signheaders = []string{"(request-target)", "host", "date", - "content-length", "content-type", "x-content-sha256"} - - if req.Header.Get("content-length") == "" { - req.Header.Set("content-length", strconv.Itoa(buf.Len())) - } - - hasher := sha256.New() - hasher.Write(buf.Bytes()) - hash := hasher.Sum(nil) - req.Header.Set("x-content-sha256", base64.StdEncoding.EncodeToString(hash)) - } else { - signheaders = []string{"date", "host", "(request-target)"} - } - - var signbuffer bytes.Buffer - for idx, header := range signheaders { - signbuffer.WriteString(header) - signbuffer.WriteString(": ") - - if header == "(request-target)" { - signbuffer.WriteString(strings.ToLower(req.Method)) - signbuffer.WriteString(" ") - signbuffer.WriteString(req.URL.RequestURI()) - } else { - signbuffer.WriteString(req.Header.Get(header)) - } - - if idx < len(signheaders)-1 { - signbuffer.WriteString("\n") - } - } - - h := sha256.New() - h.Write(signbuffer.Bytes()) - digest := h.Sum(nil) - signature, err := rsa.SignPKCS1v15(rand.Reader, t.config.Key, crypto.SHA256, digest) - if err != nil { - return nil, err - } - - authHeader := fmt.Sprintf("Signature headers=\"%s\","+ - "keyId=\"%s/%s/%s\","+ - "algorithm=\"rsa-sha256\","+ - "signature=\"%s\","+ - "version=\"1\"", - strings.Join(signheaders, " "), - t.config.Tenancy, t.config.User, t.config.Fingerprint, - base64.StdEncoding.EncodeToString(signature)) - req.Header.Add("Authorization", authHeader) - - return t.transport.RoundTrip(req) -} diff --git a/builder/oracle/oci/client/transport_test.go b/builder/oracle/oci/client/transport_test.go deleted file mode 100644 index ebf02040b..000000000 --- a/builder/oracle/oci/client/transport_test.go +++ /dev/null @@ -1,156 +0,0 @@ -package oci - -import ( - "net/http" - "strings" - "testing" -) - -const testKey = `-----BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEAyLnyzmYj0dZuDo2nclIdEyLZrFZLtw5xFldWpCUl5W3SxKDL -iIgwxpSO75Yf++Rzqc5j6S5bpIrdca6AwVXCNmjjxMPO7vLLm4l4IUOZMv5FqKaC -I2plFz9uBkzGscnYnMbsDA430082E07lYpNv1xy8JwpbrIsqIMh4XCKci/Od5sLR -kEicmOpQK42FGRTQjjmQoWtv+9XED+vYTRL0AxQEC/6i/E7yssFXZ+fpHSKWeKTQ -K/1Fc4pZ1zNzJcDXGuweISx/QMLz78TAPH5OBq/EQzHKSpKvfnWFRyBHne8pwuN8 -8wzbbD+/7OFjz28jNSERVJvfYe3X1k69IWMNGwIDAQABAoIBAQCZhcdU38AzxSrG -DMfuYymDslsEObiNWQlbig9lWlhCwx26cDVbxrZvm747NvpdgVyJmqbF+UP0dJVs -Voh51qrFTLIwk4bZMXBTFPCBmJ865knG9RuCFOUew8/WF7C82GHJf0eY7OL7xpDY -cbZ2D8gxofOydHSrYoElM88CwSI00xPCbBKEMrBO94oXC8yfp2bmV6bNhVXwFDEM -qda7M6jVAsBrTOzxUF5VdUUU/MLsu2cCk/ap1zer2Bml9Afk1bMeGJ3XDQgol0pS -CLxaGczpSNVMF9+pjA5sFHR5rmcl0b/kC9HsgOJGhLOimtS94O64dSdWifgsjf6+ -fhT2SMiRAoGBAOUDwkdzNqQfvS+qrP2ULpB4vt7MZ70rDGmyMDLZ1VWgcm2cDIad -b7MkFG6GCa48mKkFXK9mOPyq8ELoTjZo2p+relEqf49BpaNxr+cp11pX7g0AkzCa -a8LwdOOUW/poqYl2xLuw9Rz6ky6ybzatMvCwpQCwnbAdABIVxz4oQKHpAoGBAOBg -3uYC/ynGdF9gJTfdS5XPYoLcKKRRspBZrvvDHaWyBnanm5KYwDAZPzLQMqcpyPeo -5xgwMmtNlc6lKKyGkhSLNCV+eO3yAx1h/cq7ityvMS7u6o5sq+/bvtEnbUPYbEtk -AhVD7/w5Yyzzi4beiQxDKe0q1mvUAH56aGqJivBjAoGBALmUMTPbDhUzTwg4Y1Rd -ZtpVrj43H31wS+++oEYktTZc/T0LLi9Llr9w5kmlvmR94CtfF/ted6FwF5/wRajb -kQXAXC83pAR/au0mbCeDhWpFRLculxfUmqxuVBozF9G0TGYDY2rA+++OsgQuPebt -tRDL4/nKJQ4Ygf0lvr4EulM5AoGBALoIdyabu3WmfhwJujH8P8wA+ztmUCgVOIio -YwWIe49C8Er2om1ESqxWcmit6CFi6qY0Gw6Z/2OqGxgPJY8NsBZqaBziJF+cdWqq -MWMiZXqdopi4LC9T+KZROn9tQhGrYfaL/5IkFti3t/uwHbH/1f8dvKhQCSGzz4kN -8n7KdTDjAoGAKh8XdIOQlThFK108VT2yp4BGZXEOvWrR19DLbuUzHVrEX+Bd+uFo -Ruk9iKEH7PSnlRnIvWc1y9qN7fUi5OR3LvQNGlXHyUl6CtmH3/b064bBKudC+XTn -VBelcIoGpH7Dn9I6pKUFauJz1TSbQCIjYGNqrjyzLtG+lH/gy5q4xs8= ------END RSA PRIVATE KEY-----` - -type testTarget struct { - CapturedReq *http.Request - Response *http.Response -} - -func (target *testTarget) RoundTrip(req *http.Request) (*http.Response, error) { - target.CapturedReq = req - return target.Response, nil -} - -func testReq(method string, url string, body string, headers map[string]string) *http.Request { - req, err := http.NewRequest(method, url, strings.NewReader(body)) - if err != nil { - panic(err.Error()) - } - - for k, v := range headers { - req.Header.Add(k, v) - } - return req -} - -var KnownGoodCases = []struct { - name string - inputRequest func() *http.Request - expectedHeaders map[string]string -}{ - { - name: "Simple GET", - inputRequest: func() *http.Request { - return testReq("GET", "https://example.com/", "", map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT"}) - }, - expectedHeaders: map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT", - "content-type": "application/json", - "host": "example.com", - "accept": "application/json", - "Authorization": "Signature headers=\"date host (request-target)\",keyId=\"tenant/testuser/3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55\",algorithm=\"rsa-sha256\",signature=\"UMw/FImQYZ5JBpfYcR9YN72lhupGl5yS+522NS9glLodU9f4oKRqaocpGdSUSRhhSDKxIx01rV547/HemJ6QqEPaJJuDQPXsGthokWMU2DBGyaMAqhLClgCJiRQMwpg4rdL2tETzkM3wy6UN+I52RYoNSdsnat2ZArCkfl8dIl9ydcwD8/+BqB8d2wyaAIS4iagdPKLAC/Mu9OzyUPOXQhYGYsoEdOowOUkHOlob65PFrlHmKJDdjEF3MDcygEpApItf4iUEloP5bjixAbZEVpj3HLQ5uaPx9m+RsLzYMeO0adE0wOv2YNmwZrExGhXh1BpTU33m5amHeUBxSaG+2A==\",version=\"1\"", - }, - }, - { - name: "Simple PUT request", - inputRequest: func() *http.Request { - return testReq("PUT", "https://example.com/", "Some Content", map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT"}) - }, - expectedHeaders: map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT", - "content-type": "application/json", - "content-length": "12", - "x-content-sha256": "lQ8fsURxamLtHxnwTYqd3MNYadJ4ZB/U9yQBKzu/fXA=", - "accept": "application/json", - "Authorization": "Signature headers=\"(request-target) host date content-length content-type x-content-sha256\",keyId=\"tenant/testuser/3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55\",algorithm=\"rsa-sha256\",signature=\"FHyPt4PE2HGH+iftzcViB76pCJ2R9+DdTCo1Ss4mH4KHQJdyQtPsCpe6Dc19zie6cRr6dsenk21yYnncic8OwZhII8DULj2//qLFGmgFi84s7LJqMQ/COiP7O9KtCN+U8MMt4PV7ZDsiGFn3/8EUJ1wxYscxSIB19S1NpuEL062JgGfkqxTkTPd7V3Xh1NlmUUtQrAMR3l56k1iV0zXY9Uw0CjWYjueMP0JUmkO7zycYAVBrx7Q8wkmejlyD7yFrAnObyEsMm9cIL9IcruWFHeCHFxRLslw7AoLxibAm2Dc9EROuvCK2UkUp8AFkE+QyYDMrrSm1NLBMWdnYqdickA==\",version=\"1\"", - }, - }, - { - name: "Simple POST request", - inputRequest: func() *http.Request { - return testReq("POST", "https://example.com/", "Some Content", map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT"}) - }, - expectedHeaders: map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT", - "content-type": "application/json", - "content-length": "12", - "x-content-sha256": "lQ8fsURxamLtHxnwTYqd3MNYadJ4ZB/U9yQBKzu/fXA=", - "accept": "application/json", - "Authorization": "Signature headers=\"(request-target) host date content-length content-type x-content-sha256\",keyId=\"tenant/testuser/3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55\",algorithm=\"rsa-sha256\",signature=\"WzGIoySkjqydwabMTxjVs05UBu0hThAEBzVs7HbYO45o2XpaoqGiNX67mNzs1PeYrGHpJp8+Ysoz66PChWV/1trxuTU92dQ/FgwvcwBRy5dQvdLkjWCZihNunSk4gt9652w6zZg/ybLon0CFbLRnlanDJDX9BgR3ttuTxf30t5qr2A4fnjFF4VjaU/CzE13cNfaWftjSd+xNcla2sbArF3R0+CEEb0xZEPzTyjjjkyvXdaPZwEprVn8IDmdJvLmRP4EniAPxE1EZIhd712M5ondQkR4/WckM44/hlKDeXGFb4y+QnU02i4IWgOWs3dh2tuzS1hp1zfq7qgPbZ4hp0A==\",version=\"1\"", - }, - }, - - { - name: "Simple DELETE", - inputRequest: func() *http.Request { - return testReq("DELETE", "https://example.com/", "Some Content", map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT"}) - }, - expectedHeaders: map[string]string{ - "date": "Mon, 26 Sep 2016 11:04:22 GMT", - "content-type": "application/json", - "accept": "application/json", - "Authorization": "Signature headers=\"date host (request-target)\",keyId=\"tenant/testuser/3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55\",algorithm=\"rsa-sha256\",signature=\"Kj4YSpONZG1cibLbNgxIp4VoS5+80fsB2Fh2Ue28+QyXq4wwrJpMP+8jEupz1yTk1SNPYuxsk7lNOgtI6G1Hq0YJJVum74j46sUwRWe+f08tMJ3c9J+rrzLfpIrakQ8PaudLhHU0eK5kuTZme1dCwRWXvZq3r5IqkGot/OGMabKpBygRv9t0i5ry+bTslSjMqafTWLosY9hgIiGrXD+meB5tpyn+gPVYc//Hc/C7uNNgLJIMk5DKVa4U0YnoY3ojafZTXZQQNGRn2NDMcZUX3f3nJlUIfiZRiOCTkbPwx/fWb4MZtYaEsY5OPficbJRvfOBxSG1wjX+8rgO7ijhMAA==\",version=\"1\"", - }, - }, -} - -func TestKnownGoodRequests(t *testing.T) { - pKey, err := ParsePrivateKey([]byte(testKey), []byte{}) - if err != nil { - t.Fatalf("Failed to parse test key: %s", err.Error()) - } - - config := &Config{ - Key: pKey, - User: "testuser", - Tenancy: "tenant", - Fingerprint: "3c:b6:44:d7:49:1a:ac:bf:de:7d:76:22:a7:f5:df:55", - } - - expectedResponse := &http.Response{} - for _, tt := range KnownGoodCases { - targetBackend := &testTarget{Response: expectedResponse} - target := NewTransport(targetBackend, config) - - _, err = target.RoundTrip(tt.inputRequest()) - if err != nil { - t.Fatalf("%s: Failed to handle request %s", tt.name, err.Error()) - } - - sentReq := targetBackend.CapturedReq - - for header, val := range tt.expectedHeaders { - if sentReq.Header.Get(header) != val { - t.Fatalf("%s: Header mismatch in response,\n\t expecting \"%s\"\n\t got \"%s\"", tt.name, val, sentReq.Header.Get(header)) - } - } - } - -} diff --git a/builder/oracle/oci/client/vnic.go b/builder/oracle/oci/client/vnic.go deleted file mode 100644 index 9922d34aa..000000000 --- a/builder/oracle/oci/client/vnic.go +++ /dev/null @@ -1,47 +0,0 @@ -package oci - -import ( - "time" -) - -// VNICService enables communicating with the OCI compute API's VNICs -// endpoint. -type VNICService struct { - client *baseClient -} - -// NewVNICService creates a new VNICService for communicating with the -// OCI compute API's instance related endpoints. -func NewVNICService(s *baseClient) *VNICService { - return &VNICService{client: s.New().Path("vnics/")} -} - -// VNIC - a virtual network interface card. -type VNIC struct { - AvailabilityDomain string `json:"availabilityDomain"` - CompartmentID string `json:"compartmentId"` - DisplayName string `json:"displayName,omitempty"` - ID string `json:"id"` - LifecycleState string `json:"lifecycleState"` - PrivateIP string `json:"privateIp"` - PublicIP string `json:"publicIp"` - SubnetID string `json:"subnetId"` - TimeCreated time.Time `json:"timeCreated"` -} - -// GetVNICParams are the parameters available when communicating with the -// ListVNICs API endpoint. -type GetVNICParams struct { - ID string `url:"vnicId"` -} - -// Get returns an individual VNIC. -func (s *VNICService) Get(params *GetVNICParams) (VNIC, error) { - VNIC := &VNIC{} - e := &APIError{} - - _, err := s.client.New().Get(params.ID).Receive(VNIC, e) - err = firstError(err, e) - - return *VNIC, err -} diff --git a/builder/oracle/oci/client/vnic_attachment.go b/builder/oracle/oci/client/vnic_attachment.go deleted file mode 100644 index 1e42a0573..000000000 --- a/builder/oracle/oci/client/vnic_attachment.go +++ /dev/null @@ -1,52 +0,0 @@ -package oci - -import ( - "time" -) - -// VNICAttachmentService enables communicating with the OCI compute API's VNIC -// attachment endpoint. -type VNICAttachmentService struct { - client *baseClient -} - -// NewVNICAttachmentService creates a new VNICAttachmentService for communicating with the -// OCI compute API's instance related endpoints. -func NewVNICAttachmentService(s *baseClient) *VNICAttachmentService { - return &VNICAttachmentService{ - client: s.New().Path("vnicAttachments/"), - } -} - -// VNICAttachment details the attachment of a VNIC to a OCI instance. -type VNICAttachment struct { - AvailabilityDomain string `json:"availabilityDomain"` - CompartmentID string `json:"compartmentId"` - DisplayName string `json:"displayName,omitempty"` - ID string `json:"id"` - InstanceID string `json:"instanceId"` - LifecycleState string `json:"lifecycleState"` - SubnetID string `json:"subnetId"` - TimeCreated time.Time `json:"timeCreated"` - VNICID string `json:"vnicId"` -} - -// ListVnicAttachmentsParams are the parameters available when communicating -// with the ListVnicAttachments API endpoint. -type ListVnicAttachmentsParams struct { - AvailabilityDomain string `url:"availabilityDomain,omitempty"` - CompartmentID string `url:"compartmentId"` - InstanceID string `url:"instanceId,omitempty"` - VNICID string `url:"vnicId,omitempty"` -} - -// List returns an array of VNICAttachments. -func (s *VNICAttachmentService) List(params *ListVnicAttachmentsParams) ([]VNICAttachment, error) { - vnicAttachments := new([]VNICAttachment) - e := new(APIError) - - _, err := s.client.New().Get("").QueryStruct(params).Receive(vnicAttachments, e) - err = firstError(err, e) - - return *vnicAttachments, err -} diff --git a/builder/oracle/oci/client/vnic_attachment_test.go b/builder/oracle/oci/client/vnic_attachment_test.go deleted file mode 100644 index 704423fb0..000000000 --- a/builder/oracle/oci/client/vnic_attachment_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package oci - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestListVNICAttachments(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.image.oc1.phx.a" - mux.HandleFunc("/vnicAttachments/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, `[{"id":"%s"}]`, id) - }) - - params := &ListVnicAttachmentsParams{InstanceID: id} - - vnicAttachment, err := client.Compute.VNICAttachments.List(params) - if err != nil { - t.Errorf("Client.Compute.VNICAttachments.List() returned error: %v", err) - } - - want := []VNICAttachment{{ID: id}} - - if !reflect.DeepEqual(vnicAttachment, want) { - t.Errorf("Client.Compute.VNICAttachments.List() returned %+v, want %+v", vnicAttachment, want) - } -} diff --git a/builder/oracle/oci/client/vnic_test.go b/builder/oracle/oci/client/vnic_test.go deleted file mode 100644 index c208db5c4..000000000 --- a/builder/oracle/oci/client/vnic_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package oci - -import ( - "fmt" - "net/http" - "reflect" - "testing" -) - -func TestGetVNIC(t *testing.T) { - setup() - defer teardown() - - id := "ocid1.vnic.oc1.phx.a" - path := fmt.Sprintf("/vnics/%s", id) - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, `{"id": "%s"}`, id) - }) - - vnic, err := client.Compute.VNICs.Get(&GetVNICParams{ID: id}) - if err != nil { - t.Errorf("Client.Compute.VNICs.Get() returned error: %v", err) - } - - want := &VNIC{ID: id} - if reflect.DeepEqual(vnic, want) { - t.Errorf("Client.Compute.VNICs.Get() returned %+v, want %+v", vnic, want) - } -} diff --git a/builder/oracle/oci/client/waiters.go b/builder/oracle/oci/client/waiters.go deleted file mode 100644 index bb9ca1c19..000000000 --- a/builder/oracle/oci/client/waiters.go +++ /dev/null @@ -1,59 +0,0 @@ -package oci - -import ( - "fmt" - "time" -) - -const ( - defaultWaitDurationMS = 5000 - defaultMaxRetries = 0 -) - -type Waiter struct { - WaitDurationMS int - MaxRetries int -} - -type WaitableService interface { - GetResourceState(id string) (string, error) -} - -func stringSliceContains(slice []string, value string) bool { - for _, elem := range slice { - if elem == value { - return true - } - } - return false -} - -// NewWaiter creates a waiter with default wait duration and unlimited retry -// operations. -func NewWaiter() *Waiter { - return &Waiter{WaitDurationMS: defaultWaitDurationMS, MaxRetries: defaultMaxRetries} -} - -// WaitForResourceToReachState polls a resource that implements WaitableService -// repeatedly until it reaches a known state or fails if it reaches an -// unexpected state. The duration of the interval and number of polls is -// determined by the Waiter configuration. -func (w *Waiter) WaitForResourceToReachState(svc WaitableService, id string, waitStates []string, terminalState string) error { - for i := 0; w.MaxRetries == 0 || i < w.MaxRetries; i++ { - state, err := svc.GetResourceState(id) - if err != nil { - return err - } - - if stringSliceContains(waitStates, state) { - time.Sleep(time.Duration(w.WaitDurationMS) * time.Millisecond) - continue - } else if state == terminalState { - return nil - } - - return fmt.Errorf("Unexpected resource state %s, expecting a waiting state %s or terminal state %s ", state, waitStates, terminalState) - } - - return fmt.Errorf("Maximum number of retries (%d) exceeded; resource did not reach state %s", w.MaxRetries, terminalState) -} diff --git a/builder/oracle/oci/client/waiters_test.go b/builder/oracle/oci/client/waiters_test.go deleted file mode 100644 index ce52b7922..000000000 --- a/builder/oracle/oci/client/waiters_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package oci - -import ( - "errors" - "fmt" - "testing" -) - -const ( - ValidID = "ID" -) - -type testWaitSvc struct { - states []string - idx int - err error -} - -func (tw *testWaitSvc) GetResourceState(id string) (string, error) { - if id != ValidID { - return "", fmt.Errorf("Invalid id %s", id) - } - if tw.err != nil { - return "", tw.err - } - - if tw.idx >= len(tw.states) { - panic("Invalid test state") - } - state := tw.states[tw.idx] - tw.idx++ - return state, nil -} - -func TestReturnsWhenWaitStateIsReachedImmediately(t *testing.T) { - ws := &testWaitSvc{states: []string{"OK"}} - w := NewWaiter() - err := w.WaitForResourceToReachState(ws, ValidID, []string{}, "OK") - if err != nil { - t.Errorf("Failed to reach expected state, got %s", err) - } -} - -func TestReturnsWhenResourceWaitsInValidWaitingState(t *testing.T) { - w := &Waiter{WaitDurationMS: 1, MaxRetries: defaultMaxRetries} - ws := &testWaitSvc{states: []string{"WAITING", "OK"}} - err := w.WaitForResourceToReachState(ws, ValidID, []string{"WAITING"}, "OK") - if err != nil { - t.Errorf("Failed to reach expected state, got %s", err) - } -} - -func TestPropagatesErrorFromGetter(t *testing.T) { - w := NewWaiter() - ws := &testWaitSvc{states: []string{}, err: errors.New("ERROR")} - err := w.WaitForResourceToReachState(ws, ValidID, []string{"WAITING"}, "OK") - if err != ws.err { - t.Errorf("Expected error from getter got %s", err) - } -} - -func TestReportsInvalidTransitionStateAsError(t *testing.T) { - w := NewWaiter() - tw := &testWaitSvc{states: []string{"UNKNOWN_STATE"}, err: errors.New("ERROR")} - err := w.WaitForResourceToReachState(tw, ValidID, []string{"WAITING"}, "OK") - if err == nil { - t.Fatal("Expected error from getter") - } -} - -func TestErrorsWhenMaxWaitTriesExceeded(t *testing.T) { - w := Waiter{WaitDurationMS: 1, MaxRetries: 1} - - ws := &testWaitSvc{states: []string{"WAITING", "OK"}} - - err := w.WaitForResourceToReachState(ws, ValidID, []string{"WAITING"}, "OK") - if err == nil { - t.Fatal("Expecting error but wait terminated") - } -} diff --git a/builder/oracle/oci/config.go b/builder/oracle/oci/config.go index 3af6dcbdf..75fea183b 100644 --- a/builder/oracle/oci/config.go +++ b/builder/oracle/oci/config.go @@ -9,12 +9,12 @@ import ( "os" "path/filepath" - client "github.com/hashicorp/packer/builder/oracle/oci/client" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" + ocicommon "github.com/oracle/oci-go-sdk/common" "github.com/mitchellh/go-homedir" ) @@ -23,7 +23,7 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` - AccessCfg *client.Config + ConfigProvider ocicommon.ConfigurationProvider AccessCfgFile string `mapstructure:"access_cfg_file"` AccessCfgFileAccount string `mapstructure:"access_cfg_file_account"` @@ -67,68 +67,54 @@ func NewConfig(raws ...interface{}) (*Config, error) { } // Determine where the SDK config is located - var accessCfgFile string - if c.AccessCfgFile != "" { - accessCfgFile = c.AccessCfgFile - } else { - accessCfgFile, err = getDefaultOCISettingsPath() + if c.AccessCfgFile == "" { + c.AccessCfgFile, err = getDefaultOCISettingsPath() if err != nil { - accessCfgFile = "" // Access cfg might be in template + log.Println("Default OCI settings file not found") } } - accessCfg := &client.Config{} - - if accessCfgFile != "" { - loadedAccessCfgs, err := client.LoadConfigsFromFile(accessCfgFile) - if err != nil { - return nil, fmt.Errorf("Invalid config file %s: %s", accessCfgFile, err) - } - cfgAccount := "DEFAULT" - if c.AccessCfgFileAccount != "" { - cfgAccount = c.AccessCfgFileAccount - } - - var ok bool - accessCfg, ok = loadedAccessCfgs[cfgAccount] - if !ok { - return nil, fmt.Errorf("No account section '%s' found in config file %s", cfgAccount, accessCfgFile) - } - } - - // Override SDK client config with any non-empty template properties - - if c.UserID != "" { - accessCfg.User = c.UserID - } - - if c.TenancyID != "" { - accessCfg.Tenancy = c.TenancyID - } - - if c.Region != "" { - accessCfg.Region = c.Region - } - - // Default if the template nor the API config contains a region. - if accessCfg.Region == "" { - accessCfg.Region = "us-phoenix-1" - } - - if c.Fingerprint != "" { - accessCfg.Fingerprint = c.Fingerprint - } - - if c.PassPhrase != "" { - accessCfg.PassPhrase = c.PassPhrase + if c.AccessCfgFileAccount == "" { + c.AccessCfgFileAccount = "DEFAULT" } + var keyContent []byte if c.KeyFile != "" { - accessCfg.KeyFile = c.KeyFile - accessCfg.Key, err = client.LoadPrivateKey(accessCfg) + path, err := homedir.Expand(c.KeyFile) if err != nil { - return nil, fmt.Errorf("Failed to load private key %s : %s", accessCfg.KeyFile, err) + return nil, err } + + // Read API signing key + keyContent, err = ioutil.ReadFile(path) + if err != nil { + return nil, err + } + } + + fileProvider, _ := ocicommon.ConfigurationProviderFromFileWithProfile(c.AccessCfgFile, c.AccessCfgFileAccount, c.PassPhrase) + if c.Region == "" { + var region string + if fileProvider != nil { + region, _ = fileProvider.Region() + } + if region == "" { + c.Region = "us-phoenix-1" + } + } + + providers := []ocicommon.ConfigurationProvider{ + NewRawConfigurationProvider(c.TenancyID, c.UserID, c.Region, c.Fingerprint, string(keyContent), &c.PassPhrase), + } + + if fileProvider != nil { + providers = append(providers, fileProvider) + } + + // Load API access configuration from SDK + configProvider, err := ocicommon.ComposingConfigurationProvider(providers) + if err != nil { + return nil, err } var errs *packer.MultiError @@ -136,44 +122,36 @@ func NewConfig(raws ...interface{}) (*Config, error) { errs = packer.MultiErrorAppend(errs, es...) } - // Required AccessCfg configuration options - - if accessCfg.User == "" { + if userOCID, _ := configProvider.UserOCID(); userOCID == "" { errs = packer.MultiErrorAppend( errs, errors.New("'user_ocid' must be specified")) } - if accessCfg.Tenancy == "" { + tenancyOCID, _ := configProvider.TenancyOCID() + if tenancyOCID == "" { errs = packer.MultiErrorAppend( errs, errors.New("'tenancy_ocid' must be specified")) } - if accessCfg.Region == "" { - errs = packer.MultiErrorAppend( - errs, errors.New("'region' must be specified")) - } - - if accessCfg.Fingerprint == "" { + if fingerprint, _ := configProvider.KeyFingerprint(); fingerprint == "" { errs = packer.MultiErrorAppend( errs, errors.New("'fingerprint' must be specified")) } - if accessCfg.Key == nil { + if _, err := configProvider.PrivateRSAKey(); err != nil { errs = packer.MultiErrorAppend( errs, errors.New("'key_file' must be specified")) } - c.AccessCfg = accessCfg - - // Required non AccessCfg configuration options + c.ConfigProvider = configProvider if c.AvailabilityDomain == "" { errs = packer.MultiErrorAppend( errs, errors.New("'availability_domain' must be specified")) } - if c.CompartmentID == "" { - c.CompartmentID = accessCfg.Tenancy + if c.CompartmentID == "" && tenancyOCID != "" { + c.CompartmentID = tenancyOCID } if c.Shape == "" { diff --git a/builder/oracle/oci/config_provider.go b/builder/oracle/oci/config_provider.go new file mode 100644 index 000000000..25d467a4c --- /dev/null +++ b/builder/oracle/oci/config_provider.go @@ -0,0 +1,76 @@ +package oci + +import ( + "crypto/rsa" + "errors" + "fmt" + + "github.com/oracle/oci-go-sdk/common" +) + +// rawConfigurationProvider allows a user to simply construct a configuration +// provider from raw values. It errors on access when those values are empty. +type rawConfigurationProvider struct { + tenancy string + user string + region string + fingerprint string + privateKey string + privateKeyPassphrase *string +} + +// NewRawConfigurationProvider will create a rawConfigurationProvider. +func NewRawConfigurationProvider(tenancy, user, region, fingerprint, privateKey string, privateKeyPassphrase *string) common.ConfigurationProvider { + return rawConfigurationProvider{tenancy, user, region, fingerprint, privateKey, privateKeyPassphrase} +} + +func (p rawConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) { + return common.PrivateKeyFromBytes([]byte(p.privateKey), p.privateKeyPassphrase) +} + +func (p rawConfigurationProvider) KeyID() (keyID string, err error) { + tenancy, err := p.TenancyOCID() + if err != nil { + return + } + + user, err := p.UserOCID() + if err != nil { + return + } + + fingerprint, err := p.KeyFingerprint() + if err != nil { + return + } + + return fmt.Sprintf("%s/%s/%s", tenancy, user, fingerprint), nil +} + +func (p rawConfigurationProvider) TenancyOCID() (string, error) { + if p.tenancy == "" { + return "", errors.New("no tenancy provided") + } + return p.tenancy, nil +} + +func (p rawConfigurationProvider) UserOCID() (string, error) { + if p.user == "" { + return "", errors.New("no user provided") + } + return p.user, nil +} + +func (p rawConfigurationProvider) KeyFingerprint() (string, error) { + if p.fingerprint == "" { + return "", errors.New("no fingerprint provided") + } + return p.fingerprint, nil +} + +func (p rawConfigurationProvider) Region() (string, error) { + if p.region == "" { + return "", errors.New("no region provided") + } + return p.region, nil +} diff --git a/builder/oracle/oci/config_test.go b/builder/oracle/oci/config_test.go index 84002e937..72491d8d0 100644 --- a/builder/oracle/oci/config_test.go +++ b/builder/oracle/oci/config_test.go @@ -1,13 +1,16 @@ package oci import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" "io/ioutil" "os" - "reflect" "strings" "testing" - client "github.com/hashicorp/packer/builder/oracle/oci/client" + "github.com/go-ini/ini" ) func testConfig(accessConfFile *os.File) map[string]interface{} { @@ -29,22 +32,16 @@ func testConfig(accessConfFile *os.File) map[string]interface{} { } } -func getField(c *client.Config, field string) string { - r := reflect.ValueOf(c) - f := reflect.Indirect(r).FieldByName(field) - return string(f.String()) -} - func TestConfig(t *testing.T) { // Shared set-up and defered deletion - cfg, keyFile, err := client.BaseTestConfig() + cfg, keyFile, err := baseTestConfigWithTmpKeyFile() if err != nil { t.Fatal(err) } defer os.Remove(keyFile.Name()) - cfgFile, err := client.WriteTestConfig(cfg) + cfgFile, err := writeTestConfig(cfg) if err != nil { t.Fatal(err) } @@ -55,7 +52,7 @@ func TestConfig(t *testing.T) { tmpHome, err := ioutil.TempDir("", "packer_config_test") if err != nil { - t.Fatalf("err: %+v", err) + t.Fatalf("Unexpected error when creating temporary directory: %+v", err) } defer os.Remove(tmpHome) @@ -64,15 +61,13 @@ func TestConfig(t *testing.T) { defer os.Setenv("HOME", home) // Config tests - t.Run("BaseConfig", func(t *testing.T) { raw := testConfig(cfgFile) _, errs := NewConfig(raw) if errs != nil { - t.Fatalf("err: %+v", errs) + t.Fatalf("Unexpected error in configuration %+v", errs) } - }) t.Run("NoAccessConfig", func(t *testing.T) { @@ -81,14 +76,14 @@ func TestConfig(t *testing.T) { _, errs := NewConfig(raw) - s := errs.Error() expectedErrors := []string{ - "'user_ocid'", "'tenancy_ocid'", "'fingerprint'", - "'key_file'", + "'user_ocid'", "'tenancy_ocid'", "'fingerprint'", "'key_file'", } + + s := errs.Error() for _, expected := range expectedErrors { if !strings.Contains(s, expected) { - t.Errorf("Expected %s to contain '%s'", s, expected) + t.Errorf("Expected %q to contain '%s'", s, expected) } } }) @@ -113,12 +108,17 @@ func TestConfig(t *testing.T) { raw := testConfig(cfgFile) c, errs := NewConfig(raw) if errs != nil { - t.Fatalf("err: %+v", errs) + t.Fatalf("Unexpected error in configuration %+v", errs) } - expected := "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - if c.AccessCfg.Tenancy != expected { - t.Errorf("Expected tenancy: %s, got %s.", expected, c.AccessCfg.Tenancy) + tenancy, err := c.ConfigProvider.TenancyOCID() + if err != nil { + t.Fatalf("Unexpected error getting tenancy ocid: %v", err) + } + + expected := "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + if tenancy != expected { + t.Errorf("Expected tenancy: %s, got %s.", expected, tenancy) } }) @@ -127,12 +127,17 @@ func TestConfig(t *testing.T) { raw := testConfig(cfgFile) c, errs := NewConfig(raw) if errs != nil { - t.Fatalf("err: %+v", errs) + t.Fatalf("Unexpected error in configuration %+v", errs) + } + + region, err := c.ConfigProvider.Region() + if err != nil { + t.Fatalf("Unexpected error getting region: %v", err) } expected := "us-ashburn-1" - if c.AccessCfg.Region != expected { - t.Errorf("Expected region: %s, got %s.", expected, c.AccessCfg.Region) + if region != expected { + t.Errorf("Expected region: %s, got %s.", expected, region) } }) @@ -159,7 +164,7 @@ func TestConfig(t *testing.T) { c, errs := NewConfig(raw) if errs != nil { - t.Errorf("Unexpected error(s): %s", errs) + t.Fatalf("Unexpected error in configuration %+v", errs) } if !strings.Contains(c.ImageName, "packer-") { @@ -167,30 +172,138 @@ func TestConfig(t *testing.T) { } }) - // Test that AccessCfgFile properties are overridden by their - // corresponding template keys. - accessOverrides := map[string]string{ - "user_ocid": "User", - "tenancy_ocid": "Tenancy", - "region": "Region", - "fingerprint": "Fingerprint", - } - for k, v := range accessOverrides { - t.Run("AccessCfg."+v+"Overridden", func(t *testing.T) { - expected := "override" + t.Run("user_ocid_overridden", func(t *testing.T) { + expected := "override" + raw := testConfig(cfgFile) + raw["user_ocid"] = expected - raw := testConfig(cfgFile) - raw[k] = expected + c, errs := NewConfig(raw) + if errs != nil { + t.Fatalf("Unexpected error in configuration %+v", errs) + } - c, errs := NewConfig(raw) - if errs != nil { - t.Fatalf("err: %+v", errs) - } + user, _ := c.ConfigProvider.UserOCID() + if user != expected { + t.Errorf("Expected ConfigProvider.UserOCID: %s, got %s", expected, user) + } + }) - accessVal := getField(c.AccessCfg, v) - if accessVal != expected { - t.Errorf("Expected AccessCfg.%s: %s, got %s", v, expected, accessVal) - } - }) - } + t.Run("tenancy_ocid_overidden", func(t *testing.T) { + expected := "override" + raw := testConfig(cfgFile) + raw["tenancy_ocid"] = expected + + c, errs := NewConfig(raw) + if errs != nil { + t.Fatalf("Unexpected error in configuration %+v", errs) + } + + tenancy, _ := c.ConfigProvider.TenancyOCID() + if tenancy != expected { + t.Errorf("Expected ConfigProvider.TenancyOCID: %s, got %s", expected, tenancy) + } + }) + + t.Run("region_overidden", func(t *testing.T) { + expected := "override" + raw := testConfig(cfgFile) + raw["region"] = expected + + c, errs := NewConfig(raw) + if errs != nil { + t.Fatalf("Unexpected error in configuration %+v", errs) + } + + region, _ := c.ConfigProvider.Region() + if region != expected { + t.Errorf("Expected ConfigProvider.Region: %s, got %s", expected, region) + } + }) + + t.Run("fingerprint_overidden", func(t *testing.T) { + expected := "override" + raw := testConfig(cfgFile) + raw["fingerprint"] = expected + + c, errs := NewConfig(raw) + if errs != nil { + t.Fatalf("Unexpected error in configuration: %+v", errs) + } + + fingerprint, _ := c.ConfigProvider.KeyFingerprint() + if fingerprint != expected { + t.Errorf("Expected ConfigProvider.KeyFingerprint: %s, got %s", expected, fingerprint) + } + }) +} + +// BaseTestConfig creates the base (DEFAULT) config including a temporary key +// file. +// NOTE: Caller is responsible for removing temporary key file. +func baseTestConfigWithTmpKeyFile() (*ini.File, *os.File, error) { + keyFile, err := generateRSAKeyFile() + if err != nil { + return nil, keyFile, err + } + // Build ini + cfg := ini.Empty() + section, _ := cfg.NewSection("DEFAULT") + section.NewKey("region", "us-ashburn-1") + section.NewKey("tenancy", "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + section.NewKey("user", "ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + section.NewKey("fingerprint", "70:04:5z:b3:19:ab:90:75:a4:1f:50:d4:c7:c3:33:20") + section.NewKey("key_file", keyFile.Name()) + + return cfg, keyFile, nil +} + +// WriteTestConfig writes a ini.File to a temporary file for use in unit tests. +// NOTE: Caller is responsible for removing temporary file. +func writeTestConfig(cfg *ini.File) (*os.File, error) { + confFile, err := ioutil.TempFile("", "config_file") + if err != nil { + return nil, err + } + + if _, err := confFile.Write([]byte("[DEFAULT]\n")); err != nil { + os.Remove(confFile.Name()) + return nil, err + } + + if _, err := cfg.WriteTo(confFile); err != nil { + os.Remove(confFile.Name()) + return nil, err + } + return confFile, nil +} + +// generateRSAKeyFile generates an RSA key file for use in unit tests. +// NOTE: The caller is responsible for deleting the temporary file. +func generateRSAKeyFile() (*os.File, error) { + // Create temporary file for the key + f, err := ioutil.TempFile("", "key") + if err != nil { + return nil, err + } + + // Generate key + priv, err := rsa.GenerateKey(rand.Reader, 2014) + if err != nil { + return nil, err + } + + // ASN.1 DER encoded form + privDer := x509.MarshalPKCS1PrivateKey(priv) + privBlk := pem.Block{ + Type: "RSA PRIVATE KEY", + Headers: nil, + Bytes: privDer, + } + + // Write the key out + if _, err := f.Write(pem.EncodeToMemory(&privBlk)); err != nil { + return nil, err + } + + return f, nil } diff --git a/builder/oracle/oci/driver.go b/builder/oracle/oci/driver.go index 51f6c364a..704b2f2a9 100644 --- a/builder/oracle/oci/driver.go +++ b/builder/oracle/oci/driver.go @@ -1,13 +1,11 @@ package oci -import ( - client "github.com/hashicorp/packer/builder/oracle/oci/client" -) +import "github.com/oracle/oci-go-sdk/core" // Driver interfaces between the builder steps and the OCI SDK. type Driver interface { CreateInstance(publicKey string) (string, error) - CreateImage(id string) (client.Image, error) + CreateImage(id string) (core.Image, error) DeleteImage(id string) error GetInstanceIP(id string) (string, error) TerminateInstance(id string) error diff --git a/builder/oracle/oci/driver_mock.go b/builder/oracle/oci/driver_mock.go index f8bd9f920..1f2e7ec2b 100644 --- a/builder/oracle/oci/driver_mock.go +++ b/builder/oracle/oci/driver_mock.go @@ -1,8 +1,6 @@ package oci -import ( - client "github.com/hashicorp/packer/builder/oracle/oci/client" -) +import "github.com/oracle/oci-go-sdk/core" // driverMock implements the Driver interface and communicates with Oracle // OCI. @@ -40,12 +38,12 @@ func (d *driverMock) CreateInstance(publicKey string) (string, error) { } // CreateImage creates a new custom image. -func (d *driverMock) CreateImage(id string) (client.Image, error) { +func (d *driverMock) CreateImage(id string) (core.Image, error) { if d.CreateImageErr != nil { - return client.Image{}, d.CreateImageErr + return core.Image{}, d.CreateImageErr } d.CreateImageID = id - return client.Image{ID: id}, nil + return core.Image{Id: &id}, nil } // DeleteImage mocks deleting a custom image. diff --git a/builder/oracle/oci/driver_oci.go b/builder/oracle/oci/driver_oci.go index 1b6b0a3f9..90d05ea0a 100644 --- a/builder/oracle/oci/driver_oci.go +++ b/builder/oracle/oci/driver_oci.go @@ -1,123 +1,191 @@ package oci import ( + "context" "errors" "fmt" + "time" - client "github.com/hashicorp/packer/builder/oracle/oci/client" + core "github.com/oracle/oci-go-sdk/core" ) // driverOCI implements the Driver interface and communicates with Oracle // OCI. type driverOCI struct { - client *client.Client - cfg *Config + computeClient core.ComputeClient + vcnClient core.VirtualNetworkClient + cfg *Config } -// NewDriverOCI Creates a new driverOCI with a connected client. +// NewDriverOCI Creates a new driverOCI with a connected compute client and a connected vcn client. func NewDriverOCI(cfg *Config) (Driver, error) { - client, err := client.NewClient(cfg.AccessCfg) + coreClient, err := core.NewComputeClientWithConfigurationProvider(cfg.ConfigProvider) if err != nil { return nil, err } - return &driverOCI{client: client, cfg: cfg}, nil + + vcnClient, err := core.NewVirtualNetworkClientWithConfigurationProvider(cfg.ConfigProvider) + if err != nil { + return nil, err + } + + return &driverOCI{ + computeClient: coreClient, + vcnClient: vcnClient, + cfg: cfg, + }, nil } // CreateInstance creates a new compute instance. func (d *driverOCI) CreateInstance(publicKey string) (string, error) { - params := &client.LaunchInstanceParams{ - AvailabilityDomain: d.cfg.AvailabilityDomain, - CompartmentID: d.cfg.CompartmentID, - ImageID: d.cfg.BaseImageID, - Shape: d.cfg.Shape, - SubnetID: d.cfg.SubnetID, - Metadata: map[string]string{ - "ssh_authorized_keys": publicKey, - }, + metadata := map[string]string{ + "ssh_authorized_keys": publicKey, } if d.cfg.UserData != "" { - params.Metadata["user_data"] = d.cfg.UserData + metadata["user_data"] = d.cfg.UserData } - instance, err := d.client.Compute.Instances.Launch(params) + + instance, err := d.computeClient.LaunchInstance(context.TODO(), core.LaunchInstanceRequest{LaunchInstanceDetails: core.LaunchInstanceDetails{ + AvailabilityDomain: &d.cfg.AvailabilityDomain, + CompartmentId: &d.cfg.CompartmentID, + ImageId: &d.cfg.BaseImageID, + Shape: &d.cfg.Shape, + SubnetId: &d.cfg.SubnetID, + Metadata: metadata, + }}) + if err != nil { return "", err } - return instance.ID, nil + return *instance.Id, nil } // CreateImage creates a new custom image. -func (d *driverOCI) CreateImage(id string) (client.Image, error) { - params := &client.CreateImageParams{ - CompartmentID: d.cfg.CompartmentID, - InstanceID: id, - DisplayName: d.cfg.ImageName, - } - image, err := d.client.Compute.Images.Create(params) +func (d *driverOCI) CreateImage(id string) (core.Image, error) { + res, err := d.computeClient.CreateImage(context.TODO(), core.CreateImageRequest{CreateImageDetails: core.CreateImageDetails{ + CompartmentId: &d.cfg.CompartmentID, + InstanceId: &id, + DisplayName: &d.cfg.ImageName, + }}) + if err != nil { - return client.Image{}, err + return core.Image{}, err } - return image, nil + return res.Image, nil } // DeleteImage deletes a custom image. func (d *driverOCI) DeleteImage(id string) error { - return d.client.Compute.Images.Delete(&client.DeleteImageParams{ID: id}) + _, err := d.computeClient.DeleteImage(context.TODO(), core.DeleteImageRequest{ImageId: &id}) + return err } // GetInstanceIP returns the public or private IP corresponding to the given instance id. func (d *driverOCI) GetInstanceIP(id string) (string, error) { - // get nvic and cross ref to find pub ip address - vnics, err := d.client.Compute.VNICAttachments.List( - &client.ListVnicAttachmentsParams{ - InstanceID: id, - CompartmentID: d.cfg.CompartmentID, - }, - ) + vnics, err := d.computeClient.ListVnicAttachments(context.TODO(), core.ListVnicAttachmentsRequest{ + InstanceId: &id, + CompartmentId: &d.cfg.CompartmentID, + }) if err != nil { return "", err } - if len(vnics) < 1 { + if len(vnics.Items) == 0 { return "", errors.New("instance has zero VNICs") } - vnic, err := d.client.Compute.VNICs.Get(&client.GetVNICParams{ID: vnics[0].VNICID}) + vnic, err := d.vcnClient.GetVnic(context.TODO(), core.GetVnicRequest{VnicId: vnics.Items[0].VnicId}) if err != nil { return "", fmt.Errorf("Error getting VNIC details: %s", err) } if d.cfg.UsePrivateIP { - return vnic.PrivateIP, nil + return *vnic.PrivateIp, nil } - return vnic.PublicIP, nil + + if vnic.PublicIp == nil { + return "", fmt.Errorf("Error getting VNIC Public Ip for: %s", id) + } + + return *vnic.PublicIp, nil } // TerminateInstance terminates a compute instance. func (d *driverOCI) TerminateInstance(id string) error { - params := &client.TerminateInstanceParams{ID: id} - return d.client.Compute.Instances.Terminate(params) + _, err := d.computeClient.TerminateInstance(context.TODO(), core.TerminateInstanceRequest{ + InstanceId: &id, + }) + return err } // WaitForImageCreation waits for a provisioning custom image to reach the // "AVAILABLE" state. func (d *driverOCI) WaitForImageCreation(id string) error { - return client.NewWaiter().WaitForResourceToReachState( - d.client.Compute.Images, + return waitForResourceToReachState( + func(string) (string, error) { + image, err := d.computeClient.GetImage(context.TODO(), core.GetImageRequest{ImageId: &id}) + if err != nil { + return "", err + } + return string(image.LifecycleState), nil + }, id, []string{"PROVISIONING"}, "AVAILABLE", + 0, //Unlimited Retries + 5*time.Second, //5 second wait between retries ) } // WaitForInstanceState waits for an instance to reach the a given terminal // state. func (d *driverOCI) WaitForInstanceState(id string, waitStates []string, terminalState string) error { - return client.NewWaiter().WaitForResourceToReachState( - d.client.Compute.Instances, + return waitForResourceToReachState( + func(string) (string, error) { + instance, err := d.computeClient.GetInstance(context.TODO(), core.GetInstanceRequest{InstanceId: &id}) + if err != nil { + return "", err + } + return string(instance.LifecycleState), nil + }, id, waitStates, terminalState, + 0, //Unlimited Retries + 5*time.Second, //5 second wait between retries ) } + +// WaitForResourceToReachState checks the response of a request through a +// polled get and waits until the desired state or until the max retried has +// been reached. +func waitForResourceToReachState(getResourceState func(string) (string, error), id string, waitStates []string, terminalState string, maxRetries int, waitDuration time.Duration) error { + for i := 0; maxRetries == 0 || i < maxRetries; i++ { + state, err := getResourceState(id) + if err != nil { + return err + } + + if stringSliceContains(waitStates, state) { + time.Sleep(waitDuration) + continue + } else if state == terminalState { + return nil + } + return fmt.Errorf("Unexpected resource state %q, expecting a waiting state %s or terminal state %q ", state, waitStates, terminalState) + } + return fmt.Errorf("Maximum number of retries (%d) exceeded; resource did not reach state %q", maxRetries, terminalState) +} + +// stringSliceContains loops through a slice of strings returning a boolean +// based on whether a given value is contained in the slice. +func stringSliceContains(slice []string, value string) bool { + for _, elem := range slice { + if elem == value { + return true + } + } + return false +} diff --git a/builder/oracle/oci/step_image.go b/builder/oracle/oci/step_image.go index ff767f709..9589594c8 100644 --- a/builder/oracle/oci/step_image.go +++ b/builder/oracle/oci/step_image.go @@ -27,7 +27,7 @@ func (s *stepImage) Run(_ context.Context, state multistep.StateBag) multistep.S return multistep.ActionHalt } - err = driver.WaitForImageCreation(image.ID) + err = driver.WaitForImageCreation(*image.Id) if err != nil { err = fmt.Errorf("Error waiting for image creation to finish: %s", err) ui.Error(err.Error()) diff --git a/builder/oracle/oci/step_test.go b/builder/oracle/oci/step_test.go index cca58666c..55afba523 100644 --- a/builder/oracle/oci/step_test.go +++ b/builder/oracle/oci/step_test.go @@ -6,33 +6,32 @@ import ( "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" - - client "github.com/hashicorp/packer/builder/oracle/oci/client" ) // TODO(apryde): It would be good not to have to write a key file to disk to // load the config. func baseTestConfig() *Config { - _, keyFile, err := client.BaseTestConfig() + _, keyFile, err := baseTestConfigWithTmpKeyFile() if err != nil { panic(err) } cfg, err := NewConfig(map[string]interface{}{ - "availability_domain": "aaaa:PHX-AD-3", + "availability_domain": "aaaa:US-ASHBURN-AD-1", // Image - "base_image_ocid": "ocd1...", + "base_image_ocid": "ocid1.image.oc1.iad.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "shape": "VM.Standard1.1", "image_name": "HelloWorld", + "region": "us-ashburn-1", // Networking - "subnet_ocid": "ocd1...", + "subnet_ocid": "ocid1.subnet.oc1.iad.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // AccessConfig - "user_ocid": "ocid1...", - "tenancy_ocid": "ocid1...", - "fingerprint": "00:00...", + "user_ocid": "ocid1.user.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "tenancy_ocid": "ocid1.tenancy.oc1..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "fingerprint": "70:04:5z:b3:19:ab:90:75:a4:1f:50:d4:c7:c3:33:20", "key_file": keyFile.Name(), // Comm From 2f585112521c90e19f6a87b5f115d271ec2807e9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 17 Apr 2018 11:44:43 -0700 Subject: [PATCH 0922/1007] update middleman --- website/Gemfile | 2 +- website/Makefile | 2 +- website/packer.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/Gemfile b/website/Gemfile index 177bf1774..f8a10cb94 100644 --- a/website/Gemfile +++ b/website/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "middleman-hashicorp", "0.3.34" +gem "middleman-hashicorp", "0.3.37" diff --git a/website/Makefile b/website/Makefile index 0991a7753..7f14cadf9 100644 --- a/website/Makefile +++ b/website/Makefile @@ -1,4 +1,4 @@ -VERSION?="0.3.34" +VERSION?="0.3.37" build: @echo "==> Starting build in Docker..." diff --git a/website/packer.json b/website/packer.json index 21e2316e9..e1e5f77c8 100644 --- a/website/packer.json +++ b/website/packer.json @@ -9,7 +9,7 @@ "builders": [ { "type": "docker", - "image": "hashicorp/middleman-hashicorp:0.3.34", + "image": "hashicorp/middleman-hashicorp:0.3.37", "discard": "true", "volumes": { "{{ pwd }}": "/website" From 12f80208bbf75db2712dbe5b6c23aab44816fbcf Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 17 Apr 2018 15:48:27 -0700 Subject: [PATCH 0923/1007] fix vendor dep casing --- .../github.com/Sirupsen/logrus/appveyor.yml | 14 ++++++++++++++ .../logrus/terminal_check_notappengine.go | 19 +++++++++++++++++++ .../logrus/terminal_check_appengine.go | 11 ----------- vendor/vendor.json | 12 ++++++------ 4 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 vendor/github.com/Sirupsen/logrus/appveyor.yml create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go diff --git a/vendor/github.com/Sirupsen/logrus/appveyor.yml b/vendor/github.com/Sirupsen/logrus/appveyor.yml new file mode 100644 index 000000000..96c2ce15f --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/appveyor.yml @@ -0,0 +1,14 @@ +version: "{build}" +platform: x64 +clone_folder: c:\gopath\src\github.com\sirupsen\logrus +environment: + GOPATH: c:\gopath +branches: + only: + - master +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version +build_script: + - go get -t + - go test diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go new file mode 100644 index 000000000..067047a12 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go @@ -0,0 +1,19 @@ +// +build !appengine,!gopherjs + +package logrus + +import ( + "io" + "os" + + "golang.org/x/crypto/ssh/terminal" +) + +func checkIfTerminal(w io.Writer) bool { + switch v := w.(type) { + case *os.File: + return terminal.IsTerminal(int(v.Fd())) + default: + return false + } +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go deleted file mode 100644 index 3de08e802..000000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build appengine gopherjs - -package logrus - -import ( - "io" -) - -func checkIfTerminal(w io.Writer) bool { - return true -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 8a672aeb7..d45961ec8 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -233,6 +233,12 @@ "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", "revisionTime": "2018-01-10T05:50:12Z" }, + { + "checksumSHA1": "2PBDgrQHH6ZDxBWs6Z4imBzdEjk=", + "path": "github.com/Sirupsen/logrus", + "revision": "90150a8ed11b6ce285e77e8af2b0109559ce4777", + "revisionTime": "2018-03-15T01:07:03Z" + }, { "checksumSHA1": "HttiPj314X1a0i2Jen1p6lRH/vE=", "path": "github.com/aliyun/aliyun-oss-go-sdk/oss", @@ -1195,12 +1201,6 @@ "revision": "51d0290d9434dc6139dd89001236cfd989521a79", "revisionTime": "2018-03-05T22:44:21Z" }, - { - "checksumSHA1": "ByFN6xh/YGP/D3DM9c8p0D9D1XM=", - "path": "github.com/sirupsen/logrus", - "revision": "90150a8ed11b6ce285e77e8af2b0109559ce4777", - "revisionTime": "2018-03-15T01:07:03Z" - }, { "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", "comment": "v1.1.4-4-g976c720", From 678f0647ccb333f35914979b4c4bbbb056893306 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 17 Apr 2018 15:51:03 -0700 Subject: [PATCH 0924/1007] remove lowercase sirupsen --- .../github.com/sirupsen/logrus/appveyor.yml | 14 -------------- .../logrus/terminal_check_notappengine.go | 19 ------------------- 2 files changed, 33 deletions(-) delete mode 100644 vendor/github.com/sirupsen/logrus/appveyor.yml delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go diff --git a/vendor/github.com/sirupsen/logrus/appveyor.yml b/vendor/github.com/sirupsen/logrus/appveyor.yml deleted file mode 100644 index 96c2ce15f..000000000 --- a/vendor/github.com/sirupsen/logrus/appveyor.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: "{build}" -platform: x64 -clone_folder: c:\gopath\src\github.com\sirupsen\logrus -environment: - GOPATH: c:\gopath -branches: - only: - - master -install: - - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% - - go version -build_script: - - go get -t - - go test diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go deleted file mode 100644 index 067047a12..000000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build !appengine,!gopherjs - -package logrus - -import ( - "io" - "os" - - "golang.org/x/crypto/ssh/terminal" -) - -func checkIfTerminal(w io.Writer) bool { - switch v := w.(type) { - case *os.File: - return terminal.IsTerminal(int(v.Fd())) - default: - return false - } -} From 71abcdaab0dc5c7548ed5b0f7648c5126fb23cfe Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 17 Apr 2018 15:59:41 -0700 Subject: [PATCH 0925/1007] lowercase sirupsen is the right version. sirupsen/logrus#543 --- .../{Sirupsen => sirupsen}/logrus/CHANGELOG.md | 0 .../github.com/{Sirupsen => sirupsen}/logrus/LICENSE | 0 .../{Sirupsen => sirupsen}/logrus/README.md | 0 .../{Sirupsen => sirupsen}/logrus/alt_exit.go | 0 .../{Sirupsen => sirupsen}/logrus/appveyor.yml | 0 .../github.com/{Sirupsen => sirupsen}/logrus/doc.go | 0 .../{Sirupsen => sirupsen}/logrus/entry.go | 0 .../{Sirupsen => sirupsen}/logrus/exported.go | 0 .../{Sirupsen => sirupsen}/logrus/formatter.go | 0 .../{Sirupsen => sirupsen}/logrus/hooks.go | 0 .../{Sirupsen => sirupsen}/logrus/json_formatter.go | 0 .../{Sirupsen => sirupsen}/logrus/logger.go | 0 .../{Sirupsen => sirupsen}/logrus/logrus.go | 0 .../{Sirupsen => sirupsen}/logrus/terminal_bsd.go | 0 .../logrus/terminal_check_notappengine.go | 0 .../{Sirupsen => sirupsen}/logrus/terminal_linux.go | 0 .../{Sirupsen => sirupsen}/logrus/text_formatter.go | 0 .../{Sirupsen => sirupsen}/logrus/writer.go | 0 vendor/vendor.json | 12 ++++++------ 19 files changed, 6 insertions(+), 6 deletions(-) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/CHANGELOG.md (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/LICENSE (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/README.md (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/alt_exit.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/appveyor.yml (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/doc.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/entry.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/exported.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/formatter.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/hooks.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/json_formatter.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/logger.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/logrus.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/terminal_bsd.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/terminal_check_notappengine.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/terminal_linux.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/text_formatter.go (100%) rename vendor/github.com/{Sirupsen => sirupsen}/logrus/writer.go (100%) diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md similarity index 100% rename from vendor/github.com/Sirupsen/logrus/CHANGELOG.md rename to vendor/github.com/sirupsen/logrus/CHANGELOG.md diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE similarity index 100% rename from vendor/github.com/Sirupsen/logrus/LICENSE rename to vendor/github.com/sirupsen/logrus/LICENSE diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md similarity index 100% rename from vendor/github.com/Sirupsen/logrus/README.md rename to vendor/github.com/sirupsen/logrus/README.md diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/alt_exit.go rename to vendor/github.com/sirupsen/logrus/alt_exit.go diff --git a/vendor/github.com/Sirupsen/logrus/appveyor.yml b/vendor/github.com/sirupsen/logrus/appveyor.yml similarity index 100% rename from vendor/github.com/Sirupsen/logrus/appveyor.yml rename to vendor/github.com/sirupsen/logrus/appveyor.yml diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/doc.go rename to vendor/github.com/sirupsen/logrus/doc.go diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/entry.go rename to vendor/github.com/sirupsen/logrus/entry.go diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/exported.go rename to vendor/github.com/sirupsen/logrus/exported.go diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/formatter.go rename to vendor/github.com/sirupsen/logrus/formatter.go diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/hooks.go rename to vendor/github.com/sirupsen/logrus/hooks.go diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/json_formatter.go rename to vendor/github.com/sirupsen/logrus/json_formatter.go diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/logger.go rename to vendor/github.com/sirupsen/logrus/logger.go diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/logrus.go rename to vendor/github.com/sirupsen/logrus/logrus.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_bsd.go rename to vendor/github.com/sirupsen/logrus/terminal_bsd.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go rename to vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_linux.go rename to vendor/github.com/sirupsen/logrus/terminal_linux.go diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/text_formatter.go rename to vendor/github.com/sirupsen/logrus/text_formatter.go diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/writer.go rename to vendor/github.com/sirupsen/logrus/writer.go diff --git a/vendor/vendor.json b/vendor/vendor.json index d45961ec8..1864e235c 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -233,12 +233,6 @@ "revision": "c2e73f942591b0f033a3c6df00f44badb2347c38", "revisionTime": "2018-01-10T05:50:12Z" }, - { - "checksumSHA1": "2PBDgrQHH6ZDxBWs6Z4imBzdEjk=", - "path": "github.com/Sirupsen/logrus", - "revision": "90150a8ed11b6ce285e77e8af2b0109559ce4777", - "revisionTime": "2018-03-15T01:07:03Z" - }, { "checksumSHA1": "HttiPj314X1a0i2Jen1p6lRH/vE=", "path": "github.com/aliyun/aliyun-oss-go-sdk/oss", @@ -1201,6 +1195,12 @@ "revision": "51d0290d9434dc6139dd89001236cfd989521a79", "revisionTime": "2018-03-05T22:44:21Z" }, + { + "checksumSHA1": "hU3ibLi5mZBayj0HPIVpcMSvRgU=", + "path": "github.com/sirupsen/logrus", + "revision": "90150a8ed11b6ce285e77e8af2b0109559ce4777", + "revisionTime": "2018-03-15T01:07:03Z" + }, { "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", "comment": "v1.1.4-4-g976c720", From 30429deb8c48624202a281c07fbca773cba4f12b Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Tue, 17 Apr 2018 19:27:57 -0400 Subject: [PATCH 0926/1007] remove turbolinks & other analytics tests --- .../source/assets/javascripts/application.js | 1 - website/source/layouts/layout.erb | 31 ++++++------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/website/source/assets/javascripts/application.js b/website/source/assets/javascripts/application.js index ae70e571d..5d6f89378 100644 --- a/website/source/assets/javascripts/application.js +++ b/website/source/assets/javascripts/application.js @@ -1,5 +1,4 @@ //= require jquery -//= require turbolinks //= require hashicorp/mega-nav //= require hashicorp/sidebar diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index 1eeb97e08..4db676070 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -29,24 +29,11 @@ <%= stylesheet_link_tag "application" %> - <!--[if lt IE 9]> - <%= javascript_include_tag "ie-compat" %> - <![endif]--> - <%= javascript_include_tag "application" %> - <!-- Typekit script to import Klavika font --> <script src="https://use.typekit.net/wxf7mfi.js"></script> <script>try{Typekit.load({ async: true });}catch(e){}</script> <%= yield_content :head %> - - <script> - // analytics.js - !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; - analytics.load("<%= segmentId %>"); - analytics.page(); - }}(); - </script> </head> <body id="<%= body_id_for(current_page) %>" class="<%= body_classes_for(current_page) %>"> @@ -119,20 +106,22 @@ </div> </div> + <!--[if lt IE 9]> + <%= javascript_include_tag "ie-compat" %> + <![endif]--> + <%= javascript_include_tag "application" %> + <script> + // analytics.js + !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; + analytics.load("<%= segmentId %>"); + analytics.page(); + }}(); // optinmonster var om597a24292a958,om597a24292a958_poll=function(){var b=0;return function(d,c){clearInterval(b);b=setInterval(d,c)}}(); !function(b,d,c){if(b.getElementById(c))om597a24292a958_poll(function(){if(window.om_loaded&&!om597a24292a958)return om597a24292a958=new OptinMonsterApp,om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0})},25);else{var e=!1,a=b.createElement(d);a.id=c;a.src="//a.optnmstr.com/app/js/api.min.js";a.async=!0;a.onload=a.onreadystatechange=function(){if(!(e||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState))try{e=om_loaded=!0,om597a24292a958=new OptinMonsterApp, om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0}),a.onload=a.onreadystatechange=null}catch(f){}};(document.getElementsByTagName("head")[0]||document.documentElement).appendChild(a)}}(document,"script","omapi-script"); </script> - <!-- temporary test --> - <script async src="https://www.googletagmanager.com/gtag/js?id=UA-43075859-2"></script> - <script> - window.dataLayer = window.dataLayer || []; - function gtag(){dataLayer.push(arguments);} - gtag('js', new Date()); - gtag('config', 'UA-43075859-2'); - </script> <script type="application/ld+json"> { "@context": "http://schema.org", From b41e5fa63b83a01454b1908703efa3b39f4472f2 Mon Sep 17 00:00:00 2001 From: Albert Lie <alberttri23@gmail.com> Date: Wed, 18 Apr 2018 22:41:56 +0700 Subject: [PATCH 0927/1007] update aliyungo common package --- .../denverdino/aliyungo/common/client.go | 44 +++++---- .../denverdino/aliyungo/common/endpoint.go | 97 ++++++++++++++++--- .../denverdino/aliyungo/common/endpoints.xml | 10 ++ .../denverdino/aliyungo/common/regions.go | 13 ++- .../denverdino/aliyungo/common/types.go | 18 ++++ vendor/vendor.json | 6 +- 6 files changed, 154 insertions(+), 34 deletions(-) mode change 100755 => 100644 vendor/github.com/denverdino/aliyungo/common/client.go diff --git a/vendor/github.com/denverdino/aliyungo/common/client.go b/vendor/github.com/denverdino/aliyungo/common/client.go old mode 100755 new mode 100644 index 10dcd9000..436b239b2 --- a/vendor/github.com/denverdino/aliyungo/common/client.go +++ b/vendor/github.com/denverdino/aliyungo/common/client.go @@ -9,10 +9,10 @@ import ( "log" "net/http" "net/url" - "strings" - "time" "os" "strconv" + "strings" + "time" "github.com/denverdino/aliyungo/util" ) @@ -43,7 +43,11 @@ type Client struct { // Initialize properties of a client instance func (client *Client) Init(endpoint, version, accessKeyId, accessKeySecret string) { client.AccessKeyId = accessKeyId - client.AccessKeySecret = accessKeySecret + "&" + ak := accessKeySecret + if !strings.HasSuffix(ak, "&") { + ak += "&" + } + client.AccessKeySecret = ak client.debug = false handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout")) if err != nil { @@ -53,8 +57,8 @@ func (client *Client) Init(endpoint, version, accessKeyId, accessKeySecret strin client.httpClient = &http.Client{} } else { t := &http.Transport{ - TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second,} - client.httpClient = &http.Client{Transport: t,} + TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second} + client.httpClient = &http.Client{Transport: t} } client.endpoint = endpoint client.version = version @@ -65,7 +69,7 @@ func (client *Client) NewInit(endpoint, version, accessKeyId, accessKeySecret, s client.Init(endpoint, version, accessKeyId, accessKeySecret) client.serviceCode = serviceCode client.regionID = regionID - client.setEndpointByLocation(regionID, serviceCode, accessKeyId, accessKeySecret) + client.setEndpointByLocation(regionID, serviceCode, accessKeyId, accessKeySecret, client.securityToken) } // Intialize client object when all properties are ready @@ -79,16 +83,21 @@ func (client *Client) InitClient() *Client { client.httpClient = &http.Client{} } else { t := &http.Transport{ - TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second,} - client.httpClient = &http.Client{Transport: t,} + TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second} + client.httpClient = &http.Client{Transport: t} } - client.setEndpointByLocation(client.regionID, client.serviceCode, client.AccessKeyId, client.AccessKeySecret) + client.setEndpointByLocation(client.regionID, client.serviceCode, client.AccessKeyId, client.AccessKeySecret, client.securityToken) return client } +func (client *Client) NewInitForAssumeRole(endpoint, version, accessKeyId, accessKeySecret, serviceCode string, regionID Region, securityToken string) { + client.NewInit(endpoint, version, accessKeyId, accessKeySecret, serviceCode, regionID) + client.securityToken = securityToken +} + //NewClient using location service -func (client *Client) setEndpointByLocation(region Region, serviceCode, accessKeyId, accessKeySecret string) { - locationClient := NewLocationClient(accessKeyId, accessKeySecret) +func (client *Client) setEndpointByLocation(region Region, serviceCode, accessKeyId, accessKeySecret, securityToken string) { + locationClient := NewLocationClient(accessKeyId, accessKeySecret, securityToken) ep := locationClient.DescribeOpenAPIEndpoint(region, serviceCode) if ep == "" { ep = loadEndpointFromFile(region, serviceCode) @@ -218,11 +227,6 @@ func (client *Client) SetAccessKeySecret(secret string) { client.AccessKeySecret = secret + "&" } -// SetAccessKeySecret sets securityToken -func (client *Client) SetSecurityToken(securityToken string) { - client.securityToken = securityToken -} - // SetDebug sets debug mode to log the request/response message func (client *Client) SetDebug(debug bool) { client.debug = debug @@ -242,6 +246,11 @@ func (client *Client) SetUserAgent(userAgent string) { client.userAgent = userAgent } +//set SecurityToken +func (client *Client) SetSecurityToken(securityToken string) { + client.securityToken = securityToken +} + // Invoke sends the raw HTTP request for ECS services func (client *Client) Invoke(action string, args interface{}, response interface{}) error { if err := client.ensureProperties(); err != nil { @@ -268,6 +277,7 @@ func (client *Client) Invoke(action string, args interface{}, response interface // TODO move to util and add build val flag httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo) + httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent) t0 := time.Now() @@ -341,6 +351,7 @@ func (client *Client) InvokeByFlattenMethod(action string, args interface{}, res // TODO move to util and add build val flag httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo) + httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent) t0 := time.Now() @@ -397,7 +408,6 @@ func (client *Client) InvokeByAnyMethod(method, action, path string, args interf request := Request{} request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID) - data := util.ConvertToQueryValues(request) util.SetQueryValues(args, &data) diff --git a/vendor/github.com/denverdino/aliyungo/common/endpoint.go b/vendor/github.com/denverdino/aliyungo/common/endpoint.go index 16bcbf9d6..786606cf3 100644 --- a/vendor/github.com/denverdino/aliyungo/common/endpoint.go +++ b/vendor/github.com/denverdino/aliyungo/common/endpoint.go @@ -18,6 +18,51 @@ const ( var ( endpoints = make(map[Region]map[string]string) + + SpecailEnpoints = map[Region]map[string]string{ + APNorthEast1: { + "ecs": "https://ecs.ap-northeast-1.aliyuncs.com", + "slb": "https://slb.ap-northeast-1.aliyuncs.com", + "rds": "https://rds.ap-northeast-1.aliyuncs.com", + "vpc": "https://vpc.ap-northeast-1.aliyuncs.com", + }, + APSouthEast2: { + "ecs": "https://ecs.ap-southeast-2.aliyuncs.com", + "slb": "https://slb.ap-southeast-2.aliyuncs.com", + "rds": "https://rds.ap-southeast-2.aliyuncs.com", + "vpc": "https://vpc.ap-southeast-2.aliyuncs.com", + }, + APSouthEast3: { + "ecs": "https://ecs.ap-southeast-3.aliyuncs.com", + "slb": "https://slb.ap-southeast-3.aliyuncs.com", + "rds": "https://rds.ap-southeast-3.aliyuncs.com", + "vpc": "https://vpc.ap-southeast-3.aliyuncs.com", + }, + MEEast1: { + "ecs": "https://ecs.me-east-1.aliyuncs.com", + "slb": "https://slb.me-east-1.aliyuncs.com", + "rds": "https://rds.me-east-1.aliyuncs.com", + "vpc": "https://vpc.me-east-1.aliyuncs.com", + }, + EUCentral1: { + "ecs": "https://ecs.eu-central-1.aliyuncs.com", + "slb": "https://slb.eu-central-1.aliyuncs.com", + "rds": "https://rds.eu-central-1.aliyuncs.com", + "vpc": "https://vpc.eu-central-1.aliyuncs.com", + }, + Zhangjiakou: { + "ecs": "https://ecs.cn-zhangjiakou.aliyuncs.com", + "slb": "https://slb.cn-zhangjiakou.aliyuncs.com", + "rds": "https://rds.cn-zhangjiakou.aliyuncs.com", + "vpc": "https://vpc.cn-zhangjiakou.aliyuncs.com", + }, + Huhehaote: { + "ecs": "https://ecs.cn-huhehaote.aliyuncs.com", + "slb": "https://slb.cn-huhehaote.aliyuncs.com", + "rds": "https://rds.cn-huhehaote.aliyuncs.com", + "vpc": "https://vpc.cn-huhehaote.aliyuncs.com", + }, + } ) //init endpoints from file @@ -25,18 +70,39 @@ func init() { } -func NewLocationClient(accessKeyId, accessKeySecret string) *Client { +type LocationClient struct { + Client +} + +func NewLocationClient(accessKeyId, accessKeySecret, securityToken string) *LocationClient { endpoint := os.Getenv("LOCATION_ENDPOINT") if endpoint == "" { endpoint = locationDefaultEndpoint } - client := &Client{} + client := &LocationClient{} client.Init(endpoint, locationAPIVersion, accessKeyId, accessKeySecret) + client.securityToken = securityToken return client } -func (client *Client) DescribeEndpoint(args *DescribeEndpointArgs) (*DescribeEndpointResponse, error) { +func NewLocationClientWithSecurityToken(accessKeyId, accessKeySecret, securityToken string) *LocationClient { + endpoint := os.Getenv("LOCATION_ENDPOINT") + if endpoint == "" { + endpoint = locationDefaultEndpoint + } + + client := &LocationClient{} + client.WithEndpoint(endpoint). + WithVersion(locationAPIVersion). + WithAccessKeyId(accessKeyId). + WithAccessKeySecret(accessKeySecret). + WithSecurityToken(securityToken). + InitClient() + return client +} + +func (client *LocationClient) DescribeEndpoint(args *DescribeEndpointArgs) (*DescribeEndpointResponse, error) { response := &DescribeEndpointResponse{} err := client.Invoke("DescribeEndpoint", args, response) if err != nil { @@ -45,6 +111,15 @@ func (client *Client) DescribeEndpoint(args *DescribeEndpointArgs) (*DescribeEnd return response, err } +func (client *LocationClient) DescribeEndpoints(args *DescribeEndpointsArgs) (*DescribeEndpointsResponse, error) { + response := &DescribeEndpointsResponse{} + err := client.Invoke("DescribeEndpoints", args, response) + if err != nil { + return nil, err + } + return response, err +} + func getProductRegionEndpoint(region Region, serviceCode string) string { if sp, ok := endpoints[region]; ok { if endpoint, ok := sp[serviceCode]; ok { @@ -61,34 +136,34 @@ func setProductRegionEndpoint(region Region, serviceCode string, endpoint string } } -func (client *Client) DescribeOpenAPIEndpoint(region Region, serviceCode string) string { +func (client *LocationClient) DescribeOpenAPIEndpoint(region Region, serviceCode string) string { if endpoint := getProductRegionEndpoint(region, serviceCode); endpoint != "" { return endpoint } defaultProtocols := HTTP_PROTOCOL - args := &DescribeEndpointArgs{ + args := &DescribeEndpointsArgs{ Id: region, ServiceCode: serviceCode, Type: "openAPI", } - endpoint, err := client.DescribeEndpoint(args) - if err != nil || endpoint.Endpoint == "" { + endpoint, err := client.DescribeEndpoints(args) + if err != nil || len(endpoint.Endpoints.Endpoint) <= 0 { return "" } - for _, protocol := range endpoint.Protocols.Protocols { + for _, protocol := range endpoint.Endpoints.Endpoint[0].Protocols.Protocols { if strings.ToLower(protocol) == HTTPS_PROTOCOL { defaultProtocols = HTTPS_PROTOCOL break } } - ep := fmt.Sprintf("%s://%s", defaultProtocols, endpoint.Endpoint) + ep := fmt.Sprintf("%s://%s", defaultProtocols, endpoint.Endpoints.Endpoint[0].Endpoint) - setProductRegionEndpoint(region, serviceCode, ep) + //setProductRegionEndpoint(region, serviceCode, ep) return ep } @@ -97,13 +172,11 @@ func loadEndpointFromFile(region Region, serviceCode string) string { if err != nil { return "" } - var endpoints Endpoints err = xml.Unmarshal(data, &endpoints) if err != nil { return "" } - for _, endpoint := range endpoints.Endpoint { if endpoint.RegionIds.RegionId == string(region) { for _, product := range endpoint.Products.Product { diff --git a/vendor/github.com/denverdino/aliyungo/common/endpoints.xml b/vendor/github.com/denverdino/aliyungo/common/endpoints.xml index 4079bcd2b..21f3a0b2e 100644 --- a/vendor/github.com/denverdino/aliyungo/common/endpoints.xml +++ b/vendor/github.com/denverdino/aliyungo/common/endpoints.xml @@ -1346,4 +1346,14 @@ <Product><ProductName>Slb</ProductName><DomainName>slb.cn-zhangjiakou.aliyuncs.com</DomainName></Product> </Products> </Endpoint> + <Endpoint name="cn-huhehaote"> + <RegionIds><RegionId>cn-huhehaote</RegionId></RegionIds> + <Products> + <Product><ProductName>Rds</ProductName><DomainName>rds.cn-huhehaote.aliyuncs.com</DomainName></Product> + <Product><ProductName>Ecs</ProductName><DomainName>ecs.cn-huhehaote.aliyuncs.com</DomainName></Product> + <Product><ProductName>Vpc</ProductName><DomainName>vpc.cn-huhehaote.aliyuncs.com</DomainName></Product> + <Product><ProductName>Cms</ProductName><DomainName>metrics.cn-hangzhou.aliyuncs.com</DomainName></Product> + <Product><ProductName>Slb</ProductName><DomainName>slb.cn-huhehaote.aliyuncs.com</DomainName></Product> + </Products> + </Endpoint> </Endpoints> diff --git a/vendor/github.com/denverdino/aliyungo/common/regions.go b/vendor/github.com/denverdino/aliyungo/common/regions.go index c87fe0691..38b14dd86 100644 --- a/vendor/github.com/denverdino/aliyungo/common/regions.go +++ b/vendor/github.com/denverdino/aliyungo/common/regions.go @@ -12,11 +12,15 @@ const ( Shenzhen = Region("cn-shenzhen") Shanghai = Region("cn-shanghai") Zhangjiakou = Region("cn-zhangjiakou") + Huhehaote = Region("cn-huhehaote") APSouthEast1 = Region("ap-southeast-1") APNorthEast1 = Region("ap-northeast-1") APSouthEast2 = Region("ap-southeast-2") APSouthEast3 = Region("ap-southeast-3") + APSouthEast5 = Region("ap-southeast-5") + + APSouth1 = Region("ap-south-1") USWest1 = Region("us-west-1") USEast1 = Region("us-east-1") @@ -24,12 +28,17 @@ const ( MEEast1 = Region("me-east-1") EUCentral1 = Region("eu-central-1") + + ShenZhenFinance = Region("cn-shenzhen-finance-1") + ShanghaiFinance = Region("cn-shanghai-finance-1") ) var ValidRegions = []Region{ - Hangzhou, Qingdao, Beijing, Shenzhen, Hongkong, Shanghai, Zhangjiakou, + Hangzhou, Qingdao, Beijing, Shenzhen, Hongkong, Shanghai, Zhangjiakou, Huhehaote, USWest1, USEast1, - APNorthEast1, APSouthEast1, APSouthEast2, APSouthEast3, + APNorthEast1, APSouthEast1, APSouthEast2, APSouthEast3, APSouthEast5, + APSouth1, MEEast1, EUCentral1, + ShenZhenFinance, ShanghaiFinance, } diff --git a/vendor/github.com/denverdino/aliyungo/common/types.go b/vendor/github.com/denverdino/aliyungo/common/types.go index a74e150e9..cf161f11b 100644 --- a/vendor/github.com/denverdino/aliyungo/common/types.go +++ b/vendor/github.com/denverdino/aliyungo/common/types.go @@ -36,6 +36,23 @@ type DescribeEndpointResponse struct { EndpointItem } +type DescribeEndpointsArgs struct { + Id Region + ServiceCode string + Type string +} + +type DescribeEndpointsResponse struct { + Response + Endpoints APIEndpoints + RequestId string + Success bool +} + +type APIEndpoints struct { + Endpoint []EndpointItem +} + type NetType string const ( @@ -48,6 +65,7 @@ type TimeType string const ( Hour = TimeType("Hour") Day = TimeType("Day") + Week = TimeType("Week") Month = TimeType("Month") Year = TimeType("Year") ) diff --git a/vendor/vendor.json b/vendor/vendor.json index 1864e235c..b1b90163f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -602,10 +602,10 @@ "revision": "6d212800a42e8ab5c146b8ace3490ee17e5225f9" }, { - "checksumSHA1": "2+1TPdvFj4W1QS5drkFr+ibM3G0=", + "checksumSHA1": "5k4kiVJsn0CilLDx+gMjglXY6vs=", "path": "github.com/denverdino/aliyungo/common", - "revision": "ec0e57291175fc9b06c62977f384756642285aab", - "revisionTime": "2017-11-27T16:20:29Z" + "revision": "ebad04655e0385f021ed264c89ef4b93958e7204", + "revisionTime": "2018-04-17T07:55:37Z" }, { "checksumSHA1": "y4Ay4E5HqT25sweC/Bl9/odNWaI=", From aa737a58621a30c1a2260e04e3623b80deb3c9c2 Mon Sep 17 00:00:00 2001 From: Diego Casati <diego.casati@gmail.com> Date: Wed, 18 Apr 2018 10:08:00 -0700 Subject: [PATCH 0928/1007] Add a FreeBSD example --- examples/azure/freebsd.json | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 examples/azure/freebsd.json diff --git a/examples/azure/freebsd.json b/examples/azure/freebsd.json new file mode 100644 index 000000000..991950b73 --- /dev/null +++ b/examples/azure/freebsd.json @@ -0,0 +1,46 @@ +{ + "variables": { + "client_id": "{{env `ARM_CLIENT_ID`}}", + "client_secret": "{{env `ARM_CLIENT_SECRET`}}", + "resource_group": "{{env `ARM_RESOURCE_GROUP`}}", + "storage_account": "{{env `ARM_STORAGE_ACCOUNT`}}", + "subscription_id": "{{env `ARM_SUBSCRIPTION_ID`}}", + "ssh_user": "packer", + "ssh_pass": null + }, + "builders": [{ + "type": "azure-arm", + + "client_id": "{{user `client_id`}}", + "client_secret": "{{user `client_secret`}}", + "resource_group_name": "{{user `resource_group`}}", + "storage_account": "{{user `storage_account`}}", + "subscription_id": "{{user `subscription_id`}}", + + "capture_container_name": "images", + "capture_name_prefix": "packer", + + "ssh_username": "{{user `ssh_user`}}", + "ssh_password": "{{user `ssh_pass`}}", + + "os_type": "Linux", + "image_publisher": "MicrosoftOSTC", + "image_offer": "FreeBSD", + "image_sku": "11.1", + "image_version": "latest", + + "location": "West US 2", + "vm_size": "Standard_DS2_v2" + }], + "provisioners": [{ + "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", + "inline": [ + "env ASSUME_ALWAYS_YES=YES pkg bootstrap", + "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" + ], + "inline_shebang": "/bin/sh -x", + "type": "shell", + "skip_clean": "true" + }] + +} From de429da5f9d87a30421f35b15bdaa647f6523052 Mon Sep 17 00:00:00 2001 From: Diego Casati <diego.casati@gmail.com> Date: Wed, 18 Apr 2018 12:05:27 -0700 Subject: [PATCH 0929/1007] add expect_disconnect otherwise the build fails --- examples/azure/freebsd.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/azure/freebsd.json b/examples/azure/freebsd.json index 991950b73..33f90c9a6 100644 --- a/examples/azure/freebsd.json +++ b/examples/azure/freebsd.json @@ -40,7 +40,8 @@ ], "inline_shebang": "/bin/sh -x", "type": "shell", - "skip_clean": "true" + "skip_clean": "true", + "expect_disconnect": "true" }] } From b8bf421dc2752848e688c07ea4336ede02b39c3f Mon Sep 17 00:00:00 2001 From: Stefan Henseler <stefan.henseler@synax.ch> Date: Wed, 18 Apr 2018 22:14:44 +0200 Subject: [PATCH 0930/1007] Fixes missing diskblocksize parameter for gen1 vms --- common/powershell/hyperv/hyperv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/powershell/hyperv/hyperv.go b/common/powershell/hyperv/hyperv.go index 54fa39d6d..b57ed4c72 100644 --- a/common/powershell/hyperv/hyperv.go +++ b/common/powershell/hyperv/hyperv.go @@ -231,7 +231,7 @@ if ($harddrivePath){ } ` var ps powershell.PowerShellCmd - if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), switchName, strconv.FormatBool(diffDisks)); err != nil { + if err := ps.Run(script, vmName, path, harddrivePath, vhdRoot, strconv.FormatInt(ram, 10), strconv.FormatInt(diskSize, 10), strconv.FormatInt(diskBlockSize, 10), switchName, strconv.FormatBool(diffDisks)); err != nil { return err } From a8072614e1ff5b02fbcc6b391c46aeb1cb205d00 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 16:34:32 -0700 Subject: [PATCH 0931/1007] update gemfile.lock --- website/Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/Gemfile.lock b/website/Gemfile.lock index 15173900a..040e5237a 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -6,7 +6,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - autoprefixer-rails (8.1.0.1) + autoprefixer-rails (8.3.0) execjs bootstrap-sass (3.3.7) autoprefixer-rails (>= 5.2.1) @@ -78,7 +78,7 @@ GEM rack (>= 1.4.5, < 2.0) thor (>= 0.15.2, < 2.0) tilt (~> 1.4.1, < 2.0) - middleman-hashicorp (0.3.34) + middleman-hashicorp (0.3.37) bootstrap-sass (~> 3.3) builder (~> 3.2) middleman (~> 3.4) @@ -113,9 +113,9 @@ GEM padrino-support (0.12.9) activesupport (>= 3.1) rack (1.6.9) - rack-livereload (0.3.16) + rack-livereload (0.3.17) rack - rack-test (0.8.3) + rack-test (1.0.0) rack (>= 1.0, < 3) rb-fsevent (0.10.3) rb-inotify (0.9.10) @@ -137,7 +137,7 @@ GEM thor (0.20.0) thread_safe (0.3.6) tilt (1.4.1) - turbolinks (5.1.0) + turbolinks (5.1.1) turbolinks-source (~> 5.1) turbolinks-source (5.1.0) tzinfo (1.2.5) @@ -153,7 +153,7 @@ PLATFORMS ruby DEPENDENCIES - middleman-hashicorp (= 0.3.34) + middleman-hashicorp (= 0.3.37) BUNDLED WITH 1.16.1 From 38e419dd8c1a07176374f3a94a914feb8d0eb6e6 Mon Sep 17 00:00:00 2001 From: alexgottschalkmedal <37642379+alexgottschalkmedal@users.noreply.github.com> Date: Thu, 19 Apr 2018 13:07:20 -0700 Subject: [PATCH 0932/1007] Update amazon.html.md Fix typo - CreateKeypair should be CreateKeyPair --- website/source/docs/builders/amazon.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/amazon.html.md b/website/source/docs/builders/amazon.html.md index 8af3f101f..9bff6561f 100644 --- a/website/source/docs/builders/amazon.html.md +++ b/website/source/docs/builders/amazon.html.md @@ -141,7 +141,7 @@ for Packer to work: "ec2:CreateSnapshot", "ec2:CreateTags", "ec2:CreateVolume", - "ec2:DeleteKeypair", + "ec2:DeleteKeyPair", "ec2:DeleteSecurityGroup", "ec2:DeleteSnapshot", "ec2:DeleteVolume", From 673245afcf9756113e0caad1b6f74f34640af0b4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Tue, 10 Apr 2018 23:05:46 -0700 Subject: [PATCH 0933/1007] Replace boot command parser with PEG parser. --- Makefile | 3 + .../common/step_type_boot_command.go | 1 + builder/vmware/common/step_run.go | 19 - .../vmware/common/step_type_boot_command.go | 380 +--- builder/vmware/iso/builder.go | 2 +- builder/vmware/vmx/builder.go | 2 +- common/boot_command/boot_command.go | 1663 +++++++++++++++++ common/boot_command/boot_command.pigeon | 95 + common/boot_command/boot_command_ast.go | 130 ++ common/boot_command/boot_command_ast_test.go | 30 + common/boot_command/gen.go | 3 + common/boot_command/vnc_driver.go | 135 ++ main.go | 1 + 13 files changed, 2102 insertions(+), 362 deletions(-) create mode 100644 common/boot_command/boot_command.go create mode 100644 common/boot_command/boot_command.pigeon create mode 100644 common/boot_command/boot_command_ast.go create mode 100644 common/boot_command/boot_command_ast_test.go create mode 100644 common/boot_command/gen.go create mode 100644 common/boot_command/vnc_driver.go diff --git a/Makefile b/Makefile index 54852ce26..be74e8be1 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ package: deps: @go get golang.org/x/tools/cmd/stringer + @go get -u github.com/mna/pigeon @go get github.com/kardianos/govendor @govendor sync @@ -73,6 +74,8 @@ fmt-examples: # source files. generate: deps ## Generate dynamically generated code go generate . + gofmt -w common/boot_command/boot_command.go + goimports -w common/boot_command/boot_command.go gofmt -w command/plugin.go test: deps fmt-check ## Run unit tests diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index be9397e76..d0c86e22d 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -94,6 +94,7 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m var codes []string + // split string into a list of 2-char pairs for i := 0; i < len(code)/2; i++ { codes = append(codes, code[i*2:i*2+2]) } diff --git a/builder/vmware/common/step_run.go b/builder/vmware/common/step_run.go index f85d5948f..2dad6faed 100644 --- a/builder/vmware/common/step_run.go +++ b/builder/vmware/common/step_run.go @@ -19,7 +19,6 @@ import ( // Produces: // <nothing> type StepRun struct { - BootWait time.Duration DurationBeforeStop time.Duration Headless bool @@ -65,24 +64,6 @@ func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste return multistep.ActionHalt } - // Wait the wait amount - if int64(s.BootWait) > 0 { - ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String())) - wait := time.After(s.BootWait) - WAITLOOP: - for { - select { - case <-wait: - break WAITLOOP - case <-time.After(1 * time.Second): - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - } - } - - } - return multistep.ActionContinue } diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 02404af91..7b4c8ee8f 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -5,28 +5,16 @@ import ( "fmt" "log" "net" - "os" - "regexp" - "strings" "time" - "unicode" - "unicode/utf8" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/go-vnc" ) -const KeyLeftShift uint32 = 0xFFE1 - -type bootCommandTemplateData struct { - HTTPIP string - HTTPPort uint - Name string -} - // This step "types" the boot command into the VM over VNC. // // Uses: @@ -37,13 +25,19 @@ type bootCommandTemplateData struct { // Produces: // <nothing> type StepTypeBootCommand struct { - VNCEnabled bool BootCommand []string + VNCEnabled bool + BootWait time.Duration VMName string Ctx interpolate.Context } +type bootCommandTemplateData struct { + HTTPIP string + HTTPPort uint + Name string +} -func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { if !s.VNCEnabled { log.Println("Skipping boot command step...") return multistep.ActionContinue @@ -57,6 +51,19 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m vncPort := state.Get("vnc_port").(uint) vncPassword := state.Get("vnc_password") + // ---------------- + // Wait the for the vm to boot. + if int64(s.BootWait) > 0 { + ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String())) + select { + case <-time.After(s.BootWait): + break + case <-ctx.Done(): + return multistep.ActionHalt + } + } + // ---------------- + var pauseFn multistep.DebugPauseFn if debug { pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn) @@ -110,6 +117,8 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m s.VMName, } + d := bootcommand.NewVNCDriver(c) + ui.Say("Typing the boot command over VNC...") for i, command := range s.BootCommand { command, err := interpolate.Render(command, &s.Ctx) @@ -130,335 +139,24 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) } - vncSendString(c, command) + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } return multistep.ActionContinue } func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} - -func vncSendString(c *vnc.ClientConn, original string) { - // Scancodes reference: https://github.com/qemu/qemu/blob/master/ui/vnc_keysym.h - special := make(map[string]uint32) - special["<bs>"] = 0xFF08 - special["<del>"] = 0xFFFF - special["<enter>"] = 0xFF0D - special["<esc>"] = 0xFF1B - special["<f1>"] = 0xFFBE - special["<f2>"] = 0xFFBF - special["<f3>"] = 0xFFC0 - special["<f4>"] = 0xFFC1 - special["<f5>"] = 0xFFC2 - special["<f6>"] = 0xFFC3 - special["<f7>"] = 0xFFC4 - special["<f8>"] = 0xFFC5 - special["<f9>"] = 0xFFC6 - special["<f10>"] = 0xFFC7 - special["<f11>"] = 0xFFC8 - special["<f12>"] = 0xFFC9 - special["<return>"] = 0xFF0D - special["<tab>"] = 0xFF09 - special["<up>"] = 0xFF52 - special["<down>"] = 0xFF54 - special["<left>"] = 0xFF51 - special["<right>"] = 0xFF53 - special["<spacebar>"] = 0x020 - special["<insert>"] = 0xFF63 - special["<home>"] = 0xFF50 - special["<end>"] = 0xFF57 - special["<pageUp>"] = 0xFF55 - special["<pageDown>"] = 0xFF56 - special["<leftAlt>"] = 0xFFE9 - special["<leftCtrl>"] = 0xFFE3 - special["<leftShift>"] = 0xFFE1 - special["<rightAlt>"] = 0xFFEA - special["<rightCtrl>"] = 0xFFE4 - special["<rightShift>"] = 0xFFE2 - special["<leftSuper>"] = 0xFFEB - special["<rightSuper>"] = 0xFFEC - - shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" - - // We delay (default 100ms) between each key event to allow for CPU or - // network latency. See PackerKeyEnv for tuning. - keyInterval := common.PackerKeyDefault - if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil { - keyInterval = delay - } - - azOnRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])On>") - azOffRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])Off>") - - // TODO(mitchellh): Ripe for optimizations of some point, perhaps. - for len(original) > 0 { - var keyCode uint32 - keyShift := false - - if strings.HasPrefix(original, "<leftAltOn>") { - keyCode = special["<leftAlt>"] - original = original[len("<leftAltOn>"):] - log.Printf("Special code '<leftAltOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftCtrlOn>") { - keyCode = special["<leftCtrl>"] - original = original[len("<leftCtrlOn>"):] - log.Printf("Special code '<leftCtrlOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftShiftOn>") { - keyCode = special["<leftShift>"] - original = original[len("<leftShiftOn>"):] - log.Printf("Special code '<leftShiftOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftSuperOn>") { - keyCode = special["<leftSuper>"] - original = original[len("<leftSuperOn>"):] - log.Printf("Special code '<leftSuperOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if azOnRegex.MatchString(original) { - m := azOnRegex.FindStringSubmatch(original) - r, _ := utf8.DecodeRuneInString(m[1]) - original = original[len("<aOn>"):] - keyCode = uint32(r) - keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - log.Printf("Special code '%s' found, replacing with %d, shift %v", m[0], keyCode, keyShift) - - if keyShift { - c.KeyEvent(KeyLeftShift, true) - } - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftAltOff>") { - keyCode = special["<leftAlt>"] - original = original[len("<leftAltOff>"):] - log.Printf("Special code '<leftAltOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftCtrlOff>") { - keyCode = special["<leftCtrl>"] - original = original[len("<leftCtrlOff>"):] - log.Printf("Special code '<leftCtrlOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftShiftOff>") { - keyCode = special["<leftShift>"] - original = original[len("<leftShiftOff>"):] - log.Printf("Special code '<leftShiftOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<leftSuperOff>") { - keyCode = special["<leftSuper>"] - original = original[len("<leftSuperOff>"):] - log.Printf("Special code '<leftSuperOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if azOffRegex.MatchString(original) { - m := azOffRegex.FindStringSubmatch(original) - r, _ := utf8.DecodeRuneInString(m[1]) - original = original[len("<aOff>"):] - keyCode = uint32(r) - keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - log.Printf("Special code '%s' found, replacing with %d, shift %v", m[0], keyCode, keyShift) - - if keyShift { - c.KeyEvent(KeyLeftShift, false) - } - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightAltOn>") { - keyCode = special["<rightAlt>"] - original = original[len("<rightAltOn>"):] - log.Printf("Special code '<rightAltOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightCtrlOn>") { - keyCode = special["<rightCtrl>"] - original = original[len("<rightCtrlOn>"):] - log.Printf("Special code '<rightCtrlOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightShiftOn>") { - keyCode = special["<rightShift>"] - original = original[len("<rightShiftOn>"):] - log.Printf("Special code '<rightShiftOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightSuperOn>") { - keyCode = special["<rightSuper>"] - original = original[len("<rightSuperOn>"):] - log.Printf("Special code '<rightSuperOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightAltOff>") { - keyCode = special["<rightAlt>"] - original = original[len("<rightAltOff>"):] - log.Printf("Special code '<rightAltOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightCtrlOff>") { - keyCode = special["<rightCtrl>"] - original = original[len("<rightCtrlOff>"):] - log.Printf("Special code '<rightCtrlOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightShiftOff>") { - keyCode = special["<rightShift>"] - original = original[len("<rightShiftOff>"):] - log.Printf("Special code '<rightShiftOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<rightSuperOff>") { - keyCode = special["<rightSuper>"] - original = original[len("<rightSuperOff>"):] - log.Printf("Special code '<rightSuperOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - continue - } - - if strings.HasPrefix(original, "<wait>") { - log.Printf("Special code '<wait>' found, sleeping one second") - time.Sleep(1 * time.Second) - original = original[len("<wait>"):] - continue - } - - if strings.HasPrefix(original, "<wait5>") { - log.Printf("Special code '<wait5>' found, sleeping 5 seconds") - time.Sleep(5 * time.Second) - original = original[len("<wait5>"):] - continue - } - - if strings.HasPrefix(original, "<wait10>") { - log.Printf("Special code '<wait10>' found, sleeping 10 seconds") - time.Sleep(10 * time.Second) - original = original[len("<wait10>"):] - continue - } - - for specialCode, specialValue := range special { - if strings.HasPrefix(original, specialCode) { - log.Printf("Special code '%s' found, replacing with: %d", specialCode, specialValue) - keyCode = specialValue - original = original[len(specialCode):] - break - } - } - - if keyCode == 0 { - r, size := utf8.DecodeRuneInString(original) - original = original[size:] - keyCode = uint32(r) - keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - log.Printf("Sending char '%c', code %d, shift %v", r, keyCode, keyShift) - } - - if keyShift { - c.KeyEvent(KeyLeftShift, true) - } - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - if keyShift { - c.KeyEvent(KeyLeftShift, false) - } - } -} diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 9e7e74452..5f1399c06 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -319,11 +319,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Format: b.config.Format, }, &vmwcommon.StepRun{ - BootWait: b.config.BootWait, DurationBeforeStop: 5 * time.Second, Headless: b.config.Headless, }, &vmwcommon.StepTypeBootCommand{ + BootWait: b.config.BootWait, VNCEnabled: !b.config.DisableVNC, BootCommand: b.config.BootCommand, VMName: b.config.VMName, diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 97852b534..69b143ebe 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -87,11 +87,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe VNCDisablePassword: b.config.VNCDisablePassword, }, &vmwcommon.StepRun{ - BootWait: b.config.BootWait, DurationBeforeStop: 5 * time.Second, Headless: b.config.Headless, }, &vmwcommon.StepTypeBootCommand{ + BootWait: b.config.BootWait, VNCEnabled: !b.config.DisableVNC, BootCommand: b.config.BootCommand, VMName: b.config.VMName, diff --git a/common/boot_command/boot_command.go b/common/boot_command/boot_command.go new file mode 100644 index 000000000..0a38932d9 --- /dev/null +++ b/common/boot_command/boot_command.go @@ -0,0 +1,1663 @@ +package bootcommand + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "strconv" + "strings" + "time" + "unicode" + "unicode/utf8" +) + +/* +func main() { + in := "<wait><wait10><wait1s><wait1m2ns>" + in += "foo/bar > one" + in += "<fOn> b<fOff>" + in += "<f3><f12><spacebar><leftalt><rightshift><rightsuper>" + got, err := ParseReader("", strings.NewReader(in)) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%s\n", got) +} +*/ + +var g = &grammar{ + rules: []*rule{ + { + name: "Input", + pos: position{line: 21, col: 1, offset: 345}, + expr: &actionExpr{ + pos: position{line: 21, col: 10, offset: 354}, + run: (*parser).callonInput1, + expr: &seqExpr{ + pos: position{line: 21, col: 10, offset: 354}, + exprs: []interface{}{ + &labeledExpr{ + pos: position{line: 21, col: 10, offset: 354}, + label: "expr", + expr: &ruleRefExpr{ + pos: position{line: 21, col: 15, offset: 359}, + name: "Expr", + }, + }, + &ruleRefExpr{ + pos: position{line: 21, col: 20, offset: 364}, + name: "EOF", + }, + }, + }, + }, + }, + { + name: "Expr", + pos: position{line: 25, col: 1, offset: 394}, + expr: &actionExpr{ + pos: position{line: 25, col: 9, offset: 402}, + run: (*parser).callonExpr1, + expr: &labeledExpr{ + pos: position{line: 25, col: 9, offset: 402}, + label: "l", + expr: &oneOrMoreExpr{ + pos: position{line: 25, col: 11, offset: 404}, + expr: &choiceExpr{ + pos: position{line: 25, col: 13, offset: 406}, + alternatives: []interface{}{ + &ruleRefExpr{ + pos: position{line: 25, col: 13, offset: 406}, + name: "Wait", + }, + &ruleRefExpr{ + pos: position{line: 25, col: 20, offset: 413}, + name: "CharToggle", + }, + &ruleRefExpr{ + pos: position{line: 25, col: 33, offset: 426}, + name: "Special", + }, + &ruleRefExpr{ + pos: position{line: 25, col: 43, offset: 436}, + name: "Literal", + }, + }, + }, + }, + }, + }, + }, + { + name: "Wait", + pos: position{line: 29, col: 1, offset: 469}, + expr: &actionExpr{ + pos: position{line: 29, col: 8, offset: 476}, + run: (*parser).callonWait1, + expr: &seqExpr{ + pos: position{line: 29, col: 8, offset: 476}, + exprs: []interface{}{ + &ruleRefExpr{ + pos: position{line: 29, col: 8, offset: 476}, + name: "ExprStart", + }, + &litMatcher{ + pos: position{line: 29, col: 18, offset: 486}, + val: "wait", + ignoreCase: false, + }, + &labeledExpr{ + pos: position{line: 29, col: 25, offset: 493}, + label: "duration", + expr: &zeroOrOneExpr{ + pos: position{line: 29, col: 34, offset: 502}, + expr: &choiceExpr{ + pos: position{line: 29, col: 36, offset: 504}, + alternatives: []interface{}{ + &ruleRefExpr{ + pos: position{line: 29, col: 36, offset: 504}, + name: "Duration", + }, + &ruleRefExpr{ + pos: position{line: 29, col: 47, offset: 515}, + name: "Integer", + }, + }, + }, + }, + }, + &ruleRefExpr{ + pos: position{line: 29, col: 58, offset: 526}, + name: "ExprEnd", + }, + }, + }, + }, + }, + { + name: "CharToggle", + pos: position{line: 42, col: 1, offset: 772}, + expr: &actionExpr{ + pos: position{line: 42, col: 14, offset: 785}, + run: (*parser).callonCharToggle1, + expr: &seqExpr{ + pos: position{line: 42, col: 14, offset: 785}, + exprs: []interface{}{ + &ruleRefExpr{ + pos: position{line: 42, col: 14, offset: 785}, + name: "ExprStart", + }, + &labeledExpr{ + pos: position{line: 42, col: 24, offset: 795}, + label: "lit", + expr: &ruleRefExpr{ + pos: position{line: 42, col: 29, offset: 800}, + name: "Literal", + }, + }, + &labeledExpr{ + pos: position{line: 42, col: 38, offset: 809}, + label: "t", + expr: &choiceExpr{ + pos: position{line: 42, col: 41, offset: 812}, + alternatives: []interface{}{ + &ruleRefExpr{ + pos: position{line: 42, col: 41, offset: 812}, + name: "On", + }, + &ruleRefExpr{ + pos: position{line: 42, col: 46, offset: 817}, + name: "Off", + }, + }, + }, + }, + &ruleRefExpr{ + pos: position{line: 42, col: 51, offset: 822}, + name: "ExprEnd", + }, + }, + }, + }, + }, + { + name: "Special", + pos: position{line: 46, col: 1, offset: 893}, + expr: &actionExpr{ + pos: position{line: 46, col: 11, offset: 903}, + run: (*parser).callonSpecial1, + expr: &seqExpr{ + pos: position{line: 46, col: 11, offset: 903}, + exprs: []interface{}{ + &ruleRefExpr{ + pos: position{line: 46, col: 11, offset: 903}, + name: "ExprStart", + }, + &labeledExpr{ + pos: position{line: 46, col: 21, offset: 913}, + label: "s", + expr: &ruleRefExpr{ + pos: position{line: 46, col: 24, offset: 916}, + name: "SpecialKey", + }, + }, + &labeledExpr{ + pos: position{line: 46, col: 36, offset: 928}, + label: "t", + expr: &zeroOrOneExpr{ + pos: position{line: 46, col: 38, offset: 930}, + expr: &choiceExpr{ + pos: position{line: 46, col: 39, offset: 931}, + alternatives: []interface{}{ + &ruleRefExpr{ + pos: position{line: 46, col: 39, offset: 931}, + name: "On", + }, + &ruleRefExpr{ + pos: position{line: 46, col: 44, offset: 936}, + name: "Off", + }, + }, + }, + }, + }, + &ruleRefExpr{ + pos: position{line: 46, col: 50, offset: 942}, + name: "ExprEnd", + }, + }, + }, + }, + }, + { + name: "Number", + pos: position{line: 55, col: 1, offset: 1211}, + expr: &actionExpr{ + pos: position{line: 55, col: 10, offset: 1220}, + run: (*parser).callonNumber1, + expr: &seqExpr{ + pos: position{line: 55, col: 10, offset: 1220}, + exprs: []interface{}{ + &zeroOrOneExpr{ + pos: position{line: 55, col: 10, offset: 1220}, + expr: &litMatcher{ + pos: position{line: 55, col: 10, offset: 1220}, + val: "-", + ignoreCase: false, + }, + }, + &ruleRefExpr{ + pos: position{line: 55, col: 15, offset: 1225}, + name: "Integer", + }, + &zeroOrOneExpr{ + pos: position{line: 55, col: 23, offset: 1233}, + expr: &seqExpr{ + pos: position{line: 55, col: 25, offset: 1235}, + exprs: []interface{}{ + &litMatcher{ + pos: position{line: 55, col: 25, offset: 1235}, + val: ".", + ignoreCase: false, + }, + &oneOrMoreExpr{ + pos: position{line: 55, col: 29, offset: 1239}, + expr: &ruleRefExpr{ + pos: position{line: 55, col: 29, offset: 1239}, + name: "Digit", + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Integer", + pos: position{line: 59, col: 1, offset: 1285}, + expr: &choiceExpr{ + pos: position{line: 59, col: 11, offset: 1295}, + alternatives: []interface{}{ + &litMatcher{ + pos: position{line: 59, col: 11, offset: 1295}, + val: "0", + ignoreCase: false, + }, + &actionExpr{ + pos: position{line: 59, col: 17, offset: 1301}, + run: (*parser).callonInteger3, + expr: &seqExpr{ + pos: position{line: 59, col: 17, offset: 1301}, + exprs: []interface{}{ + &ruleRefExpr{ + pos: position{line: 59, col: 17, offset: 1301}, + name: "NonZeroDigit", + }, + &zeroOrMoreExpr{ + pos: position{line: 59, col: 30, offset: 1314}, + expr: &ruleRefExpr{ + pos: position{line: 59, col: 30, offset: 1314}, + name: "Digit", + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "Duration", + pos: position{line: 63, col: 1, offset: 1378}, + expr: &actionExpr{ + pos: position{line: 63, col: 12, offset: 1389}, + run: (*parser).callonDuration1, + expr: &oneOrMoreExpr{ + pos: position{line: 63, col: 12, offset: 1389}, + expr: &seqExpr{ + pos: position{line: 63, col: 14, offset: 1391}, + exprs: []interface{}{ + &ruleRefExpr{ + pos: position{line: 63, col: 14, offset: 1391}, + name: "Number", + }, + &ruleRefExpr{ + pos: position{line: 63, col: 21, offset: 1398}, + name: "TimeUnit", + }, + }, + }, + }, + }, + }, + { + name: "On", + pos: position{line: 67, col: 1, offset: 1461}, + expr: &actionExpr{ + pos: position{line: 67, col: 6, offset: 1466}, + run: (*parser).callonOn1, + expr: &litMatcher{ + pos: position{line: 67, col: 6, offset: 1466}, + val: "on", + ignoreCase: true, + }, + }, + }, + { + name: "Off", + pos: position{line: 71, col: 1, offset: 1499}, + expr: &actionExpr{ + pos: position{line: 71, col: 7, offset: 1505}, + run: (*parser).callonOff1, + expr: &litMatcher{ + pos: position{line: 71, col: 7, offset: 1505}, + val: "off", + ignoreCase: true, + }, + }, + }, + { + name: "Literal", + pos: position{line: 75, col: 1, offset: 1540}, + expr: &actionExpr{ + pos: position{line: 75, col: 11, offset: 1550}, + run: (*parser).callonLiteral1, + expr: &anyMatcher{ + line: 75, col: 11, offset: 1550, + }, + }, + }, + { + name: "ExprEnd", + pos: position{line: 80, col: 1, offset: 1631}, + expr: &litMatcher{ + pos: position{line: 80, col: 11, offset: 1641}, + val: ">", + ignoreCase: false, + }, + }, + { + name: "ExprStart", + pos: position{line: 81, col: 1, offset: 1645}, + expr: &litMatcher{ + pos: position{line: 81, col: 13, offset: 1657}, + val: "<", + ignoreCase: false, + }, + }, + { + name: "SpecialKey", + pos: position{line: 82, col: 1, offset: 1661}, + expr: &choiceExpr{ + pos: position{line: 82, col: 14, offset: 1674}, + alternatives: []interface{}{ + &litMatcher{ + pos: position{line: 82, col: 14, offset: 1674}, + val: "bs", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 82, col: 22, offset: 1682}, + val: "del", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 82, col: 31, offset: 1691}, + val: "enter", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 82, col: 42, offset: 1702}, + val: "esc", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 82, col: 51, offset: 1711}, + val: "f10", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 82, col: 60, offset: 1720}, + val: "f11", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 82, col: 69, offset: 1729}, + val: "f12", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 11, offset: 1746}, + val: "f1", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 19, offset: 1754}, + val: "f2", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 27, offset: 1762}, + val: "f3", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 35, offset: 1770}, + val: "f4", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 43, offset: 1778}, + val: "f5", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 51, offset: 1786}, + val: "f6", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 59, offset: 1794}, + val: "f7", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 67, offset: 1802}, + val: "f8", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 83, col: 75, offset: 1810}, + val: "f9", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 12, offset: 1827}, + val: "return", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 24, offset: 1839}, + val: "tab", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 33, offset: 1848}, + val: "up", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 41, offset: 1856}, + val: "down", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 51, offset: 1866}, + val: "spacebar", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 65, offset: 1880}, + val: "insert", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 84, col: 77, offset: 1892}, + val: "home", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 85, col: 11, offset: 1910}, + val: "end", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 85, col: 20, offset: 1919}, + val: "pageup", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 85, col: 32, offset: 1931}, + val: "pagedown", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 85, col: 46, offset: 1945}, + val: "leftalt", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 85, col: 59, offset: 1958}, + val: "leftctrl", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 85, col: 73, offset: 1972}, + val: "leftshift", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 86, col: 11, offset: 1995}, + val: "rightalt", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 86, col: 25, offset: 2009}, + val: "rightctrl", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 86, col: 40, offset: 2024}, + val: "rightshift", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 86, col: 56, offset: 2040}, + val: "leftsuper", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 86, col: 71, offset: 2055}, + val: "rightsuper", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 87, col: 11, offset: 2079}, + val: "left", + ignoreCase: true, + }, + &litMatcher{ + pos: position{line: 87, col: 21, offset: 2089}, + val: "right", + ignoreCase: true, + }, + }, + }, + }, + { + name: "NonZeroDigit", + pos: position{line: 89, col: 1, offset: 2099}, + expr: &charClassMatcher{ + pos: position{line: 89, col: 16, offset: 2114}, + val: "[1-9]", + ranges: []rune{'1', '9'}, + ignoreCase: false, + inverted: false, + }, + }, + { + name: "Digit", + pos: position{line: 90, col: 1, offset: 2120}, + expr: &charClassMatcher{ + pos: position{line: 90, col: 9, offset: 2128}, + val: "[0-9]", + ranges: []rune{'0', '9'}, + ignoreCase: false, + inverted: false, + }, + }, + { + name: "TimeUnit", + pos: position{line: 91, col: 1, offset: 2134}, + expr: &choiceExpr{ + pos: position{line: 91, col: 13, offset: 2146}, + alternatives: []interface{}{ + &litMatcher{ + pos: position{line: 91, col: 13, offset: 2146}, + val: "ns", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 91, col: 20, offset: 2153}, + val: "us", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 91, col: 27, offset: 2160}, + val: "µs", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 91, col: 34, offset: 2168}, + val: "ms", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 91, col: 41, offset: 2175}, + val: "s", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 91, col: 47, offset: 2181}, + val: "m", + ignoreCase: false, + }, + &litMatcher{ + pos: position{line: 91, col: 53, offset: 2187}, + val: "h", + ignoreCase: false, + }, + }, + }, + }, + { + name: "_", + displayName: "\"whitespace\"", + pos: position{line: 93, col: 1, offset: 2193}, + expr: &zeroOrMoreExpr{ + pos: position{line: 93, col: 19, offset: 2211}, + expr: &charClassMatcher{ + pos: position{line: 93, col: 19, offset: 2211}, + val: "[ \\n\\t\\r]", + chars: []rune{' ', '\n', '\t', '\r'}, + ignoreCase: false, + inverted: false, + }, + }, + }, + { + name: "EOF", + pos: position{line: 95, col: 1, offset: 2223}, + expr: &notExpr{ + pos: position{line: 95, col: 8, offset: 2230}, + expr: &anyMatcher{ + line: 95, col: 9, offset: 2231, + }, + }, + }, + }, +} + +func (c *current) onInput1(expr interface{}) (interface{}, error) { + return expr, nil +} + +func (p *parser) callonInput1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onInput1(stack["expr"]) +} + +func (c *current) onExpr1(l interface{}) (interface{}, error) { + return l, nil +} + +func (p *parser) callonExpr1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onExpr1(stack["l"]) +} + +func (c *current) onWait1(duration interface{}) (interface{}, error) { + var d time.Duration + switch t := duration.(type) { + case time.Duration: + d = t + case int64: + d = time.Duration(t) * time.Second + default: + d = time.Second + } + return &waitExpression{d}, nil +} + +func (p *parser) callonWait1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onWait1(stack["duration"]) +} + +func (c *current) onCharToggle1(lit, t interface{}) (interface{}, error) { + return &literal{lit.(*literal).s, t.(KeyAction)}, nil +} + +func (p *parser) callonCharToggle1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onCharToggle1(stack["lit"], stack["t"]) +} + +func (c *current) onSpecial1(s, t interface{}) (interface{}, error) { + if t == nil { + //return fmt.Sprintf("S(%s)", s), nil + return &specialExpression{string(s.([]byte)), KeyPress}, nil + } + return &specialExpression{string(s.([]byte)), t.(KeyAction)}, nil + //return fmt.Sprintf("S%s(%s)", t, s), nil +} + +func (p *parser) callonSpecial1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onSpecial1(stack["s"], stack["t"]) +} + +func (c *current) onNumber1() (interface{}, error) { + return string(c.text), nil +} + +func (p *parser) callonNumber1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onNumber1() +} + +func (c *current) onInteger3() (interface{}, error) { + return strconv.ParseInt(string(c.text), 10, 64) +} + +func (p *parser) callonInteger3() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onInteger3() +} + +func (c *current) onDuration1() (interface{}, error) { + return time.ParseDuration(string(c.text)) +} + +func (p *parser) callonDuration1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onDuration1() +} + +func (c *current) onOn1() (interface{}, error) { + return KeyOn, nil +} + +func (p *parser) callonOn1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onOn1() +} + +func (c *current) onOff1() (interface{}, error) { + return KeyOff, nil +} + +func (p *parser) callonOff1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onOff1() +} + +func (c *current) onLiteral1() (interface{}, error) { + r, _ := utf8.DecodeRune(c.text) + return &literal{r, KeyPress}, nil +} + +func (p *parser) callonLiteral1() (interface{}, error) { + stack := p.vstack[len(p.vstack)-1] + _ = stack + return p.cur.onLiteral1() +} + +var ( + // errNoRule is returned when the grammar to parse has no rule. + errNoRule = errors.New("grammar has no rule") + + // errInvalidEncoding is returned when the source is not properly + // utf8-encoded. + errInvalidEncoding = errors.New("invalid encoding") + + // errNoMatch is returned if no match could be found. + errNoMatch = errors.New("no match found") +) + +// Option is a function that can set an option on the parser. It returns +// the previous setting as an Option. +type Option func(*parser) Option + +// Debug creates an Option to set the debug flag to b. When set to true, +// debugging information is printed to stdout while parsing. +// +// The default is false. +func Debug(b bool) Option { + return func(p *parser) Option { + old := p.debug + p.debug = b + return Debug(old) + } +} + +// Memoize creates an Option to set the memoize flag to b. When set to true, +// the parser will cache all results so each expression is evaluated only +// once. This guarantees linear parsing time even for pathological cases, +// at the expense of more memory and slower times for typical cases. +// +// The default is false. +func Memoize(b bool) Option { + return func(p *parser) Option { + old := p.memoize + p.memoize = b + return Memoize(old) + } +} + +// Recover creates an Option to set the recover flag to b. When set to +// true, this causes the parser to recover from panics and convert it +// to an error. Setting it to false can be useful while debugging to +// access the full stack trace. +// +// The default is true. +func Recover(b bool) Option { + return func(p *parser) Option { + old := p.recover + p.recover = b + return Recover(old) + } +} + +// ParseFile parses the file identified by filename. +func ParseFile(filename string, opts ...Option) (interface{}, error) { + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer f.Close() + return ParseReader(filename, f, opts...) +} + +// ParseReader parses the data from r using filename as information in the +// error messages. +func ParseReader(filename string, r io.Reader, opts ...Option) (interface{}, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + return Parse(filename, b, opts...) +} + +// Parse parses the data from b using filename as information in the +// error messages. +func Parse(filename string, b []byte, opts ...Option) (interface{}, error) { + return newParser(filename, b, opts...).parse(g) +} + +// position records a position in the text. +type position struct { + line, col, offset int +} + +func (p position) String() string { + return fmt.Sprintf("%d:%d [%d]", p.line, p.col, p.offset) +} + +// savepoint stores all state required to go back to this point in the +// parser. +type savepoint struct { + position + rn rune + w int +} + +type current struct { + pos position // start position of the match + text []byte // raw text of the match +} + +// the AST types... + +type grammar struct { + pos position + rules []*rule +} + +type rule struct { + pos position + name string + displayName string + expr interface{} +} + +type choiceExpr struct { + pos position + alternatives []interface{} +} + +type actionExpr struct { + pos position + expr interface{} + run func(*parser) (interface{}, error) +} + +type seqExpr struct { + pos position + exprs []interface{} +} + +type labeledExpr struct { + pos position + label string + expr interface{} +} + +type expr struct { + pos position + expr interface{} +} + +type andExpr expr +type notExpr expr +type zeroOrOneExpr expr +type zeroOrMoreExpr expr +type oneOrMoreExpr expr + +type ruleRefExpr struct { + pos position + name string +} + +type andCodeExpr struct { + pos position + run func(*parser) (bool, error) +} + +type notCodeExpr struct { + pos position + run func(*parser) (bool, error) +} + +type litMatcher struct { + pos position + val string + ignoreCase bool +} + +type charClassMatcher struct { + pos position + val string + chars []rune + ranges []rune + classes []*unicode.RangeTable + ignoreCase bool + inverted bool +} + +type anyMatcher position + +// errList cumulates the errors found by the parser. +type errList []error + +func (e *errList) add(err error) { + *e = append(*e, err) +} + +func (e errList) err() error { + if len(e) == 0 { + return nil + } + e.dedupe() + return e +} + +func (e *errList) dedupe() { + var cleaned []error + set := make(map[string]bool) + for _, err := range *e { + if msg := err.Error(); !set[msg] { + set[msg] = true + cleaned = append(cleaned, err) + } + } + *e = cleaned +} + +func (e errList) Error() string { + switch len(e) { + case 0: + return "" + case 1: + return e[0].Error() + default: + var buf bytes.Buffer + + for i, err := range e { + if i > 0 { + buf.WriteRune('\n') + } + buf.WriteString(err.Error()) + } + return buf.String() + } +} + +// parserError wraps an error with a prefix indicating the rule in which +// the error occurred. The original error is stored in the Inner field. +type parserError struct { + Inner error + pos position + prefix string +} + +// Error returns the error message. +func (p *parserError) Error() string { + return p.prefix + ": " + p.Inner.Error() +} + +// newParser creates a parser with the specified input source and options. +func newParser(filename string, b []byte, opts ...Option) *parser { + p := &parser{ + filename: filename, + errs: new(errList), + data: b, + pt: savepoint{position: position{line: 1}}, + recover: true, + } + p.setOptions(opts) + return p +} + +// setOptions applies the options to the parser. +func (p *parser) setOptions(opts []Option) { + for _, opt := range opts { + opt(p) + } +} + +type resultTuple struct { + v interface{} + b bool + end savepoint +} + +type parser struct { + filename string + pt savepoint + cur current + + data []byte + errs *errList + + recover bool + debug bool + depth int + + memoize bool + // memoization table for the packrat algorithm: + // map[offset in source] map[expression or rule] {value, match} + memo map[int]map[interface{}]resultTuple + + // rules table, maps the rule identifier to the rule node + rules map[string]*rule + // variables stack, map of label to value + vstack []map[string]interface{} + // rule stack, allows identification of the current rule in errors + rstack []*rule + + // stats + exprCnt int +} + +// push a variable set on the vstack. +func (p *parser) pushV() { + if cap(p.vstack) == len(p.vstack) { + // create new empty slot in the stack + p.vstack = append(p.vstack, nil) + } else { + // slice to 1 more + p.vstack = p.vstack[:len(p.vstack)+1] + } + + // get the last args set + m := p.vstack[len(p.vstack)-1] + if m != nil && len(m) == 0 { + // empty map, all good + return + } + + m = make(map[string]interface{}) + p.vstack[len(p.vstack)-1] = m +} + +// pop a variable set from the vstack. +func (p *parser) popV() { + // if the map is not empty, clear it + m := p.vstack[len(p.vstack)-1] + if len(m) > 0 { + // GC that map + p.vstack[len(p.vstack)-1] = nil + } + p.vstack = p.vstack[:len(p.vstack)-1] +} + +func (p *parser) print(prefix, s string) string { + if !p.debug { + return s + } + + fmt.Printf("%s %d:%d:%d: %s [%#U]\n", + prefix, p.pt.line, p.pt.col, p.pt.offset, s, p.pt.rn) + return s +} + +func (p *parser) in(s string) string { + p.depth++ + return p.print(strings.Repeat(" ", p.depth)+">", s) +} + +func (p *parser) out(s string) string { + p.depth-- + return p.print(strings.Repeat(" ", p.depth)+"<", s) +} + +func (p *parser) addErr(err error) { + p.addErrAt(err, p.pt.position) +} + +func (p *parser) addErrAt(err error, pos position) { + var buf bytes.Buffer + if p.filename != "" { + buf.WriteString(p.filename) + } + if buf.Len() > 0 { + buf.WriteString(":") + } + buf.WriteString(fmt.Sprintf("%d:%d (%d)", pos.line, pos.col, pos.offset)) + if len(p.rstack) > 0 { + if buf.Len() > 0 { + buf.WriteString(": ") + } + rule := p.rstack[len(p.rstack)-1] + if rule.displayName != "" { + buf.WriteString("rule " + rule.displayName) + } else { + buf.WriteString("rule " + rule.name) + } + } + pe := &parserError{Inner: err, pos: pos, prefix: buf.String()} + p.errs.add(pe) +} + +// read advances the parser to the next rune. +func (p *parser) read() { + p.pt.offset += p.pt.w + rn, n := utf8.DecodeRune(p.data[p.pt.offset:]) + p.pt.rn = rn + p.pt.w = n + p.pt.col++ + if rn == '\n' { + p.pt.line++ + p.pt.col = 0 + } + + if rn == utf8.RuneError { + if n == 1 { + p.addErr(errInvalidEncoding) + } + } +} + +// restore parser position to the savepoint pt. +func (p *parser) restore(pt savepoint) { + if p.debug { + defer p.out(p.in("restore")) + } + if pt.offset == p.pt.offset { + return + } + p.pt = pt +} + +// get the slice of bytes from the savepoint start to the current position. +func (p *parser) sliceFrom(start savepoint) []byte { + return p.data[start.position.offset:p.pt.position.offset] +} + +func (p *parser) getMemoized(node interface{}) (resultTuple, bool) { + if len(p.memo) == 0 { + return resultTuple{}, false + } + m := p.memo[p.pt.offset] + if len(m) == 0 { + return resultTuple{}, false + } + res, ok := m[node] + return res, ok +} + +func (p *parser) setMemoized(pt savepoint, node interface{}, tuple resultTuple) { + if p.memo == nil { + p.memo = make(map[int]map[interface{}]resultTuple) + } + m := p.memo[pt.offset] + if m == nil { + m = make(map[interface{}]resultTuple) + p.memo[pt.offset] = m + } + m[node] = tuple +} + +func (p *parser) buildRulesTable(g *grammar) { + p.rules = make(map[string]*rule, len(g.rules)) + for _, r := range g.rules { + p.rules[r.name] = r + } +} + +func (p *parser) parse(g *grammar) (val interface{}, err error) { + if len(g.rules) == 0 { + p.addErr(errNoRule) + return nil, p.errs.err() + } + + // TODO : not super critical but this could be generated + p.buildRulesTable(g) + + if p.recover { + // panic can be used in action code to stop parsing immediately + // and return the panic as an error. + defer func() { + if e := recover(); e != nil { + if p.debug { + defer p.out(p.in("panic handler")) + } + val = nil + switch e := e.(type) { + case error: + p.addErr(e) + default: + p.addErr(fmt.Errorf("%v", e)) + } + err = p.errs.err() + } + }() + } + + // start rule is rule [0] + p.read() // advance to first rune + val, ok := p.parseRule(g.rules[0]) + if !ok { + if len(*p.errs) == 0 { + // make sure this doesn't go out silently + p.addErr(errNoMatch) + } + return nil, p.errs.err() + } + return val, p.errs.err() +} + +func (p *parser) parseRule(rule *rule) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseRule " + rule.name)) + } + + if p.memoize { + res, ok := p.getMemoized(rule) + if ok { + p.restore(res.end) + return res.v, res.b + } + } + + start := p.pt + p.rstack = append(p.rstack, rule) + p.pushV() + val, ok := p.parseExpr(rule.expr) + p.popV() + p.rstack = p.rstack[:len(p.rstack)-1] + if ok && p.debug { + p.print(strings.Repeat(" ", p.depth)+"MATCH", string(p.sliceFrom(start))) + } + + if p.memoize { + p.setMemoized(start, rule, resultTuple{val, ok, p.pt}) + } + return val, ok +} + +func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { + var pt savepoint + var ok bool + + if p.memoize { + res, ok := p.getMemoized(expr) + if ok { + p.restore(res.end) + return res.v, res.b + } + pt = p.pt + } + + p.exprCnt++ + var val interface{} + switch expr := expr.(type) { + case *actionExpr: + val, ok = p.parseActionExpr(expr) + case *andCodeExpr: + val, ok = p.parseAndCodeExpr(expr) + case *andExpr: + val, ok = p.parseAndExpr(expr) + case *anyMatcher: + val, ok = p.parseAnyMatcher(expr) + case *charClassMatcher: + val, ok = p.parseCharClassMatcher(expr) + case *choiceExpr: + val, ok = p.parseChoiceExpr(expr) + case *labeledExpr: + val, ok = p.parseLabeledExpr(expr) + case *litMatcher: + val, ok = p.parseLitMatcher(expr) + case *notCodeExpr: + val, ok = p.parseNotCodeExpr(expr) + case *notExpr: + val, ok = p.parseNotExpr(expr) + case *oneOrMoreExpr: + val, ok = p.parseOneOrMoreExpr(expr) + case *ruleRefExpr: + val, ok = p.parseRuleRefExpr(expr) + case *seqExpr: + val, ok = p.parseSeqExpr(expr) + case *zeroOrMoreExpr: + val, ok = p.parseZeroOrMoreExpr(expr) + case *zeroOrOneExpr: + val, ok = p.parseZeroOrOneExpr(expr) + default: + panic(fmt.Sprintf("unknown expression type %T", expr)) + } + if p.memoize { + p.setMemoized(pt, expr, resultTuple{val, ok, p.pt}) + } + return val, ok +} + +func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseActionExpr")) + } + + start := p.pt + val, ok := p.parseExpr(act.expr) + if ok { + p.cur.pos = start.position + p.cur.text = p.sliceFrom(start) + actVal, err := act.run(p) + if err != nil { + p.addErrAt(err, start.position) + } + val = actVal + } + if ok && p.debug { + p.print(strings.Repeat(" ", p.depth)+"MATCH", string(p.sliceFrom(start))) + } + return val, ok +} + +func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseAndCodeExpr")) + } + + ok, err := and.run(p) + if err != nil { + p.addErr(err) + } + return nil, ok +} + +func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseAndExpr")) + } + + pt := p.pt + p.pushV() + _, ok := p.parseExpr(and.expr) + p.popV() + p.restore(pt) + return nil, ok +} + +func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseAnyMatcher")) + } + + if p.pt.rn != utf8.RuneError { + start := p.pt + p.read() + return p.sliceFrom(start), true + } + return nil, false +} + +func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseCharClassMatcher")) + } + + cur := p.pt.rn + // can't match EOF + if cur == utf8.RuneError { + return nil, false + } + start := p.pt + if chr.ignoreCase { + cur = unicode.ToLower(cur) + } + + // try to match in the list of available chars + for _, rn := range chr.chars { + if rn == cur { + if chr.inverted { + return nil, false + } + p.read() + return p.sliceFrom(start), true + } + } + + // try to match in the list of ranges + for i := 0; i < len(chr.ranges); i += 2 { + if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] { + if chr.inverted { + return nil, false + } + p.read() + return p.sliceFrom(start), true + } + } + + // try to match in the list of Unicode classes + for _, cl := range chr.classes { + if unicode.Is(cl, cur) { + if chr.inverted { + return nil, false + } + p.read() + return p.sliceFrom(start), true + } + } + + if chr.inverted { + p.read() + return p.sliceFrom(start), true + } + return nil, false +} + +func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseChoiceExpr")) + } + + for _, alt := range ch.alternatives { + p.pushV() + val, ok := p.parseExpr(alt) + p.popV() + if ok { + return val, ok + } + } + return nil, false +} + +func (p *parser) parseLabeledExpr(lab *labeledExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseLabeledExpr")) + } + + p.pushV() + val, ok := p.parseExpr(lab.expr) + p.popV() + if ok && lab.label != "" { + m := p.vstack[len(p.vstack)-1] + m[lab.label] = val + } + return val, ok +} + +func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseLitMatcher")) + } + + start := p.pt + for _, want := range lit.val { + cur := p.pt.rn + if lit.ignoreCase { + cur = unicode.ToLower(cur) + } + if cur != want { + p.restore(start) + return nil, false + } + p.read() + } + return p.sliceFrom(start), true +} + +func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseNotCodeExpr")) + } + + ok, err := not.run(p) + if err != nil { + p.addErr(err) + } + return nil, !ok +} + +func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseNotExpr")) + } + + pt := p.pt + p.pushV() + _, ok := p.parseExpr(not.expr) + p.popV() + p.restore(pt) + return nil, !ok +} + +func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseOneOrMoreExpr")) + } + + var vals []interface{} + + for { + p.pushV() + val, ok := p.parseExpr(expr.expr) + p.popV() + if !ok { + if len(vals) == 0 { + // did not match once, no match + return nil, false + } + return vals, true + } + vals = append(vals, val) + } +} + +func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseRuleRefExpr " + ref.name)) + } + + if ref.name == "" { + panic(fmt.Sprintf("%s: invalid rule: missing name", ref.pos)) + } + + rule := p.rules[ref.name] + if rule == nil { + p.addErr(fmt.Errorf("undefined rule: %s", ref.name)) + return nil, false + } + return p.parseRule(rule) +} + +func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseSeqExpr")) + } + + var vals []interface{} + + pt := p.pt + for _, expr := range seq.exprs { + val, ok := p.parseExpr(expr) + if !ok { + p.restore(pt) + return nil, false + } + vals = append(vals, val) + } + return vals, true +} + +func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseZeroOrMoreExpr")) + } + + var vals []interface{} + + for { + p.pushV() + val, ok := p.parseExpr(expr.expr) + p.popV() + if !ok { + return vals, true + } + vals = append(vals, val) + } +} + +func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseZeroOrOneExpr")) + } + + p.pushV() + val, _ := p.parseExpr(expr.expr) + p.popV() + // whether it matched or not, consider it a match + return val, true +} + +func rangeTable(class string) *unicode.RangeTable { + if rt, ok := unicode.Categories[class]; ok { + return rt + } + if rt, ok := unicode.Properties[class]; ok { + return rt + } + if rt, ok := unicode.Scripts[class]; ok { + return rt + } + + // cannot happen + panic(fmt.Sprintf("invalid Unicode class: %s", class)) +} diff --git a/common/boot_command/boot_command.pigeon b/common/boot_command/boot_command.pigeon new file mode 100644 index 000000000..a496bb552 --- /dev/null +++ b/common/boot_command/boot_command.pigeon @@ -0,0 +1,95 @@ +{ +package bootcommand + + + +/* +func main() { + in := "<wait><wait10><wait1s><wait1m2ns>" + in += "foo/bar > one" + in += "<fOn> b<fOff>" + in += "<f3><f12><spacebar><leftalt><rightshift><rightsuper>" + got, err := ParseReader("", strings.NewReader(in)) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%s\n", got) +} +*/ +} + +Input <- expr:Expr EOF { + return expr, nil +} + +Expr <- l:( Wait / CharToggle / Special / Literal)+ { + return l, nil +} + +Wait = ExprStart "wait" duration:( Duration / Integer )? ExprEnd { + var d time.Duration + switch t := duration.(type) { + case time.Duration: + d = t + case int64: + d = time.Duration(t) * time.Second + default: + d = time.Second + } + return &waitExpression{d}, nil +} + +CharToggle = ExprStart lit:(Literal) t:(On / Off) ExprEnd { + return &literal{lit.(*literal).s, t.(KeyAction)}, nil +} + +Special = ExprStart s:(SpecialKey) t:(On / Off)? ExprEnd { + if t == nil { + //return fmt.Sprintf("S(%s)", s), nil + return &specialExpression{string(s.([]byte)), KeyPress}, nil + } + return &specialExpression{string(s.([]byte)), t.(KeyAction)}, nil + //return fmt.Sprintf("S%s(%s)", t, s), nil +} + +Number = '-'? Integer ( '.' Digit+ )? { + return string(c.text), nil +} + +Integer = '0' / NonZeroDigit Digit* { + return strconv.ParseInt(string(c.text), 10, 64) +} + +Duration = ( Number TimeUnit )+ { + return time.ParseDuration(string(c.text)) +} + +On = "on"i { + return KeyOn, nil +} + +Off = "off"i { + return KeyOff, nil +} + +Literal = . { + r, _ := utf8.DecodeRune(c.text) + return &literal{r, KeyPress}, nil +} + +ExprEnd = ">" +ExprStart = "<" +SpecialKey = "bs"i / "del"i / "enter"i / "esc"i / "f10"i / "f11"i / "f12"i + / "f1"i / "f2"i / "f3"i / "f4"i / "f5"i / "f6"i / "f7"i / "f8"i / "f9"i + / "return"i / "tab"i / "up"i / "down"i / "spacebar"i / "insert"i / "home"i + / "end"i / "pageUp"i / "pageDown"i / "leftAlt"i / "leftCtrl"i / "leftShift"i + / "rightAlt"i / "rightCtrl"i / "rightShift"i / "leftSuper"i / "rightSuper"i + / "left"i / "right"i + +NonZeroDigit = [1-9] +Digit = [0-9] +TimeUnit = ("ns" / "us" / "µs" / "ms" / "s" / "m" / "h") + +_ "whitespace" <- [ \n\t\r]* + +EOF <- !. diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go new file mode 100644 index 000000000..fe235f96e --- /dev/null +++ b/common/boot_command/boot_command_ast.go @@ -0,0 +1,130 @@ +package bootcommand + +import ( + "context" + "fmt" + "log" + "strings" + "time" +) + +/* +TODO: + * tests + * comments +*/ + +// Keys actions can take 3 states +// we either want to +// * press the key once +// * press and hold +// * press and release + +type KeyAction int + +const ( + KeyOn KeyAction = iota + KeyOff + KeyPress +) + +func onOffToAction(t string) KeyAction { + if strings.EqualFold(t, "on") { + return KeyOn + } else if strings.EqualFold(t, "off") { + return KeyOff + } + panic(fmt.Sprintf("Unknown state '%s'. Expecting On or Off.", t)) +} + +func (k KeyAction) String() string { + switch k { + case KeyOn: + return "On" + case KeyOff: + return "Off" + case KeyPress: + return "Press" + } + panic(fmt.Sprintf("Unknwon KeyAction %d", k)) +} + +// BCDriver is our access to the VM we want to type boot commands to +type BCDriver interface { + SendKey(key rune, action KeyAction) error + SendSpecial(special string, action KeyAction) error +} + +type expression interface { + Do(context.Context, BCDriver) error +} + +type expressionSequence []expression + +func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { + for _, exp := range s { + if err := exp.Do(ctx, b); err != nil { + return err + } + } + return nil +} + +func GenerateExpressionSequence(command string) (expressionSequence, error) { + got, err := ParseReader("", strings.NewReader(command)) + if err != nil { + return nil, err + } + if got == nil { + return nil, fmt.Errorf("No expressions found.") + } + seq := expressionSequence{} + for _, exp := range got.([]interface{}) { + seq = append(seq, exp.(expression)) + } + return seq, nil +} + +type waitExpression struct { + d time.Duration +} + +func (w *waitExpression) Do(ctx context.Context, _ BCDriver) error { + log.Printf("[INFO] Waiting %s", w.d) + select { + case <-time.After(w.d): + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (w *waitExpression) String() string { + return fmt.Sprintf("Wait<%s>", w.d) +} + +type specialExpression struct { + s string + action KeyAction +} + +func (s *specialExpression) Do(ctx context.Context, driver BCDriver) error { + return driver.SendSpecial(s.s, s.action) +} + +func (s *specialExpression) String() string { + return fmt.Sprintf("Spec-%s(%s)", s.action, s.s) +} + +type literal struct { + s rune + action KeyAction +} + +func (l *literal) Do(ctx context.Context, driver BCDriver) error { + return driver.SendKey(l.s, l.action) +} + +func (l *literal) String() string { + return fmt.Sprintf("LIT-%s(%s)", l.action, string(l.s)) +} diff --git a/common/boot_command/boot_command_ast_test.go b/common/boot_command/boot_command_ast_test.go new file mode 100644 index 000000000..3b4ad7568 --- /dev/null +++ b/common/boot_command/boot_command_ast_test.go @@ -0,0 +1,30 @@ +package bootcommand + +import ( + "log" + "strings" + "testing" +) + +func toIfaceSlice(v interface{}) []interface{} { + if v == nil { + return nil + } + return v.([]interface{}) +} + +func TestParse(t *testing.T) { + in := "<wait><wait20><wait3s><wait4m2ns>" + in += "foo/bar > one 界" + in += "<fOn> b<fOff>" + in += "<f3><f12><spacebar><leftalt><rightshift><rightsuper>" + got, err := ParseReader("", strings.NewReader(in)) + if err != nil { + log.Fatal(err) + } + gL := toIfaceSlice(got) + for _, g := range gL { + log.Printf("%s\n", g) + } + +} diff --git a/common/boot_command/gen.go b/common/boot_command/gen.go new file mode 100644 index 000000000..c5796e65e --- /dev/null +++ b/common/boot_command/gen.go @@ -0,0 +1,3 @@ +package bootcommand + +//go:generate pigeon -o boot_command.go boot_command.pigeon diff --git a/common/boot_command/vnc_driver.go b/common/boot_command/vnc_driver.go new file mode 100644 index 000000000..728582968 --- /dev/null +++ b/common/boot_command/vnc_driver.go @@ -0,0 +1,135 @@ +package bootcommand + +import ( + "log" + "os" + "strings" + "time" + "unicode" + + "github.com/hashicorp/packer/common" + vnc "github.com/mitchellh/go-vnc" +) + +const shiftedChars = "~!@#$%^&*()_+{}|:\"<>?" +const KeyLeftShift uint32 = 0xFFE1 + +func NewVNCDriver(c *vnc.ClientConn) *bcDriver { + // We delay (default 100ms) between each key event to allow for CPU or + // network latency. See PackerKeyEnv for tuning. + keyInterval := common.PackerKeyDefault + if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil { + keyInterval = delay + } + + // Scancodes reference: https://github.com/qemu/qemu/blob/master/ui/vnc_keysym.h + sMap := make(map[string]uint32) + sMap["bs"] = 0xFF08 + sMap["del"] = 0xFFFF + sMap["enter"] = 0xFF0D + sMap["esc"] = 0xFF1B + sMap["f1"] = 0xFFBE + sMap["f2"] = 0xFFBF + sMap["f3"] = 0xFFC0 + sMap["f4"] = 0xFFC1 + sMap["f5"] = 0xFFC2 + sMap["f6"] = 0xFFC3 + sMap["f7"] = 0xFFC4 + sMap["f8"] = 0xFFC5 + sMap["f9"] = 0xFFC6 + sMap["f10"] = 0xFFC7 + sMap["f11"] = 0xFFC8 + sMap["f12"] = 0xFFC9 + sMap["return"] = 0xFF0D + sMap["tab"] = 0xFF09 + sMap["up"] = 0xFF52 + sMap["down"] = 0xFF54 + sMap["left"] = 0xFF51 + sMap["right"] = 0xFF53 + sMap["spacebar"] = 0x020 + sMap["insert"] = 0xFF63 + sMap["home"] = 0xFF50 + sMap["end"] = 0xFF57 + sMap["pageUp"] = 0xFF55 + sMap["pageDown"] = 0xFF56 + sMap["leftAlt"] = 0xFFE9 + sMap["leftCtrl"] = 0xFFE3 + sMap["leftShift"] = 0xFFE1 + sMap["rightAlt"] = 0xFFEA + sMap["rightCtrl"] = 0xFFE4 + sMap["rightShift"] = 0xFFE2 + sMap["leftSuper"] = 0xFFEB + sMap["rightSuper"] = 0xFFEC + + return &bcDriver{ + c: c, + interval: keyInterval, + specialMap: sMap, + } +} + +type bcDriver struct { + c *vnc.ClientConn + interval time.Duration + specialMap map[string]uint32 + // keyEvent can set this error which will prevent it from continuing + err error +} + +func (d *bcDriver) keyEvent(k uint32, down bool) error { + if d.err != nil { + return nil + } + if err := d.c.KeyEvent(k, down); err != nil { + d.err = err + return err + } + time.Sleep(d.interval) + return nil +} + +func (d *bcDriver) SendKey(key rune, action KeyAction) error { + keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) + keyCode := uint32(key) + log.Printf("Sending char '%c', code 0x%X, shift %v", key, keyCode, keyShift) + + switch action { + case KeyOn: + if keyShift { + d.keyEvent(KeyLeftShift, true) + } + d.keyEvent(keyCode, true) + case KeyOff: + if keyShift { + d.keyEvent(KeyLeftShift, false) + } + d.keyEvent(keyCode, false) + case KeyPress: + if keyShift { + d.keyEvent(KeyLeftShift, true) + } + d.keyEvent(keyCode, true) + d.keyEvent(keyCode, false) + if keyShift { + d.keyEvent(KeyLeftShift, false) + } + } + return d.err +} + +func (d *bcDriver) SendSpecial(special string, action KeyAction) error { + keyCode := d.specialMap[special] + log.Printf("Special code '<%s>' found, replacing with: 0x%X", special, keyCode) + + switch action { + case KeyOn: + d.keyEvent(keyCode, true) + case KeyOff: + d.keyEvent(keyCode, false) + case KeyPress: + d.keyEvent(keyCode, true) + d.keyEvent(keyCode, false) + } + + return d.err +} diff --git a/main.go b/main.go index 26a1a541d..daa8ce590 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ // This is the main package for the `packer` application. //go:generate go run ./scripts/generate-plugins.go +//go:generate go generate ./common/boot_command/... package main import ( From 4e2f14196a5cd354b6ce45432059e86bc63468db Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 11:48:36 -0700 Subject: [PATCH 0934/1007] Rely on context to cancel typing boot command. --- builder/vmware/common/step_type_boot_command.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 7b4c8ee8f..c3b95b668 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -129,12 +129,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return multistep.ActionHalt } - // Check for interrupts between typing things so we can cancel - // since this isn't the fastest thing. - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - if pauseFn != nil { pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) } From 1c0af28662825079af131e047fd24b7a4299738d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 11:34:21 -0700 Subject: [PATCH 0935/1007] Some cleanup and comments. --- .../vmware/common/step_type_boot_command.go | 1 - common/boot_command/boot_command.go | 834 +++++++++++++----- common/boot_command/boot_command.pigeon | 17 - common/boot_command/boot_command_ast.go | 9 +- common/boot_command/boot_command_ast_test.go | 2 +- 5 files changed, 628 insertions(+), 235 deletions(-) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index c3b95b668..ca46b5d88 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -147,7 +147,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) ui.Error(err.Error()) return multistep.ActionHalt } - } return multistep.ActionContinue diff --git a/common/boot_command/boot_command.go b/common/boot_command/boot_command.go index 0a38932d9..1ecd23fe0 100644 --- a/common/boot_command/boot_command.go +++ b/common/boot_command/boot_command.go @@ -6,7 +6,9 @@ import ( "fmt" "io" "io/ioutil" + "math" "os" + "sort" "strconv" "strings" "time" @@ -14,41 +16,27 @@ import ( "unicode/utf8" ) -/* -func main() { - in := "<wait><wait10><wait1s><wait1m2ns>" - in += "foo/bar > one" - in += "<fOn> b<fOff>" - in += "<f3><f12><spacebar><leftalt><rightshift><rightsuper>" - got, err := ParseReader("", strings.NewReader(in)) - if err != nil { - log.Fatal(err) - } - fmt.Printf("%s\n", got) -} -*/ - var g = &grammar{ rules: []*rule{ { name: "Input", - pos: position{line: 21, col: 1, offset: 345}, + pos: position{line: 6, col: 1, offset: 26}, expr: &actionExpr{ - pos: position{line: 21, col: 10, offset: 354}, + pos: position{line: 6, col: 10, offset: 35}, run: (*parser).callonInput1, expr: &seqExpr{ - pos: position{line: 21, col: 10, offset: 354}, + pos: position{line: 6, col: 10, offset: 35}, exprs: []interface{}{ &labeledExpr{ - pos: position{line: 21, col: 10, offset: 354}, + pos: position{line: 6, col: 10, offset: 35}, label: "expr", expr: &ruleRefExpr{ - pos: position{line: 21, col: 15, offset: 359}, + pos: position{line: 6, col: 15, offset: 40}, name: "Expr", }, }, &ruleRefExpr{ - pos: position{line: 21, col: 20, offset: 364}, + pos: position{line: 6, col: 20, offset: 45}, name: "EOF", }, }, @@ -57,32 +45,32 @@ var g = &grammar{ }, { name: "Expr", - pos: position{line: 25, col: 1, offset: 394}, + pos: position{line: 10, col: 1, offset: 75}, expr: &actionExpr{ - pos: position{line: 25, col: 9, offset: 402}, + pos: position{line: 10, col: 9, offset: 83}, run: (*parser).callonExpr1, expr: &labeledExpr{ - pos: position{line: 25, col: 9, offset: 402}, + pos: position{line: 10, col: 9, offset: 83}, label: "l", expr: &oneOrMoreExpr{ - pos: position{line: 25, col: 11, offset: 404}, + pos: position{line: 10, col: 11, offset: 85}, expr: &choiceExpr{ - pos: position{line: 25, col: 13, offset: 406}, + pos: position{line: 10, col: 13, offset: 87}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 25, col: 13, offset: 406}, + pos: position{line: 10, col: 13, offset: 87}, name: "Wait", }, &ruleRefExpr{ - pos: position{line: 25, col: 20, offset: 413}, + pos: position{line: 10, col: 20, offset: 94}, name: "CharToggle", }, &ruleRefExpr{ - pos: position{line: 25, col: 33, offset: 426}, + pos: position{line: 10, col: 33, offset: 107}, name: "Special", }, &ruleRefExpr{ - pos: position{line: 25, col: 43, offset: 436}, + pos: position{line: 10, col: 43, offset: 117}, name: "Literal", }, }, @@ -93,36 +81,36 @@ var g = &grammar{ }, { name: "Wait", - pos: position{line: 29, col: 1, offset: 469}, + pos: position{line: 14, col: 1, offset: 150}, expr: &actionExpr{ - pos: position{line: 29, col: 8, offset: 476}, + pos: position{line: 14, col: 8, offset: 157}, run: (*parser).callonWait1, expr: &seqExpr{ - pos: position{line: 29, col: 8, offset: 476}, + pos: position{line: 14, col: 8, offset: 157}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 29, col: 8, offset: 476}, + pos: position{line: 14, col: 8, offset: 157}, name: "ExprStart", }, &litMatcher{ - pos: position{line: 29, col: 18, offset: 486}, + pos: position{line: 14, col: 18, offset: 167}, val: "wait", ignoreCase: false, }, &labeledExpr{ - pos: position{line: 29, col: 25, offset: 493}, + pos: position{line: 14, col: 25, offset: 174}, label: "duration", expr: &zeroOrOneExpr{ - pos: position{line: 29, col: 34, offset: 502}, + pos: position{line: 14, col: 34, offset: 183}, expr: &choiceExpr{ - pos: position{line: 29, col: 36, offset: 504}, + pos: position{line: 14, col: 36, offset: 185}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 29, col: 36, offset: 504}, + pos: position{line: 14, col: 36, offset: 185}, name: "Duration", }, &ruleRefExpr{ - pos: position{line: 29, col: 47, offset: 515}, + pos: position{line: 14, col: 47, offset: 196}, name: "Integer", }, }, @@ -130,7 +118,7 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 29, col: 58, offset: 526}, + pos: position{line: 14, col: 58, offset: 207}, name: "ExprEnd", }, }, @@ -139,44 +127,44 @@ var g = &grammar{ }, { name: "CharToggle", - pos: position{line: 42, col: 1, offset: 772}, + pos: position{line: 27, col: 1, offset: 453}, expr: &actionExpr{ - pos: position{line: 42, col: 14, offset: 785}, + pos: position{line: 27, col: 14, offset: 466}, run: (*parser).callonCharToggle1, expr: &seqExpr{ - pos: position{line: 42, col: 14, offset: 785}, + pos: position{line: 27, col: 14, offset: 466}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 42, col: 14, offset: 785}, + pos: position{line: 27, col: 14, offset: 466}, name: "ExprStart", }, &labeledExpr{ - pos: position{line: 42, col: 24, offset: 795}, + pos: position{line: 27, col: 24, offset: 476}, label: "lit", expr: &ruleRefExpr{ - pos: position{line: 42, col: 29, offset: 800}, + pos: position{line: 27, col: 29, offset: 481}, name: "Literal", }, }, &labeledExpr{ - pos: position{line: 42, col: 38, offset: 809}, + pos: position{line: 27, col: 38, offset: 490}, label: "t", expr: &choiceExpr{ - pos: position{line: 42, col: 41, offset: 812}, + pos: position{line: 27, col: 41, offset: 493}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 42, col: 41, offset: 812}, + pos: position{line: 27, col: 41, offset: 493}, name: "On", }, &ruleRefExpr{ - pos: position{line: 42, col: 46, offset: 817}, + pos: position{line: 27, col: 46, offset: 498}, name: "Off", }, }, }, }, &ruleRefExpr{ - pos: position{line: 42, col: 51, offset: 822}, + pos: position{line: 27, col: 51, offset: 503}, name: "ExprEnd", }, }, @@ -185,39 +173,39 @@ var g = &grammar{ }, { name: "Special", - pos: position{line: 46, col: 1, offset: 893}, + pos: position{line: 31, col: 1, offset: 574}, expr: &actionExpr{ - pos: position{line: 46, col: 11, offset: 903}, + pos: position{line: 31, col: 11, offset: 584}, run: (*parser).callonSpecial1, expr: &seqExpr{ - pos: position{line: 46, col: 11, offset: 903}, + pos: position{line: 31, col: 11, offset: 584}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 46, col: 11, offset: 903}, + pos: position{line: 31, col: 11, offset: 584}, name: "ExprStart", }, &labeledExpr{ - pos: position{line: 46, col: 21, offset: 913}, + pos: position{line: 31, col: 21, offset: 594}, label: "s", expr: &ruleRefExpr{ - pos: position{line: 46, col: 24, offset: 916}, + pos: position{line: 31, col: 24, offset: 597}, name: "SpecialKey", }, }, &labeledExpr{ - pos: position{line: 46, col: 36, offset: 928}, + pos: position{line: 31, col: 36, offset: 609}, label: "t", expr: &zeroOrOneExpr{ - pos: position{line: 46, col: 38, offset: 930}, + pos: position{line: 31, col: 38, offset: 611}, expr: &choiceExpr{ - pos: position{line: 46, col: 39, offset: 931}, + pos: position{line: 31, col: 39, offset: 612}, alternatives: []interface{}{ &ruleRefExpr{ - pos: position{line: 46, col: 39, offset: 931}, + pos: position{line: 31, col: 39, offset: 612}, name: "On", }, &ruleRefExpr{ - pos: position{line: 46, col: 44, offset: 936}, + pos: position{line: 31, col: 44, offset: 617}, name: "Off", }, }, @@ -225,7 +213,7 @@ var g = &grammar{ }, }, &ruleRefExpr{ - pos: position{line: 46, col: 50, offset: 942}, + pos: position{line: 31, col: 50, offset: 623}, name: "ExprEnd", }, }, @@ -234,39 +222,39 @@ var g = &grammar{ }, { name: "Number", - pos: position{line: 55, col: 1, offset: 1211}, + pos: position{line: 38, col: 1, offset: 799}, expr: &actionExpr{ - pos: position{line: 55, col: 10, offset: 1220}, + pos: position{line: 38, col: 10, offset: 808}, run: (*parser).callonNumber1, expr: &seqExpr{ - pos: position{line: 55, col: 10, offset: 1220}, + pos: position{line: 38, col: 10, offset: 808}, exprs: []interface{}{ &zeroOrOneExpr{ - pos: position{line: 55, col: 10, offset: 1220}, + pos: position{line: 38, col: 10, offset: 808}, expr: &litMatcher{ - pos: position{line: 55, col: 10, offset: 1220}, + pos: position{line: 38, col: 10, offset: 808}, val: "-", ignoreCase: false, }, }, &ruleRefExpr{ - pos: position{line: 55, col: 15, offset: 1225}, + pos: position{line: 38, col: 15, offset: 813}, name: "Integer", }, &zeroOrOneExpr{ - pos: position{line: 55, col: 23, offset: 1233}, + pos: position{line: 38, col: 23, offset: 821}, expr: &seqExpr{ - pos: position{line: 55, col: 25, offset: 1235}, + pos: position{line: 38, col: 25, offset: 823}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 55, col: 25, offset: 1235}, + pos: position{line: 38, col: 25, offset: 823}, val: ".", ignoreCase: false, }, &oneOrMoreExpr{ - pos: position{line: 55, col: 29, offset: 1239}, + pos: position{line: 38, col: 29, offset: 827}, expr: &ruleRefExpr{ - pos: position{line: 55, col: 29, offset: 1239}, + pos: position{line: 38, col: 29, offset: 827}, name: "Digit", }, }, @@ -279,29 +267,29 @@ var g = &grammar{ }, { name: "Integer", - pos: position{line: 59, col: 1, offset: 1285}, + pos: position{line: 42, col: 1, offset: 873}, expr: &choiceExpr{ - pos: position{line: 59, col: 11, offset: 1295}, + pos: position{line: 42, col: 11, offset: 883}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 59, col: 11, offset: 1295}, + pos: position{line: 42, col: 11, offset: 883}, val: "0", ignoreCase: false, }, &actionExpr{ - pos: position{line: 59, col: 17, offset: 1301}, + pos: position{line: 42, col: 17, offset: 889}, run: (*parser).callonInteger3, expr: &seqExpr{ - pos: position{line: 59, col: 17, offset: 1301}, + pos: position{line: 42, col: 17, offset: 889}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 59, col: 17, offset: 1301}, + pos: position{line: 42, col: 17, offset: 889}, name: "NonZeroDigit", }, &zeroOrMoreExpr{ - pos: position{line: 59, col: 30, offset: 1314}, + pos: position{line: 42, col: 30, offset: 902}, expr: &ruleRefExpr{ - pos: position{line: 59, col: 30, offset: 1314}, + pos: position{line: 42, col: 30, offset: 902}, name: "Digit", }, }, @@ -313,21 +301,21 @@ var g = &grammar{ }, { name: "Duration", - pos: position{line: 63, col: 1, offset: 1378}, + pos: position{line: 46, col: 1, offset: 966}, expr: &actionExpr{ - pos: position{line: 63, col: 12, offset: 1389}, + pos: position{line: 46, col: 12, offset: 977}, run: (*parser).callonDuration1, expr: &oneOrMoreExpr{ - pos: position{line: 63, col: 12, offset: 1389}, + pos: position{line: 46, col: 12, offset: 977}, expr: &seqExpr{ - pos: position{line: 63, col: 14, offset: 1391}, + pos: position{line: 46, col: 14, offset: 979}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 63, col: 14, offset: 1391}, + pos: position{line: 46, col: 14, offset: 979}, name: "Number", }, &ruleRefExpr{ - pos: position{line: 63, col: 21, offset: 1398}, + pos: position{line: 46, col: 21, offset: 986}, name: "TimeUnit", }, }, @@ -337,12 +325,12 @@ var g = &grammar{ }, { name: "On", - pos: position{line: 67, col: 1, offset: 1461}, + pos: position{line: 50, col: 1, offset: 1049}, expr: &actionExpr{ - pos: position{line: 67, col: 6, offset: 1466}, + pos: position{line: 50, col: 6, offset: 1054}, run: (*parser).callonOn1, expr: &litMatcher{ - pos: position{line: 67, col: 6, offset: 1466}, + pos: position{line: 50, col: 6, offset: 1054}, val: "on", ignoreCase: true, }, @@ -350,12 +338,12 @@ var g = &grammar{ }, { name: "Off", - pos: position{line: 71, col: 1, offset: 1499}, + pos: position{line: 54, col: 1, offset: 1087}, expr: &actionExpr{ - pos: position{line: 71, col: 7, offset: 1505}, + pos: position{line: 54, col: 7, offset: 1093}, run: (*parser).callonOff1, expr: &litMatcher{ - pos: position{line: 71, col: 7, offset: 1505}, + pos: position{line: 54, col: 7, offset: 1093}, val: "off", ignoreCase: true, }, @@ -363,216 +351,216 @@ var g = &grammar{ }, { name: "Literal", - pos: position{line: 75, col: 1, offset: 1540}, + pos: position{line: 58, col: 1, offset: 1128}, expr: &actionExpr{ - pos: position{line: 75, col: 11, offset: 1550}, + pos: position{line: 58, col: 11, offset: 1138}, run: (*parser).callonLiteral1, expr: &anyMatcher{ - line: 75, col: 11, offset: 1550, + line: 58, col: 11, offset: 1138, }, }, }, { name: "ExprEnd", - pos: position{line: 80, col: 1, offset: 1631}, + pos: position{line: 63, col: 1, offset: 1219}, expr: &litMatcher{ - pos: position{line: 80, col: 11, offset: 1641}, + pos: position{line: 63, col: 11, offset: 1229}, val: ">", ignoreCase: false, }, }, { name: "ExprStart", - pos: position{line: 81, col: 1, offset: 1645}, + pos: position{line: 64, col: 1, offset: 1233}, expr: &litMatcher{ - pos: position{line: 81, col: 13, offset: 1657}, + pos: position{line: 64, col: 13, offset: 1245}, val: "<", ignoreCase: false, }, }, { name: "SpecialKey", - pos: position{line: 82, col: 1, offset: 1661}, + pos: position{line: 65, col: 1, offset: 1249}, expr: &choiceExpr{ - pos: position{line: 82, col: 14, offset: 1674}, + pos: position{line: 65, col: 14, offset: 1262}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 82, col: 14, offset: 1674}, + pos: position{line: 65, col: 14, offset: 1262}, val: "bs", ignoreCase: true, }, &litMatcher{ - pos: position{line: 82, col: 22, offset: 1682}, + pos: position{line: 65, col: 22, offset: 1270}, val: "del", ignoreCase: true, }, &litMatcher{ - pos: position{line: 82, col: 31, offset: 1691}, + pos: position{line: 65, col: 31, offset: 1279}, val: "enter", ignoreCase: true, }, &litMatcher{ - pos: position{line: 82, col: 42, offset: 1702}, + pos: position{line: 65, col: 42, offset: 1290}, val: "esc", ignoreCase: true, }, &litMatcher{ - pos: position{line: 82, col: 51, offset: 1711}, + pos: position{line: 65, col: 51, offset: 1299}, val: "f10", ignoreCase: true, }, &litMatcher{ - pos: position{line: 82, col: 60, offset: 1720}, + pos: position{line: 65, col: 60, offset: 1308}, val: "f11", ignoreCase: true, }, &litMatcher{ - pos: position{line: 82, col: 69, offset: 1729}, + pos: position{line: 65, col: 69, offset: 1317}, val: "f12", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 11, offset: 1746}, + pos: position{line: 66, col: 11, offset: 1334}, val: "f1", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 19, offset: 1754}, + pos: position{line: 66, col: 19, offset: 1342}, val: "f2", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 27, offset: 1762}, + pos: position{line: 66, col: 27, offset: 1350}, val: "f3", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 35, offset: 1770}, + pos: position{line: 66, col: 35, offset: 1358}, val: "f4", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 43, offset: 1778}, + pos: position{line: 66, col: 43, offset: 1366}, val: "f5", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 51, offset: 1786}, + pos: position{line: 66, col: 51, offset: 1374}, val: "f6", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 59, offset: 1794}, + pos: position{line: 66, col: 59, offset: 1382}, val: "f7", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 67, offset: 1802}, + pos: position{line: 66, col: 67, offset: 1390}, val: "f8", ignoreCase: true, }, &litMatcher{ - pos: position{line: 83, col: 75, offset: 1810}, + pos: position{line: 66, col: 75, offset: 1398}, val: "f9", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 12, offset: 1827}, + pos: position{line: 67, col: 12, offset: 1415}, val: "return", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 24, offset: 1839}, + pos: position{line: 67, col: 24, offset: 1427}, val: "tab", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 33, offset: 1848}, + pos: position{line: 67, col: 33, offset: 1436}, val: "up", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 41, offset: 1856}, + pos: position{line: 67, col: 41, offset: 1444}, val: "down", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 51, offset: 1866}, + pos: position{line: 67, col: 51, offset: 1454}, val: "spacebar", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 65, offset: 1880}, + pos: position{line: 67, col: 65, offset: 1468}, val: "insert", ignoreCase: true, }, &litMatcher{ - pos: position{line: 84, col: 77, offset: 1892}, + pos: position{line: 67, col: 77, offset: 1480}, val: "home", ignoreCase: true, }, &litMatcher{ - pos: position{line: 85, col: 11, offset: 1910}, + pos: position{line: 68, col: 11, offset: 1498}, val: "end", ignoreCase: true, }, &litMatcher{ - pos: position{line: 85, col: 20, offset: 1919}, + pos: position{line: 68, col: 20, offset: 1507}, val: "pageup", ignoreCase: true, }, &litMatcher{ - pos: position{line: 85, col: 32, offset: 1931}, + pos: position{line: 68, col: 32, offset: 1519}, val: "pagedown", ignoreCase: true, }, &litMatcher{ - pos: position{line: 85, col: 46, offset: 1945}, + pos: position{line: 68, col: 46, offset: 1533}, val: "leftalt", ignoreCase: true, }, &litMatcher{ - pos: position{line: 85, col: 59, offset: 1958}, + pos: position{line: 68, col: 59, offset: 1546}, val: "leftctrl", ignoreCase: true, }, &litMatcher{ - pos: position{line: 85, col: 73, offset: 1972}, + pos: position{line: 68, col: 73, offset: 1560}, val: "leftshift", ignoreCase: true, }, &litMatcher{ - pos: position{line: 86, col: 11, offset: 1995}, + pos: position{line: 69, col: 11, offset: 1583}, val: "rightalt", ignoreCase: true, }, &litMatcher{ - pos: position{line: 86, col: 25, offset: 2009}, + pos: position{line: 69, col: 25, offset: 1597}, val: "rightctrl", ignoreCase: true, }, &litMatcher{ - pos: position{line: 86, col: 40, offset: 2024}, + pos: position{line: 69, col: 40, offset: 1612}, val: "rightshift", ignoreCase: true, }, &litMatcher{ - pos: position{line: 86, col: 56, offset: 2040}, + pos: position{line: 69, col: 56, offset: 1628}, val: "leftsuper", ignoreCase: true, }, &litMatcher{ - pos: position{line: 86, col: 71, offset: 2055}, + pos: position{line: 69, col: 71, offset: 1643}, val: "rightsuper", ignoreCase: true, }, &litMatcher{ - pos: position{line: 87, col: 11, offset: 2079}, + pos: position{line: 70, col: 11, offset: 1667}, val: "left", ignoreCase: true, }, &litMatcher{ - pos: position{line: 87, col: 21, offset: 2089}, + pos: position{line: 70, col: 21, offset: 1677}, val: "right", ignoreCase: true, }, @@ -581,9 +569,9 @@ var g = &grammar{ }, { name: "NonZeroDigit", - pos: position{line: 89, col: 1, offset: 2099}, + pos: position{line: 72, col: 1, offset: 1687}, expr: &charClassMatcher{ - pos: position{line: 89, col: 16, offset: 2114}, + pos: position{line: 72, col: 16, offset: 1702}, val: "[1-9]", ranges: []rune{'1', '9'}, ignoreCase: false, @@ -592,9 +580,9 @@ var g = &grammar{ }, { name: "Digit", - pos: position{line: 90, col: 1, offset: 2120}, + pos: position{line: 73, col: 1, offset: 1708}, expr: &charClassMatcher{ - pos: position{line: 90, col: 9, offset: 2128}, + pos: position{line: 73, col: 9, offset: 1716}, val: "[0-9]", ranges: []rune{'0', '9'}, ignoreCase: false, @@ -603,42 +591,42 @@ var g = &grammar{ }, { name: "TimeUnit", - pos: position{line: 91, col: 1, offset: 2134}, + pos: position{line: 74, col: 1, offset: 1722}, expr: &choiceExpr{ - pos: position{line: 91, col: 13, offset: 2146}, + pos: position{line: 74, col: 13, offset: 1734}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 91, col: 13, offset: 2146}, + pos: position{line: 74, col: 13, offset: 1734}, val: "ns", ignoreCase: false, }, &litMatcher{ - pos: position{line: 91, col: 20, offset: 2153}, + pos: position{line: 74, col: 20, offset: 1741}, val: "us", ignoreCase: false, }, &litMatcher{ - pos: position{line: 91, col: 27, offset: 2160}, + pos: position{line: 74, col: 27, offset: 1748}, val: "µs", ignoreCase: false, }, &litMatcher{ - pos: position{line: 91, col: 34, offset: 2168}, + pos: position{line: 74, col: 34, offset: 1756}, val: "ms", ignoreCase: false, }, &litMatcher{ - pos: position{line: 91, col: 41, offset: 2175}, + pos: position{line: 74, col: 41, offset: 1763}, val: "s", ignoreCase: false, }, &litMatcher{ - pos: position{line: 91, col: 47, offset: 2181}, + pos: position{line: 74, col: 47, offset: 1769}, val: "m", ignoreCase: false, }, &litMatcher{ - pos: position{line: 91, col: 53, offset: 2187}, + pos: position{line: 74, col: 53, offset: 1775}, val: "h", ignoreCase: false, }, @@ -648,11 +636,11 @@ var g = &grammar{ { name: "_", displayName: "\"whitespace\"", - pos: position{line: 93, col: 1, offset: 2193}, + pos: position{line: 76, col: 1, offset: 1781}, expr: &zeroOrMoreExpr{ - pos: position{line: 93, col: 19, offset: 2211}, + pos: position{line: 76, col: 19, offset: 1799}, expr: &charClassMatcher{ - pos: position{line: 93, col: 19, offset: 2211}, + pos: position{line: 76, col: 19, offset: 1799}, val: "[ \\n\\t\\r]", chars: []rune{' ', '\n', '\t', '\r'}, ignoreCase: false, @@ -662,11 +650,11 @@ var g = &grammar{ }, { name: "EOF", - pos: position{line: 95, col: 1, offset: 2223}, + pos: position{line: 78, col: 1, offset: 1811}, expr: &notExpr{ - pos: position{line: 95, col: 8, offset: 2230}, + pos: position{line: 78, col: 8, offset: 1818}, expr: &anyMatcher{ - line: 95, col: 9, offset: 2231, + line: 78, col: 9, offset: 1819, }, }, }, @@ -724,11 +712,9 @@ func (p *parser) callonCharToggle1() (interface{}, error) { func (c *current) onSpecial1(s, t interface{}) (interface{}, error) { if t == nil { - //return fmt.Sprintf("S(%s)", s), nil return &specialExpression{string(s.([]byte)), KeyPress}, nil } return &specialExpression{string(s.([]byte)), t.(KeyAction)}, nil - //return fmt.Sprintf("S%s(%s)", t, s), nil } func (p *parser) callonSpecial1() (interface{}, error) { @@ -802,18 +788,85 @@ var ( // errNoRule is returned when the grammar to parse has no rule. errNoRule = errors.New("grammar has no rule") + // errInvalidEntrypoint is returned when the specified entrypoint rule + // does not exit. + errInvalidEntrypoint = errors.New("invalid entrypoint") + // errInvalidEncoding is returned when the source is not properly // utf8-encoded. errInvalidEncoding = errors.New("invalid encoding") - // errNoMatch is returned if no match could be found. - errNoMatch = errors.New("no match found") + // errMaxExprCnt is used to signal that the maximum number of + // expressions have been parsed. + errMaxExprCnt = errors.New("max number of expresssions parsed") ) // Option is a function that can set an option on the parser. It returns // the previous setting as an Option. type Option func(*parser) Option +// MaxExpressions creates an Option to stop parsing after the provided +// number of expressions have been parsed, if the value is 0 then the parser will +// parse for as many steps as needed (possibly an infinite number). +// +// The default for maxExprCnt is 0. +func MaxExpressions(maxExprCnt uint64) Option { + return func(p *parser) Option { + oldMaxExprCnt := p.maxExprCnt + p.maxExprCnt = maxExprCnt + return MaxExpressions(oldMaxExprCnt) + } +} + +// Entrypoint creates an Option to set the rule name to use as entrypoint. +// The rule name must have been specified in the -alternate-entrypoints +// if generating the parser with the -optimize-grammar flag, otherwise +// it may have been optimized out. Passing an empty string sets the +// entrypoint to the first rule in the grammar. +// +// The default is to start parsing at the first rule in the grammar. +func Entrypoint(ruleName string) Option { + return func(p *parser) Option { + oldEntrypoint := p.entrypoint + p.entrypoint = ruleName + if ruleName == "" { + p.entrypoint = g.rules[0].name + } + return Entrypoint(oldEntrypoint) + } +} + +// Statistics adds a user provided Stats struct to the parser to allow +// the user to process the results after the parsing has finished. +// Also the key for the "no match" counter is set. +// +// Example usage: +// +// input := "input" +// stats := Stats{} +// _, err := Parse("input-file", []byte(input), Statistics(&stats, "no match")) +// if err != nil { +// log.Panicln(err) +// } +// b, err := json.MarshalIndent(stats.ChoiceAltCnt, "", " ") +// if err != nil { +// log.Panicln(err) +// } +// fmt.Println(string(b)) +// +func Statistics(stats *Stats, choiceNoMatch string) Option { + return func(p *parser) Option { + oldStats := p.Stats + p.Stats = stats + oldChoiceNoMatch := p.choiceNoMatch + p.choiceNoMatch = choiceNoMatch + if p.Stats.ChoiceAltCnt == nil { + p.Stats.ChoiceAltCnt = make(map[string]map[string]int) + } + return Statistics(oldStats, oldChoiceNoMatch) + } +} + // Debug creates an Option to set the debug flag to b. When set to true, // debugging information is printed to stdout while parsing. // @@ -840,6 +893,20 @@ func Memoize(b bool) Option { } } +// AllowInvalidUTF8 creates an Option to allow invalid UTF-8 bytes. +// Every invalid UTF-8 byte is treated as a utf8.RuneError (U+FFFD) +// by character class matchers and is matched by the any matcher. +// The returned matched value, c.text and c.offset are NOT affected. +// +// The default is false. +func AllowInvalidUTF8(b bool) Option { + return func(p *parser) Option { + old := p.allowInvalidUTF8 + p.allowInvalidUTF8 = b + return AllowInvalidUTF8(old) + } +} + // Recover creates an Option to set the recover flag to b. When set to // true, this causes the parser to recover from panics and convert it // to an error. Setting it to false can be useful while debugging to @@ -854,13 +921,37 @@ func Recover(b bool) Option { } } +// GlobalStore creates an Option to set a key to a certain value in +// the globalStore. +func GlobalStore(key string, value interface{}) Option { + return func(p *parser) Option { + old := p.cur.globalStore[key] + p.cur.globalStore[key] = value + return GlobalStore(key, old) + } +} + +// InitState creates an Option to set a key to a certain value in +// the global "state" store. +func InitState(key string, value interface{}) Option { + return func(p *parser) Option { + old := p.cur.state[key] + p.cur.state[key] = value + return InitState(key, old) + } +} + // ParseFile parses the file identified by filename. -func ParseFile(filename string, opts ...Option) (interface{}, error) { +func ParseFile(filename string, opts ...Option) (i interface{}, err error) { f, err := os.Open(filename) if err != nil { return nil, err } - defer f.Close() + defer func() { + if closeErr := f.Close(); closeErr != nil { + err = closeErr + } + }() return ParseReader(filename, f, opts...) } @@ -901,8 +992,22 @@ type savepoint struct { type current struct { pos position // start position of the match text []byte // raw text of the match + + // state is a store for arbitrary key,value pairs that the user wants to be + // tied to the backtracking of the parser. + // This is always rolled back if a parsing rule fails. + state storeDict + + // globalStore is a general store for the user to store arbitrary key-value + // pairs that they need to manage and that they do not want tied to the + // backtracking of the parser. This is only modified by the user and never + // rolled back by the parser. It is always up to the user to keep this in a + // consistent state. + globalStore storeDict } +type storeDict map[string]interface{} + // the AST types... type grammar struct { @@ -928,11 +1033,23 @@ type actionExpr struct { run func(*parser) (interface{}, error) } +type recoveryExpr struct { + pos position + expr interface{} + recoverExpr interface{} + failureLabel []string +} + type seqExpr struct { pos position exprs []interface{} } +type throwExpr struct { + pos position + label string +} + type labeledExpr struct { pos position label string @@ -955,6 +1072,11 @@ type ruleRefExpr struct { name string } +type stateCodeExpr struct { + pos position + run func(*parser) error +} + type andCodeExpr struct { pos position run func(*parser) (bool, error) @@ -972,13 +1094,14 @@ type litMatcher struct { } type charClassMatcher struct { - pos position - val string - chars []rune - ranges []rune - classes []*unicode.RangeTable - ignoreCase bool - inverted bool + pos position + val string + basicLatinChars [128]bool + chars []rune + ranges []rune + classes []*unicode.RangeTable + ignoreCase bool + inverted bool } type anyMatcher position @@ -1032,9 +1155,10 @@ func (e errList) Error() string { // parserError wraps an error with a prefix indicating the rule in which // the error occurred. The original error is stored in the Inner field. type parserError struct { - Inner error - pos position - prefix string + Inner error + pos position + prefix string + expected []string } // Error returns the error message. @@ -1044,14 +1168,33 @@ func (p *parserError) Error() string { // newParser creates a parser with the specified input source and options. func newParser(filename string, b []byte, opts ...Option) *parser { + stats := Stats{ + ChoiceAltCnt: make(map[string]map[string]int), + } + p := &parser{ filename: filename, errs: new(errList), data: b, pt: savepoint{position: position{line: 1}}, recover: true, + cur: current{ + state: make(storeDict), + globalStore: make(storeDict), + }, + maxFailPos: position{col: 1, line: 1}, + maxFailExpected: make([]string, 0, 20), + Stats: &stats, + // start rule is rule [0] unless an alternate entrypoint is specified + entrypoint: g.rules[0].name, + emptyState: make(storeDict), } p.setOptions(opts) + + if p.maxExprCnt == 0 { + p.maxExprCnt = math.MaxUint64 + } + return p } @@ -1068,6 +1211,30 @@ type resultTuple struct { end savepoint } +const choiceNoMatch = -1 + +// Stats stores some statistics, gathered during parsing +type Stats struct { + // ExprCnt counts the number of expressions processed during parsing + // This value is compared to the maximum number of expressions allowed + // (set by the MaxExpressions option). + ExprCnt uint64 + + // ChoiceAltCnt is used to count for each ordered choice expression, + // which alternative is used how may times. + // These numbers allow to optimize the order of the ordered choice expression + // to increase the performance of the parser + // + // The outer key of ChoiceAltCnt is composed of the name of the rule as well + // as the line and the column of the ordered choice. + // The inner key of ChoiceAltCnt is the number (one-based) of the matching alternative. + // For each alternative the number of matches are counted. If an ordered choice does not + // match, a special counter is incremented. The name of this counter is set with + // the parser option Statistics. + // For an alternative to be included in ChoiceAltCnt, it has to match at least once. + ChoiceAltCnt map[string]map[string]int +} + type parser struct { filename string pt savepoint @@ -1076,9 +1243,9 @@ type parser struct { data []byte errs *errList + depth int recover bool debug bool - depth int memoize bool // memoization table for the packrat algorithm: @@ -1092,8 +1259,26 @@ type parser struct { // rule stack, allows identification of the current rule in errors rstack []*rule - // stats - exprCnt int + // parse fail + maxFailPos position + maxFailExpected []string + maxFailInvertExpected bool + + // max number of expressions to be parsed + maxExprCnt uint64 + // entrypoint for the parser + entrypoint string + + allowInvalidUTF8 bool + + *Stats + + choiceNoMatch string + // recovery expression stack, keeps track of the currently available recovery expression, these are traversed in reverse + recoveryStack []map[string]interface{} + + // emptyState contains an empty storeDict, which is used to optimize cloneState if global "state" store is not used. + emptyState storeDict } // push a variable set on the vstack. @@ -1128,6 +1313,31 @@ func (p *parser) popV() { p.vstack = p.vstack[:len(p.vstack)-1] } +// push a recovery expression with its labels to the recoveryStack +func (p *parser) pushRecovery(labels []string, expr interface{}) { + if cap(p.recoveryStack) == len(p.recoveryStack) { + // create new empty slot in the stack + p.recoveryStack = append(p.recoveryStack, nil) + } else { + // slice to 1 more + p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)+1] + } + + m := make(map[string]interface{}, len(labels)) + for _, fl := range labels { + m[fl] = expr + } + p.recoveryStack[len(p.recoveryStack)-1] = m +} + +// pop a recovery expression from the recoveryStack +func (p *parser) popRecovery() { + // GC that map + p.recoveryStack[len(p.recoveryStack)-1] = nil + + p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)-1] +} + func (p *parser) print(prefix, s string) string { if !p.debug { return s @@ -1149,10 +1359,10 @@ func (p *parser) out(s string) string { } func (p *parser) addErr(err error) { - p.addErrAt(err, p.pt.position) + p.addErrAt(err, p.pt.position, []string{}) } -func (p *parser) addErrAt(err error, pos position) { +func (p *parser) addErrAt(err error, pos position, expected []string) { var buf bytes.Buffer if p.filename != "" { buf.WriteString(p.filename) @@ -1172,10 +1382,29 @@ func (p *parser) addErrAt(err error, pos position) { buf.WriteString("rule " + rule.name) } } - pe := &parserError{Inner: err, pos: pos, prefix: buf.String()} + pe := &parserError{Inner: err, pos: pos, prefix: buf.String(), expected: expected} p.errs.add(pe) } +func (p *parser) failAt(fail bool, pos position, want string) { + // process fail if parsing fails and not inverted or parsing succeeds and invert is set + if fail == p.maxFailInvertExpected { + if pos.offset < p.maxFailPos.offset { + return + } + + if pos.offset > p.maxFailPos.offset { + p.maxFailPos = pos + p.maxFailExpected = p.maxFailExpected[:0] + } + + if p.maxFailInvertExpected { + want = "!" + want + } + p.maxFailExpected = append(p.maxFailExpected, want) + } +} + // read advances the parser to the next rune. func (p *parser) read() { p.pt.offset += p.pt.w @@ -1188,8 +1417,8 @@ func (p *parser) read() { p.pt.col = 0 } - if rn == utf8.RuneError { - if n == 1 { + if rn == utf8.RuneError && n == 1 { // see utf8.DecodeRune + if !p.allowInvalidUTF8 { p.addErr(errInvalidEncoding) } } @@ -1206,6 +1435,50 @@ func (p *parser) restore(pt savepoint) { p.pt = pt } +// Cloner is implemented by any value that has a Clone method, which returns a +// copy of the value. This is mainly used for types which are not passed by +// value (e.g map, slice, chan) or structs that contain such types. +// +// This is used in conjunction with the global state feature to create proper +// copies of the state to allow the parser to properly restore the state in +// the case of backtracking. +type Cloner interface { + Clone() interface{} +} + +// clone and return parser current state. +func (p *parser) cloneState() storeDict { + if p.debug { + defer p.out(p.in("cloneState")) + } + + if len(p.cur.state) == 0 { + if len(p.emptyState) > 0 { + p.emptyState = make(storeDict) + } + return p.emptyState + } + + state := make(storeDict, len(p.cur.state)) + for k, v := range p.cur.state { + if c, ok := v.(Cloner); ok { + state[k] = c.Clone() + } else { + state[k] = v + } + } + return state +} + +// restore parser current state to the state storeDict. +// every restoreState should applied only one time for every cloned state +func (p *parser) restoreState(state storeDict) { + if p.debug { + defer p.out(p.in("restoreState")) + } + p.cur.state = state +} + // get the slice of bytes from the savepoint start to the current position. func (p *parser) sliceFrom(start savepoint) []byte { return p.data[start.position.offset:p.pt.position.offset] @@ -1271,19 +1544,54 @@ func (p *parser) parse(g *grammar) (val interface{}, err error) { }() } - // start rule is rule [0] + startRule, ok := p.rules[p.entrypoint] + if !ok { + p.addErr(errInvalidEntrypoint) + return nil, p.errs.err() + } + p.read() // advance to first rune - val, ok := p.parseRule(g.rules[0]) + val, ok = p.parseRule(startRule) if !ok { if len(*p.errs) == 0 { - // make sure this doesn't go out silently - p.addErr(errNoMatch) + // If parsing fails, but no errors have been recorded, the expected values + // for the farthest parser position are returned as error. + maxFailExpectedMap := make(map[string]struct{}, len(p.maxFailExpected)) + for _, v := range p.maxFailExpected { + maxFailExpectedMap[v] = struct{}{} + } + expected := make([]string, 0, len(maxFailExpectedMap)) + eof := false + if _, ok := maxFailExpectedMap["!."]; ok { + delete(maxFailExpectedMap, "!.") + eof = true + } + for k := range maxFailExpectedMap { + expected = append(expected, k) + } + sort.Strings(expected) + if eof { + expected = append(expected, "EOF") + } + p.addErrAt(errors.New("no match found, expected: "+listJoin(expected, ", ", "or")), p.maxFailPos, expected) } + return nil, p.errs.err() } return val, p.errs.err() } +func listJoin(list []string, sep string, lastSep string) string { + switch len(list) { + case 0: + return "" + case 1: + return list[0] + default: + return fmt.Sprintf("%s %s %s", strings.Join(list[:len(list)-1], sep), lastSep, list[len(list)-1]) + } +} + func (p *parser) parseRule(rule *rule) (interface{}, bool) { if p.debug { defer p.out(p.in("parseRule " + rule.name)) @@ -1315,7 +1623,6 @@ func (p *parser) parseRule(rule *rule) (interface{}, bool) { func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { var pt savepoint - var ok bool if p.memoize { res, ok := p.getMemoized(expr) @@ -1326,8 +1633,13 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { pt = p.pt } - p.exprCnt++ + p.ExprCnt++ + if p.ExprCnt > p.maxExprCnt { + panic(errMaxExprCnt) + } + var val interface{} + var ok bool switch expr := expr.(type) { case *actionExpr: val, ok = p.parseActionExpr(expr) @@ -1351,10 +1663,16 @@ func (p *parser) parseExpr(expr interface{}) (interface{}, bool) { val, ok = p.parseNotExpr(expr) case *oneOrMoreExpr: val, ok = p.parseOneOrMoreExpr(expr) + case *recoveryExpr: + val, ok = p.parseRecoveryExpr(expr) case *ruleRefExpr: val, ok = p.parseRuleRefExpr(expr) case *seqExpr: val, ok = p.parseSeqExpr(expr) + case *stateCodeExpr: + val, ok = p.parseStateCodeExpr(expr) + case *throwExpr: + val, ok = p.parseThrowExpr(expr) case *zeroOrMoreExpr: val, ok = p.parseZeroOrMoreExpr(expr) case *zeroOrOneExpr: @@ -1378,10 +1696,13 @@ func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) { if ok { p.cur.pos = start.position p.cur.text = p.sliceFrom(start) + state := p.cloneState() actVal, err := act.run(p) if err != nil { - p.addErrAt(err, start.position) + p.addErrAt(err, start.position, []string{}) } + p.restoreState(state) + val = actVal } if ok && p.debug { @@ -1395,10 +1716,14 @@ func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) { defer p.out(p.in("parseAndCodeExpr")) } + state := p.cloneState() + ok, err := and.run(p) if err != nil { p.addErr(err) } + p.restoreState(state) + return nil, ok } @@ -1408,10 +1733,13 @@ func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) { } pt := p.pt + state := p.cloneState() p.pushV() _, ok := p.parseExpr(and.expr) p.popV() + p.restoreState(state) p.restore(pt) + return nil, ok } @@ -1420,12 +1748,15 @@ func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) { defer p.out(p.in("parseAnyMatcher")) } - if p.pt.rn != utf8.RuneError { - start := p.pt - p.read() - return p.sliceFrom(start), true + if p.pt.rn == utf8.RuneError && p.pt.w == 0 { + // EOF - see utf8.DecodeRune + p.failAt(false, p.pt.position, ".") + return nil, false } - return nil, false + start := p.pt + p.read() + p.failAt(true, start.position, ".") + return p.sliceFrom(start), true } func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) { @@ -1434,11 +1765,14 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool } cur := p.pt.rn + start := p.pt + // can't match EOF - if cur == utf8.RuneError { + if cur == utf8.RuneError && p.pt.w == 0 { // see utf8.DecodeRune + p.failAt(false, start.position, chr.val) return nil, false } - start := p.pt + if chr.ignoreCase { cur = unicode.ToLower(cur) } @@ -1447,9 +1781,11 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for _, rn := range chr.chars { if rn == cur { if chr.inverted { + p.failAt(false, start.position, chr.val) return nil, false } p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } @@ -1458,9 +1794,11 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for i := 0; i < len(chr.ranges); i += 2 { if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] { if chr.inverted { + p.failAt(false, start.position, chr.val) return nil, false } p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } @@ -1469,33 +1807,60 @@ func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool for _, cl := range chr.classes { if unicode.Is(cl, cur) { if chr.inverted { + p.failAt(false, start.position, chr.val) return nil, false } p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } } if chr.inverted { p.read() + p.failAt(true, start.position, chr.val) return p.sliceFrom(start), true } + p.failAt(false, start.position, chr.val) return nil, false } +func (p *parser) incChoiceAltCnt(ch *choiceExpr, altI int) { + choiceIdent := fmt.Sprintf("%s %d:%d", p.rstack[len(p.rstack)-1].name, ch.pos.line, ch.pos.col) + m := p.ChoiceAltCnt[choiceIdent] + if m == nil { + m = make(map[string]int) + p.ChoiceAltCnt[choiceIdent] = m + } + // We increment altI by 1, so the keys do not start at 0 + alt := strconv.Itoa(altI + 1) + if altI == choiceNoMatch { + alt = p.choiceNoMatch + } + m[alt]++ +} + func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseChoiceExpr")) } - for _, alt := range ch.alternatives { + for altI, alt := range ch.alternatives { + // dummy assignment to prevent compile error if optimized + _ = altI + + state := p.cloneState() + p.pushV() val, ok := p.parseExpr(alt) p.popV() if ok { + p.incChoiceAltCnt(ch, altI) return val, ok } + p.restoreState(state) } + p.incChoiceAltCnt(ch, choiceNoMatch) return nil, false } @@ -1519,6 +1884,11 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { defer p.out(p.in("parseLitMatcher")) } + ignoreCase := "" + if lit.ignoreCase { + ignoreCase = "i" + } + val := fmt.Sprintf("%q%s", lit.val, ignoreCase) start := p.pt for _, want := range lit.val { cur := p.pt.rn @@ -1526,11 +1896,13 @@ func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) { cur = unicode.ToLower(cur) } if cur != want { + p.failAt(false, start.position, val) p.restore(start) return nil, false } p.read() } + p.failAt(true, start.position, val) return p.sliceFrom(start), true } @@ -1539,10 +1911,14 @@ func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) { defer p.out(p.in("parseNotCodeExpr")) } + state := p.cloneState() + ok, err := not.run(p) if err != nil { p.addErr(err) } + p.restoreState(state) + return nil, !ok } @@ -1552,10 +1928,15 @@ func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) { } pt := p.pt + state := p.cloneState() p.pushV() + p.maxFailInvertExpected = !p.maxFailInvertExpected _, ok := p.parseExpr(not.expr) + p.maxFailInvertExpected = !p.maxFailInvertExpected p.popV() + p.restoreState(state) p.restore(pt) + return nil, !ok } @@ -1581,6 +1962,18 @@ func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) { } } +func (p *parser) parseRecoveryExpr(recover *recoveryExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseRecoveryExpr (" + strings.Join(recover.failureLabel, ",") + ")")) + } + + p.pushRecovery(recover.failureLabel, recover.recoverExpr) + val, ok := p.parseExpr(recover.expr) + p.popRecovery() + + return val, ok +} + func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseRuleRefExpr " + ref.name)) @@ -1603,12 +1996,14 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { defer p.out(p.in("parseSeqExpr")) } - var vals []interface{} + vals := make([]interface{}, 0, len(seq.exprs)) pt := p.pt + state := p.cloneState() for _, expr := range seq.exprs { val, ok := p.parseExpr(expr) if !ok { + p.restoreState(state) p.restore(pt) return nil, false } @@ -1617,6 +2012,34 @@ func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) { return vals, true } +func (p *parser) parseStateCodeExpr(state *stateCodeExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseStateCodeExpr")) + } + + err := state.run(p) + if err != nil { + p.addErr(err) + } + return nil, true +} + +func (p *parser) parseThrowExpr(expr *throwExpr) (interface{}, bool) { + if p.debug { + defer p.out(p.in("parseThrowExpr")) + } + + for i := len(p.recoveryStack) - 1; i >= 0; i-- { + if recoverExpr, ok := p.recoveryStack[i][expr.label]; ok { + if val, ok := p.parseExpr(recoverExpr); ok { + return val, ok + } + } + } + + return nil, false +} + func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) { if p.debug { defer p.out(p.in("parseZeroOrMoreExpr")) @@ -1646,18 +2069,3 @@ func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) { // whether it matched or not, consider it a match return val, true } - -func rangeTable(class string) *unicode.RangeTable { - if rt, ok := unicode.Categories[class]; ok { - return rt - } - if rt, ok := unicode.Properties[class]; ok { - return rt - } - if rt, ok := unicode.Scripts[class]; ok { - return rt - } - - // cannot happen - panic(fmt.Sprintf("invalid Unicode class: %s", class)) -} diff --git a/common/boot_command/boot_command.pigeon b/common/boot_command/boot_command.pigeon index a496bb552..ac1297010 100644 --- a/common/boot_command/boot_command.pigeon +++ b/common/boot_command/boot_command.pigeon @@ -1,21 +1,6 @@ { package bootcommand - - -/* -func main() { - in := "<wait><wait10><wait1s><wait1m2ns>" - in += "foo/bar > one" - in += "<fOn> b<fOff>" - in += "<f3><f12><spacebar><leftalt><rightshift><rightsuper>" - got, err := ParseReader("", strings.NewReader(in)) - if err != nil { - log.Fatal(err) - } - fmt.Printf("%s\n", got) -} -*/ } Input <- expr:Expr EOF { @@ -45,11 +30,9 @@ CharToggle = ExprStart lit:(Literal) t:(On / Off) ExprEnd { Special = ExprStart s:(SpecialKey) t:(On / Off)? ExprEnd { if t == nil { - //return fmt.Sprintf("S(%s)", s), nil return &specialExpression{string(s.([]byte)), KeyPress}, nil } return &specialExpression{string(s.([]byte)), t.(KeyAction)}, nil - //return fmt.Sprintf("S%s(%s)", t, s), nil } Number = '-'? Integer ( '.' Digit+ )? { diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index fe235f96e..2bff8dc6c 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -12,14 +12,15 @@ import ( TODO: * tests * comments + * lower-case specials + * check that `<del>` works on parallels. It's different now. */ -// Keys actions can take 3 states -// we either want to +// KeysAction represents what we want to do with a key press. +// It can take 3 states. We either want to: // * press the key once // * press and hold // * press and release - type KeyAction int const ( @@ -70,6 +71,8 @@ func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { return nil } +// GenerateExpressionSequence generates a sequence of expressions from the +// given command. func GenerateExpressionSequence(command string) (expressionSequence, error) { got, err := ParseReader("", strings.NewReader(command)) if err != nil { diff --git a/common/boot_command/boot_command_ast_test.go b/common/boot_command/boot_command_ast_test.go index 3b4ad7568..a568e1a4e 100644 --- a/common/boot_command/boot_command_ast_test.go +++ b/common/boot_command/boot_command_ast_test.go @@ -17,7 +17,7 @@ func TestParse(t *testing.T) { in := "<wait><wait20><wait3s><wait4m2ns>" in += "foo/bar > one 界" in += "<fOn> b<fOff>" - in += "<f3><f12><spacebar><leftalt><rightshift><rightsuper>" + in += "<foo><f3><f12><spacebar><leftalt><rightshift><rightsuper>" got, err := ParseReader("", strings.NewReader(in)) if err != nil { log.Fatal(err) From e4af71858fecbf10d6c58ce0ce7e252ecc1d5ecc Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 14:42:53 -0700 Subject: [PATCH 0936/1007] Implement new parser for Virtualbox boot command Remove boot wait for virtualbox run step --- builder/virtualbox/common/step_run.go | 18 - .../common/step_type_boot_command.go | 407 ++++++------------ .../common/step_type_boot_command_test.go | 6 +- builder/virtualbox/iso/builder.go | 2 +- builder/virtualbox/ovf/builder.go | 2 +- common/boot_command/boot_command_ast.go | 2 +- common/boot_command/vnc_driver.go | 6 +- 7 files changed, 137 insertions(+), 306 deletions(-) diff --git a/builder/virtualbox/common/step_run.go b/builder/virtualbox/common/step_run.go index 62d98d894..689b58602 100644 --- a/builder/virtualbox/common/step_run.go +++ b/builder/virtualbox/common/step_run.go @@ -3,7 +3,6 @@ package common import ( "context" "fmt" - "time" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -18,7 +17,6 @@ import ( // // Produces: type StepRun struct { - BootWait time.Duration Headless bool vmName string @@ -60,22 +58,6 @@ func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste s.vmName = vmName - if int64(s.BootWait) > 0 { - ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait)) - wait := time.After(s.BootWait) - WAITLOOP: - for { - select { - case <-wait: - break WAITLOOP - case <-time.After(1 * time.Second): - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - } - } - } - return multistep.ActionContinue } diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index d0c86e22d..e5c76d224 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -4,13 +4,13 @@ import ( "context" "fmt" "log" - "regexp" "strings" "time" "unicode" "unicode/utf8" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -36,17 +36,29 @@ type bootCommandTemplateData struct { // <nothing> type StepTypeBootCommand struct { BootCommand []string + BootWait time.Duration VMName string Ctx interpolate.Context } -func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { debug := state.Get("debug").(bool) driver := state.Get("driver").(Driver) httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) + // Wait the for the vm to boot. + if int64(s.BootWait) > 0 { + ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String())) + select { + case <-time.After(s.BootWait): + break + case <-ctx.Done(): + return multistep.ActionHalt + } + } + var pauseFn multistep.DebugPauseFn if debug { pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn) @@ -60,6 +72,11 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m s.VMName, } + d := &VBoxBCDriver{ + driver, + vmName, + } + ui.Say("Typing the boot command...") for i, command := range s.BootCommand { command, err := interpolate.Render(command, &s.Ctx) @@ -70,44 +87,23 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - for _, code := range scancodes(command) { - if code == "wait" { - time.Sleep(1 * time.Second) - continue - } + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if code == "wait5" { - time.Sleep(5 * time.Second) - continue - } - - if code == "wait10" { - time.Sleep(10 * time.Second) - continue - } - - // Since typing is sometimes so slow, we check for an interrupt - // in between each character. - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - - var codes []string - - // split string into a list of 2-char pairs - for i := 0; i < len(code)/2; i++ { - codes = append(codes, code[i*2:i*2+2]) - } - - args := []string{"controlvm", vmName, "keyboardputscancode"} - args = append(args, codes...) - - if err := driver.VBoxManage(args...); err != nil { - err := fmt.Errorf("Error sending boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + // This executes vboxmanage once for each character code. This seems + // fine for now, but changes the prior behavior. If this becomes + // a problem, we can always have the driver cache scancodes, and then + // add a `Flush` method which we can call after this. + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } if pauseFn != nil { @@ -121,53 +117,22 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} -func scancodes(message string) []string { - // Scancodes reference: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html - // - // Scancodes represent raw keyboard output and are fed to the VM by the - // VBoxManage controlvm keyboardputscancode program. - // - // Scancodes are recorded here in pairs. The first entry represents - // the key press and the second entry represents the key release and is - // derived from the first by the addition of 0x80. - special := make(map[string][]string) - special["<bs>"] = []string{"0e", "8e"} - special["<del>"] = []string{"e053", "e0d3"} - special["<enter>"] = []string{"1c", "9c"} - special["<esc>"] = []string{"01", "81"} - special["<f1>"] = []string{"3b", "bb"} - special["<f2>"] = []string{"3c", "bc"} - special["<f3>"] = []string{"3d", "bd"} - special["<f4>"] = []string{"3e", "be"} - special["<f5>"] = []string{"3f", "bf"} - special["<f6>"] = []string{"40", "c0"} - special["<f7>"] = []string{"41", "c1"} - special["<f8>"] = []string{"42", "c2"} - special["<f9>"] = []string{"43", "c3"} - special["<f10>"] = []string{"44", "c4"} - special["<f11>"] = []string{"57", "d7"} - special["<f12>"] = []string{"58", "d8"} - special["<return>"] = []string{"1c", "9c"} - special["<tab>"] = []string{"0f", "8f"} - special["<up>"] = []string{"e048", "e0c8"} - special["<down>"] = []string{"e050", "e0d0"} - special["<left>"] = []string{"e04b", "e0cb"} - special["<right>"] = []string{"e04d", "e0cd"} - special["<spacebar>"] = []string{"39", "b9"} - special["<insert>"] = []string{"e052", "e0d2"} - special["<home>"] = []string{"e047", "e0c7"} - special["<end>"] = []string{"e04f", "e0cf"} - special["<pageUp>"] = []string{"e049", "e0c9"} - special["<pageDown>"] = []string{"e051", "e0d1"} - special["<leftAlt>"] = []string{"38", "b8"} - special["<leftCtrl>"] = []string{"1d", "9d"} - special["<leftShift>"] = []string{"2a", "aa"} - special["<rightAlt>"] = []string{"e038", "e0b8"} - special["<rightCtrl>"] = []string{"e01d", "e09d"} - special["<rightShift>"] = []string{"36", "b6"} - special["<leftSuper>"] = []string{"e05b", "e0db"} - special["<rightSuper>"] = []string{"e05c", "e0dc"} +type VBoxBCDriver struct { + driver Driver + vmName string +} +func (d *VBoxBCDriver) sendCode(codes []string) error { + args := []string{"controlvm", d.vmName, "keyboardputscancode"} + args = append(args, codes...) + + if err := d.driver.VBoxManage(args...); err != nil { + return err + } + return nil + +} +func (d *VBoxBCDriver) SendKey(key rune, action bootcommand.KeyAction) error { shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" scancodeIndex := make(map[string]uint) @@ -192,205 +157,87 @@ func scancodes(message string) []string { } } - azOnRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])On>") - azOffRegex := regexp.MustCompile("^<(?P<ordinary>[a-zA-Z])Off>") + keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) - result := make([]string, 0, len(message)*2) - for len(message) > 0 { - var scancode []string + var scancode []string - if azOnRegex.MatchString(message) { - m := azOnRegex.FindStringSubmatch(message) - r, _ := utf8.DecodeRuneInString(m[1]) - message = message[len("<aOn>"):] - scancodeInt := scancodeMap[r] - keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - if keyShift { - scancode = append(scancode, "2a") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - - log.Printf("Sending char '%c', code '%v', shift %v", r, scancodeInt, keyShift) - } - - if azOffRegex.MatchString(message) { - m := azOffRegex.FindStringSubmatch(message) - r, _ := utf8.DecodeRuneInString(m[1]) - message = message[len("<aOff>"):] - scancodeInt := scancodeMap[r] + 0x80 - keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - if keyShift { - scancode = append(scancode, "aa") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - - log.Printf("Sending char '%c', code '%v', shift %v", r, scancodeInt, keyShift) - } - - if strings.HasPrefix(message, "<f12On>") { - scancode = append(scancode, "58") - message = message[len("<f12On>"):] - log.Printf("Special code '<f12On>', replacing with: 58") - } - - if strings.HasPrefix(message, "<leftAltOn>") { - scancode = append(scancode, "38") - message = message[len("<leftAltOn>"):] - log.Printf("Special code '<leftAltOn>' found, replacing with: 38") - } - - if strings.HasPrefix(message, "<leftCtrlOn>") { - scancode = append(scancode, "1d") - message = message[len("<leftCtrlOn>"):] - log.Printf("Special code '<leftCtrlOn>' found, replacing with: 1d") - } - - if strings.HasPrefix(message, "<leftShiftOn>") { + if action&(bootcommand.KeyOn|bootcommand.KeyPress) != 0 { + scancodeInt := scancodeMap[key] + if keyShift { scancode = append(scancode, "2a") - message = message[len("<leftShiftOn>"):] - log.Printf("Special code '<leftShiftOn>' found, replacing with: 2a") } - - if strings.HasPrefix(message, "<leftSuperOn>") { - scancode = append(scancode, "e05b") - message = message[len("<leftSuperOn>"):] - log.Printf("Special code '<leftSuperOn>' found, replacing with: e05b") - } - - if strings.HasPrefix(message, "<f12Off>") { - scancode = append(scancode, "d8") - message = message[len("<f12Off>"):] - log.Printf("Special code '<f12Off>' found, replacing with: d8") - } - - if strings.HasPrefix(message, "<leftAltOff>") { - scancode = append(scancode, "b8") - message = message[len("<leftAltOff>"):] - log.Printf("Special code '<leftAltOff>' found, replacing with: b8") - } - - if strings.HasPrefix(message, "<leftCtrlOff>") { - scancode = append(scancode, "9d") - message = message[len("<leftCtrlOff>"):] - log.Printf("Special code '<leftCtrlOff>' found, replacing with: 9d") - } - - if strings.HasPrefix(message, "<leftShiftOff>") { - scancode = append(scancode, "aa") - message = message[len("<leftShiftOff>"):] - log.Printf("Special code '<leftShiftOff>' found, replacing with: aa") - } - - if strings.HasPrefix(message, "<leftSuperOff>") { - scancode = append(scancode, "e0db") - message = message[len("<leftSuperOff>"):] - log.Printf("Special code '<leftSuperOff>' found, replacing with: e0db") - } - - if strings.HasPrefix(message, "<rightAltOn>") { - scancode = append(scancode, "e038") - message = message[len("<rightAltOn>"):] - log.Printf("Special code '<rightAltOn>' found, replacing with: e038") - } - - if strings.HasPrefix(message, "<rightCtrlOn>") { - scancode = append(scancode, "e01d") - message = message[len("<rightCtrlOn>"):] - log.Printf("Special code '<rightCtrlOn>' found, replacing with: e01d") - } - - if strings.HasPrefix(message, "<rightShiftOn>") { - scancode = append(scancode, "36") - message = message[len("<rightShiftOn>"):] - log.Printf("Special code '<rightShiftOn>' found, replacing with: 36") - } - - if strings.HasPrefix(message, "<rightSuperOn>") { - scancode = append(scancode, "e05c") - message = message[len("<rightSuperOn>"):] - log.Printf("Special code '<rightSuperOn>' found, replacing with: e05c") - } - - if strings.HasPrefix(message, "<rightAltOff>") { - scancode = append(scancode, "e0b8") - message = message[len("<rightAltOff>"):] - log.Printf("Special code '<rightAltOff>' found, replacing with: e0b8") - } - - if strings.HasPrefix(message, "<rightCtrlOff>") { - scancode = append(scancode, "e09d") - message = message[len("<rightCtrlOff>"):] - log.Printf("Special code '<rightCtrlOff>' found, replacing with: e09d") - } - - if strings.HasPrefix(message, "<rightShiftOff>") { - scancode = append(scancode, "b6") - message = message[len("<rightShiftOff>"):] - log.Printf("Special code '<rightShiftOff>' found, replacing with: b6") - } - - if strings.HasPrefix(message, "<rightSuperOff>") { - scancode = append(scancode, "e0dc") - message = message[len("<rightSuperOff>"):] - log.Printf("Special code '<rightSuperOff>' found, replacing with: e0dc") - } - - if strings.HasPrefix(message, "<wait>") { - log.Printf("Special code <wait> found, will sleep 1 second at this point.") - scancode = append(scancode, "wait") - message = message[len("<wait>"):] - } - - if strings.HasPrefix(message, "<wait5>") { - log.Printf("Special code <wait5> found, will sleep 5 seconds at this point.") - scancode = append(scancode, "wait5") - message = message[len("<wait5>"):] - } - - if strings.HasPrefix(message, "<wait10>") { - log.Printf("Special code <wait10> found, will sleep 10 seconds at this point.") - scancode = append(scancode, "wait10") - message = message[len("<wait10>"):] - } - - if scancode == nil { - for specialCode, specialValue := range special { - if strings.HasPrefix(message, specialCode) { - log.Printf("Special code '%s' found, replacing with: %s", specialCode, specialValue) - scancode = append(scancode, specialValue...) - message = message[len(specialCode):] - break - } - } - } - - if scancode == nil { - r, size := utf8.DecodeRuneInString(message) - message = message[size:] - scancodeInt := scancodeMap[r] - keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - scancode = make([]string, 0, 4) - if keyShift { - scancode = append(scancode, "2a") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - - if keyShift { - scancode = append(scancode, "aa") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt+0x80)) - log.Printf("Sending char '%c', code '%v', shift %v", r, scancode, keyShift) - } - - result = append(result, scancode...) + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) } - return result + if action&(bootcommand.KeyOff|bootcommand.KeyPress) != 0 { + scancodeInt := scancodeMap[key] + 0x80 + if keyShift { + scancode = append(scancode, "aa") + } + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + } + + for _, sc := range scancode { + log.Printf("Sending char '%c', code '%s', shift %v", key, sc, keyShift) + } + + d.sendCode(scancode) + + return nil +} + +func (d *VBoxBCDriver) SendSpecial(special string, action bootcommand.KeyAction) error { + // special contains on/off tuples + sMap := make(map[string][]string) + sMap["bs"] = []string{"0e", "8e"} + sMap["del"] = []string{"e053", "e0d3"} + sMap["enter"] = []string{"1c", "9c"} + sMap["esc"] = []string{"01", "81"} + sMap["f1"] = []string{"3b", "bb"} + sMap["f2"] = []string{"3c", "bc"} + sMap["f3"] = []string{"3d", "bd"} + sMap["f4"] = []string{"3e", "be"} + sMap["f5"] = []string{"3f", "bf"} + sMap["f6"] = []string{"40", "c0"} + sMap["f7"] = []string{"41", "c1"} + sMap["f8"] = []string{"42", "c2"} + sMap["f9"] = []string{"43", "c3"} + sMap["f10"] = []string{"44", "c4"} + sMap["f11"] = []string{"57", "d7"} + sMap["f12"] = []string{"58", "d8"} + sMap["return"] = []string{"1c", "9c"} + sMap["tab"] = []string{"0f", "8f"} + sMap["up"] = []string{"e048", "e0c8"} + sMap["down"] = []string{"e050", "e0d0"} + sMap["left"] = []string{"e04b", "e0cb"} + sMap["right"] = []string{"e04d", "e0cd"} + sMap["spacebar"] = []string{"39", "b9"} + sMap["insert"] = []string{"e052", "e0d2"} + sMap["home"] = []string{"e047", "e0c7"} + sMap["end"] = []string{"e04f", "e0cf"} + sMap["pageUp"] = []string{"e049", "e0c9"} + sMap["pageDown"] = []string{"e051", "e0d1"} + sMap["leftAlt"] = []string{"38", "b8"} + sMap["leftCtrl"] = []string{"1d", "9d"} + sMap["leftShift"] = []string{"2a", "aa"} + sMap["rightAlt"] = []string{"e038", "e0b8"} + sMap["rightCtrl"] = []string{"e01d", "e09d"} + sMap["rightShift"] = []string{"36", "b6"} + sMap["leftSuper"] = []string{"e05b", "e0db"} + sMap["rightSuper"] = []string{"e05c", "e0dc"} + + keyCode, ok := sMap[special] + if !ok { + return fmt.Errorf("special %s not found.", special) + } + + switch action { + case bootcommand.KeyOn: + d.sendCode([]string{keyCode[0]}) + case bootcommand.KeyOff: + d.sendCode([]string{keyCode[1]}) + case bootcommand.KeyPress: + d.sendCode(keyCode) + } + return nil } diff --git a/builder/virtualbox/common/step_type_boot_command_test.go b/builder/virtualbox/common/step_type_boot_command_test.go index 23a5d9077..7d4291530 100644 --- a/builder/virtualbox/common/step_type_boot_command_test.go +++ b/builder/virtualbox/common/step_type_boot_command_test.go @@ -1,9 +1,6 @@ package common -import ( - "testing" -) - +/* func TestScancodes(t *testing.T) { var bootcommand = []string{ "1234567890-=<enter><wait>", @@ -41,3 +38,4 @@ func TestScancodes(t *testing.T) { } } } +*/ diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 0d1be21dd..5a53854ae 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -240,10 +240,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &vboxcommon.StepRun{ - BootWait: b.config.BootWait, Headless: b.config.Headless, }, &vboxcommon.StepTypeBootCommand{ + BootWait: b.config.BootWait, BootCommand: b.config.BootCommand, VMName: b.config.VMName, Ctx: b.config.ctx, diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index d9783244f..71921106e 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -103,10 +103,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Ctx: b.config.ctx, }, &vboxcommon.StepRun{ - BootWait: b.config.BootWait, Headless: b.config.Headless, }, &vboxcommon.StepTypeBootCommand{ + BootWait: b.config.BootWait, BootCommand: b.config.BootCommand, VMName: b.config.VMName, Ctx: b.config.ctx, diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 2bff8dc6c..ecd3acf8b 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -24,7 +24,7 @@ TODO: type KeyAction int const ( - KeyOn KeyAction = iota + KeyOn KeyAction = 1 << iota KeyOff KeyPress ) diff --git a/common/boot_command/vnc_driver.go b/common/boot_command/vnc_driver.go index 728582968..fbcb7a257 100644 --- a/common/boot_command/vnc_driver.go +++ b/common/boot_command/vnc_driver.go @@ -1,6 +1,7 @@ package bootcommand import ( + "fmt" "log" "os" "strings" @@ -118,7 +119,10 @@ func (d *bcDriver) SendKey(key rune, action KeyAction) error { } func (d *bcDriver) SendSpecial(special string, action KeyAction) error { - keyCode := d.specialMap[special] + keyCode, ok := d.specialMap[special] + if !ok { + return fmt.Errorf("special %s not found.", special) + } log.Printf("Special code '<%s>' found, replacing with: 0x%X", special, keyCode) switch action { From 99d61920d084907fd765eee58de3f300aa9fa4cc Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 15:59:07 -0700 Subject: [PATCH 0937/1007] Abstract vbox driver into PC-AT driver. --- .../common/step_type_boot_command.go | 141 ++---------------- common/boot_command/boot_command_ast.go | 7 +- common/boot_command/driver.go | 9 ++ common/boot_command/pc_at_driver.go | 134 +++++++++++++++++ common/boot_command/vnc_driver.go | 17 +-- 5 files changed, 161 insertions(+), 147 deletions(-) create mode 100644 common/boot_command/driver.go create mode 100644 common/boot_command/pc_at_driver.go diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index e5c76d224..2af3b8b50 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -3,11 +3,7 @@ package common import ( "context" "fmt" - "log" - "strings" "time" - "unicode" - "unicode/utf8" "github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common/boot_command" @@ -72,10 +68,16 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) s.VMName, } - d := &VBoxBCDriver{ - driver, - vmName, + sendCodes := func(codes []string) error { + args := []string{"controlvm", vmName, "keyboardputscancode"} + args = append(args, codes...) + + if err := driver.VBoxManage(args...); err != nil { + return err + } + return nil } + d := bootcommand.NewPCATDriver(sendCodes) ui.Say("Typing the boot command...") for i, command := range s.BootCommand { @@ -116,128 +118,3 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) } func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} - -type VBoxBCDriver struct { - driver Driver - vmName string -} - -func (d *VBoxBCDriver) sendCode(codes []string) error { - args := []string{"controlvm", d.vmName, "keyboardputscancode"} - args = append(args, codes...) - - if err := d.driver.VBoxManage(args...); err != nil { - return err - } - return nil - -} -func (d *VBoxBCDriver) SendKey(key rune, action bootcommand.KeyAction) error { - shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" - - scancodeIndex := make(map[string]uint) - scancodeIndex["1234567890-="] = 0x02 - scancodeIndex["!@#$%^&*()_+"] = 0x02 - scancodeIndex["qwertyuiop[]"] = 0x10 - scancodeIndex["QWERTYUIOP{}"] = 0x10 - scancodeIndex["asdfghjkl;'`"] = 0x1e - scancodeIndex[`ASDFGHJKL:"~`] = 0x1e - scancodeIndex[`\zxcvbnm,./`] = 0x2b - scancodeIndex["|ZXCVBNM<>?"] = 0x2b - scancodeIndex[" "] = 0x39 - - scancodeMap := make(map[rune]uint) - for chars, start := range scancodeIndex { - var i uint = 0 - for len(chars) > 0 { - r, size := utf8.DecodeRuneInString(chars) - chars = chars[size:] - scancodeMap[r] = start + i - i += 1 - } - } - - keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) - - var scancode []string - - if action&(bootcommand.KeyOn|bootcommand.KeyPress) != 0 { - scancodeInt := scancodeMap[key] - if keyShift { - scancode = append(scancode, "2a") - } - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - } - - if action&(bootcommand.KeyOff|bootcommand.KeyPress) != 0 { - scancodeInt := scancodeMap[key] + 0x80 - if keyShift { - scancode = append(scancode, "aa") - } - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - } - - for _, sc := range scancode { - log.Printf("Sending char '%c', code '%s', shift %v", key, sc, keyShift) - } - - d.sendCode(scancode) - - return nil -} - -func (d *VBoxBCDriver) SendSpecial(special string, action bootcommand.KeyAction) error { - // special contains on/off tuples - sMap := make(map[string][]string) - sMap["bs"] = []string{"0e", "8e"} - sMap["del"] = []string{"e053", "e0d3"} - sMap["enter"] = []string{"1c", "9c"} - sMap["esc"] = []string{"01", "81"} - sMap["f1"] = []string{"3b", "bb"} - sMap["f2"] = []string{"3c", "bc"} - sMap["f3"] = []string{"3d", "bd"} - sMap["f4"] = []string{"3e", "be"} - sMap["f5"] = []string{"3f", "bf"} - sMap["f6"] = []string{"40", "c0"} - sMap["f7"] = []string{"41", "c1"} - sMap["f8"] = []string{"42", "c2"} - sMap["f9"] = []string{"43", "c3"} - sMap["f10"] = []string{"44", "c4"} - sMap["f11"] = []string{"57", "d7"} - sMap["f12"] = []string{"58", "d8"} - sMap["return"] = []string{"1c", "9c"} - sMap["tab"] = []string{"0f", "8f"} - sMap["up"] = []string{"e048", "e0c8"} - sMap["down"] = []string{"e050", "e0d0"} - sMap["left"] = []string{"e04b", "e0cb"} - sMap["right"] = []string{"e04d", "e0cd"} - sMap["spacebar"] = []string{"39", "b9"} - sMap["insert"] = []string{"e052", "e0d2"} - sMap["home"] = []string{"e047", "e0c7"} - sMap["end"] = []string{"e04f", "e0cf"} - sMap["pageUp"] = []string{"e049", "e0c9"} - sMap["pageDown"] = []string{"e051", "e0d1"} - sMap["leftAlt"] = []string{"38", "b8"} - sMap["leftCtrl"] = []string{"1d", "9d"} - sMap["leftShift"] = []string{"2a", "aa"} - sMap["rightAlt"] = []string{"e038", "e0b8"} - sMap["rightCtrl"] = []string{"e01d", "e09d"} - sMap["rightShift"] = []string{"36", "b6"} - sMap["leftSuper"] = []string{"e05b", "e0db"} - sMap["rightSuper"] = []string{"e05c", "e0dc"} - - keyCode, ok := sMap[special] - if !ok { - return fmt.Errorf("special %s not found.", special) - } - - switch action { - case bootcommand.KeyOn: - d.sendCode([]string{keyCode[0]}) - case bootcommand.KeyOff: - d.sendCode([]string{keyCode[1]}) - case bootcommand.KeyPress: - d.sendCode(keyCode) - } - return nil -} diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index ecd3acf8b..cc28aed08 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -11,6 +11,7 @@ import ( /* TODO: * tests + * fix vbox tests * comments * lower-case specials * check that `<del>` works on parallels. It's different now. @@ -50,12 +51,6 @@ func (k KeyAction) String() string { panic(fmt.Sprintf("Unknwon KeyAction %d", k)) } -// BCDriver is our access to the VM we want to type boot commands to -type BCDriver interface { - SendKey(key rune, action KeyAction) error - SendSpecial(special string, action KeyAction) error -} - type expression interface { Do(context.Context, BCDriver) error } diff --git a/common/boot_command/driver.go b/common/boot_command/driver.go new file mode 100644 index 000000000..b9c20710a --- /dev/null +++ b/common/boot_command/driver.go @@ -0,0 +1,9 @@ +package bootcommand + +const shiftedChars = "~!@#$%^&*()_+{}|:\"<>?" + +// BCDriver is our access to the VM we want to type boot commands to +type BCDriver interface { + SendKey(key rune, action KeyAction) error + SendSpecial(special string, action KeyAction) error +} diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go new file mode 100644 index 000000000..51def2932 --- /dev/null +++ b/common/boot_command/pc_at_driver.go @@ -0,0 +1,134 @@ +package bootcommand + +import ( + "fmt" + "log" + "strings" + "unicode" + "unicode/utf8" +) + +type SendCodeFunc func([]string) error + +type pcATDriver struct { + //driver Driver + //vmName string + send SendCodeFunc + specialMap map[string][]string + scancodeMap map[rune]byte +} + +func NewPCATDriver(send SendCodeFunc) *pcATDriver { + // sMap contains on/off tuples + sMap := make(map[string][]string) + sMap["bs"] = []string{"0e", "8e"} + sMap["del"] = []string{"e053", "e0d3"} + sMap["enter"] = []string{"1c", "9c"} + sMap["esc"] = []string{"01", "81"} + sMap["f1"] = []string{"3b", "bb"} + sMap["f2"] = []string{"3c", "bc"} + sMap["f3"] = []string{"3d", "bd"} + sMap["f4"] = []string{"3e", "be"} + sMap["f5"] = []string{"3f", "bf"} + sMap["f6"] = []string{"40", "c0"} + sMap["f7"] = []string{"41", "c1"} + sMap["f8"] = []string{"42", "c2"} + sMap["f9"] = []string{"43", "c3"} + sMap["f10"] = []string{"44", "c4"} + sMap["f11"] = []string{"57", "d7"} + sMap["f12"] = []string{"58", "d8"} + sMap["return"] = []string{"1c", "9c"} + sMap["tab"] = []string{"0f", "8f"} + sMap["up"] = []string{"e048", "e0c8"} + sMap["down"] = []string{"e050", "e0d0"} + sMap["left"] = []string{"e04b", "e0cb"} + sMap["right"] = []string{"e04d", "e0cd"} + sMap["spacebar"] = []string{"39", "b9"} + sMap["insert"] = []string{"e052", "e0d2"} + sMap["home"] = []string{"e047", "e0c7"} + sMap["end"] = []string{"e04f", "e0cf"} + sMap["pageUp"] = []string{"e049", "e0c9"} + sMap["pageDown"] = []string{"e051", "e0d1"} + sMap["leftAlt"] = []string{"38", "b8"} + sMap["leftCtrl"] = []string{"1d", "9d"} + sMap["leftShift"] = []string{"2a", "aa"} + sMap["rightAlt"] = []string{"e038", "e0b8"} + sMap["rightCtrl"] = []string{"e01d", "e09d"} + sMap["rightShift"] = []string{"36", "b6"} + sMap["leftSuper"] = []string{"e05b", "e0db"} + sMap["rightSuper"] = []string{"e05c", "e0dc"} + + scancodeIndex := make(map[string]byte) + scancodeIndex["1234567890-="] = 0x02 + scancodeIndex["!@#$%^&*()_+"] = 0x02 + scancodeIndex["qwertyuiop[]"] = 0x10 + scancodeIndex["QWERTYUIOP{}"] = 0x10 + scancodeIndex["asdfghjkl;'`"] = 0x1e + scancodeIndex[`ASDFGHJKL:"~`] = 0x1e + scancodeIndex[`\zxcvbnm,./`] = 0x2b + scancodeIndex["|ZXCVBNM<>?"] = 0x2b + scancodeIndex[" "] = 0x39 + + scancodeMap := make(map[rune]byte) + for chars, start := range scancodeIndex { + var i byte = 0 + for len(chars) > 0 { + r, size := utf8.DecodeRuneInString(chars) + chars = chars[size:] + scancodeMap[r] = start + i + i += 1 + } + } + + return &pcATDriver{ + send: send, + specialMap: sMap, + scancodeMap: scancodeMap, + } +} + +func (d *pcATDriver) SendKey(key rune, action KeyAction) error { + + keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) + + var scancode []string + + if action&(KeyOn|KeyPress) != 0 { + scancodeInt := d.scancodeMap[key] + if keyShift { + scancode = append(scancode, "2a") + } + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + } + + if action&(KeyOff|KeyPress) != 0 { + scancodeInt := d.scancodeMap[key] + 0x80 + if keyShift { + scancode = append(scancode, "aa") + } + scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + } + + for _, sc := range scancode { + log.Printf("Sending char '%c', code '%s', shift %v", key, sc, keyShift) + } + + return d.send(scancode) +} + +func (d *pcATDriver) SendSpecial(special string, action KeyAction) (err error) { + keyCode, ok := d.specialMap[special] + if !ok { + return fmt.Errorf("special %s not found.", special) + } + + switch action { + case KeyOn: + err = d.send([]string{keyCode[0]}) + case KeyOff: + err = d.send([]string{keyCode[1]}) + case KeyPress: + err = d.send(keyCode) + } + return +} diff --git a/common/boot_command/vnc_driver.go b/common/boot_command/vnc_driver.go index fbcb7a257..7cc9ec0b1 100644 --- a/common/boot_command/vnc_driver.go +++ b/common/boot_command/vnc_driver.go @@ -12,9 +12,16 @@ import ( vnc "github.com/mitchellh/go-vnc" ) -const shiftedChars = "~!@#$%^&*()_+{}|:\"<>?" const KeyLeftShift uint32 = 0xFFE1 +type bcDriver struct { + c *vnc.ClientConn + interval time.Duration + specialMap map[string]uint32 + // keyEvent can set this error which will prevent it from continuing + err error +} + func NewVNCDriver(c *vnc.ClientConn) *bcDriver { // We delay (default 100ms) between each key event to allow for CPU or // network latency. See PackerKeyEnv for tuning. @@ -69,14 +76,6 @@ func NewVNCDriver(c *vnc.ClientConn) *bcDriver { } } -type bcDriver struct { - c *vnc.ClientConn - interval time.Duration - specialMap map[string]uint32 - // keyEvent can set this error which will prevent it from continuing - err error -} - func (d *bcDriver) keyEvent(k uint32, down bool) error { if d.err != nil { return nil From 9b7704c7147a8ac6c4f8aa18b0800787c3bd76a9 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 16:32:22 -0700 Subject: [PATCH 0938/1007] Implement new parser for Parallels boot command --- builder/parallels/common/step_run.go | 19 -- .../common/step_type_boot_command.go | 295 ++---------------- builder/parallels/iso/builder.go | 5 +- builder/parallels/pvm/builder.go | 5 +- .../common/step_type_boot_command.go | 20 +- common/boot_command/pc_at_driver.go | 14 +- 6 files changed, 48 insertions(+), 310 deletions(-) diff --git a/builder/parallels/common/step_run.go b/builder/parallels/common/step_run.go index 073ad0550..3835baef6 100644 --- a/builder/parallels/common/step_run.go +++ b/builder/parallels/common/step_run.go @@ -3,7 +3,6 @@ package common import ( "context" "fmt" - "time" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -18,8 +17,6 @@ import ( // // Produces: type StepRun struct { - BootWait time.Duration - vmName string } @@ -40,22 +37,6 @@ func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste s.vmName = vmName - if int64(s.BootWait) > 0 { - ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait)) - wait := time.After(s.BootWait) - WAITLOOP: - for { - select { - case <-wait: - break WAITLOOP - case <-time.After(1 * time.Second): - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - } - } - } - return multistep.ActionContinue } diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index e39a90b6c..5f509ddf9 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -4,12 +4,10 @@ import ( "context" "fmt" "log" - "strings" "time" - "unicode" - "unicode/utf8" packer_common "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -23,29 +21,32 @@ type bootCommandTemplateData struct { // StepTypeBootCommand is a step that "types" the boot command into the VM via // the prltype script, built on the Parallels Virtualization SDK - Python API. -// -// Uses: -// driver Driver -// http_port int -// ui packer.Ui -// vmName string -// -// Produces: -// <nothing> type StepTypeBootCommand struct { BootCommand []string + BootWait time.Duration HostInterfaces []string VMName string Ctx interpolate.Context } // Run types the boot command by sending key scancodes into the VM. -func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { debug := state.Get("debug").(bool) httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) driver := state.Get("driver").(Driver) + // Wait the for the vm to boot. + if int64(s.BootWait) > 0 { + ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String())) + select { + case <-time.After(s.BootWait): + break + case <-ctx.Done(): + return multistep.ActionHalt + } + } + var pauseFn multistep.DebugPauseFn if debug { pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn) @@ -76,6 +77,12 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m s.VMName, } + sendCodes := func(codes []string) error { + log.Printf("Sending scancodes: %#v", codes) + return driver.SendKeyScanCodes(s.VMName, codes...) + } + d := bootcommand.NewPCATDriver(sendCodes) + ui.Say("Typing the boot command...") for i, command := range s.BootCommand { command, err := interpolate.Render(command, &s.Ctx) @@ -86,63 +93,24 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - codes := []string{} - for _, code := range scancodes(command) { - if code == "wait" { - if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil { - err = fmt.Errorf("Error sending boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - codes = []string{} - time.Sleep(1 * time.Second) - continue - } + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if code == "wait5" { - if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil { - err = fmt.Errorf("Error sending boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - codes = []string{} - time.Sleep(5 * time.Second) - continue - } - - if code == "wait10" { - if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil { - err = fmt.Errorf("Error sending boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - codes = []string{} - time.Sleep(10 * time.Second) - continue - } - - // Since typing is sometimes so slow, we check for an interrupt - // in between each character. - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - codes = append(codes, code) + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } if pauseFn != nil { pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) } - - log.Printf("Sending scancodes: %#v", codes) - if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil { - err = fmt.Errorf("Error sending boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } } return multistep.ActionContinue @@ -150,202 +118,3 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m // Cleanup does nothing. func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} - -func scancodes(message string) []string { - // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html - // - // Scancodes represent raw keyboard output and are fed to the VM by the - // Parallels Virtualization SDK - C API, PrlDevKeyboard_SendKeyEvent - // - // Scancodes are recorded here in pairs. The first entry represents - // the key press and the second entry represents the key release and is - // derived from the first by the addition of 0x80. - special := make(map[string][]string) - special["<bs>"] = []string{"0e", "8e"} - special["<del>"] = []string{"53", "d3"} - special["<enter>"] = []string{"1c", "9c"} - special["<esc>"] = []string{"01", "81"} - special["<f1>"] = []string{"3b", "bb"} - special["<f2>"] = []string{"3c", "bc"} - special["<f3>"] = []string{"3d", "bd"} - special["<f4>"] = []string{"3e", "be"} - special["<f5>"] = []string{"3f", "bf"} - special["<f6>"] = []string{"40", "c0"} - special["<f7>"] = []string{"41", "c1"} - special["<f8>"] = []string{"42", "c2"} - special["<f9>"] = []string{"43", "c3"} - special["<f10>"] = []string{"44", "c4"} - special["<return>"] = []string{"1c", "9c"} - special["<tab>"] = []string{"0f", "8f"} - - special["<up>"] = []string{"48", "c8"} - special["<down>"] = []string{"50", "d0"} - special["<left>"] = []string{"4b", "cb"} - special["<right>"] = []string{"4d", "cd"} - special["<spacebar>"] = []string{"39", "b9"} - special["<insert>"] = []string{"52", "d2"} - special["<home>"] = []string{"47", "c7"} - special["<end>"] = []string{"4f", "cf"} - special["<pageUp>"] = []string{"49", "c9"} - special["<pageDown>"] = []string{"51", "d1"} - - special["<leftAlt>"] = []string{"38", "b8"} - special["<leftCtrl>"] = []string{"1d", "9d"} - special["<leftShift>"] = []string{"2a", "aa"} - special["<rightAlt>"] = []string{"e038", "e0b8"} - special["<rightCtrl>"] = []string{"e01d", "e09d"} - special["<rightShift>"] = []string{"36", "b6"} - - shiftedChars := "!@#$%^&*()_+{}:\"~|<>?" - - scancodeIndex := make(map[string]uint) - scancodeIndex["1234567890-="] = 0x02 - scancodeIndex["!@#$%^&*()_+"] = 0x02 - scancodeIndex["qwertyuiop[]"] = 0x10 - scancodeIndex["QWERTYUIOP{}"] = 0x10 - scancodeIndex["asdfghjkl;'`"] = 0x1e - scancodeIndex[`ASDFGHJKL:"~`] = 0x1e - scancodeIndex["\\zxcvbnm,./"] = 0x2b - scancodeIndex["|ZXCVBNM<>?"] = 0x2b - scancodeIndex[" "] = 0x39 - - scancodeMap := make(map[rune]uint) - for chars, start := range scancodeIndex { - var i uint - for len(chars) > 0 { - r, size := utf8.DecodeRuneInString(chars) - chars = chars[size:] - scancodeMap[r] = start + i - i++ - } - } - - result := make([]string, 0, len(message)*2) - for len(message) > 0 { - var scancode []string - - if strings.HasPrefix(message, "<leftAltOn>") { - scancode = []string{"38"} - message = message[len("<leftAltOn>"):] - log.Printf("Special code '<leftAltOn>' found, replacing with: 38") - } - - if strings.HasPrefix(message, "<leftCtrlOn>") { - scancode = []string{"1d"} - message = message[len("<leftCtrlOn>"):] - log.Printf("Special code '<leftCtrlOn>' found, replacing with: 1d") - } - - if strings.HasPrefix(message, "<leftShiftOn>") { - scancode = []string{"2a"} - message = message[len("<leftShiftOn>"):] - log.Printf("Special code '<leftShiftOn>' found, replacing with: 2a") - } - - if strings.HasPrefix(message, "<leftAltOff>") { - scancode = []string{"b8"} - message = message[len("<leftAltOff>"):] - log.Printf("Special code '<leftAltOff>' found, replacing with: b8") - } - - if strings.HasPrefix(message, "<leftCtrlOff>") { - scancode = []string{"9d"} - message = message[len("<leftCtrlOff>"):] - log.Printf("Special code '<leftCtrlOff>' found, replacing with: 9d") - } - - if strings.HasPrefix(message, "<leftShiftOff>") { - scancode = []string{"aa"} - message = message[len("<leftShiftOff>"):] - log.Printf("Special code '<leftShiftOff>' found, replacing with: aa") - } - - if strings.HasPrefix(message, "<rightAltOn>") { - scancode = []string{"e038"} - message = message[len("<rightAltOn>"):] - log.Printf("Special code '<rightAltOn>' found, replacing with: e038") - } - - if strings.HasPrefix(message, "<rightCtrlOn>") { - scancode = []string{"e01d"} - message = message[len("<rightCtrlOn>"):] - log.Printf("Special code '<rightCtrlOn>' found, replacing with: e01d") - } - - if strings.HasPrefix(message, "<rightShiftOn>") { - scancode = []string{"36"} - message = message[len("<rightShiftOn>"):] - log.Printf("Special code '<rightShiftOn>' found, replacing with: 36") - } - - if strings.HasPrefix(message, "<rightAltOff>") { - scancode = []string{"e0b8"} - message = message[len("<rightAltOff>"):] - log.Printf("Special code '<rightAltOff>' found, replacing with: e0b8") - } - - if strings.HasPrefix(message, "<rightCtrlOff>") { - scancode = []string{"e09d"} - message = message[len("<rightCtrlOff>"):] - log.Printf("Special code '<rightCtrlOff>' found, replacing with: e09d") - } - - if strings.HasPrefix(message, "<rightShiftOff>") { - scancode = []string{"b6"} - message = message[len("<rightShiftOff>"):] - log.Printf("Special code '<rightShiftOff>' found, replacing with: b6") - } - - if strings.HasPrefix(message, "<wait>") { - log.Printf("Special code <wait> found, will sleep 1 second at this point.") - scancode = []string{"wait"} - message = message[len("<wait>"):] - } - - if strings.HasPrefix(message, "<wait5>") { - log.Printf("Special code <wait5> found, will sleep 5 seconds at this point.") - scancode = []string{"wait5"} - message = message[len("<wait5>"):] - } - - if strings.HasPrefix(message, "<wait10>") { - log.Printf("Special code <wait10> found, will sleep 10 seconds at this point.") - scancode = []string{"wait10"} - message = message[len("<wait10>"):] - } - - if scancode == nil { - for specialCode, specialValue := range special { - if strings.HasPrefix(message, specialCode) { - log.Printf("Special code '%s' found, replacing with: %s", specialCode, specialValue) - scancode = specialValue - message = message[len(specialCode):] - break - } - } - } - - if scancode == nil { - r, size := utf8.DecodeRuneInString(message) - message = message[size:] - scancodeInt := scancodeMap[r] - keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - scancode = make([]string, 0, 4) - if keyShift { - scancode = append(scancode, "2a") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt+0x80)) - - if keyShift { - scancode = append(scancode, "aa") - } - } - - result = append(result, scancode...) - } - - return result -} diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index cf8159f6b..e4710b5a6 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -185,10 +185,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Commands: b.config.Prlctl, Ctx: b.config.ctx, }, - &parallelscommon.StepRun{ - BootWait: b.config.BootWait, - }, + &parallelscommon.StepRun{}, &parallelscommon.StepTypeBootCommand{ + BootWait: b.config.BootWait, BootCommand: b.config.BootCommand, HostInterfaces: b.config.HostInterfaces, VMName: b.config.VMName, diff --git a/builder/parallels/pvm/builder.go b/builder/parallels/pvm/builder.go index 1e0d3c49a..4fd5e73d9 100644 --- a/builder/parallels/pvm/builder.go +++ b/builder/parallels/pvm/builder.go @@ -74,11 +74,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe Commands: b.config.Prlctl, Ctx: b.config.ctx, }, - &parallelscommon.StepRun{ - BootWait: b.config.BootWait, - }, + &parallelscommon.StepRun{}, &parallelscommon.StepTypeBootCommand{ BootCommand: b.config.BootCommand, + BootWait: b.config.BootWait, HostInterfaces: []string{}, VMName: b.config.VMName, Ctx: b.config.ctx, diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 2af3b8b50..5b633d09b 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -20,16 +20,6 @@ type bootCommandTemplateData struct { Name string } -// This step "types" the boot command into the VM over VNC. -// -// Uses: -// driver Driver -// http_port int -// ui packer.Ui -// vmName string -// -// Produces: -// <nothing> type StepTypeBootCommand struct { BootCommand []string BootWait time.Duration @@ -72,10 +62,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) args := []string{"controlvm", vmName, "keyboardputscancode"} args = append(args, codes...) - if err := driver.VBoxManage(args...); err != nil { - return err - } - return nil + return driver.VBoxManage(args...) } d := bootcommand.NewPCATDriver(sendCodes) @@ -97,10 +84,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return multistep.ActionHalt } - // This executes vboxmanage once for each character code. This seems - // fine for now, but changes the prior behavior. If this becomes - // a problem, we can always have the driver cache scancodes, and then - // add a `Flush` method which we can call after this. if err := seq.Do(ctx, d); err != nil { err := fmt.Errorf("Error running boot command: %s", err) state.Put("error", err) @@ -111,7 +94,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) if pauseFn != nil { pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) } - } return multistep.ActionContinue diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go index 51def2932..1fa99f175 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_at_driver.go @@ -8,18 +8,26 @@ import ( "unicode/utf8" ) +// This driver executes the driver once for each character code. This seems +// fine for now, but changes the prior behavior. If this becomes a problem, we +// can always have the driver cache scancodes, and then add a `Flush` method +// which we can call after this. + +// SendCodeFunc will be called to send codes to the VM type SendCodeFunc func([]string) error type pcATDriver struct { - //driver Driver - //vmName string send SendCodeFunc specialMap map[string][]string scancodeMap map[rune]byte } func NewPCATDriver(send SendCodeFunc) *pcATDriver { - // sMap contains on/off tuples + // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + // + // Scancodes are recorded here in pairs. The first entry represents + // the key press and the second entry represents the key release and is + // derived from the first by the addition of 0x80. sMap := make(map[string][]string) sMap["bs"] = []string{"0e", "8e"} sMap["del"] = []string{"e053", "e0d3"} From 59376294efc1169d3955cef09f682ac08fd9e5b0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 17:00:09 -0700 Subject: [PATCH 0939/1007] Maximize scancode throughput. Let's cache the scancodes and flush them at the end. Also make sure to send only as many as the driver can send correctly. It's important here to chunk the scancodes correctly, so that we don't accidentally split them over successive calls to the driver --- .../common/step_type_boot_command.go | 2 +- .../common/step_type_boot_command.go | 2 +- common/boot_command/boot_command_ast.go | 4 +- common/boot_command/driver.go | 2 + common/boot_command/pc_at_driver.go | 71 +- common/boot_command/pc_at_driver_test.go | 68 + common/boot_command/vnc_driver.go | 17 +- vendor/github.com/davecgh/go-spew/LICENSE | 2 +- .../github.com/davecgh/go-spew/spew/bypass.go | 2 +- .../davecgh/go-spew/spew/bypasssafe.go | 38 - .../github.com/davecgh/go-spew/spew/common.go | 2 +- .../github.com/davecgh/go-spew/spew/config.go | 11 +- vendor/github.com/davecgh/go-spew/spew/doc.go | 11 +- .../github.com/davecgh/go-spew/spew/dump.go | 8 +- .../github.com/davecgh/go-spew/spew/format.go | 2 +- .../github.com/davecgh/go-spew/spew/spew.go | 2 +- vendor/github.com/stretchr/objx/Gopkg.lock | 27 + vendor/github.com/stretchr/objx/Gopkg.toml | 3 + vendor/github.com/stretchr/objx/LICENSE | 22 + vendor/github.com/stretchr/objx/README.md | 78 + vendor/github.com/stretchr/objx/Taskfile.yml | 26 + vendor/github.com/stretchr/objx/accessors.go | 171 ++ vendor/github.com/stretchr/objx/constants.go | 13 + .../github.com/stretchr/objx/conversions.go | 108 + vendor/github.com/stretchr/objx/doc.go | 66 + vendor/github.com/stretchr/objx/map.go | 193 ++ vendor/github.com/stretchr/objx/mutations.go | 74 + vendor/github.com/stretchr/objx/security.go | 17 + vendor/github.com/stretchr/objx/tests.go | 17 + .../stretchr/objx/type_specific_codegen.go | 2501 +++++++++++++++++ vendor/github.com/stretchr/objx/value.go | 56 + .../testify/assert/assertion_format.go | 349 +++ .../testify/assert/assertion_format.go.tmpl | 4 + .../testify/assert/assertion_forward.go | 565 +++- .../stretchr/testify/assert/assertions.go | 619 ++-- .../testify/assert/forward_assertions.go | 2 +- .../testify/assert/http_assertions.go | 61 +- vendor/vendor.json | 23 +- 38 files changed, 4822 insertions(+), 417 deletions(-) create mode 100644 common/boot_command/pc_at_driver_test.go delete mode 100644 vendor/github.com/davecgh/go-spew/spew/bypasssafe.go create mode 100644 vendor/github.com/stretchr/objx/Gopkg.lock create mode 100644 vendor/github.com/stretchr/objx/Gopkg.toml create mode 100644 vendor/github.com/stretchr/objx/LICENSE create mode 100644 vendor/github.com/stretchr/objx/README.md create mode 100644 vendor/github.com/stretchr/objx/Taskfile.yml create mode 100644 vendor/github.com/stretchr/objx/accessors.go create mode 100644 vendor/github.com/stretchr/objx/constants.go create mode 100644 vendor/github.com/stretchr/objx/conversions.go create mode 100644 vendor/github.com/stretchr/objx/doc.go create mode 100644 vendor/github.com/stretchr/objx/map.go create mode 100644 vendor/github.com/stretchr/objx/mutations.go create mode 100644 vendor/github.com/stretchr/objx/security.go create mode 100644 vendor/github.com/stretchr/objx/tests.go create mode 100644 vendor/github.com/stretchr/objx/type_specific_codegen.go create mode 100644 vendor/github.com/stretchr/objx/value.go create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_format.go create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index 5f509ddf9..306182d6a 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -81,7 +81,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) log.Printf("Sending scancodes: %#v", codes) return driver.SendKeyScanCodes(s.VMName, codes...) } - d := bootcommand.NewPCATDriver(sendCodes) + d := bootcommand.NewPCATDriver(sendCodes, -1) ui.Say("Typing the boot command...") for i, command := range s.BootCommand { diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 5b633d09b..a33c61e3d 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -64,7 +64,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return driver.VBoxManage(args...) } - d := bootcommand.NewPCATDriver(sendCodes) + d := bootcommand.NewPCATDriver(sendCodes, 20) ui.Say("Typing the boot command...") for i, command := range s.BootCommand { diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index cc28aed08..87457a22c 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -15,6 +15,8 @@ TODO: * comments * lower-case specials * check that `<del>` works on parallels. It's different now. + * take `Finalize` out of the Driver interface. let builders that need it + * use it. also rename to `Flush`. */ // KeysAction represents what we want to do with a key press. @@ -63,7 +65,7 @@ func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { return err } } - return nil + return b.Finalize() } // GenerateExpressionSequence generates a sequence of expressions from the diff --git a/common/boot_command/driver.go b/common/boot_command/driver.go index b9c20710a..ddbae0bc5 100644 --- a/common/boot_command/driver.go +++ b/common/boot_command/driver.go @@ -6,4 +6,6 @@ const shiftedChars = "~!@#$%^&*()_+{}|:\"<>?" type BCDriver interface { SendKey(key rune, action KeyAction) error SendSpecial(special string, action KeyAction) error + // Finalize will be called after every expression has been processed. + Finalize() error } diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go index 1fa99f175..834a4b02a 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_at_driver.go @@ -8,21 +8,19 @@ import ( "unicode/utf8" ) -// This driver executes the driver once for each character code. This seems -// fine for now, but changes the prior behavior. If this becomes a problem, we -// can always have the driver cache scancodes, and then add a `Flush` method -// which we can call after this. - // SendCodeFunc will be called to send codes to the VM type SendCodeFunc func([]string) error type pcATDriver struct { - send SendCodeFunc + sendImpl SendCodeFunc specialMap map[string][]string scancodeMap map[rune]byte + buffer [][]string + // TODO: set from env + scancodeChunkSize int } -func NewPCATDriver(send SendCodeFunc) *pcATDriver { +func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html // // Scancodes are recorded here in pairs. The first entry represents @@ -89,12 +87,30 @@ func NewPCATDriver(send SendCodeFunc) *pcATDriver { } return &pcATDriver{ - send: send, - specialMap: sMap, - scancodeMap: scancodeMap, + sendImpl: send, + specialMap: sMap, + scancodeMap: scancodeMap, + scancodeChunkSize: chunkSize, } } +// Finalize flushes all scanecodes. +func (d *pcATDriver) Finalize() error { + defer func() { + d.buffer = nil + }() + sc, err := chunkScanCodes(d.buffer, d.scancodeChunkSize) + if err != nil { + return err + } + for _, b := range sc { + if err := d.sendImpl(b); err != nil { + return err + } + } + return nil +} + func (d *pcATDriver) SendKey(key rune, action KeyAction) error { keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) @@ -121,10 +137,11 @@ func (d *pcATDriver) SendKey(key rune, action KeyAction) error { log.Printf("Sending char '%c', code '%s', shift %v", key, sc, keyShift) } - return d.send(scancode) + d.send(scancode) + return nil } -func (d *pcATDriver) SendSpecial(special string, action KeyAction) (err error) { +func (d *pcATDriver) SendSpecial(special string, action KeyAction) error { keyCode, ok := d.specialMap[special] if !ok { return fmt.Errorf("special %s not found.", special) @@ -132,11 +149,35 @@ func (d *pcATDriver) SendSpecial(special string, action KeyAction) (err error) { switch action { case KeyOn: - err = d.send([]string{keyCode[0]}) + d.send([]string{keyCode[0]}) case KeyOff: - err = d.send([]string{keyCode[1]}) + d.send([]string{keyCode[1]}) case KeyPress: - err = d.send(keyCode) + d.send(keyCode) + } + return nil +} + +func (d *pcATDriver) send(codes []string) { + d.buffer = append(d.buffer, codes) +} + +func chunkScanCodes(sc [][]string, size int) (out [][]string, err error) { + var running []string + for _, codes := range sc { + if size > 0 { + if len(codes) > size { + return nil, fmt.Errorf("chunkScanCodes: size cannot be smaller than sc width.") + } + if len(running)+len(codes) > size { + out = append(out, running) + running = nil + } + } + running = append(running, codes...) + } + if running != nil { + out = append(out, running) } return } diff --git a/common/boot_command/pc_at_driver_test.go b/common/boot_command/pc_at_driver_test.go new file mode 100644 index 000000000..893f2446c --- /dev/null +++ b/common/boot_command/pc_at_driver_test.go @@ -0,0 +1,68 @@ +package bootcommand + +import "testing" +import "github.com/stretchr/testify/assert" + +func Test_chunkScanCodes(t *testing.T) { + + var chunktests = []struct { + size int + in [][]string + out [][]string + }{ + { + 3, + [][]string{ + {"a", "b"}, + {"c"}, + {"d"}, + {"e", "f"}, + {"g", "h"}, + {"i", "j"}, + {"k"}, + {"l", "m"}, + }, + [][]string{ + {"a", "b", "c"}, + {"d", "e", "f"}, + {"g", "h"}, + {"i", "j", "k"}, + {"l", "m"}, + }, + }, + { + -1, + [][]string{ + {"a", "b"}, + {"c"}, + {"d"}, + {"e", "f"}, + {"g", "h"}, + {"i", "j"}, + {"k"}, + {"l", "m"}, + }, + [][]string{ + {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"}, + }, + }, + } + + for _, tt := range chunktests { + out, err := chunkScanCodes(tt.in, tt.size) + assert.NoError(t, err) + assert.Equalf(t, tt.out, out, "expecting chunks of %d.", tt.size) + } +} + +func Test_chunkScanCodeError(t *testing.T) { + // can't go from wider to thinner + in := [][]string{ + {"a", "b", "c"}, + {"d", "e", "f"}, + {"g", "h"}, + } + + _, err := chunkScanCodes(in, 2) + assert.Error(t, err) +} diff --git a/common/boot_command/vnc_driver.go b/common/boot_command/vnc_driver.go index 7cc9ec0b1..811932aba 100644 --- a/common/boot_command/vnc_driver.go +++ b/common/boot_command/vnc_driver.go @@ -14,7 +14,7 @@ import ( const KeyLeftShift uint32 = 0xFFE1 -type bcDriver struct { +type vncDriver struct { c *vnc.ClientConn interval time.Duration specialMap map[string]uint32 @@ -22,7 +22,7 @@ type bcDriver struct { err error } -func NewVNCDriver(c *vnc.ClientConn) *bcDriver { +func NewVNCDriver(c *vnc.ClientConn) *vncDriver { // We delay (default 100ms) between each key event to allow for CPU or // network latency. See PackerKeyEnv for tuning. keyInterval := common.PackerKeyDefault @@ -69,14 +69,14 @@ func NewVNCDriver(c *vnc.ClientConn) *bcDriver { sMap["leftSuper"] = 0xFFEB sMap["rightSuper"] = 0xFFEC - return &bcDriver{ + return &vncDriver{ c: c, interval: keyInterval, specialMap: sMap, } } -func (d *bcDriver) keyEvent(k uint32, down bool) error { +func (d *vncDriver) keyEvent(k uint32, down bool) error { if d.err != nil { return nil } @@ -88,7 +88,12 @@ func (d *bcDriver) keyEvent(k uint32, down bool) error { return nil } -func (d *bcDriver) SendKey(key rune, action KeyAction) error { +// Finalize does nothing here +func (d *vncDriver) Finalize() error { + return nil +} + +func (d *vncDriver) SendKey(key rune, action KeyAction) error { keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) keyCode := uint32(key) log.Printf("Sending char '%c', code 0x%X, shift %v", key, keyCode, keyShift) @@ -117,7 +122,7 @@ func (d *bcDriver) SendKey(key rune, action KeyAction) error { return d.err } -func (d *bcDriver) SendSpecial(special string, action KeyAction) error { +func (d *vncDriver) SendSpecial(special string, action KeyAction) error { keyCode, ok := d.specialMap[special] if !ok { return fmt.Errorf("special %s not found.", special) diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE index bb6733231..c83641619 100644 --- a/vendor/github.com/davecgh/go-spew/LICENSE +++ b/vendor/github.com/davecgh/go-spew/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright (c) 2012-2013 Dave Collins <dave@davec.name> +Copyright (c) 2012-2016 Dave Collins <dave@davec.name> Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go index d42a0bc4a..8a4a6589a 100644 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015 Dave Collins <dave@davec.name> +// Copyright (c) 2015-2016 Dave Collins <dave@davec.name> // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go deleted file mode 100644 index e47a4e795..000000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015 Dave Collins <dave@davec.name> -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is running on Google App Engine, compiled by GopherJS, or -// "-tags safe" is added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe - -package spew - -import "reflect" - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = true -) - -// unsafeReflectValue typically converts the passed reflect.Value into a one -// that bypasses the typical safety restrictions preventing access to -// unaddressable and unexported data. However, doing this relies on access to -// the unsafe package. This is a stub version which simply returns the passed -// reflect.Value when the unsafe package is not available. -func unsafeReflectValue(v reflect.Value) reflect.Value { - return v -} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go index 14f02dc15..7c519ff47 100644 --- a/vendor/github.com/davecgh/go-spew/spew/common.go +++ b/vendor/github.com/davecgh/go-spew/spew/common.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Dave Collins <dave@davec.name> + * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go index 555282723..2e3d22f31 100644 --- a/vendor/github.com/davecgh/go-spew/spew/config.go +++ b/vendor/github.com/davecgh/go-spew/spew/config.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Dave Collins <dave@davec.name> + * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -67,6 +67,15 @@ type ConfigState struct { // Google App Engine or with the "safe" build tag specified. DisablePointerMethods bool + // DisablePointerAddresses specifies whether to disable the printing of + // pointer addresses. This is useful when diffing data structures in tests. + DisablePointerAddresses bool + + // DisableCapacities specifies whether to disable the printing of capacities + // for arrays, slices, maps and channels. This is useful when diffing + // data structures in tests. + DisableCapacities bool + // ContinueOnMethod specifies whether or not recursion should continue once // a custom error or Stringer interface is invoked. The default, false, // means it will print the results of invoking the custom error or Stringer diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go index 5be0c4060..aacaac6f1 100644 --- a/vendor/github.com/davecgh/go-spew/spew/doc.go +++ b/vendor/github.com/davecgh/go-spew/spew/doc.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Dave Collins <dave@davec.name> + * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -91,6 +91,15 @@ The following configuration options are available: which only accept pointer receivers from non-pointer variables. Pointer method invocation is enabled by default. + * DisablePointerAddresses + DisablePointerAddresses specifies whether to disable the printing of + pointer addresses. This is useful when diffing data structures in tests. + + * DisableCapacities + DisableCapacities specifies whether to disable the printing of + capacities for arrays, slices, maps and channels. This is useful when + diffing data structures in tests. + * ContinueOnMethod Enables recursion into types after invoking error and Stringer interface methods. Recursion after method invocation is disabled by default. diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go index a0ff95e27..df1d582a7 100644 --- a/vendor/github.com/davecgh/go-spew/spew/dump.go +++ b/vendor/github.com/davecgh/go-spew/spew/dump.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Dave Collins <dave@davec.name> + * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -129,7 +129,7 @@ func (d *dumpState) dumpPtr(v reflect.Value) { d.w.Write(closeParenBytes) // Display pointer information. - if len(pointerChain) > 0 { + if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { d.w.Write(openParenBytes) for i, addr := range pointerChain { if i > 0 { @@ -282,13 +282,13 @@ func (d *dumpState) dump(v reflect.Value) { case reflect.Map, reflect.String: valueLen = v.Len() } - if valueLen != 0 || valueCap != 0 { + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { d.w.Write(openParenBytes) if valueLen != 0 { d.w.Write(lenEqualsBytes) printInt(d.w, int64(valueLen), 10) } - if valueCap != 0 { + if !d.cs.DisableCapacities && valueCap != 0 { if valueLen != 0 { d.w.Write(spaceBytes) } diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go index ecf3b80e2..c49875bac 100644 --- a/vendor/github.com/davecgh/go-spew/spew/format.go +++ b/vendor/github.com/davecgh/go-spew/spew/format.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Dave Collins <dave@davec.name> + * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go index d8233f542..32c0e3388 100644 --- a/vendor/github.com/davecgh/go-spew/spew/spew.go +++ b/vendor/github.com/davecgh/go-spew/spew/spew.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Dave Collins <dave@davec.name> + * Copyright (c) 2013-2016 Dave Collins <dave@davec.name> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/vendor/github.com/stretchr/objx/Gopkg.lock b/vendor/github.com/stretchr/objx/Gopkg.lock new file mode 100644 index 000000000..1f5739c91 --- /dev/null +++ b/vendor/github.com/stretchr/objx/Gopkg.lock @@ -0,0 +1,27 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + name = "github.com/stretchr/testify" + packages = ["assert"] + revision = "b91bfb9ebec76498946beb6af7c0230c7cc7ba6c" + version = "v1.2.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "50e2495ec1af6e2f7ffb2f3551e4300d30357d7c7fe38ff6056469fa9cfb3673" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/stretchr/objx/Gopkg.toml b/vendor/github.com/stretchr/objx/Gopkg.toml new file mode 100644 index 000000000..f87e18eb5 --- /dev/null +++ b/vendor/github.com/stretchr/objx/Gopkg.toml @@ -0,0 +1,3 @@ +[[constraint]] + name = "github.com/stretchr/testify" + version = "~1.2.0" diff --git a/vendor/github.com/stretchr/objx/LICENSE b/vendor/github.com/stretchr/objx/LICENSE new file mode 100644 index 000000000..44d4d9d5a --- /dev/null +++ b/vendor/github.com/stretchr/objx/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2014 Stretchr, Inc. +Copyright (c) 2017-2018 objx contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/stretchr/objx/README.md b/vendor/github.com/stretchr/objx/README.md new file mode 100644 index 000000000..4e2400eb1 --- /dev/null +++ b/vendor/github.com/stretchr/objx/README.md @@ -0,0 +1,78 @@ +# Objx +[![Build Status](https://travis-ci.org/stretchr/objx.svg?branch=master)](https://travis-ci.org/stretchr/objx) +[![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/objx)](https://goreportcard.com/report/github.com/stretchr/objx) +[![Sourcegraph](https://sourcegraph.com/github.com/stretchr/objx/-/badge.svg)](https://sourcegraph.com/github.com/stretchr/objx) +[![GoDoc](https://godoc.org/github.com/stretchr/objx?status.svg)](https://godoc.org/github.com/stretchr/objx) + +Objx - Go package for dealing with maps, slices, JSON and other data. + +Get started: + +- Install Objx with [one line of code](#installation), or [update it with another](#staying-up-to-date) +- Check out the API Documentation http://godoc.org/github.com/stretchr/objx + +## Overview +Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes a powerful `Get` method (among others) that allows you to easily and quickly get access to data within the map, without having to worry too much about type assertions, missing data, default values etc. + +### Pattern +Objx uses a preditable pattern to make access data from within `map[string]interface{}` easy. Call one of the `objx.` functions to create your `objx.Map` to get going: + + m, err := objx.FromJSON(json) + +NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, the rest will be optimistic and try to figure things out without panicking. + +Use `Get` to access the value you're interested in. You can use dot and array +notation too: + + m.Get("places[0].latlng") + +Once you have sought the `Value` you're interested in, you can use the `Is*` methods to determine its type. + + if m.Get("code").IsStr() { // Your code... } + +Or you can just assume the type, and use one of the strong type methods to extract the real value: + + m.Get("code").Int() + +If there's no value there (or if it's the wrong type) then a default value will be returned, or you can be explicit about the default value. + + Get("code").Int(-1) + +If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating, manipulating and selecting that data. You can find out more by exploring the index below. + +### Reading data +A simple example of how to use Objx: + + // Use MustFromJSON to make an objx.Map from some JSON + m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) + + // Get the details + name := m.Get("name").Str() + age := m.Get("age").Int() + + // Get their nickname (or use their name if they don't have one) + nickname := m.Get("nickname").Str(name) + +### Ranging +Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For example, to `range` the data, do what you would expect: + + m := objx.MustFromJSON(json) + for key, value := range m { + // Your code... + } + +## Installation +To install Objx, use go get: + + go get github.com/stretchr/objx + +### Staying up to date +To update Objx to the latest version, run: + + go get -u github.com/stretchr/objx + +### Supported go versions +We support the lastest two major Go versions, which are 1.8 and 1.9 at the moment. + +## Contributing +Please feel free to submit issues, fork the repository and send pull requests! diff --git a/vendor/github.com/stretchr/objx/Taskfile.yml b/vendor/github.com/stretchr/objx/Taskfile.yml new file mode 100644 index 000000000..403b5f06e --- /dev/null +++ b/vendor/github.com/stretchr/objx/Taskfile.yml @@ -0,0 +1,26 @@ +default: + deps: [test] + +dl-deps: + desc: Downloads cli dependencies + cmds: + - go get -u github.com/golang/lint/golint + - go get -u github.com/golang/dep/cmd/dep + +update-deps: + desc: Updates dependencies + cmds: + - dep ensure + - dep ensure -update + - dep prune + +lint: + desc: Runs golint + cmds: + - golint $(ls *.go | grep -v "doc.go") + silent: true + +test: + desc: Runs go tests + cmds: + - go test -race . diff --git a/vendor/github.com/stretchr/objx/accessors.go b/vendor/github.com/stretchr/objx/accessors.go new file mode 100644 index 000000000..d95be0ca9 --- /dev/null +++ b/vendor/github.com/stretchr/objx/accessors.go @@ -0,0 +1,171 @@ +package objx + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +// arrayAccesRegexString is the regex used to extract the array number +// from the access path +const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$` + +// arrayAccesRegex is the compiled arrayAccesRegexString +var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString) + +// Get gets the value using the specified selector and +// returns it inside a new Obj object. +// +// If it cannot find the value, Get will return a nil +// value inside an instance of Obj. +// +// Get can only operate directly on map[string]interface{} and []interface. +// +// Example +// +// To access the title of the third chapter of the second book, do: +// +// o.Get("books[1].chapters[2].title") +func (m Map) Get(selector string) *Value { + rawObj := access(m, selector, nil, false, false) + return &Value{data: rawObj} +} + +// Set sets the value using the specified selector and +// returns the object on which Set was called. +// +// Set can only operate directly on map[string]interface{} and []interface +// +// Example +// +// To set the title of the third chapter of the second book, do: +// +// o.Set("books[1].chapters[2].title","Time to Go") +func (m Map) Set(selector string, value interface{}) Map { + access(m, selector, value, true, false) + return m +} + +// access accesses the object using the selector and performs the +// appropriate action. +func access(current, selector, value interface{}, isSet, panics bool) interface{} { + + switch selector.(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + + if array, ok := current.([]interface{}); ok { + index := intFromInterface(selector) + + if index >= len(array) { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) + } + return nil + } + + return array[index] + } + + return nil + + case string: + + selStr := selector.(string) + selSegs := strings.SplitN(selStr, PathSeparator, 2) + thisSel := selSegs[0] + index := -1 + var err error + + if strings.Contains(thisSel, "[") { + arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel) + + if len(arrayMatches) > 0 { + // Get the key into the map + thisSel = arrayMatches[1] + + // Get the index into the array at the key + index, err = strconv.Atoi(arrayMatches[2]) + + if err != nil { + // This should never happen. If it does, something has gone + // seriously wrong. Panic. + panic("objx: Array index is not an integer. Must use array[int].") + } + } + } + + if curMap, ok := current.(Map); ok { + current = map[string]interface{}(curMap) + } + + // get the object in question + switch current.(type) { + case map[string]interface{}: + curMSI := current.(map[string]interface{}) + if len(selSegs) <= 1 && isSet { + curMSI[thisSel] = value + return nil + } + current = curMSI[thisSel] + default: + current = nil + } + + if current == nil && panics { + panic(fmt.Sprintf("objx: '%v' invalid on object.", selector)) + } + + // do we need to access the item of an array? + if index > -1 { + if array, ok := current.([]interface{}); ok { + if index < len(array) { + current = array[index] + } else { + if panics { + panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) + } + current = nil + } + } + } + + if len(selSegs) > 1 { + current = access(current, selSegs[1], value, isSet, panics) + } + + } + return current +} + +// intFromInterface converts an interface object to the largest +// representation of an unsigned integer using a type switch and +// assertions +func intFromInterface(selector interface{}) int { + var value int + switch selector.(type) { + case int: + value = selector.(int) + case int8: + value = int(selector.(int8)) + case int16: + value = int(selector.(int16)) + case int32: + value = int(selector.(int32)) + case int64: + value = int(selector.(int64)) + case uint: + value = int(selector.(uint)) + case uint8: + value = int(selector.(uint8)) + case uint16: + value = int(selector.(uint16)) + case uint32: + value = int(selector.(uint32)) + case uint64: + value = int(selector.(uint64)) + default: + panic("objx: array access argument is not an integer type (this should never happen)") + } + return value +} diff --git a/vendor/github.com/stretchr/objx/constants.go b/vendor/github.com/stretchr/objx/constants.go new file mode 100644 index 000000000..f9eb42a25 --- /dev/null +++ b/vendor/github.com/stretchr/objx/constants.go @@ -0,0 +1,13 @@ +package objx + +const ( + // PathSeparator is the character used to separate the elements + // of the keypath. + // + // For example, `location.address.city` + PathSeparator string = "." + + // SignatureSeparator is the character that is used to + // separate the Base64 string from the security signature. + SignatureSeparator = "_" +) diff --git a/vendor/github.com/stretchr/objx/conversions.go b/vendor/github.com/stretchr/objx/conversions.go new file mode 100644 index 000000000..5e020f310 --- /dev/null +++ b/vendor/github.com/stretchr/objx/conversions.go @@ -0,0 +1,108 @@ +package objx + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/url" +) + +// JSON converts the contained object to a JSON string +// representation +func (m Map) JSON() (string, error) { + result, err := json.Marshal(m) + if err != nil { + err = errors.New("objx: JSON encode failed with: " + err.Error()) + } + return string(result), err +} + +// MustJSON converts the contained object to a JSON string +// representation and panics if there is an error +func (m Map) MustJSON() string { + result, err := m.JSON() + if err != nil { + panic(err.Error()) + } + return result +} + +// Base64 converts the contained object to a Base64 string +// representation of the JSON string representation +func (m Map) Base64() (string, error) { + var buf bytes.Buffer + + jsonData, err := m.JSON() + if err != nil { + return "", err + } + + encoder := base64.NewEncoder(base64.StdEncoding, &buf) + _, err = encoder.Write([]byte(jsonData)) + if err != nil { + return "", err + } + _ = encoder.Close() + + return buf.String(), nil +} + +// MustBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and panics +// if there is an error +func (m Map) MustBase64() string { + result, err := m.Base64() + if err != nil { + panic(err.Error()) + } + return result +} + +// SignedBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and signs it +// using the provided key. +func (m Map) SignedBase64(key string) (string, error) { + base64, err := m.Base64() + if err != nil { + return "", err + } + + sig := HashWithKey(base64, key) + return base64 + SignatureSeparator + sig, nil +} + +// MustSignedBase64 converts the contained object to a Base64 string +// representation of the JSON string representation and signs it +// using the provided key and panics if there is an error +func (m Map) MustSignedBase64(key string) string { + result, err := m.SignedBase64(key) + if err != nil { + panic(err.Error()) + } + return result +} + +/* + URL Query + ------------------------------------------------ +*/ + +// URLValues creates a url.Values object from an Obj. This +// function requires that the wrapped object be a map[string]interface{} +func (m Map) URLValues() url.Values { + vals := make(url.Values) + for k, v := range m { + //TODO: can this be done without sprintf? + vals.Set(k, fmt.Sprintf("%v", v)) + } + return vals +} + +// URLQuery gets an encoded URL query representing the given +// Obj. This function requires that the wrapped object be a +// map[string]interface{} +func (m Map) URLQuery() (string, error) { + return m.URLValues().Encode(), nil +} diff --git a/vendor/github.com/stretchr/objx/doc.go b/vendor/github.com/stretchr/objx/doc.go new file mode 100644 index 000000000..6d6af1a83 --- /dev/null +++ b/vendor/github.com/stretchr/objx/doc.go @@ -0,0 +1,66 @@ +/* +Objx - Go package for dealing with maps, slices, JSON and other data. + +Overview + +Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes +a powerful `Get` method (among others) that allows you to easily and quickly get +access to data within the map, without having to worry too much about type assertions, +missing data, default values etc. + +Pattern + +Objx uses a preditable pattern to make access data from within `map[string]interface{}` easy. +Call one of the `objx.` functions to create your `objx.Map` to get going: + + m, err := objx.FromJSON(json) + +NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, +the rest will be optimistic and try to figure things out without panicking. + +Use `Get` to access the value you're interested in. You can use dot and array +notation too: + + m.Get("places[0].latlng") + +Once you have sought the `Value` you're interested in, you can use the `Is*` methods to determine its type. + + if m.Get("code").IsStr() { // Your code... } + +Or you can just assume the type, and use one of the strong type methods to extract the real value: + + m.Get("code").Int() + +If there's no value there (or if it's the wrong type) then a default value will be returned, +or you can be explicit about the default value. + + Get("code").Int(-1) + +If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating, +manipulating and selecting that data. You can find out more by exploring the index below. + +Reading data + +A simple example of how to use Objx: + + // Use MustFromJSON to make an objx.Map from some JSON + m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) + + // Get the details + name := m.Get("name").Str() + age := m.Get("age").Int() + + // Get their nickname (or use their name if they don't have one) + nickname := m.Get("nickname").Str(name) + +Ranging + +Since `objx.Map` is a `map[string]interface{}` you can treat it as such. +For example, to `range` the data, do what you would expect: + + m := objx.MustFromJSON(json) + for key, value := range m { + // Your code... + } +*/ +package objx diff --git a/vendor/github.com/stretchr/objx/map.go b/vendor/github.com/stretchr/objx/map.go new file mode 100644 index 000000000..7e9389a20 --- /dev/null +++ b/vendor/github.com/stretchr/objx/map.go @@ -0,0 +1,193 @@ +package objx + +import ( + "encoding/base64" + "encoding/json" + "errors" + "io/ioutil" + "net/url" + "strings" +) + +// MSIConvertable is an interface that defines methods for converting your +// custom types to a map[string]interface{} representation. +type MSIConvertable interface { + // MSI gets a map[string]interface{} (msi) representing the + // object. + MSI() map[string]interface{} +} + +// Map provides extended functionality for working with +// untyped data, in particular map[string]interface (msi). +type Map map[string]interface{} + +// Value returns the internal value instance +func (m Map) Value() *Value { + return &Value{data: m} +} + +// Nil represents a nil Map. +var Nil = New(nil) + +// New creates a new Map containing the map[string]interface{} in the data argument. +// If the data argument is not a map[string]interface, New attempts to call the +// MSI() method on the MSIConvertable interface to create one. +func New(data interface{}) Map { + if _, ok := data.(map[string]interface{}); !ok { + if converter, ok := data.(MSIConvertable); ok { + data = converter.MSI() + } else { + return nil + } + } + return Map(data.(map[string]interface{})) +} + +// MSI creates a map[string]interface{} and puts it inside a new Map. +// +// The arguments follow a key, value pattern. +// +// Panics +// +// Panics if any key argument is non-string or if there are an odd number of arguments. +// +// Example +// +// To easily create Maps: +// +// m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true)) +// +// // creates an Map equivalent to +// m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}}) +func MSI(keyAndValuePairs ...interface{}) Map { + newMap := make(map[string]interface{}) + keyAndValuePairsLen := len(keyAndValuePairs) + if keyAndValuePairsLen%2 != 0 { + panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.") + } + + for i := 0; i < keyAndValuePairsLen; i = i + 2 { + key := keyAndValuePairs[i] + value := keyAndValuePairs[i+1] + + // make sure the key is a string + keyString, keyStringOK := key.(string) + if !keyStringOK { + panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.") + } + newMap[keyString] = value + } + return New(newMap) +} + +// ****** Conversion Constructors + +// MustFromJSON creates a new Map containing the data specified in the +// jsonString. +// +// Panics if the JSON is invalid. +func MustFromJSON(jsonString string) Map { + o, err := FromJSON(jsonString) + if err != nil { + panic("objx: MustFromJSON failed with error: " + err.Error()) + } + return o +} + +// FromJSON creates a new Map containing the data specified in the +// jsonString. +// +// Returns an error if the JSON is invalid. +func FromJSON(jsonString string) (Map, error) { + var data interface{} + err := json.Unmarshal([]byte(jsonString), &data) + if err != nil { + return Nil, err + } + return New(data), nil +} + +// FromBase64 creates a new Obj containing the data specified +// in the Base64 string. +// +// The string is an encoded JSON string returned by Base64 +func FromBase64(base64String string) (Map, error) { + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String)) + decoded, err := ioutil.ReadAll(decoder) + if err != nil { + return nil, err + } + return FromJSON(string(decoded)) +} + +// MustFromBase64 creates a new Obj containing the data specified +// in the Base64 string and panics if there is an error. +// +// The string is an encoded JSON string returned by Base64 +func MustFromBase64(base64String string) Map { + result, err := FromBase64(base64String) + if err != nil { + panic("objx: MustFromBase64 failed with error: " + err.Error()) + } + return result +} + +// FromSignedBase64 creates a new Obj containing the data specified +// in the Base64 string. +// +// The string is an encoded JSON string returned by SignedBase64 +func FromSignedBase64(base64String, key string) (Map, error) { + parts := strings.Split(base64String, SignatureSeparator) + if len(parts) != 2 { + return nil, errors.New("objx: Signed base64 string is malformed") + } + + sig := HashWithKey(parts[0], key) + if parts[1] != sig { + return nil, errors.New("objx: Signature for base64 data does not match") + } + return FromBase64(parts[0]) +} + +// MustFromSignedBase64 creates a new Obj containing the data specified +// in the Base64 string and panics if there is an error. +// +// The string is an encoded JSON string returned by Base64 +func MustFromSignedBase64(base64String, key string) Map { + result, err := FromSignedBase64(base64String, key) + if err != nil { + panic("objx: MustFromSignedBase64 failed with error: " + err.Error()) + } + return result +} + +// FromURLQuery generates a new Obj by parsing the specified +// query. +// +// For queries with multiple values, the first value is selected. +func FromURLQuery(query string) (Map, error) { + vals, err := url.ParseQuery(query) + if err != nil { + return nil, err + } + + m := make(map[string]interface{}) + for k, vals := range vals { + m[k] = vals[0] + } + return New(m), nil +} + +// MustFromURLQuery generates a new Obj by parsing the specified +// query. +// +// For queries with multiple values, the first value is selected. +// +// Panics if it encounters an error +func MustFromURLQuery(query string) Map { + o, err := FromURLQuery(query) + if err != nil { + panic("objx: MustFromURLQuery failed with error: " + err.Error()) + } + return o +} diff --git a/vendor/github.com/stretchr/objx/mutations.go b/vendor/github.com/stretchr/objx/mutations.go new file mode 100644 index 000000000..e7b8eb794 --- /dev/null +++ b/vendor/github.com/stretchr/objx/mutations.go @@ -0,0 +1,74 @@ +package objx + +// Exclude returns a new Map with the keys in the specified []string +// excluded. +func (m Map) Exclude(exclude []string) Map { + excluded := make(Map) + for k, v := range m { + var shouldInclude = true + for _, toExclude := range exclude { + if k == toExclude { + shouldInclude = false + break + } + } + if shouldInclude { + excluded[k] = v + } + } + return excluded +} + +// Copy creates a shallow copy of the Obj. +func (m Map) Copy() Map { + copied := make(map[string]interface{}) + for k, v := range m { + copied[k] = v + } + return New(copied) +} + +// Merge blends the specified map with a copy of this map and returns the result. +// +// Keys that appear in both will be selected from the specified map. +// This method requires that the wrapped object be a map[string]interface{} +func (m Map) Merge(merge Map) Map { + return m.Copy().MergeHere(merge) +} + +// MergeHere blends the specified map with this map and returns the current map. +// +// Keys that appear in both will be selected from the specified map. The original map +// will be modified. This method requires that +// the wrapped object be a map[string]interface{} +func (m Map) MergeHere(merge Map) Map { + for k, v := range merge { + m[k] = v + } + return m +} + +// Transform builds a new Obj giving the transformer a chance +// to change the keys and values as it goes. This method requires that +// the wrapped object be a map[string]interface{} +func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map { + newMap := make(map[string]interface{}) + for k, v := range m { + modifiedKey, modifiedVal := transformer(k, v) + newMap[modifiedKey] = modifiedVal + } + return New(newMap) +} + +// TransformKeys builds a new map using the specified key mapping. +// +// Unspecified keys will be unaltered. +// This method requires that the wrapped object be a map[string]interface{} +func (m Map) TransformKeys(mapping map[string]string) Map { + return m.Transform(func(key string, value interface{}) (string, interface{}) { + if newKey, ok := mapping[key]; ok { + return newKey, value + } + return key, value + }) +} diff --git a/vendor/github.com/stretchr/objx/security.go b/vendor/github.com/stretchr/objx/security.go new file mode 100644 index 000000000..e052ff890 --- /dev/null +++ b/vendor/github.com/stretchr/objx/security.go @@ -0,0 +1,17 @@ +package objx + +import ( + "crypto/sha1" + "encoding/hex" +) + +// HashWithKey hashes the specified string using the security +// key. +func HashWithKey(data, key string) string { + hash := sha1.New() + _, err := hash.Write([]byte(data + ":" + key)) + if err != nil { + return "" + } + return hex.EncodeToString(hash.Sum(nil)) +} diff --git a/vendor/github.com/stretchr/objx/tests.go b/vendor/github.com/stretchr/objx/tests.go new file mode 100644 index 000000000..d9e0b479a --- /dev/null +++ b/vendor/github.com/stretchr/objx/tests.go @@ -0,0 +1,17 @@ +package objx + +// Has gets whether there is something at the specified selector +// or not. +// +// If m is nil, Has will always return false. +func (m Map) Has(selector string) bool { + if m == nil { + return false + } + return !m.Get(selector).IsNil() +} + +// IsNil gets whether the data is nil or not. +func (v *Value) IsNil() bool { + return v == nil || v.data == nil +} diff --git a/vendor/github.com/stretchr/objx/type_specific_codegen.go b/vendor/github.com/stretchr/objx/type_specific_codegen.go new file mode 100644 index 000000000..202a91f8c --- /dev/null +++ b/vendor/github.com/stretchr/objx/type_specific_codegen.go @@ -0,0 +1,2501 @@ +package objx + +/* + Inter (interface{} and []interface{}) +*/ + +// Inter gets the value as a interface{}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Inter(optionalDefault ...interface{}) interface{} { + if s, ok := v.data.(interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInter gets the value as a interface{}. +// +// Panics if the object is not a interface{}. +func (v *Value) MustInter() interface{} { + return v.data.(interface{}) +} + +// InterSlice gets the value as a []interface{}, returns the optionalDefault +// value or nil if the value is not a []interface{}. +func (v *Value) InterSlice(optionalDefault ...[]interface{}) []interface{} { + if s, ok := v.data.([]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInterSlice gets the value as a []interface{}. +// +// Panics if the object is not a []interface{}. +func (v *Value) MustInterSlice() []interface{} { + return v.data.([]interface{}) +} + +// IsInter gets whether the object contained is a interface{} or not. +func (v *Value) IsInter() bool { + _, ok := v.data.(interface{}) + return ok +} + +// IsInterSlice gets whether the object contained is a []interface{} or not. +func (v *Value) IsInterSlice() bool { + _, ok := v.data.([]interface{}) + return ok +} + +// EachInter calls the specified callback for each object +// in the []interface{}. +// +// Panics if the object is the wrong type. +func (v *Value) EachInter(callback func(int, interface{}) bool) *Value { + for index, val := range v.MustInterSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereInter uses the specified decider function to select items +// from the []interface{}. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInter(decider func(int, interface{}) bool) *Value { + var selected []interface{} + v.EachInter(func(index int, val interface{}) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupInter uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]interface{}. +func (v *Value) GroupInter(grouper func(int, interface{}) string) *Value { + groups := make(map[string][]interface{}) + v.EachInter(func(index int, val interface{}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]interface{}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceInter uses the specified function to replace each interface{}s +// by iterating each item. The data in the returned result will be a +// []interface{} containing the replaced items. +func (v *Value) ReplaceInter(replacer func(int, interface{}) interface{}) *Value { + arr := v.MustInterSlice() + replaced := make([]interface{}, len(arr)) + v.EachInter(func(index int, val interface{}) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectInter uses the specified collector function to collect a value +// for each of the interface{}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInter(collector func(int, interface{}) interface{}) *Value { + arr := v.MustInterSlice() + collected := make([]interface{}, len(arr)) + v.EachInter(func(index int, val interface{}) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + MSI (map[string]interface{} and []map[string]interface{}) +*/ + +// MSI gets the value as a map[string]interface{}, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} { + if s, ok := v.data.(map[string]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustMSI gets the value as a map[string]interface{}. +// +// Panics if the object is not a map[string]interface{}. +func (v *Value) MustMSI() map[string]interface{} { + return v.data.(map[string]interface{}) +} + +// MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault +// value or nil if the value is not a []map[string]interface{}. +func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} { + if s, ok := v.data.([]map[string]interface{}); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustMSISlice gets the value as a []map[string]interface{}. +// +// Panics if the object is not a []map[string]interface{}. +func (v *Value) MustMSISlice() []map[string]interface{} { + return v.data.([]map[string]interface{}) +} + +// IsMSI gets whether the object contained is a map[string]interface{} or not. +func (v *Value) IsMSI() bool { + _, ok := v.data.(map[string]interface{}) + return ok +} + +// IsMSISlice gets whether the object contained is a []map[string]interface{} or not. +func (v *Value) IsMSISlice() bool { + _, ok := v.data.([]map[string]interface{}) + return ok +} + +// EachMSI calls the specified callback for each object +// in the []map[string]interface{}. +// +// Panics if the object is the wrong type. +func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value { + for index, val := range v.MustMSISlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereMSI uses the specified decider function to select items +// from the []map[string]interface{}. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value { + var selected []map[string]interface{} + v.EachMSI(func(index int, val map[string]interface{}) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupMSI uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]map[string]interface{}. +func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value { + groups := make(map[string][]map[string]interface{}) + v.EachMSI(func(index int, val map[string]interface{}) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]map[string]interface{}, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceMSI uses the specified function to replace each map[string]interface{}s +// by iterating each item. The data in the returned result will be a +// []map[string]interface{} containing the replaced items. +func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value { + arr := v.MustMSISlice() + replaced := make([]map[string]interface{}, len(arr)) + v.EachMSI(func(index int, val map[string]interface{}) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectMSI uses the specified collector function to collect a value +// for each of the map[string]interface{}s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value { + arr := v.MustMSISlice() + collected := make([]interface{}, len(arr)) + v.EachMSI(func(index int, val map[string]interface{}) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + ObjxMap ((Map) and [](Map)) +*/ + +// ObjxMap gets the value as a (Map), returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) ObjxMap(optionalDefault ...(Map)) Map { + if s, ok := v.data.((Map)); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return New(nil) +} + +// MustObjxMap gets the value as a (Map). +// +// Panics if the object is not a (Map). +func (v *Value) MustObjxMap() Map { + return v.data.((Map)) +} + +// ObjxMapSlice gets the value as a [](Map), returns the optionalDefault +// value or nil if the value is not a [](Map). +func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) { + if s, ok := v.data.([](Map)); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustObjxMapSlice gets the value as a [](Map). +// +// Panics if the object is not a [](Map). +func (v *Value) MustObjxMapSlice() [](Map) { + return v.data.([](Map)) +} + +// IsObjxMap gets whether the object contained is a (Map) or not. +func (v *Value) IsObjxMap() bool { + _, ok := v.data.((Map)) + return ok +} + +// IsObjxMapSlice gets whether the object contained is a [](Map) or not. +func (v *Value) IsObjxMapSlice() bool { + _, ok := v.data.([](Map)) + return ok +} + +// EachObjxMap calls the specified callback for each object +// in the [](Map). +// +// Panics if the object is the wrong type. +func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value { + for index, val := range v.MustObjxMapSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereObjxMap uses the specified decider function to select items +// from the [](Map). The object contained in the result will contain +// only the selected items. +func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value { + var selected [](Map) + v.EachObjxMap(func(index int, val Map) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupObjxMap uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][](Map). +func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value { + groups := make(map[string][](Map)) + v.EachObjxMap(func(index int, val Map) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([](Map), 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceObjxMap uses the specified function to replace each (Map)s +// by iterating each item. The data in the returned result will be a +// [](Map) containing the replaced items. +func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value { + arr := v.MustObjxMapSlice() + replaced := make([](Map), len(arr)) + v.EachObjxMap(func(index int, val Map) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectObjxMap uses the specified collector function to collect a value +// for each of the (Map)s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value { + arr := v.MustObjxMapSlice() + collected := make([]interface{}, len(arr)) + v.EachObjxMap(func(index int, val Map) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Bool (bool and []bool) +*/ + +// Bool gets the value as a bool, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Bool(optionalDefault ...bool) bool { + if s, ok := v.data.(bool); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return false +} + +// MustBool gets the value as a bool. +// +// Panics if the object is not a bool. +func (v *Value) MustBool() bool { + return v.data.(bool) +} + +// BoolSlice gets the value as a []bool, returns the optionalDefault +// value or nil if the value is not a []bool. +func (v *Value) BoolSlice(optionalDefault ...[]bool) []bool { + if s, ok := v.data.([]bool); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustBoolSlice gets the value as a []bool. +// +// Panics if the object is not a []bool. +func (v *Value) MustBoolSlice() []bool { + return v.data.([]bool) +} + +// IsBool gets whether the object contained is a bool or not. +func (v *Value) IsBool() bool { + _, ok := v.data.(bool) + return ok +} + +// IsBoolSlice gets whether the object contained is a []bool or not. +func (v *Value) IsBoolSlice() bool { + _, ok := v.data.([]bool) + return ok +} + +// EachBool calls the specified callback for each object +// in the []bool. +// +// Panics if the object is the wrong type. +func (v *Value) EachBool(callback func(int, bool) bool) *Value { + for index, val := range v.MustBoolSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereBool uses the specified decider function to select items +// from the []bool. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereBool(decider func(int, bool) bool) *Value { + var selected []bool + v.EachBool(func(index int, val bool) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupBool uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]bool. +func (v *Value) GroupBool(grouper func(int, bool) string) *Value { + groups := make(map[string][]bool) + v.EachBool(func(index int, val bool) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]bool, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceBool uses the specified function to replace each bools +// by iterating each item. The data in the returned result will be a +// []bool containing the replaced items. +func (v *Value) ReplaceBool(replacer func(int, bool) bool) *Value { + arr := v.MustBoolSlice() + replaced := make([]bool, len(arr)) + v.EachBool(func(index int, val bool) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectBool uses the specified collector function to collect a value +// for each of the bools in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectBool(collector func(int, bool) interface{}) *Value { + arr := v.MustBoolSlice() + collected := make([]interface{}, len(arr)) + v.EachBool(func(index int, val bool) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Str (string and []string) +*/ + +// Str gets the value as a string, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Str(optionalDefault ...string) string { + if s, ok := v.data.(string); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return "" +} + +// MustStr gets the value as a string. +// +// Panics if the object is not a string. +func (v *Value) MustStr() string { + return v.data.(string) +} + +// StrSlice gets the value as a []string, returns the optionalDefault +// value or nil if the value is not a []string. +func (v *Value) StrSlice(optionalDefault ...[]string) []string { + if s, ok := v.data.([]string); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustStrSlice gets the value as a []string. +// +// Panics if the object is not a []string. +func (v *Value) MustStrSlice() []string { + return v.data.([]string) +} + +// IsStr gets whether the object contained is a string or not. +func (v *Value) IsStr() bool { + _, ok := v.data.(string) + return ok +} + +// IsStrSlice gets whether the object contained is a []string or not. +func (v *Value) IsStrSlice() bool { + _, ok := v.data.([]string) + return ok +} + +// EachStr calls the specified callback for each object +// in the []string. +// +// Panics if the object is the wrong type. +func (v *Value) EachStr(callback func(int, string) bool) *Value { + for index, val := range v.MustStrSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereStr uses the specified decider function to select items +// from the []string. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereStr(decider func(int, string) bool) *Value { + var selected []string + v.EachStr(func(index int, val string) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupStr uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]string. +func (v *Value) GroupStr(grouper func(int, string) string) *Value { + groups := make(map[string][]string) + v.EachStr(func(index int, val string) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]string, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceStr uses the specified function to replace each strings +// by iterating each item. The data in the returned result will be a +// []string containing the replaced items. +func (v *Value) ReplaceStr(replacer func(int, string) string) *Value { + arr := v.MustStrSlice() + replaced := make([]string, len(arr)) + v.EachStr(func(index int, val string) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectStr uses the specified collector function to collect a value +// for each of the strings in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectStr(collector func(int, string) interface{}) *Value { + arr := v.MustStrSlice() + collected := make([]interface{}, len(arr)) + v.EachStr(func(index int, val string) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Int (int and []int) +*/ + +// Int gets the value as a int, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int(optionalDefault ...int) int { + if s, ok := v.data.(int); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt gets the value as a int. +// +// Panics if the object is not a int. +func (v *Value) MustInt() int { + return v.data.(int) +} + +// IntSlice gets the value as a []int, returns the optionalDefault +// value or nil if the value is not a []int. +func (v *Value) IntSlice(optionalDefault ...[]int) []int { + if s, ok := v.data.([]int); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustIntSlice gets the value as a []int. +// +// Panics if the object is not a []int. +func (v *Value) MustIntSlice() []int { + return v.data.([]int) +} + +// IsInt gets whether the object contained is a int or not. +func (v *Value) IsInt() bool { + _, ok := v.data.(int) + return ok +} + +// IsIntSlice gets whether the object contained is a []int or not. +func (v *Value) IsIntSlice() bool { + _, ok := v.data.([]int) + return ok +} + +// EachInt calls the specified callback for each object +// in the []int. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt(callback func(int, int) bool) *Value { + for index, val := range v.MustIntSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereInt uses the specified decider function to select items +// from the []int. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt(decider func(int, int) bool) *Value { + var selected []int + v.EachInt(func(index int, val int) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupInt uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int. +func (v *Value) GroupInt(grouper func(int, int) string) *Value { + groups := make(map[string][]int) + v.EachInt(func(index int, val int) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceInt uses the specified function to replace each ints +// by iterating each item. The data in the returned result will be a +// []int containing the replaced items. +func (v *Value) ReplaceInt(replacer func(int, int) int) *Value { + arr := v.MustIntSlice() + replaced := make([]int, len(arr)) + v.EachInt(func(index int, val int) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectInt uses the specified collector function to collect a value +// for each of the ints in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt(collector func(int, int) interface{}) *Value { + arr := v.MustIntSlice() + collected := make([]interface{}, len(arr)) + v.EachInt(func(index int, val int) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Int8 (int8 and []int8) +*/ + +// Int8 gets the value as a int8, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int8(optionalDefault ...int8) int8 { + if s, ok := v.data.(int8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt8 gets the value as a int8. +// +// Panics if the object is not a int8. +func (v *Value) MustInt8() int8 { + return v.data.(int8) +} + +// Int8Slice gets the value as a []int8, returns the optionalDefault +// value or nil if the value is not a []int8. +func (v *Value) Int8Slice(optionalDefault ...[]int8) []int8 { + if s, ok := v.data.([]int8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt8Slice gets the value as a []int8. +// +// Panics if the object is not a []int8. +func (v *Value) MustInt8Slice() []int8 { + return v.data.([]int8) +} + +// IsInt8 gets whether the object contained is a int8 or not. +func (v *Value) IsInt8() bool { + _, ok := v.data.(int8) + return ok +} + +// IsInt8Slice gets whether the object contained is a []int8 or not. +func (v *Value) IsInt8Slice() bool { + _, ok := v.data.([]int8) + return ok +} + +// EachInt8 calls the specified callback for each object +// in the []int8. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt8(callback func(int, int8) bool) *Value { + for index, val := range v.MustInt8Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereInt8 uses the specified decider function to select items +// from the []int8. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt8(decider func(int, int8) bool) *Value { + var selected []int8 + v.EachInt8(func(index int, val int8) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupInt8 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int8. +func (v *Value) GroupInt8(grouper func(int, int8) string) *Value { + groups := make(map[string][]int8) + v.EachInt8(func(index int, val int8) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int8, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceInt8 uses the specified function to replace each int8s +// by iterating each item. The data in the returned result will be a +// []int8 containing the replaced items. +func (v *Value) ReplaceInt8(replacer func(int, int8) int8) *Value { + arr := v.MustInt8Slice() + replaced := make([]int8, len(arr)) + v.EachInt8(func(index int, val int8) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectInt8 uses the specified collector function to collect a value +// for each of the int8s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt8(collector func(int, int8) interface{}) *Value { + arr := v.MustInt8Slice() + collected := make([]interface{}, len(arr)) + v.EachInt8(func(index int, val int8) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Int16 (int16 and []int16) +*/ + +// Int16 gets the value as a int16, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int16(optionalDefault ...int16) int16 { + if s, ok := v.data.(int16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt16 gets the value as a int16. +// +// Panics if the object is not a int16. +func (v *Value) MustInt16() int16 { + return v.data.(int16) +} + +// Int16Slice gets the value as a []int16, returns the optionalDefault +// value or nil if the value is not a []int16. +func (v *Value) Int16Slice(optionalDefault ...[]int16) []int16 { + if s, ok := v.data.([]int16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt16Slice gets the value as a []int16. +// +// Panics if the object is not a []int16. +func (v *Value) MustInt16Slice() []int16 { + return v.data.([]int16) +} + +// IsInt16 gets whether the object contained is a int16 or not. +func (v *Value) IsInt16() bool { + _, ok := v.data.(int16) + return ok +} + +// IsInt16Slice gets whether the object contained is a []int16 or not. +func (v *Value) IsInt16Slice() bool { + _, ok := v.data.([]int16) + return ok +} + +// EachInt16 calls the specified callback for each object +// in the []int16. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt16(callback func(int, int16) bool) *Value { + for index, val := range v.MustInt16Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereInt16 uses the specified decider function to select items +// from the []int16. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt16(decider func(int, int16) bool) *Value { + var selected []int16 + v.EachInt16(func(index int, val int16) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupInt16 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int16. +func (v *Value) GroupInt16(grouper func(int, int16) string) *Value { + groups := make(map[string][]int16) + v.EachInt16(func(index int, val int16) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int16, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceInt16 uses the specified function to replace each int16s +// by iterating each item. The data in the returned result will be a +// []int16 containing the replaced items. +func (v *Value) ReplaceInt16(replacer func(int, int16) int16) *Value { + arr := v.MustInt16Slice() + replaced := make([]int16, len(arr)) + v.EachInt16(func(index int, val int16) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectInt16 uses the specified collector function to collect a value +// for each of the int16s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt16(collector func(int, int16) interface{}) *Value { + arr := v.MustInt16Slice() + collected := make([]interface{}, len(arr)) + v.EachInt16(func(index int, val int16) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Int32 (int32 and []int32) +*/ + +// Int32 gets the value as a int32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int32(optionalDefault ...int32) int32 { + if s, ok := v.data.(int32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt32 gets the value as a int32. +// +// Panics if the object is not a int32. +func (v *Value) MustInt32() int32 { + return v.data.(int32) +} + +// Int32Slice gets the value as a []int32, returns the optionalDefault +// value or nil if the value is not a []int32. +func (v *Value) Int32Slice(optionalDefault ...[]int32) []int32 { + if s, ok := v.data.([]int32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt32Slice gets the value as a []int32. +// +// Panics if the object is not a []int32. +func (v *Value) MustInt32Slice() []int32 { + return v.data.([]int32) +} + +// IsInt32 gets whether the object contained is a int32 or not. +func (v *Value) IsInt32() bool { + _, ok := v.data.(int32) + return ok +} + +// IsInt32Slice gets whether the object contained is a []int32 or not. +func (v *Value) IsInt32Slice() bool { + _, ok := v.data.([]int32) + return ok +} + +// EachInt32 calls the specified callback for each object +// in the []int32. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt32(callback func(int, int32) bool) *Value { + for index, val := range v.MustInt32Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereInt32 uses the specified decider function to select items +// from the []int32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt32(decider func(int, int32) bool) *Value { + var selected []int32 + v.EachInt32(func(index int, val int32) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupInt32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int32. +func (v *Value) GroupInt32(grouper func(int, int32) string) *Value { + groups := make(map[string][]int32) + v.EachInt32(func(index int, val int32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceInt32 uses the specified function to replace each int32s +// by iterating each item. The data in the returned result will be a +// []int32 containing the replaced items. +func (v *Value) ReplaceInt32(replacer func(int, int32) int32) *Value { + arr := v.MustInt32Slice() + replaced := make([]int32, len(arr)) + v.EachInt32(func(index int, val int32) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectInt32 uses the specified collector function to collect a value +// for each of the int32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt32(collector func(int, int32) interface{}) *Value { + arr := v.MustInt32Slice() + collected := make([]interface{}, len(arr)) + v.EachInt32(func(index int, val int32) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Int64 (int64 and []int64) +*/ + +// Int64 gets the value as a int64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Int64(optionalDefault ...int64) int64 { + if s, ok := v.data.(int64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustInt64 gets the value as a int64. +// +// Panics if the object is not a int64. +func (v *Value) MustInt64() int64 { + return v.data.(int64) +} + +// Int64Slice gets the value as a []int64, returns the optionalDefault +// value or nil if the value is not a []int64. +func (v *Value) Int64Slice(optionalDefault ...[]int64) []int64 { + if s, ok := v.data.([]int64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustInt64Slice gets the value as a []int64. +// +// Panics if the object is not a []int64. +func (v *Value) MustInt64Slice() []int64 { + return v.data.([]int64) +} + +// IsInt64 gets whether the object contained is a int64 or not. +func (v *Value) IsInt64() bool { + _, ok := v.data.(int64) + return ok +} + +// IsInt64Slice gets whether the object contained is a []int64 or not. +func (v *Value) IsInt64Slice() bool { + _, ok := v.data.([]int64) + return ok +} + +// EachInt64 calls the specified callback for each object +// in the []int64. +// +// Panics if the object is the wrong type. +func (v *Value) EachInt64(callback func(int, int64) bool) *Value { + for index, val := range v.MustInt64Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereInt64 uses the specified decider function to select items +// from the []int64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereInt64(decider func(int, int64) bool) *Value { + var selected []int64 + v.EachInt64(func(index int, val int64) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupInt64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]int64. +func (v *Value) GroupInt64(grouper func(int, int64) string) *Value { + groups := make(map[string][]int64) + v.EachInt64(func(index int, val int64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]int64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceInt64 uses the specified function to replace each int64s +// by iterating each item. The data in the returned result will be a +// []int64 containing the replaced items. +func (v *Value) ReplaceInt64(replacer func(int, int64) int64) *Value { + arr := v.MustInt64Slice() + replaced := make([]int64, len(arr)) + v.EachInt64(func(index int, val int64) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectInt64 uses the specified collector function to collect a value +// for each of the int64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectInt64(collector func(int, int64) interface{}) *Value { + arr := v.MustInt64Slice() + collected := make([]interface{}, len(arr)) + v.EachInt64(func(index int, val int64) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Uint (uint and []uint) +*/ + +// Uint gets the value as a uint, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint(optionalDefault ...uint) uint { + if s, ok := v.data.(uint); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint gets the value as a uint. +// +// Panics if the object is not a uint. +func (v *Value) MustUint() uint { + return v.data.(uint) +} + +// UintSlice gets the value as a []uint, returns the optionalDefault +// value or nil if the value is not a []uint. +func (v *Value) UintSlice(optionalDefault ...[]uint) []uint { + if s, ok := v.data.([]uint); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUintSlice gets the value as a []uint. +// +// Panics if the object is not a []uint. +func (v *Value) MustUintSlice() []uint { + return v.data.([]uint) +} + +// IsUint gets whether the object contained is a uint or not. +func (v *Value) IsUint() bool { + _, ok := v.data.(uint) + return ok +} + +// IsUintSlice gets whether the object contained is a []uint or not. +func (v *Value) IsUintSlice() bool { + _, ok := v.data.([]uint) + return ok +} + +// EachUint calls the specified callback for each object +// in the []uint. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint(callback func(int, uint) bool) *Value { + for index, val := range v.MustUintSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereUint uses the specified decider function to select items +// from the []uint. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint(decider func(int, uint) bool) *Value { + var selected []uint + v.EachUint(func(index int, val uint) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupUint uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint. +func (v *Value) GroupUint(grouper func(int, uint) string) *Value { + groups := make(map[string][]uint) + v.EachUint(func(index int, val uint) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceUint uses the specified function to replace each uints +// by iterating each item. The data in the returned result will be a +// []uint containing the replaced items. +func (v *Value) ReplaceUint(replacer func(int, uint) uint) *Value { + arr := v.MustUintSlice() + replaced := make([]uint, len(arr)) + v.EachUint(func(index int, val uint) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectUint uses the specified collector function to collect a value +// for each of the uints in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint(collector func(int, uint) interface{}) *Value { + arr := v.MustUintSlice() + collected := make([]interface{}, len(arr)) + v.EachUint(func(index int, val uint) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Uint8 (uint8 and []uint8) +*/ + +// Uint8 gets the value as a uint8, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint8(optionalDefault ...uint8) uint8 { + if s, ok := v.data.(uint8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint8 gets the value as a uint8. +// +// Panics if the object is not a uint8. +func (v *Value) MustUint8() uint8 { + return v.data.(uint8) +} + +// Uint8Slice gets the value as a []uint8, returns the optionalDefault +// value or nil if the value is not a []uint8. +func (v *Value) Uint8Slice(optionalDefault ...[]uint8) []uint8 { + if s, ok := v.data.([]uint8); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint8Slice gets the value as a []uint8. +// +// Panics if the object is not a []uint8. +func (v *Value) MustUint8Slice() []uint8 { + return v.data.([]uint8) +} + +// IsUint8 gets whether the object contained is a uint8 or not. +func (v *Value) IsUint8() bool { + _, ok := v.data.(uint8) + return ok +} + +// IsUint8Slice gets whether the object contained is a []uint8 or not. +func (v *Value) IsUint8Slice() bool { + _, ok := v.data.([]uint8) + return ok +} + +// EachUint8 calls the specified callback for each object +// in the []uint8. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint8(callback func(int, uint8) bool) *Value { + for index, val := range v.MustUint8Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereUint8 uses the specified decider function to select items +// from the []uint8. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint8(decider func(int, uint8) bool) *Value { + var selected []uint8 + v.EachUint8(func(index int, val uint8) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupUint8 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint8. +func (v *Value) GroupUint8(grouper func(int, uint8) string) *Value { + groups := make(map[string][]uint8) + v.EachUint8(func(index int, val uint8) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint8, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceUint8 uses the specified function to replace each uint8s +// by iterating each item. The data in the returned result will be a +// []uint8 containing the replaced items. +func (v *Value) ReplaceUint8(replacer func(int, uint8) uint8) *Value { + arr := v.MustUint8Slice() + replaced := make([]uint8, len(arr)) + v.EachUint8(func(index int, val uint8) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectUint8 uses the specified collector function to collect a value +// for each of the uint8s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint8(collector func(int, uint8) interface{}) *Value { + arr := v.MustUint8Slice() + collected := make([]interface{}, len(arr)) + v.EachUint8(func(index int, val uint8) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Uint16 (uint16 and []uint16) +*/ + +// Uint16 gets the value as a uint16, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint16(optionalDefault ...uint16) uint16 { + if s, ok := v.data.(uint16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint16 gets the value as a uint16. +// +// Panics if the object is not a uint16. +func (v *Value) MustUint16() uint16 { + return v.data.(uint16) +} + +// Uint16Slice gets the value as a []uint16, returns the optionalDefault +// value or nil if the value is not a []uint16. +func (v *Value) Uint16Slice(optionalDefault ...[]uint16) []uint16 { + if s, ok := v.data.([]uint16); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint16Slice gets the value as a []uint16. +// +// Panics if the object is not a []uint16. +func (v *Value) MustUint16Slice() []uint16 { + return v.data.([]uint16) +} + +// IsUint16 gets whether the object contained is a uint16 or not. +func (v *Value) IsUint16() bool { + _, ok := v.data.(uint16) + return ok +} + +// IsUint16Slice gets whether the object contained is a []uint16 or not. +func (v *Value) IsUint16Slice() bool { + _, ok := v.data.([]uint16) + return ok +} + +// EachUint16 calls the specified callback for each object +// in the []uint16. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint16(callback func(int, uint16) bool) *Value { + for index, val := range v.MustUint16Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereUint16 uses the specified decider function to select items +// from the []uint16. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint16(decider func(int, uint16) bool) *Value { + var selected []uint16 + v.EachUint16(func(index int, val uint16) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupUint16 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint16. +func (v *Value) GroupUint16(grouper func(int, uint16) string) *Value { + groups := make(map[string][]uint16) + v.EachUint16(func(index int, val uint16) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint16, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceUint16 uses the specified function to replace each uint16s +// by iterating each item. The data in the returned result will be a +// []uint16 containing the replaced items. +func (v *Value) ReplaceUint16(replacer func(int, uint16) uint16) *Value { + arr := v.MustUint16Slice() + replaced := make([]uint16, len(arr)) + v.EachUint16(func(index int, val uint16) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectUint16 uses the specified collector function to collect a value +// for each of the uint16s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint16(collector func(int, uint16) interface{}) *Value { + arr := v.MustUint16Slice() + collected := make([]interface{}, len(arr)) + v.EachUint16(func(index int, val uint16) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Uint32 (uint32 and []uint32) +*/ + +// Uint32 gets the value as a uint32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint32(optionalDefault ...uint32) uint32 { + if s, ok := v.data.(uint32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint32 gets the value as a uint32. +// +// Panics if the object is not a uint32. +func (v *Value) MustUint32() uint32 { + return v.data.(uint32) +} + +// Uint32Slice gets the value as a []uint32, returns the optionalDefault +// value or nil if the value is not a []uint32. +func (v *Value) Uint32Slice(optionalDefault ...[]uint32) []uint32 { + if s, ok := v.data.([]uint32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint32Slice gets the value as a []uint32. +// +// Panics if the object is not a []uint32. +func (v *Value) MustUint32Slice() []uint32 { + return v.data.([]uint32) +} + +// IsUint32 gets whether the object contained is a uint32 or not. +func (v *Value) IsUint32() bool { + _, ok := v.data.(uint32) + return ok +} + +// IsUint32Slice gets whether the object contained is a []uint32 or not. +func (v *Value) IsUint32Slice() bool { + _, ok := v.data.([]uint32) + return ok +} + +// EachUint32 calls the specified callback for each object +// in the []uint32. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint32(callback func(int, uint32) bool) *Value { + for index, val := range v.MustUint32Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereUint32 uses the specified decider function to select items +// from the []uint32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint32(decider func(int, uint32) bool) *Value { + var selected []uint32 + v.EachUint32(func(index int, val uint32) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupUint32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint32. +func (v *Value) GroupUint32(grouper func(int, uint32) string) *Value { + groups := make(map[string][]uint32) + v.EachUint32(func(index int, val uint32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceUint32 uses the specified function to replace each uint32s +// by iterating each item. The data in the returned result will be a +// []uint32 containing the replaced items. +func (v *Value) ReplaceUint32(replacer func(int, uint32) uint32) *Value { + arr := v.MustUint32Slice() + replaced := make([]uint32, len(arr)) + v.EachUint32(func(index int, val uint32) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectUint32 uses the specified collector function to collect a value +// for each of the uint32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint32(collector func(int, uint32) interface{}) *Value { + arr := v.MustUint32Slice() + collected := make([]interface{}, len(arr)) + v.EachUint32(func(index int, val uint32) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Uint64 (uint64 and []uint64) +*/ + +// Uint64 gets the value as a uint64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uint64(optionalDefault ...uint64) uint64 { + if s, ok := v.data.(uint64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUint64 gets the value as a uint64. +// +// Panics if the object is not a uint64. +func (v *Value) MustUint64() uint64 { + return v.data.(uint64) +} + +// Uint64Slice gets the value as a []uint64, returns the optionalDefault +// value or nil if the value is not a []uint64. +func (v *Value) Uint64Slice(optionalDefault ...[]uint64) []uint64 { + if s, ok := v.data.([]uint64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUint64Slice gets the value as a []uint64. +// +// Panics if the object is not a []uint64. +func (v *Value) MustUint64Slice() []uint64 { + return v.data.([]uint64) +} + +// IsUint64 gets whether the object contained is a uint64 or not. +func (v *Value) IsUint64() bool { + _, ok := v.data.(uint64) + return ok +} + +// IsUint64Slice gets whether the object contained is a []uint64 or not. +func (v *Value) IsUint64Slice() bool { + _, ok := v.data.([]uint64) + return ok +} + +// EachUint64 calls the specified callback for each object +// in the []uint64. +// +// Panics if the object is the wrong type. +func (v *Value) EachUint64(callback func(int, uint64) bool) *Value { + for index, val := range v.MustUint64Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereUint64 uses the specified decider function to select items +// from the []uint64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUint64(decider func(int, uint64) bool) *Value { + var selected []uint64 + v.EachUint64(func(index int, val uint64) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupUint64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uint64. +func (v *Value) GroupUint64(grouper func(int, uint64) string) *Value { + groups := make(map[string][]uint64) + v.EachUint64(func(index int, val uint64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uint64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceUint64 uses the specified function to replace each uint64s +// by iterating each item. The data in the returned result will be a +// []uint64 containing the replaced items. +func (v *Value) ReplaceUint64(replacer func(int, uint64) uint64) *Value { + arr := v.MustUint64Slice() + replaced := make([]uint64, len(arr)) + v.EachUint64(func(index int, val uint64) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectUint64 uses the specified collector function to collect a value +// for each of the uint64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUint64(collector func(int, uint64) interface{}) *Value { + arr := v.MustUint64Slice() + collected := make([]interface{}, len(arr)) + v.EachUint64(func(index int, val uint64) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Uintptr (uintptr and []uintptr) +*/ + +// Uintptr gets the value as a uintptr, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Uintptr(optionalDefault ...uintptr) uintptr { + if s, ok := v.data.(uintptr); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustUintptr gets the value as a uintptr. +// +// Panics if the object is not a uintptr. +func (v *Value) MustUintptr() uintptr { + return v.data.(uintptr) +} + +// UintptrSlice gets the value as a []uintptr, returns the optionalDefault +// value or nil if the value is not a []uintptr. +func (v *Value) UintptrSlice(optionalDefault ...[]uintptr) []uintptr { + if s, ok := v.data.([]uintptr); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustUintptrSlice gets the value as a []uintptr. +// +// Panics if the object is not a []uintptr. +func (v *Value) MustUintptrSlice() []uintptr { + return v.data.([]uintptr) +} + +// IsUintptr gets whether the object contained is a uintptr or not. +func (v *Value) IsUintptr() bool { + _, ok := v.data.(uintptr) + return ok +} + +// IsUintptrSlice gets whether the object contained is a []uintptr or not. +func (v *Value) IsUintptrSlice() bool { + _, ok := v.data.([]uintptr) + return ok +} + +// EachUintptr calls the specified callback for each object +// in the []uintptr. +// +// Panics if the object is the wrong type. +func (v *Value) EachUintptr(callback func(int, uintptr) bool) *Value { + for index, val := range v.MustUintptrSlice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereUintptr uses the specified decider function to select items +// from the []uintptr. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereUintptr(decider func(int, uintptr) bool) *Value { + var selected []uintptr + v.EachUintptr(func(index int, val uintptr) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupUintptr uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]uintptr. +func (v *Value) GroupUintptr(grouper func(int, uintptr) string) *Value { + groups := make(map[string][]uintptr) + v.EachUintptr(func(index int, val uintptr) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]uintptr, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceUintptr uses the specified function to replace each uintptrs +// by iterating each item. The data in the returned result will be a +// []uintptr containing the replaced items. +func (v *Value) ReplaceUintptr(replacer func(int, uintptr) uintptr) *Value { + arr := v.MustUintptrSlice() + replaced := make([]uintptr, len(arr)) + v.EachUintptr(func(index int, val uintptr) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectUintptr uses the specified collector function to collect a value +// for each of the uintptrs in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectUintptr(collector func(int, uintptr) interface{}) *Value { + arr := v.MustUintptrSlice() + collected := make([]interface{}, len(arr)) + v.EachUintptr(func(index int, val uintptr) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Float32 (float32 and []float32) +*/ + +// Float32 gets the value as a float32, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Float32(optionalDefault ...float32) float32 { + if s, ok := v.data.(float32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustFloat32 gets the value as a float32. +// +// Panics if the object is not a float32. +func (v *Value) MustFloat32() float32 { + return v.data.(float32) +} + +// Float32Slice gets the value as a []float32, returns the optionalDefault +// value or nil if the value is not a []float32. +func (v *Value) Float32Slice(optionalDefault ...[]float32) []float32 { + if s, ok := v.data.([]float32); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustFloat32Slice gets the value as a []float32. +// +// Panics if the object is not a []float32. +func (v *Value) MustFloat32Slice() []float32 { + return v.data.([]float32) +} + +// IsFloat32 gets whether the object contained is a float32 or not. +func (v *Value) IsFloat32() bool { + _, ok := v.data.(float32) + return ok +} + +// IsFloat32Slice gets whether the object contained is a []float32 or not. +func (v *Value) IsFloat32Slice() bool { + _, ok := v.data.([]float32) + return ok +} + +// EachFloat32 calls the specified callback for each object +// in the []float32. +// +// Panics if the object is the wrong type. +func (v *Value) EachFloat32(callback func(int, float32) bool) *Value { + for index, val := range v.MustFloat32Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereFloat32 uses the specified decider function to select items +// from the []float32. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereFloat32(decider func(int, float32) bool) *Value { + var selected []float32 + v.EachFloat32(func(index int, val float32) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupFloat32 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]float32. +func (v *Value) GroupFloat32(grouper func(int, float32) string) *Value { + groups := make(map[string][]float32) + v.EachFloat32(func(index int, val float32) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]float32, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceFloat32 uses the specified function to replace each float32s +// by iterating each item. The data in the returned result will be a +// []float32 containing the replaced items. +func (v *Value) ReplaceFloat32(replacer func(int, float32) float32) *Value { + arr := v.MustFloat32Slice() + replaced := make([]float32, len(arr)) + v.EachFloat32(func(index int, val float32) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectFloat32 uses the specified collector function to collect a value +// for each of the float32s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectFloat32(collector func(int, float32) interface{}) *Value { + arr := v.MustFloat32Slice() + collected := make([]interface{}, len(arr)) + v.EachFloat32(func(index int, val float32) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Float64 (float64 and []float64) +*/ + +// Float64 gets the value as a float64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Float64(optionalDefault ...float64) float64 { + if s, ok := v.data.(float64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustFloat64 gets the value as a float64. +// +// Panics if the object is not a float64. +func (v *Value) MustFloat64() float64 { + return v.data.(float64) +} + +// Float64Slice gets the value as a []float64, returns the optionalDefault +// value or nil if the value is not a []float64. +func (v *Value) Float64Slice(optionalDefault ...[]float64) []float64 { + if s, ok := v.data.([]float64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustFloat64Slice gets the value as a []float64. +// +// Panics if the object is not a []float64. +func (v *Value) MustFloat64Slice() []float64 { + return v.data.([]float64) +} + +// IsFloat64 gets whether the object contained is a float64 or not. +func (v *Value) IsFloat64() bool { + _, ok := v.data.(float64) + return ok +} + +// IsFloat64Slice gets whether the object contained is a []float64 or not. +func (v *Value) IsFloat64Slice() bool { + _, ok := v.data.([]float64) + return ok +} + +// EachFloat64 calls the specified callback for each object +// in the []float64. +// +// Panics if the object is the wrong type. +func (v *Value) EachFloat64(callback func(int, float64) bool) *Value { + for index, val := range v.MustFloat64Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereFloat64 uses the specified decider function to select items +// from the []float64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereFloat64(decider func(int, float64) bool) *Value { + var selected []float64 + v.EachFloat64(func(index int, val float64) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupFloat64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]float64. +func (v *Value) GroupFloat64(grouper func(int, float64) string) *Value { + groups := make(map[string][]float64) + v.EachFloat64(func(index int, val float64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]float64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceFloat64 uses the specified function to replace each float64s +// by iterating each item. The data in the returned result will be a +// []float64 containing the replaced items. +func (v *Value) ReplaceFloat64(replacer func(int, float64) float64) *Value { + arr := v.MustFloat64Slice() + replaced := make([]float64, len(arr)) + v.EachFloat64(func(index int, val float64) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectFloat64 uses the specified collector function to collect a value +// for each of the float64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectFloat64(collector func(int, float64) interface{}) *Value { + arr := v.MustFloat64Slice() + collected := make([]interface{}, len(arr)) + v.EachFloat64(func(index int, val float64) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Complex64 (complex64 and []complex64) +*/ + +// Complex64 gets the value as a complex64, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Complex64(optionalDefault ...complex64) complex64 { + if s, ok := v.data.(complex64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustComplex64 gets the value as a complex64. +// +// Panics if the object is not a complex64. +func (v *Value) MustComplex64() complex64 { + return v.data.(complex64) +} + +// Complex64Slice gets the value as a []complex64, returns the optionalDefault +// value or nil if the value is not a []complex64. +func (v *Value) Complex64Slice(optionalDefault ...[]complex64) []complex64 { + if s, ok := v.data.([]complex64); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustComplex64Slice gets the value as a []complex64. +// +// Panics if the object is not a []complex64. +func (v *Value) MustComplex64Slice() []complex64 { + return v.data.([]complex64) +} + +// IsComplex64 gets whether the object contained is a complex64 or not. +func (v *Value) IsComplex64() bool { + _, ok := v.data.(complex64) + return ok +} + +// IsComplex64Slice gets whether the object contained is a []complex64 or not. +func (v *Value) IsComplex64Slice() bool { + _, ok := v.data.([]complex64) + return ok +} + +// EachComplex64 calls the specified callback for each object +// in the []complex64. +// +// Panics if the object is the wrong type. +func (v *Value) EachComplex64(callback func(int, complex64) bool) *Value { + for index, val := range v.MustComplex64Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereComplex64 uses the specified decider function to select items +// from the []complex64. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereComplex64(decider func(int, complex64) bool) *Value { + var selected []complex64 + v.EachComplex64(func(index int, val complex64) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupComplex64 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]complex64. +func (v *Value) GroupComplex64(grouper func(int, complex64) string) *Value { + groups := make(map[string][]complex64) + v.EachComplex64(func(index int, val complex64) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]complex64, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceComplex64 uses the specified function to replace each complex64s +// by iterating each item. The data in the returned result will be a +// []complex64 containing the replaced items. +func (v *Value) ReplaceComplex64(replacer func(int, complex64) complex64) *Value { + arr := v.MustComplex64Slice() + replaced := make([]complex64, len(arr)) + v.EachComplex64(func(index int, val complex64) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectComplex64 uses the specified collector function to collect a value +// for each of the complex64s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectComplex64(collector func(int, complex64) interface{}) *Value { + arr := v.MustComplex64Slice() + collected := make([]interface{}, len(arr)) + v.EachComplex64(func(index int, val complex64) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} + +/* + Complex128 (complex128 and []complex128) +*/ + +// Complex128 gets the value as a complex128, returns the optionalDefault +// value or a system default object if the value is the wrong type. +func (v *Value) Complex128(optionalDefault ...complex128) complex128 { + if s, ok := v.data.(complex128); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return 0 +} + +// MustComplex128 gets the value as a complex128. +// +// Panics if the object is not a complex128. +func (v *Value) MustComplex128() complex128 { + return v.data.(complex128) +} + +// Complex128Slice gets the value as a []complex128, returns the optionalDefault +// value or nil if the value is not a []complex128. +func (v *Value) Complex128Slice(optionalDefault ...[]complex128) []complex128 { + if s, ok := v.data.([]complex128); ok { + return s + } + if len(optionalDefault) == 1 { + return optionalDefault[0] + } + return nil +} + +// MustComplex128Slice gets the value as a []complex128. +// +// Panics if the object is not a []complex128. +func (v *Value) MustComplex128Slice() []complex128 { + return v.data.([]complex128) +} + +// IsComplex128 gets whether the object contained is a complex128 or not. +func (v *Value) IsComplex128() bool { + _, ok := v.data.(complex128) + return ok +} + +// IsComplex128Slice gets whether the object contained is a []complex128 or not. +func (v *Value) IsComplex128Slice() bool { + _, ok := v.data.([]complex128) + return ok +} + +// EachComplex128 calls the specified callback for each object +// in the []complex128. +// +// Panics if the object is the wrong type. +func (v *Value) EachComplex128(callback func(int, complex128) bool) *Value { + for index, val := range v.MustComplex128Slice() { + carryon := callback(index, val) + if !carryon { + break + } + } + return v +} + +// WhereComplex128 uses the specified decider function to select items +// from the []complex128. The object contained in the result will contain +// only the selected items. +func (v *Value) WhereComplex128(decider func(int, complex128) bool) *Value { + var selected []complex128 + v.EachComplex128(func(index int, val complex128) bool { + shouldSelect := decider(index, val) + if !shouldSelect { + selected = append(selected, val) + } + return true + }) + return &Value{data: selected} +} + +// GroupComplex128 uses the specified grouper function to group the items +// keyed by the return of the grouper. The object contained in the +// result will contain a map[string][]complex128. +func (v *Value) GroupComplex128(grouper func(int, complex128) string) *Value { + groups := make(map[string][]complex128) + v.EachComplex128(func(index int, val complex128) bool { + group := grouper(index, val) + if _, ok := groups[group]; !ok { + groups[group] = make([]complex128, 0) + } + groups[group] = append(groups[group], val) + return true + }) + return &Value{data: groups} +} + +// ReplaceComplex128 uses the specified function to replace each complex128s +// by iterating each item. The data in the returned result will be a +// []complex128 containing the replaced items. +func (v *Value) ReplaceComplex128(replacer func(int, complex128) complex128) *Value { + arr := v.MustComplex128Slice() + replaced := make([]complex128, len(arr)) + v.EachComplex128(func(index int, val complex128) bool { + replaced[index] = replacer(index, val) + return true + }) + return &Value{data: replaced} +} + +// CollectComplex128 uses the specified collector function to collect a value +// for each of the complex128s in the slice. The data returned will be a +// []interface{}. +func (v *Value) CollectComplex128(collector func(int, complex128) interface{}) *Value { + arr := v.MustComplex128Slice() + collected := make([]interface{}, len(arr)) + v.EachComplex128(func(index int, val complex128) bool { + collected[index] = collector(index, val) + return true + }) + return &Value{data: collected} +} diff --git a/vendor/github.com/stretchr/objx/value.go b/vendor/github.com/stretchr/objx/value.go new file mode 100644 index 000000000..956a2211d --- /dev/null +++ b/vendor/github.com/stretchr/objx/value.go @@ -0,0 +1,56 @@ +package objx + +import ( + "fmt" + "strconv" +) + +// Value provides methods for extracting interface{} data in various +// types. +type Value struct { + // data contains the raw data being managed by this Value + data interface{} +} + +// Data returns the raw data contained by this Value +func (v *Value) Data() interface{} { + return v.data +} + +// String returns the value always as a string +func (v *Value) String() string { + switch { + case v.IsStr(): + return v.Str() + case v.IsBool(): + return strconv.FormatBool(v.Bool()) + case v.IsFloat32(): + return strconv.FormatFloat(float64(v.Float32()), 'f', -1, 32) + case v.IsFloat64(): + return strconv.FormatFloat(v.Float64(), 'f', -1, 64) + case v.IsInt(): + return strconv.FormatInt(int64(v.Int()), 10) + case v.IsInt(): + return strconv.FormatInt(int64(v.Int()), 10) + case v.IsInt8(): + return strconv.FormatInt(int64(v.Int8()), 10) + case v.IsInt16(): + return strconv.FormatInt(int64(v.Int16()), 10) + case v.IsInt32(): + return strconv.FormatInt(int64(v.Int32()), 10) + case v.IsInt64(): + return strconv.FormatInt(v.Int64(), 10) + case v.IsUint(): + return strconv.FormatUint(uint64(v.Uint()), 10) + case v.IsUint8(): + return strconv.FormatUint(uint64(v.Uint8()), 10) + case v.IsUint16(): + return strconv.FormatUint(uint64(v.Uint16()), 10) + case v.IsUint32(): + return strconv.FormatUint(uint64(v.Uint32()), 10) + case v.IsUint64(): + return strconv.FormatUint(v.Uint64(), 10) + } + + return fmt.Sprintf("%#v", v.Data()) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go new file mode 100644 index 000000000..ae06a54e2 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -0,0 +1,349 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND + */ + +package assert + +import ( + http "net/http" + url "net/url" + time "time" +) + +// Conditionf uses a Comparison to assert a complex condition. +func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool { + return Condition(t, comp, append([]interface{}{msg}, args...)...) +} + +// Containsf asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { + return Contains(t, s, contains, append([]interface{}{msg}, args...)...) +} + +// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + return DirExists(t, path, append([]interface{}{msg}, args...)...) +} + +// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) +} + +// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Emptyf(t, obj, "error message %s", "formatted") +func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + return Empty(t, object, append([]interface{}{msg}, args...)...) +} + +// Equalf asserts that two objects are equal. +// +// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { + return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) +} + +// EqualValuesf asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123)) +func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Errorf asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } +func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { + return Error(t, err, append([]interface{}{msg}, args...)...) +} + +// Exactlyf asserts that two objects are equal in value and type. +// +// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123)) +func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Failf reports a failure through +func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { + return Fail(t, failureMessage, append([]interface{}{msg}, args...)...) +} + +// FailNowf fails test +func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { + return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...) +} + +// Falsef asserts that the specified value is false. +// +// assert.Falsef(t, myBool, "error message %s", "formatted") +func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { + return False(t, value, append([]interface{}{msg}, args...)...) +} + +// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + return FileExists(t, path, append([]interface{}{msg}, args...)...) +} + +// HTTPBodyContainsf asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) +} + +// HTTPBodyNotContainsf asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) +} + +// HTTPErrorf asserts that a specified handler returns an error status code. +// +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// HTTPRedirectf asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// HTTPSuccessf asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// Implementsf asserts that an object is implemented by the specified interface. +// +// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject)) +func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { + return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) +} + +// InDeltaf asserts that the two numerals are within delta of each other. +// +// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01) +func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InDeltaSlicef is the same as InDelta, except it compares two slices. +func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InEpsilonf asserts that expected and actual have a relative error less than epsilon +func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) +} + +// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) +} + +// IsTypef asserts that the specified objects are of the same type. +func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { + return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...) +} + +// JSONEqf asserts that two JSON strings are equivalent. +// +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { + return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Lenf asserts that the specified object has specific length. +// Lenf also fails if the object has a type that len() not accept. +// +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { + return Len(t, object, length, append([]interface{}{msg}, args...)...) +} + +// Nilf asserts that the specified object is nil. +// +// assert.Nilf(t, err, "error message %s", "formatted") +func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + return Nil(t, object, append([]interface{}{msg}, args...)...) +} + +// NoErrorf asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } +func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { + return NoError(t, err, append([]interface{}{msg}, args...)...) +} + +// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { + return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) +} + +// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } +func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + return NotEmpty(t, object, append([]interface{}{msg}, args...)...) +} + +// NotEqualf asserts that the specified values are NOT equal. +// +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// NotNilf asserts that the specified object is not nil. +// +// assert.NotNilf(t, err, "error message %s", "formatted") +func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + return NotNil(t, object, append([]interface{}{msg}, args...)...) +} + +// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { + return NotPanics(t, f, append([]interface{}{msg}, args...)...) +} + +// NotRegexpf asserts that a specified regexp does not match a string. +// +// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { + return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...) +} + +// NotSubsetf asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { + return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...) +} + +// NotZerof asserts that i is not the zero value for its type. +func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { + return NotZero(t, i, append([]interface{}{msg}, args...)...) +} + +// Panicsf asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { + return Panics(t, f, append([]interface{}{msg}, args...)...) +} + +// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { + return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...) +} + +// Regexpf asserts that a specified regexp matches a string. +// +// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { + return Regexp(t, rx, str, append([]interface{}{msg}, args...)...) +} + +// Subsetf asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { + return Subset(t, list, subset, append([]interface{}{msg}, args...)...) +} + +// Truef asserts that the specified value is true. +// +// assert.Truef(t, myBool, "error message %s", "formatted") +func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { + return True(t, value, append([]interface{}{msg}, args...)...) +} + +// WithinDurationf asserts that the two times are within duration delta of each other. +// +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { + return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// Zerof asserts that i is the zero value for its type. +func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { + return Zero(t, i, append([]interface{}{msg}, args...)...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl new file mode 100644 index 000000000..c5cc66f43 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl @@ -0,0 +1,4 @@ +{{.CommentFormat}} +func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { + return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index e6a796046..ffa5428f3 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -1,387 +1,686 @@ /* * CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen * THIS FILE MUST NOT BE EDITED BY HAND -*/ + */ package assert import ( - http "net/http" url "net/url" time "time" ) - // Condition uses a Comparison to assert a complex condition. func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { return Condition(a.t, comp, msgAndArgs...) } +// Conditionf uses a Comparison to assert a complex condition. +func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool { + return Conditionf(a.t, comp, msg, args...) +} // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. -// -// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") -// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") -// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { return Contains(a.t, s, contains, msgAndArgs...) } +// Containsf asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { + return Containsf(a.t, s, contains, msg, args...) +} + +// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool { + return DirExists(a.t, path, msgAndArgs...) +} + +// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool { + return DirExistsf(a.t, path, msg, args...) +} + +// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]) +func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { + return ElementsMatch(a.t, listA, listB, msgAndArgs...) +} + +// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + return ElementsMatchf(a.t, listA, listB, msg, args...) +} // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. -// +// // a.Empty(obj) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { return Empty(a.t, object, msgAndArgs...) } +// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Emptyf(obj, "error message %s", "formatted") +func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { + return Emptyf(a.t, object, msg, args...) +} // Equal asserts that two objects are equal. -// -// a.Equal(123, 123, "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.Equal(123, 123) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Equal(a.t, expected, actual, msgAndArgs...) } - // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. -// +// // actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// -// Returns whether the assertion was successful (true) or not (false). +// a.EqualError(err, expectedErrorString) func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { return EqualError(a.t, theError, errString, msgAndArgs...) } +// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { + return EqualErrorf(a.t, theError, errString, msg, args...) +} // EqualValues asserts that two objects are equal or convertable to the same types // and equal. -// -// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return EqualValues(a.t, expected, actual, msgAndArgs...) } +// EqualValuesf asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123)) +func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return EqualValuesf(a.t, expected, actual, msg, args...) +} + +// Equalf asserts that two objects are equal. +// +// a.Equalf(123, 123, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return Equalf(a.t, expected, actual, msg, args...) +} // Error asserts that a function returned an error (i.e. not `nil`). -// +// // actualObj, err := SomeFunction() -// if a.Error(err, "An error was expected") { -// assert.Equal(t, err, expectedError) +// if a.Error(err) { +// assert.Equal(t, expectedError, err) // } -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { return Error(a.t, err, msgAndArgs...) } +// Errorf asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } +func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { + return Errorf(a.t, err, msg, args...) +} -// Exactly asserts that two objects are equal is value and type. -// -// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") -// -// Returns whether the assertion was successful (true) or not (false). +// Exactly asserts that two objects are equal in value and type. +// +// a.Exactly(int32(123), int64(123)) func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return Exactly(a.t, expected, actual, msgAndArgs...) } +// Exactlyf asserts that two objects are equal in value and type. +// +// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123)) +func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return Exactlyf(a.t, expected, actual, msg, args...) +} // Fail reports a failure through func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { return Fail(a.t, failureMessage, msgAndArgs...) } - // FailNow fails test func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { return FailNow(a.t, failureMessage, msgAndArgs...) } +// FailNowf fails test +func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool { + return FailNowf(a.t, failureMessage, msg, args...) +} + +// Failf reports a failure through +func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool { + return Failf(a.t, failureMessage, msg, args...) +} // False asserts that the specified value is false. -// -// a.False(myBool, "myBool should be false") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.False(myBool) func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { return False(a.t, value, msgAndArgs...) } +// Falsef asserts that the specified value is false. +// +// a.Falsef(myBool, "error message %s", "formatted") +func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { + return Falsef(a.t, value, msg, args...) +} + +// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool { + return FileExists(a.t, path, msgAndArgs...) +} + +// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool { + return FileExistsf(a.t, path, msg, args...) +} // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. -// +// // a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// +// // Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { - return HTTPBodyContains(a.t, handler, method, url, values, str) +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...) } +// HTTPBodyContainsf asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...) +} // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. -// +// // a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// +// // Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { - return HTTPBodyNotContains(a.t, handler, method, url, values, str) +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...) } +// HTTPBodyNotContainsf asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...) +} // HTTPError asserts that a specified handler returns an error status code. -// +// // a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// +// // Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool { - return HTTPError(a.t, handler, method, url, values) +func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + return HTTPError(a.t, handler, method, url, values, msgAndArgs...) } +// HTTPErrorf asserts that a specified handler returns an error status code. +// +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + return HTTPErrorf(a.t, handler, method, url, values, msg, args...) +} // HTTPRedirect asserts that a specified handler returns a redirect status code. -// +// // a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// +// // Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool { - return HTTPRedirect(a.t, handler, method, url, values) +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...) } +// HTTPRedirectf asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + return HTTPRedirectf(a.t, handler, method, url, values, msg, args...) +} // HTTPSuccess asserts that a specified handler returns a success status code. -// +// // a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// +// // Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool { - return HTTPSuccess(a.t, handler, method, url, values) +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...) } +// HTTPSuccessf asserts that a specified handler returns a success status code. +// +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + return HTTPSuccessf(a.t, handler, method, url, values, msg, args...) +} // Implements asserts that an object is implemented by the specified interface. -// -// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") +// +// a.Implements((*MyInterface)(nil), new(MyObject)) func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { return Implements(a.t, interfaceObject, object, msgAndArgs...) } +// Implementsf asserts that an object is implemented by the specified interface. +// +// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject)) +func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { + return Implementsf(a.t, interfaceObject, object, msg, args...) +} // InDelta asserts that the two numerals are within delta of each other. -// +// // a.InDelta(math.Pi, (22 / 7.0), 0.01) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { return InDelta(a.t, expected, actual, delta, msgAndArgs...) } +// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...) +} // InDeltaSlice is the same as InDelta, except it compares two slices. func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) } +// InDeltaSlicef is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + return InDeltaSlicef(a.t, expected, actual, delta, msg, args...) +} + +// InDeltaf asserts that the two numerals are within delta of each other. +// +// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01) +func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + return InDeltaf(a.t, expected, actual, delta, msg, args...) +} // InEpsilon asserts that expected and actual have a relative error less than epsilon -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) } - -// InEpsilonSlice is the same as InEpsilon, except it compares two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - return InEpsilonSlice(a.t, expected, actual, delta, msgAndArgs...) +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) } +// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...) +} + +// InEpsilonf asserts that expected and actual have a relative error less than epsilon +func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + return InEpsilonf(a.t, expected, actual, epsilon, msg, args...) +} // IsType asserts that the specified objects are of the same type. func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { return IsType(a.t, expectedType, object, msgAndArgs...) } +// IsTypef asserts that the specified objects are of the same type. +func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { + return IsTypef(a.t, expectedType, object, msg, args...) +} // JSONEq asserts that two JSON strings are equivalent. -// +// // a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { return JSONEq(a.t, expected, actual, msgAndArgs...) } +// JSONEqf asserts that two JSON strings are equivalent. +// +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { + return JSONEqf(a.t, expected, actual, msg, args...) +} // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. -// -// a.Len(mySlice, 3, "The size of slice is not 3") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.Len(mySlice, 3) func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { return Len(a.t, object, length, msgAndArgs...) } +// Lenf asserts that the specified object has specific length. +// Lenf also fails if the object has a type that len() not accept. +// +// a.Lenf(mySlice, 3, "error message %s", "formatted") +func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { + return Lenf(a.t, object, length, msg, args...) +} // Nil asserts that the specified object is nil. -// -// a.Nil(err, "err should be nothing") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.Nil(err) func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { return Nil(a.t, object, msgAndArgs...) } +// Nilf asserts that the specified object is nil. +// +// a.Nilf(err, "error message %s", "formatted") +func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { + return Nilf(a.t, object, msg, args...) +} // NoError asserts that a function returned no error (i.e. `nil`). -// +// // actualObj, err := SomeFunction() // if a.NoError(err) { -// assert.Equal(t, actualObj, expectedObj) +// assert.Equal(t, expectedObj, actualObj) // } -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } +// NoErrorf asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } +func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { + return NoErrorf(a.t, err, msg, args...) +} // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. -// -// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") -// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") -// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { return NotContains(a.t, s, contains, msgAndArgs...) } +// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { + return NotContainsf(a.t, s, contains, msg, args...) +} // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. -// +// // if a.NotEmpty(obj) { // assert.Equal(t, "two", obj[1]) // } -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { return NotEmpty(a.t, object, msgAndArgs...) } +// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } +func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { + return NotEmptyf(a.t, object, msg, args...) +} // NotEqual asserts that the specified values are NOT equal. -// -// a.NotEqual(obj1, obj2, "two objects shouldn't be equal") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.NotEqual(obj1, obj2) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { return NotEqual(a.t, expected, actual, msgAndArgs...) } +// NotEqualf asserts that the specified values are NOT equal. +// +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + return NotEqualf(a.t, expected, actual, msg, args...) +} // NotNil asserts that the specified object is not nil. -// -// a.NotNil(err, "err should be something") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.NotNil(err) func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { return NotNil(a.t, object, msgAndArgs...) } +// NotNilf asserts that the specified object is not nil. +// +// a.NotNilf(err, "error message %s", "formatted") +func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { + return NotNilf(a.t, object, msg, args...) +} // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanics(func(){ -// RemainCalm() -// }, "Calling RemainCalm() should NOT panic") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.NotPanics(func(){ RemainCalm() }) func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { return NotPanics(a.t, f, msgAndArgs...) } +// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { + return NotPanicsf(a.t, f, msg, args...) +} // NotRegexp asserts that a specified regexp does not match a string. -// +// // a.NotRegexp(regexp.MustCompile("starts"), "it's starting") // a.NotRegexp("^start", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { return NotRegexp(a.t, rx, str, msgAndArgs...) } +// NotRegexpf asserts that a specified regexp does not match a string. +// +// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { + return NotRegexpf(a.t, rx, str, msg, args...) +} -// NotZero asserts that i is not the zero value for its type and returns the truth. +// NotSubset asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { + return NotSubset(a.t, list, subset, msgAndArgs...) +} + +// NotSubsetf asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { + return NotSubsetf(a.t, list, subset, msg, args...) +} + +// NotZero asserts that i is not the zero value for its type. func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { return NotZero(a.t, i, msgAndArgs...) } +// NotZerof asserts that i is not the zero value for its type. +func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool { + return NotZerof(a.t, i, msg, args...) +} // Panics asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panics(func(){ -// GoCrazy() -// }, "Calling GoCrazy() should panic") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.Panics(func(){ GoCrazy() }) func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { return Panics(a.t, f, msgAndArgs...) } +// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { + return PanicsWithValue(a.t, expected, f, msgAndArgs...) +} + +// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { + return PanicsWithValuef(a.t, expected, f, msg, args...) +} + +// Panicsf asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { + return Panicsf(a.t, f, msg, args...) +} // Regexp asserts that a specified regexp matches a string. -// +// // a.Regexp(regexp.MustCompile("start"), "it's starting") // a.Regexp("start...$", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { return Regexp(a.t, rx, str, msgAndArgs...) } +// Regexpf asserts that a specified regexp matches a string. +// +// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { + return Regexpf(a.t, rx, str, msg, args...) +} + +// Subset asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { + return Subset(a.t, list, subset, msgAndArgs...) +} + +// Subsetf asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { + return Subsetf(a.t, list, subset, msg, args...) +} // True asserts that the specified value is true. -// -// a.True(myBool, "myBool should be true") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.True(myBool) func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { return True(a.t, value, msgAndArgs...) } +// Truef asserts that the specified value is true. +// +// a.Truef(myBool, "error message %s", "formatted") +func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { + return Truef(a.t, value, msg, args...) +} // WithinDuration asserts that the two times are within duration delta of each other. -// -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// -// Returns whether the assertion was successful (true) or not (false). +// +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) } +// WithinDurationf asserts that the two times are within duration delta of each other. +// +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { + return WithinDurationf(a.t, expected, actual, delta, msg, args...) +} -// Zero asserts that i is the zero value for its type and returns the truth. +// Zero asserts that i is the zero value for its type. func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { return Zero(a.t, i, msgAndArgs...) } + +// Zerof asserts that i is the zero value for its type. +func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool { + return Zerof(a.t, i, msg, args...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index 348d5f1bc..47bda7786 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -4,8 +4,10 @@ import ( "bufio" "bytes" "encoding/json" + "errors" "fmt" "math" + "os" "reflect" "regexp" "runtime" @@ -18,6 +20,8 @@ import ( "github.com/pmezard/go-difflib/difflib" ) +//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl + // TestingT is an interface wrapper around *testing.T type TestingT interface { Errorf(format string, args ...interface{}) @@ -38,7 +42,15 @@ func ObjectsAreEqual(expected, actual interface{}) bool { if expected == nil || actual == nil { return expected == actual } - + if exp, ok := expected.([]byte); ok { + act, ok := actual.([]byte) + if !ok { + return false + } else if exp == nil || act == nil { + return exp == nil && act == nil + } + return bytes.Equal(exp, act) + } return reflect.DeepEqual(expected, actual) } @@ -65,7 +77,7 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool { /* CallerInfo is necessary because the assert functions use the testing object internally, causing it to print the file:line of the assert method, rather than where -the problem actually occured in calling code.*/ +the problem actually occurred in calling code.*/ // CallerInfo returns an array of strings containing the file and line number // of each stack frame leading from the current test to the assert call that @@ -82,7 +94,9 @@ func CallerInfo() []string { for i := 0; ; i++ { pc, file, line, ok = runtime.Caller(i) if !ok { - return nil + // The breaks below failed to terminate the loop, and we ran off the + // end of the call stack. + break } // This is a huge edge case, but it will panic if this is the case, see #180 @@ -90,18 +104,30 @@ func CallerInfo() []string { break } - parts := strings.Split(file, "/") - dir := parts[len(parts)-2] - file = parts[len(parts)-1] - if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { - callers = append(callers, fmt.Sprintf("%s:%d", file, line)) - } - f := runtime.FuncForPC(pc) if f == nil { break } name = f.Name() + + // testing.tRunner is the standard library function that calls + // tests. Subtests are called directly by tRunner, without going through + // the Test/Benchmark/Example function that contains the t.Run calls, so + // with subtests we should break when we hit tRunner, without adding it + // to the list of callers. + if name == "testing.tRunner" { + break + } + + parts := strings.Split(file, "/") + file = parts[len(parts)-1] + if len(parts) > 1 { + dir := parts[len(parts)-2] + if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { + callers = append(callers, fmt.Sprintf("%s:%d", file, line)) + } + } + // Drop the package segments := strings.Split(name, ".") name = segments[len(segments)-1] @@ -141,7 +167,7 @@ func getWhitespaceString() string { parts := strings.Split(file, "/") file = parts[len(parts)-1] - return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) + return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) } @@ -158,22 +184,18 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { return "" } -// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's -// test printing (see inner comment for specifics) -func indentMessageLines(message string, tabs int) string { +// Aligns the provided message so that all lines after the first line start at the same location as the first line. +// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). +// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the +// basis on which the alignment occurs). +func indentMessageLines(message string, longestLabelLen int) string { outBuf := new(bytes.Buffer) for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { + // no need to align first line because it starts at the correct location (after the label) if i != 0 { - outBuf.WriteRune('\n') - } - for ii := 0; ii < tabs; ii++ { - outBuf.WriteRune('\t') - // Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter - // by 1 prematurely. - if ii == 0 && i > 0 { - ii++ - } + // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab + outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") } outBuf.WriteString(scanner.Text()) } @@ -205,42 +227,70 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool // Fail reports a failure through func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + content := []labeledContent{ + {"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")}, + {"Error", failureMessage}, + } + + // Add test name if the Go version supports it + if n, ok := t.(interface { + Name() string + }); ok { + content = append(content, labeledContent{"Test", n.Name()}) + } message := messageFromMsgAndArgs(msgAndArgs...) - - errorTrace := strings.Join(CallerInfo(), "\n\r\t\t\t") if len(message) > 0 { - t.Errorf("\r%s\r\tError Trace:\t%s\n"+ - "\r\tError:%s\n"+ - "\r\tMessages:\t%s\n\r", - getWhitespaceString(), - errorTrace, - indentMessageLines(failureMessage, 2), - message) - } else { - t.Errorf("\r%s\r\tError Trace:\t%s\n"+ - "\r\tError:%s\n\r", - getWhitespaceString(), - errorTrace, - indentMessageLines(failureMessage, 2)) + content = append(content, labeledContent{"Messages", message}) } + t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...)) + return false } +type labeledContent struct { + label string + content string +} + +// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: +// +// \r\t{{label}}:{{align_spaces}}\t{{content}}\n +// +// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. +// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this +// alignment is achieved, "\t{{content}}\n" is added for the output. +// +// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line. +func labeledOutput(content ...labeledContent) string { + longestLabel := 0 + for _, v := range content { + if len(v.label) > longestLabel { + longestLabel = len(v.label) + } + } + var output string + for _, v := range content { + output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" + } + return output +} + // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - interfaceType := reflect.TypeOf(interfaceObject).Elem() + if object == nil { + return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) + } if !reflect.TypeOf(object).Implements(interfaceType) { return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) } return true - } // IsType asserts that the specified objects are of the same type. @@ -255,43 +305,66 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123, "123 and 123 should be equal") +// assert.Equal(t, 123, 123) // -// Returns whether the assertion was successful (true) or not (false). +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", + expected, actual, err), msgAndArgs...) + } if !ObjectsAreEqual(expected, actual) { diff := diff(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ - " != %#v (actual)%s", expected, actual, diff), msgAndArgs...) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) } return true } +// formatUnequalValues takes two values of arbitrary types and returns string +// representations appropriate to be presented to the user. +// +// If the values are not of like type, the returned strings will be prefixed +// with the type name, and the value will be enclosed in parenthesis similar +// to a type conversion in the Go grammar. +func formatUnequalValues(expected, actual interface{}) (e string, a string) { + if reflect.TypeOf(expected) != reflect.TypeOf(actual) { + return fmt.Sprintf("%T(%#v)", expected, expected), + fmt.Sprintf("%T(%#v)", actual, actual) + } + + return fmt.Sprintf("%#v", expected), + fmt.Sprintf("%#v", actual) +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if !ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ - " != %#v (actual)", expected, actual), msgAndArgs...) + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) } return true } -// Exactly asserts that two objects are equal is value and type. +// Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.Exactly(t, int32(123), int64(123)) func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { aType := reflect.TypeOf(expected) @@ -307,9 +380,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err, "err should be something") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.NotNil(t, err) func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if !isNil(object) { return true @@ -334,9 +405,7 @@ func isNil(object interface{}) bool { // Nil asserts that the specified object is nil. // -// assert.Nil(t, err, "err should be nothing") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.Nil(t, err) func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if isNil(object) { return true @@ -344,74 +413,38 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) } -var numericZeros = []interface{}{ - int(0), - int8(0), - int16(0), - int32(0), - int64(0), - uint(0), - uint8(0), - uint16(0), - uint32(0), - uint64(0), - float32(0), - float64(0), -} - // isEmpty gets whether the specified object is considered empty or not. func isEmpty(object interface{}) bool { + // get nil case out of the way if object == nil { return true - } else if object == "" { - return true - } else if object == false { - return true - } - - for _, v := range numericZeros { - if object == v { - return true - } } objValue := reflect.ValueOf(object) switch objValue.Kind() { - case reflect.Map: - fallthrough - case reflect.Slice, reflect.Chan: - { - return (objValue.Len() == 0) - } - case reflect.Struct: - switch object.(type) { - case time.Time: - return object.(time.Time).IsZero() - } + // collection types are empty when they have no element + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + return objValue.Len() == 0 + // pointers are empty if nil or if the value they point to is empty case reflect.Ptr: - { - if objValue.IsNil() { - return true - } - switch object.(type) { - case *time.Time: - return object.(*time.Time).IsZero() - default: - return false - } + if objValue.IsNil() { + return true } + deref := objValue.Elem().Interface() + return isEmpty(deref) + // for all other types, compare against the zero value + default: + zero := reflect.Zero(objValue.Type()) + return reflect.DeepEqual(object, zero.Interface()) } - return false } // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // // assert.Empty(t, obj) -// -// Returns whether the assertion was successful (true) or not (false). func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { pass := isEmpty(object) @@ -429,8 +462,6 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { // if assert.NotEmpty(t, obj) { // assert.Equal(t, "two", obj[1]) // } -// -// Returns whether the assertion was successful (true) or not (false). func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { pass := !isEmpty(object) @@ -457,9 +488,7 @@ func getLen(x interface{}) (ok bool, length int) { // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3, "The size of slice is not 3") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.Len(t, mySlice, 3) func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { ok, l := getLen(object) if !ok { @@ -474,9 +503,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // True asserts that the specified value is true. // -// assert.True(t, myBool, "myBool should be true") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.True(t, myBool) func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { if value != true { @@ -489,9 +516,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { // False asserts that the specified value is false. // -// assert.False(t, myBool, "myBool should be false") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.False(t, myBool) func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { if value != false { @@ -504,10 +529,15 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") +// assert.NotEqual(t, obj1, obj2) // -// Returns whether the assertion was successful (true) or not (false). +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", + expected, actual, err), msgAndArgs...) + } if ObjectsAreEqual(expected, actual) { return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) @@ -558,11 +588,9 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) { // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") -// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") -// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { ok, found := includeElement(s, contains) @@ -580,11 +608,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") -// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") -// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { ok, found := includeElement(s, contains) @@ -599,6 +625,142 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) } +// Subset asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { + if subset == nil { + return true // we consider nil to be equal to the nil set + } + + subsetValue := reflect.ValueOf(subset) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + + listKind := reflect.TypeOf(list).Kind() + subsetKind := reflect.TypeOf(subset).Kind() + + if listKind != reflect.Array && listKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + } + + if subsetKind != reflect.Array && subsetKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + } + + for i := 0; i < subsetValue.Len(); i++ { + element := subsetValue.Index(i).Interface() + ok, found := includeElement(list, element) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) + } + } + + return true +} + +// NotSubset asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { + if subset == nil { + return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...) + } + + subsetValue := reflect.ValueOf(subset) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + + listKind := reflect.TypeOf(list).Kind() + subsetKind := reflect.TypeOf(subset).Kind() + + if listKind != reflect.Array && listKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + } + + if subsetKind != reflect.Array && subsetKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + } + + for i := 0; i < subsetValue.Len(); i++ { + element := subsetValue.Index(i).Interface() + ok, found := includeElement(list, element) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + } + if !found { + return true + } + } + + return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) +} + +// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) +func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { + if isEmpty(listA) && isEmpty(listB) { + return true + } + + aKind := reflect.TypeOf(listA).Kind() + bKind := reflect.TypeOf(listB).Kind() + + if aKind != reflect.Array && aKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...) + } + + if bKind != reflect.Array && bKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...) + } + + aValue := reflect.ValueOf(listA) + bValue := reflect.ValueOf(listB) + + aLen := aValue.Len() + bLen := bValue.Len() + + if aLen != bLen { + return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...) + } + + // Mark indexes in bValue that we already used + visited := make([]bool, bLen) + for i := 0; i < aLen; i++ { + element := aValue.Index(i).Interface() + found := false + for j := 0; j < bLen; j++ { + if visited[j] { + continue + } + if ObjectsAreEqual(bValue.Index(j).Interface(), element) { + visited[j] = true + found = true + break + } + } + if !found { + return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...) + } + } + + return true +} + // Condition uses a Comparison to assert a complex condition. func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { result := comp() @@ -636,11 +798,7 @@ func didPanic(f PanicTestFunc) (bool, interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ -// GoCrazy() -// }, "Calling GoCrazy() should panic") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.Panics(t, func(){ GoCrazy() }) func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { @@ -650,13 +808,26 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { return true } +// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { + + funcDidPanic, panicValue := didPanic(f) + if !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + if panicValue != expected { + return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...) + } + + return true +} + // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ -// RemainCalm() -// }, "Calling RemainCalm() should NOT panic") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.NotPanics(t, func(){ RemainCalm() }) func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { if funcDidPanic, panicValue := didPanic(f); funcDidPanic { @@ -668,9 +839,7 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// -// Returns whether the assertion was successful (true) or not (false). +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { dt := expected.Sub(actual) @@ -708,6 +877,8 @@ func toFloat(x interface{}) (float64, bool) { xf = float64(xn) case float64: xf = float64(xn) + case time.Duration: + xf = float64(xn) default: xok = false } @@ -718,8 +889,6 @@ func toFloat(x interface{}) (float64, bool) { // InDelta asserts that the two numerals are within delta of each other. // // assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) -// -// Returns whether the assertion was successful (true) or not (false). func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { af, aok := toFloat(expected) @@ -730,7 +899,7 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs } if math.IsNaN(af) { - return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...) + return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...) } if math.IsNaN(bf) { @@ -757,7 +926,7 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn expectedSlice := reflect.ValueOf(expected) for i := 0; i < actualSlice.Len(); i++ { - result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta) + result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) if !result { return result } @@ -766,6 +935,47 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn return true } +// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Map || + reflect.TypeOf(expected).Kind() != reflect.Map { + return Fail(t, "Arguments must be maps", msgAndArgs...) + } + + expectedMap := reflect.ValueOf(expected) + actualMap := reflect.ValueOf(actual) + + if expectedMap.Len() != actualMap.Len() { + return Fail(t, "Arguments must have the same number of keys", msgAndArgs...) + } + + for _, k := range expectedMap.MapKeys() { + ev := expectedMap.MapIndex(k) + av := actualMap.MapIndex(k) + + if !ev.IsValid() { + return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) + } + + if !av.IsValid() { + return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) + } + + if !InDelta( + t, + ev.Interface(), + av.Interface(), + delta, + msgAndArgs..., + ) { + return false + } + } + + return true +} + func calcRelativeError(expected, actual interface{}) (float64, error) { af, aok := toFloat(expected) if !aok { @@ -776,15 +986,13 @@ func calcRelativeError(expected, actual interface{}) (float64, error) { } bf, bok := toFloat(actual) if !bok { - return 0, fmt.Errorf("expected value %q cannot be converted to float", actual) + return 0, fmt.Errorf("actual value %q cannot be converted to float", actual) } return math.Abs(af-bf) / math.Abs(af), nil } // InEpsilon asserts that expected and actual have a relative error less than epsilon -// -// Returns whether the assertion was successful (true) or not (false). func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { actualEpsilon, err := calcRelativeError(expected, actual) if err != nil { @@ -792,7 +1000,7 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd } if actualEpsilon > epsilon { return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ - " < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...) + " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) } return true @@ -827,13 +1035,11 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m // // actualObj, err := SomeFunction() // if assert.NoError(t, err) { -// assert.Equal(t, actualObj, expectedObj) +// assert.Equal(t, expectedObj, actualObj) // } -// -// Returns whether the assertion was successful (true) or not (false). func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if err != nil { - return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) } return true @@ -842,16 +1048,13 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { // Error asserts that a function returned an error (i.e. not `nil`). // // actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) // } -// -// Returns whether the assertion was successful (true) or not (false). func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { - message := messageFromMsgAndArgs(msgAndArgs...) if err == nil { - return Fail(t, "An error is expected but got nil. %s", message) + return Fail(t, "An error is expected but got nil.", msgAndArgs...) } return true @@ -861,20 +1064,20 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// -// Returns whether the assertion was successful (true) or not (false). +// assert.EqualError(t, err, expectedErrorString) func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { - - message := messageFromMsgAndArgs(msgAndArgs...) - if !NotNil(t, theError, "An error is expected but got nil. %s", message) { + if !Error(t, theError, msgAndArgs...) { return false } - s := "An error with value \"%s\" is expected but got \"%s\". %s" - return Equal(t, errString, theError.Error(), - s, errString, theError.Error(), message) + expected := errString + actual := theError.Error() + // don't need to use deep equals here, we know they are both strings + if expected != actual { + return Fail(t, fmt.Sprintf("Error message not equal:\n"+ + "expected: %q\n"+ + "actual : %q", expected, actual), msgAndArgs...) + } + return true } // matchRegexp return true if a specified regexp matches a string. @@ -895,8 +1098,6 @@ func matchRegexp(rx interface{}, str interface{}) bool { // // assert.Regexp(t, regexp.MustCompile("start"), "it's starting") // assert.Regexp(t, "start...$", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { match := matchRegexp(rx, str) @@ -912,8 +1113,6 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // // assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") // assert.NotRegexp(t, "^start", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { match := matchRegexp(rx, str) @@ -925,7 +1124,7 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf } -// Zero asserts that i is the zero value for its type and returns the truth. +// Zero asserts that i is the zero value for its type. func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) @@ -933,7 +1132,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { return true } -// NotZero asserts that i is not the zero value for its type and returns the truth. +// NotZero asserts that i is not the zero value for its type. func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) @@ -941,11 +1140,39 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { return true } +// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) + } + return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) + } + if info.IsDir() { + return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) + } + return true +} + +// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) + } + return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) + } + if !info.IsDir() { + return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) + } + return true +} + // JSONEq asserts that two JSON strings are equivalent. // // assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Returns whether the assertion was successful (true) or not (false). func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { var expectedJSONAsInterface, actualJSONAsInterface interface{} @@ -989,9 +1216,8 @@ func diff(expected interface{}, actual interface{}) string { return "" } - spew.Config.SortKeys = true - e := spew.Sdump(expected) - a := spew.Sdump(actual) + e := spewConfig.Sdump(expected) + a := spewConfig.Sdump(actual) diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ A: difflib.SplitLines(e), @@ -1005,3 +1231,26 @@ func diff(expected interface{}, actual interface{}) string { return "\n\nDiff:\n" + diff } + +// validateEqualArgs checks whether provided arguments can be safely used in the +// Equal/NotEqual functions. +func validateEqualArgs(expected, actual interface{}) error { + if isFunction(expected) || isFunction(actual) { + return errors.New("cannot take func type as argument") + } + return nil +} + +func isFunction(arg interface{}) bool { + if arg == nil { + return false + } + return reflect.TypeOf(arg).Kind() == reflect.Func +} + +var spewConfig = spew.ConfigState{ + Indent: " ", + DisablePointerAddresses: true, + DisableCapacities: true, + SortKeys: true, +} diff --git a/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/vendor/github.com/stretchr/testify/assert/forward_assertions.go index b867e95ea..9ad56851d 100644 --- a/vendor/github.com/stretchr/testify/assert/forward_assertions.go +++ b/vendor/github.com/stretchr/testify/assert/forward_assertions.go @@ -13,4 +13,4 @@ func New(t TestingT) *Assertions { } } -//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl +//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go index e1b9442b5..3101e78dd 100644 --- a/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -8,16 +8,16 @@ import ( "strings" ) -// httpCode is a helper that returns HTTP code of the response. It returns -1 -// if building a new request fails. -func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int { +// httpCode is a helper that returns HTTP code of the response. It returns -1 and +// an error if building a new request fails. +func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { w := httptest.NewRecorder() req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) if err != nil { - return -1 + return -1, err } handler(w, req) - return w.Code + return w.Code, nil } // HTTPSuccess asserts that a specified handler returns a success status code. @@ -25,12 +25,19 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) i // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). -func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { - code := httpCode(handler, method, url, values) - if code == -1 { +func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) return false } - return code >= http.StatusOK && code <= http.StatusPartialContent + + isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent + if !isSuccessCode { + Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isSuccessCode } // HTTPRedirect asserts that a specified handler returns a redirect status code. @@ -38,12 +45,19 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { - code := httpCode(handler, method, url, values) - if code == -1 { +func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) return false } - return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect + + isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect + if !isRedirectCode { + Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isRedirectCode } // HTTPError asserts that a specified handler returns an error status code. @@ -51,12 +65,19 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { - code := httpCode(handler, method, url, values) - if code == -1 { +func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) return false } - return code >= http.StatusBadRequest + + isErrorCode := code >= http.StatusBadRequest + if !isErrorCode { + Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isErrorCode } // HTTPBody is a helper that returns HTTP body of the response. It returns @@ -77,7 +98,7 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { body := HTTPBody(handler, method, url, values) contains := strings.Contains(body, fmt.Sprint(str)) @@ -94,12 +115,12 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { body := HTTPBody(handler, method, url, values) contains := strings.Contains(body, fmt.Sprint(str)) if contains { - Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) } return !contains diff --git a/vendor/vendor.json b/vendor/vendor.json index b1b90163f..5bf27241f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -596,10 +596,13 @@ "revisionTime": "2018-02-10T03:43:46Z" }, { - "checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=", + "checksumSHA1": "/5cvgU+J4l7EhMXTK76KaCAfOuU=", "comment": "v1.0.0-3-g6d21280", "path": "github.com/davecgh/go-spew/spew", - "revision": "6d212800a42e8ab5c146b8ace3490ee17e5225f9" + "revision": "346938d642f2ec3594ed81d874461961cd0faa76", + "revisionTime": "2016-10-29T20:57:26Z", + "version": "v1.1.0", + "versionExact": "v1.1.0" }, { "checksumSHA1": "5k4kiVJsn0CilLDx+gMjglXY6vs=", @@ -1202,11 +1205,21 @@ "revisionTime": "2018-03-15T01:07:03Z" }, { - "checksumSHA1": "iydUphwYqZRq3WhstEdGsbvBAKs=", + "checksumSHA1": "xqtDGN726+wHn43myII/VQ4vQn8=", + "path": "github.com/stretchr/objx", + "revision": "facf9a85c22f48d2f52f2380e4efce1768749a89", + "revisionTime": "2018-01-06T01:13:53Z", + "version": "v0.1", + "versionExact": "v0.1" + }, + { + "checksumSHA1": "pbq5LYckA7/rqe03l9MtXDekmRg=", "comment": "v1.1.4-4-g976c720", "path": "github.com/stretchr/testify/assert", - "revision": "d77da356e56a7428ad25149ca77381849a6a5232", - "revisionTime": "2016-06-15T09:26:46Z" + "revision": "12b6f73e6084dad08a7c6e575284b177ecafbc71", + "revisionTime": "2018-01-31T22:23:50Z", + "version": "v1.2.1", + "versionExact": "v1.2.1" }, { "checksumSHA1": "GQ9bu6PuydK3Yor1JgtVKUfEJm8=", From 81d127768c638a8df038862ca79608de00b89be3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 23:05:05 -0700 Subject: [PATCH 0940/1007] Add key press interval to virtualbox. --- builder/virtualbox/common/step_type_boot_command.go | 2 +- common/boot_command/pc_at_driver.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index a33c61e3d..b979ef59f 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -64,7 +64,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return driver.VBoxManage(args...) } - d := bootcommand.NewPCATDriver(sendCodes, 20) + d := bootcommand.NewPCATDriver(sendCodes, 25) ui.Say("Typing the boot command...") for i, command := range s.BootCommand { diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go index 834a4b02a..ca87c1926 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_at_driver.go @@ -3,15 +3,20 @@ package bootcommand import ( "fmt" "log" + "os" "strings" + "time" "unicode" "unicode/utf8" + + "github.com/hashicorp/packer/common" ) // SendCodeFunc will be called to send codes to the VM type SendCodeFunc func([]string) error type pcATDriver struct { + interval time.Duration sendImpl SendCodeFunc specialMap map[string][]string scancodeMap map[rune]byte @@ -21,6 +26,12 @@ type pcATDriver struct { } func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { + // We delay (default 100ms) between each input event to allow for CPU or + // network latency. See PackerKeyEnv for tuning. + keyInterval := common.PackerKeyDefault + if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil { + keyInterval = delay + } // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html // // Scancodes are recorded here in pairs. The first entry represents @@ -87,6 +98,7 @@ func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { } return &pcATDriver{ + interval: keyInterval, sendImpl: send, specialMap: sMap, scancodeMap: scancodeMap, @@ -107,6 +119,7 @@ func (d *pcATDriver) Finalize() error { if err := d.sendImpl(b); err != nil { return err } + time.Sleep(d.interval) } return nil } From f9ad264f4dd361fce70435d3c33021b4a0b3631a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 12 Apr 2018 23:11:14 -0700 Subject: [PATCH 0941/1007] Comments --- common/boot_command/boot_command_ast.go | 2 -- common/boot_command/pc_at_driver.go | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 87457a22c..f9605a67b 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -15,8 +15,6 @@ TODO: * comments * lower-case specials * check that `<del>` works on parallels. It's different now. - * take `Finalize` out of the Driver interface. let builders that need it - * use it. also rename to `Flush`. */ // KeysAction represents what we want to do with a key press. diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go index ca87c1926..b89dcc081 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_at_driver.go @@ -25,6 +25,9 @@ type pcATDriver struct { scancodeChunkSize int } +// NewPCATDriver creates a new boot command driver for VMs that expect PC-AT +// keyboard codes. `send` should send its argument to the VM. `chunkSize` should +// be the maximum number of keyboard codes to send to `send` at one time. func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { // We delay (default 100ms) between each input event to allow for CPU or // network latency. See PackerKeyEnv for tuning. From bdb1eee7d859f49074f19fbbd10c9f79b8ea509a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 12:49:54 -0700 Subject: [PATCH 0942/1007] Implement new parser for HyperV boot command --- builder/hyperv/common/step_run.go | 19 -- .../hyperv/common/step_type_boot_command.go | 243 +++--------------- builder/hyperv/iso/builder.go | 5 +- builder/hyperv/vmcx/builder.go | 5 +- common/boot_command/boot_command_ast.go | 5 +- 5 files changed, 43 insertions(+), 234 deletions(-) diff --git a/builder/hyperv/common/step_run.go b/builder/hyperv/common/step_run.go index cd8213c5e..02996fb6f 100644 --- a/builder/hyperv/common/step_run.go +++ b/builder/hyperv/common/step_run.go @@ -3,15 +3,12 @@ package common import ( "context" "fmt" - "time" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) type StepRun struct { - BootWait time.Duration - vmName string } @@ -32,22 +29,6 @@ func (s *StepRun) Run(_ context.Context, state multistep.StateBag) multistep.Ste s.vmName = vmName - if int64(s.BootWait) > 0 { - ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait)) - wait := time.After(s.BootWait) - WAITLOOP: - for { - select { - case <-wait: - break WAITLOOP - case <-time.After(1 * time.Second): - if _, ok := state.GetOk(multistep.StateCancelled); ok { - return multistep.ActionHalt - } - } - } - } - return multistep.ActionContinue } diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index 43deee1fd..5772ce1b9 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -3,12 +3,11 @@ package common import ( "context" "fmt" - "log" "strings" - "unicode" - "unicode/utf8" + "time" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -23,16 +22,28 @@ type bootCommandTemplateData struct { // This step "types" the boot command into the VM via the Hyper-V virtual keyboard type StepTypeBootCommand struct { BootCommand []string + BootWait time.Duration SwitchName string Ctx interpolate.Context } -func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) driver := state.Get("driver").(Driver) vmName := state.Get("vmName").(string) + // Wait the for the vm to boot. + if int64(s.BootWait) > 0 { + ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String())) + select { + case <-time.After(s.BootWait): + break + case <-ctx.Done(): + return multistep.ActionHalt + } + } + hostIp, err := driver.GetHostAdapterIpAddressForSwitch(s.SwitchName) if err != nil { @@ -52,7 +63,9 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m } ui.Say("Typing the boot command...") - scanCodesToSend := []string{} + + // Flatten command so we send it all at once + commands := []string{} for _, command := range s.BootCommand { command, err := interpolate.Render(command, &s.Ctx) @@ -64,13 +77,26 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - scanCodesToSend = append(scanCodesToSend, scancodes(command)...) + commands = append(commands, command) } - scanCodesToSendString := strings.Join(scanCodesToSend, " ") + sendCodes := func(codes []string) error { + scanCodesToSendString := strings.Join(codes, " ") + return driver.TypeScanCodes(vmName, scanCodesToSendString) + } + d := bootcommand.NewPCATDriver(sendCodes, -1) - if err := driver.TypeScanCodes(vmName, scanCodesToSendString); err != nil { - err := fmt.Errorf("Error sending boot command: %s", err) + flatCommands := strings.Join(commands, "") + seq, err := bootcommand.GenerateExpressionSequence(flatCommands) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) state.Put("error", err) ui.Error(err.Error()) return multistep.ActionHalt @@ -80,202 +106,3 @@ func (s *StepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m } func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} - -func scancodes(message string) []string { - // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html - // - // Scancodes represent raw keyboard output and are fed to the VM by using - // powershell to use Msvm_Keyboard - // - // Scancodes are recorded here in pairs. The first entry represents - // the key press and the second entry represents the key release and is - // derived from the first by the addition of 0x80. - special := make(map[string][]string) - special["<bs>"] = []string{"0e", "8e"} - special["<del>"] = []string{"53", "d3"} - special["<enter>"] = []string{"1c", "9c"} - special["<esc>"] = []string{"01", "81"} - special["<f1>"] = []string{"3b", "bb"} - special["<f2>"] = []string{"3c", "bc"} - special["<f3>"] = []string{"3d", "bd"} - special["<f4>"] = []string{"3e", "be"} - special["<f5>"] = []string{"3f", "bf"} - special["<f6>"] = []string{"40", "c0"} - special["<f7>"] = []string{"41", "c1"} - special["<f8>"] = []string{"42", "c2"} - special["<f9>"] = []string{"43", "c3"} - special["<f10>"] = []string{"44", "c4"} - special["<return>"] = []string{"1c", "9c"} - special["<tab>"] = []string{"0f", "8f"} - special["<up>"] = []string{"48", "c8"} - special["<down>"] = []string{"50", "d0"} - special["<left>"] = []string{"4b", "cb"} - special["<right>"] = []string{"4d", "cd"} - special["<spacebar>"] = []string{"39", "b9"} - special["<insert>"] = []string{"52", "d2"} - special["<home>"] = []string{"47", "c7"} - special["<end>"] = []string{"4f", "cf"} - special["<pageUp>"] = []string{"49", "c9"} - special["<pageDown>"] = []string{"51", "d1"} - special["<leftAlt>"] = []string{"38", "b8"} - special["<leftCtrl>"] = []string{"1d", "9d"} - special["<leftShift>"] = []string{"2a", "aa"} - special["<rightAlt>"] = []string{"e038", "e0b8"} - special["<rightCtrl>"] = []string{"e01d", "e09d"} - special["<rightShift>"] = []string{"36", "b6"} - - shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" - - scancodeIndex := make(map[string]uint) - scancodeIndex["1234567890-="] = 0x02 - scancodeIndex["!@#$%^&*()_+"] = 0x02 - scancodeIndex["qwertyuiop[]"] = 0x10 - scancodeIndex["QWERTYUIOP{}"] = 0x10 - scancodeIndex["asdfghjkl;'`"] = 0x1e - scancodeIndex[`ASDFGHJKL:"~`] = 0x1e - scancodeIndex[`\zxcvbnm,./`] = 0x2b - scancodeIndex["|ZXCVBNM<>?"] = 0x2b - scancodeIndex[" "] = 0x39 - - scancodeMap := make(map[rune]uint) - for chars, start := range scancodeIndex { - var i uint = 0 - for len(chars) > 0 { - r, size := utf8.DecodeRuneInString(chars) - chars = chars[size:] - scancodeMap[r] = start + i - i += 1 - } - } - - result := make([]string, 0, len(message)*2) - for len(message) > 0 { - var scancode []string - - if strings.HasPrefix(message, "<leftAltOn>") { - scancode = []string{"38"} - message = message[len("<leftAltOn>"):] - log.Printf("Special code '<leftAltOn>' found, replacing with: 38") - } - - if strings.HasPrefix(message, "<leftCtrlOn>") { - scancode = []string{"1d"} - message = message[len("<leftCtrlOn>"):] - log.Printf("Special code '<leftCtrlOn>' found, replacing with: 1d") - } - - if strings.HasPrefix(message, "<leftShiftOn>") { - scancode = []string{"2a"} - message = message[len("<leftShiftOn>"):] - log.Printf("Special code '<leftShiftOn>' found, replacing with: 2a") - } - - if strings.HasPrefix(message, "<leftAltOff>") { - scancode = []string{"b8"} - message = message[len("<leftAltOff>"):] - log.Printf("Special code '<leftAltOff>' found, replacing with: b8") - } - - if strings.HasPrefix(message, "<leftCtrlOff>") { - scancode = []string{"9d"} - message = message[len("<leftCtrlOff>"):] - log.Printf("Special code '<leftCtrlOff>' found, replacing with: 9d") - } - - if strings.HasPrefix(message, "<leftShiftOff>") { - scancode = []string{"aa"} - message = message[len("<leftShiftOff>"):] - log.Printf("Special code '<leftShiftOff>' found, replacing with: aa") - } - - if strings.HasPrefix(message, "<rightAltOn>") { - scancode = []string{"e038"} - message = message[len("<rightAltOn>"):] - log.Printf("Special code '<rightAltOn>' found, replacing with: e038") - } - - if strings.HasPrefix(message, "<rightCtrlOn>") { - scancode = []string{"e01d"} - message = message[len("<rightCtrlOn>"):] - log.Printf("Special code '<rightCtrlOn>' found, replacing with: e01d") - } - - if strings.HasPrefix(message, "<rightShiftOn>") { - scancode = []string{"36"} - message = message[len("<rightShiftOn>"):] - log.Printf("Special code '<rightShiftOn>' found, replacing with: 36") - } - - if strings.HasPrefix(message, "<rightAltOff>") { - scancode = []string{"e0b8"} - message = message[len("<rightAltOff>"):] - log.Printf("Special code '<rightAltOff>' found, replacing with: e0b8") - } - - if strings.HasPrefix(message, "<rightCtrlOff>") { - scancode = []string{"e09d"} - message = message[len("<rightCtrlOff>"):] - log.Printf("Special code '<rightCtrlOff>' found, replacing with: e09d") - } - - if strings.HasPrefix(message, "<rightShiftOff>") { - scancode = []string{"b6"} - message = message[len("<rightShiftOff>"):] - log.Printf("Special code '<rightShiftOff>' found, replacing with: b6") - } - - if strings.HasPrefix(message, "<wait>") { - log.Printf("Special code <wait> found, will sleep 1 second at this point.") - scancode = []string{"wait"} - message = message[len("<wait>"):] - } - - if strings.HasPrefix(message, "<wait5>") { - log.Printf("Special code <wait5> found, will sleep 5 seconds at this point.") - scancode = []string{"wait5"} - message = message[len("<wait5>"):] - } - - if strings.HasPrefix(message, "<wait10>") { - log.Printf("Special code <wait10> found, will sleep 10 seconds at this point.") - scancode = []string{"wait10"} - message = message[len("<wait10>"):] - } - - if scancode == nil { - for specialCode, specialValue := range special { - if strings.HasPrefix(message, specialCode) { - log.Printf("Special code '%s' found, replacing with: %s", specialCode, specialValue) - scancode = specialValue - message = message[len(specialCode):] - break - } - } - } - - if scancode == nil { - r, size := utf8.DecodeRuneInString(message) - message = message[size:] - scancodeInt := scancodeMap[r] - keyShift := unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - scancode = make([]string, 0, 4) - if keyShift { - scancode = append(scancode, "2a") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) - - if keyShift { - scancode = append(scancode, "aa") - } - - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt+0x80)) - log.Printf("Sending char '%c', code '%v', shift %v", r, scancode, keyShift) - } - - result = append(result, scancode...) - } - - return result -} diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index feb09598f..2ad3c324a 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -404,12 +404,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchVlanId: b.config.SwitchVlanId, }, - &hypervcommon.StepRun{ - BootWait: b.config.BootWait, - }, + &hypervcommon.StepRun{}, &hypervcommon.StepTypeBootCommand{ BootCommand: b.config.BootCommand, + BootWait: b.config.BootWait, SwitchName: b.config.SwitchName, Ctx: b.config.ctx, }, diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 8309759fb..2d7d17771 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -434,12 +434,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SwitchVlanId: b.config.SwitchVlanId, }, - &hypervcommon.StepRun{ - BootWait: b.config.BootWait, - }, + &hypervcommon.StepRun{}, &hypervcommon.StepTypeBootCommand{ BootCommand: b.config.BootCommand, + BootWait: b.config.BootWait, SwitchName: b.config.SwitchName, Ctx: b.config.ctx, }, diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index f9605a67b..9a5ec1eed 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -14,7 +14,10 @@ TODO: * fix vbox tests * comments * lower-case specials - * check that `<del>` works on parallels. It's different now. + * pc-at abstraction + * check that `<del>` works. It's different now. + * parallels + * hyperv- */ // KeysAction represents what we want to do with a key press. From bf0a3201253edeac780ee7a4190efedcb1e6b1ee Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 12:58:35 -0700 Subject: [PATCH 0943/1007] Implement new parser for qemu boot command --- builder/qemu/builder.go | 1 - builder/qemu/step_boot_wait.go | 27 -- builder/qemu/step_type_boot_command.go | 284 ++---------------- .../vmware/common/step_type_boot_command.go | 9 +- 4 files changed, 35 insertions(+), 286 deletions(-) delete mode 100644 builder/qemu/step_boot_wait.go diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index d1d91d79f..dfcc9357f 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -388,7 +388,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe steps = append(steps, new(stepConfigureVNC), steprun, - &stepBootWait{}, &stepTypeBootCommand{}, ) diff --git a/builder/qemu/step_boot_wait.go b/builder/qemu/step_boot_wait.go deleted file mode 100644 index 0c3935004..000000000 --- a/builder/qemu/step_boot_wait.go +++ /dev/null @@ -1,27 +0,0 @@ -package qemu - -import ( - "context" - "fmt" - "time" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -// stepBootWait waits the configured time period. -type stepBootWait struct{} - -func (s *stepBootWait) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - ui := state.Get("ui").(packer.Ui) - - if int64(config.bootWait) > 0 { - ui.Say(fmt.Sprintf("Waiting %s for boot...", config.bootWait)) - time.Sleep(config.bootWait) - } - - return multistep.ActionContinue -} - -func (s *stepBootWait) Cleanup(state multistep.StateBag) {} diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index f1dc895e9..a0cbb7a90 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -5,15 +5,10 @@ import ( "fmt" "log" "net" - "regexp" - "strings" "time" - "unicode" - "unicode/utf8" - - "os" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -40,13 +35,24 @@ type bootCommandTemplateData struct { // <nothing> type stepTypeBootCommand struct{} -func (s *stepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*Config) debug := state.Get("debug").(bool) httpPort := state.Get("http_port").(uint) ui := state.Get("ui").(packer.Ui) vncPort := state.Get("vnc_port").(uint) + // Wait the for the vm to boot. + if int64(config.bootWait) > 0 { + ui.Say(fmt.Sprintf("Waiting %s for boot...", config.bootWait.String())) + select { + case <-time.After(config.bootWait): + break + case <-ctx.Done(): + return multistep.ActionHalt + } + } + var pauseFn multistep.DebugPauseFn if debug { pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn) @@ -76,16 +82,18 @@ func (s *stepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m hostIP := "10.0.2.2" common.SetHTTPIP(hostIP) - ctx := config.ctx - ctx.Data = &bootCommandTemplateData{ + configCtx := config.ctx + configCtx.Data = &bootCommandTemplateData{ hostIP, httpPort, config.VMName, } + d := bootcommand.NewVNCDriver(c) + ui.Say("Typing the boot command over VNC...") for i, command := range config.BootCommand { - command, err := interpolate.Render(command, &ctx) + command, err := interpolate.Render(command, &configCtx) if err != nil { err := fmt.Errorf("Error preparing boot command: %s", err) state.Put("error", err) @@ -93,259 +101,27 @@ func (s *stepTypeBootCommand) Run(_ context.Context, state multistep.StateBag) m return multistep.ActionHalt } - // Check for interrupts between typing things so we can cancel - // since this isn't the fastest thing. - if _, ok := state.GetOk(multistep.StateCancelled); ok { + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) return multistep.ActionHalt } if pauseFn != nil { pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) } - - vncSendString(c, command) } return multistep.ActionContinue } func (*stepTypeBootCommand) Cleanup(multistep.StateBag) {} - -func vncSendString(c *vnc.ClientConn, original string) { - // Scancodes reference: https://github.com/qemu/qemu/blob/master/ui/vnc_keysym.h - special := make(map[string]uint32) - special["<bs>"] = 0xFF08 - special["<del>"] = 0xFFFF - special["<enter>"] = 0xFF0D - special["<esc>"] = 0xFF1B - special["<f1>"] = 0xFFBE - special["<f2>"] = 0xFFBF - special["<f3>"] = 0xFFC0 - special["<f4>"] = 0xFFC1 - special["<f5>"] = 0xFFC2 - special["<f6>"] = 0xFFC3 - special["<f7>"] = 0xFFC4 - special["<f8>"] = 0xFFC5 - special["<f9>"] = 0xFFC6 - special["<f10>"] = 0xFFC7 - special["<f11>"] = 0xFFC8 - special["<f12>"] = 0xFFC9 - special["<return>"] = 0xFF0D - special["<tab>"] = 0xFF09 - special["<up>"] = 0xFF52 - special["<down>"] = 0xFF54 - special["<left>"] = 0xFF51 - special["<right>"] = 0xFF53 - special["<spacebar>"] = 0x020 - special["<insert>"] = 0xFF63 - special["<home>"] = 0xFF50 - special["<end>"] = 0xFF57 - special["<pageUp>"] = 0xFF55 - special["<pageDown>"] = 0xFF56 - special["<leftAlt>"] = 0xFFE9 - special["<leftCtrl>"] = 0xFFE3 - special["<leftShift>"] = 0xFFE1 - special["<rightAlt>"] = 0xFFEA - special["<rightCtrl>"] = 0xFFE4 - special["<rightShift>"] = 0xFFE2 - - shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" - waitRe := regexp.MustCompile(`^<wait([0-9hms]+)>`) - - // We delay (default 100ms) between each key event to allow for CPU or - // network latency. See PackerKeyEnv for tuning. - keyInterval := common.PackerKeyDefault - if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil { - keyInterval = delay - } - - // TODO(mitchellh): Ripe for optimizations of some point, perhaps. - for len(original) > 0 { - var keyCode uint32 - keyShift := false - - if strings.HasPrefix(original, "<leftAltOn>") { - keyCode = special["<leftAlt>"] - original = original[len("<leftAltOn>"):] - log.Printf("Special code '<leftAltOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<leftCtrlOn>") { - keyCode = special["<leftCtrl>"] - original = original[len("<leftCtrlOn>"):] - log.Printf("Special code '<leftCtrlOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<leftShiftOn>") { - keyCode = special["<leftShift>"] - original = original[len("<leftShiftOn>"):] - log.Printf("Special code '<leftShiftOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<leftAltOff>") { - keyCode = special["<leftAlt>"] - original = original[len("<leftAltOff>"):] - log.Printf("Special code '<leftAltOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<leftCtrlOff>") { - keyCode = special["<leftCtrl>"] - original = original[len("<leftCtrlOff>"):] - log.Printf("Special code '<leftCtrlOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<leftShiftOff>") { - keyCode = special["<leftShift>"] - original = original[len("<leftShiftOff>"):] - log.Printf("Special code '<leftShiftOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<rightAltOn>") { - keyCode = special["<rightAlt>"] - original = original[len("<rightAltOn>"):] - log.Printf("Special code '<rightAltOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<rightCtrlOn>") { - keyCode = special["<rightCtrl>"] - original = original[len("<rightCtrlOn>"):] - log.Printf("Special code '<rightCtrlOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<rightShiftOn>") { - keyCode = special["<rightShift>"] - original = original[len("<rightShiftOn>"):] - log.Printf("Special code '<rightShiftOn>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<rightAltOff>") { - keyCode = special["<rightAlt>"] - original = original[len("<rightAltOff>"):] - log.Printf("Special code '<rightAltOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<rightCtrlOff>") { - keyCode = special["<rightCtrl>"] - original = original[len("<rightCtrlOff>"):] - log.Printf("Special code '<rightCtrlOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<rightShiftOff>") { - keyCode = special["<rightShift>"] - original = original[len("<rightShiftOff>"):] - log.Printf("Special code '<rightShiftOff>' found, replacing with: %d", keyCode) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - continue - } - - if strings.HasPrefix(original, "<wait>") { - log.Printf("Special code '<wait>' found, sleeping one second") - time.Sleep(1 * time.Second) - original = original[len("<wait>"):] - continue - } - - if strings.HasPrefix(original, "<wait5>") { - log.Printf("Special code '<wait5>' found, sleeping 5 seconds") - time.Sleep(5 * time.Second) - original = original[len("<wait5>"):] - continue - } - - if strings.HasPrefix(original, "<wait10>") { - log.Printf("Special code '<wait10>' found, sleeping 10 seconds") - time.Sleep(10 * time.Second) - original = original[len("<wait10>"):] - continue - } - - waitMatch := waitRe.FindStringSubmatch(original) - if len(waitMatch) > 1 { - log.Printf("Special code %s found, sleeping", waitMatch[0]) - if dt, err := time.ParseDuration(waitMatch[1]); err == nil { - time.Sleep(dt) - original = original[len(waitMatch[0]):] - continue - } - } - - for specialCode, specialValue := range special { - if strings.HasPrefix(original, specialCode) { - log.Printf("Special code '%s' found, replacing with: %d", specialCode, specialValue) - keyCode = specialValue - original = original[len(specialCode):] - break - } - } - - if keyCode == 0 { - r, size := utf8.DecodeRuneInString(original) - original = original[size:] - keyCode = uint32(r) - keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) - - log.Printf("Sending char '%c', code %d, shift %v", r, keyCode, keyShift) - } - - if keyShift { - c.KeyEvent(KeyLeftShift, true) - } - - c.KeyEvent(keyCode, true) - time.Sleep(keyInterval) - - c.KeyEvent(keyCode, false) - time.Sleep(keyInterval) - - if keyShift { - c.KeyEvent(KeyLeftShift, false) - } - time.Sleep(keyInterval) - } -} diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index ca46b5d88..6cfb196e3 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -129,10 +129,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return multistep.ActionHalt } - if pauseFn != nil { - pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) - } - seq, err := bootcommand.GenerateExpressionSequence(command) if err != nil { err := fmt.Errorf("Error generating boot command: %s", err) @@ -147,6 +143,11 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) ui.Error(err.Error()) return multistep.ActionHalt } + + if pauseFn != nil { + pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) + } + } return multistep.ActionContinue From cba4d3235f13a46e14227edb01e260dee243218e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 13:18:55 -0700 Subject: [PATCH 0944/1007] cleanup --- .../vmware/common/step_type_boot_command.go | 2 -- common/boot_command/boot_command_ast.go | 19 +++++++------------ common/boot_command/pc_at_driver.go | 1 + 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 6cfb196e3..6821b8e1b 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -51,7 +51,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) vncPort := state.Get("vnc_port").(uint) vncPassword := state.Get("vnc_password") - // ---------------- // Wait the for the vm to boot. if int64(s.BootWait) > 0 { ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait.String())) @@ -62,7 +61,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return multistep.ActionHalt } } - // ---------------- var pauseFn multistep.DebugPauseFn if debug { diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 9a5ec1eed..0fb8fa470 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -11,8 +11,7 @@ import ( /* TODO: * tests - * fix vbox tests - * comments + * fix vbox tests * lower-case specials * pc-at abstraction * check that `<del>` works. It's different now. @@ -33,15 +32,6 @@ const ( KeyPress ) -func onOffToAction(t string) KeyAction { - if strings.EqualFold(t, "on") { - return KeyOn - } else if strings.EqualFold(t, "off") { - return KeyOff - } - panic(fmt.Sprintf("Unknown state '%s'. Expecting On or Off.", t)) -} - func (k KeyAction) String() string { switch k { case KeyOn: @@ -60,6 +50,7 @@ type expression interface { type expressionSequence []expression +// Do executes every expression in the sequence and then finalizes the driver. func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { for _, exp := range s { if err := exp.Do(ctx, b); err != nil { @@ -70,7 +61,7 @@ func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { } // GenerateExpressionSequence generates a sequence of expressions from the -// given command. +// given command. This is the primary entry point to the boot command parser. func GenerateExpressionSequence(command string) (expressionSequence, error) { got, err := ParseReader("", strings.NewReader(command)) if err != nil { @@ -90,6 +81,8 @@ type waitExpression struct { d time.Duration } +// Do waits the amount of time described by the expression. It is cancellable +// through the context. func (w *waitExpression) Do(ctx context.Context, _ BCDriver) error { log.Printf("[INFO] Waiting %s", w.d) select { @@ -109,6 +102,7 @@ type specialExpression struct { action KeyAction } +// Do sends the special command to the driver, along with the key action. func (s *specialExpression) Do(ctx context.Context, driver BCDriver) error { return driver.SendSpecial(s.s, s.action) } @@ -122,6 +116,7 @@ type literal struct { action KeyAction } +// Do sends the key to the driver, along with the key action. func (l *literal) Do(ctx context.Context, driver BCDriver) error { return driver.SendKey(l.s, l.action) } diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go index b89dcc081..a3398177e 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_at_driver.go @@ -174,6 +174,7 @@ func (d *pcATDriver) SendSpecial(special string, action KeyAction) error { return nil } +// send stores the codes in an internal buffer. Use finalize to flush them. func (d *pcATDriver) send(codes []string) { d.buffer = append(d.buffer, codes) } From e2e7bc65fdb9e21f52d350e26d2a9cc398b559e8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 14:41:17 -0700 Subject: [PATCH 0945/1007] Make special keys case insensitive. add tests --- common/boot_command/boot_command.go | 195 ++++++++++--------- common/boot_command/boot_command.pigeon | 5 +- common/boot_command/boot_command_ast.go | 1 - common/boot_command/boot_command_ast_test.go | 79 +++++++- common/boot_command/pc_at_driver.go | 20 +- common/boot_command/pc_at_driver_test.go | 24 ++- common/boot_command/vnc_driver.go | 29 +-- common/boot_command/vnc_driver_test.go | 39 ++++ 8 files changed, 263 insertions(+), 129 deletions(-) create mode 100644 common/boot_command/vnc_driver_test.go diff --git a/common/boot_command/boot_command.go b/common/boot_command/boot_command.go index 1ecd23fe0..18578a42f 100644 --- a/common/boot_command/boot_command.go +++ b/common/boot_command/boot_command.go @@ -222,39 +222,39 @@ var g = &grammar{ }, { name: "Number", - pos: position{line: 38, col: 1, offset: 799}, + pos: position{line: 39, col: 1, offset: 810}, expr: &actionExpr{ - pos: position{line: 38, col: 10, offset: 808}, + pos: position{line: 39, col: 10, offset: 819}, run: (*parser).callonNumber1, expr: &seqExpr{ - pos: position{line: 38, col: 10, offset: 808}, + pos: position{line: 39, col: 10, offset: 819}, exprs: []interface{}{ &zeroOrOneExpr{ - pos: position{line: 38, col: 10, offset: 808}, + pos: position{line: 39, col: 10, offset: 819}, expr: &litMatcher{ - pos: position{line: 38, col: 10, offset: 808}, + pos: position{line: 39, col: 10, offset: 819}, val: "-", ignoreCase: false, }, }, &ruleRefExpr{ - pos: position{line: 38, col: 15, offset: 813}, + pos: position{line: 39, col: 15, offset: 824}, name: "Integer", }, &zeroOrOneExpr{ - pos: position{line: 38, col: 23, offset: 821}, + pos: position{line: 39, col: 23, offset: 832}, expr: &seqExpr{ - pos: position{line: 38, col: 25, offset: 823}, + pos: position{line: 39, col: 25, offset: 834}, exprs: []interface{}{ &litMatcher{ - pos: position{line: 38, col: 25, offset: 823}, + pos: position{line: 39, col: 25, offset: 834}, val: ".", ignoreCase: false, }, &oneOrMoreExpr{ - pos: position{line: 38, col: 29, offset: 827}, + pos: position{line: 39, col: 29, offset: 838}, expr: &ruleRefExpr{ - pos: position{line: 38, col: 29, offset: 827}, + pos: position{line: 39, col: 29, offset: 838}, name: "Digit", }, }, @@ -267,29 +267,29 @@ var g = &grammar{ }, { name: "Integer", - pos: position{line: 42, col: 1, offset: 873}, + pos: position{line: 43, col: 1, offset: 884}, expr: &choiceExpr{ - pos: position{line: 42, col: 11, offset: 883}, + pos: position{line: 43, col: 11, offset: 894}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 42, col: 11, offset: 883}, + pos: position{line: 43, col: 11, offset: 894}, val: "0", ignoreCase: false, }, &actionExpr{ - pos: position{line: 42, col: 17, offset: 889}, + pos: position{line: 43, col: 17, offset: 900}, run: (*parser).callonInteger3, expr: &seqExpr{ - pos: position{line: 42, col: 17, offset: 889}, + pos: position{line: 43, col: 17, offset: 900}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 42, col: 17, offset: 889}, + pos: position{line: 43, col: 17, offset: 900}, name: "NonZeroDigit", }, &zeroOrMoreExpr{ - pos: position{line: 42, col: 30, offset: 902}, + pos: position{line: 43, col: 30, offset: 913}, expr: &ruleRefExpr{ - pos: position{line: 42, col: 30, offset: 902}, + pos: position{line: 43, col: 30, offset: 913}, name: "Digit", }, }, @@ -301,21 +301,21 @@ var g = &grammar{ }, { name: "Duration", - pos: position{line: 46, col: 1, offset: 966}, + pos: position{line: 47, col: 1, offset: 977}, expr: &actionExpr{ - pos: position{line: 46, col: 12, offset: 977}, + pos: position{line: 47, col: 12, offset: 988}, run: (*parser).callonDuration1, expr: &oneOrMoreExpr{ - pos: position{line: 46, col: 12, offset: 977}, + pos: position{line: 47, col: 12, offset: 988}, expr: &seqExpr{ - pos: position{line: 46, col: 14, offset: 979}, + pos: position{line: 47, col: 14, offset: 990}, exprs: []interface{}{ &ruleRefExpr{ - pos: position{line: 46, col: 14, offset: 979}, + pos: position{line: 47, col: 14, offset: 990}, name: "Number", }, &ruleRefExpr{ - pos: position{line: 46, col: 21, offset: 986}, + pos: position{line: 47, col: 21, offset: 997}, name: "TimeUnit", }, }, @@ -325,12 +325,12 @@ var g = &grammar{ }, { name: "On", - pos: position{line: 50, col: 1, offset: 1049}, + pos: position{line: 51, col: 1, offset: 1060}, expr: &actionExpr{ - pos: position{line: 50, col: 6, offset: 1054}, + pos: position{line: 51, col: 6, offset: 1065}, run: (*parser).callonOn1, expr: &litMatcher{ - pos: position{line: 50, col: 6, offset: 1054}, + pos: position{line: 51, col: 6, offset: 1065}, val: "on", ignoreCase: true, }, @@ -338,12 +338,12 @@ var g = &grammar{ }, { name: "Off", - pos: position{line: 54, col: 1, offset: 1087}, + pos: position{line: 55, col: 1, offset: 1098}, expr: &actionExpr{ - pos: position{line: 54, col: 7, offset: 1093}, + pos: position{line: 55, col: 7, offset: 1104}, run: (*parser).callonOff1, expr: &litMatcher{ - pos: position{line: 54, col: 7, offset: 1093}, + pos: position{line: 55, col: 7, offset: 1104}, val: "off", ignoreCase: true, }, @@ -351,216 +351,216 @@ var g = &grammar{ }, { name: "Literal", - pos: position{line: 58, col: 1, offset: 1128}, + pos: position{line: 59, col: 1, offset: 1139}, expr: &actionExpr{ - pos: position{line: 58, col: 11, offset: 1138}, + pos: position{line: 59, col: 11, offset: 1149}, run: (*parser).callonLiteral1, expr: &anyMatcher{ - line: 58, col: 11, offset: 1138, + line: 59, col: 11, offset: 1149, }, }, }, { name: "ExprEnd", - pos: position{line: 63, col: 1, offset: 1219}, + pos: position{line: 64, col: 1, offset: 1230}, expr: &litMatcher{ - pos: position{line: 63, col: 11, offset: 1229}, + pos: position{line: 64, col: 11, offset: 1240}, val: ">", ignoreCase: false, }, }, { name: "ExprStart", - pos: position{line: 64, col: 1, offset: 1233}, + pos: position{line: 65, col: 1, offset: 1244}, expr: &litMatcher{ - pos: position{line: 64, col: 13, offset: 1245}, + pos: position{line: 65, col: 13, offset: 1256}, val: "<", ignoreCase: false, }, }, { name: "SpecialKey", - pos: position{line: 65, col: 1, offset: 1249}, + pos: position{line: 66, col: 1, offset: 1260}, expr: &choiceExpr{ - pos: position{line: 65, col: 14, offset: 1262}, + pos: position{line: 66, col: 14, offset: 1273}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 65, col: 14, offset: 1262}, + pos: position{line: 66, col: 14, offset: 1273}, val: "bs", ignoreCase: true, }, &litMatcher{ - pos: position{line: 65, col: 22, offset: 1270}, + pos: position{line: 66, col: 22, offset: 1281}, val: "del", ignoreCase: true, }, &litMatcher{ - pos: position{line: 65, col: 31, offset: 1279}, + pos: position{line: 66, col: 31, offset: 1290}, val: "enter", ignoreCase: true, }, &litMatcher{ - pos: position{line: 65, col: 42, offset: 1290}, + pos: position{line: 66, col: 42, offset: 1301}, val: "esc", ignoreCase: true, }, &litMatcher{ - pos: position{line: 65, col: 51, offset: 1299}, + pos: position{line: 66, col: 51, offset: 1310}, val: "f10", ignoreCase: true, }, &litMatcher{ - pos: position{line: 65, col: 60, offset: 1308}, + pos: position{line: 66, col: 60, offset: 1319}, val: "f11", ignoreCase: true, }, &litMatcher{ - pos: position{line: 65, col: 69, offset: 1317}, + pos: position{line: 66, col: 69, offset: 1328}, val: "f12", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 11, offset: 1334}, + pos: position{line: 67, col: 11, offset: 1345}, val: "f1", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 19, offset: 1342}, + pos: position{line: 67, col: 19, offset: 1353}, val: "f2", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 27, offset: 1350}, + pos: position{line: 67, col: 27, offset: 1361}, val: "f3", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 35, offset: 1358}, + pos: position{line: 67, col: 35, offset: 1369}, val: "f4", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 43, offset: 1366}, + pos: position{line: 67, col: 43, offset: 1377}, val: "f5", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 51, offset: 1374}, + pos: position{line: 67, col: 51, offset: 1385}, val: "f6", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 59, offset: 1382}, + pos: position{line: 67, col: 59, offset: 1393}, val: "f7", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 67, offset: 1390}, + pos: position{line: 67, col: 67, offset: 1401}, val: "f8", ignoreCase: true, }, &litMatcher{ - pos: position{line: 66, col: 75, offset: 1398}, + pos: position{line: 67, col: 75, offset: 1409}, val: "f9", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 12, offset: 1415}, + pos: position{line: 68, col: 12, offset: 1426}, val: "return", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 24, offset: 1427}, + pos: position{line: 68, col: 24, offset: 1438}, val: "tab", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 33, offset: 1436}, + pos: position{line: 68, col: 33, offset: 1447}, val: "up", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 41, offset: 1444}, + pos: position{line: 68, col: 41, offset: 1455}, val: "down", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 51, offset: 1454}, + pos: position{line: 68, col: 51, offset: 1465}, val: "spacebar", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 65, offset: 1468}, + pos: position{line: 68, col: 65, offset: 1479}, val: "insert", ignoreCase: true, }, &litMatcher{ - pos: position{line: 67, col: 77, offset: 1480}, + pos: position{line: 68, col: 77, offset: 1491}, val: "home", ignoreCase: true, }, &litMatcher{ - pos: position{line: 68, col: 11, offset: 1498}, + pos: position{line: 69, col: 11, offset: 1509}, val: "end", ignoreCase: true, }, &litMatcher{ - pos: position{line: 68, col: 20, offset: 1507}, + pos: position{line: 69, col: 20, offset: 1518}, val: "pageup", ignoreCase: true, }, &litMatcher{ - pos: position{line: 68, col: 32, offset: 1519}, + pos: position{line: 69, col: 32, offset: 1530}, val: "pagedown", ignoreCase: true, }, &litMatcher{ - pos: position{line: 68, col: 46, offset: 1533}, + pos: position{line: 69, col: 46, offset: 1544}, val: "leftalt", ignoreCase: true, }, &litMatcher{ - pos: position{line: 68, col: 59, offset: 1546}, + pos: position{line: 69, col: 59, offset: 1557}, val: "leftctrl", ignoreCase: true, }, &litMatcher{ - pos: position{line: 68, col: 73, offset: 1560}, + pos: position{line: 69, col: 73, offset: 1571}, val: "leftshift", ignoreCase: true, }, &litMatcher{ - pos: position{line: 69, col: 11, offset: 1583}, + pos: position{line: 70, col: 11, offset: 1594}, val: "rightalt", ignoreCase: true, }, &litMatcher{ - pos: position{line: 69, col: 25, offset: 1597}, + pos: position{line: 70, col: 25, offset: 1608}, val: "rightctrl", ignoreCase: true, }, &litMatcher{ - pos: position{line: 69, col: 40, offset: 1612}, + pos: position{line: 70, col: 40, offset: 1623}, val: "rightshift", ignoreCase: true, }, &litMatcher{ - pos: position{line: 69, col: 56, offset: 1628}, + pos: position{line: 70, col: 56, offset: 1639}, val: "leftsuper", ignoreCase: true, }, &litMatcher{ - pos: position{line: 69, col: 71, offset: 1643}, + pos: position{line: 70, col: 71, offset: 1654}, val: "rightsuper", ignoreCase: true, }, &litMatcher{ - pos: position{line: 70, col: 11, offset: 1667}, + pos: position{line: 71, col: 11, offset: 1678}, val: "left", ignoreCase: true, }, &litMatcher{ - pos: position{line: 70, col: 21, offset: 1677}, + pos: position{line: 71, col: 21, offset: 1688}, val: "right", ignoreCase: true, }, @@ -569,9 +569,9 @@ var g = &grammar{ }, { name: "NonZeroDigit", - pos: position{line: 72, col: 1, offset: 1687}, + pos: position{line: 73, col: 1, offset: 1698}, expr: &charClassMatcher{ - pos: position{line: 72, col: 16, offset: 1702}, + pos: position{line: 73, col: 16, offset: 1713}, val: "[1-9]", ranges: []rune{'1', '9'}, ignoreCase: false, @@ -580,9 +580,9 @@ var g = &grammar{ }, { name: "Digit", - pos: position{line: 73, col: 1, offset: 1708}, + pos: position{line: 74, col: 1, offset: 1719}, expr: &charClassMatcher{ - pos: position{line: 73, col: 9, offset: 1716}, + pos: position{line: 74, col: 9, offset: 1727}, val: "[0-9]", ranges: []rune{'0', '9'}, ignoreCase: false, @@ -591,42 +591,42 @@ var g = &grammar{ }, { name: "TimeUnit", - pos: position{line: 74, col: 1, offset: 1722}, + pos: position{line: 75, col: 1, offset: 1733}, expr: &choiceExpr{ - pos: position{line: 74, col: 13, offset: 1734}, + pos: position{line: 75, col: 13, offset: 1745}, alternatives: []interface{}{ &litMatcher{ - pos: position{line: 74, col: 13, offset: 1734}, + pos: position{line: 75, col: 13, offset: 1745}, val: "ns", ignoreCase: false, }, &litMatcher{ - pos: position{line: 74, col: 20, offset: 1741}, + pos: position{line: 75, col: 20, offset: 1752}, val: "us", ignoreCase: false, }, &litMatcher{ - pos: position{line: 74, col: 27, offset: 1748}, + pos: position{line: 75, col: 27, offset: 1759}, val: "µs", ignoreCase: false, }, &litMatcher{ - pos: position{line: 74, col: 34, offset: 1756}, + pos: position{line: 75, col: 34, offset: 1767}, val: "ms", ignoreCase: false, }, &litMatcher{ - pos: position{line: 74, col: 41, offset: 1763}, + pos: position{line: 75, col: 41, offset: 1774}, val: "s", ignoreCase: false, }, &litMatcher{ - pos: position{line: 74, col: 47, offset: 1769}, + pos: position{line: 75, col: 47, offset: 1780}, val: "m", ignoreCase: false, }, &litMatcher{ - pos: position{line: 74, col: 53, offset: 1775}, + pos: position{line: 75, col: 53, offset: 1786}, val: "h", ignoreCase: false, }, @@ -636,11 +636,11 @@ var g = &grammar{ { name: "_", displayName: "\"whitespace\"", - pos: position{line: 76, col: 1, offset: 1781}, + pos: position{line: 77, col: 1, offset: 1792}, expr: &zeroOrMoreExpr{ - pos: position{line: 76, col: 19, offset: 1799}, + pos: position{line: 77, col: 19, offset: 1810}, expr: &charClassMatcher{ - pos: position{line: 76, col: 19, offset: 1799}, + pos: position{line: 77, col: 19, offset: 1810}, val: "[ \\n\\t\\r]", chars: []rune{' ', '\n', '\t', '\r'}, ignoreCase: false, @@ -650,11 +650,11 @@ var g = &grammar{ }, { name: "EOF", - pos: position{line: 78, col: 1, offset: 1811}, + pos: position{line: 79, col: 1, offset: 1822}, expr: &notExpr{ - pos: position{line: 78, col: 8, offset: 1818}, + pos: position{line: 79, col: 8, offset: 1829}, expr: &anyMatcher{ - line: 78, col: 9, offset: 1819, + line: 79, col: 9, offset: 1830, }, }, }, @@ -711,10 +711,11 @@ func (p *parser) callonCharToggle1() (interface{}, error) { } func (c *current) onSpecial1(s, t interface{}) (interface{}, error) { + l := strings.ToLower(string(s.([]byte))) if t == nil { - return &specialExpression{string(s.([]byte)), KeyPress}, nil + return &specialExpression{l, KeyPress}, nil } - return &specialExpression{string(s.([]byte)), t.(KeyAction)}, nil + return &specialExpression{l, t.(KeyAction)}, nil } func (p *parser) callonSpecial1() (interface{}, error) { diff --git a/common/boot_command/boot_command.pigeon b/common/boot_command/boot_command.pigeon index ac1297010..fdfbba0cf 100644 --- a/common/boot_command/boot_command.pigeon +++ b/common/boot_command/boot_command.pigeon @@ -29,10 +29,11 @@ CharToggle = ExprStart lit:(Literal) t:(On / Off) ExprEnd { } Special = ExprStart s:(SpecialKey) t:(On / Off)? ExprEnd { + l := strings.ToLower(string(s.([]byte))) if t == nil { - return &specialExpression{string(s.([]byte)), KeyPress}, nil + return &specialExpression{l, KeyPress}, nil } - return &specialExpression{string(s.([]byte)), t.(KeyAction)}, nil + return &specialExpression{l, t.(KeyAction)}, nil } Number = '-'? Integer ( '.' Digit+ )? { diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 0fb8fa470..3c663d51b 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -12,7 +12,6 @@ import ( TODO: * tests * fix vbox tests - * lower-case specials * pc-at abstraction * check that `<del>` works. It's different now. * parallels diff --git a/common/boot_command/boot_command_ast_test.go b/common/boot_command/boot_command_ast_test.go index a568e1a4e..613b427b7 100644 --- a/common/boot_command/boot_command_ast_test.go +++ b/common/boot_command/boot_command_ast_test.go @@ -1,9 +1,12 @@ package bootcommand import ( + "fmt" "log" "strings" "testing" + + "github.com/stretchr/testify/assert" ) func toIfaceSlice(v interface{}) []interface{} { @@ -13,18 +16,86 @@ func toIfaceSlice(v interface{}) []interface{} { return v.([]interface{}) } -func TestParse(t *testing.T) { +func Test_parse(t *testing.T) { in := "<wait><wait20><wait3s><wait4m2ns>" in += "foo/bar > one 界" - in += "<fOn> b<fOff>" + in += "<fon> b<fOff>" in += "<foo><f3><f12><spacebar><leftalt><rightshift><rightsuper>" + expected := []string{ + "Wait<1s>", + "Wait<20s>", + "Wait<3s>", + "Wait<4m0.000000002s>", + "LIT-Press(f)", + "LIT-Press(o)", + "LIT-Press(o)", + "LIT-Press(/)", + "LIT-Press(b)", + "LIT-Press(a)", + "LIT-Press(r)", + "LIT-Press( )", + "LIT-Press(>)", + "LIT-Press( )", + "LIT-Press(o)", + "LIT-Press(n)", + "LIT-Press(e)", + "LIT-Press( )", + "LIT-Press(界)", + "LIT-On(f)", + "LIT-Press( )", + "LIT-Press(b)", + "LIT-Off(f)", + "LIT-Press(<)", + "LIT-Press(f)", + "LIT-Press(o)", + "LIT-Press(o)", + "LIT-Press(>)", + "Spec-Press(f3)", + "Spec-Press(f12)", + "Spec-Press(spacebar)", + "Spec-Press(leftalt)", + "Spec-Press(rightshift)", + "Spec-Press(rightsuper)", + } + got, err := ParseReader("", strings.NewReader(in)) if err != nil { log.Fatal(err) } gL := toIfaceSlice(got) - for _, g := range gL { + for i, g := range gL { + assert.Equal(t, expected[i], fmt.Sprintf("%s", g)) log.Printf("%s\n", g) } - +} + +func Test_special(t *testing.T) { + var specials = []struct { + in string + out string + }{ + { + "<rightShift><rightshift><RIGHTSHIFT>", + "Spec-Press(rightshift)", + }, + { + "<delon><delON><deLoN><DELON>", + "Spec-On(del)", + }, + { + "<enteroff><enterOFF><eNtErOfF><ENTEROFF>", + "Spec-Off(enter)", + }, + } + for _, tt := range specials { + got, err := ParseReader("", strings.NewReader(tt.in)) + if err != nil { + log.Fatal(err) + } + + gL := toIfaceSlice(got) + for _, g := range gL { + assert.Equal(t, tt.out, g.(*specialExpression).String()) + } + } } diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_at_driver.go index a3398177e..e227f3eca 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_at_driver.go @@ -67,16 +67,16 @@ func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { sMap["insert"] = []string{"e052", "e0d2"} sMap["home"] = []string{"e047", "e0c7"} sMap["end"] = []string{"e04f", "e0cf"} - sMap["pageUp"] = []string{"e049", "e0c9"} - sMap["pageDown"] = []string{"e051", "e0d1"} - sMap["leftAlt"] = []string{"38", "b8"} - sMap["leftCtrl"] = []string{"1d", "9d"} - sMap["leftShift"] = []string{"2a", "aa"} - sMap["rightAlt"] = []string{"e038", "e0b8"} - sMap["rightCtrl"] = []string{"e01d", "e09d"} - sMap["rightShift"] = []string{"36", "b6"} - sMap["leftSuper"] = []string{"e05b", "e0db"} - sMap["rightSuper"] = []string{"e05c", "e0dc"} + sMap["pageup"] = []string{"e049", "e0c9"} + sMap["pagedown"] = []string{"e051", "e0d1"} + sMap["leftalt"] = []string{"38", "b8"} + sMap["leftctrl"] = []string{"1d", "9d"} + sMap["leftshift"] = []string{"2a", "aa"} + sMap["rightalt"] = []string{"e038", "e0b8"} + sMap["rightctrl"] = []string{"e01d", "e09d"} + sMap["rightshift"] = []string{"36", "b6"} + sMap["leftsuper"] = []string{"e05b", "e0db"} + sMap["rightsuper"] = []string{"e05c", "e0dc"} scancodeIndex := make(map[string]byte) scancodeIndex["1234567890-="] = 0x02 diff --git a/common/boot_command/pc_at_driver_test.go b/common/boot_command/pc_at_driver_test.go index 893f2446c..f9323cfea 100644 --- a/common/boot_command/pc_at_driver_test.go +++ b/common/boot_command/pc_at_driver_test.go @@ -1,7 +1,11 @@ package bootcommand -import "testing" -import "github.com/stretchr/testify/assert" +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" +) func Test_chunkScanCodes(t *testing.T) { @@ -66,3 +70,19 @@ func Test_chunkScanCodeError(t *testing.T) { _, err := chunkScanCodes(in, 2) assert.Error(t, err) } + +func Test_pcatSpecialLookup(t *testing.T) { + in := "<rightShift><rightshiftoff><RIGHTSHIFTON>" + expected := []string{"36", "b6", "b6", "36"} + var codes []string + sendCodes := func(c []string) error { + codes = c + return nil + } + d := NewPCATDriver(sendCodes, -1) + seq, err := GenerateExpressionSequence(in) + assert.NoError(t, err) + err = seq.Do(context.Background(), d) + assert.NoError(t, err) + assert.Equal(t, expected, codes) +} diff --git a/common/boot_command/vnc_driver.go b/common/boot_command/vnc_driver.go index 811932aba..41fa5bb2a 100644 --- a/common/boot_command/vnc_driver.go +++ b/common/boot_command/vnc_driver.go @@ -9,20 +9,23 @@ import ( "unicode" "github.com/hashicorp/packer/common" - vnc "github.com/mitchellh/go-vnc" ) const KeyLeftShift uint32 = 0xFFE1 +type VNCKeyEvent interface { + KeyEvent(uint32, bool) error +} + type vncDriver struct { - c *vnc.ClientConn + c VNCKeyEvent interval time.Duration specialMap map[string]uint32 // keyEvent can set this error which will prevent it from continuing err error } -func NewVNCDriver(c *vnc.ClientConn) *vncDriver { +func NewVNCDriver(c VNCKeyEvent) *vncDriver { // We delay (default 100ms) between each key event to allow for CPU or // network latency. See PackerKeyEnv for tuning. keyInterval := common.PackerKeyDefault @@ -58,16 +61,16 @@ func NewVNCDriver(c *vnc.ClientConn) *vncDriver { sMap["insert"] = 0xFF63 sMap["home"] = 0xFF50 sMap["end"] = 0xFF57 - sMap["pageUp"] = 0xFF55 - sMap["pageDown"] = 0xFF56 - sMap["leftAlt"] = 0xFFE9 - sMap["leftCtrl"] = 0xFFE3 - sMap["leftShift"] = 0xFFE1 - sMap["rightAlt"] = 0xFFEA - sMap["rightCtrl"] = 0xFFE4 - sMap["rightShift"] = 0xFFE2 - sMap["leftSuper"] = 0xFFEB - sMap["rightSuper"] = 0xFFEC + sMap["pageup"] = 0xFF55 + sMap["pagedown"] = 0xFF56 + sMap["leftalt"] = 0xFFE9 + sMap["leftctrl"] = 0xFFE3 + sMap["leftshift"] = 0xFFE1 + sMap["leftsuper"] = 0xFFEB + sMap["rightalt"] = 0xFFEA + sMap["rightctrl"] = 0xFFE4 + sMap["rightshift"] = 0xFFE2 + sMap["rightsuper"] = 0xFFEC return &vncDriver{ c: c, diff --git a/common/boot_command/vnc_driver_test.go b/common/boot_command/vnc_driver_test.go new file mode 100644 index 000000000..11ca41669 --- /dev/null +++ b/common/boot_command/vnc_driver_test.go @@ -0,0 +1,39 @@ +package bootcommand + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" +) + +type event struct { + u uint32 + down bool +} + +type sender struct { + e []event +} + +func (s *sender) KeyEvent(u uint32, down bool) error { + s.e = append(s.e, event{u, down}) + return nil +} + +func Test_vncSpecialLookup(t *testing.T) { + in := "<rightShift><rightshiftoff><RIGHTSHIFTON>" + expected := []event{ + {0xFFE2, true}, + {0xFFE2, false}, + {0xFFE2, false}, + {0xFFE2, true}, + } + s := &sender{} + d := NewVNCDriver(s) + seq, err := GenerateExpressionSequence(in) + assert.NoError(t, err) + err = seq.Do(context.Background(), d) + assert.NoError(t, err) + assert.Equal(t, expected, s.e) +} From a46a7afa20186b4c9cc397b90e188f716ccf9082 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 14:44:28 -0700 Subject: [PATCH 0946/1007] Remove old tests. --- .../common/step_type_boot_command_test.go | 78 ------------------- .../common/step_type_boot_command_test.go | 41 ---------- common/boot_command/boot_command_ast.go | 2 - 3 files changed, 121 deletions(-) delete mode 100644 builder/parallels/common/step_type_boot_command_test.go delete mode 100644 builder/virtualbox/common/step_type_boot_command_test.go diff --git a/builder/parallels/common/step_type_boot_command_test.go b/builder/parallels/common/step_type_boot_command_test.go deleted file mode 100644 index 72b5056b4..000000000 --- a/builder/parallels/common/step_type_boot_command_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package common - -import ( - "context" - "strings" - "testing" - - "github.com/hashicorp/packer/helper/multistep" - "github.com/hashicorp/packer/packer" -) - -func TestStepTypeBootCommand(t *testing.T) { - state := testState(t) - - var bootcommand = []string{ - "1234567890-=<enter><wait>", - "!@#$%^&*()_+<enter>", - "qwertyuiop[]<enter>", - "QWERTYUIOP{}<enter>", - "asdfghjkl;'`<enter>", - `ASDFGHJKL:"~<enter>`, - "\\zxcvbnm,./<enter>", - "|ZXCVBNM<>?<enter>", - " <enter>", - } - - step := StepTypeBootCommand{ - BootCommand: bootcommand, - HostInterfaces: []string{}, - VMName: "myVM", - Ctx: *testConfigTemplate(t), - } - - comm := new(packer.MockCommunicator) - state.Put("communicator", comm) - - driver := state.Get("driver").(*DriverMock) - driver.VersionResult = "foo" - state.Put("http_port", uint(0)) - - // Test the run - if action := step.Run(context.Background(), state); action != multistep.ActionContinue { - t.Fatalf("bad action: %#v", action) - } - if _, ok := state.GetOk("error"); ok { - t.Fatal("should NOT have error") - } - - // Verify - var expected = [][]string{ - {"02", "82", "03", "83", "04", "84", "05", "85", "06", "86", "07", "87", "08", "88", "09", "89", "0a", "8a", "0b", "8b", "0c", "8c", "0d", "8d", "1c", "9c"}, - {}, - {"2a", "02", "82", "aa", "2a", "03", "83", "aa", "2a", "04", "84", "aa", "2a", "05", "85", "aa", "2a", "06", "86", "aa", "2a", "07", "87", "aa", "2a", "08", "88", "aa", "2a", "09", "89", "aa", "2a", "0a", "8a", "aa", "2a", "0b", "8b", "aa", "2a", "0c", "8c", "aa", "2a", "0d", "8d", "aa", "1c", "9c"}, - {"10", "90", "11", "91", "12", "92", "13", "93", "14", "94", "15", "95", "16", "96", "17", "97", "18", "98", "19", "99", "1a", "9a", "1b", "9b", "1c", "9c"}, - {"2a", "10", "90", "aa", "2a", "11", "91", "aa", "2a", "12", "92", "aa", "2a", "13", "93", "aa", "2a", "14", "94", "aa", "2a", "15", "95", "aa", "2a", "16", "96", "aa", "2a", "17", "97", "aa", "2a", "18", "98", "aa", "2a", "19", "99", "aa", "2a", "1a", "9a", "aa", "2a", "1b", "9b", "aa", "1c", "9c"}, - {"1e", "9e", "1f", "9f", "20", "a0", "21", "a1", "22", "a2", "23", "a3", "24", "a4", "25", "a5", "26", "a6", "27", "a7", "28", "a8", "29", "a9", "1c", "9c"}, - {"2a", "1e", "9e", "aa", "2a", "1f", "9f", "aa", "2a", "20", "a0", "aa", "2a", "21", "a1", "aa", "2a", "22", "a2", "aa", "2a", "23", "a3", "aa", "2a", "24", "a4", "aa", "2a", "25", "a5", "aa", "2a", "26", "a6", "aa", "2a", "27", "a7", "aa", "2a", "28", "a8", "aa", "2a", "29", "a9", "aa", "1c", "9c"}, - {"2b", "ab", "2c", "ac", "2d", "ad", "2e", "ae", "2f", "af", "30", "b0", "31", "b1", "32", "b2", "33", "b3", "34", "b4", "35", "b5", "1c", "9c"}, - {"2a", "2b", "ab", "aa", "2a", "2c", "ac", "aa", "2a", "2d", "ad", "aa", "2a", "2e", "ae", "aa", "2a", "2f", "af", "aa", "2a", "30", "b0", "aa", "2a", "31", "b1", "aa", "2a", "32", "b2", "aa", "2a", "33", "b3", "aa", "2a", "34", "b4", "aa", "2a", "35", "b5", "aa", "1c", "9c"}, - {"39", "b9", "1c", "9c"}, - } - fail := false - - for i := range driver.SendKeyScanCodesCalls { - t.Logf("prltype %s\n", strings.Join(driver.SendKeyScanCodesCalls[i], " ")) - } - - for i := range expected { - for j := range expected[i] { - if driver.SendKeyScanCodesCalls[i][j] != expected[i][j] { - fail = true - } - } - } - if fail { - t.Fatalf("Sent bad scancodes: %#v\n Expected: %#v", driver.SendKeyScanCodesCalls, expected) - } -} diff --git a/builder/virtualbox/common/step_type_boot_command_test.go b/builder/virtualbox/common/step_type_boot_command_test.go deleted file mode 100644 index 7d4291530..000000000 --- a/builder/virtualbox/common/step_type_boot_command_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package common - -/* -func TestScancodes(t *testing.T) { - var bootcommand = []string{ - "1234567890-=<enter><wait>", - "!@#$%^&*()_+<enter>", - "qwertyuiop[]<enter>", - "QWERTYUIOP{}<enter>", - "asdfghjkl;'`<enter>", - `ASDFGHJKL:"~<enter>`, - "\\zxcvbnm,./<enter>", - "|ZXCVBNM<>?<enter>", - "<enter>", - "<leftAltOn><esc><leftAltOff><wait5>", - "<tab><tab><tab><tab><tab><spacebar><wait5>", - } - - var expected = [][]string{ - {"02", "82", "03", "83", "04", "84", "05", "85", "06", "86", "07", "87", "08", "88", "09", "89", "0a", "8a", "0b", "8b", "0c", "8c", "0d", "8d", "1c", "9c", "wait"}, - {"2a", "02", "aa", "82", "2a", "03", "aa", "83", "2a", "04", "aa", "84", "2a", "05", "aa", "85", "2a", "06", "aa", "86", "2a", "07", "aa", "87", "2a", "08", "aa", "88", "2a", "09", "aa", "89", "2a", "0a", "aa", "8a", "2a", "0b", "aa", "8b", "2a", "0c", "aa", "8c", "2a", "0d", "aa", "8d", "1c", "9c"}, - {"10", "90", "11", "91", "12", "92", "13", "93", "14", "94", "15", "95", "16", "96", "17", "97", "18", "98", "19", "99", "1a", "9a", "1b", "9b", "1c", "9c"}, - {"2a", "10", "aa", "90", "2a", "11", "aa", "91", "2a", "12", "aa", "92", "2a", "13", "aa", "93", "2a", "14", "aa", "94", "2a", "15", "aa", "95", "2a", "16", "aa", "96", "2a", "17", "aa", "97", "2a", "18", "aa", "98", "2a", "19", "aa", "99", "2a", "1a", "aa", "9a", "2a", "1b", "aa", "9b", "1c", "9c"}, - {"1e", "9e", "1f", "9f", "20", "a0", "21", "a1", "22", "a2", "23", "a3", "24", "a4", "25", "a5", "26", "a6", "27", "a7", "28", "a8", "29", "a9", "1c", "9c"}, - {"2a", "1e", "aa", "9e", "2a", "1f", "aa", "9f", "2a", "20", "aa", "a0", "2a", "21", "aa", "a1", "2a", "22", "aa", "a2", "2a", "23", "aa", "a3", "2a", "24", "aa", "a4", "2a", "25", "aa", "a5", "2a", "26", "aa", "a6", "2a", "27", "aa", "a7", "2a", "28", "aa", "a8", "2a", "29", "aa", "a9", "1c", "9c"}, - {"2b", "ab", "2c", "ac", "2d", "ad", "2e", "ae", "2f", "af", "30", "b0", "31", "b1", "32", "b2", "33", "b3", "34", "b4", "35", "b5", "1c", "9c"}, - {"2a", "2b", "aa", "ab", "2a", "2c", "aa", "ac", "2a", "2d", "aa", "ad", "2a", "2e", "aa", "ae", "2a", "2f", "aa", "af", "2a", "30", "aa", "b0", "2a", "31", "aa", "b1", "2a", "32", "aa", "b2", "2a", "33", "aa", "b3", "2a", "34", "aa", "b4", "2a", "35", "aa", "b5", "1c", "9c"}, - {"1c", "9c"}, - {"38", "01", "81", "b8", "wait5"}, - {"0f", "8f", "0f", "8f", "0f", "8f", "0f", "8f", "0f", "8f", "39", "b9", "wait5"}, - } - - for i, command := range bootcommand { - for j, code := range scancodes(command) { - if code != expected[i][j] { - t.Fatalf("%#v should have become %#v", scancodes(command), expected[i]) - } - } - } -} -*/ diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 3c663d51b..fceb8c51b 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -10,8 +10,6 @@ import ( /* TODO: - * tests - * fix vbox tests * pc-at abstraction * check that `<del>` works. It's different now. * parallels From 36aeaf27b33161a4db910116f48568ef5276daac Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 16:48:26 -0700 Subject: [PATCH 0947/1007] Use a partial for the boot command docs. I know we rejected this idea back in #4061, but we are closer to being at a point where we can host a version of the website on master, and this will help push that through. --- .../source/docs/builders/hyperv-iso.html.md | 64 +---------------- .../source/docs/builders/hyperv-vmcx.html.md | 59 +--------------- .../docs/builders/parallels-iso.html.md | 63 +---------------- .../docs/builders/parallels-pvm.html.md | 55 +-------------- website/source/docs/builders/qemu.html.md | 68 +------------------ .../docs/builders/virtualbox-iso.html.md | 67 +----------------- .../docs/builders/virtualbox-ovf.html.md | 61 +---------------- .../source/docs/builders/vmware-iso.html.md | 66 +----------------- .../source/docs/builders/vmware-vmx.html.md | 58 +--------------- .../partials/builders/_boot-command.html.md | 68 +++++++++++++++++++ 10 files changed, 90 insertions(+), 539 deletions(-) create mode 100644 website/source/partials/builders/_boot-command.html.md diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md index e33e14ab1..ca5553d68 100644 --- a/website/source/docs/builders/hyperv-iso.html.md +++ b/website/source/docs/builders/hyperv-iso.html.md @@ -102,7 +102,7 @@ can be configured for this builder. - `skip_export` (boolean) - If true skips VM export. If you are interested only in the vhd/vhdx files, you can enable this option. This will create inline disks which improves the build performance. There will not be any copying of source vhds to temp directory. This defaults to false. - + - `enable_dynamic_memory` (boolean) - If true enable dynamic memory for virtual machine. This defaults to false. @@ -245,67 +245,9 @@ strings are all typed in sequence. It is an array only to improve readability within the template. The boot command is "typed" character for character over the virtual keyboard -to the machine, simulating a human actually typing the keyboard. There are -a set of special keys available. If these are in your boot command, they -will be replaced by the proper key: +to the machine, simulating a human actually typing the keyboard. -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, -otherwise they will be held down until the machine reboots. Use lowercase -characters as well inside modifiers. For example: to simulate ctrl+c use -`<leftCtrlOn>c<leftCtrlOff>`. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). -The available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will - be blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md index 5ff7b604d..084c37043 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md +++ b/website/source/docs/builders/hyperv-vmcx.html.md @@ -245,64 +245,9 @@ strings are all typed in sequence. It is an array only to improve readability within the template. The boot command is "typed" character for character over the virtual keyboard -to the machine, simulating a human actually typing the keyboard. There are -a set of special keys available. If these are in your boot command, they -will be replaced by the proper key: +to the machine, simulating a human actually typing the keyboard. -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, otherwise they will be held down until the machine reboots. Use lowercase characters as well inside modifiers. For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. - -In addition to the special keys, each command to type is treated as a -[configuration template](/docs/templates/configuration-templates.html). -The available variables are: - -* `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will - be blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/docs/builders/parallels-iso.html.md b/website/source/docs/builders/parallels-iso.html.md index e7f0dd4a4..24bae4b17 100644 --- a/website/source/docs/builders/parallels-iso.html.md +++ b/website/source/docs/builders/parallels-iso.html.md @@ -246,68 +246,9 @@ template. The boot command is "typed" character for character (using the Parallels Virtualization SDK, see [Parallels Builder](/docs/builders/parallels.html)) -simulating a human actually typing the keyboard. There are a set of special keys -available. If these are in your boot command, they will be replaced by the -proper key: +simulating a human actually typing the keyboard. -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, -otherwise they will be held down until the machine reboots. Use lowercase -characters as well inside modifiers. - -For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/docs/builders/parallels-pvm.html.md b/website/source/docs/builders/parallels-pvm.html.md index 59accdcd1..b14705fa0 100644 --- a/website/source/docs/builders/parallels-pvm.html.md +++ b/website/source/docs/builders/parallels-pvm.html.md @@ -179,60 +179,9 @@ template. The boot command is "typed" character for character (using the Parallels Virtualization SDK, see [Parallels Builder](/docs/builders/parallels.html)) -simulating a human actually typing the keyboard. There are a set of special keys -available. If these are in your boot command, they will be replaced by the -proper key: +simulating a human actually typing the keyboard. -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -For more examples of various boot commands, see the sample projects from our -[community templates page](/community-tools.html#templates). +<%= partial "partials/builders/boot-command" %> ## prlctl Commands diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md index bdd39410b..33f6c5014 100644 --- a/website/source/docs/builders/qemu.html.md +++ b/website/source/docs/builders/qemu.html.md @@ -110,8 +110,8 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). ### Optional: - `accelerator` (string) - The accelerator type to use when running the VM. - This may be `none`, `kvm`, `tcg`, `hax`, or `xen`. The appropriate software - must have already been installed on your build machine to use the accelerator + This may be `none`, `kvm`, `tcg`, `hax`, or `xen`. The appropriate software + must have already been installed on your build machine to use the accelerator you specified. When no accelerator is specified, Packer will try to use `kvm` if it is available but will default to `tcg` otherwise. @@ -370,69 +370,7 @@ default 100ms delay. The delay alleviates issues with latency and CPU contention. For local builds you can tune this delay by specifying e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command. -There are a set of special keys available. If these are in your boot -command, they will be replaced by the proper key: - -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -- `<waitXX>` - Add user defined time.Duration pause before sending any - additional keys. For example `<wait10m>` or `<wait1m20s>` - -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, -otherwise they will be held down until the machine reboots. Use lowercase -characters as well inside modifiers. For example: to simulate ctrl+c use -`<leftCtrlOn>c<leftCtrlOff>`. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an CentOS 6.4 installer: diff --git a/website/source/docs/builders/virtualbox-iso.html.md b/website/source/docs/builders/virtualbox-iso.html.md index 85d4905ed..0fc2152dc 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md +++ b/website/source/docs/builders/virtualbox-iso.html.md @@ -331,71 +331,10 @@ As documented above, the `boot_command` is an array of strings. The strings are all typed in sequence. It is an array only to improve readability within the template. -The boot command is "typed" character for character over a VNC connection to the -machine, simulating a human actually typing the keyboard. There are a set of -special keys available. If these are in your boot command, they will be replaced -by the proper key: +The boot command is sent to the VM through the `VBoxManage` utility in as few +invocations as possible. -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the - ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the - shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, -otherwise they will be held down until the machine reboots. Use lowercase -characters as well inside modifiers. - -For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/docs/builders/virtualbox-ovf.html.md b/website/source/docs/builders/virtualbox-ovf.html.md index d58101100..91e718f56 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md +++ b/website/source/docs/builders/virtualbox-ovf.html.md @@ -293,65 +293,10 @@ As documented above, the `boot_command` is an array of strings. The strings are all typed in sequence. It is an array only to improve readability within the template. -The boot command is "typed" character for character over a VNC connection to the -machine, simulating a human actually typing the keyboard. There are a set of -special keys available. If these are in your boot command, they will be replaced -by the proper key: +The boot command is sent to the VM through the `VBoxManage` utility in as few +invocations as possible. -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the - ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the - shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 86d79e93b..1598421ab 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -108,7 +108,7 @@ builder. is full. By default this is set to 40,000 (about 40 GB). - `disk_type_id` (string) - The type of VMware virtual disk to create. This - option is for advanced usage. + option is for advanced usage. For desktop VMware clients: @@ -122,7 +122,7 @@ builder. `5` | Compressed disk optimized for streaming. The default is "1". - + For ESXi, this defaults to "zeroedthick". The available options for ESXi are: `zeroedthick`, `eagerzeroedthick`, `thin`, `rdm:dev`, `rdmp:dev`, `2gbsparse`. @@ -425,67 +425,7 @@ default 100ms delay. The delay alleviates issues with latency and CPU contention. For local builds you can tune this delay by specifying e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command. -There are a set of special keys available. If these are in your boot -command, they will be replaced by the proper key: - -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, -otherwise they will be held down until the machine reboots. Use lowercase -characters as well inside modifiers. - -For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index ae5bfd29f..f564626b6 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -198,63 +198,7 @@ default 100ms delay. The delay alleviates issues with latency and CPU contention. For local builds you can tune this delay by specifying e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command. -There are a set of special keys available. If these are in your boot -command, they will be replaced by the proper key: - -- `<bs>` - Backspace - -- `<del>` - Delete - -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. - -- `<esc>` - Simulates pressing the escape key. - -- `<tab>` - Simulates pressing the tab key. - -- `<f1>` - `<f12>` - Simulates pressing a function key. - -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. - -- `<spacebar>` - Simulates pressing the spacebar. - -- `<insert>` - Simulates pressing the insert key. - -- `<home>` `<end>` - Simulates pressing the home and end keys. - -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. - -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. - -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. - -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. - -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. - -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl - key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the - shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before - sending any additional keys. This is useful if you have to generally wait - for the UI to update before typing more. - -In addition to the special keys, each command to type is treated as a -[template engine](/docs/templates/engine.html). The -available variables are: - -- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server - that is started serving the directory specified by the `http_directory` - configuration parameter. If `http_directory` isn't specified, these will be - blank! +<%= partial "partials/builders/boot-command" %> Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: diff --git a/website/source/partials/builders/_boot-command.html.md b/website/source/partials/builders/_boot-command.html.md new file mode 100644 index 000000000..e4e206cae --- /dev/null +++ b/website/source/partials/builders/_boot-command.html.md @@ -0,0 +1,68 @@ +There are a set of special keys available. If these are in your boot +command, they will be replaced by the proper key: + +- `<bs>` - Backspace + +- `<del>` - Delete + +- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. + +- `<esc>` - Simulates pressing the escape key. + +- `<tab>` - Simulates pressing the tab key. + +- `<f1>` - `<f12>` - Simulates pressing a function key. + +- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. + +- `<spacebar>` - Simulates pressing the spacebar. + +- `<insert>` - Simulates pressing the insert key. + +- `<home>` `<end>` - Simulates pressing the home and end keys. + +- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. + +- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. + +- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. + +- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. + +- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. + +- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. + +- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. + +- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. + +- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. + +- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. + +- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before + sending any additional keys. This is useful if you have to generally wait + for the UI to update before typing more. + +- `<waitXX>` - Add user defined time.Duration pause before sending any + additional keys. For example `<wait10m>` or `<wait1m20s>` + +When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, +otherwise they will be held down until the machine reboots. Use lowercase +characters as well inside modifiers. + +For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. + +In addition to the special keys, each command to type is treated as a +[template engine](/docs/templates/engine.html). The +available variables are: + +- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server + that is started serving the directory specified by the `http_directory` + configuration parameter. If `http_directory` isn't specified, these will be + blank! + +For more examples of various boot commands, see the sample projects from our +[community templates page](/community-tools.html#templates). + From 4454e4fb4f660a08a092238bc22319255e68193e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 16:58:13 -0700 Subject: [PATCH 0948/1007] Use erb to add support for partials. --- .../docs/builders/{hyperv-iso.html.md => hyperv-iso.html.md.erb} | 0 .../builders/{hyperv-vmcx.html.md => hyperv-vmcx.html.md.erb} | 0 .../builders/{parallels-iso.html.md => parallels-iso.html.md.erb} | 0 .../builders/{parallels-pvm.html.md => parallels-pvm.html.md.erb} | 0 website/source/docs/builders/{qemu.html.md => qemu.html.md.erb} | 0 .../{virtualbox-iso.html.md => virtualbox-iso.html.md.erb} | 0 .../{virtualbox-ovf.html.md => virtualbox-ovf.html.md.erb} | 0 .../docs/builders/{vmware-iso.html.md => vmware-iso.html.md.erb} | 0 .../docs/builders/{vmware-vmx.html.md => vmware-vmx.html.md.erb} | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename website/source/docs/builders/{hyperv-iso.html.md => hyperv-iso.html.md.erb} (100%) rename website/source/docs/builders/{hyperv-vmcx.html.md => hyperv-vmcx.html.md.erb} (100%) rename website/source/docs/builders/{parallels-iso.html.md => parallels-iso.html.md.erb} (100%) rename website/source/docs/builders/{parallels-pvm.html.md => parallels-pvm.html.md.erb} (100%) rename website/source/docs/builders/{qemu.html.md => qemu.html.md.erb} (100%) rename website/source/docs/builders/{virtualbox-iso.html.md => virtualbox-iso.html.md.erb} (100%) rename website/source/docs/builders/{virtualbox-ovf.html.md => virtualbox-ovf.html.md.erb} (100%) rename website/source/docs/builders/{vmware-iso.html.md => vmware-iso.html.md.erb} (100%) rename website/source/docs/builders/{vmware-vmx.html.md => vmware-vmx.html.md.erb} (100%) diff --git a/website/source/docs/builders/hyperv-iso.html.md b/website/source/docs/builders/hyperv-iso.html.md.erb similarity index 100% rename from website/source/docs/builders/hyperv-iso.html.md rename to website/source/docs/builders/hyperv-iso.html.md.erb diff --git a/website/source/docs/builders/hyperv-vmcx.html.md b/website/source/docs/builders/hyperv-vmcx.html.md.erb similarity index 100% rename from website/source/docs/builders/hyperv-vmcx.html.md rename to website/source/docs/builders/hyperv-vmcx.html.md.erb diff --git a/website/source/docs/builders/parallels-iso.html.md b/website/source/docs/builders/parallels-iso.html.md.erb similarity index 100% rename from website/source/docs/builders/parallels-iso.html.md rename to website/source/docs/builders/parallels-iso.html.md.erb diff --git a/website/source/docs/builders/parallels-pvm.html.md b/website/source/docs/builders/parallels-pvm.html.md.erb similarity index 100% rename from website/source/docs/builders/parallels-pvm.html.md rename to website/source/docs/builders/parallels-pvm.html.md.erb diff --git a/website/source/docs/builders/qemu.html.md b/website/source/docs/builders/qemu.html.md.erb similarity index 100% rename from website/source/docs/builders/qemu.html.md rename to website/source/docs/builders/qemu.html.md.erb diff --git a/website/source/docs/builders/virtualbox-iso.html.md b/website/source/docs/builders/virtualbox-iso.html.md.erb similarity index 100% rename from website/source/docs/builders/virtualbox-iso.html.md rename to website/source/docs/builders/virtualbox-iso.html.md.erb diff --git a/website/source/docs/builders/virtualbox-ovf.html.md b/website/source/docs/builders/virtualbox-ovf.html.md.erb similarity index 100% rename from website/source/docs/builders/virtualbox-ovf.html.md rename to website/source/docs/builders/virtualbox-ovf.html.md.erb diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md.erb similarity index 100% rename from website/source/docs/builders/vmware-iso.html.md rename to website/source/docs/builders/vmware-iso.html.md.erb diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md.erb similarity index 100% rename from website/source/docs/builders/vmware-vmx.html.md rename to website/source/docs/builders/vmware-vmx.html.md.erb From f5b09c8c38491480fb90c3162926f4d79d7bd676 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 19:48:19 -0700 Subject: [PATCH 0949/1007] set vim pandoc modeline --- website/source/docs/builders/hyperv-iso.html.md.erb | 2 ++ website/source/docs/builders/hyperv-vmcx.html.md.erb | 2 ++ website/source/docs/builders/parallels-iso.html.md.erb | 2 ++ website/source/docs/builders/parallels-pvm.html.md.erb | 2 ++ website/source/docs/builders/qemu.html.md.erb | 2 ++ website/source/docs/builders/virtualbox-iso.html.md.erb | 2 ++ website/source/docs/builders/virtualbox-ovf.html.md.erb | 2 ++ website/source/docs/builders/vmware-iso.html.md.erb | 2 ++ website/source/docs/builders/vmware-vmx.html.md.erb | 2 ++ 9 files changed, 18 insertions(+) diff --git a/website/source/docs/builders/hyperv-iso.html.md.erb b/website/source/docs/builders/hyperv-iso.html.md.erb index ca5553d68..95bfa6293 100644 --- a/website/source/docs/builders/hyperv-iso.html.md.erb +++ b/website/source/docs/builders/hyperv-iso.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | The Hyper-V Packer builder is able to create Hyper-V virtual machines and export them. diff --git a/website/source/docs/builders/hyperv-vmcx.html.md.erb b/website/source/docs/builders/hyperv-vmcx.html.md.erb index 084c37043..9f4da1f20 100644 --- a/website/source/docs/builders/hyperv-vmcx.html.md.erb +++ b/website/source/docs/builders/hyperv-vmcx.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: |- The Hyper-V Packer builder is able to clone an existing Hyper-V virtual machine and export them. layout: "docs" diff --git a/website/source/docs/builders/parallels-iso.html.md.erb b/website/source/docs/builders/parallels-iso.html.md.erb index 24bae4b17..5e1b19da4 100644 --- a/website/source/docs/builders/parallels-iso.html.md.erb +++ b/website/source/docs/builders/parallels-iso.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | The Parallels Packer builder is able to create Parallels Desktop for Mac virtual machines and export them in the PVM format, starting from an ISO diff --git a/website/source/docs/builders/parallels-pvm.html.md.erb b/website/source/docs/builders/parallels-pvm.html.md.erb index b14705fa0..9cc9ab14a 100644 --- a/website/source/docs/builders/parallels-pvm.html.md.erb +++ b/website/source/docs/builders/parallels-pvm.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | This Parallels builder is able to create Parallels Desktop for Mac virtual machines and export them in the PVM format, starting from an existing PVM diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index 33f6c5014..a1c2073db 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | The Qemu Packer builder is able to create KVM and Xen virtual machine images. layout: docs diff --git a/website/source/docs/builders/virtualbox-iso.html.md.erb b/website/source/docs/builders/virtualbox-iso.html.md.erb index 0fc2152dc..b89eb0586 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md.erb +++ b/website/source/docs/builders/virtualbox-iso.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | The VirtualBox Packer builder is able to create VirtualBox virtual machines and export them in the OVF format, starting from an ISO image. diff --git a/website/source/docs/builders/virtualbox-ovf.html.md.erb b/website/source/docs/builders/virtualbox-ovf.html.md.erb index 91e718f56..a1f0015d8 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md.erb +++ b/website/source/docs/builders/virtualbox-ovf.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | This VirtualBox Packer builder is able to create VirtualBox virtual machines and export them in the OVF format, starting from an existing OVF/OVA (exported diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index 1598421ab..5ad13c117 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | This VMware Packer builder is able to create VMware virtual machines from an ISO file as a source. It currently supports building virtual machines on hosts diff --git a/website/source/docs/builders/vmware-vmx.html.md.erb b/website/source/docs/builders/vmware-vmx.html.md.erb index f564626b6..bd4a84312 100644 --- a/website/source/docs/builders/vmware-vmx.html.md.erb +++ b/website/source/docs/builders/vmware-vmx.html.md.erb @@ -1,4 +1,6 @@ --- +modeline: | + vim: set ft=pandoc: description: | This VMware Packer builder is able to create VMware virtual machines from an existing VMware virtual machine (a VMX file). It currently supports building From c753391f43a506d24043708743acd13446b04b60 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 20:08:22 -0700 Subject: [PATCH 0950/1007] fill out and reformat the boot command docs --- .../partials/builders/_boot-command.html.md | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/website/source/partials/builders/_boot-command.html.md b/website/source/partials/builders/_boot-command.html.md index e4e206cae..a8dc570a0 100644 --- a/website/source/partials/builders/_boot-command.html.md +++ b/website/source/partials/builders/_boot-command.html.md @@ -5,54 +5,53 @@ command, they will be replaced by the proper key: - `<del>` - Delete -- `<enter>` and `<return>` - Simulates an actual "enter" or "return" keypress. +- `<enter> <return>` - Simulates an actual "enter" or "return" keypress. - `<esc>` - Simulates pressing the escape key. - `<tab>` - Simulates pressing the tab key. -- `<f1>` - `<f12>` - Simulates pressing a function key. +- `<f1> - <f12>` - Simulates pressing a function key. -- `<up>` `<down>` `<left>` `<right>` - Simulates pressing an arrow key. +- `<up> <down> <left> <right>` - Simulates pressing an arrow key. - `<spacebar>` - Simulates pressing the spacebar. - `<insert>` - Simulates pressing the insert key. -- `<home>` `<end>` - Simulates pressing the home and end keys. +- `<home> <end>` - Simulates pressing the home and end keys. -- `<pageUp>` `<pageDown>` - Simulates pressing the page up and page down keys. +- `<pageUp> <pageDown>` - Simulates pressing the page up and page down keys. -- `<leftAlt>` `<rightAlt>` - Simulates pressing the alt key. +- `<leftAlt> <rightAlt>` - Simulates pressing the alt key. -- `<leftCtrl>` `<rightCtrl>` - Simulates pressing the ctrl key. +- `<leftCtrl> <rightCtrl>` - Simulates pressing the ctrl key. -- `<leftShift>` `<rightShift>` - Simulates pressing the shift key. +- `<leftShift> <rightShift>` - Simulates pressing the shift key. -- `<leftAltOn>` `<rightAltOn>` - Simulates pressing and holding the alt key. +- `<leftSuper> <rightSuper>` - Simulates pressing the ⌘ or Windows key. -- `<leftCtrlOn>` `<rightCtrlOn>` - Simulates pressing and holding the ctrl key. - -- `<leftShiftOn>` `<rightShiftOn>` - Simulates pressing and holding the shift key. - -- `<leftAltOff>` `<rightAltOff>` - Simulates releasing a held alt key. - -- `<leftCtrlOff>` `<rightCtrlOff>` - Simulates releasing a held ctrl key. - -- `<leftShiftOff>` `<rightShiftOff>` - Simulates releasing a held shift key. - -- `<wait>` `<wait5>` `<wait10>` - Adds a 1, 5 or 10 second pause before +- `<wait> <wait5> <wait10>` - Adds a 1, 5 or 10 second pause before sending any additional keys. This is useful if you have to generally wait for the UI to update before typing more. -- `<waitXX>` - Add user defined time.Duration pause before sending any - additional keys. For example `<wait10m>` or `<wait1m20s>` +- `<waitXX>` - Add an arbitrary pause before sending any additional keys. The + format of `XX` is a possibly signed sequence of decimal numbers, each with + optional fraction and a unit suffix, such as `300ms`, `-1.5h` or `2h45m`. + Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. For example + `<wait10m>` or `<wait1m20s>` -When using modifier keys `ctrl`, `alt`, `shift` ensure that you release them, -otherwise they will be held down until the machine reboots. Use lowercase -characters as well inside modifiers. -For example: to simulate ctrl+c use `<leftCtrlOn>c<leftCtrlOff>`. +### On/Off variants + +Any printable keyboard character, and of these "special" expressions, with the +exception of the `<wait>` types, can also be toggled on or off. For example, to +simulate ctrl+c, use `<leftCtrlOn>c<leftCtrlOff>`. Be sure to release them, +otherwise they will be held down until the machine reboots. + +To hold the `c` key down, you would use `<cOn>`. Likewise, `<cOff>` to release. + +### Templates inside boot command In addition to the special keys, each command to type is treated as a [template engine](/docs/templates/engine.html). The @@ -62,6 +61,7 @@ available variables are: that is started serving the directory specified by the `http_directory` configuration parameter. If `http_directory` isn't specified, these will be blank! +* `Name` - The name of the VM. For more examples of various boot commands, see the sample projects from our [community templates page](/community-tools.html#templates). From 94129b7fe3aba2e78cfec5771bb627de31b931d4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 13 Apr 2018 21:06:37 -0700 Subject: [PATCH 0951/1007] we're using PC-XT (set1) not PC-AT --- .../hyperv/common/step_type_boot_command.go | 2 +- .../common/step_type_boot_command.go | 2 +- .../common/step_type_boot_command.go | 2 +- .../{pc_at_driver.go => pc_xt_driver.go} | 19 ++++++++++--------- ...at_driver_test.go => pc_xt_driver_test.go} | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) rename common/boot_command/{pc_at_driver.go => pc_xt_driver.go} (90%) rename common/boot_command/{pc_at_driver_test.go => pc_xt_driver_test.go} (94%) diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index 5772ce1b9..9b8b08654 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -84,7 +84,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) scanCodesToSendString := strings.Join(codes, " ") return driver.TypeScanCodes(vmName, scanCodesToSendString) } - d := bootcommand.NewPCATDriver(sendCodes, -1) + d := bootcommand.NewPCXTDriver(sendCodes, -1) flatCommands := strings.Join(commands, "") seq, err := bootcommand.GenerateExpressionSequence(flatCommands) diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index 306182d6a..899462f15 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -81,7 +81,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) log.Printf("Sending scancodes: %#v", codes) return driver.SendKeyScanCodes(s.VMName, codes...) } - d := bootcommand.NewPCATDriver(sendCodes, -1) + d := bootcommand.NewPCXTDriver(sendCodes, -1) ui.Say("Typing the boot command...") for i, command := range s.BootCommand { diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index b979ef59f..cb0df4e40 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -64,7 +64,7 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) return driver.VBoxManage(args...) } - d := bootcommand.NewPCATDriver(sendCodes, 25) + d := bootcommand.NewPCXTDriver(sendCodes, 25) ui.Say("Typing the boot command...") for i, command := range s.BootCommand { diff --git a/common/boot_command/pc_at_driver.go b/common/boot_command/pc_xt_driver.go similarity index 90% rename from common/boot_command/pc_at_driver.go rename to common/boot_command/pc_xt_driver.go index e227f3eca..9107f5b85 100644 --- a/common/boot_command/pc_at_driver.go +++ b/common/boot_command/pc_xt_driver.go @@ -15,7 +15,7 @@ import ( // SendCodeFunc will be called to send codes to the VM type SendCodeFunc func([]string) error -type pcATDriver struct { +type pcXTDriver struct { interval time.Duration sendImpl SendCodeFunc specialMap map[string][]string @@ -25,17 +25,18 @@ type pcATDriver struct { scancodeChunkSize int } -// NewPCATDriver creates a new boot command driver for VMs that expect PC-AT +// NewPCXTDriver creates a new boot command driver for VMs that expect PC-XT // keyboard codes. `send` should send its argument to the VM. `chunkSize` should // be the maximum number of keyboard codes to send to `send` at one time. -func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { +func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver { // We delay (default 100ms) between each input event to allow for CPU or // network latency. See PackerKeyEnv for tuning. keyInterval := common.PackerKeyDefault if delay, err := time.ParseDuration(os.Getenv(common.PackerKeyEnv)); err == nil { keyInterval = delay } - // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + // Scancodes reference: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + // https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html // // Scancodes are recorded here in pairs. The first entry represents // the key press and the second entry represents the key release and is @@ -100,7 +101,7 @@ func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { } } - return &pcATDriver{ + return &pcXTDriver{ interval: keyInterval, sendImpl: send, specialMap: sMap, @@ -110,7 +111,7 @@ func NewPCATDriver(send SendCodeFunc, chunkSize int) *pcATDriver { } // Finalize flushes all scanecodes. -func (d *pcATDriver) Finalize() error { +func (d *pcXTDriver) Finalize() error { defer func() { d.buffer = nil }() @@ -127,7 +128,7 @@ func (d *pcATDriver) Finalize() error { return nil } -func (d *pcATDriver) SendKey(key rune, action KeyAction) error { +func (d *pcXTDriver) SendKey(key rune, action KeyAction) error { keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) @@ -157,7 +158,7 @@ func (d *pcATDriver) SendKey(key rune, action KeyAction) error { return nil } -func (d *pcATDriver) SendSpecial(special string, action KeyAction) error { +func (d *pcXTDriver) SendSpecial(special string, action KeyAction) error { keyCode, ok := d.specialMap[special] if !ok { return fmt.Errorf("special %s not found.", special) @@ -175,7 +176,7 @@ func (d *pcATDriver) SendSpecial(special string, action KeyAction) error { } // send stores the codes in an internal buffer. Use finalize to flush them. -func (d *pcATDriver) send(codes []string) { +func (d *pcXTDriver) send(codes []string) { d.buffer = append(d.buffer, codes) } diff --git a/common/boot_command/pc_at_driver_test.go b/common/boot_command/pc_xt_driver_test.go similarity index 94% rename from common/boot_command/pc_at_driver_test.go rename to common/boot_command/pc_xt_driver_test.go index f9323cfea..ca4f5eb3d 100644 --- a/common/boot_command/pc_at_driver_test.go +++ b/common/boot_command/pc_xt_driver_test.go @@ -71,7 +71,7 @@ func Test_chunkScanCodeError(t *testing.T) { assert.Error(t, err) } -func Test_pcatSpecialLookup(t *testing.T) { +func Test_pcxtSpecialLookup(t *testing.T) { in := "<rightShift><rightshiftoff><RIGHTSHIFTON>" expected := []string{"36", "b6", "b6", "36"} var codes []string @@ -79,7 +79,7 @@ func Test_pcatSpecialLookup(t *testing.T) { codes = c return nil } - d := NewPCATDriver(sendCodes, -1) + d := NewPCXTDriver(sendCodes, -1) seq, err := GenerateExpressionSequence(in) assert.NoError(t, err) err = seq.Do(context.Background(), d) From 9a839c401b694c15ead15ee9128dbb6193236e74 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sat, 14 Apr 2018 13:00:43 -0700 Subject: [PATCH 0952/1007] fix formatting --- website/source/partials/builders/_boot-command.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/partials/builders/_boot-command.html.md b/website/source/partials/builders/_boot-command.html.md index a8dc570a0..084fbd8fc 100644 --- a/website/source/partials/builders/_boot-command.html.md +++ b/website/source/partials/builders/_boot-command.html.md @@ -61,7 +61,7 @@ available variables are: that is started serving the directory specified by the `http_directory` configuration parameter. If `http_directory` isn't specified, these will be blank! -* `Name` - The name of the VM. +- `Name` - The name of the VM. For more examples of various boot commands, see the sample projects from our [community templates page](/community-tools.html#templates). From add7e8acb93a90235b257727d6c98d6d9ab6f504 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sun, 15 Apr 2018 22:08:40 -0700 Subject: [PATCH 0953/1007] Stop sending boot commands when context canceled. --- common/boot_command/boot_command_ast.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index fceb8c51b..16b562e95 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -50,6 +50,9 @@ type expressionSequence []expression // Do executes every expression in the sequence and then finalizes the driver. func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { for _, exp := range s { + if err := ctx.Err(); err != nil { + return err + } if err := exp.Do(ctx, b); err != nil { return err } From 9a8acbbcab65ebd7b7b7d38bc65b3dc6908ae3be Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 16 Apr 2018 13:37:17 -0700 Subject: [PATCH 0954/1007] negative wait WIP --- common/boot_command/boot_command_ast.go | 6 ++++++ common/boot_command/boot_command_ast_test.go | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 16b562e95..38ce97144 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -84,6 +84,12 @@ type waitExpression struct { // Do waits the amount of time described by the expression. It is cancellable // through the context. func (w *waitExpression) Do(ctx context.Context, _ BCDriver) error { + /* + // do I want this to not parse or to error? + if w.d < 0 { + panic("Was not expecting negative wait duration.") + } + */ log.Printf("[INFO] Waiting %s", w.d) select { case <-time.After(w.d): diff --git a/common/boot_command/boot_command_ast_test.go b/common/boot_command/boot_command_ast_test.go index 613b427b7..60369f572 100644 --- a/common/boot_command/boot_command_ast_test.go +++ b/common/boot_command/boot_command_ast_test.go @@ -99,3 +99,18 @@ func Test_special(t *testing.T) { } } } + +func Test_negativeWait(t *testing.T) { + in := "<wait-1m>" + _, err := ParseReader("", strings.NewReader(in)) + if err != nil { + log.Fatal(err) + } + + /* + gL := toIfaceSlice(got) + for _, g := range gL { + assert.Equal(t, tt.out, g.(*specialExpression).String()) + } + */ +} From 84894ca459a20dc14d2c25cb65161c3f4824384b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 16 Apr 2018 14:03:54 -0700 Subject: [PATCH 0955/1007] remove nonsensical negative waits. --- website/source/partials/builders/_boot-command.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/partials/builders/_boot-command.html.md b/website/source/partials/builders/_boot-command.html.md index 084fbd8fc..4230426cb 100644 --- a/website/source/partials/builders/_boot-command.html.md +++ b/website/source/partials/builders/_boot-command.html.md @@ -36,8 +36,8 @@ command, they will be replaced by the proper key: for the UI to update before typing more. - `<waitXX>` - Add an arbitrary pause before sending any additional keys. The - format of `XX` is a possibly signed sequence of decimal numbers, each with - optional fraction and a unit suffix, such as `300ms`, `-1.5h` or `2h45m`. + format of `XX` is a sequence of positive decimal numbers, each with + optional fraction and a unit suffix, such as `300ms`, `1.5h` or `2h45m`. Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. For example `<wait10m>` or `<wait1m20s>` From 408eba88ade17311bc9d3a650c1495093beb5e80 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 14:10:28 -0700 Subject: [PATCH 0956/1007] flatten boot command config and implement for vmware --- builder/vmware/common/run_config.go | 34 ++-------- builder/vmware/common/run_config_test.go | 36 ---------- .../vmware/common/step_type_boot_command.go | 50 +++++++------- builder/vmware/iso/builder.go | 5 +- builder/vmware/vmx/builder.go | 2 +- builder/vmware/vmx/config.go | 3 + common/boot_command/boot_command_ast.go | 6 -- common/boot_command/boot_command_ast_test.go | 6 +- common/boot_command/config.go | 50 ++++++++++++++ common/boot_command/config_test.go | 65 +++++++++++++++++++ 10 files changed, 154 insertions(+), 103 deletions(-) delete mode 100644 builder/vmware/common/run_config_test.go create mode 100644 common/boot_command/config.go create mode 100644 common/boot_command/config_test.go diff --git a/builder/vmware/common/run_config.go b/builder/vmware/common/run_config.go index 9463d8753..c4bfc3413 100644 --- a/builder/vmware/common/run_config.go +++ b/builder/vmware/common/run_config.go @@ -2,30 +2,20 @@ package common import ( "fmt" - "time" "github.com/hashicorp/packer/template/interpolate" ) type RunConfig struct { - Headless bool `mapstructure:"headless"` - RawBootWait string `mapstructure:"boot_wait"` - DisableVNC bool `mapstructure:"disable_vnc"` - BootCommand []string `mapstructure:"boot_command"` + Headless bool `mapstructure:"headless"` VNCBindAddress string `mapstructure:"vnc_bind_address"` VNCPortMin uint `mapstructure:"vnc_port_min"` VNCPortMax uint `mapstructure:"vnc_port_max"` VNCDisablePassword bool `mapstructure:"vnc_disable_password"` - - BootWait time.Duration `` } -func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { - if c.RawBootWait == "" { - c.RawBootWait = "10s" - } - +func (c *RunConfig) Prepare(ctx *interpolate.Context) (errs []error) { if c.VNCPortMin == 0 { c.VNCPortMin = 5900 } @@ -38,25 +28,9 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.VNCBindAddress = "127.0.0.1" } - var errs []error - var err error - if len(c.BootCommand) > 0 && c.DisableVNC { - errs = append(errs, - fmt.Errorf("A boot command cannot be used when vnc is disabled.")) - } - - if c.RawBootWait != "" { - c.BootWait, err = time.ParseDuration(c.RawBootWait) - if err != nil { - errs = append( - errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) - } - } - if c.VNCPortMin > c.VNCPortMax { - errs = append( - errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) + errs = append(errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) } - return errs + return } diff --git a/builder/vmware/common/run_config_test.go b/builder/vmware/common/run_config_test.go deleted file mode 100644 index d94e254f7..000000000 --- a/builder/vmware/common/run_config_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package common - -import ( - "testing" -) - -func TestRunConfigPrepare(t *testing.T) { - var c *RunConfig - - // Test a default boot_wait - c = new(RunConfig) - c.RawBootWait = "" - errs := c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("bad: %#v", errs) - } - if c.RawBootWait != "10s" { - t.Fatalf("bad value: %s", c.RawBootWait) - } - - // Test with a bad boot_wait - c = new(RunConfig) - c.RawBootWait = "this is not good" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) == 0 { - t.Fatal("should error") - } - - // Test with a good one - c = new(RunConfig) - c.RawBootWait = "5s" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("bad: %#v", errs) - } -} diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 6821b8e1b..7544c4c3e 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -25,7 +25,7 @@ import ( // Produces: // <nothing> type StepTypeBootCommand struct { - BootCommand []string + BootCommand string VNCEnabled bool BootWait time.Duration VMName string @@ -118,34 +118,32 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) d := bootcommand.NewVNCDriver(c) ui.Say("Typing the boot command over VNC...") - for i, command := range s.BootCommand { - command, err := interpolate.Render(command, &s.Ctx) - if err != nil { - err := fmt.Errorf("Error preparing boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + command, err := interpolate.Render(s.BootCommand, &s.Ctx) + if err != nil { + err := fmt.Errorf("Error preparing boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - seq, err := bootcommand.GenerateExpressionSequence(command) - if err != nil { - err := fmt.Errorf("Error generating boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if err := seq.Do(ctx, d); err != nil { - err := fmt.Errorf("Error running boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - if pauseFn != nil { - pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) - } + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + if pauseFn != nil { + pauseFn(multistep.DebugLocationAfterRun, + fmt.Sprintf("boot_command: %s", command), state) } return multistep.ActionContinue diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 5f1399c06..1edd778ee 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -11,6 +11,7 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" @@ -30,6 +31,7 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.VNCConfig `mapstructure:",squash"` vmwcommon.DriverConfig `mapstructure:",squash"` vmwcommon.OutputConfig `mapstructure:",squash"` vmwcommon.RunConfig `mapstructure:",squash"` @@ -122,6 +124,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.ToolsConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.VMXConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.VNCConfig.Prepare(&b.config.ctx)...) if b.config.DiskName == "" { b.config.DiskName = "disk" @@ -325,7 +328,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &vmwcommon.StepTypeBootCommand{ BootWait: b.config.BootWait, VNCEnabled: !b.config.DisableVNC, - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), VMName: b.config.VMName, Ctx: b.config.ctx, }, diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 69b143ebe..bfe6b06c9 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -93,7 +93,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &vmwcommon.StepTypeBootCommand{ BootWait: b.config.BootWait, VNCEnabled: !b.config.DisableVNC, - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), VMName: b.config.VMName, Ctx: b.config.ctx, }, diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index b4d1c009f..e937136a4 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -6,6 +6,7 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -16,6 +17,7 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` common.HTTPConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.VNCConfig `mapstructure:",squash"` vmwcommon.DriverConfig `mapstructure:",squash"` vmwcommon.OutputConfig `mapstructure:",squash"` vmwcommon.RunConfig `mapstructure:",squash"` @@ -65,6 +67,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.ToolsConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.VMXConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.VNCConfig.Prepare(&c.ctx)...) if c.SourcePath == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is blank, but is required")) diff --git a/common/boot_command/boot_command_ast.go b/common/boot_command/boot_command_ast.go index 38ce97144..16b562e95 100644 --- a/common/boot_command/boot_command_ast.go +++ b/common/boot_command/boot_command_ast.go @@ -84,12 +84,6 @@ type waitExpression struct { // Do waits the amount of time described by the expression. It is cancellable // through the context. func (w *waitExpression) Do(ctx context.Context, _ BCDriver) error { - /* - // do I want this to not parse or to error? - if w.d < 0 { - panic("Was not expecting negative wait duration.") - } - */ log.Printf("[INFO] Waiting %s", w.d) select { case <-time.After(w.d): diff --git a/common/boot_command/boot_command_ast_test.go b/common/boot_command/boot_command_ast_test.go index 60369f572..8536f58c0 100644 --- a/common/boot_command/boot_command_ast_test.go +++ b/common/boot_command/boot_command_ast_test.go @@ -109,8 +109,8 @@ func Test_negativeWait(t *testing.T) { /* gL := toIfaceSlice(got) - for _, g := range gL { - assert.Equal(t, tt.out, g.(*specialExpression).String()) - } + for _, g := range gL { + assert.Equal(t, tt.out, g.(*specialExpression).String()) + } */ } diff --git a/common/boot_command/config.go b/common/boot_command/config.go new file mode 100644 index 000000000..6a5b18cd9 --- /dev/null +++ b/common/boot_command/config.go @@ -0,0 +1,50 @@ +package bootcommand + +import ( + "fmt" + "strings" + "time" + + "github.com/hashicorp/packer/template/interpolate" +) + +type Config struct { + RawBootWait string `mapstructure:"boot_wait"` + BootCommand []string `mapstructure:"boot_command"` + + BootWait time.Duration `` +} + +type VNCConfig struct { + Config + DisableVNC bool `mapstructure:"disable_vnc"` +} + +func (c *Config) Prepare(ctx *interpolate.Context) (errs []error) { + if c.RawBootWait == "" { + c.RawBootWait = "10s" + } + if c.RawBootWait != "" { + bw, err := time.ParseDuration(c.RawBootWait) + if err != nil { + errs = append( + errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) + } else { + c.BootWait = bw + } + } + return +} + +func (c *Config) FlatBootCommand() string { + return strings.Join(c.BootCommand, "") +} + +func (c *VNCConfig) Prepare(ctx *interpolate.Context) (errs []error) { + if len(c.BootCommand) > 0 && c.DisableVNC { + errs = append(errs, + fmt.Errorf("A boot command cannot be used when vnc is disabled.")) + } + errs = append(errs, c.Config.Prepare(ctx)...) + return +} diff --git a/common/boot_command/config_test.go b/common/boot_command/config_test.go new file mode 100644 index 000000000..608e48c0a --- /dev/null +++ b/common/boot_command/config_test.go @@ -0,0 +1,65 @@ +package bootcommand + +import ( + "testing" + + "github.com/hashicorp/packer/template/interpolate" +) + +func TestConfigPrepare(t *testing.T) { + var c *Config + + // Test a default boot_wait + c = new(Config) + c.RawBootWait = "" + errs := c.Prepare(&interpolate.Context{}) + if len(errs) > 0 { + t.Fatalf("bad: %#v", errs) + } + if c.RawBootWait != "10s" { + t.Fatalf("bad value: %s", c.RawBootWait) + } + + // Test with a bad boot_wait + c = new(Config) + c.RawBootWait = "this is not good" + errs = c.Prepare(&interpolate.Context{}) + if len(errs) == 0 { + t.Fatal("should error") + } + + // Test with a good one + c = new(Config) + c.RawBootWait = "5s" + errs = c.Prepare(&interpolate.Context{}) + if len(errs) > 0 { + t.Fatalf("bad: %#v", errs) + } +} + +func TestVNCConfigPrepare(t *testing.T) { + var c *VNCConfig + + // Test with a boot command + c = new(VNCConfig) + c.BootCommand = []string{"a", "b"} + errs := c.Prepare(&interpolate.Context{}) + if len(errs) > 0 { + t.Fatalf("bad: %#v", errs) + } + + // Test with disabled vnc + c.DisableVNC = true + errs = c.Prepare(&interpolate.Context{}) + if len(errs) == 0 { + t.Fatal("should error") + } + + // Test no boot command with no vnc + c = new(VNCConfig) + c.DisableVNC = true + errs = c.Prepare(&interpolate.Context{}) + if len(errs) > 0 { + t.Fatalf("bad: %#v", errs) + } +} From e662927623ec9607690154308a449dba334d396d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sun, 15 Apr 2018 21:54:02 -0700 Subject: [PATCH 0957/1007] Implement boot config struct for parallels --- builder/parallels/common/run_config.go | 30 ------------ builder/parallels/common/run_config_test.go | 37 -------------- .../common/step_type_boot_command.go | 48 +++++++++---------- builder/parallels/iso/builder.go | 8 ++-- builder/parallels/pvm/builder.go | 2 +- builder/parallels/pvm/config.go | 12 ++--- 6 files changed, 34 insertions(+), 103 deletions(-) delete mode 100644 builder/parallels/common/run_config.go delete mode 100644 builder/parallels/common/run_config_test.go diff --git a/builder/parallels/common/run_config.go b/builder/parallels/common/run_config.go deleted file mode 100644 index 53fb8757b..000000000 --- a/builder/parallels/common/run_config.go +++ /dev/null @@ -1,30 +0,0 @@ -package common - -import ( - "fmt" - "time" - - "github.com/hashicorp/packer/template/interpolate" -) - -// RunConfig contains the configuration for VM run. -type RunConfig struct { - RawBootWait string `mapstructure:"boot_wait"` - - BootWait time.Duration `` -} - -// Prepare sets the configuration for VM run. -func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { - if c.RawBootWait == "" { - c.RawBootWait = "10s" - } - - var err error - c.BootWait, err = time.ParseDuration(c.RawBootWait) - if err != nil { - return []error{fmt.Errorf("Failed parsing boot_wait: %s", err)} - } - - return nil -} diff --git a/builder/parallels/common/run_config_test.go b/builder/parallels/common/run_config_test.go deleted file mode 100644 index 8068fe625..000000000 --- a/builder/parallels/common/run_config_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package common - -import ( - "testing" -) - -func TestRunConfigPrepare_BootWait(t *testing.T) { - var c *RunConfig - var errs []error - - // Test a default boot_wait - c = new(RunConfig) - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("should not have error: %s", errs) - } - - if c.RawBootWait != "10s" { - t.Fatalf("bad value: %s", c.RawBootWait) - } - - // Test with a bad boot_wait - c = new(RunConfig) - c.RawBootWait = "this is not good" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) == 0 { - t.Fatalf("bad: %#v", errs) - } - - // Test with a good one - c = new(RunConfig) - c.RawBootWait = "5s" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("should not have error: %s", errs) - } -} diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index 899462f15..cedc10b8a 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -22,7 +22,7 @@ type bootCommandTemplateData struct { // StepTypeBootCommand is a step that "types" the boot command into the VM via // the prltype script, built on the Parallels Virtualization SDK - Python API. type StepTypeBootCommand struct { - BootCommand []string + BootCommand string BootWait time.Duration HostInterfaces []string VMName string @@ -84,33 +84,31 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) d := bootcommand.NewPCXTDriver(sendCodes, -1) ui.Say("Typing the boot command...") - for i, command := range s.BootCommand { - command, err := interpolate.Render(command, &s.Ctx) - if err != nil { - err = fmt.Errorf("Error preparing boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + command, err := interpolate.Render(s.BootCommand, &s.Ctx) + if err != nil { + err = fmt.Errorf("Error preparing boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - seq, err := bootcommand.GenerateExpressionSequence(command) - if err != nil { - err := fmt.Errorf("Error generating boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if err := seq.Do(ctx, d); err != nil { - err := fmt.Errorf("Error running boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if pauseFn != nil { - pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) - } + if pauseFn != nil { + pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command: %s", command), state) } return multistep.ActionContinue diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index e4710b5a6..0bb8b4209 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -7,6 +7,7 @@ import ( parallelscommon "github.com/hashicorp/packer/builder/parallels/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" @@ -26,16 +27,15 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.Config `mapstructure:",squash"` parallelscommon.OutputConfig `mapstructure:",squash"` parallelscommon.PrlctlConfig `mapstructure:",squash"` parallelscommon.PrlctlPostConfig `mapstructure:",squash"` parallelscommon.PrlctlVersionConfig `mapstructure:",squash"` - parallelscommon.RunConfig `mapstructure:",squash"` parallelscommon.ShutdownConfig `mapstructure:",squash"` parallelscommon.SSHConfig `mapstructure:",squash"` parallelscommon.ToolsConfig `mapstructure:",squash"` - BootCommand []string `mapstructure:"boot_command"` DiskSize uint `mapstructure:"disk_size"` DiskType string `mapstructure:"disk_type"` GuestOSType string `mapstructure:"guest_os_type"` @@ -76,13 +76,13 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend( errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) - errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.PrlctlConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.PrlctlPostConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.PrlctlVersionConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ToolsConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.Config.Prepare(&b.config.ctx)...) if b.config.DiskSize == 0 { b.config.DiskSize = 40000 @@ -188,7 +188,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &parallelscommon.StepRun{}, &parallelscommon.StepTypeBootCommand{ BootWait: b.config.BootWait, - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), HostInterfaces: b.config.HostInterfaces, VMName: b.config.VMName, Ctx: b.config.ctx, diff --git a/builder/parallels/pvm/builder.go b/builder/parallels/pvm/builder.go index 4fd5e73d9..d21388eff 100644 --- a/builder/parallels/pvm/builder.go +++ b/builder/parallels/pvm/builder.go @@ -76,7 +76,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &parallelscommon.StepRun{}, &parallelscommon.StepTypeBootCommand{ - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), BootWait: b.config.BootWait, HostInterfaces: []string{}, VMName: b.config.VMName, diff --git a/builder/parallels/pvm/config.go b/builder/parallels/pvm/config.go index 7641e0c9d..0ece6e11e 100644 --- a/builder/parallels/pvm/config.go +++ b/builder/parallels/pvm/config.go @@ -6,6 +6,7 @@ import ( parallelscommon "github.com/hashicorp/packer/builder/parallels/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/boot_command" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -19,15 +20,14 @@ type Config struct { parallelscommon.PrlctlConfig `mapstructure:",squash"` parallelscommon.PrlctlPostConfig `mapstructure:",squash"` parallelscommon.PrlctlVersionConfig `mapstructure:",squash"` - parallelscommon.RunConfig `mapstructure:",squash"` parallelscommon.SSHConfig `mapstructure:",squash"` parallelscommon.ShutdownConfig `mapstructure:",squash"` + bootcommand.Config `mapstructure:",squash"` parallelscommon.ToolsConfig `mapstructure:",squash"` - BootCommand []string `mapstructure:"boot_command"` - SourcePath string `mapstructure:"source_path"` - VMName string `mapstructure:"vm_name"` - ReassignMAC bool `mapstructure:"reassign_mac"` + SourcePath string `mapstructure:"source_path"` + VMName string `mapstructure:"vm_name"` + ReassignMAC bool `mapstructure:"reassign_mac"` ctx interpolate.Context } @@ -61,7 +61,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.PrlctlConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.PrlctlPostConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.PrlctlVersionConfig.Prepare(&c.ctx)...) - errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.Config.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ToolsConfig.Prepare(&c.ctx)...) From 7990966a0921d7610e7b28f988db2eecd58b890f Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 14:20:34 -0700 Subject: [PATCH 0958/1007] fix boot command config struct name --- builder/parallels/iso/builder.go | 4 ++-- builder/parallels/pvm/config.go | 4 ++-- common/boot_command/config.go | 10 +++++----- common/boot_command/config_test.go | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index 0bb8b4209..85d1199e6 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -27,7 +27,7 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` - bootcommand.Config `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` parallelscommon.OutputConfig `mapstructure:",squash"` parallelscommon.PrlctlConfig `mapstructure:",squash"` parallelscommon.PrlctlPostConfig `mapstructure:",squash"` @@ -82,7 +82,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ToolsConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.Config.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.BootConfig.Prepare(&b.config.ctx)...) if b.config.DiskSize == 0 { b.config.DiskSize = 40000 diff --git a/builder/parallels/pvm/config.go b/builder/parallels/pvm/config.go index 0ece6e11e..8d34f24b5 100644 --- a/builder/parallels/pvm/config.go +++ b/builder/parallels/pvm/config.go @@ -22,7 +22,7 @@ type Config struct { parallelscommon.PrlctlVersionConfig `mapstructure:",squash"` parallelscommon.SSHConfig `mapstructure:",squash"` parallelscommon.ShutdownConfig `mapstructure:",squash"` - bootcommand.Config `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` parallelscommon.ToolsConfig `mapstructure:",squash"` SourcePath string `mapstructure:"source_path"` @@ -61,7 +61,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.PrlctlConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.PrlctlPostConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.PrlctlVersionConfig.Prepare(&c.ctx)...) - errs = packer.MultiErrorAppend(errs, c.Config.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ToolsConfig.Prepare(&c.ctx)...) diff --git a/common/boot_command/config.go b/common/boot_command/config.go index 6a5b18cd9..058efc2ed 100644 --- a/common/boot_command/config.go +++ b/common/boot_command/config.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/packer/template/interpolate" ) -type Config struct { +type BootConfig struct { RawBootWait string `mapstructure:"boot_wait"` BootCommand []string `mapstructure:"boot_command"` @@ -16,11 +16,11 @@ type Config struct { } type VNCConfig struct { - Config + BootConfig DisableVNC bool `mapstructure:"disable_vnc"` } -func (c *Config) Prepare(ctx *interpolate.Context) (errs []error) { +func (c *BootConfig) Prepare(ctx *interpolate.Context) (errs []error) { if c.RawBootWait == "" { c.RawBootWait = "10s" } @@ -36,7 +36,7 @@ func (c *Config) Prepare(ctx *interpolate.Context) (errs []error) { return } -func (c *Config) FlatBootCommand() string { +func (c *BootConfig) FlatBootCommand() string { return strings.Join(c.BootCommand, "") } @@ -45,6 +45,6 @@ func (c *VNCConfig) Prepare(ctx *interpolate.Context) (errs []error) { errs = append(errs, fmt.Errorf("A boot command cannot be used when vnc is disabled.")) } - errs = append(errs, c.Config.Prepare(ctx)...) + errs = append(errs, c.BootConfig.Prepare(ctx)...) return } diff --git a/common/boot_command/config_test.go b/common/boot_command/config_test.go index 608e48c0a..551f2c785 100644 --- a/common/boot_command/config_test.go +++ b/common/boot_command/config_test.go @@ -7,10 +7,10 @@ import ( ) func TestConfigPrepare(t *testing.T) { - var c *Config + var c *BootConfig // Test a default boot_wait - c = new(Config) + c = new(BootConfig) c.RawBootWait = "" errs := c.Prepare(&interpolate.Context{}) if len(errs) > 0 { @@ -21,7 +21,7 @@ func TestConfigPrepare(t *testing.T) { } // Test with a bad boot_wait - c = new(Config) + c = new(BootConfig) c.RawBootWait = "this is not good" errs = c.Prepare(&interpolate.Context{}) if len(errs) == 0 { @@ -29,7 +29,7 @@ func TestConfigPrepare(t *testing.T) { } // Test with a good one - c = new(Config) + c = new(BootConfig) c.RawBootWait = "5s" errs = c.Prepare(&interpolate.Context{}) if len(errs) > 0 { From c6299972b9d21af337f615358d5327e5754c14e7 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 14:53:59 -0700 Subject: [PATCH 0959/1007] s/boot_command/bootcommand/ --- Makefile | 4 ++-- builder/hyperv/common/step_type_boot_command.go | 2 +- builder/parallels/common/step_type_boot_command.go | 2 +- builder/parallels/iso/builder.go | 2 +- builder/parallels/pvm/config.go | 2 +- builder/qemu/step_type_boot_command.go | 2 +- builder/virtualbox/common/step_type_boot_command.go | 2 +- builder/vmware/common/step_type_boot_command.go | 2 +- builder/vmware/iso/builder.go | 2 +- builder/vmware/iso/step_create_vmx_test.go | 3 ++- builder/vmware/vmx/config.go | 2 +- common/{boot_command => bootcommand}/boot_command.go | 0 common/{boot_command => bootcommand}/boot_command.pigeon | 0 common/{boot_command => bootcommand}/boot_command_ast.go | 0 common/{boot_command => bootcommand}/boot_command_ast_test.go | 0 common/{boot_command => bootcommand}/config.go | 0 common/{boot_command => bootcommand}/config_test.go | 0 common/{boot_command => bootcommand}/driver.go | 0 common/{boot_command => bootcommand}/gen.go | 0 common/{boot_command => bootcommand}/pc_xt_driver.go | 0 common/{boot_command => bootcommand}/pc_xt_driver_test.go | 0 common/{boot_command => bootcommand}/vnc_driver.go | 0 common/{boot_command => bootcommand}/vnc_driver_test.go | 0 fix/fixer_powershell_escapes.go | 3 ++- main.go | 2 +- post-processor/vagrant/google_test.go | 3 ++- post-processor/vagrant/scaleway.go | 3 ++- post-processor/vsphere/artifact_test.go | 3 ++- 28 files changed, 22 insertions(+), 17 deletions(-) rename common/{boot_command => bootcommand}/boot_command.go (100%) rename common/{boot_command => bootcommand}/boot_command.pigeon (100%) rename common/{boot_command => bootcommand}/boot_command_ast.go (100%) rename common/{boot_command => bootcommand}/boot_command_ast_test.go (100%) rename common/{boot_command => bootcommand}/config.go (100%) rename common/{boot_command => bootcommand}/config_test.go (100%) rename common/{boot_command => bootcommand}/driver.go (100%) rename common/{boot_command => bootcommand}/gen.go (100%) rename common/{boot_command => bootcommand}/pc_xt_driver.go (100%) rename common/{boot_command => bootcommand}/pc_xt_driver_test.go (100%) rename common/{boot_command => bootcommand}/vnc_driver.go (100%) rename common/{boot_command => bootcommand}/vnc_driver_test.go (100%) diff --git a/Makefile b/Makefile index be74e8be1..0ccd547b4 100644 --- a/Makefile +++ b/Makefile @@ -74,8 +74,8 @@ fmt-examples: # source files. generate: deps ## Generate dynamically generated code go generate . - gofmt -w common/boot_command/boot_command.go - goimports -w common/boot_command/boot_command.go + gofmt -w common/bootcommand/boot_command.go + goimports -w common/bootcommand/boot_command.go gofmt -w command/plugin.go test: deps fmt-check ## Run unit tests diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index 9b8b08654..5f449e4e6 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -7,7 +7,7 @@ import ( "time" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index cedc10b8a..794bd6549 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -7,7 +7,7 @@ import ( "time" packer_common "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index 85d1199e6..9ba2002f7 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -7,7 +7,7 @@ import ( parallelscommon "github.com/hashicorp/packer/builder/parallels/common" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/parallels/pvm/config.go b/builder/parallels/pvm/config.go index 8d34f24b5..edccea50e 100644 --- a/builder/parallels/pvm/config.go +++ b/builder/parallels/pvm/config.go @@ -6,7 +6,7 @@ import ( parallelscommon "github.com/hashicorp/packer/builder/parallels/common" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index a0cbb7a90..a552e2805 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index cb0df4e40..2ae5957af 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -6,7 +6,7 @@ import ( "time" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/vmware/common/step_type_boot_command.go b/builder/vmware/common/step_type_boot_command.go index 7544c4c3e..83d55ce11 100644 --- a/builder/vmware/common/step_type_boot_command.go +++ b/builder/vmware/common/step_type_boot_command.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 1edd778ee..60c0fc462 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -11,7 +11,7 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" diff --git a/builder/vmware/iso/step_create_vmx_test.go b/builder/vmware/iso/step_create_vmx_test.go index 7553dff82..26605a1f5 100644 --- a/builder/vmware/iso/step_create_vmx_test.go +++ b/builder/vmware/iso/step_create_vmx_test.go @@ -12,10 +12,11 @@ import ( "strconv" "strings" + "testing" + "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/provisioner/shell" "github.com/hashicorp/packer/template" - "testing" ) var vmxTestBuilderConfig = map[string]string{ diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index e937136a4..0fb9993aa 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -6,7 +6,7 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/common" - "github.com/hashicorp/packer/common/boot_command" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" diff --git a/common/boot_command/boot_command.go b/common/bootcommand/boot_command.go similarity index 100% rename from common/boot_command/boot_command.go rename to common/bootcommand/boot_command.go diff --git a/common/boot_command/boot_command.pigeon b/common/bootcommand/boot_command.pigeon similarity index 100% rename from common/boot_command/boot_command.pigeon rename to common/bootcommand/boot_command.pigeon diff --git a/common/boot_command/boot_command_ast.go b/common/bootcommand/boot_command_ast.go similarity index 100% rename from common/boot_command/boot_command_ast.go rename to common/bootcommand/boot_command_ast.go diff --git a/common/boot_command/boot_command_ast_test.go b/common/bootcommand/boot_command_ast_test.go similarity index 100% rename from common/boot_command/boot_command_ast_test.go rename to common/bootcommand/boot_command_ast_test.go diff --git a/common/boot_command/config.go b/common/bootcommand/config.go similarity index 100% rename from common/boot_command/config.go rename to common/bootcommand/config.go diff --git a/common/boot_command/config_test.go b/common/bootcommand/config_test.go similarity index 100% rename from common/boot_command/config_test.go rename to common/bootcommand/config_test.go diff --git a/common/boot_command/driver.go b/common/bootcommand/driver.go similarity index 100% rename from common/boot_command/driver.go rename to common/bootcommand/driver.go diff --git a/common/boot_command/gen.go b/common/bootcommand/gen.go similarity index 100% rename from common/boot_command/gen.go rename to common/bootcommand/gen.go diff --git a/common/boot_command/pc_xt_driver.go b/common/bootcommand/pc_xt_driver.go similarity index 100% rename from common/boot_command/pc_xt_driver.go rename to common/bootcommand/pc_xt_driver.go diff --git a/common/boot_command/pc_xt_driver_test.go b/common/bootcommand/pc_xt_driver_test.go similarity index 100% rename from common/boot_command/pc_xt_driver_test.go rename to common/bootcommand/pc_xt_driver_test.go diff --git a/common/boot_command/vnc_driver.go b/common/bootcommand/vnc_driver.go similarity index 100% rename from common/boot_command/vnc_driver.go rename to common/bootcommand/vnc_driver.go diff --git a/common/boot_command/vnc_driver_test.go b/common/bootcommand/vnc_driver_test.go similarity index 100% rename from common/boot_command/vnc_driver_test.go rename to common/bootcommand/vnc_driver_test.go diff --git a/fix/fixer_powershell_escapes.go b/fix/fixer_powershell_escapes.go index 9da9ae91f..e9e3b0033 100644 --- a/fix/fixer_powershell_escapes.go +++ b/fix/fixer_powershell_escapes.go @@ -1,8 +1,9 @@ package fix import ( - "github.com/mitchellh/mapstructure" "strings" + + "github.com/mitchellh/mapstructure" ) // FixerPowerShellEscapes removes the PowerShell escape character from user diff --git a/main.go b/main.go index daa8ce590..ff53d1744 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ // This is the main package for the `packer` application. //go:generate go run ./scripts/generate-plugins.go -//go:generate go generate ./common/boot_command/... +//go:generate go generate ./common/bootcommand/... package main import ( diff --git a/post-processor/vagrant/google_test.go b/post-processor/vagrant/google_test.go index a66be8539..22eab0c77 100644 --- a/post-processor/vagrant/google_test.go +++ b/post-processor/vagrant/google_test.go @@ -1,9 +1,10 @@ package vagrant import ( - "github.com/hashicorp/packer/packer" "strings" "testing" + + "github.com/hashicorp/packer/packer" ) func TestGoogleProvider_impl(t *testing.T) { diff --git a/post-processor/vagrant/scaleway.go b/post-processor/vagrant/scaleway.go index 879f2b59e..ee275cffd 100644 --- a/post-processor/vagrant/scaleway.go +++ b/post-processor/vagrant/scaleway.go @@ -3,9 +3,10 @@ package vagrant import ( "bytes" "fmt" - "github.com/hashicorp/packer/packer" "strings" "text/template" + + "github.com/hashicorp/packer/packer" ) type scalewayVagrantfileTemplate struct { diff --git a/post-processor/vsphere/artifact_test.go b/post-processor/vsphere/artifact_test.go index b4f17c759..f6d0d54be 100644 --- a/post-processor/vsphere/artifact_test.go +++ b/post-processor/vsphere/artifact_test.go @@ -1,8 +1,9 @@ package vsphere import ( - "github.com/hashicorp/packer/packer" "testing" + + "github.com/hashicorp/packer/packer" ) func TestArtifact_ImplementsArtifact(t *testing.T) { From c8e76ce298a4a07526a6941357ad0d14716b0abf Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 16:18:12 -0700 Subject: [PATCH 0960/1007] implement config struct for qemu --- builder/qemu/builder.go | 25 ++++------- builder/qemu/builder_test.go | 40 ------------------ builder/qemu/step_type_boot_command.go | 57 ++++++++++++++------------ 3 files changed, 37 insertions(+), 85 deletions(-) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index dfcc9357f..76bfd72d1 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -11,6 +11,7 @@ import ( "time" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" @@ -79,15 +80,15 @@ type Builder struct { } type Config struct { - common.PackerConfig `mapstructure:",squash"` - common.HTTPConfig `mapstructure:",squash"` - common.ISOConfig `mapstructure:",squash"` - Comm communicator.Config `mapstructure:",squash"` - common.FloppyConfig `mapstructure:",squash"` + common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` + common.ISOConfig `mapstructure:",squash"` + bootcommand.VNCConfig `mapstructure:",squash"` + Comm communicator.Config `mapstructure:",squash"` + common.FloppyConfig `mapstructure:",squash"` ISOSkipCache bool `mapstructure:"iso_skip_cache"` Accelerator string `mapstructure:"accelerator"` - BootCommand []string `mapstructure:"boot_command"` DiskInterface string `mapstructure:"disk_interface"` DiskSize uint `mapstructure:"disk_size"` DiskCache string `mapstructure:"disk_cache"` @@ -118,10 +119,8 @@ type Config struct { // TODO(mitchellh): deprecate RunOnce bool `mapstructure:"run_once"` - RawBootWait string `mapstructure:"boot_wait"` RawShutdownTimeout string `mapstructure:"shutdown_timeout"` - bootWait time.Duration `` shutdownTimeout time.Duration `` ctx interpolate.Context } @@ -188,10 +187,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.QemuBinary = "qemu-system-x86_64" } - if b.config.RawBootWait == "" { - b.config.RawBootWait = "10s" - } - if b.config.SSHHostPortMin == 0 { b.config.SSHHostPortMin = 2222 } @@ -291,12 +286,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } - b.config.bootWait, err = time.ParseDuration(b.config.RawBootWait) - if err != nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) - } - if b.config.RawShutdownTimeout == "" { b.config.RawShutdownTimeout = "5m" } diff --git a/builder/qemu/builder_test.go b/builder/qemu/builder_test.go index 7ef29034e..4ddfa1560 100644 --- a/builder/qemu/builder_test.go +++ b/builder/qemu/builder_test.go @@ -94,46 +94,6 @@ func TestBuilderPrepare_Defaults(t *testing.T) { } } -func TestBuilderPrepare_BootWait(t *testing.T) { - var b Builder - config := testConfig() - - // Test a default boot_wait - delete(config, "boot_wait") - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("err: %s", err) - } - - if b.config.RawBootWait != "10s" { - t.Fatalf("bad value: %s", b.config.RawBootWait) - } - - // Test with a bad boot_wait - config["boot_wait"] = "this is not good" - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Test with a good one - config["boot_wait"] = "5s" - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } -} - func TestBuilderPrepare_VNCBindAddress(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/qemu/step_type_boot_command.go b/builder/qemu/step_type_boot_command.go index a552e2805..da3eb48aa 100644 --- a/builder/qemu/step_type_boot_command.go +++ b/builder/qemu/step_type_boot_command.go @@ -42,11 +42,16 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) ui := state.Get("ui").(packer.Ui) vncPort := state.Get("vnc_port").(uint) + if config.VNCConfig.DisableVNC { + log.Println("Skipping boot command step...") + return multistep.ActionContinue + } + // Wait the for the vm to boot. - if int64(config.bootWait) > 0 { - ui.Say(fmt.Sprintf("Waiting %s for boot...", config.bootWait.String())) + if int64(config.BootConfig.BootWait) > 0 { + ui.Say(fmt.Sprintf("Waiting %s for boot...", config.BootWait.String())) select { - case <-time.After(config.bootWait): + case <-time.After(config.BootWait): break case <-ctx.Done(): return multistep.ActionHalt @@ -92,33 +97,31 @@ func (s *stepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) d := bootcommand.NewVNCDriver(c) ui.Say("Typing the boot command over VNC...") - for i, command := range config.BootCommand { - command, err := interpolate.Render(command, &configCtx) - if err != nil { - err := fmt.Errorf("Error preparing boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + command, err := interpolate.Render(config.VNCConfig.FlatBootCommand(), &configCtx) + if err != nil { + err := fmt.Errorf("Error preparing boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - seq, err := bootcommand.GenerateExpressionSequence(command) - if err != nil { - err := fmt.Errorf("Error generating boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if err := seq.Do(ctx, d); err != nil { - err := fmt.Errorf("Error running boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if pauseFn != nil { - pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) - } + if pauseFn != nil { + pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command: %s", command), state) } return multistep.ActionContinue From a0c9ddb9ae90a20b582b4bd8af39e90890601e0d Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 16:19:44 -0700 Subject: [PATCH 0961/1007] implement boot config struct for virtualbox --- builder/virtualbox/common/run_config.go | 21 ++------ builder/virtualbox/common/run_config_test.go | 32 ------------- .../common/step_type_boot_command.go | 48 +++++++++---------- builder/virtualbox/iso/builder.go | 34 ++++++------- builder/virtualbox/ovf/builder.go | 2 +- builder/virtualbox/ovf/config.go | 4 +- 6 files changed, 48 insertions(+), 93 deletions(-) diff --git a/builder/virtualbox/common/run_config.go b/builder/virtualbox/common/run_config.go index 6d3f58686..cf94c306b 100644 --- a/builder/virtualbox/common/run_config.go +++ b/builder/virtualbox/common/run_config.go @@ -2,27 +2,19 @@ package common import ( "fmt" - "time" "github.com/hashicorp/packer/template/interpolate" ) type RunConfig struct { - Headless bool `mapstructure:"headless"` - RawBootWait string `mapstructure:"boot_wait"` + Headless bool `mapstructure:"headless"` VRDPBindAddress string `mapstructure:"vrdp_bind_address"` VRDPPortMin uint `mapstructure:"vrdp_port_min"` VRDPPortMax uint `mapstructure:"vrdp_port_max"` - - BootWait time.Duration `` } -func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { - if c.RawBootWait == "" { - c.RawBootWait = "10s" - } - +func (c *RunConfig) Prepare(ctx *interpolate.Context) (errs []error) { if c.VRDPBindAddress == "" { c.VRDPBindAddress = "127.0.0.1" } @@ -35,17 +27,10 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.VRDPPortMax = 6000 } - var errs []error - var err error - c.BootWait, err = time.ParseDuration(c.RawBootWait) - if err != nil { - errs = append(errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) - } - if c.VRDPPortMin > c.VRDPPortMax { errs = append( errs, fmt.Errorf("vrdp_port_min must be less than vrdp_port_max")) } - return errs + return } diff --git a/builder/virtualbox/common/run_config_test.go b/builder/virtualbox/common/run_config_test.go index 87b9b1b69..1caa7e3c8 100644 --- a/builder/virtualbox/common/run_config_test.go +++ b/builder/virtualbox/common/run_config_test.go @@ -4,38 +4,6 @@ import ( "testing" ) -func TestRunConfigPrepare_BootWait(t *testing.T) { - var c *RunConfig - var errs []error - - // Test a default boot_wait - c = new(RunConfig) - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("should not have error: %s", errs) - } - - if c.RawBootWait != "10s" { - t.Fatalf("bad value: %s", c.RawBootWait) - } - - // Test with a bad boot_wait - c = new(RunConfig) - c.RawBootWait = "this is not good" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) == 0 { - t.Fatalf("bad: %#v", errs) - } - - // Test with a good one - c = new(RunConfig) - c.RawBootWait = "5s" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("should not have error: %s", errs) - } -} - func TestRunConfigPrepare_VRDPBindAddress(t *testing.T) { var c *RunConfig var errs []error diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 2ae5957af..0effc3628 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -21,7 +21,7 @@ type bootCommandTemplateData struct { } type StepTypeBootCommand struct { - BootCommand []string + BootCommand string BootWait time.Duration VMName string Ctx interpolate.Context @@ -67,33 +67,31 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) d := bootcommand.NewPCXTDriver(sendCodes, 25) ui.Say("Typing the boot command...") - for i, command := range s.BootCommand { - command, err := interpolate.Render(command, &s.Ctx) - if err != nil { - err := fmt.Errorf("Error preparing boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + command, err := interpolate.Render(s.BootCommand, &s.Ctx) + if err != nil { + err := fmt.Errorf("Error preparing boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - seq, err := bootcommand.GenerateExpressionSequence(command) - if err != nil { - err := fmt.Errorf("Error generating boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + seq, err := bootcommand.GenerateExpressionSequence(command) + if err != nil { + err := fmt.Errorf("Error generating boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if err := seq.Do(ctx, d); err != nil { - err := fmt.Errorf("Error running boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + if err := seq.Do(ctx, d); err != nil { + err := fmt.Errorf("Error running boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - if pauseFn != nil { - pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) - } + if pauseFn != nil { + pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command: %s", command), state) } return multistep.ActionContinue diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 5a53854ae..2ea19e70f 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -8,6 +8,7 @@ import ( vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/multistep" @@ -27,6 +28,7 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.ExportOpts `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"` @@ -37,21 +39,20 @@ type Config struct { vboxcommon.VBoxManagePostConfig `mapstructure:",squash"` vboxcommon.VBoxVersionConfig `mapstructure:",squash"` - BootCommand []string `mapstructure:"boot_command"` - DiskSize uint `mapstructure:"disk_size"` - GuestAdditionsMode string `mapstructure:"guest_additions_mode"` - GuestAdditionsPath string `mapstructure:"guest_additions_path"` - GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` - GuestAdditionsURL string `mapstructure:"guest_additions_url"` - GuestOSType string `mapstructure:"guest_os_type"` - HardDriveDiscard bool `mapstructure:"hard_drive_discard"` - HardDriveInterface string `mapstructure:"hard_drive_interface"` - SATAPortCount int `mapstructure:"sata_port_count"` - HardDriveNonrotational bool `mapstructure:"hard_drive_nonrotational"` - ISOInterface string `mapstructure:"iso_interface"` - KeepRegistered bool `mapstructure:"keep_registered"` - SkipExport bool `mapstructure:"skip_export"` - VMName string `mapstructure:"vm_name"` + DiskSize uint `mapstructure:"disk_size"` + GuestAdditionsMode string `mapstructure:"guest_additions_mode"` + GuestAdditionsPath string `mapstructure:"guest_additions_path"` + GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` + GuestAdditionsURL string `mapstructure:"guest_additions_url"` + GuestOSType string `mapstructure:"guest_os_type"` + HardDriveDiscard bool `mapstructure:"hard_drive_discard"` + HardDriveInterface string `mapstructure:"hard_drive_interface"` + SATAPortCount int `mapstructure:"sata_port_count"` + HardDriveNonrotational bool `mapstructure:"hard_drive_nonrotational"` + ISOInterface string `mapstructure:"iso_interface"` + KeepRegistered bool `mapstructure:"keep_registered"` + SkipExport bool `mapstructure:"skip_export"` + VMName string `mapstructure:"vm_name"` ctx interpolate.Context } @@ -94,6 +95,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.VBoxManageConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.VBoxManagePostConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.VBoxVersionConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.BootConfig.Prepare(&b.config.ctx)...) if b.config.DiskSize == 0 { b.config.DiskSize = 40000 @@ -244,7 +246,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &vboxcommon.StepTypeBootCommand{ BootWait: b.config.BootWait, - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), VMName: b.config.VMName, Ctx: b.config.ctx, }, diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index 71921106e..09fd416a3 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -107,7 +107,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, &vboxcommon.StepTypeBootCommand{ BootWait: b.config.BootWait, - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), VMName: b.config.VMName, Ctx: b.config.ctx, }, diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index 9a90b1a5b..bd60a4c4c 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -6,6 +6,7 @@ import ( vboxcommon "github.com/hashicorp/packer/builder/virtualbox/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/bootcommand" "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" @@ -16,6 +17,7 @@ type Config struct { common.PackerConfig `mapstructure:",squash"` common.HTTPConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.ExportOpts `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"` @@ -26,7 +28,6 @@ type Config struct { vboxcommon.VBoxManagePostConfig `mapstructure:",squash"` vboxcommon.VBoxVersionConfig `mapstructure:",squash"` - BootCommand []string `mapstructure:"boot_command"` Checksum string `mapstructure:"checksum"` ChecksumType string `mapstructure:"checksum_type"` GuestAdditionsMode string `mapstructure:"guest_additions_mode"` @@ -90,6 +91,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.VBoxManagePostConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.BootConfig.Prepare(&c.ctx)...) c.ChecksumType = strings.ToLower(c.ChecksumType) c.Checksum = strings.ToLower(c.Checksum) From 1d36ef038cef0e4f4204ed63f1092dc7e64b4c01 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 16:26:48 -0700 Subject: [PATCH 0962/1007] implement boot config struct for hyperv --- builder/hyperv/common/run_config.go | 33 ----------------- builder/hyperv/common/run_config_test.go | 37 ------------------- .../hyperv/common/step_type_boot_command.go | 33 ++++++----------- builder/hyperv/iso/builder.go | 30 +++++++-------- builder/hyperv/iso/builder_test.go | 2 +- builder/hyperv/vmcx/builder.go | 18 ++++----- builder/hyperv/vmcx/builder_test.go | 2 +- 7 files changed, 38 insertions(+), 117 deletions(-) delete mode 100644 builder/hyperv/common/run_config.go delete mode 100644 builder/hyperv/common/run_config_test.go diff --git a/builder/hyperv/common/run_config.go b/builder/hyperv/common/run_config.go deleted file mode 100644 index 8e29511b7..000000000 --- a/builder/hyperv/common/run_config.go +++ /dev/null @@ -1,33 +0,0 @@ -package common - -import ( - "fmt" - "time" - - "github.com/hashicorp/packer/template/interpolate" -) - -type RunConfig struct { - RawBootWait string `mapstructure:"boot_wait"` - - BootWait time.Duration `` -} - -func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { - if c.RawBootWait == "" { - c.RawBootWait = "10s" - } - - var errs []error - var err error - - if c.RawBootWait != "" { - c.BootWait, err = time.ParseDuration(c.RawBootWait) - if err != nil { - errs = append( - errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) - } - } - - return errs -} diff --git a/builder/hyperv/common/run_config_test.go b/builder/hyperv/common/run_config_test.go deleted file mode 100644 index 8068fe625..000000000 --- a/builder/hyperv/common/run_config_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package common - -import ( - "testing" -) - -func TestRunConfigPrepare_BootWait(t *testing.T) { - var c *RunConfig - var errs []error - - // Test a default boot_wait - c = new(RunConfig) - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("should not have error: %s", errs) - } - - if c.RawBootWait != "10s" { - t.Fatalf("bad value: %s", c.RawBootWait) - } - - // Test with a bad boot_wait - c = new(RunConfig) - c.RawBootWait = "this is not good" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) == 0 { - t.Fatalf("bad: %#v", errs) - } - - // Test with a good one - c = new(RunConfig) - c.RawBootWait = "5s" - errs = c.Prepare(testConfigTemplate(t)) - if len(errs) > 0 { - t.Fatalf("should not have error: %s", errs) - } -} diff --git a/builder/hyperv/common/step_type_boot_command.go b/builder/hyperv/common/step_type_boot_command.go index 5f449e4e6..de96d4293 100644 --- a/builder/hyperv/common/step_type_boot_command.go +++ b/builder/hyperv/common/step_type_boot_command.go @@ -21,7 +21,7 @@ type bootCommandTemplateData struct { // This step "types" the boot command into the VM via the Hyper-V virtual keyboard type StepTypeBootCommand struct { - BootCommand []string + BootCommand string BootWait time.Duration SwitchName string Ctx interpolate.Context @@ -62,32 +62,23 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) vmName, } - ui.Say("Typing the boot command...") - - // Flatten command so we send it all at once - commands := []string{} - - for _, command := range s.BootCommand { - command, err := interpolate.Render(command, &s.Ctx) - - if err != nil { - err := fmt.Errorf("Error preparing boot command: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } - - commands = append(commands, command) - } - sendCodes := func(codes []string) error { scanCodesToSendString := strings.Join(codes, " ") return driver.TypeScanCodes(vmName, scanCodesToSendString) } d := bootcommand.NewPCXTDriver(sendCodes, -1) - flatCommands := strings.Join(commands, "") - seq, err := bootcommand.GenerateExpressionSequence(flatCommands) + ui.Say("Typing the boot command...") + command, err := interpolate.Render(s.BootCommand, &s.Ctx) + + if err != nil { + err := fmt.Errorf("Error preparing boot command: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + + seq, err := bootcommand.GenerateExpressionSequence(command) if err != nil { err := fmt.Errorf("Error generating boot command: %s", err) state.Put("error", err) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 2ad3c324a..9d32eef43 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -10,6 +10,7 @@ import ( hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/bootcommand" powershell "github.com/hashicorp/packer/common/powershell" "github.com/hashicorp/packer/common/powershell/hyperv" "github.com/hashicorp/packer/helper/communicator" @@ -51,9 +52,9 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` hypervcommon.OutputConfig `mapstructure:",squash"` hypervcommon.SSHConfig `mapstructure:",squash"` - hypervcommon.RunConfig `mapstructure:",squash"` hypervcommon.ShutdownConfig `mapstructure:",squash"` // The size, in megabytes, of the hard disk to create for the VM. @@ -81,18 +82,17 @@ type Config struct { // By default this is "packer-BUILDNAME", where "BUILDNAME" is the name of the build. VMName string `mapstructure:"vm_name"` - BootCommand []string `mapstructure:"boot_command"` - SwitchName string `mapstructure:"switch_name"` - SwitchVlanId string `mapstructure:"switch_vlan_id"` - MacAddress string `mapstructure:"mac_address"` - VlanId string `mapstructure:"vlan_id"` - Cpu uint `mapstructure:"cpu"` - Generation uint `mapstructure:"generation"` - EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` - EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` - EnableSecureBoot bool `mapstructure:"enable_secure_boot"` - EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` - TempPath string `mapstructure:"temp_path"` + SwitchName string `mapstructure:"switch_name"` + SwitchVlanId string `mapstructure:"switch_vlan_id"` + MacAddress string `mapstructure:"mac_address"` + VlanId string `mapstructure:"vlan_id"` + Cpu uint `mapstructure:"cpu"` + Generation uint `mapstructure:"generation"` + EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` + EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` + EnableSecureBoot bool `mapstructure:"enable_secure_boot"` + EnableVirtualizationExtensions bool `mapstructure:"enable_virtualization_extensions"` + TempPath string `mapstructure:"temp_path"` // A separate path can be used for storing the VM's disk image. The purpose is to enable // reading and writing to take place on different physical disks (read from VHD temp path @@ -136,9 +136,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) + errs = packer.MultiErrorAppend(errs, b.config.BootConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) @@ -407,7 +407,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &hypervcommon.StepRun{}, &hypervcommon.StepTypeBootCommand{ - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), BootWait: b.config.BootWait, SwitchName: b.config.SwitchName, Ctx: b.config.ctx, diff --git a/builder/hyperv/iso/builder_test.go b/builder/hyperv/iso/builder_test.go index 8523876ef..1663b4727 100644 --- a/builder/hyperv/iso/builder_test.go +++ b/builder/hyperv/iso/builder_test.go @@ -562,7 +562,7 @@ func TestUserVariablesInBootCommand(t *testing.T) { state.Put("vmName", "packer-foo") step := &hypervcommon.StepTypeBootCommand{ - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), SwitchName: b.config.SwitchName, Ctx: b.config.ctx, } diff --git a/builder/hyperv/vmcx/builder.go b/builder/hyperv/vmcx/builder.go index 2d7d17771..31212e1f5 100644 --- a/builder/hyperv/vmcx/builder.go +++ b/builder/hyperv/vmcx/builder.go @@ -9,6 +9,7 @@ import ( hypervcommon "github.com/hashicorp/packer/builder/hyperv/common" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/common/bootcommand" powershell "github.com/hashicorp/packer/common/powershell" "github.com/hashicorp/packer/common/powershell/hyperv" "github.com/hashicorp/packer/helper/communicator" @@ -42,9 +43,9 @@ type Config struct { common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` common.FloppyConfig `mapstructure:",squash"` + bootcommand.BootConfig `mapstructure:",squash"` hypervcommon.OutputConfig `mapstructure:",squash"` hypervcommon.SSHConfig `mapstructure:",squash"` - hypervcommon.RunConfig `mapstructure:",squash"` hypervcommon.ShutdownConfig `mapstructure:",squash"` // The size, in megabytes, of the computer memory in the VM. @@ -79,12 +80,11 @@ type Config struct { // Use differencing disk DifferencingDisk bool `mapstructure:"differencing_disk"` - BootCommand []string `mapstructure:"boot_command"` - SwitchName string `mapstructure:"switch_name"` - SwitchVlanId string `mapstructure:"switch_vlan_id"` - MacAddress string `mapstructure:"mac_address"` - VlanId string `mapstructure:"vlan_id"` - Cpu uint `mapstructure:"cpu"` + SwitchName string `mapstructure:"switch_name"` + SwitchVlanId string `mapstructure:"switch_vlan_id"` + MacAddress string `mapstructure:"mac_address"` + VlanId string `mapstructure:"vlan_id"` + Cpu uint `mapstructure:"cpu"` Generation uint EnableMacSpoofing bool `mapstructure:"enable_mac_spoofing"` EnableDynamicMemory bool `mapstructure:"enable_dynamic_memory"` @@ -125,9 +125,9 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, isoErrs...) } + errs = packer.MultiErrorAppend(errs, b.config.BootConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) @@ -437,7 +437,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &hypervcommon.StepRun{}, &hypervcommon.StepTypeBootCommand{ - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), BootWait: b.config.BootWait, SwitchName: b.config.SwitchName, Ctx: b.config.ctx, diff --git a/builder/hyperv/vmcx/builder_test.go b/builder/hyperv/vmcx/builder_test.go index 08444c26d..9a4a54c33 100644 --- a/builder/hyperv/vmcx/builder_test.go +++ b/builder/hyperv/vmcx/builder_test.go @@ -530,7 +530,7 @@ func TestUserVariablesInBootCommand(t *testing.T) { state.Put("vmName", "packer-foo") step := &hypervcommon.StepTypeBootCommand{ - BootCommand: b.config.BootCommand, + BootCommand: b.config.FlatBootCommand(), SwitchName: b.config.SwitchName, Ctx: b.config.ctx, } From e9e27941cc000653c9c3c5486ecdcda40ce9972c Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 16:54:48 -0700 Subject: [PATCH 0963/1007] sort keycode lists --- common/bootcommand/pc_xt_driver.go | 24 ++++++++++++------------ common/bootcommand/vnc_driver.go | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/common/bootcommand/pc_xt_driver.go b/common/bootcommand/pc_xt_driver.go index 9107f5b85..6a47755d0 100644 --- a/common/bootcommand/pc_xt_driver.go +++ b/common/bootcommand/pc_xt_driver.go @@ -44,6 +44,8 @@ func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver { sMap := make(map[string][]string) sMap["bs"] = []string{"0e", "8e"} sMap["del"] = []string{"e053", "e0d3"} + sMap["down"] = []string{"e050", "e0d0"} + sMap["end"] = []string{"e04f", "e0cf"} sMap["enter"] = []string{"1c", "9c"} sMap["esc"] = []string{"01", "81"} sMap["f1"] = []string{"3b", "bb"} @@ -58,26 +60,24 @@ func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver { sMap["f10"] = []string{"44", "c4"} sMap["f11"] = []string{"57", "d7"} sMap["f12"] = []string{"58", "d8"} - sMap["return"] = []string{"1c", "9c"} - sMap["tab"] = []string{"0f", "8f"} - sMap["up"] = []string{"e048", "e0c8"} - sMap["down"] = []string{"e050", "e0d0"} - sMap["left"] = []string{"e04b", "e0cb"} - sMap["right"] = []string{"e04d", "e0cd"} - sMap["spacebar"] = []string{"39", "b9"} - sMap["insert"] = []string{"e052", "e0d2"} sMap["home"] = []string{"e047", "e0c7"} - sMap["end"] = []string{"e04f", "e0cf"} - sMap["pageup"] = []string{"e049", "e0c9"} - sMap["pagedown"] = []string{"e051", "e0d1"} + sMap["insert"] = []string{"e052", "e0d2"} + sMap["left"] = []string{"e04b", "e0cb"} sMap["leftalt"] = []string{"38", "b8"} sMap["leftctrl"] = []string{"1d", "9d"} sMap["leftshift"] = []string{"2a", "aa"} + sMap["leftsuper"] = []string{"e05b", "e0db"} + sMap["pagedown"] = []string{"e051", "e0d1"} + sMap["pageup"] = []string{"e049", "e0c9"} + sMap["return"] = []string{"1c", "9c"} + sMap["right"] = []string{"e04d", "e0cd"} sMap["rightalt"] = []string{"e038", "e0b8"} sMap["rightctrl"] = []string{"e01d", "e09d"} sMap["rightshift"] = []string{"36", "b6"} - sMap["leftsuper"] = []string{"e05b", "e0db"} sMap["rightsuper"] = []string{"e05c", "e0dc"} + sMap["spacebar"] = []string{"39", "b9"} + sMap["tab"] = []string{"0f", "8f"} + sMap["up"] = []string{"e048", "e0c8"} scancodeIndex := make(map[string]byte) scancodeIndex["1234567890-="] = 0x02 diff --git a/common/bootcommand/vnc_driver.go b/common/bootcommand/vnc_driver.go index 41fa5bb2a..00e6dc955 100644 --- a/common/bootcommand/vnc_driver.go +++ b/common/bootcommand/vnc_driver.go @@ -37,6 +37,8 @@ func NewVNCDriver(c VNCKeyEvent) *vncDriver { sMap := make(map[string]uint32) sMap["bs"] = 0xFF08 sMap["del"] = 0xFFFF + sMap["down"] = 0xFF54 + sMap["end"] = 0xFF57 sMap["enter"] = 0xFF0D sMap["esc"] = 0xFF1B sMap["f1"] = 0xFFBE @@ -51,26 +53,24 @@ func NewVNCDriver(c VNCKeyEvent) *vncDriver { sMap["f10"] = 0xFFC7 sMap["f11"] = 0xFFC8 sMap["f12"] = 0xFFC9 - sMap["return"] = 0xFF0D - sMap["tab"] = 0xFF09 - sMap["up"] = 0xFF52 - sMap["down"] = 0xFF54 - sMap["left"] = 0xFF51 - sMap["right"] = 0xFF53 - sMap["spacebar"] = 0x020 - sMap["insert"] = 0xFF63 sMap["home"] = 0xFF50 - sMap["end"] = 0xFF57 - sMap["pageup"] = 0xFF55 - sMap["pagedown"] = 0xFF56 + sMap["insert"] = 0xFF63 + sMap["left"] = 0xFF51 sMap["leftalt"] = 0xFFE9 sMap["leftctrl"] = 0xFFE3 sMap["leftshift"] = 0xFFE1 sMap["leftsuper"] = 0xFFEB + sMap["pagedown"] = 0xFF56 + sMap["pageup"] = 0xFF55 + sMap["return"] = 0xFF0D + sMap["right"] = 0xFF53 sMap["rightalt"] = 0xFFEA sMap["rightctrl"] = 0xFFE4 sMap["rightshift"] = 0xFFE2 sMap["rightsuper"] = 0xFFEC + sMap["spacebar"] = 0x020 + sMap["tab"] = 0xFF09 + sMap["up"] = 0xFF52 return &vncDriver{ c: c, From 7d43324359490b28f4dfc06d20cea19f681201c0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 16:55:32 -0700 Subject: [PATCH 0964/1007] add menu key. Replaces #5989 --- common/bootcommand/pc_xt_driver.go | 1 + common/bootcommand/vnc_driver.go | 1 + website/source/partials/builders/_boot-command.html.md | 2 ++ 3 files changed, 4 insertions(+) diff --git a/common/bootcommand/pc_xt_driver.go b/common/bootcommand/pc_xt_driver.go index 6a47755d0..f23b7ffc3 100644 --- a/common/bootcommand/pc_xt_driver.go +++ b/common/bootcommand/pc_xt_driver.go @@ -67,6 +67,7 @@ func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver { sMap["leftctrl"] = []string{"1d", "9d"} sMap["leftshift"] = []string{"2a", "aa"} sMap["leftsuper"] = []string{"e05b", "e0db"} + sMap["menu"] = []string{"e05d", "e0dd"} sMap["pagedown"] = []string{"e051", "e0d1"} sMap["pageup"] = []string{"e049", "e0c9"} sMap["return"] = []string{"1c", "9c"} diff --git a/common/bootcommand/vnc_driver.go b/common/bootcommand/vnc_driver.go index 00e6dc955..86d6497c1 100644 --- a/common/bootcommand/vnc_driver.go +++ b/common/bootcommand/vnc_driver.go @@ -60,6 +60,7 @@ func NewVNCDriver(c VNCKeyEvent) *vncDriver { sMap["leftctrl"] = 0xFFE3 sMap["leftshift"] = 0xFFE1 sMap["leftsuper"] = 0xFFEB + sMap["menu"] = 0xFF67 sMap["pagedown"] = 0xFF56 sMap["pageup"] = 0xFF55 sMap["return"] = 0xFF0D diff --git a/website/source/partials/builders/_boot-command.html.md b/website/source/partials/builders/_boot-command.html.md index 4230426cb..225cec9b8 100644 --- a/website/source/partials/builders/_boot-command.html.md +++ b/website/source/partials/builders/_boot-command.html.md @@ -23,6 +23,8 @@ command, they will be replaced by the proper key: - `<pageUp> <pageDown>` - Simulates pressing the page up and page down keys. +- `<menu>` - Simulates pressing the Menu key. + - `<leftAlt> <rightAlt>` - Simulates pressing the alt key. - `<leftCtrl> <rightCtrl>` - Simulates pressing the ctrl key. From aa69bdf74e0922f3f5fa67c98cde50c602c42c94 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 17:48:35 -0700 Subject: [PATCH 0965/1007] Perform validation of boot command. --- common/bootcommand/boot_command_ast.go | 40 +++++++++++++++++-- common/bootcommand/boot_command_ast_test.go | 44 ++++++++++++++++----- common/bootcommand/config.go | 10 +++++ 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/common/bootcommand/boot_command_ast.go b/common/bootcommand/boot_command_ast.go index 16b562e95..02ec5fbff 100644 --- a/common/bootcommand/boot_command_ast.go +++ b/common/bootcommand/boot_command_ast.go @@ -42,13 +42,22 @@ func (k KeyAction) String() string { } type expression interface { + // Do executes the expression Do(context.Context, BCDriver) error + // Validate validates the expression without executing it + Validate() error } type expressionSequence []expression // Do executes every expression in the sequence and then finalizes the driver. func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { + // validate should never fail here, since it should be called before + // expressionSequence.Do. Only reason we don't panic is so we can clean up. + if errs := s.Validate(); errs != nil { + return fmt.Errorf("Found an invalid boot command. This is likely an error in Packer, so please open a ticket.") + } + for _, exp := range s { if err := ctx.Err(); err != nil { return err @@ -60,6 +69,16 @@ func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { return b.Finalize() } +// Do executes every expression in the sequence and then finalizes the driver. +func (s expressionSequence) Validate() (errs []error) { + for _, exp := range s { + if err := exp.Validate(); err != nil { + errs = append(errs, err) + } + } + return +} + // GenerateExpressionSequence generates a sequence of expressions from the // given command. This is the primary entry point to the boot command parser. func GenerateExpressionSequence(command string) (expressionSequence, error) { @@ -67,9 +86,6 @@ func GenerateExpressionSequence(command string) (expressionSequence, error) { if err != nil { return nil, err } - if got == nil { - return nil, fmt.Errorf("No expressions found.") - } seq := expressionSequence{} for _, exp := range got.([]interface{}) { seq = append(seq, exp.(expression)) @@ -93,6 +109,14 @@ func (w *waitExpression) Do(ctx context.Context, _ BCDriver) error { } } +// Validate returns an error if the time is <= 0 +func (w *waitExpression) Validate() error { + if w.d <= 0 { + return fmt.Errorf("Expecting a positive wait value. Got %s", w.d) + } + return nil +} + func (w *waitExpression) String() string { return fmt.Sprintf("Wait<%s>", w.d) } @@ -107,6 +131,11 @@ func (s *specialExpression) Do(ctx context.Context, driver BCDriver) error { return driver.SendSpecial(s.s, s.action) } +// Validate always passes +func (s *specialExpression) Validate() error { + return nil +} + func (s *specialExpression) String() string { return fmt.Sprintf("Spec-%s(%s)", s.action, s.s) } @@ -121,6 +150,11 @@ func (l *literal) Do(ctx context.Context, driver BCDriver) error { return driver.SendKey(l.s, l.action) } +// Validate always passes +func (l *literal) Validate() error { + return nil +} + func (l *literal) String() string { return fmt.Sprintf("LIT-%s(%s)", l.action, string(l.s)) } diff --git a/common/bootcommand/boot_command_ast_test.go b/common/bootcommand/boot_command_ast_test.go index 8536f58c0..9638da42f 100644 --- a/common/bootcommand/boot_command_ast_test.go +++ b/common/bootcommand/boot_command_ast_test.go @@ -100,17 +100,41 @@ func Test_special(t *testing.T) { } } -func Test_negativeWait(t *testing.T) { - in := "<wait-1m>" - _, err := ParseReader("", strings.NewReader(in)) - if err != nil { - log.Fatal(err) +func Test_validation(t *testing.T) { + var expressions = []struct { + in string + valid bool + }{ + { + "<wait1m>", + true, + }, + { + "<wait-1m>", + false, + }, + { + "<f1>", + true, + }, + { + "<", + true, + }, } + for _, tt := range expressions { + got, err := ParseReader("", strings.NewReader(tt.in)) + if err != nil { + log.Fatal(err) + } - /* gL := toIfaceSlice(got) - for _, g := range gL { - assert.Equal(t, tt.out, g.(*specialExpression).String()) - } - */ + assert.Len(t, gL, 1) + err = gL[0].(expression).Validate() + if tt.valid { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } + } } diff --git a/common/bootcommand/config.go b/common/bootcommand/config.go index 058efc2ed..ac5834701 100644 --- a/common/bootcommand/config.go +++ b/common/bootcommand/config.go @@ -33,6 +33,16 @@ func (c *BootConfig) Prepare(ctx *interpolate.Context) (errs []error) { c.BootWait = bw } } + + if c.BootCommand != nil { + expSeq, err := GenerateExpressionSequence(c.FlatBootCommand()) + if err != nil { + errs = append(errs, err) + } else if vErrs := expSeq.Validate(); vErrs != nil { + errs = append(errs, vErrs...) + } + } + return } From df6224d04ed2a1026c9da65f8bc19208baaecac3 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Wed, 18 Apr 2018 17:57:49 -0700 Subject: [PATCH 0966/1007] fix vnc config --- common/bootcommand/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/bootcommand/config.go b/common/bootcommand/config.go index ac5834701..532c7c82c 100644 --- a/common/bootcommand/config.go +++ b/common/bootcommand/config.go @@ -16,7 +16,7 @@ type BootConfig struct { } type VNCConfig struct { - BootConfig + BootConfig `mapstructure:",squash"` DisableVNC bool `mapstructure:"disable_vnc"` } From 31d04f1945ea6ee58e23039aac920ec176ec8bdb Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 12:06:29 -0700 Subject: [PATCH 0967/1007] remove outdated comment --- common/bootcommand/boot_command_ast.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/common/bootcommand/boot_command_ast.go b/common/bootcommand/boot_command_ast.go index 02ec5fbff..669f7f50d 100644 --- a/common/bootcommand/boot_command_ast.go +++ b/common/bootcommand/boot_command_ast.go @@ -8,14 +8,6 @@ import ( "time" ) -/* -TODO: - * pc-at abstraction - * check that `<del>` works. It's different now. - * parallels - * hyperv- -*/ - // KeysAction represents what we want to do with a key press. // It can take 3 states. We either want to: // * press the key once From 374d8f089f12c56ac19a8392527d740a64510e36 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 16:09:38 -0700 Subject: [PATCH 0968/1007] better log message --- common/bootcommand/pc_xt_driver.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/common/bootcommand/pc_xt_driver.go b/common/bootcommand/pc_xt_driver.go index f23b7ffc3..de148e42e 100644 --- a/common/bootcommand/pc_xt_driver.go +++ b/common/bootcommand/pc_xt_driver.go @@ -130,7 +130,6 @@ func (d *pcXTDriver) Finalize() error { } func (d *pcXTDriver) SendKey(key rune, action KeyAction) error { - keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) var scancode []string @@ -151,9 +150,8 @@ func (d *pcXTDriver) SendKey(key rune, action KeyAction) error { scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) } - for _, sc := range scancode { - log.Printf("Sending char '%c', code '%s', shift %v", key, sc, keyShift) - } + log.Printf("Sending char '%c', code '%s', shift %v", + key, strings.Join(scancode, ""), keyShift) d.send(scancode) return nil From c920e0a20ba3a284c8d8088277252903469eaf2a Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 16:11:29 -0700 Subject: [PATCH 0969/1007] forcefully stop parallels vm. also only output parallels version once. --- builder/parallels/common/driver.go | 1 + builder/parallels/common/driver_9.go | 3 +-- builder/parallels/common/step_run.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder/parallels/common/driver.go b/builder/parallels/common/driver.go index ac23a7880..4fde15a6c 100644 --- a/builder/parallels/common/driver.go +++ b/builder/parallels/common/driver.go @@ -131,6 +131,7 @@ func NewDriver() (Driver, error) { latestDriver := 11 version, _ := drivers[strconv.Itoa(latestDriver)].Version() majVer, _ := strconv.Atoi(strings.SplitN(version, ".", 2)[0]) + log.Printf("Parallels version: %s", version) if majVer > latestDriver { log.Printf("Your version of Parallels Desktop for Mac is %s, Packer will use driver for version %d.", version, latestDriver) return drivers[strconv.Itoa(latestDriver)], nil diff --git a/builder/parallels/common/driver_9.go b/builder/parallels/common/driver_9.go index b8b697ba1..5634fb123 100644 --- a/builder/parallels/common/driver_9.go +++ b/builder/parallels/common/driver_9.go @@ -222,7 +222,7 @@ func (d *Parallels9Driver) IsRunning(name string) (bool, error) { // Stop forcibly stops the VM. func (d *Parallels9Driver) Stop(name string) error { - if err := d.Prlctl("stop", name); err != nil { + if err := d.Prlctl("stop", name, "--kill"); err != nil { return err } @@ -275,7 +275,6 @@ func (d *Parallels9Driver) Version() (string, error) { } version := matches[1] - log.Printf("Parallels Desktop version: %s", version) return version, nil } diff --git a/builder/parallels/common/step_run.go b/builder/parallels/common/step_run.go index 073ad0550..4d5652483 100644 --- a/builder/parallels/common/step_run.go +++ b/builder/parallels/common/step_run.go @@ -69,7 +69,7 @@ func (s *StepRun) Cleanup(state multistep.StateBag) { ui := state.Get("ui").(packer.Ui) if running, _ := driver.IsRunning(s.vmName); running { - if err := driver.Prlctl("stop", s.vmName); err != nil { + if err := driver.Stop(s.vmName); err != nil { ui.Error(fmt.Sprintf("Error stopping VM: %s", err)) } } From 11de2b97598c16c6621fe59d83fcc80a466b9031 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 16:13:24 -0700 Subject: [PATCH 0970/1007] remove unnecessary log line. --- builder/parallels/common/step_type_boot_command.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/builder/parallels/common/step_type_boot_command.go b/builder/parallels/common/step_type_boot_command.go index 794bd6549..ed21c049d 100644 --- a/builder/parallels/common/step_type_boot_command.go +++ b/builder/parallels/common/step_type_boot_command.go @@ -3,7 +3,6 @@ package common import ( "context" "fmt" - "log" "time" packer_common "github.com/hashicorp/packer/common" @@ -78,7 +77,6 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) } sendCodes := func(codes []string) error { - log.Printf("Sending scancodes: %#v", codes) return driver.SendKeyScanCodes(s.VMName, codes...) } d := bootcommand.NewPCXTDriver(sendCodes, -1) From 675eae1e9253025aedc3a09bbbbd7b997b084f8e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 16:44:50 -0700 Subject: [PATCH 0971/1007] flush scancodes when we wait --- common/bootcommand/boot_command_ast.go | 10 ++++++---- common/bootcommand/driver.go | 4 ++-- common/bootcommand/pc_xt_driver.go | 7 ++++--- common/bootcommand/pc_xt_driver_test.go | 19 +++++++++++++++++++ common/bootcommand/vnc_driver.go | 4 ++-- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/common/bootcommand/boot_command_ast.go b/common/bootcommand/boot_command_ast.go index 669f7f50d..98a4afc81 100644 --- a/common/bootcommand/boot_command_ast.go +++ b/common/bootcommand/boot_command_ast.go @@ -42,7 +42,8 @@ type expression interface { type expressionSequence []expression -// Do executes every expression in the sequence and then finalizes the driver. +// Do executes every expression in the sequence and then flushes remaining +// scancodes. func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { // validate should never fail here, since it should be called before // expressionSequence.Do. Only reason we don't panic is so we can clean up. @@ -58,10 +59,10 @@ func (s expressionSequence) Do(ctx context.Context, b BCDriver) error { return err } } - return b.Finalize() + return b.Flush() } -// Do executes every expression in the sequence and then finalizes the driver. +// Validate tells us if every expression in the sequence is valid. func (s expressionSequence) Validate() (errs []error) { for _, exp := range s { if err := exp.Validate(); err != nil { @@ -91,7 +92,8 @@ type waitExpression struct { // Do waits the amount of time described by the expression. It is cancellable // through the context. -func (w *waitExpression) Do(ctx context.Context, _ BCDriver) error { +func (w *waitExpression) Do(ctx context.Context, driver BCDriver) error { + driver.Flush() log.Printf("[INFO] Waiting %s", w.d) select { case <-time.After(w.d): diff --git a/common/bootcommand/driver.go b/common/bootcommand/driver.go index ddbae0bc5..04b0eecd6 100644 --- a/common/bootcommand/driver.go +++ b/common/bootcommand/driver.go @@ -6,6 +6,6 @@ const shiftedChars = "~!@#$%^&*()_+{}|:\"<>?" type BCDriver interface { SendKey(key rune, action KeyAction) error SendSpecial(special string, action KeyAction) error - // Finalize will be called after every expression has been processed. - Finalize() error + // Flush will be called when we want to send scancodes to the VM. + Flush() error } diff --git a/common/bootcommand/pc_xt_driver.go b/common/bootcommand/pc_xt_driver.go index de148e42e..8b6a75d92 100644 --- a/common/bootcommand/pc_xt_driver.go +++ b/common/bootcommand/pc_xt_driver.go @@ -111,8 +111,8 @@ func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver { } } -// Finalize flushes all scanecodes. -func (d *pcXTDriver) Finalize() error { +// Flush send all scanecodes. +func (d *pcXTDriver) Flush() error { defer func() { d.buffer = nil }() @@ -162,6 +162,7 @@ func (d *pcXTDriver) SendSpecial(special string, action KeyAction) error { if !ok { return fmt.Errorf("special %s not found.", special) } + log.Printf("Special code '%s' '<%s>' found, replacing with: %v", action.String(), special, keyCode) switch action { case KeyOn: @@ -174,7 +175,7 @@ func (d *pcXTDriver) SendSpecial(special string, action KeyAction) error { return nil } -// send stores the codes in an internal buffer. Use finalize to flush them. +// send stores the codes in an internal buffer. Use Flush to send them. func (d *pcXTDriver) send(codes []string) { d.buffer = append(d.buffer, codes) } diff --git a/common/bootcommand/pc_xt_driver_test.go b/common/bootcommand/pc_xt_driver_test.go index ca4f5eb3d..b3a3c94ea 100644 --- a/common/bootcommand/pc_xt_driver_test.go +++ b/common/bootcommand/pc_xt_driver_test.go @@ -86,3 +86,22 @@ func Test_pcxtSpecialLookup(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expected, codes) } + +func Test_flushes(t *testing.T) { + in := "abc123<wait>098" + expected := [][]string{ + {"1e", "9e", "30", "b0", "2e", "ae", "02", "82", "03", "83", "04", "84"}, + {"0b", "8b", "0a", "8a", "09", "89"}, + } + var actual [][]string + sendCodes := func(c []string) error { + actual = append(actual, c) + return nil + } + d := NewPCXTDriver(sendCodes, -1) + seq, err := GenerateExpressionSequence(in) + assert.NoError(t, err) + err = seq.Do(context.Background(), d) + assert.NoError(t, err) + assert.Equal(t, expected, actual) +} diff --git a/common/bootcommand/vnc_driver.go b/common/bootcommand/vnc_driver.go index 86d6497c1..dfe75b9b2 100644 --- a/common/bootcommand/vnc_driver.go +++ b/common/bootcommand/vnc_driver.go @@ -92,8 +92,8 @@ func (d *vncDriver) keyEvent(k uint32, down bool) error { return nil } -// Finalize does nothing here -func (d *vncDriver) Finalize() error { +// Flush does nothing here +func (d *vncDriver) Flush() error { return nil } From 7e9af8247a3bfc7a70e70f0e9a8d71c3e3e71aef Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 17:02:39 -0700 Subject: [PATCH 0972/1007] fix 2 byte scancodes for pc-xt VMs. --- common/bootcommand/pc_xt_driver.go | 112 +++++++++++++----------- common/bootcommand/pc_xt_driver_test.go | 18 +++- 2 files changed, 78 insertions(+), 52 deletions(-) diff --git a/common/bootcommand/pc_xt_driver.go b/common/bootcommand/pc_xt_driver.go index 8b6a75d92..7aca80852 100644 --- a/common/bootcommand/pc_xt_driver.go +++ b/common/bootcommand/pc_xt_driver.go @@ -14,17 +14,27 @@ import ( // SendCodeFunc will be called to send codes to the VM type SendCodeFunc func([]string) error +type scMap map[string]*scancode type pcXTDriver struct { interval time.Duration sendImpl SendCodeFunc - specialMap map[string][]string + specialMap scMap scancodeMap map[rune]byte buffer [][]string // TODO: set from env scancodeChunkSize int } +type scancode struct { + make []string + break_ []string +} + +func (sc *scancode) makeBreak() []string { + return append(sc.make, sc.break_...) +} + // NewPCXTDriver creates a new boot command driver for VMs that expect PC-XT // keyboard codes. `send` should send its argument to the VM. `chunkSize` should // be the maximum number of keyboard codes to send to `send` at one time. @@ -41,44 +51,44 @@ func NewPCXTDriver(send SendCodeFunc, chunkSize int) *pcXTDriver { // Scancodes are recorded here in pairs. The first entry represents // the key press and the second entry represents the key release and is // derived from the first by the addition of 0x80. - sMap := make(map[string][]string) - sMap["bs"] = []string{"0e", "8e"} - sMap["del"] = []string{"e053", "e0d3"} - sMap["down"] = []string{"e050", "e0d0"} - sMap["end"] = []string{"e04f", "e0cf"} - sMap["enter"] = []string{"1c", "9c"} - sMap["esc"] = []string{"01", "81"} - sMap["f1"] = []string{"3b", "bb"} - sMap["f2"] = []string{"3c", "bc"} - sMap["f3"] = []string{"3d", "bd"} - sMap["f4"] = []string{"3e", "be"} - sMap["f5"] = []string{"3f", "bf"} - sMap["f6"] = []string{"40", "c0"} - sMap["f7"] = []string{"41", "c1"} - sMap["f8"] = []string{"42", "c2"} - sMap["f9"] = []string{"43", "c3"} - sMap["f10"] = []string{"44", "c4"} - sMap["f11"] = []string{"57", "d7"} - sMap["f12"] = []string{"58", "d8"} - sMap["home"] = []string{"e047", "e0c7"} - sMap["insert"] = []string{"e052", "e0d2"} - sMap["left"] = []string{"e04b", "e0cb"} - sMap["leftalt"] = []string{"38", "b8"} - sMap["leftctrl"] = []string{"1d", "9d"} - sMap["leftshift"] = []string{"2a", "aa"} - sMap["leftsuper"] = []string{"e05b", "e0db"} - sMap["menu"] = []string{"e05d", "e0dd"} - sMap["pagedown"] = []string{"e051", "e0d1"} - sMap["pageup"] = []string{"e049", "e0c9"} - sMap["return"] = []string{"1c", "9c"} - sMap["right"] = []string{"e04d", "e0cd"} - sMap["rightalt"] = []string{"e038", "e0b8"} - sMap["rightctrl"] = []string{"e01d", "e09d"} - sMap["rightshift"] = []string{"36", "b6"} - sMap["rightsuper"] = []string{"e05c", "e0dc"} - sMap["spacebar"] = []string{"39", "b9"} - sMap["tab"] = []string{"0f", "8f"} - sMap["up"] = []string{"e048", "e0c8"} + sMap := make(scMap) + sMap["bs"] = &scancode{[]string{"0e"}, []string{"8e"}} + sMap["del"] = &scancode{[]string{"e0", "53"}, []string{"e0", "d3"}} + sMap["down"] = &scancode{[]string{"e0", "50"}, []string{"e0", "d0"}} + sMap["end"] = &scancode{[]string{"e0", "4f"}, []string{"e0", "cf"}} + sMap["enter"] = &scancode{[]string{"1c"}, []string{"9c"}} + sMap["esc"] = &scancode{[]string{"01"}, []string{"81"}} + sMap["f1"] = &scancode{[]string{"3b"}, []string{"bb"}} + sMap["f2"] = &scancode{[]string{"3c"}, []string{"bc"}} + sMap["f3"] = &scancode{[]string{"3d"}, []string{"bd"}} + sMap["f4"] = &scancode{[]string{"3e"}, []string{"be"}} + sMap["f5"] = &scancode{[]string{"3f"}, []string{"bf"}} + sMap["f6"] = &scancode{[]string{"40"}, []string{"c0"}} + sMap["f7"] = &scancode{[]string{"41"}, []string{"c1"}} + sMap["f8"] = &scancode{[]string{"42"}, []string{"c2"}} + sMap["f9"] = &scancode{[]string{"43"}, []string{"c3"}} + sMap["f10"] = &scancode{[]string{"44"}, []string{"c4"}} + sMap["f11"] = &scancode{[]string{"57"}, []string{"d7"}} + sMap["f12"] = &scancode{[]string{"58"}, []string{"d8"}} + sMap["home"] = &scancode{[]string{"e0", "47"}, []string{"e0", "c7"}} + sMap["insert"] = &scancode{[]string{"e0", "52"}, []string{"e0", "d2"}} + sMap["left"] = &scancode{[]string{"e0", "4b"}, []string{"e0", "cb"}} + sMap["leftalt"] = &scancode{[]string{"38"}, []string{"b8"}} + sMap["leftctrl"] = &scancode{[]string{"1d"}, []string{"9d"}} + sMap["leftshift"] = &scancode{[]string{"2a"}, []string{"aa"}} + sMap["leftsuper"] = &scancode{[]string{"e0", "5b"}, []string{"e0", "db"}} + sMap["menu"] = &scancode{[]string{"e0", "5d"}, []string{"e0", "dd"}} + sMap["pagedown"] = &scancode{[]string{"e0", "51"}, []string{"e0", "d1"}} + sMap["pageup"] = &scancode{[]string{"e0", "49"}, []string{"e0", "c9"}} + sMap["return"] = &scancode{[]string{"1c"}, []string{"9c"}} + sMap["right"] = &scancode{[]string{"e0", "4d"}, []string{"e0", "cd"}} + sMap["rightalt"] = &scancode{[]string{"e0", "38"}, []string{"e0", "b8"}} + sMap["rightctrl"] = &scancode{[]string{"e0", "1d"}, []string{"e0", "9d"}} + sMap["rightshift"] = &scancode{[]string{"36"}, []string{"b6"}} + sMap["rightsuper"] = &scancode{[]string{"e0", "5c"}, []string{"e0", "dc"}} + sMap["spacebar"] = &scancode{[]string{"39"}, []string{"b9"}} + sMap["tab"] = &scancode{[]string{"0f"}, []string{"8f"}} + sMap["up"] = &scancode{[]string{"e0", "48"}, []string{"e0", "c8"}} scancodeIndex := make(map[string]byte) scancodeIndex["1234567890-="] = 0x02 @@ -132,28 +142,28 @@ func (d *pcXTDriver) Flush() error { func (d *pcXTDriver) SendKey(key rune, action KeyAction) error { keyShift := unicode.IsUpper(key) || strings.ContainsRune(shiftedChars, key) - var scancode []string + var sc []string if action&(KeyOn|KeyPress) != 0 { - scancodeInt := d.scancodeMap[key] + scInt := d.scancodeMap[key] if keyShift { - scancode = append(scancode, "2a") + sc = append(sc, "2a") } - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + sc = append(sc, fmt.Sprintf("%02x", scInt)) } if action&(KeyOff|KeyPress) != 0 { - scancodeInt := d.scancodeMap[key] + 0x80 + scInt := d.scancodeMap[key] + 0x80 if keyShift { - scancode = append(scancode, "aa") + sc = append(sc, "aa") } - scancode = append(scancode, fmt.Sprintf("%02x", scancodeInt)) + sc = append(sc, fmt.Sprintf("%02x", scInt)) } log.Printf("Sending char '%c', code '%s', shift %v", - key, strings.Join(scancode, ""), keyShift) + key, strings.Join(sc, ""), keyShift) - d.send(scancode) + d.send(sc) return nil } @@ -166,11 +176,11 @@ func (d *pcXTDriver) SendSpecial(special string, action KeyAction) error { switch action { case KeyOn: - d.send([]string{keyCode[0]}) + d.send(keyCode.make) case KeyOff: - d.send([]string{keyCode[1]}) + d.send(keyCode.break_) case KeyPress: - d.send(keyCode) + d.send(keyCode.makeBreak()) } return nil } diff --git a/common/bootcommand/pc_xt_driver_test.go b/common/bootcommand/pc_xt_driver_test.go index b3a3c94ea..eb4ac621f 100644 --- a/common/bootcommand/pc_xt_driver_test.go +++ b/common/bootcommand/pc_xt_driver_test.go @@ -71,7 +71,7 @@ func Test_chunkScanCodeError(t *testing.T) { assert.Error(t, err) } -func Test_pcxtSpecialLookup(t *testing.T) { +func Test_pcxtSpecialOnOff(t *testing.T) { in := "<rightShift><rightshiftoff><RIGHTSHIFTON>" expected := []string{"36", "b6", "b6", "36"} var codes []string @@ -87,6 +87,22 @@ func Test_pcxtSpecialLookup(t *testing.T) { assert.Equal(t, expected, codes) } +func Test_pcxtSpecial(t *testing.T) { + in := "<left>" + expected := []string{"0e", "4b", "e0", "cb"} + var codes []string + sendCodes := func(c []string) error { + codes = c + return nil + } + d := NewPCXTDriver(sendCodes, -1) + seq, err := GenerateExpressionSequence(in) + assert.NoError(t, err) + err = seq.Do(context.Background(), d) + assert.NoError(t, err) + assert.Equal(t, expected, codes) +} + func Test_flushes(t *testing.T) { in := "abc123<wait>098" expected := [][]string{ From b5a97e468f5de01ef0e8c28fcc4670c4d74ef4d0 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Thu, 19 Apr 2018 17:07:58 -0700 Subject: [PATCH 0973/1007] fix test --- common/bootcommand/pc_xt_driver_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/bootcommand/pc_xt_driver_test.go b/common/bootcommand/pc_xt_driver_test.go index eb4ac621f..cd0e04ec8 100644 --- a/common/bootcommand/pc_xt_driver_test.go +++ b/common/bootcommand/pc_xt_driver_test.go @@ -89,7 +89,7 @@ func Test_pcxtSpecialOnOff(t *testing.T) { func Test_pcxtSpecial(t *testing.T) { in := "<left>" - expected := []string{"0e", "4b", "e0", "cb"} + expected := []string{"e0", "4b", "e0", "cb"} var codes []string sendCodes := func(c []string) error { codes = c From 5a10e5a038a55d129b3f688024fdd411d6b803ee Mon Sep 17 00:00:00 2001 From: Evgeni Golov <evgeni@golov.de> Date: Fri, 20 Apr 2018 13:17:40 +0200 Subject: [PATCH 0974/1007] fix invalid disc_discard setting error message --- builder/qemu/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index d1d91d79f..5e102825c 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -280,7 +280,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { if _, ok := diskDiscard[b.config.DiskDiscard]; !ok { errs = packer.MultiErrorAppend( - errs, errors.New("unrecognized disk cache type")) + errs, errors.New("unrecognized disk discard type")) } if !b.config.PackerForce { From 45b519945382301e5094d203c905273236be79c2 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 20 Apr 2018 12:23:27 -0700 Subject: [PATCH 0975/1007] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e5e744e8..9a8a5f4a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * post-processor/vagrant: Large VMDKs should no longer show a 0-byte size on OS X. [GH-6084] * builder/scaleway: Fix compilation issues on solaris/amd64. [GH-6069] +* common/bootcommand: Fix numerous bugs in the boot command code, and make supported features consistent across builders. [GH-6129] ### IMPROVEMENTS: From 40d054a1a78e61b2409ad722b97e5f3c8ae6fe27 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Fri, 20 Apr 2018 12:28:11 -0700 Subject: [PATCH 0976/1007] add recommended vmware network setting when using HTTPIP. --- website/source/docs/builders/vmware-iso.html.md.erb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index 5ad13c117..8155cedbe 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -429,6 +429,12 @@ e.g. `PACKER_KEY_INTERVAL=10ms` to speed through the boot command. <%= partial "partials/builders/boot-command" %> +-&gt; **Note**: for the `HTTPIP` to be resolved correctly, your VM's network +configuration has to include a `hostonly` or `nat` type network interface. +If you are using this feature, it is recommended to leave the default network +configuration while you are building the VM, and use the `vmx_data_post` hook +to modify the network configuration after the VM is done building. + Example boot command. This is actually a working boot command used to start an Ubuntu 12.04 installer: From e4bd30e53d9b7b1fdc136d828cd26fe38e287a3b Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sat, 21 Apr 2018 11:40:47 -0700 Subject: [PATCH 0977/1007] fix bug with empty boot command. --- common/bootcommand/boot_command_ast.go | 5 ++++- common/bootcommand/boot_command_ast_test.go | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/common/bootcommand/boot_command_ast.go b/common/bootcommand/boot_command_ast.go index 98a4afc81..f680345c4 100644 --- a/common/bootcommand/boot_command_ast.go +++ b/common/bootcommand/boot_command_ast.go @@ -75,11 +75,14 @@ func (s expressionSequence) Validate() (errs []error) { // GenerateExpressionSequence generates a sequence of expressions from the // given command. This is the primary entry point to the boot command parser. func GenerateExpressionSequence(command string) (expressionSequence, error) { + seq := expressionSequence{} + if command == "" { + return seq, nil + } got, err := ParseReader("", strings.NewReader(command)) if err != nil { return nil, err } - seq := expressionSequence{} for _, exp := range got.([]interface{}) { seq = append(seq, exp.(expression)) } diff --git a/common/bootcommand/boot_command_ast_test.go b/common/bootcommand/boot_command_ast_test.go index 9638da42f..d5ad21900 100644 --- a/common/bootcommand/boot_command_ast_test.go +++ b/common/bootcommand/boot_command_ast_test.go @@ -138,3 +138,9 @@ func Test_validation(t *testing.T) { } } } + +func Test_empty(t *testing.T) { + exp, err := GenerateExpressionSequence("") + assert.NoError(t, err, "should have parsed an empty input okay.") + assert.Len(t, exp, 0) +} From 6c9d4efd9fdaffa73ef18b82ad06a22055f10e55 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 30 Mar 2018 21:59:38 +0100 Subject: [PATCH 0978/1007] Fix error on compaction step of vmx build. Support compacting multi-disk vm --- builder/vmware/vmx/step_clone_vmx.go | 124 ++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 21 deletions(-) diff --git a/builder/vmware/vmx/step_clone_vmx.go b/builder/vmware/vmx/step_clone_vmx.go index f0bdd586d..edd81ea99 100644 --- a/builder/vmware/vmx/step_clone_vmx.go +++ b/builder/vmware/vmx/step_clone_vmx.go @@ -18,14 +18,70 @@ type StepCloneVMX struct { VMName string } +type vmxAdapter struct { + // The string portion of the address used in the vmx file + strAddr string + // Max address for adapter, controller, or controller channel + aAddrMax int + // Max address for device or channel supported by adapter + dAddrMax int +} + +const ( + // VMware Configuration Maximums - Virtual Hardware Versions 13/14 + // + // Specifying the max numbers for the adapter/controller:bus/channel + // *address* as opposed to specifying the maximums as per the VMware + // documentation allows consistent (inclusive) treatment when looping + // over each adapter/controller type + // + // SCSI - Address range: scsi0:0 to scsi3:15 + scsiAddrName = "scsi" // String part of address used in the vmx file + maxSCSIAdapterAddr = 3 // Max 4 adapters + maxSCSIDeviceAddr = 15 // Max 15 devices per adapter; ID 7 is the HBA + // SATA - Address range: sata0:0 to scsi3:29 + sataAddrName = "sata" // String part of address used in the vmx file + maxSATAAdapterAddr = 3 // Max 4 controllers + maxSATADeviceAddr = 29 // Max 30 devices per controller + // NVMe - Address range: nvme0:0 to nvme3:14 + nvmeAddrName = "nvme" // String part of address used in the vmx file + maxNVMeAdapterAddr = 3 // Max 4 adapters + maxNVMeDeviceAddr = 14 // Max 15 devices per adapter + // IDE - Address range: ide0:0 to ide1:1 + ideAddrName = "ide" // String part of address used in the vmx file + maxIDEAdapterAddr = 1 // One controller with primary/secondary channels + maxIDEDeviceAddr = 1 // Each channel supports master and slave +) + +var ( + scsiAdapter = vmxAdapter{ + strAddr: scsiAddrName, + aAddrMax: maxSCSIAdapterAddr, + dAddrMax: maxSCSIDeviceAddr, + } + sataAdapter = vmxAdapter{ + strAddr: sataAddrName, + aAddrMax: maxSATAAdapterAddr, + dAddrMax: maxSATADeviceAddr, + } + nvmeAdapter = vmxAdapter{ + strAddr: nvmeAddrName, + aAddrMax: maxNVMeAdapterAddr, + dAddrMax: maxNVMeDeviceAddr, + } + ideAdapter = vmxAdapter{ + strAddr: ideAddrName, + aAddrMax: maxIDEAdapterAddr, + dAddrMax: maxIDEDeviceAddr, + } +) + func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(vmwcommon.Driver) ui := state.Get("ui").(packer.Ui) - // initially we need to stash the path to the original .vmx file + // Set the path we want for the new .vmx file and clone vmxPath := filepath.Join(s.OutputDir, s.VMName+".vmx") - - // so first, let's clone the source path to the vmxPath ui.Say("Cloning source VM...") log.Printf("Cloning from: %s", s.Path) log.Printf("Cloning to: %s", vmxPath) @@ -33,34 +89,44 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste state.Put("error", err) return multistep.ActionHalt } - ui.Say(fmt.Sprintf("Successfully cloned source VM to: %s", vmxPath)) - // now we read the .vmx so we can determine what else to stash + // Read in the machine configuration from the cloned VMX file + // + // * The main driver needs the path to the vmx (set above) and the + // network type so that it can work out things like IP's and MAC + // addresses + // * The disk compaction step needs the paths to all attached disks vmxData, err := vmwcommon.ReadVMX(vmxPath) if err != nil { state.Put("error", err) return multistep.ActionHalt } - // figure out the disk filename by walking through all device types - var diskName string - if _, ok := vmxData["scsi0:0.filename"]; ok { - diskName = vmxData["scsi0:0.filename"] + // Search across all adapter types to get the filenames of attached disks + allDiskAdapters := []vmxAdapter{ + scsiAdapter, + sataAdapter, + nvmeAdapter, + ideAdapter, } - if _, ok := vmxData["sata0:0.filename"]; ok { - diskName = vmxData["sata0:0.filename"] + var diskFilenames []string + for _, adapter := range allDiskAdapters { + diskFilenames = append(diskFilenames, getAttachedDisks(adapter, vmxData)...) } - if _, ok := vmxData["ide0:0.filename"]; ok { - diskName = vmxData["ide0:0.filename"] + + // Write out the relative, host filesystem paths to the disks + var diskFullPaths []string + for _, diskFilename := range diskFilenames { + log.Printf("Found attached disk with filename: %s", diskFilename) + diskFullPaths = append(diskFullPaths, filepath.Join(s.OutputDir, diskFilename)) } - if diskName == "" { - err := fmt.Errorf("Root disk filename could not be found!") - state.Put("error", err) + + if len(diskFullPaths) == 0 { + state.Put("error", fmt.Errorf("Could not enumerate disk info from the vmx file")) return multistep.ActionHalt } - log.Printf("Found root disk filename: %s", diskName) - // determine the network type by reading out of the .vmx + // Determine the network type by reading out of the .vmx var networkType string if _, ok := vmxData["ethernet0.connectiontype"]; ok { networkType = vmxData["ethernet0.connectiontype"] @@ -70,11 +136,13 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste networkType = "nat" log.Printf("Defaulting to network type: %s", networkType) } - ui.Say(fmt.Sprintf("Using network type: %s", networkType)) - // we were able to find everything, so stash it in our state. + // Stash all required information in our state bag state.Put("vmx_path", vmxPath) - state.Put("full_disk_path", filepath.Join(s.OutputDir, diskName)) + // What disks get assigned to what key doesn't actually matter here + // since it's unimportant to the way the disk compaction step works + state.Put("full_disk_path", diskFullPaths[0]) + state.Put("additional_disk_paths", diskFullPaths[1:]) state.Put("vmnetwork", networkType) return multistep.ActionContinue @@ -82,3 +150,17 @@ func (s *StepCloneVMX) Run(_ context.Context, state multistep.StateBag) multiste func (s *StepCloneVMX) Cleanup(state multistep.StateBag) { } + +func getAttachedDisks(a vmxAdapter, data map[string]string) (attachedDisks []string) { + // Loop over possible adapter, controller or controller channel + for x := 0; x <= a.aAddrMax; x++ { + // Loop over possible addresses for attached devices + for y := 0; y <= a.dAddrMax; y++ { + address := fmt.Sprintf("%s%d:%d.filename", a.strAddr, x, y) + if device, _ := data[address]; filepath.Ext(device) == ".vmdk" { + attachedDisks = append(attachedDisks, device) + } + } + } + return +} From 1aee759f0673d424d321bdbb50b49abb00a0609c Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 30 Mar 2018 22:00:21 +0100 Subject: [PATCH 0979/1007] Fix tests and reconfigure for support of multi-disk vm --- builder/vmware/vmx/step_clone_vmx_test.go | 37 ++++++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/builder/vmware/vmx/step_clone_vmx_test.go b/builder/vmware/vmx/step_clone_vmx_test.go index e086f0ce5..990a2d20e 100644 --- a/builder/vmware/vmx/step_clone_vmx_test.go +++ b/builder/vmware/vmx/step_clone_vmx_test.go @@ -2,6 +2,7 @@ package vmx import ( "context" + "fmt" "io/ioutil" "os" "path/filepath" @@ -9,6 +10,14 @@ import ( vmwcommon "github.com/hashicorp/packer/builder/vmware/common" "github.com/hashicorp/packer/helper/multistep" + "github.com/stretchr/testify/assert" +) + +const ( + scsiFilename = "scsiDisk.vmdk" + sataFilename = "sataDisk.vmdk" + nvmeFilename = "nvmeDisk.vmdk" + ideFilename = "ideDisk.vmdk" ) func TestStepCloneVMX_impl(t *testing.T) { @@ -23,6 +32,21 @@ func TestStepCloneVMX(t *testing.T) { } defer os.RemoveAll(td) + // Set up mock vmx file contents + var testCloneVMX = fmt.Sprintf("scsi0:0.filename = \"%s\"\n"+ + "sata0:0.filename = \"%s\"\n"+ + "nvme0:0.filename = \"%s\"\n"+ + "ide1:0.filename = \"%s\"\n"+ + "ide0:0.filename = \"auto detect\"\n", scsiFilename, + sataFilename, nvmeFilename, ideFilename) + + // Set up expected mock disk file paths + diskFilenames := []string{scsiFilename, sataFilename, ideFilename, nvmeFilename} + var diskPaths []string + for _, diskFilename := range diskFilenames { + diskPaths = append(diskPaths, filepath.Join(td, diskFilename)) + } + // Create the source sourcePath := filepath.Join(td, "source.vmx") if err := ioutil.WriteFile(sourcePath, []byte(testCloneVMX), 0644); err != nil { @@ -65,11 +89,14 @@ func TestStepCloneVMX(t *testing.T) { if diskPath, ok := state.GetOk("full_disk_path"); !ok { t.Fatal("should set full_disk_path") - } else if diskPath != filepath.Join(td, "foo") { + } else if diskPath != diskPaths[0] { t.Fatalf("bad: %#v", diskPath) } -} -const testCloneVMX = ` -scsi0:0.fileName = "foo" -` + if stateDiskPaths, ok := state.GetOk("additional_disk_paths"); !ok { + t.Fatal("should set additional_disk_paths") + } else { + assert.ElementsMatchf(t, stateDiskPaths.([]string), diskPaths[1:], + "%s\nshould contain the same elements as:\n%s", stateDiskPaths.([]string), diskPaths[1:]) + } +} From 94d5a7f2e2c5cd40ece1faf67a09fd816361820d Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 29 Mar 2018 01:19:15 +0100 Subject: [PATCH 0980/1007] Fix copy/paste error referencing Virtualbox --- builder/vmware/vmx/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index bfe6b06c9..130c533d7 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -32,7 +32,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } // Run executes a Packer build and returns a packer.Artifact representing -// a VirtualBox appliance. +// a VMware image. func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { driver, err := vmwcommon.NewDriver(&b.config.DriverConfig, &b.config.SSHConfig) if err != nil { From bd9e585cb993222e14281061d140c91c2df3e24b Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 30 Mar 2018 22:44:14 +0100 Subject: [PATCH 0981/1007] Add test for enumeration of vmx network type --- builder/vmware/vmx/step_clone_vmx_test.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/builder/vmware/vmx/step_clone_vmx_test.go b/builder/vmware/vmx/step_clone_vmx_test.go index 990a2d20e..e7ef9ff95 100644 --- a/builder/vmware/vmx/step_clone_vmx_test.go +++ b/builder/vmware/vmx/step_clone_vmx_test.go @@ -37,7 +37,8 @@ func TestStepCloneVMX(t *testing.T) { "sata0:0.filename = \"%s\"\n"+ "nvme0:0.filename = \"%s\"\n"+ "ide1:0.filename = \"%s\"\n"+ - "ide0:0.filename = \"auto detect\"\n", scsiFilename, + "ide0:0.filename = \"auto detect\"\n"+ + "ethernet0.connectiontype = \"nat\"\n", scsiFilename, sataFilename, nvmeFilename, ideFilename) // Set up expected mock disk file paths @@ -84,13 +85,13 @@ func TestStepCloneVMX(t *testing.T) { if vmxPath, ok := state.GetOk("vmx_path"); !ok { t.Fatal("should set vmx_path") } else if vmxPath != destPath { - t.Fatalf("bad: %#v", vmxPath) + t.Fatalf("bad path to vmx: %#v", vmxPath) } if diskPath, ok := state.GetOk("full_disk_path"); !ok { t.Fatal("should set full_disk_path") } else if diskPath != diskPaths[0] { - t.Fatalf("bad: %#v", diskPath) + t.Fatalf("bad disk path: %#v", diskPath) } if stateDiskPaths, ok := state.GetOk("additional_disk_paths"); !ok { @@ -99,4 +100,11 @@ func TestStepCloneVMX(t *testing.T) { assert.ElementsMatchf(t, stateDiskPaths.([]string), diskPaths[1:], "%s\nshould contain the same elements as:\n%s", stateDiskPaths.([]string), diskPaths[1:]) } + + // Test we got the network type + if networkType, ok := state.GetOk("vmnetwork"); !ok { + t.Fatal("should set vmnetwork") + } else if networkType != "nat" { + t.Fatalf("bad network type: %#v", networkType) + } } From 90fde9fc4624fb36e5ade7ddb5bab9a38354e8d2 Mon Sep 17 00:00:00 2001 From: Tyler Tidman <tyler.tidman@draak.ca> Date: Sat, 21 Apr 2018 20:50:40 -0400 Subject: [PATCH 0982/1007] More cleanup in communicator and builder docs Tested and verified using "make website". Fix up the vmware, vbox and qemu builder and communicator docs. Sort more things in alphabetical order. Use backtick delimiters for values. Wrap long lines to 80 characters. Show actual default value for boot_wait. Copy vrdp_bind_address info from vbox iso to vbox ovf builder. Show defaults for vmx_remove_ethernet_interfaces. Show default port values for ssh in vbox ovf builder. Remove executable bit on openstack builder doc. Show default for skip_compaction in vmware vmx builder. Add a bunch of missing periods. Remove a few redundant commas. --- .../source/docs/builders/openstack.html.md | 0 website/source/docs/builders/qemu.html.md.erb | 104 +++++++------- .../docs/builders/virtualbox-iso.html.md.erb | 85 ++++++------ .../docs/builders/virtualbox-ovf.html.md.erb | 70 +++++----- .../docs/builders/vmware-iso.html.md.erb | 131 +++++++++--------- .../docs/builders/vmware-vmx.html.md.erb | 60 ++++---- .../docs/templates/communicator.html.md | 76 +++++----- 7 files changed, 270 insertions(+), 256 deletions(-) mode change 100755 => 100644 website/source/docs/builders/openstack.html.md diff --git a/website/source/docs/builders/openstack.html.md b/website/source/docs/builders/openstack.html.md old mode 100755 new mode 100644 diff --git a/website/source/docs/builders/qemu.html.md.erb b/website/source/docs/builders/qemu.html.md.erb index a1c2073db..c47cd1e51 100644 --- a/website/source/docs/builders/qemu.html.md.erb +++ b/website/source/docs/builders/qemu.html.md.erb @@ -92,8 +92,8 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). over `iso_checksum_url` type. - `iso_checksum_type` (string) - The type of the checksum specified in - `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or - "sha512" currently. While "none" will skip checksumming, this is not + `iso_checksum`. Valid values are `none`, `md5`, `sha1`, `sha256`, or + `sha512` currently. While `none` will skip checksumming, this is not recommended since ISO files are generally large and corruption does happen from time to time. @@ -107,15 +107,15 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). this is an HTTP URL, Packer will download it and cache it between runs. This can also be a URL to an IMG or QCOW2 file, in which case QEMU will boot directly from it. When passing a path to an IMG or QCOW2 file, you - should set `disk_image` to "true". + should set `disk_image` to `true`. ### Optional: - `accelerator` (string) - The accelerator type to use when running the VM. This may be `none`, `kvm`, `tcg`, `hax`, or `xen`. The appropriate software - must have already been installed on your build machine to use the accelerator - you specified. When no accelerator is specified, Packer will try to use `kvm` - if it is available but will default to `tcg` otherwise. + must have already been installed on your build machine to use the + accelerator you specified. When no accelerator is specified, Packer will try + to use `kvm` if it is available but will default to `tcg` otherwise. -&gt; The `hax` accelerator has issues attaching CDROM ISOs. This is an upstream issue which can be tracked @@ -130,19 +130,19 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). - `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be - a duration. Examples are "5s" and "1m30s" which will cause Packer to wait + a duration. Examples are `5s` and `1m30s` which will cause Packer to wait five seconds and one minute 30 seconds, respectively. If this isn't - specified, the default is 10 seconds. + specified, the default is `10s` or 10 seconds. - `disk_cache` (string) - The cache mode to use for disk. Allowed values - include any of "writethrough", "writeback", "none", "unsafe" - or "directsync". By default, this is set to "writeback". + include any of `writethrough`, `writeback`, `none`, `unsafe` + or `directsync`. By default, this is set to `writeback`. - `disk_compression` (boolean) - Apply compression to the QCOW2 disk file using `qemu-img convert`. Defaults to `false`. - `disk_discard` (string) - The discard mode to use for disk. Allowed values - include any of "unmap" or "ignore". By default, this is set to "ignore". + include any of `unmap` or `ignore`. By default, this is set to `ignore`. - `disk_image` (boolean) - Packer defaults to building from an ISO file, this parameter controls whether the ISO URL supplied is actually a bootable @@ -150,20 +150,28 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). source, resize it according to `disk_size` and boot the image. - `disk_interface` (string) - The interface to use for the disk. Allowed - values include any of "ide", "scsi", "virtio" or "virtio-scsi"^\* . Note also - that any boot commands or kickstart type scripts must have proper - adjustments for resulting device names. The Qemu builder uses "virtio" by + values include any of `ide`, `scsi`, `virtio` or `virtio-scsi`^\*. Note + also that any boot commands or kickstart type scripts must have proper + adjustments for resulting device names. The Qemu builder uses `virtio` by default. - ^\* Please be aware that use of the "scsi" disk interface has been disabled + ^\* Please be aware that use of the `scsi` disk interface has been disabled by Red Hat due to a bug described [here](https://bugzilla.redhat.com/show_bug.cgi?id=1019220). If you are running Qemu on RHEL or a RHEL variant such as CentOS, you - *must* choose one of the other listed interfaces. Using the "scsi" + *must* choose one of the other listed interfaces. Using the `scsi` interface under these circumstances will cause the build to fail. - `disk_size` (number) - The size, in megabytes, of the hard disk to create - for the VM. By default, this is 40960 (40 GB). + for the VM. By default, this is `40960` (40 GB). + +- `floppy_dirs` (array of strings) - A list of directories to place onto + the floppy disk recursively. This is similar to the `floppy_files` option + except that the directory structure is preserved. This is useful for when + your floppy disk includes drivers or if you just want to organize it's + contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. + The maximum summary size of all files in the listed directories are the + same as in `floppy_files`. - `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for @@ -177,20 +185,12 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). listed files must not exceed 1.44 MB. The supported ways to move large files into the OS are using `http_directory` or [the file provisioner](https://www.packer.io/docs/provisioners/file.html). -- `floppy_dirs` (array of strings) - A list of directories to place onto - the floppy disk recursively. This is similar to the `floppy_files` option - except that the directory structure is preserved. This is useful for when - your floppy disk includes drivers or if you just want to organize it's - contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. - The maximum summary size of all files in the listed directories are the - same as in `floppy_files`. - -- `format` (string) - Either "qcow2" or "raw", this specifies the output +- `format` (string) - Either `qcow2` or `raw`, this specifies the output format of the virtual machine image. This defaults to `qcow2`. - `headless` (boolean) - Packer defaults to building QEMU virtual machines by launching a GUI that shows the console of the machine being built. When this - value is set to true, the machine will start without a console. + value is set to `true`, the machine will start without a console. You can still see the console if you make a note of the VNC display number chosen, and then connect using `vncviewer -Shared <host>:<display>` @@ -198,22 +198,23 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). - `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting - kickstart files and so on. By default this is "", which means no HTTP server - will be started. The address and port of the HTTP server will be available - as variables in `boot_command`. This is covered in more detail below. + kickstart files and so on. By default this is an empty string, which means + no HTTP server will be started. The address and port of the HTTP server will + be available as variables in `boot_command`. This is covered in more detail + below. - `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP server to be on one port, make this minimum and maximum - port the same. By default the values are 8000 and 9000, respectively. + port the same. By default the values are `8000` and `9000`, respectively. - `iso_skip_cache` (boolean) - Use iso from provided url. Qemu must support curl block device. This defaults to `false`. - `iso_target_extension` (string) - The extension of the iso file after - download. This defaults to "iso". + download. This defaults to `iso`. - `iso_target_path` (string) - The path where the iso should be saved after download. By default will go in the packer cache, with a hash of the @@ -227,25 +228,25 @@ Linux server and have not enabled X11 forwarding (`ssh -X`). - `machine_type` (string) - The type of machine emulation to use. Run your qemu binary with the flags `-machine help` to list available types for - your system. This defaults to "pc". + your system. This defaults to `pc`. - `net_device` (string) - The driver to use for the network interface. Allowed - values "ne2k\_pci", "i82551", "i82557b", "i82559er", "rtl8139", "e1000", - "pcnet", "virtio", "virtio-net", "virtio-net-pci", "usb-net", "i82559a", - "i82559b", "i82559c", "i82550", "i82562", "i82557a", "i82557c", "i82801", - "vmxnet3", "i82558a" or "i82558b". The Qemu builder uses "virtio-net" by + values `ne2k_pci`, `i82551`, `i82557b`, `i82559er`, `rtl8139`, `e1000`, + `pcnet`, `virtio`, `virtio-net`, `virtio-net-pci`, `usb-net`, `i82559a`, + `i82559b`, `i82559c`, `i82550`, `i82562`, `i82557a`, `i82557c`, `i82801`, + `vmxnet3`, `i82558a` or `i82558b`. The Qemu builder uses `virtio-net` by default. - `output_directory` (string) - This is the path to the directory where the resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` is executed. This directory must not exist or be empty prior to running - the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the + the builder. By default this is `output-BUILDNAME` where "BUILDNAME" is the name of the build. - `qemu_binary` (string) - The name of the Qemu binary to look for. This - defaults to "qemu-system-x86\_64", but may need to be changed for - some platforms. For example "qemu-kvm", or "qemu-system-i386" may be a + defaults to `qemu-system-x86_64`, but may need to be changed for + some platforms. For example `qemu-kvm`, or `qemu-system-i386` may be a better choice for some systems. - `qemuargs` (array of array of strings) - Allows complete control over the @@ -314,7 +315,7 @@ default port of `5985` or whatever value you have the service set to listen on. - `use_default_display` (boolean) - If true, do not pass a `-display` option to qemu, allowing it to choose the default. This may be needed when running - under OS X, and getting errors about `sdl` not being available. + under macOS, and getting errors about `sdl` not being available. - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty @@ -327,31 +328,32 @@ default port of `5985` or whatever value you have the service set to listen on. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it doesn't shut down in this time, it is an error. By default, the timeout is - `5m`, or five minutes. + `5m` or five minutes. -- `skip_compaction` (boolean) - Packer compacts the QCOW2 image using `qemu-img convert`. - Set this option to `true` to disable compacting. Defaults to `false`. +- `skip_compaction` (boolean) - Packer compacts the QCOW2 image using + `qemu-img convert`. Set this option to `true` to disable compacting. + Defaults to `false`. - `ssh_host_port_min` and `ssh_host_port_max` (number) - The minimum and maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to use as the - host port. By default this is 2222 to 4444. + host port. By default this is `2222` to `4444`. - `vm_name` (string) - This is the name of the image (QCOW2 or IMG) file for - the new virtual machine. By default this is "packer-BUILDNAME", where - `BUILDNAME` is the name of the build. Currently, no file extension will be + the new virtual machine. By default this is `packer-BUILDNAME`, where + "BUILDNAME" is the name of the build. Currently, no file extension will be used unless it is specified in this option. -- `vnc_bind_address` (string / IP address) - The IP address that should be binded - to for VNC. By default packer will use 127.0.0.1 for this. If you wish to bind - to all interfaces use 0.0.0.0 +- `vnc_bind_address` (string / IP address) - The IP address that should be + binded to for VNC. By default packer will use `127.0.0.1` for this. If you + wish to bind to all interfaces use `0.0.0.0`. - `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type the initial `boot_command`. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By - default this is 5900 to 6000. The minimum and maximum ports are inclusive. + default this is `5900` to `6000`. The minimum and maximum ports are inclusive. ## Boot Command diff --git a/website/source/docs/builders/virtualbox-iso.html.md.erb b/website/source/docs/builders/virtualbox-iso.html.md.erb index b89eb0586..78de79af8 100644 --- a/website/source/docs/builders/virtualbox-iso.html.md.erb +++ b/website/source/docs/builders/virtualbox-iso.html.md.erb @@ -65,8 +65,8 @@ builder. over `iso_checksum_url` type. - `iso_checksum_type` (string) - The type of the checksum specified in - `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or - "sha512" currently. While "none" will skip checksumming, this is not + `iso_checksum`. Valid values are `none`, `md5`, `sha1`, `sha256`, or + `sha512` currently. While `none` will skip checksumming, this is not recommended since ISO files are generally large and corruption does happen from time to time. @@ -90,12 +90,12 @@ builder. - `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be - a duration. Examples are "5s" and "1m30s" which will cause Packer to wait + a duration. Examples are `5s` and `1m30s` which will cause Packer to wait five seconds and one minute 30 seconds, respectively. If this isn't - specified, the default is 10 seconds. + specified, the default is `10s` or 10 seconds. - `disk_size` (number) - The size, in megabytes, of the hard disk to create - for the VM. By default, this is 40000 (about 40 GB). + for the VM. By default, this is `40000` (about 40 GB). - `export_opts` (array of strings) - Additional options to pass to the [VBoxManage @@ -139,6 +139,12 @@ builder. "packer_conf.json" ``` +- `floppy_dirs` (array of strings) - A list of directories to place onto + the floppy disk recursively. This is similar to the `floppy_files` option + except that the directory structure is preserved. This is useful for when + your floppy disk includes drivers or if you just want to organize it's + contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. + - `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for unattended Windows installs, which look for an `Autounattend.xml` file on @@ -149,26 +155,20 @@ builder. and \[\]) are allowed. Directory names are also allowed, which will add all the files found in the directory to the floppy. -- `floppy_dirs` (array of strings) - A list of directories to place onto - the floppy disk recursively. This is similar to the `floppy_files` option - except that the directory structure is preserved. This is useful for when - your floppy disk includes drivers or if you just want to organize it's - contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. - -- `format` (string) - Either "ovf" or "ova", this specifies the output format - of the exported virtual machine. This defaults to "ovf". +- `format` (string) - Either `ovf` or `ova`, this specifies the output format + of the exported virtual machine. This defaults to `ovf`. - `guest_additions_mode` (string) - The method by which guest additions are - made available to the guest for installation. Valid options are "upload", - "attach", or "disable". If the mode is "attach" the guest additions ISO will - be attached as a CD device to the virtual machine. If the mode is "upload" + made available to the guest for installation. Valid options are `upload`, + `attach`, or `disable`. If the mode is `attach` the guest additions ISO will + be attached as a CD device to the virtual machine. If the mode is `upload` the guest additions ISO will be uploaded to the path specified by - `guest_additions_path`. The default value is "upload". If "disable" is used, + `guest_additions_path`. The default value is `upload`. If `disable` is used, guest additions won't be downloaded, either. - `guest_additions_path` (string) - The path on the guest virtual machine where the VirtualBox guest additions ISO will be uploaded. By default this - is "VBoxGuestAdditions.iso" which should upload into the login directory of + is `VBoxGuestAdditions.iso` which should upload into the login directory of the user. This is a [configuration template](/docs/templates/engine.html) where the `Version` variable is replaced with the VirtualBox version. @@ -185,24 +185,24 @@ builder. download the proper guest additions ISO from the internet. - `guest_os_type` (string) - The guest OS type being installed. By default - this is "other", but you can get *dramatic* performance improvements by + this is `other`, but you can get *dramatic* performance improvements by setting this to the proper value. To view all available values for this run `VBoxManage list ostypes`. Setting the correct value hints to VirtualBox how to optimize the virtual hardware to work best with that operating system. - `hard_drive_interface` (string) - The type of controller that the primary - hard drive is attached to, defaults to "ide". When set to "sata", the drive - is attached to an AHCI SATA controller. When set to "scsi", the drive is + hard drive is attached to, defaults to `ide`. When set to `sata`, the drive + is attached to an AHCI SATA controller. When set to `scsi`, the drive is attached to an LsiLogic SCSI controller. - `sata_port_count` (number) - The number of ports available on any SATA - controller created, defaults to 1. VirtualBox supports up to 30 ports on a + controller created, defaults to `1`. VirtualBox supports up to 30 ports on a maximum of 1 SATA controller. Increasing this value can be useful if you want to attach additional drives. - `hard_drive_nonrotational` (boolean) - Forces some guests (i.e. Windows 7+) to treat disks as SSDs and stops them from performing disk fragmentation. - Also set `hard_drive_Discard` to `true` to enable TRIM support. + Also set `hard_drive_discard` to `true` to enable TRIM support. - `hard_drive_discard` (boolean) - When this value is set to `true`, a VDI image will be shrunk in response to the trim command from the guest OS. @@ -211,29 +211,30 @@ builder. - `headless` (boolean) - Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console of the machine - being built. When this value is set to `true`, the machine will start without - a console. + being built. When this value is set to `true`, the machine will start + without a console. - `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting - kickstart files and so on. By default this is "", which means no HTTP server - will be started. The address and port of the HTTP server will be available - as variables in `boot_command`. This is covered in more detail below. + kickstart files and so on. By default this is an empty string, which means + no HTTP server will be started. The address and port of the HTTP server will + be available as variables in `boot_command`. This is covered in more detail + below. - `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP server to be on one port, make this minimum and maximum - port the same. By default the values are 8000 and 9000, respectively. + port the same. By default the values are `8000` and `9000`, respectively. - `iso_interface` (string) - The type of controller that the ISO is attached - to, defaults to "ide". When set to "sata", the drive is attached to an AHCI + to, defaults to `ide`. When set to `sata`, the drive is attached to an AHCI SATA controller. - `iso_target_extension` (string) - The extension of the iso file after - download. This defaults to "iso". + download. This defaults to `iso`. - `iso_target_path` (string) - The path where the iso should be saved after download. By default will go in the packer cache, with a hash of the @@ -252,13 +253,13 @@ builder. resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` is executed. This directory must not exist or be empty prior to running - the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the + the builder. By default this is `output-BUILDNAME` where "BUILDNAME" is the name of the build. - `post_shutdown_delay` (string) - The amount of time to wait after shutting down the virtual machine. If you get the error `Error removing floppy controller`, you might need to set this to `5m` - or so. By default, the delay is `0s`, or disabled. + or so. By default, the delay is `0s` or disabled. - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty @@ -271,7 +272,7 @@ builder. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it doesn't shut down in this time, it is an error. By default, the timeout is - `5m`, or five minutes. + `5m` or five minutes. - `skip_export` (boolean) - Defaults to `false`. When enabled, Packer will not export the VM. Useful if the build output is not the resultant image, @@ -281,11 +282,11 @@ builder. maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to use as the - host port. By default this is 2222 to 4444. + host port. By default this is `2222` to `4444`. - `ssh_skip_nat_mapping` (boolean) - Defaults to `false`. When enabled, Packer does not setup forwarded port mapping for SSH requests and uses `ssh_port` - on the host to communicate to the virtual machine + on the host to communicate to the virtual machine. - `vboxmanage` (array of array of strings) - Custom `VBoxManage` commands to execute in order to further customize the virtual machine being created. The @@ -305,22 +306,22 @@ builder. - `virtualbox_version_file` (string) - The path within the virtual machine to upload a file that contains the VirtualBox version that was used to create the machine. This information can be useful for provisioning. By default - this is ".vbox\_version", which will generally be upload it into the + this is `.vbox_version`, which will generally be upload it into the home directory. Set to an empty string to skip uploading this file, which can be useful when using the `none` communicator. - `vm_name` (string) - This is the name of the OVF file for the new virtual - machine, without the file extension. By default this is "packer-BUILDNAME", + machine, without the file extension. By default this is `packer-BUILDNAME`, where "BUILDNAME" is the name of the build. - `vrdp_bind_address` (string / IP address) - The IP address that should be - binded to for VRDP. By default packer will use 127.0.0.1 for this. If you - wish to bind to all interfaces use 0.0.0.0 + binded to for VRDP. By default packer will use `127.0.0.1` for this. If you + wish to bind to all interfaces use `0.0.0.0`. - `vrdp_port_min` and `vrdp_port_max` (number) - The minimum and maximum port to use for VRDP access to the virtual machine. Packer uses a randomly chosen - port in this range that appears available. By default this is 5900 to 6000. - The minimum and maximum ports are inclusive. + port in this range that appears available. By default this is `5900` to + `6000`. The minimum and maximum ports are inclusive. ## Boot Command diff --git a/website/source/docs/builders/virtualbox-ovf.html.md.erb b/website/source/docs/builders/virtualbox-ovf.html.md.erb index a1f0015d8..89edcd89f 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.md.erb +++ b/website/source/docs/builders/virtualbox-ovf.html.md.erb @@ -78,15 +78,15 @@ builder. - `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be - a duration. Examples are "5s" and "1m30s" which will cause Packer to wait + a duration. Examples are `5s` and `1m30s` which will cause Packer to wait five seconds and one minute 30 seconds, respectively. If this isn't - specified, the default is 10 seconds. + specified, the default is `10s` or 10 seconds. - `checksum` (string) - The checksum for the OVA file. The type of the checksum is specified with `checksum_type`, documented below. - `checksum_type` (string) - The type of the checksum specified in `checksum`. - Valid values are "none", "md5", "sha1", "sha256", or "sha512". Although the + Valid values are `none`, `md5`, `sha1`, `sha256`, or `sha512`. Although the checksum will not be verified when `checksum_type` is set to "none", this is not recommended since OVA files can be very large and corruption does happen from time to time. @@ -133,6 +133,12 @@ builder. "packer_conf.json" ``` +- `floppy_dirs` (array of strings) - A list of directories to place onto the + floppy disk recursively. This is similar to the `floppy_files` option except + that the directory structure is preserved. This is useful for when your + floppy disk includes drivers or if you just want to organize it's contents + as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. + - `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for unattended Windows installs, which look for an `Autounattend.xml` file on @@ -143,26 +149,20 @@ builder. and \[\]) are allowed. Directory names are also allowed, which will add all the files found in the directory to the floppy. -- `floppy_dirs` (array of strings) - A list of directories to place onto the - floppy disk recursively. This is similar to the `floppy_files` option except - that the directory structure is preserved. This is useful for when your - floppy disk includes drivers or if you just want to organize it's contents - as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. - -- `format` (string) - Either "ovf" or "ova", this specifies the output format - of the exported virtual machine. This defaults to "ovf". +- `format` (string) - Either `ovf` or `ova`, this specifies the output format + of the exported virtual machine. This defaults to `ovf`. - `guest_additions_mode` (string) - The method by which guest additions are - made available to the guest for installation. Valid options are "upload", - "attach", or "disable". If the mode is "attach" the guest additions ISO will - be attached as a CD device to the virtual machine. If the mode is "upload" + made available to the guest for installation. Valid options are `upload`, + `attach`, or `disable`. If the mode is `attach` the guest additions ISO will + be attached as a CD device to the virtual machine. If the mode is `upload` the guest additions ISO will be uploaded to the path specified by - `guest_additions_path`. The default value is "upload". If "disable" is used, + `guest_additions_path`. The default value is `upload`. If `disable` is used, guest additions won't be downloaded, either. - `guest_additions_path` (string) - The path on the guest virtual machine where the VirtualBox guest additions ISO will be uploaded. By default this - is "VBoxGuestAdditions.iso" which should upload into the login directory of + is `VBoxGuestAdditions.iso` which should upload into the login directory of the user. This is a [configuration template](/docs/templates/engine.html) where the `Version` variable is replaced with the VirtualBox version. @@ -179,30 +179,31 @@ builder. - `headless` (boolean) - Packer defaults to building VirtualBox virtual machines by launching a GUI that shows the console of the machine - being built. When this value is set to true, the machine will start without - a console. + being built. When this value is set to `true`, the machine will start + without a console. - `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting - kickstart files and so on. By default this is "", which means no HTTP server - will be started. The address and port of the HTTP server will be available - as variables in `boot_command`. This is covered in more detail below. + kickstart files and so on. By default this is an empty string, which means + no HTTP server will be started. The address and port of the HTTP server will + be available as variables in `boot_command`. This is covered in more detail + below. - `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP server to be on one port, make this minimum and maximum - port the same. By default the values are 8000 and 9000, respectively. + port the same. By default the values are `8000` and `9000`, respectively. - `import_flags` (array of strings) - Additional flags to pass to `VBoxManage import`. This can be used to add additional command-line flags such as `--eula-accept` to accept a EULA in the OVF. - `import_opts` (string) - Additional options to pass to the - `VBoxManage import`. This can be useful for passing "keepallmacs" or - "keepnatmacs" options for existing ovf images. + `VBoxManage import`. This can be useful for passing `keepallmacs` or + `keepnatmacs` options for existing ovf images. - `keep_registered` (boolean) - Set this to `true` if you would like to keep the VM registered with virtualbox. Defaults to `false`. @@ -211,13 +212,13 @@ builder. resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` is executed. This directory must not exist or be empty prior to running - the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the + the builder. By default this is `output-BUILDNAME` where "BUILDNAME" is the name of the build. - `post_shutdown_delay` (string) - The amount of time to wait after shutting down the virtual machine. If you get the error `Error removing floppy controller`, you might need to set this to `5m` - or so. By default, the delay is `0s`, or disabled. + or so. By default, the delay is `0s` or disabled. - `shutdown_command` (string) - The command to use to gracefully shut down the machine once all the provisioning is done. By default this is an empty @@ -230,7 +231,7 @@ builder. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it doesn't shut down in this time, it is an error. By default, the timeout is - "5m", or five minutes. + `5m` or five minutes. - `skip_export` (boolean) - Defaults to `false`. When enabled, Packer will not export the VM. Useful if the build output is not the resultant image, @@ -240,11 +241,11 @@ builder. maximum port to use for the SSH port on the host machine which is forwarded to the SSH port on the guest machine. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to use as the - host port. + host port. By default this is `2222` to `4444`. - `ssh_skip_nat_mapping` (boolean) - Defaults to false. When enabled, Packer does not setup forwarded port mapping for SSH requests and uses `ssh_port` - on the host to communicate to the virtual machine + on the host to communicate to the virtual machine. - `target_path` (string) - The path where the OVA should be saved after download. By default, it will go in the packer cache, with a hash of @@ -268,22 +269,23 @@ builder. - `virtualbox_version_file` (string) - The path within the virtual machine to upload a file that contains the VirtualBox version that was used to create the machine. This information can be useful for provisioning. By default - this is ".vbox\_version", which will generally be upload it into the + this is `.vbox_version`, which will generally be upload it into the home directory. Set to an empty string to skip uploading this file, which can be useful when using the `none` communicator. - `vm_name` (string) - This is the name of the virtual machine when it is imported as well as the name of the OVF file when the virtual machine - is exported. By default this is "packer-BUILDNAME", where "BUILDNAME" is the + is exported. By default this is `packer-BUILDNAME`, where "BUILDNAME" is the name of the build. - `vrdp_bind_address` (string / IP address) - The IP address that should be - binded to for VRDP. By default packer will use 127.0.0.1 for this. + binded to for VRDP. By default packer will use `127.0.0.1` for this. If you + wish to bind to all interfaces use `0.0.0.0`. - `vrdp_port_min` and `vrdp_port_max` (number) - The minimum and maximum port to use for VRDP access to the virtual machine. Packer uses a randomly chosen - port in this range that appears available. By default this is 5900 to 6000. - The minimum and maximum ports are inclusive. + port in this range that appears available. By default this is `5900` to + `6000`. The minimum and maximum ports are inclusive. ## Boot Command diff --git a/website/source/docs/builders/vmware-iso.html.md.erb b/website/source/docs/builders/vmware-iso.html.md.erb index 8155cedbe..21d19c183 100644 --- a/website/source/docs/builders/vmware-iso.html.md.erb +++ b/website/source/docs/builders/vmware-iso.html.md.erb @@ -69,8 +69,8 @@ builder. over `iso_checksum_url` type. - `iso_checksum_type` (string) - The type of the checksum specified in - `iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or - "sha512" currently. While "none" will skip checksumming, this is not + `iso_checksum`. Valid values are `none`, `md5`, `sha1`, `sha256`, or + `sha512` currently. While `none` will skip checksumming, this is not recommended since ISO files are generally large and corruption does happen from time to time. @@ -94,9 +94,29 @@ builder. - `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be - a duration. Examples are "5s" and "1m30s" which will cause Packer to wait + a duration. Examples are `5s` and `1m30s` which will cause Packer to wait five seconds and one minute 30 seconds, respectively. If this isn't - specified, the default is 10 seconds. + specified, the default is `10s` or 10 seconds. + +- `cdrom_adapter_type` (string) - The adapter type (or bus) that will be used + by the cdrom device. This is chosen by default based on the disk adapter + type. VMware tends to lean towards `ide` for the cdrom device unless + `sata` is chosen for the disk adapter and so Packer attempts to mirror + this logic. This field can be specified as either `ide`, `sata`, or `scsi`. + +- `disable_vnc` (boolean) - Whether to create a VNC connection or not. + A `boot_command` cannot be used when this is `false`. Defaults to `false`. + +- `disk_adapter_type` (string) - The adapter type of the VMware virtual disk + to create. This option is for advanced usage, modify only if you know what + you're doing. Some of the options you can specify are `ide`, `sata`, `nvme` + or `scsi` (which uses the "lsilogic" scsi interface by default). If you + specify another option, Packer will assume that you're specifying a `scsi` + interface of that specified type. For more information, please consult the + <a href="http://www.vmware.com/pdf/VirtualDiskManager.pdf" target="_blank" + rel="nofollow noopener noreferrer"> + Virtual Disk Manager User's Guide</a> for desktop VMware clients. + For ESXi, refer to the proper ESXi documentation. - `disk_additional_size` (array of integers) - The size(s) of any additional hard disks for the VM in megabytes. If this is not specified then the VM @@ -107,7 +127,7 @@ builder. - `disk_size` (number) - The size of the hard disk for the VM in megabytes. The builder uses expandable, not fixed-size virtual hard disks, so the actual file representing the disk will not use the full size unless it - is full. By default this is set to 40,000 (about 40 GB). + is full. By default this is set to `40000` (about 40 GB). - `disk_type_id` (string) - The type of VMware virtual disk to create. This option is for advanced usage. @@ -123,9 +143,9 @@ builder. `4` | Preallocated virtual disk compatible with ESX server (VMFS flat). `5` | Compressed disk optimized for streaming. - The default is "1". + The default is `1`. - For ESXi, this defaults to "zeroedthick". The available options for ESXi + For ESXi, this defaults to `zeroedthick`. The available options for ESXi are: `zeroedthick`, `eagerzeroedthick`, `thin`, `rdm:dev`, `rdmp:dev`, `2gbsparse`. @@ -133,25 +153,11 @@ builder. Guide](https://www.vmware.com/pdf/VirtualDiskManager.pdf) for desktop VMware clients. For ESXi, refer to the proper ESXi documentation. -- `disk_adapter_type` (string) - The adapter type of the VMware virtual disk - to create. This option is for advanced usage, modify only if you know what - you're doing. Some of the options you can specify are "ide", "sata", "nvme" - or "scsi" (which uses the "lsilogic" scsi interface by default). If you - specify another option, Packer will assume that you're specifying a "scsi" - interface of that specified type. For more information, please consult the - <a href="http://www.vmware.com/pdf/VirtualDiskManager.pdf" target="_blank" - rel="nofollow noopener noreferrer"> - Virtual Disk Manager User's Guide</a> for desktop VMware clients. - For ESXi, refer to the proper ESXi documentation. - -- `cdrom_adapter_type` (string) - The adapter type (or bus) that will be used - by the cdrom device. This is chosen by default based on the disk adapter - type. VMware tends to lean towards "ide" for the cdrom device unless - "sata" is chosen for the disk adapter and so Packer attempts to mirror - this logic. This field can be specified as either "ide", "sata", or "scsi". - -- `disable_vnc` (boolean) - Whether to create a VNC connection or not. - A `boot_command` cannot be used when this is `false`. Defaults to `false`. +- `floppy_dirs` (array of strings) - A list of directories to place onto + the floppy disk recursively. This is similar to the `floppy_files` option + except that the directory structure is preserved. This is useful for when + your floppy disk includes drivers or if you just want to organize it's + contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. - `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for @@ -163,44 +169,39 @@ builder. and \[\]) are allowed. Directory names are also allowed, which will add all the files found in the directory to the floppy. -- `floppy_dirs` (array of strings) - A list of directories to place onto - the floppy disk recursively. This is similar to the `floppy_files` option - except that the directory structure is preserved. This is useful for when - your floppy disk includes drivers or if you just want to organize it's - contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. - - `fusion_app_path` (string) - Path to "VMware Fusion.app". By default this is - "/Applications/VMware Fusion.app" but this setting allows you to + `/Applications/VMware Fusion.app` but this setting allows you to customize this. - `guest_os_type` (string) - The guest OS type being installed. This will be - set in the VMware VMX. By default this is "other". By specifying a more + set in the VMware VMX. By default this is `other`. By specifying a more specific OS type, VMware may perform some optimizations or virtual hardware changes to better support the operating system running in the virtual machine. - `headless` (boolean) - Packer defaults to building VMware virtual machines by launching a GUI that shows the console of the machine being built. When - this value is set to true, the machine will start without a console. For + this value is set to `true`, the machine will start without a console. For VMware machines, Packer will output VNC connection information in case you need to connect to the console to debug the build process. - `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting - kickstart files and so on. By default this is "", which means no HTTP server - will be started. The address and port of the HTTP server will be available - as variables in `boot_command`. This is covered in more detail below. + kickstart files and so on. By default this is an empty string, which means + no HTTP server will be started. The address and port of the HTTP server will + be available as variables in `boot_command`. This is covered in more detail + below. - `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP server to be on one port, make this minimum and maximum - port the same. By default the values are 8000 and 9000, respectively. + port the same. By default the values are `8000` and `9000`, respectively. - `iso_target_extension` (string) - The extension of the iso file after - download. This defaults to "iso". + download. This defaults to `iso`. - `iso_target_path` (string) - The path where the iso should be saved after download. By default will go in the packer cache, with a hash of the @@ -214,11 +215,11 @@ builder. - `network` (string) - This is the network type that the virtual machine will be created with. This can be one of the generic values that map to a device - such as "hostonly", "nat", or "bridged". If the network is not one of these + such as `hostonly`, `nat`, or `bridged`. If the network is not one of these values, then it is assumed to be a VMware network device. (VMnet0..x) - `network_adapter_type` (string) - This is the ethernet adapter type the the - virtual machine will be created with. By default the "e1000" network adapter + virtual machine will be created with. By default the `e1000` network adapter type will be used by Packer. For more information, please consult the <a href="https://kb.vmware.com/s/article/1001805" target="_blank" rel="nofollow noopener noreferrer"> @@ -229,12 +230,12 @@ builder. resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` is executed. This directory must not exist or be empty prior to running - the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the + the builder. By default this is `output-BUILDNAME` where "BUILDNAME" is the name of the build. - `parallel` (string) - This specifies a parallel port to add to the VM. It has the format of `Type:option1,option2,...`. Type can be one of the - following values: "FILE", "DEVICE", "AUTO", or "NONE". + following values: `FILE`, `DEVICE`, `AUTO`, or `NONE`. * `FILE:path` - Specifies the path to the local file to be used for the parallel port. @@ -254,12 +255,12 @@ builder. - `remote_cache_directory` (string) - The path where the ISO and/or floppy files will be stored during the build on the remote machine. The path is relative to the `remote_cache_datastore` on the remote machine. By default - this is "packer\_cache". This only has an effect if `remote_type` + this is `packer_cache`. This only has an effect if `remote_type` is enabled. - `remote_datastore` (string) - The path to the datastore where the resulting VM will be stored when it is built on the remote machine. By default this - is "datastore1". This only has an effect if `remote_type` is enabled. + is `datastore1`. This only has an effect if `remote_type` is enabled. - `remote_host` (string) - The host of the remote machine used for access. This is only required if `remote_type` is enabled. @@ -274,7 +275,7 @@ builder. - `remote_type` (string) - The type of remote machine that will be used to build this VM rather than a local desktop product. The only value accepted - for this currently is "esx5". If this is not set, a desktop product will + for this currently is `esx5`. If this is not set, a desktop product will be used. By default, this is not set. - `remote_username` (string) - The username for the SSH user that will access @@ -322,7 +323,7 @@ builder. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it doesn't shut down in this time, it is an error. By default, the timeout is - "5m", or five minutes. + `5m` or five minutes. - `skip_compaction` (boolean) - VMware-created disks are defragmented and compacted at the end of the build process using `vmware-vdiskmanager`. In @@ -348,7 +349,7 @@ builder. - `sound` (boolean) - Enable VMware's virtual soundcard device for the VM. - `tools_upload_flavor` (string) - The flavor of the VMware Tools ISO to - upload into the VM. Valid values are "darwin", "linux", and "windows". By + upload into the VM. Valid values are `darwin`, `linux`, and `windows`. By default, this is empty, which means VMware tools won't be uploaded. - `tools_upload_path` (string) - The path in the VM to upload the @@ -357,23 +358,23 @@ builder. template](/docs/templates/engine.html) that has a single valid variable: `Flavor`, which will be the value of `tools_upload_flavor`. By default the upload path is set to `{{.Flavor}}.iso`. This setting is not - used when `remote_type` is "esx5". + used when `remote_type` is `esx5`. - `usb` (boolean) - Enable VMware's USB bus for the guest VM. To enable usage of the XHCI bus for USB 3 (5 Gbit/s), one can use the `vmx_data` option to - enable it by specifying "true" for the `usb_xhci.present` property. + enable it by specifying `true` for the `usb_xhci.present` property. - `version` (string) - The [vmx hardware version](http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1003746) for the new virtual machine. Only the default value has been tested, any - other value is experimental. Default value is '9'. + other value is experimental. Default value is `9`. - `vm_name` (string) - This is the name of the VMX file for the new virtual - machine, without the file extension. By default this is "packer-BUILDNAME", + machine, without the file extension. By default this is `packer-BUILDNAME`, where "BUILDNAME" is the name of the build. - `vmdk_name` (string) - The filename of the virtual disk that'll be created, - without the extension. This defaults to "packer". + without the extension. This defaults to `packer`. - `vmx_data` (object of key/value strings) - Arbitrary key/values to enter into the virtual machine VMX file. This is for advanced users who want to @@ -383,10 +384,11 @@ builder. except that it is run after the virtual machine is shutdown, and before the virtual machine is exported. -- `vmx_remove_ethernet_interfaces` (boolean) - Remove all ethernet interfaces from - the VMX file after building. This is for advanced users who understand the - ramifications, but is useful for building Vagrant boxes since Vagrant will - create ethernet interfaces when provisioning a box. +- `vmx_remove_ethernet_interfaces` (boolean) - Remove all ethernet interfaces + from the VMX file after building. This is for advanced users who understand + the ramifications, but is useful for building Vagrant boxes since Vagrant + will create ethernet interfaces when provisioning a box. Defaults to + `false`. - `vmx_template_path` (string) - Path to a [configuration template](/docs/templates/engine.html) that defines the @@ -395,18 +397,19 @@ builder. below for more information. For basic VMX modifications, try `vmx_data` first. -- `vnc_bind_address` (string / IP address) - The IP address that should be binded - to for VNC. By default packer will use 127.0.0.1 for this. If you wish to bind - to all interfaces use 0.0.0.0 +- `vnc_bind_address` (string / IP address) - The IP address that should be + binded to for VNC. By default packer will use `127.0.0.1` for this. If you + wish to bind to all interfaces use `0.0.0.0`. -- `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that is - used to secure the VNC communication with the VM. +- `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that + is used to secure the VNC communication with the VM. - `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type the initial `boot_command`. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By - default this is 5900 to 6000. The minimum and maximum ports are inclusive. + default this is `5900` to `6000`. The minimum and maximum ports are + inclusive. ## Boot Command diff --git a/website/source/docs/builders/vmware-vmx.html.md.erb b/website/source/docs/builders/vmware-vmx.html.md.erb index bd4a84312..90880cb54 100644 --- a/website/source/docs/builders/vmware-vmx.html.md.erb +++ b/website/source/docs/builders/vmware-vmx.html.md.erb @@ -69,13 +69,19 @@ builder. - `boot_wait` (string) - The time to wait after booting the initial virtual machine before typing the `boot_command`. The value of this should be - a duration. Examples are "5s" and "1m30s" which will cause Packer to wait + a duration. Examples are `5s` and `1m30s` which will cause Packer to wait five seconds and one minute 30 seconds, respectively. If this isn't - specified, the default is 10 seconds. + specified, the default is `10s` or 10 seconds. * `disable_vnc` (boolean) - Whether to create a VNC connection or not. A `boot_command` cannot be used when this is `false`. Defaults to `false`. +- `floppy_dirs` (array of strings) - A list of directories to place onto + the floppy disk recursively. This is similar to the `floppy_files` option + except that the directory structure is preserved. This is useful for when + your floppy disk includes drivers or if you just want to organize it's + contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. + - `floppy_files` (array of strings) - A list of files to place onto a floppy disk that is attached when the VM is booted. This is most useful for unattended Windows installs, which look for an `Autounattend.xml` file on @@ -86,41 +92,36 @@ builder. and \[\]) are allowed. Directory names are also allowed, which will add all the files found in the directory to the floppy. -- `floppy_dirs` (array of strings) - A list of directories to place onto - the floppy disk recursively. This is similar to the `floppy_files` option - except that the directory structure is preserved. This is useful for when - your floppy disk includes drivers or if you just want to organize it's - contents as a hierarchy. Wildcard characters (\*, ?, and \[\]) are allowed. - - `fusion_app_path` (string) - Path to "VMware Fusion.app". By default this is - "/Applications/VMware Fusion.app" but this setting allows you to + `/Applications/VMware Fusion.app` but this setting allows you to customize this. - `headless` (boolean) - Packer defaults to building VMware virtual machines by launching a GUI that shows the console of the machine being built. When - this value is set to true, the machine will start without a console. For + this value is set to `true`, the machine will start without a console. For VMware machines, Packer will output VNC connection information in case you need to connect to the console to debug the build process. - `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP that will be requestable from the virtual machine. This is useful for hosting - kickstart files and so on. By default this is "", which means no HTTP server - will be started. The address and port of the HTTP server will be available - as variables in `boot_command`. This is covered in more detail below. + kickstart files and so on. By default this is an empty string, which means + no HTTP server will be started. The address and port of the HTTP server will + be available as variables in `boot_command`. This is covered in more detail + below. - `http_port_min` and `http_port_max` (number) - These are the minimum and maximum port to use for the HTTP server started to serve the `http_directory`. Because Packer often runs in parallel, Packer will choose a randomly available port in this range to run the HTTP server. If you want to force the HTTP server to be on one port, make this minimum and maximum - port the same. By default the values are 8000 and 9000, respectively. + port the same. By default the values are `8000` and `9000`, respectively. - `output_directory` (string) - This is the path to the directory where the resulting virtual machine will be created. This may be relative or absolute. If relative, the path is relative to the working directory when `packer` is executed. This directory must not exist or be empty prior to running - the builder. By default this is "output-BUILDNAME" where "BUILDNAME" is the + the builder. By default this is `output-BUILDNAME` where "BUILDNAME" is the name of the build. - `shutdown_command` (string) - The command to use to gracefully shut down the @@ -134,16 +135,16 @@ builder. - `shutdown_timeout` (string) - The amount of time to wait after executing the `shutdown_command` for the virtual machine to actually shut down. If it doesn't shut down in this time, it is an error. By default, the timeout is - "5m", or five minutes. + `5m` or five minutes. - `skip_compaction` (boolean) - VMware-created disks are defragmented and compacted at the end of the build process using `vmware-vdiskmanager`. In certain rare cases, this might actually end up making the resulting disks slightly larger. If you find this to be the case, you can disable compaction - using this configuration value. + using this configuration value. Defaults to `false`. - `tools_upload_flavor` (string) - The flavor of the VMware Tools ISO to - upload into the VM. Valid values are "darwin", "linux", and "windows". By + upload into the VM. Valid values are `darwin`, `linux`, and `windows`. By default, this is empty, which means VMware tools won't be uploaded. - `tools_upload_path` (string) - The path in the VM to upload the @@ -154,7 +155,7 @@ builder. By default the upload path is set to `{{.Flavor}}.iso`. - `vm_name` (string) - This is the name of the VMX file for the new virtual - machine, without the file extension. By default this is "packer-BUILDNAME", + machine, without the file extension. By default this is `packer-BUILDNAME`, where "BUILDNAME" is the name of the build. - `vmx_data` (object of key/value strings) - Arbitrary key/values to enter @@ -165,22 +166,25 @@ builder. except that it is run after the virtual machine is shutdown, and before the virtual machine is exported. -- `vmx_remove_ethernet_interfaces` (boolean) - Remove all ethernet interfaces from - the VMX file after building. This is for advanced users who understand the - ramifications, but is useful for building Vagrant boxes since Vagrant will - create ethernet interfaces when provisioning a box. +- `vmx_remove_ethernet_interfaces` (boolean) - Remove all ethernet interfaces + from the VMX file after building. This is for advanced users who understand + the ramifications, but is useful for building Vagrant boxes since Vagrant + will create ethernet interfaces when provisioning a box. Defaults to + `false`. -- `vnc_bind_address` (string / IP address) - The IP address that should be binded - to for VNC. By default packer will use 127.0.0.1 for this. +- `vnc_bind_address` (string / IP address) - The IP address that should be + binded to for VNC. By default packer will use `127.0.0.1` for this. If you + wish to bind to all interfaces use `0.0.0.0`. -- `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that is - used to secure the VNC communication with the VM. +- `vnc_disable_password` (boolean) - Don't auto-generate a VNC password that + is used to secure the VNC communication with the VM. - `vnc_port_min` and `vnc_port_max` (number) - The minimum and maximum port to use for VNC access to the virtual machine. The builder uses VNC to type the initial `boot_command`. Because Packer generally runs in parallel, Packer uses a randomly chosen port in this range that appears available. By - default this is 5900 to 6000. The minimum and maximum ports are inclusive. + default this is `5900` to `6000`. The minimum and maximum ports are + inclusive. ## Boot Command diff --git a/website/source/docs/templates/communicator.html.md b/website/source/docs/templates/communicator.html.md index 0165ab5a1..352d370e8 100644 --- a/website/source/docs/templates/communicator.html.md +++ b/website/source/docs/templates/communicator.html.md @@ -59,11 +59,11 @@ to the remote host. The SSH communicator has the following options: -- `ssh_agent_auth` (boolean) - If true, the local SSH agent will be used to - authenticate connections to the remote host. Defaults to false. +- `ssh_agent_auth` (boolean) - If `true`, the local SSH agent will be used to + authenticate connections to the remote host. Defaults to `false`. -- `ssh_bastion_agent_auth` (boolean) - If true, the local SSH agent will - be used to authenticate with the bastion host. Defaults to false. +- `ssh_bastion_agent_auth` (boolean) - If `true`, the local SSH agent will + be used to authenticate with the bastion host. Defaults to `false`. - `ssh_bastion_host` (string) - A bastion host to use for the actual SSH connection. @@ -71,7 +71,7 @@ The SSH communicator has the following options: - `ssh_bastion_password` (string) - The password to use to authenticate with the bastion host. -- `ssh_bastion_port` (number) - The port of the bastion host. Defaults to 1. +- `ssh_bastion_port` (number) - The port of the bastion host. Defaults to `1`. - `ssh_bastion_private_key_file` (string) - A private key file to use to authenticate with the bastion host. @@ -80,51 +80,52 @@ The SSH communicator has the following options: host. - `ssh_disable_agent_forwarding` (boolean) - If true, SSH agent forwarding - will be disabled. Defaults to false. + will be disabled. Defaults to `false`. - `ssh_file_transfer_method` (`scp` or `sftp`) - How to transfer files, Secure copy (default) or SSH File Transfer Protocol. - `ssh_handshake_attempts` (number) - The number of handshakes to attempt - with SSH once it can connect. This defaults to 10. + with SSH once it can connect. This defaults to `10`. - `ssh_host` (string) - The address to SSH to. This usually is automatically configured by the builder. * `ssh_keep_alive_interval` (string) - How often to send "keep alive" - messages to the server. Set to a negative value (`-1s`) to disable. Example value: - "10s". Defaults to "5s". + messages to the server. Set to a negative value (`-1s`) to disable. Example + value: `10s`. Defaults to `5s`. - `ssh_password` (string) - A plaintext password to use to authenticate with SSH. -- `ssh_port` (number) - The port to connect to SSH. This defaults to 22. +- `ssh_port` (number) - The port to connect to SSH. This defaults to `22`. - `ssh_private_key_file` (string) - Path to a PEM encoded private key file to use to authenticate with SSH. -- `ssh_pty` (boolean) - If true, a PTY will be requested for the SSH - connection. This defaults to false. - -* `ssh_read_write_timeout` (string) - The amount of time to wait for a remote - command to end. This might be useful if, for example, packer hangs on - a connection after a reboot. Example: "5m". Disabled by default. - -- `ssh_timeout` (string) - The time to wait for SSH to become available. - Packer uses this to determine when the machine has booted so this is - usually quite long. Example value: "10m" - -- `ssh_username` (string) - The username to connect to SSH with. Required - if using SSH. - `ssh_proxy_host` (string) - A SOCKS proxy host to use for SSH connection -- `ssh_proxy_port` (Integer) - A port of the SOCKS proxy, defaults to 1080 +- `ssh_proxy_password` (string) - The password to use to authenticate with + the proxy server. Optional. + +- `ssh_proxy_port` (number) - A port of the SOCKS proxy. Defaults to `1080`. - `ssh_proxy_username` (string) - The username to authenticate with the proxy server. Optional. -- `ssh_proxy_password` (string) - The password to use to authenticate with - the proxy server. Optional. +- `ssh_pty` (boolean) - If `true`, a PTY will be requested for the SSH + connection. This defaults to `false`. + +* `ssh_read_write_timeout` (string) - The amount of time to wait for a remote + command to end. This might be useful if, for example, packer hangs on + a connection after a reboot. Example: `5m`. Disabled by default. + +- `ssh_timeout` (string) - The time to wait for SSH to become available. + Packer uses this to determine when the machine has booted so this is + usually quite long. Example value: `10m`. + +- `ssh_username` (string) - The username to connect to SSH with. Required + if using SSH. ## WinRM Communicator @@ -132,23 +133,24 @@ The WinRM communicator has the following options. - `winrm_host` (string) - The address for WinRM to connect to. -- `winrm_port` (number) - The WinRM port to connect to. This defaults to - 5985 for plain unencrypted connection and 5986 for SSL when `winrm_use_ssl` is set to true. - -- `winrm_username` (string) - The username to use to connect to WinRM. +- `winrm_insecure` (boolean) - If `true`, do not check server certificate + chain and host name. - `winrm_password` (string) - The password to use to connect to WinRM. +- `winrm_port` (number) - The WinRM port to connect to. This defaults to + `5985` for plain unencrypted connection and `5986` for SSL when + `winrm_use_ssl` is set to true. + - `winrm_timeout` (string) - The amount of time to wait for WinRM to - become available. This defaults to "30m" since setting up a Windows + become available. This defaults to `30m` since setting up a Windows machine generally takes a long time. -- `winrm_use_ssl` (boolean) - If true, use HTTPS for WinRM - -- `winrm_insecure` (boolean) - If true, do not check server certificate - chain and host name - -- `winrm_use_ntlm` (boolean) - If true, NTLM authentication will be used for WinRM, +- `winrm_use_ntlm` (boolean) - If `true`, NTLM authentication will be used for WinRM, rather than default (basic authentication), removing the requirement for basic authentication to be enabled within the target guest. Further reading for remote connection authentication can be found [here](https://msdn.microsoft.com/en-us/library/aa384295(v=vs.85).aspx). + +- `winrm_use_ssl` (boolean) - If `true`, use HTTPS for WinRM. + +- `winrm_username` (string) - The username to use to connect to WinRM. From 7e31768a9b7885bc4c5d6fc89dbc15d747cdfb24 Mon Sep 17 00:00:00 2001 From: Rickard von Essen <rickard.von.essen@gmail.com> Date: Mon, 23 Apr 2018 09:04:24 +0200 Subject: [PATCH 0983/1007] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a8a5f4a4..b93652196 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * builder/amazon: Setting `force_delete` will only delete AMIs owned by the user. This should prevent failures where we try to delete an AMI with a matching name, but owned by someone else. [GH-6111] +* builder/openstack: Add configuration option for `instance_name`. [GH-6041] ## 1.2.2 (March 26, 2018) From a0fa374844013dc323e8cf2ec6a06fbce5eb8ebf Mon Sep 17 00:00:00 2001 From: Jeff Escalante <gh.je@mailhero.io> Date: Fri, 20 Apr 2018 14:15:48 -0400 Subject: [PATCH 0984/1007] bring back turbolinks and adjust scripts to match --- .../source/assets/javascripts/analytics.js | 4 ++- .../source/assets/javascripts/application.js | 1 + website/source/layouts/layout.erb | 29 +++++++------------ 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/website/source/assets/javascripts/analytics.js b/website/source/assets/javascripts/analytics.js index 0e7dff179..e6ad037bc 100644 --- a/website/source/assets/javascripts/analytics.js +++ b/website/source/assets/javascripts/analytics.js @@ -1,4 +1,6 @@ -document.addEventListener('DOMContentLoaded', function() { +document.addEventListener('turbolinks:load', function() { + analytics.page() + track('.downloads .download .details li a', function(el) { var m = el.href.match(/packer_(\d+\.\d+\.\d+)_(.*?)_(.*?)\.zip/) return { diff --git a/website/source/assets/javascripts/application.js b/website/source/assets/javascripts/application.js index 5d6f89378..ae70e571d 100644 --- a/website/source/assets/javascripts/application.js +++ b/website/source/assets/javascripts/application.js @@ -1,4 +1,5 @@ //= require jquery +//= require turbolinks //= require hashicorp/mega-nav //= require hashicorp/sidebar diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index 4db676070..90ab477e0 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -27,11 +27,18 @@ <title><%= title_for(current_page) %></title> + <!-- Stylesheets --> + <link rel="stylesheet" href="https://use.typekit.net/wxf7mfi.css"> <%= stylesheet_link_tag "application" %> - <!-- Typekit script to import Klavika font --> - <script src="https://use.typekit.net/wxf7mfi.js"></script> - <script>try{Typekit.load({ async: true });}catch(e){}</script> + <!-- Site scripts --> + <!--[if lt IE 9]><%= javascript_include_tag "ie-compat", defer: true %><![endif]--> + <%= javascript_include_tag "application", defer: true %> + + <!-- Analytics scrpts --> + <script defer> + !function(){var e=window.analytics=window.analytics||[];if(!e.initialize)if(e.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{e.invoked=!0,e.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"],e.factory=function(t){return function(){var a=Array.prototype.slice.call(arguments);return a.unshift(t),e.push(a),e}};for(var t=0;t<e.methods.length;t++){var a=e.methods[t];e[a]=e.factory(a)}e.load=function(e){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+e+"/analytics.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(t,a)},e.SNIPPET_VERSION="4.0.0",e.load("<%= segmentId %>")}}();var om597a24292a958,om597a24292a958_poll=function(){var e=0;return function(t,a){clearInterval(e),e=setInterval(t,a)}}();!function(e,t,a){if(e.getElementById(a))om597a24292a958_poll(function(){if(window.om_loaded&&!om597a24292a958)return(om597a24292a958=new OptinMonsterApp).init({s:"35109.597a24292a958",staging:0,dev:0,beta:0})},25);else{var n=!1,o=e.createElement("script");o.id=a,o.src="//a.optnmstr.com/app/js/api.min.js",o.async=!0,o.onload=o.onreadystatechange=function(){if(!(n||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState))try{n=om_loaded=!0,(om597a24292a958=new OptinMonsterApp).init({s:"35109.597a24292a958",staging:0,dev:0,beta:0}),o.onload=o.onreadystatechange=null}catch(e){}},(document.getElementsByTagName("head")[0]||document.documentElement).appendChild(o)}}(document,0,"omapi-script"); + </script> <%= yield_content :head %> </head> @@ -106,22 +113,6 @@ </div> </div> - <!--[if lt IE 9]> - <%= javascript_include_tag "ie-compat" %> - <![endif]--> - <%= javascript_include_tag "application" %> - - <script> - // analytics.js - !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0"; - analytics.load("<%= segmentId %>"); - analytics.page(); - }}(); - // optinmonster - var om597a24292a958,om597a24292a958_poll=function(){var b=0;return function(d,c){clearInterval(b);b=setInterval(d,c)}}(); - !function(b,d,c){if(b.getElementById(c))om597a24292a958_poll(function(){if(window.om_loaded&&!om597a24292a958)return om597a24292a958=new OptinMonsterApp,om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0})},25);else{var e=!1,a=b.createElement(d);a.id=c;a.src="//a.optnmstr.com/app/js/api.min.js";a.async=!0;a.onload=a.onreadystatechange=function(){if(!(e||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState))try{e=om_loaded=!0,om597a24292a958=new OptinMonsterApp, - om597a24292a958.init({s:"35109.597a24292a958",staging:0,dev:0,beta:0}),a.onload=a.onreadystatechange=null}catch(f){}};(document.getElementsByTagName("head")[0]||document.documentElement).appendChild(a)}}(document,"script","omapi-script"); - </script> <script type="application/ld+json"> { "@context": "http://schema.org", From cbdf9db832c8186240419fc9ea02d2f527a674b8 Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Mon, 23 Apr 2018 12:57:04 -0700 Subject: [PATCH 0985/1007] Use contexts with amazon waiters. --- builder/amazon/common/step_run_source_instance.go | 4 ++-- builder/amazon/common/step_run_spot_instance.go | 4 ++-- builder/amazon/common/step_stop_ebs_instance.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 8542e9387..114da38e1 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -39,7 +39,7 @@ type StepRunSourceInstance struct { instanceId string } -func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) var keyName string if name, ok := state.GetOk("keyPair"); ok { @@ -185,7 +185,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - if err := ec2conn.WaitUntilInstanceRunning(describeInstance); err != nil { + if err := ec2conn.WaitUntilInstanceRunningWithContext(ctx, describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index d90dd391a..8c7cbf74a 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -43,7 +43,7 @@ type StepRunSpotInstance struct { spotRequest *ec2.SpotInstanceRequest } -func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) var keyName string if name, ok := state.GetOk("keyPair"); ok { @@ -235,7 +235,7 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m describeInstance := &ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } - if err := ec2conn.WaitUntilInstanceRunning(describeInstance); err != nil { + if err := ec2conn.WaitUntilInstanceRunningWithContext(ctx, describeInstance); err != nil { err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err) state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/common/step_stop_ebs_instance.go b/builder/amazon/common/step_stop_ebs_instance.go index 10a2f5a45..184430b91 100644 --- a/builder/amazon/common/step_stop_ebs_instance.go +++ b/builder/amazon/common/step_stop_ebs_instance.go @@ -16,7 +16,7 @@ type StepStopEBSBackedInstance struct { DisableStopInstance bool } -func (s *StepStopEBSBackedInstance) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepStopEBSBackedInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) ui := state.Get("ui").(packer.Ui) @@ -78,7 +78,7 @@ func (s *StepStopEBSBackedInstance) Run(_ context.Context, state multistep.State // Wait for the instance to actually stop ui.Say("Waiting for the instance to stop...") - err = ec2conn.WaitUntilInstanceStopped(&ec2.DescribeInstancesInput{ + err = ec2conn.WaitUntilInstanceStoppedWithContext(ctx, &ec2.DescribeInstancesInput{ InstanceIds: []*string{instance.InstanceId}, }) From 6f727cd85daf2d55f1c5d55839deeab8aec31fb2 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Mon, 23 Apr 2018 14:52:00 -0700 Subject: [PATCH 0986/1007] clarify how to change google compute's firewall setting --- website/source/docs/builders/googlecompute.html.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/googlecompute.html.md b/website/source/docs/builders/googlecompute.html.md index c54ca367c..005258f12 100644 --- a/website/source/docs/builders/googlecompute.html.md +++ b/website/source/docs/builders/googlecompute.html.md @@ -120,8 +120,12 @@ is assumed to be the path to the file containing the JSON. ### Windows Example -Running WinRM requires that it is opened in the firewall and that the VM enables WinRM for the -user used to connect in a startup-script. +Before you can provision using the winrm communicator, you need to navigate to +https://console.cloud.google.com/networking/firewalls/list to allow traffic +through google's firewall on the winrm port (tcp:5986). + +Once this is set up, the following is a complete working packer config after +setting a valid `account_file` and `project_id`: ``` {.json} { From a3bf2c786a063f39dc827f8ef6ada874197b137e Mon Sep 17 00:00:00 2001 From: Matthew Hooker <mwhooker@gmail.com> Date: Sun, 22 Apr 2018 19:26:42 -0700 Subject: [PATCH 0987/1007] Use expression sequence generator in tests. --- common/bootcommand/boot_command_ast_test.go | 32 +++++++-------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/common/bootcommand/boot_command_ast_test.go b/common/bootcommand/boot_command_ast_test.go index d5ad21900..49bbb5cd4 100644 --- a/common/bootcommand/boot_command_ast_test.go +++ b/common/bootcommand/boot_command_ast_test.go @@ -3,19 +3,11 @@ package bootcommand import ( "fmt" "log" - "strings" "testing" "github.com/stretchr/testify/assert" ) -func toIfaceSlice(v interface{}) []interface{} { - if v == nil { - return nil - } - return v.([]interface{}) -} - func Test_parse(t *testing.T) { in := "<wait><wait20><wait3s><wait4m2ns>" in += "foo/bar > one 界" @@ -58,14 +50,13 @@ func Test_parse(t *testing.T) { "Spec-Press(rightsuper)", } - got, err := ParseReader("", strings.NewReader(in)) + seq, err := GenerateExpressionSequence(in) if err != nil { log.Fatal(err) } - gL := toIfaceSlice(got) - for i, g := range gL { - assert.Equal(t, expected[i], fmt.Sprintf("%s", g)) - log.Printf("%s\n", g) + for i, exp := range seq { + assert.Equal(t, expected[i], fmt.Sprintf("%s", exp)) + log.Printf("%s\n", exp) } } @@ -88,14 +79,12 @@ func Test_special(t *testing.T) { }, } for _, tt := range specials { - got, err := ParseReader("", strings.NewReader(tt.in)) + seq, err := GenerateExpressionSequence(tt.in) if err != nil { log.Fatal(err) } - - gL := toIfaceSlice(got) - for _, g := range gL { - assert.Equal(t, tt.out, g.(*specialExpression).String()) + for _, exp := range seq { + assert.Equal(t, tt.out, exp.(*specialExpression).String()) } } } @@ -123,14 +112,13 @@ func Test_validation(t *testing.T) { }, } for _, tt := range expressions { - got, err := ParseReader("", strings.NewReader(tt.in)) + exp, err := GenerateExpressionSequence(tt.in) if err != nil { log.Fatal(err) } - gL := toIfaceSlice(got) - assert.Len(t, gL, 1) - err = gL[0].(expression).Validate() + assert.Len(t, exp, 1) + err = exp[0].Validate() if tt.valid { assert.NoError(t, err) } else { From db65c99bf4d53d1259870d07059bedac8711a874 Mon Sep 17 00:00:00 2001 From: Richard Nienaber <rnienaber@salesforce.com> Date: Tue, 24 Apr 2018 10:35:27 +0100 Subject: [PATCH 0988/1007] update code based on master and update docs --- builder/googlecompute/step_create_windows_password.go | 2 +- website/source/docs/provisioners/powershell.html.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builder/googlecompute/step_create_windows_password.go b/builder/googlecompute/step_create_windows_password.go index a389ad97a..38d52d869 100644 --- a/builder/googlecompute/step_create_windows_password.go +++ b/builder/googlecompute/step_create_windows_password.go @@ -113,7 +113,7 @@ func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.State } state.Put("winrm_password", data.password) - commonhelper.SetSharedState("winrm_password", data.password) + commonhelper.SetSharedState("winrm_password", data.password, c.PackerConfig.PackerBuildName) return multistep.ActionContinue } diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index 0a97d41ac..602cddbb3 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -73,7 +73,7 @@ Optional parameters: inject prior to the execute\_command. The format should be `key=value`. Packer injects some environmental variables by default into the environment, as well, which are covered in the section below. - If you are running on AWS or Azure and would like to access the generated + If you are running on AWS, Azure or Google Compute and would like to access the generated password that Packer uses to connect to the instance via WinRM, you can use the template variable `{{.WinRMPassword}}` to set this as an environment variable. For example: @@ -101,8 +101,8 @@ Optional parameters: - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given - Windows user. If you are running a build on AWS and would like to run using - the AWS-generated password that Packer uses to connect to the instance via, + Windows user. If you are running a build on AWS, Azure or Google Compute and would like to run using + the generated password that Packer uses to connect to the instance via, WinRM, you may do so by using the template variable {{.WinRMPassword}}. For example: From 2cfbb83b70f3a1c7159cd346f44d14394e0328c1 Mon Sep 17 00:00:00 2001 From: Richard Nienaber <rnienaber@salesforce.com> Date: Tue, 24 Apr 2018 10:36:54 +0100 Subject: [PATCH 0989/1007] fix typo --- website/source/docs/provisioners/powershell.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index 602cddbb3..160fe7fab 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -102,7 +102,7 @@ Optional parameters: - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given Windows user. If you are running a build on AWS, Azure or Google Compute and would like to run using - the generated password that Packer uses to connect to the instance via, + the generated password that Packer uses to connect to the instance via WinRM, you may do so by using the template variable {{.WinRMPassword}}. For example: From 4e7feea184fc3b157b9b59fc534fc4db47387d39 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 23 Mar 2018 11:46:55 +0000 Subject: [PATCH 0990/1007] Allow users to specify the location that the env vars file is uploaded to Previously the location the file was uploaded to was set internally and used ${env:SYSTEMROOT}/Temp as the destination folder. By default, in order to inject the required environment variables, the file is 'dot sourced' by the 'execute_command' using the {{ .Vars }} variable. Unfortunately the inclusion of the dollar in the path caused issues for users connecting over ssh as the (typically bash) shell running the execute command would try and interpret the dollar sign. The change allows users to specify the location the file is uploaded to, thereby allowing the user to specify a custom 'execute_command' that escapes any dollar signs that could be present in the path. If not set the upload path now defaults to using C:/Windows/Temp as the upload folder. --- provisioner/powershell/provisioner.go | 34 +++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index c5a4845f7..8bcdaded4 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -57,6 +57,11 @@ type Config struct { // This should be set to a writable file that is in a pre-existing directory. RemotePath string `mapstructure:"remote_path"` + // The remote path where the file containing the environment variables + // will be uploaded to. This should be set to a writable file that is + // in a pre-existing directory. + RemoteEnvVarPath string `mapstructure:"remote_env_var_path"` + // The command used to execute the script. The '{{ .Path }}' variable // should be used to specify where the script goes, {{ .Vars }} // can be used to inject the environment_vars into the environment. @@ -159,6 +164,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { p.config.RemotePath = fmt.Sprintf(`c:/Windows/Temp/script-%s.ps1`, uuid) } + if p.config.RemoteEnvVarPath == "" { + uuid := uuid.TimeOrderedUUID() + p.config.RemoteEnvVarPath = fmt.Sprintf(`c:/Windows/Temp/packer-ps-env-vars-%s.ps1`, uuid) + } + if p.config.Scripts == nil { p.config.Scripts = make([]string, 0) } @@ -351,13 +361,13 @@ func (p *Provisioner) retryable(f func() error) error { // Environment variables required within the remote environment are uploaded within a PS script and // then enabled by 'dot sourcing' the script immediately prior to execution of the main command -func (p *Provisioner) prepareEnvVars(elevated bool) (envVarPath string, err error) { +func (p *Provisioner) prepareEnvVars(elevated bool) (err error) { // Collate all required env vars into a plain string with required formatting applied flattenedEnvVars := p.createFlattenedEnvVars(elevated) // Create a powershell script on the target build fs containing the flattened env vars - envVarPath, err = p.uploadEnvVars(flattenedEnvVars) + err = p.uploadEnvVars(flattenedEnvVars) if err != nil { - return "", err + return err } return } @@ -413,15 +423,13 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { return } -func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (envVarPath string, err error) { +func (p *Provisioner) uploadEnvVars(flattenedEnvVars string) (err error) { // Upload all env vars to a powershell script on the target build file system envVarReader := strings.NewReader(flattenedEnvVars) - uuid := uuid.TimeOrderedUUID() - envVarPath = fmt.Sprintf(`${env:SYSTEMROOT}/Temp/packer-env-vars-%s.ps1`, uuid) - log.Printf("Uploading env vars to %s", envVarPath) - err = p.communicator.Upload(envVarPath, envVarReader, nil) + log.Printf("Uploading env vars to %s", p.config.RemoteEnvVarPath) + err = p.communicator.Upload(p.config.RemoteEnvVarPath, envVarReader, nil) if err != nil { - return "", fmt.Errorf("Error uploading ps script containing env vars: %s", err) + return fmt.Errorf("Error uploading ps script containing env vars: %s", err) } return } @@ -437,14 +445,14 @@ func (p *Provisioner) createCommandText() (command string, err error) { func (p *Provisioner) createCommandTextNonPrivileged() (command string, err error) { // Prepare everything needed to enable the required env vars within the remote environment - envVarPath, err := p.prepareEnvVars(false) + err = p.prepareEnvVars(false) if err != nil { return "", err } p.config.ctx.Data = &ExecuteCommandTemplate{ Path: p.config.RemotePath, - Vars: envVarPath, + Vars: p.config.RemoteEnvVarPath, WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } command, err = interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) @@ -464,14 +472,14 @@ func getWinRMPassword(buildName string) string { func (p *Provisioner) createCommandTextPrivileged() (command string, err error) { // Prepare everything needed to enable the required env vars within the remote environment - envVarPath, err := p.prepareEnvVars(true) + err = p.prepareEnvVars(true) if err != nil { return "", err } p.config.ctx.Data = &ExecuteCommandTemplate{ Path: p.config.RemotePath, - Vars: envVarPath, + Vars: p.config.RemoteEnvVarPath, WinRMPassword: getWinRMPassword(p.config.PackerBuildName), } command, err = interpolate.Render(p.config.ElevatedExecuteCommand, &p.config.ctx) From 5b652316d9a8c8f88b19a790a14835f798c32926 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 23 Mar 2018 12:26:48 +0000 Subject: [PATCH 0991/1007] Dollar's in env vars used in paths may cause problems for ssh * Dollars are interpreted by *nix shells so paths using env vars such as ${env:SYSTEMROOT} will cause issues --- provisioner/powershell/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 8bcdaded4..8ec58c776 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -565,7 +565,7 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin return "", err } uuid := uuid.TimeOrderedUUID() - path := fmt.Sprintf(`${env:TEMP}/packer-elevated-shell-%s.ps1`, uuid) + path := fmt.Sprintf(`C:/Windows/Temp/packer-elevated-shell-%s.ps1`, uuid) log.Printf("Uploading elevated shell wrapper for command [%s] to [%s]", command, path) err = p.communicator.Upload(path, &buffer, nil) if err != nil { From 54193754132f51f4eee572d7bf98353bfc951e68 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Fri, 23 Mar 2018 12:33:35 +0000 Subject: [PATCH 0992/1007] Change to CMD % style path is no longer required --- provisioner/powershell/provisioner.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 8ec58c776..82ec98c82 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -571,8 +571,5 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin if err != nil { return "", fmt.Errorf("Error preparing elevated powershell script: %s", err) } - - // CMD formatted Path required for this op - path = fmt.Sprintf("%s-%s.ps1", "%TEMP%/packer-elevated-shell", uuid) return path, err } From ccf687dac6ca27a98d8c932d4a930fc30710f8e9 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 18 Apr 2018 02:14:21 +0100 Subject: [PATCH 0993/1007] Fix tests --- provisioner/powershell/provisioner_test.go | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/provisioner/powershell/provisioner_test.go b/provisioner/powershell/provisioner_test.go index 9c8237eb8..06fe39ef7 100644 --- a/provisioner/powershell/provisioner_test.go +++ b/provisioner/powershell/provisioner_test.go @@ -414,7 +414,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { } cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -434,7 +434,7 @@ func TestProvisionerProvision_Inline(t *testing.T) { } cmd = comm.StartCmd.Command - re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) + re = regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/inlineScript.ps1';exit \$LastExitCode }"`) matched = re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -461,7 +461,7 @@ func TestProvisionerProvision_Scripts(t *testing.T) { } cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -495,7 +495,7 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) { } cmd := comm.StartCmd.Command - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -612,7 +612,7 @@ func TestProvision_createCommandText(t *testing.T) { // Non-elevated cmd, _ := p.createCommandText() - re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. \${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) + re := regexp.MustCompile(`powershell -executionpolicy bypass "& { if \(Test-Path variable:global:ProgressPreference\){\$ProgressPreference='SilentlyContinue'};\. c:/Windows/Temp/packer-ps-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1; &'c:/Windows/Temp/script.ps1';exit \$LastExitCode }"`) matched := re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected command: %s", cmd) @@ -622,7 +622,7 @@ func TestProvision_createCommandText(t *testing.T) { p.config.ElevatedUser = "vagrant" p.config.ElevatedPassword = "vagrant" cmd, _ = p.createCommandText() - re = regexp.MustCompile(`powershell -executionpolicy bypass -file "%TEMP%/packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) + re = regexp.MustCompile(`powershell -executionpolicy bypass -file "C:/Windows/Temp/packer-elevated-shell-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1"`) matched = re.MatchString(cmd) if !matched { t.Fatalf("Got unexpected elevated command: %s", cmd) @@ -636,7 +636,7 @@ func TestProvision_uploadEnvVars(t *testing.T) { flattenedEnvVars := `$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild";` - envVarPath, err := p.uploadEnvVars(flattenedEnvVars) + err := p.uploadEnvVars(flattenedEnvVars) if err != nil { t.Fatalf("Did not expect error: %s", err.Error()) } @@ -644,12 +644,6 @@ func TestProvision_uploadEnvVars(t *testing.T) { if comm.UploadCalled != true { t.Fatalf("Failed to upload env var file") } - - re := regexp.MustCompile(`\${env:SYSTEMROOT}/Temp/packer-env-vars-[[:alnum:]]{8}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{4}-[[:alnum:]]{12}\.ps1`) - matched := re.MatchString(envVarPath) - if !matched { - t.Fatalf("Got unexpected path for env var file: %s", envVarPath) - } } func TestProvision_generateElevatedShellRunner(t *testing.T) { @@ -670,7 +664,7 @@ func TestProvision_generateElevatedShellRunner(t *testing.T) { t.Fatalf("Should have uploaded file") } - matched, _ := regexp.MatchString("%TEMP%(.{1})packer-elevated-shell.*", path) + matched, _ := regexp.MatchString("C:/Windows/Temp/packer-elevated-shell.*", path) if !matched { t.Fatalf("Got unexpected file: %s", path) } From 5db82aab215f350d29927e4a722ce85898447418 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 18 Apr 2018 11:18:47 +0100 Subject: [PATCH 0994/1007] Doc option allowing override of the path the env var script is uploaded to --- .../source/docs/provisioners/powershell.html.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index 0a97d41ac..b4e1d2ed8 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -115,6 +115,20 @@ Optional parameters: the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must be a writable location and any parent directories must already exist. +- `remote_env_var_path` (string) - Environment variables required within + the remote environment are uploaded within a PowerShell script and then + enabled by 'dot sourcing' the script immediately prior to execution of + the main command or script. + + The path the environment variables script will be uploaded to defaults to + `C:/Windows/Temp/packer-ps-env-vars-UUID.ps1` where UUID is replaced + with a dynamically generated string that uniquely identifies the + script. + + This setting allows users to override the location the environment + variable script is uploaded to. The value must be a writable location + and any parent directories must already exist. + - `start_retry_timeout` (string) - The amount of time to attempt to *start* the remote process. By default this is "5m" or 5 minutes. This setting exists in order to deal with times when SSH may restart, such as a From 2779fb0042da063b81155d13c0073155268dc3a6 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 19 Apr 2018 15:50:12 +0100 Subject: [PATCH 0995/1007] Additional information for using PowerShell with SSH --- .../docs/provisioners/powershell.html.md | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index b4e1d2ed8..24083da68 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -13,7 +13,11 @@ sidebar_current: 'docs-provisioners-powershell' Type: `powershell` The PowerShell Packer provisioner runs PowerShell scripts on Windows machines. -It assumes that the communicator in use is WinRM. +It assumes that the communicator in use is WinRM. However, the provisioner +can work equally well (with a few caveats) when combined with the SSH +communicator. See the [section +below](/docs/provisioners/powershell.html#combining-the-powershell-provisioner-with-the-ssh-communicator) +for details. ## Basic Example @@ -161,6 +165,41 @@ commonly useful environmental variables: slower speeds using the default file provisioner. A file provisioner using the `winrm` communicator may experience these types of difficulties. +## Combining the PowerShell Provisioner with the SSH Communicator + +The good news first. If you are using the +[Microsoft port of OpenSSH](https://github.com/PowerShell/Win32-OpenSSH/wiki) +then the provisioner should just work as expected - no extra configuration +effort is required. + +Now the caveats. If you are using an alternative configuration, and your SSH +connection lands you in a *nix shell on the remote host, then you will most +likely need to manually set the `execute_command`; The default +`execute_command` used by Packer will not work for you. +When configuring the command you will need to ensure that any dollar signs +or other characters that may be incorrectly interpreted by the remote shell +are escaped accordingly. + +The following example shows how the standard `execute_command` can be +reconfigured to work on a remote system with +[Cygwin/OpenSSH](https://cygwin.com/) installed. +The `execute_command` has each dollar sign backslash escaped so that it is +not interpreted by the remote Bash shell - Bash being the default shell for +Cygwin environments. + +```json + "provisioners": [ + { + "type": "powershell", + "execute_command": "powershell -executionpolicy bypass \"& { if (Test-Path variable:global:ProgressPreference){\\$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit \\$LastExitCode }\"", + "inline": [ + "Write-Host \"Hello from PowerShell\"", + ] + } + ] +``` + + ## Packer's Handling of Characters Special to PowerShell The escape character in PowerShell is the `backtick`, also sometimes From 8bbc9be71395043c44d39181e5c9a18e2bf8f511 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 18 Apr 2018 12:07:56 +0100 Subject: [PATCH 0996/1007] Explain how to manually set {{.Path}} and {{.Vars}} --- website/source/docs/provisioners/powershell.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index 24083da68..e1de273ec 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -101,7 +101,9 @@ Optional parameters: template](/docs/templates/engine.html). There are two available variables: `Path`, which is the path to the script to run, and `Vars`, which is the location of a temp file containing the list of - `environment_vars`, if configured. + `environment_vars`. The value of both `Path` and `Vars` can be + manually configured by setting the values for `remote_path` and + `remote_env_var_path` respectively. - `elevated_user` and `elevated_password` (string) - If specified, the PowerShell script will be run with elevated privileges using the given From f17523401e9d07a4a6c75c3f085a470483ba5852 Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Wed, 18 Apr 2018 12:20:52 +0100 Subject: [PATCH 0997/1007] The default path for uploading the PS script now incorporates a UUID --- website/source/docs/provisioners/powershell.html.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index e1de273ec..f5b19529d 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -117,9 +117,14 @@ Optional parameters: "elevated_password": "{{.WinRMPassword}}", ``` -- `remote_path` (string) - The path where the script will be uploaded to in - the machine. This defaults to "c:/Windows/Temp/script.ps1". This value must - be a writable location and any parent directories must already exist. +- `remote_path` (string) - The path where the PowerShell script will be + uploaded to within the target build machine. This defaults to + `C:/Windows/Temp/script-UUID.ps1` where UUID is replaced with a + dynamically generated string that uniquely identifies the script. + + This setting allows users to override the default upload location. The + value must be a writable location and any parent directories must + already exist. - `remote_env_var_path` (string) - Environment variables required within the remote environment are uploaded within a PowerShell script and then From 540a6a29f414f1ae44b312060227e7bdc0047332 Mon Sep 17 00:00:00 2001 From: Matthew Aynalem <mayn@users.noreply.github.com> Date: Tue, 24 Apr 2018 13:07:00 -0700 Subject: [PATCH 0998/1007] minor fix for some links that aren't being rendered and incorrect datatype --- website/source/docs/builders/alicloud-ecs.html.md | 4 ++-- website/source/docs/builders/triton.html.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/website/source/docs/builders/alicloud-ecs.html.md b/website/source/docs/builders/alicloud-ecs.html.md index df7abbeff..266b59445 100644 --- a/website/source/docs/builders/alicloud-ecs.html.md +++ b/website/source/docs/builders/alicloud-ecs.html.md @@ -67,7 +67,7 @@ builder. limit of 0 to 256 characters. Leaving it blank means null, which is the default value. It cannot begin with `http://` or `https://`. --   `image_disk_mappings` (array of image disk mappings) - Add one or more data disks +- `image_disk_mappings` (array of image disk mappings) - Add one or more data disks to the image. - `disk_category` (string) - Category of the data disk. Optional values are: @@ -77,7 +77,7 @@ builder. Default value: cloud. - - `disk_delete_with_instance` (string) - Whether or not the disk is released along with the instance: + - `disk_delete_with_instance` (boolean) - Whether or not the disk is released along with the instance: - True indicates that when the instance is released, this disk will be released with it - False indicates that when the instance is released, this disk will be retained. diff --git a/website/source/docs/builders/triton.html.md b/website/source/docs/builders/triton.html.md index 889b0d9d8..956228c84 100644 --- a/website/source/docs/builders/triton.html.md +++ b/website/source/docs/builders/triton.html.md @@ -50,6 +50,7 @@ builder. - `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 From ffaa60eb37f0c45e166ed2033b7249a721bf4468 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Tue, 24 Apr 2018 16:25:04 -0700 Subject: [PATCH 0999/1007] fix accidental deletion in vendor file --- vendor/vendor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/vendor.json b/vendor/vendor.json index bb00a6f68..aef17fba9 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1,6 +1,6 @@ { "comment": "", - "ignore": "test", + "ignore": "test appengine", "package": [ { "checksumSHA1": "aABATU51PlDHfGeSe5cc9udwSXg=", From ef03e97dc3f590ad20135137ec2c18064dba970a Mon Sep 17 00:00:00 2001 From: Matthew Donoughe <mdonoughe@gmail.com> Date: Tue, 24 Apr 2018 20:38:57 -0400 Subject: [PATCH 1000/1007] pass MacAddress to StepCreateVM --- builder/hyperv/iso/builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/builder/hyperv/iso/builder.go b/builder/hyperv/iso/builder.go index 9d32eef43..816299cbc 100644 --- a/builder/hyperv/iso/builder.go +++ b/builder/hyperv/iso/builder.go @@ -378,6 +378,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe DifferencingDisk: b.config.DifferencingDisk, SkipExport: b.config.SkipExport, OutputDir: b.config.OutputDir, + MacAddress: b.config.MacAddress, }, &hypervcommon.StepEnableIntegrationService{}, From 0130f1f794b393cf8ac610773cdc206287e077d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BARTH=C3=89L=C3=89MY?= <barthelemy@crans.org> Date: Wed, 25 Apr 2018 21:12:09 +0200 Subject: [PATCH 1001/1007] Hint about using --on-error=ask when debugging --- website/source/docs/other/debugging.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/other/debugging.html.md b/website/source/docs/other/debugging.html.md index f71e8b5e4..74f266c96 100644 --- a/website/source/docs/other/debugging.html.md +++ b/website/source/docs/other/debugging.html.md @@ -10,6 +10,9 @@ sidebar_current: 'docs-other-debugging' # Debugging Packer Builds +Using `packer build -on-error=ask` allows you to inspect failures and try out +solutions before restarting the build. + For remote builds with cloud providers like Amazon Web Services AMIs, debugging a Packer build can be eased greatly with `packer build -debug`. This disables parallelization and enables debug mode. From 1d87839debfa8ce727b8e0e16452392b01ff2a07 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 25 Apr 2018 14:11:50 -0700 Subject: [PATCH 1002/1007] update changelog for 1.2.3 release --- CHANGELOG.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b93652196..c29039f87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,67 @@ -## (UNRELEASED) +## 1.2.3 (April 25, 2018) ### BUG FIXES: -* post-processor/vagrant: Large VMDKs should no longer show a 0-byte size on OS X. [GH-6084] +* builder/azure: Azure CLI may now be logged into several accounts. [GH-6087] +* builder/ebssurrogate: Snapshot all launch devices. [GH-6056] +* builder/hyper-v: Fix CopyExportedVirtualMachine script so it works with + links. [GH-6082] +* builder/oracle-classic: Fix panics when cleaning up resources that haven't + been created. [GH-6095] +* builder/parallels: Allow user to cancel build while the OS is starting up. + [GH-6166] +* builder/qemu: Avoid warning when using raw format. [GH-6080] * builder/scaleway: Fix compilation issues on solaris/amd64. [GH-6069] -* common/bootcommand: Fix numerous bugs in the boot command code, and make supported features consistent across builders. [GH-6129] +* builder/virtualbox: Fix broken scancodes in boot_command. [GH-6067] +* builder/vmware-iso: Fail in validation if user gives wrong remote_type value. + [GH-4563] +* builder/vmware: Fixed a case-sensitivity issue when determing the network + type during the cloning step in the vmware-vmx builder. [GH-6057] +* builder/vmware: Fixes the DHCP lease and configuration pathfinders for VMware + Player. [GH-6096] +* builder/vmware: Multi-disk VM's can be properly handled by the compacting + stage. [GH-6074] +* common/bootcommand: Fix numerous bugs in the boot command code, and make + supported features consistent across builders. [GH-6129] +* communicator/ssh: Stop trying to discover whether destination is a directory + from uploader. [GH-6124] +* post-processor/vagrant: Large VMDKs should no longer show a 0-byte size on OS + X. [GH-6084] +* post-processor/vsphere: Fix encoding of spaces in passwords for upload. + [GH-6110] +* provisioner/ansible: Pass the inventory_directory configuration option to + ansible -i when it is set. [GH-6065] +* provisioner/powershell: fix bug with SSH communicator + cygwin. [GH-6160] +* provisioner/powershell: The {{.WinRMPassword}} template variable now works + with parallel builders. [GH-6144] ### IMPROVEMENTS: +* builder/alicloud: Update aliyungo common package. [GH-6157] +* builder/amazon: Expose more source ami data as template variables. [GH-6088] * builder/amazon: Setting `force_delete` will only delete AMIs owned by the - user. This should prevent failures where we try to delete an AMI with - a matching name, but owned by someone else. [GH-6111] + user. This should prevent failures where we try to delete an AMI with a + matching name, but owned by someone else. [GH-6111] +* builder/azure: Users of Powershell provisioner may access the randomly- + generated winrm password using the template variable {{.WinRMPassword}}. + [GH-6113] +* builder/google: Users of Powershell provisioner may access the randomly- + generated winrm password using the template variable {{.WinRMPassword}}. + [GH-6141] +* builder/hyper-v: User can now configure hyper-v disk block size. [GH-5941] * builder/openstack: Add configuration option for `instance_name`. [GH-6041] +* builder/oracle-classic: Better validation of destination image name. + [GH-6089] +* builder/oracle-oci: New config options for user data and user data file. + [GH-6079] +* builder/oracle-oci: use the official OCI sdk instead of handcrafted client. + [GH-6142] +* builder/triton: Add support to Skip TLS Verification of Triton Certificate. + [GH-6039] +* provisioner/ansible: Ansible users may provide a custom inventory file. + [GH-6107] +* provisioner/file: New `generated` tag allows users to upload files created + during Packer run. [GH-3891] ## 1.2.2 (March 26, 2018) From 227af03625bc8b24cf646cbfa535061069c8a8c6 Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 25 Apr 2018 14:12:38 -0700 Subject: [PATCH 1003/1007] update version and website for 1.2.3 --- version/version.go | 2 +- website/config.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index ff47b820f..9864764ff 100644 --- a/version/version.go +++ b/version/version.go @@ -14,7 +14,7 @@ const Version = "1.2.3" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" func FormattedVersion() string { var versionString bytes.Buffer diff --git a/website/config.rb b/website/config.rb index 6c4b1eb23..7601f6b78 100644 --- a/website/config.rb +++ b/website/config.rb @@ -2,7 +2,7 @@ set :base_url, "https://www.packer.io/" activate :hashicorp do |h| h.name = "packer" - h.version = "1.2.2" + h.version = "1.2.3" h.github_slug = "hashicorp/packer" h.website_root = "website" end From 79daa2fd536ee6116560604e6715d780cea893ce Mon Sep 17 00:00:00 2001 From: Megan Marsh <megan@hashicorp.com> Date: Wed, 25 Apr 2018 14:32:44 -0700 Subject: [PATCH 1005/1007] update to 1.2.4-dev --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 9864764ff..baaac8187 100644 --- a/version/version.go +++ b/version/version.go @@ -9,12 +9,12 @@ import ( var GitCommit string // The main version number that is being run at the moment. -const Version = "1.2.3" +const Version = "1.2.4" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" func FormattedVersion() string { var versionString bytes.Buffer From b9ab2c8048d766a6bb4d13f285f8e699304dad6c Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 26 Apr 2018 00:17:13 +0100 Subject: [PATCH 1006/1007] Remove script containing PowerShell inline commands from local tmp when done --- provisioner/powershell/provisioner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 82ec98c82..6eb9c5572 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -269,6 +269,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Error(fmt.Sprintf("Unable to extract inline scripts into a file: %s", err)) } scripts = append(scripts, temp) + // Remove temp script containing the inline commands when done + defer os.Remove(temp) } for _, path := range scripts { From 7cf31060ebbbc1970f3ce93be61a3f4d24a0bc1d Mon Sep 17 00:00:00 2001 From: DanHam <DanHam@users.noreply.github.com> Date: Thu, 26 Apr 2018 00:20:17 +0100 Subject: [PATCH 1007/1007] Remove script containing Win-Shell inline commands from local tmp when done --- provisioner/windows-shell/provisioner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provisioner/windows-shell/provisioner.go b/provisioner/windows-shell/provisioner.go index babc9b5ec..f9b105121 100644 --- a/provisioner/windows-shell/provisioner.go +++ b/provisioner/windows-shell/provisioner.go @@ -190,6 +190,8 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ui.Error(fmt.Sprintf("Unable to extract inline scripts into a file: %s", err)) } scripts = append(scripts, temp) + // Remove temp script containing the inline commands when done + defer os.Remove(temp) } for _, path := range scripts {